author | Boris Zbarsky <bzbarsky@mit.edu> |
Tue, 07 Jan 2014 19:53:17 -0500 (2014-01-08) | |
changeset 162455 | a3427a45608df38c83b7d5f68b4a99645f87b14d |
parent 162454 | db68ac22b0424afc81235a8ab21b2b5f67316a25 |
child 162456 | e0de03b97222e6ce7d6c2a1c402690eb23ea35f1 |
push id | 38202 |
push user | bzbarsky@mozilla.com |
push date | Wed, 08 Jan 2014 00:53:59 +0000 (2014-01-08) |
treeherder | mozilla-inbound@8e95a6fcee23 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mccr8, terrence |
bugs | 932837 |
milestone | 29.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/bindings/Exceptions.cpp +++ b/dom/bindings/Exceptions.cpp @@ -198,16 +198,72 @@ GetCurrentJSStack() caller) { stack = caller; } return stack.forget(); } namespace exceptions { +class StackDescriptionOwner { +public: + StackDescriptionOwner(JS::StackDescription* aDescription) + : mDescription(aDescription) + { + mozilla::HoldJSObjects(this); + } + + ~StackDescriptionOwner() + { + // Make sure to set mDescription to null before calling DropJSObjects, since + // in debug builds DropJSObjects try to trace us and we don't want to trace + // a dead StackDescription. + if (mDescription) { + JS::FreeStackDescription(nullptr, mDescription); + mDescription = nullptr; + } + mozilla::DropJSObjects(this); + } + + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(StackDescriptionOwner) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(StackDescriptionOwner) + + JS::FrameDescription& FrameAt(size_t aIndex) + { + MOZ_ASSERT(aIndex < mDescription->nframes); + return mDescription->frames[aIndex]; + } + +private: + JS::StackDescription* mDescription; +}; + +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(StackDescriptionOwner, AddRef) +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(StackDescriptionOwner, Release) + +NS_IMPL_CYCLE_COLLECTION_CLASS(StackDescriptionOwner) +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(StackDescriptionOwner) + if (tmp->mDescription) { + JS::FreeStackDescription(nullptr, tmp->mDescription); + tmp->mDescription = nullptr; + } +NS_IMPL_CYCLE_COLLECTION_UNLINK_END +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(StackDescriptionOwner) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(StackDescriptionOwner) + JS::StackDescription* desc = tmp->mDescription; + if (tmp->mDescription) { + for (size_t i = 0; i < desc->nframes; ++i) { + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDescription->frames[i].script()); + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDescription->frames[i].fun()); + } + } +NS_IMPL_CYCLE_COLLECTION_TRACE_END + class JSStackFrame : public nsIStackFrame { public: NS_DECL_ISUPPORTS NS_DECL_NSISTACKFRAME JSStackFrame(); virtual ~JSStackFrame(); @@ -351,16 +407,18 @@ JSStackFrame::CreateStack(JSContext* cx) nsRefPtr<JSStackFrame> first = new JSStackFrame(); nsRefPtr<JSStackFrame> self = first; JS::StackDescription* desc = JS::DescribeStack(cx, MAX_FRAMES); if (!desc) { return nullptr; } + nsRefPtr<StackDescriptionOwner> descOwner = new StackDescriptionOwner(desc); + for (size_t i = 0; i < desc->nframes && self; i++) { self->mLanguage = nsIProgrammingLanguage::JAVASCRIPT; JSAutoCompartment ac(cx, desc->frames[i].script()); const char* filename = JS_GetScriptFilename(cx, desc->frames[i].script()); if (filename) { self->mFilename = (char*)nsMemory::Clone(filename, sizeof(char)*(strlen(filename)+1)); @@ -383,18 +441,16 @@ JSStackFrame::CreateStack(JSContext* cx) } } nsRefPtr<JSStackFrame> frame = new JSStackFrame(); self->mCaller = frame; self.swap(frame); } - JS::FreeStackDescription(cx, desc); - return first.forget(); } /* static */ already_AddRefed<nsIStackFrame> JSStackFrame::CreateStackFrameLocation(uint32_t aLanguage, const char* aFilename, const char* aFunctionName, int32_t aLineNumber,
--- a/js/public/OldDebugAPI.h +++ b/js/public/OldDebugAPI.h @@ -43,27 +43,27 @@ class FrameDescription unsigned lineno() { if (!linenoComputed) { lineno_ = JS_PCToLineNumber(nullptr, script_, pc_); linenoComputed = true; } return lineno_; } - JSScript *script() const { + Heap<JSScript*> &script() { return script_; } - JSFunction *fun() const { + Heap<JSFunction*> &fun() { return fun_; } private: - JSScript *script_; - JSFunction *fun_; + Heap<JSScript*> script_; + Heap<JSFunction*> fun_; jsbytecode *pc_; unsigned lineno_; bool linenoComputed; }; struct StackDescription { unsigned nframes;
--- a/js/public/Tracer.h +++ b/js/public/Tracer.h @@ -152,16 +152,19 @@ extern JS_PUBLIC_API(void) JS_CallHeapObjectTracer(JSTracer *trc, JS::Heap<JSObject *> *objp, const char *name); extern JS_PUBLIC_API(void) JS_CallHeapStringTracer(JSTracer *trc, JS::Heap<JSString *> *strp, const char *name); extern JS_PUBLIC_API(void) JS_CallHeapScriptTracer(JSTracer *trc, JS::Heap<JSScript *> *scriptp, const char *name); +extern JS_PUBLIC_API(void) +JS_CallHeapFunctionTracer(JSTracer *trc, JS::Heap<JSFunction *> *funp, const char *name); + template <typename HashSetEnum> inline void JS_CallHashSetObjectTracer(JSTracer *trc, HashSetEnum &e, JSObject *const &key, const char *name) { JSObject *updated = key; JS_SET_TRACING_LOCATION(trc, reinterpret_cast<void *>(&const_cast<JSObject *&>(key))); JS_CallObjectTracer(trc, &updated, name); if (updated != key)
--- a/js/src/gc/Tracer.cpp +++ b/js/src/gc/Tracer.cpp @@ -74,16 +74,22 @@ JS_CallHeapStringTracer(JSTracer *trc, J JS_PUBLIC_API(void) JS_CallHeapScriptTracer(JSTracer *trc, JS::Heap<JSScript *> *scriptp, const char *name) { MarkScriptUnbarriered(trc, scriptp->unsafeGet(), name); } JS_PUBLIC_API(void) +JS_CallHeapFunctionTracer(JSTracer *trc, JS::Heap<JSFunction *> *funp, const char *name) +{ + MarkObjectUnbarriered(trc, funp->unsafeGet(), name); +} + +JS_PUBLIC_API(void) JS_CallTenuredObjectTracer(JSTracer *trc, JS::TenuredHeap<JSObject *> *objp, const char *name) { JSObject *obj = objp->getPtr(); if (!obj) return; JS_SET_TRACING_LOCATION(trc, (void*)objp); MarkObjectUnbarriered(trc, &obj, name);
--- a/js/src/vm/OldDebugAPI.cpp +++ b/js/src/vm/OldDebugAPI.cpp @@ -948,17 +948,19 @@ JS::DescribeStack(JSContext *cx, unsigne desc->nframes = frames.length(); desc->frames = frames.extractRawBuffer(); return desc; } JS_PUBLIC_API(void) JS::FreeStackDescription(JSContext *cx, JS::StackDescription *desc) { - js_delete(desc->frames); + for (size_t i = 0; i < desc->nframes; ++i) + desc->frames[i].~FrameDescription(); + js_free(desc->frames); js_delete(desc); } namespace { class AutoPropertyDescArray { JSContext *cx_;
--- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -745,16 +745,19 @@ struct JsGcTracer : public TraceCallback JS_CallHeapObjectTracer(static_cast<JSTracer*>(closure), p, name); } virtual void Trace(JS::Heap<JSString *> *p, const char *name, void *closure) const MOZ_OVERRIDE { JS_CallHeapStringTracer(static_cast<JSTracer*>(closure), p, name); } virtual void Trace(JS::Heap<JSScript *> *p, const char *name, void *closure) const MOZ_OVERRIDE { JS_CallHeapScriptTracer(static_cast<JSTracer*>(closure), p, name); } + virtual void Trace(JS::Heap<JSFunction *> *p, const char *name, void *closure) const MOZ_OVERRIDE { + JS_CallHeapFunctionTracer(static_cast<JSTracer*>(closure), p, name); + } }; static PLDHashOperator TraceJSHolder(void* aHolder, nsScriptObjectTracer*& aTracer, void* aArg) { aTracer->Trace(aHolder, JsGcTracer(), aArg); return PL_DHASH_NEXT; @@ -797,16 +800,21 @@ struct ClearJSHolder : TraceCallbacks { *aPtr = nullptr; } virtual void Trace(JS::Heap<JSScript*>* aPtr, const char*, void*) const MOZ_OVERRIDE { *aPtr = nullptr; } + + virtual void Trace(JS::Heap<JSFunction*>* aPtr, const char*, void*) const MOZ_OVERRIDE + { + *aPtr = nullptr; + } }; void CycleCollectedJSRuntime::RemoveJSHolder(void* aHolder) { nsScriptObjectTracer* tracer = mJSHolders.Get(aHolder); if (!tracer) { return;
--- a/xpcom/glue/nsCycleCollectionParticipant.cpp +++ b/xpcom/glue/nsCycleCollectionParticipant.cpp @@ -83,16 +83,22 @@ TraceCallbackFunc::Trace(JS::Heap<jsid>* void TraceCallbackFunc::Trace(JS::Heap<JSObject*>* p, const char* name, void* closure) const { mCallback(*p, name, closure); } void +TraceCallbackFunc::Trace(JS::Heap<JSFunction*>* p, const char* name, void* closure) const +{ + mCallback(*p, name, closure); +} + +void TraceCallbackFunc::Trace(JS::Heap<JSString*>* p, const char* name, void* closure) const { mCallback(*p, name, closure); } void TraceCallbackFunc::Trace(JS::Heap<JSScript*>* p, const char* name, void* closure) const {
--- a/xpcom/glue/nsCycleCollectionParticipant.h +++ b/xpcom/glue/nsCycleCollectionParticipant.h @@ -55,16 +55,17 @@ template <class T> class Heap; */ struct TraceCallbacks { virtual void Trace(JS::Heap<JS::Value>* p, const char* name, void* closure) const = 0; virtual void Trace(JS::Heap<jsid>* p, const char* name, void* closure) const = 0; virtual void Trace(JS::Heap<JSObject*>* p, const char* name, void* closure) const = 0; virtual void Trace(JS::Heap<JSString*>* p, const char* name, void* closure) const = 0; virtual void Trace(JS::Heap<JSScript*>* p, const char* name, void* closure) const = 0; + virtual void Trace(JS::Heap<JSFunction*>* p, const char* name, void* closure) const = 0; }; /* * An implementation of TraceCallbacks that calls a single function for all JS * GC thing types encountered. */ struct TraceCallbackFunc : public TraceCallbacks { @@ -72,16 +73,17 @@ struct TraceCallbackFunc : public TraceC explicit TraceCallbackFunc(Func cb) : mCallback(cb) {} virtual void Trace(JS::Heap<JS::Value>* p, const char* name, void* closure) const MOZ_OVERRIDE; virtual void Trace(JS::Heap<jsid>* p, const char* name, void* closure) const MOZ_OVERRIDE; virtual void Trace(JS::Heap<JSObject*>* p, const char* name, void* closure) const MOZ_OVERRIDE; virtual void Trace(JS::Heap<JSString*>* p, const char* name, void* closure) const MOZ_OVERRIDE; virtual void Trace(JS::Heap<JSScript*>* p, const char* name, void* closure) const MOZ_OVERRIDE; + virtual void Trace(JS::Heap<JSFunction*>* p, const char* name, void* closure) const MOZ_OVERRIDE; private: Func mCallback; }; /** * Participant implementation classes */