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/bytecode/CodeBlock.cpp

    r130726 r131516  
    440440}
    441441
    442 #if ENABLE(JIT)
    443 static bool isGlobalResolve(OpcodeID opcodeID)
    444 {
    445     return opcodeID == op_resolve_global || opcodeID == op_resolve_global_dynamic;
    446 }
    447 
    448 static unsigned instructionOffsetForNth(ExecState* exec, const RefCountedArray<Instruction>& instructions, int nth, bool (*predicate)(OpcodeID))
    449 {
    450     size_t i = 0;
    451     while (i < instructions.size()) {
    452         OpcodeID currentOpcode = exec->interpreter()->getOpcodeID(instructions[i].u.opcode);
    453         if (predicate(currentOpcode)) {
    454             if (!--nth)
    455                 return i;
    456         }
    457         i += opcodeLengths[currentOpcode];
    458     }
    459 
    460     ASSERT_NOT_REACHED();
    461     return 0;
    462 }
    463 
    464 static void printGlobalResolveInfo(const GlobalResolveInfo& resolveInfo, unsigned instructionOffset)
    465 {
    466     dataLog("  [%4d] %s: %s\n", instructionOffset, "resolve_global", pointerToSourceString(resolveInfo.structure).utf8().data());
    467 }
    468 #endif
    469 
    470442void CodeBlock::printStructure(const char* name, const Instruction* vPC, int operand)
    471443{
     
    505477    if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
    506478        printStructure("put_by_id_replace", vPC, 4);
    507         return;
    508     }
    509     if (vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global)) {
    510         printStructure("resolve_global", vPC, 4);
    511         return;
    512     }
    513     if (vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global_dynamic)) {
    514         printStructure("resolve_global_dynamic", vPC, 4);
    515479        return;
    516480    }
     
    578542
    579543#if ENABLE(JIT)
    580     if (!m_globalResolveInfos.isEmpty() || !m_structureStubInfos.isEmpty())
     544    if (!m_structureStubInfos.isEmpty())
    581545        dataLog("\nStructures:\n");
    582 
    583     if (!m_globalResolveInfos.isEmpty()) {
    584         size_t i = 0;
    585         do {
    586              printGlobalResolveInfo(m_globalResolveInfos[i], instructionOffsetForNth(exec, instructions(), i + 1, isGlobalResolve));
    587              ++i;
    588         } while (i < m_globalResolveInfos.size());
    589     }
    590546#endif
    591547
     
    903859            break;
    904860        }
    905         case op_resolve: {
    906             int r0 = (++it)->u.operand;
     861        case op_put_to_base_variable:
     862        case op_put_to_base: {
     863            int base = (++it)->u.operand;
    907864            int id0 = (++it)->u.operand;
    908             dataLog("[%4d] resolve\t\t %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
     865            int value = (++it)->u.operand;
     866            int resolveInfo = (++it)->u.operand;
     867            dataLog("[%4d] put_to_base\t %s, %s, %s, %d", location, registerName(exec, base).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, value).data(), resolveInfo);
     868            dumpBytecodeCommentAndNewLine(location);
     869            break;
     870        }
     871        case op_resolve:
     872        case op_resolve_global_property:
     873        case op_resolve_global_var:
     874        case op_resolve_scoped_var:
     875        case op_resolve_scoped_var_on_top_scope:
     876        case op_resolve_scoped_var_with_top_scope_check: {
     877            int r0 = (++it)->u.operand;
     878            int id0 = (++it)->u.operand;
     879            int resolveInfo = (++it)->u.operand;
     880            dataLog("[%4d] resolve\t\t %s, %s, %d", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo);
    909881            dumpBytecodeCommentAndNewLine(location);
    910882            it++;
    911883            break;
    912884        }
    913         case op_resolve_skip: {
    914             int r0 = (++it)->u.operand;
    915             int id0 = (++it)->u.operand;
    916             int skipLevels = (++it)->u.operand;
    917             dataLog("[%4d] resolve_skip\t %s, %s, %d", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), skipLevels);
    918             dumpBytecodeCommentAndNewLine(location);
    919             it++;
    920             break;
    921         }
    922         case op_resolve_global: {
    923             int r0 = (++it)->u.operand;
    924             int id0 = (++it)->u.operand;
    925             dataLog("[%4d] resolve_global\t %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
    926             dumpBytecodeCommentAndNewLine(location);
    927             it += 3;
    928             break;
    929         }
    930         case op_resolve_global_dynamic: {
    931             int r0 = (++it)->u.operand;
    932             int id0 = (++it)->u.operand;
    933             JSValue scope = JSValue((++it)->u.jsCell.get());
    934             ++it;
    935             int depth = (++it)->u.operand;
    936             dataLog("[%4d] resolve_global_dynamic\t %s, %s, %s, %d", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data(), depth);
    937             dumpBytecodeCommentAndNewLine(location);
    938             ++it;
    939             break;
    940         }
    941         case op_get_scoped_var: {
    942             int r0 = (++it)->u.operand;
    943             int index = (++it)->u.operand;
    944             int skipLevels = (++it)->u.operand;
    945             dataLog("[%4d] get_scoped_var\t %s, %d, %d", location, registerName(exec, r0).data(), index, skipLevels);
    946             dumpBytecodeCommentAndNewLine(location);
    947             it++;
    948             break;
    949         }
    950         case op_put_scoped_var: {
    951             int index = (++it)->u.operand;
    952             int skipLevels = (++it)->u.operand;
    953             int r0 = (++it)->u.operand;
    954             dataLog("[%4d] put_scoped_var\t %d, %d, %s", location, index, skipLevels, registerName(exec, r0).data());
    955             dumpBytecodeCommentAndNewLine(location);
    956             break;
    957         }
    958         case op_get_global_var: {
    959             int r0 = (++it)->u.operand;
     885        case op_init_global_const: {
    960886            WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
    961             dataLog("[%4d] get_global_var\t %s, g%d(%p)", location, registerName(exec, r0).data(), m_globalObject->findRegisterIndex(registerPointer), registerPointer);
    962             dumpBytecodeCommentAndNewLine(location);
    963             it++;
    964             break;
    965         }
    966         case op_get_global_var_watchable: {
    967             int r0 = (++it)->u.operand;
     887            int r0 = (++it)->u.operand;
     888            dataLog("[%4d] init_global_const\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
     889            dumpBytecodeCommentAndNewLine(location);
     890            break;
     891        }
     892        case op_init_global_const_check: {
    968893            WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
    969             dataLog("[%4d] get_global_var_watchable\t %s, g%d(%p)", location, registerName(exec, r0).data(), m_globalObject->findRegisterIndex(registerPointer), registerPointer);
     894            int r0 = (++it)->u.operand;
     895            dataLog("[%4d] init_global_const_check\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
    970896            dumpBytecodeCommentAndNewLine(location);
    971897            it++;
     
    973899            break;
    974900        }
    975         case op_put_global_var: {
    976             WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
    977             int r0 = (++it)->u.operand;
    978             dataLog("[%4d] put_global_var\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
    979             dumpBytecodeCommentAndNewLine(location);
    980             break;
    981         }
    982         case op_put_global_var_check: {
    983             WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
    984             int r0 = (++it)->u.operand;
    985             dataLog("[%4d] put_global_var_check\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
    986             dumpBytecodeCommentAndNewLine(location);
    987             it++;
    988             it++;
    989             break;
    990         }
    991         case op_init_global_const: {
    992             WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
    993             int r0 = (++it)->u.operand;
    994             dataLog("[%4d] init_global_const\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
    995             dumpBytecodeCommentAndNewLine(location);
    996             break;
    997         }
    998         case op_init_global_const_check: {
    999             WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
    1000             int r0 = (++it)->u.operand;
    1001             dataLog("[%4d] init_global_const_check\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
    1002             dumpBytecodeCommentAndNewLine(location);
    1003             it++;
    1004             it++;
    1005             break;
    1006         }
     901        case op_resolve_base_to_global:
     902        case op_resolve_base_to_global_dynamic:
     903        case op_resolve_base_to_scope:
     904        case op_resolve_base_to_scope_with_top_scope_check:
    1007905        case op_resolve_base: {
    1008906            int r0 = (++it)->u.operand;
    1009907            int id0 = (++it)->u.operand;
    1010908            int isStrict = (++it)->u.operand;
    1011             dataLog("[%4d] resolve_base%s\t %s, %s", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
     909            int resolveInfo = (++it)->u.operand;
     910            int putToBaseInfo = (++it)->u.operand;
     911            dataLog("[%4d] resolve_base%s\t %s, %s, %d, %d", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo, putToBaseInfo);
    1012912            dumpBytecodeCommentAndNewLine(location);
    1013913            it++;
     
    1025925            int r1 = (++it)->u.operand;
    1026926            int id0 = (++it)->u.operand;
    1027             dataLog("[%4d] resolve_with_base %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
     927            int resolveInfo = (++it)->u.operand;
     928            int putToBaseInfo = (++it)->u.operand;
     929            dataLog("[%4d] resolve_with_base %s, %s, %s, %d, %d", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo, putToBaseInfo);
    1028930            dumpBytecodeCommentAndNewLine(location);
    1029931            it++;
     
    1034936            int r1 = (++it)->u.operand;
    1035937            int id0 = (++it)->u.operand;
    1036             dataLog("[%4d] resolve_with_this %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
     938            int resolveInfo = (++it)->u.operand;
     939            dataLog("[%4d] resolve_with_this %s, %s, %s, %d", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo);
    1037940            dumpBytecodeCommentAndNewLine(location);
    1038941            it++;
     
    16981601    , m_argumentsRegister(other.m_argumentsRegister)
    16991602    , m_activationRegister(other.m_activationRegister)
     1603    , m_globalObjectConstant(other.m_globalObjectConstant)
    17001604    , m_needsFullScopeChain(other.m_needsFullScopeChain)
    17011605    , m_usesEval(other.m_usesEval)
     
    17051609    , m_source(other.m_source)
    17061610    , m_sourceOffset(other.m_sourceOffset)
    1707 #if ENABLE(JIT)
    1708     , m_globalResolveInfos(other.m_globalResolveInfos.size())
    1709 #endif
    17101611#if ENABLE(VALUE_PROFILER)
    17111612    , m_executionEntryCount(0)
     
    17221623    , m_reoptimizationRetryCounter(0)
    17231624    , m_lineInfo(other.m_lineInfo)
     1625    , m_resolveOperations(other.m_resolveOperations)
     1626    , m_putToBaseOperations(other.m_putToBaseOperations)
    17241627#if ENABLE(BYTECODE_COMMENTS)
    17251628    , m_bytecodeCommentIterator(0)
     
    17321635    optimizeAfterWarmUp();
    17331636    jitAfterWarmUp();
    1734 
    1735 #if ENABLE(JIT)
    1736     for (unsigned i = m_globalResolveInfos.size(); i--;)
    1737         m_globalResolveInfos[i] = GlobalResolveInfo(other.m_globalResolveInfos[i].bytecodeOffset);
    1738 #endif
    17391637
    17401638    if (other.m_rareData) {
     
    17811679{
    17821680    ASSERT(m_source);
    1783    
     1681
    17841682    optimizeAfterWarmUp();
    17851683    jitAfterWarmUp();
     
    17881686    liveCodeBlockSet.add(this);
    17891687#endif
     1688    // We have a stub putToBase operation to allow resolve_base to
     1689    // remain branchless
     1690    m_putToBaseOperations.append(PutToBaseOperation(isStrictMode()));
    17901691}
    17911692
     
    18841785    if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
    18851786        visitor.append(&vPC[4].u.structure);
    1886         return;
    1887     }
    1888     if (vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global) || vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global_dynamic)) {
    1889         if (vPC[3].u.structure)
    1890             visitor.append(&vPC[3].u.structure);
    18911787        return;
    18921788    }
     
    20421938static const bool verboseUnlinking = false;
    20431939#endif
    2044    
     1940
    20451941void CodeBlock::finalizeUnconditionally()
    20461942{
     
    20871983            }
    20881984        }
    2089         for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i) {
    2090             Instruction* curInstruction = &instructions()[m_globalResolveInstructions[i]];
    2091             ASSERT(interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global
    2092                    || interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global_dynamic);
    2093             if (!curInstruction[3].u.structure || Heap::isMarked(curInstruction[3].u.structure.get()))
    2094                 continue;
    2095             if (verboseUnlinking)
    2096                 dataLog("Clearing LLInt global resolve cache with structure %p.\n", curInstruction[3].u.structure.get());
    2097             curInstruction[3].u.structure.clear();
    2098             curInstruction[4].u.operand = 0;
    2099         }
     1985
    21001986        for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) {
    21011987            if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) {
     
    21242010    }
    21252011#endif // ENABLE(DFG_JIT)
    2126    
     2012
     2013    for (size_t size = m_putToBaseOperations.size(), i = 0; i < size; ++i) {
     2014        if (m_putToBaseOperations[i].m_structure && !Heap::isMarked(m_putToBaseOperations[i].m_structure.get())) {
     2015            if (verboseUnlinking)
     2016                dataLog("Clearing putToBase info in %p.\n", this);
     2017            m_putToBaseOperations[i].m_structure.clear();
     2018        }
     2019    }
     2020    for (size_t size = m_resolveOperations.size(), i = 0; i < size; ++i) {
     2021        if (m_resolveOperations[i].isEmpty())
     2022            continue;
     2023#ifndef NDEBUG
     2024        for (size_t insnSize = m_resolveOperations[i].size() - 1, k = 0; k < insnSize; ++k)
     2025            ASSERT(!m_resolveOperations[i][k].m_structure);
     2026#endif
     2027        m_resolveOperations[i].last().m_structure.clear();
     2028        if (m_resolveOperations[i].last().m_structure && !Heap::isMarked(m_resolveOperations[i].last().m_structure.get())) {
     2029            if (verboseUnlinking)
     2030                dataLog("Clearing resolve info in %p.\n", this);
     2031            m_resolveOperations[i].last().m_structure.clear();
     2032        }
     2033    }
     2034
    21272035#if ENABLE(JIT)
    21282036    // Handle inline caches.
     
    21392047                callLinkInfo(i).lastSeenCallee.clear();
    21402048        }
    2141         for (size_t size = m_globalResolveInfos.size(), i = 0; i < size; ++i) {
    2142             if (m_globalResolveInfos[i].structure && !Heap::isMarked(m_globalResolveInfos[i].structure.get())) {
    2143                 if (verboseUnlinking)
    2144                     dataLog("Clearing resolve info in %p.\n", this);
    2145                 m_globalResolveInfos[i].structure.clear();
    2146             }
    2147         }
    2148 
    21492049        for (size_t size = m_structureStubInfos.size(), i = 0; i < size; ++i) {
    21502050            StructureStubInfo& stubInfo = m_structureStubInfos[i];
     
    24162316}
    24172317
    2418 #if ENABLE(JIT)
    2419 bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
    2420 {
    2421     if (m_globalResolveInfos.isEmpty())
    2422         return false;
    2423 
    2424     int low = 0;
    2425     int high = m_globalResolveInfos.size();
    2426     while (low < high) {
    2427         int mid = low + (high - low) / 2;
    2428         if (m_globalResolveInfos[mid].bytecodeOffset <= bytecodeOffset)
    2429             low = mid + 1;
    2430         else
    2431             high = mid;
    2432     }
    2433 
    2434     if (!low || m_globalResolveInfos[low - 1].bytecodeOffset != bytecodeOffset)
    2435         return false;
    2436     return true;
    2437 }
    2438 GlobalResolveInfo& CodeBlock::globalResolveInfoForBytecodeOffset(unsigned bytecodeOffset)
    2439 {
    2440     return *(binarySearch<GlobalResolveInfo, unsigned, getGlobalResolveInfoBytecodeOffset>(m_globalResolveInfos.begin(), m_globalResolveInfos.size(), bytecodeOffset));
    2441 }
    2442 #endif
    2443 
    24442318void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
    24452319{
    24462320    m_propertyAccessInstructions.shrinkToFit();
    2447     m_globalResolveInstructions.shrinkToFit();
    24482321#if ENABLE(LLINT)
    24492322    m_llintCallLinkInfos.shrinkToFit();
     
    24512324#if ENABLE(JIT)
    24522325    m_structureStubInfos.shrinkToFit();
    2453     if (shrinkMode == EarlyShrink)
    2454         m_globalResolveInfos.shrinkToFit();
    24552326    m_callLinkInfos.shrinkToFit();
    24562327    m_methodCallLinkInfos.shrinkToFit();
     
    24712342    } // else don't shrink these, because we would have already pointed pointers into these tables.
    24722343
     2344    m_resolveOperations.shrinkToFit();
    24732345    m_lineInfo.shrinkToFit();
    24742346    if (m_rareData) {
Note: See TracChangeset for help on using the changeset viewer.