Ignore:
Timestamp:
Sep 15, 2021, 3:18:52 PM (4 years ago)
Author:
[email protected]
Message:

Move some profiling to UnlinkedCodeBlock
https://bugs.webkit.org/show_bug.cgi?id=230078
<rdar://problem/82947571>

Reviewed by Yusuke Suzuki.

This patch moves ValueProfiles and ArrayProfiles for non-call opcodes into
UnlinkedCodeBlock. This way, the data is shared between the linked CodeBlocks
of the same UnlinkedCodeBlock. The profiling bet here is that when the same code
runs in a different global object, it largely runs in the same way. We've made
this same bet in other ways with our profiling, and it largely makes sense
to do for ValueProfile and ArrayProfile since they both hold global object
independent data.

Because ArrayProfiles are now shared between CodeBlocks, the existing m_usesOriginalArrayStructures
bit is slightly harder to track now, since the ArrayProfile may see inputs from a different
global object, an array may be an original array in one lexical global object,
but not another. So we now track when an ArrayProfile sees a different global
object than the lexical global object, and when we observe exits in the DFG,
we propagate that bit to the m_usesOriginalArrayStructures bit.

This patch also makes it so we no longer hold the CodeBlock lock when
processing ValueProfiles and ArrayProfiles. We now allow multiple compiler
threads to race against each other when updating these profiles. This is fine.
It may end up with incomplete data in the profiles, but it won't corrupt them.

This patch also makes it so we finalized visited UnlinkedCodeBlocks to finalize
their value profiles. We no longer do that work inside CodeBlock for the
ValueProfiles that UnlinkedCodeBlock owns. This also means that we have to
WriteBarrier UnlinkedCodeBlock when executing in the LLInt, Baseline, and
other areas, such as OSR exit, and in the GC when a CodeBlock was executing.
That way we're guaranteed to visit the UnlinkedCodeBlock, add it to the
visited set, and then finalize it at the end of GC.

This patch also makes it so that inside CodeBlock::finishCreation, we finish
linking before we do anything that can throw an exception. It's not valid to
finalize a CodeBlock that isn't linked.

This was measured as a 0.5-1% speedup on Speedometer2.

  • bytecode/ArrayProfile.cpp:

(JSC::ArrayProfile::computeUpdatedPrediction):
(JSC::ArrayProfile::briefDescription):
(JSC::ArrayProfile::briefDescriptionWithoutUpdating):

  • bytecode/ArrayProfile.h:

(JSC::ArrayProfile::ArrayProfile):
(JSC::ArrayProfile::observedArrayModes const):
(JSC::ArrayProfile::mayInterceptIndexedAccesses const):
(JSC::ArrayProfile::mayStoreToHole const):
(JSC::ArrayProfile::outOfBounds const):
(JSC::ArrayProfile::usesOriginalArrayStructures const):
(JSC::ArrayProfile::setDoesNotUseOriginalArrayStructures):
(JSC::ArrayProfile::observedDifferentGlobalObject const):

  • bytecode/BytecodeList.rb:
  • bytecode/BytecodeOperandsForCheckpoint.h:

(JSC::valueProfileForImpl):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::setConstantRegisters):
(JSC::CodeBlock::initializeTemplateObjects):
(JSC::CodeBlock::setNumParameters):
(JSC::CodeBlock::visitChildren):
(JSC::CodeBlock::finalizeUnconditionally):
(JSC::CodeBlock::getArrayProfile):
(JSC::CodeBlock::updateAllValueProfilePredictionsAndCountLiveness):
(JSC::CodeBlock::updateAllArrayPredictions):
(JSC::CodeBlock::tryGetValueProfileForBytecodeIndex):
(JSC::CodeBlock::valueProfilePredictionForBytecodeIndex):

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::offsetOfUnlinkedCodeBlock):
(JSC::CodeBlock::numberOfArgumentValueProfiles):
(JSC::CodeBlock::valueProfileForArgument):
(JSC::CodeBlock::metadata):

  • bytecode/CodeBlockInlines.h:

(JSC::CodeBlock::forEachValueProfile):
(JSC::CodeBlock::forEachArrayProfile):

  • bytecode/DFGExitProfile.cpp:

(JSC::DFG::ExitProfile::hasAnyExitsAt const):

  • bytecode/DFGExitProfile.h:
  • bytecode/GetByIdMetadata.h:

(JSC::GetByIdModeMetadata::setArrayLengthMode):

  • bytecode/LazyOperandValueProfile.cpp:

(JSC::CompressedLazyOperandValueProfileHolder::computeUpdatedPredictions):
(JSC::LazyOperandValueProfileParser::prediction const):

  • bytecode/MetadataTable.cpp:

(JSC::DeallocTable::withOpcodeType):

  • bytecode/MetadataTable.h:

(JSC::MetadataTable::get):
(JSC::MetadataTable::forEach):
(JSC::MetadataTable::getWithoutAligning):
(JSC::MetadataTable::getImpl): Deleted.

  • bytecode/Opcode.h:
  • bytecode/UnlinkedCodeBlock.cpp:

(JSC::UnlinkedCodeBlock::visitChildrenImpl):
(JSC::UnlinkedCodeBlock::allocateSharedProfiles):
(JSC::UnlinkedCodeBlock::finalizeUnconditionally):

  • bytecode/UnlinkedCodeBlock.h:

(JSC::UnlinkedCodeBlock::hasAnyExitsAt const):
(JSC::UnlinkedCodeBlock::hasAnyExitsAt):
(JSC::UnlinkedCodeBlock::valueProfile):
(JSC::UnlinkedCodeBlock::arrayProfile):
(JSC::UnlinkedCodeBlock::numValueProfiles const):
(JSC::UnlinkedCodeBlock::numArrayProfiles const):

  • bytecode/UnlinkedCodeBlockGenerator.cpp:

(JSC::UnlinkedCodeBlockGenerator::finalize):

  • bytecode/UnlinkedMetadataTable.cpp:

(JSC::UnlinkedMetadataTable::finalize):

  • bytecode/UnlinkedMetadataTable.h:

(JSC::UnlinkedMetadataTable::isFinalized):
(JSC::UnlinkedMetadataTable::hasMetadata):

  • bytecode/UnlinkedMetadataTableInlines.h:

(JSC::UnlinkedMetadataTable::numEntries):

  • bytecode/ValueProfile.h:

(JSC::ValueProfileBase::ValueProfileBase):
(JSC::ValueProfileBase::clearBuckets):
(JSC::ValueProfileBase::briefDescription):
(JSC::ValueProfileBase::computeUpdatedPrediction):
(JSC::ValueProfile::offsetOfFirstBucket):
(JSC::ValueProfileBase::classInfo const): Deleted.

  • dfg/DFGArrayMode.cpp:

(JSC::DFG::ArrayMode::fromObserved):

  • dfg/DFGArrayMode.h:

(JSC::DFG::ArrayMode::withSpeculationFromProfile const):
(JSC::DFG::ArrayMode::withProfile const):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
(JSC::DFG::ByteCodeParser::getArrayMode):
(JSC::DFG::ByteCodeParser::handleVarargsInlining):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::handlePutByVal):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::attemptToMakeGetArrayLength):

  • dfg/DFGGraph.h:
  • dfg/DFGOSRExitCompilerCommon.cpp:

(JSC::DFG::osrWriteBarrier):
(JSC::DFG::adjustAndJumpToTarget):

  • dfg/DFGPredictionInjectionPhase.cpp:

(JSC::DFG::PredictionInjectionPhase::run):

  • heap/CodeBlockSetInlines.h:

(JSC::CodeBlockSet::iterateViaSubspaces):

  • heap/Heap.cpp:

(JSC::Heap::finalizeMarkedUnconditionalFinalizers):
(JSC::Heap::finalizeUnconditionalFinalizers):
(JSC::Heap::deleteUnmarkedCompiledCode):
(JSC::Heap::runEndPhase):
(JSC::Heap::addCoreConstraints):

  • jit/JIT.h:
  • jit/JITInlines.h:

(JSC::JIT::emitValueProfilingSiteIfProfiledOpcode):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_enter):
(JSC::JIT::op_enter_handlerGenerator):

  • jit/JITOperations.cpp:

