Ignore:
Timestamp:
Sep 12, 2013, 4:07:36 PM (12 years ago)
Author:
[email protected]
Message:

Source/JavaScriptCore: Web Inspector shouldn't artificially allocate the arguments object in functions that don't use it
https://bugs.webkit.org/show_bug.cgi?id=121206
<rdar://problem/6911886>

Reviewed by Joseph Pecoraro.

This is a step toward better tools, and a 23% speedup in a simple
JavaScript benchmark run with the Web Inspector open.

We want the Web Inspector to be fast, and we want it to produce reliable
CPU and memory profiles. We can't do that if just opening the Web Inspector
incurs huge CPU/memory penalties like the arguments object.

Also, since use of the 'arguments' identifier is an API for allocating
an object, I think it's good for the UI to let developers know when
they've invoked that API and when they haven't.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator): No need to allocate the
arguments object artificially for the debugger's sake. The activation
object no longer assumes that the stack frame is laid out for one.

(Long-term, this code will move out of the activation object, into a
special object for interfacing with the debugger.)

  • runtime/JSActivation.cpp:

(JSC::JSActivation::getOwnNonIndexPropertyNames):
(JSC::JSActivation::getOwnPropertySlot): Don't advertise or provide an
arguments object if the user function didn't include one. The bytecode
generator will not have laid out the stack frame to support one.

(Eventually, we do want the Web Inspector to see an arguments
object in scope in the console. That's a one-line change in JSActivation,
but it's blocked by https://bugs.webkit.org/show_bug.cgi?id=121208.)

(JSC::JSActivation::argumentsGetter):

  • runtime/JSActivation.h: Removed this obsolete performance

work-around. C++ property access to an activation object is no longer
hot.

LayoutTests: Web Inspector shouldn't artificially allocate the arguments object in functions that don't use it
https://bugs.webkit.org/show_bug.cgi?id=121206

Reviewed by Joseph Pecoraro.
<rdar://problem/6911886>

  • inspector/debugger/debugger-expand-scope-expected.txt: Updated these

results to reflect the fact that it's correct to exclude the 'arguments'
identifier from function scopes that don't use it.

  • inspector/debugger/debugger-expand-scope.html: Edited this test to

include one frame that uses the 'arguments' identifier and one frame
that doesn't, so we test both cases.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSActivation.cpp

    r154459 r155657  
    111111    JSActivation* thisObject = jsCast<JSActivation*>(object);
    112112
    113     if (mode == IncludeDontEnumProperties && !thisObject->isTornOff())
     113    CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(thisObject->m_registers));
     114    if (mode == IncludeDontEnumProperties && !thisObject->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval()))
    114115        propertyNames.add(exec->propertyNames().arguments);
    115116
     
    157158    if (propertyName == exec->propertyNames().arguments) {
    158159        // Defend against the inspector asking for the arguments object after it has been optimized out.
    159         if (!thisObject->isTornOff()) {
    160             slot.setCustom(thisObject, DontEnum, thisObject->getArgumentsGetter());
     160        CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(thisObject->m_registers));
     161        if (!thisObject->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval())) {
     162            slot.setCustom(thisObject, DontEnum, argumentsGetter);
    161163            return true;
    162164        }
     
    212214{
    213215    JSActivation* activation = jsCast<JSActivation*>(slotBase);
    214     if (activation->isTornOff())
     216    CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->m_registers));
     217    ASSERT(!activation->isTornOff() && (callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval()));
     218    if (activation->isTornOff() || !(callFrame->codeBlock()->usesArguments() || callFrame->codeBlock()->usesEval()))
    215219        return jsUndefined();
    216220
    217     CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->m_registers));
    218221    int argumentsRegister = callFrame->codeBlock()->argumentsRegister();
    219222    if (JSValue arguments = callFrame->uncheckedR(argumentsRegister).jsValue())
     
    229232}
    230233
    231 // These two functions serve the purpose of isolating the common case from a
    232 // PIC branch.
    233 
    234 PropertySlot::GetValueFunc JSActivation::getArgumentsGetter()
    235 {
    236     return argumentsGetter;
    237 }
    238 
    239234} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.