Changeset 176479 in webkit


Ignore:
Timestamp:
Nov 21, 2014 3:41:26 PM (9 years ago)
Author:
msaboff@apple.com
Message:

Allocate local ScopeChain register
https://bugs.webkit.org/show_bug.cgi?id=138793

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

Now we allocate the scope register as a local. The allocated register is stored in the
CodeBlock for use by other components. Update the DFG to work with a local scope register.
Changed usage of JSStack::ScopeChain access to the CallFrame header to use the allocated
local register.

  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
Updated to properly represent the operand inputs and bytecode result.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::CodeBlock):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::setScopeRegister):
(JSC::CodeBlock::scopeRegister):

  • bytecode/UnlinkedCodeBlock.h:

(JSC::UnlinkedCodeBlock::setScopeRegister):
(JSC::UnlinkedCodeBlock::scopeRegister):
Added scope register member and accessors.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::allocateAndEmitScope):

  • bytecompiler/BytecodeGenerator.h:

(JSC::BytecodeGenerator::scopeRegister):
Change m_scopeRegister to an allocated register. Added allocateAndEmitScope helper to
allocate the scope register, set the CodeBlock with its value and emit op_get_scope.

  • debugger/DebuggerCallFrame.cpp:

(JSC::DebuggerCallFrame::scope): Changed to access the scope using the new convention.

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::get):
(JSC::DFG::ByteCodeParser::flush):
(JSC::DFG::ByteCodeParser::inlineCall):
(JSC::DFG::ByteCodeParser::parseBlock):
Changed op_create_lexical_environment to set the scope VirtualRegister operand.
Filled out op_get_scope processing to emit a GetScope node putting the result in
the scope VirtualRegister result operand.
Added Phantoms where appropriate to keep the Scope register alive in places where
it use is optimized away, but where the baseline JIT would need to use its value.
Eliminated uses of JSStack::ScopeChain.

  • dfg/DFGStackLayoutPhase.cpp:

(JSC::DFG::StackLayoutPhase::run):
Make sure that the scope register stack location is allocated using the same place
that the codeBlock expects.

  • dfg/DFGStrengthReductionPhase.cpp:

(JSC::DFG::StrengthReductionPhase::handleNode):
Allow strength reduction of Flush to skip of GetScope nodes looking for a prior
corresponding SetLocal.

  • interpreter/CallFrame.h:

(JSC::ExecState::scope):
(JSC::ExecState::setScope):
Added new scope() and setScope() helpers that take a VirtualRegister offset.

  • interpreter/Interpreter.cpp:

(JSC::eval):
Changed eval() to get the scope from the caller's scope register instead of from the
temporary frame created for eval.

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::unwind):
Changed unwind() to manipulate the scope n the allocated register instead of from the
call frame slot.

  • interpreter/StackVisitor.cpp:

(JSC::StackVisitor::readNonInlinedFrame):
(JSC::StackVisitor::readInlinedFrame):

  • interpreter/StackVisitor.h:

(JSC::StackVisitor::Frame::callee):
(JSC::StackVisitor::Frame::scope): Deleted.
Eliminated the scope member as it needed to change and no StackVisitor users use it.

  • jit/JITOperations.cpp:

(JSC::operationPushNameScope):
(JSC::operationPushWithScope):

  • runtime/JSNameScope.h:

(JSC::JSNameScope::create):

  • runtime/JSWithScope.h:

(JSC::JSWithScope::create): Deleted.

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):
Deleted JSNameScope::create() and JSWithScope::create() flavors tht used the ScopeChain slot
in the CallFrame header. Changed the only user of these function, op_push_name_scope and
op_push_with_scope helpers, to use the remaining create variants that require explicit scope.
Those operations get the scope from the register pointed to by their scope operands.

  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:

Changed resolveScope to use the allocated register.

LayoutTests:

New test that sets a breakpoint in a callee of a DFG caller. While stopped in the
breakpoint, it modifies a global via the scope chain of the DFG caller as well as
a local of the DFG caller.

  • inspector-protocol/debugger/resources/breakpoint.js:

(notInlineable3):
(dfgWithoutInline3):

  • inspector-protocol/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local-expected.txt: Added.
  • inspector-protocol/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local.html: Added.
Location:
trunk
Files:
2 added
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r176473 r176479  
     12014-11-21  Michael Saboff  <msaboff@apple.com>
     2
     3        Allocate local ScopeChain register
     4        https://bugs.webkit.org/show_bug.cgi?id=138793
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        New test that sets a breakpoint in a callee of a DFG caller.  While stopped in the
     9        breakpoint, it modifies a global via the scope chain of the DFG caller as well as
     10        a local of the DFG caller.
     11
     12        * inspector-protocol/debugger/resources/breakpoint.js:
     13        (notInlineable3):
     14        (dfgWithoutInline3):
     15        * inspector-protocol/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local-expected.txt: Added.
     16        * inspector-protocol/debugger/setBreakpoint-dfg-callee-and-examine-dfg-local.html: Added.
     17
    1182014-11-21  Glenn Adams  <glenn@skynav.com> and Myles C. Maxfield  <mmaxfield@apple.com>
    219
  • trunk/LayoutTests/inspector-protocol/debugger/resources/breakpoint.js

    r165008 r176479  
    9292}
    9393
     94function notInlineable3(x)
     95{
     96    var func = new Function("return x + 100;");
     97    if (x == 1999)
     98        breakpointBasic();
     99    return x + 3;
     100}
     101
     102var globalVal3 = 0;
     103
     104function dfgWithoutInline3()
     105{
     106    globalVal3 = 0;
     107    var i;
     108    var result = 0;
     109    var localVal3 = 0;
     110    for (i = 0; i < 2000; i++)
     111        result += notInlineable3(i);
     112    if (globalVal3)
     113        result = globalVal3 + localVal3;
     114    log("result: " + result);
     115}
  • trunk/Source/JavaScriptCore/ChangeLog

    r176446 r176479  
     12014-11-21  Michael Saboff  <msaboff@apple.com>
     2
     3        Allocate local ScopeChain register
     4        https://bugs.webkit.org/show_bug.cgi?id=138793
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Now we allocate the scope register as a local.  The allocated register is stored in the
     9        CodeBlock for use by other components.  Update the DFG to work with a local scope register.
     10        Changed usage of JSStack::ScopeChain access to the CallFrame header to use the allocated
     11        local register.
     12
     13        * bytecode/BytecodeUseDef.h:
     14        (JSC::computeUsesForBytecodeOffset):
     15        (JSC::computeDefsForBytecodeOffset):
     16        Updated to properly represent the operand inputs and bytecode result.
     17
     18        * bytecode/CodeBlock.cpp:
     19        (JSC::CodeBlock::CodeBlock):
     20        * bytecode/CodeBlock.h:
     21        (JSC::CodeBlock::setScopeRegister):
     22        (JSC::CodeBlock::scopeRegister):
     23        * bytecode/UnlinkedCodeBlock.h:
     24        (JSC::UnlinkedCodeBlock::setScopeRegister):
     25        (JSC::UnlinkedCodeBlock::scopeRegister):
     26        Added scope register member and accessors.
     27
     28        * bytecompiler/BytecodeGenerator.cpp:
     29        (JSC::BytecodeGenerator::BytecodeGenerator):
     30        (JSC::BytecodeGenerator::allocateAndEmitScope):
     31        * bytecompiler/BytecodeGenerator.h:
     32        (JSC::BytecodeGenerator::scopeRegister):
     33        Change m_scopeRegister to an allocated register.  Added allocateAndEmitScope helper to
     34        allocate the scope register, set the CodeBlock with its value and emit op_get_scope.
     35
     36        * debugger/DebuggerCallFrame.cpp:
     37        (JSC::DebuggerCallFrame::scope): Changed to access the scope using the new convention.
     38
     39        * dfg/DFGByteCodeParser.cpp:
     40        (JSC::DFG::ByteCodeParser::get):
     41        (JSC::DFG::ByteCodeParser::flush):
     42        (JSC::DFG::ByteCodeParser::inlineCall):
     43        (JSC::DFG::ByteCodeParser::parseBlock):
     44        Changed op_create_lexical_environment to set the scope VirtualRegister operand.
     45        Filled out op_get_scope processing to emit a GetScope node putting the result in
     46        the scope VirtualRegister result operand.
     47        Added Phantoms where appropriate to keep the Scope register alive in places where
     48        it use is optimized away, but where the baseline JIT would need to use its value.
     49        Eliminated uses of JSStack::ScopeChain.
     50
     51        * dfg/DFGStackLayoutPhase.cpp:
     52        (JSC::DFG::StackLayoutPhase::run):
     53        Make sure that the scope register stack location is allocated using the same place
     54        that the codeBlock expects.
     55
     56        * dfg/DFGStrengthReductionPhase.cpp:
     57        (JSC::DFG::StrengthReductionPhase::handleNode):
     58        Allow strength reduction of Flush to skip of GetScope nodes looking for a prior
     59        corresponding SetLocal.
     60
     61        * interpreter/CallFrame.h:
     62        (JSC::ExecState::scope):
     63        (JSC::ExecState::setScope):
     64        Added new scope() and setScope() helpers that take a VirtualRegister offset.
     65
     66        * interpreter/Interpreter.cpp:
     67        (JSC::eval):
     68        Changed eval() to get the scope from the caller's scope register instead of from the
     69        temporary frame created for eval.
     70
     71        * interpreter/Interpreter.cpp:
     72        (JSC::Interpreter::unwind):
     73        Changed unwind() to manipulate the scope n the allocated register instead of from the
     74        call frame slot.
     75
     76        * interpreter/StackVisitor.cpp:
     77        (JSC::StackVisitor::readNonInlinedFrame):
     78        (JSC::StackVisitor::readInlinedFrame):
     79        * interpreter/StackVisitor.h:
     80        (JSC::StackVisitor::Frame::callee):
     81        (JSC::StackVisitor::Frame::scope): Deleted.
     82        Eliminated the scope member as it needed to change and no StackVisitor users use it.
     83
     84        * jit/JITOperations.cpp:
     85        (JSC::operationPushNameScope):
     86        (JSC::operationPushWithScope):
     87        * runtime/JSNameScope.h:
     88        (JSC::JSNameScope::create):
     89        * runtime/JSWithScope.h:
     90        (JSC::JSWithScope::create): Deleted.
     91        * llint/LLIntSlowPaths.cpp:
     92        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     93        Deleted JSNameScope::create() and JSWithScope::create() flavors tht used the ScopeChain slot
     94        in the CallFrame header.  Changed the only user of these function, op_push_name_scope and
     95        op_push_with_scope helpers, to use the remaining create variants that require explicit scope. 
     96        Those operations get the scope from the register pointed to by their scope operands.
     97
     98        * llint/LowLevelInterpreter32_64.asm:
     99        * llint/LowLevelInterpreter64.asm:
     100        Changed resolveScope to use the allocated register.
     101
    11022014-11-21  Csaba Osztrogonác  <ossy@webkit.org>
    2103
  • trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h

    r175508 r176479  
    4545    case op_throw_static_error:
    4646    case op_debug:
    47     case op_resolve_scope:
    48     case op_pop_scope:
    4947    case op_jneq_ptr:
    50     case op_new_func_exp:
    5148    case op_loop_hint:
    5249    case op_jmp:
     
    5855    case op_touch_entry:
    5956        return;
    60     case op_new_func:
    61     case op_create_lexical_environment:
     57    case op_create_lexical_environment:
    6258    case op_get_scope:
    6359    case op_create_arguments:
    6460    case op_to_this:
     61    case op_pop_scope:
    6562    case op_profile_will_call:
    6663    case op_profile_did_call:
    6764    case op_profile_type:
    6865    case op_throw:
    69     case op_push_with_scope:
    7066    case op_end:
    7167    case op_ret:
     
    7975        return;
    8076    }
     77    case op_new_func:
    8178    case op_ret_object_or_this:
    8279    case op_jlesseq:
     
    118115    }
    119116    case op_get_enumerable_length:
     117    case op_new_func_exp:
    120118    case op_to_index_string:
    121119    case op_init_global_const_nop:
    122120    case op_init_global_const:
    123121    case op_push_name_scope:
     122    case op_push_with_scope:
     123    case op_resolve_scope:
    124124    case op_get_from_scope:
    125125    case op_to_primitive:
     
    245245    case op_init_global_const:
    246246    case op_init_global_const_nop:
    247     case op_push_name_scope:
    248     case op_push_with_scope:
    249247    case op_put_to_scope:
    250     case op_pop_scope:
    251248    case op_end:
    252249    case op_profile_will_call:
     
    302299    case op_get_structure_property_enumerator:
    303300    case op_next_enumerator_pname:
     301    case op_pop_scope:
     302    case op_push_name_scope:
     303    case op_push_with_scope:
    304304    case op_resolve_scope:
    305305    case op_strcat:
     
    366366    case op_get_callee:
    367367    case op_init_lazy_reg:
    368     case op_create_lexical_environment:
    369368    case op_get_scope:
    370369    case op_create_arguments:
     
    375374        return;
    376375    }
     376    case op_create_lexical_environment: {
     377        functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
     378        functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
     379        return;
     380    }
    377381    case op_enter: {
    378382        for (unsigned i = codeBlock->m_numVars; i--;)
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r176109 r176479  
    16311631    , m_instructions(other.m_instructions)
    16321632    , m_thisRegister(other.m_thisRegister)
     1633    , m_scopeRegister(other.m_scopeRegister)
    16331634    , m_argumentsRegister(other.m_argumentsRegister)
    16341635    , m_lexicalEnvironmentRegister(other.m_lexicalEnvironmentRegister)
     
    16901691    , m_vm(unlinkedCodeBlock->vm())
    16911692    , m_thisRegister(unlinkedCodeBlock->thisRegister())
     1693    , m_scopeRegister(unlinkedCodeBlock->scopeRegister())
    16921694    , m_argumentsRegister(unlinkedCodeBlock->argumentsRegister())
    16931695    , m_lexicalEnvironmentRegister(unlinkedCodeBlock->activationRegister())
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r175691 r176479  
    324324    bool usesEval() const { return m_unlinkedCode->usesEval(); }
    325325
     326    void setScopeRegister(VirtualRegister scopeRegister)
     327    {
     328        m_scopeRegister = scopeRegister;
     329    }
     330
     331    VirtualRegister scopeRegister() const
     332    {
     333        ASSERT(m_scopeRegister.isValid());
     334        return m_scopeRegister;
     335    }
     336
    326337    void setArgumentsRegister(VirtualRegister argumentsRegister)
    327338    {
     
    341352        return argumentsRegister();
    342353    }
     354
    343355    void setActivationRegister(VirtualRegister activationRegister)
    344356    {
     
    10331045    WriteBarrier<SymbolTable> m_symbolTable;
    10341046    VirtualRegister m_thisRegister;
     1047    VirtualRegister m_scopeRegister;
    10351048    VirtualRegister m_argumentsRegister;
    10361049    VirtualRegister m_lexicalEnvironmentRegister;
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h

    r173517 r176479  
    283283    // Special registers
    284284    void setThisRegister(VirtualRegister thisRegister) { m_thisRegister = thisRegister; }
     285    void setScopeRegister(VirtualRegister scopeRegister) { m_scopeRegister = scopeRegister; }
    285286    void setActivationRegister(VirtualRegister activationRegister) { m_lexicalEnvironmentRegister = activationRegister; }
    286287
     
    430431
    431432    VirtualRegister thisRegister() const { return m_thisRegister; }
     433    VirtualRegister scopeRegister() const { return m_scopeRegister; }
    432434    VirtualRegister activationRegister() const { return m_lexicalEnvironmentRegister; }
    433435    bool hasActivationRegister() const { return m_lexicalEnvironmentRegister.isValid(); }
     
    521523    VirtualRegister m_thisRegister;
    522524    VirtualRegister m_argumentsRegister;
     525    VirtualRegister m_scopeRegister;
    523526    VirtualRegister m_lexicalEnvironmentRegister;
    524527    VirtualRegister m_globalObjectRegister;
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r176109 r176479  
    165165    , m_codeBlock(vm, codeBlock)
    166166    , m_thisRegister(CallFrame::thisArgumentOffset())
    167     , m_scopeRegister(JSStack::ScopeChain)
     167    , m_scopeRegister(0)
    168168    , m_lexicalEnvironmentRegister(0)
    169169    , m_emptyValueRegister(0)
     
    191191    emitOpcode(op_enter);
    192192
    193     emitGetScope();
     193    allocateAndEmitScope();
    194194
    195195    const VarStack& varStack = programNode->varStack();
     
    213213    , m_scopeNode(functionBody)
    214214    , m_codeBlock(vm, codeBlock)
    215     , m_scopeRegister(JSStack::ScopeChain)
     215    , m_scopeRegister(0)
    216216    , m_lexicalEnvironmentRegister(0)
    217217    , m_emptyValueRegister(0)
     
    252252    emitOpcode(op_enter);
    253253
    254     emitGetScope();
     254    allocateAndEmitScope();
    255255
    256256    if (m_codeBlock->needsFullScopeChain() || m_shouldEmitDebugHooks) {
     
    453453    , m_codeBlock(vm, codeBlock)
    454454    , m_thisRegister(CallFrame::thisArgumentOffset())
    455     , m_scopeRegister(JSStack::ScopeChain)
     455    , m_scopeRegister(0)
    456456    , m_lexicalEnvironmentRegister(0)
    457457    , m_emptyValueRegister(0)
     
    480480    emitOpcode(op_enter);
    481481
    482     emitGetScope();
     482    allocateAndEmitScope();
    483483
    484484    const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
     
    22172217    }
    22182218    return LabelScopePtr::null();
     2219}
     2220
     2221void BytecodeGenerator::allocateAndEmitScope()
     2222{
     2223    m_scopeRegister = addVar();
     2224    m_scopeRegister->ref();
     2225    m_codeBlock->setScopeRegister(scopeRegister()->virtualRegister());
     2226    emitGetScope();
    22192227}
    22202228
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r175508 r176479  
    291291        RegisterID* thisRegister() { return &m_thisRegister; }
    292292       
    293         RegisterID* scopeRegister() { return &m_scopeRegister; }
     293        RegisterID* scopeRegister() { return m_scopeRegister; }
    294294
    295295        // Returns the next available temporary register. Registers returned by
     
    595595        ALWAYS_INLINE void rewindUnaryOp();
    596596
     597        void allocateAndEmitScope();
    597598        void emitComplexPopScopes(RegisterID*, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
    598599
     
    755756        RegisterID m_thisRegister;
    756757        RegisterID m_calleeRegister;
    757         RegisterID m_scopeRegister;
     758        RegisterID* m_scopeRegister;
    758759        RegisterID* m_lexicalEnvironmentRegister;
    759760        RegisterID* m_emptyValueRegister;
  • trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp

    r173896 r176479  
    144144    if (!m_scope) {
    145145        VM& vm = m_callFrame->vm();
     146        JSScope* scope;
    146147        CodeBlock* codeBlock = m_callFrame->codeBlock();
    147         if (codeBlock && codeBlock->needsActivation() && !m_callFrame->hasActivation()) {
    148             ASSERT(!m_callFrame->scope()->isWithScope());
    149             JSLexicalEnvironment* lexicalEnvironment = JSLexicalEnvironment::create(vm, m_callFrame, codeBlock);
    150             m_callFrame->setActivation(lexicalEnvironment);
    151             m_callFrame->setScope(lexicalEnvironment);
    152         }
    153 
    154         m_scope.set(vm, DebuggerScope::create(vm, m_callFrame->scope()));
     148        if (codeBlock && codeBlock->scopeRegister().isValid())
     149            scope = m_callFrame->scope(codeBlock->scopeRegister().offset());
     150        else
     151            scope = jsCast<JSCallee*>(m_callFrame->callee())->scope();
     152
     153        m_scope.set(vm, DebuggerScope::create(vm, scope));
    155154    }
    156155    return m_scope.get();
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r176109 r176479  
    263263                if (operand.offset() == JSStack::Callee)
    264264                    return weakJSConstant(callee);
    265                 if (operand.offset() == JSStack::ScopeChain)
     265                if (operand == m_inlineStackTop->m_codeBlock->scopeRegister())
    266266                    return weakJSConstant(callee->scope());
    267267            }
    268268        } else if (operand.offset() == JSStack::Callee)
    269269            return addToGraph(GetCallee);
    270         else if (operand.offset() == JSStack::ScopeChain)
    271             return addToGraph(GetMyScope);
    272270       
    273271        return getDirect(m_inlineStackTop->remapOperand(operand));
     
    527525        if (InlineCallFrame* inlineCallFrame = inlineStackEntry->m_inlineCallFrame) {
    528526            numArguments = inlineCallFrame->arguments.size();
    529             if (inlineCallFrame->isClosureCall) {
     527            if (inlineCallFrame->isClosureCall)
    530528                flushDirect(inlineStackEntry->remapOperand(VirtualRegister(JSStack::Callee)));
    531                 flushDirect(inlineStackEntry->remapOperand(VirtualRegister(JSStack::ScopeChain)));
    532             }
    533529        } else
    534530            numArguments = inlineStackEntry->m_codeBlock->numParameters();
     
    12631259        VariableAccessData* calleeVariable =
    12641260            set(VirtualRegister(JSStack::Callee), callTargetNode, ImmediateNakedSet)->variableAccessData();
    1265         VariableAccessData* scopeVariable =
    1266             set(VirtualRegister(JSStack::ScopeChain), addToGraph(GetScope, callTargetNode), ImmediateNakedSet)->variableAccessData();
    12671261       
    12681262        calleeVariable->mergeShouldNeverUnbox(true);
    1269         scopeVariable->mergeShouldNeverUnbox(true);
    12701263       
    12711264        inlineVariableData.calleeVariable = calleeVariable;
     
    31963189                    && lexicalEnvironment->symbolTable()->m_functionEnteredOnce.isStillValid()) {
    31973190                    addToGraph(FunctionReentryWatchpoint, OpInfo(lexicalEnvironment->symbolTable()));
     3191                    addToGraph(Phantom, getDirect(m_inlineStackTop->remapOperand(VirtualRegister(currentInstruction[2].u.operand))));
    31983192                    set(VirtualRegister(dst), weakJSConstant(lexicalEnvironment));
    31993193                    break;
    32003194                }
    32013195                set(VirtualRegister(dst), getScope(VirtualRegister(currentInstruction[2].u.operand), depth));
     3196                if (inlineCallFrame())
     3197                    addToGraph(Phantom, getDirect(m_inlineStackTop->remapOperand(VirtualRegister(currentInstruction[2].u.operand))));
    32023198                break;
    32033199            }
     
    33963392           
    33973393        case op_create_lexical_environment: {
    3398             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CreateActivation, get(VirtualRegister(currentInstruction[1].u.operand))));
     3394            Node* lexicalEnvironment = addToGraph(CreateActivation, get(VirtualRegister(currentInstruction[1].u.operand)));
     3395            set(VirtualRegister(currentInstruction[1].u.operand), lexicalEnvironment);
     3396            set(VirtualRegister(currentInstruction[2].u.operand), lexicalEnvironment);
    33993397            NEXT_OPCODE(op_create_lexical_environment);
    34003398        }
    34013399           
    34023400        case op_get_scope: {
     3401            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(GetScope, get(VirtualRegister(JSStack::Callee))));
    34033402            NEXT_OPCODE(op_get_scope);
    34043403        }
  • trunk/Source/JavaScriptCore/dfg/DFGStackLayoutPhase.cpp

    r174165 r176479  
    169169        }
    170170       
     171        if (codeBlock()->scopeRegister().isValid()) {
     172            codeBlock()->setScopeRegister(
     173                virtualRegisterForLocal(allocation[codeBlock()->scopeRegister().toLocal()]));
     174        }
     175
    171176        for (unsigned i = m_graph.m_inlineVariableData.size(); i--;) {
    172177            InlineVariableData data = m_graph.m_inlineVariableData[i];
  • trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp

    r172129 r176479  
    256256                    case DoubleConstant:
    257257                    case Int52Constant:
     258                    case GetScope:
    258259                        break;
    259260               
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.h

    r175967 r176479  
    5252        }
    5353
     54        JSScope* scope(int scopeRegisterOffset) const
     55        {
     56            ASSERT(this[scopeRegisterOffset].Register::scope());
     57            return this[scopeRegisterOffset].Register::scope();
     58        }
     59
    5460        bool hasActivation() const;
    5561        JSLexicalEnvironment* lexicalEnvironment() const;
     
    187193        void setCallerFrame(CallFrame* frame) { callerFrameAndPC().callerFrame = frame; }
    188194        void setScope(JSScope* scope) { static_cast<Register*>(this)[JSStack::ScopeChain] = scope; }
     195        void setScope(int scopeRegisterOffset, JSScope* scope) { static_cast<Register*>(this)[scopeRegisterOffset] = scope; }
    189196        void setActivation(JSLexicalEnvironment*);
    190197
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r174361 r176479  
    106106    CallFrame* callerFrame = callFrame->callerFrame();
    107107    CodeBlock* callerCodeBlock = callerFrame->codeBlock();
    108     JSScope* callerScopeChain = callerFrame->scope();
     108    JSScope* callerScopeChain = callerFrame->uncheckedR(callerCodeBlock->scopeRegister().offset()).Register::scope();
    109109    EvalExecutable* eval = callerCodeBlock->evalCodeCache().tryGet(callerCodeBlock->isStrictMode(), programSource, callerScopeChain);
    110110
     
    727727        ++targetScopeDepth;
    728728
    729     JSScope* scope = callFrame->scope();
     729    int scopeRegisterOffset = codeBlock->scopeRegister().offset();
     730    JSScope* scope = callFrame->scope(scopeRegisterOffset);
    730731    int scopeDelta = scope->depth() - targetScopeDepth;
    731732    RELEASE_ASSERT(scopeDelta >= 0);
     
    733734    while (scopeDelta--)
    734735        scope = scope->next();
    735     callFrame->setScope(scope);
     736
     737    callFrame->setScope(scopeRegisterOffset, scope);
    736738
    737739    return handler;
  • trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp

    r175967 r176479  
    122122    m_frame.m_callerIsVMEntryFrame = m_frame.m_CallerVMEntryFrame != m_frame.m_VMEntryFrame;
    123123    m_frame.m_callee = callFrame->callee();
    124     m_frame.m_scope = callFrame->scope();
    125124    m_frame.m_codeBlock = callFrame->codeBlock();
    126125    m_frame.m_bytecodeOffset = !m_frame.codeBlock() ? 0
     
    156155
    157156        JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame);
    158         m_frame.m_scope = callee->scope();
    159157        m_frame.m_callee = callee;
    160         ASSERT(m_frame.scope());
    161158        ASSERT(m_frame.callee());
    162159
  • trunk/Source/JavaScriptCore/interpreter/StackVisitor.h

    r175706 r176479  
    6161        CallFrame* callerFrame() const { return m_callerFrame; }
    6262        JSObject* callee() const { return m_callee; }
    63         JSScope* scope() const { return m_scope; }
    6463        CodeBlock* codeBlock() const { return m_codeBlock; }
    6564        unsigned bytecodeOffset() const { return m_bytecodeOffset; }
     
    102101        CallFrame* m_callerFrame;
    103102        JSObject* m_callee;
    104         JSScope* m_scope;
    105103        CodeBlock* m_codeBlock;
    106104        unsigned m_bytecodeOffset;
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r176109 r176479  
    13141314    NativeCallFrameTracer tracer(&vm, exec);
    13151315
     1316    // FIXME: This won't work if this operation is called from the DFG or FTL.
     1317    // This should be changed to pass in the new scope.
     1318    JSScope* currentScope = exec->uncheckedR(dst).Register::scope();
    13161319    JSNameScope::Type scopeType = static_cast<JSNameScope::Type>(type);
    1317     JSNameScope* scope = JSNameScope::create(exec, *identifier, JSValue::decode(encodedValue), attibutes, scopeType);
    1318 
     1320    JSNameScope* scope = JSNameScope::create(exec, currentScope, *identifier, JSValue::decode(encodedValue), attibutes, scopeType);
     1321
     1322    // FIXME: This won't work if this operation is called from the DFG or FTL.
     1323    // This should be changed to return the new scope.
    13191324    exec->uncheckedR(dst) = scope;
    13201325}
     
    13411346        return;
    13421347
    1343     exec->uncheckedR(dst) = JSWithScope::create(exec, o);
     1348    // FIXME: This won't work if this operation is called from the DFG or FTL.
     1349    // This should be changed to pass in the old scope and return the new scope.
     1350    JSScope* currentScope = exec->uncheckedR(dst).Register::scope();
     1351    exec->uncheckedR(dst) = JSWithScope::create(exec, o, currentScope);
    13441352}
    13451353
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r176109 r176479  
    12361236    execCallee->setCallerFrame(exec);
    12371237    execCallee->uncheckedR(JSStack::Callee) = calleeAsValue;
    1238     execCallee->setScope(exec->scope());
     1238    JSScope* callerScope = exec->uncheckedR(exec->codeBlock()->scopeRegister().offset()).Register::scope();
     1239    execCallee->setScope(callerScope);
    12391240    execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point));
    12401241    execCallee->setCodeBlock(0);
     
    12761277    LLINT_CHECK_EXCEPTION();
    12771278
    1278     exec->uncheckedR(pc[1].u.operand) = JSWithScope::create(exec, o);
     1279    int scopeReg = pc[1].u.operand;
     1280    JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
     1281    exec->uncheckedR(scopeReg) = JSWithScope::create(exec, o, currentScope);
    12791282   
    12801283    LLINT_END();
     
    12941297    LLINT_BEGIN();
    12951298    CodeBlock* codeBlock = exec->codeBlock();
     1299    int scopeReg = pc[1].u.operand;
     1300    JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
    12961301    JSNameScope::Type type = static_cast<JSNameScope::Type>(pc[5].u.operand);
    1297     JSNameScope* scope = JSNameScope::create(exec, codeBlock->identifier(pc[2].u.operand), LLINT_OP(3).jsValue(), pc[4].u.operand, type);
    1298     exec->uncheckedR(pc[1].u.operand) = scope;
     1302    JSNameScope* scope = JSNameScope::create(exec, currentScope, codeBlock->identifier(pc[2].u.operand), LLINT_OP(3).jsValue(), pc[4].u.operand, type);
     1303    exec->uncheckedR(scopeReg) = scope;
    12991304    LLINT_END();
    13001305}
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r176109 r176479  
    21722172    loadisFromInstruction(5, t2)
    21732173
    2174     loadp ScopeChain + PayloadOffset[cfr], t0
     2174    loadisFromInstruction(2, t0)
     2175    loadp PayloadOffset[cfr, t0, 8], t0
    21752176    btiz t2, .resolveScopeLoopEnd
    21762177
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r176109 r176479  
    20012001
    20022002macro resolveScope()
    2003     loadp CodeBlock[cfr], t0
    20042003    loadisFromInstruction(5, t2)
    2005     loadp ScopeChain[cfr], t0
     2004    loadisFromInstruction(2, t0)
     2005    loadp [cfr, t0, 8], t0
    20062006    btiz t2, .resolveScopeLoopEnd
    20072007
  • trunk/Source/JavaScriptCore/runtime/JSNameScope.h

    r176357 r176479  
    4242    };
    4343
    44     static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes, Type type)
     44    static JSNameScope* create(ExecState* exec, JSScope* currentScope, const Identifier& identifier, JSValue value, unsigned attributes, Type type)
    4545    {
    4646        VM& vm = exec->vm();
    47         JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(vm.heap)) JSNameScope(vm, exec->lexicalGlobalObject(), exec->scope(), type);
     47        JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(vm.heap)) JSNameScope(vm, exec->lexicalGlobalObject(), currentScope, type);
    4848        scopeObject->finishCreation(vm, identifier, value, attributes);
    4949        return scopeObject;
  • trunk/Source/JavaScriptCore/runtime/JSWithScope.h

    r171939 r176479  
    3434public:
    3535    typedef JSScope Base;
    36 
    37     static JSWithScope* create(ExecState* exec, JSObject* object)
    38     {
    39         JSWithScope* withScope = new (NotNull, allocateCell<JSWithScope>(*exec->heap())) JSWithScope(exec, object);
    40         withScope->finishCreation(exec->vm());
    41         return withScope;
    42     }
    4336
    4437    static JSWithScope* create(ExecState* exec, JSObject* object, JSScope* next)
Note: See TracChangeset for help on using the changeset viewer.