mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 932837 part 2. Create a refcounted object to manage the lifetime of a JS::StackDescription. r=mccr8, terrence
This commit is contained in:
parent
a989ae183c
commit
72e2ce7440
@ -203,6 +203,62 @@ GetCurrentJSStack()
|
||||
|
||||
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:
|
||||
@ -356,6 +412,8 @@ JSStackFrame::CreateStack(JSContext* cx)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<StackDescriptionOwner> descOwner = new StackDescriptionOwner(desc);
|
||||
|
||||
for (size_t i = 0; i < desc->nframes && self; i++) {
|
||||
self->mLanguage = nsIProgrammingLanguage::JAVASCRIPT;
|
||||
|
||||
@ -388,8 +446,6 @@ JSStackFrame::CreateStack(JSContext* cx)
|
||||
self.swap(frame);
|
||||
}
|
||||
|
||||
JS::FreeStackDescription(cx, desc);
|
||||
|
||||
return first.forget();
|
||||
}
|
||||
|
||||
|
@ -48,17 +48,17 @@ class FrameDescription
|
||||
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;
|
||||
|
@ -157,6 +157,9 @@ JS_CallHeapStringTracer(JSTracer *trc, JS::Heap<JSString *> *strp, const char *n
|
||||
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)
|
||||
|
@ -78,6 +78,12 @@ JS_CallHeapScriptTracer(JSTracer *trc, JS::Heap<JSScript *> *scriptp, const char
|
||||
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)
|
||||
{
|
||||
|
@ -953,7 +953,9 @@ JS::DescribeStack(JSContext *cx, unsigned maxFrames)
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -750,6 +750,9 @@ struct JsGcTracer : public TraceCallbacks
|
||||
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
|
||||
@ -802,6 +805,11 @@ struct ClearJSHolder : TraceCallbacks
|
||||
{
|
||||
*aPtr = nullptr;
|
||||
}
|
||||
|
||||
virtual void Trace(JS::Heap<JSFunction*>* aPtr, const char*, void*) const MOZ_OVERRIDE
|
||||
{
|
||||
*aPtr = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -87,6 +87,12 @@ TraceCallbackFunc::Trace(JS::Heap<JSObject*>* p, const char* name, void* closure
|
||||
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
|
||||
{
|
||||
|
@ -60,6 +60,7 @@ struct TraceCallbacks
|
||||
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;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -77,6 +78,7 @@ struct TraceCallbackFunc : public TraceCallbacks
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user