From 6850557d11fcf71d02f48b4849eef534aaa7e24c Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Wed, 8 May 2013 11:45:12 -0700 Subject: [PATCH] Bug 869235 - Disable Zone::needsBarrier during minor GCs; r=billm --HG-- extra : rebase_source : be141178dc9cf2da06d9eb2f13189f1db0876433 --- js/src/gc/Nursery.cpp | 18 +++++++++++++++--- js/src/gc/Zone.h | 23 ++++++++++++++++++++++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index bacdfaf6bfa8..19ad94b77a96 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -181,7 +181,7 @@ class MinorCollectionTracer : public JSTracer RelocationOverlay **tail; /* Save and restore all of the runtime state we use during MinorGC. */ - bool priorNeedsBarrier; + bool savedNeedsBarrier; AutoDisableProxyCheck disableStrictProxyChecking; /* Insert the given relocation entry into the list of things to visit. */ @@ -198,7 +198,7 @@ class MinorCollectionTracer : public JSTracer session(runtime, MinorCollecting), head(NULL), tail(&head), - priorNeedsBarrier(runtime->needsBarrier()), + savedNeedsBarrier(runtime->needsBarrier()), disableStrictProxyChecking(runtime) { JS_TracerInit(this, runtime, Nursery::MinorGCCallback); @@ -206,10 +206,14 @@ class MinorCollectionTracer : public JSTracer runtime->gcNumber++; runtime->setNeedsBarrier(false); + for (ZonesIter zone(rt); !zone.done(); zone.next()) + zone->saveNeedsBarrier(false); } ~MinorCollectionTracer() { - runtime->setNeedsBarrier(priorNeedsBarrier); + runtime->setNeedsBarrier(savedNeedsBarrier); + for (ZonesIter zone(runtime); !zone.done(); zone.next()) + zone->restoreNeedsBarrier(); } }; @@ -242,6 +246,14 @@ js::Nursery::allocateFromTenured(Zone *zone, AllocKind thingKind) zone->allocator.arenas.checkEmptyFreeList(thingKind); t = zone->allocator.arenas.allocateFromArena(zone, thingKind); } + + /* + * Pre barriers are disabled during minor collection, however, we still + * want objects to be allocated black if an incremental GC is in progress. + */ + if (zone->savedNeedsBarrier()) + static_cast(t)->markIfUnmarked(); + return t; } diff --git a/js/src/gc/Zone.h b/js/src/gc/Zone.h index a1519890daab..a9c444b6a5ab 100644 --- a/js/src/gc/Zone.h +++ b/js/src/gc/Zone.h @@ -113,10 +113,31 @@ struct Zone : private JS::shadow::Zone, public js::gc::GraphNodeBase private: bool ionUsingBarriers_; - public: + /* + * This flag saves the value of needsBarrier_ during minor collection, + * since needsBarrier_ is always set to false during minor collection. + * Outside of minor collection, the value of savedNeedsBarrier_ is + * undefined. + */ + bool savedNeedsBarrier_; + + public: bool active; // GC flag, whether there are active frames + void saveNeedsBarrier(bool newNeeds) { + savedNeedsBarrier_ = needsBarrier_; + needsBarrier_ = newNeeds; + } + + void restoreNeedsBarrier() { + needsBarrier_ = savedNeedsBarrier_; + } + + bool savedNeedsBarrier() const { + return savedNeedsBarrier_; + } + bool needsBarrier() const { return needsBarrier_; }