[JSC] Shrink the Math inline caches some more
authorbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Sep 2016 21:11:31 +0000 (21:11 +0000)
committerbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Sep 2016 21:11:31 +0000 (21:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=162485

Reviewed by Saam Barati.

Source/JavaScriptCore:

This patch applies some lessons learnt from op_negate
to shrink the generated asm of the previous 3 inline
caches.

In order of importance:
-We do not need to pass the pointer to ArithProfile
 on the slow path. We can just get the profile out
 of the Math IC.
 This saves us from materializing a 64bits value
 in a register before the call on the slow path.
-We can remove a bunch of mov by setting up the registers
 in the way the slow path needs them.
 The slow path makes a function calls with the input
 as second and third arguments, and return the result in
 the "return register". By using those as target when
 loading/storing from the stack, we remove 3 mov per slow path.
-When performing integer add, we can set the result directly in
 the output register if that does not trashes one of the input
 register. This removes one mov per integer add.

The inline cache average sizes on Sunspider change as follow:
-Adds: 147.573099->131.555556 (~10%)
-Muls: 186.882353->170.991597 (~8%)
-Subs: 139.127907->121.523256 (~12%)

* jit/JIT.h:
* jit/JITAddGenerator.cpp:
(JSC::JITAddGenerator::generateInline):
(JSC::JITAddGenerator::generateFastPath):
* jit/JITArithmetic.cpp:
(JSC::JIT::emitMathICFast):
(JSC::JIT::emitMathICSlow):
* jit/JITInlines.h:
(JSC::JIT::callOperation): Deleted.
* jit/JITOperations.cpp:
* jit/JITOperations.h:

Source/WTF:

* wtf/Bag.h:
Don't copy the arguments before initializing the nodes.

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

23 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/ArithProfile.cpp
Source/JavaScriptCore/bytecode/ArithProfile.h
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecode/CodeBlock.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITAddGenerator.cpp
Source/JavaScriptCore/jit/JITAddGenerator.h
Source/JavaScriptCore/jit/JITArithmetic.cpp
Source/JavaScriptCore/jit/JITInlines.h
Source/JavaScriptCore/jit/JITMathIC.h
Source/JavaScriptCore/jit/JITMulGenerator.cpp
Source/JavaScriptCore/jit/JITMulGenerator.h
Source/JavaScriptCore/jit/JITNegGenerator.cpp
Source/JavaScriptCore/jit/JITNegGenerator.h
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/jit/JITSubGenerator.cpp
Source/JavaScriptCore/jit/JITSubGenerator.h
Source/WTF/ChangeLog
Source/WTF/wtf/Bag.h

index 86bb2a3..078d2cf 100644 (file)
@@ -1,3 +1,47 @@
+2016-09-26  Benjamin Poulain  <benjamin@webkit.org>
+
+        [JSC] Shrink the Math inline caches some more
+        https://bugs.webkit.org/show_bug.cgi?id=162485
+
+        Reviewed by Saam Barati.
+
+        This patch applies some lessons learnt from op_negate
+        to shrink the generated asm of the previous 3 inline
+        caches.
+
+        In order of importance:
+        -We do not need to pass the pointer to ArithProfile
+         on the slow path. We can just get the profile out
+         of the Math IC.
+         This saves us from materializing a 64bits value
+         in a register before the call on the slow path.
+        -We can remove a bunch of mov by setting up the registers
+         in the way the slow path needs them.
+         The slow path makes a function calls with the input
+         as second and third arguments, and return the result in
+         the "return register". By using those as target when
+         loading/storing from the stack, we remove 3 mov per slow path.
+        -When performing integer add, we can set the result directly in
+         the output register if that does not trashes one of the input
+         register. This removes one mov per integer add.
+
+        The inline cache average sizes on Sunspider change as follow:
+        -Adds: 147.573099->131.555556 (~10%)
+        -Muls: 186.882353->170.991597 (~8%)
+        -Subs: 139.127907->121.523256 (~12%)
+
+        * jit/JIT.h:
+        * jit/JITAddGenerator.cpp:
+        (JSC::JITAddGenerator::generateInline):
+        (JSC::JITAddGenerator::generateFastPath):
+        * jit/JITArithmetic.cpp:
+        (JSC::JIT::emitMathICFast):
+        (JSC::JIT::emitMathICSlow):
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation): Deleted.
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+
 2016-09-26  Mark Lam  <mark.lam@apple.com>
 
         Added RETURN_IF_EXCEPTION() macro and use it for exception checks.
index 6154306..1fa7c79 100644 (file)
@@ -53,7 +53,7 @@ bool ArithProfile::shouldEmitSetDouble() const
     return (m_bits & mask) != mask;
 }
 
-void ArithProfile::emitSetDouble(CCallHelpers& jit)
+void ArithProfile::emitSetDouble(CCallHelpers& jit) const
 {
     if (shouldEmitSetDouble())
         jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int32Overflow | ArithProfile::Int52Overflow | ArithProfile::NegZeroDouble | ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(addressOfBits()));
@@ -65,7 +65,7 @@ bool ArithProfile::shouldEmitSetNonNumber() const
     return (m_bits & mask) != mask;
 }
 
-void ArithProfile::emitSetNonNumber(CCallHelpers& jit)
+void ArithProfile::emitSetNonNumber(CCallHelpers& jit) const
 {
     if (shouldEmitSetNonNumber())
         jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNumber), CCallHelpers::AbsoluteAddress(addressOfBits()));
index 7a6ee5d..40fad1b 100644 (file)
@@ -158,7 +158,7 @@ public:
     void setObservedInt32Overflow() { setBit(Int32Overflow); }
     void setObservedInt52Overflow() { setBit(Int52Overflow); }
 
-    void* addressOfBits() { return &m_bits; }
+    const void* addressOfBits() const { return &m_bits; }
 
     void observeResult(JSValue value)
     {
@@ -215,10 +215,10 @@ public:
     
     // Sets (Int32Overflow | Int52Overflow | NonNegZeroDouble | NegZeroDouble).
     bool shouldEmitSetDouble() const;
-    void emitSetDouble(CCallHelpers&);
+    void emitSetDouble(CCallHelpers&) const;
     
     // Sets NonNumber.
-    void emitSetNonNumber(CCallHelpers&);
+    void emitSetNonNumber(CCallHelpers&) const;
     bool shouldEmitSetNonNumber() const;
 #endif // ENABLE(JIT)
 
index f00d98c..7c9b5c2 100644 (file)
@@ -3000,24 +3000,24 @@ StructureStubInfo* CodeBlock::addStubInfo(AccessType accessType)
     return m_stubInfos.add(accessType);
 }
 
-JITAddIC* CodeBlock::addJITAddIC()
+JITAddIC* CodeBlock::addJITAddIC(ArithProfile* arithProfile)
 {
-    return m_addICs.add();
+    return m_addICs.add(arithProfile);
 }
 
-JITMulIC* CodeBlock::addJITMulIC()
+JITMulIC* CodeBlock::addJITMulIC(ArithProfile* arithProfile)
 {
-    return m_mulICs.add();
+    return m_mulICs.add(arithProfile);
 }
 
-JITSubIC* CodeBlock::addJITSubIC()
+JITSubIC* CodeBlock::addJITSubIC(ArithProfile* arithProfile)
 {
-    return m_subICs.add();
+    return m_subICs.add(arithProfile);
 }
 
-JITNegIC* CodeBlock::addJITNegIC()
+JITNegIC* CodeBlock::addJITNegIC(ArithProfile* arithProfile)
 {
-    return m_negICs.add();
+    return m_negICs.add(arithProfile);
 }
 
 StructureStubInfo* CodeBlock::findStubInfo(CodeOrigin codeOrigin)
index a6f5903..acaf09e 100644 (file)
@@ -243,10 +243,10 @@ public:
     
 #if ENABLE(JIT)
     StructureStubInfo* addStubInfo(AccessType);
-    JITAddIC* addJITAddIC();
-    JITMulIC* addJITMulIC();
-    JITNegIC* addJITNegIC();
-    JITSubIC* addJITSubIC();
+    JITAddIC* addJITAddIC(ArithProfile*);
+    JITMulIC* addJITMulIC(ArithProfile*);
+    JITNegIC* addJITNegIC(ArithProfile*);
+    JITSubIC* addJITSubIC(ArithProfile*);
     Bag<StructureStubInfo>::iterator stubInfoBegin() { return m_stubInfos.begin(); }
     Bag<StructureStubInfo>::iterator stubInfoEnd() { return m_stubInfos.end(); }
     
index 8aa82fa..2e628f9 100644 (file)
@@ -3424,7 +3424,8 @@ void SpeculativeJIT::compileValueAdd(Node* node)
     bool needsScratchFPRReg = true;
 #endif
 
-    JITAddIC* addIC = m_jit.codeBlock()->addJITAddIC();
+    ArithProfile* arithProfile = m_jit.graph().baselineCodeBlockFor(node->origin.semantic)->arithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex);
+    JITAddIC* addIC = m_jit.codeBlock()->addJITAddIC(arithProfile);
     auto repatchingFunction = operationValueAddOptimize;
     auto nonRepatchingFunction = operationValueAdd;
     
@@ -3500,8 +3501,7 @@ void SpeculativeJIT::compileMathIC(Node* node, JITBinaryMathIC<Generator>* mathI
 #endif
 
     Box<MathICGenerationState> addICGenerationState = Box<MathICGenerationState>::create();
-    ArithProfile* arithProfile = m_jit.graph().baselineCodeBlockFor(node->origin.semantic)->arithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex);
-    mathIC->m_generator = Generator(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs, leftFPR, rightFPR, scratchGPR, scratchFPR, arithProfile);
+    mathIC->m_generator = Generator(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs, leftFPR, rightFPR, scratchGPR, scratchFPR);
 
     bool shouldEmitProfiling = false;
     bool generatedInline = mathIC->generateInline(m_jit, *addICGenerationState, shouldEmitProfiling);
@@ -4093,7 +4093,8 @@ void SpeculativeJIT::compileArithSub(Node* node)
         bool needsScratchFPRReg = true;
 #endif
 
-        JITSubIC* subIC = m_jit.codeBlock()->addJITSubIC();
+        ArithProfile* arithProfile = m_jit.graph().baselineCodeBlockFor(node->origin.semantic)->arithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex);
+        JITSubIC* subIC = m_jit.codeBlock()->addJITSubIC(arithProfile);
         auto repatchingFunction = operationValueSubOptimize;
         auto nonRepatchingFunction = operationValueSub;
         
@@ -4355,7 +4356,9 @@ void SpeculativeJIT::compileArithMul(Node* node)
         bool needsScratchGPRReg = true;
         bool needsScratchFPRReg = true;
 #endif
-        JITMulIC* mulIC = m_jit.codeBlock()->addJITMulIC();
+
+        ArithProfile* arithProfile = m_jit.graph().baselineCodeBlockFor(node->origin.semantic)->arithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex);
+        JITMulIC* mulIC = m_jit.codeBlock()->addJITMulIC(arithProfile);
         auto repatchingFunction = operationValueMulOptimize;
         auto nonRepatchingFunction = operationValueMul;
         
index a085556..9f885b8 100644 (file)
@@ -1553,7 +1553,8 @@ private:
 
     void compileValueAdd()
     {
-        JITAddIC* addIC = codeBlock()->addJITAddIC();
+        ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
+        JITAddIC* addIC = codeBlock()->addJITAddIC(arithProfile);
         auto repatchingFunction = operationValueAddOptimize;
         auto nonRepatchingFunction = operationValueAdd;
         compileMathIC(addIC, repatchingFunction, nonRepatchingFunction);
@@ -1593,10 +1594,9 @@ private:
 #endif
 
                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
-                ArithProfile* arithProfile = state->graph.baselineCodeBlockFor(node->origin.semantic)->arithProfileForBytecodeOffset(node->origin.semantic.bytecodeIndex);
                 mathIC->m_generator = Generator(leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
                     JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()), params.fpScratch(0),
-                    params.fpScratch(1), params.gpScratch(0), InvalidFPRReg, arithProfile);
+                    params.fpScratch(1), params.gpScratch(0), InvalidFPRReg);
 
                 bool shouldEmitProfiling = false;
                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
@@ -1724,7 +1724,8 @@ private:
                 break;
             }
 
-            JITSubIC* subIC = codeBlock()->addJITSubIC();
+            ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
+            JITSubIC* subIC = codeBlock()->addJITSubIC(arithProfile);
             auto repatchingFunction = operationValueSubOptimize;
             auto nonRepatchingFunction = operationValueSub;
             compileMathIC(subIC, repatchingFunction, nonRepatchingFunction);
@@ -1818,7 +1819,8 @@ private:
         }
 
         case UntypedUse: {
-            JITMulIC* mulIC = codeBlock()->addJITMulIC();
+            ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
+            JITMulIC* mulIC = codeBlock()->addJITMulIC(arithProfile);
             auto repatchingFunction = operationValueMulOptimize;
             auto nonRepatchingFunction = operationValueMul;
             compileMathIC(mulIC, repatchingFunction, nonRepatchingFunction);
index 1b7585c..a14a856 100644 (file)
@@ -762,7 +762,6 @@ namespace JSC {
         MacroAssembler::Call callOperation(J_JITOperation_EJArp, JSValueRegs, JSValueRegs, ArithProfile*);
         MacroAssembler::Call callOperation(J_JITOperation_EJJArp, JSValueRegs, JSValueRegs, JSValueRegs, ArithProfile*);
         MacroAssembler::Call callOperation(J_JITOperation_EJJ, JSValueRegs, JSValueRegs, JSValueRegs);
-        MacroAssembler::Call callOperation(J_JITOperation_EJJArpMic, JSValueRegs, JSValueRegs, JSValueRegs, ArithProfile*, TrustedImmPtr);
         MacroAssembler::Call callOperation(J_JITOperation_EJMic, JSValueRegs, JSValueRegs, TrustedImmPtr);
         MacroAssembler::Call callOperation(J_JITOperation_EJJMic, JSValueRegs, JSValueRegs, JSValueRegs, TrustedImmPtr);
         MacroAssembler::Call callOperation(J_JITOperation_EJJAp, int, GPRReg, GPRReg, ArrayProfile*);
index b16621a..627af27 100644 (file)
 
 namespace JSC {
 
-JITMathICInlineResult JITAddGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state)
+JITMathICInlineResult JITAddGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)
 {
     // We default to speculating int32.
     ObservedType lhs = ObservedType().withInt32();
     ObservedType rhs = ObservedType().withInt32();
-    if (m_arithProfile) {
-        lhs = m_arithProfile->lhsObservedType();
-        rhs = m_arithProfile->rhsObservedType();
+    if (arithProfile) {
+        lhs = arithProfile->lhsObservedType();
+        rhs = arithProfile->rhsObservedType();
     }
 
     if (lhs.isOnlyNonNumber() && rhs.isOnlyNonNumber())
@@ -54,20 +54,26 @@ JITMathICInlineResult JITAddGenerator::generateInline(CCallHelpers& jit, MathICG
         if (!m_rightOperand.isConstInt32())
             state.slowPathJumps.append(jit.branchIfNotInt32(m_right));
 
+        GPRReg scratch = m_scratchGPR;
         if (m_leftOperand.isConstInt32() || m_rightOperand.isConstInt32()) {
             JSValueRegs var = m_leftOperand.isConstInt32() ? m_right : m_left;
             int32_t constValue = m_leftOperand.isConstInt32() ? m_leftOperand.asConstInt32() : m_rightOperand.asConstInt32();
-            state.slowPathJumps.append(jit.branchAdd32(CCallHelpers::Overflow, var.payloadGPR(), CCallHelpers::Imm32(constValue), m_scratchGPR));
-        } else
-            state.slowPathJumps.append(jit.branchAdd32(CCallHelpers::Overflow, m_right.payloadGPR(), m_left.payloadGPR(), m_scratchGPR));
-        jit.boxInt32(m_scratchGPR, m_result);
+            if (var.payloadGPR() != m_result.payloadGPR())
+                scratch = m_result.payloadGPR();
+            state.slowPathJumps.append(jit.branchAdd32(CCallHelpers::Overflow, var.payloadGPR(), CCallHelpers::Imm32(constValue), scratch));
+        } else {
+            if (m_left.payloadGPR() != m_result.payloadGPR() && m_right.payloadGPR() != m_result.payloadGPR())
+                scratch = m_result.payloadGPR();
+            state.slowPathJumps.append(jit.branchAdd32(CCallHelpers::Overflow, m_right.payloadGPR(), m_left.payloadGPR(), scratch));
+        }
+        jit.boxInt32(scratch, m_result);
         return JITMathICInlineResult::GeneratedFastPath;
     }
 
     return JITMathICInlineResult::GenerateFullSnippet;
 }
 
-bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, bool shouldEmitProfiling)
+bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)
 {
     ASSERT(m_scratchGPR != InvalidGPRReg);
     ASSERT(m_scratchGPR != m_left.payloadGPR());
@@ -91,9 +97,12 @@ bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
         // Try to do intVar + intConstant.
         CCallHelpers::Jump notInt32 = jit.branchIfNotInt32(var);
 
-        slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, var.payloadGPR(), CCallHelpers::Imm32(constOpr.asConstInt32()), m_scratchGPR));
+        GPRReg scratch = m_scratchGPR;
+        if (var.payloadGPR() != m_result.payloadGPR())
+            scratch = m_result.payloadGPR();
+        slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, var.payloadGPR(), CCallHelpers::Imm32(constOpr.asConstInt32()), scratch));
 
-        jit.boxInt32(m_scratchGPR, m_result);
+        jit.boxInt32(scratch, m_result);
         endJumpList.append(jit.jump());
 
         if (!jit.supportsFloatingPoint()) {
@@ -122,9 +131,12 @@ bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
         leftNotInt = jit.branchIfNotInt32(m_left);
         rightNotInt = jit.branchIfNotInt32(m_right);
 
-        slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, m_right.payloadGPR(), m_left.payloadGPR(), m_scratchGPR));
+        GPRReg scratch = m_scratchGPR;
+        if (m_left.payloadGPR() != m_result.payloadGPR() && m_right.payloadGPR() != m_result.payloadGPR())
+            scratch = m_result.payloadGPR();
+        slowPathJumpList.append(jit.branchAdd32(CCallHelpers::Overflow, m_right.payloadGPR(), m_left.payloadGPR(), scratch));
 
-        jit.boxInt32(m_scratchGPR, m_result);
+        jit.boxInt32(scratch, m_result);
         endJumpList.append(jit.jump());
 
 
@@ -162,9 +174,9 @@ bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
 
     // Do doubleVar + doubleVar.
     jit.addDouble(m_rightFPR, m_leftFPR);
-    if (m_arithProfile && shouldEmitProfiling)
-        m_arithProfile->emitSetDouble(jit);
-        
+    if (arithProfile && shouldEmitProfiling)
+        arithProfile->emitSetDouble(jit);
+
     jit.boxDouble(m_leftFPR, m_result);
 
     return true;
index 473643f..6f92990 100644 (file)
@@ -43,8 +43,7 @@ public:
 
     JITAddGenerator(SnippetOperand leftOperand, SnippetOperand rightOperand,
         JSValueRegs result, JSValueRegs left, JSValueRegs right,
-        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR,
-        ArithProfile* arithProfile = nullptr)
+        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR)
         : m_leftOperand(leftOperand)
         , m_rightOperand(rightOperand)
         , m_result(result)
@@ -54,18 +53,15 @@ public:
         , m_rightFPR(rightFPR)
         , m_scratchGPR(scratchGPR)
         , m_scratchFPR(scratchFPR)
-        , m_arithProfile(arithProfile)
     {
         ASSERT(!m_leftOperand.isConstInt32() || !m_rightOperand.isConstInt32());
     }
 
-    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&);
-    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, bool shouldEmitProfiling);
+    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);
+    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);
 
     static bool isLeftOperandValidConstant(SnippetOperand leftOperand) { return leftOperand.isPositiveConstInt32(); }
     static bool isRightOperandValidConstant(SnippetOperand rightOperand) { return rightOperand.isPositiveConstInt32(); }
-    
-    ArithProfile* arithProfile() const { return m_arithProfile; }
 
 private:
     SnippetOperand m_leftOperand;
@@ -77,7 +73,6 @@ private:
     FPRReg m_rightFPR;
     GPRReg m_scratchGPR;
     FPRReg m_scratchFPR;
-    ArithProfile* m_arithProfile;
 };
 
 } // namespace JSC
index 780bca9..58fdb10 100644 (file)
@@ -469,7 +469,8 @@ void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&)
 
 void JIT::emit_op_negate(Instruction* currentInstruction)
 {
-    JITNegIC* negateIC = m_codeBlock->addJITNegIC();
+    ArithProfile* arithProfile = m_codeBlock->arithProfileForPC(currentInstruction);
+    JITNegIC* negateIC = m_codeBlock->addJITNegIC(arithProfile);
     m_instructionToMathIC.add(currentInstruction, negateIC);
     emitMathICFast(negateIC, currentInstruction, operationArithNegateProfiled, operationArithNegate);
 }
@@ -664,7 +665,8 @@ ALWAYS_INLINE static OperandTypes getOperandTypes(Instruction* instruction)
 
 void JIT::emit_op_add(Instruction* currentInstruction)
 {
-    JITAddIC* addIC = m_codeBlock->addJITAddIC();
+    ArithProfile* arithProfile = m_codeBlock->arithProfileForPC(currentInstruction);
+    JITAddIC* addIC = m_codeBlock->addJITAddIC(arithProfile);
     m_instructionToMathIC.add(currentInstruction, addIC);
     emitMathICFast(addIC, currentInstruction, operationValueAddProfiled, operationValueAdd);
 }
@@ -699,8 +701,7 @@ void JIT::emitMathICFast(JITUnaryMathIC<Generator>* mathIC, Instruction* current
     auto inlineStart = label();
 #endif
 
-    ArithProfile& arithProfile = *bitwise_cast<ArithProfile*>(&currentInstruction[3].u.operand);
-    mathIC->m_generator = Generator(resultRegs, srcRegs, scratchGPR, arithProfile);
+    mathIC->m_generator = Generator(resultRegs, srcRegs, scratchGPR);
 
     emitGetVirtualRegister(operand, srcRegs);
 
@@ -708,8 +709,9 @@ void JIT::emitMathICFast(JITUnaryMathIC<Generator>* mathIC, Instruction* current
 
     bool generatedInlineCode = mathIC->generateInline(*this, mathICGenerationState);
     if (!generatedInlineCode) {
-        if (shouldEmitProfiling())
-            callOperation(profiledFunction, resultRegs, srcRegs, &arithProfile);
+        ArithProfile* arithProfile = mathIC->arithProfile();
+        if (arithProfile && shouldEmitProfiling())
+            callOperation(profiledFunction, resultRegs, srcRegs, arithProfile);
         else
             callOperation(nonProfiledFunction, resultRegs, srcRegs);
     } else
@@ -735,9 +737,9 @@ void JIT::emitMathICFast(JITBinaryMathIC<Generator>* mathIC, Instruction* curren
 
 #if USE(JSVALUE64)
     OperandTypes types = getOperandTypes(copiedInstruction(currentInstruction));
-    JSValueRegs leftRegs = JSValueRegs(regT0);
-    JSValueRegs rightRegs = JSValueRegs(regT1);
-    JSValueRegs resultRegs = JSValueRegs(regT2);
+    JSValueRegs leftRegs = JSValueRegs(regT1);
+    JSValueRegs rightRegs = JSValueRegs(regT2);
+    JSValueRegs resultRegs = JSValueRegs(regT0);
     GPRReg scratchGPR = regT3;
     FPRReg scratchFPR = fpRegT2;
 #else
@@ -749,10 +751,6 @@ void JIT::emitMathICFast(JITBinaryMathIC<Generator>* mathIC, Instruction* curren
     FPRReg scratchFPR = fpRegT2;
 #endif
 
-    ArithProfile* arithProfile = nullptr;
-    if (shouldEmitProfiling())
-        arithProfile = m_codeBlock->arithProfileForPC(currentInstruction);
-
     SnippetOperand leftOperand(types.first());
     SnippetOperand rightOperand(types.second());
 
@@ -763,7 +761,7 @@ void JIT::emitMathICFast(JITBinaryMathIC<Generator>* mathIC, Instruction* curren
 
     RELEASE_ASSERT(!leftOperand.isConst() || !rightOperand.isConst());
 
-    mathIC->m_generator = Generator(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs, fpRegT0, fpRegT1, scratchGPR, scratchFPR, arithProfile);
+    mathIC->m_generator = Generator(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs, fpRegT0, fpRegT1, scratchGPR, scratchFPR);
     
     ASSERT(!(Generator::isLeftOperandValidConstant(leftOperand) && Generator::isRightOperandValidConstant(rightOperand)));
     
@@ -784,7 +782,8 @@ void JIT::emitMathICFast(JITBinaryMathIC<Generator>* mathIC, Instruction* curren
             emitGetVirtualRegister(op1, leftRegs);
         else if (rightOperand.isConst())
             emitGetVirtualRegister(op2, rightRegs);
-        if (arithProfile)
+        ArithProfile* arithProfile = mathIC->arithProfile();
+        if (arithProfile && shouldEmitProfiling())
             callOperation(profiledFunction, resultRegs, leftRegs, rightRegs, arithProfile);
         else
             callOperation(nonProfiledFunction, resultRegs, leftRegs, rightRegs);
@@ -822,8 +821,8 @@ void JIT::emitMathICSlow(JITUnaryMathIC<Generator>* mathIC, Instruction* current
     auto slowPathStart = label();
 #endif
 
-    if (shouldEmitProfiling()) {
-        ArithProfile* arithProfile = bitwise_cast<ArithProfile*>(&currentInstruction[3].u.operand);
+    ArithProfile* arithProfile = mathIC->arithProfile();
+    if (arithProfile && shouldEmitProfiling()) {
         if (mathICGenerationState.shouldSlowPathRepatch)
             mathICGenerationState.slowPathCall = callOperation(reinterpret_cast<J_JITOperation_EJMic>(profiledRepatchFunction), resultRegs, srcRegs, TrustedImmPtr(mathIC));
         else
@@ -859,9 +858,9 @@ void JIT::emitMathICSlow(JITBinaryMathIC<Generator>* mathIC, Instruction* curren
 
 #if USE(JSVALUE64)
     OperandTypes types = getOperandTypes(copiedInstruction(currentInstruction));
-    JSValueRegs leftRegs = JSValueRegs(regT0);
-    JSValueRegs rightRegs = JSValueRegs(regT1);
-    JSValueRegs resultRegs = JSValueRegs(regT2);
+    JSValueRegs leftRegs = JSValueRegs(regT1);
+    JSValueRegs rightRegs = JSValueRegs(regT2);
+    JSValueRegs resultRegs = JSValueRegs(regT0);
 #else
     OperandTypes types = getOperandTypes(currentInstruction);
     JSValueRegs leftRegs = JSValueRegs(regT1, regT0);
@@ -888,12 +887,12 @@ void JIT::emitMathICSlow(JITBinaryMathIC<Generator>* mathIC, Instruction* curren
     auto slowPathStart = label();
 #endif
 
-    if (shouldEmitProfiling()) {
-        ArithProfile& arithProfile = *m_codeBlock->arithProfileForPC(currentInstruction);
+    ArithProfile* arithProfile = mathIC->arithProfile();
+    if (arithProfile && shouldEmitProfiling()) {
         if (mathICGenerationState.shouldSlowPathRepatch)
-            mathICGenerationState.slowPathCall = callOperation(bitwise_cast<J_JITOperation_EJJArpMic>(profiledRepatchFunction), resultRegs, leftRegs, rightRegs, &arithProfile, TrustedImmPtr(mathIC));
+            mathICGenerationState.slowPathCall = callOperation(bitwise_cast<J_JITOperation_EJJMic>(profiledRepatchFunction), resultRegs, leftRegs, rightRegs, TrustedImmPtr(mathIC));
         else
-            mathICGenerationState.slowPathCall = callOperation(profiledFunction, resultRegs, leftRegs, rightRegs, &arithProfile);
+            mathICGenerationState.slowPathCall = callOperation(profiledFunction, resultRegs, leftRegs, rightRegs, arithProfile);
     } else
         mathICGenerationState.slowPathCall = callOperation(bitwise_cast<J_JITOperation_EJJMic>(repatchFunction), resultRegs, leftRegs, rightRegs, TrustedImmPtr(mathIC));
 
@@ -989,7 +988,8 @@ void JIT::emitSlow_op_div(Instruction* currentInstruction, Vector<SlowCaseEntry>
 
 void JIT::emit_op_mul(Instruction* currentInstruction)
 {
-    JITMulIC* mulIC = m_codeBlock->addJITMulIC();
+    ArithProfile* arithProfile = m_codeBlock->arithProfileForPC(currentInstruction);
+    JITMulIC* mulIC = m_codeBlock->addJITMulIC(arithProfile);
     m_instructionToMathIC.add(currentInstruction, mulIC);
     emitMathICFast(mulIC, currentInstruction, operationValueMulProfiled, operationValueMul);
 }
@@ -1004,7 +1004,8 @@ void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>
 
 void JIT::emit_op_sub(Instruction* currentInstruction)
 {
-    JITSubIC* subIC = m_codeBlock->addJITSubIC();
+    ArithProfile* arithProfile = m_codeBlock->arithProfileForPC(currentInstruction);
+    JITSubIC* subIC = m_codeBlock->addJITSubIC(arithProfile);
     m_instructionToMathIC.add(currentInstruction, subIC);
     emitMathICFast(subIC, currentInstruction, operationValueSubProfiled, operationValueSub);
 }
index 4510a9b..e39eb54 100644 (file)
@@ -448,14 +448,6 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJJArp oper
     return call;
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJJArpMic operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2, ArithProfile* arithProfile, TrustedImmPtr mathIC)
-{
-    setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(arithProfile), mathIC);
-    Call call = appendCallWithExceptionCheck(operation);
-    setupResults(result);
-    return call;
-}
-
 ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJMic operation, JSValueRegs result, JSValueRegs arg, TrustedImmPtr mathIC)
 {
     setupArgumentsWithExecState(arg, mathIC);
index 1ca4b1f..3806f3a 100644 (file)
@@ -53,9 +53,14 @@ struct MathICGenerationState {
 
 #define ENABLE_MATH_IC_STATS 0
 
-template <typename GeneratorType, bool(*isProfileEmpty)(ArithProfile*)>
+template <typename GeneratorType, bool(*isProfileEmpty)(ArithProfile&)>
 class JITMathIC {
 public:
+    JITMathIC(ArithProfile* arithProfile)
+        : m_arithProfile(arithProfile)
+    {
+    }
+
     CodeLocationLabel doneLocation() { return m_inlineStart.labelAtOffset(m_inlineSize); }
     CodeLocationLabel slowPathStartLocation() { return m_inlineStart.labelAtOffset(m_deltaFromStartToSlowPathStart); }
     CodeLocationCall slowPathCallLocation() { return m_inlineStart.callAtOffset(m_deltaFromStartToSlowPathCallLocation); }
@@ -72,8 +77,8 @@ public:
         state.fastPathStart = jit.label();
         size_t startSize = jit.m_assembler.buffer().codeSize();
 
-        if (ArithProfile* arithProfile = m_generator.arithProfile()) {
-            if (!isProfileEmpty(arithProfile)) {
+        if (m_arithProfile) {
+            if (isProfileEmpty(*m_arithProfile)) {
                 // It looks like the MathIC has yet to execute. We don't want to emit code in this
                 // case for a couple reasons. First, the operation may never execute, so if we don't emit
                 // code, it's a win. Second, if the operation does execute, we can emit better code
@@ -89,7 +94,7 @@ public:
             }
         }
 
-        JITMathICInlineResult result = m_generator.generateInline(jit, state);
+        JITMathICInlineResult result = m_generator.generateInline(jit, state, m_arithProfile);
 
         switch (result) {
         case JITMathICInlineResult::GeneratedFastPath: {
@@ -104,7 +109,7 @@ public:
         }
         case JITMathICInlineResult::GenerateFullSnippet: {
             MacroAssembler::JumpList endJumpList;
-            bool result = m_generator.generateFastPath(jit, endJumpList, state.slowPathJumps, shouldEmitProfiling);
+            bool result = m_generator.generateFastPath(jit, endJumpList, state.slowPathJumps, m_arithProfile, shouldEmitProfiling);
             if (result) {
                 state.fastPathEnd = jit.label();
                 state.shouldSlowPathRepatch = false;
@@ -190,7 +195,7 @@ public:
             MacroAssembler::JumpList endJumpList; 
             MacroAssembler::JumpList slowPathJumpList; 
 
-            bool emittedFastPath = m_generator.generateFastPath(jit, endJumpList, slowPathJumpList, shouldEmitProfiling);
+            bool emittedFastPath = m_generator.generateFastPath(jit, endJumpList, slowPathJumpList, m_arithProfile, shouldEmitProfiling);
             if (!emittedFastPath)
                 return;
             endJumpList.append(jit.jump());
@@ -224,6 +229,8 @@ public:
             start, linkBuffer.locationOf(state.slowPathStart));
     }
 
+    ArithProfile* arithProfile() const { return m_arithProfile; }
+
 #if ENABLE(MATH_IC_STATS)
     size_t m_generatedCodeSize { 0 };
     size_t codeSize() const
@@ -235,6 +242,7 @@ public:
     }
 #endif
 
+    ArithProfile* m_arithProfile;
     MacroAssemblerCodeRef m_code;
     CodeLocationLabel m_inlineStart;
     int32_t m_inlineSize;
@@ -244,24 +252,36 @@ public:
     GeneratorType m_generator;
 };
 
-inline bool canGenerateWithBinaryProfile(ArithProfile* arithProfile)
+inline bool isBinaryProfileEmpty(ArithProfile& arithProfile)
 {
-    return !arithProfile->lhsObservedType().isEmpty() && !arithProfile->rhsObservedType().isEmpty();
+    return arithProfile.lhsObservedType().isEmpty() || arithProfile.rhsObservedType().isEmpty();
 }
 template <typename GeneratorType>
-class JITBinaryMathIC : public JITMathIC<GeneratorType, canGenerateWithBinaryProfile> { };
+class JITBinaryMathIC : public JITMathIC<GeneratorType, isBinaryProfileEmpty> {
+public:
+    JITBinaryMathIC(ArithProfile* arithProfile)
+        : JITMathIC<GeneratorType, isBinaryProfileEmpty>(arithProfile)
+    {
+    }
+};
 
 typedef JITBinaryMathIC<JITAddGenerator> JITAddIC;
 typedef JITBinaryMathIC<JITMulGenerator> JITMulIC;
 typedef JITBinaryMathIC<JITSubGenerator> JITSubIC;
 
 
-inline bool canGenerateWithUnaryProfile(ArithProfile* arithProfile)
+inline bool isUnaryProfileEmpty(ArithProfile& arithProfile)
 {
-    return !arithProfile->lhsObservedType().isEmpty();
+    return arithProfile.lhsObservedType().isEmpty();
 }
 template <typename GeneratorType>
-class JITUnaryMathIC : public JITMathIC<GeneratorType, canGenerateWithUnaryProfile> { };
+class JITUnaryMathIC : public JITMathIC<GeneratorType, isUnaryProfileEmpty> {
+public:
+    JITUnaryMathIC(ArithProfile* arithProfile)
+        : JITMathIC<GeneratorType, isUnaryProfileEmpty>(arithProfile)
+    {
+    }
+};
 
 typedef JITUnaryMathIC<JITNegGenerator> JITNegIC;
 
index 63abf31..93c69e2 100644 (file)
 
 namespace JSC {
 
-JITMathICInlineResult JITMulGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state)
+JITMathICInlineResult JITMulGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)
 {
     // We default to speculating int32.
     ObservedType lhs = ObservedType().withInt32();
     ObservedType rhs = ObservedType().withInt32();
-
-    if (m_arithProfile) {
-        lhs = m_arithProfile->lhsObservedType();
-        rhs = m_arithProfile->rhsObservedType();
+    if (arithProfile) {
+        lhs = arithProfile->lhsObservedType();
+        rhs = arithProfile->rhsObservedType();
     }
 
     if (lhs.isOnlyNonNumber() && rhs.isOnlyNonNumber())
@@ -88,7 +87,7 @@ JITMathICInlineResult JITMulGenerator::generateInline(CCallHelpers& jit, MathICG
     return JITMathICInlineResult::GenerateFullSnippet;
 }
 
-bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, bool shouldEmitProfiling)
+bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)
 {
     ASSERT(m_scratchGPR != InvalidGPRReg);
     ASSERT(m_scratchGPR != m_left.payloadGPR());
@@ -191,7 +190,7 @@ bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
     // Do doubleVar * doubleVar.
     jit.mulDouble(m_rightFPR, m_leftFPR);
 
-    if (!m_arithProfile || !shouldEmitProfiling)
+    if (!arithProfile || !shouldEmitProfiling)
         jit.boxDouble(m_leftFPR, m_result);
     else {
         // The Int52 overflow check below intentionally omits 1ll << 51 as a valid negative Int52 value.
@@ -204,18 +203,18 @@ bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
 
         CCallHelpers::Jump notNegativeZero = jit.branch64(CCallHelpers::NotEqual, m_result.payloadGPR(), CCallHelpers::TrustedImm64(negativeZeroBits));
 
-        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(m_arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
         CCallHelpers::Jump done = jit.jump();
 
         notNegativeZero.link(&jit);
-        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(m_arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
 
         jit.move(m_result.payloadGPR(), m_scratchGPR);
         jit.urshiftPtr(CCallHelpers::Imm32(52), m_scratchGPR);
         jit.and32(CCallHelpers::Imm32(0x7ff), m_scratchGPR);
         CCallHelpers::Jump noInt52Overflow = jit.branch32(CCallHelpers::LessThanOrEqual, m_scratchGPR, CCallHelpers::TrustedImm32(0x431));
 
-        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(m_arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
         noInt52Overflow.link(&jit);
 
         done.link(&jit);
@@ -226,18 +225,18 @@ bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
         notNegativeZero.append(jit.branch32(CCallHelpers::NotEqual, m_result.payloadGPR(), CCallHelpers::TrustedImm32(0)));
         notNegativeZero.append(jit.branch32(CCallHelpers::NotEqual, m_result.tagGPR(), CCallHelpers::TrustedImm32(negativeZeroBits >> 32)));
 
-        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(m_arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
         CCallHelpers::Jump done = jit.jump();
 
         notNegativeZero.link(&jit);
-        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(m_arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
 
         jit.move(m_result.tagGPR(), m_scratchGPR);
         jit.urshiftPtr(CCallHelpers::Imm32(52 - 32), m_scratchGPR);
         jit.and32(CCallHelpers::Imm32(0x7ff), m_scratchGPR);
         CCallHelpers::Jump noInt52Overflow = jit.branch32(CCallHelpers::LessThanOrEqual, m_scratchGPR, CCallHelpers::TrustedImm32(0x431));
         
-        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(m_arithProfile->addressOfBits()));
+        jit.or32(CCallHelpers::TrustedImm32(ArithProfile::Int52Overflow), CCallHelpers::AbsoluteAddress(arithProfile->addressOfBits()));
 
         endJumpList.append(noInt52Overflow);
         if (m_scratchGPR == m_result.tagGPR() || m_scratchGPR == m_result.payloadGPR())
index 3759908..8bb662e 100644 (file)
@@ -43,8 +43,7 @@ public:
 
     JITMulGenerator(SnippetOperand leftOperand, SnippetOperand rightOperand,
         JSValueRegs result, JSValueRegs left, JSValueRegs right,
-        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR,
-        ArithProfile* arithProfile = nullptr)
+        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR)
         : m_leftOperand(leftOperand)
         , m_rightOperand(rightOperand)
         , m_result(result)
@@ -54,19 +53,16 @@ public:
         , m_rightFPR(rightFPR)
         , m_scratchGPR(scratchGPR)
         , m_scratchFPR(scratchFPR)
-        , m_arithProfile(arithProfile)
     {
         ASSERT(!m_leftOperand.isPositiveConstInt32() || !m_rightOperand.isPositiveConstInt32());
     }
 
-    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&);
-    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowJumpList, bool shouldEmitProfiling);
+    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);
+    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowJumpList, const ArithProfile*, bool shouldEmitProfiling);
 
     static bool isLeftOperandValidConstant(SnippetOperand leftOperand) { return leftOperand.isPositiveConstInt32(); }
     static bool isRightOperandValidConstant(SnippetOperand rightOperand) { return rightOperand.isPositiveConstInt32(); }
     
-    ArithProfile* arithProfile() const { return m_arithProfile; }
-
 private:
     SnippetOperand m_leftOperand;
     SnippetOperand m_rightOperand;
@@ -77,7 +73,6 @@ private:
     FPRReg m_rightFPR;
     GPRReg m_scratchGPR;
     FPRReg m_scratchFPR;
-    ArithProfile* m_arithProfile;
 };
 
 } // namespace JSC
index 4de1f6c..df91c48 100644 (file)
@@ -32,7 +32,7 @@
 
 namespace JSC {
 
-JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state)
+JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)
 {
     ASSERT(m_scratchGPR != InvalidGPRReg);
     ASSERT(m_scratchGPR != m_src.payloadGPR());
@@ -42,7 +42,10 @@ JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers& jit, MathICG
     ASSERT(m_scratchGPR != m_result.tagGPR());
 #endif
 
-    ObservedType observedTypes = m_arithProfile->lhsObservedType();
+    // We default to speculating int32.
+    ObservedType observedTypes = ObservedType().withInt32();
+    if (arithProfile)
+        observedTypes = arithProfile->lhsObservedType();
     ASSERT_WITH_MESSAGE(!observedTypes.isEmpty(), "We should not attempt to generate anything if we do not have a profile.");
 
     if (observedTypes.isOnlyNonNumber())
@@ -79,7 +82,7 @@ JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers& jit, MathICG
     return JITMathICInlineResult::GenerateFullSnippet;
 }
 
-bool JITNegGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, bool)
+bool JITNegGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool)
 {
     ASSERT(m_scratchGPR != m_src.payloadGPR());
     ASSERT(m_scratchGPR != m_result.payloadGPR());
index 30de2c5..3e925e9 100644 (file)
@@ -38,20 +38,16 @@ class JITNegGenerator {
 public:
     JITNegGenerator() = default;
 
-    JITNegGenerator(JSValueRegs result, JSValueRegs src, GPRReg scratchGPR, ArithProfile& arithProfile)
-        : m_arithProfile(&arithProfile)
-        , m_result(result)
+    JITNegGenerator(JSValueRegs result, JSValueRegs src, GPRReg scratchGPR)
+        : m_result(result)
         , m_src(src)
         , m_scratchGPR(scratchGPR)
     { }
 
-    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&);
-    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, bool shouldEmitProfiling);
-
-    ArithProfile* arithProfile() const { return m_arithProfile; }
+    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);
+    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);
 
 private:
-    ArithProfile* m_arithProfile { nullptr };
     JSValueRegs m_result;
     JSValueRegs m_src;
     GPRReg m_scratchGPR;
index 1ee9bef..189730a 100644 (file)
@@ -2270,7 +2270,7 @@ ALWAYS_INLINE static EncodedJSValue unprofiledAdd(ExecState* exec, EncodedJSValu
     return JSValue::encode(jsAdd(exec, op1, op2));
 }
 
-ALWAYS_INLINE static EncodedJSValue profiledAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
+ALWAYS_INLINE static EncodedJSValue profiledAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
@@ -2278,11 +2278,9 @@ ALWAYS_INLINE static EncodedJSValue profiledAdd(ExecState* exec, EncodedJSValue
     JSValue op1 = JSValue::decode(encodedOp1);
     JSValue op2 = JSValue::decode(encodedOp2);
 
-    ASSERT(arithProfile);
-    arithProfile->observeLHSAndRHS(op1, op2);
-
+    arithProfile.observeLHSAndRHS(op1, op2);
     JSValue result = jsAdd(exec, op1, op2);
-    arithProfile->observeResult(result);
+    arithProfile.observeResult(result);
 
     return JSValue::encode(result);
 }
@@ -2294,10 +2292,11 @@ EncodedJSValue JIT_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue e
 
 EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
 {
-    return profiledAdd(exec, encodedOp1, encodedOp2, arithProfile);
+    ASSERT(arithProfile);
+    return profiledAdd(exec, encodedOp1, encodedOp2, *arithProfile);
 }
 
-EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, JITAddIC* addIC)
+EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC* addIC)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
@@ -2305,6 +2304,7 @@ EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState* exec,
     JSValue op1 = JSValue::decode(encodedOp1);
     JSValue op2 = JSValue::decode(encodedOp2);
 
+    ArithProfile* arithProfile = addIC->arithProfile();
     ASSERT(arithProfile);
     arithProfile->observeLHSAndRHS(op1, op2);
     auto nonOptimizeVariant = operationValueAddProfiledNoOptimize;
@@ -2320,9 +2320,14 @@ EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState* exec,
     return JSValue::encode(result);
 }
 
-EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, JITAddIC*)
+EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC* addIC)
 {
-    return profiledAdd(exec, encodedOp1, encodedOp2, arithProfile);
+    VM* vm = &exec->vm();
+    NativeCallFrameTracer tracer(vm, exec);
+
+    ArithProfile* arithProfile = addIC->arithProfile();
+    ASSERT(arithProfile);
+    return profiledAdd(exec, encodedOp1, encodedOp2, *arithProfile);
 }
 
 EncodedJSValue JIT_OPERATION operationValueAddOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC* addIC)
@@ -2334,7 +2339,7 @@ EncodedJSValue JIT_OPERATION operationValueAddOptimize(ExecState* exec, EncodedJ
     JSValue op2 = JSValue::decode(encodedOp2);
 
     auto nonOptimizeVariant = operationValueAddNoOptimize;
-    if (ArithProfile* arithProfile = addIC->m_generator.arithProfile())
+    if (ArithProfile* arithProfile = addIC->arithProfile())
         arithProfile->observeLHSAndRHS(op1, op2);
     addIC->generateOutOfLine(*vm, exec->codeBlock(), nonOptimizeVariant);
 
@@ -2370,14 +2375,14 @@ ALWAYS_INLINE static EncodedJSValue unprofiledMul(VM& vm, ExecState* exec, Encod
     return JSValue::encode(jsNumber(a * b));
 }
 
-ALWAYS_INLINE static EncodedJSValue profiledMul(VM& vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, bool shouldObserveLHSAndRHSTypes = true)
+ALWAYS_INLINE static EncodedJSValue profiledMul(VM& vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSValue op1 = JSValue::decode(encodedOp1);
     JSValue op2 = JSValue::decode(encodedOp2);
 
     if (shouldObserveLHSAndRHSTypes)
-        arithProfile->observeLHSAndRHS(op1, op2);
+        arithProfile.observeLHSAndRHS(op1, op2);
 
     double a = op1.toNumber(exec);
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
@@ -2385,7 +2390,7 @@ ALWAYS_INLINE static EncodedJSValue profiledMul(VM& vm, ExecState* exec, Encoded
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
     
     JSValue result = jsNumber(a * b);
-    arithProfile->observeResult(result);
+    arithProfile.observeResult(result);
     return JSValue::encode(result);
 }
 
@@ -2411,7 +2416,7 @@ EncodedJSValue JIT_OPERATION operationValueMulOptimize(ExecState* exec, EncodedJ
     NativeCallFrameTracer tracer(vm, exec);
 
     auto nonOptimizeVariant = operationValueMulNoOptimize;
-    if (ArithProfile* arithProfile = mulIC->m_generator.arithProfile())
+    if (ArithProfile* arithProfile = mulIC->arithProfile())
         arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
     mulIC->generateOutOfLine(*vm, exec->codeBlock(), nonOptimizeVariant);
 
@@ -2427,14 +2432,17 @@ EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState* exec, EncodedJ
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
-    return profiledMul(*vm, exec, encodedOp1, encodedOp2, arithProfile);
+    ASSERT(arithProfile);
+    return profiledMul(*vm, exec, encodedOp1, encodedOp2, *arithProfile);
 }
 
-EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, JITMulIC* mulIC)
+EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC* mulIC)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
+    ArithProfile* arithProfile = mulIC->arithProfile();
+    ASSERT(arithProfile);
     arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
     auto nonOptimizeVariant = operationValueMulProfiledNoOptimize;
     mulIC->generateOutOfLine(*vm, exec->codeBlock(), nonOptimizeVariant);
@@ -2443,15 +2451,17 @@ EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState* exec,
     exec->codeBlock()->dumpMathICStats();
 #endif
 
-    return profiledMul(*vm, exec, encodedOp1, encodedOp2, arithProfile, false);
+    return profiledMul(*vm, exec, encodedOp1, encodedOp2, *arithProfile, false);
 }
 
-EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, JITMulIC*)
+EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC* mulIC)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
-    return profiledMul(*vm, exec, encodedOp1, encodedOp2, arithProfile);
+    ArithProfile* arithProfile = mulIC->arithProfile();
+    ASSERT(arithProfile);
+    return profiledMul(*vm, exec, encodedOp1, encodedOp2, *arithProfile);
 }
 
 ALWAYS_INLINE static EncodedJSValue unprofiledNegate(ExecState* exec, EncodedJSValue encodedOperand)
@@ -2467,15 +2477,14 @@ ALWAYS_INLINE static EncodedJSValue unprofiledNegate(ExecState* exec, EncodedJSV
     return JSValue::encode(jsNumber(-number));
 }
 
-ALWAYS_INLINE static EncodedJSValue profiledNegate(ExecState* exec, EncodedJSValue encodedOperand, ArithProfile* arithProfile)
+ALWAYS_INLINE static EncodedJSValue profiledNegate(ExecState* exec, EncodedJSValue encodedOperand, ArithProfile& arithProfile)
 {
-    ASSERT(arithProfile);
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
     NativeCallFrameTracer tracer(&vm, exec);
 
     JSValue operand = JSValue::decode(encodedOperand);
-    arithProfile->observeLHS(operand);
+    arithProfile.observeLHS(operand);
     double number = operand.toNumber(exec);
     if (UNLIKELY(scope.exception()))
         return JSValue::encode(JSValue());
@@ -2489,7 +2498,8 @@ EncodedJSValue JIT_OPERATION operationArithNegate(ExecState* exec, EncodedJSValu
 
 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState* exec, EncodedJSValue operand, ArithProfile* arithProfile)
 {
-    return profiledNegate(exec, operand, arithProfile);
+    ASSERT(arithProfile);
+    return profiledNegate(exec, operand, *arithProfile);
 }
 
 EncodedJSValue JIT_OPERATION operationArithNegateProfiledOptimize(ExecState* exec, EncodedJSValue encodedOperand, JITNegIC* negIC)
@@ -2500,7 +2510,7 @@ EncodedJSValue JIT_OPERATION operationArithNegateProfiledOptimize(ExecState* exe
     
     JSValue operand = JSValue::decode(encodedOperand);
 
-    ArithProfile* arithProfile = negIC->m_generator.arithProfile();
+    ArithProfile* arithProfile = negIC->arithProfile();
     ASSERT(arithProfile);
     arithProfile->observeLHS(operand);
     negIC->generateOutOfLine(vm, exec->codeBlock(), operationArithNegateProfiled);
@@ -2523,9 +2533,8 @@ EncodedJSValue JIT_OPERATION operationArithNegateOptimize(ExecState* exec, Encod
 
     JSValue operand = JSValue::decode(encodedOperand);
 
-    ArithProfile* arithProfile = negIC->m_generator.arithProfile();
-    ASSERT(arithProfile);
-    arithProfile->observeLHS(operand);
+    if (ArithProfile* arithProfile = negIC->arithProfile())
+        arithProfile->observeLHS(operand);
     negIC->generateOutOfLine(vm, exec->codeBlock(), operationArithNegate);
 
 #if ENABLE(MATH_IC_STATS)
@@ -2550,14 +2559,14 @@ ALWAYS_INLINE static EncodedJSValue unprofiledSub(VM& vm, ExecState* exec, Encod
     return JSValue::encode(jsNumber(a - b));
 }
 
-ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, bool shouldObserveLHSAndRHSTypes = true)
+ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile& arithProfile, bool shouldObserveLHSAndRHSTypes = true)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSValue op1 = JSValue::decode(encodedOp1);
     JSValue op2 = JSValue::decode(encodedOp2);
 
     if (shouldObserveLHSAndRHSTypes)
-        arithProfile->observeLHSAndRHS(op1, op2);
+        arithProfile.observeLHSAndRHS(op1, op2);
 
     double a = op1.toNumber(exec);
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
@@ -2565,7 +2574,7 @@ ALWAYS_INLINE static EncodedJSValue profiledSub(VM& vm, ExecState* exec, Encoded
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
     
     JSValue result = jsNumber(a - b);
-    arithProfile->observeResult(result);
+    arithProfile.observeResult(result);
     return JSValue::encode(result);
 }
 
@@ -2578,10 +2587,12 @@ EncodedJSValue JIT_OPERATION operationValueSub(ExecState* exec, EncodedJSValue e
 
 EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile)
 {
+    ASSERT(arithProfile);
+
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
-    return profiledSub(*vm, exec, encodedOp1, encodedOp2, arithProfile);
+    return profiledSub(*vm, exec, encodedOp1, encodedOp2, *arithProfile);
 }
 
 EncodedJSValue JIT_OPERATION operationValueSubOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC* subIC)
