Title: [167591] trunk/Source/_javascript_Core
Revision
167591
Author
[email protected]
Date
2014-04-21 08:11:33 -0700 (Mon, 21 Apr 2014)

Log Message

Inline allocate Arguments objects in the DFG
https://bugs.webkit.org/show_bug.cgi?id=131897

Reviewed by Geoffrey Garen.

Many libraries/frameworks depend on the arguments object for overloaded API entry points. 
This is the first step to making Arguments fast(er). We'll duplicate the logic in Arguments::create 
for now and take the slow path for complicated cases like slow arguments, tearing off for strict mode, etc.

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitAllocateArguments):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::emitAllocateDestructibleObject):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* runtime/Arguments.h:
(JSC::Arguments::offsetOfActivation):
(JSC::Arguments::offsetOfOverrodeLength):
(JSC::Arguments::offsetOfIsStrictMode):
(JSC::Arguments::offsetOfRegisterArray):
(JSC::Arguments::offsetOfCallee):
(JSC::Arguments::allocationSize):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (167590 => 167591)


--- trunk/Source/_javascript_Core/ChangeLog	2014-04-21 10:39:51 UTC (rev 167590)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-04-21 15:11:33 UTC (rev 167591)
@@ -1,3 +1,30 @@
+2014-04-21  Mark Hahnenberg  <[email protected]>
+
+        Inline allocate Arguments objects in the DFG
+        https://bugs.webkit.org/show_bug.cgi?id=131897
+
+        Reviewed by Geoffrey Garen.
+
+        Many libraries/frameworks depend on the arguments object for overloaded API entry points. 
+        This is the first step to making Arguments fast(er). We'll duplicate the logic in Arguments::create 
+        for now and take the slow path for complicated cases like slow arguments, tearing off for strict mode, etc.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitAllocateArguments):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::emitAllocateDestructibleObject):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * runtime/Arguments.h:
+        (JSC::Arguments::offsetOfActivation):
+        (JSC::Arguments::offsetOfOverrodeLength):
+        (JSC::Arguments::offsetOfIsStrictMode):
+        (JSC::Arguments::offsetOfRegisterArray):
+        (JSC::Arguments::offsetOfCallee):
+        (JSC::Arguments::allocationSize):
+
 2014-04-20  Andreas Kling  <[email protected]>
 
         Speed up jsStringWithCache() through WeakGCMap inlining.

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (167590 => 167591)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2014-04-21 10:39:51 UTC (rev 167590)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2014-04-21 15:11:33 UTC (rev 167591)
@@ -106,6 +106,29 @@
             structure, numElements)));
 }
 
+void SpeculativeJIT::emitAllocateArguments(GPRReg resultGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
+{
+    Structure* structure = m_jit.graph().globalObjectFor(m_currentNode->origin.semantic)->argumentsStructure();
+    emitAllocateDestructibleObject<Arguments>(resultGPR, structure, scratchGPR1, scratchGPR2, slowPath);
+
+    m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfActivation()));
+
+    m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), scratchGPR1);
+    m_jit.sub32(TrustedImm32(1), scratchGPR1);
+    m_jit.store32(scratchGPR1, MacroAssembler::Address(resultGPR, Arguments::offsetOfNumArguments()));
+
+    m_jit.store32(TrustedImm32(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfOverrodeLength()));
+    m_jit.store8(TrustedImm32(m_jit.isStrictModeFor(m_currentNode->origin.semantic)), 
+        MacroAssembler::Address(resultGPR, Arguments::offsetOfIsStrictMode()));
+
+    m_jit.storePtr(GPRInfo::callFrameRegister, MacroAssembler::Address(resultGPR, Arguments::offsetOfRegisters()));
+    m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfRegisterArray()));
+    m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfSlowArgumentData()));
+
+    m_jit.loadPtr(JITCompiler::addressFor(JSStack::Callee), scratchGPR1);
+    m_jit.storePtr(scratchGPR1, MacroAssembler::Address(resultGPR, Arguments::offsetOfCallee()));
+}
+
 void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Node* node, MacroAssembler::Jump jumpToFail)
 {
     if (!m_compileOkay)

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (167590 => 167591)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2014-04-21 10:39:51 UTC (rev 167590)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2014-04-21 15:11:33 UTC (rev 167591)
@@ -2178,7 +2178,7 @@
         m_jit.storePtr(storage, MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()));
     }
 
-    // Convenience allocator for a buit-in object.
+    // Convenience allocator for a built-in object.
     template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
     void emitAllocateJSObject(GPRReg resultGPR, StructureType structure, StorageType storage,
         GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
@@ -2195,7 +2195,16 @@
         emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);
     }
 
+    template <typename T>
+    void emitAllocateDestructibleObject(GPRReg resultGPR, Structure* structure, 
+        GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
+    {
+        emitAllocateJSObject<T>(resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR1, scratchGPR2, slowPath);
+        m_jit.storePtr(TrustedImmPtr(structure->classInfo()), MacroAssembler::Address(resultGPR, JSDestructibleObject::classInfoOffset()));
+    }
+
     void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements);
+    void emitAllocateArguments(GPRReg resultGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath);
 
     // Add a speculation check.
     void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (167590 => 167591)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2014-04-21 10:39:51 UTC (rev 167590)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2014-04-21 15:11:33 UTC (rev 167591)
