Skip to content

Instantly share code, notes, and snippets.

@jorendorff
Created April 4, 2012 16:43
Show Gist options
  • Save jorendorff/2303710 to your computer and use it in GitHub Desktop.
Save jorendorff/2303710 to your computer and use it in GitHub Desktop.
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