Created
April 4, 2012 16:43
-
-
Save jorendorff/2303710 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h | |
--- a/js/src/jscntxt.h | |
+++ b/js/src/jscntxt.h | |
@@ -178,16 +178,23 @@ struct ConservativeGCData | |
} | |
#endif | |
bool hasStackToScan() const { | |
return !!nativeStackTop; | |
} | |
}; | |
+/* | |
+ * A FreeOp can do one thing: free memory. For convenience, it has delete_ | |
+ * convenience methods that also call destructors. | |
+ * | |
+ * FreeOp is passed to finalizers and other sweep-phase hooks so that we do not | |
+ * need to pass a JSContext to those hooks. | |
+ */ | |
class FreeOp : public JSFreeOp { | |
bool shouldFreeLater_; | |
bool onBackgroundThread_; | |
public: | |
static FreeOp *get(JSFreeOp *fop) { | |
return static_cast<FreeOp *>(fop); | |
} | |
@@ -210,17 +217,17 @@ class FreeOp : public JSFreeOp { | |
inline void free_(void* p); | |
JS_DECLARE_DELETE_METHODS(free_, inline) | |
static void staticAsserts() { | |
/* | |
* Check that JSFreeOp is the first base class for FreeOp and we can | |
* reinterpret a pointer to JSFreeOp as a pointer to FreeOp without | |
- * any offset adjustments. JSClass::freeOp <-> Class::freeOp depends | |
+ * any offset adjustments. JSClass::finalize <-> Class::finalize depends | |
* on this. | |
*/ | |
JS_STATIC_ASSERT(offsetof(FreeOp, shouldFreeLater_) == sizeof(JSFreeOp)); | |
} | |
}; | |
} /* namespace js */ | |
@@ -1131,16 +1138,24 @@ struct JSContext : js::ContextFriendFiel | |
#ifdef JS_THREADSAFE | |
/* | |
* When non-null JSContext::free_ delegates the job to the background | |
* thread. | |
*/ | |
js::GCHelperThread *gcBackgroundFree; | |
#endif | |
+ bool hasBackgroundFreeThread() const { | |
+#ifdef JS_THREADSAFE | |
+ return !!gcBackgroundFree; | |
+#else | |
+ return false; | |
+#endif | |
+ } | |
+ | |
inline void* malloc_(size_t bytes) { | |
return runtime->malloc_(bytes, this); | |
} | |
inline void* mallocNoReport(size_t bytes) { | |
JS_ASSERT(bytes != 0); | |
return runtime->malloc_(bytes, NULL); | |
} | |
diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp | |
--- a/js/src/jsgc.cpp | |
+++ b/js/src/jsgc.cpp | |
@@ -3110,17 +3110,17 @@ SweepPhase(JSContext *cx, JSGCInvocation | |
if (rt->hasContexts() && rt->gcHelperThread.prepareForBackgroundSweep()) | |
cx->gcBackgroundFree = &rt->gcHelperThread; | |
#endif | |
/* Purge the ArenaLists before sweeping. */ | |
for (GCCompartmentsIter c(rt); !c.done(); c.next()) | |
c->arenas.purge(); | |
- FreeOp fop(rt, !!cx->gcBackgroundFree, false); | |
+ FreeOp fop(rt, cx->hasBackgroundFreeThread(), false); | |
{ | |
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_FINALIZE_START); | |
if (rt->gcFinalizeCallback) | |
rt->gcFinalizeCallback(&fop, JSFINALIZE_START); | |
} | |
/* Finalize unreachable (key,value) pairs in all weak maps. */ | |
WeakMapBase::sweepAll(&rt->gcMarker); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment