Back out 0f5f58d5d410:8db4d719f5f8 (bug 973780) for debug WinXP mochitest-3 assertions

CLOSED TREE
This commit is contained in:
Phil Ringnalda 2014-02-20 20:46:50 -08:00
Родитель 8e5e2743ce
Коммит 01ad150169
13 изменённых файлов: 100 добавлений и 216 удалений

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

@ -1512,6 +1512,39 @@ AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
return true;
}
JSObject*
GetXrayExpandoChain(JSObject* obj)
{
const js::Class* clasp = js::GetObjectClass(obj);
JS::Value v;
if (IsNonProxyDOMClass(clasp) || IsDOMIfaceAndProtoClass(clasp)) {
v = js::GetReservedSlot(obj, DOM_XRAY_EXPANDO_SLOT);
} else if (clasp->isProxy()) {
MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily());
v = js::GetProxyExtra(obj, JSPROXYSLOT_XRAY_EXPANDO);
} else {
MOZ_ASSERT(JS_IsNativeFunction(obj, Constructor));
v = js::GetFunctionNativeReserved(obj, CONSTRUCTOR_XRAY_EXPANDO_SLOT);
}
return v.isUndefined() ? nullptr : &v.toObject();
}
void
SetXrayExpandoChain(JSObject* obj, JSObject* chain)
{
JS::Value v = chain ? JS::ObjectValue(*chain) : JSVAL_VOID;
const js::Class* clasp = js::GetObjectClass(obj);
if (IsNonProxyDOMClass(clasp) || IsDOMIfaceAndProtoClass(clasp)) {
js::SetReservedSlot(obj, DOM_XRAY_EXPANDO_SLOT, v);
} else if (clasp->isProxy()) {
MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily());
js::SetProxyExtra(obj, JSPROXYSLOT_XRAY_EXPANDO, v);
} else {
MOZ_ASSERT(JS_IsNativeFunction(obj, Constructor));
js::SetFunctionNativeReserved(obj, CONSTRUCTOR_XRAY_EXPANDO_SLOT, v);
}
}
bool
DictionaryBase::ParseJSON(JSContext* aCx,
const nsAString& aJSON,
@ -1724,6 +1757,7 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
// Expandos from other compartments are attached to the target JS object.
// Copy them over, and let the old ones die a natural death.
SetXrayExpandoChain(newobj, nullptr);
if (!xpc::XrayUtils::CloneExpandoChain(aCx, newobj, aObj)) {
return NS_ERROR_FAILURE;
}

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

@ -1955,12 +1955,14 @@ extern NativePropertyHooks sWorkerNativePropertyHooks;
// the real JSNative in the mNative member of a JSNativeHolder in the
// CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT slot of the JSFunction object for a
// specific interface object. We also store the NativeProperties in the
// JSNativeHolder.
// JSNativeHolder. The CONSTRUCTOR_XRAY_EXPANDO_SLOT is used to store the
// expando chain of the Xray for the interface object.
// Note that some interface objects are not yet a JSFunction but a normal
// JSObject with a DOMJSClass, those do not use these slots.
enum {
CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT = 0
CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT = 0,
CONSTRUCTOR_XRAY_EXPANDO_SLOT
};
bool
@ -2005,6 +2007,11 @@ MustInheritFromNonRefcountedDOMObject(NonRefcountedDOMObject*)
{
}
// Set the chain of expando objects for various consumers of the given object.
// For Paris Bindings only. See the relevant infrastructure in XrayWrapper.cpp.
JSObject* GetXrayExpandoChain(JSObject *obj);
void SetXrayExpandoChain(JSObject *obj, JSObject *chain);
/**
* This creates a JSString containing the value that the toString function for
* obj should create according to the WebIDL specification, ignoring any

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

@ -21,7 +21,8 @@ namespace dom {
class DOMClass;
enum {
JSPROXYSLOT_EXPANDO = 0
JSPROXYSLOT_EXPANDO = 0,
JSPROXYSLOT_XRAY_EXPANDO
};
template<typename T> struct Prefable;

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

@ -14,15 +14,20 @@
// globals and non-globals.
#define DOM_OBJECT_SLOT 0
// We use slot 1 for holding the expando object. This is not safe for globals
// until bug 760095 is fixed, so that bug blocks converting Window to new
// bindings.
#define DOM_XRAY_EXPANDO_SLOT 1
// We use slot 2 for holding either a JS::ObjectValue which points to the cached
// SOW or JS::UndefinedValue if this class doesn't need SOWs. This is not safe
// for globals until bug 760095 is fixed, so that bug blocks converting Window
// to new bindings.
#define DOM_OBJECT_SLOT_SOW 1
#define DOM_OBJECT_SLOT_SOW 2
// The total number of slots non-proxy DOM objects use by default.
// Specific objects may have more for storing cached values.
#define DOM_INSTANCE_RESERVED_SLOTS 2
#define DOM_INSTANCE_RESERVED_SLOTS 3
// NOTE: This is baked into the Ion JIT as 0 in codegen for LGetDOMProperty and
// LSetDOMProperty. Those constants need to be changed accordingly if this value
@ -31,11 +36,15 @@
// Interface objects store a number of reserved slots equal to
// DOM_INTERFACE_SLOTS_BASE + number of named constructors.
#define DOM_INTERFACE_SLOTS_BASE 0
#define DOM_INTERFACE_SLOTS_BASE (DOM_XRAY_EXPANDO_SLOT + 1)
// Interface prototype objects store a number of reserved slots equal to
// DOM_INTERFACE_PROTO_SLOTS_BASE or DOM_INTERFACE_PROTO_SLOTS_BASE + 1 if a
// slot for the unforgeable holder is needed.
#define DOM_INTERFACE_PROTO_SLOTS_BASE (DOM_PROTO_INSTANCE_CLASS_SLOT + 1)
#define DOM_INTERFACE_PROTO_SLOTS_BASE (DOM_XRAY_EXPANDO_SLOT + 1)
static_assert(DOM_PROTO_INSTANCE_CLASS_SLOT != DOM_XRAY_EXPANDO_SLOT,
"Interface prototype object use both of these, so they must "
"not be the same slot.");
#endif /* mozilla_dom_DOMSlots_h */

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

@ -1,46 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef js_WeakMapPtr_h
#define js_WeakMapPtr_h
#include "jspubtd.h"
#include "js/TypeDecls.h"
namespace JS {
// A wrapper around the internal C++ representation of SpiderMonkey WeakMaps,
// usable outside the engine.
//
// The supported template specializations are enumerated in WeakMapPtr.cpp. If
// you want to use this class for a different key/value combination, add it to
// the list and the compiler will generate the relevant machinery.
template <typename K, typename V>
class JS_PUBLIC_API(WeakMapPtr)
{
public:
WeakMapPtr() : ptr(nullptr) {};
bool init(JSContext *cx);
bool initialized() { return ptr != nullptr; };
void destroy();
virtual ~WeakMapPtr() { MOZ_ASSERT(!initialized()); }
void trace(JSTracer *tracer);
V lookup(const K &key);
bool put(const K &key, const V &value);
private:
void *ptr;
// WeakMapPtr is neither copyable nor assignable.
WeakMapPtr(const WeakMapPtr &wmp) MOZ_DELETE;
WeakMapPtr &operator=(const WeakMapPtr &wmp) MOZ_DELETE;
};
} /* namespace JS */
#endif /* js_WeakMapPtr_h */

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

@ -37,7 +37,6 @@
#include "js/Utility.h"
#include "js/Value.h"
#include "js/Vector.h"
#include "js/WeakMapPtr.h"
#include "jsapi-tests/tests.h"
/*

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

@ -85,8 +85,7 @@ class WeakMapBase {
// Trace all delayed weak map bindings. Used by the cycle collector.
static void traceAllMappings(WeakMapTracer *tracer);
bool isInList() { return next != WeakMapNotInList; }
void check() { JS_ASSERT(!isInList()); }
void check() { JS_ASSERT(next == WeakMapNotInList); }
// Remove everything from the weak map list for a compartment.
static void resetCompartmentWeakMapList(JSCompartment *c);

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

@ -88,7 +88,6 @@ EXPORTS.js += [
'../public/Utility.h',
'../public/Value.h',
'../public/Vector.h',
'../public/WeakMapPtr.h',
]
UNIFIED_SOURCES += [
@ -190,7 +189,6 @@ UNIFIED_SOURCES += [
'vm/TypedArrayObject.cpp',
'vm/Unicode.cpp',
'vm/Value.cpp',
'vm/WeakMapPtr.cpp',
'vm/Xdr.cpp',
'yarr/PageBlock.cpp',
'yarr/YarrCanonicalizeUCS2.cpp',

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

@ -1,114 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "js/WeakMapPtr.h"
#include "jsweakmap.h"
//
// Machinery for the externally-linkable JS::WeakMapPtr, which wraps js::WeakMap
// for a few public data types.
//
using namespace js;
namespace {
template<typename T>
struct DataType
{
};
template<>
struct DataType<JSObject*>
{
typedef EncapsulatedPtrObject Encapsulated;
static JSObject *NullValue() { return nullptr; }
};
template<>
struct DataType<JS::Value>
{
typedef EncapsulatedValue Encapsulated;
static JS::Value NullValue() { return JS::UndefinedValue(); }
};
template <typename K, typename V>
struct Utils
{
typedef typename DataType<K>::Encapsulated KeyType;
typedef typename DataType<V>::Encapsulated ValueType;
typedef WeakMap<KeyType, ValueType> Type;
typedef Type* PtrType;
static PtrType cast(void *ptr) { return static_cast<PtrType>(ptr); }
};
} /* namespace */
template <typename K, typename V>
void
JS::WeakMapPtr<K, V>::destroy()
{
MOZ_ASSERT(initialized());
auto map = Utils<K, V>::cast(ptr);
// If this destruction happens mid-GC, we might be in the compartment's list
// of known live weakmaps. If we are, remove ourselves before deleting.
if (map->isInList())
WeakMapBase::removeWeakMapFromList(map);
map->check();
js_delete(map);
ptr = nullptr;
}
template <typename K, typename V>
bool
JS::WeakMapPtr<K, V>::init(JSContext *cx)
{
MOZ_ASSERT(!initialized());
typename Utils<K, V>::PtrType map = cx->runtime()->new_<typename Utils<K,V>::Type>(cx);
if (!map || !map->init())
return false;
ptr = map;
return true;
}
template <typename K, typename V>
void
JS::WeakMapPtr<K, V>::trace(JSTracer *trc)
{
MOZ_ASSERT(initialized());
return Utils<K, V>::cast(ptr)->trace(trc);
}
template <typename K, typename V>
V
JS::WeakMapPtr<K, V>::lookup(const K &key)
{
MOZ_ASSERT(initialized());
typename Utils<K, V>::Type::Ptr result = Utils<K, V>::cast(ptr)->lookup(key);
if (!result)
return DataType<V>::NullValue();
return result->value();
}
template <typename K, typename V>
bool
JS::WeakMapPtr<K, V>::put(const K &key, const V &value)
{
MOZ_ASSERT(initialized());
return Utils<K, V>::cast(ptr)->put(key, value);
}
//
// Supported specializations of JS::WeakMap:
//
template class JS::WeakMapPtr<JSObject*, JSObject*>;
#ifdef DEBUG
// Nobody's using this at the moment, but we want to make sure it compiles.
template class JS::WeakMapPtr<JSObject*, JS::Value>;
#endif

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

@ -859,6 +859,10 @@ XPCWrappedNative::FinishInit()
{
AutoJSContext cx;
// For all WNs, we want to make sure that the expando chain slot starts out
// as null.
JS_SetReservedSlot(mFlatJSObject, WN_XRAYEXPANDOCHAIN_SLOT, JSVAL_NULL);
// This reference will be released when mFlatJSObject is finalized.
// Since this reference will push the refcount to 2 it will also root
// mFlatJSObject;
@ -1182,6 +1186,7 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCWrappedNativeScope* aOldScope,
// Expandos from other compartments are attached to the target JS object.
// Copy them over, and let the old ones die a natural death.
SetWNExpandoChain(newobj, nullptr);
if (!XrayUtils::CloneExpandoChain(cx, newobj, flat))
return NS_ERROR_FAILURE;

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

@ -302,9 +302,6 @@ XPCWrappedNativeScope::~XPCWrappedNativeScope()
// XXX might not want to do this at xpconnect shutdown time???
mComponents = nullptr;
if (mXrayExpandos.initialized())
mXrayExpandos.destroy();
JSRuntime *rt = XPCJSRuntime::Get()->Runtime();
mXBLScope.finalize(rt);
mGlobalJSObject.finalize(rt);
@ -602,27 +599,6 @@ XPCWrappedNativeScope::RemoveWrappedNativeProtos()
GetRuntime()->GetDetachedWrappedNativeProtoMap());
}
JSObject *
XPCWrappedNativeScope::GetExpandoChain(JSObject *target)
{
MOZ_ASSERT(GetObjectScope(target) == this);
if (!mXrayExpandos.initialized())
return nullptr;
return mXrayExpandos.lookup(target);
}
bool
XPCWrappedNativeScope::SetExpandoChain(JSContext *cx, HandleObject target,
HandleObject chain)
{
MOZ_ASSERT(GetObjectScope(target) == this);
MOZ_ASSERT(js::IsObjectInContextCompartment(target, cx));
MOZ_ASSERT_IF(chain, GetObjectScope(chain) == this);
if (!mXrayExpandos.initialized() && !mXrayExpandos.init(cx))
return false;
return mXrayExpandos.put(target, chain);
}
/***************************************************************************/
// static

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

@ -90,7 +90,6 @@
#include "xpcpublic.h"
#include "js/Tracer.h"
#include "js/WeakMapPtr.h"
#include "pldhash.h"
#include "nscore.h"
#include "nsXPCOM.h"
@ -213,10 +212,17 @@ extern const char XPC_XPCONNECT_CONTRACTID[];
return (result || !src) ? NS_OK : NS_ERROR_OUT_OF_MEMORY
#define WRAPPER_SLOTS (JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS )
#define WRAPPER_SLOTS (JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | \
JSCLASS_HAS_RESERVED_SLOTS(1))
#define INVALID_OBJECT ((JSObject *)1)
// NB: This slot isn't actually reserved for us on globals, because SpiderMonkey
// uses the first N slots on globals internally. The fact that we use it for
// wrapped global objects is totally broken. But due to a happy coincidence, the
// JS engine never uses that slot. This still needs fixing though. See bug 760095.
#define WN_XRAYEXPANDOCHAIN_SLOT 0
// If IS_WN_CLASS for the JSClass of an object is true, the object is a
// wrappednative wrapper, holding the XPCWrappedNative in its private slot.
static inline bool IS_WN_CLASS(const js::Class* clazz)
@ -229,6 +235,18 @@ static inline bool IS_WN_REFLECTOR(JSObject *obj)
return IS_WN_CLASS(js::GetObjectClass(obj));
}
inline void SetWNExpandoChain(JSObject *obj, JSObject *chain)
{
MOZ_ASSERT(IS_WN_REFLECTOR(obj));
JS_SetReservedSlot(obj, WN_XRAYEXPANDOCHAIN_SLOT, JS::ObjectOrNullValue(chain));
}
inline JSObject* GetWNExpandoChain(JSObject *obj)
{
MOZ_ASSERT(IS_WN_REFLECTOR(obj));
return JS_GetReservedSlot(obj, WN_XRAYEXPANDOCHAIN_SLOT).toObjectOrNull();
}
/***************************************************************************
****************************************************************************
*
@ -1019,12 +1037,6 @@ public:
return nsJSPrincipals::get(JS_GetCompartmentPrincipals(c));
}
JSObject*
GetExpandoChain(JSObject *target);
bool
SetExpandoChain(JSContext *cx, JS::HandleObject target, JS::HandleObject chain);
void RemoveWrappedNativeProtos();
static void
@ -1038,8 +1050,6 @@ public:
mGlobalJSObject.trace(trc, "XPCWrappedNativeScope::mGlobalJSObject");
if (mXBLScope)
mXBLScope.trace(trc, "XPCWrappedNativeScope::mXBLScope");
if (mXrayExpandos.initialized())
mXrayExpandos.trace(trc);
}
static void
@ -1159,8 +1169,6 @@ private:
nsAutoPtr<DOMExpandoSet> mDOMExpandoSet;
JS::WeakMapPtr<JSObject*, JSObject*> mXrayExpandos;
bool mIsXBLScope;
// For remote XUL domains, we run all XBL in the content scope for compat

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

@ -169,13 +169,8 @@ public:
JSObject* ensureHolder(JSContext *cx, HandleObject wrapper);
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper) = 0;
JSObject* getExpandoChain(JSObject *obj) {
return GetObjectScope(obj)->GetExpandoChain(obj);
}
bool setExpandoChain(JSContext *cx, HandleObject obj, HandleObject chain) {
return GetObjectScope(obj)->SetExpandoChain(cx, obj, chain);
}
virtual JSObject* getExpandoChain(JSObject *obj) = 0;
virtual void setExpandoChain(JSObject *obj, JSObject *chain) = 0;
bool cloneExpandoChain(JSContext *cx, HandleObject dst, HandleObject src);
private:
@ -226,6 +221,12 @@ public:
typedef ResolvingId ResolvingIdImpl;
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper);
virtual JSObject* getExpandoChain(JSObject *obj) {
return GetWNExpandoChain(obj);
}
virtual void setExpandoChain(JSObject *obj, JSObject *chain) {
SetWNExpandoChain(obj, chain);
}
static XPCWrappedNativeXrayTraits singleton;
};
@ -262,6 +263,13 @@ public:
virtual JSObject* createHolder(JSContext *cx, JSObject *wrapper);
virtual JSObject* getExpandoChain(JSObject *obj) {
return mozilla::dom::GetXrayExpandoChain(obj);
}
virtual void setExpandoChain(JSObject *obj, JSObject *chain) {
mozilla::dom::SetXrayExpandoChain(obj, chain);
}
static DOMXrayTraits singleton;
};
@ -432,7 +440,7 @@ XrayTraits::attachExpandoObject(JSContext *cx, HandleObject target,
// Insert it at the front of the chain.
JS_SetReservedSlot(expandoObject, JSSLOT_EXPANDO_NEXT, OBJECT_TO_JSVAL(chain));
setExpandoChain(cx, target, expandoObject);
setExpandoChain(target, expandoObject);
return expandoObject;
}