@@ -4167,26 +4167,47 @@
         
     case CreateArguments: {
         JSValueOperand value(this, node->child1());
+        GPRTemporary scratch1(this);
+        GPRTemporary scratch2(this);
         GPRTemporary result(this, Reuse, value, PayloadWord);
         
         GPRReg valueTagGPR = value.tagGPR();
         GPRReg valuePayloadGPR = value.payloadGPR();
+        GPRReg scratch1GPR = scratch1.gpr();
+        GPRReg scratch2GPR = scratch2.gpr();
         GPRReg resultGPR = result.gpr();
         
         m_jit.move(valuePayloadGPR, resultGPR);
         
-        JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
-        
         if (node->origin.semantic.inlineCallFrame) {
+            JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
             addSlowPathGenerator(
                 slowPathCall(
                     notCreated, this, operationCreateInlinedArguments, resultGPR,
                     node->origin.semantic.inlineCallFrame));
-        } else {
+            cellResult(resultGPR, node);
+            break;
+        } 
+
+        FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_jit.graph().executableFor(node->origin.semantic));
+        if (m_jit.codeBlock()->hasSlowArguments()
+            || executable->isStrictMode() 
+            || !executable->parameterCount()) {
+            JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
             addSlowPathGenerator(
                 slowPathCall(notCreated, this, operationCreateArguments, resultGPR));
+            cellResult(resultGPR, node);
+            break;
         }
-        
+
+        JITCompiler::Jump alreadyCreated = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
+
+        MacroAssembler::JumpList slowPaths;
+        emitAllocateArguments(resultGPR, scratch1GPR, scratch2GPR, slowPaths);
+            addSlowPathGenerator(
+                slowPathCall(slowPaths, this, operationCreateArguments, resultGPR));
+
+        alreadyCreated.link(&m_jit); 
         cellResult(resultGPR, node);
         break;
     }

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (167590 => 167591)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2014-04-21 10:39:51 UTC (rev 167590)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2014-04-21 15:11:33 UTC (rev 167591)
@@ -4224,25 +4224,46 @@
         
     case CreateArguments: {
         JSValueOperand value(this, node->child1());
+        GPRTemporary scratch1(this);
+        GPRTemporary scratch2(this);
         GPRTemporary result(this, Reuse, value);
         
         GPRReg valueGPR = value.gpr();
+        GPRReg scratchGPR1 = scratch1.gpr();
+        GPRReg scratchGPR2 = scratch2.gpr();
         GPRReg resultGPR = result.gpr();
         
         m_jit.move(valueGPR, resultGPR);
         
-        JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
-        
         if (node->origin.semantic.inlineCallFrame) {
+            JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
             addSlowPathGenerator(
                 slowPathCall(
                     notCreated, this, operationCreateInlinedArguments, resultGPR,
                     node->origin.semantic.inlineCallFrame));
-        } else {
+            cellResult(resultGPR, node);
+            break;
+        } 
+
+        FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_jit.graph().executableFor(node->origin.semantic));
+        if (m_jit.codeBlock()->hasSlowArguments()
+            || executable->isStrictMode() 
+            || !executable->parameterCount()) {
+            JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
             addSlowPathGenerator(
                 slowPathCall(notCreated, this, operationCreateArguments, resultGPR));
+            cellResult(resultGPR, node);
+            break;
         }
-        
+
+        JITCompiler::Jump alreadyCreated = m_jit.branchTest64(JITCompiler::NonZero, resultGPR);
+
+        MacroAssembler::JumpList slowPaths;
+        emitAllocateArguments(resultGPR, scratchGPR1, scratchGPR2, slowPaths);
+        addSlowPathGenerator(
+            slowPathCall(slowPaths, this, operationCreateArguments, resultGPR));
+
+        alreadyCreated.link(&m_jit);
         cellResult(resultGPR, node);
         break;
     }

Modified: trunk/Source/_javascript_Core/runtime/Arguments.h (167590 => 167591)


--- trunk/Source/_javascript_Core/runtime/Arguments.h	2014-04-21 10:39:51 UTC (rev 167590)
+++ trunk/Source/_javascript_Core/runtime/Arguments.h	2014-04-21 15:11:33 UTC (rev 167591)
@@ -89,10 +89,20 @@
         return Structure::create(vm, globalObject, prototype, TypeInfo(ArgumentsType, StructureFlags), info()); 
     }
     
+    static ptrdiff_t offsetOfActivation() { return OBJECT_OFFSETOF(Arguments, m_activation); }
     static ptrdiff_t offsetOfNumArguments() { return OBJECT_OFFSETOF(Arguments, m_numArguments); }
+    static ptrdiff_t offsetOfOverrodeLength() { return OBJECT_OFFSETOF(Arguments, m_overrodeLength); }
+    static ptrdiff_t offsetOfIsStrictMode() { return OBJECT_OFFSETOF(Arguments, m_isStrictMode); }
     static ptrdiff_t offsetOfRegisters() { return OBJECT_OFFSETOF(Arguments, m_registers); }
+    static ptrdiff_t offsetOfRegisterArray() { return OBJECT_OFFSETOF(Arguments, m_registerArray); }
     static ptrdiff_t offsetOfSlowArgumentData() { return OBJECT_OFFSETOF(Arguments, m_slowArgumentData); }
-    static ptrdiff_t offsetOfOverrodeLength() { return OBJECT_OFFSETOF(Arguments, m_overrodeLength); }
+    static ptrdiff_t offsetOfCallee() { return OBJECT_OFFSETOF(Arguments, m_callee); }
+
+    static size_t allocationSize(size_t inlineCapacity)
+    {
+        ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
+        return sizeof(Arguments);
+    }
     
 protected:
     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to