Backed out changeset bea8bb703913 (bug 650161) for rooting hazzard failures

This commit is contained in:
Ed Morley 2014-09-17 17:34:20 +01:00
parent d6c3849d1b
commit cea5a26d63
12 changed files with 57 additions and 212 deletions

View File

@ -668,12 +668,10 @@ public:
unsigned flags,
JS::MutableHandle<JS::Value> vp) const MOZ_OVERRIDE;
static void ObjectMoved(JSObject *obj, const JSObject *old);
static const nsOuterWindowProxy singleton;
protected:
static nsGlobalWindow* GetWindow(JSObject *proxy)
nsGlobalWindow* GetWindow(JSObject *proxy) const
{
return nsGlobalWindow::FromSupports(
static_cast<nsISupports*>(js::GetProxyExtra(proxy, 0).toPrivate()));
@ -705,8 +703,7 @@ const js::Class OuterWindowProxyClass =
nullptr, /* outerObject */
js::proxy_innerObject,
nullptr, /* iteratorObject */
false, /* isWrappedNative */
nsOuterWindowProxy::ObjectMoved
false /* isWrappedNative */
));
bool
@ -1026,15 +1023,6 @@ nsOuterWindowProxy::unwatch(JSContext *cx, JS::Handle<JSObject*> proxy,
return js::UnwatchGuts(cx, proxy, id);
}
void
nsOuterWindowProxy::ObjectMoved(JSObject *obj, const JSObject *old)
{
nsGlobalWindow* global = GetWindow(obj);
if (global) {
global->UpdateWrapper(obj, old);
}
}
const nsOuterWindowProxy
nsOuterWindowProxy::singleton;

View File

@ -8,7 +8,6 @@
#include "nsCycleCollectionParticipant.h"
#include "mozilla/Assertions.h"
#include "js/Class.h"
#include "js/Id.h" // must come before js/RootingAPI.h
#include "js/Value.h" // must come before js/RootingAPI.h
#include "js/RootingAPI.h"
@ -45,14 +44,6 @@ class XPCWrappedNativeScope;
*
* The finalizer for the wrapper clears the cache.
*
* A compacting GC can move the wrapper object. Pointers to moved objects are
* usually found and updated by tracing the heap, however non-preserved wrappers
* are weak references and are not traced, so another approach is
* necessary. Instead a class hook (objectMovedOp) is provided that is called
* when an object is moved and is responsible for ensuring pointers are
* updated. It does this by calling UpdateWrapper() on the wrapper
* cache. SetWrapper() asserts that the hook is implemented for any wrapper set.
*
* A number of the methods are implemented in nsWrapperCacheInlines.h because we
* have to include some JS headers that don't play nicely with the rest of the
* codebase. Include nsWrapperCacheInlines.h if you need to call those methods.
@ -98,8 +89,6 @@ public:
{
MOZ_ASSERT(!PreservingWrapper(), "Clearing a preserved wrapper!");
MOZ_ASSERT(aWrapper, "Use ClearWrapper!");
MOZ_ASSERT(js::HasObjectMovedOp(aWrapper),
"Object has not provided the hook to update the wrapper if it is moved");
SetWrapperJSObject(aWrapper);
}
@ -115,18 +104,6 @@ public:
SetWrapperJSObject(nullptr);
}
/**
* Update the wrapper if the object it contains is moved.
*
* This method must be called from the objectMovedOp class extension hook for
* any wrapper cached object.
*/
void UpdateWrapper(JSObject* aNewObject, const JSObject* aOldObject)
{
MOZ_ASSERT(mWrapper == aOldObject);
mWrapper = aNewObject;
}
bool PreservingWrapper()
{
return HasWrapperFlag(WRAPPER_BIT_PRESERVED);
@ -185,7 +162,7 @@ public:
}
}
/*
/*
* The following methods for getting and manipulating flags allow the unused
* bits of mFlags to be used by derived classes.
*/

View File

@ -1213,22 +1213,6 @@ ClearWrapper(T* p, void*)
ClearWrapper(p, cache);
}
template<class T>
inline void
UpdateWrapper(T* p, nsWrapperCache* cache, JSObject* obj, const JSObject* old)
{
cache->UpdateWrapper(obj, old);
}
template<class T>
inline void
UpdateWrapper(T* p, void*, JSObject* obj, const JSObject* old)
{
nsWrapperCache* cache;
CallQueryInterface(p, &cache);
UpdateWrapper(p, cache, obj, old);
}
// Attempt to preserve the wrapper, if any, for a Paris DOM bindings object.
// Return true if we successfully preserved the wrapper, or there is no wrapper
// to preserve. In the latter case we don't need to preserve the wrapper, because

View File

