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

This time for sure?

The cause of the leak was an invalidated compilation.

There was vestigial manual memory management code that eagerly removed
a CodeBlock from the set of CodeBlocks if compilation was invalidated.
That's not cool since we rely on the set of CodeBlocks when we run
destructors.

The fix is to remove the vestigial code.

I ran the leaks, correctness, and performance tests locally and did not
see any problems.

Restored changesets:

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


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@190694 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index e060105..8de2a53 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -82,6 +82,70 @@
 
 namespace JSC {
 
+const ClassInfo CodeBlock::s_info = {
+    "CodeBlock", 0, 0,
+    CREATE_METHOD_TABLE(CodeBlock)
+};
+
+const ClassInfo FunctionCodeBlock::s_info = {
+    "FunctionCodeBlock", &Base::s_info, 0,
+    CREATE_METHOD_TABLE(FunctionCodeBlock)
+};
+
+#if ENABLE(WEBASSEMBLY)
+const ClassInfo WebAssemblyCodeBlock::s_info = {
+    "WebAssemblyCodeBlock", &Base::s_info, 0,
+    CREATE_METHOD_TABLE(WebAssemblyCodeBlock)
+};
+#endif
+
+const ClassInfo GlobalCodeBlock::s_info = {
+    "GlobalCodeBlock", &Base::s_info, 0,
+    CREATE_METHOD_TABLE(GlobalCodeBlock)
+};
+
+const ClassInfo ProgramCodeBlock::s_info = {
+    "ProgramCodeBlock", &Base::s_info, 0,
+    CREATE_METHOD_TABLE(ProgramCodeBlock)
+};
+
+const ClassInfo ModuleProgramCodeBlock::s_info = {
+    "ModuleProgramCodeBlock", &Base::s_info, 0,
+    CREATE_METHOD_TABLE(ModuleProgramCodeBlock)
+};
+
+const ClassInfo EvalCodeBlock::s_info = {
+    "EvalCodeBlock", &Base::s_info, 0,
+    CREATE_METHOD_TABLE(EvalCodeBlock)
+};
+
+void FunctionCodeBlock::destroy(JSCell* cell)
+{
+    jsCast<FunctionCodeBlock*>(cell)->~FunctionCodeBlock();
+}
+
+#if ENABLE(WEBASSEMBLY)
+void WebAssemblyCodeBlock::destroy(JSCell* cell)
+{
+    jsCast<WebAssemblyCodeBlock*>(cell)->~WebAssemblyCodeBlock();
+}
+#endif
+
+void ProgramCodeBlock::destroy(JSCell* cell)
+{
+    jsCast<ProgramCodeBlock*>(cell)->~ProgramCodeBlock();
+}
+
+void ModuleProgramCodeBlock::destroy(JSCell* cell)
+{
+    jsCast<ModuleProgramCodeBlock*>(cell)->~ModuleProgramCodeBlock();
+}
+
+void EvalCodeBlock::destroy(JSCell* cell)
+{
+    jsCast<EvalCodeBlock*>(cell)->~EvalCodeBlock();
+}
+
 CString CodeBlock::inferredName() const
 {
     switch (codeType()) {
@@ -153,7 +217,7 @@
     out.print(inferredName(), "#", hashAsStringIfPossible());
     out.print(":[", RawPointer(this), "->");
     if (!!m_alternative)
-        out.print(RawPointer(m_alternative.get()), "->");
+        out.print(RawPointer(alternative()), "->");
     out.print(RawPointer(ownerExecutable()), ", ", jitType, codeType());
 
     if (codeType() == FunctionCode)
@@ -1581,8 +1645,9 @@
 
 } // anonymous namespace
 
-CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
-    : m_globalObject(other.m_globalObject)
+CodeBlock::CodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, CodeBlock& other)
+    : JSCell(*vm, structure)
+    , m_globalObject(other.m_globalObject)
     , m_heap(other.m_heap)
     , m_numCalleeRegisters(other.m_numCalleeRegisters)
     , m_numVars(other.m_numVars)
@@ -1590,11 +1655,11 @@
     , m_shouldAlwaysBeInlined(true)
     , m_didFailFTLCompilation(false)
     , m_hasBeenCompiledWithFTL(false)
-    , m_unlinkedCode(*other.m_vm, other.m_ownerExecutable.get(), other.m_unlinkedCode.get())
+    , m_unlinkedCode(*other.m_vm, this, other.m_unlinkedCode.get())
     , m_hasDebuggerStatement(false)
     , m_steppingMode(SteppingModeDisabled)
     , m_numBreakpoints(0)
-    , m_ownerExecutable(*other.m_vm, other.m_ownerExecutable.get(), other.m_ownerExecutable.get())
+    , m_ownerExecutable(*other.m_vm, this, other.m_ownerExecutable.get())
     , m_vm(other.m_vm)
     , m_instructions(other.m_instructions)
     , m_thisRegister(other.m_thisRegister)
@@ -1619,13 +1684,18 @@
     , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
 #endif
 {
-    m_visitStronglyHasBeenCalled.store(false, std::memory_order_relaxed);
-    m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
+    m_visitWeaklyHasBeenCalled.store(false, std::memory_order_relaxed);
 
     ASSERT(m_heap->isDeferred());
     ASSERT(m_scopeRegister.isLocal());
 
     setNumParameters(other.numParameters());
+}
+
+void CodeBlock::finishCreation(VM& vm, CopyParsedBlockTag, CodeBlock& other)
+{
+    Base::finishCreation(vm);
+
     optimizeAfterWarmUp();
     jitAfterWarmUp();
 
@@ -1639,11 +1709,12 @@
     }
     
     m_heap->m_codeBlocks.add(this);
-    m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock));
 }
 
-CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
-    : m_globalObject(scope->globalObject()->vm(), ownerExecutable, scope->globalObject())
+CodeBlock::CodeBlock(VM* vm, Structure* structure, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock,
+    JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
+    : JSCell(*vm, structure)
+    , m_globalObject(scope->globalObject()->vm(), this, scope->globalObject())
     , m_heap(&m_globalObject->vm().heap)
     , m_numCalleeRegisters(unlinkedCodeBlock->m_numCalleeRegisters)
     , m_numVars(unlinkedCodeBlock->m_numVars)
@@ -1651,11 +1722,11 @@
     , m_shouldAlwaysBeInlined(true)
     , m_didFailFTLCompilation(false)
     , m_hasBeenCompiledWithFTL(false)
-    , m_unlinkedCode(m_globalObject->vm(), ownerExecutable, unlinkedCodeBlock)
+    , m_unlinkedCode(m_globalObject->vm(), this, unlinkedCodeBlock)
     , m_hasDebuggerStatement(false)
     , m_steppingMode(SteppingModeDisabled)
     , m_numBreakpoints(0)
-    , m_ownerExecutable(m_globalObject->vm(), ownerExecutable, ownerExecutable)
+    , m_ownerExecutable(m_globalObject->vm(), this, ownerExecutable)
     , m_vm(unlinkedCodeBlock->vm())
     , m_thisRegister(unlinkedCodeBlock->thisRegister())
     , m_scopeRegister(unlinkedCodeBlock->scopeRegister())
@@ -1674,26 +1745,31 @@
     , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
 #endif
 {
-    m_visitStronglyHasBeenCalled.store(false, std::memory_order_relaxed);
-    m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
+    m_visitWeaklyHasBeenCalled.store(false, std::memory_order_relaxed);
 
     ASSERT(m_heap->isDeferred());
     ASSERT(m_scopeRegister.isLocal());
 
     ASSERT(m_source);
     setNumParameters(unlinkedCodeBlock->numParameters());
+}
 
-    if (vm()->typeProfiler() || vm()->controlFlowProfiler())
-        vm()->functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(), ownerExecutable->typeProfilingEndOffset());
+void CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock,
+    JSScope* scope)
+{
+    Base::finishCreation(vm);
+
+    if (vm.typeProfiler() || vm.controlFlowProfiler())
+        vm.functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(), ownerExecutable->typeProfilingEndOffset());
 
     setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation());
     if (unlinkedCodeBlock->usesGlobalObject())
-        m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, ownerExecutable, m_globalObject.get());
+        m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, this, m_globalObject.get());
 
     for (unsigned i = 0; i < LinkTimeConstantCount; i++) {
         LinkTimeConstant type = static_cast<LinkTimeConstant>(i);
         if (unsigned registerIndex = unlinkedCodeBlock->registerIndexForLinkTimeConstant(type))
-            m_constantRegisters[registerIndex].set(*m_vm, ownerExecutable, m_globalObject->jsCellForLinkTimeConstant(type));
+            m_constantRegisters[registerIndex].set(*m_vm, this, m_globalObject->jsCellForLinkTimeConstant(type));
     }
 
     HashSet<int, WTF::IntHash<int>, WTF::UnsignedWithZeroKeyHashTraits<int>> clonedConstantSymbolTables;
@@ -1708,7 +1784,7 @@
                     ConcurrentJITLocker locker(symbolTable->m_lock);
                     symbolTable->prepareForTypeProfiling(locker);
                 }
