Closed Bug 941311 Opened 11 years ago Closed 11 years ago

Improve GGC pretenuring heuristics

Categories

(Core :: JavaScript Engine: JIT, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla28

People

(Reporter: bhackett1024, Assigned: bhackett1024)

References

(Blocks 1 open bug)

Details

(Whiteboard: [qa-])

Attachments

(1 file)

Attached patch patchSplinter Review
The way we determine whether objects should be pretenured has some problems and doesn't work reliably on octane-splay.  The main issue is that only 'new' scripts are pretenured, and not object/array initializers.  Only a small fraction of the objects octane-splay creates are such 'new' script nodes (splay nodes) --- the vast majority are in the payload trees and are currently in the nursery.  A secondary issue is that the heuristics are very fragile and trigger on other benchmarks as well.  The attached patch reworks the heuristics so that they only fire on splay, by only looking at what is promoted during single collections rather than the total number of times objects with a type have been promoted.  It also fixes things so that both 'new' scripts and initializer objects can be pretenured (only for JIT and VM cache hit allocations, atm), and fixes the invalidation mechanism used for recompiling code when types are marked as pretenured.
Attachment #8335618 - Flags: review?(terrence)
Attachment #8335618 - Flags: review?(jdemooij)
Oh, testing splay individually this improves splay on x64 builds from ~7k to ~12-14k.  Trunk is ~14k.
Comment on attachment 8335618 [details] [diff] [review]
patch

Review of attachment 8335618 [details] [diff] [review]:
-----------------------------------------------------------------

r=me

::: js/src/gc/Nursery.cpp
@@ +393,5 @@
> +        return;
> +
> +    double promotionRate = trc->tenuredSize / double(allocationEnd() - start());
> +
> +    if (promotionRate < .8 && reason != JS::gcreason::FULL_STORE_BUFFER)

Maybe a comment explaining why this is important.

@@ +400,5 @@
> +    for (size_t i = 0; i < ArrayLength(tenureCounts); i++) {
> +        const TenureCount &entry = tenureCounts[i];
> +        if (entry.count >= 3000)
> +            pretenureTypes->append(entry.type); // ignore alloc failure
> +    }

Instead of copying promotion rate, how about we punch TenureCount[16] through and put this in the body of Nursery::collect?
Attachment #8335618 - Flags: review?(terrence) → review+
Summary: Improve GCC pretenuring heuristics → Improve GGC pretenuring heuristics
Comment on attachment 8335618 [details] [diff] [review]
patch

Review of attachment 8335618 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/src/jit/IonBuilder.cpp
@@ +4578,5 @@
>      current->add(callObj);
>  
>      // Insert a post barrier to protect the following writes if we allocated
>      // the new call object directly into tenured storage.
> +    if (script()->treatAsRunOnce)

I was confused by this change, until I saw the script()->treatAsRunOnce a few lines above. Can you use callObj->needsSingletonType() here instead?

::: js/src/jsgc.cpp
@@ +4892,5 @@
> +    Nursery::TypeObjectList pretenureTypes;
> +    cx->runtime()->gcNursery.collect(cx->runtime(), reason, &pretenureTypes);
> +    for (size_t i = 0; i < pretenureTypes.length(); i++) {
> +        if (pretenureTypes[i]->canPreTenure())
> +            pretenureTypes[i]->setShouldPreTenure(cx);

Can we use JS_ALWAYS_TRUE? If not, will we leave a pending exception?
Attachment #8335618 - Flags: review?(jdemooij) → review+
https://hg.mozilla.org/mozilla-central/rev/5f093277a586
Assignee: nobody → bhackett1024
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla28
Whiteboard: [qa-]
Blocks: 1507445
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: