Ignore:
Timestamp:
Oct 16, 2012, 3:28:32 PM (13 years ago)
Author:
[email protected]
Message:

Bytecode should not have responsibility for determining how to perform non-local resolves
https://bugs.webkit.org/show_bug.cgi?id=99349

Reviewed by Gavin Barraclough.

This patch removes lexical analysis from the bytecode generation. This allows
us to delay lookup of a non-local variables until the lookup is actually necessary,
and simplifies a lot of the resolve logic in BytecodeGenerator.

Once a lookup is performed we cache the lookup information in a set of out-of-line
buffers in CodeBlock. This allows subsequent lookups to avoid unnecessary hashing,
etc, and allows the respective JITs to recreated optimal lookup code.

This is currently still a performance regression in LLInt, but most of the remaining
regression is caused by a lot of indirection that I'll remove in future work, as well
as some work necessary to allow LLInt to perform in line instruction repatching.
We will also want to improve the behaviour of the baseline JIT for some of the lookup
operations, however this patch was getting quite large already so I'm landing it now
that we've reached the bar of "performance-neutral".

  • GNUmakefile.list.am:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::printStructures):
(JSC::CodeBlock::dump):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::visitStructures):
(JSC):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::shrinkToFit):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::addResolve):
(JSC::CodeBlock::addPutToBase):
(CodeBlock):
(JSC::CodeBlock::resolveOperations):
(JSC::CodeBlock::putToBaseOperation):
(JSC::CodeBlock::numberOfResolveOperations):
(JSC::CodeBlock::numberOfPutToBaseOperations):
(JSC::CodeBlock::addPropertyAccessInstruction):
(JSC::CodeBlock::globalObjectConstant):
(JSC::CodeBlock::setGlobalObjectConstant):

  • bytecode/GlobalResolveInfo.h: Removed.
  • bytecode/Opcode.h:

(JSC):
(JSC::padOpcodeName):

  • bytecode/ResolveGlobalStatus.cpp:

(JSC::computeForStructure):
(JSC::ResolveGlobalStatus::computeFor):

  • bytecode/ResolveGlobalStatus.h:

(JSC):
(ResolveGlobalStatus):

  • bytecode/ResolveOperation.h: Added. The new types and logic we use to perform the cached lookups.

(JSC):
(ResolveOperation):
(JSC::ResolveOperation::getAndReturnScopedVar):
(JSC::ResolveOperation::checkForDynamicEntriesBeforeGlobalScope):
(JSC::ResolveOperation::getAndReturnGlobalVar):
(JSC::ResolveOperation::getAndReturnGlobalProperty):
(JSC::ResolveOperation::resolveFail):
(JSC::ResolveOperation::skipTopScopeNode):
(JSC::ResolveOperation::skipScopes):
(JSC::ResolveOperation::returnGlobalObjectAsBase):
(JSC::ResolveOperation::setBaseToGlobal):
(JSC::ResolveOperation::setBaseToUndefined):
(JSC::ResolveOperation::setBaseToScope):
(JSC::ResolveOperation::returnScopeAsBase):
(JSC::PutToBaseOperation::PutToBaseOperation):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::ResolveResult::checkValidity):
(JSC):
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::resolve):
(JSC::BytecodeGenerator::resolveConstDecl):
(JSC::BytecodeGenerator::shouldAvoidResolveGlobal):
(JSC::BytecodeGenerator::emitResolve):
(JSC::BytecodeGenerator::emitResolveBase):
(JSC::BytecodeGenerator::emitResolveBaseForPut):
(JSC::BytecodeGenerator::emitResolveWithBaseForPut):
(JSC::BytecodeGenerator::emitResolveWithThis):
(JSC::BytecodeGenerator::emitGetLocalVar):
(JSC::BytecodeGenerator::emitInitGlobalConst):
(JSC::BytecodeGenerator::emitPutToBase):

  • bytecompiler/BytecodeGenerator.h:

