2015-10-09  Geoffrey Garen  <ggaren@apple.com>

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

        This time for double sure?

        The cause of the crash was an incorrect write barrier.

        OSR exit was barriering the baseline codeblock for the top of the stack
        twice, missing the baseline codeblock for the bottom of the stack.

        Restored changesets:

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



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@190827 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/heap/CodeBlockSet.cpp b/Source/JavaScriptCore/heap/CodeBlockSet.cpp
index ed6ed89..7c6cee2 100644
--- a/Source/JavaScriptCore/heap/CodeBlockSet.cpp
+++ b/Source/JavaScriptCore/heap/CodeBlockSet.cpp
@@ -41,17 +41,11 @@
 
 CodeBlockSet::~CodeBlockSet()
 {
-    for (CodeBlock* codeBlock : m_oldCodeBlocks)
-        codeBlock->deref();
-
-    for (CodeBlock* codeBlock : m_newCodeBlocks)
-        codeBlock->deref();
 }
 
-void CodeBlockSet::add(PassRefPtr<CodeBlock> codeBlock)
+void CodeBlockSet::add(CodeBlock* codeBlock)
 {
-    CodeBlock* block = codeBlock.leakRef();
-    bool isNewEntry = m_newCodeBlocks.add(block).isNewEntry;
+    bool isNewEntry = m_newCodeBlocks.add(codeBlock).isNewEntry;
     ASSERT_UNUSED(isNewEntry, isNewEntry);
 }
 
@@ -64,52 +58,35 @@
 void CodeBlockSet::clearMarksForFullCollection()
 {
     for (CodeBlock* codeBlock : m_oldCodeBlocks)
-        codeBlock->clearMarks();
+        codeBlock->clearVisitWeaklyHasBeenCalled();
 
     // We promote after we clear marks on the old generation CodeBlocks because
     // none of the young generations CodeBlocks need to be cleared.
     promoteYoungCodeBlocks();
 }
 
-void CodeBlockSet::clearMarksForEdenCollection(const Vector<const JSCell*>& rememberedSet)
+void CodeBlockSet::lastChanceToFinalize()
 {
-    // This ensures that we will revisit CodeBlocks in remembered Executables even if they were previously marked.
-    for (const JSCell* cell : rememberedSet) {
-        ScriptExecutable* executable = const_cast<ScriptExecutable*>(jsDynamicCast<const ScriptExecutable*>(cell));
-        if (!executable)
-            continue;
-        executable->forEachCodeBlock([this](CodeBlock* codeBlock) {
-            codeBlock->clearMarks();
-            m_remembered.add(codeBlock);
-        });
-    }
+    for (CodeBlock* codeBlock : m_newCodeBlocks)
+        codeBlock->classInfo()->methodTable.destroy(codeBlock);
+
+    for (CodeBlock* codeBlock : m_oldCodeBlocks)
+        codeBlock->classInfo()->methodTable.destroy(codeBlock);
 }
 
 void CodeBlockSet::deleteUnmarkedAndUnreferenced(HeapOperation collectionType)
 {
     HashSet<CodeBlock*>& set = collectionType == EdenCollection ? m_newCodeBlocks : m_oldCodeBlocks;
+    Vector<CodeBlock*> unmarked;
+    for (CodeBlock* codeBlock : set) {
+        if (Heap::isMarked(codeBlock))
+            continue;
+        unmarked.append(codeBlock);
+    }
 
-    // This needs to be a fixpoint because code blocks that are unmarked may
-    // refer to each other. For example, a DFG code block that is owned by
-    // the GC may refer to an FTL for-entry code block that is also owned by
-    // the GC.
-    Vector<CodeBlock*, 16> toRemove;
-    if (verbose)
-        dataLog("Fixpointing over unmarked, set size = ", set.size(), "...\n");
-    for (;;) {
-        for (CodeBlock* codeBlock : set) {
-            if (!codeBlock->hasOneRef())
-                continue;
-            codeBlock->deref();
-            toRemove.append(codeBlock);
-        }
-        if (verbose)
-            dataLog("    Removing ", toRemove.size(), " blocks.\n");
-        if (toRemove.isEmpty())
-            break;
-        for (CodeBlock* codeBlock : toRemove)
-            set.remove(codeBlock);
-        toRemove.resize(0);
+    for (CodeBlock* codeBlock : unmarked) {
+        codeBlock->classInfo()->methodTable.destroy(codeBlock);
+        set.remove(codeBlock);
     }
 
     // Any remaining young CodeBlocks are live and need to be promoted to the set of old CodeBlocks.
@@ -119,7 +96,6 @@
 
 void CodeBlockSet::remove(CodeBlock* codeBlock)
 {
-    codeBlock->deref();
     if (m_oldCodeBlocks.contains(codeBlock)) {
         m_oldCodeBlocks.remove(codeBlock);
         return;
@@ -128,35 +104,16 @@
     m_newCodeBlocks.remove(codeBlock);
 }
 
-void CodeBlockSet::traceMarked(SlotVisitor& visitor)
-{
-    if (verbose)
-        dataLog("Tracing ", m_currentlyExecuting.size(), " code blocks.\n");
-
-    // We strongly visit the currently executing set because jettisoning code
-    // is not valuable once it's on the stack. We're past the point where
-    // jettisoning would avoid the cost of OSR exit.
-    for (const RefPtr<CodeBlock>& codeBlock : m_currentlyExecuting)
-        codeBlock->visitStrongly(visitor);
-
-    // We strongly visit the remembered set because jettisoning old code during
-    // Eden GC is unsound. There might be an old object with a strong reference
-    // to the code.
-    for (const RefPtr<CodeBlock>& codeBlock : m_remembered)
-        codeBlock->visitStrongly(visitor);
-}
-
-void CodeBlockSet::rememberCurrentlyExecutingCodeBlocks(Heap* heap)
+void CodeBlockSet::writeBarrierCurrentlyExecutingCodeBlocks(Heap* heap)
 {
     if (verbose)
         dataLog("Remembering ", m_currentlyExecuting.size(), " code blocks.\n");
-    for (const RefPtr<CodeBlock>& codeBlock : m_currentlyExecuting)
-        heap->writeBarrier(codeBlock->ownerExecutable());
+    for (CodeBlock* codeBlock : m_currentlyExecuting)
+        heap->writeBarrier(codeBlock);
 
-    // It's safe to clear these RefPtr sets because we won't delete the CodeBlocks
-    // in them until the next GC, and we'll recompute them at that time.
+    // It's safe to clear this set because we won't delete the CodeBlocks
+    // in it until the next GC, and we'll recompute it at that time.
     m_currentlyExecuting.clear();
-    m_remembered.clear();
 }
 
 void CodeBlockSet::dump(PrintStream& out) const
@@ -171,8 +128,8 @@
         out.print(comma, pointerDump(codeBlock));
     out.print("], currentlyExecuting = [");
     comma = CommaPrinter();
-    for (const RefPtr<CodeBlock>& codeBlock : m_currentlyExecuting)
-        out.print(comma, pointerDump(codeBlock.get()));
+    for (CodeBlock* codeBlock : m_currentlyExecuting)
+        out.print(comma, pointerDump(codeBlock));
     out.print("]}");
 }