-                m_constantRegisters[i].set(*m_vm, ownerExecutable, symbolTable->cloneScopePart(*m_vm));
+                m_constantRegisters[i].set(*m_vm, this, symbolTable->cloneScopePart(*m_vm));
                 clonedConstantSymbolTables.add(i + FirstConstantRegisterIndex);
             }
         }
@@ -1728,17 +1804,17 @@
     m_functionDecls.resizeToFit(unlinkedCodeBlock->numberOfFunctionDecls());
     for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) {
         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
-        if (vm()->typeProfiler() || vm()->controlFlowProfiler())
-            vm()->functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
-        m_functionDecls[i].set(*m_vm, ownerExecutable, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
+        if (vm.typeProfiler() || vm.controlFlowProfiler())
+            vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
+        m_functionDecls[i].set(*m_vm, this, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
     }
 
     m_functionExprs.resizeToFit(unlinkedCodeBlock->numberOfFunctionExprs());
     for (size_t count = unlinkedCodeBlock->numberOfFunctionExprs(), i = 0; i < count; ++i) {
         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i);
-        if (vm()->typeProfiler() || vm()->controlFlowProfiler())
-            vm()->functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
-        m_functionExprs[i].set(*m_vm, ownerExecutable, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
+        if (vm.typeProfiler() || vm.controlFlowProfiler())
+            vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
+        m_functionExprs[i].set(*m_vm, this, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
     }
 
     if (unlinkedCodeBlock->hasRareData()) {
@@ -1817,7 +1893,7 @@
 
         unsigned opLength = opcodeLength(pc[0].u.opcode);
 
-        instructions[i] = vm()->interpreter->getOpcode(pc[0].u.opcode);
+        instructions[i] = vm.interpreter->getOpcode(pc[0].u.opcode);
         for (size_t j = 1; j < opLength; ++j) {
             if (sizeof(int32_t) != sizeof(intptr_t))
                 instructions[i + j].u.pointer = 0;
@@ -1876,8 +1952,8 @@
             int inferredInlineCapacity = pc[opLength - 2].u.operand;
 
             instructions[i + opLength - 1] = objectAllocationProfile;
-            objectAllocationProfile->initialize(*vm(),
-                ownerExecutable, m_globalObject->objectPrototype(), inferredInlineCapacity);
+            objectAllocationProfile->initialize(vm,
+                this, m_globalObject->objectPrototype(), inferredInlineCapacity);
             break;
         }
 
@@ -1925,11 +2001,11 @@
                     // Keep the linked module environment strongly referenced.
                     if (stronglyReferencedModuleEnvironments.add(jsCast<JSModuleEnvironment*>(op.lexicalEnvironment)).isNewEntry)
                         addConstant(op.lexicalEnvironment);
-                    instructions[i + 6].u.jsCell.set(*vm(), ownerExecutable, op.lexicalEnvironment);
+                    instructions[i + 6].u.jsCell.set(vm, this, op.lexicalEnvironment);
                 } else
-                    instructions[i + 6].u.symbolTable.set(*vm(), ownerExecutable, op.lexicalEnvironment->symbolTable());
+                    instructions[i + 6].u.symbolTable.set(vm, this, op.lexicalEnvironment->symbolTable());
             } else if (JSScope* constantScope = JSScope::constantScopeForCodeBlock(op.type, this))
-                instructions[i + 6].u.jsCell.set(*vm(), ownerExecutable, constantScope);
+                instructions[i + 6].u.jsCell.set(vm, this, constantScope);
             else
                 instructions[i + 6].u.pointer = nullptr;
             break;
@@ -1962,7 +2038,7 @@
             if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks || op.type == GlobalLexicalVar || op.type == GlobalLexicalVarWithVarInjectionChecks)
                 instructions[i + 5].u.watchpointSet = op.watchpointSet;
             else if (op.structure)
-                instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
+                instructions[i + 5].u.structure.set(vm, this, op.structure);
             instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand);
             break;
         }
@@ -1999,14 +2075,14 @@
                 if (op.watchpointSet)
                     op.watchpointSet->invalidate(PutToScopeFireDetail(this, ident));
             } else if (op.structure)
-                instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
+                instructions[i + 5].u.structure.set(vm, this, op.structure);
             instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand);
 
             break;
         }
 
         case op_profile_type: {
-            RELEASE_ASSERT(vm()->typeProfiler());
+            RELEASE_ASSERT(vm.typeProfiler());
             // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
             size_t instructionOffset = i + opLength - 1;
             unsigned divotStart, divotEnd;
@@ -2036,8 +2112,8 @@
                     ConcurrentJITLocker locker(symbolTable->m_lock);
                     // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet.
                     symbolTable->prepareForTypeProfiling(locker);
-                    globalVariableID = symbolTable->uniqueIDForVariable(locker, impl, *vm());
-                    globalTypeSet = symbolTable->globalTypeSetForVariable(locker, impl, *vm());
+                    globalVariableID = symbolTable->uniqueIDForVariable(locker, impl, vm);
+                    globalTypeSet = symbolTable->globalTypeSetForVariable(locker, impl, vm);
                 } else
                     globalVariableID = TypeProfilerNoGlobalIDExists;
 
@@ -2050,8 +2126,8 @@
                 const Identifier& ident = identifier(pc[4].u.operand);
                 ConcurrentJITLocker locker(symbolTable->m_lock);
                 // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet.
-                globalVariableID = symbolTable->uniqueIDForVariable(locker, ident.impl(), *vm());
-                globalTypeSet = symbolTable->globalTypeSetForVariable(locker, ident.impl(), *vm());
+                globalVariableID = symbolTable->uniqueIDForVariable(locker, ident.impl(), vm);
+                globalTypeSet = symbolTable->globalTypeSetForVariable(locker, ident.impl(), vm);
 
                 break;
             }
@@ -2077,8 +2153,8 @@
             }
             }
 
-            std::pair<TypeLocation*, bool> locationPair = vm()->typeProfiler()->typeLocationCache()->getTypeLocation(globalVariableID,
-                ownerExecutable->sourceID(), divotStart, divotEnd, globalTypeSet, vm());
+            std::pair<TypeLocation*, bool> locationPair = vm.typeProfiler()->typeLocationCache()->getTypeLocation(globalVariableID,
+                ownerExecutable->sourceID(), divotStart, divotEnd, globalTypeSet, &vm);
             TypeLocation* location = locationPair.first;
             bool isNewLocation = locationPair.second;
 
@@ -2086,7 +2162,7 @@
                 location->m_divotForFunctionOffsetIfReturnStatement = ownerExecutable->typeProfilingStartOffset();
 
             if (shouldAnalyze && isNewLocation)
-                vm()->typeProfiler()->insertNewLocation(location);
+                vm.typeProfiler()->insertNewLocation(location);
 
             instructions[i + 2].u.location = location;
             break;
@@ -2104,7 +2180,7 @@
         i += opLength;
     }
 
-    if (vm()->controlFlowProfiler())
+    if (vm.controlFlowProfiler())
         insertBasicBlockBoundariesForControlFlowProfiler(instructions);
 
     m_instructions = WTF::RefCountedArray<Instruction>(instructions);
@@ -2124,12 +2200,13 @@
         dumpBytecode();
     
     m_heap->m_codeBlocks.add(this);
-    m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock) + m_instructions.size() * sizeof(Instruction));
+    m_heap->reportExtraMemoryAllocated(m_instructions.size() * sizeof(Instruction));
 }
 
 #if ENABLE(WEBASSEMBLY)
-CodeBlock::CodeBlock(WebAssemblyExecutable* ownerExecutable, VM& vm, JSGlobalObject* globalObject)
-    : m_globalObject(globalObject->vm(), ownerExecutable, globalObject)
+CodeBlock::CodeBlock(VM* vm, Structure* structure, WebAssemblyExecutable* ownerExecutable, VM& vm, JSGlobalObject* globalObject)
+    : JSCell(vm, structure)
+    , m_globalObject(globalObject->vm(), this, globalObject)
     , m_heap(&m_globalObject->vm().heap)
     , m_numCalleeRegisters(0)
     , m_numVars(0)
@@ -2140,7 +2217,7 @@
     , m_hasDebuggerStatement(false)
     , m_steppingMode(SteppingModeDisabled)
     , m_numBreakpoints(0)
-    , m_ownerExecutable(m_globalObject->vm(), ownerExecutable, ownerExecutable)
+    , m_ownerExecutable(m_globalObject->vm(), this, ownerExecutable)
     , m_vm(&vm)
     , m_isStrictMode(false)
     , m_needsActivation(false)
@@ -2154,9 +2231,13 @@
 #endif
 {
     ASSERT(m_heap->isDeferred());
+}
+
+void CodeBlock::finishCreation(VM& vm, WebAssemblyExecutable*, JSGlobalObject*)
+{
+    Base::finishCreation(vm);
 
     m_heap->m_codeBlocks.add(this);
-    m_heap->reportExtraMemoryAllocated(sizeof(CodeBlock));
 }
 #endif
 
