Changeset 167591 in webkit


Ignore:
Timestamp:
Apr 21, 2014 8:11:33 AM (10 years ago)
Author:
mhahnenberg@apple.com
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):

Location:
trunk/Source/JavaScriptCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r167577 r167591  
     12014-04-21  Mark Hahnenberg  <mhahnenberg@apple.com>
     2
     3        Inline allocate Arguments objects in the DFG
     4        https://bugs.webkit.org/show_bug.cgi?id=131897
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Many libraries/frameworks depend on the arguments object for overloaded API entry points.
     9        This is the first step to making Arguments fast(er). We'll duplicate the logic in Arguments::create
     10        for now and take the slow path for complicated cases like slow arguments, tearing off for strict mode, etc.
     11
     12        * dfg/DFGSpeculativeJIT.cpp:
     13        (JSC::DFG::SpeculativeJIT::emitAllocateArguments):
     14        * dfg/DFGSpeculativeJIT.h:
     15        (JSC::DFG::SpeculativeJIT::emitAllocateDestructibleObject):
     16        * dfg/DFGSpeculativeJIT32_64.cpp:
     17        (JSC::DFG::SpeculativeJIT::compile):
     18        * dfg/DFGSpeculativeJIT64.cpp:
     19        (JSC::DFG::SpeculativeJIT::compile):
     20        * runtime/Arguments.h:
     21        (JSC::Arguments::offsetOfActivation):
     22        (JSC::Arguments::offsetOfOverrodeLength):
     23        (JSC::Arguments::offsetOfIsStrictMode):
     24        (JSC::Arguments::offsetOfRegisterArray):
     25        (JSC::Arguments::offsetOfCallee):
     26        (JSC::Arguments::allocationSize):
     27
    1282014-04-20  Andreas Kling  <akling@apple.com>
    229
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r167418 r167591  
    105105            slowCases, this, operationNewArrayWithSize, resultGPR, storageGPR,
    106106            structure, numElements)));
     107}
     108
     109void SpeculativeJIT::emitAllocateArguments(GPRReg resultGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
     110{
     111    Structure* structure = m_jit.graph().globalObjectFor(m_currentNode->origin.semantic)->argumentsStructure();
     112    emitAllocateDestructibleObject<Arguments>(resultGPR, structure, scratchGPR1, scratchGPR2, slowPath);
     113
     114    m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfActivation()));
     115
     116    m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), scratchGPR1);
     117    m_jit.sub32(TrustedImm32(1), scratchGPR1);
     118    m_jit.store32(scratchGPR1, MacroAssembler::Address(resultGPR, Arguments::offsetOfNumArguments()));
     119
     120    m_jit.store32(TrustedImm32(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfOverrodeLength()));
     121    m_jit.store8(TrustedImm32(m_jit.isStrictModeFor(m_currentNode->origin.semantic)),
     122        MacroAssembler::Address(resultGPR, Arguments::offsetOfIsStrictMode()));
     123
     124    m_jit.storePtr(GPRInfo::callFrameRegister, MacroAssembler::Address(resultGPR, Arguments::offsetOfRegisters()));
     125    m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfRegisterArray()));
     126    m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfSlowArgumentData()));
     127
     128    m_jit.loadPtr(JITCompiler::addressFor(JSStack::Callee), scratchGPR1);
     129    m_jit.storePtr(scratchGPR1, MacroAssembler::Address(resultGPR, Arguments::offsetOfCallee()));
    107130}
    108131
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r167325 r167591  
    21792179    }
    21802180
    2181     // Convenience allocator for a buit-in object.
     2181    // Convenience allocator for a built-in object.
    21822182    template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
    21832183    void emitAllocateJSObject(GPRReg resultGPR, StructureType structure, StorageType storage,
     
    21962196    }
    21972197
     2198    template <typename T>
     2199    void emitAllocateDestructibleObject(GPRReg resultGPR, Structure* structure,
     2200        GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
     2201    {
     2202        emitAllocateJSObject<T>(resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR1, scratchGPR2, slowPath);
     2203        m_jit.storePtr(TrustedImmPtr(structure->classInfo()), MacroAssembler::Address(resultGPR, JSDestructibleObject::classInfoOffset()));
     2204    }
     2205
    21982206    void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements);
     2207    void emitAllocateArguments(GPRReg resultGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath);
    21992208
    22002209    // Add a speculation check.
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r167433 r167591  
    41684168    case CreateArguments: {
    41694169        JSValueOperand value(this, node->child1());
     4170        GPRTemporary scratch1(this);
     4171        GPRTemporary scratch2(this);
    41704172        GPRTemporary result(this, Reuse, value, PayloadWord);
    41714173       
    41724174        GPRReg valueTagGPR = value.tagGPR();
    41734175        GPRReg valuePayloadGPR = value.payloadGPR();
     4176        GPRReg scratch1GPR = scratch1.gpr();
     4177        GPRReg scratch2GPR = scratch2.gpr();
    41744178        GPRReg resultGPR = result.gpr();
    41754179       
    41764180        m_jit.move(valuePayloadGPR, resultGPR);
    41774181       
    4178         JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
    4179        
    41804182        if (node->origin.semantic.inlineCallFrame) {
     4183            JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
    41814184            addSlowPathGenerator(
    41824185                slowPathCall(
    41834186                    notCreated, this, operationCreateInlinedArguments, resultGPR,
    41844187                    node->origin.semantic.inlineCallFrame));
    4185         } else {
     4188            cellResult(resultGPR, node);
     4189            break;
     4190        }
     4191
     4192        FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_jit.graph().executableFor(node->origin.semantic));
     4193        if (m_jit.codeBlock()->hasSlowArguments()
     4194            || executable->isStrictMode()
     4195            || !executable->parameterCount()) {
     4196            JITCompiler::Jump notCreated = m_jit.branch32(JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
    41864197            addSlowPathGenerator(
    41874198                slowPathCall(notCreated, this, operationCreateArguments, resultGPR));
    4188         }
    4189        
     4199            cellResult(resultGPR, node);
     4200            break;
     4201        }
     4202
     4203        JITCompiler::Jump alreadyCreated = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
     4204
     4205        MacroAssembler::JumpList slowPaths;
     4206        emitAllocateArguments(resultGPR, scratch1GPR, scratch2GPR, slowPaths);
     4207            addSlowPathGenerator(
     4208                slowPathCall(slowPaths, this, operationCreateArguments, resultGPR));
     4209
     4210        alreadyCreated.link(&m_jit);
    41904211        cellResult(resultGPR, node);
    41914212        break;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r167433 r167591  
    42254225    case CreateArguments: {
    42264226        JSValueOperand value(this, node->child1());
     4227        GPRTemporary scratch1(this);
     4228        GPRTemporary scratch2(this);
    42274229        GPRTemporary result(this, Reuse, value);
    42284230       
    42294231        GPRReg valueGPR = value.gpr();
     4232        GPRReg scratchGPR1 = scratch1.gpr();
     4233        GPRReg scratchGPR2 = scratch2.gpr();
    42304234        GPRReg resultGPR = result.gpr();
    42314235       
    42324236        m_jit.move(valueGPR, resultGPR);
    42334237       
    4234         JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
    4235        
    42364238        if (node->origin.semantic.inlineCallFrame) {
     4239            JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
    42374240            addSlowPathGenerator(
    42384241                slowPathCall(
    42394242                    notCreated, this, operationCreateInlinedArguments, resultGPR,
    42404243                    node->origin.semantic.inlineCallFrame));
    4241         } else {
     4244            cellResult(resultGPR, node);
     4245            break;
     4246        }
     4247
     4248        FunctionExecutable* executable = jsCast<FunctionExecutable*>(m_jit.graph().executableFor(node->origin.semantic));
     4249        if (m_jit.codeBlock()->hasSlowArguments()
     4250            || executable->isStrictMode()
     4251            || !executable->parameterCount()) {
     4252            JITCompiler::Jump notCreated = m_jit.branchTest64(JITCompiler::Zero, resultGPR);
    42424253            addSlowPathGenerator(
    42434254                slowPathCall(notCreated, this, operationCreateArguments, resultGPR));
    4244         }
    4245        
     4255            cellResult(resultGPR, node);
     4256            break;
     4257        }
     4258
     4259        JITCompiler::Jump alreadyCreated = m_jit.branchTest64(JITCompiler::NonZero, resultGPR);
     4260
     4261        MacroAssembler::JumpList slowPaths;
     4262        emitAllocateArguments(resultGPR, scratchGPR1, scratchGPR2, slowPaths);
     4263        addSlowPathGenerator(
     4264            slowPathCall(slowPaths, this, operationCreateArguments, resultGPR));
     4265
     4266        alreadyCreated.link(&m_jit);
    42464267        cellResult(resultGPR, node);
    42474268        break;
  • trunk/Source/JavaScriptCore/runtime/Arguments.h

    r164764 r167591  
    9090    }
    9191   
     92    static ptrdiff_t offsetOfActivation() { return OBJECT_OFFSETOF(Arguments, m_activation); }
    9293    static ptrdiff_t offsetOfNumArguments() { return OBJECT_OFFSETOF(Arguments, m_numArguments); }
     94    static ptrdiff_t offsetOfOverrodeLength() { return OBJECT_OFFSETOF(Arguments, m_overrodeLength); }
     95    static ptrdiff_t offsetOfIsStrictMode() { return OBJECT_OFFSETOF(Arguments, m_isStrictMode); }
    9396    static ptrdiff_t offsetOfRegisters() { return OBJECT_OFFSETOF(Arguments, m_registers); }
     97    static ptrdiff_t offsetOfRegisterArray() { return OBJECT_OFFSETOF(Arguments, m_registerArray); }
    9498    static ptrdiff_t offsetOfSlowArgumentData() { return OBJECT_OFFSETOF(Arguments, m_slowArgumentData); }
    95     static ptrdiff_t offsetOfOverrodeLength() { return OBJECT_OFFSETOF(Arguments, m_overrodeLength); }
     99    static ptrdiff_t offsetOfCallee() { return OBJECT_OFFSETOF(Arguments, m_callee); }
     100
     101    static size_t allocationSize(size_t inlineCapacity)
     102    {
     103        ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
     104        return sizeof(Arguments);
     105    }
    96106   
    97107protected:
Note: See TracChangeset for help on using the changeset viewer.