Changeset 127393 in webkit


Ignore:
Timestamp:
Sep 2, 2012 2:27:23 PM (12 years ago)
Author:
ggaren@apple.com
Message:

Refactored scope chain opcodes to support optimization for named function expressions
https://bugs.webkit.org/show_bug.cgi?id=95658

Reviewed by Sam Weinig.

Renamed

push_scope => push_with_scope
push_new_scope => push_name_scope

to clarify the difference between them.

Changed push_with_scope and push_name_scope not to save the new scope in
a temporary register, since doing so made optimization harder.

(The old behavior was a hold-over from when the scope chain wasn't
a GC object, and wouldn't be marked otherwise. Now, the scope chain is
marked because it is a GC object pointed to by the call frame.)

Changed push_name_scope to accept an operand specifying the attributes
for the named property, instead of assuming DontDelete, because a named
function expression needs ReadOnly|DontDelete.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::highestUsedRegister): Removed this function,
which used to be related to preserving saved scope object temporaries,
because it had no callers.

Location:
trunk/Source/JavaScriptCore
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r127376 r127393  
     12012-09-02  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Refactored scope chain opcodes to support optimization for named function expressions
     4        https://bugs.webkit.org/show_bug.cgi?id=95658
     5
     6        Reviewed by Sam Weinig.
     7
     8        Renamed
     9            push_scope => push_with_scope
     10            push_new_scope => push_name_scope
     11        to clarify the difference between them.
     12
     13        Changed push_with_scope and push_name_scope not to save the new scope in
     14        a temporary register, since doing so made optimization harder.
     15
     16        (The old behavior was a hold-over from when the scope chain wasn't
     17        a GC object, and wouldn't be marked otherwise. Now, the scope chain is
     18        marked because it is a GC object pointed to by the call frame.)
     19
     20        Changed push_name_scope to accept an operand specifying the attributes
     21        for the named property, instead of assuming DontDelete, because a named
     22        function expression needs ReadOnly|DontDelete.
     23
     24        * bytecompiler/BytecodeGenerator.cpp:
     25        (JSC::BytecodeGenerator::highestUsedRegister): Removed this function,
     26        which used to be related to preserving saved scope object temporaries,
     27        because it had no callers.
     28
    1292012-09-01  Geoffrey Garen  <ggaren@apple.com>
    230
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r127374 r127393  
    14801480            break;
    14811481        }
    1482         case op_push_scope: {
    1483             int r0 = (++it)->u.operand;
    1484             dataLog("[%4d] push_scope\t %s", location, registerName(exec, r0).data());
     1482        case op_push_with_scope: {
     1483            int r0 = (++it)->u.operand;
     1484            dataLog("[%4d] push_with_scope\t %s", location, registerName(exec, r0).data());
    14851485            dumpBytecodeCommentAndNewLine(location);
    14861486            break;
     
    14911491            break;
    14921492        }
    1493         case op_push_new_scope: {
    1494             int r0 = (++it)->u.operand;
     1493        case op_push_name_scope: {
    14951494            int id0 = (++it)->u.operand;
    14961495            int r1 = (++it)->u.operand;
    1497             dataLog("[%4d] push_new_scope \t%s, %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
     1496            unsigned attributes = (++it)->u.operand;
     1497            dataLog("[%4d] push_name_scope \t%s, %s, %u", location, idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data(), attributes);
    14981498            dumpBytecodeCommentAndNewLine(location);
    14991499            break;
  • trunk/Source/JavaScriptCore/bytecode/Opcode.h

    r127199 r127393  
    189189        macro(op_next_pname, 7) \
    190190        \
    191         macro(op_push_scope, 2) \
     191        macro(op_push_with_scope, 2) \
    192192        macro(op_pop_scope, 1) \
    193         macro(op_push_new_scope, 4) \
     193        macro(op_push_name_scope, 4) \
    194194        \
    195195        macro(op_catch, 2) \
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r127202 r127393  
    641641    result->setTemporary();
    642642    return result;
    643 }
    644 
    645 RegisterID* BytecodeGenerator::highestUsedRegister()
    646 {
    647     size_t count = m_codeBlock->m_numCalleeRegisters;
    648     while (m_calleeRegisters.size() < count)
    649         newRegister();
    650     return &m_calleeRegisters.last();
    651643}
    652644
     
    20942086}
    20952087
    2096 RegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope)
    2097 {
    2098     ASSERT(scope->isTemporary());
     2088RegisterID* BytecodeGenerator::emitPushWithScope(RegisterID* scope)
     2089{
    20992090    ControlFlowContext context;
    21002091    context.isFinallyBlock = false;
     
    21022093    m_dynamicScopeDepth++;
    21032094
    2104     return emitUnaryNoDstOp(op_push_scope, scope);
     2095    return emitUnaryNoDstOp(op_push_with_scope, scope);
    21052096}
    21062097
     
    24532444}
    24542445
    2455 void BytecodeGenerator::emitPushNewScope(RegisterID* dst, const Identifier& property, RegisterID* value)
     2446void BytecodeGenerator::emitPushNameScope(const Identifier& property, RegisterID* value, unsigned attributes)
    24562447{
    24572448    ControlFlowContext context;
     
    24602451    m_dynamicScopeDepth++;
    24612452
    2462     emitOpcode(op_push_new_scope);
    2463     instructions().append(dst->index());
     2453    emitOpcode(op_push_name_scope);
    24642454    instructions().append(addConstant(property));
    24652455    instructions().append(value->index());
     2456    instructions().append(attributes);
    24662457}
    24672458
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r127202 r127393  
    297297        RegisterID* newTemporary();
    298298
    299         RegisterID* highestUsedRegister();
    300 
    301299        // The same as newTemporary(), but this function returns "suggestion" if
    302300        // "suggestion" is a temporary. This function is helpful in situations
     
    523521        void emitThrowReferenceError(const String& message);
    524522
    525         void emitPushNewScope(RegisterID* dst, const Identifier& property, RegisterID* value);
    526 
    527         RegisterID* emitPushScope(RegisterID* scope);
     523        void emitPushNameScope(const Identifier& property, RegisterID* value, unsigned attributes);
     524
     525        RegisterID* emitPushWithScope(RegisterID* scope);
    528526        void emitPopScope();
    529527
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r127191 r127393  
    17571757{
    17581758    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine(), column());
    1759    
    1760     RefPtr<RegisterID> scope = generator.newTemporary();
    1761     generator.emitNode(scope.get(), m_expr); // scope must be protected until popped
     1759
     1760    RefPtr<RegisterID> scope = generator.emitNode(m_expr);
    17621761    generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
    1763     generator.emitPushScope(scope.get());
     1762    generator.emitPushWithScope(scope.get());
    17641763    RegisterID* result = generator.emitNode(dst, m_statement);
    17651764    generator.emitPopScope();
     
    19971996        }
    19981997       
    1999         generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
     1998        generator.emitPushNameScope(m_exceptionIdent, exceptionRegister.get(), DontDelete);
    20001999        generator.emitNode(dst, m_catchBlock);
    20012000        generator.emitPopScope();
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r127374 r127393  
    14271427   
    14281428#if ENABLE(CLASSIC_INTERPRETER)
    1429 NEVER_INLINE JSScope* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
     1429NEVER_INLINE JSScope* Interpreter::createNameScope(CallFrame* callFrame, const Instruction* vPC)
    14301430{
    1431     int dst = vPC[1].u.operand;
    14321431    CodeBlock* codeBlock = callFrame->codeBlock();
    1433     Identifier& property = codeBlock->identifier(vPC[2].u.operand);
    1434     JSValue value = callFrame->r(vPC[3].u.operand).jsValue();
    1435     JSNameScope* scope = JSNameScope::create(callFrame, property, value, DontDelete);
    1436     callFrame->uncheckedR(dst) = JSValue(scope);
     1432    Identifier& property = codeBlock->identifier(vPC[1].u.operand);
     1433    JSValue value = callFrame->r(vPC[2].u.operand).jsValue();
     1434    unsigned attributes = vPC[3].u.operand;
     1435    JSNameScope* scope = JSNameScope::create(callFrame, property, value, attributes);
    14371436    return scope;
    14381437}
     
    48154814        NEXT_INSTRUCTION();
    48164815    }
    4817     DEFINE_OPCODE(op_push_scope) {
    4818         /* push_scope scope(r)
     4816    DEFINE_OPCODE(op_push_with_scope) {
     4817        /* push_with_scope scope(r)
    48194818
    48204819           Converts register scope to object, and pushes it onto the top
    4821            of the current scope chain.  The contents of the register scope
    4822            are replaced by the result of toObject conversion of the scope.
     4820           of the scope chain.
    48234821        */
    48244822        int scope = vPC[1].u.operand;
     
    48274825        CHECK_FOR_EXCEPTION();
    48284826
    4829         callFrame->uncheckedR(scope) = JSValue(o);
    48304827        callFrame->setScope(JSWithScope::create(callFrame, o));
    48314828
    4832         vPC += OPCODE_LENGTH(op_push_scope);
     4829        vPC += OPCODE_LENGTH(op_push_with_scope);
    48334830        NEXT_INSTRUCTION();
    48344831    }
     
    49284925    goto *(&&skip_new_scope);
    49294926#endif
    4930     DEFINE_OPCODE(op_push_new_scope) {
    4931         /* new_scope dst(r) property(id) value(r)
     4927    DEFINE_OPCODE(op_push_name_scope) {
     4928        /* new_scope property(id) value(r) attributes(unsigned)
    49324929         
    4933            Constructs a new NameScopeObject with property set to value.  That scope
    4934            object is then pushed onto the ScopeChain.  The scope object is then stored
    4935            in dst for GC.
     4930           Constructs a name scope of the form { property<attributes>: value },
     4931           and pushes it onto the scope chain.
    49364932         */
    4937         callFrame->setScope(createExceptionScope(callFrame, vPC));
    4938 
    4939         vPC += OPCODE_LENGTH(op_push_new_scope);
     4933        callFrame->setScope(createNameScope(callFrame, vPC));
     4934
     4935        vPC += OPCODE_LENGTH(op_push_name_scope);
    49404936        NEXT_INSTRUCTION();
    49414937    }
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r126926 r127393  
    319319        DEFINE_OP(op_profile_did_call)
    320320        DEFINE_OP(op_profile_will_call)
    321         DEFINE_OP(op_push_new_scope)
    322         DEFINE_OP(op_push_scope)
     321        DEFINE_OP(op_push_name_scope)
     322        DEFINE_OP(op_push_with_scope)
    323323        case op_put_by_id_out_of_line:
    324324        case op_put_by_id_transition_direct:
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r127202 r127393  
    672672        void emit_op_profile_did_call(Instruction*);
    673673        void emit_op_profile_will_call(Instruction*);
    674         void emit_op_push_new_scope(Instruction*);
    675         void emit_op_push_scope(Instruction*);
     674        void emit_op_push_name_scope(Instruction*);
     675        void emit_op_push_with_scope(Instruction*);
    676676        void emit_op_put_by_id(Instruction*);
    677677        void emit_op_put_by_index(Instruction*);
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r127345 r127393  
    10041004}
    10051005
    1006 void JIT::emit_op_push_scope(Instruction* currentInstruction)
    1007 {
    1008     JITStubCall stubCall(this, cti_op_push_scope);
     1006void JIT::emit_op_push_with_scope(Instruction* currentInstruction)
     1007{
     1008    JITStubCall stubCall(this, cti_op_push_with_scope);
    10091009    stubCall.addArgument(currentInstruction[1].u.operand, regT2);
    10101010    stubCall.call(currentInstruction[1].u.operand);
     
    10731073}
    10741074
    1075 void JIT::emit_op_push_new_scope(Instruction* currentInstruction)
    1076 {
    1077     JITStubCall stubCall(this, cti_op_push_new_scope);
    1078     stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
    1079     stubCall.addArgument(currentInstruction[3].u.operand, regT2);
    1080     stubCall.call(currentInstruction[1].u.operand);
     1075void JIT::emit_op_push_name_scope(Instruction* currentInstruction)
     1076{
     1077    JITStubCall stubCall(this, cti_op_push_name_scope);
     1078    stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[1].u.operand)));
     1079    stubCall.addArgument(currentInstruction[2].u.operand, regT2);
     1080    stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
     1081    stubCall.call();
    10811082}
    10821083
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r127202 r127393  
    13591359}
    13601360
    1361 void JIT::emit_op_push_scope(Instruction* currentInstruction)
    1362 {
    1363     JITStubCall stubCall(this, cti_op_push_scope);
     1361void JIT::emit_op_push_with_scope(Instruction* currentInstruction)
     1362{
     1363    JITStubCall stubCall(this, cti_op_push_with_scope);
    13641364    stubCall.addArgument(currentInstruction[1].u.operand);
    13651365    stubCall.call(currentInstruction[1].u.operand);
     
    13981398}
    13991399
    1400 void JIT::emit_op_push_new_scope(Instruction* currentInstruction)
    1401 {
    1402     JITStubCall stubCall(this, cti_op_push_new_scope);
    1403     stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
    1404     stubCall.addArgument(currentInstruction[3].u.operand);
    1405     stubCall.call(currentInstruction[1].u.operand);
     1400void JIT::emit_op_push_name_scope(Instruction* currentInstruction)
     1401{
     1402    JITStubCall stubCall(this, cti_op_push_name_scope);
     1403    stubCall.addArgument(TrustedImmPtr(&m_codeBlock->identifier(currentInstruction[1].u.operand)));
     1404    stubCall.addArgument(currentInstruction[2].u.operand);
     1405    stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand));
     1406    stubCall.call();
    14061407}
    14071408
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r127349 r127393  
    31423142}
    31433143
    3144 DEFINE_STUB_FUNCTION(JSObject*, op_push_scope)
     3144DEFINE_STUB_FUNCTION(JSObject*, op_push_with_scope)
    31453145{
    31463146    STUB_INIT_STACK_FRAME(stackFrame);
     
    32593259}
    32603260
    3261 DEFINE_STUB_FUNCTION(JSObject*, op_push_new_scope)
    3262 {
    3263     STUB_INIT_STACK_FRAME(stackFrame);
    3264 
    3265     JSNameScope* scope = JSNameScope::create(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].jsValue(), DontDelete);
     3261DEFINE_STUB_FUNCTION(void, op_push_name_scope)
     3262{
     3263    STUB_INIT_STACK_FRAME(stackFrame);
     3264
     3265    JSNameScope* scope = JSNameScope::create(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].jsValue(), stackFrame.args[2].int32());
    32663266
    32673267    CallFrame* callFrame = stackFrame.callFrame;
    32683268    callFrame->setScope(scope);
    3269     return scope;
    32703269}
    32713270
  • trunk/Source/JavaScriptCore/jit/JITStubs.h

    r127374 r127393  
    418418    JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS_DECLARATION) WTF_INTERNAL;
    419419    JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS_DECLARATION) WTF_INTERNAL;
    420     JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL;
    421     JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL;
     420    void JIT_STUB cti_op_push_name_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL;
     421    JSObject* JIT_STUB cti_op_push_with_scope(STUB_ARGS_DECLARATION) WTF_INTERNAL;
    422422    JSObject* JIT_STUB cti_op_put_by_id_transition_realloc(STUB_ARGS_DECLARATION) WTF_INTERNAL;
    423423    JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS_DECLARATION) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r127349 r127393  
    15311531}
    15321532
    1533 LLINT_SLOW_PATH_DECL(slow_path_push_scope)
    1534 {
    1535     LLINT_BEGIN();
    1536     JSValue v = LLINT_OP(1).jsValue();
     1533LLINT_SLOW_PATH_DECL(slow_path_push_with_scope)
     1534{
     1535    LLINT_BEGIN();
     1536    JSValue v = LLINT_OP_C(1).jsValue();
    15371537    JSObject* o = v.toObject(exec);
    15381538    LLINT_CHECK_EXCEPTION();
    15391539   
    1540     LLINT_OP(1) = o;
    15411540    exec->setScope(JSWithScope::create(exec, o));
    15421541   
     
    15511550}
    15521551
    1553 LLINT_SLOW_PATH_DECL(slow_path_push_new_scope)
     1552LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
    15541553{
    15551554    LLINT_BEGIN();
    15561555    CodeBlock* codeBlock = exec->codeBlock();
    1557     JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[2].u.operand), LLINT_OP(3).jsValue(), DontDelete);
     1556    JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[1].u.operand), LLINT_OP(2).jsValue(), pc[3].u.operand);
    15581557    exec->setScope(scope);
    1559     LLINT_RETURN(scope);
     1558    LLINT_END();
    15601559}
    15611560
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h

    r127333 r127393  
    203203LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_pnames);
    204204LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_next_pname);
    205 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_push_scope);
     205LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_push_with_scope);
    206206LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_pop_scope);
    207 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_push_new_scope);
     207LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_push_name_scope);
    208208LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw);
    209209LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_throw_reference_error);
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r127374 r127393  
    774774
    775775
    776 _llint_op_push_scope:
    777     traceExecution()
    778     callSlowPath(_llint_slow_path_push_scope)
     776_llint_op_push_with_scope:
     777    traceExecution()
     778    callSlowPath(_llint_slow_path_push_with_scope)
    779779    dispatch(2)
    780780
     
    786786
    787787
    788 _llint_op_push_new_scope:
    789     traceExecution()
    790     callSlowPath(_llint_slow_path_push_new_scope)
     788_llint_op_push_name_scope:
     789    traceExecution()
     790    callSlowPath(_llint_slow_path_push_name_scope)
    791791    dispatch(4)
    792792
Note: See TracChangeset for help on using the changeset viewer.