Bug 737365 - stop using the cx during finalization, part 1.

This part changes the signatures for various finalization API to take
not JSContext* but rather either JSFreeOp structure or its
library-private counterpart FreeOp. These structures wrap parameters
that are passed to the finalizers removing most of explicit dependencies
on JSContext in the finalization code.
This commit is contained in:
Igor Bukanov 2012-03-19 15:34:55 +01:00
Родитель 344b2b1753
Коммит 2d04a4fe3d
90 изменённых файлов: 435 добавлений и 328 удалений

Просмотреть файл

@ -102,7 +102,7 @@
// The JS class for XBLBinding
//
static void
XBLFinalize(JSContext *cx, JSObject *obj)
XBLFinalize(JSFreeOp *fop, JSObject *obj)
{
nsXBLDocumentInfo* docInfo =
static_cast<nsXBLDocumentInfo*>(::JS_GetPrivate(obj));

Просмотреть файл

@ -172,7 +172,7 @@ nsXBLDocGlobalObject_checkAccess(JSContext *cx, JSObject *obj, jsid id,
}
static void
nsXBLDocGlobalObject_finalize(JSContext *cx, JSObject *obj)
nsXBLDocGlobalObject_finalize(JSFreeOp *fop, JSObject *obj)
{
nsISupports *nativeThis = (nsISupports*)JS_GetPrivate(obj);

Просмотреть файл

@ -120,7 +120,7 @@ PRUint32 nsXULPrototypeDocument::gRefCnt;
void
nsXULPDGlobalObject_finalize(JSContext *cx, JSObject *obj)
nsXULPDGlobalObject_finalize(JSFreeOp *fop, JSObject *obj)
{
nsISupports *nativeThis = (nsISupports*)JS_GetPrivate(obj);

Просмотреть файл

@ -4799,7 +4799,7 @@ nsDOMClassInfo::Convert(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
NS_IMETHODIMP
nsDOMClassInfo::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
nsDOMClassInfo::Finalize(nsIXPConnectWrappedNative *wrapper, JSFreeOp *fop,
JSObject *obj)
{
NS_WARNING("nsDOMClassInfo::Finalize Don't call me!");
@ -7403,7 +7403,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
}
NS_IMETHODIMP
nsWindowSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
nsWindowSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSFreeOp *fop,
JSObject *obj)
{
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryWrappedNative(wrapper));
@ -8940,7 +8940,7 @@ nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JSObject *obj, jsid id,
// sGlobalScopePolluterClass!
void
nsHTMLDocumentSH::ReleaseDocument(JSContext *cx, JSObject *obj)
nsHTMLDocumentSH::ReleaseDocument(JSFreeOp *fop, JSObject *obj)
{
nsIHTMLDocument *doc = (nsIHTMLDocument *)::JS_GetPrivate(obj);

Просмотреть файл

@ -416,7 +416,7 @@ public:
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, jsid id, PRUint32 flags,
JSObject **objp, bool *_retval);
NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
NS_IMETHOD Finalize(nsIXPConnectWrappedNative *wrapper, JSFreeOp *fop,
JSObject *obj);
NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval);
@ -798,7 +798,7 @@ public:
jsval *vp);
static JSBool DocumentAllNewResolve(JSContext *cx, JSObject *obj, jsid id,
unsigned flags, JSObject **objp);
static void ReleaseDocument(JSContext *cx, JSObject *obj);
static void ReleaseDocument(JSFreeOp *fop, JSObject *obj);
static JSBool CallToGetPropMapper(JSContext *cx, unsigned argc, jsval *vp);
static JSBool DocumentAllHelperGetProperty(JSContext *cx, JSObject *obj,
jsid id, jsval *vp);

Просмотреть файл

@ -808,7 +808,7 @@ public:
return true;
}
JSString *obj_toString(JSContext *cx, JSObject *wrapper);
void finalize(JSContext *cx, JSObject *proxy);
void finalize(JSFreeOp *fop, JSObject *proxy);
static nsOuterWindowProxy singleton;
};
@ -823,7 +823,7 @@ nsOuterWindowProxy::obj_toString(JSContext *cx, JSObject *proxy)
}
void
nsOuterWindowProxy::finalize(JSContext *cx, JSObject *proxy)
nsOuterWindowProxy::finalize(JSFreeOp *fop, JSObject *proxy)
{
nsISupports *global =
static_cast<nsISupports*>(js::GetProxyExtra(proxy, 0).toPrivate());

Просмотреть файл

@ -470,7 +470,7 @@ class CGClassFinalizeHook(CGAbstractClassHook):
A hook for finalize, used to release our native object.
"""
def __init__(self, descriptor):
args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'obj')]
args = [Argument('JSFreeOp*', 'fop'), Argument('JSObject*', 'obj')]
CGAbstractClassHook.__init__(self, descriptor, FINALIZE_HOOK_NAME,
'void', args)

Просмотреть файл

@ -166,7 +166,7 @@ static JSBool
NPObjWrapper_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
static void
NPObjWrapper_Finalize(JSContext *cx, JSObject *obj);
NPObjWrapper_Finalize(JSFreeOp *fop, JSObject *obj);
static JSBool
NPObjWrapper_Call(JSContext *cx, unsigned argc, jsval *vp);
@ -201,7 +201,7 @@ static JSBool
NPObjectMember_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
static void
NPObjectMember_Finalize(JSContext *cx, JSObject *obj);
NPObjectMember_Finalize(JSFreeOp *fop, JSObject *obj);
static JSBool
NPObjectMember_Call(JSContext *cx, unsigned argc, jsval *vp);
@ -1712,7 +1712,7 @@ NPObjWrapper_Convert(JSContext *cx, JSObject *obj, JSType hint, jsval *vp)
}
static void
NPObjWrapper_Finalize(JSContext *cx, JSObject *obj)
NPObjWrapper_Finalize(JSFreeOp *fop, JSObject *obj)
{
NPObject *npobj = (NPObject *)::JS_GetPrivate(obj);
if (npobj) {
@ -2214,7 +2214,7 @@ NPObjectMember_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
}
static void
NPObjectMember_Finalize(JSContext *cx, JSObject *obj)
NPObjectMember_Finalize(JSFreeOp *fop, JSObject *obj)
{
NPObjectMemberPrivate *memberPrivate;

Просмотреть файл

@ -39,7 +39,7 @@ DOMBindingBase::_Trace(JSTracer* aTrc)
}
void
DOMBindingBase::_Finalize(JSContext* aCx)
DOMBindingBase::_Finalize(JSFreeOp* aFop)
{
ClearWrapper();
NS_RELEASE_THIS();

Просмотреть файл

@ -40,7 +40,7 @@ protected:
_Trace(JSTracer* aTrc);
virtual void
_Finalize(JSContext* aCx);
_Finalize(JSFreeOp* aFop);
JSContext*
GetJSContextFromContextStack() const;

Просмотреть файл

@ -84,11 +84,11 @@ struct ListenerData : PRCList
};
inline void
DestroyList(JSContext* aCx, PRCList* aListHead)
DestroyList(JSFreeOp* aFop, PRCList* aListHead)
{
for (PRCList* elem = PR_NEXT_LINK(aListHead); elem != aListHead; ) {
PRCList* nextElem = PR_NEXT_LINK(elem);
JS_free(aCx, elem);
JS_freeop(aFop, elem);
elem = nextElem;
}
}
@ -174,17 +174,17 @@ EventListenerManager::TraceInternal(JSTracer* aTrc) const
}
void
EventListenerManager::FinalizeInternal(JSContext* aCx)
EventListenerManager::FinalizeInternal(JSFreeOp* aFop)
{
MOZ_ASSERT(!PR_CLIST_IS_EMPTY(&mCollectionHead));
for (PRCList* elem = PR_NEXT_LINK(&mCollectionHead);
elem != &mCollectionHead;
elem = PR_NEXT_LINK(elem)) {
DestroyList(aCx, &static_cast<ListenerCollection*>(elem)->mListenerHead);
DestroyList(aFop, &static_cast<ListenerCollection*>(elem)->mListenerHead);
}
DestroyList(aCx, &mCollectionHead);
DestroyList(aFop, &mCollectionHead);
#ifdef DEBUG
PR_INIT_CLIST(&mCollectionHead);

Просмотреть файл

@ -39,10 +39,10 @@ public:
}
void
_Finalize(JSContext* aCx)
_Finalize(JSFreeOp* aFop)
{
if (!PR_CLIST_IS_EMPTY(&mCollectionHead)) {
FinalizeInternal(aCx);
FinalizeInternal(aFop);
}
}
@ -110,7 +110,7 @@ private:
TraceInternal(JSTracer* aTrc) const;
void
FinalizeInternal(JSContext* aCx);
FinalizeInternal(JSFreeOp* aFop);
void
Add(JSContext* aCx, const jsid& aType, JSObject* aListener, Phase aPhase,

Просмотреть файл

@ -15,10 +15,10 @@ EventTarget::_Trace(JSTracer* aTrc)
}
void
EventTarget::_Finalize(JSContext* aCx)
EventTarget::_Finalize(JSFreeOp* aFop)
{
mListenerManager._Finalize(aCx);
DOMBindingBase::_Finalize(aCx);
mListenerManager._Finalize(aFop);
DOMBindingBase::_Finalize(aFop);
}
JSObject*
@ -96,4 +96,4 @@ EventTarget::RemoveEventListener(const nsAString& aType, JSObject* aListener,
mListenerManager.RemoveEventListener(cx, INTERNED_STRING_TO_JSID(cx, type),
aListener, aCapturing);
}
}

Просмотреть файл

@ -34,7 +34,7 @@ public:
_Trace(JSTracer* aTrc) MOZ_OVERRIDE;
virtual void
_Finalize(JSContext* aCx) MOZ_OVERRIDE;
_Finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
void
AddEventListener(const nsAString& aType, JSObject* aListener,

Просмотреть файл

@ -246,7 +246,7 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(IsThisClass(JS_GetClass(aObj)));
delete GetJSPrivateSafeish<Event>(aObj);
@ -529,12 +529,12 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(IsThisClass(JS_GetClass(aObj)));
MessageEvent* priv = GetJSPrivateSafeish<MessageEvent>(aObj);
if (priv) {
JS_free(aCx, priv->mData);
JS_freeop(aFop, priv->mData);
#ifdef DEBUG
priv->mData = NULL;
#endif
@ -744,7 +744,7 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(IsThisClass(JS_GetClass(aObj)));
delete GetJSPrivateSafeish<ErrorEvent>(aObj);
@ -924,7 +924,7 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == &sClass);
delete GetJSPrivateSafeish<ProgressEvent>(aObj);

Просмотреть файл

@ -109,7 +109,7 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == &sClass);
delete GetJSPrivateSafeish<DOMException>(aObj);
@ -316,7 +316,7 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == &sClass);
delete GetJSPrivateSafeish<FileException>(aObj);

Просмотреть файл

@ -141,7 +141,7 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == &sClass);
@ -330,7 +330,7 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == &sClass);

Просмотреть файл

@ -156,7 +156,7 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == &sClass);
FileReaderSyncPrivate* fileReader =

Просмотреть файл

@ -132,7 +132,7 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == &sClass);
delete static_cast<Location*>(JS_GetPrivate(aObj));

Просмотреть файл

@ -143,7 +143,7 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == &sClass);
delete static_cast<Navigator*>(JS_GetPrivate(aObj));

Просмотреть файл

@ -246,12 +246,12 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == Class());
WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj, Class());
if (worker) {
worker->_Finalize(aCx);
worker->_Finalize(aFop);
}
}
@ -404,12 +404,12 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == Class());
WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj, Class());
if (worker) {
worker->_Finalize(aCx);
worker->_Finalize(aFop);
}
}

Просмотреть файл

@ -2043,7 +2043,7 @@ WorkerPrivateParent<Derived>::_Trace(JSTracer* aTrc)
template <class Derived>
void
WorkerPrivateParent<Derived>::_Finalize(JSContext* aCx)
WorkerPrivateParent<Derived>::_Finalize(JSFreeOp* aFop)
{
AssertIsOnParentThread();
@ -2053,7 +2053,7 @@ WorkerPrivateParent<Derived>::_Finalize(JSContext* aCx)
// Clear the JS object.
mJSObject = nsnull;
if (!TerminatePrivate(aCx, true)) {
if (!TerminatePrivate(aFop->context, true)) {
NS_WARNING("Failed to terminate!");
}
@ -2069,7 +2069,7 @@ WorkerPrivateParent<Derived>::_Finalize(JSContext* aCx)
NS_ADDREF(extraSelfRef = this);
}
EventTarget::_Finalize(aCx);
EventTarget::_Finalize(aFop);
if (extraSelfRef) {
nsCOMPtr<nsIRunnable> runnable =

Просмотреть файл

@ -287,7 +287,7 @@ public:
_Trace(JSTracer* aTrc) MOZ_OVERRIDE;
virtual void
_Finalize(JSContext* aCx) MOZ_OVERRIDE;
_Finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
void
Finish(JSContext* aCx)

Просмотреть файл

@ -159,9 +159,9 @@ protected:
}
virtual void
_Finalize(JSContext* aCx) MOZ_OVERRIDE
_Finalize(JSFreeOp* aFop) MOZ_OVERRIDE
{
EventTarget::_Finalize(aCx);
EventTarget::_Finalize(aFop);
}
private:
@ -826,14 +826,14 @@ private:
}
static void
Finalize(JSContext* aCx, JSObject* aObj)
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == Class());
DedicatedWorkerGlobalScope* scope =
UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj, Class());
if (scope) {
DestroyProtoOrIfaceCache(aObj);
scope->_Finalize(aCx);
scope->_Finalize(aFop);
}
}

Просмотреть файл

@ -1470,10 +1470,10 @@ XMLHttpRequest::_Trace(JSTracer* aTrc)
}
void
XMLHttpRequest::_Finalize(JSContext* aCx)
XMLHttpRequest::_Finalize(JSFreeOp* aFop)
{
ReleaseProxy(XHRIsGoingAway);
XMLHttpRequestEventTarget::_Finalize(aCx);
XMLHttpRequestEventTarget::_Finalize(aFop);
}
// static

Просмотреть файл

@ -68,7 +68,7 @@ public:
_Trace(JSTracer* aTrc) MOZ_OVERRIDE;
virtual void
_Finalize(JSContext* aCx) MOZ_OVERRIDE;
_Finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
static XMLHttpRequest*
_Constructor(JSContext* aCx, JSObject* aGlobal, nsresult& aRv);

Просмотреть файл

@ -14,7 +14,7 @@ XMLHttpRequestEventTarget::_Trace(JSTracer* aTrc)
}
void
XMLHttpRequestEventTarget::_Finalize(JSContext* aCx)
XMLHttpRequestEventTarget::_Finalize(JSFreeOp* aFop)
{
EventTarget::_Finalize(aCx);
EventTarget::_Finalize(aFop);
}

Просмотреть файл

@ -25,7 +25,7 @@ public:
_Trace(JSTracer* aTrc) MOZ_OVERRIDE;
virtual void
_Finalize(JSContext* aCx) MOZ_OVERRIDE;
_Finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
#define IMPL_GETTER_AND_SETTER(_type) \
JSObject* \

Просмотреть файл

@ -29,7 +29,7 @@ XMLHttpRequestUpload::_Trace(JSTracer* aTrc)
}
void
XMLHttpRequestUpload::_Finalize(JSContext* aCx)
XMLHttpRequestUpload::_Finalize(JSFreeOp* aFop)
{
XMLHttpRequestEventTarget::_Finalize(aCx);
XMLHttpRequestEventTarget::_Finalize(aFop);
}

Просмотреть файл

@ -32,7 +32,7 @@ public:
_Trace(JSTracer* aTrc) MOZ_OVERRIDE;
virtual void
_Finalize(JSContext* aCx) MOZ_OVERRIDE;
_Finalize(JSFreeOp* aFop) MOZ_OVERRIDE;
};
END_WORKERS_NAMESPACE

Просмотреть файл

@ -411,7 +411,7 @@ static const PRUint32 sNextIdIndexSlot = 0;
static const PRUint32 sNumNewEnumerateStateSlots = 1;
static void
CPOW_NewEnumerateState_Finalize(JSContext* cx, JSObject* state)
CPOW_NewEnumerateState_FreeIds(JSObject* state)
{
nsTArray<nsString>* strIds =
static_cast<nsTArray<nsString>*>(JS_GetPrivate(state));
@ -422,6 +422,12 @@ CPOW_NewEnumerateState_Finalize(JSContext* cx, JSObject* state)
}
}
static void
CPOW_NewEnumerateState_Finalize(JSFreeOp* fop, JSObject* state)
{
CPOW_NewEnumerateState_FreeIds(state);
}
// Similar to IteratorClass in XPCWrapper.cpp
static const JSClass sCPOW_NewEnumerateState_JSClass = {
"CPOW NewEnumerate State",
@ -531,7 +537,7 @@ ObjectWrapperChild::RecvNewEnumerateDestroy(const JSVariant& in_state)
if (!JSObject_from_JSVariant(cx, in_state, &state))
return false;
CPOW_NewEnumerateState_Finalize(cx, state);
CPOW_NewEnumerateState_FreeIds(state);
return true;
}

Просмотреть файл

@ -627,7 +627,7 @@ ObjectWrapperParent::CPOW_Convert(JSContext *cx, JSObject *obj, JSType type,
}
/*static*/ void
ObjectWrapperParent::CPOW_Finalize(JSContext* cx, JSObject* obj)
ObjectWrapperParent::CPOW_Finalize(js::FreeOp* fop, JSObject* obj)
{
CPOW_LOG(("Calling CPOW_Finalize..."));

Просмотреть файл

@ -119,7 +119,7 @@ private:
CPOW_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
static void
CPOW_Finalize(JSContext* cx, JSObject* obj);
CPOW_Finalize(js::FreeOp* fop, JSObject* obj);
static JSBool
CPOW_Call(JSContext* cx, unsigned argc, jsval* vp);

Просмотреть файл

@ -196,11 +196,11 @@ MapObject::mark(JSTracer *trc, JSObject *obj)
}
void
MapObject::finalize(JSContext *cx, JSObject *obj)
MapObject::finalize(FreeOp *fop, JSObject *obj)
{
MapObject *mapobj = static_cast<MapObject *>(obj);
if (ValueMap *map = mapobj->getData())
cx->delete_(map);
fop->delete_(map);
}
class AddToMap {
@ -397,11 +397,11 @@ SetObject::mark(JSTracer *trc, JSObject *obj)
}
void
SetObject::finalize(JSContext *cx, JSObject *obj)
SetObject::finalize(FreeOp *fop, JSObject *obj)
{
SetObject *setobj = static_cast<SetObject *>(obj);
if (ValueSet *set = setobj->getData())
cx->delete_(set);
fop->delete_(set);
}
class AddToSet {

Просмотреть файл

@ -87,7 +87,7 @@ class MapObject : public JSObject {
static JSFunctionSpec methods[];
ValueMap *getData() { return static_cast<ValueMap *>(getPrivate()); }
static void mark(JSTracer *trc, JSObject *obj);
static void finalize(JSContext *cx, JSObject *obj);
static void finalize(FreeOp *fop, JSObject *obj);
static JSBool construct(JSContext *cx, unsigned argc, Value *vp);
static JSBool size(JSContext *cx, unsigned argc, Value *vp);
static JSBool get(JSContext *cx, unsigned argc, Value *vp);
@ -105,7 +105,7 @@ class SetObject : public JSObject {
static JSFunctionSpec methods[];
ValueSet *getData() { return static_cast<ValueSet *>(getPrivate()); }
static void mark(JSTracer *trc, JSObject *obj);
static void finalize(JSContext *cx, JSObject *obj);
static void finalize(FreeOp *fop, JSObject *obj);
static JSBool construct(JSContext *cx, unsigned argc, Value *vp);
static JSBool size(JSContext *cx, unsigned argc, Value *vp);
static JSBool has(JSContext *cx, unsigned argc, Value *vp);

Просмотреть файл

@ -390,7 +390,7 @@ CountHeap(JSContext *cx, unsigned argc, jsval *vp)
static unsigned finalizeCount = 0;
static void
finalize_counter_finalize(JSContext *cx, JSObject *obj)
finalize_counter_finalize(JSFreeOp *fop, JSObject *obj)
{
JS_ATOMIC_INCREMENT(&finalizeCount);
}

Просмотреть файл

@ -78,8 +78,8 @@ namespace CType {
static JSBool ConstructBasic(JSContext* cx, JSObject* obj, unsigned argc, jsval* vp);
static void Trace(JSTracer* trc, JSObject* obj);
static void Finalize(JSContext* cx, JSObject* obj);
static void FinalizeProtoClass(JSContext* cx, JSObject* obj);
static void Finalize(JSFreeOp *fop, JSObject* obj);
static void FinalizeProtoClass(JSFreeOp *fop, JSObject* obj);
static JSBool PrototypeGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp);
@ -168,7 +168,7 @@ namespace FunctionType {
namespace CClosure {
static void Trace(JSTracer* trc, JSObject* obj);
static void Finalize(JSContext* cx, JSObject* obj);
static void Finalize(JSFreeOp *fop, JSObject* obj);
// libffi callback
static void ClosureStub(ffi_cif* cif, void* result, void** args,
@ -176,7 +176,7 @@ namespace CClosure {
}
namespace CData {
static void Finalize(JSContext* cx, JSObject* obj);
static void Finalize(JSFreeOp *fop, JSObject* obj);
static JSBool ValueGetter(JSContext* cx, JSObject* obj, jsid idval,
jsval* vp);
@ -208,7 +208,7 @@ namespace Int64Base {
JSBool ToSource(JSContext* cx, JSObject* obj, unsigned argc, jsval* vp,
bool isUnsigned);
static void Finalize(JSContext* cx, JSObject* obj);
static void Finalize(JSFreeOp *fop, JSObject* obj);
}
namespace Int64 {
@ -2758,7 +2758,7 @@ CType::DefineBuiltin(JSContext* cx,
}
void
CType::Finalize(JSContext* cx, JSObject* obj)
CType::Finalize(JSFreeOp *fop, JSObject* obj)
{
// Make sure our TypeCode slot is legit. If it's not, bail.
jsval slot = JS_GetReservedSlot(obj, SLOT_TYPECODE);
@ -2771,7 +2771,7 @@ CType::Finalize(JSContext* cx, JSObject* obj)
// Free the FunctionInfo.
slot = JS_GetReservedSlot(obj, SLOT_FNINFO);
if (!JSVAL_IS_VOID(slot))
cx->delete_(static_cast<FunctionInfo*>(JSVAL_TO_PRIVATE(slot)));
FreeOp::get(fop)->delete_(static_cast<FunctionInfo*>(JSVAL_TO_PRIVATE(slot)));
break;
}
@ -2780,7 +2780,7 @@ CType::Finalize(JSContext* cx, JSObject* obj)
slot = JS_GetReservedSlot(obj, SLOT_FIELDINFO);
if (!JSVAL_IS_VOID(slot)) {
void* info = JSVAL_TO_PRIVATE(slot);
cx->delete_(static_cast<FieldInfoHash*>(info));
FreeOp::get(fop)->delete_(static_cast<FieldInfoHash*>(info));
}
}
@ -2790,8 +2790,8 @@ CType::Finalize(JSContext* cx, JSObject* obj)
slot = JS_GetReservedSlot(obj, SLOT_FFITYPE);
if (!JSVAL_IS_VOID(slot)) {
ffi_type* ffiType = static_cast<ffi_type*>(JSVAL_TO_PRIVATE(slot));
cx->array_delete(ffiType->elements);
cx->delete_(ffiType);
FreeOp::get(fop)->array_delete(ffiType->elements);
FreeOp::get(fop)->delete_(ffiType);
}
break;
@ -2803,7 +2803,7 @@ CType::Finalize(JSContext* cx, JSObject* obj)
}
void
CType::FinalizeProtoClass(JSContext* cx, JSObject* obj)
CType::FinalizeProtoClass(JSFreeOp *fop, JSObject* obj)
{
// Finalize the CTypeProto class. The only important bit here is our
// SLOT_CLOSURECX -- it contains the JSContext that was (lazily) instantiated
@ -5494,7 +5494,7 @@ CClosure::Trace(JSTracer* trc, JSObject* obj)
}
void
CClosure::Finalize(JSContext* cx, JSObject* obj)
CClosure::Finalize(JSFreeOp *fop, JSObject* obj)
{
// Make sure our ClosureInfo slot is legit. If it's not, bail.
jsval slot = JS_GetReservedSlot(obj, SLOT_CLOSUREINFO);
@ -5502,7 +5502,7 @@ CClosure::Finalize(JSContext* cx, JSObject* obj)
return;
ClosureInfo* cinfo = static_cast<ClosureInfo*>(JSVAL_TO_PRIVATE(slot));
cx->delete_(cinfo);
FreeOp::get(fop)->delete_(cinfo);
}
void
@ -5740,7 +5740,7 @@ CData::Create(JSContext* cx,
}
void
CData::Finalize(JSContext* cx, JSObject* obj)
CData::Finalize(JSFreeOp *fop, JSObject* obj)
{
// Delete our buffer, and the data it contains if we own it.
jsval slot = JS_GetReservedSlot(obj, SLOT_OWNS);
@ -5755,8 +5755,8 @@ CData::Finalize(JSContext* cx, JSObject* obj)
char** buffer = static_cast<char**>(JSVAL_TO_PRIVATE(slot));
if (owns)
cx->array_delete(*buffer);
cx->delete_(buffer);
FreeOp::get(fop)->array_delete(*buffer);
FreeOp::get(fop)->delete_(buffer);
}
JSObject*
@ -6124,13 +6124,13 @@ Int64Base::Construct(JSContext* cx,
}
void
Int64Base::Finalize(JSContext* cx, JSObject* obj)
Int64Base::Finalize(JSFreeOp *fop, JSObject* obj)
{
jsval slot = JS_GetReservedSlot(obj, SLOT_INT64);
if (JSVAL_IS_VOID(slot))
return;
cx->delete_(static_cast<uint64_t*>(JSVAL_TO_PRIVATE(slot)));
FreeOp::get(fop)->delete_(static_cast<uint64_t*>(JSVAL_TO_PRIVATE(slot)));
}
uint64_t

Просмотреть файл

@ -53,7 +53,7 @@ namespace ctypes {
namespace Library
{
static void Finalize(JSContext* cx, JSObject* obj);
static void Finalize(JSFreeOp *fop, JSObject* obj);
static JSBool Close(JSContext* cx, unsigned argc, jsval* vp);
static JSBool Declare(JSContext* cx, unsigned argc, jsval* vp);
@ -205,15 +205,20 @@ Library::GetLibrary(JSObject* obj)
return static_cast<PRLibrary*>(JSVAL_TO_PRIVATE(slot));
}
void
Library::Finalize(JSContext* cx, JSObject* obj)
static void
UnloadLibrary(JSObject* obj)
{
// unload the library
PRLibrary* library = GetLibrary(obj);
PRLibrary* library = Library::GetLibrary(obj);
if (library)
PR_UnloadLibrary(library);
}
void
Library::Finalize(JSFreeOp *fop, JSObject* obj)
{
UnloadLibrary(obj);
}
JSBool
Library::Open(JSContext* cx, unsigned argc, jsval *vp)
{
@ -251,7 +256,7 @@ Library::Close(JSContext* cx, unsigned argc, jsval* vp)
}
// delete our internal objects
Finalize(cx, obj);
UnloadLibrary(obj);
JS_SetReservedSlot(obj, SLOT_LIBRARY, PRIVATE_TO_JSVAL(NULL));
JS_SET_RVAL(cx, vp, JSVAL_VOID);

Просмотреть файл

@ -24,7 +24,7 @@ struct StringWrapper
} sw;
void
FinalizeCallback(JSContext *cx, JSFinalizeStatus status)
FinalizeCallback(JSFreeOp *fop, JSFinalizeStatus status)
{
if (status == JSFINALIZE_START)
sw.strOk = !JS_IsAboutToBeFinalized(sw.str);

Просмотреть файл

@ -2229,6 +2229,12 @@ JS_free(JSContext *cx, void *p)
return cx->free_(p);
}
JS_PUBLIC_API(void)
JS_freeop(JSFreeOp *fop, void *p)
{
return FreeOp::get(fop)->free_(p);
}
JS_PUBLIC_API(void)
JS_updateMallocCounter(JSContext *cx, size_t nbytes)
{
@ -4190,7 +4196,7 @@ JS_ClearScope(JSContext *cx, JSObject *obj)
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
JSFinalizeOp clearOp = obj->getOps()->clear;
ClearOp clearOp = obj->getOps()->clear;
if (clearOp)
clearOp(cx, obj);
@ -4230,7 +4236,7 @@ JS_Enumerate(JSContext *cx, JSObject *obj)
const uint32_t JSSLOT_ITER_INDEX = 0;
static void
prop_iter_finalize(JSContext *cx, JSObject *obj)
prop_iter_finalize(FreeOp *fop, JSObject *obj)
{
void *pdata = obj->getPrivate();
if (!pdata)
@ -4239,7 +4245,7 @@ prop_iter_finalize(JSContext *cx, JSObject *obj)
if (obj->getSlot(JSSLOT_ITER_INDEX).toInt32() >= 0) {
/* Non-native case: destroy the ida enumerated when obj was created. */
JSIdArray *ida = (JSIdArray *) pdata;
JS_DestroyIdArray(cx, ida);
JS_DestroyIdArray(fop->context, ida);
}
}

Просмотреть файл

@ -1344,13 +1344,34 @@ typedef JSBool
typedef JSType
(* JSTypeOfOp)(JSContext *cx, JSObject *obj);
typedef struct JSFreeOp JSFreeOp;
struct JSFreeOp {
JSContext *context;
#ifndef __cplusplus
JSRuntime *runtime;
#else
private:
JSRuntime *runtime_;
protected:
JSFreeOp(JSRuntime *rt, JSContext *cx)
: context(cx), runtime_(rt) { }
public:
JSRuntime *runtime() const {
return runtime_;
}
#endif
};
/*
* Finalize obj, which the garbage collector has determined to be unreachable
* from other live objects or from GC roots. Obviously, finalizers must never
* store a reference to obj.
*/
typedef void
(* JSFinalizeOp)(JSContext *cx, JSObject *obj);
(* JSFinalizeOp)(JSFreeOp *fop, JSObject *obj);
/*
* Finalizes external strings created by JS_NewExternalString.
@ -1455,7 +1476,7 @@ typedef enum JSFinalizeStatus {
} JSFinalizeStatus;
typedef void
(* JSFinalizeCallback)(JSContext *cx, JSFinalizeStatus status);
(* JSFinalizeCallback)(JSFreeOp *fop, JSFinalizeStatus status);
/*
* Generic trace operation that calls JS_CallTracer on each traceable thing
@ -2954,9 +2975,20 @@ JS_malloc(JSContext *cx, size_t nbytes);
extern JS_PUBLIC_API(void *)
JS_realloc(JSContext *cx, void *p, size_t nbytes);
/*
* A wrapper for js_free(p) that may delay js_free(p) invocation as a
* performance optimization.
*/
extern JS_PUBLIC_API(void)
JS_free(JSContext *cx, void *p);
/*
* A wrapper for js_free(p) that may delay js_free(p) invocation as a
* performance optimization as specified by the given JSFreeOp instance.
*/
extern JS_PUBLIC_API(void)
JS_freeop(JSFreeOp *fop, void *p);
extern JS_PUBLIC_API(void)
JS_updateMallocCounter(JSContext *cx, size_t nbytes);

Просмотреть файл

@ -218,8 +218,9 @@ js_FinishAtomState(JSRuntime *rt)
return;
}
FreeOp fop(rt, false, false, NULL);
for (AtomSet::Range r = state->atoms.all(); !r.empty(); r.popFront())
r.front().asPtr()->finalize(rt);
r.front().asPtr()->finalize(&fop);
}
bool

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=4 sw=4 et tw=79 ft=cpp:
*
* ***** BEGIN LICENSE BLOCK *****
@ -248,7 +248,9 @@ typedef JSBool
typedef JSObject *
(* ObjectOp)(JSContext *cx, JSObject *obj);
typedef void
(* FinalizeOp)(JSContext *cx, JSObject *obj);
(* FinalizeOp)(FreeOp *fop, JSObject *obj);
typedef void
(* ClearOp)(JSContext *cx, JSObject *obj);
#define JS_CLASS_MEMBERS \
const char *name; \
@ -262,7 +264,7 @@ typedef void
JSEnumerateOp enumerate; \
JSResolveOp resolve; \
JSConvertOp convert; \
JSFinalizeOp finalize; \
FinalizeOp finalize; \
\
/* Optionally non-null members start here. */ \
JSCheckAccessOp checkAccess; \
@ -332,7 +334,7 @@ struct ObjectOps
TypeOfOp typeOf;
FixOp fix;
ObjectOp thisObject;
FinalizeOp clear;
ClearOp clear;
};
#define JS_NULL_OBJECT_OPS \

Просмотреть файл

@ -744,7 +744,7 @@ namespace VersionFlags {
static const unsigned MASK = 0x0FFF; /* see JSVersion in jspubtd.h */
static const unsigned HAS_XML = 0x1000; /* flag induced by XML option */
static const unsigned FULL_MASK = 0x3FFF;
}
} /* namespace VersionFlags */
static inline JSVersion
VersionNumber(JSVersion version)
@ -807,6 +807,53 @@ typedef HashSet<JSObject *,
DefaultHasher<JSObject *>,
SystemAllocPolicy> BusyArraysSet;
class FreeOp : public JSFreeOp {
bool shouldFreeLater_;
bool onBackgroundThread_;
public:
static FreeOp *get(JSFreeOp *fop) {
return static_cast<FreeOp *>(fop);
}
FreeOp(JSRuntime *rt, bool shouldFreeLater, bool onBackgroundThread, JSContext *cx)
: JSFreeOp(rt, cx),
shouldFreeLater_(shouldFreeLater),
onBackgroundThread_(onBackgroundThread)
{
}
bool shouldFreeLater() const {
return shouldFreeLater_;
}
bool onBackgroundThread() const {
return onBackgroundThread_;
}
void free_(void* p) {
#ifdef JS_THREADSAFE
if (shouldFreeLater()) {
runtime()->gcHelperThread.freeLater(p);
return;
}
#endif
runtime()->free_(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
* on this.
*/
JS_STATIC_ASSERT(offsetof(FreeOp, shouldFreeLater_) == sizeof(JSFreeOp));
}
};
} /* namespace js */
struct JSContext : js::ContextFriendFields

Просмотреть файл

@ -490,7 +490,7 @@ JSCompartment::discardJitCode(JSContext *cx)
}
void
JSCompartment::sweep(JSContext *cx, bool releaseTypes)
JSCompartment::sweep(FreeOp *fop, bool releaseTypes)
{
/* Remove dead wrappers from the table. */
for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
@ -507,21 +507,21 @@ JSCompartment::sweep(JSContext *cx, bool releaseTypes)
regExps.sweep(rt);
sweepBaseShapeTable(cx);
sweepInitialShapeTable(cx);
sweepNewTypeObjectTable(cx, newTypeObjects);
sweepNewTypeObjectTable(cx, lazyTypeObjects);
sweepBaseShapeTable();
sweepInitialShapeTable();
sweepNewTypeObjectTable(newTypeObjects);
sweepNewTypeObjectTable(lazyTypeObjects);
if (emptyTypeObject && IsAboutToBeFinalized(emptyTypeObject))
emptyTypeObject = NULL;
newObjectCache.reset();
sweepBreakpoints(cx);
sweepBreakpoints(fop);
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_DISCARD_CODE);
discardJitCode(cx);
discardJitCode(fop->context);
}
if (!activeAnalysis) {
@ -552,7 +552,7 @@ JSCompartment::sweep(JSContext *cx, bool releaseTypes)
for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
if (script->types) {
types::TypeScript::Sweep(cx, script);
types::TypeScript::Sweep(fop->context, script);
if (releaseTypes) {
script->types->destroy();
@ -565,7 +565,7 @@ JSCompartment::sweep(JSContext *cx, bool releaseTypes)
{
gcstats::AutoPhase ap2(rt->gcStats, gcstats::PHASE_SWEEP_TYPES);
types.sweep(cx);
types.sweep(fop->context);
}
{
@ -766,9 +766,9 @@ JSCompartment::clearTraps(JSContext *cx)
}
void
JSCompartment::sweepBreakpoints(JSContext *cx)
JSCompartment::sweepBreakpoints(FreeOp *fop)
{
if (JS_CLIST_IS_EMPTY(&cx->runtime->debuggerList))
if (JS_CLIST_IS_EMPTY(&rt->debuggerList))
return;
for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
@ -786,7 +786,7 @@ JSCompartment::sweepBreakpoints(JSContext *cx)
for (Breakpoint *bp = site->firstBreakpoint(); bp; bp = nextbp) {
nextbp = bp->nextInSite();
if (scriptGone || IsAboutToBeFinalized(bp->debugger->toJSObject()))
bp->destroy(cx);
bp->destroy(fop->context);
}
}
}

Просмотреть файл

@ -314,16 +314,16 @@ struct JSCompartment
/* Set of all unowned base shapes in the compartment. */
js::BaseShapeSet baseShapes;
void sweepBaseShapeTable(JSContext *cx);
void sweepBaseShapeTable();
/* Set of initial shapes in the compartment. */
js::InitialShapeSet initialShapes;
void sweepInitialShapeTable(JSContext *cx);
void sweepInitialShapeTable();
/* Set of default 'new' or lazy types in the compartment. */
js::types::TypeObjectSet newTypeObjects;
js::types::TypeObjectSet lazyTypeObjects;
void sweepNewTypeObjectTable(JSContext *cx, js::types::TypeObjectSet &table);
void sweepNewTypeObjectTable(js::types::TypeObjectSet &table);
js::types::TypeObject *emptyTypeObject;
@ -384,7 +384,7 @@ struct JSCompartment
void markTypes(JSTracer *trc);
void discardJitCode(JSContext *cx);
void sweep(JSContext *cx, bool releaseTypes);
void sweep(js::FreeOp *fop, bool releaseTypes);
void purge();
void setGCLastBytes(size_t lastBytes, size_t lastMallocBytes, js::JSGCInvocationKind gckind);
@ -459,7 +459,7 @@ struct JSCompartment
void clearTraps(JSContext *cx);
private:
void sweepBreakpoints(JSContext *cx);
void sweepBreakpoints(js::FreeOp *fop);
public:
js::WatchpointMap *watchpointMap;

Просмотреть файл

@ -86,7 +86,7 @@ static void
exn_trace(JSTracer *trc, JSObject *obj);
static void
exn_finalize(JSContext *cx, JSObject *obj);
exn_finalize(FreeOp *fop, JSObject *obj);
static JSBool
exn_resolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
@ -488,16 +488,16 @@ SetExnPrivate(JSContext *cx, JSObject *exnObject, JSExnPrivate *priv)
}
static void
exn_finalize(JSContext *cx, JSObject *obj)
exn_finalize(FreeOp *fop, JSObject *obj)
{
if (JSExnPrivate *priv = GetExnPrivate(obj)) {
if (JSErrorReport *report = priv->errorReport) {
/* HOLD called by SetExnPrivate. */
if (JSPrincipals *prin = report->originPrincipals)
JS_DropPrincipals(cx->runtime, prin);
cx->free_(report);
JS_DropPrincipals(fop->runtime(), prin);
fop->free_(report);
}
cx->free_(priv);
fop->free_(priv);
}
}

Просмотреть файл

@ -307,7 +307,6 @@ TraceWeakMaps(WeakMapTracer *trc);
extern JS_FRIEND_API(bool)
GCThingIsMarkedGray(void *thing);
/*
* Shadow declarations of JS internal structures, for access by inline access
* functions below. Do not use these structures in any other way. When adding
@ -763,7 +762,6 @@ class ObjectPtr
IncrementalReferenceBarrier(value);
value = NULL;
}
void finalize(JSContext *cx) { finalize(JS_GetRuntime(cx)); }
void init(JSObject *obj) { value = obj; }
@ -787,6 +785,17 @@ class ObjectPtr
extern JS_FRIEND_API(JSObject *)
GetTestingFunctions(JSContext *cx);
/*
* Helper to convert FreeOp to JSFreeOp when the definition of FreeOp is not
* available and the compiler does not know that FreeOp inherits from
* JSFreeOp.
*/
inline JSFreeOp *
CastToJSFreeOp(FreeOp *fop)
{
return reinterpret_cast<JSFreeOp *>(fop);
}
} /* namespace js */
#endif

Просмотреть файл

@ -274,7 +274,7 @@ Arena::staticAsserts()
template<typename T>
inline bool
Arena::finalize(JSContext *cx, AllocKind thingKind, size_t thingSize, bool background)
Arena::finalize(FreeOp *fop, AllocKind thingKind, size_t thingSize)
{
/* Enforce requirements on size of T. */
JS_ASSERT(thingSize % Cell::CellSize == 0);
@ -325,7 +325,7 @@ Arena::finalize(JSContext *cx, AllocKind thingKind, size_t thingSize, bool backg
} else {
if (!newFreeSpanStart)
newFreeSpanStart = thing;
t->finalize(cx, background);
t->finalize(fop);
JS_POISON(t, JS_FREE_PATTERN, thingSize);
}
}
@ -360,7 +360,7 @@ Arena::finalize(JSContext *cx, AllocKind thingKind, size_t thingSize, bool backg
template<typename T>
inline void
FinalizeTypedArenas(JSContext *cx, ArenaLists::ArenaList *al, AllocKind thingKind, bool background)
FinalizeTypedArenas(FreeOp *fop, ArenaLists::ArenaList *al, AllocKind thingKind)
{
/*
* Release empty arenas and move non-full arenas with some free things into
@ -372,7 +372,7 @@ FinalizeTypedArenas(JSContext *cx, ArenaLists::ArenaList *al, AllocKind thingKin
ArenaHeader **ap = &al->head;
size_t thingSize = Arena::thingSize(thingKind);
while (ArenaHeader *aheader = *ap) {
bool allClear = aheader->getArena()->finalize<T>(cx, thingKind, thingSize, background);
bool allClear = aheader->getArena()->finalize<T>(fop, thingKind, thingSize);
if (allClear) {
*ap = aheader->next;
aheader->chunk()->releaseArena(aheader);
@ -397,7 +397,7 @@ FinalizeTypedArenas(JSContext *cx, ArenaLists::ArenaList *al, AllocKind thingKin
* after the al->head.
*/
static void
FinalizeArenas(JSContext *cx, ArenaLists::ArenaList *al, AllocKind thingKind, bool background)
FinalizeArenas(FreeOp *fop, ArenaLists::ArenaList *al, AllocKind thingKind)
{
switch(thingKind) {
case FINALIZE_OBJECT0:
@ -412,33 +412,33 @@ FinalizeArenas(JSContext *cx, ArenaLists::ArenaList *al, AllocKind thingKind, bo
case FINALIZE_OBJECT12_BACKGROUND:
case FINALIZE_OBJECT16:
case FINALIZE_OBJECT16_BACKGROUND:
FinalizeTypedArenas<JSObject>(cx, al, thingKind, background);
FinalizeTypedArenas<JSObject>(fop, al, thingKind);
break;
case FINALIZE_SCRIPT:
FinalizeTypedArenas<JSScript>(cx, al, thingKind, background);
FinalizeTypedArenas<JSScript>(fop, al, thingKind);
break;
case FINALIZE_SHAPE:
FinalizeTypedArenas<Shape>(cx, al, thingKind, background);
FinalizeTypedArenas<Shape>(fop, al, thingKind);
break;
case FINALIZE_BASE_SHAPE:
FinalizeTypedArenas<BaseShape>(cx, al, thingKind, background);
FinalizeTypedArenas<BaseShape>(fop, al, thingKind);
break;
case FINALIZE_TYPE_OBJECT:
FinalizeTypedArenas<types::TypeObject>(cx, al, thingKind, background);
FinalizeTypedArenas<types::TypeObject>(fop, al, thingKind);
break;
#if JS_HAS_XML_SUPPORT
case FINALIZE_XML:
FinalizeTypedArenas<JSXML>(cx, al, thingKind, background);
FinalizeTypedArenas<JSXML>(fop, al, thingKind);
break;
#endif
case FINALIZE_STRING:
FinalizeTypedArenas<JSString>(cx, al, thingKind, background);
FinalizeTypedArenas<JSString>(fop, al, thingKind);
break;
case FINALIZE_SHORT_STRING:
FinalizeTypedArenas<JSShortString>(cx, al, thingKind, background);
FinalizeTypedArenas<JSShortString>(fop, al, thingKind);
break;
case FINALIZE_EXTERNAL_STRING:
FinalizeTypedArenas<JSExternalString>(cx, al, thingKind, background);
FinalizeTypedArenas<JSExternalString>(fop, al, thingKind);
break;
}
}
@ -1491,16 +1491,17 @@ ArenaLists::allocateFromArena(JSCompartment *comp, AllocKind thingKind)
}
void
ArenaLists::finalizeNow(JSContext *cx, AllocKind thingKind)
ArenaLists::finalizeNow(FreeOp *fop, AllocKind thingKind)
{
JS_ASSERT(!fop->onBackgroundThread());
#ifdef JS_THREADSAFE
JS_ASSERT(backgroundFinalizeState[thingKind] == BFS_DONE);
#endif
FinalizeArenas(cx, &arenaLists[thingKind], thingKind, false);
FinalizeArenas(fop, &arenaLists[thingKind], thingKind);
}
inline void
ArenaLists::finalizeLater(JSContext *cx, AllocKind thingKind)
ArenaLists::finalizeLater(FreeOp *fop, AllocKind thingKind)
{
JS_ASSERT(thingKind == FINALIZE_OBJECT0_BACKGROUND ||
thingKind == FINALIZE_OBJECT2_BACKGROUND ||
@ -1510,9 +1511,10 @@ ArenaLists::finalizeLater(JSContext *cx, AllocKind thingKind)
thingKind == FINALIZE_OBJECT16_BACKGROUND ||
thingKind == FINALIZE_SHORT_STRING ||
thingKind == FINALIZE_STRING);
JS_ASSERT(!fop->onBackgroundThread());
#ifdef JS_THREADSAFE
JS_ASSERT(!cx->runtime->gcHelperThread.sweeping());
JS_ASSERT(!fop->runtime()->gcHelperThread.sweeping());
ArenaList *al = &arenaLists[thingKind];
if (!al->head) {
@ -1528,37 +1530,38 @@ ArenaLists::finalizeLater(JSContext *cx, AllocKind thingKind)
JS_ASSERT(backgroundFinalizeState[thingKind] == BFS_DONE ||
backgroundFinalizeState[thingKind] == BFS_JUST_FINISHED);
if (cx->gcBackgroundFree) {
if (fop->shouldFreeLater()) {
/*
* To ensure the finalization order even during the background GC we
* must use infallibleAppend so arenas scheduled for background
* finalization would not be finalized now if the append fails.
*/
cx->gcBackgroundFree->finalizeVector.infallibleAppend(al->head);
fop->runtime()->gcHelperThread.finalizeVector.infallibleAppend(al->head);
al->clear();
backgroundFinalizeState[thingKind] = BFS_RUN;
} else {
FinalizeArenas(cx, al, thingKind, false);
FinalizeArenas(fop, al, thingKind);
backgroundFinalizeState[thingKind] = BFS_DONE;
}
#else /* !JS_THREADSAFE */
finalizeNow(cx, thingKind);
finalizeNow(fop, thingKind);
#endif
}
#ifdef JS_THREADSAFE
/*static*/ void
ArenaLists::backgroundFinalize(JSContext *cx, ArenaHeader *listHead)
ArenaLists::backgroundFinalize(FreeOp *fop, ArenaHeader *listHead)
{
JS_ASSERT(fop->onBackgroundThread());
JS_ASSERT(listHead);
AllocKind thingKind = listHead->getAllocKind();
JSCompartment *comp = listHead->compartment;
ArenaList finalized;
finalized.head = listHead;
FinalizeArenas(cx, &finalized, thingKind, true);
FinalizeArenas(fop, &finalized, thingKind);
/*
* After we finish the finalization al->cursor must point to the end of
@ -1568,7 +1571,7 @@ ArenaLists::backgroundFinalize(JSContext *cx, ArenaHeader *listHead)
ArenaLists *lists = &comp->arenas;
ArenaList *al = &lists->arenaLists[thingKind];
AutoLockGC lock(cx->runtime);
AutoLockGC lock(fop->runtime());
JS_ASSERT(lists->backgroundFinalizeState[thingKind] == BFS_RUN);
JS_ASSERT(!*al->cursor);
@ -1593,50 +1596,50 @@ ArenaLists::backgroundFinalize(JSContext *cx, ArenaHeader *listHead)
#endif /* JS_THREADSAFE */
void
ArenaLists::finalizeObjects(JSContext *cx)
ArenaLists::finalizeObjects(FreeOp *fop)
{
finalizeNow(cx, FINALIZE_OBJECT0);
finalizeNow(cx, FINALIZE_OBJECT2);
finalizeNow(cx, FINALIZE_OBJECT4);
finalizeNow(cx, FINALIZE_OBJECT8);
finalizeNow(cx, FINALIZE_OBJECT12);
finalizeNow(cx, FINALIZE_OBJECT16);
finalizeNow(fop, FINALIZE_OBJECT0);
finalizeNow(fop, FINALIZE_OBJECT2);
finalizeNow(fop, FINALIZE_OBJECT4);
finalizeNow(fop, FINALIZE_OBJECT8);
finalizeNow(fop, FINALIZE_OBJECT12);
finalizeNow(fop, FINALIZE_OBJECT16);
#ifdef JS_THREADSAFE
finalizeLater(cx, FINALIZE_OBJECT0_BACKGROUND);
finalizeLater(cx, FINALIZE_OBJECT2_BACKGROUND);
finalizeLater(cx, FINALIZE_OBJECT4_BACKGROUND);
finalizeLater(cx, FINALIZE_OBJECT8_BACKGROUND);
finalizeLater(cx, FINALIZE_OBJECT12_BACKGROUND);
finalizeLater(cx, FINALIZE_OBJECT16_BACKGROUND);
finalizeLater(fop, FINALIZE_OBJECT0_BACKGROUND);
finalizeLater(fop, FINALIZE_OBJECT2_BACKGROUND);
finalizeLater(fop, FINALIZE_OBJECT4_BACKGROUND);
finalizeLater(fop, FINALIZE_OBJECT8_BACKGROUND);
finalizeLater(fop, FINALIZE_OBJECT12_BACKGROUND);
finalizeLater(fop, FINALIZE_OBJECT16_BACKGROUND);
#endif
#if JS_HAS_XML_SUPPORT
finalizeNow(cx, FINALIZE_XML);
finalizeNow(fop, FINALIZE_XML);
#endif
}
void
ArenaLists::finalizeStrings(JSContext *cx)
ArenaLists::finalizeStrings(FreeOp *fop)
{
finalizeLater(cx, FINALIZE_SHORT_STRING);
finalizeLater(cx, FINALIZE_STRING);
finalizeLater(fop, FINALIZE_SHORT_STRING);
finalizeLater(fop, FINALIZE_STRING);
finalizeNow(cx, FINALIZE_EXTERNAL_STRING);
finalizeNow(fop, FINALIZE_EXTERNAL_STRING);
}
void
ArenaLists::finalizeShapes(JSContext *cx)
ArenaLists::finalizeShapes(FreeOp *fop)
{
finalizeNow(cx, FINALIZE_SHAPE);
finalizeNow(cx, FINALIZE_BASE_SHAPE);
finalizeNow(cx, FINALIZE_TYPE_OBJECT);
finalizeNow(fop, FINALIZE_SHAPE);
finalizeNow(fop, FINALIZE_BASE_SHAPE);
finalizeNow(fop, FINALIZE_TYPE_OBJECT);
}
void
ArenaLists::finalizeScripts(JSContext *cx)
ArenaLists::finalizeScripts(FreeOp *fop)
{
finalizeNow(cx, FINALIZE_SCRIPT);
finalizeNow(fop, FINALIZE_SCRIPT);
}
static void
@ -2771,8 +2774,9 @@ GCHelperThread::doSweep()
* We must finalize in the insert order, see comments in
* finalizeObjects.
*/
FreeOp fop(rt, false, true, cx);
for (ArenaHeader **i = finalizeVector.begin(); i != finalizeVector.end(); ++i)
ArenaLists::backgroundFinalize(cx, *i);
ArenaLists::backgroundFinalize(&fop, *i);
finalizeVector.resize(0);
if (freeCursor) {
@ -2827,9 +2831,9 @@ ReleaseObservedTypes(JSRuntime *rt)
}
static void
SweepCompartments(JSContext *cx, JSGCInvocationKind gckind)
SweepCompartments(FreeOp *fop, JSGCInvocationKind gckind)
{
JSRuntime *rt = cx->runtime;
JSRuntime *rt = fop->runtime();
JSCompartmentCallback callback = rt->compartmentCallback;
/* Skip the atomsCompartment. */
@ -2847,10 +2851,10 @@ SweepCompartments(JSContext *cx, JSGCInvocationKind gckind)
{
compartment->arenas.checkEmptyFreeLists();
if (callback)
JS_ALWAYS_TRUE(callback(cx, compartment, JSCOMPARTMENT_DESTROY));
JS_ALWAYS_TRUE(callback(fop->context, compartment, JSCOMPARTMENT_DESTROY));
if (compartment->principals)
JS_DropPrincipals(rt, compartment->principals);
cx->delete_(compartment);
fop->delete_(compartment);
continue;
}
*write++ = compartment;
@ -3112,10 +3116,11 @@ SweepPhase(JSContext *cx, JSGCInvocationKind gckind)
for (GCCompartmentsIter c(rt); !c.done(); c.next())
c->arenas.purge();
FreeOp fop(rt, !!cx->gcBackgroundFree, false, cx);
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_FINALIZE_START);
if (rt->gcFinalizeCallback)
rt->gcFinalizeCallback(cx, JSFINALIZE_START);
rt->gcFinalizeCallback(&fop, JSFINALIZE_START);
}
/* Finalize unreachable (key,value) pairs in all weak maps. */
@ -3127,14 +3132,14 @@ SweepPhase(JSContext *cx, JSGCInvocationKind gckind)
WatchpointMap::sweepAll(rt);
/* Detach unreachable debuggers and global objects from each other. */
Debugger::sweepAll(cx);
Debugger::sweepAll(&fop);
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_COMPARTMENTS);
bool releaseTypes = rt->gcIsFull && ReleaseObservedTypes(rt);
for (GCCompartmentsIter c(rt); !c.done(); c.next())
c->sweep(cx, releaseTypes);
c->sweep(&fop, releaseTypes);
}
{
@ -3145,29 +3150,29 @@ SweepPhase(JSContext *cx, JSGCInvocationKind gckind)
* finalizer can access the other things even if they will be freed.
*/
for (GCCompartmentsIter c(rt); !c.done(); c.next())
c->arenas.finalizeObjects(cx);
c->arenas.finalizeObjects(&fop);
}
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_STRING);
for (GCCompartmentsIter c(rt); !c.done(); c.next())
c->arenas.finalizeStrings(cx);
c->arenas.finalizeStrings(&fop);
}
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_SCRIPT);
for (GCCompartmentsIter c(rt); !c.done(); c.next())
c->arenas.finalizeScripts(cx);
c->arenas.finalizeScripts(&fop);
}
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_SHAPE);
for (GCCompartmentsIter c(rt); !c.done(); c.next())
c->arenas.finalizeShapes(cx);
c->arenas.finalizeShapes(&fop);
}
#ifdef DEBUG
PropertyTree::dumpShapes(cx);
PropertyTree::dumpShapes(rt);
#endif
{
@ -3187,7 +3192,7 @@ SweepPhase(JSContext *cx, JSGCInvocationKind gckind)
* sure we don't miss sweeping any compartments.
*/
if (rt->gcIsFull)
SweepCompartments(cx, gckind);
SweepCompartments(&fop, gckind);
#ifndef JS_THREADSAFE
/*
@ -3202,7 +3207,7 @@ SweepPhase(JSContext *cx, JSGCInvocationKind gckind)
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_FINALIZE_END);
if (rt->gcFinalizeCallback)
rt->gcFinalizeCallback(cx, JSFINALIZE_END);
rt->gcFinalizeCallback(&fop, JSFINALIZE_END);
}
for (CompartmentsIter c(rt); !c.done(); c.next())

Просмотреть файл

@ -592,7 +592,7 @@ struct Arena {
}
template <typename T>
bool finalize(JSContext *cx, AllocKind thingKind, size_t thingSize, bool background);
bool finalize(FreeOp *fop, AllocKind thingKind, size_t thingSize);
};
/* The chunk header (located at the end of the chunk to preserve arena alignment). */
@ -1251,18 +1251,18 @@ struct ArenaLists {
JS_ASSERT(freeLists[kind].isEmpty());
}
void finalizeObjects(JSContext *cx);
void finalizeStrings(JSContext *cx);
void finalizeShapes(JSContext *cx);
void finalizeScripts(JSContext *cx);
void finalizeObjects(FreeOp *fop);
void finalizeStrings(FreeOp *fop);
void finalizeShapes(FreeOp *fop);
void finalizeScripts(FreeOp *fop);
#ifdef JS_THREADSAFE
static void backgroundFinalize(JSContext *cx, ArenaHeader *listHead);
static void backgroundFinalize(FreeOp *fop, ArenaHeader *listHead);
#endif
private:
inline void finalizeNow(JSContext *cx, AllocKind thingKind);
inline void finalizeLater(JSContext *cx, AllocKind thingKind);
inline void finalizeNow(FreeOp *fop, AllocKind thingKind);
inline void finalizeLater(FreeOp *fop, AllocKind thingKind);
inline void *allocateFromArena(JSCompartment *comp, AllocKind thingKind);
};

Просмотреть файл

@ -5977,7 +5977,7 @@ TypeCompartment::sweep(JSContext *cx)
}
void
JSCompartment::sweepNewTypeObjectTable(JSContext *cx, TypeObjectSet &table)
JSCompartment::sweepNewTypeObjectTable(TypeObjectSet &table)
{
if (table.initialized()) {
for (TypeObjectSet::Enum e(table); !e.empty(); e.popFront()) {

Просмотреть файл

@ -875,7 +875,7 @@ struct TypeObject : gc::Cell
* object pending deletion is released when weak references are sweeped
* from all the compartment's type objects.
*/
void finalize(JSContext *cx, bool background) {}
void finalize(FreeOp *fop) {}
static inline void writeBarrierPre(TypeObject *type);
static inline void writeBarrierPost(TypeObject *type, void *addr);

Просмотреть файл

@ -84,7 +84,7 @@ using namespace mozilla;
using namespace js;
using namespace js::gc;
static void iterator_finalize(JSContext *cx, JSObject *obj);
static void iterator_finalize(FreeOp *fop, JSObject *obj);
static void iterator_trace(JSTracer *trc, JSObject *obj);
static JSObject *iterator_iterator(JSContext *cx, JSObject *obj, JSBool keysonly);
@ -151,14 +151,14 @@ NativeIterator::mark(JSTracer *trc)
}
static void
iterator_finalize(JSContext *cx, JSObject *obj)
iterator_finalize(FreeOp *fop, JSObject *obj)
{
JS_ASSERT(obj->isIterator());
NativeIterator *ni = obj->getNativeIterator();
if (ni) {
obj->setPrivate(NULL);
cx->free_(ni);
fop->free_(ni);
}
}
@ -1331,7 +1331,7 @@ Class js::StopIterationClass = {
#if JS_HAS_GENERATORS
static void
generator_finalize(JSContext *cx, JSObject *obj)
generator_finalize(FreeOp *fop, JSObject *obj)
{
JSGenerator *gen = (JSGenerator *) obj->getPrivate();
if (!gen)
@ -1344,7 +1344,7 @@ generator_finalize(JSContext *cx, JSObject *obj)
JS_ASSERT(gen->state == JSGEN_NEWBORN ||
gen->state == JSGEN_CLOSED ||
gen->state == JSGEN_OPEN);
cx->free_(gen);
fop->free_(gen);
}
static void

Просмотреть файл

@ -844,8 +844,8 @@ struct JSObject : public js::ObjectImpl
*/
inline bool isCallable();
inline void finish(JSContext *cx);
JS_ALWAYS_INLINE void finalize(JSContext *cx, bool background);
inline void finish(js::FreeOp *fop);
JS_ALWAYS_INLINE void finalize(js::FreeOp *fop);
inline bool hasProperty(JSContext *cx, jsid id, bool *foundp, unsigned flags = 0);

Просмотреть файл

@ -241,11 +241,11 @@ JSObject::deleteSpecial(JSContext *cx, js::SpecialId sid, js::Value *rval, bool
}
inline void
JSObject::finalize(JSContext *cx, bool background)
JSObject::finalize(js::FreeOp *fop)
{
js::Probes::finalizeObject(this);
if (!background) {
if (!fop->onBackgroundThread()) {
/*
* Finalize obj first, in case it needs map and slots. Objects with
* finalize hooks are not finalized in the background, as the class is
@ -253,10 +253,10 @@ JSObject::finalize(JSContext *cx, bool background)
*/
js::Class *clasp = getClass();
if (clasp->finalize)
clasp->finalize(cx, this);
clasp->finalize(fop, this);
}
finish(cx);
finish(fop);
}
inline JSObject *
@ -892,12 +892,12 @@ JSObject::createDenseArray(JSContext *cx, js::gc::AllocKind kind,
}
inline void
JSObject::finish(JSContext *cx)
JSObject::finish(js::FreeOp *fop)
{
if (hasDynamicSlots())
cx->free_(slots);
fop->free_(slots);
if (hasDynamicElements())
cx->free_(getElementsHeader());
fop->free_(getElementsHeader());
}
inline bool

Просмотреть файл

@ -220,14 +220,14 @@ PropertyTree::getChild(JSContext *cx, Shape *parent, uint32_t nfixed, const Stac
}
void
Shape::finalize(JSContext *cx, bool background)
Shape::finalize(FreeOp *fop)
{
if (!inDictionary()) {
if (parent && parent->isMarked())
parent->removeChild(this);
if (kids.isHash())
cx->delete_(kids.toHash());
fop->delete_(kids.toHash());
}
}
@ -337,7 +337,7 @@ Shape::dumpSubtree(JSContext *cx, int level, FILE *fp) const
}
void
js::PropertyTree::dumpShapes(JSContext *cx)
js::PropertyTree::dumpShapes(JSRuntime *rt)
{
static bool init = false;
static FILE *dumpfp = NULL;
@ -352,7 +352,6 @@ js::PropertyTree::dumpShapes(JSContext *cx)
if (!dumpfp)
return;
JSRuntime *rt = cx->runtime;
fprintf(dumpfp, "rt->gcNumber = %lu", (unsigned long)rt->gcNumber);
for (gc::GCCompartmentsIter c(rt); !c.done(); c.next()) {
@ -363,7 +362,7 @@ js::PropertyTree::dumpShapes(JSContext *cx)
HS &h = c->emptyShapes;
for (HS::Range r = h.all(); !r.empty(); r.popFront()) {
Shape *empty = r.front();
empty->dumpSubtree(cx, 0, dumpfp);
empty->dumpSubtree(rt, 0, dumpfp);
putc('\n', dumpfp);
}
*/

Просмотреть файл

@ -119,7 +119,7 @@ class PropertyTree
js::Shape *getChild(JSContext *cx, Shape *parent, uint32_t nfixed, const StackShape &child);
#ifdef DEBUG
static void dumpShapes(JSContext *cx);
static void dumpShapes(JSRuntime *rt);
static void meter(JSBasicStats *bs, js::Shape *node);
#endif
};

Просмотреть файл

@ -400,7 +400,7 @@ ProxyHandler::objectClassIs(JSObject *proxy, ESClassValue classValue, JSContext
}
void
ProxyHandler::finalize(JSContext *cx, JSObject *proxy)
ProxyHandler::finalize(JSFreeOp *fop, JSObject *proxy)
{
}
@ -1302,11 +1302,11 @@ proxy_Fix(JSContext *cx, JSObject *obj, bool *fixed, AutoIdVector *props)
}
static void
proxy_Finalize(JSContext *cx, JSObject *obj)
proxy_Finalize(FreeOp *fop, JSObject *obj)
{
JS_ASSERT(obj->isProxy());
if (!obj->getSlot(JSSLOT_PROXY_HANDLER).isUndefined())
GetProxyHandler(obj)->finalize(cx, obj);
GetProxyHandler(obj)->finalize(fop, obj);
}
static JSBool

Просмотреть файл

@ -87,7 +87,7 @@ class JS_FRIEND_API(ProxyHandler) {
virtual bool regexp_toShared(JSContext *cx, JSObject *proxy, RegExpGuard *g);
virtual bool defaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
virtual bool iteratorNext(JSContext *cx, JSObject *proxy, Value *vp);
virtual void finalize(JSContext *cx, JSObject *proxy);
virtual void finalize(JSFreeOp *fop, JSObject *proxy);
virtual void trace(JSTracer *trc, JSObject *proxy);
virtual bool getElementIfPresent(JSContext *cx, JSObject *obj, JSObject *receiver,
uint32_t index, Value *vp, bool *present);

Просмотреть файл

@ -324,6 +324,8 @@ enum XDRMode {
template <XDRMode mode>
class XDRState;
class FreeOp;
} /* namespace js */
namespace JSC {

Просмотреть файл

@ -1215,7 +1215,7 @@ BaseShape::getUnowned(JSContext *cx, const StackBaseShape &base)
}
void
JSCompartment::sweepBaseShapeTable(JSContext *cx)
JSCompartment::sweepBaseShapeTable()
{
if (baseShapes.initialized()) {
for (BaseShapeSet::Enum e(baseShapes); !e.empty(); e.popFront()) {
@ -1227,10 +1227,10 @@ JSCompartment::sweepBaseShapeTable(JSContext *cx)
}
void
BaseShape::finalize(JSContext *cx, bool background)
BaseShape::finalize(FreeOp *fop)
{
if (table_) {
cx->delete_(table_);
fop->delete_(table_);
table_ = NULL;
}
}
@ -1397,7 +1397,7 @@ EmptyShape::insertInitialShape(JSContext *cx, Shape *shape, JSObject *proto)
}
void
JSCompartment::sweepInitialShapeTable(JSContext *cx)
JSCompartment::sweepInitialShapeTable()
{
if (initialShapes.initialized()) {
for (InitialShapeSet::Enum e(initialShapes); !e.empty(); e.popFront()) {

Просмотреть файл

@ -328,7 +328,7 @@ class BaseShape : public js::gc::Cell
PropertyTable *table_;
public:
void finalize(JSContext *cx, bool background);
void finalize(FreeOp *fop);
inline BaseShape(Class *clasp, JSObject *parent, uint32_t objectFlags);
inline BaseShape(Class *clasp, JSObject *parent, uint32_t objectFlags,
@ -865,7 +865,7 @@ struct Shape : public js::gc::Cell
void dumpSubtree(JSContext *cx, int level, FILE *fp) const;
#endif
void finalize(JSContext *cx, bool background);
void finalize(FreeOp *fop);
void removeChild(js::Shape *child);
static inline void writeBarrierPre(const Shape *shape);

Просмотреть файл

@ -1392,27 +1392,27 @@ js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
}
void
JSScript::finalize(JSContext *cx, bool background)
JSScript::finalize(FreeOp *fop)
{
js_CallDestroyScriptHook(cx, this);
js_CallDestroyScriptHook(fop->context, this);
JS_ASSERT_IF(principals, originPrincipals);
if (principals)
JS_DropPrincipals(cx->runtime, principals);
JS_DropPrincipals(fop->runtime(), principals);
if (originPrincipals)
JS_DropPrincipals(cx->runtime, originPrincipals);
JS_DropPrincipals(fop->runtime(), originPrincipals);
if (types)
types->destroy();
#ifdef JS_METHODJIT
mjit::ReleaseScriptCode(cx, this);
mjit::ReleaseScriptCode(fop->context, this);
#endif
destroyScriptCounts(cx);
destroyScriptCounts(fop->context);
if (sourceMap)
cx->free_(sourceMap);
fop->free_(sourceMap);
if (debug) {
jsbytecode *end = code + length;
@ -1420,15 +1420,15 @@ JSScript::finalize(JSContext *cx, bool background)
if (BreakpointSite *site = getBreakpointSite(pc)) {
/* Breakpoints are swept before finalization. */
JS_ASSERT(site->firstBreakpoint() == NULL);
site->clearTrap(cx, NULL, NULL);
site->clearTrap(fop->context, NULL, NULL);
JS_ASSERT(getBreakpointSite(pc) == NULL);
}
}
cx->free_(debug);
fop->free_(debug);
}
JS_POISON(data, 0xdb, computedSizeOfData());
cx->free_(data);
fop->free_(data);
}
namespace js {

Просмотреть файл

@ -803,7 +803,7 @@ struct JSScript : public js::gc::Cell
uint32_t stepModeCount() { return debug ? (debug->stepMode & stepCountMask) : 0; }
#endif
void finalize(JSContext *cx, bool background);
void finalize(js::FreeOp *fop);
static inline void writeBarrierPre(JSScript *script);
static inline void writeBarrierPost(JSScript *script, void *addr);

Просмотреть файл

@ -335,16 +335,16 @@ WeakMap_mark(JSTracer *trc, JSObject *obj)
}
static void
WeakMap_finalize(JSContext *cx, JSObject *obj)
WeakMap_finalize(FreeOp *fop, JSObject *obj)
{
if (ObjectValueMap *map = GetObjectMap(obj)) {
map->check();
#ifdef DEBUG
map->~ObjectValueMap();
memset(static_cast<void *>(map), 0xdc, sizeof(*map));
cx->free_(map);
fop->free_(map);
#else
cx->delete_(map);
fop->delete_(map);
#endif
}
}

Просмотреть файл

@ -1175,13 +1175,13 @@ static const char xml_namespace_str[] = "http://www.w3.org/XML/1998/namespace";
static const char xmlns_namespace_str[] = "http://www.w3.org/2000/xmlns/";
void
JSXML::finalize(JSContext *cx, bool builtin)
JSXML::finalize(FreeOp *fop)
{
if (JSXML_HAS_KIDS(this)) {
xml_kids.finish(cx);
xml_kids.finish(fop->context);
if (xml_class == JSXML_CLASS_ELEMENT) {
xml_namespaces.finish(cx);
xml_attrs.finish(cx);
xml_namespaces.finish(fop->context);
xml_attrs.finish(fop->context);
}
}
#ifdef DEBUG_notme
@ -7901,13 +7901,13 @@ xmlfilter_trace(JSTracer *trc, JSObject *obj)
}
static void
xmlfilter_finalize(JSContext *cx, JSObject *obj)
xmlfilter_finalize(FreeOp *fop, JSObject *obj)
{
JSXMLFilter *filter = (JSXMLFilter *) obj->getPrivate();
if (!filter)
return;
cx->delete_(filter);
fop->delete_(filter);
}
Class js_XMLFilterClass = {

Просмотреть файл

@ -203,7 +203,7 @@ struct JSXML : js::gc::Cell {
void *pad;
#endif
void finalize(JSContext *cx, bool background);
void finalize(js::FreeOp *fop);
static void writeBarrierPre(JSXML *xml);
static void writeBarrierPost(JSXML *xml, void *addr);

Просмотреть файл

@ -184,7 +184,7 @@ static const struct pm_const {
#undef CONSTANT
static JSBool pm_construct(JSContext* cx, unsigned argc, jsval* vp);
static void pm_finalize(JSContext* cx, JSObject* obj);
static void pm_finalize(JSFreeOp* fop, JSObject* obj);
static JSClass pm_class = {
"PerfMeasurement", JSCLASS_HAS_PRIVATE,
@ -220,9 +220,9 @@ pm_construct(JSContext* cx, unsigned argc, jsval* vp)
}
static void
pm_finalize(JSContext* cx, JSObject* obj)
pm_finalize(JSFreeOp* fop, JSObject* obj)
{
cx->delete_((PerfMeasurement*) JS_GetPrivate(obj));
js::FreeOp::get(fop)->delete_(static_cast<PerfMeasurement*>(JS_GetPrivate(obj)));
}
// Helpers (declared above)

Просмотреть файл

@ -4087,14 +4087,14 @@ its_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
}
static void
its_finalize(JSContext *cx, JSObject *obj)
its_finalize(JSFreeOp *fop, JSObject *obj)
{
jsval *rootedVal;
if (its_noisy)
fprintf(gOutFile, "finalizing it\n");
rootedVal = (jsval *) JS_GetPrivate(obj);
if (rootedVal) {
JS_RemoveValueRoot(cx, rootedVal);
JS_RemoveValueRoot(fop->context, rootedVal);
JS_SetPrivate(obj, NULL);
delete rootedVal;
}

Просмотреть файл

@ -576,7 +576,7 @@ class ThreadPool
}
static void jsFinalize(JSContext *cx, JSObject *obj) {
static void jsFinalize(JSFreeOp *fop, JSObject *obj) {
if (ThreadPool *tp = unwrap(obj))
delete tp;
}
@ -712,7 +712,7 @@ class Worker MOZ_FINAL : public WorkerParent
}
}
static void jsFinalize(JSContext *cx, JSObject *obj) {
static void jsFinalize(JSFreeOp *fop, JSObject *obj) {
JS_ASSERT(JS_GetClass(obj) == &jsWorkerClass);
if (Worker *w = (Worker *) JS_GetPrivate(obj))
delete w;

Просмотреть файл

@ -496,9 +496,9 @@ strictargs_enumerate(JSContext *cx, JSObject *obj)
}
static void
args_finalize(JSContext *cx, JSObject *obj)
args_finalize(FreeOp *fop, JSObject *obj)
{
cx->free_(reinterpret_cast<void *>(obj->asArguments().data()));
fop->free_(reinterpret_cast<void *>(obj->asArguments().data()));
}
static void

Просмотреть файл

@ -1462,9 +1462,9 @@ Debugger::trace(JSTracer *trc)
}
void
Debugger::sweepAll(JSContext *cx)
Debugger::sweepAll(FreeOp *fop)
{
JSRuntime *rt = cx->runtime;
JSRuntime *rt = fop->runtime();
for (JSCList *p = &rt->debuggerList; (p = JS_NEXT_LINK(p)) != &rt->debuggerList;) {
Debugger *dbg = Debugger::fromLinks(p);
@ -1476,7 +1476,7 @@ Debugger::sweepAll(JSContext *cx)
* objects, this must be done before finalize time.
*/
for (GlobalObjectSet::Enum e(dbg->debuggees); !e.empty(); e.popFront())
dbg->removeDebuggeeGlobal(cx, e.front(), NULL, &e);
dbg->removeDebuggeeGlobal(fop->context, e.front(), NULL, &e);
}
}
@ -1487,7 +1487,7 @@ Debugger::sweepAll(JSContext *cx)
for (GlobalObjectSet::Enum e(debuggees); !e.empty(); e.popFront()) {
GlobalObject *global = e.front();
if (IsAboutToBeFinalized(global))
detachAllDebuggersFromGlobal(cx, global, &e);
detachAllDebuggersFromGlobal(fop->context, global, &e);
}
}
}
@ -1503,13 +1503,13 @@ Debugger::detachAllDebuggersFromGlobal(JSContext *cx, GlobalObject *global,
}
void
Debugger::finalize(JSContext *cx, JSObject *obj)
Debugger::finalize(FreeOp *fop, JSObject *obj)
{
Debugger *dbg = fromJSObject(obj);
if (!dbg)
return;
JS_ASSERT(dbg->debuggees.empty());
cx->delete_(dbg);
fop->delete_(dbg);
}
Class Debugger::jsclass = {

Просмотреть файл

@ -174,7 +174,7 @@ class Debugger {
static void traceObject(JSTracer *trc, JSObject *obj);
void trace(JSTracer *trc);
static void finalize(JSContext *cx, JSObject *obj);
static void finalize(FreeOp *fop, JSObject *obj);
void markKeysInCompartment(JSTracer *tracer);
static Class jsclass;
@ -263,7 +263,7 @@ class Debugger {
*/
static void markCrossCompartmentDebuggerObjectReferents(JSTracer *tracer);
static bool markAllIteratively(GCMarker *trc);
static void sweepAll(JSContext *cx);
static void sweepAll(FreeOp *fop);
static void detachAllDebuggersFromGlobal(JSContext *cx, GlobalObject *global,
GlobalObjectSet::Enum *compartmentEnum);

Просмотреть файл

@ -453,9 +453,9 @@ DefinePropertiesAndBrand(JSContext *cx, JSObject *obj, JSPropertySpec *ps, JSFun
}
void
GlobalDebuggees_finalize(JSContext *cx, JSObject *obj)
GlobalDebuggees_finalize(FreeOp *fop, JSObject *obj)
{
cx->delete_((GlobalObject::DebuggerVector *) obj->getPrivate());
fop->delete_((GlobalObject::DebuggerVector *) obj->getPrivate());
}
static Class

Просмотреть файл

@ -54,10 +54,10 @@ using namespace js;
*/
static void
resc_finalize(JSContext *cx, JSObject *obj)
resc_finalize(FreeOp *fop, JSObject *obj)
{
RegExpStatics *res = static_cast<RegExpStatics *>(obj->getPrivate());
cx->delete_(res);
fop->delete_(res);
}
static void

Просмотреть файл

@ -388,19 +388,19 @@ js::StaticStrings::lookup(const jschar *chars, size_t length)
}
JS_ALWAYS_INLINE void
JSString::finalize(JSContext *cx, bool background)
JSString::finalize(js::FreeOp *fop)
{
/* Shorts are in a different arena. */
JS_ASSERT(!isShort());
if (isFlat())
asFlat().finalize(cx->runtime);
asFlat().finalize(fop);
else
JS_ASSERT(isDependent() || isRope());
}
inline void
JSFlatString::finalize(JSRuntime *rt)
JSFlatString::finalize(js::FreeOp *fop)
{
JS_ASSERT(!isShort());
@ -409,33 +409,27 @@ JSFlatString::finalize(JSRuntime *rt)
* beginning of inlineStorage. E.g., this is not the case for short strings.
*/
if (chars() != d.inlineStorage)
rt->free_(const_cast<jschar *>(chars()));
fop->free_(const_cast<jschar *>(chars()));
}
inline void
JSShortString::finalize(JSContext *cx, bool background)
JSShortString::finalize(js::FreeOp *fop)
{
JS_ASSERT(JSString::isShort());
}
inline void
JSAtom::finalize(JSRuntime *rt)
JSAtom::finalize(js::FreeOp *fop)
{
JS_ASSERT(JSString::isAtom());
if (getAllocKind() == js::gc::FINALIZE_STRING)
JSFlatString::finalize(rt);
JSFlatString::finalize(fop);
else
JS_ASSERT(getAllocKind() == js::gc::FINALIZE_SHORT_STRING);
}
inline void
JSExternalString::finalize(JSContext *cx, bool background)
{
finalize();
}
inline void
JSExternalString::finalize()
JSExternalString::finalize(js::FreeOp *fop)
{
const JSStringFinalizer *fin = externalFinalizer();
fin->finalize(fin, const_cast<jschar *>(chars()));

Просмотреть файл

@ -391,7 +391,7 @@ class JSString : public js::gc::Cell
/* Only called by the GC for strings with the FINALIZE_STRING kind. */
inline void finalize(JSContext *cx, bool background);
inline void finalize(js::FreeOp *fop);
/* Gets the number of bytes that the chars take on the heap. */
@ -529,9 +529,7 @@ class JSFlatString : public JSLinearString
*/
inline js::PropertyName *toPropertyName(JSContext *cx);
/* Only called by the GC for strings with the FINALIZE_STRING kind. */
inline void finalize(JSRuntime *rt);
inline void finalize(js::FreeOp *fop);
};
JS_STATIC_ASSERT(sizeof(JSFlatString) == sizeof(JSString));
@ -626,7 +624,7 @@ class JSShortString : public JSInlineString
/* Only called by the GC for strings with the FINALIZE_EXTERNAL_STRING kind. */
JS_ALWAYS_INLINE void finalize(JSContext *cx, bool background);
JS_ALWAYS_INLINE void finalize(js::FreeOp *fop);
};
JS_STATIC_ASSERT(sizeof(JSShortString) == 2 * sizeof(JSString));
@ -650,8 +648,7 @@ class JSExternalString : public JSFixedString
/* Only called by the GC for strings with the FINALIZE_EXTERNAL_STRING kind. */
inline void finalize(JSContext *cx, bool background);
inline void finalize();
inline void finalize(js::FreeOp *fop);
};
JS_STATIC_ASSERT(sizeof(JSExternalString) == sizeof(JSString));
@ -666,7 +663,7 @@ class JSAtom : public JSFixedString
/* Returns the PropertyName for this. isIndex() must be false. */
inline js::PropertyName *asPropertyName();
inline void finalize(JSRuntime *rt);
inline void finalize(js::FreeOp *fop);
#ifdef DEBUG
void dump();

Просмотреть файл

@ -161,7 +161,7 @@ interface nsIXPCScriptable : nsISupports
in PRUint32 type, in JSValPtr vp);
void finalize(in nsIXPConnectWrappedNative wrapper,
in JSContextPtr cx, in JSObjectPtr obj);
in JSFreeOpPtr fop, in JSObjectPtr obj);
boolean checkAccess(in nsIXPConnectWrappedNative wrapper,
in JSContextPtr cx, in JSObjectPtr obj, in jsid id,

Просмотреть файл

@ -67,6 +67,7 @@ class nsWrapperCache;
[ptr] native JSContextPtr(JSContext);
[ptr] native JSClassPtr(JSClass);
[ptr] native JSFreeOpPtr(JSFreeOp);
[ptr] native JSObjectPtr(JSObject);
[ptr] native JSValPtr(jsval);
[ptr] native JSValConstPtr(const jsval);

Просмотреть файл

@ -181,7 +181,7 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::Convert(nsIXPConnectWrappedNative *wrapper, JSC
#endif
#ifndef XPC_MAP_WANT_FINALIZE
NS_IMETHODIMP XPC_MAP_CLASSNAME::Finalize(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj)
NS_IMETHODIMP XPC_MAP_CLASSNAME::Finalize(nsIXPConnectWrappedNative *wrapper, JSFreeOp * fop, JSObject * obj)
{NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
#endif

Просмотреть файл

@ -2888,7 +2888,7 @@ sandbox_resolve(JSContext *cx, JSObject *obj, jsid id)
}
static void
sandbox_finalize(JSContext *cx, JSObject *obj)
sandbox_finalize(JSFreeOp *fop, JSObject *obj)
{
nsIScriptObjectPrincipal *sop =
(nsIScriptObjectPrincipal *)xpc_GetJSPrivate(obj);

Просмотреть файл

@ -703,7 +703,7 @@ XPCJSRuntime::GCCallback(JSRuntime *rt, JSGCStatus status)
}
/* static */ void
XPCJSRuntime::FinalizeCallback(JSContext *cx, JSFinalizeStatus status)
XPCJSRuntime::FinalizeCallback(JSFreeOp *fop, JSFinalizeStatus status)
{
XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
if (!self)
@ -734,7 +734,7 @@ XPCJSRuntime::FinalizeCallback(JSContext *cx, JSFinalizeStatus status)
Enumerate(WrappedJSDyingJSObjectFinder, dyingWrappedJSArray);
// Find dying scopes.
XPCWrappedNativeScope::FinishedMarkPhaseOfGC(cx, self);
XPCWrappedNativeScope::StartFinalizationPhaseOfGC(fop, self);
// Sweep compartments.
self->GetCompartmentMap().EnumerateRead((XPCCompartmentMap::EnumReadFunction)
@ -850,7 +850,7 @@ XPCJSRuntime::FinalizeCallback(JSContext *cx, JSFinalizeStatus status)
#endif
// Sweep scopes needing cleanup
XPCWrappedNativeScope::FinishedFinalizationPhaseOfGC(cx);
XPCWrappedNativeScope::FinishedFinalizationPhaseOfGC();
// Now we are going to recycle any unused WrappedNativeTearoffs.
// We do this by iterating all the live callcontexts (on all

Просмотреть файл

@ -165,7 +165,7 @@ PropertyOpForwarder(JSContext *cx, unsigned argc, jsval *vp)
}
static void
PointerFinalize(JSContext *cx, JSObject *obj)
PointerFinalize(JSFreeOp *fop, JSObject *obj)
{
JSPropertyOp *popp = static_cast<JSPropertyOp *>(JS_GetPrivate(obj));
delete popp;

Просмотреть файл

@ -167,7 +167,7 @@ SafeGlobalResolve(JSContext *cx, JSObject *obj, jsid id)
}
static void
SafeFinalize(JSContext* cx, JSObject* obj)
SafeFinalize(JSFreeOp *fop, JSObject* obj)
{
nsIScriptObjectPrincipal* sop =
static_cast<nsIScriptObjectPrincipal*>(xpc_GetJSPrivate(obj));

Просмотреть файл

@ -616,7 +616,7 @@ static PRUint32 sFinalizedSlimWrappers;
#endif
static void
XPC_WN_NoHelper_Finalize(JSContext *cx, JSObject *obj)
XPC_WN_NoHelper_Finalize(js::FreeOp *fop, JSObject *obj)
{
js::Class* clazz = js::GetObjectClass(obj);
if (clazz->flags & JSCLASS_DOM_GLOBAL) {
@ -1046,7 +1046,7 @@ XPC_WN_Helper_HasInstance(JSContext *cx, JSObject *obj, const jsval *valp, JSBoo
}
static void
XPC_WN_Helper_Finalize(JSContext *cx, JSObject *obj)
XPC_WN_Helper_Finalize(js::FreeOp *fop, JSObject *obj)
{
js::Class* clazz = js::GetObjectClass(obj);
if (clazz->flags & JSCLASS_DOM_GLOBAL) {
@ -1067,7 +1067,8 @@ XPC_WN_Helper_Finalize(JSContext *cx, JSObject *obj)
XPCWrappedNative* wrapper = (XPCWrappedNative*)p;
if (!wrapper)
return;
wrapper->GetScriptableCallback()->Finalize(wrapper, cx, obj);
wrapper->GetScriptableCallback()->Finalize(wrapper, js::CastToJSFreeOp(fop), obj);
wrapper->FlatJSObjectFinalized();
}
@ -1640,12 +1641,12 @@ XPC_WN_Shared_Proto_Enumerate(JSContext *cx, JSObject *obj)
}
static void
XPC_WN_Shared_Proto_Finalize(JSContext *cx, JSObject *obj)
XPC_WN_Shared_Proto_Finalize(js::FreeOp *fop, JSObject *obj)
{
// This can be null if xpc shutdown has already happened
XPCWrappedNativeProto* p = (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
if (p)
p->JSProtoObjectFinalized(cx, obj);
p->JSProtoObjectFinalized(fop, obj);
}
static void
@ -1899,7 +1900,7 @@ XPC_WN_TearOff_Resolve(JSContext *cx, JSObject *obj, jsid id)
}
static void
XPC_WN_TearOff_Finalize(JSContext *cx, JSObject *obj)
XPC_WN_TearOff_Finalize(js::FreeOp *fop, JSObject *obj)
{
XPCWrappedNativeTearOff* p = (XPCWrappedNativeTearOff*)
xpc_GetJSPrivate(obj);

Просмотреть файл

@ -163,7 +163,7 @@ XPCWrappedNativeProto::CallPostCreatePrototype(XPCCallContext& ccx)
}
void
XPCWrappedNativeProto::JSProtoObjectFinalized(JSContext *cx, JSObject *obj)
XPCWrappedNativeProto::JSProtoObjectFinalized(js::FreeOp *fop, JSObject *obj)
{
NS_ASSERTION(obj == mJSProtoObject, "huh?");
@ -178,7 +178,7 @@ XPCWrappedNativeProto::JSProtoObjectFinalized(JSContext *cx, JSObject *obj)
GetRuntime()->GetDetachedWrappedNativeProtoMap()->Remove(this);
GetRuntime()->GetDyingWrappedNativeProtoMap()->Add(this);
mJSProtoObject.finalize(cx);
mJSProtoObject.finalize(js::CastToJSFreeOp(fop)->runtime());
}
void

Просмотреть файл

@ -396,7 +396,7 @@ XPCWrappedNativeScope::SuspectAllWrappers(XPCJSRuntime* rt,
// static
void
XPCWrappedNativeScope::FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt)
XPCWrappedNativeScope::StartFinalizationPhaseOfGC(JSFreeOp *fop, XPCJSRuntime* rt)
{
// FIXME The lock may not be necessary since we are inside JSGC_MARK_END
// callback and GX serializes access to JS runtime. See bug 380139.
@ -416,7 +416,7 @@ XPCWrappedNativeScope::FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt)
if (cur->mGlobalJSObject &&
JS_IsAboutToBeFinalized(cur->mGlobalJSObject)) {
cur->mGlobalJSObject.finalize(cx);
cur->mGlobalJSObject.finalize(fop->runtime());
cur->mScriptObjectPrincipal = nsnull;
if (cur->GetCachedDOMPrototypes().IsInitialized())
cur->GetCachedDOMPrototypes().Clear();
@ -431,7 +431,7 @@ XPCWrappedNativeScope::FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt)
} else {
if (cur->mPrototypeJSObject &&
JS_IsAboutToBeFinalized(cur->mPrototypeJSObject)) {
cur->mPrototypeJSObject.finalize(cx);
cur->mPrototypeJSObject.finalize(fop->runtime());
}
if (cur->mPrototypeNoHelper &&
JS_IsAboutToBeFinalized(cur->mPrototypeNoHelper)) {
@ -446,7 +446,7 @@ XPCWrappedNativeScope::FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt)
// static
void
XPCWrappedNativeScope::FinishedFinalizationPhaseOfGC(JSContext* cx)
XPCWrappedNativeScope::FinishedFinalizationPhaseOfGC()
{
XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();

Просмотреть файл

@ -1231,7 +1231,7 @@ ListBase<LC>::obj_toString(JSContext *cx, JSObject *proxy)
template<class LC>
void
ListBase<LC>::finalize(JSContext *cx, JSObject *proxy)
ListBase<LC>::finalize(JSFreeOp *fop, JSObject *proxy)
{
ListType *list = getListObject(proxy);
nsWrapperCache *cache;

Просмотреть файл

@ -228,7 +228,7 @@ public:
/* Spidermonkey extensions. */
bool hasInstance(JSContext *cx, JSObject *proxy, const JS::Value *vp, bool *bp);
JSString *obj_toString(JSContext *cx, JSObject *proxy);
void finalize(JSContext *cx, JSObject *proxy);
void finalize(JSFreeOp *fop, JSObject *proxy);
static bool proxyHandlerIsList(js::ProxyHandler *handler) {
return handler == &instance;

Просмотреть файл

@ -747,7 +747,7 @@ public:
void UnmarkSkippableJSHolders();
static void GCCallback(JSRuntime *rt, JSGCStatus status);
static void FinalizeCallback(JSContext *cx, JSFinalizeStatus status);
static void FinalizeCallback(JSFreeOp *fop, JSFinalizeStatus status);
inline void AddVariantRoot(XPCTraceableVariant* variant);
inline void AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS);
@ -1562,10 +1562,10 @@ public:
SuspectAllWrappers(XPCJSRuntime* rt, nsCycleCollectionTraversalCallback &cb);
static void
FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt);
StartFinalizationPhaseOfGC(JSFreeOp *fop, XPCJSRuntime* rt);
static void
FinishedFinalizationPhaseOfGC(JSContext* cx);
FinishedFinalizationPhaseOfGC();
static void
MarkAllWrappedNativesAndProtos();
@ -2308,7 +2308,7 @@ public:
{NS_ASSERTION(!mScriptableInfo, "leak here!"); mScriptableInfo = si;}
bool CallPostCreatePrototype(XPCCallContext& ccx);
void JSProtoObjectFinalized(JSContext *cx, JSObject *obj);
void JSProtoObjectFinalized(js::FreeOp *fop, JSObject *obj);
void SystemIsBeingShutDown();