CodeBlockSet should be generational
https://bugs.webkit.org/show_bug.cgi?id=127152

Reviewed by Geoffrey Garen.

During EdenCollections we now only visit those CodeBlocks that:
a) Are new since the last collection if they were somehow otherwise reachable.
b) Are reachable from an Executable that is part of the remembered set.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock): Initialize uninitialized variables.
(JSC::CodeBlock::visitAggregate): Move the addition of the weak reference harvester after the
shouldImmediatelyAssumeLivenessDuringScan check since it's redundant if we assume liveness.
* bytecode/CodeBlock.h:
(JSC::CodeBlock::forEachRelatedCodeBlock): Executes a functor for each CodeBlock reachable from the current CodeBlock (including this).
We use this to clear marks for the CodeBlocks of remembered Executables (see: CodeBlockSet::clearMarksForEdenCollection).
(JSC::CodeBlockSet::mark): Also check the set of new CodeBlocks for memebership when doing conservative scanning.
(JSC::ScriptExecutable::forEachCodeBlock): Executes a functor for each of this Executable's CodeBlocks.
* heap/CodeBlockSet.cpp:
(JSC::CodeBlockSet::~CodeBlockSet):
(JSC::CodeBlockSet::add):
(JSC::CodeBlockSet::promoteYoungCodeBlocks): Moves all CodeBlocks currently in the set of new CodeBlocks into
the set of old CodeBlocks.
(JSC::CodeBlockSet::clearMarksForFullCollection): Clears the marks for all CodeBlocks.
(JSC::CodeBlockSet::clearMarksForEdenCollection): Clears the marks for CodeBlocks owned by Executables in the
remembered set. When an Executable is added to the remembered set it's typically because we need to do something
with its CodeBlock.
(JSC::CodeBlockSet::clearMarks):
(JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced): Fixpoints over either just the new CodeBlocks or all CodeBlocks
to determine which CodeBlocks are dead and eagerly finalizes/deletes them.
(JSC::CodeBlockSet::remove):
(JSC::CodeBlockSet::traceMarked): Iterate only the currently executing CodeBlocks instead of all CodeBlocks.
(JSC::CodeBlockSet::rememberCurrentlyExecutingCodeBlocks): Clear m_mayBeExecuting for all currently executing
CodeBlocks because we no longer always do this at the beginning of EdenCollections.
* heap/CodeBlockSet.h:
(JSC::CodeBlockSet::iterate):
* heap/Heap.cpp:
(JSC::Heap::markRoots):
(JSC::Heap::deleteAllCompiledCode):
(JSC::Heap::deleteUnmarkedCompiledCode):
* runtime/Executable.cpp:
(JSC::ScriptExecutable::installCode): Write barrier code on installation. We do this due to the following situation:
a) A CodeBlock is created and is compiled on a DFG worker thread.
b) No GC happens.
c) The CodeBlock has finished being compiled and is installed in the Executable.
d) The function never executes before the next GC.
e) The next GC needs needs to visit the new CodeBlock but the Executable won't be revisited unless
    it's added to the remembered set.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@166678 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 6e5bc37..c782c25 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -1446,6 +1446,8 @@
     , m_activationRegister(other.m_activationRegister)
     , m_isStrictMode(other.m_isStrictMode)
     , m_needsActivation(other.m_needsActivation)
+    , m_mayBeExecuting(false)
+    , m_visitAggregateHasBeenCalled(false)
     , m_source(other.m_source)
     , m_sourceOffset(other.m_sourceOffset)
     , m_firstLineColumnOffset(other.m_firstLineColumnOffset)
@@ -1503,6 +1505,8 @@
     , m_activationRegister(unlinkedCodeBlock->activationRegister())
     , m_isStrictMode(unlinkedCodeBlock->isStrictMode())
     , m_needsActivation(unlinkedCodeBlock->hasActivationRegister() && unlinkedCodeBlock->codeType() == FunctionCode)
+    , m_mayBeExecuting(false)
+    , m_visitAggregateHasBeenCalled(false)
     , m_source(sourceProvider)
     , m_sourceOffset(sourceOffset)
     , m_firstLineColumnOffset(firstLineColumnOffset)
@@ -1937,10 +1941,6 @@
     // and when it runs, it figures out whether it has any work to do.
     visitor.addUnconditionalFinalizer(this);
     
-    // 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);
     m_allTransitionsHaveBeenMarked = false;
     
     if (shouldImmediatelyAssumeLivenessDuringScan()) {
@@ -1951,6 +1951,11 @@
         return;
     }
     
+    // 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);
+
 #if ENABLE(DFG_JIT)
     // We get here if we're live in the sense that our owner executable is live,
     // but we're not yet live for sure in another sense: we may yet decide that this