Add super sampler begin and end bytecodes.
authorkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Nov 2017 21:26:33 +0000 (21:26 +0000)
committerkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Nov 2017 21:26:33 +0000 (21:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179376

Reviewed by Filip Pizlo.

This patch adds a way to measure a narrow range of bytecodes for
performance. This is done using the same infrastructure as the
super sampler. I also added a class that helps do the bytecode
checking with RAII. One problem with the current way this is done
is that we don't handle decrementing early exits, either from
branches or exceptions. So, when using this API users need to
ensure that there are no early exits or that those exits don't
occur on the measure code.

* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/BytecodeDumper.cpp:
(JSC::BytecodeDumper<Block>::dumpBytecode):
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitSuperSamplerBegin):
(JSC::BytecodeGenerator::emitSuperSamplerEnd):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/SuperSamplerBytecodeScope.h: Added.
(JSC::SuperSamplerBytecodeScope::SuperSamplerBytecodeScope):
(JSC::SuperSamplerBytecodeScope::~SuperSamplerBytecodeScope):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGClobbersExitState.cpp:
(JSC::DFG::clobbersExitState):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGMayExit.cpp:
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileSuperSamplerBegin):
(JSC::FTL::DFG::LowerDFGToB3::compileSuperSamplerEnd):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_super_sampler_begin):
(JSC::JIT::emit_op_super_sampler_end):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224594 268f45cc-cd09-0410-ab3c-d52691b4dbfc

29 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/bytecode/BytecodeDumper.cpp
Source/JavaScriptCore/bytecode/BytecodeList.json
Source/JavaScriptCore/bytecode/BytecodeUseDef.h
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
Source/JavaScriptCore/bytecompiler/SuperSamplerBytecodeScope.h [new file with mode: 0644]
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGClobberize.h
Source/JavaScriptCore/dfg/DFGClobbersExitState.cpp
Source/JavaScriptCore/dfg/DFGDoesGC.cpp
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGMayExit.cpp
Source/JavaScriptCore/dfg/DFGNodeType.h
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
Source/JavaScriptCore/dfg/DFGSafeToExecute.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
Source/JavaScriptCore/ftl/FTLCapabilities.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/jit/JIT.cpp
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.h
Source/JavaScriptCore/llint/LowLevelInterpreter.asm

index e171108..93c8647 100644 (file)
@@ -1,3 +1,72 @@
+2017-11-08  Keith Miller  <keith_miller@apple.com>
+
+        Add super sampler begin and end bytecodes.
+        https://bugs.webkit.org/show_bug.cgi?id=179376
+
+        Reviewed by Filip Pizlo.
+
+        This patch adds a way to measure a narrow range of bytecodes for
+        performance. This is done using the same infrastructure as the
+        super sampler. I also added a class that helps do the bytecode
+        checking with RAII. One problem with the current way this is done
+        is that we don't handle decrementing early exits, either from
+        branches or exceptions. So, when using this API users need to
+        ensure that there are no early exits or that those exits don't
+        occur on the measure code.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/BytecodeDumper.cpp:
+        (JSC::BytecodeDumper<Block>::dumpBytecode):
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitSuperSamplerBegin):
+        (JSC::BytecodeGenerator::emitSuperSamplerEnd):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/SuperSamplerBytecodeScope.h: Added.
+        (JSC::SuperSamplerBytecodeScope::SuperSamplerBytecodeScope):
+        (JSC::SuperSamplerBytecodeScope::~SuperSamplerBytecodeScope):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGClobbersExitState.cpp:
+        (JSC::DFG::clobbersExitState):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGMayExit.cpp:
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileSuperSamplerBegin):
+        (JSC::FTL::DFG::LowerDFGToB3::compileSuperSamplerEnd):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_super_sampler_begin):
+        (JSC::JIT::emit_op_super_sampler_end):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+
 2017-11-08  Robin Morisset  <rmorisset@apple.com>
 
         Turn recursive tail calls into loops