@@ -2168,29 +2249,30 @@
 #if ENABLE(VERBOSE_VALUE_PROFILE)
     dumpValueProfiles();
 #endif
-    while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
-        m_incomingLLIntCalls.begin()->remove();
-#if ENABLE(JIT)
+
     // We may be destroyed before any CodeBlocks that refer to us are destroyed.
     // Consider that two CodeBlocks become unreachable at the same time. There
     // is no guarantee about the order in which the CodeBlocks are destroyed.
     // So, if we don't remove incoming calls, and get destroyed before the
     // CodeBlock(s) that have calls into us, then the CallLinkInfo vector's
     // destructor will try to remove nodes from our (no longer valid) linked list.
-    while (m_incomingCalls.begin() != m_incomingCalls.end())
-        m_incomingCalls.begin()->remove();
-    while (m_incomingPolymorphicCalls.begin() != m_incomingPolymorphicCalls.end())
-        m_incomingPolymorphicCalls.begin()->remove();
+    unlinkIncomingCalls();
     
     // Note that our outgoing calls will be removed from other CodeBlocks'
     // m_incomingCalls linked lists through the execution of the ~CallLinkInfo
     // destructors.
 
+#if ENABLE(JIT)
     for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter)
         (*iter)->deref();
 #endif // ENABLE(JIT)
 }
 
+void CodeBlock::setAlternative(VM& vm, CodeBlock* alternative)
+{
+    m_alternative.set(vm, this, alternative);
+}
+
 void CodeBlock::setNumParameters(int newValue)
 {
     m_numParameters = newValue;
@@ -2211,73 +2293,43 @@
     if (jitType() != JITCode::DFGJIT)
         return 0;
     DFG::JITCode* jitCode = m_jitCode->dfg();
-    return jitCode->osrEntryBlock.get();
+    return jitCode->osrEntryBlock();
 #else // ENABLE(FTL_JIT)
     return 0;
 #endif // ENABLE(FTL_JIT)
 }
 
-void CodeBlock::visitStrongly(SlotVisitor& visitor)
+void CodeBlock::visitWeakly(SlotVisitor& visitor)
 {
-    bool setByMe = m_visitStronglyHasBeenCalled.compareExchangeStrong(false, true);
+    bool setByMe = m_visitWeaklyHasBeenCalled.compareExchangeStrong(false, true);
     if (!setByMe)
         return;
 
-    visitAggregate(visitor);
-
-    stronglyVisitStrongReferences(visitor);
-    stronglyVisitWeakReferences(visitor);
-    propagateTransitions(visitor);
-}
-
-void CodeBlock::visitAggregate(SlotVisitor& visitor)
-{
-    // I may be asked to scan myself more than once, and it may even happen concurrently.
-    // To this end, use an atomic operation to check (and set) if I've been called already.
-    // Only one thread may proceed past this point - whichever one wins the atomic set race.
-    bool setByMe = m_visitAggregateHasBeenCalled.compareExchangeStrong(false, true);
-    if (!setByMe)
+    if (Heap::isMarked(this))
         return;
-    
-    if (!!m_alternative)
-        m_alternative->visitAggregate(visitor);
-    
-    if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
-        otherBlock->visitAggregate(visitor);
 
-    visitor.reportExtraMemoryVisited(sizeof(CodeBlock));
-    if (m_jitCode)
-        visitor.reportExtraMemoryVisited(m_jitCode->size());
-    if (m_instructions.size()) {
-        // Divide by refCount() because m_instructions points to something that is shared
-        // by multiple CodeBlocks, and we only want to count it towards the heap size once.
-        // Having each CodeBlock report only its proportional share of the size is one way
-        // of accomplishing this.
-        visitor.reportExtraMemoryVisited(m_instructions.size() * sizeof(Instruction) / m_instructions.refCount());
+    if (shouldVisitStrongly()) {
+        visitor.appendUnbarrieredReadOnlyPointer(this);
+        return;
     }
 
-    visitor.append(&m_unlinkedCode);
-
     // There are two things that may use unconditional finalizers: inline cache clearing
     // and jettisoning. The probability of us wanting to do at least one of those things
     // is probably quite close to 1. So we add one no matter what and when it runs, it
     // figures out whether it has any work to do.
-    visitor.addUnconditionalFinalizer(this);
-    
-    m_allTransitionsHaveBeenMarked = false;
-    
-    if (shouldVisitStrongly()) {
-        visitStrongly(visitor);
-        return;
-    }
-    
+    visitor.addUnconditionalFinalizer(&m_unconditionalFinalizer);
+
     if (!JITCode::isOptimizingJIT(jitType()))
         return;
 
+    // If we jettison ourselves we'll install our alternative, so make sure that it
+    // survives GC even if we don't.
+    visitor.append(&m_alternative);
+    
     // There are two things that we use weak reference harvesters for: DFG fixpoint for
     // jettisoning, and trying to find structures that would be live based on some
     // inline cache. So it makes sense to register them regardless.
-    visitor.addWeakReferenceHarvester(this);
+    visitor.addWeakReferenceHarvester(&m_weakReferenceHarvester);
 
 #if ENABLE(DFG_JIT)
     // We get here if we're live in the sense that our owner executable is live,
@@ -2288,14 +2340,48 @@
     // either us marking additional objects, or by other objects being marked for
     // other reasons, that this iteration should run again; it will notify us of this
     // decision by calling harvestWeakReferences().
-    
-    m_jitCode->dfgCommon()->livenessHasBeenProved = false;
-    
+
+    m_allTransitionsHaveBeenMarked = false;
     propagateTransitions(visitor);
+
+    m_jitCode->dfgCommon()->livenessHasBeenProved = false;
     determineLiveness(visitor);
 #endif // ENABLE(DFG_JIT)
 }
 
+void CodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    CodeBlock* thisObject = jsCast<CodeBlock*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    JSCell::visitChildren(thisObject, visitor);
+    thisObject->visitChildren(visitor);
+}
+
+void CodeBlock::visitChildren(SlotVisitor& visitor)
+{
+    // There are two things that may use unconditional finalizers: inline cache clearing
+    // and jettisoning. The probability of us wanting to do at least one of those things
+    // is probably quite close to 1. So we add one no matter what and when it runs, it
+    // figures out whether it has any work to do.
+    visitor.addUnconditionalFinalizer(&m_unconditionalFinalizer);
+
+    if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
+        visitor.appendUnbarrieredReadOnlyPointer(otherBlock);
+
+    if (m_jitCode)
+        visitor.reportExtraMemoryVisited(m_jitCode->size());
+    if (m_instructions.size())
+        visitor.reportExtraMemoryVisited(m_instructions.size() * sizeof(Instruction) / m_instructions.refCount());
+
+    visitor.append(&m_unlinkedCode);
+
+    stronglyVisitStrongReferences(visitor);
+    stronglyVisitWeakReferences(visitor);
+
+    m_allTransitionsHaveBeenMarked = false;
+    propagateTransitions(visitor);
+}
+
 bool CodeBlock::shouldVisitStrongly()
 {
     if (Options::forceCodeBlockLiveness())
@@ -2323,17 +2409,7 @@
     //   because livenessHasBeenProved would have survived as true.
     // - Code blocks that don't have any dead weak references.
 
-    if (m_visitStronglyHasBeenCalled.load(std::memory_order_relaxed))
-        return true;
-
-#if ENABLE(DFG_JIT)
-    if (JITCode::isOptimizingJIT(jitType())) {
-        if (m_jitCode->dfgCommon()->livenessHasBeenProved)
-            return true;
-    }
-#endif
-
-    return false;
+    return Heap::isMarked(this);
 }
 
 bool CodeBlock::shouldJettisonDueToWeakReference()
@@ -2343,12 +2419,34 @@
     return !isKnownToBeLiveDuringGC();
 }
 
+static std::chrono::milliseconds timeToLive(JITCode::JITType jitType)
+{
+    switch (jitType) {
+    case JITCode::InterpreterThunk:
+        return std::chrono::duration_cast<std::chrono::milliseconds>(
+            std::chrono::seconds(5));
+    case JITCode::BaselineJIT:
+        // Effectively 10 additional seconds, since BaselineJIT and
+        // InterpreterThunk share a CodeBlock.
+        return std::chrono::duration_cast<std::chrono::milliseconds>(
+            std::chrono::seconds(15));
+    case JITCode::DFGJIT:
+        return std::chrono::duration_cast<std::chrono::milliseconds>(
+            std::chrono::seconds(20));
+    case JITCode::FTLJIT:
+        return std::chrono::duration_cast<std::chrono::milliseconds>(
+            std::chrono::seconds(60));
+    default:
+        return std::chrono::milliseconds::max();
+    }
+}
+
 bool CodeBlock::shouldJettisonDueToOldAge()
 {
-    if (m_visitStronglyHasBeenCalled.load(std::memory_order_relaxed))
+    if (Heap::isMarked(this))
         return false;
 
-    if (timeSinceCreation() < JITCode::timeToLive(jitType()))
+    if (timeSinceCreation() < timeToLive(jitType()))
         return false;
 
     return true;
@@ -2501,14 +2599,18 @@
     // All weak references are live. Record this information so we don't
     // come back here again, and scan the strong references.
     dfgCommon->livenessHasBeenProved = true;
-    stronglyVisitStrongReferences(visitor);
+    visitor.appendUnbarrieredReadOnlyPointer(this);
 #endif // ENABLE(DFG_JIT)
 }
 
