Ignore:
Timestamp:
Oct 1, 2008, 3:18:50 PM (17 years ago)
Author:
[email protected]
Message:

2008-10-01 Cameron Zwarich <[email protected]>

Reviewed by Darin Adler.

Bug 21123: using "arguments" in a function should not force creation of an activation object
<https://bugs.webkit.org/show_bug.cgi?id=21123>

Make the 'arguments' object not require a JSActivation. We store the
'arguments' object in the OptionalCalleeArguments call frame slot. We
need to be able to get the original 'arguments' object to tear it off
when returning from a function, but 'arguments' may be assigned to in a
number of ways.

Therefore, we use the OptionalCalleeArguments slot when we want to get
the original activation or we know that 'arguments' was not assigned a
different value. When 'arguments' may have been assigned a new value,
we use a new local variable that is initialized with 'arguments'. Since
a function parameter named 'arguments' may overwrite the value of
'arguments', we also need to be careful to look up 'arguments' in the
symbol table, so we get the parameter named 'arguments' instead of the
local variable that we have added for holding the 'arguments' object.

This is a 19.1% win on the V8 Raytrace benchmark using the SunSpider
harness, and a 20.7% win using the V8 harness. This amounts to a 6.5%
total speedup on the V8 benchmark suite using the V8 harness.

JavaScriptCore:

  • VM/CTI.cpp: (JSC::CTI::privateCompileMainPass):
  • VM/CodeBlock.h:
  • VM/CodeGenerator.cpp: (JSC::CodeGenerator::CodeGenerator):
  • VM/Machine.cpp: (JSC::Machine::unwindCallFrame): (JSC::Machine::privateExecute): (JSC::Machine::retrieveArguments): (JSC::Machine::cti_op_init_arguments): (JSC::Machine::cti_op_ret_activation_arguments):
  • VM/Machine.h:
  • VM/RegisterFile.h: (JSC::RegisterFile::):
  • kjs/Arguments.cpp: (JSC::Arguments::mark): (JSC::Arguments::fillArgList): (JSC::Arguments::getOwnPropertySlot): (JSC::Arguments::put):
  • kjs/Arguments.h: (JSC::Arguments::setRegisters): (JSC::Arguments::init): (JSC::Arguments::Arguments): (JSC::Arguments::copyRegisters): (JSC::JSActivation::copyRegisters):
  • kjs/JSActivation.cpp: (JSC::JSActivation::argumentsGetter):
  • kjs/JSActivation.h: (JSC::JSActivation::JSActivationData::JSActivationData):
  • kjs/grammar.y:
  • kjs/nodes.h: (JSC::ScopeNode::setUsesArguments):
  • masm/X86Assembler.h: (JSC::X86Assembler::): (JSC::X86Assembler::orl_mr):

LayoutTests:

  • fast/js/arguments-expected.txt:
  • fast/js/function-dot-arguments-expected.txt:
  • fast/js/resources/arguments.js:
  • fast/js/resources/function-dot-arguments.js:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/JSActivation.cpp

    r37068 r37160  
    156156    JSActivation* thisObj = static_cast<JSActivation*>(slot.slotBase());
    157157
    158     Arguments* arguments = static_cast<Arguments*>(thisObj->d()->registers[RegisterFile::OptionalCalleeArguments].jsValue(exec));
    159     if (!arguments) {
    160         arguments = thisObj->createArgumentsObject(exec);
    161         thisObj->d()->registers[RegisterFile::OptionalCalleeArguments] = arguments;
     158    JSValue* arguments;
     159    if (thisObj->d()->functionBody->usesArguments()) {
     160        PropertySlot slot;
     161        thisObj->symbolTableGet(exec->propertyNames().arguments, slot);
     162        arguments = slot.getValue(exec, exec->propertyNames().arguments);
     163    } else {
     164        arguments = thisObj->d()->registers[RegisterFile::OptionalCalleeArguments].getJSValue();
     165        if (!arguments) {
     166            arguments = new (exec) Arguments(exec, thisObj);
     167            thisObj->d()->registers[RegisterFile::OptionalCalleeArguments] = arguments;
     168        }
     169        ASSERT(arguments->isObject(&Arguments::info));
    162170    }
    163171
     
    173181}
    174182
    175 Arguments* JSActivation::createArgumentsObject(ExecState* exec)
    176 {
    177     JSFunction* function;
    178     Register* argv;
    179     int argc;
    180     int firstParameterIndex;
    181     exec->machine()->getArgumentsData(d()->registers, function, firstParameterIndex, argv, argc);
    182 
    183     return new (exec) Arguments(exec, function, this, firstParameterIndex, argv, argc);
    184 }
    185 
    186183} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.