Changeset 190522 in webkit


Ignore:
Timestamp:
Oct 2, 2015 2:16:20 PM (8 years ago)
Author:
ggaren@apple.com
Message:

Unreviewed, rolling back in r190450
https://bugs.webkit.org/show_bug.cgi?id=149727

The cause of the crash was a CodeBlock, after surviving a call to
deleteAllCode by virtue of being in the remembered set, trying to mark
its inlined CodeBlocks via pointers from its inlined executables.
Since deleteAllCode clears those pointers, the CodeBlock would ASSERT.
(Any other choice to retain a CodeBlock after deleteAllCode -- for
example, conservative marking -- could trigger the same bug.)

The fix is for InlineCallFrame to point directly to its inlined CodeBlock
instead of pointing indirectly via an executable. This guarantees that
CodeBlocks are GC safe regardless of whether we've called deleteAllCode.

Restored changesets:

"CodeBlock should be a GC object"
https://bugs.webkit.org/show_bug.cgi?id=149727
http://trac.webkit.org/changeset/190450

Location:
trunk/Source/JavaScriptCore
Files:
56 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r190520 r190522  
     12015-10-01  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Unreviewed, rolling back in r190450
     4        https://bugs.webkit.org/show_bug.cgi?id=149727
     5
     6        The cause of the crash was a CodeBlock, after surviving a call to
     7        deleteAllCode by virtue of being in the remembered set, trying to mark
     8        its inlined CodeBlocks via pointers from its inlined executables.
     9        Since deleteAllCode clears those pointers, the CodeBlock would ASSERT.
     10        (Any other choice to retain a CodeBlock after deleteAllCode -- for
     11        example, conservative marking -- could trigger the same bug.)
     12
     13        The fix is for InlineCallFrame to point directly to its inlined CodeBlock
     14        instead of pointing indirectly via an executable. This guarantees that
     15        CodeBlocks are GC safe regardless of whether we've called deleteAllCode.
     16
     17        Restored changesets:
     18
     19        "CodeBlock should be a GC object"
     20        https://bugs.webkit.org/show_bug.cgi?id=149727
     21        http://trac.webkit.org/changeset/190450
     22
    1232015-10-02  Joseph Pecoraro  <pecoraro@apple.com>
    224
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r190453 r190522  
    8383namespace JSC {
    8484
     85const ClassInfo CodeBlock::s_info = {
     86    "CodeBlock", 0, 0,
     87    CREATE_METHOD_TABLE(CodeBlock)
     88};
     89
     90const ClassInfo FunctionCodeBlock::s_info = {
     91    "FunctionCodeBlock", &Base::s_info, 0,
     92    CREATE_METHOD_TABLE(FunctionCodeBlock)
     93};
     94
     95#if ENABLE(WEBASSEMBLY)
     96const ClassInfo WebAssemblyCodeBlock::s_info = {
     97    "WebAssemblyCodeBlock", &Base::s_info, 0,
     98    CREATE_METHOD_TABLE(WebAssemblyCodeBlock)
     99};
     100#endif
     101
     102const ClassInfo GlobalCodeBlock::s_info = {
     103    "GlobalCodeBlock", &Base::s_info, 0,
     104    CREATE_METHOD_TABLE(GlobalCodeBlock)
     105};
     106
     107const ClassInfo ProgramCodeBlock::s_info = {
     108    "ProgramCodeBlock", &Base::s_info, 0,
     109    CREATE_METHOD_TABLE(ProgramCodeBlock)
     110};
     111
     112const ClassInfo ModuleProgramCodeBlock::s_info = {
     113    "ModuleProgramCodeBlock", &Base::s_info, 0,
     114    CREATE_METHOD_TABLE(ModuleProgramCodeBlock)
     115};
     116
     117const ClassInfo EvalCodeBlock::s_info = {
     118    "EvalCodeBlock", &Base::s_info, 0,
     119    CREATE_METHOD_TABLE(EvalCodeBlock)
     120};
     121
     122void FunctionCodeBlock::destroy(JSCell* cell)
     123{
     124    jsCast<FunctionCodeBlock*>(cell)->~FunctionCodeBlock();
     125}
     126
     127#if ENABLE(WEBASSEMBLY)
     128void WebAssemblyCodeBlock::destroy(JSCell* cell)
     129{
     130    jsCast<WebAssemblyCodeBlock*>(cell)->~WebAssemblyCodeBlock();
     131}
     132#endif
     133
     134void ProgramCodeBlock::destroy(JSCell* cell)
     135{
     136    jsCast<ProgramCodeBlock*>(cell)->~ProgramCodeBlock();
     137}
     138
     139void ModuleProgramCodeBlock::destroy(JSCell* cell)
     140{
     141    jsCast<ModuleProgramCodeBlock*>(cell)->~ModuleProgramCodeBlock();
     142}
     143
     144void EvalCodeBlock::destroy(JSCell* cell)
     145{
     146    jsCast<EvalCodeBlock*>(cell)->~EvalCodeBlock();
     147}
     148
    85149CString CodeBlock::inferredName() const
    86150{
     
    154218    out.print(":[", RawPointer(this), "->");
    155219    if (!!m_alternative)
    156         out.print(RawPointer(m_alternative.get()), "->");
     220        out.print(RawPointer(alternative()), "->");
    157221    out.print(RawPointer(ownerExecutable()), ", ", jitType, codeType());
    158222
     
    15861650} // anonymous namespace
    15871651
    1588 CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
    1589     : m_globalObject(other.m_globalObject)
     1652CodeBlock::CodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, CodeBlock& other)
     1653    : JSCell(*vm, structure)
     1654    , m_globalObject(other.m_globalObject)
    15901655    , m_heap(other.m_heap)
    15911656    , m_numCalleeRegisters(other.m_numCalleeRegisters)
     
    15951660    , m_didFailFTLCompilation(false)
    15961661    , m_hasBeenCompiledWithFTL(false)
    1597     , m_unlinkedCode(*other.m_vm, other.m_ownerExecutable.get(), other.m_unlinkedCode.get())
     1662    , m_unlinkedCode(*other.m_vm, this, other.m_unlinkedCode.get())
    15981663    , m_hasDebuggerStatement(false)
    15991664    , m_steppingMode(SteppingModeDisabled)
    16001665    , m_numBreakpoints(0)
    1601     , m_ownerExecutable(*other.m_vm, other.m_ownerExecutable.get(), other.m_ownerExecutable.get())
     1666    , m_ownerExecutable(*other.m_vm, this, other.m_ownerExecutable.get())
    16021667    , m_vm(other.m_vm)
    16031668    , m_instructions(other.m_instructions)
     
    16241689#endif
    16251690{
    1626     m_visitStronglyHasBeenCalled.store(false, std::memory_order_relaxed);
    1627     m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
     1691    m_visitWeaklyHasBeenCalled.store(false, std::memory_order_relaxed);
    16281692
    16291693    ASSERT(m_heap->isDeferred());
     
    16311695
    16321696    setNumParameters(other.numParameters());
     1697}
     1698
     1699void CodeBlock::finishCreation(VM& vm, CopyParsedBlockTag, CodeBlock& other)
     1700{
     1701    Base::finishCreation(vm);
     1702
    16331703    optimizeAfterWarmUp();
    16341704    jitAfterWarmUp();
     
    16441714   
    16451715    m_heap->m_codeBlocks.add(this);
    1646     m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock));
    1647 }
    1648 
    1649 CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
    1650     : m_globalObject(scope->globalObject()->vm(), ownerExecutable, scope->globalObject())
     1716}
     1717
     1718CodeBlock::CodeBlock(VM* vm, Structure* structure, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock,
     1719    JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
     1720    : JSCell(*vm, structure)
     1721    , m_globalObject(scope->globalObject()->vm(), this, scope->globalObject())
    16511722    , m_heap(&m_globalObject->vm().heap)
    16521723    , m_numCalleeRegisters(unlinkedCodeBlock->m_numCalleeRegisters)
     
    16561727    , m_didFailFTLCompilation(false)
    16571728    , m_hasBeenCompiledWithFTL(false)
    1658     , m_unlinkedCode(m_globalObject->vm(), ownerExecutable, unlinkedCodeBlock)
     1729    , m_unlinkedCode(m_globalObject->vm(), this, unlinkedCodeBlock)
    16591730    , m_hasDebuggerStatement(false)
    16601731    , m_steppingMode(SteppingModeDisabled)
    16611732    , m_numBreakpoints(0)
    1662     , m_ownerExecutable(m_globalObject->vm(), ownerExecutable, ownerExecutable)
     1733    , m_ownerExecutable(m_globalObject->vm(), this, ownerExecutable)
    16631734    , m_vm(unlinkedCodeBlock->vm())
    16641735    , m_thisRegister(unlinkedCodeBlock->thisRegister())
     
    16791750#endif
    16801751{
    1681     m_visitStronglyHasBeenCalled.store(false, std::memory_order_relaxed);
    1682     m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
     1752    m_visitWeaklyHasBeenCalled.store(false, std::memory_order_relaxed);
    16831753
    16841754    ASSERT(m_heap->isDeferred());
     
    16871757    ASSERT(m_source);
    16881758    setNumParameters(unlinkedCodeBlock->numParameters());
    1689 
    1690     if (vm()->typeProfiler() || vm()->controlFlowProfiler())
    1691         vm()->functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(), ownerExecutable->typeProfilingEndOffset());
     1759}
     1760
     1761void CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock,
     1762    JSScope* scope)
     1763{
     1764    Base::finishCreation(vm);
     1765
     1766    if (vm.typeProfiler() || vm.controlFlowProfiler())
     1767        vm.functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(), ownerExecutable->typeProfilingEndOffset());
    16921768
    16931769    setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation());
    16941770    if (unlinkedCodeBlock->usesGlobalObject())
    1695         m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, ownerExecutable, m_globalObject.get());
     1771        m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, this, m_globalObject.get());
    16961772
    16971773    for (unsigned i = 0; i < LinkTimeConstantCount; i++) {
    16981774        LinkTimeConstant type = static_cast<LinkTimeConstant>(i);
    16991775        if (unsigned registerIndex = unlinkedCodeBlock->registerIndexForLinkTimeConstant(type))
    1700             m_constantRegisters[registerIndex].set(*m_vm, ownerExecutable, m_globalObject->jsCellForLinkTimeConstant(type));
     1776            m_constantRegisters[registerIndex].set(*m_vm, this, m_globalObject->jsCellForLinkTimeConstant(type));
    17011777    }
    17021778
     
    17131789                    symbolTable->prepareForTypeProfiling(locker);
    17141790                }
    1715                 m_constantRegisters[i].set(*m_vm, ownerExecutable, symbolTable->cloneScopePart(*m_vm));
     1791                m_constantRegisters[i].set(*m_vm, this, symbolTable->cloneScopePart(*m_vm));
    17161792                clonedConstantSymbolTables.add(i + FirstConstantRegisterIndex);
    17171793            }
     
    17331809    for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) {
    17341810        UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
    1735         if (vm()->typeProfiler() || vm()->controlFlowProfiler())
    1736             vm()->functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
    1737         m_functionDecls[i].set(*m_vm, ownerExecutable, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
     1811        if (vm.typeProfiler() || vm.controlFlowProfiler())
     1812            vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
     1813        m_functionDecls[i].set(*m_vm, this, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
    17381814    }
    17391815
     
    17411817    for (size_t count = unlinkedCodeBlock->numberOfFunctionExprs(), i = 0; i < count; ++i) {
    17421818        UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i);
    1743         if (vm()->typeProfiler() || vm()->controlFlowProfiler())
    1744             vm()->functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
    1745         m_functionExprs[i].set(*m_vm, ownerExecutable, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
     1819        if (vm.typeProfiler() || vm.controlFlowProfiler())
     1820            vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
     1821        m_functionExprs[i].set(*m_vm, this, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
    17461822    }
    17471823
     
    18221898        unsigned opLength = opcodeLength(pc[0].u.opcode);
    18231899
    1824         instructions[i] = vm()->interpreter->getOpcode(pc[0].u.opcode);
     1900        instructions[i] = vm.interpreter->getOpcode(pc[0].u.opcode);
    18251901        for (size_t j = 1; j < opLength; ++j) {
    18261902            if (sizeof(int32_t) != sizeof(intptr_t))
     
    18811957
    18821958            instructions[i + opLength - 1] = objectAllocationProfile;
    1883             objectAllocationProfile->initialize(*vm(),
     1959            objectAllocationProfile->initialize(vm,
    18841960                ownerExecutable, m_globalObject->objectPrototype(), inferredInlineCapacity);
    18851961            break;
     
    19302006                    if (stronglyReferencedModuleEnvironments.add(jsCast<JSModuleEnvironment*>(op.lexicalEnvironment)).isNewEntry)
    19312007                        addConstant(op.lexicalEnvironment);
    1932                     instructions[i + 6].u.jsCell.set(*vm(), ownerExecutable, op.lexicalEnvironment);
     2008                    instructions[i + 6].u.jsCell.set(vm, this, op.lexicalEnvironment);
    19332009                } else
    1934                     instructions[i + 6].u.symbolTable.set(*vm(), ownerExecutable, op.lexicalEnvironment->symbolTable());
     2010                    instructions[i + 6].u.symbolTable.set(vm, this, op.lexicalEnvironment->symbolTable());
    19352011            } else if (JSScope* constantScope = JSScope::constantScopeForCodeBlock(op.type, this))
    1936                 instructions[i + 6].u.jsCell.set(*vm(), ownerExecutable, constantScope);
     2012                instructions[i + 6].u.jsCell.set(vm, this, constantScope);
    19372013            else
    19382014                instructions[i + 6].u.pointer = nullptr;
     
    19672043                instructions[i + 5].u.watchpointSet = op.watchpointSet;
    19682044            else if (op.structure)
    1969                 instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
     2045                instructions[i + 5].u.structure.set(vm, this, op.structure);
    19702046            instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand);
    19712047            break;
     
    20042080                    op.watchpointSet->invalidate(PutToScopeFireDetail(this, ident));
    20052081            } else if (op.structure)
    2006                 instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
     2082                instructions[i + 5].u.structure.set(vm, this, op.structure);
    20072083            instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand);
    20082084
     
    20112087
    20122088        case op_profile_type: {
    2013             RELEASE_ASSERT(vm()->typeProfiler());
     2089            RELEASE_ASSERT(vm.typeProfiler());
    20142090            // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
    20152091            size_t instructionOffset = i + opLength - 1;
     
    20412117                    // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet.
    20422118                    symbolTable->prepareForTypeProfiling(locker);
    2043                     globalVariableID = symbolTable->uniqueIDForVariable(locker, impl, *vm());
    2044                     globalTypeSet = symbolTable->globalTypeSetForVariable(locker, impl, *vm());
     2119                    globalVariableID = symbolTable->uniqueIDForVariable(locker, impl, vm);
     2120                    globalTypeSet = symbolTable->globalTypeSetForVariable(locker, impl, vm);
    20452121                } else
    20462122                    globalVariableID = TypeProfilerNoGlobalIDExists;
     
    20552131                ConcurrentJITLocker locker(symbolTable->m_lock);
    20562132                // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet.
    2057                 globalVariableID = symbolTable->uniqueIDForVariable(locker, ident.impl(), *vm());
    2058                 globalTypeSet = symbolTable->globalTypeSetForVariable(locker, ident.impl(), *vm());
     2133                globalVariableID = symbolTable->uniqueIDForVariable(locker, ident.impl(), vm);
     2134                globalTypeSet = symbolTable->globalTypeSetForVariable(locker, ident.impl(), vm);
    20592135
    20602136                break;
     
    20822158            }
    20832159
    2084             std::pair<TypeLocation*, bool> locationPair = vm()->typeProfiler()->typeLocationCache()->getTypeLocation(globalVariableID,
    2085                 ownerExecutable->sourceID(), divotStart, divotEnd, globalTypeSet, vm());
     2160            std::pair<TypeLocation*, bool> locationPair = vm.typeProfiler()->typeLocationCache()->getTypeLocation(globalVariableID,
     2161                ownerExecutable->sourceID(), divotStart, divotEnd, globalTypeSet, &vm);
    20862162            TypeLocation* location = locationPair.first;
    20872163            bool isNewLocation = locationPair.second;
     
    20912167
    20922168            if (shouldAnalyze && isNewLocation)
    2093                 vm()->typeProfiler()->insertNewLocation(location);
     2169                vm.typeProfiler()->insertNewLocation(location);
    20942170
    20952171            instructions[i + 2].u.location = location;
     
    21092185    }
    21102186
    2111     if (vm()->controlFlowProfiler())
     2187    if (vm.controlFlowProfiler())
    21122188        insertBasicBlockBoundariesForControlFlowProfiler(instructions);
    21132189
     
    21292205   
    21302206    m_heap->m_codeBlocks.add(this);
    2131     m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock) + m_instructions.size() * sizeof(Instruction));
     2207    m_heap->reportExtraMemoryAllocated(m_instructions.size() * sizeof(Instruction));
    21322208}
    21332209
    21342210#if ENABLE(WEBASSEMBLY)
    2135 CodeBlock::CodeBlock(WebAssemblyExecutable* ownerExecutable, VM& vm, JSGlobalObject* globalObject)
    2136     : m_globalObject(globalObject->vm(), ownerExecutable, globalObject)
     2211CodeBlock::CodeBlock(VM* vm, Structure* structure, WebAssemblyExecutable* ownerExecutable, VM& vm, JSGlobalObject* globalObject)
     2212    : JSCell(vm, structure)
     2213    , m_globalObject(globalObject->vm(), this, globalObject)
    21372214    , m_heap(&m_globalObject->vm().heap)
    21382215    , m_numCalleeRegisters(0)
     
    21452222    , m_steppingMode(SteppingModeDisabled)
    21462223    , m_numBreakpoints(0)
    2147     , m_ownerExecutable(m_globalObject->vm(), ownerExecutable, ownerExecutable)
     2224    , m_ownerExecutable(m_globalObject->vm(), this, ownerExecutable)
    21482225    , m_vm(&vm)
    21492226    , m_isStrictMode(false)
     
    21592236{
    21602237    ASSERT(m_heap->isDeferred());
     2238}
     2239
     2240void CodeBlock::finishCreation(VM& vm, WebAssemblyExecutable*, JSGlobalObject*)
     2241{
     2242    Base::finishCreation(vm);
    21612243
    21622244    m_heap->m_codeBlocks.add(this);
    2163     m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock));
    21642245}
    21652246#endif
     
    21732254    dumpValueProfiles();
    21742255#endif
    2175     while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
    2176         m_incomingLLIntCalls.begin()->remove();
    2177 #if ENABLE(JIT)
     2256
    21782257    // We may be destroyed before any CodeBlocks that refer to us are destroyed.
    21792258    // Consider that two CodeBlocks become unreachable at the same time. There
     
    21822261    // CodeBlock(s) that have calls into us, then the CallLinkInfo vector's
    21832262    // destructor will try to remove nodes from our (no longer valid) linked list.
    2184     while (m_incomingCalls.begin() != m_incomingCalls.end())
    2185         m_incomingCalls.begin()->remove();
    2186     while (m_incomingPolymorphicCalls.begin() != m_incomingPolymorphicCalls.end())
    2187         m_incomingPolymorphicCalls.begin()->remove();
     2263    unlinkIncomingCalls();
    21882264   
    21892265    // Note that our outgoing calls will be removed from other CodeBlocks'
     
    21912267    // destructors.
    21922268
     2269#if ENABLE(JIT)
    21932270    for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter)
    21942271        (*iter)->deref();
    21952272#endif // ENABLE(JIT)
     2273}
     2274
     2275void CodeBlock::setAlternative(VM& vm, CodeBlock* alternative)
     2276{
     2277    m_alternative.set(vm, this, alternative);
    21962278}
    21972279
     
    22162298        return 0;
    22172299    DFG::JITCode* jitCode = m_jitCode->dfg();
    2218     return jitCode->osrEntryBlock.get();
     2300    return jitCode->osrEntryBlock();
    22192301#else // ENABLE(FTL_JIT)
    22202302    return 0;
     
    22222304}
    22232305
    2224 void CodeBlock::visitStrongly(SlotVisitor& visitor)
    2225 {
    2226     bool setByMe = m_visitStronglyHasBeenCalled.compareExchangeStrong(false, true);
     2306void CodeBlock::visitWeakly(SlotVisitor& visitor)
     2307{
     2308    bool setByMe = m_visitWeaklyHasBeenCalled.compareExchangeStrong(false, true);
    22272309    if (!setByMe)
    22282310        return;
    22292311
    2230     visitAggregate(visitor);
    2231 
    2232     stronglyVisitStrongReferences(visitor);
    2233     stronglyVisitWeakReferences(visitor);
    2234     propagateTransitions(visitor);
    2235 }
    2236 
    2237 void CodeBlock::visitAggregate(SlotVisitor& visitor)
    2238 {
    2239     // I may be asked to scan myself more than once, and it may even happen concurrently.
    2240     // To this end, use an atomic operation to check (and set) if I've been called already.
    2241     // Only one thread may proceed past this point - whichever one wins the atomic set race.
    2242     bool setByMe = m_visitAggregateHasBeenCalled.compareExchangeStrong(false, true);
    2243     if (!setByMe)
     2312    if (Heap::isMarked(this))
    22442313        return;
    2245    
    2246     if (!!m_alternative)
    2247         m_alternative->visitAggregate(visitor);
    2248    
    2249     if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
    2250         otherBlock->visitAggregate(visitor);
    2251 
    2252     visitor.reportExtraMemoryVisited(ownerExecutable(), sizeof(CodeBlock));
    2253     if (m_jitCode)
    2254         visitor.reportExtraMemoryVisited(ownerExecutable(), m_jitCode->size());
    2255     if (m_instructions.size()) {
    2256         // Divide by refCount() because m_instructions points to something that is shared
    2257         // by multiple CodeBlocks, and we only want to count it towards the heap size once.
    2258         // Having each CodeBlock report only its proportional share of the size is one way
    2259         // of accomplishing this.
    2260         visitor.reportExtraMemoryVisited(ownerExecutable(), m_instructions.size() * sizeof(Instruction) / m_instructions.refCount());
    2261     }
    2262 
    2263     visitor.append(&m_unlinkedCode);
     2314
     2315    if (shouldVisitStrongly()) {
     2316        visitor.appendUnbarrieredReadOnlyPointer(this);
     2317        return;
     2318    }
    22642319
    22652320    // There are two things that may use unconditional finalizers: inline cache clearing
     
    22672322    // is probably quite close to 1. So we add one no matter what and when it runs, it
    22682323    // figures out whether it has any work to do.
    2269     visitor.addUnconditionalFinalizer(this);
    2270    
    2271     m_allTransitionsHaveBeenMarked = false;
    2272    
    2273     if (shouldVisitStrongly()) {
    2274         visitStrongly(visitor);
    2275         return;
    2276     }
    2277    
     2324    visitor.addUnconditionalFinalizer(&m_unconditionalFinalizer);
     2325
    22782326    if (!JITCode::isOptimizingJIT(jitType()))
    22792327        return;
    22802328
     2329    // If we jettison ourselves we'll install our alternative, so make sure that it
     2330    // survives GC even if we don't.
     2331    visitor.append(&m_alternative);
     2332   
    22812333    // There are two things that we use weak reference harvesters for: DFG fixpoint for
    22822334    // jettisoning, and trying to find structures that would be live based on some
    22832335    // inline cache. So it makes sense to register them regardless.
    2284     visitor.addWeakReferenceHarvester(this);
     2336    visitor.addWeakReferenceHarvester(&m_weakReferenceHarvester);
    22852337
    22862338#if ENABLE(DFG_JIT)
     
    22932345    // other reasons, that this iteration should run again; it will notify us of this
    22942346    // decision by calling harvestWeakReferences().
    2295    
     2347
     2348    m_allTransitionsHaveBeenMarked = false;
     2349    propagateTransitions(visitor);
     2350
    22962351    m_jitCode->dfgCommon()->livenessHasBeenProved = false;
    2297    
    2298     propagateTransitions(visitor);
    22992352    determineLiveness(visitor);
    23002353#endif // ENABLE(DFG_JIT)
     2354}
     2355
     2356void CodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
     2357{
     2358    CodeBlock* thisObject = jsCast<CodeBlock*>(cell);
     2359    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     2360    JSCell::visitChildren(thisObject, visitor);
     2361    thisObject->visitChildren(visitor);
     2362}
     2363
     2364void CodeBlock::visitChildren(SlotVisitor& visitor)
     2365{
     2366    // There are two things that may use unconditional finalizers: inline cache clearing
     2367    // and jettisoning. The probability of us wanting to do at least one of those things
     2368    // is probably quite close to 1. So we add one no matter what and when it runs, it
     2369    // figures out whether it has any work to do.
     2370    visitor.addUnconditionalFinalizer(&m_unconditionalFinalizer);
     2371
     2372    if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
     2373        visitor.appendUnbarrieredReadOnlyPointer(otherBlock);
     2374
     2375    if (m_jitCode)
     2376        visitor.reportExtraMemoryVisited(this, m_jitCode->size());
     2377    if (m_instructions.size())
     2378        visitor.reportExtraMemoryVisited(this, m_instructions.size() * sizeof(Instruction) / m_instructions.refCount());
     2379
     2380    visitor.append(&m_unlinkedCode);
     2381
     2382    stronglyVisitStrongReferences(visitor);
     2383    stronglyVisitWeakReferences(visitor);
     2384
     2385    m_allTransitionsHaveBeenMarked = false;
     2386    propagateTransitions(visitor);
    23012387}
    23022388
     
    23282414    // - Code blocks that don't have any dead weak references.
    23292415
    2330     if (m_visitStronglyHasBeenCalled.load(std::memory_order_relaxed))
    2331         return true;
    2332 
    2333 #if ENABLE(DFG_JIT)
    2334     if (JITCode::isOptimizingJIT(jitType())) {
    2335         if (m_jitCode->dfgCommon()->livenessHasBeenProved)
    2336             return true;
    2337     }
    2338 #endif
    2339 
    2340     return false;
     2416    return Heap::isMarked(this);
    23412417}
    23422418
     
    23482424}
    23492425
     2426static std::chrono::milliseconds timeToLive(JITCode::JITType jitType)
     2427{
     2428    switch (jitType) {
     2429    case JITCode::InterpreterThunk:
     2430        return std::chrono::duration_cast<std::chrono::milliseconds>(
     2431            std::chrono::seconds(5));
     2432    case JITCode::BaselineJIT:
     2433        // Effectively 10 additional seconds, since BaselineJIT and
     2434        // InterpreterThunk share a CodeBlock.
     2435        return std::chrono::duration_cast<std::chrono::milliseconds>(
     2436            std::chrono::seconds(15));
     2437    case JITCode::DFGJIT:
     2438        return std::chrono::duration_cast<std::chrono::milliseconds>(
     2439            std::chrono::seconds(20));
     2440    case JITCode::FTLJIT:
     2441        return std::chrono::duration_cast<std::chrono::milliseconds>(
     2442            std::chrono::seconds(60));
     2443    default:
     2444        return std::chrono::milliseconds::max();
     2445    }
     2446}
     2447
    23502448bool CodeBlock::shouldJettisonDueToOldAge()
    23512449{
    2352     if (m_visitStronglyHasBeenCalled.load(std::memory_order_relaxed))
     2450    if (Heap::isMarked(this))
    23532451        return false;
    23542452
    2355     if (timeSinceCreation() < JITCode::timeToLive(jitType()))
     2453    if (timeSinceCreation() < timeToLive(jitType()))
    23562454        return false;
    23572455
     
    25062604    // come back here again, and scan the strong references.
    25072605    dfgCommon->livenessHasBeenProved = true;
    2508     stronglyVisitStrongReferences(visitor);
     2606    visitor.appendUnbarrieredReadOnlyPointer(this);
    25092607#endif // ENABLE(DFG_JIT)
    25102608}
    25112609
    2512 void CodeBlock::visitWeakReferences(SlotVisitor& visitor)
    2513 {
    2514     propagateTransitions(visitor);
    2515     determineLiveness(visitor);
     2610void CodeBlock::WeakReferenceHarvester::visitWeakReferences(SlotVisitor& visitor)
     2611{
     2612    CodeBlock* codeBlock =
     2613        bitwise_cast<CodeBlock*>(
     2614            bitwise_cast<char*>(this) - OBJECT_OFFSETOF(CodeBlock, m_weakReferenceHarvester));
     2615
     2616    codeBlock->propagateTransitions(visitor);
     2617    codeBlock->determineLiveness(visitor);
    25162618}
    25172619
     
    26332735}
    26342736
    2635 void CodeBlock::finalizeUnconditionally()
    2636 {
     2737void CodeBlock::UnconditionalFinalizer::finalizeUnconditionally()
     2738{
     2739    CodeBlock* codeBlock = bitwise_cast<CodeBlock*>(
     2740        bitwise_cast<char*>(this) - OBJECT_OFFSETOF(CodeBlock, m_unconditionalFinalizer));
     2741
    26372742#if ENABLE(DFG_JIT)
    2638     if (shouldJettisonDueToWeakReference()) {
    2639         jettison(Profiler::JettisonDueToWeakReference);
     2743    if (codeBlock->shouldJettisonDueToWeakReference()) {
     2744        codeBlock->jettison(Profiler::JettisonDueToWeakReference);
    26402745        return;
    26412746    }
    26422747#endif // ENABLE(DFG_JIT)
    26432748
    2644     if (shouldJettisonDueToOldAge()) {
    2645         jettison(Profiler::JettisonDueToOldAge);
     2749    if (codeBlock->shouldJettisonDueToOldAge()) {
     2750        codeBlock->jettison(Profiler::JettisonDueToOldAge);
    26462751        return;
    26472752    }
    26482753
    2649     if (JITCode::couldBeInterpreted(jitType()))
    2650         finalizeLLIntInlineCaches();
     2754    if (JITCode::couldBeInterpreted(codeBlock->jitType()))
     2755        codeBlock->finalizeLLIntInlineCaches();
    26512756
    26522757#if ENABLE(JIT)
    2653     if (!!jitCode())
    2654         finalizeBaselineJITInlineCaches();
     2758    if (!!codeBlock->jitCode())
     2759        codeBlock->finalizeBaselineJITInlineCaches();
    26552760#endif
    26562761}
     
    27472852    // the OSR exit against.
    27482853
    2749     alternative()->visitStrongly(visitor);
     2854    visitor.append(&m_alternative);
    27502855
    27512856#if ENABLE(DFG_JIT)
     
    27532858    if (dfgCommon->inlineCallFrames) {
    27542859        for (auto* inlineCallFrame : *dfgCommon->inlineCallFrames) {
    2755             ASSERT(inlineCallFrame->baselineCodeBlock());
    2756             inlineCallFrame->baselineCodeBlock()->visitStrongly(visitor);
     2860            ASSERT(inlineCallFrame->baselineCodeBlock);
     2861            visitor.append(&inlineCallFrame->baselineCodeBlock);
    27572862        }
    27582863    }
     
    29633068        m_incomingLLIntCalls.begin()->unlink();
    29643069#if ENABLE(JIT)
    2965     if (m_incomingCalls.isEmpty() && m_incomingPolymorphicCalls.isEmpty())
    2966         return;
    29673070    while (m_incomingCalls.begin() != m_incomingCalls.end())
    29683071        m_incomingCalls.begin()->unlink(*vm());
     
    29783081}
    29793082
    2980 PassRefPtr<CodeBlock> CodeBlock::newReplacement()
     3083CodeBlock* CodeBlock::newReplacement()
    29813084{
    29823085    return ownerScriptExecutable()->newReplacementCodeBlockFor(specializationKind());
     
    29843087
    29853088#if ENABLE(JIT)
    2986 CodeBlock* ProgramCodeBlock::replacement()
    2987 {
    2988     return jsCast<ProgramExecutable*>(ownerExecutable())->codeBlock();
    2989 }
    2990 
    2991 CodeBlock* ModuleProgramCodeBlock::replacement()
    2992 {
    2993     return jsCast<ModuleProgramExecutable*>(ownerExecutable())->codeBlock();
    2994 }
    2995 
    2996 CodeBlock* EvalCodeBlock::replacement()
    2997 {
    2998     return jsCast<EvalExecutable*>(ownerExecutable())->codeBlock();
    2999 }
    3000 
    3001 CodeBlock* FunctionCodeBlock::replacement()
    3002 {
    3003     return jsCast<FunctionExecutable*>(ownerExecutable())->codeBlockFor(m_isConstructor ? CodeForConstruct : CodeForCall);
    3004 }
    3005 
    3006 DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal()
    3007 {
    3008     return DFG::programCapabilityLevel(this);
    3009 }
    3010 
    3011 DFG::CapabilityLevel ModuleProgramCodeBlock::capabilityLevelInternal()
    3012 {
    3013     return DFG::programCapabilityLevel(this);
    3014 }
    3015 
    3016 DFG::CapabilityLevel EvalCodeBlock::capabilityLevelInternal()
    3017 {
    3018     return DFG::evalCapabilityLevel(this);
    3019 }
    3020 
    3021 DFG::CapabilityLevel FunctionCodeBlock::capabilityLevelInternal()
    3022 {
    3023     if (m_isConstructor)
    3024         return DFG::functionForConstructCapabilityLevel(this);
    3025     return DFG::functionForCallCapabilityLevel(this);
    3026 }
     3089CodeBlock* CodeBlock::replacement()
     3090{
     3091    const ClassInfo* classInfo = this->classInfo();
     3092
     3093    if (classInfo == FunctionCodeBlock::info())
     3094        return jsCast<FunctionExecutable*>(ownerExecutable())->codeBlockFor(m_isConstructor ? CodeForConstruct : CodeForCall);
     3095
     3096    if (classInfo == EvalCodeBlock::info())
     3097        return jsCast<EvalExecutable*>(ownerExecutable())->codeBlock();
     3098
     3099    if (classInfo == ProgramCodeBlock::info())
     3100        return jsCast<ProgramExecutable*>(ownerExecutable())->codeBlock();
     3101
     3102    if (classInfo == ModuleProgramCodeBlock::info())
     3103        return jsCast<ModuleProgramExecutable*>(ownerExecutable())->codeBlock();
    30273104
    30283105#if ENABLE(WEBASSEMBLY)
    3029 CodeBlock* WebAssemblyCodeBlock::replacement()
    3030 {
     3106    if (classInfo == WebAssemblyCodeBlock::info())
     3107        return nullptr
     3108#endif
     3109
     3110    RELEASE_ASSERT_NOT_REACHED();
    30313111    return nullptr;
    30323112}
    30333113
    3034 DFG::CapabilityLevel WebAssemblyCodeBlock::capabilityLevelInternal()
    3035 {
     3114DFG::CapabilityLevel CodeBlock::computeCapabilityLevel()
     3115{
     3116    const ClassInfo* classInfo = this->classInfo();
     3117
     3118    if (classInfo == FunctionCodeBlock::info()) {
     3119        if (m_isConstructor)
     3120            return DFG::functionForConstructCapabilityLevel(this);
     3121        return DFG::functionForCallCapabilityLevel(this);
     3122    }
     3123
     3124    if (classInfo == EvalCodeBlock::info())
     3125        return DFG::evalCapabilityLevel(this);
     3126
     3127    if (classInfo == ProgramCodeBlock::info())
     3128        return DFG::programCapabilityLevel(this);
     3129
     3130    if (classInfo == ModuleProgramCodeBlock::info())
     3131        return DFG::programCapabilityLevel(this);
     3132
     3133#if ENABLE(WEBASSEMBLY)
     3134    if (classInfo == WebAssemblyCodeBlock::info())
     3135        return DFG::CannotCompile;
     3136#endif
     3137
     3138    RELEASE_ASSERT_NOT_REACHED();
    30363139    return DFG::CannotCompile;
    30373140}
    3038 #endif
    3039 #endif
     3141
     3142#endif // ENABLE(JIT)
    30403143
    30413144void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode, const FireDetail* detail)
     
    31413244    if (!codeOrigin.inlineCallFrame)
    31423245        return globalObject();
    3143     return jsCast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())->eitherCodeBlock()->globalObject();
     3246    return codeOrigin.inlineCallFrame->baselineCodeBlock->globalObject();
    31443247}
    31453248
     
    39814084DFG::CapabilityLevel CodeBlock::capabilityLevel()
    39824085{
    3983     DFG::CapabilityLevel result = capabilityLevelInternal();
     4086    DFG::CapabilityLevel result = computeCapabilityLevel();
    39844087    m_capabilityLevelState = result;
    39854088    return result;
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r190453 r190522  
    3939#include "CodeBlockHash.h"
    4040#include "CodeBlockSet.h"
    41 #include "ConcurrentJITLock.h"
    4241#include "CodeOrigin.h"
    4342#include "CodeType.h"
    4443#include "CompactJITCodeMap.h"
     44#include "ConcurrentJITLock.h"
    4545#include "DFGCommon.h"
    4646#include "DFGExitProfile.h"
     
    5050#include "ExpressionRangeInfo.h"
    5151#include "HandlerInfo.h"
    52 #include "ObjectAllocationProfile.h"
    53 #include "Options.h"
    54 #include "PutPropertySlot.h"
    5552#include "Instruction.h"
    5653#include "JITCode.h"
    5754#include "JITWriteBarrier.h"
     55#include "JSCell.h"
    5856#include "JSGlobalObject.h"
    5957#include "JumpTable.h"
    6058#include "LLIntCallLinkInfo.h"
    6159#include "LazyOperandValueProfile.h"
     60#include "ObjectAllocationProfile.h"
     61#include "Options.h"
    6262#include "ProfilerCompilation.h"
    6363#include "ProfilerJettisonReason.h"
     64#include "PutPropertySlot.h"
    6465#include "RegExpObject.h"
    6566#include "StructureStubInfo.h"
     
    8687enum ReoptimizationMode { DontCountReoptimization, CountReoptimization };
    8788
    88 class CodeBlock : public ThreadSafeRefCounted<CodeBlock>, public UnconditionalFinalizer, public WeakReferenceHarvester {
    89     WTF_MAKE_FAST_ALLOCATED;
     89class CodeBlock : public JSCell {
     90    typedef JSCell Base;
    9091    friend class BytecodeLivenessAnalysis;
    9192    friend class JIT;
    9293    friend class LLIntOffsetsExtractor;
     94
     95    class UnconditionalFinalizer : public JSC::UnconditionalFinalizer {
     96        virtual void finalizeUnconditionally() override;
     97    };
     98
     99    class WeakReferenceHarvester : public JSC::WeakReferenceHarvester {
     100        virtual void visitWeakReferences(SlotVisitor&) override;
     101    };
     102
    93103public:
    94104    enum CopyParsedBlockTag { CopyParsedBlock };
     105
     106    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
     107
     108    DECLARE_INFO;
     109
    95110protected:
    96     CodeBlock(CopyParsedBlockTag, CodeBlock& other);
    97        
    98     CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSScope*, PassRefPtr<SourceProvider>, unsigned sourceOffset, unsigned firstLineColumnOffset);
     111    CodeBlock(VM*, Structure*, CopyParsedBlockTag, CodeBlock& other);
     112    CodeBlock(VM*, Structure*, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSScope*, PassRefPtr<SourceProvider>, unsigned sourceOffset, unsigned firstLineColumnOffset);
    99113#if ENABLE(WEBASSEMBLY)
    100     CodeBlock(WebAssemblyExecutable* ownerExecutable, VM&, JSGlobalObject*);
     114    CodeBlock(VM*, Structure*, WebAssemblyExecutable* ownerExecutable, VM&, JSGlobalObject*);
     115#endif
     116
     117    void finishCreation(VM&, CopyParsedBlockTag, CodeBlock& other);
     118    void finishCreation(VM&, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSScope*);
     119#if ENABLE(WEBASSEMBLY)
     120    void finishCreation(VM&, WebAssemblyExecutable* ownerExecutable, JSGlobalObject*);
    101121#endif
    102122
     
    105125
    106126public:
    107     JS_EXPORT_PRIVATE virtual ~CodeBlock();
     127    JS_EXPORT_PRIVATE ~CodeBlock();
    108128
    109129    UnlinkedCodeBlock* unlinkedCodeBlock() const { return m_unlinkedCode.get(); }
     
    125145    static ptrdiff_t offsetOfNumParameters() { return OBJECT_OFFSETOF(CodeBlock, m_numParameters); }
    126146
    127     CodeBlock* alternative() { return m_alternative.get(); }
    128     void setAlternative(PassRefPtr<CodeBlock> alternative) { m_alternative = alternative; }
     147    CodeBlock* alternative() const { return static_cast<CodeBlock*>(m_alternative.get()); }
     148    void setAlternative(VM&, CodeBlock*);
    129149
    130150    template <typename Functor> void forEachRelatedCodeBlock(Functor&& functor)
     
    149169        return specializationFromIsConstruct(m_isConstructor);
    150170    }
    151    
     171
     172    CodeBlock* alternativeForJettison();   
    152173    CodeBlock* baselineAlternative();
    153174   
     
    156177    CodeBlock* baselineVersion();
    157178
    158     void clearMarks();
    159     void visitAggregate(SlotVisitor&);
    160     void visitStrongly(SlotVisitor&);
     179    static void visitChildren(JSCell*, SlotVisitor&);
     180    void visitChildren(SlotVisitor&);
     181    void visitWeakly(SlotVisitor&);
     182    void clearVisitWeaklyHasBeenCalled();
    161183
    162184    void dumpSource();
     
    266288
    267289    // Exactly equivalent to codeBlock->ownerExecutable()->newReplacementCodeBlockFor(codeBlock->specializationKind())
    268     PassRefPtr<CodeBlock> newReplacement();
     290    CodeBlock* newReplacement();
    269291   
    270292    void setJITCode(PassRefPtr<JITCode> code)
     
    292314   
    293315#if ENABLE(JIT)
    294     virtual CodeBlock* replacement() = 0;
    295 
    296     virtual DFG::CapabilityLevel capabilityLevelInternal() = 0;
     316    CodeBlock* replacement();
     317
     318    DFG::CapabilityLevel computeCapabilityLevel();
    297319    DFG::CapabilityLevel capabilityLevel();
    298320    DFG::CapabilityLevel capabilityLevelState() { return m_capabilityLevelState; }
     
    544566        unsigned result = m_constantRegisters.size();
    545567        m_constantRegisters.append(WriteBarrier<Unknown>());
    546         m_constantRegisters.last().set(m_globalObject->vm(), m_ownerExecutable.get(), v);
     568        m_constantRegisters.last().set(m_globalObject->vm(), this, v);
    547569        m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
    548570        return result;
     
    896918
    897919protected:
    898     virtual void visitWeakReferences(SlotVisitor&) override;
    899     virtual void finalizeUnconditionally() override;
    900920    void finalizeLLIntInlineCaches();
    901921    void finalizeBaselineJITInlineCaches();
     
    924944        m_constantRegisters.resizeToFit(count);
    925945        for (size_t i = 0; i < count; i++)
    926             m_constantRegisters[i].set(*m_vm, ownerExecutable(), constants[i].get());
     946            m_constantRegisters[i].set(*m_vm, this, constants[i].get());
    927947        m_constantsSourceCodeRepresentation = constantsSourceCodeRepresentation;
    928948    }
     
    931951    {
    932952        ASSERT(isConstantRegisterIndex(index) && static_cast<size_t>(index - FirstConstantRegisterIndex) < m_constantRegisters.size());
    933         m_constantRegisters[index - FirstConstantRegisterIndex].set(m_globalObject->vm(), m_ownerExecutable.get(), value);
     953        m_constantRegisters[index - FirstConstantRegisterIndex].set(m_globalObject->vm(), this, value);
    934954    }
    935955
     
    10031023    bool m_needsActivation;
    10041024
    1005     Atomic<bool> m_visitAggregateHasBeenCalled;
    1006     Atomic<bool> m_visitStronglyHasBeenCalled;
     1025    Atomic<bool> m_visitWeaklyHasBeenCalled;
    10071026
    10081027    RefPtr<SourceProvider> m_source;
     
    10461065    Vector<WriteBarrier<FunctionExecutable>> m_functionExprs;
    10471066
    1048     RefPtr<CodeBlock> m_alternative;
     1067    WriteBarrier<CodeBlock> m_alternative;
    10491068   
    10501069    BaselineExecutionCounter m_llintExecuteCounter;
     
    10661085    DFG::CapabilityLevel m_capabilityLevelState;
    10671086#endif
     1087
     1088    UnconditionalFinalizer m_unconditionalFinalizer;
     1089    WeakReferenceHarvester m_weakReferenceHarvester;
    10681090};
    10691091
     
    10721094
    10731095class GlobalCodeBlock : public CodeBlock {
     1096    typedef CodeBlock Base;
     1097    DECLARE_INFO;
     1098
    10741099protected:
    1075     GlobalCodeBlock(CopyParsedBlockTag, GlobalCodeBlock& other)
    1076     : CodeBlock(CopyParsedBlock, other)
    1077     {
    1078     }
    1079        
    1080     GlobalCodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
    1081         : CodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset)
     1100    GlobalCodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, GlobalCodeBlock& other)
     1101        : CodeBlock(vm, structure, CopyParsedBlock, other)
     1102    {
     1103    }
     1104
     1105    GlobalCodeBlock(VM* vm, Structure* structure, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
     1106        : CodeBlock(vm, structure, ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset)
    10821107    {
    10831108    }
     
    10861111class ProgramCodeBlock : public GlobalCodeBlock {
    10871112public:
    1088     ProgramCodeBlock(CopyParsedBlockTag, ProgramCodeBlock& other)
    1089     : GlobalCodeBlock(CopyParsedBlock, other)
    1090     {
    1091     }
    1092 
    1093     ProgramCodeBlock(ProgramExecutable* ownerExecutable, UnlinkedProgramCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
    1094         : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset)
    1095     {
    1096     }
    1097 
    1098 #if ENABLE(JIT)
    1099 protected:
    1100     virtual CodeBlock* replacement() override;
    1101     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
    1102 #endif
     1113    typedef GlobalCodeBlock Base;
     1114    DECLARE_INFO;
     1115
     1116    static ProgramCodeBlock* create(VM* vm, CopyParsedBlockTag, ProgramCodeBlock& other)
     1117    {
     1118        ProgramCodeBlock* instance = new (NotNull, allocateCell<ProgramCodeBlock>(vm->heap))
     1119            ProgramCodeBlock(vm, vm->programCodeBlockStructure.get(), CopyParsedBlock, other);
     1120        instance->finishCreation(*vm, CopyParsedBlock, other);
     1121        return instance;
     1122    }
     1123
     1124    static ProgramCodeBlock* create(VM* vm, ProgramExecutable* ownerExecutable, UnlinkedProgramCodeBlock* unlinkedCodeBlock,
     1125        JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
     1126    {
     1127        ProgramCodeBlock* instance = new (NotNull, allocateCell<ProgramCodeBlock>(vm->heap))
     1128            ProgramCodeBlock(vm, vm->programCodeBlockStructure.get(), ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, firstLineColumnOffset);
     1129        instance->finishCreation(*vm, ownerExecutable, unlinkedCodeBlock, scope);
     1130        return instance;
     1131    }
     1132
     1133    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     1134    {
     1135        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     1136    }
     1137
     1138private:
     1139    ProgramCodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, ProgramCodeBlock& other)
     1140        : GlobalCodeBlock(vm, structure, CopyParsedBlock, other)
     1141    {
     1142    }
     1143
     1144    ProgramCodeBlock(VM* vm, Structure* structure, ProgramExecutable* ownerExecutable, UnlinkedProgramCodeBlock* unlinkedCodeBlock,
     1145        JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
     1146        : GlobalCodeBlock(vm, structure, ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset)
     1147    {
     1148    }
     1149
     1150    static void destroy(JSCell*);
    11031151};
    11041152
    11051153class ModuleProgramCodeBlock : public GlobalCodeBlock {
    11061154public:
    1107     ModuleProgramCodeBlock(CopyParsedBlockTag, ModuleProgramCodeBlock& other)
    1108         : GlobalCodeBlock(CopyParsedBlock, other)
    1109     {
    1110     }
    1111 
    1112     ModuleProgramCodeBlock(ModuleProgramExecutable* ownerExecutable, UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
    1113         : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset)
    1114     {
    1115     }
    1116 
    1117 #if ENABLE(JIT)
    1118 protected:
    1119     virtual CodeBlock* replacement() override;
    1120     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
    1121 #endif
     1155    typedef GlobalCodeBlock Base;
     1156    DECLARE_INFO;
     1157
     1158    static ModuleProgramCodeBlock* create(VM* vm, CopyParsedBlockTag, ModuleProgramCodeBlock& other)
     1159    {
     1160        ModuleProgramCodeBlock* instance = new (NotNull, allocateCell<ModuleProgramCodeBlock>(vm->heap))
     1161            ModuleProgramCodeBlock(vm, vm->moduleProgramCodeBlockStructure.get(), CopyParsedBlock, other);
     1162        instance->finishCreation(*vm, CopyParsedBlock, other);
     1163        return instance;
     1164    }
     1165
     1166    static ModuleProgramCodeBlock* create(VM* vm, ModuleProgramExecutable* ownerExecutable, UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock,
     1167        JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
     1168    {
     1169        ModuleProgramCodeBlock* instance = new (NotNull, allocateCell<ModuleProgramCodeBlock>(vm->heap))
     1170            ModuleProgramCodeBlock(vm, vm->moduleProgramCodeBlockStructure.get(), ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, firstLineColumnOffset);
     1171        instance->finishCreation(*vm, ownerExecutable, unlinkedCodeBlock, scope);
     1172        return instance;
     1173    }
     1174
     1175    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     1176    {
     1177        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     1178    }
     1179
     1180private:
     1181    ModuleProgramCodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, ModuleProgramCodeBlock& other)
     1182        : GlobalCodeBlock(vm, structure, CopyParsedBlock, other)
     1183    {
     1184    }
     1185
     1186    ModuleProgramCodeBlock(VM* vm, Structure* structure, ModuleProgramExecutable* ownerExecutable, UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock,
     1187        JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
     1188        : GlobalCodeBlock(vm, structure, ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset)
     1189    {
     1190    }
     1191
     1192    static void destroy(JSCell*);
    11221193};
    11231194
    11241195class EvalCodeBlock : public GlobalCodeBlock {
    11251196public:
    1126     EvalCodeBlock(CopyParsedBlockTag, EvalCodeBlock& other)
    1127         : GlobalCodeBlock(CopyParsedBlock, other)
    1128     {
    1129     }
    1130        
    1131     EvalCodeBlock(EvalExecutable* ownerExecutable, UnlinkedEvalCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider)
    1132         : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, 1)
    1133     {
    1134     }
    1135    
     1197    typedef GlobalCodeBlock Base;
     1198    DECLARE_INFO;
     1199
     1200    static EvalCodeBlock* create(VM* vm, CopyParsedBlockTag, EvalCodeBlock& other)
     1201    {
     1202        EvalCodeBlock* instance = new (NotNull, allocateCell<EvalCodeBlock>(vm->heap))
     1203            EvalCodeBlock(vm, vm->evalCodeBlockStructure.get(), CopyParsedBlock, other);
     1204        instance->finishCreation(*vm, CopyParsedBlock, other);
     1205        return instance;
     1206    }
     1207
     1208    static EvalCodeBlock* create(VM* vm, EvalExecutable* ownerExecutable, UnlinkedEvalCodeBlock* unlinkedCodeBlock,
     1209        JSScope* scope, PassRefPtr<SourceProvider> sourceProvider)
     1210    {
     1211        EvalCodeBlock* instance = new (NotNull, allocateCell<EvalCodeBlock>(vm->heap))
     1212            EvalCodeBlock(vm, vm->evalCodeBlockStructure.get(), ownerExecutable, unlinkedCodeBlock, scope, sourceProvider);
     1213        instance->finishCreation(*vm, ownerExecutable, unlinkedCodeBlock, scope);
     1214        return instance;
     1215    }
     1216
     1217    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     1218    {
     1219        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     1220    }
     1221
    11361222    const Identifier& variable(unsigned index) { return unlinkedEvalCodeBlock()->variable(index); }
    11371223    unsigned numVariables() { return unlinkedEvalCodeBlock()->numVariables(); }
    11381224   
    1139 #if ENABLE(JIT)
    1140 protected:
    1141     virtual CodeBlock* replacement() override;
    1142     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
    1143 #endif
    1144    
     1225private:
     1226    EvalCodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, EvalCodeBlock& other)
     1227        : GlobalCodeBlock(vm, structure, CopyParsedBlock, other)
     1228    {
     1229    }
     1230       
     1231    EvalCodeBlock(VM* vm, Structure* structure, EvalExecutable* ownerExecutable, UnlinkedEvalCodeBlock* unlinkedCodeBlock,
     1232        JSScope* scope, PassRefPtr<SourceProvider> sourceProvider)
     1233        : GlobalCodeBlock(vm, structure, ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, 1)
     1234    {
     1235    }
     1236   
     1237    static void destroy(JSCell*);
     1238
    11451239private:
    11461240    UnlinkedEvalCodeBlock* unlinkedEvalCodeBlock() const { return jsCast<UnlinkedEvalCodeBlock*>(unlinkedCodeBlock()); }
     
    11491243class FunctionCodeBlock : public CodeBlock {
    11501244public:
    1151     FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other)
    1152         : CodeBlock(CopyParsedBlock, other)
    1153     {
    1154     }
    1155 
    1156     FunctionCodeBlock(FunctionExecutable* ownerExecutable, UnlinkedFunctionCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
    1157         : CodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset)
    1158     {
    1159     }
    1160    
    1161 #if ENABLE(JIT)
    1162 protected:
    1163     virtual CodeBlock* replacement() override;
    1164     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
    1165 #endif
     1245    typedef CodeBlock Base;
     1246    DECLARE_INFO;
     1247
     1248    static FunctionCodeBlock* create(VM* vm, CopyParsedBlockTag, FunctionCodeBlock& other)
     1249    {
     1250        FunctionCodeBlock* instance = new (NotNull, allocateCell<FunctionCodeBlock>(vm->heap))
     1251            FunctionCodeBlock(vm, vm->functionCodeBlockStructure.get(), CopyParsedBlock, other);
     1252        instance->finishCreation(*vm, CopyParsedBlock, other);
     1253        return instance;
     1254    }
     1255
     1256    static FunctionCodeBlock* create(VM* vm, FunctionExecutable* ownerExecutable, UnlinkedFunctionCodeBlock* unlinkedCodeBlock, JSScope* scope,
     1257        PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
     1258    {
     1259        FunctionCodeBlock* instance = new (NotNull, allocateCell<FunctionCodeBlock>(vm->heap))
     1260            FunctionCodeBlock(vm, vm->functionCodeBlockStructure.get(), ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset);
     1261        instance->finishCreation(*vm, ownerExecutable, unlinkedCodeBlock, scope);
     1262        return instance;
     1263    }
     1264
     1265    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     1266    {
     1267        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     1268    }
     1269
     1270private:
     1271    FunctionCodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, FunctionCodeBlock& other)
     1272        : CodeBlock(vm, structure, CopyParsedBlock, other)
     1273    {
     1274    }
     1275
     1276    FunctionCodeBlock(VM* vm, Structure* structure, FunctionExecutable* ownerExecutable, UnlinkedFunctionCodeBlock* unlinkedCodeBlock, JSScope* scope,
     1277        PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
     1278        : CodeBlock(vm, structure, ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset)
     1279    {
     1280    }
     1281   
     1282    static void destroy(JSCell*);
    11661283};
    11671284
     
    11691286class WebAssemblyCodeBlock : public CodeBlock {
    11701287public:
    1171     WebAssemblyCodeBlock(CopyParsedBlockTag, WebAssemblyCodeBlock& other)
    1172         : CodeBlock(CopyParsedBlock, other)
    1173     {
    1174     }
    1175 
    1176     WebAssemblyCodeBlock(WebAssemblyExecutable* ownerExecutable, VM& vm, JSGlobalObject* globalObject)
    1177         : CodeBlock(ownerExecutable, vm, globalObject)
    1178     {
    1179     }
    1180 
    1181 #if ENABLE(JIT)
    1182 protected:
    1183     virtual CodeBlock* replacement() override;
    1184     virtual DFG::CapabilityLevel capabilityLevelInternal() override;
    1185 #endif
     1288    DECLARE_INFO;
     1289
     1290    static WebAssemblyCodeBlock* create(VM* vm, CopyParsedBlockTag, WebAssemblyCodeBlock& other)
     1291    {
     1292        WebAssemblyCodeBlock* instance = new (NotNull, allocateCell<WebAssemblyCodeBlock>(vm->heap))
     1293            WebAssemblyCodeBlock(vm, vm->webAssemblyCodeBlockStructure.get(), CopyParsedBlock, other);
     1294        instance->finishCreation(*vm);
     1295        return instance;
     1296    }
     1297
     1298    static WebAssemblyCodeBlock* create(VM* vm, WebAssemblyExecutable* ownerExecutable, JSGlobalObject* globalObject)
     1299    {
     1300        WebAssemblyCodeBlock* instance = new (NotNull, allocateCell<WebAssemblyCodeBlock>(vm->heap))
     1301            WebAssemblyCodeBlock(vm, vm->webAssemblyCodeBlockStructure.get(), ownerExecutable, globalObject);
     1302        instance->finishCreation(*vm);
     1303        return instance;
     1304    }
     1305
     1306    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     1307    {
     1308        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     1309    }
     1310
     1311private:
     1312    WebAssemblyCodeBlock(VM& vm, Structure* structure, CopyParsedBlockTag, WebAssemblyCodeBlock& other)
     1313        : CodeBlock(vm, structure, CopyParsedBlock, other)
     1314    {
     1315    }
     1316
     1317    WebAssemblyCodeBlock(VM& vm, Structure* structure, WebAssemblyExecutable* ownerExecutable, JSGlobalObject* globalObject)
     1318        : CodeBlock(vm, structure, ownerExecutable, vm, globalObject)
     1319    {
     1320    }
     1321
     1322    static void destroy(JSCell*);
    11861323};
    11871324#endif
     
    12111348}
    12121349
    1213 inline void CodeBlock::clearMarks()
     1350inline void CodeBlock::clearVisitWeaklyHasBeenCalled()
    12141351{
    1215     m_visitStronglyHasBeenCalled.store(false, std::memory_order_relaxed);
    1216     m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
     1352    m_visitWeaklyHasBeenCalled.store(false, std::memory_order_relaxed);
    12171353}
    12181354
     
    12391375    if (!codeBlock)
    12401376        return;
    1241    
    1242     // Force GC to visit all CodeBlocks on the stack, including old CodeBlocks
    1243     // that have not executed a barrier. This is overkill, but we have always
    1244     // done this, and it might help us recover gracefully if we forget to execute
    1245     // a barrier when a CodeBlock needs it.
    1246     codeBlock->clearMarks();
     1377
     1378    // Try to recover gracefully if we forget to execute a barrier for a
     1379    // CodeBlock that does value profiling. This is probably overkill, but we
     1380    // have always done it.
     1381    Heap::heap(codeBlock)->writeBarrier(codeBlock);
    12471382
    12481383    m_currentlyExecuting.add(codeBlock);
     
    12531388    switch (type()) {
    12541389    case ProgramExecutableType: {
    1255         if (CodeBlock* codeBlock = jsCast<ProgramExecutable*>(this)->m_programCodeBlock.get())
     1390        if (CodeBlock* codeBlock = static_cast<CodeBlock*>(jsCast<ProgramExecutable*>(this)->m_programCodeBlock.get()))
    12561391            codeBlock->forEachRelatedCodeBlock(std::forward<Functor>(functor));
    12571392        break;
     
    12591394
    12601395    case EvalExecutableType: {
    1261         if (CodeBlock* codeBlock = jsCast<EvalExecutable*>(this)->m_evalCodeBlock.get())
     1396        if (CodeBlock* codeBlock = static_cast<CodeBlock*>(jsCast<EvalExecutable*>(this)->m_evalCodeBlock.get()))
    12621397            codeBlock->forEachRelatedCodeBlock(std::forward<Functor>(functor));
    12631398        break;
     
    12671402        Functor f(std::forward<Functor>(functor));
    12681403        FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
    1269         if (CodeBlock* codeBlock = executable->m_codeBlockForCall.get())
     1404        if (CodeBlock* codeBlock = static_cast<CodeBlock*>(executable->m_codeBlockForCall.get()))
    12701405            codeBlock->forEachRelatedCodeBlock(f);
    1271         if (CodeBlock* codeBlock = executable->m_codeBlockForConstruct.get())
     1406        if (CodeBlock* codeBlock = static_cast<CodeBlock*>(executable->m_codeBlockForConstruct.get()))
    12721407            codeBlock->forEachRelatedCodeBlock(f);
    12731408        break;
     
    12751410
    12761411    case ModuleProgramExecutableType: {
    1277         if (CodeBlock* codeBlock = jsCast<ModuleProgramExecutable*>(this)->m_moduleProgramCodeBlock.get())
     1412        if (CodeBlock* codeBlock = static_cast<CodeBlock*>(jsCast<ModuleProgramExecutable*>(this)->m_moduleProgramCodeBlock.get()))
    12781413            codeBlock->forEachRelatedCodeBlock(std::forward<Functor>(functor));
    12791414        break;
  • trunk/Source/JavaScriptCore/bytecode/CodeOrigin.cpp

    r190220 r190522  
    7676            return true;
    7777       
    78         if (a.inlineCallFrame->executable.get() != b.inlineCallFrame->executable.get())
     78        if (a.inlineCallFrame->baselineCodeBlock.get() != b.inlineCallFrame->baselineCodeBlock.get())
    7979            return false;
    8080       
     
    9999            return result;
    100100       
    101         result += WTF::PtrHash<JSCell*>::hash(codeOrigin.inlineCallFrame->executable.get());
     101        result += WTF::PtrHash<JSCell*>::hash(codeOrigin.inlineCallFrame->baselineCodeBlock.get());
    102102       
    103103        codeOrigin = codeOrigin.inlineCallFrame->directCaller;
     
    116116}
    117117
    118 ScriptExecutable* CodeOrigin::codeOriginOwner() const
     118CodeBlock* CodeOrigin::codeOriginOwner() const
    119119{
    120120    if (!inlineCallFrame)
    121121        return 0;
    122     return inlineCallFrame->executable.get();
     122    return inlineCallFrame->baselineCodeBlock.get();
    123123}
    124124
     
    144144       
    145145        if (InlineCallFrame* frame = stack[i].inlineCallFrame) {
    146             out.print(frame->briefFunctionInformation(), ":<", RawPointer(frame->executable.get()), "> ");
     146            out.print(frame->briefFunctionInformation(), ":<", RawPointer(frame->baselineCodeBlock.get()), "> ");
    147147            if (frame->isClosureCall)
    148148                out.print("(closure) ");
  • trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h

    r190220 r190522  
    8888    // If the code origin corresponds to inlined code, gives you the heap object that
    8989    // would have owned the code if it had not been inlined. Otherwise returns 0.
    90     ScriptExecutable* codeOriginOwner() const;
     90    CodeBlock* codeOriginOwner() const;
    9191   
    9292    int stackOffset() const;
  • trunk/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp

    r190453 r190522  
    3434DeferredCompilationCallback::~DeferredCompilationCallback() { }
    3535
    36 void DeferredCompilationCallback::compilationDidComplete(CodeBlock* codeBlock, CompilationResult result)
     36void DeferredCompilationCallback::compilationDidComplete(CodeBlock* codeBlock, CodeBlock*, CompilationResult result)
    3737{
    3838    dumpCompiledSourcesIfNeeded();
  • trunk/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h

    r190453 r190522  
    4343    virtual ~DeferredCompilationCallback();
    4444
    45     virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*) = 0;
    46     virtual void compilationDidComplete(CodeBlock*, CompilationResult);
     45    virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*, CodeBlock* profiledDFGCodeBlock) = 0;
     46    virtual void compilationDidComplete(CodeBlock*, CodeBlock* profiledDFGCodeBlock, CompilationResult);
    4747
    4848    Vector<DeferredSourceDump>& ensureDeferredSourceDump();
  • trunk/Source/JavaScriptCore/bytecode/EvalCodeCache.h

    r190453 r190522  
    5252        }
    5353       
    54         EvalExecutable* getSlow(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, ThisTDZMode thisTDZMode, const String& evalSource, JSScope* scope)
     54        EvalExecutable* getSlow(ExecState* exec, JSCell* owner, bool inStrictContext, ThisTDZMode thisTDZMode, const String& evalSource, JSScope* scope)
    5555        {
    5656            VariableEnvironment variablesUnderTDZ;
  • trunk/Source/JavaScriptCore/bytecode/InlineCallFrame.cpp

    r190220 r190522  
    4848CodeBlockHash InlineCallFrame::hash() const
    4949{
    50     return jsCast<FunctionExecutable*>(executable.get())->codeBlockFor(
    51         specializationKind())->hash();
     50    return baselineCodeBlock->hash();
    5251}
    5352
    5453CString InlineCallFrame::hashAsStringIfPossible() const
    5554{
    56     return jsCast<FunctionExecutable*>(executable.get())->codeBlockFor(
    57         specializationKind())->hashAsStringIfPossible();
     55    return baselineCodeBlock->hashAsStringIfPossible();
    5856}
    5957
    6058CString InlineCallFrame::inferredName() const
    6159{
    62     return jsCast<FunctionExecutable*>(executable.get())->inferredName().utf8();
    63 }
    64 
    65 CodeBlock* InlineCallFrame::baselineCodeBlock() const
    66 {
    67     return jsCast<FunctionExecutable*>(executable.get())->baselineCodeBlockFor(specializationKind());
     60    return jsCast<FunctionExecutable*>(baselineCodeBlock->ownerExecutable())->inferredName().utf8();
    6861}
    6962
     
    7568void InlineCallFrame::dumpInContext(PrintStream& out, DumpContext* context) const
    7669{
    77     out.print(briefFunctionInformation(), ":<", RawPointer(executable.get()));
    78     if (executable->isStrictMode())
     70    out.print(briefFunctionInformation(), ":<", RawPointer(baselineCodeBlock.get()));
     71    if (isStrictMode())
    7972        out.print(" (StrictMode)");
    8073    out.print(", bc#", directCaller.bytecodeIndex, ", ", static_cast<Kind>(kind));
  • trunk/Source/JavaScriptCore/bytecode/InlineCallFrame.h

    r190220 r190522  
    3030#include "CodeBlockHash.h"
    3131#include "CodeOrigin.h"
    32 #include "Executable.h"
    3332#include "ValueRecovery.h"
    3433#include "WriteBarrier.h"
     
    4342struct InlineCallFrame;
    4443class ExecState;
    45 class ScriptExecutable;
    4644class JSFunction;
    4745
     
    175173   
    176174    Vector<ValueRecovery> arguments; // Includes 'this'.
    177     WriteBarrier<ScriptExecutable> executable;
     175    WriteBarrier<CodeBlock> baselineCodeBlock;
    178176    ValueRecovery calleeRecovery;
    179177    CodeOrigin directCaller;
     
    210208    CString hashAsStringIfPossible() const;
    211209   
    212     CodeBlock* baselineCodeBlock() const;
    213    
    214210    void setStackOffset(signed offset)
    215211    {
     
    220216    ptrdiff_t callerFrameOffset() const { return stackOffset * sizeof(Register) + CallFrame::callerFrameOffset(); }
    221217    ptrdiff_t returnPCOffset() const { return stackOffset * sizeof(Register) + CallFrame::returnPCOffset(); }
     218
     219    bool isStrictMode() const { return baselineCodeBlock->isStrictMode(); }
    222220
    223221    void dumpBriefFunctionInformation(PrintStream&) const;
     
    232230{
    233231    RELEASE_ASSERT(inlineCallFrame);
    234     ScriptExecutable* executable = inlineCallFrame->executable.get();
    235     RELEASE_ASSERT(executable->structure()->classInfo() == FunctionExecutable::info());
    236     return static_cast<FunctionExecutable*>(executable)->baselineCodeBlockFor(inlineCallFrame->specializationKind());
     232    return inlineCallFrame->baselineCodeBlock.get();
    237233}
    238234
  • trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp

    r190453 r190522  
    412412
    413413        // We will emit code that has a weak reference that isn't otherwise listed anywhere.
    414         state.weakReferences.append(WriteBarrier<JSCell>(vm, codeBlock->ownerExecutable(), structure));
     414        state.weakReferences.append(WriteBarrier<JSCell>(vm, codeBlock, structure));
    415415       
    416416        jit.move(CCallHelpers::TrustedImmPtr(condition.object()), scratchGPR);
     
    11711171        doesCalls |= entry->doesCalls();
    11721172   
    1173     m_stubRoutine = createJITStubRoutine(code, vm, codeBlock->ownerExecutable(), doesCalls);
     1173    m_stubRoutine = createJITStubRoutine(code, vm, codeBlock, doesCalls);
    11741174    m_watchpoints = WTF::move(state.watchpoints);
    11751175    if (!state.weakReferences.isEmpty())
  • trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp

    r190453 r190522  
    6363   
    6464    std::unique_ptr<AccessCase> previousCase =
    65         AccessCase::fromStructureStubInfo(vm, codeBlock->ownerExecutable(), *this);
     65        AccessCase::fromStructureStubInfo(vm, codeBlock, *this);
    6666    if (previousCase)
    6767        accessCases.append(WTF::move(previousCase));
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r190453 r190522  
    46344634       
    46354635        m_inlineCallFrame = byteCodeParser->m_graph.m_plan.inlineCallFrames->add();
    4636         byteCodeParser->m_graph.freeze(codeBlock->ownerExecutable());
     4636        byteCodeParser->m_graph.freeze(codeBlock->baselineVersion());
    46374637        // The owner is the machine code block, and we already have a barrier on that when the
    46384638        // plan finishes.
    4639         m_inlineCallFrame->executable.setWithoutWriteBarrier(codeBlock->ownerScriptExecutable());
     4639        m_inlineCallFrame->baselineCodeBlock.setWithoutWriteBarrier(codeBlock->baselineVersion());
    46404640        m_inlineCallFrame->setStackOffset(inlineCallFrameStart.offset() - JSStack::CallFrameHeaderSize);
    46414641        if (callee) {
     
    48294829        dataLog("Parsing ", *m_codeBlock, "\n");
    48304830   
    4831     m_dfgCodeBlock = m_graph.m_plan.profiledDFGCodeBlock.get();
     4831    m_dfgCodeBlock = m_graph.m_plan.profiledDFGCodeBlock;
    48324832    if (isFTL(m_graph.m_plan.mode) && m_dfgCodeBlock
    48334833        && Options::enablePolyvariantDevirtualization()) {
  • trunk/Source/JavaScriptCore/dfg/DFGCommonData.cpp

    r190128 r190522  
    9090            }
    9191           
    92             if (ScriptExecutable* executable = inlineCallFrame->executable.get())
    93                 trackedReferences.check(executable);
     92            if (CodeBlock* baselineCodeBlock = inlineCallFrame->baselineCodeBlock.get())
     93                trackedReferences.check(baselineCodeBlock);
    9494           
    9595            if (inlineCallFrame->calleeRecovery.isConstant())
  • trunk/Source/JavaScriptCore/dfg/DFGDesiredTransitions.cpp

    r190453 r190522  
    3535namespace JSC { namespace DFG {
    3636
    37 DesiredTransition::DesiredTransition(CodeBlock* codeBlock, ScriptExecutable* codeOriginOwner, Structure* oldStructure, Structure* newStructure)
     37DesiredTransition::DesiredTransition(CodeBlock* codeBlock, CodeBlock* codeOriginOwner, Structure* oldStructure, Structure* newStructure)
    3838    : m_codeBlock(codeBlock)
    3939    , m_codeOriginOwner(codeOriginOwner)
     
    4747    common->transitions.append(
    4848        WeakReferenceTransition(
    49             vm, m_codeBlock->ownerExecutable(),
     49            vm, m_codeBlock,
    5050            m_codeOriginOwner,
    5151            m_oldStructure, m_newStructure));
     
    6767}
    6868
    69 void DesiredTransitions::addLazily(CodeBlock* codeBlock, ScriptExecutable* codeOriginOwner, Structure* oldStructure, Structure* newStructure)
     69void DesiredTransitions::addLazily(CodeBlock* codeBlock, CodeBlock* codeOriginOwner, Structure* oldStructure, Structure* newStructure)
    7070{
    7171    m_transitions.append(DesiredTransition(codeBlock, codeOriginOwner, oldStructure, newStructure));
  • trunk/Source/JavaScriptCore/dfg/DFGDesiredTransitions.h

    r163691 r190522  
    4545class DesiredTransition {
    4646public:
    47     DesiredTransition(CodeBlock*, ScriptExecutable*, Structure*, Structure*);
     47    DesiredTransition(CodeBlock*, CodeBlock* codeOriginOwner, Structure*, Structure*);
    4848
    4949    void reallyAdd(VM&, CommonData*);
     
    5353private:
    5454    CodeBlock* m_codeBlock;
    55     ScriptExecutable* m_codeOriginOwner;
     55    CodeBlock* m_codeOriginOwner;
    5656    Structure* m_oldStructure;
    5757    Structure* m_newStructure;
     
    6363    ~DesiredTransitions();
    6464
    65     void addLazily(CodeBlock*, ScriptExecutable*, Structure*, Structure*);
     65    void addLazily(CodeBlock*, CodeBlock* codeOriginOwner, Structure*, Structure*);
    6666    void reallyAdd(VM&, CommonData*);
    6767    void visitChildren(SlotVisitor&);
  • trunk/Source/JavaScriptCore/dfg/DFGDesiredWeakReferences.cpp

    r190453 r190522  
    7171        if (Structure* structure = jsDynamicCast<Structure*>(target)) {
    7272            common->weakStructureReferences.append(
    73                 WriteBarrier<Structure>(vm, m_codeBlock->ownerExecutable(), structure));
     73                WriteBarrier<Structure>(vm, m_codeBlock, structure));
    7474        } else {
    7575            common->weakReferences.append(
    76                 WriteBarrier<JSCell>(vm, m_codeBlock->ownerExecutable(), target));
     76                WriteBarrier<JSCell>(vm, m_codeBlock, target));
    7777        }
    7878    }
  • trunk/Source/JavaScriptCore/dfg/DFGDriver.cpp

    r190453 r190522  
    122122        callback);
    123123    if (result != CompilationDeferred)
    124         callback->compilationDidComplete(codeBlock, result);
     124        callback->compilationDidComplete(codeBlock, profiledDFGCodeBlock, result);
    125125    return result;
    126126}
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp

    r190453 r190522  
    6262    : m_vm(vm)
    6363    , m_plan(plan)
    64     , m_codeBlock(m_plan.codeBlock.get())
     64    , m_codeBlock(m_plan.codeBlock)
    6565    , m_profiledBlock(m_codeBlock->alternative())
    6666    , m_allocator(longLivedState.m_allocator)
  • trunk/Source/JavaScriptCore/dfg/DFGGraph.h

    r190220 r190522  
    349349            return m_codeBlock->ownerScriptExecutable();
    350350       
    351         return inlineCallFrame->executable.get();
     351        return inlineCallFrame->baselineCodeBlock->ownerScriptExecutable();
    352352    }
    353353   
     
    373373        if (!codeOrigin.inlineCallFrame)
    374374            return m_codeBlock->isStrictMode();
    375         return jsCast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())->isStrictMode();
     375        return codeOrigin.inlineCallFrame->isStrictMode();
    376376    }
    377377   
  • trunk/Source/JavaScriptCore/dfg/DFGJITCode.h

    r190453 r190522  
    2929#if ENABLE(DFG_JIT)
    3030
     31#include "CodeBlock.h"
    3132#include "CompilationResult.h"
    3233#include "DFGCommonData.h"
     
    115116   
    116117    void shrinkToFit();
     118
     119#if ENABLE(FTL_JIT)
     120    CodeBlock* osrEntryBlock() { return m_osrEntryBlock.get(); }
     121    void setOSREntryBlock(VM& vm, const JSCell* owner, CodeBlock* osrEntryBlock) { m_osrEntryBlock.set(vm, owner, osrEntryBlock); }
     122    void clearOSREntryBlock() { m_osrEntryBlock.clear(); }
     123#endif
    117124   
    118125private:
     
    129136    uint8_t nestedTriggerIsSet { 0 };
    130137    UpperTierExecutionCounter tierUpCounter;
    131     RefPtr<CodeBlock> osrEntryBlock;
     138    WriteBarrier<CodeBlock> m_osrEntryBlock;
    132139    unsigned osrEntryRetry;
    133140    bool abandonOSREntry;
  • trunk/Source/JavaScriptCore/dfg/DFGJITFinalizer.cpp

    r190453 r190522  
    5858{
    5959    m_jitCode->initializeCodeRef(
    60         FINALIZE_DFG_CODE(*m_linkBuffer, ("DFG JIT code for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::DFGJIT)).data())),
     60        FINALIZE_DFG_CODE(*m_linkBuffer, ("DFG JIT code for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock, JITCode::DFGJIT)).data())),
    6161        MacroAssemblerCodePtr());
    6262   
     
    7272    RELEASE_ASSERT(!m_withArityCheck.isEmptyValue());
    7373    m_jitCode->initializeCodeRef(
    74         FINALIZE_DFG_CODE(*m_linkBuffer, ("DFG JIT code for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::DFGJIT)).data())),
     74        FINALIZE_DFG_CODE(*m_linkBuffer, ("DFG JIT code for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock, JITCode::DFGJIT)).data())),
    7575        m_withArityCheck);
    7676    m_plan.codeBlock->setJITCode(m_jitCode);
     
    8484{
    8585#if ENABLE(FTL_JIT)
    86     m_jitCode->optimizeAfterWarmUp(m_plan.codeBlock.get());
     86    m_jitCode->optimizeAfterWarmUp(m_plan.codeBlock);
    8787#endif // ENABLE(FTL_JIT)
    8888   
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp

    r190453 r190522  
    7070                AssemblyHelpers::NonZero,
    7171                AssemblyHelpers::AbsoluteAddress(
    72                     inlineCallFrame->executable->addressOfDidTryToEnterInLoop())));
     72                    inlineCallFrame->baselineCodeBlock->ownerScriptExecutable()->addressOfDidTryToEnterInLoop())));
    7373    }
    7474   
     
    269269void adjustAndJumpToTarget(CCallHelpers& jit, const OSRExitBase& exit, bool isExitingToOpCatch)
    270270{
    271     jit.move(AssemblyHelpers::TrustedImmPtr(jit.codeBlock()->ownerExecutable()), GPRInfo::argumentGPR1);
     271    CodeBlock* baselineCodeBlock = jit.baselineCodeBlockFor(exit.m_codeOrigin);
     272    jit.move(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), GPRInfo::argumentGPR1);
    272273    osrWriteBarrier(jit, GPRInfo::argumentGPR1, GPRInfo::nonArgGPR0);
    273274    InlineCallFrameSet* inlineCallFrames = jit.codeBlock()->jitCode()->dfgCommon()->inlineCallFrames.get();
    274275    if (inlineCallFrames) {
    275276        for (InlineCallFrame* inlineCallFrame : *inlineCallFrames) {
    276             ScriptExecutable* ownerExecutable = inlineCallFrame->executable.get();
    277             jit.move(AssemblyHelpers::TrustedImmPtr(ownerExecutable), GPRInfo::argumentGPR1);
     277            CodeBlock* baselineCodeBlock = inlineCallFrame->baselineCodeBlock.get();
     278            jit.move(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), GPRInfo::argumentGPR1);
    278279            osrWriteBarrier(jit, GPRInfo::argumentGPR1, GPRInfo::nonArgGPR0);
    279280        }
     
    283284        jit.addPtr(AssemblyHelpers::TrustedImm32(exit.m_codeOrigin.inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister);
    284285
    285     CodeBlock* baselineCodeBlock = jit.baselineCodeBlockFor(exit.m_codeOrigin);
    286286    Vector<BytecodeAndMachineOffset>& decodedCodeMap = jit.decodedCodeMapFor(baselineCodeBlock);
    287287   
  • trunk/Source/JavaScriptCore/dfg/DFGOSRExitPreparation.cpp

    r190220 r190522  
    4343   
    4444    for (; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->directCaller) {
    45         CodeBlock* codeBlock = codeOrigin.inlineCallFrame->baselineCodeBlock();
     45        CodeBlock* codeBlock = codeOrigin.inlineCallFrame->baselineCodeBlock.get();
    4646        if (codeBlock->jitType() == JSC::JITCode::BaselineJIT)
    4747            continue;
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r190453 r190522  
    13081308    bool didTryToEnterIntoInlinedLoops = false;
    13091309    for (InlineCallFrame* inlineCallFrame = exit->m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->directCaller.inlineCallFrame) {
    1310         if (inlineCallFrame->executable->didTryToEnterInLoop()) {
     1310        if (inlineCallFrame->baselineCodeBlock->ownerScriptExecutable()->didTryToEnterInLoop()) {
    13111311            didTryToEnterIntoInlinedLoops = true;
    13121312            break;
     
    13781378    // We need to compile the code.
    13791379    compile(
    1380         *vm, codeBlock->newReplacement().get(), codeBlock, FTLMode, UINT_MAX,
    1381         Operands<JSValue>(), ToFTLDeferredCompilationCallback::create(codeBlock));
     1380        *vm, codeBlock->newReplacement(), codeBlock, FTLMode, UINT_MAX,
     1381        Operands<JSValue>(), ToFTLDeferredCompilationCallback::create());
    13821382}
    13831383
     
    14641464        return 0;
    14651465   
    1466     if (CodeBlock* entryBlock = jitCode->osrEntryBlock.get()) {
     1466    if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
    14671467        void* address = FTL::prepareOSREntry(
    14681468            exec, codeBlock, entryBlock, bytecodeIndex, streamIndex);
     
    14781478        // OSR entry failed. Oh no! This implies that we need to retry. We retry
    14791479        // without exponential backoff and we only do this for the entry code block.
    1480         jitCode->osrEntryBlock = nullptr;
     1480        jitCode->clearOSREntryBlock();
    14811481        jitCode->osrEntryRetry = 0;
    14821482        return 0;
     
    14951495    jitCode->reconstruct(
    14961496        exec, codeBlock, CodeOrigin(bytecodeIndex), streamIndex, mustHandleValues);
    1497     RefPtr<CodeBlock> replacementCodeBlock = codeBlock->newReplacement();
     1497    CodeBlock* replacementCodeBlock = codeBlock->newReplacement();
    14981498    CompilationResult forEntryResult = compile(
    1499         *vm, replacementCodeBlock.get(), codeBlock, FTLForOSREntryMode, bytecodeIndex,
    1500         mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create(codeBlock));
    1501    
    1502     if (forEntryResult != CompilationSuccessful) {
    1503         ASSERT(forEntryResult == CompilationDeferred || replacementCodeBlock->hasOneRef());
     1499        *vm, replacementCodeBlock, codeBlock, FTLForOSREntryMode, bytecodeIndex,
     1500        mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create());
     1501   
     1502    if (forEntryResult != CompilationSuccessful)
    15041503        return 0;
    1505     }
    15061504
    15071505    // It's possible that the for-entry compile already succeeded. In that case OSR
     
    15091507    // We signal to try again after a while if that happens.
    15101508    void* address = FTL::prepareOSREntry(
    1511         exec, codeBlock, jitCode->osrEntryBlock.get(), bytecodeIndex, streamIndex);
     1509        exec, codeBlock, jitCode->osrEntryBlock(), bytecodeIndex, streamIndex);
    15121510    return static_cast<char*>(address);
    15131511}
  • trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp

    r190453 r190522  
    132132} // anonymous namespace
    133133
    134 Plan::Plan(PassRefPtr<CodeBlock> passedCodeBlock, CodeBlock* profiledDFGCodeBlock,
     134Plan::Plan(CodeBlock* passedCodeBlock, CodeBlock* profiledDFGCodeBlock,
    135135    CompilationMode mode, unsigned osrEntryBytecodeIndex,
    136136    const Operands<JSValue>& mustHandleValues)
     
    141141    , osrEntryBytecodeIndex(osrEntryBytecodeIndex)
    142142    , mustHandleValues(mustHandleValues)
    143     , compilation(codeBlock->vm()->m_perBytecodeProfiler ? adoptRef(new Profiler::Compilation(codeBlock->vm()->m_perBytecodeProfiler->ensureBytecodesFor(codeBlock.get()), profilerCompilationKindForMode(mode))) : 0)
     143    , compilation(codeBlock->vm()->m_perBytecodeProfiler ? adoptRef(new Profiler::Compilation(codeBlock->vm()->m_perBytecodeProfiler->ensureBytecodesFor(codeBlock), profilerCompilationKindForMode(mode))) : 0)
    144144    , inlineCallFrames(adoptRef(new InlineCallFrameSet()))
    145     , identifiers(codeBlock.get())
    146     , weakReferences(codeBlock.get())
     145    , identifiers(codeBlock)
     146    , weakReferences(codeBlock)
    147147    , willTryToTierUp(false)
    148148    , stage(Preparing)
     
    536536void Plan::reallyAdd(CommonData* commonData)
    537537{
    538     watchpoints.reallyAdd(codeBlock.get(), *commonData);
     538    watchpoints.reallyAdd(codeBlock, *commonData);
    539539    identifiers.reallyAdd(vm, commonData);
    540540    weakReferences.reallyAdd(vm, commonData);
     
    554554void Plan::notifyReady()
    555555{
    556     callback->compilationDidBecomeReadyAsynchronously(codeBlock.get());
     556    callback->compilationDidBecomeReadyAsynchronously(codeBlock, profiledDFGCodeBlock);
    557557    stage = Ready;
    558558}
     
    561561{
    562562    // We will establish new references from the code block to things. So, we need a barrier.
    563     vm.heap.writeBarrier(codeBlock->ownerExecutable());
     563    vm.heap.writeBarrier(codeBlock);
    564564   
    565565    if (!isStillValid())
     
    597597void Plan::finalizeAndNotifyCallback()
    598598{
    599     callback->compilationDidComplete(codeBlock.get(), finalizeWithoutNotifyingCallback());
     599    callback->compilationDidComplete(codeBlock, profiledDFGCodeBlock, finalizeWithoutNotifyingCallback());
    600600}
    601601
     
    605605}
    606606
    607 void Plan::clearCodeBlockMarks()
     607void Plan::rememberCodeBlocks()
    608608{
    609609    // Compilation writes lots of values to a CodeBlock without performing
     
    611611    // all our CodeBlocks must be visited during GC.
    612612
    613     codeBlock->clearMarks();
    614     codeBlock->alternative()->clearMarks();
     613    Heap::heap(codeBlock)->writeBarrier(codeBlock);
    615614    if (profiledDFGCodeBlock)
    616         profiledDFGCodeBlock->clearMarks();
     615        Heap::heap(profiledDFGCodeBlock)->writeBarrier(profiledDFGCodeBlock);
    617616}
    618617
     
    625624        visitor.appendUnbarrieredValue(&mustHandleValues[i]);
    626625
    627     codeBlock->visitStrongly(visitor);
    628     codeBlock->alternative()->visitStrongly(visitor);
    629     if (profiledDFGCodeBlock)
    630         profiledDFGCodeBlock->visitStrongly(visitor);
     626    visitor.appendUnbarrieredReadOnlyPointer(codeBlock);
     627    visitor.appendUnbarrieredReadOnlyPointer(profiledDFGCodeBlock);
    631628
    632629    if (inlineCallFrames) {
    633630        for (auto* inlineCallFrame : *inlineCallFrames) {
    634             ASSERT(inlineCallFrame->baselineCodeBlock());
    635             inlineCallFrame->baselineCodeBlock()->visitStrongly(visitor);
     631            ASSERT(inlineCallFrame->baselineCodeBlock.get());
     632            visitor.appendUnbarrieredReadOnlyPointer(inlineCallFrame->baselineCodeBlock.get());
    636633        }
    637634    }
  • trunk/Source/JavaScriptCore/dfg/DFGPlan.h

    r190453 r190522  
    5656struct Plan : public ThreadSafeRefCounted<Plan> {
    5757    Plan(
    58         PassRefPtr<CodeBlock> codeBlockToCompile, CodeBlock* profiledDFGCodeBlock,
     58        CodeBlock* codeBlockToCompile, CodeBlock* profiledDFGCodeBlock,
    5959        CompilationMode, unsigned osrEntryBytecodeIndex,
    6060        const Operands<JSValue>& mustHandleValues);
     
    7272    CompilationKey key();
    7373   
    74     void clearCodeBlockMarks();
     74    void rememberCodeBlocks();
    7575    void checkLivenessAndVisitChildren(SlotVisitor&);
    7676    bool isKnownToBeLiveDuringGC();
     
    7878   
    7979    VM& vm;
    80     RefPtr<CodeBlock> codeBlock;
    81     RefPtr<CodeBlock> profiledDFGCodeBlock;
     80
     81    // These can be raw pointers because we visit them during every GC in checkLivenessAndVisitChildren.
     82    CodeBlock* codeBlock;
     83    CodeBlock* profiledDFGCodeBlock;
     84
    8285    CompilationMode mode;
    8386    const unsigned osrEntryBytecodeIndex;
  • trunk/Source/JavaScriptCore/dfg/DFGToFTLDeferredCompilationCallback.cpp

    r190453 r190522  
    3636namespace JSC { namespace DFG {
    3737
    38 ToFTLDeferredCompilationCallback::ToFTLDeferredCompilationCallback(
    39     PassRefPtr<CodeBlock> dfgCodeBlock)
    40     : m_dfgCodeBlock(dfgCodeBlock)
     38ToFTLDeferredCompilationCallback::ToFTLDeferredCompilationCallback()
    4139{
    4240}
     
    4442ToFTLDeferredCompilationCallback::~ToFTLDeferredCompilationCallback() { }
    4543
    46 Ref<ToFTLDeferredCompilationCallback> ToFTLDeferredCompilationCallback::create(PassRefPtr<CodeBlock> dfgCodeBlock)
     44Ref<ToFTLDeferredCompilationCallback> ToFTLDeferredCompilationCallback::create()
    4745{
    48     return adoptRef(*new ToFTLDeferredCompilationCallback(dfgCodeBlock));
     46    return adoptRef(*new ToFTLDeferredCompilationCallback());
    4947}
    5048
    5149void ToFTLDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously(
    52     CodeBlock* codeBlock)
     50    CodeBlock* codeBlock, CodeBlock* profiledDFGCodeBlock)
    5351{
    5452    if (Options::verboseOSR()) {
    5553        dataLog(
    56             "Optimizing compilation of ", *codeBlock, " (for ", *m_dfgCodeBlock,
     54            "Optimizing compilation of ", *codeBlock, " (for ", *profiledDFGCodeBlock,
    5755            ") did become ready.\n");
    5856    }
    5957   
    60     m_dfgCodeBlock->jitCode()->dfg()->forceOptimizationSlowPathConcurrently(
    61         m_dfgCodeBlock.get());
     58    profiledDFGCodeBlock->jitCode()->dfg()->forceOptimizationSlowPathConcurrently(
     59        profiledDFGCodeBlock);
    6260}
    6361
    6462void ToFTLDeferredCompilationCallback::compilationDidComplete(
    65     CodeBlock* codeBlock, CompilationResult result)
     63    CodeBlock* codeBlock, CodeBlock* profiledDFGCodeBlock, CompilationResult result)
    6664{
    6765    if (Options::verboseOSR()) {
    6866        dataLog(
    69             "Optimizing compilation of ", *codeBlock, " (for ", *m_dfgCodeBlock,
     67            "Optimizing compilation of ", *codeBlock, " (for ", *profiledDFGCodeBlock,
    7068            ") result: ", result, "\n");
    7169    }
    7270   
    73     if (m_dfgCodeBlock->replacement() != m_dfgCodeBlock) {
     71    if (profiledDFGCodeBlock->replacement() != profiledDFGCodeBlock) {
    7472        if (Options::verboseOSR()) {
    7573            dataLog(
    7674                "Dropping FTL code block ", *codeBlock, " on the floor because the "
    77                 "DFG code block ", *m_dfgCodeBlock, " was jettisoned.\n");
     75                "DFG code block ", *profiledDFGCodeBlock, " was jettisoned.\n");
    7876        }
    7977        return;
     
    8381        codeBlock->ownerScriptExecutable()->installCode(codeBlock);
    8482   
    85     m_dfgCodeBlock->jitCode()->dfg()->setOptimizationThresholdBasedOnCompilationResult(
    86         m_dfgCodeBlock.get(), result);
     83    profiledDFGCodeBlock->jitCode()->dfg()->setOptimizationThresholdBasedOnCompilationResult(
     84        profiledDFGCodeBlock, result);
    8785
    88     DeferredCompilationCallback::compilationDidComplete(codeBlock, result);
     86    DeferredCompilationCallback::compilationDidComplete(codeBlock, profiledDFGCodeBlock, result);
    8987}
    9088
  • trunk/Source/JavaScriptCore/dfg/DFGToFTLDeferredCompilationCallback.h

    r190453 r190522  
    4141class ToFTLDeferredCompilationCallback : public DeferredCompilationCallback {
    4242protected:
    43     ToFTLDeferredCompilationCallback(PassRefPtr<CodeBlock> dfgCodeBlock);
     43    ToFTLDeferredCompilationCallback();
    4444
    4545public:
    4646    virtual ~ToFTLDeferredCompilationCallback();
    4747
    48     static Ref<ToFTLDeferredCompilationCallback> create(PassRefPtr<CodeBlock> dfgCodeBlock);
     48    static Ref<ToFTLDeferredCompilationCallback> create();
    4949   
    50     virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*);
    51     virtual void compilationDidComplete(CodeBlock*, CompilationResult);
    52 
    53 private:
    54     RefPtr<CodeBlock> m_dfgCodeBlock;
     50    virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*, CodeBlock* profiledDFGCodeBlock);
     51    virtual void compilationDidComplete(CodeBlock*, CodeBlock* profiledDFGCodeBlock, CompilationResult);
    5552};
    5653
  • trunk/Source/JavaScriptCore/dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp

    r190453 r190522  
    3636namespace JSC { namespace DFG {
    3737
    38 ToFTLForOSREntryDeferredCompilationCallback::ToFTLForOSREntryDeferredCompilationCallback(
    39     PassRefPtr<CodeBlock> dfgCodeBlock)
    40     : m_dfgCodeBlock(dfgCodeBlock)
     38ToFTLForOSREntryDeferredCompilationCallback::ToFTLForOSREntryDeferredCompilationCallback()
    4139{
    4240}
     
    4644}
    4745
    48 Ref<ToFTLForOSREntryDeferredCompilationCallback>ToFTLForOSREntryDeferredCompilationCallback::create(
    49     PassRefPtr<CodeBlock> dfgCodeBlock)
     46Ref<ToFTLForOSREntryDeferredCompilationCallback>ToFTLForOSREntryDeferredCompilationCallback::create()
    5047{
    51     return adoptRef(*new ToFTLForOSREntryDeferredCompilationCallback(dfgCodeBlock));
     48    return adoptRef(*new ToFTLForOSREntryDeferredCompilationCallback());
    5249}
    5350
    5451void ToFTLForOSREntryDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously(
    55     CodeBlock* codeBlock)
     52    CodeBlock* codeBlock, CodeBlock* profiledDFGCodeBlock)
    5653{
    5754    if (Options::verboseOSR()) {
    5855        dataLog(
    59             "Optimizing compilation of ", *codeBlock, " (for ", *m_dfgCodeBlock,
     56            "Optimizing compilation of ", *codeBlock, " (for ", *profiledDFGCodeBlock,
    6057            ") did become ready.\n");
    6158    }
    6259   
    63     m_dfgCodeBlock->jitCode()->dfg()->forceOptimizationSlowPathConcurrently(
    64         m_dfgCodeBlock.get());
     60    profiledDFGCodeBlock->jitCode()->dfg()->forceOptimizationSlowPathConcurrently(
     61        profiledDFGCodeBlock);
    6562}
    6663
    6764void ToFTLForOSREntryDeferredCompilationCallback::compilationDidComplete(
    68     CodeBlock* codeBlock, CompilationResult result)
     65    CodeBlock* codeBlock, CodeBlock* profiledDFGCodeBlock, CompilationResult result)
    6966{
    7067    if (Options::verboseOSR()) {
    7168        dataLog(
    72             "Optimizing compilation of ", *codeBlock, " (for ", *m_dfgCodeBlock,
     69            "Optimizing compilation of ", *codeBlock, " (for ", *profiledDFGCodeBlock,
    7370            ") result: ", result, "\n");
    7471    }
    7572   
    76     JITCode* jitCode = m_dfgCodeBlock->jitCode()->dfg();
     73    JITCode* jitCode = profiledDFGCodeBlock->jitCode()->dfg();
    7774       
    7875    switch (result) {
    7976    case CompilationSuccessful:
    80         jitCode->osrEntryBlock = codeBlock;
     77        jitCode->setOSREntryBlock(*codeBlock->vm(), profiledDFGCodeBlock, codeBlock);
    8178        break;
    8279    case CompilationFailed:
     
    9188    }
    9289   
    93     DeferredCompilationCallback::compilationDidComplete(codeBlock, result);
     90    DeferredCompilationCallback::compilationDidComplete(codeBlock, profiledDFGCodeBlock, result);
    9491}
    9592
  • trunk/Source/JavaScriptCore/dfg/DFGToFTLForOSREntryDeferredCompilationCallback.h

    r190453 r190522  
    4141class ToFTLForOSREntryDeferredCompilationCallback : public DeferredCompilationCallback {
    4242protected:
    43     ToFTLForOSREntryDeferredCompilationCallback(PassRefPtr<CodeBlock> dfgCodeBlock);
     43    ToFTLForOSREntryDeferredCompilationCallback();
    4444
    4545public:
    4646    virtual ~ToFTLForOSREntryDeferredCompilationCallback();
    4747
    48     static Ref<ToFTLForOSREntryDeferredCompilationCallback> create(PassRefPtr<CodeBlock> dfgCodeBlock);
     48    static Ref<ToFTLForOSREntryDeferredCompilationCallback> create();
    4949   
    50     virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*);
    51     virtual void compilationDidComplete(CodeBlock*, CompilationResult);
    52 
    53 private:
    54     RefPtr<CodeBlock> m_dfgCodeBlock;
     50    virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*, CodeBlock* profiledDFGCodeBlock);
     51    virtual void compilationDidComplete(CodeBlock*, CodeBlock* profiledDFGCodeBlock, CompilationResult);
    5552};
    5653
  • trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp

    r190453 r190522  
    208208}
    209209
    210 void Worklist::clearCodeBlockMarks(VM& vm)
     210void Worklist::rememberCodeBlocks(VM& vm)
    211211{
    212212    LockHolder locker(m_lock);
     
    215215        if (&plan->vm != &vm)
    216216            continue;
    217         plan->clearCodeBlockMarks();
     217        plan->rememberCodeBlocks();
    218218    }
    219219}
     
    468468}
    469469
    470 void clearCodeBlockMarks(VM& vm)
     470void rememberCodeBlocks(VM& vm)
    471471{
    472472    for (unsigned i = DFG::numberOfWorklists(); i--;) {
    473473        if (DFG::Worklist* worklist = DFG::worklistForIndexOrNull(i))
    474             worklist->clearCodeBlockMarks(vm);
     474            worklist->rememberCodeBlocks(vm);
    475475    }
    476476}
  • trunk/Source/JavaScriptCore/dfg/DFGWorklist.h

    r190453 r190522  
    5858    void completeAllPlansForVM(VM&);
    5959
    60     void clearCodeBlockMarks(VM&);
     60    void rememberCodeBlocks(VM&);
    6161
    6262    void waitUntilAllPlansForVMAreReady(VM&);
     
    142142
    143143void completeAllPlansForVM(VM&);
    144 void clearCodeBlockMarks(VM&);
     144void rememberCodeBlocks(VM&);
    145145
    146146} } // namespace JSC::DFG
  • trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp

    r190453 r190522  
    100100            FINALIZE_DFG_CODE(
    101101                *exitThunksLinkBuffer,
    102                 ("FTL exit thunks for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data())));
     102                ("FTL exit thunks for %s", toCString(CodeBlockWithJITType(m_plan.codeBlock, JITCode::FTLJIT)).data())));
    103103    } // else this function had no OSR exits, so no exit thunks.
    104104   
     
    117117            *sideCodeLinkBuffer,
    118118            ("FTL side code for %s",
    119                 toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data()))
     119                toCString(CodeBlockWithJITType(m_plan.codeBlock, JITCode::FTLJIT)).data()))
    120120            .executableMemory());
    121121    }
     
    125125            *handleExceptionsLinkBuffer,
    126126            ("FTL exception handler for %s",
    127                 toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data()))
     127                toCString(CodeBlockWithJITType(m_plan.codeBlock, JITCode::FTLJIT)).data()))
    128128            .executableMemory());
    129129    }
     
    138138        FINALIZE_DFG_CODE(
    139139            *entrypointLinkBuffer,
    140             ("FTL entrypoint thunk for %s with LLVM generated code at %p", toCString(CodeBlockWithJITType(m_plan.codeBlock.get(), JITCode::FTLJIT)).data(), function)));
     140            ("FTL entrypoint thunk for %s with LLVM generated code at %p", toCString(CodeBlockWithJITType(m_plan.codeBlock, JITCode::FTLJIT)).data(), function)));
    141141   
    142142    m_plan.codeBlock->setJITCode(jitCode);
  • trunk/Source/JavaScriptCore/heap/CodeBlockSet.cpp

    r190453 r190522  
    4242CodeBlockSet::~CodeBlockSet()
    4343{
    44     for (CodeBlock* codeBlock : m_oldCodeBlocks)
    45         codeBlock->deref();
    46 
    47     for (CodeBlock* codeBlock : m_newCodeBlocks)
    48         codeBlock->deref();
    4944}
    5045
    51 void CodeBlockSet::add(PassRefPtr<CodeBlock> codeBlock)
     46void CodeBlockSet::add(CodeBlock* codeBlock)
    5247{
    53     CodeBlock* block = codeBlock.leakRef();
    54     bool isNewEntry = m_newCodeBlocks.add(block).isNewEntry;
     48    bool isNewEntry = m_newCodeBlocks.add(codeBlock).isNewEntry;
    5549    ASSERT_UNUSED(isNewEntry, isNewEntry);
    5650}
     
    6559{
    6660    for (CodeBlock* codeBlock : m_oldCodeBlocks)
    67         codeBlock->clearMarks();
     61        codeBlock->clearVisitWeaklyHasBeenCalled();
    6862
    6963    // We promote after we clear marks on the old generation CodeBlocks because
     
    7266}
    7367
    74 void CodeBlockSet::clearMarksForEdenCollection(const Vector<const JSCell*>& rememberedSet)
    75 {
    76     // This ensures that we will revisit CodeBlocks in remembered Executables even if they were previously marked.
    77     for (const JSCell* cell : rememberedSet) {
    78         ScriptExecutable* executable = const_cast<ScriptExecutable*>(jsDynamicCast<const ScriptExecutable*>(cell));
    79         if (!executable)
    80             continue;
    81         executable->forEachCodeBlock([this](CodeBlock* codeBlock) {
    82             codeBlock->clearMarks();
    83             m_remembered.add(codeBlock);
    84         });
    85     }
    86 }
    87 
    8868void CodeBlockSet::deleteUnmarkedAndUnreferenced(HeapOperation collectionType)
    8969{
    9070    HashSet<CodeBlock*>& set = collectionType == EdenCollection ? m_newCodeBlocks : m_oldCodeBlocks;
     71    Vector<CodeBlock*> unmarked;
     72    for (CodeBlock* codeBlock : set) {
     73        if (Heap::isMarked(codeBlock))
     74            continue;
     75        unmarked.append(codeBlock);
     76    }
    9177
    92     // This needs to be a fixpoint because code blocks that are unmarked may
    93     // refer to each other. For example, a DFG code block that is owned by
    94     // the GC may refer to an FTL for-entry code block that is also owned by
    95     // the GC.
    96     Vector<CodeBlock*, 16> toRemove;
    97     if (verbose)
    98         dataLog("Fixpointing over unmarked, set size = ", set.size(), "...\n");
    99     for (;;) {
    100         for (CodeBlock* codeBlock : set) {
    101             if (!codeBlock->hasOneRef())
    102                 continue;
    103             codeBlock->deref();
    104             toRemove.append(codeBlock);
    105         }
    106         if (verbose)
    107             dataLog("    Removing ", toRemove.size(), " blocks.\n");
    108         if (toRemove.isEmpty())
    109             break;
    110         for (CodeBlock* codeBlock : toRemove)
    111             set.remove(codeBlock);
    112         toRemove.resize(0);
     78    for (CodeBlock* codeBlock : unmarked) {
     79        codeBlock->classInfo()->methodTable.destroy(codeBlock);
     80        set.remove(codeBlock);
    11381    }
    11482
     
    12088void CodeBlockSet::remove(CodeBlock* codeBlock)
    12189{
    122     codeBlock->deref();
    12390    if (m_oldCodeBlocks.contains(codeBlock)) {
    12491        m_oldCodeBlocks.remove(codeBlock);
     
    12996}
    13097
    131 void CodeBlockSet::traceMarked(SlotVisitor& visitor)
    132 {
    133     if (verbose)
    134         dataLog("Tracing ", m_currentlyExecuting.size(), " code blocks.\n");
    135 
    136     // We strongly visit the currently executing set because jettisoning code
    137     // is not valuable once it's on the stack. We're past the point where
    138     // jettisoning would avoid the cost of OSR exit.
    139     for (const RefPtr<CodeBlock>& codeBlock : m_currentlyExecuting)
    140         codeBlock->visitStrongly(visitor);
    141 
    142     // We strongly visit the remembered set because jettisoning old code during
    143     // Eden GC is unsound. There might be an old object with a strong reference
    144     // to the code.
    145     for (const RefPtr<CodeBlock>& codeBlock : m_remembered)
    146         codeBlock->visitStrongly(visitor);
    147 }
    148 
    14998void CodeBlockSet::rememberCurrentlyExecutingCodeBlocks(Heap* heap)
    15099{
    151100    if (verbose)
    152101        dataLog("Remembering ", m_currentlyExecuting.size(), " code blocks.\n");
    153     for (const RefPtr<CodeBlock>& codeBlock : m_currentlyExecuting)
    154         heap->addToRememberedSet(codeBlock->ownerExecutable());
    155 
    156     // It's safe to clear these RefPtr sets because we won't delete the CodeBlocks
    157     // in them until the next GC, and we'll recompute them at that time.
     102    for (CodeBlock* codeBlock : m_currentlyExecuting)
     103        heap->addToRememberedSet(codeBlock);
    158104    m_currentlyExecuting.clear();
    159     m_remembered.clear();
    160105}
    161106
     
    172117    out.print("], currentlyExecuting = [");
    173118    comma = CommaPrinter();
    174     for (const RefPtr<CodeBlock>& codeBlock : m_currentlyExecuting)
    175         out.print(comma, pointerDump(codeBlock.get()));
     119    for (CodeBlock* codeBlock : m_currentlyExecuting)
     120        out.print(comma, pointerDump(codeBlock));
    176121    out.print("]}");
    177122}
  • trunk/Source/JavaScriptCore/heap/CodeBlockSet.h

    r190453 r190522  
    5454   
    5555    // Add a CodeBlock. This is only called by CodeBlock constructors.
    56     void add(PassRefPtr<CodeBlock>);
     56    void add(CodeBlock*);
    5757   
    58     // Clear mark bits for certain CodeBlocks depending on the type of collection.
    59     void clearMarksForEdenCollection(const Vector<const JSCell*>&);
    60 
    6158    // Clear all mark bits for all CodeBlocks.
    6259    void clearMarksForFullCollection();
     
    7370    void remove(CodeBlock*);
    7471   
    75     // Trace all marked code blocks. The CodeBlock is free to make use of
    76     // mayBeExecuting.
    77     void traceMarked(SlotVisitor&);
    78 
    7972    // Add all currently executing CodeBlocks to the remembered set to be
    8073    // re-scanned during the next collection.
     
    10598    void promoteYoungCodeBlocks();
    10699
    107     // This is not a set of RefPtr<CodeBlock> because we need to be able to find
    108     // arbitrary bogus pointers. I could have written a thingy that had peek types
    109     // and all, but that seemed like overkill.
    110100    HashSet<CodeBlock*> m_oldCodeBlocks;
    111101    HashSet<CodeBlock*> m_newCodeBlocks;
    112     HashSet<RefPtr<CodeBlock>> m_currentlyExecuting;
    113     HashSet<RefPtr<CodeBlock>> m_remembered;
     102    HashSet<CodeBlock*> m_currentlyExecuting;
    114103};
    115104
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r190520 r190522  
    520520    ASSERT(isValidThreadState(m_vm));
    521521
    522     Vector<const JSCell*> rememberedSet(m_slotVisitor.markStack().size());
    523     m_slotVisitor.markStack().fillVector(rememberedSet);
    524 
    525 #if ENABLE(DFG_JIT)
    526     DFG::clearCodeBlockMarks(*m_vm);
    527 #endif
    528     if (m_operationInProgress == EdenCollection)
    529         m_codeBlocks.clearMarksForEdenCollection(rememberedSet);
    530     else
    531         m_codeBlocks.clearMarksForFullCollection();
    532 
    533522    // We gather conservative roots before clearing mark bits because conservative
    534523    // gathering uses the mark bits to determine whether a reference is valid.
     
    538527    gatherScratchBufferRoots(conservativeRoots);
    539528
     529#if ENABLE(DFG_JIT)
     530    DFG::rememberCodeBlocks(*m_vm);
     531#endif
     532
     533    if (m_operationInProgress == FullCollection) {
     534        m_opaqueRoots.clear();
     535        m_slotVisitor.clearMarkStack();
     536    }
     537
     538    Vector<const JSCell*> rememberedSet(m_slotVisitor.markStack().size());
     539    m_slotVisitor.markStack().fillVector(rememberedSet);
     540
    540541    clearLivenessData();
    541542
    542     if (m_operationInProgress == FullCollection)
    543         m_opaqueRoots.clear();
    544543
    545544    m_shouldHashCons = m_vm->haveEnoughNewStringsToHashCons();
     
    582581        ParallelModeEnabler enabler(m_slotVisitor);
    583582
     583        m_slotVisitor.donateAndDrain();
    584584        visitExternalRememberedSet();
    585585        visitSmallStrings();
     
    697697{
    698698    GCPHASE(ClearLivenessData);
     699    if (m_operationInProgress == FullCollection)
     700        m_codeBlocks.clearMarksForFullCollection();
     701
    699702    m_objectSpace.clearNewlyAllocated();
    700703    m_objectSpace.clearMarks();
     
    818821{
    819822    GCPHASE(TraceCodeBlocksAndJITStubRoutines);
    820     m_codeBlocks.traceMarked(m_slotVisitor);
    821823    m_jitStubRoutines.traceMarkedStubRoutines(m_slotVisitor);
    822824
     
    963965    // we'll end up returning to deleted code.
    964966    RELEASE_ASSERT(!m_vm->entryScope);
     967    ASSERT(m_operationInProgress == NoOperation);
    965968
    966969    completeAllDFGPlans();
    967970
    968     for (ExecutableBase* current : m_executables) {
    969         if (!current->isFunctionExecutable())
    970             continue;
    971         static_cast<FunctionExecutable*>(current)->clearCode();
    972     }
    973 
    974     ASSERT(m_operationInProgress == FullCollection || m_operationInProgress == NoOperation);
    975     m_codeBlocks.clearMarksForFullCollection();
    976     m_codeBlocks.deleteUnmarkedAndUnreferenced(FullCollection);
     971    for (ExecutableBase* executable : m_executables)
     972        executable->clearCode();
    977973}
    978974
     
    994990            continue;
    995991
    996         // We do this because executable memory is limited on some platforms and because
    997         // CodeBlock requires eager finalization.
    998         ExecutableBase::clearCodeVirtual(current);
     992        // Eagerly dereference the Executable's JITCode in order to run watchpoint
     993        // destructors. Otherwise, watchpoints might fire for deleted CodeBlocks.
     994        current->clearCode();
    999995        std::swap(m_executables[i], m_executables.last());
    1000996        m_executables.removeLast();
     
    11501146    if (shouldDoFullCollection(collectionType)) {
    11511147        m_operationInProgress = FullCollection;
    1152         m_slotVisitor.clearMarkStack();
    11531148        m_shouldDoFullCollection = false;
    11541149        if (Options::logGC())
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r190453 r190522  
    174174
    175175        ThisTDZMode thisTDZMode = callerCodeBlock->unlinkedCodeBlock()->constructorKind() == ConstructorKind::Derived ? ThisTDZMode::AlwaysCheck : ThisTDZMode::CheckIfNeeded;
    176         eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock->ownerScriptExecutable(), callerCodeBlock->isStrictMode(), thisTDZMode, programSource, callerScopeChain);
     176        eval = callerCodeBlock->evalCodeCache().getSlow(callFrame, callerCodeBlock, callerCodeBlock->isStrictMode(), thisTDZMode, programSource, callerScopeChain);
    177177        if (!eval)
    178178            return jsUndefined();
  • trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp

    r190220 r190522  
    171171        else
    172172            m_frame.m_argumentCountIncludingThis = inlineCallFrame->arguments.size();
    173         m_frame.m_codeBlock = inlineCallFrame->baselineCodeBlock();
     173        m_frame.m_codeBlock = inlineCallFrame->baselineCodeBlock.get();
    174174        m_frame.m_bytecodeOffset = codeOrigin->bytecodeIndex;
    175175
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp

    r190370 r190522  
    3939        return m_codeBlock->ownerExecutable();
    4040   
    41     return codeOrigin.inlineCallFrame->executable.get();
     41    return codeOrigin.inlineCallFrame->baselineCodeBlock->ownerExecutable();
    4242}
    4343
  • trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h

    r190230 r190522  
    10751075        if (!codeOrigin.inlineCallFrame)
    10761076            return codeBlock()->isStrictMode();
    1077         return jsCast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())->isStrictMode();
     1077        return codeOrigin.inlineCallFrame->isStrictMode();
    10781078    }
    10791079   
  • trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h

    r190453 r190522  
    116116// that codeBlock gets "executed" more than once.
    117117#define FINALIZE_CODE_FOR_GC_AWARE_STUB(codeBlock, patchBuffer, makesCalls, cell, dataLogFArguments) \
    118     (createJITStubRoutine(FINALIZE_CODE_FOR((codeBlock), (patchBuffer), dataLogFArguments), *(codeBlock)->vm(), (codeBlock)->ownerExecutable(), (makesCalls), (cell)))
     118    (createJITStubRoutine(FINALIZE_CODE_FOR((codeBlock), (patchBuffer), dataLogFArguments), *(codeBlock)->vm(), (codeBlock), (makesCalls), (cell)))
    119119
    120120} // namespace JSC
  • trunk/Source/JavaScriptCore/jit/JITCode.h

    r190453 r190522  
    122122    }
    123123
    124     static std::chrono::milliseconds timeToLive(JITType jitType)
    125     {
    126         switch (jitType) {
    127         case InterpreterThunk:
    128             return std::chrono::duration_cast<std::chrono::milliseconds>(
    129                 std::chrono::seconds(5));
    130         case BaselineJIT:
    131             // Effectively 10 additional seconds, since BaselineJIT and
    132             // InterpreterThunk share a CodeBlock.
    133             return std::chrono::duration_cast<std::chrono::milliseconds>(
    134                 std::chrono::seconds(15));
    135         case DFGJIT:
    136             return std::chrono::duration_cast<std::chrono::milliseconds>(
    137                 std::chrono::seconds(20));
    138         case FTLJIT:
    139             return std::chrono::duration_cast<std::chrono::milliseconds>(
    140                 std::chrono::seconds(60));
    141         default:
    142             return std::chrono::milliseconds::max();
    143         }
    144     }
    145 
    146124    static bool isLowerTier(JITType expectedLower, JITType expectedHigher)
    147125    {
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r190453 r190522  
    667667        emitInitRegister(virtualRegisterForLocal(j).offset());
    668668
    669     emitWriteBarrier(m_codeBlock->ownerExecutable());
     669    emitWriteBarrier(m_codeBlock);
    670670
    671671    emitEnterOptimizationCheck();
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r190453 r190522  
    12741274        }
    12751275
    1276         RefPtr<CodeBlock> replacementCodeBlock = codeBlock->newReplacement();
     1276        CodeBlock* replacementCodeBlock = codeBlock->newReplacement();
    12771277        CompilationResult result = DFG::compile(
    1278             vm, replacementCodeBlock.get(), 0, DFG::DFGMode, bytecodeIndex,
     1278            vm, replacementCodeBlock, nullptr, DFG::DFGMode, bytecodeIndex,
    12791279            mustHandleValues, JITToDFGDeferredCompilationCallback::create());
    12801280       
    1281         if (result != CompilationSuccessful) {
    1282             ASSERT(result == CompilationDeferred || replacementCodeBlock->hasOneRef());
     1281        if (result != CompilationSuccessful)
    12831282            return encodeResult(0, 0);
    1284         }
    12851283    }
    12861284   
  • trunk/Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.cpp

    r190453 r190522  
    4444
    4545void JITToDFGDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously(
    46     CodeBlock* codeBlock)
     46    CodeBlock* codeBlock, CodeBlock* profiledDFGCodeBlock)
    4747{
     48    ASSERT_UNUSED(profiledDFGCodeBlock, !profiledDFGCodeBlock);
    4849    ASSERT(codeBlock->alternative()->jitType() == JITCode::BaselineJIT);
    4950   
     
    5556
    5657void JITToDFGDeferredCompilationCallback::compilationDidComplete(
    57     CodeBlock* codeBlock, CompilationResult result)
     58    CodeBlock* codeBlock, CodeBlock* profiledDFGCodeBlock, CompilationResult result)
    5859{
     60    ASSERT(!profiledDFGCodeBlock);
    5961    ASSERT(codeBlock->alternative()->jitType() == JITCode::BaselineJIT);
    6062   
     
    6769    codeBlock->alternative()->setOptimizationThresholdBasedOnCompilationResult(result);
    6870
    69     DeferredCompilationCallback::compilationDidComplete(codeBlock, result);
     71    DeferredCompilationCallback::compilationDidComplete(codeBlock, profiledDFGCodeBlock, result);
    7072}
    7173
  • trunk/Source/JavaScriptCore/jit/JITToDFGDeferredCompilationCallback.h

    r190453 r190522  
    4545    static Ref<JITToDFGDeferredCompilationCallback> create();
    4646   
    47     virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*) override;
    48     virtual void compilationDidComplete(CodeBlock*, CompilationResult) override;
     47    virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*, CodeBlock* profiledDFGCodeBlock) override;
     48    virtual void compilationDidComplete(CodeBlock*, CodeBlock* profiledDFGCodeBlock, CompilationResult) override;
    4949};
    5050
  • trunk/Source/JavaScriptCore/jit/Repatch.cpp

    r190453 r190522  
    228228
    229229    CodeBlock* codeBlock = exec->codeBlock();
    230     ScriptExecutable* owner = codeBlock->ownerScriptExecutable();
    231230    VM& vm = exec->vm();
    232231
     
    234233
    235234    if (isJSArray(baseValue) && propertyName == exec->propertyNames().length)
    236         newCase = AccessCase::getLength(vm, owner, AccessCase::ArrayLength);
     235        newCase = AccessCase::getLength(vm, codeBlock, AccessCase::ArrayLength);
    237236    else if (isJSString(baseValue) && propertyName == exec->propertyNames().length)
    238         newCase = AccessCase::getLength(vm, owner, AccessCase::StringLength);
     237        newCase = AccessCase::getLength(vm, codeBlock, AccessCase::StringLength);
    239238    else {
    240239        if (!slot.isCacheable() && !slot.isUnset())
     
    267266            structure->startWatchingPropertyForReplacements(vm, slot.cachedOffset());
    268267            repatchByIdSelfAccess(codeBlock, stubInfo, structure, slot.cachedOffset(), operationGetByIdOptimize, true);
    269             stubInfo.initGetByIdSelf(vm, codeBlock->ownerExecutable(), structure, slot.cachedOffset());
     268            stubInfo.initGetByIdSelf(vm, codeBlock, structure, slot.cachedOffset());
    270269            return RetryCacheLater;
    271270        }
     
    280279            if (slot.isUnset()) {
    281280                conditionSet = generateConditionsForPropertyMiss(
    282                     vm, codeBlock->ownerExecutable(), exec, structure, propertyName.impl());
     281                    vm, codeBlock, exec, structure, propertyName.impl());
    283282            } else {
    284283                conditionSet = generateConditionsForPrototypePropertyHit(
    285                     vm, codeBlock->ownerExecutable(), exec, structure, slot.slotBase(),
     284                    vm, codeBlock, exec, structure, slot.slotBase(),
    286285                    propertyName.impl());
    287286            }
     
    304303
    305304        newCase = AccessCase::get(
    306             vm, owner, type, offset, structure, conditionSet, loadTargetFromProxy,
     305            vm, codeBlock, type, offset, structure, conditionSet, loadTargetFromProxy,
    307306            slot.watchpointSet(), slot.isCacheableCustom() ? slot.customGetter() : nullptr,
    308307            slot.isCacheableCustom() ? slot.slotBase() : nullptr);
     
    358357   
    359358    CodeBlock* codeBlock = exec->codeBlock();
    360     ScriptExecutable* owner = codeBlock->ownerScriptExecutable();
    361359    VM& vm = exec->vm();
    362360
     
    386384                    appropriateOptimizingPutByIdFunction(slot, putKind), false);
    387385                stubInfo.initPutByIdReplace(
    388                     vm, codeBlock->ownerExecutable(), structure, slot.cachedOffset());
     386                    vm, codeBlock, structure, slot.cachedOffset());
    389387                return RetryCacheLater;
    390388            }
    391389
    392             newCase = AccessCase::replace(vm, owner, structure, slot.cachedOffset());
     390            newCase = AccessCase::replace(vm, codeBlock, structure, slot.cachedOffset());
    393391        } else {
    394392            ASSERT(slot.type() == PutPropertySlot::NewProperty);
     
    412410                conditionSet =
    413411                    generateConditionsForPropertySetterMiss(
    414                         vm, owner, exec, newStructure, ident.impl());
     412                        vm, codeBlock, exec, newStructure, ident.impl());
    415413                if (!conditionSet.isValid())
    416414                    return GiveUpOnCache;
    417415            }
    418416
    419             newCase = AccessCase::transition(vm, owner, structure, newStructure, offset, conditionSet);
     417            newCase = AccessCase::transition(vm, codeBlock, structure, newStructure, offset, conditionSet);
    420418        }
    421419    } else if (slot.isCacheableCustom() || slot.isCacheableSetter()) {
     
    426424                conditionSet =
    427425                    generateConditionsForPrototypePropertyHitCustom(
    428                         vm, owner, exec, structure, slot.base(), ident.impl());
     426                        vm, codeBlock, exec, structure, slot.base(), ident.impl());
    429427                if (!conditionSet.isValid())
    430428                    return GiveUpOnCache;
     
    432430
    433431            newCase = AccessCase::setter(
    434                 vm, owner, AccessCase::CustomSetter, structure, invalidOffset, conditionSet,
     432                vm, codeBlock, AccessCase::CustomSetter, structure, invalidOffset, conditionSet,
    435433                slot.customSetter(), slot.base());
    436434        } else {
     
    441439                conditionSet =
    442440                    generateConditionsForPrototypePropertyHit(
    443                         vm, owner, exec, structure, slot.base(), ident.impl());
     441                        vm, codeBlock, exec, structure, slot.base(), ident.impl());
    444442                if (!conditionSet.isValid())
    445443                    return GiveUpOnCache;
     
    449447
    450448            newCase = AccessCase::setter(
    451                 vm, owner, AccessCase::Setter, structure, offset, conditionSet);
     449                vm, codeBlock, AccessCase::Setter, structure, offset, conditionSet);
    452450        }
    453451    }
     
    492490   
    493491    CodeBlock* codeBlock = exec->codeBlock();
    494     ScriptExecutable* owner = codeBlock->ownerScriptExecutable();
    495492    VM& vm = exec->vm();
    496493    Structure* structure = base->structure(vm);
     
    500497        if (slot.slotBase() != base) {
    501498            conditionSet = generateConditionsForPrototypePropertyHit(
    502                 vm, codeBlock->ownerExecutable(), exec, structure, slot.slotBase(), ident.impl());
     499                vm, codeBlock, exec, structure, slot.slotBase(), ident.impl());
    503500        }
    504501    } else {
    505502        conditionSet = generateConditionsForPropertyMiss(
    506             vm, codeBlock->ownerExecutable(), exec, structure, ident.impl());
     503            vm, codeBlock, exec, structure, ident.impl());
    507504    }
    508505    if (!conditionSet.isValid())
     
    510507
    511508    std::unique_ptr<AccessCase> newCase = AccessCase::in(
    512         vm, owner, wasFound ? AccessCase::InHit : AccessCase::InMiss, structure, conditionSet);
     509        vm, codeBlock, wasFound ? AccessCase::InHit : AccessCase::InMiss, structure, conditionSet);
    513510
    514511    MacroAssemblerCodePtr codePtr = stubInfo.addAccessCase(vm, codeBlock, ident, WTF::move(newCase));
     
    559556   
    560557    ASSERT(!callLinkInfo.isLinked());
    561     callLinkInfo.setCallee(exec->callerFrame()->vm(), callLinkInfo.hotPathBegin(), callerCodeBlock->ownerExecutable(), callee);
    562     callLinkInfo.setLastSeenCallee(exec->callerFrame()->vm(), callerCodeBlock->ownerExecutable(), callee);
     558    callLinkInfo.setCallee(exec->callerFrame()->vm(), callLinkInfo.hotPathBegin(), callerCodeBlock, callee);
     559    callLinkInfo.setLastSeenCallee(exec->callerFrame()->vm(), callerCodeBlock, callee);
    563560    if (shouldShowDisassemblyFor(callerCodeBlock))
    564561        dataLog("Linking call in ", *callerCodeBlock, " at ", callLinkInfo.codeOrigin(), " to ", pointerDump(calleeCodeBlock), ", entrypoint at ", codePtr, "\n");
     
    877874                toCString(*callerCodeBlock).data(), callLinkInfo.callReturnLocation().labelAtOffset(0).executableAddress(),
    878875                toCString(listDump(callCases)).data())),
    879         *vm, callerCodeBlock->ownerExecutable(), exec->callerFrame(), callLinkInfo, callCases,
     876        *vm, callerCodeBlock, exec->callerFrame(), callLinkInfo, callCases,
    880877        WTF::move(fastCounts)));
    881878   
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r190453 r190522  
    577577            && !structure->typeInfo().prohibitsPropertyCaching()
    578578            && !structure->typeInfo().newImpurePropertyFiresWatchpoints()) {
    579             vm.heap.writeBarrier(codeBlock->ownerExecutable());
     579            vm.heap.writeBarrier(codeBlock);
    580580           
    581581            ConcurrentJITLocker locker(codeBlock->m_lock);
     
    642642            && baseCell == slot.base()) {
    643643
    644             vm.heap.writeBarrier(codeBlock->ownerExecutable());
     644            vm.heap.writeBarrier(codeBlock);
    645645           
    646646            if (slot.type() == PutPropertySlot::NewProperty) {
     
    659659                            ASSERT(chain);
    660660                            pc[7].u.structureChain.set(
    661                                 vm, codeBlock->ownerExecutable(), chain);
     661                                vm, codeBlock, chain);
    662662                        }
    663663                        pc[8].u.putByIdFlags = static_cast<PutByIdFlags>(
     
    11911191        if (callLinkInfo->isOnList())
    11921192            callLinkInfo->remove();
    1193         callLinkInfo->callee.set(vm, callerCodeBlock->ownerExecutable(), callee);
    1194         callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock->ownerExecutable(), callee);
     1193        callLinkInfo->callee.set(vm, callerCodeBlock, callee);
     1194        callLinkInfo->lastSeenCallee.set(vm, callerCodeBlock, callee);
    11951195        callLinkInfo->machineCodeTarget = codePtr;
    11961196        if (codeBlock)
  • trunk/Source/JavaScriptCore/profiler/ProfilerOriginStack.cpp

    r188585 r190522  
    5353    for (unsigned i = 1; i < stack.size(); ++i) {
    5454        append(Origin(
    55             database.ensureBytecodesFor(stack[i].inlineCallFrame->baselineCodeBlock()),
     55            database.ensureBytecodesFor(stack[i].inlineCallFrame->baselineCodeBlock.get()),
    5656            stack[i].bytecodeIndex));
    5757    }
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r190453 r190522  
    232232    auto& cacheWriteBarrier = pc[4].u.jsCell;
    233233    if (!cacheWriteBarrier)
    234         cacheWriteBarrier.set(exec->vm(), exec->codeBlock()->ownerExecutable(), constructor);
     234        cacheWriteBarrier.set(exec->vm(), exec->codeBlock(), constructor);
    235235    else if (cacheWriteBarrier.unvalidatedGet() != JSCell::seenMultipleCalleeObjects() && cacheWriteBarrier.get() != constructor)
    236236        cacheWriteBarrier.setWithoutWriteBarrier(JSCell::seenMultipleCalleeObjects());
     
    251251            if (otherStructure)
    252252                pc[3].u.toThisStatus = ToThisConflicted;
    253             pc[2].u.structure.set(vm, exec->codeBlock()->ownerExecutable(), myStructure);
     253            pc[2].u.structure.set(vm, exec->codeBlock(), myStructure);
    254254        }
    255255    } else {
     
    527527{
    528528    BEGIN();
    529     ExecutableBase* ownerExecutable = exec->codeBlock()->ownerExecutable();
    530     Heap::heap(ownerExecutable)->writeBarrier(ownerExecutable);
     529    CodeBlock* codeBlock = exec->codeBlock();
     530    Heap::heap(codeBlock)->writeBarrier(codeBlock);
    531531    END();
    532532}
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h

    r190453 r190522  
    130130
    131131        ConcurrentJITLocker locker(codeBlock->m_lock);
    132         pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
     132        pc[5].u.structure.set(exec->vm(), codeBlock, scope->structure());
    133133        pc[6].u.operand = slot.cachedOffset();
    134134    }
     
    163163            {
    164164                ConcurrentJITLocker locker(codeBlock->m_lock);
    165                 pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), structure);
     165                pc[5].u.structure.set(exec->vm(), codeBlock, structure);
    166166                pc[6].u.operand = slot.cachedOffset();
    167167            }
  • trunk/Source/JavaScriptCore/runtime/Executable.cpp

    r190453 r190522  
    6161    m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED;
    6262    m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED;
     63
     64    if (classInfo() == FunctionExecutable::info()) {
     65        FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
     66        executable->m_codeBlockForCall.clear();
     67        executable->m_codeBlockForConstruct.clear();
     68        return;
     69    }
     70
     71    if (classInfo() == EvalExecutable::info()) {
     72        EvalExecutable* executable = jsCast<EvalExecutable*>(this);
     73        executable->m_evalCodeBlock.clear();
     74        executable->m_unlinkedEvalCodeBlock.clear();
     75        return;
     76    }
     77   
     78    if (classInfo() == ProgramExecutable::info()) {
     79        ProgramExecutable* executable = jsCast<ProgramExecutable*>(this);
     80        executable->m_programCodeBlock.clear();
     81        executable->m_unlinkedProgramCodeBlock.clear();
     82        return;
     83    }
     84
     85    if (classInfo() == ModuleProgramExecutable::info()) {
     86        ModuleProgramExecutable* executable = jsCast<ModuleProgramExecutable*>(this);
     87        executable->m_moduleProgramCodeBlock.clear();
     88        executable->m_unlinkedModuleProgramCodeBlock.clear();
     89        executable->m_moduleEnvironmentSymbolTable.clear();
     90        return;
     91    }
     92   
     93#if ENABLE(WEBASSEMBLY)
     94    if (classInfo() == WebAssemblyExecutable::info()) {
     95        WebAssemblyExecutable* executable = jsCast<WebAssemblyExecutable*>(this);
     96        executable->m_codeBlockForCall.clear();
     97        return;
     98    }
     99#endif
     100
     101    ASSERT(classInfo() == NativeExecutable::info());
    63102}
    64103
     
    124163    ASSERT(vm.heap.isDeferred());
    125164   
    126     RefPtr<CodeBlock> oldCodeBlock;
     165    CodeBlock* oldCodeBlock = nullptr;
    127166   
    128167    switch (codeType) {
     
    133172        ASSERT(kind == CodeForCall);
    134173       
    135         oldCodeBlock = executable->m_programCodeBlock;
    136         executable->m_programCodeBlock = codeBlock;
     174        oldCodeBlock = executable->m_programCodeBlock.get();
     175        executable->m_programCodeBlock.setMayBeNull(vm, this, codeBlock);
    137176        break;
    138177    }
     
    144183        ASSERT(kind == CodeForCall);
    145184
    146         oldCodeBlock = executable->m_moduleProgramCodeBlock;
    147         executable->m_moduleProgramCodeBlock = codeBlock;
     185        oldCodeBlock = executable->m_moduleProgramCodeBlock.get();
     186        executable->m_moduleProgramCodeBlock.setMayBeNull(vm, this, codeBlock);
    148187        break;
    149188    }
     
    155194        ASSERT(kind == CodeForCall);
    156195       
    157         oldCodeBlock = executable->m_evalCodeBlock;
    158         executable->m_evalCodeBlock = codeBlock;
     196        oldCodeBlock = executable->m_evalCodeBlock.get();
     197        executable->m_evalCodeBlock.setMayBeNull(vm, this, codeBlock);
    159198        break;
    160199    }
     
    166205        switch (kind) {
    167206        case CodeForCall:
    168             oldCodeBlock = executable->m_codeBlockForCall;
    169             executable->m_codeBlockForCall = codeBlock;
     207            oldCodeBlock = executable->m_codeBlockForCall.get();
     208            executable->m_codeBlockForCall.setMayBeNull(vm, this, codeBlock);
    170209            break;
    171210        case CodeForConstruct:
    172             oldCodeBlock = executable->m_codeBlockForConstruct;
    173             executable->m_codeBlockForConstruct = codeBlock;
     211            oldCodeBlock = executable->m_codeBlockForConstruct.get();
     212            executable->m_codeBlockForConstruct.setMayBeNull(vm, this, codeBlock);
    174213            break;
    175214        }
     
    211250}
    212251
    213 RefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor(
     252CodeBlock* ScriptExecutable::newCodeBlockFor(
    214253    CodeSpecializationKind kind, JSFunction* function, JSScope* scope, JSObject*& exception)
    215254{
     
    225264        RELEASE_ASSERT(!executable->m_evalCodeBlock);
    226265        RELEASE_ASSERT(!function);
    227         return adoptRef(new EvalCodeBlock(
     266        return EvalCodeBlock::create(vm,
    228267            executable, executable->m_unlinkedEvalCodeBlock.get(), scope,
    229             executable->source().provider()));
     268            executable->source().provider());
    230269    }
    231270   
     
    235274        RELEASE_ASSERT(!executable->m_programCodeBlock);
    236275        RELEASE_ASSERT(!function);
    237         return adoptRef(new ProgramCodeBlock(
     276        return ProgramCodeBlock::create(vm,
    238277            executable, executable->m_unlinkedProgramCodeBlock.get(), scope,
    239             executable->source().provider(), executable->source().startColumn()));
     278            executable->source().provider(), executable->source().startColumn());
    240279    }
    241280
     
    245284        RELEASE_ASSERT(!executable->m_moduleProgramCodeBlock);
    246285        RELEASE_ASSERT(!function);
    247         return adoptRef(new ModuleProgramCodeBlock(
     286        return ModuleProgramCodeBlock::create(vm,
    248287            executable, executable->m_unlinkedModuleProgramCodeBlock.get(), scope,
    249             executable->source().provider(), executable->source().startColumn()));
     288            executable->source().provider(), executable->source().startColumn());
    250289    }
    251290
     
    277316    unsigned startColumn = executable->source().startColumn();
    278317
    279     return adoptRef(new FunctionCodeBlock(
    280         executable, unlinkedCodeBlock, scope, provider, sourceOffset, startColumn));
    281 }
    282 
    283 PassRefPtr<CodeBlock> ScriptExecutable::newReplacementCodeBlockFor(
     318    return FunctionCodeBlock::create(vm,
     319        executable, unlinkedCodeBlock, scope, provider, sourceOffset, startColumn);
     320}
     321
     322CodeBlock* ScriptExecutable::newReplacementCodeBlockFor(
    284323    CodeSpecializationKind kind)
    285324{
     
    289328        EvalCodeBlock* baseline = static_cast<EvalCodeBlock*>(
    290329            executable->m_evalCodeBlock->baselineVersion());
    291         RefPtr<EvalCodeBlock> result = adoptRef(new EvalCodeBlock(
    292             CodeBlock::CopyParsedBlock, *baseline));
    293         result->setAlternative(baseline);
     330        EvalCodeBlock* result = EvalCodeBlock::create(vm(),
     331            CodeBlock::CopyParsedBlock, *baseline);
     332        result->setAlternative(*vm(), baseline);
    294333        return result;
    295334    }
     
    300339        ProgramCodeBlock* baseline = static_cast<ProgramCodeBlock*>(
    301340            executable->m_programCodeBlock->baselineVersion());
    302         RefPtr<ProgramCodeBlock> result = adoptRef(new ProgramCodeBlock(
    303             CodeBlock::CopyParsedBlock, *baseline));
    304         result->setAlternative(baseline);
     341        ProgramCodeBlock* result = ProgramCodeBlock::create(vm(),
     342            CodeBlock::CopyParsedBlock, *baseline);
     343        result->setAlternative(*vm(), baseline);
    305344        return result;
    306345    }
     
    311350        ModuleProgramCodeBlock* baseline = static_cast<ModuleProgramCodeBlock*>(
    312351            executable->m_moduleProgramCodeBlock->baselineVersion());
    313         RefPtr<ModuleProgramCodeBlock> result = adoptRef(new ModuleProgramCodeBlock(
    314             CodeBlock::CopyParsedBlock, *baseline));
    315         result->setAlternative(baseline);
     352        ModuleProgramCodeBlock* result = ModuleProgramCodeBlock::create(vm(),
     353            CodeBlock::CopyParsedBlock, *baseline);
     354        result->setAlternative(*vm(), baseline);
    316355        return result;
    317356    }
     
    321360    FunctionCodeBlock* baseline = static_cast<FunctionCodeBlock*>(
    322361        executable->codeBlockFor(kind)->baselineVersion());
    323     RefPtr<FunctionCodeBlock> result = adoptRef(new FunctionCodeBlock(
    324         CodeBlock::CopyParsedBlock, *baseline));
    325     result->setAlternative(baseline);
     362    FunctionCodeBlock* result = FunctionCodeBlock::create(vm(),
     363        CodeBlock::CopyParsedBlock, *baseline);
     364    result->setAlternative(*vm(), baseline);
    326365    return result;
    327366}
     
    351390   
    352391    JSObject* exception = 0;
    353     RefPtr<CodeBlock> codeBlock = newCodeBlockFor(kind, function, scope, exception);
     392    CodeBlock* codeBlock = newCodeBlockFor(kind, function, scope, exception);
    354393    if (!codeBlock) {
    355394        RELEASE_ASSERT(exception);
     
    361400   
    362401    if (Options::useLLInt())
    363         setupLLInt(vm, codeBlock.get());
     402        setupLLInt(vm, codeBlock);
    364403    else
    365         setupJIT(vm, codeBlock.get());
    366    
    367     installCode(*codeBlock->vm(), codeBlock.get(), codeBlock->codeType(), codeBlock->specializationKind());
     404        setupJIT(vm, codeBlock);
     405   
     406    installCode(*codeBlock->vm(), codeBlock, codeBlock->codeType(), codeBlock->specializationKind());
    368407    return 0;
    369408}
     
    503542    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    504543    ScriptExecutable::visitChildren(thisObject, visitor);
     544    visitor.append(&thisObject->m_unlinkedEvalCodeBlock);
    505545    if (thisObject->m_evalCodeBlock)
    506         thisObject->m_evalCodeBlock->visitAggregate(visitor);
    507     visitor.append(&thisObject->m_unlinkedEvalCodeBlock);
    508 }
    509 
    510 void EvalExecutable::clearCode()
    511 {
    512     m_evalCodeBlock = nullptr;
    513     m_unlinkedEvalCodeBlock.clear();
    514     Base::clearCode();
     546        thisObject->m_evalCodeBlock->visitWeakly(visitor);
    515547}
    516548
     
    619651    visitor.append(&thisObject->m_unlinkedProgramCodeBlock);
    620652    if (thisObject->m_programCodeBlock)
    621         thisObject->m_programCodeBlock->visitAggregate(visitor);
    622 }
    623 
    624 void ProgramExecutable::clearCode()
    625 {
    626     m_programCodeBlock = nullptr;
    627     m_unlinkedProgramCodeBlock.clear();
    628     Base::clearCode();
     653        thisObject->m_programCodeBlock->visitWeakly(visitor);
    629654}
    630655
     
    637662    visitor.append(&thisObject->m_moduleEnvironmentSymbolTable);
    638663    if (thisObject->m_moduleProgramCodeBlock)
    639         thisObject->m_moduleProgramCodeBlock->visitAggregate(visitor);
    640 }
    641 
    642 void ModuleProgramExecutable::clearCode()
    643 {
    644     m_moduleProgramCodeBlock = nullptr;
    645     m_unlinkedModuleProgramCodeBlock.clear();
    646     m_moduleEnvironmentSymbolTable.clear();
    647     Base::clearCode();
     664        thisObject->m_moduleProgramCodeBlock->visitWeakly(visitor);
    648665}
    649666
     
    668685    ScriptExecutable::visitChildren(thisObject, visitor);
    669686    if (thisObject->m_codeBlockForCall)
    670         thisObject->m_codeBlockForCall->visitAggregate(visitor);
     687        thisObject->m_codeBlockForCall->visitWeakly(visitor);
    671688    if (thisObject->m_codeBlockForConstruct)
    672         thisObject->m_codeBlockForConstruct->visitAggregate(visitor);
     689        thisObject->m_codeBlockForConstruct->visitWeakly(visitor);
    673690    visitor.append(&thisObject->m_unlinkedExecutable);
    674691    visitor.append(&thisObject->m_singletonFunction);
    675 }
    676 
    677 void FunctionExecutable::clearCode()
    678 {
    679     m_codeBlockForCall = nullptr;
    680     m_codeBlockForConstruct = nullptr;
    681     Base::clearCode();
    682692}
    683693
     
    717727    ExecutableBase::visitChildren(thisObject, visitor);
    718728    if (thisObject->m_codeBlockForCall)
    719         thisObject->m_codeBlockForCall->visitAggregate(visitor);
     729        thisObject->m_codeBlockForCall->visitWeakly(visitor);
    720730    visitor.append(&thisObject->m_module);
    721 }
    722 
    723 void WebAssemblyExecutable::clearCode()
    724 {
    725     m_codeBlockForCall = nullptr;
    726     Base::clearCode();
    727731}
    728732
     
    735739    DeferGC deferGC(vm.heap);
    736740
    737     RefPtr<WebAssemblyCodeBlock> codeBlock = adoptRef(new WebAssemblyCodeBlock(
    738         this, vm, exec->lexicalGlobalObject()));
    739 
    740     WASMFunctionParser::compile(vm, codeBlock.get(), m_module.get(), m_source, m_functionIndex);
     741    WebAssemblyCodeBlock* codeBlock = WebAssemblyCodeBlock::create(vm,
     742        this, exec->lexicalGlobalObject()));
     743
     744    WASMFunctionParser::compile(vm, codeBlock, m_module.get(), m_source, m_functionIndex);
    741745
    742746    m_jitCodeForCall = codeBlock->jitCode();
     
    744748    m_numParametersForCall = codeBlock->numParameters();
    745749
    746     m_codeBlockForCall = codeBlock;
     750    m_codeBlockForCall.set(vm, this, codeBlock);
    747751
    748752    Heap::heap(this)->writeBarrier(this);
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r190453 r190522  
    140140
    141141public:
    142     static void clearCodeVirtual(ExecutableBase*);
    143 
    144142    PassRefPtr<JITCode> generatedJITCodeForCall()
    145143    {
     
    307305
    308306private:
     307    friend class ExecutableBase;
     308
    309309    NativeExecutable(VM& vm, NativeFunction function, NativeFunction constructor)
    310310        : ExecutableBase(vm, vm.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
     
    377377    void installCode(CodeBlock*);
    378378    void installCode(VM&, CodeBlock*, CodeType, CodeSpecializationKind);
    379     RefPtr<CodeBlock> newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope*, JSObject*& exception);
    380     PassRefPtr<CodeBlock> newReplacementCodeBlockFor(CodeSpecializationKind);
     379    CodeBlock* newCodeBlockFor(CodeSpecializationKind, JSFunction*, JSScope*, JSObject*& exception);
     380    CodeBlock* newReplacementCodeBlockFor(CodeSpecializationKind);
    381381   
    382382    JSObject* prepareForExecution(ExecState* exec, JSFunction* function, JSScope* scope, CodeSpecializationKind kind)
     
    390390
    391391private:
     392    friend class ExecutableBase;
    392393    JSObject* prepareForExecutionImpl(ExecState*, JSFunction*, JSScope*, CodeSpecializationKind);
    393394
     
    448449    DECLARE_INFO;
    449450
    450     void clearCode();
    451 
    452451    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false); }
    453452
     
    456455
    457456private:
     457    friend class ExecutableBase;
    458458    friend class ScriptExecutable;
    459459    EvalExecutable(ExecState*, const SourceCode&, bool);
     
    461461    static void visitChildren(JSCell*, SlotVisitor&);
    462462
    463     RefPtr<EvalCodeBlock> m_evalCodeBlock;
     463    WriteBarrier<EvalCodeBlock> m_evalCodeBlock;
    464464    WriteBarrier<UnlinkedEvalCodeBlock> m_unlinkedEvalCodeBlock;
    465465};
     
    502502    DECLARE_INFO;
    503503
    504     void clearCode();
    505 
    506504    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false); }
    507505
    508506private:
     507    friend class ExecutableBase;
    509508    friend class ScriptExecutable;
    510509
     
    514513
    515514    WriteBarrier<UnlinkedProgramCodeBlock> m_unlinkedProgramCodeBlock;
    516     RefPtr<ProgramCodeBlock> m_programCodeBlock;
     515    WriteBarrier<ProgramCodeBlock> m_programCodeBlock;
    517516};
    518517
     
    544543    DECLARE_INFO;
    545544
    546     void clearCode();
    547 
    548545    ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false); }
    549546    UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock() { return m_unlinkedModuleProgramCodeBlock.get(); }
     
    552549
    553550private:
     551    friend class ExecutableBase;
    554552    friend class ScriptExecutable;
    555553
     
    560558    WriteBarrier<UnlinkedModuleProgramCodeBlock> m_unlinkedModuleProgramCodeBlock;
    561559    WriteBarrier<SymbolTable> m_moduleEnvironmentSymbolTable;
    562     RefPtr<ModuleProgramCodeBlock> m_moduleProgramCodeBlock;
     560    WriteBarrier<ModuleProgramCodeBlock> m_moduleProgramCodeBlock;
    563561};
    564562
     
    601599    bool isGeneratedForCall() const
    602600    {
    603         return m_codeBlockForCall;
     601        return !!m_codeBlockForCall;
    604602    }
    605603
     
    611609    bool isGeneratedForConstruct() const
    612610    {
    613         return m_codeBlockForConstruct;
     611        return m_codeBlockForConstruct.get();
    614612    }
    615613
     
    677675    DECLARE_INFO;
    678676
    679     void clearCode();
    680    
    681677    InferredValue* singletonFunction() { return m_singletonFunction.get(); }
    682678
    683679private:
     680    friend class ExecutableBase;
    684681    FunctionExecutable(
    685682        VM&, const SourceCode&, UnlinkedFunctionExecutable*, unsigned firstLine,
     
    691688   
    692689    WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
    693     RefPtr<FunctionCodeBlock> m_codeBlockForCall;
    694     RefPtr<FunctionCodeBlock> m_codeBlockForConstruct;
     690    WriteBarrier<FunctionCodeBlock> m_codeBlockForCall;
     691    WriteBarrier<FunctionCodeBlock> m_codeBlockForConstruct;
    695692    RefPtr<TypeSet> m_returnStatementTypeSet;
    696693    unsigned m_parametersStartOffset;
     
    720717    DECLARE_INFO;
    721718
    722     void clearCode();
    723 
    724719    void prepareForExecution(ExecState*);
    725720
     
    730725
    731726private:
     727    friend class ExecutableBase;
    732728    WebAssemblyExecutable(VM&, const SourceCode&, JSWASMModule*, unsigned functionIndex);
    733729
     
    738734    unsigned m_functionIndex;
    739735
    740     RefPtr<WebAssemblyCodeBlock> m_codeBlockForCall;
     736    WriteBarrier<WebAssemblyCodeBlock> m_codeBlockForCall;
    741737};
    742738#endif
    743739
    744 inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable)
    745 {
    746     switch (executable->type()) {
    747     case EvalExecutableType:
    748         return jsCast<EvalExecutable*>(executable)->clearCode();
    749     case ProgramExecutableType:
    750         return jsCast<ProgramExecutable*>(executable)->clearCode();
    751     case FunctionExecutableType:
    752         return jsCast<FunctionExecutable*>(executable)->clearCode();
    753 #if ENABLE(WEBASSEMBLY)
    754     case WebAssemblyExecutableType:
    755         return jsCast<WebAssemblyExecutable*>(executable)->clearCode();
    756 #endif
    757     case ModuleProgramExecutableType:
    758         return jsCast<ModuleProgramExecutable*>(executable)->clearCode();
    759     default:
    760         return jsCast<NativeExecutable*>(executable)->clearCode();
    761     }
    762 }
    763 
    764 }
    765 
    766 #endif
     740} // namespace JSC
     741
     742#endif // Executable_h
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r190453 r190522  
    249249    promiseDeferredStructure.set(*this, JSPromiseDeferred::createStructure(*this, 0, jsNull()));
    250250    internalPromiseDeferredStructure.set(*this, JSInternalPromiseDeferred::createStructure(*this, 0, jsNull()));
     251    programCodeBlockStructure.set(*this, ProgramCodeBlock::createStructure(*this, 0, jsNull()));
     252    moduleProgramCodeBlockStructure.set(*this, ModuleProgramCodeBlock::createStructure(*this, 0, jsNull()));
     253    evalCodeBlockStructure.set(*this, EvalCodeBlock::createStructure(*this, 0, jsNull()));
     254    functionCodeBlockStructure.set(*this, FunctionCodeBlock::createStructure(*this, 0, jsNull()));
     255#if ENABLE(WEBASSEMBLY)
     256    webAssemblyCodeBlockStructure.set(*this, WebAssemblyCodeBlock::createStructure(*this, 0, jsNull()));
     257#endif
     258
    251259    iterationTerminator.set(*this, JSFinalObject::create(*this, JSFinalObject::createStructure(*this, 0, jsNull(), 1)));
    252260    nativeStdFunctionCellStructure.set(*this, NativeStdFunctionCell::createStructure(*this, 0, jsNull()));
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r190453 r190522  
    310310    Strong<Structure> internalPromiseDeferredStructure;
    311311    Strong<Structure> nativeStdFunctionCellStructure;
     312    Strong<Structure> programCodeBlockStructure;
     313    Strong<Structure> moduleProgramCodeBlockStructure;
     314    Strong<Structure> evalCodeBlockStructure;
     315    Strong<Structure> functionCodeBlockStructure;
     316    Strong<Structure> webAssemblyCodeBlockStructure;
     317
    312318    Strong<JSCell> iterationTerminator;
    313319    Strong<JSCell> emptyPropertyNameEnumerator;
Note: See TracChangeset for help on using the changeset viewer.