-void CodeBlock::visitWeakReferences(SlotVisitor& visitor)
+void CodeBlock::WeakReferenceHarvester::visitWeakReferences(SlotVisitor& visitor)
 {
-    propagateTransitions(visitor);
-    determineLiveness(visitor);
+    CodeBlock* codeBlock =
+        bitwise_cast<CodeBlock*>(
+            bitwise_cast<char*>(this) - OBJECT_OFFSETOF(CodeBlock, m_weakReferenceHarvester));
+
+    codeBlock->propagateTransitions(visitor);
+    codeBlock->determineLiveness(visitor);
 }
 
 void CodeBlock::finalizeLLIntInlineCaches()
@@ -2628,26 +2730,29 @@
 #endif
 }
 
-void CodeBlock::finalizeUnconditionally()
+void CodeBlock::UnconditionalFinalizer::finalizeUnconditionally()
 {
+    CodeBlock* codeBlock = bitwise_cast<CodeBlock*>(
+        bitwise_cast<char*>(this) - OBJECT_OFFSETOF(CodeBlock, m_unconditionalFinalizer));
+
 #if ENABLE(DFG_JIT)
-    if (shouldJettisonDueToWeakReference()) {
-        jettison(Profiler::JettisonDueToWeakReference);
+    if (codeBlock->shouldJettisonDueToWeakReference()) {
+        codeBlock->jettison(Profiler::JettisonDueToWeakReference);
         return;
     }
 #endif // ENABLE(DFG_JIT)
 
-    if (shouldJettisonDueToOldAge()) {
-        jettison(Profiler::JettisonDueToOldAge);
+    if (codeBlock->shouldJettisonDueToOldAge()) {
+        codeBlock->jettison(Profiler::JettisonDueToOldAge);
         return;
     }
 
-    if (JITCode::couldBeInterpreted(jitType()))
-        finalizeLLIntInlineCaches();
+    if (JITCode::couldBeInterpreted(codeBlock->jitType()))
+        codeBlock->finalizeLLIntInlineCaches();
 
 #if ENABLE(JIT)
-    if (!!jitCode())
-        finalizeBaselineJITInlineCaches();
+    if (!!codeBlock->jitCode())
+        codeBlock->finalizeBaselineJITInlineCaches();
 #endif
 }
 
@@ -2742,14 +2847,14 @@
     // guaranteeing that it matches the details of the CodeBlock we compiled
     // the OSR exit against.
 
-    alternative()->visitStrongly(visitor);
+    visitor.append(&m_alternative);
 
 #if ENABLE(DFG_JIT)
     DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
     if (dfgCommon->inlineCallFrames) {
         for (auto* inlineCallFrame : *dfgCommon->inlineCallFrames) {
-            ASSERT(inlineCallFrame->baselineCodeBlock());
-            inlineCallFrame->baselineCodeBlock()->visitStrongly(visitor);
+            ASSERT(inlineCallFrame->baselineCodeBlock);
+            visitor.append(&inlineCallFrame->baselineCodeBlock);
         }
     }
 #endif
@@ -2958,8 +3063,6 @@
     while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
         m_incomingLLIntCalls.begin()->unlink();
 #if ENABLE(JIT)
-    if (m_incomingCalls.isEmpty() && m_incomingPolymorphicCalls.isEmpty())
-        return;
     while (m_incomingCalls.begin() != m_incomingCalls.end())
         m_incomingCalls.begin()->unlink(*vm());
     while (m_incomingPolymorphicCalls.begin() != m_incomingPolymorphicCalls.end())
@@ -2973,66 +3076,66 @@
     m_incomingLLIntCalls.push(incoming);
 }
 
-PassRefPtr<CodeBlock> CodeBlock::newReplacement()
+CodeBlock* CodeBlock::newReplacement()
 {
     return ownerScriptExecutable()->newReplacementCodeBlockFor(specializationKind());
 }
 
 #if ENABLE(JIT)
-CodeBlock* ProgramCodeBlock::replacement()
+CodeBlock* CodeBlock::replacement()
 {
-    return jsCast<ProgramExecutable*>(ownerExecutable())->codeBlock();
-}
+    const ClassInfo* classInfo = this->classInfo();
 
-CodeBlock* ModuleProgramCodeBlock::replacement()
-{
-    return jsCast<ModuleProgramExecutable*>(ownerExecutable())->codeBlock();
-}
+    if (classInfo == FunctionCodeBlock::info())
+        return jsCast<FunctionExecutable*>(ownerExecutable())->codeBlockFor(m_isConstructor ? CodeForConstruct : CodeForCall);
 
-CodeBlock* EvalCodeBlock::replacement()
-{
-    return jsCast<EvalExecutable*>(ownerExecutable())->codeBlock();
-}
+    if (classInfo == EvalCodeBlock::info())
+        return jsCast<EvalExecutable*>(ownerExecutable())->codeBlock();
 
-CodeBlock* FunctionCodeBlock::replacement()
-{
-    return jsCast<FunctionExecutable*>(ownerExecutable())->codeBlockFor(m_isConstructor ? CodeForConstruct : CodeForCall);
-}
+    if (classInfo == ProgramCodeBlock::info())
+        return jsCast<ProgramExecutable*>(ownerExecutable())->codeBlock();
 
-DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal()
-{
-    return DFG::programCapabilityLevel(this);
-}
-
-DFG::CapabilityLevel ModuleProgramCodeBlock::capabilityLevelInternal()
-{
-    return DFG::programCapabilityLevel(this);
-}
-
-DFG::CapabilityLevel EvalCodeBlock::capabilityLevelInternal()
-{
-    return DFG::evalCapabilityLevel(this);
-}
-
-DFG::CapabilityLevel FunctionCodeBlock::capabilityLevelInternal()
-{
-    if (m_isConstructor)
-        return DFG::functionForConstructCapabilityLevel(this);
-    return DFG::functionForCallCapabilityLevel(this);
-}
+    if (classInfo == ModuleProgramCodeBlock::info())
+        return jsCast<ModuleProgramExecutable*>(ownerExecutable())->codeBlock();
 
 #if ENABLE(WEBASSEMBLY)
-CodeBlock* WebAssemblyCodeBlock::replacement()
-{
+    if (classInfo == WebAssemblyCodeBlock::info())
+        return nullptr;
+#endif
+
+    RELEASE_ASSERT_NOT_REACHED();
     return nullptr;
 }
 
-DFG::CapabilityLevel WebAssemblyCodeBlock::capabilityLevelInternal()
+DFG::CapabilityLevel CodeBlock::computeCapabilityLevel()
 {
+    const ClassInfo* classInfo = this->classInfo();
+
+    if (classInfo == FunctionCodeBlock::info()) {
+        if (m_isConstructor)
+            return DFG::functionForConstructCapabilityLevel(this);
+        return DFG::functionForCallCapabilityLevel(this);
+    }
+
+    if (classInfo == EvalCodeBlock::info())
+        return DFG::evalCapabilityLevel(this);
+
+    if (classInfo == ProgramCodeBlock::info())
+        return DFG::programCapabilityLevel(this);
+
+    if (classInfo == ModuleProgramCodeBlock::info())
+        return DFG::programCapabilityLevel(this);
+
+#if ENABLE(WEBASSEMBLY)
+    if (classInfo == WebAssemblyCodeBlock::info())
+        return DFG::CannotCompile;
+#endif
+
+    RELEASE_ASSERT_NOT_REACHED();
     return DFG::CannotCompile;
 }
-#endif
-#endif
+
+#endif // ENABLE(JIT)
 
 void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode, const FireDetail* detail)
 {
@@ -3136,7 +3239,7 @@
 {
     if (!codeOrigin.inlineCallFrame)
         return globalObject();
-    return jsCast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())->eitherCodeBlock()->globalObject();
+    return codeOrigin.inlineCallFrame->baselineCodeBlock->globalObject();
 }
 
 class RecursionCheckFunctor {
@@ -3976,7 +4079,7 @@
 #if ENABLE(JIT)
 DFG::CapabilityLevel CodeBlock::capabilityLevel()
 {
-    DFG::CapabilityLevel result = capabilityLevelInternal();
+    DFG::CapabilityLevel result = computeCapabilityLevel();
     m_capabilityLevelState = result;
     return result;
 }
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index 5c2b10c4b..1e4e3ecf 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -38,10 +38,10 @@
 #include "CallReturnOffsetToBytecodeOffset.h"
 #include "CodeBlockHash.h"
 #include "CodeBlockSet.h"
-#include "ConcurrentJITLock.h"
 #include "CodeOrigin.h"
 #include "CodeType.h"
 #include "CompactJITCodeMap.h"
+#include "ConcurrentJITLock.h"
 #include "DFGCommon.h"
 #include "DFGExitProfile.h"
 #include "DeferredCompilationCallback.h"
@@ -49,18 +49,19 @@
 #include "ExecutionCounter.h"
 #include "ExpressionRangeInfo.h"
 #include "HandlerInfo.h"
-#include "ObjectAllocationProfile.h"
-#include "Options.h"
-#include "PutPropertySlot.h"
 #include "Instruction.h"
 #include "JITCode.h"
 #include "JITWriteBarrier.h"
+#include "JSCell.h"
 #include "JSGlobalObject.h"
 #include "JumpTable.h"
 #include "LLIntCallLinkInfo.h"
 #include "LazyOperandValueProfile.h"
+#include "ObjectAllocationProfile.h"
+#include "Options.h"
 #include "ProfilerCompilation.h"
 #include "ProfilerJettisonReason.h"
+#include "PutPropertySlot.h"
 #include "RegExpObject.h"
 #include "StructureStubInfo.h"
 #include "UnconditionalFinalizer.h"
@@ -85,26 +86,45 @@
 
 enum ReoptimizationMode { DontCountReoptimization, CountReoptimization };
 
-class CodeBlock : public ThreadSafeRefCounted<CodeBlock>, public UnconditionalFinalizer, public WeakReferenceHarvester {
-    WTF_MAKE_FAST_ALLOCATED;
+class CodeBlock : public JSCell {
+    typedef JSCell Base;
     friend class BytecodeLivenessAnalysis;
     friend class JIT;
     friend class LLIntOffsetsExtractor;
+
+    class UnconditionalFinalizer : public JSC::UnconditionalFinalizer { 
+        virtual void finalizeUnconditionally() override;
+    };
+
+    class WeakReferenceHarvester : public JSC::WeakReferenceHarvester {
+        virtual void visitWeakReferences(SlotVisitor&) override;
+    };
+
 public:
     enum CopyParsedBlockTag { CopyParsedBlock };
+
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
+    DECLARE_INFO;
+
 protected:
-    CodeBlock(CopyParsedBlockTag, CodeBlock& other);
-        
-    CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSScope*, PassRefPtr<SourceProvider>, unsigned sourceOffset, unsigned firstLineColumnOffset);
+    CodeBlock(VM*, Structure*, CopyParsedBlockTag, CodeBlock& other);
+    CodeBlock(VM*, Structure*, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSScope*, PassRefPtr<SourceProvider>, unsigned sourceOffset, unsigned firstLineColumnOffset);
 #if ENABLE(WEBASSEMBLY)
-    CodeBlock(WebAssemblyExecutable* ownerExecutable, VM&, JSGlobalObject*);
+    CodeBlock(VM*, Structure*, WebAssemblyExecutable* ownerExecutable, VM&, JSGlobalObject*);
+#endif
+
+    void finishCreation(VM&, CopyParsedBlockTag, CodeBlock& other);
+    void finishCreation(VM&, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock*, JSScope*);
+#if ENABLE(WEBASSEMBLY)
+    void finishCreation(VM&, WebAssemblyExecutable* ownerExecutable, JSGlobalObject*);
 #endif
 
     WriteBarrier<JSGlobalObject> m_globalObject;
     Heap* m_heap;
 
 public:
-    JS_EXPORT_PRIVATE virtual ~CodeBlock();
+    JS_EXPORT_PRIVATE ~CodeBlock();
 
     UnlinkedCodeBlock* unlinkedCodeBlock() const { return m_unlinkedCode.get(); }
 
@@ -124,8 +144,8 @@
     int* addressOfNumParameters() { return &m_numParameters; }
     static ptrdiff_t offsetOfNumParameters() { return OBJECT_OFFSETOF(CodeBlock, m_numParameters); }
 
-    CodeBlock* alternative() { return m_alternative.get(); }
-    void setAlternative(PassRefPtr<CodeBlock> alternative) { m_alternative = alternative; }
+    CodeBlock* alternative() const { return static_cast<CodeBlock*>(m_alternative.get()); }
+    void setAlternative(VM&, CodeBlock*);
 
     template <typename Functor> void forEachRelatedCodeBlock(Functor&& functor)
     {
@@ -148,16 +168,18 @@
     {
         return specializationFromIsConstruct(m_isConstructor);
     }
-    
+
+    CodeBlock* alternativeForJettison();    
     CodeBlock* baselineAlternative();
     
     // FIXME: Get rid of this.
     // https://bugs.webkit.org/show_bug.cgi?id=123677
     CodeBlock* baselineVersion();
 
-    void clearMarks();
-    void visitAggregate(SlotVisitor&);
-    void visitStrongly(SlotVisitor&);
+    static void visitChildren(JSCell*, SlotVisitor&);
+    void visitChildren(SlotVisitor&);
+    void visitWeakly(SlotVisitor&);
+    void clearVisitWeaklyHasBeenCalled();
 
     void dumpSource();
     void dumpSource(PrintStream&);
@@ -265,7 +287,7 @@
     unsigned instructionCount() const { return m_instructions.size(); }
 
     // Exactly equivalent to codeBlock->ownerExecutable()->newReplacementCodeBlockFor(codeBlock->specializationKind())
-    PassRefPtr<CodeBlock> newReplacement();
+    CodeBlock* newReplacement();
     
     void setJITCode(PassRefPtr<JITCode> code)
     {
@@ -291,9 +313,9 @@
     }
     
 #if ENABLE(JIT)
-    virtual CodeBlock* replacement() = 0;
+    CodeBlock* replacement();
 
-    virtual DFG::CapabilityLevel capabilityLevelInternal() = 0;
+    DFG::CapabilityLevel computeCapabilityLevel();
     DFG::CapabilityLevel capabilityLevel();
     DFG::CapabilityLevel capabilityLevelState() { return m_capabilityLevelState; }
 
@@ -543,7 +565,7 @@
     {
         unsigned result = m_constantRegisters.size();
         m_constantRegisters.append(WriteBarrier<Unknown>());
-        m_constantRegisters.last().set(m_globalObject->vm(), m_ownerExecutable.get(), v);
+        m_constantRegisters.last().set(m_globalObject->vm(), this, v);
         m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other);
         return result;
     }
@@ -895,8 +917,6 @@
     }
 
 protected:
-    virtual void visitWeakReferences(SlotVisitor&) override;
-    virtual void finalizeUnconditionally() override;
     void finalizeLLIntInlineCaches();
     void finalizeBaselineJITInlineCaches();
 
@@ -923,14 +943,14 @@
         size_t count = constants.size();
         m_constantRegisters.resizeToFit(count);
         for (size_t i = 0; i < count; i++)
-            m_constantRegisters[i].set(*m_vm, ownerExecutable(), constants[i].get());
+            m_constantRegisters[i].set(*m_vm, this, constants[i].get());
         m_constantsSourceCodeRepresentation = constantsSourceCodeRepresentation;
     }
 
     void replaceConstant(int index, JSValue value)
     {
         ASSERT(isConstantRegisterIndex(index) && static_cast<size_t>(index - FirstConstantRegisterIndex) < m_constantRegisters.size());
-        m_constantRegisters[index - FirstConstantRegisterIndex].set(m_globalObject->vm(), m_ownerExecutable.get(), value);
+        m_constantRegisters[index - FirstConstantRegisterIndex].set(m_globalObject->vm(), this, value);
     }
 
     void dumpBytecode(
@@ -1002,8 +1022,7 @@
     bool m_isStrictMode;
     bool m_needsActivation;
 
-    Atomic<bool> m_visitAggregateHasBeenCalled;
-    Atomic<bool> m_visitStronglyHasBeenCalled;
+    Atomic<bool> m_visitWeaklyHasBeenCalled;
 
     RefPtr<SourceProvider> m_source;
     unsigned m_sourceOffset;
@@ -1045,7 +1064,7 @@
     Vector<WriteBarrier<FunctionExecutable>> m_functionDecls;
     Vector<WriteBarrier<FunctionExecutable>> m_functionExprs;
 
-    RefPtr<CodeBlock> m_alternative;
+    WriteBarrier<CodeBlock> m_alternative;
     
     BaselineExecutionCounter m_llintExecuteCounter;
 
@@ -1065,124 +1084,242 @@
 #if ENABLE(JIT)
     DFG::CapabilityLevel m_capabilityLevelState;
 #endif
+
+    UnconditionalFinalizer m_unconditionalFinalizer;
+    WeakReferenceHarvester m_weakReferenceHarvester;
 };
 
 // Program code is not marked by any function, so we make the global object
 // responsible for marking it.
 
 class GlobalCodeBlock : public CodeBlock {
+    typedef CodeBlock Base;
+    DECLARE_INFO;
+
 protected:
-    GlobalCodeBlock(CopyParsedBlockTag, GlobalCodeBlock& other)
-    : CodeBlock(CopyParsedBlock, other)
+    GlobalCodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, GlobalCodeBlock& other)
+        : CodeBlock(vm, structure, CopyParsedBlock, other)
     {
     }