(JSC::putByValOptimize):
(JSC::directPutByValOptimize):
(JSC::JSC_DEFINE_JIT_OPERATION):

  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::generateGetByValSlowCase):
(JSC::JIT::emit_op_put_by_val):
(JSC::JIT::emitSlow_op_put_by_val):
(JSC::JIT::emit_op_get_by_id):
(JSC::JIT::emit_op_in_by_val):
(JSC::JIT::emitSlow_op_in_by_val):
(JSC::JIT::generateOpGetFromScopeThunk):
(JSC::JIT::slow_op_get_from_scopeGenerator):
(JSC::JIT::emit_op_enumerator_get_by_val):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emitSlow_op_get_by_val):
(JSC::JIT::emit_op_put_by_val):
(JSC::JIT::emitSlow_op_put_by_val):
(JSC::JIT::emit_op_get_by_id):
(JSC::JIT::emit_op_in_by_val):
(JSC::JIT::emitSlow_op_in_by_val):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::performLLIntGetByID):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
(JSC::LLInt::getByVal):

  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • profiler/ProfilerBytecodeSequence.cpp:

(JSC::Profiler::BytecodeSequence::BytecodeSequence):

  • runtime/CachedTypes.cpp:

(JSC::CachedCodeBlock::numValueProfiles const):
(JSC::CachedCodeBlock::numArrayProfiles const):
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
(JSC::CachedCodeBlock<CodeBlockType>::encode):

  • runtime/CommonSlowPaths.cpp:

(JSC::iteratorNextTryFastImpl):
(JSC::JSC_DEFINE_COMMON_SLOW_PATH):

  • runtime/JSScope.cpp:

(JSC::abstractAccess):
(JSC::JSScope::abstractResolve):

  • runtime/VM.cpp:
  • runtime/VM.h:

(JSC::VM::forEachUnlinkedCodeBlockSpace):
(JSC::VM::forEachCodeBlockSpace): Deleted.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r281684 r282478  
    375375    JSScope* scope)
    376376{
     377    // We can't finalize a GC while in here since we need to make sure to
     378    // make sure our ValueProfiles and ArrayProfiles all point to proper locations.
     379    RELEASE_ASSERT(vm.heap.isDeferred());
     380
    377381    Base::finishCreation(vm);
    378382    finishCreationCommon(vm);
     
    384388
    385389    ScriptExecutable* topLevelExecutable = ownerExecutable->topLevelExecutable();
    386     setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation(), topLevelExecutable);
    387     RETURN_IF_EXCEPTION(throwScope, false);
     390
     391    // We wait to initialize template objects until the end of finishCreation beecause it can
     392    // throw. We rely on linking to put the CodeBlock into a coherent state, so we can't throw
     393    // until we're all done linking.
     394    Vector<unsigned> templateObjectIndices = setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation());
    388395
    389396    // We already have the cloned symbol table for the module environment since we need to instantiate
     
    436443    HashSet<JSModuleEnvironment*> stronglyReferencedModuleEnvironments;
    437444
    438     auto link_profile = [&](const auto& /*instruction*/, auto /*bytecode*/, auto& /*metadata*/) {
     445    auto link_profile = [&](const auto& /*instruction*/, auto /*bytecode*/, auto& metadata) {
     446        static_assert(std::is_same_v<ValueProfile*, decltype(metadata.m_profile)>);
    439447        m_numberOfNonArgumentValueProfiles++;
    440448    };
     
    500508        LINK(OpGetById, profile)
    501509
    502         LINK(OpEnumeratorNext, profile)
    503         LINK(OpEnumeratorInByVal, profile)
    504         LINK(OpEnumeratorHasOwnProperty, profile)
     510        LINK(OpEnumeratorNext)
     511        LINK(OpEnumeratorInByVal)
     512        LINK(OpEnumeratorHasOwnProperty)
    505513        LINK(OpEnumeratorGetByVal, profile)
    506514
     
    564572
    565573            ResolveOp op = JSScope::abstractResolve(m_globalObject.get(), bytecode.m_localScopeDepth, scope, ident, Get, bytecode.m_resolveType, InitializationMode::NotInitialization);
    566             RETURN_IF_EXCEPTION(throwScope, false);
    567574
    568575            metadata.m_resolveType = op.type;
     
    599606            const Identifier& ident = identifier(bytecode.m_var);
    600607            ResolveOp op = JSScope::abstractResolve(m_globalObject.get(), bytecode.m_localScopeDepth, scope, ident, Get, bytecode.m_getPutInfo.resolveType(), InitializationMode::NotInitialization);
    601             RETURN_IF_EXCEPTION(throwScope, false);
    602608
    603609            metadata.m_getPutInfo = GetPutInfo(bytecode.m_getPutInfo.resolveMode(), op.type, bytecode.m_getPutInfo.initializationMode(), bytecode.m_getPutInfo.ecmaMode());
     
    633639            metadata.m_watchpointSet = nullptr;
    634640            ResolveOp op = JSScope::abstractResolve(m_globalObject.get(), bytecode.m_symbolTableOrScopeDepth.scopeDepth(), scope, ident, Put, bytecode.m_getPutInfo.resolveType(), bytecode.m_getPutInfo.initializationMode());
    635             RETURN_IF_EXCEPTION(throwScope, false);
    636641
    637642            metadata.m_getPutInfo = GetPutInfo(bytecode.m_getPutInfo.resolveMode(), op.type, bytecode.m_getPutInfo.initializationMode(), bytecode.m_getPutInfo.ecmaMode());
     
    666671                // we're abstractly "read"ing from a JSScope.
    667672                ResolveOp op = JSScope::abstractResolve(m_globalObject.get(), localScopeDepth, scope, ident, Get, bytecode.m_resolveType, InitializationMode::NotInitialization);
    668                 RETURN_IF_EXCEPTION(throwScope, false);
    669673
    670674                if (op.type == ClosureVar || op.type == ModuleVar)
     
    762766#undef LINK
    763767
     768    {
     769        unsigned index = numberOfArgumentValueProfiles(); // The first numberOfArgumentValueProfiles() profiles are argument value profiles
     770
     771        if (m_metadata) {
     772            auto assign = [&] (ValueProfile*& profile) {
     773                profile = &unlinkedCodeBlock->valueProfile(index++);
     774            };
     775
     776#define VISIT(__op) \
     777            m_metadata->forEach<__op>([&] (auto& metadata) { assign(metadata.m_profile); });
     778            FOR_EACH_OPCODE_WITH_VALUE_PROFILE(VISIT)
     779#undef VISIT
     780
     781            m_metadata->forEach<OpIteratorOpen>([&] (auto& metadata) {
     782                assign(metadata.m_iterableProfile);
     783                assign(metadata.m_iteratorProfile);
     784                assign(metadata.m_nextProfile);
     785            });
     786
     787            m_metadata->forEach<OpIteratorNext>([&] (auto& metadata) {
     788                assign(metadata.m_nextResultProfile);
     789                assign(metadata.m_doneProfile);
     790                assign(metadata.m_valueProfile);
     791            });
     792        }
     793
     794        RELEASE_ASSERT(index == unlinkedCodeBlock->numValueProfiles());
     795    }
     796
     797    if (m_metadata) {
     798        unsigned index = 0;
     799
     800        auto assign = [&] (ArrayProfile*& profile) {
     801            profile = &unlinkedCodeBlock->arrayProfile(index++);
     802        };
     803
     804        // We only share array profiles for the opcodes in FOR_EACH_OPCODE_WITH_ARRAY_PROFILE.
     805        // We don't yet share array profiles for things with LLInt CallLinkInfos.
     806#define VISIT(__op) \
     807        m_metadata->forEach<__op>([&] (auto& metadata) { assign(metadata.m_arrayProfile); });
     808        FOR_EACH_OPCODE_WITH_ARRAY_PROFILE(VISIT)
     809#undef VISIT
     810
     811        m_metadata->forEach<OpIteratorNext>([&] (auto& metadata) {
     812            assign(metadata.m_iterableProfile);
     813        });
     814
     815        RELEASE_ASSERT(index == unlinkedCodeBlock->numArrayProfiles());
     816    }
     817
    764818    if (m_unlinkedCode->wasCompiledWithControlFlowProfilerOpcodes())
    765819        insertBasicBlockBoundariesForControlFlowProfiler();
     
    781835    if (m_metadata)
    782836        vm.heap.reportExtraMemoryAllocated(m_metadata->sizeInBytes());
     837
     838    initializeTemplateObjects(topLevelExecutable, templateObjectIndices);
     839    RETURN_IF_EXCEPTION(throwScope, false);
    783840
    784841    return true;
     
    870927}
    871928
    872 void CodeBlock::setConstantRegisters(const FixedVector<WriteBarrier<Unknown>>& constants, const FixedVector<SourceCodeRepresentation>& constantsSourceCodeRepresentation, ScriptExecutable* topLevelExecutable)
     929Vector<unsigned> CodeBlock::setConstantRegisters(const FixedVector<WriteBarrier<Unknown>>& constants, const FixedVector<SourceCodeRepresentation>& constantsSourceCodeRepresentation)
    873930{
    874931    VM& vm = *m_vm;
    875     auto scope = DECLARE_THROW_SCOPE(vm);
    876932    JSGlobalObject* globalObject = m_globalObject.get();
    877933
     934    Vector<unsigned> templateObjectIndices;
     935
    878936    ASSERT(constants.size() == constantsSourceCodeRepresentation.size());
    879     size_t count = constants.size();
     937    unsigned count = constants.size();
    880938    {
    881939        ConcurrentJSLocker locker(m_lock);
    882940        m_constantRegisters.resizeToFit(count);
    883941    }
    884     for (size_t i = 0; i < count; i++) {
     942    for (unsigned i = 0; i < count; i++) {
    885943        JSValue constant = constants[i].get();
    886944        SourceCodeRepresentation representation = constantsSourceCodeRepresentation[i];
     
    906964
    907965                        constant = clone;
    908                     } else if (auto* descriptor = jsDynamicCast<JSTemplateObjectDescriptor*>(vm, cell)) {
    909                         auto* templateObject = topLevelExecutable->createTemplateObject(globalObject, descriptor);
    910                         RETURN_IF_EXCEPTION(scope, void());
    911                         constant = templateObject;
    912                     }
     966                    } else if (jsDynamicCast<JSTemplateObjectDescriptor*>(vm, cell))
     967                        templateObjectIndices.append(i);
    913968                }
    914969            }
     
    917972        m_constantRegisters[i].set(vm, this, constant);
    918973    }
     974
     975    return templateObjectIndices;
     976}
     977
     978void CodeBlock::initializeTemplateObjects(ScriptExecutable* topLevelExecutable, const Vector<unsigned>& templateObjectIndices)
     979{
     980    auto scope = DECLARE_THROW_SCOPE(vm());
     981    for (unsigned i : templateObjectIndices) {
     982        auto* descriptor = jsCast<JSTemplateObjectDescriptor*>(m_constantRegisters[i].get());
     983        auto* templateObject = topLevelExecutable->createTemplateObject(globalObject(), descriptor);
     984        RETURN_IF_EXCEPTION(scope, void());
     985        m_constantRegisters[i].set(vm(), this, templateObject);
     986    }
    919987}
    920988
     
    929997{
    930998    m_numParameters = newValue;
    931 
    932     m_argumentValueProfiles = FixedVector<ValueProfile>(Options::useJIT() ? newValue : 0);
    933999}
    9341000
     
    9911057    stronglyVisitWeakReferences(locker, visitor);
    9921058   
    993     VM::SpaceAndSet::setFor(*subspace()).add(this);
     1059    vm().codeBlockSpace.set.add(this);
    9941060}
    9951061
     
    15181584    UNUSED_PARAM(vm);
    15191585
    1520     updateAllPredictions();
     1586    {
     1587        // We only update the profiles that the UnlinkedCodeBlock doesn't own.
     1588
     1589        if (m_metadata) {
     1590#define UPDATE(__op) \
     1591            m_metadata->forEach<__op>([&] (auto& metadata) { metadata.m_callLinkInfo.m_arrayProfile.computeUpdatedPrediction(this); });
     1592            FOR_EACH_OPCODE_WITH_LLINT_CALL_LINK_INFO(UPDATE)
     1593#undef UPDATE
     1594
     1595            m_metadata->forEach<OpCatch>([&](auto& metadata) {
     1596                if (metadata.m_buffer) {
     1597                    metadata.m_buffer->forEach([&](ValueProfileAndVirtualRegister& profile) {
     1598                        profile.computeUpdatedPrediction();
     1599                    });
     1600                }
     1601            });
     1602        }
     1603
     1604        {
     1605            ConcurrentJSLocker locker(m_lock);
     1606#if ENABLE(DFG_JIT)
     1607            lazyOperandValueProfiles(locker).computeUpdatedPredictions(locker);
     1608#endif
     1609        }
     1610
     1611        forEachArrayAllocationProfile([&](ArrayAllocationProfile& profile) {
     1612            profile.updateProfile();
     1613        });
     1614    }
    15211615
    15221616#if ENABLE(JIT)
     
    16041698    updateActivity();
    16051699
    1606     VM::SpaceAndSet::setFor(*subspace()).remove(this);
     1700    vm.codeBlockSpace.set.remove(this);
    16071701
    16081702    // In CodeBlock::shouldVisitStrongly() we may have decided to skip visiting this
     
    27742868#define CASE1(Op) \
    27752869    case Op::opcodeID: \
    2776         return &instruction->as<Op>().metadata(this).m_arrayProfile;
     2870        return instruction->as<Op>().metadata(this).m_arrayProfile;
    27772871
    27782872#define CASE2(Op) \
     
    27862880#undef CASE2
    27872881
    2788     case OpGetById::opcodeID: {
    2789         auto bytecode = instruction->as<OpGetById>();
    2790         auto& metadata = bytecode.metadata(this);
    2791         if (metadata.m_modeMetadata.mode == GetByIdMode::ArrayLength)
    2792             return &metadata.m_modeMetadata.arrayLengthMode.arrayProfile;
    2793         break;
    2794     }
    27952882    default:
    27962883        break;
     
    29012988        numberOfSamplesInProfiles += numSamples;
    29022989        if (isArgument) {
    2903             profile.computeUpdatedPrediction(locker);
     2990            profile.computeUpdatedPrediction();
    29042991            return;
    29052992        }
    29062993        if (profile.numberOfSamples() || profile.isSampledBefore())
    29072994            numberOfLiveNonArgumentValueProfiles++;
    2908         profile.computeUpdatedPrediction(locker);
     2995        profile.computeUpdatedPrediction();
    29092996    });
    29102997
     
    29133000            if (metadata.m_buffer) {
    29143001                metadata.m_buffer->forEach([&](ValueProfileAndVirtualRegister& profile) {
    2915                     profile.computeUpdatedPrediction(locker);
     3002                    profile.computeUpdatedPrediction();
    29163003                });
    29173004            }
     
    29323019void CodeBlock::updateAllArrayPredictions()
    29333020{
    2934     ConcurrentJSLocker locker(m_lock);
    2935    
    29363021    forEachArrayProfile([&](ArrayProfile& profile) {
    2937         profile.computeUpdatedPrediction(locker, this);
     3022        profile.computeUpdatedPrediction(this);
    29383023    });
    29393024   
     
    31653250#define CASE(Op) \
    31663251    case Op::opcodeID: \
    3167         return &instruction->as<Op>().metadata(this).m_profile;
     3252        return instruction->as<Op>().metadata(this).m_profile;
    31683253
    31693254        FOR_EACH_OPCODE_WITH_VALUE_PROFILE(CASE)
     
    31823267}
    31833268
    3184 SpeculatedType CodeBlock::valueProfilePredictionForBytecodeIndex(const ConcurrentJSLocker& locker, BytecodeIndex bytecodeIndex)
     3269SpeculatedType CodeBlock::valueProfilePredictionForBytecodeIndex(BytecodeIndex bytecodeIndex)
    31853270{
    31863271    if (ValueProfile* valueProfile = tryGetValueProfileForBytecodeIndex(bytecodeIndex))
    3187         return valueProfile->computeUpdatedPrediction(locker);
     3272        return valueProfile->computeUpdatedPrediction();
    31883273    return SpecNone;
    31893274}
Note: See TracChangeset for help on using the changeset viewer.