index 9315e35..c570ef6 100644 (file)
                530A66C21FA3E78B0026A545 /* UnifiedSource143.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 530A66B71FA3E77D0026A545 /* UnifiedSource143.cpp */; };
                530A66C31FA3E78B0026A545 /* UnifiedSource144.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 530A66AD1FA3E7770026A545 /* UnifiedSource144.cpp */; };
                530A66C41FA3E78B0026A545 /* UnifiedSource145.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 530A66B01FA3E77A0026A545 /* UnifiedSource145.cpp */; };
+               530A66CD1FB1346D0026A545 /* SuperSamplerBytecodeScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 530A66CC1FB1346D0026A545 /* SuperSamplerBytecodeScope.h */; };
                530FB3021E7A0B6E003C19DD /* WasmWorklist.h in Headers */ = {isa = PBXBuildFile; fileRef = 530FB3011E7A0B6E003C19DD /* WasmWorklist.h */; };
                5311BD4B1EA581E500525281 /* WasmOMGPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 5311BD491EA581E500525281 /* WasmOMGPlan.h */; };
                531374BD1D5CE67600AF7A0B /* WasmPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 531374BC1D5CE67600AF7A0B /* WasmPlan.h */; };
                530A66B51FA3E77D0026A545 /* UnifiedSource5-mm.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UnifiedSource5-mm.mm"; sourceTree = "<group>"; };
                530A66B61FA3E77D0026A545 /* UnifiedSource142.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnifiedSource142.cpp; sourceTree = "<group>"; };
                530A66B71FA3E77D0026A545 /* UnifiedSource143.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnifiedSource143.cpp; sourceTree = "<group>"; };
-               530A66B81FA3E77E0026A545 /* UnifiedSource4-mm.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UnifiedSource4-mm.mm"; sourceTree = "<group>"; };
-               530FB3011E7A0B6E003C19DD /* WasmWorklist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmWorklist.h; sourceTree = "<group>"; };
+                530A66B81FA3E77E0026A545 /* UnifiedSource4-mm.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UnifiedSource4-mm.mm"; sourceTree = "<group>"; };
+                530A66CC1FB1346D0026A545 /* SuperSamplerBytecodeScope.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SuperSamplerBytecodeScope.h; sourceTree = "<group>"; };
+                530FB3011E7A0B6E003C19DD /* WasmWorklist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmWorklist.h; sourceTree = "<group>"; };
                530FB3031E7A1146003C19DD /* WasmWorklist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmWorklist.cpp; sourceTree = "<group>"; };
                5311BD481EA581E500525281 /* WasmOMGPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmOMGPlan.cpp; sourceTree = "<group>"; };
                5311BD491EA581E500525281 /* WasmOMGPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmOMGPlan.h; sourceTree = "<group>"; };
                                969A07280ED1CE6900F1F681 /* RegisterID.h */,
                                14DF04D916B3996D0016A513 /* StaticPropertyAnalysis.h */,
                                14CA958A16AB50DE00938A06 /* StaticPropertyAnalyzer.h */,
+                               530A66CC1FB1346D0026A545 /* SuperSamplerBytecodeScope.h */,
                        );
                        path = bytecompiler;
                        sourceTree = "<group>";
                                0F7DF1371E2970E10095951B /* Subspace.h in Headers */,
                                0F7DF1381E2970E40095951B /* SubspaceInlines.h in Headers */,
                                0F4A38FA1C8E13DF00190318 /* SuperSampler.h in Headers */,
+                               530A66CD1FB1346D0026A545 /* SuperSamplerBytecodeScope.h in Headers */,
                                0FD0E5EE1E468A570006AB08 /* SweepingScope.h in Headers */,
                                705B41AC1A6E501E00716757 /* Symbol.h in Headers */,
                                705B41AE1A6E501E00716757 /* SymbolConstructor.h in Headers */,
index 4f9834e..5a0d6d1 100644 (file)
@@ -1276,6 +1276,14 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block:
         printLocationAndOp(out, location, it, "nop");
         break;
     }