-        
-    GlobalCodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
-        : CodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset)
+
+    GlobalCodeBlock(VM* vm, Structure* structure, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
+        : CodeBlock(vm, structure, ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset)
     {
     }
 };
 
 class ProgramCodeBlock : public GlobalCodeBlock {
 public:
-    ProgramCodeBlock(CopyParsedBlockTag, ProgramCodeBlock& other)
-    : GlobalCodeBlock(CopyParsedBlock, other)
+    typedef GlobalCodeBlock Base;
+    DECLARE_INFO;
+
+    static ProgramCodeBlock* create(VM* vm, CopyParsedBlockTag, ProgramCodeBlock& other)
+    {
+        ProgramCodeBlock* instance = new (NotNull, allocateCell<ProgramCodeBlock>(vm->heap))
+            ProgramCodeBlock(vm, vm->programCodeBlockStructure.get(), CopyParsedBlock, other);
+        instance->finishCreation(*vm, CopyParsedBlock, other);
+        return instance;
+    }
+
+    static ProgramCodeBlock* create(VM* vm, ProgramExecutable* ownerExecutable, UnlinkedProgramCodeBlock* unlinkedCodeBlock,
+        JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
+    {
+        ProgramCodeBlock* instance = new (NotNull, allocateCell<ProgramCodeBlock>(vm->heap))
+            ProgramCodeBlock(vm, vm->programCodeBlockStructure.get(), ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, firstLineColumnOffset);
+        instance->finishCreation(*vm, ownerExecutable, unlinkedCodeBlock, scope);
+        return instance;
+    }
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+    }
+
+private:
+    ProgramCodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, ProgramCodeBlock& other)
+        : GlobalCodeBlock(vm, structure, CopyParsedBlock, other)
     {
     }
 