@@ -2590,7 +2601,7 @@ EncodedJSValue JIT_OPERATION operationValueSubOptimize(ExecState* exec, EncodedJ
     NativeCallFrameTracer tracer(vm, exec);
 
     auto nonOptimizeVariant = operationValueSubNoOptimize;
-    if (ArithProfile* arithProfile = subIC->m_generator.arithProfile())
+    if (ArithProfile* arithProfile = subIC->arithProfile())
         arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
     subIC->generateOutOfLine(*vm, exec->codeBlock(), nonOptimizeVariant);
 
@@ -2609,11 +2620,13 @@ EncodedJSValue JIT_OPERATION operationValueSubNoOptimize(ExecState* exec, Encode
     return unprofiledSub(*vm, exec, encodedOp1, encodedOp2);
 }
 
-EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, JITSubIC* subIC)
+EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC* subIC)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
+    ArithProfile* arithProfile = subIC->arithProfile();
+    ASSERT(arithProfile);
     arithProfile->observeLHSAndRHS(JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
     auto nonOptimizeVariant = operationValueSubProfiledNoOptimize;
     subIC->generateOutOfLine(*vm, exec->codeBlock(), nonOptimizeVariant);
@@ -2622,15 +2635,17 @@ EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState* exec,
     exec->codeBlock()->dumpMathICStats();
 #endif
 
-    return profiledSub(*vm, exec, encodedOp1, encodedOp2, arithProfile, false);
+    return profiledSub(*vm, exec, encodedOp1, encodedOp2, *arithProfile, false);
 }
 