(JSC::ResolveResult::registerResolve):
(JSC::ResolveResult::dynamicResolve):
(ResolveResult):
(JSC::ResolveResult::ResolveResult):
(JSC):
(NonlocalResolveInfo):
(JSC::NonlocalResolveInfo::NonlocalResolveInfo):
(JSC::NonlocalResolveInfo::~NonlocalResolveInfo):
(JSC::NonlocalResolveInfo::resolved):
(JSC::NonlocalResolveInfo::put):
(BytecodeGenerator):
(JSC::BytecodeGenerator::getResolveOperations):
(JSC::BytecodeGenerator::getResolveWithThisOperations):
(JSC::BytecodeGenerator::getResolveBaseOperations):
(JSC::BytecodeGenerator::getResolveBaseForPutOperations):
(JSC::BytecodeGenerator::getResolveWithBaseForPutOperations):
(JSC::BytecodeGenerator::getPutToBaseOperation):

  • bytecompiler/NodesCodegen.cpp:

(JSC::ResolveNode::isPure):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::PostfixNode::emitResolve):
(JSC::PrefixNode::emitResolve):
(JSC::ReadModifyResolveNode::emitBytecode):
(JSC::AssignResolveNode::emitBytecode):
(JSC::ConstDeclNode::emitCodeSingle):
(JSC::ForInNode::emitBytecode):

  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::execute):

  • dfg/DFGByteCodeParser.cpp:

(ByteCodeParser):
(InlineStackEntry):
(JSC::DFG::ByteCodeParser::handleGetByOffset):
(DFG):
(JSC::DFG::ByteCodeParser::parseResolveOperations):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):

  • dfg/DFGCapabilities.h:

(JSC::DFG::canCompileResolveOperations):
(DFG):
(JSC::DFG::canCompilePutToBaseOperation):
(JSC::DFG::canCompileOpcode):
(JSC::DFG::canInlineOpcode):

  • dfg/DFGGraph.h:

(ResolveGlobalData):
(ResolveOperationData):
(DFG):
(PutToBaseOperationData):
(Graph):

  • dfg/DFGNode.h:

(JSC::DFG::Node::hasIdentifier):
(JSC::DFG::Node::resolveOperationsDataIndex):
(Node):

  • dfg/DFGNodeType.h:

(DFG):

  • dfg/DFGOSRExit.cpp:

(JSC::DFG::OSRExit::OSRExit):

  • dfg/DFGOSRExit.h:

(OSRExit):

  • dfg/DFGOSRExitCompiler.cpp:
  • dfg/DFGOSRExitCompiler32_64.cpp:

(JSC::DFG::OSRExitCompiler::compileExit):

  • dfg/DFGOSRExitCompiler64.cpp:

(JSC::DFG::OSRExitCompiler::compileExit):

  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGRepatch.cpp:

(JSC::DFG::tryCacheGetByID):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::resolveOperations):
(SpeculativeJIT):
(JSC::DFG::SpeculativeJIT::putToBaseOperation):
(JSC::DFG::SpeculativeJIT::callOperation):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGStructureCheckHoistingPhase.cpp:

(JSC::DFG::StructureCheckHoistingPhase::run):

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):

  • jit/JIT.h:

(JIT):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_put_to_base):
(JSC):
(JSC::JIT::emit_resolve_operations):
(JSC::JIT::emitSlow_link_resolve_operations):
(JSC::JIT::emit_op_resolve):
(JSC::JIT::emitSlow_op_resolve):
(JSC::JIT::emit_op_resolve_base):
(JSC::JIT::emitSlow_op_resolve_base):
(JSC::JIT::emit_op_resolve_with_base):
(JSC::JIT::emitSlow_op_resolve_with_base):
(JSC::JIT::emit_op_resolve_with_this):
(JSC::JIT::emitSlow_op_resolve_with_this):
(JSC::JIT::emitSlow_op_put_to_base):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_put_to_base):
(JSC):

  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emit_op_init_global_const):