-    ProgramCodeBlock(ProgramExecutable* ownerExecutable, UnlinkedProgramCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
-        : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset)
+    ProgramCodeBlock(VM* vm, Structure* structure, ProgramExecutable* ownerExecutable, UnlinkedProgramCodeBlock* unlinkedCodeBlock,
+        JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
+        : GlobalCodeBlock(vm, structure, ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset)
     {
     }
 
-#if ENABLE(JIT)
-protected:
-    virtual CodeBlock* replacement() override;
-    virtual DFG::CapabilityLevel capabilityLevelInternal() override;
-#endif
+    static void destroy(JSCell*);
 };
 
 class ModuleProgramCodeBlock : public GlobalCodeBlock {
 public:
-    ModuleProgramCodeBlock(CopyParsedBlockTag, ModuleProgramCodeBlock& other)
-        : GlobalCodeBlock(CopyParsedBlock, other)
+    typedef GlobalCodeBlock Base;
+    DECLARE_INFO;
+
+    static ModuleProgramCodeBlock* create(VM* vm, CopyParsedBlockTag, ModuleProgramCodeBlock& other)
+    {
+        ModuleProgramCodeBlock* instance = new (NotNull, allocateCell<ModuleProgramCodeBlock>(vm->heap))
+            ModuleProgramCodeBlock(vm, vm->moduleProgramCodeBlockStructure.get(), CopyParsedBlock, other);
+        instance->finishCreation(*vm, CopyParsedBlock, other);
+        return instance;
+    }
+
+    static ModuleProgramCodeBlock* create(VM* vm, ModuleProgramExecutable* ownerExecutable, UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock,
+        JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
+    {
+        ModuleProgramCodeBlock* instance = new (NotNull, allocateCell<ModuleProgramCodeBlock>(vm->heap))
+            ModuleProgramCodeBlock(vm, vm->moduleProgramCodeBlockStructure.get(), ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, firstLineColumnOffset);
+        instance->finishCreation(*vm, ownerExecutable, unlinkedCodeBlock, scope);
+        return instance;
+    }
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+    }
+
+private:
+    ModuleProgramCodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, ModuleProgramCodeBlock& other)
+        : GlobalCodeBlock(vm, structure, CopyParsedBlock, other)
     {
     }
 
-    ModuleProgramCodeBlock(ModuleProgramExecutable* ownerExecutable, UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
-        : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset)
+    ModuleProgramCodeBlock(VM* vm, Structure* structure, ModuleProgramExecutable* ownerExecutable, UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock,
+        JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset)
+        : GlobalCodeBlock(vm, structure, ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset)
     {
     }
 
-#if ENABLE(JIT)
-protected:
-    virtual CodeBlock* replacement() override;
-    virtual DFG::CapabilityLevel capabilityLevelInternal() override;
-#endif
+    static void destroy(JSCell*);
 };
 
 class EvalCodeBlock : public GlobalCodeBlock {
 public:
-    EvalCodeBlock(CopyParsedBlockTag, EvalCodeBlock& other)
-        : GlobalCodeBlock(CopyParsedBlock, other)
+    typedef GlobalCodeBlock Base;
+    DECLARE_INFO;
+
+    static EvalCodeBlock* create(VM* vm, CopyParsedBlockTag, EvalCodeBlock& other)
     {
+        EvalCodeBlock* instance = new (NotNull, allocateCell<EvalCodeBlock>(vm->heap))
+            EvalCodeBlock(vm, vm->evalCodeBlockStructure.get(), CopyParsedBlock, other);
+        instance->finishCreation(*vm, CopyParsedBlock, other);
+        return instance;
     }
-        
-    EvalCodeBlock(EvalExecutable* ownerExecutable, UnlinkedEvalCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider)
-        : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, 1)
+
+    static EvalCodeBlock* create(VM* vm, EvalExecutable* ownerExecutable, UnlinkedEvalCodeBlock* unlinkedCodeBlock,
+        JSScope* scope, PassRefPtr<SourceProvider> sourceProvider)
     {
+        EvalCodeBlock* instance = new (NotNull, allocateCell<EvalCodeBlock>(vm->heap))
+            EvalCodeBlock(vm, vm->evalCodeBlockStructure.get(), ownerExecutable, unlinkedCodeBlock, scope, sourceProvider);
+        instance->finishCreation(*vm, ownerExecutable, unlinkedCodeBlock, scope);
+        return instance;
     }
-    
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+    }
+
     const Identifier& variable(unsigned index) { return unlinkedEvalCodeBlock()->variable(index); }
     unsigned numVariables() { return unlinkedEvalCodeBlock()->numVariables(); }
     
-#if ENABLE(JIT)
-protected:
-    virtual CodeBlock* replacement() override;
-    virtual DFG::CapabilityLevel capabilityLevelInternal() override;
-#endif
+private:
+    EvalCodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, EvalCodeBlock& other)
+        : GlobalCodeBlock(vm, structure, CopyParsedBlock, other)
+    {
+    }
+        
+    EvalCodeBlock(VM* vm, Structure* structure, EvalExecutable* ownerExecutable, UnlinkedEvalCodeBlock* unlinkedCodeBlock,
+        JSScope* scope, PassRefPtr<SourceProvider> sourceProvider)
+        : GlobalCodeBlock(vm, structure, ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, 1)
+    {
+    }
     
+    static void destroy(JSCell*);
+
 private:
     UnlinkedEvalCodeBlock* unlinkedEvalCodeBlock() const { return jsCast<UnlinkedEvalCodeBlock*>(unlinkedCodeBlock()); }
 };
 
 class FunctionCodeBlock : public CodeBlock {
 public:
-    FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other)
-        : CodeBlock(CopyParsedBlock, other)
+    typedef CodeBlock Base;
+    DECLARE_INFO;
+
+    static FunctionCodeBlock* create(VM* vm, CopyParsedBlockTag, FunctionCodeBlock& other)
+    {
+        FunctionCodeBlock* instance = new (NotNull, allocateCell<FunctionCodeBlock>(vm->heap))
+            FunctionCodeBlock(vm, vm->functionCodeBlockStructure.get(), CopyParsedBlock, other);
+        instance->finishCreation(*vm, CopyParsedBlock, other);
+        return instance;
+    }
+
+    static FunctionCodeBlock* create(VM* vm, FunctionExecutable* ownerExecutable, UnlinkedFunctionCodeBlock* unlinkedCodeBlock, JSScope* scope,
+        PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
+    {
+        FunctionCodeBlock* instance = new (NotNull, allocateCell<FunctionCodeBlock>(vm->heap))
+            FunctionCodeBlock(vm, vm->functionCodeBlockStructure.get(), ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset);
+        instance->finishCreation(*vm, ownerExecutable, unlinkedCodeBlock, scope);
+        return instance;
+    }
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+    }
+
+private:
+    FunctionCodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, FunctionCodeBlock& other)
+        : CodeBlock(vm, structure, CopyParsedBlock, other)
     {
     }
 
