Changeset 128832 in webkit


Ignore:
Timestamp:
Sep 17, 2012 6:15:04 PM (12 years ago)
Author:
ggaren@apple.com
Message:

Refactored the arguments object so it doesn't dictate closure layout
https://bugs.webkit.org/show_bug.cgi?id=96955

Reviewed by Oliver Hunt.

  • bytecode/CodeBlock.h:

(JSC::ExecState::argumentAfterCapture): Helper function for accessing an
argument that has been moved for capture.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator): Generate metadata for arguments
that are captured. We don't move any arguments yet, but we do use this
metadata to tell the arguments object if an argument is stored in the
activation.

  • dfg/DFGOperations.cpp:
  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
(JSC::DFG::SpeculativeJIT::compileGetArgumentsLength):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile): Updated for the arguments object not
malloc'ing a separate backing store, and for a rename from deletedArguments
to slowArguments.

  • interpreter/CallFrame.h:

(ExecState):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::unwindCallFrame):
(JSC::Interpreter::privateExecute):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL): Updated for small interface changes.

  • runtime/Arguments.cpp:

(JSC::Arguments::visitChildren):
(JSC::Arguments::copyToArguments):
(JSC::Arguments::fillArgList):
(JSC::Arguments::getOwnPropertySlotByIndex):
(JSC::Arguments::createStrictModeCallerIfNecessary):
(JSC::Arguments::createStrictModeCalleeIfNecessary):
(JSC::Arguments::getOwnPropertySlot):
(JSC::Arguments::getOwnPropertyDescriptor):
(JSC::Arguments::getOwnPropertyNames):
(JSC::Arguments::putByIndex):
(JSC::Arguments::put):
(JSC::Arguments::deletePropertyByIndex):
(JSC::Arguments::deleteProperty):
(JSC::Arguments::defineOwnProperty):
(JSC::Arguments::tearOff): Moved all data inline into the object, for speed,
and refactored all internal argument accesses to use helper functions, so
we can change the implementation without changing lots of code.

(JSC::Arguments::didTearOffActivation): This function needs to account
for arguments that were moved by the activation object. We do this accounting
through a side vector that tells us where our arguments will be in the
activation.

(JSC::Arguments::tearOffForInlineCallFrame):

  • runtime/Arguments.h:

(Arguments):
(JSC::Arguments::length):
(JSC::Arguments::isTornOff):
(JSC::Arguments::Arguments):
(JSC::Arguments::allocateSlowArguments):
(JSC::Arguments::tryDeleteArgument):
(JSC::Arguments::trySetArgument):
(JSC::Arguments::tryGetArgument):
(JSC::Arguments::isDeletedArgument):
(JSC::Arguments::isArgument):
(JSC::Arguments::argument):
(JSC::Arguments::finishCreation):

  • runtime/JSActivation.h:

(JSC::JSActivation::create):
(JSActivation):
(JSC::JSActivation::captureStart):
(JSC::JSActivation::storageSize):
(JSC::JSActivation::registerOffset):
(JSC::JSActivation::isValid): The activation object is no longer responsible
for copying extra arguments provided by the caller. The argumnents object
does this instead. This means we can allocate and initialize an activation
without worrying about the call frame's argument count.

  • runtime/SymbolTable.h:

(JSC::SlowArgument::SlowArgument):
(SlowArgument):
(JSC):
(JSC::SharedSymbolTable::parameterCount):
(SharedSymbolTable):
(JSC::SharedSymbolTable::slowArguments):
(JSC::SharedSymbolTable::setSlowArguments): Added data structures to back
the algorithms above.

Location:
trunk/Source/JavaScriptCore
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r128822 r128832  
     12012-09-17  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Refactored the arguments object so it doesn't dictate closure layout
     4        https://bugs.webkit.org/show_bug.cgi?id=96955
     5
     6        Reviewed by Oliver Hunt.
     7
     8        * bytecode/CodeBlock.h:
     9        (JSC::ExecState::argumentAfterCapture): Helper function for accessing an
     10        argument that has been moved for capture.
     11
     12        * bytecompiler/BytecodeGenerator.cpp:
     13        (JSC::BytecodeGenerator::BytecodeGenerator): Generate metadata for arguments
     14        that are captured. We don't move any arguments yet, but we do use this
     15        metadata to tell the arguments object if an argument is stored in the
     16        activation.
     17
     18        * dfg/DFGOperations.cpp:
     19        * dfg/DFGSpeculativeJIT.cpp:
     20        (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
     21        (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength):
     22        * dfg/DFGSpeculativeJIT64.cpp:
     23        (JSC::DFG::SpeculativeJIT::compile): Updated for the arguments object not
     24        malloc'ing a separate backing store, and for a rename from deletedArguments
     25        to slowArguments.
     26
     27        * interpreter/CallFrame.h:
     28        (ExecState):
     29        * interpreter/Interpreter.cpp:
     30        (JSC::Interpreter::unwindCallFrame):
     31        (JSC::Interpreter::privateExecute):
     32        * jit/JITStubs.cpp:
     33        (JSC::DEFINE_STUB_FUNCTION):
     34        * llint/LLIntSlowPaths.cpp:
     35        (JSC::LLInt::LLINT_SLOW_PATH_DECL): Updated for small interface changes.
     36
     37        * runtime/Arguments.cpp:
     38        (JSC::Arguments::visitChildren):
     39        (JSC::Arguments::copyToArguments):
     40        (JSC::Arguments::fillArgList):
     41        (JSC::Arguments::getOwnPropertySlotByIndex):
     42        (JSC::Arguments::createStrictModeCallerIfNecessary):
     43        (JSC::Arguments::createStrictModeCalleeIfNecessary):
     44        (JSC::Arguments::getOwnPropertySlot):
     45        (JSC::Arguments::getOwnPropertyDescriptor):
     46        (JSC::Arguments::getOwnPropertyNames):
     47        (JSC::Arguments::putByIndex):
     48        (JSC::Arguments::put):
     49        (JSC::Arguments::deletePropertyByIndex):
     50        (JSC::Arguments::deleteProperty):
     51        (JSC::Arguments::defineOwnProperty):
     52        (JSC::Arguments::tearOff): Moved all data inline into the object, for speed,
     53        and refactored all internal argument accesses to use helper functions, so
     54        we can change the implementation without changing lots of code.
     55
     56        (JSC::Arguments::didTearOffActivation): This function needs to account
     57        for arguments that were moved by the activation object. We do this accounting
     58        through a side vector that tells us where our arguments will be in the
     59        activation.
     60
     61        (JSC::Arguments::tearOffForInlineCallFrame):
     62        * runtime/Arguments.h:
     63        (Arguments):
     64        (JSC::Arguments::length):
     65        (JSC::Arguments::isTornOff):
     66        (JSC::Arguments::Arguments):
     67        (JSC::Arguments::allocateSlowArguments):
     68        (JSC::Arguments::tryDeleteArgument):
     69        (JSC::Arguments::trySetArgument):
     70        (JSC::Arguments::tryGetArgument):
     71        (JSC::Arguments::isDeletedArgument):
     72        (JSC::Arguments::isArgument):
     73        (JSC::Arguments::argument):
     74        (JSC::Arguments::finishCreation):
     75
     76        * runtime/JSActivation.h:
     77        (JSC::JSActivation::create):
     78        (JSActivation):
     79        (JSC::JSActivation::captureStart):
     80        (JSC::JSActivation::storageSize):
     81        (JSC::JSActivation::registerOffset):
     82        (JSC::JSActivation::isValid): The activation object is no longer responsible
     83        for copying extra arguments provided by the caller. The argumnents object
     84        does this instead. This means we can allocate and initialize an activation
     85        without worrying about the call frame's argument count.
     86
     87        * runtime/SymbolTable.h:
     88        (JSC::SlowArgument::SlowArgument):
     89        (SlowArgument):
     90        (JSC):
     91        (JSC::SharedSymbolTable::parameterCount):
     92        (SharedSymbolTable):
     93        (JSC::SharedSymbolTable::slowArguments):
     94        (JSC::SharedSymbolTable::setSlowArguments): Added data structures to back
     95        the algorithms above.
     96
    1972012-09-17  Filip Pizlo  <fpizlo@apple.com>
    298
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r128544 r128832  
    15451545#endif
    15461546
     1547    inline JSValue ExecState::argumentAfterCapture(size_t argument)
     1548    {
     1549        if (argument >= argumentCount())
     1550             return jsUndefined();
     1551
     1552        if (!codeBlock())
     1553            return this[argumentOffset(argument)].jsValue();
     1554
     1555        if (argument >= static_cast<size_t>(codeBlock()->symbolTable()->parameterCount()))
     1556            return this[argumentOffset(argument)].jsValue();
     1557
     1558        const SlowArgument* slowArguments = codeBlock()->symbolTable()->slowArguments();
     1559        if (!slowArguments || slowArguments[argument].status == SlowArgument::Normal)
     1560            return this[argumentOffset(argument)].jsValue();
     1561
     1562        ASSERT(slowArguments[argument].status == SlowArgument::Captured);
     1563        return this[slowArguments[argument].indexIfCaptured].jsValue();
     1564    }
     1565
    15471566#if ENABLE(DFG_JIT)
    15481567    inline void DFGCodeBlocks::mark(void* candidateCodeBlock)
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r128534 r128832  
    424424    }
    425425
    426     bool capturesAnyArgument = codeBlock->usesArguments() || codeBlock->usesEval() || m_shouldEmitDebugHooks; // May reify arguments object.
    427     if (!capturesAnyArgument && functionBody->hasCapturedVariables()) {
     426    bool mayReifyArgumentsObject = codeBlock->usesArguments() || codeBlock->usesEval() || m_shouldEmitDebugHooks;
     427    bool capturesAnyArgumentByName = false;
     428    if (functionBody->hasCapturedVariables()) {
    428429        FunctionParameters& parameters = *functionBody->parameters();
    429430        for (size_t i = 0; i < parameters.size(); ++i) {
    430431            if (!functionBody->captures(parameters[i]))
    431432                continue;
    432             capturesAnyArgument = true;
     433            capturesAnyArgumentByName = true;
    433434            break;
    434435        }
    435436    }
    436437
    437     if (capturesAnyArgument) {
     438    if (mayReifyArgumentsObject || capturesAnyArgumentByName) {
    438439        symbolTable->setCaptureMode(SharedSymbolTable::AllOfTheThings);
    439440        symbolTable->setCaptureStart(-CallFrame::offsetFor(symbolTable->parameterCountIncludingThis()));
     
    441442        symbolTable->setCaptureMode(SharedSymbolTable::SomeOfTheThings);
    442443        symbolTable->setCaptureStart(m_codeBlock->m_numVars);
     444    }
     445
     446    if (mayReifyArgumentsObject && capturesAnyArgumentByName) {
     447        size_t parameterCount = symbolTable->parameterCount();
     448        OwnArrayPtr<SlowArgument> slowArguments = adoptArrayPtr(new SlowArgument[parameterCount]);
     449        for (size_t i = 0; i < parameterCount; ++i) {
     450            slowArguments[i].status = SlowArgument::Captured;
     451            slowArguments[i].indexIfCaptured = CallFrame::argumentOffset(i);
     452        }
     453        symbolTable->setSlowArguments(slowArguments.release());
    443454    }
    444455
     
    682693    if (entry.isNull())
    683694        return false;
    684    
     695
    685696    if (m_codeBlock->usesArguments() && m_codeType == FunctionCode)
    686697        return true;
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r128400 r128832  
    11791179    ASSERT(exec->codeBlock()->usesArguments());
    11801180    if (activationCell) {
    1181         jsCast<Arguments*>(argumentsCell)->didTearOffActivation(exec->globalData(), jsCast<JSActivation*>(activationCell));
     1181        jsCast<Arguments*>(argumentsCell)->didTearOffActivation(exec, jsCast<JSActivation*>(activationCell));
    11821182        return;
    11831183    }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r128802 r128832  
    30583058    ASSERT(modeAlreadyChecked(m_state.forNode(node.child1()), Array::Arguments));
    30593059   
    3060     m_jit.loadPtr(
    3061         MacroAssembler::Address(baseReg, Arguments::offsetOfData()),
    3062         scratchReg);
    3063 
    30643060    // Two really lame checks.
    30653061    speculationCheck(
     
    30673063        m_jit.branchPtr(
    30683064            MacroAssembler::AboveOrEqual, propertyReg,
    3069             MacroAssembler::Address(scratchReg, OBJECT_OFFSETOF(ArgumentsData, numArguments))));
     3065            MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_numArguments))));
    30703066    speculationCheck(
    30713067        Uncountable, JSValueSource(), NoNode,
     
    30733069            MacroAssembler::NonZero,
    30743070            MacroAssembler::Address(
    3075                 scratchReg, OBJECT_OFFSETOF(ArgumentsData, deletedArguments))));
     3071                baseReg, OBJECT_OFFSETOF(Arguments, m_slowArguments))));
    30763072   
    30773073    m_jit.move(propertyReg, resultReg);
     
    30793075    m_jit.signExtend32ToPtr(resultReg, resultReg);
    30803076    m_jit.loadPtr(
    3081         MacroAssembler::Address(scratchReg, OBJECT_OFFSETOF(ArgumentsData, registers)),
     3077        MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_registers)),
    30823078        scratchReg);
    30833079   
     
    31193115    ASSERT(modeAlreadyChecked(m_state.forNode(node.child1()), Array::Arguments));
    31203116   
    3121     m_jit.loadPtr(
    3122         MacroAssembler::Address(baseReg, Arguments::offsetOfData()),
    3123         resultReg);
    3124 
    31253117    speculationCheck(
    31263118        Uncountable, JSValueSource(), NoNode,
    31273119        m_jit.branchTest8(
    31283120            MacroAssembler::NonZero,
    3129             MacroAssembler::Address(resultReg, OBJECT_OFFSETOF(ArgumentsData, overrodeLength))));
     3121            MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_overrodeLength))));
    31303122   
    31313123    m_jit.load32(
    3132         MacroAssembler::Address(resultReg, OBJECT_OFFSETOF(ArgumentsData, numArguments)),
     3124        MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_numArguments)),
    31333125        resultReg);
    31343126    integerResult(resultReg, m_compileIndex);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r128802 r128832  
    28112811                return;
    28122812
    2813             m_jit.loadPtr(
    2814                 MacroAssembler::Address(baseReg, Arguments::offsetOfData()),
    2815                 scratchReg);
    2816 
    28172813            // Two really lame checks.
    28182814            speculationCheck(
     
    28202816                m_jit.branchPtr(
    28212817                    MacroAssembler::AboveOrEqual, propertyReg,
    2822                     MacroAssembler::Address(scratchReg, OBJECT_OFFSETOF(ArgumentsData, numArguments))));
     2818                    MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_numArguments))));
    28232819            speculationCheck(
    28242820                Uncountable, JSValueSource(), NoNode,
     
    28262822                    MacroAssembler::NonZero,
    28272823                    MacroAssembler::Address(
    2828                         scratchReg, OBJECT_OFFSETOF(ArgumentsData, deletedArguments))));
     2824                        baseReg, OBJECT_OFFSETOF(Arguments, m_slowArguments))));
    28292825   
    28302826            m_jit.move(propertyReg, scratch2Reg);
     
    28322828            m_jit.signExtend32ToPtr(scratch2Reg, scratch2Reg);
    28332829            m_jit.loadPtr(
    2834                 MacroAssembler::Address(scratchReg, OBJECT_OFFSETOF(ArgumentsData, registers)),
     2830                MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_registers)),
    28352831                scratchReg);
    28362832           
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.h

    r128260 r128832  
    188188        Register& uncheckedR(int);
    189189
    190         // Access to arguments.
     190        // Access to arguments as passed. (After capture, arguments may move to a different location.)
    191191        size_t argumentCount() const { return argumentCountIncludingThis() - 1; }
    192192        size_t argumentCountIncludingThis() const { return this[RegisterFile::ArgumentCount].payload(); }
     
    208208        JSValue thisValue() { return this[thisArgumentOffset()].jsValue(); }
    209209        void setThisValue(JSValue value) { this[thisArgumentOffset()] = value; }
     210
     211        JSValue argumentAfterCapture(size_t argument);
    210212
    211213        static int offsetFor(size_t argumentCountIncludingThis) { return argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize; }
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r128611 r128832  
    474474        if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) {
    475475            if (activation)
    476                 jsCast<Arguments*>(arguments)->didTearOffActivation(callFrame->globalData(), jsCast<JSActivation*>(activation));
     476                jsCast<Arguments*>(arguments)->didTearOffActivation(callFrame, jsCast<JSActivation*>(activation));
    477477            else
    478478                jsCast<Arguments*>(arguments)->tearOff(callFrame);
     
    45094509        if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
    45104510            if (JSValue activationValue = callFrame->r(activation).jsValue())
    4511                 asArguments(argumentsValue)->didTearOffActivation(callFrame->globalData(), asActivation(activationValue));
     4511                asArguments(argumentsValue)->didTearOffActivation(callFrame, asActivation(activationValue));
    45124512            else
    45134513                asArguments(argumentsValue)->tearOff(callFrame);
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r128400 r128832  
    23242324    Arguments* arguments = jsCast<Arguments*>(stackFrame.args[0].jsValue());
    23252325    if (JSValue activationValue = stackFrame.args[1].jsValue()) {
    2326         arguments->didTearOffActivation(callFrame->globalData(), jsCast<JSActivation*>(activationValue));
     2326        arguments->didTearOffActivation(callFrame, jsCast<JSActivation*>(activationValue));
    23272327        return;
    23282328    }
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r128400 r128832  
    14761476    Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)).jsValue());
    14771477    if (JSValue activationValue = LLINT_OP_C(2).jsValue())
    1478         arguments->didTearOffActivation(globalData, jsCast<JSActivation*>(activationValue));
     1478        arguments->didTearOffActivation(exec, jsCast<JSActivation*>(activationValue));
    14791479    else
    14801480        arguments->tearOff(exec);
  • trunk/Source/JavaScriptCore/runtime/Arguments.cpp

    r128813 r128832  
    4646    JSObject::visitChildren(thisObject, visitor);
    4747
    48     if (thisObject->d->registerArray)
    49         visitor.appendValues(thisObject->d->registerArray.get(), thisObject->d->numArguments);
    50     visitor.append(&thisObject->d->callee);
    51     visitor.append(&thisObject->d->activation);
     48    if (thisObject->m_registerArray)
     49        visitor.appendValues(thisObject->m_registerArray.get(), thisObject->m_numArguments);
     50    visitor.append(&thisObject->m_callee);
     51    visitor.append(&thisObject->m_activation);
    5252}
    5353
     
    5959void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t length)
    6060{
    61     if (UNLIKELY(d->overrodeLength)) {
     61    if (UNLIKELY(m_overrodeLength)) {
    6262        length = min(get(exec, exec->propertyNames().length).toUInt32(exec), length);
    6363        for (unsigned i = 0; i < length; i++)
     
    6767    ASSERT(length == this->length(exec));
    6868    for (size_t i = 0; i < length; ++i) {
    69         if (!d->deletedArguments || !d->deletedArguments[i])
    70             callFrame->setArgument(i, argument(i).get());
     69        if (JSValue value = tryGetArgument(i))
     70            callFrame->setArgument(i, value);
    7171        else
    7272            callFrame->setArgument(i, get(exec, i));
     
    7676void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
    7777{
    78     if (UNLIKELY(d->overrodeLength)) {
     78    if (UNLIKELY(m_overrodeLength)) {
    7979        unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec);
    8080        for (unsigned i = 0; i < length; i++)
     
    8484    uint32_t length = this->length(exec);
    8585    for (size_t i = 0; i < length; ++i) {
    86         if (!d->deletedArguments || !d->deletedArguments[i])
    87             args.append(argument(i).get());
     86        if (JSValue value = tryGetArgument(i))
     87            args.append(value);
    8888        else
    8989            args.append(get(exec, i));
     
    9494{
    9595    Arguments* thisObject = jsCast<Arguments*>(cell);
    96     if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
    97         slot.setValue(thisObject->argument(i).get());
     96    if (JSValue value = thisObject->tryGetArgument(i)) {
     97        slot.setValue(value);
    9898        return true;
    9999    }
     
    104104void Arguments::createStrictModeCallerIfNecessary(ExecState* exec)
    105105{
    106     if (d->overrodeCaller)
    107         return;
    108 
    109     d->overrodeCaller = true;
     106    if (m_overrodeCaller)
     107        return;
     108
     109    m_overrodeCaller = true;
    110110    PropertyDescriptor descriptor;
    111111    descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(exec), DontEnum | DontDelete | Accessor);
     
    115115void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec)
    116116{
    117     if (d->overrodeCallee)
    118         return;
    119    
    120     d->overrodeCallee = true;
     117    if (m_overrodeCallee)
     118        return;
     119   
     120    m_overrodeCallee = true;
    121121    PropertyDescriptor descriptor;
    122122    descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(exec), DontEnum | DontDelete | Accessor);
     
    128128    Arguments* thisObject = jsCast<Arguments*>(cell);
    129129    unsigned i = propertyName.asIndex();
    130     if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
     130    if (JSValue value = thisObject->tryGetArgument(i)) {
    131131        ASSERT(i < PropertyName::NotAnIndex);
    132         slot.setValue(thisObject->argument(i).get());
    133         return true;
    134     }
    135 
    136     if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->d->overrodeLength)) {
    137         slot.setValue(jsNumber(thisObject->d->numArguments));
    138         return true;
    139     }
    140 
    141     if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->d->overrodeCallee)) {
    142         if (!thisObject->d->isStrictMode) {
    143             slot.setValue(thisObject->d->callee.get());
     132        slot.setValue(value);
     133        return true;
     134    }
     135
     136    if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->m_overrodeLength)) {
     137        slot.setValue(jsNumber(thisObject->m_numArguments));
     138        return true;
     139    }
     140
     141    if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->m_overrodeCallee)) {
     142        if (!thisObject->m_isStrictMode) {
     143            slot.setValue(thisObject->m_callee.get());
    144144            return true;
    145145        }
     
    147147    }
    148148
    149     if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
     149    if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
    150150        thisObject->createStrictModeCallerIfNecessary(exec);
    151151
     
    157157    Arguments* thisObject = jsCast<Arguments*>(object);
    158158    unsigned i = propertyName.asIndex();
    159     if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
     159    if (JSValue value = thisObject->tryGetArgument(i)) {
    160160        ASSERT(i < PropertyName::NotAnIndex);
    161         descriptor.setDescriptor(thisObject->argument(i).get(), None);
    162         return true;
    163     }
    164    
    165     if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->d->overrodeLength)) {
    166         descriptor.setDescriptor(jsNumber(thisObject->d->numArguments), DontEnum);
    167         return true;
    168     }
    169    
    170     if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->d->overrodeCallee)) {
    171         if (!thisObject->d->isStrictMode) {
    172             descriptor.setDescriptor(thisObject->d->callee.get(), DontEnum);
     161        descriptor.setDescriptor(value, None);
     162        return true;
     163    }
     164   
     165    if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->m_overrodeLength)) {
     166        descriptor.setDescriptor(jsNumber(thisObject->m_numArguments), DontEnum);
     167        return true;
     168    }
     169   
     170    if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->m_overrodeCallee)) {
     171        if (!thisObject->m_isStrictMode) {
     172            descriptor.setDescriptor(thisObject->m_callee.get(), DontEnum);
    173173            return true;
    174174        }
     
    176176    }
    177177
    178     if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
     178    if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
    179179        thisObject->createStrictModeCallerIfNecessary(exec);
    180180   
     
    185185{
    186186    Arguments* thisObject = jsCast<Arguments*>(object);
    187     for (unsigned i = 0; i < thisObject->d->numArguments; ++i) {
    188         if (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])
    189             propertyNames.add(Identifier(exec, String::number(i)));
     187    for (unsigned i = 0; i < thisObject->m_numArguments; ++i) {
     188        if (!thisObject->isArgument(i))
     189            continue;
     190        propertyNames.add(Identifier(exec, String::number(i)));
    190191    }
    191192    if (mode == IncludeDontEnumProperties) {
     
    199200{
    200201    Arguments* thisObject = jsCast<Arguments*>(cell);
    201     if (i < static_cast<unsigned>(thisObject->d->numArguments) && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
    202         thisObject->argument(i).set(exec->globalData(), thisObject, value);
    203         return;
    204     }
     202    if (thisObject->trySetArgument(exec->globalData(), i, value))
     203        return;
    205204
    206205    PutPropertySlot slot(shouldThrow);
     
    212211    Arguments* thisObject = jsCast<Arguments*>(cell);
    213212    unsigned i = propertyName.asIndex();
    214     if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
    215         ASSERT(i < PropertyName::NotAnIndex);
    216         thisObject->argument(i).set(exec->globalData(), thisObject, value);
    217         return;
    218     }
    219 
    220     if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) {
    221         thisObject->d->overrodeLength = true;
     213    if (thisObject->trySetArgument(exec->globalData(), i, value))
     214        return;
     215
     216    if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
     217        thisObject->m_overrodeLength = true;
    222218        thisObject->putDirect(exec->globalData(), propertyName, value, DontEnum);
    223219        return;
    224220    }
    225221
    226     if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) {
    227         if (!thisObject->d->isStrictMode) {
    228             thisObject->d->overrodeCallee = true;
     222    if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
     223        if (!thisObject->m_isStrictMode) {
     224            thisObject->m_overrodeCallee = true;
    229225            thisObject->putDirect(exec->globalData(), propertyName, value, DontEnum);
    230226            return;
     
    233229    }
    234230
    235     if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
     231    if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
    236232        thisObject->createStrictModeCallerIfNecessary(exec);
    237233
     
    242238{
    243239    Arguments* thisObject = jsCast<Arguments*>(cell);
    244     if (i < thisObject->d->numArguments) {
     240    if (i < thisObject->m_numArguments) {
    245241        if (!Base::deletePropertyByIndex(cell, exec, i))
    246242            return false;
    247 
    248         if (!thisObject->d->deletedArguments) {
    249             thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
    250             memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
    251         }
    252         if (!thisObject->d->deletedArguments[i]) {
    253             thisObject->d->deletedArguments[i] = true;
     243        if (thisObject->tryDeleteArgument(i))
    254244            return true;
    255         }
    256     }
    257 
     245    }
    258246    return JSObject::deletePropertyByIndex(thisObject, exec, i);
    259247}
     
    266254    Arguments* thisObject = jsCast<Arguments*>(cell);
    267255    unsigned i = propertyName.asIndex();
    268     if (i < thisObject->d->numArguments) {
     256    if (i < thisObject->m_numArguments) {
    269257        ASSERT(i < PropertyName::NotAnIndex);
    270258        if (!Base::deleteProperty(cell, exec, propertyName))
    271259            return false;
    272 
    273         if (!thisObject->d->deletedArguments) {
    274             thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
    275             memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
    276         }
    277         if (!thisObject->d->deletedArguments[i]) {
    278             thisObject->d->deletedArguments[i] = true;
     260        if (thisObject->tryDeleteArgument(i))
    279261            return true;
    280         }
    281     }
    282 
    283     if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) {
    284         thisObject->d->overrodeLength = true;
    285         return true;
    286     }
    287 
    288     if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) {
    289         if (!thisObject->d->isStrictMode) {
    290             thisObject->d->overrodeCallee = true;
     262    }
     263
     264    if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
     265        thisObject->m_overrodeLength = true;
     266        return true;
     267    }
     268
     269    if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
     270        if (!thisObject->m_isStrictMode) {
     271            thisObject->m_overrodeCallee = true;
    291272            return true;
    292273        }
     
    294275    }
    295276   
    296     if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
     277    if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
    297278        thisObject->createStrictModeCallerIfNecessary(exec);
    298279
     
    304285    Arguments* thisObject = jsCast<Arguments*>(object);
    305286    unsigned i = propertyName.asIndex();
    306     if (i < thisObject->d->numArguments) {
     287    if (i < thisObject->m_numArguments) {
    307288        ASSERT(i < PropertyName::NotAnIndex);
    308289        // If the property is not yet present on the object, and is not yet marked as deleted, then add it now.
    309290        PropertySlot slot;
    310         if ((!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i]) && !JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot))
    311             object->putDirectMayBeIndex(exec, propertyName, thisObject->argument(i).get());
     291        if (!thisObject->isDeletedArgument(i) && !JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) {
     292            JSValue value = thisObject->tryGetArgument(i);
     293            ASSERT(value);
     294            object->putDirectMayBeIndex(exec, propertyName, value);
     295        }
    312296        if (!Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow))
    313297            return false;
    314298
    315         if (!thisObject->d->deletedArguments) {
    316             thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
    317             memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
    318         }
    319299        // From ES 5.1, 10.6 Arguments Object
    320300        // 5. If the value of isMapped is not undefined, then
    321         if (!thisObject->d->deletedArguments[i]) {
     301        if (thisObject->isArgument(i)) {
    322302            // a. If IsAccessorDescriptor(Desc) is true, then
    323303            if (descriptor.isAccessorDescriptor()) {
    324304                // i. Call the [[Delete]] internal method of map passing P, and false as the arguments.
    325                 thisObject->d->deletedArguments[i] = true;
     305                thisObject->tryDeleteArgument(i);
    326306            } else { // b. Else
    327307                // i. If Desc.[[Value]] is present, then
    328308                // 1. Call the [[Put]] internal method of map passing P, Desc.[[Value]], and Throw as the arguments.
    329309                if (descriptor.value())
    330                     thisObject->argument(i).set(exec->globalData(), thisObject, descriptor.value());
     310                    thisObject->trySetArgument(exec->globalData(), i, descriptor.value());
    331311                // ii. If Desc.[[Writable]] is present and its value is false, then
    332312                // 1. Call the [[Delete]] internal method of map passing P and false as arguments.
    333313                if (descriptor.writablePresent() && !descriptor.writable())
    334                     thisObject->d->deletedArguments[i] = true;
     314                    thisObject->tryDeleteArgument(i);
    335315            }
    336316        }
     
    338318    }
    339319
    340     if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) {
    341         thisObject->putDirect(exec->globalData(), propertyName, jsNumber(thisObject->d->numArguments), DontEnum);
    342         thisObject->d->overrodeLength = true;
    343     } else if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) {
    344         thisObject->putDirect(exec->globalData(), propertyName, thisObject->d->callee.get(), DontEnum);
    345         thisObject->d->overrodeCallee = true;
    346     } else if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
     320    if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
     321        thisObject->putDirect(exec->globalData(), propertyName, jsNumber(thisObject->m_numArguments), DontEnum);
     322        thisObject->m_overrodeLength = true;
     323    } else if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
     324        thisObject->putDirect(exec->globalData(), propertyName, thisObject->m_callee.get(), DontEnum);
     325        thisObject->m_overrodeCallee = true;
     326    } else if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
    347327        thisObject->createStrictModeCallerIfNecessary(exec);
    348328
     
    355335        return;
    356336
    357     if (!d->numArguments)
     337    if (!m_numArguments)
    358338        return;
    359339
    360340    // Must be called for the same call frame from which it was created.
    361     ASSERT(bitwise_cast<WriteBarrier<Unknown>*>(callFrame) == d->registers);
    362    
    363     d->registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[d->numArguments]);
    364     d->registers = d->registerArray.get() + CallFrame::offsetFor(d->numArguments + 1);
     341    ASSERT(bitwise_cast<WriteBarrier<Unknown>*>(callFrame) == m_registers);
     342   
     343    m_registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[m_numArguments]);
     344    m_registers = m_registerArray.get() + CallFrame::offsetFor(m_numArguments + 1);
    365345
    366346    if (!callFrame->isInlineCallFrame()) {
    367         for (size_t i = 0; i < d->numArguments; ++i)
    368             argument(i).set(callFrame->globalData(), this, callFrame->argument(i));
     347        for (size_t i = 0; i < m_numArguments; ++i)
     348            trySetArgument(callFrame->globalData(), i, callFrame->argumentAfterCapture(i));
    369349        return;
    370350    }
     
    374354}
    375355
     356void Arguments::didTearOffActivation(ExecState* exec, JSActivation* activation)
     357{
     358    ASSERT(activation);
     359    if (isTornOff())
     360        return;
     361
     362    if (!m_numArguments)
     363        return;
     364   
     365    tearOff(exec);
     366
     367    SharedSymbolTable* symbolTable = activation->symbolTable();
     368    const SlowArgument* slowArguments = symbolTable->slowArguments();
     369    if (!slowArguments)
     370        return;
     371
     372    ASSERT(symbolTable->captureMode() == SharedSymbolTable::AllOfTheThings);
     373    m_activation.set(exec->globalData(), this, activation);
     374
     375    allocateSlowArguments();
     376    size_t count = min<unsigned>(m_numArguments, symbolTable->parameterCount());
     377    for (size_t i = 0; i < count; ++i)
     378        m_slowArguments[i] = slowArguments[i];
     379}
     380
    376381void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
    377382{
     
    379384        return;
    380385   
    381     if (!d->numArguments)
    382         return;
    383    
    384     d->registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[d->numArguments]);
    385     d->registers = d->registerArray.get() + CallFrame::offsetFor(d->numArguments + 1);
     386    if (!m_numArguments)
     387        return;
     388   
     389    m_registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[m_numArguments]);
     390    m_registers = m_registerArray.get() + CallFrame::offsetFor(m_numArguments + 1);
    386391
    387392    tearOffForInlineCallFrame(
     
    392397void Arguments::tearOffForInlineCallFrame(JSGlobalData& globalData, Register* registers, InlineCallFrame* inlineCallFrame)
    393398{
    394     for (size_t i = 0; i < d->numArguments; ++i) {
     399    for (size_t i = 0; i < m_numArguments; ++i) {
    395400        ValueRecovery& recovery = inlineCallFrame->arguments[i + 1];
    396401        // In the future we'll support displaced recoveries (indicating that the
     
    428433            break;
    429434        }
    430         argument(i).set(globalData, this, value);
     435        trySetArgument(globalData, i, value);
    431436    }
    432437}
  • trunk/Source/JavaScriptCore/runtime/Arguments.h

    r128813 r128832  
    3535namespace JSC {
    3636
    37     struct ArgumentsData {
    38         WTF_MAKE_NONCOPYABLE(ArgumentsData); WTF_MAKE_FAST_ALLOCATED;
    39     public:
    40         ArgumentsData() { }
    41         WriteBarrier<JSActivation> activation;
    42 
    43         unsigned numArguments;
    44 
    45         // We make these full byte booleans to make them easy to test from the JIT,
    46         // and because even if they were single-bit booleans we still wouldn't save
    47         // any space.
    48         bool overrodeLength;
    49         bool overrodeCallee;
    50         bool overrodeCaller;
    51         bool isStrictMode;
    52 
    53         WriteBarrierBase<Unknown>* registers;
    54         OwnArrayPtr<WriteBarrier<Unknown> > registerArray;
    55 
    56         OwnArrayPtr<bool> deletedArguments;
    57 
    58         WriteBarrier<JSFunction> callee;
    59     };
    60 
    6137    class Arguments : public JSDestructibleObject {
     38        friend class JIT;
     39        friend class DFG::SpeculativeJIT;
    6240    public:
    6341        typedef JSDestructibleObject Base;
     
    9674        uint32_t length(ExecState* exec) const
    9775        {
    98             if (UNLIKELY(d->overrodeLength))
     76            if (UNLIKELY(m_overrodeLength))
    9977                return get(exec, exec->propertyNames().length).toUInt32(exec);
    100             return d->numArguments;
     78            return m_numArguments;
    10179        }
    10280       
     
    10482        void tearOff(CallFrame*);
    10583        void tearOff(CallFrame*, InlineCallFrame*);
    106         bool isTornOff() const { return d->registerArray; }
    107         void didTearOffActivation(JSGlobalData& globalData, JSActivation* activation)
    108         {
    109             if (isTornOff())
    110                 return;
    111             d->activation.set(globalData, this, activation);
    112             d->registers = &activation->registerAt(0);
    113         }
     84        bool isTornOff() const { return m_registerArray; }
     85        void didTearOffActivation(ExecState*, JSActivation*);
    11486
    11587        static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
     
    11890        }
    11991       
    120         static ptrdiff_t offsetOfData() { return OBJECT_OFFSETOF(Arguments, d); }
    121 
    12292    protected:
    12393        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
     
    140110        void createStrictModeCalleeIfNecessary(ExecState*);
    141111
     112        bool isArgument(size_t);
     113        bool trySetArgument(JSGlobalData&, size_t argument, JSValue);
     114        JSValue tryGetArgument(size_t argument);
     115        bool isDeletedArgument(size_t);
     116        bool tryDeleteArgument(size_t);
    142117        WriteBarrierBase<Unknown>& argument(size_t);
     118        void allocateSlowArguments();
    143119
    144120        void init(CallFrame*);
    145121
    146         OwnPtr<ArgumentsData> d;
     122        WriteBarrier<JSActivation> m_activation;
     123
     124        unsigned m_numArguments;
     125
     126        // We make these full byte booleans to make them easy to test from the JIT,
     127        // and because even if they were single-bit booleans we still wouldn't save
     128        // any space.
     129        bool m_overrodeLength;
     130        bool m_overrodeCallee;
     131        bool m_overrodeCaller;
     132        bool m_isStrictMode;
     133
     134        WriteBarrierBase<Unknown>* m_registers;
     135        OwnArrayPtr<WriteBarrier<Unknown> > m_registerArray;
     136
     137        OwnArrayPtr<SlowArgument> m_slowArguments;
     138
     139        WriteBarrier<JSFunction> m_callee;
    147140    };
    148141
     
    157150    inline Arguments::Arguments(CallFrame* callFrame)
    158151        : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
    159         , d(adoptPtr(new ArgumentsData))
    160152    {
    161153    }
     
    163155    inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
    164156        : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
    165         , d(adoptPtr(new ArgumentsData))
    166     {
    167     }
    168 
    169     inline WriteBarrierBase<Unknown>& Arguments::argument(size_t i)
    170     {
    171         return d->registers[CallFrame::argumentOffset(i)];
     157    {
     158    }
     159
     160    inline void Arguments::allocateSlowArguments()
     161    {
     162        if (m_slowArguments)
     163            return;
     164        m_slowArguments = adoptArrayPtr(new SlowArgument[m_numArguments]);
     165    }
     166
     167    inline bool Arguments::tryDeleteArgument(size_t argument)
     168    {
     169        if (!isArgument(argument))
     170            return false;
     171        allocateSlowArguments();
     172        m_slowArguments[argument].status = SlowArgument::Deleted;
     173        return true;
     174    }
     175
     176    inline bool Arguments::trySetArgument(JSGlobalData& globalData, size_t argument, JSValue value)
     177    {
     178        if (!isArgument(argument))
     179            return false;
     180        this->argument(argument).set(globalData, this, value);
     181        return true;
     182    }
     183
     184    inline JSValue Arguments::tryGetArgument(size_t argument)
     185    {
     186        if (!isArgument(argument))
     187            return JSValue();
     188        return this->argument(argument).get();
     189    }
     190
     191    inline bool Arguments::isDeletedArgument(size_t argument)
     192    {
     193        if (argument >= m_numArguments)
     194            return false;
     195        if (!m_slowArguments)
     196            return false;
     197        if (m_slowArguments[argument].status != SlowArgument::Deleted)
     198            return false;
     199        return true;
     200    }
     201
     202    inline bool Arguments::isArgument(size_t argument)
     203    {
     204        if (argument >= m_numArguments)
     205            return false;
     206        if (m_slowArguments && m_slowArguments[argument].status == SlowArgument::Deleted)
     207            return false;
     208        return true;
     209    }
     210
     211    inline WriteBarrierBase<Unknown>& Arguments::argument(size_t argument)
     212    {
     213        ASSERT(isArgument(argument));
     214        if (!m_slowArguments || m_slowArguments[argument].status == SlowArgument::Normal)
     215            return m_registers[CallFrame::argumentOffset(argument)];
     216
     217        ASSERT(m_slowArguments[argument].status == SlowArgument::Captured);
     218        if (!m_activation)
     219            return m_registers[m_slowArguments[argument].indexIfCaptured];
     220
     221        return m_activation->registerAt(m_slowArguments[argument].indexIfCaptured);
    172222    }
    173223
     
    178228
    179229        JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
    180         d->numArguments = callFrame->argumentCount();
    181         d->registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers());
    182         d->callee.set(callFrame->globalData(), this, callee);
    183         d->overrodeLength = false;
    184         d->overrodeCallee = false;
    185         d->overrodeCaller = false;
    186         d->isStrictMode = callFrame->codeBlock()->isStrictMode();
     230        m_numArguments = callFrame->argumentCount();
     231        m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers());
     232        m_callee.set(callFrame->globalData(), this, callee);
     233        m_overrodeLength = false;
     234        m_overrodeCallee = false;
     235        m_overrodeCaller = false;
     236        m_isStrictMode = callFrame->codeBlock()->isStrictMode();
    187237
    188238        // The bytecode generator omits op_tear_off_activation in cases of no
    189239        // declared parameters, so we need to tear off immediately.
    190         if (d->isStrictMode || !callee->jsExecutable()->parameterCount())
     240        if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
    191241            tearOff(callFrame);
    192242    }
     
    198248
    199249        JSFunction* callee = inlineCallFrame->callee.get();
    200         d->numArguments = inlineCallFrame->arguments.size() - 1;
    201         d->registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset;
    202         d->callee.set(callFrame->globalData(), this, callee);
    203         d->overrodeLength = false;
    204         d->overrodeCallee = false;
    205         d->overrodeCaller = false;
    206         d->isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
     250        m_numArguments = inlineCallFrame->arguments.size() - 1;
     251        m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset;
     252        m_callee.set(callFrame->globalData(), this, callee);
     253        m_overrodeLength = false;
     254        m_overrodeCallee = false;
     255        m_overrodeCaller = false;
     256        m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
    207257
    208258        // The bytecode generator omits op_tear_off_activation in cases of no
    209259        // declared parameters, so we need to tear off immediately.
    210         if (d->isStrictMode || !callee->jsExecutable()->parameterCount())
     260        if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
    211261            tearOff(callFrame, inlineCallFrame);
    212262    }
  • trunk/Source/JavaScriptCore/runtime/JSActivation.h

    r128400 r128832  
    4949        static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, FunctionExecutable* functionExecutable)
    5050        {
    51             size_t storageSize = JSActivation::storageSize(callFrame, functionExecutable->symbolTable());
     51            size_t storageSize = JSActivation::storageSize(functionExecutable->symbolTable());
    5252            JSActivation* activation = new (
    5353                NotNull,
     
    9999
    100100        static size_t allocationSize(size_t storageSize);
    101         static size_t storageSize(CallFrame*, SharedSymbolTable*);
    102         static int captureStart(CallFrame*, SharedSymbolTable*);
     101        static size_t storageSize(SharedSymbolTable*);
     102        static int captureStart(SharedSymbolTable*);
    103103
    104104        int registerOffset();
     
    143143    }
    144144
    145     inline int JSActivation::captureStart(CallFrame* callFrame, SharedSymbolTable* symbolTable)
     145    inline int JSActivation::captureStart(SharedSymbolTable* symbolTable)
    146146    {
    147147        if (symbolTable->captureMode() == SharedSymbolTable::AllOfTheThings)
    148             return -CallFrame::offsetFor(std::max<size_t>(callFrame->argumentCountIncludingThis(), symbolTable->parameterCountIncludingThis()));
     148            return -CallFrame::offsetFor(symbolTable->parameterCountIncludingThis());
    149149        return symbolTable->captureStart();
    150150    }
    151151
    152     inline size_t JSActivation::storageSize(CallFrame* callFrame, SharedSymbolTable* symbolTable)
    153     {
    154         return symbolTable->captureEnd() - captureStart(callFrame, symbolTable);
     152    inline size_t JSActivation::storageSize(SharedSymbolTable* symbolTable)
     153    {
     154        return symbolTable->captureEnd() - captureStart(symbolTable);
    155155    }
    156156
    157157    inline int JSActivation::registerOffset()
    158158    {
    159         return -captureStart(CallFrame::create(reinterpret_cast<Register*>(m_registers)), symbolTable());
     159        return -captureStart(symbolTable());
    160160    }
    161161
    162162    inline size_t JSActivation::storageSize()
    163163    {
    164         return storageSize(CallFrame::create(reinterpret_cast<Register*>(m_registers)), symbolTable());
     164        return storageSize(symbolTable());
    165165    }
    166166
     
    217217    inline bool JSActivation::isValid(const SymbolTableEntry& entry)
    218218    {
    219         if (entry.getIndex() < captureStart(CallFrame::create(reinterpret_cast<Register*>(m_registers)), symbolTable()))
     219        if (entry.getIndex() < captureStart(symbolTable()))
    220220            return false;
    221221        if (entry.getIndex() >= symbolTable()->captureEnd())
  • trunk/Source/JavaScriptCore/runtime/SymbolTable.h

    r128813 r128832  
    4141    class WatchpointSet;
    4242
     43    struct SlowArgument {
     44        enum Status {
     45            Normal = 0,
     46            Captured = 1,
     47            Deleted = 2
     48        };
     49
     50        SlowArgument()
     51            : status(Normal)
     52            , indexIfCaptured(0)
     53        {
     54        }
     55
     56        Status status;
     57        int indexIfCaptured; // If status is 'Captured', indexIfCaptured is our index in the CallFrame.
     58    };
     59
    4360    static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
    4461
     
    360377        void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }
    361378
     379        int parameterCount() { return m_parameterCountIncludingThis - 1; }
    362380        int parameterCountIncludingThis() { return m_parameterCountIncludingThis; }
    363381        void setParameterCountIncludingThis(int parameterCountIncludingThis) { m_parameterCountIncludingThis = parameterCountIncludingThis; }
     382
     383        // 0 if we don't capture any arguments; parameterCount() in length if we do.
     384        const SlowArgument* slowArguments() { return m_slowArguments.get(); }
     385        void setSlowArguments(PassOwnArrayPtr<SlowArgument> slowArguments) { m_slowArguments = slowArguments; }
    364386
    365387        static JS_EXPORTDATA const ClassInfo s_info;
     
    382404        int m_captureStart;
    383405        int m_captureEnd;
     406
     407        OwnArrayPtr<SlowArgument> m_slowArguments;
    384408    };
    385409   
    386410    HAS_IMMORTAL_STRUCTURE(SharedSymbolTable);
    387  
     411
    388412} // namespace JSC
    389413
Note: See TracChangeset for help on using the changeset viewer.