+    case op_super_sampler_begin: {
+        printLocationAndOp(out, location, it, "super_sampler_begin");
+        break;
+    }
+    case op_super_sampler_end: {
+        printLocationAndOp(out, location, it, "super_sampler_end");
+        break;
+    }
     case op_log_shadow_chicken_prologue: {
         int r0 = (++it)->u.operand;
         printLocationAndOp(out, location, it, "log_shadow_chicken_prologue");
index 09005ea..b5b8f99 100644 (file)
             { "name" : "op_log_shadow_chicken_prologue", "length" : 2},
             { "name" : "op_log_shadow_chicken_tail", "length" : 3},
             { "name" : "op_resolve_scope_for_hoisting_func_decl_in_eval", "length" : 4 },
-            { "name" : "op_nop", "length" : 1 }
+            { "name" : "op_nop", "length" : 1 },
+            { "name" : "op_super_sampler_begin", "length" : 1 },
+            { "name" : "op_super_sampler_end", "length" : 1 }
         ]
     },
     {
index ff25218..759a1eb 100644 (file)
@@ -55,6 +55,8 @@ void computeUsesForBytecodeOffset(Block* codeBlock, OpcodeID opcodeID, Instructi
     case op_get_argument:
     case op_nop:
     case op_unreachable:
+    case op_super_sampler_begin:
+    case op_super_sampler_end:
         return;
     case op_assert:
     case op_get_scope:
@@ -377,6 +379,8 @@ void computeDefsForBytecodeOffset(Block* codeBlock, OpcodeID opcodeID, Instructi
     case op_yield:
     case op_nop:
     case op_unreachable:
+    case op_super_sampler_begin:
+    case op_super_sampler_end:
 #define LLINT_HELPER_OPCODES(opcode, length) case opcode:
         FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
 #undef LLINT_HELPER_OPCODES
index 3021cc1..c5e9810 100644 (file)
@@ -48,6 +48,7 @@
 #include "Options.h"
 #include "StackAlignment.h"
 #include "StrongInlines.h"
+#include "SuperSamplerBytecodeScope.h"
 #include "UnlinkedCodeBlock.h"
 #include "UnlinkedEvalCodeBlock.h"
 #include "UnlinkedFunctionCodeBlock.h"
@@ -2967,6 +2968,16 @@ RegisterID* BytecodeGenerator::emitAssert(RegisterID* condition, int line)
     return condition;
 }
 
+void BytecodeGenerator::emitSuperSamplerBegin()
+{
+    emitOpcode(op_super_sampler_begin);
+}
+
+void BytecodeGenerator::emitSuperSamplerEnd()
+{
+    emitOpcode(op_super_sampler_end);
+}
+
 RegisterID* BytecodeGenerator::emitIdWithProfile(RegisterID* src, SpeculatedType profile)
 {
     emitOpcode(op_identity_with_profile);
index fc49be4..2b24264 100644 (file)
@@ -690,6 +690,9 @@ namespace JSC {
         RegisterID* emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value);
 
         RegisterID* emitAssert(RegisterID* condition, int line);
+        void emitSuperSamplerBegin();
+        void emitSuperSamplerEnd();
+
         RegisterID* emitIdWithProfile(RegisterID* src, SpeculatedType profile);
         void emitUnreachable();
 
diff --git a/Source/JavaScriptCore/bytecompiler/SuperSamplerBytecodeScope.h b/Source/JavaScriptCore/bytecompiler/SuperSamplerBytecodeScope.h
new file mode 100644 (file)
index 0000000..f25b210
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "BytecodeGenerator.h"
+
+namespace JSC {
+
+class SuperSamplerBytecodeScope {
+public:
+    SuperSamplerBytecodeScope(BytecodeGenerator& generator)
+        : m_generator(generator)
+    {
+        m_generator.emitSuperSamplerBegin();
+    }
+
+    ~SuperSamplerBytecodeScope()
+    {
+        m_generator.emitSuperSamplerEnd();
+    }
+
+private:
+    BytecodeGenerator& m_generator;
+};
+
+}
index cd0a4cb..48c14da 100644 (file)
@@ -3245,6 +3245,8 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
     case CheckTierUpInLoop:
     case CheckTierUpAtReturn:
     case CheckTypeInfoFlags:
+    case SuperSamplerBegin:
+    case SuperSamplerEnd:
         break;
 
     case ParseInt: {
index 5c6822e..29befe0 100644 (file)
@@ -5959,7 +5959,17 @@ void ByteCodeParser::parseBlock(unsigned limit)
             addToGraph(Check); // We add a nop here so that basic block linking doesn't break.
             NEXT_OPCODE(op_nop);
         }
-            
+
+        case op_super_sampler_begin: {
+            addToGraph(SuperSamplerBegin);
+            NEXT_OPCODE(op_super_sampler_begin);
+        }
+
+        case op_super_sampler_end: {
+            addToGraph(SuperSamplerEnd);
+            NEXT_OPCODE(op_super_sampler_end);
+        }
+
         case op_create_lexical_environment: {
             VirtualRegister symbolTableRegister(currentInstruction[3].u.operand);
             VirtualRegister initialValueRegister(currentInstruction[4].u.operand);
index bbd450a..ba848e5 100644 (file)
@@ -1575,6 +1575,8 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
         }
         
     case CountExecution:
+    case SuperSamplerBegin:
+    case SuperSamplerEnd:
         read(InternalState);
         write(InternalState);
         return;
index fb94364..6609f0f 100644 (file)
@@ -68,6 +68,8 @@ bool clobbersExitState(Graph& graph, Node* node)
     case PhantomCreateActivation:
     case MaterializeCreateActivation:
     case CountExecution:
+    case SuperSamplerBegin:
+    case SuperSamplerEnd:
     case StoreBarrier:
     case FencedStoreBarrier:
     case AllocatePropertyStorage:
index 59596e8..90e3703 100644 (file)
@@ -197,6 +197,8 @@ bool doesGC(Graph& graph, Node* node)
     case TailCallVarargs:
     case Throw:
     case CountExecution:
+    case SuperSamplerBegin:
+    case SuperSamplerEnd:
     case ForceOSRExit:
     case CheckTraps:
     case StringFromCharCode:
index 019e77b..443c4d3 100644 (file)
@@ -2103,6 +2103,8 @@ private:
         case TailCallVarargs:
         case Throw:
         case CountExecution:
+        case SuperSamplerBegin:
+        case SuperSamplerEnd:
         case ForceOSRExit:
         case CheckBadCell:
         case CheckNotEmpty:
index de4ce54..6e08736 100644 (file)
@@ -78,6 +78,8 @@ ExitMode mayExitImpl(Graph& graph, Node* node, StateType& state)
     case GetScope:
     case PhantomLocal:
     case CountExecution:
+    case SuperSamplerBegin:
+    case SuperSamplerEnd:
     case Jump:
     case EntrySwitch:
     case Branch:
index 57fd197..839beb2 100644 (file)
@@ -408,6 +408,9 @@ namespace JSC { namespace DFG {
     \
     /* Count execution. */\
     macro(CountExecution, NodeMustGenerate) \
+    /* Super sampler. */\
+    macro(SuperSamplerBegin, NodeMustGenerate) \
+    macro(SuperSamplerEnd, NodeMustGenerate) \
     \
     /* This is a pseudo-terminal. It means that execution should fall out of DFG at */\
     /* this point, but execution does continue in the basic block - just in a */\
index 8bcdd2d..612d453 100644 (file)
@@ -1177,6 +1177,8 @@ private:
             
         // These gets ignored because it doesn't do anything.
         case CountExecution:
+        case SuperSamplerBegin:
+        case SuperSamplerEnd:
         case PhantomLocal:
         case Flush:
             break;
index 2208775..4f5bbb8 100644 (file)
@@ -348,6 +348,8 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case Throw:
     case ThrowStaticError:
     case CountExecution:
+    case SuperSamplerBegin:
+    case SuperSamplerEnd:
     case ForceOSRExit:
     case CheckTraps:
     case LogShadowChickenPrologue:
index b5eb7f2..5778f33 100644 (file)
@@ -59,6 +59,7 @@
 #include "RegExpConstructor.h"
 #include "ScopedArguments.h"
 #include "ScratchRegisterAllocator.h"
+#include "SuperSampler.h"
 #include <wtf/BitVector.h>
 #include <wtf/Box.h>
 #include <wtf/MathExtras.h>
index 4131530..6f73c28 100644 (file)
@@ -5537,6 +5537,14 @@ void SpeculativeJIT::compile(Node* node)
         m_jit.add64(TrustedImm32(1), MacroAssembler::AbsoluteAddress(node->executionCounter()->address()));
         break;
 
+    case SuperSamplerBegin:
+        m_jit.add32(TrustedImm32(1), MacroAssembler::AbsoluteAddress(bitwise_cast<void*>(&g_superSamplerCount)));
+        break;
+
+    case SuperSamplerEnd:
+        m_jit.sub32(TrustedImm32(1), MacroAssembler::AbsoluteAddress(bitwise_cast<void*>(&g_superSamplerCount)));
+        break;
+
     case Phantom:
     case Check:
         DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
index df76097..0789cab 100644 (file)
@@ -5575,6 +5575,14 @@ void SpeculativeJIT::compile(Node* node)
         m_jit.add64(TrustedImm32(1), MacroAssembler::AbsoluteAddress(node->executionCounter()->address()));
         break;
 
+    case SuperSamplerBegin:
+        m_jit.add32(TrustedImm32(1), MacroAssembler::AbsoluteAddress(bitwise_cast<void*>(&g_superSamplerCount)));
+        break;
+
+    case SuperSamplerEnd:
+        m_jit.sub32(TrustedImm32(1), MacroAssembler::AbsoluteAddress(bitwise_cast<void*>(&g_superSamplerCount)));
+        break;
+
     case ForceOSRExit: {
         terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
         break;
index af6689b..e277e24 100644 (file)
@@ -174,6 +174,8 @@ inline CapabilityLevel canCompile(Node* node)
     case ConstantStoragePointer:
     case Check:
     case CountExecution:
+    case SuperSamplerBegin:
+    case SuperSamplerEnd:
     case GetExecutable:
     case GetScope:
     case GetCallee:
index 649930c..9259ebf 100644 (file)
@@ -84,6 +84,7 @@
 #include "SetupVarargsFrame.h"
 #include "ShadowChicken.h"
 #include "StructureStubInfo.h"
+#include "SuperSampler.h"
 #include "ThunkGenerators.h"
 #include "VirtualRegister.h"
 #include "Watchdog.h"
@@ -1080,6 +1081,12 @@ private:
         case CountExecution:
             compileCountExecution();
             break;
+        case SuperSamplerBegin:
+            compileSuperSamplerBegin();
+            break;
+        case SuperSamplerEnd:
+            compileSuperSamplerEnd();
+            break;
         case StoreBarrier:
         case FencedStoreBarrier:
             compileStoreBarrier();
@@ -9188,7 +9195,19 @@ private:
         TypedPointer counter = m_out.absolute(m_node->executionCounter()->address());
         m_out.store64(m_out.add(m_out.load64(counter), m_out.constInt64(1)), counter);
     }
-    
+
+    void compileSuperSamplerBegin()
+    {
+        TypedPointer counter = m_out.absolute(bitwise_cast<void*>(&g_superSamplerCount));
+        m_out.store32(m_out.add(m_out.load32(counter), m_out.constInt32(1)), counter);
+    }
+
+    void compileSuperSamplerEnd()
+    {
+        TypedPointer counter = m_out.absolute(bitwise_cast<void*>(&g_superSamplerCount));
+        m_out.store32(m_out.sub(m_out.load32(counter), m_out.constInt32(1)), counter);
+    }
+
     void compileStoreBarrier()
     {
         emitStoreBarrier(lowCell(m_node->child1()), m_node->op() == FencedStoreBarrier);
index 8f0e72c..c86aa31 100644 (file)
@@ -347,6 +347,8 @@ void JIT::privateCompileMainPass()
         DEFINE_OP(op_loop_hint)
         DEFINE_OP(op_check_traps)
         DEFINE_OP(op_nop)
+        DEFINE_OP(op_super_sampler_begin)
+        DEFINE_OP(op_super_sampler_end)
         DEFINE_OP(op_lshift)
         DEFINE_OP(op_mod)
         DEFINE_OP(op_mov)
index 6aa4874..e7632f6 100644 (file)
@@ -528,6 +528,8 @@ namespace JSC {
         void emit_op_loop_hint(Instruction*);
         void emit_op_check_traps(Instruction*);
         void emit_op_nop(Instruction*);
+        void emit_op_super_sampler_begin(Instruction*);
+        void emit_op_super_sampler_end(Instruction*);
         void emit_op_lshift(Instruction*);
         void emit_op_mod(Instruction*);
         void emit_op_mov(Instruction*);
index f3dcb51..c79fdac 100644 (file)
@@ -41,6 +41,7 @@
 #include "LinkBuffer.h"
 #include "MaxFrameExtentForSlowPathCall.h"
 #include "SlowPathCall.h"
+#include "SuperSampler.h"
 #include "ThunkGenerators.h"
 #include "TypeLocation.h"
 #include "TypeProfilerLog.h"
@@ -968,6 +969,16 @@ void JIT::emit_op_nop(Instruction*)
 {
 }
 
+void JIT::emit_op_super_sampler_begin(Instruction*)
+{
+    add32(TrustedImm32(1), AbsoluteAddress(bitwise_cast<void*>(&g_superSamplerCount)));
+}
+
+void JIT::emit_op_super_sampler_end(Instruction*)
+{
+    sub32(TrustedImm32(1), AbsoluteAddress(bitwise_cast<void*>(&g_superSamplerCount)));
+}
+
 void JIT::emitSlow_op_check_traps(Instruction*, Vector<SlowCaseEntry>::iterator& iter)
 {
     linkAllSlowCases(iter);
index 297b6c1..d8d069c 100644 (file)
@@ -66,6 +66,7 @@
 #include "RegExpObject.h"
 #include "ShadowChicken.h"
 #include "StructureRareDataInlines.h"
+#include "SuperSampler.h"
 #include "VMInlines.h"
 #include <wtf/NeverDestroyed.h>
 #include <wtf/StringPrintStream.h>
@@ -1732,6 +1733,24 @@ LLINT_SLOW_PATH_DECL(slow_path_profile_catch)
     LLINT_END();
 }
 
+LLINT_SLOW_PATH_DECL(slow_path_super_sampler_begin)
+{
+    // FIXME: It seems like we should be able to do this in asm but llint doesn't seem to like global variables.
+    // See: https://bugs.webkit.org/show_bug.cgi?id=179438
+    UNUSED_PARAM(exec);
+    g_superSamplerCount++;
+    LLINT_END_IMPL();
+}
+
+LLINT_SLOW_PATH_DECL(slow_path_super_sampler_end)
+{
+    // FIXME: It seems like we should be able to do this in asm but llint doesn't seem to like global variables.
+    // See: https://bugs.webkit.org/show_bug.cgi?id=179438
+    UNUSED_PARAM(exec);
+    g_superSamplerCount--;
+    LLINT_END_IMPL();
+}
+
 extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame)
 {
     ExecState* exec = vm->topCallFrame;
index d9954d2..edd00e0 100644 (file)
@@ -129,6 +129,8 @@ LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_check_if_exception_is_uncatchable_and_noti
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_profile_catch);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_log_shadow_chicken_prologue);
 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_log_shadow_chicken_tail);
+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_super_sampler_begin);
+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_super_sampler_end);
 extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM*, ProtoCallFrame*) WTF_INTERNAL;
 #if !ENABLE(JIT)
 extern "C" SlowPathReturnType llint_stack_check_at_vm_entry(VM*, Register*) WTF_INTERNAL;
index 6c054fa..cffb1c5 100644 (file)
@@ -1638,6 +1638,17 @@ _llint_op_nop:
     dispatch(constexpr op_nop_length)
 
 
+_llint_op_super_sampler_begin:
+    callOpcodeSlowPath(_llint_slow_path_super_sampler_begin)
+    dispatch(constexpr op_super_sampler_begin_length)
+
+
+_llint_op_super_sampler_end:
+    traceExecution()
+    callOpcodeSlowPath(_llint_slow_path_super_sampler_end)
+    dispatch(constexpr op_super_sampler_end_length)
+
+
 _llint_op_switch_string:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_switch_string)