-    FunctionCodeBlock(FunctionExecutable* ownerExecutable, UnlinkedFunctionCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
-        : CodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset)
+    FunctionCodeBlock(VM* vm, Structure* structure, FunctionExecutable* ownerExecutable, UnlinkedFunctionCodeBlock* unlinkedCodeBlock, JSScope* scope,
+        PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
+        : CodeBlock(vm, structure, ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, sourceOffset, firstLineColumnOffset)
     {
     }
     
-#if ENABLE(JIT)
-protected:
-    virtual CodeBlock* replacement() override;
-    virtual DFG::CapabilityLevel capabilityLevelInternal() override;
-#endif
+    static void destroy(JSCell*);
 };
 
 #if ENABLE(WEBASSEMBLY)
 class WebAssemblyCodeBlock : public CodeBlock {
 public:
-    WebAssemblyCodeBlock(CopyParsedBlockTag, WebAssemblyCodeBlock& other)
-        : CodeBlock(CopyParsedBlock, other)
+    DECLARE_INFO;
+
+    static WebAssemblyCodeBlock* create(VM* vm, CopyParsedBlockTag, WebAssemblyCodeBlock& other)
+    {
+        WebAssemblyCodeBlock* instance = new (NotNull, allocateCell<WebAssemblyCodeBlock>(vm->heap))
+            WebAssemblyCodeBlock(vm, vm->webAssemblyCodeBlockStructure.get(), CopyParsedBlock, other);
+        instance->finishCreation(*vm);
+        return instance;
+    }
+
+    static WebAssemblyCodeBlock* create(VM* vm, WebAssemblyExecutable* ownerExecutable, JSGlobalObject* globalObject)
+    {
+        WebAssemblyCodeBlock* instance = new (NotNull, allocateCell<WebAssemblyCodeBlock>(vm->heap))
+            WebAssemblyCodeBlock(vm, vm->webAssemblyCodeBlockStructure.get(), ownerExecutable, globalObject);
+        instance->finishCreation(*vm);
+        return instance;
+    }
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+    }
+
+private:
+    WebAssemblyCodeBlock(VM& vm, Structure* structure, CopyParsedBlockTag, WebAssemblyCodeBlock& other)
+        : CodeBlock(vm, structure, CopyParsedBlock, other)
     {
     }
 
-    WebAssemblyCodeBlock(WebAssemblyExecutable* ownerExecutable, VM& vm, JSGlobalObject* globalObject)
-        : CodeBlock(ownerExecutable, vm, globalObject)
+    WebAssemblyCodeBlock(VM& vm, Structure* structure, WebAssemblyExecutable* ownerExecutable, JSGlobalObject* globalObject)
+        : CodeBlock(vm, structure, ownerExecutable, vm, globalObject)
     {
     }
 
-#if ENABLE(JIT)
-protected:
-    virtual CodeBlock* replacement() override;
-    virtual DFG::CapabilityLevel capabilityLevelInternal() override;
-#endif
+    static void destroy(JSCell*);
 };
 #endif
 
@@ -1210,10 +1347,9 @@
     return uncheckedR(reg.offset());
 }
 
-inline void CodeBlock::clearMarks()
+inline void CodeBlock::clearVisitWeaklyHasBeenCalled()
 {
-    m_visitStronglyHasBeenCalled.store(false, std::memory_order_relaxed);
-    m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
+    m_visitWeaklyHasBeenCalled.store(false, std::memory_order_relaxed);
 }
 
 inline void CodeBlockSet::mark(void* candidateCodeBlock)
@@ -1238,12 +1374,11 @@
 {
     if (!codeBlock)
         return;
-    
-    // Force GC to visit all CodeBlocks on the stack, including old CodeBlocks
-    // that have not executed a barrier. This is overkill, but we have always
-    // done this, and it might help us recover gracefully if we forget to execute
-    // a barrier when a CodeBlock needs it.
-    codeBlock->clearMarks();
+
+    // Try to recover gracefully if we forget to execute a barrier for a
+    // CodeBlock that does value profiling. This is probably overkill, but we
+    // have always done it.
+    Heap::heap(codeBlock)->writeBarrier(codeBlock);
 
     m_currentlyExecuting.add(codeBlock);
 }
@@ -1252,13 +1387,13 @@
 {
     switch (type()) {
     case ProgramExecutableType: {
-        if (CodeBlock* codeBlock = jsCast<ProgramExecutable*>(this)->m_programCodeBlock.get())
+        if (CodeBlock* codeBlock = static_cast<CodeBlock*>(jsCast<ProgramExecutable*>(this)->m_programCodeBlock.get()))
             codeBlock->forEachRelatedCodeBlock(std::forward<Functor>(functor));
         break;
     }
 
     case EvalExecutableType: {
-        if (CodeBlock* codeBlock = jsCast<EvalExecutable*>(this)->m_evalCodeBlock.get())
+        if (CodeBlock* codeBlock = static_cast<CodeBlock*>(jsCast<EvalExecutable*>(this)->m_evalCodeBlock.get()))
             codeBlock->forEachRelatedCodeBlock(std::forward<Functor>(functor));
         break;
     }
@@ -1266,15 +1401,15 @@
     case FunctionExecutableType: {
         Functor f(std::forward<Functor>(functor));
         FunctionExecutable* executable = jsCast<FunctionExecutable*>(this);
-        if (CodeBlock* codeBlock = executable->m_codeBlockForCall.get())
+        if (CodeBlock* codeBlock = static_cast<CodeBlock*>(executable->m_codeBlockForCall.get()))
             codeBlock->forEachRelatedCodeBlock(f);
-        if (CodeBlock* codeBlock = executable->m_codeBlockForConstruct.get())
+        if (CodeBlock* codeBlock = static_cast<CodeBlock*>(executable->m_codeBlockForConstruct.get()))
             codeBlock->forEachRelatedCodeBlock(f);
         break;
     }
 
     case ModuleProgramExecutableType: {
-        if (CodeBlock* codeBlock = jsCast<ModuleProgramExecutable*>(this)->m_moduleProgramCodeBlock.get())
+        if (CodeBlock* codeBlock = static_cast<CodeBlock*>(jsCast<ModuleProgramExecutable*>(this)->m_moduleProgramCodeBlock.get()))
             codeBlock->forEachRelatedCodeBlock(std::forward<Functor>(functor));
         break;
     }
diff --git a/Source/JavaScriptCore/bytecode/CodeOrigin.cpp b/Source/JavaScriptCore/bytecode/CodeOrigin.cpp
index 5646a53..d516950 100644
--- a/Source/JavaScriptCore/bytecode/CodeOrigin.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeOrigin.cpp
@@ -75,7 +75,7 @@
         if (!a.inlineCallFrame)
             return true;
         
-        if (a.inlineCallFrame->executable.get() != b.inlineCallFrame->executable.get())
+        if (a.inlineCallFrame->baselineCodeBlock.get() != b.inlineCallFrame->baselineCodeBlock.get())
             return false;
         
         a = a.inlineCallFrame->directCaller;
@@ -98,7 +98,7 @@
         if (!codeOrigin.inlineCallFrame)
             return result;
         
-        result += WTF::PtrHash<JSCell*>::hash(codeOrigin.inlineCallFrame->executable.get());
+        result += WTF::PtrHash<JSCell*>::hash(codeOrigin.inlineCallFrame->baselineCodeBlock.get());
         
         codeOrigin = codeOrigin.inlineCallFrame->directCaller;
     }
@@ -115,11 +115,11 @@
     return result;
 }
 
-ScriptExecutable* CodeOrigin::codeOriginOwner() const
+CodeBlock* CodeOrigin::codeOriginOwner() const
 {
     if (!inlineCallFrame)
         return 0;
-    return inlineCallFrame->executable.get();
+    return inlineCallFrame->baselineCodeBlock.get();
 }
 
 int CodeOrigin::stackOffset() const
@@ -143,7 +143,7 @@
             out.print(" --> ");
         
         if (InlineCallFrame* frame = stack[i].inlineCallFrame) {
-            out.print(frame->briefFunctionInformation(), ":<", RawPointer(frame->executable.get()), "> ");
+            out.print(frame->briefFunctionInformation(), ":<", RawPointer(frame->baselineCodeBlock.get()), "> ");
             if (frame->isClosureCall)
                 out.print("(closure) ");
         }
diff --git a/Source/JavaScriptCore/bytecode/CodeOrigin.h b/Source/JavaScriptCore/bytecode/CodeOrigin.h
index a522ba9..c944e81 100644
--- a/Source/JavaScriptCore/bytecode/CodeOrigin.h
+++ b/Source/JavaScriptCore/bytecode/CodeOrigin.h
@@ -87,7 +87,7 @@
     
     // If the code origin corresponds to inlined code, gives you the heap object that
     // would have owned the code if it had not been inlined. Otherwise returns 0.
-    ScriptExecutable* codeOriginOwner() const;
+    CodeBlock* codeOriginOwner() const;
     
     int stackOffset() const;
     
diff --git a/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp b/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp
index 761e95b..762387c 100644
--- a/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp
+++ b/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.cpp
@@ -33,15 +33,13 @@
 DeferredCompilationCallback::DeferredCompilationCallback() { }
 DeferredCompilationCallback::~DeferredCompilationCallback() { }
 
