Bug 940573 - make the global's ProtoAndIfaceArray an actual object; r=bz

This commit is contained in:
Nathan Froyd 2013-11-19 14:28:09 -05:00
parent f41fd7641d
commit 7a55485352
4 changed files with 27 additions and 21 deletions

View File

@ -1117,7 +1117,7 @@ ResolvePrototypeOrConstructor(JSContext* cx, JS::Handle<JSObject*> wrapper,
JS::Rooted<JSObject*> global(cx, js::GetGlobalForObjectCrossCompartment(obj));
{
JSAutoCompartment ac(cx, global);
JS::Heap<JSObject*>* protoAndIfaceArray = GetProtoAndIfaceArray(global);
ProtoAndIfaceArray& protoAndIfaceArray = *GetProtoAndIfaceArray(global);
JSObject* protoOrIface = protoAndIfaceArray[protoAndIfaceArrayIndex];
if (!protoOrIface) {
return false;

View File

@ -10,6 +10,7 @@
#include "jsfriendapi.h"
#include "jswrapper.h"
#include "mozilla/Alignment.h"
#include "mozilla/Array.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/CallbackObject.h"
#include "mozilla/dom/DOMJSClass.h"
@ -280,21 +281,28 @@ static_assert((size_t)constructors::id::_ID_Start ==
"Overlapping or discontiguous indexes.");
const size_t kProtoAndIfaceCacheCount = constructors::id::_ID_Count;
class ProtoAndIfaceArray : public Array<JS::Heap<JSObject*>, kProtoAndIfaceCacheCount>
{
public:
ProtoAndIfaceArray() {
MOZ_COUNT_CTOR(ProtoAndIfaceArray);
}
~ProtoAndIfaceArray() {
MOZ_COUNT_DTOR(ProtoAndIfaceArray);
}
};
inline void
AllocateProtoAndIfaceCache(JSObject* obj)
{
MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
MOZ_ASSERT(js::GetReservedSlot(obj, DOM_PROTOTYPE_SLOT).isUndefined());
JS::Heap<JSObject*>* protoAndIfaceArray = new JS::Heap<JSObject*>[kProtoAndIfaceCacheCount];
ProtoAndIfaceArray* protoAndIfaceArray = new ProtoAndIfaceArray();
js::SetReservedSlot(obj, DOM_PROTOTYPE_SLOT,
JS::PrivateValue(protoAndIfaceArray));
#ifdef NS_BUILD_REFCNT_LOGGING
NS_LogCtor((void*)protoAndIfaceArray, "ProtoAndIfaceArray",
sizeof(JS::Heap<JSObject*>) * kProtoAndIfaceCacheCount);
#endif
}
inline void
@ -304,8 +312,8 @@ TraceProtoAndIfaceCache(JSTracer* trc, JSObject* obj)
if (!HasProtoAndIfaceArray(obj))
return;
JS::Heap<JSObject*>* protoAndIfaceArray = GetProtoAndIfaceArray(obj);
for (size_t i = 0; i < kProtoAndIfaceCacheCount; ++i) {
ProtoAndIfaceArray& protoAndIfaceArray = *GetProtoAndIfaceArray(obj);
for (size_t i = 0; i < ArrayLength(protoAndIfaceArray); ++i) {
if (protoAndIfaceArray[i]) {
JS_CallHeapObjectTracer(trc, &protoAndIfaceArray[i], "protoAndIfaceArray[i]");
}
@ -317,14 +325,9 @@ DestroyProtoAndIfaceCache(JSObject* obj)
{
MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
JS::Heap<JSObject*>* protoAndIfaceArray = GetProtoAndIfaceArray(obj);
ProtoAndIfaceArray* protoAndIfaceArray = GetProtoAndIfaceArray(obj);
#ifdef NS_BUILD_REFCNT_LOGGING
NS_LogDtor((void*)protoAndIfaceArray, "ProtoAndIfaceArray",
sizeof(JS::Heap<JSObject*>) * kProtoAndIfaceCacheCount);
#endif
delete [] protoAndIfaceArray;
delete protoAndIfaceArray;
}
/**
@ -2066,7 +2069,7 @@ ReportLenientThisUnwrappingFailure(JSContext* cx, JSObject* obj);
inline JSObject*
GetUnforgeableHolder(JSObject* aGlobal, prototypes::ID aId)
{
JS::Heap<JSObject*>* protoAndIfaceArray = GetProtoAndIfaceArray(aGlobal);
ProtoAndIfaceArray& protoAndIfaceArray = *GetProtoAndIfaceArray(aGlobal);
JSObject* interfaceProto = protoAndIfaceArray[aId];
return &js::GetReservedSlot(interfaceProto,
DOM_INTERFACE_PROTO_SLOTS_BASE).toObject();

View File

@ -1800,7 +1800,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
def __init__(self, descriptor, properties):
args = [Argument('JSContext*', 'aCx'),
Argument('JS::Handle<JSObject*>', 'aGlobal'),
Argument('JS::Heap<JSObject*>*', 'aProtoAndIfaceArray'),
Argument('ProtoAndIfaceArray&', 'aProtoAndIfaceArray'),
Argument('bool', 'aDefineOnGlobal')]
CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'void', args)
self.properties = properties
@ -2012,7 +2012,7 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
return JS::NullPtr();
}
/* Check to see whether the interface objects are already installed */
JS::Heap<JSObject*>* protoAndIfaceArray = GetProtoAndIfaceArray(aGlobal);
ProtoAndIfaceArray& protoAndIfaceArray = *GetProtoAndIfaceArray(aGlobal);
if (!protoAndIfaceArray[%s]) {
CreateInterfaceObjects(aCx, aGlobal, protoAndIfaceArray, aDefineOnGlobal);
}
@ -9068,6 +9068,7 @@ class CGForwardDeclarations(CGWrapper):
# We just about always need NativePropertyHooks
builder.addInMozillaDom("NativePropertyHooks")
builder.addInMozillaDom("ProtoAndIfaceArray")
for callback in mainCallbacks:
forwardDeclareForType(callback)

View File

@ -216,6 +216,8 @@ struct DOMIfaceAndProtoJSClass
const JSClass* ToJSClass() const { return &mBase; }
};
class ProtoAndIfaceArray;
inline bool
HasProtoAndIfaceArray(JSObject* global)
{
@ -224,11 +226,11 @@ HasProtoAndIfaceArray(JSObject* global)
return !js::GetReservedSlot(global, DOM_PROTOTYPE_SLOT).isUndefined();
}
inline JS::Heap<JSObject*>*
inline ProtoAndIfaceArray*
GetProtoAndIfaceArray(JSObject* global)
{
MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL);
return static_cast<JS::Heap<JSObject*>*>(
return static_cast<ProtoAndIfaceArray*>(
js::GetReservedSlot(global, DOM_PROTOTYPE_SLOT).toPrivate());
}