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/LowLevelInterpreter64.asm

    r131276 r131516  
    816816end
    817817
    818 macro resolveGlobal(size, slow)
    819     # Operands are as follows:
    820     # 8[PB, PC, 8]   Destination for the load.
    821     # 16[PB, PC, 8]  Property identifier index in the code block.
    822     # 24[PB, PC, 8]  Structure pointer, initialized to 0 by bytecode generator.
    823     # 32[PB, PC, 8]  Offset in global object, initialized to 0 by bytecode generator.
    824     loadp CodeBlock[cfr], t0
    825     loadp CodeBlock::m_globalObject[t0], t0
    826     loadp JSCell::m_structure[t0], t1
    827     bpneq t1, 24[PB, PC, 8], slow
    828     loadis 32[PB, PC, 8], t1
    829     loadPropertyAtVariableOffsetKnownNotInline(t1, t0, t2)
    830     loadis 8[PB, PC, 8], t0
    831     storep t2, [cfr, t0, 8]
    832     loadp (size - 1) * 8[PB, PC, 8], t0
    833     valueProfile(t2, t0)
    834 end
    835 
    836 _llint_op_resolve_global:
    837     traceExecution()
    838     resolveGlobal(6, .opResolveGlobalSlow)
    839     dispatch(6)
    840 
    841 .opResolveGlobalSlow:
    842     callSlowPath(_llint_slow_path_resolve_global)
    843     dispatch(6)
    844 
    845 
    846 # Gives you the scope in t0, while allowing you to optionally perform additional checks on the
    847 # scopes as they are traversed. scopeCheck() is called with two arguments: the register
    848 # holding the scope, and a register that can be used for scratch. Note that this does not
    849 # use t3, so you can hold stuff in t3 if need be.
    850 macro getScope(deBruijinIndexOperand, scopeCheck)
    851     loadp ScopeChain[cfr], t0
    852     loadis deBruijinIndexOperand, t2
    853    
    854     btiz t2, .done
    855    
    856     loadp CodeBlock[cfr], t1
    857     bineq CodeBlock::m_codeType[t1], FunctionCode, .loop
    858     btbz CodeBlock::m_needsFullScopeChain[t1], .loop
    859    
    860     loadis CodeBlock::m_activationRegister[t1], t1
    861 
    862     # Need to conditionally skip over one scope.
    863     btpz [cfr, t1, 8], .noActivation
    864     scopeCheck(t0, t1)
    865     loadp JSScope::m_next[t0], t0
    866 .noActivation:
    867     subi 1, t2
    868    
    869     btiz t2, .done
    870 .loop:
    871     scopeCheck(t0, t1)
    872     loadp JSScope::m_next[t0], t0
    873     subi 1, t2
    874     btinz t2, .loop
    875 
    876 .done:
    877 end
    878 
    879 _llint_op_resolve_global_dynamic:
    880     traceExecution()
    881     loadp CodeBlock[cfr], t3
    882     loadp CodeBlock::m_globalObject[t3], t3
    883     loadp JSGlobalObject::m_activationStructure[t3], t3
    884     getScope(
    885         40[PB, PC, 8],
    886         macro (scope, scratch)
    887             bpneq JSCell::m_structure[scope], t3, .opResolveGlobalDynamicSuperSlow
    888         end)
    889     resolveGlobal(7, .opResolveGlobalDynamicSlow)
    890     dispatch(7)
    891 
    892 .opResolveGlobalDynamicSuperSlow:
    893     callSlowPath(_llint_slow_path_resolve_for_resolve_global_dynamic)
    894     dispatch(7)
    895 
    896 .opResolveGlobalDynamicSlow:
    897     callSlowPath(_llint_slow_path_resolve_global_dynamic)
    898     dispatch(7)
    899 
    900 
    901 _llint_op_get_scoped_var:
    902     traceExecution()
    903     # Operands are as follows:
    904     # 8[PB, PC, 8]   Destination for the load
    905     # 16[PB, PC, 8]  Index of register in the scope
    906     # 24[PB, PC, 8]  De Bruijin index.
    907     getScope(24[PB, PC, 8], macro (scope, scratch) end)
    908     loadis 8[PB, PC, 8], t1
    909     loadis 16[PB, PC, 8], t2
    910     loadp JSVariableObject::m_registers[t0], t0
    911     loadp [t0, t2, 8], t3
    912     storep t3, [cfr, t1, 8]
    913     loadp 32[PB, PC, 8], t1
    914     valueProfile(t3, t1)
    915     dispatch(5)
    916 
    917 
    918 _llint_op_put_scoped_var:
    919     traceExecution()
    920     getScope(16[PB, PC, 8], macro (scope, scratch) end)
    921     loadis 24[PB, PC, 8], t1
    922     loadConstantOrVariable(t1, t3)
    923     loadis 8[PB, PC, 8], t1
    924     writeBarrier(t3)
    925     loadp JSVariableObject::m_registers[t0], t0
    926     storep t3, [t0, t1, 8]
    927     dispatch(4)
    928 
    929 
    930 macro getGlobalVar(size)
    931     traceExecution()
    932     loadp 16[PB, PC, 8], t0
    933     loadis 8[PB, PC, 8], t3
    934     loadp [t0], t1
    935     storep t1, [cfr, t3, 8]
    936     loadp (size - 1) * 8[PB, PC, 8], t0
    937     valueProfile(t1, t0)
    938     dispatch(size)
    939 end
    940 
    941 _llint_op_get_global_var:
    942     getGlobalVar(4)
    943 
    944 
    945 _llint_op_get_global_var_watchable:
    946     getGlobalVar(5)
    947 
    948 
    949818_llint_op_init_global_const:
    950 _llint_op_put_global_var:
    951819    traceExecution()
    952820    loadis 16[PB, PC, 8], t1
     
    959827
    960828_llint_op_init_global_const_check:
    961 _llint_op_put_global_var_check:
    962829    traceExecution()
    963830    loadp 24[PB, PC, 8], t2
    964831    loadis 16[PB, PC, 8], t1
    965832    loadp 8[PB, PC, 8], t0
    966     btbnz [t2], .opPutGlobalVarCheckSlow
     833    btbnz [t2], .opInitGlobalConstCheckSlow
    967834    loadConstantOrVariable(t1, t2)
    968835    writeBarrier(t2)
    969836    storep t2, [t0]
    970837    dispatch(5)
    971 .opPutGlobalVarCheckSlow:
    972     callSlowPath(_llint_slow_path_put_global_var_check)
     838.opInitGlobalConstCheckSlow:
     839    callSlowPath(_llint_slow_path_init_global_const_check)
    973840    dispatch(5)
    974 
    975841
    976842macro getById(getPropertyStorage)
Note: See TracChangeset for help on using the changeset viewer.