-void DeferredCompilationCallback::compilationDidComplete(CodeBlock* codeBlock, CompilationResult result)
+void DeferredCompilationCallback::compilationDidComplete(CodeBlock*, CodeBlock*, CompilationResult result)
 {
     dumpCompiledSourcesIfNeeded();
 
     switch (result) {
     case CompilationFailed:
     case CompilationInvalidated:
-        codeBlock->heap()->removeCodeBlock(codeBlock);
-        break;
     case CompilationSuccessful:
         break;
     case CompilationDeferred:
diff --git a/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h b/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h
index 37568d2..adecb82 100644
--- a/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h
+++ b/Source/JavaScriptCore/bytecode/DeferredCompilationCallback.h
@@ -42,8 +42,8 @@
 public:
     virtual ~DeferredCompilationCallback();
 
-    virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*) = 0;
-    virtual void compilationDidComplete(CodeBlock*, CompilationResult);
+    virtual void compilationDidBecomeReadyAsynchronously(CodeBlock*, CodeBlock* profiledDFGCodeBlock) = 0;
+    virtual void compilationDidComplete(CodeBlock*, CodeBlock* profiledDFGCodeBlock, CompilationResult);
 
     Vector<DeferredSourceDump>& ensureDeferredSourceDump();
 
diff --git a/Source/JavaScriptCore/bytecode/EvalCodeCache.h b/Source/JavaScriptCore/bytecode/EvalCodeCache.h
index 7a89898..62521fc 100644
--- a/Source/JavaScriptCore/bytecode/EvalCodeCache.h
+++ b/Source/JavaScriptCore/bytecode/EvalCodeCache.h
@@ -51,7 +51,7 @@
             return 0;
         }
         
-        EvalExecutable* getSlow(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, ThisTDZMode thisTDZMode, const String& evalSource, JSScope* scope)
+        EvalExecutable* getSlow(ExecState* exec, JSCell* owner, bool inStrictContext, ThisTDZMode thisTDZMode, const String& evalSource, JSScope* scope)
         {
             VariableEnvironment variablesUnderTDZ;
             JSScope::collectVariablesUnderTDZ(scope, variablesUnderTDZ);
diff --git a/Source/JavaScriptCore/bytecode/InlineCallFrame.cpp b/Source/JavaScriptCore/bytecode/InlineCallFrame.cpp
index 7a3d8af..447bc7e 100644
--- a/Source/JavaScriptCore/bytecode/InlineCallFrame.cpp
+++ b/Source/JavaScriptCore/bytecode/InlineCallFrame.cpp
@@ -47,24 +47,17 @@
 
 CodeBlockHash InlineCallFrame::hash() const
 {
-    return jsCast<FunctionExecutable*>(executable.get())->codeBlockFor(
-        specializationKind())->hash();
+    return baselineCodeBlock->hash();
 }
 
 CString InlineCallFrame::hashAsStringIfPossible() const
 {
-    return jsCast<FunctionExecutable*>(executable.get())->codeBlockFor(
-        specializationKind())->hashAsStringIfPossible();
+    return baselineCodeBlock->hashAsStringIfPossible();
 }
 
 CString InlineCallFrame::inferredName() const
 {
-    return jsCast<FunctionExecutable*>(executable.get())->inferredName().utf8();
-}
-
-CodeBlock* InlineCallFrame::baselineCodeBlock() const
-{
-    return jsCast<FunctionExecutable*>(executable.get())->baselineCodeBlockFor(specializationKind());
+    return jsCast<FunctionExecutable*>(baselineCodeBlock->ownerExecutable())->inferredName().utf8();
 }
 
 void InlineCallFrame::dumpBriefFunctionInformation(PrintStream& out) const
@@ -74,8 +67,8 @@
 
 void InlineCallFrame::dumpInContext(PrintStream& out, DumpContext* context) const
 {
-    out.print(briefFunctionInformation(), ":<", RawPointer(executable.get()));
-    if (executable->isStrictMode())
+    out.print(briefFunctionInformation(), ":<", RawPointer(baselineCodeBlock.get()));
+    if (isStrictMode())
         out.print(" (StrictMode)");
     out.print(", bc#", directCaller.bytecodeIndex, ", ", static_cast<Kind>(kind));
     if (isClosureCall)
diff --git a/Source/JavaScriptCore/bytecode/InlineCallFrame.h b/Source/JavaScriptCore/bytecode/InlineCallFrame.h
index 62f25fc..9eb7fb3 100644
--- a/Source/JavaScriptCore/bytecode/InlineCallFrame.h
+++ b/Source/JavaScriptCore/bytecode/InlineCallFrame.h
@@ -29,7 +29,6 @@
 #include "CodeBlock.h"
 #include "CodeBlockHash.h"
 #include "CodeOrigin.h"
-#include "Executable.h"
 #include "ValueRecovery.h"
 #include "WriteBarrier.h"
 #include <wtf/BitVector.h>
@@ -42,7 +41,6 @@
 
 struct InlineCallFrame;
 class ExecState;
-class ScriptExecutable;
 class JSFunction;
 
 struct InlineCallFrame {
@@ -174,7 +172,7 @@
     }
     
     Vector<ValueRecovery> arguments; // Includes 'this'.
-    WriteBarrier<ScriptExecutable> executable;
+    WriteBarrier<CodeBlock> baselineCodeBlock;
     ValueRecovery calleeRecovery;
     CodeOrigin directCaller;
 
@@ -209,8 +207,6 @@
     CodeBlockHash hash() const;
     CString hashAsStringIfPossible() const;
     
-    CodeBlock* baselineCodeBlock() const;
-    
     void setStackOffset(signed offset)
     {
         stackOffset = offset;
@@ -220,6 +216,8 @@
     ptrdiff_t callerFrameOffset() const { return stackOffset * sizeof(Register) + CallFrame::callerFrameOffset(); }
     ptrdiff_t returnPCOffset() const { return stackOffset * sizeof(Register) + CallFrame::returnPCOffset(); }
 
+    bool isStrictMode() const { return baselineCodeBlock->isStrictMode(); }
+
     void dumpBriefFunctionInformation(PrintStream&) const;
     void dump(PrintStream&) const;
     void dumpInContext(PrintStream&, DumpContext*) const;
@@ -231,9 +229,7 @@
 inline CodeBlock* baselineCodeBlockForInlineCallFrame(InlineCallFrame* inlineCallFrame)
 {
     RELEASE_ASSERT(inlineCallFrame);
-    ScriptExecutable* executable = inlineCallFrame->executable.get();
-    RELEASE_ASSERT(executable->structure()->classInfo() == FunctionExecutable::info());
-    return static_cast<FunctionExecutable*>(executable)->baselineCodeBlockFor(inlineCallFrame->specializationKind());
+    return inlineCallFrame->baselineCodeBlock.get();
 }
 
 inline CodeBlock* baselineCodeBlockForOriginAndBaselineCodeBlock(const CodeOrigin& codeOrigin, CodeBlock* baselineCodeBlock)
diff --git a/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp b/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
index 109568c..98fcf26 100644
--- a/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
+++ b/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
@@ -411,7 +411,7 @@
         }
 
         // We will emit code that has a weak reference that isn't otherwise listed anywhere.
-        state.weakReferences.append(WriteBarrier<JSCell>(vm, codeBlock->ownerExecutable(), structure));
+        state.weakReferences.append(WriteBarrier<JSCell>(vm, codeBlock, structure));
         
         jit.move(CCallHelpers::TrustedImmPtr(condition.object()), scratchGPR);
         state.failAndRepatch.append(
@@ -1177,7 +1177,7 @@
     for (auto& entry : cases)
         doesCalls |= entry->doesCalls();
     
-    m_stubRoutine = createJITStubRoutine(code, vm, codeBlock->ownerExecutable(), doesCalls);
+    m_stubRoutine = createJITStubRoutine(code, vm, codeBlock, doesCalls);
     m_watchpoints = WTF::move(state.watchpoints);
     if (!state.weakReferences.isEmpty())
         m_weakReferences = std::make_unique<Vector<WriteBarrier<JSCell>>>(WTF::move(state.weakReferences));
diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
index 5587710..8728518 100644
--- a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
+++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
@@ -55,7 +55,7 @@
     cacheType = CacheType::GetByIdSelf;
     
     u.byIdSelf.baseObjectStructure.set(
-        *codeBlock->vm(), codeBlock->ownerExecutable(), baseObjectStructure);
+        *codeBlock->vm(), codeBlock, baseObjectStructure);
     u.byIdSelf.offset = offset;
 }
 
@@ -64,7 +64,7 @@
     cacheType = CacheType::PutByIdReplace;
     
     u.byIdSelf.baseObjectStructure.set(
-        *codeBlock->vm(), codeBlock->ownerExecutable(), baseObjectStructure);
+        *codeBlock->vm(), codeBlock, baseObjectStructure);
     u.byIdSelf.offset = offset;
 }
 
@@ -105,7 +105,7 @@
     Vector<std::unique_ptr<AccessCase>> accessCases;
     
     std::unique_ptr<AccessCase> previousCase =
-        AccessCase::fromStructureStubInfo(vm, codeBlock->ownerExecutable(), *this);
+        AccessCase::fromStructureStubInfo(vm, codeBlock, *this);
     if (previousCase)
         accessCases.append(WTF::move(previousCase));