@ -17,7 +17,6 @@ AUTOGENERATED_WARNING_COMMENT = \
"/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n"
ADDPROPERTY_HOOK_NAME = '_addProperty'
FINALIZE_HOOK_NAME = '_finalize'
OBJECT_MOVED_HOOK_NAME = '_objectMoved'
CONSTRUCT_HOOK_NAME = '_constructor'
LEGACYCALLER_HOOK_NAME = '_legacycaller'
HASINSTANCE_HOOK_NAME = '_hasInstance'
@ -365,61 +364,48 @@ class CGDOMJSClass(CGThing):
def define(self):
traceHook = 'nullptr'
callHook = LEGACYCALLER_HOOK_NAME if self.descriptor.operations["LegacyCaller"] else 'nullptr'
objectMovedHook = OBJECT_MOVED_HOOK_NAME if self.descriptor.wrapperCache else 'nullptr'
slotCount = INSTANCE_RESERVED_SLOTS + self.descriptor.interface.totalMembersInSlots
classFlags = "JSCLASS_IS_DOMJSCLASS | "
classExtensionAndObjectOps = fill(
"""
{
nullptr, /* outerObject */
nullptr, /* innerObject */
nullptr, /* iteratorObject */
false, /* isWrappedNative */
nullptr, /* weakmapKeyDelegateOp */
${objectMoved} /* objectMovedOp */
},
JS_NULL_OBJECT_OPS
""",
objectMoved=objectMovedHook)
classExtensionAndObjectOps = """\
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
"""
if self.descriptor.isGlobal():
classFlags += "JSCLASS_DOM_GLOBAL | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(DOM_GLOBAL_SLOTS) | JSCLASS_IMPLEMENTS_BARRIERS"
traceHook = "JS_GlobalObjectTraceHook"
reservedSlots = "JSCLASS_GLOBAL_APPLICATION_SLOTS"
if not self.descriptor.workers:
classExtensionAndObjectOps = fill(
"""
{
nsGlobalWindow::OuterObject, /* outerObject */
nullptr, /* innerObject */
nullptr, /* iteratorObject */
false, /* isWrappedNative */
nullptr, /* weakmapKeyDelegateOp */
${objectMoved} /* objectMovedOp */
},
{
nullptr, /* lookupGeneric */
nullptr, /* lookupProperty */
nullptr, /* lookupElement */
nullptr, /* defineGeneric */
nullptr, /* defineProperty */
nullptr, /* defineElement */
nullptr, /* getGeneric */
nullptr, /* getProperty */
nullptr, /* getElement */
nullptr, /* setGeneric */
nullptr, /* setProperty */
nullptr, /* setElement */
nullptr, /* getGenericAttributes */
nullptr, /* setGenericAttributes */
nullptr, /* deleteGeneric */
nullptr, /* watch */
nullptr, /* unwatch */
nullptr, /* slice */
nullptr, /* enumerate */
JS_ObjectToOuterObject /* thisObject */
}
""",
objectMoved=objectMovedHook)
classExtensionAndObjectOps = """\
{
nsGlobalWindow::OuterObject, /* outerObject */
nullptr, /* innerObject */
nullptr, /* iteratorObject */
false, /* isWrappedNative */
nullptr /* weakmapKeyDelegateOp */
},
{
nullptr, /* lookupGeneric */
nullptr, /* lookupProperty */
nullptr, /* lookupElement */
nullptr, /* defineGeneric */
nullptr, /* defineProperty */
nullptr, /* defineElement */
nullptr, /* getGeneric */
nullptr, /* getProperty */
nullptr, /* getElement */
nullptr, /* setGeneric */
nullptr, /* setProperty */
nullptr, /* setElement */
nullptr, /* getGenericAttributes */
nullptr, /* setGenericAttributes */
nullptr, /* deleteGeneric */
nullptr, /* watch */
nullptr, /* unwatch */
nullptr, /* slice */
nullptr, /* enumerate */
JS_ObjectToOuterObject /* thisObject */
}
"""
else:
classFlags += "JSCLASS_HAS_RESERVED_SLOTS(%d)" % slotCount
reservedSlots = slotCount
@ -495,24 +481,17 @@ class CGDOMProxyJSClass(CGThing):
# HTMLAllCollection. So just hardcode it here.
if self.descriptor.interface.identifier.name == "HTMLAllCollection":
flags.append("JSCLASS_EMULATES_UNDEFINED")
objectMovedHook = OBJECT_MOVED_HOOK_NAME if self.descriptor.wrapperCache else 'nullptr'
return fill(
"""
static const DOMJSClass Class = {
PROXY_CLASS_WITH_EXT("${name}",
0, /* extra slots */
${flags},
PROXY_MAKE_EXT(nullptr, /* outerObject */
nullptr, /* innerObject */
nullptr, /* iteratorObject */
false, /* isWrappedNative */
${objectMoved})),
PROXY_CLASS_DEF("${name}",
0, /* extra slots */
${flags}),
$*{descriptor}
};
""",
name=self.descriptor.interface.identifier.name,
flags=" | ".join(flags),
objectMoved=objectMovedHook,
descriptor=DOMClass(self.descriptor))
@ -1570,28 +1549,11 @@ class CGClassFinalizeHook(CGAbstractClassHook):
return finalizeHook(self.descriptor, self.name, self.args[0].name).define()
class CGClassObjectMovedHook(CGAbstractClassHook):
"""
A hook for objectMovedOp, used to update the wrapper cache when an object it
is holding moves.
"""
def __init__(self, descriptor):
args = [Argument('JSObject*', 'obj'), Argument('const JSObject*', 'old')]
CGAbstractClassHook.__init__(self, descriptor, OBJECT_MOVED_HOOK_NAME,
'void', args)
def generate_code(self):
assert self.descriptor.wrapperCache
return CGIfWrapper(CGGeneric("UpdateWrapper(self, self, obj, old);\n"),
"self").define()
def JSNativeArguments():
return [Argument('JSContext*', 'cx'),
Argument('unsigned', 'argc'),
Argument('JS::Value*', 'vp')]
class CGClassConstructor(CGAbstractStaticMethod):
"""
JS-visible constructor for our objects
@ -10957,9 +10919,6 @@ class CGDescriptor(CGThing):
# wants a custom hook.
cgThings.append(CGClassFinalizeHook(descriptor))
if descriptor.concrete and descriptor.wrapperCache:
cgThings.append(CGClassObjectMovedHook(descriptor))
if len(descriptor.permissions):
for (k, v) in sorted(descriptor.permissions.items()):
perms = CGList((CGGeneric('"%s",' % p) for p in k), joiner="\n")

View File

@ -23,8 +23,7 @@ const js::Class OuterWrapperClass =
nullptr, /* outerObject */
js::proxy_innerObject,
nullptr, /* iteratorObject */
false, /* isWrappedNative */
nullptr /* objectMoved */
false /* isWrappedNative */
));
static JSObject *

View File

@ -252,14 +252,14 @@ namespace js {
* allow for potention JSClass extensions.
*/
#define PROXY_MAKE_EXT(outerObject, innerObject, iteratorObject, \
isWrappedNative, objectMoved) \
isWrappedNative) \
{ \
outerObject, \
innerObject, \
iteratorObject, \
isWrappedNative, \
js::proxy_WeakmapKeyDelegate, \
objectMoved \
js::proxy_ObjectMoved \
}
#define PROXY_CLASS_WITH_EXT(name, extraSlots, flags, ext) \
@ -313,8 +313,7 @@ namespace js {
nullptr, /* outerObject */ \
nullptr, /* innerObject */ \
nullptr, /* iteratorObject */ \
false, /* isWrappedNative */ \
js::proxy_ObjectMoved \
false /* isWrappedNative */ \
))
/*

View File

@ -2374,6 +2374,7 @@ MovingTracer::Sweep(JSTracer *jstrc)
// TODO: Should possibly just call PurgeRuntime() here.
rt->newObjectCache.purge();
rt->nativeIterCache.purge();
rt->regExpTestCache.purge();
}
/*

View File

@ -49,11 +49,6 @@ public:
ClearWrapper();
}
void ObjectMoved(JSObject *obj, const JSObject *old)
{
UpdateWrapper(obj, old);
}
private:
virtual ~SandboxPrivate() { }

View File

@ -310,7 +310,7 @@ sandbox_resolve(JSContext *cx, HandleObject obj, HandleId id)
}
static void
sandbox_finalize(js::FreeOp *fop, JSObject *obj)
sandbox_finalize(JSFreeOp *fop, JSObject *obj)
{
nsIScriptObjectPrincipal *sop =
static_cast<nsIScriptObjectPrincipal *>(xpc_GetJSPrivate(obj));
@ -324,15 +324,6 @@ sandbox_finalize(js::FreeOp *fop, JSObject *obj)
DestroyProtoAndIfaceCache(obj);
}
static void
sandbox_moved(JSObject *obj, const JSObject *old)
{
nsIScriptObjectPrincipal *sop =
static_cast<nsIScriptObjectPrincipal *>(xpc_GetJSPrivate(obj));
MOZ_ASSERT(sop);
static_cast<SandboxPrivate *>(sop)->ObjectMoved(obj, old);
}
static bool
sandbox_convert(JSContext *cx, HandleObject obj, JSType type, MutableHandleValue vp)
{
@ -452,42 +443,22 @@ sandbox_addProperty(JSContext *cx, HandleObject obj, HandleId id, MutableHandleV
#define XPCONNECT_SANDBOX_CLASS_METADATA_SLOT (XPCONNECT_GLOBAL_EXTRA_SLOT_OFFSET)
static const js::Class SandboxClass = {
static const JSClass SandboxClass = {
"Sandbox",
XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(1),
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
sandbox_enumerate, sandbox_resolve, sandbox_convert, sandbox_finalize,
nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook,
JS_NULL_CLASS_SPEC,
{
nullptr, /* outerObject */
nullptr, /* innerObject */
nullptr, /* iteratorObject */
false, /* isWrappedNative */
nullptr, /* weakmapKeyDelegateOp */
sandbox_moved /* objectMovedOp */
},
JS_NULL_OBJECT_OPS
nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook
};
// Note to whomever comes here to remove addProperty hooks: billm has promised
// to do the work for this class.
static const js::Class SandboxWriteToProtoClass = {
static const JSClass SandboxWriteToProtoClass = {
"Sandbox",
XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(1),
sandbox_addProperty, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
sandbox_enumerate, sandbox_resolve, sandbox_convert, sandbox_finalize,
nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook,
JS_NULL_CLASS_SPEC,
{
nullptr, /* outerObject */
nullptr, /* innerObject */
nullptr, /* iteratorObject */
false, /* isWrappedNative */
nullptr, /* weakmapKeyDelegateOp */
sandbox_moved /* objectMovedOp */
},
JS_NULL_OBJECT_OPS
nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook
};
static const JSFunctionSpec SandboxFunctions[] = {
@ -500,7 +471,7 @@ static const JSFunctionSpec SandboxFunctions[] = {
bool
xpc::IsSandbox(JSObject *obj)
{
const Class *clasp = GetObjectClass(obj);
const JSClass *clasp = GetObjectJSClass(obj);
return clasp == &SandboxClass || clasp == &SandboxWriteToProtoClass;
}
@ -890,11 +861,11 @@ xpc::CreateSandboxObject(JSContext *cx, MutableHandleValue vp, nsISupports *prin
compartmentOptions.setAddonId(addonId);
const Class *clasp = options.writeToGlobalPrototype
? &SandboxWriteToProtoClass
: &SandboxClass;
const JSClass *clasp = options.writeToGlobalPrototype
? &SandboxWriteToProtoClass
: &SandboxClass;
RootedObject sandbox(cx, xpc::CreateGlobalObject(cx, js::Jsvalify(clasp),
RootedObject sandbox(cx, xpc::CreateGlobalObject(cx, clasp,
principal, compartmentOptions));
if (!sandbox)
return NS_ERROR_FAILURE;

View File

@ -991,19 +991,6 @@ XPCWrappedNative::FlatJSObjectFinalized()
Release();
}
void
XPCWrappedNative::FlatJSObjectMoved(JSObject *obj, const JSObject *old)
{
MOZ_ASSERT(mFlatJSObject == old);
nsWrapperCache *cache = nullptr;
CallQueryInterface(mIdentity, &cache);
if (cache)
cache->UpdateWrapper(obj, old);
mFlatJSObject = obj;
}
void
XPCWrappedNative::SystemIsBeingShutDown()
{

View File

@ -572,17 +572,6 @@ WrappedNativeFinalize(js::FreeOp *fop, JSObject *obj, WNHelperType helperType)
wrapper->FlatJSObjectFinalized();
}
static void
WrappedNativeObjectMoved(JSObject *obj, const JSObject *old)
{
nsISupports* p = static_cast<nsISupports*>(xpc_GetJSPrivate(obj));
if (!p)
return;
XPCWrappedNative* wrapper = static_cast<XPCWrappedNative*>(p);
wrapper->FlatJSObjectMoved(obj, old);
}
static void
XPC_WN_NoHelper_Finalize(js::FreeOp *fop, JSObject *obj)
{
@ -669,9 +658,7 @@ const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
nullptr, // outerObject
nullptr, // innerObject
nullptr, // iteratorObject
true, // isWrappedNative
nullptr, // weakmapKeyDelegateOp
WrappedNativeObjectMoved
true, // isWrappedNative
},
// ObjectOps
@ -1178,7 +1165,6 @@ XPCNativeScriptableShared::PopulateJSClass()
mJSClass.base.trace = XPCWrappedNative::Trace;
mJSClass.base.ext.isWrappedNative = true;
mJSClass.base.ext.objectMovedOp = WrappedNativeObjectMoved;
}
/***************************************************************************/

View File

@ -2141,7 +2141,6 @@ public:
nsresult RescueOrphans();
void FlatJSObjectFinalized();
void FlatJSObjectMoved(JSObject *obj, const JSObject *old);
void SystemIsBeingShutDown();