Bug 127152 - CodeBlockSet should be generational
Summary: CodeBlockSet should be generational
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Mark Hahnenberg
URL:
Keywords:
Depends on: 131356
Blocks:
  Show dependency treegraph
 
Reported: 2014-01-16 17:05 PST by Mark Hahnenberg
Modified: 2014-04-08 05:03 PDT (History)
2 users (show)

See Also:


Attachments
Patch (18.09 KB, patch)
2014-01-30 12:14 PST, Mark Hahnenberg
no flags Details | Formatted Diff | Diff
Patch (21.09 KB, patch)
2014-03-31 16:16 PDT, Mark Hahnenberg
no flags Details | Formatted Diff | Diff
Patch (21.42 KB, patch)
2014-03-31 16:23 PDT, Mark Hahnenberg
no flags Details | Formatted Diff | Diff
Final patch (20.58 KB, patch)
2014-04-02 14:08 PDT, Mark Hahnenberg
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Hahnenberg 2014-01-16 17:05:21 PST
This is a big overhead during EdenCollections. We should think about how we can generationalize our CodeBlock lifetimes.
Comment 1 Mark Hahnenberg 2014-01-30 12:14:13 PST
Created attachment 222707 [details]
Patch
Comment 2 Geoffrey Garen 2014-01-30 12:33:55 PST
Comment on attachment 222707 [details]
Patch

r=me
Comment 3 Mark Hahnenberg 2014-01-30 16:09:14 PST
(In reply to comment #1)
> Created an attachment (id=222707) [details]
> Patch

Hmm, I think this patch has issues. The correctness of the weakReferenceHarvester stuff in which CodeBlocks participate is dependent on visiting all marked CodeBlocks during a collection. Otherwise we won't propagate liveness for all the things that hang off of CodeBlock that need it.

Another alternative is to just ignore all new CodeBlocks (i.e. auto-promote, pretenure, etc.). We'd still have to visit them to LUB value profiles.
Comment 4 Mark Hahnenberg 2014-03-31 16:16:19 PDT
Created attachment 228214 [details]
Patch
Comment 5 Mark Hahnenberg 2014-03-31 16:23:06 PDT
Created attachment 228216 [details]
Patch
Comment 6 Geoffrey Garen 2014-03-31 16:49:30 PDT
Comment on attachment 228216 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=228216&action=review

r=me

> Source/JavaScriptCore/bytecode/CodeBlock.h:1004
> +        // During EdenCollections all CodeBlocks that are visited are assumed to be live.

Would be nice to explain our reasoning here: It's probably cheaper to assume liveness, and we don't want to worry about write barrier subtleties required by the mutually weak liveness methodology.

> Source/JavaScriptCore/heap/CodeBlockSet.cpp:71
> +void CodeBlockSet::clearAllMarks()
>  {
> -    for (CodeBlock* codeBlock : m_set) {
> +    promoteYoungCodeBlocks();
> +    for (CodeBlock* codeBlock : m_oldCodeBlocks) {
>          codeBlock->m_mayBeExecuting = false;
>          codeBlock->m_visitAggregateHasBeenCalled = false;
>      }
>  }

It feels strange for "clearAllMarks" to promote. And might this get us into a bad state if deleteAllCompiledCode is called at the start of an eden collection? Similarly strange, though less so, for deleteUnmarkedAndUnreferenced to promote.

Can we make the caller promote instead? For example, Heap::deleteAllCompiledCode could run only during full collections, and Heap::markRoots could eagerly promote code blocks before full collections and lazily promote code blocks after eden collections. Or, Heap::resetAllocators() could promote code blocks unconditionally, and Heap::deleteAllCompiledCode could run after Heap::resetAllocators().
Comment 7 Geoffrey Garen 2014-04-02 12:19:03 PDT
Comment on attachment 228216 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=228216&action=review

> Source/JavaScriptCore/heap/CodeBlockSet.cpp:135
> +        m_oldCodeBlocks.remove(codeBlock);

Needs early return.
Comment 8 Mark Hahnenberg 2014-04-02 14:08:44 PDT
Created attachment 228428 [details]
Final patch
Comment 9 Mark Hahnenberg 2014-04-02 14:10:31 PDT
Comment on attachment 228428 [details]
Final patch

View in context: https://bugs.webkit.org/attachment.cgi?id=228428&action=review

> Source/JavaScriptCore/bytecode/CodeBlock.h:151
> +    template <typename Functor> void forEachRelatedCodeBlock(Functor&& functor)
> +    {
> +        Functor f(std::forward<Functor>(functor));
> +        Vector<CodeBlock*, 4> codeBlocks;
> +        codeBlocks.append(this);
> +
> +        while (!codeBlocks.isEmpty()) {
> +            CodeBlock* currentCodeBlock = codeBlocks.takeLast();
> +            f(currentCodeBlock);
> +
> +            if (CodeBlock* alternative = currentCodeBlock->alternative())
> +                codeBlocks.append(alternative);
> +            if (CodeBlock* osrEntryBlock = currentCodeBlock->specialOSREntryBlockOrNull())
> +                codeBlocks.append(osrEntryBlock);
> +        }
> +    }

I had to add handling of the OSR entry block along with the alternative blocks. To make it more general, I turned it into a DFS of a DAG. There's no defense against cycles.
Comment 10 Geoffrey Garen 2014-04-02 16:17:46 PDT
Comment on attachment 228428 [details]
Final patch

r=me
Comment 11 WebKit Commit Bot 2014-04-02 16:50:52 PDT
Comment on attachment 228428 [details]
Final patch

Clearing flags on attachment: 228428

Committed r166678: <http://trac.webkit.org/changeset/166678>
Comment 12 WebKit Commit Bot 2014-04-02 16:50:56 PDT
All reviewed patches have been landed.  Closing bug.