(JSC::JIT::emit_op_init_global_const_check):
(JSC::JIT::emitSlow_op_init_global_const_check):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emit_op_init_global_const):
(JSC::JIT::emit_op_init_global_const_check):
(JSC::JIT::emitSlow_op_init_global_const_check):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):
(JSC):

  • jit/JITStubs.h:
  • llint/LLIntSlowPaths.cpp:

(LLInt):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • llint/LLIntSlowPaths.h:

(LLInt):

  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/JSScope.cpp:

(JSC::LookupResult::base):
(JSC::LookupResult::value):
(JSC::LookupResult::setBase):
(JSC::LookupResult::setValue):
(LookupResult):
(JSC):
(JSC::setPutPropertyAccessOffset):
(JSC::executeResolveOperations):
(JSC::JSScope::resolveContainingScopeInternal):
(JSC::JSScope::resolveContainingScope):
(JSC::JSScope::resolve):
(JSC::JSScope::resolveBase):
(JSC::JSScope::resolveWithBase):
(JSC::JSScope::resolveWithThis):
(JSC::JSScope::resolvePut):
(JSC::JSScope::resolveGlobal):

  • runtime/JSScope.h:

(JSScope):

  • runtime/JSVariableObject.cpp:

(JSC):

  • runtime/JSVariableObject.h:

(JSVariableObject):

  • runtime/Structure.h:

(JSC::Structure::propertyAccessesAreCacheable):
(Structure):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r131276 r131516  
    5555    const tagTypeNumber = csr1
    5656    const tagMask = csr2
     57   
     58    macro loadisFromInstruction(offset, dest)
     59        loadis offset * 8[PB, PC, 8], dest
     60    end
     61   
     62    macro loadpFromInstruction(offset, dest)
     63        loadp offset * 8[PB, PC, 8], dest
     64    end
     65   
     66    macro storepToInstruction(value, offset)
     67        storep value, offset * 8[PB, PC, 8]
     68    end
     69
    5770else
    5871    const PC = t4
     72    macro loadisFromInstruction(offset, dest)
     73        loadis offset * 4[PC], dest
     74    end
     75   
     76    macro loadpFromInstruction(offset, dest)
     77        loadp offset * 4[PC], dest
     78    end
    5979end
    6080
     
    100120# Copied from PropertyOffset.h
    101121const firstOutOfLineOffset = 100
     122
     123# From ResolveOperations.h
     124const ResolveOperationFail = 0
     125const ResolveOperationSetBaseToUndefined = 1
     126const ResolveOperationReturnScopeAsBase = 2
     127const ResolveOperationSetBaseToScope = 3
     128const ResolveOperationSetBaseToGlobal = 4
     129const ResolveOperationGetAndReturnScopedVar = 5
     130const ResolveOperationGetAndReturnGlobalVar = 6
     131const ResolveOperationGetAndReturnGlobalVarWatchable = 7
     132const ResolveOperationSkipTopScopeNode = 8
     133const ResolveOperationSkipScopes = 9
     134const ResolveOperationReturnGlobalObjectAsBase = 10
     135const ResolveOperationGetAndReturnGlobalProperty = 11
     136const ResolveOperationCheckForDynamicEntriesBeforeGlobalScope = 12
     137
     138const PutToBaseOperationKindUninitialised = 0
     139const PutToBaseOperationKindGeneric = 1
     140const PutToBaseOperationKindReadonly = 2
     141const PutToBaseOperationKindGlobalVariablePut = 3
     142const PutToBaseOperationKindGlobalVariablePutChecked = 4
     143const PutToBaseOperationKindGlobalPropertyPut = 5
     144const PutToBaseOperationKindVariablePut = 6
    102145
    103146# Allocation constants
     
    494537    dispatch(4)
    495538
     539macro getPutToBaseOperationField(scratch, scratch1, fieldOffset, fieldGetter)
     540    loadisFromInstruction(4, scratch)
     541    mulp sizeof PutToBaseOperation, scratch, scratch
     542    loadp CodeBlock[cfr], scratch1
     543    loadp VectorBufferOffset + CodeBlock::m_putToBaseOperations[scratch1], scratch1
     544    fieldGetter(fieldOffset[scratch1, scratch, 1])
     545end
     546
     547macro moveJSValueFromRegisterWithoutProfiling(value, destBuffer, destOffsetReg)
     548    storep value, [destBuffer, destOffsetReg, 8]
     549end
     550
     551
     552macro moveJSValueFromRegistersWithoutProfiling(tag, payload, destBuffer, destOffsetReg)
     553    storep tag, TagOffset[destBuffer, destOffsetReg, 8]
     554    storep payload, PayloadOffset[destBuffer, destOffsetReg, 8]
     555end
     556
     557macro putToBaseVariableBody(variableOffset, scratch1, scratch2, scratch3)
     558    loadisFromInstruction(1, scratch1)
     559    loadp PayloadOffset[cfr, scratch1, 8], scratch1
     560    loadp JSVariableObject::m_registers[scratch1], scratch1
     561    loadisFromInstruction(3, scratch2)
     562    if JSVALUE64
     563        loadConstantOrVariable(scratch2, scratch3)
     564        moveJSValueFromRegisterWithoutProfiling(scratch3, scratch1, variableOffset)
     565    else
     566        loadConstantOrVariable(scratch2, scratch3, scratch2) # scratch3=tag, scratch2=payload
     567        moveJSValueFromRegistersWithoutProfiling(scratch3, scratch2, scratch1, variableOffset)
     568    end
     569end
     570
     571_llint_op_put_to_base_variable:
     572    traceExecution()
     573    getPutToBaseOperationField(t0, t1, PutToBaseOperation::m_offset, macro(addr)
     574                                              loadis  addr, t0
     575                                          end)
     576    putToBaseVariableBody(t0, t1, t2, t3)
     577    dispatch(5)
     578
     579_llint_op_put_to_base:
     580    traceExecution()
     581    getPutToBaseOperationField(t0, t1, 0, macro(addr)
     582                                              leap addr, t0
     583                                              bbneq PutToBaseOperation::m_kindAsUint8[t0], PutToBaseOperationKindVariablePut, .notPutToBaseVariable
     584                                              loadis PutToBaseOperation::m_offset[t0], t0
     585                                              putToBaseVariableBody(t0, t1, t2, t3)
     586                                              dispatch(5)
     587                                              .notPutToBaseVariable:
     588                                          end)
     589    callSlowPath(_llint_slow_path_put_to_base)
     590    dispatch(5)
     591
     592macro getResolveOperation(resolveOperationIndex, dest, scratch)
     593    loadisFromInstruction(resolveOperationIndex, dest)
     594    mulp sizeof ResolveOperations, dest, dest
     595    loadp CodeBlock[cfr], scratch
     596    loadp VectorBufferOffset + CodeBlock::m_resolveOperations[scratch], scratch
     597    loadp VectorBufferOffset[scratch, dest, 1], dest
     598end
     599
     600macro getScope(loadInitialScope, scopeCount, dest, scratch)
     601    loadInitialScope(dest)
     602    loadi scopeCount, scratch
     603
     604    btiz scratch, .done
     605.loop:
     606    loadp JSScope::m_next[dest], dest
     607    subi 1, scratch
     608    btinz scratch, .loop
     609
     610.done:
     611end
     612
     613macro moveJSValue(sourceBuffer, sourceOffsetReg, destBuffer, destOffsetReg, profileOffset, scratchRegister)
     614    if JSVALUE64
     615        loadp [sourceBuffer, sourceOffsetReg, 8], scratchRegister
     616        storep scratchRegister, [destBuffer, destOffsetReg, 8]
     617        loadpFromInstruction(profileOffset, destOffsetReg)
     618        valueProfile(scratchRegister, destOffsetReg)
     619    else
     620        loadp PayloadOffset[sourceBuffer, sourceOffsetReg, 8], scratchRegister
     621        storep scratchRegister, PayloadOffset[destBuffer, destOffsetReg, 8]
     622        loadp TagOffset[sourceBuffer, sourceOffsetReg, 8], sourceOffsetReg
     623        storep sourceOffsetReg, TagOffset[destBuffer, destOffsetReg, 8]
     624        loadpFromInstruction(profileOffset, destOffsetReg)
     625        valueProfile(sourceOffsetReg, scratchRegister, destOffsetReg)
     626    end
     627end
     628
     629macro moveJSValueFromSlot(slot, destBuffer, destOffsetReg, profileOffset, scratchRegister)
     630    if JSVALUE64
     631        loadp [slot], scratchRegister
     632        storep scratchRegister, [destBuffer, destOffsetReg, 8]
     633        loadpFromInstruction(profileOffset, destOffsetReg)
     634        valueProfile(scratchRegister, destOffsetReg)
     635    else
     636        loadp PayloadOffset[slot], scratchRegister
     637        storep scratchRegister, PayloadOffset[destBuffer, destOffsetReg, 8]
     638        loadp TagOffset[slot], slot
     639        storep slot, TagOffset[destBuffer, destOffsetReg, 8]
     640        loadpFromInstruction(profileOffset, destOffsetReg)
     641        valueProfile(slot, scratchRegister, destOffsetReg)
     642    end
     643end
     644
     645macro moveJSValueFromRegister(value, destBuffer, destOffsetReg, profileOffset)
     646    storep value, [destBuffer, destOffsetReg, 8]
     647    loadpFromInstruction(profileOffset, destOffsetReg)
     648    valueProfile(value, destOffsetReg)
     649end
     650
     651macro moveJSValueFromRegisters(tag, payload, destBuffer, destOffsetReg, profileOffset)
     652    storep tag, TagOffset[destBuffer, destOffsetReg, 8]
     653    storep payload, PayloadOffset[destBuffer, destOffsetReg, 8]
     654    loadpFromInstruction(profileOffset, destOffsetReg)
     655    valueProfile(tag, payload, destOffsetReg)
     656end
     657
     658_llint_op_resolve_global_property:
     659    traceExecution()
     660    getResolveOperation(3, t0, t1)
     661    loadp CodeBlock[cfr], t1
     662    loadp CodeBlock::m_globalObject[t1], t1
     663    loadp ResolveOperation::m_structure[t0], t2
     664    bpneq JSCell::m_structure[t1], t2, _llint_op_resolve
     665    loadis ResolveOperation::m_offset[t0], t0
     666    if JSVALUE64
     667        loadPropertyAtVariableOffsetKnownNotInline(t0, t1, t2)
     668        loadisFromInstruction(1, t0)
     669        moveJSValueFromRegister(t2, cfr, t0, 4)
     670    else
     671        loadPropertyAtVariableOffsetKnownNotInline(t0, t1, t2, t3)
     672        loadisFromInstruction(1, t0)
     673        moveJSValueFromRegisters(t2, t3, cfr, t0, 4)
     674    end
     675    dispatch(5)
     676
     677_llint_op_resolve_global_var:
     678    traceExecution()
     679    getResolveOperation(3, t0, t1)
     680    loadp ResolveOperation::m_registerAddress[t0], t0
     681    loadisFromInstruction(1, t1)
     682    moveJSValueFromSlot(t0, cfr, t1, 4, t3)
     683    dispatch(5)
     684
     685macro resolveScopedVarBody(resolveOperations)
     686    # First ResolveOperation is to skip scope chain nodes
     687    getScope(macro(dest)
     688                 loadp ScopeChain + PayloadOffset[cfr], dest
     689             end,
     690             ResolveOperation::m_scopesToSkip[resolveOperations], t1, t2)
     691    loadp JSVariableObject::m_registers[t1], t1 # t1 now contains the activation registers
     692   
     693    # Second ResolveOperation tells us what offset to use
     694    loadis ResolveOperation::m_offset + sizeof ResolveOperation[resolveOperations], t2
     695    loadisFromInstruction(1, t3)
     696    moveJSValue(t1, t2, cfr, t3, 4, t0)
     697end
     698
     699_llint_op_resolve_scoped_var:
     700    traceExecution()
     701    getResolveOperation(3, t0, t1)
     702    resolveScopedVarBody(t0)
     703    dispatch(5)
     704   
     705_llint_op_resolve_scoped_var_on_top_scope:
     706    traceExecution()
     707    getResolveOperation(3, t0, t1)
     708
     709    # Load destination index
     710    loadisFromInstruction(1, t3)
     711
     712    # We know we want the top scope chain entry
     713    loadp ScopeChain + PayloadOffset[cfr], t1
     714    loadp JSVariableObject::m_registers[t1], t1 # t1 now contains the activation registers
     715   
     716    # Second ResolveOperation tells us what offset to use
     717    loadis ResolveOperation::m_offset + sizeof ResolveOperation[t0], t2
     718
     719    moveJSValue(t1, t2, cfr, t3, 4, t0)
     720    dispatch(5)
     721
     722_llint_op_resolve_scoped_var_with_top_scope_check:
     723    traceExecution()
     724    getResolveOperation(3, t0, t1)
     725    # First ResolveOperation tells us what register to check
     726    loadis ResolveOperation::m_activationRegister[t0], t1
     727
     728    loadp PayloadOffset[cfr, t1, 8], t1
     729
     730    getScope(macro(dest)
     731                 btpz t1, .scopeChainNotCreated
     732                     loadp JSScope::m_next[t1], dest
     733                 jmp .done
     734                 .scopeChainNotCreated:
     735                     loadp ScopeChain + PayloadOffset[cfr], dest
     736                 .done:
     737             end,
     738             # Second ResolveOperation tells us how many more nodes to skip
     739             ResolveOperation::m_scopesToSkip + sizeof ResolveOperation[t0], t1, t2)
     740    loadp JSVariableObject::m_registers[t1], t1 # t1 now contains the activation registers
     741   
     742    # Third operation tells us what offset to use
     743    loadis ResolveOperation::m_offset + 2 * sizeof ResolveOperation[t0], t2
     744    loadisFromInstruction(1, t3)
     745    moveJSValue(t1, t2, cfr, t3, 4, t0)
     746    dispatch(5)
    496747
    497748_llint_op_resolve:
    498749    traceExecution()
     750    getResolveOperation(3, t0, t1)
     751    btpz t0, .noInstructions
     752    loadis ResolveOperation::m_operation[t0], t1
     753    bineq t1, ResolveOperationSkipScopes, .notSkipScopes
     754        resolveScopedVarBody(t0)
     755        dispatch(5)
     756.notSkipScopes:
     757    bineq t1, ResolveOperationGetAndReturnGlobalVar, .notGetAndReturnGlobalVar
     758        loadp ResolveOperation::m_registerAddress[t0], t0
     759        loadisFromInstruction(1, t1)
     760        moveJSValueFromSlot(t0, cfr, t1, 4, t3)
     761        dispatch(5)
     762.notGetAndReturnGlobalVar:
     763
     764.noInstructions:
    499765    callSlowPath(_llint_slow_path_resolve)
    500     dispatch(4)
    501 
    502 
    503 _llint_op_resolve_skip:
    504     traceExecution()
    505     callSlowPath(_llint_slow_path_resolve_skip)
    506766    dispatch(5)
    507767
     768_llint_op_resolve_base_to_global:
     769    traceExecution()
     770    loadp CodeBlock[cfr], t1
     771    loadp CodeBlock::m_globalObject[t1], t1
     772    loadisFromInstruction(1, t3)
     773    if JSVALUE64
     774        moveJSValueFromRegister(t1, cfr, t3, 6)
     775    else
     776        move CellTag, t2
     777        moveJSValueFromRegisters(t2, t1, cfr, t3, 6)
     778    end
     779    dispatch(7)
     780
     781_llint_op_resolve_base_to_global_dynamic:
     782    jmp _llint_op_resolve_base
     783
     784_llint_op_resolve_base_to_scope:
     785    traceExecution()
     786    getResolveOperation(4, t0, t1)
     787    # First ResolveOperation is to skip scope chain nodes
     788    getScope(macro(dest)
     789                 loadp ScopeChain + PayloadOffset[cfr], dest
     790             end,
     791             ResolveOperation::m_scopesToSkip[t0], t1, t2)
     792    loadisFromInstruction(1, t3)
     793    if JSVALUE64
     794        moveJSValueFromRegister(t1, cfr, t3, 6)
     795    else
     796        move CellTag, t2
     797        moveJSValueFromRegisters(t2, t1, cfr, t3, 6)
     798    end
     799    dispatch(7)
     800
     801_llint_op_resolve_base_to_scope_with_top_scope_check:
     802    traceExecution()
     803    getResolveOperation(4, t0, t1)
     804    # First ResolveOperation tells us what register to check
     805    loadis ResolveOperation::m_activationRegister[t0], t1
     806
     807    loadp PayloadOffset[cfr, t1, 8], t1
     808
     809    getScope(macro(dest)
     810                 btpz t1, .scopeChainNotCreated
     811                     loadp JSScope::m_next[t1], dest
     812                 jmp .done
     813                 .scopeChainNotCreated:
     814                     loadp ScopeChain + PayloadOffset[cfr], dest
     815                 .done:
     816             end,
     817             # Second ResolveOperation tells us how many more nodes to skip
     818             ResolveOperation::m_scopesToSkip + sizeof ResolveOperation[t0], t1, t2)
     819
     820    loadisFromInstruction(1, t3)
     821    if JSVALUE64
     822        moveJSValueFromRegister(t1, cfr, t3, 6)
     823    else
     824        move CellTag, t2
     825        moveJSValueFromRegisters(t2, t1, cfr, t3, 6)
     826    end
     827    dispatch(7)
    508828
    509829_llint_op_resolve_base:
    510830    traceExecution()
    511831    callSlowPath(_llint_slow_path_resolve_base)
    512     dispatch(5)
    513 
     832    dispatch(7)
    514833
    515834_llint_op_ensure_property_exists:
     
    518837    dispatch(3)
    519838
     839macro interpretResolveWithBase(opcodeLength, slowPath)
     840    traceExecution()
     841    getResolveOperation(4, t0, t1)
     842    btpz t0, .slowPath
     843
     844    loadp ScopeChain[cfr], t3
     845    # Get the base
     846    loadis ResolveOperation::m_operation[t0], t2
     847
     848    bineq t2, ResolveOperationSkipScopes, .notSkipScopes
     849        getScope(macro(dest) move t3, dest end,
     850                 ResolveOperation::m_scopesToSkip[t0], t1, t2)
     851        move t1, t3
     852        addp sizeof ResolveOperation, t0, t0
     853        jmp .haveCorrectScope
     854
     855    .notSkipScopes:
     856
     857    bineq t2, ResolveOperationSkipTopScopeNode, .notSkipTopScopeNode
     858        loadis ResolveOperation::m_activationRegister[t0], t1
     859        loadp PayloadOffset[cfr, t1, 8], t1
     860
     861        getScope(macro(dest)
     862                     btpz t1, .scopeChainNotCreated
     863                         loadp JSScope::m_next[t1], dest
     864                     jmp .done
     865                     .scopeChainNotCreated:
     866                         loadp ScopeChain + PayloadOffset[cfr], dest
     867                     .done:
     868                 end,
     869                 sizeof ResolveOperation + ResolveOperation::m_scopesToSkip[t0], t1, t2)
     870        move t1, t3
     871        # We've handled two opcodes here
     872        addp 2 * sizeof ResolveOperation, t0, t0
     873
     874    .notSkipTopScopeNode:
     875
     876    .haveCorrectScope:
     877
     878    # t3 now contains the correct Scope
     879    # t0 contains a pointer to the current ResolveOperation
     880
     881    loadis ResolveOperation::m_operation[t0], t2
     882    # t2 contains the next instruction
     883
     884    loadisFromInstruction(1, t1)
     885    # t1 now contains the index for the base register
     886
     887    bineq t2, ResolveOperationSetBaseToScope, .notSetBaseToScope
     888        storep t3, PayloadOffset[cfr, t1, 8]
     889        if JSVALUE64
     890        else
     891            storep CellTag, TagOffset[cfr, t1, 8]
     892        end
     893        jmp .haveSetBase
     894
     895    .notSetBaseToScope:
     896
     897    bineq t2, ResolveOperationSetBaseToUndefined, .notSetBaseToUndefined
     898        if JSVALUE64
     899            storep ValueUndefined, PayloadOffset[cfr, t1, 8]
     900        else
     901            storep 0, PayloadOffset[cfr, t1, 8]
     902            storep UndefinedTag, TagOffset[cfr, t1, 8]
     903        end
     904        jmp .haveSetBase
     905
     906    .notSetBaseToUndefined:
     907    bineq t2, ResolveOperationSetBaseToGlobal, .slowPath
     908        loadp JSCell::m_structure[t3], t2
     909        loadp Structure::m_globalObject[t2], t2
     910        storep t2, PayloadOffset[cfr, t1, 8]
     911        if JSVALUE64
     912        else
     913            storep CellTag, TagOffset[cfr, t1, 8]
     914        end
     915
     916    .haveSetBase:
     917
     918    # Get the value
     919
     920    # Load the operation into t2
     921    loadis ResolveOperation::m_operation + sizeof ResolveOperation[t0], t2
     922
     923    # Load the index for the value register into t1
     924    loadisFromInstruction(2, t1)
     925
     926    bineq t2, ResolveOperationGetAndReturnScopedVar, .notGetAndReturnScopedVar
     927        loadp JSVariableObject::m_registers[t3], t3 # t3 now contains the activation registers
     928
     929        # Second ResolveOperation tells us what offset to use
     930        loadis ResolveOperation::m_offset + sizeof ResolveOperation[t0], t2
     931        moveJSValue(t3, t2, cfr, t1, opcodeLength - 1, t0)
     932        dispatch(opcodeLength)
     933
     934    .notGetAndReturnScopedVar:
     935    bineq t2, ResolveOperationGetAndReturnGlobalProperty, .slowPath
     936        callSlowPath(slowPath)
     937        dispatch(opcodeLength)
     938
     939.slowPath:
     940    callSlowPath(slowPath)
     941    dispatch(opcodeLength)
     942end
    520943
    521944_llint_op_resolve_with_base:
    522     traceExecution()
    523     callSlowPath(_llint_slow_path_resolve_with_base)
    524     dispatch(5)
     945    interpretResolveWithBase(7, _llint_slow_path_resolve_with_base)
    525946
    526947
    527948_llint_op_resolve_with_this:
    528     traceExecution()
    529     callSlowPath(_llint_slow_path_resolve_with_this)
    530     dispatch(5)
     949    interpretResolveWithBase(6, _llint_slow_path_resolve_with_this)
    531950
    532951
Note: See TracChangeset for help on using the changeset viewer.