-EncodedJSValue JIT_OPERATION operationValueSubProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile* arithProfile, JITSubIC*)
+EncodedJSValue JIT_OPERATION operationValueSubProfiledNoOptimize(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC* subIC)
 {
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
-    return profiledSub(*vm, exec, encodedOp1, encodedOp2, arithProfile);
+    ArithProfile* arithProfile = subIC->arithProfile();
+    ASSERT(arithProfile);
+    return profiledSub(*vm, exec, encodedOp1, encodedOp2, *arithProfile);
 }
 
 void JIT_OPERATION operationProcessTypeProfilerLog(ExecState* exec)
index 6726407..935c4fa 100644 (file)
@@ -148,7 +148,6 @@ typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJAp)(ExecState*, Encoded
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJBy)(ExecState*, EncodedJSValue, EncodedJSValue, ByValInfo*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJArp)(ExecState*, EncodedJSValue, EncodedJSValue, ArithProfile*);
-typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJArpMic)(ExecState*, EncodedJSValue, EncodedJSValue, ArithProfile*, void*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJMic)(ExecState*, EncodedJSValue, EncodedJSValue, void*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJMic)(ExecState*, EncodedJSValue, void*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJssZ)(ExecState*, JSString*, int32_t);
@@ -429,15 +428,15 @@ JSCell* JIT_OPERATION operationToIndexString(ExecState*, int32_t);
 
 EncodedJSValue JIT_OPERATION operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueAddProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*, JITAddIC*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*, JITAddIC*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationValueAddProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationValueAddProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueAddOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueAddNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITAddIC*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueMul(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueMulOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueMulNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*, JITMulIC*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*, JITMulIC*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationValueMulProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationValueMulProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITMulIC*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueMulProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationArithNegate(ExecState*, EncodedJSValue operand);
 EncodedJSValue JIT_OPERATION operationArithNegateProfiled(ExecState*, EncodedJSValue operand, ArithProfile*);
@@ -447,8 +446,8 @@ EncodedJSValue JIT_OPERATION operationValueSub(ExecState*, EncodedJSValue encode
 EncodedJSValue JIT_OPERATION operationValueSubProfiled(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueSubOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationValueSubNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*, JITSubIC*) WTF_INTERNAL;
-EncodedJSValue JIT_OPERATION operationValueSubProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, ArithProfile*, JITSubIC*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationValueSubProfiledOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL;
+EncodedJSValue JIT_OPERATION operationValueSubProfiledNoOptimize(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, JITSubIC*) WTF_INTERNAL;
 
 void JIT_OPERATION operationProcessTypeProfilerLog(ExecState*) WTF_INTERNAL;
 void JIT_OPERATION operationProcessShadowChickenLog(ExecState*) WTF_INTERNAL;
index 5a323c3..795c275 100644 (file)
 
 namespace JSC {
 
-JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state)
+JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state, const ArithProfile* arithProfile)
 {
     // We default to speculating int32.
     ObservedType lhs = ObservedType().withInt32();
     ObservedType rhs = ObservedType().withInt32();
-    if (m_arithProfile) {
-        lhs = m_arithProfile->lhsObservedType();
-        rhs = m_arithProfile->rhsObservedType();
+    if (arithProfile) {
+        lhs = arithProfile->lhsObservedType();
+        rhs = arithProfile->rhsObservedType();
     }
 
     if (lhs.isOnlyNonNumber() && rhs.isOnlyNonNumber())
@@ -78,7 +78,7 @@ JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers& jit, MathICG
     return JITMathICInlineResult::GenerateFullSnippet;
 }
 
-bool JITSubGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, bool shouldEmitProfiling)
+bool JITSubGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile* arithProfile, bool shouldEmitProfiling)
 {
     ASSERT(m_scratchGPR != InvalidGPRReg);
     ASSERT(m_scratchGPR != m_left.payloadGPR());
@@ -129,8 +129,8 @@ bool JITSubGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
     rightWasInteger.link(&jit);
 
     jit.subDouble(m_rightFPR, m_leftFPR);
-    if (m_arithProfile && shouldEmitProfiling)
-        m_arithProfile->emitSetDouble(jit);
+    if (arithProfile && shouldEmitProfiling)
+        arithProfile->emitSetDouble(jit);
 
     jit.boxDouble(m_leftFPR, m_result);
 
index c8276b7..f300166 100644 (file)
@@ -42,8 +42,7 @@ public:
 
     JITSubGenerator(SnippetOperand leftOperand, SnippetOperand rightOperand,
         JSValueRegs result, JSValueRegs left, JSValueRegs right,
-        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR,
-        ArithProfile* arithProfile = nullptr)
+        FPRReg leftFPR, FPRReg rightFPR, GPRReg scratchGPR, FPRReg scratchFPR)
         : m_leftOperand(leftOperand)
         , m_rightOperand(rightOperand)
         , m_result(result)
@@ -53,17 +52,14 @@ public:
         , m_rightFPR(rightFPR)
         , m_scratchGPR(scratchGPR)
         , m_scratchFPR(scratchFPR)
-        , m_arithProfile(arithProfile)
     { }
 
-    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&);
-    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, bool shouldEmitProfiling);
+    JITMathICInlineResult generateInline(CCallHelpers&, MathICGenerationState&, const ArithProfile*);
+    bool generateFastPath(CCallHelpers&, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, const ArithProfile*, bool shouldEmitProfiling);
 
     static bool isLeftOperandValidConstant(SnippetOperand) { return false; }
     static bool isRightOperandValidConstant(SnippetOperand) { return false; }
 
-    ArithProfile* arithProfile() const { return m_arithProfile; }
-
 private:
     SnippetOperand m_leftOperand;
     SnippetOperand m_rightOperand;
@@ -74,7 +70,6 @@ private:
     FPRReg m_rightFPR;
     GPRReg m_scratchGPR;
     FPRReg m_scratchFPR;
-    ArithProfile* m_arithProfile;
 };
 
 } // namespace JSC
index d971402..8de5bf9 100644 (file)
@@ -1,3 +1,13 @@
+2016-09-26  Benjamin Poulain  <benjamin@webkit.org>
+
+        [JSC] Shrink the Math inline caches some more
+        https://bugs.webkit.org/show_bug.cgi?id=162485
+
+        Reviewed by Saam Barati.
+
+        * wtf/Bag.h:
+        Don't copy the arguments before initializing the nodes.
+
 2016-09-26  Michael Catanzaro  <mcatanzaro@igalia.com>
 
         std::unique_ptr deleter functions should not check if pointer is null
index 52040c5..01eca74 100644 (file)
@@ -37,8 +37,8 @@ private:
         WTF_MAKE_FAST_ALLOCATED;
     public:
         template<typename... Args>
-        Node(Args... args)
-            : m_item(args...)
+        Node(Args&&... args)
+            : m_item(std::forward<Args>(args)...)
         {
         }
         
@@ -81,9 +81,9 @@ public:
     }
     
     template<typename... Args>
-    T* add(Args... args)
+    T* add(Args&&... args)
     {
-        Node* newNode = new Node(args...);
+        Node* newNode = new Node(std::forward<Args>(args)...);
         newNode->m_next = m_head;
         m_head = newNode;
         return &newNode->m_item;