From 17cd65acea28a10638a5637caa406335aec5edfd Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Fri, 27 Jan 2012 15:34:30 +0100 Subject: [PATCH] Back out 570dd369e02a, bc777c65c5ca and 12a483042e9a to fix bustage --- dom/base/crashtests/693811-1.html | 14 --- dom/base/crashtests/693811-2.html | 16 --- dom/base/crashtests/crashtests.list | 2 - js/xpconnect/src/dombindings.cpp | 163 +++++----------------------- js/xpconnect/src/dombindings.h | 7 +- js/xpconnect/src/dombindingsgen.py | 23 +--- 6 files changed, 32 insertions(+), 193 deletions(-) delete mode 100644 dom/base/crashtests/693811-1.html delete mode 100644 dom/base/crashtests/693811-2.html diff --git a/dom/base/crashtests/693811-1.html b/dom/base/crashtests/693811-1.html deleted file mode 100644 index e3629fbb24a..00000000000 --- a/dom/base/crashtests/693811-1.html +++ /dev/null @@ -1,14 +0,0 @@ - - diff --git a/dom/base/crashtests/693811-2.html b/dom/base/crashtests/693811-2.html deleted file mode 100644 index 858e66f4f32..00000000000 --- a/dom/base/crashtests/693811-2.html +++ /dev/null @@ -1,16 +0,0 @@ - - diff --git a/dom/base/crashtests/crashtests.list b/dom/base/crashtests/crashtests.list index 364688e14d9..0503d1f3648 100644 --- a/dom/base/crashtests/crashtests.list +++ b/dom/base/crashtests/crashtests.list @@ -30,8 +30,6 @@ load 637116.html load 666869.html load 675621-1.html load 693894.html -load 693811-1.html -load 693811-2.html load 695867.html load 697643.html load 706283-1.html diff --git a/js/xpconnect/src/dombindings.cpp b/js/xpconnect/src/dombindings.cpp index e6008860bdd..949e9db149d 100644 --- a/js/xpconnect/src/dombindings.cpp +++ b/js/xpconnect/src/dombindings.cpp @@ -64,8 +64,6 @@ static jsid s_prototype_id = JSID_VOID; static jsid s_length_id = JSID_VOID; -static jsid s_VOID_id = JSID_VOID; - bool DefineStaticJSVal(JSContext *cx, jsid &id, const char *string) { @@ -226,39 +224,6 @@ Unwrap(JSContext *cx, jsval v, NoType **ppArg, nsISupports **ppArgRef, jsval *vp } -// Because we use proxies for wrapping DOM list objects we don't get the benefits of the property -// cache. To improve performance when using a property that lives on the prototype chain we -// implemented a cheap caching mechanism. Every DOM list proxy object stores a pointer to a shape -// in an extra slot. The first time we access a property on the object that lives on the prototype -// we check if all the DOM properties on the prototype chain are the real DOM properties and in -// that case we store a pointer to the shape of the object's prototype in the extra slot. From -// then on, every time we access a DOM property that lives on the prototype we check that the -// shape of the prototype is still identical to the cached shape and we do a fast lookup of the -// property. If the shape has changed, we recheck all the DOM properties on the prototype chain -// and we update the shape pointer if they are still the real DOM properties. This mechanism -// covers addition/removal of properties, changes in getters/setters, changes in the prototype -// chain, ... It does not cover changes in the values of the properties. For those we store an -// enum value in a reserved slot in every DOM prototype object. The value starts off as USE_CACHE. -// If a property of a DOM prototype object is set to a different value, we set the value to -// CHECK_CACHE. The next time we try to access the value of a property on that DOM prototype -// object we check if all the DOM properties on that DOM prototype object still match the real DOM -// properties. If they do we set the value to USE_CACHE again, if they're not we set the value to -// DONT_USE_CACHE. If the value is USE_CACHE we do the fast lookup. - -template -typename ListBase::Properties ListBase::sProtoProperties[] = { - { s_VOID_id, NULL, NULL } -}; -template -size_t ListBase::sProtoPropertiesCount = 0; - -template -typename ListBase::Methods ListBase::sProtoMethods[] = { - { s_VOID_id, NULL, 0 } -}; -template -size_t ListBase::sProtoMethodsCount = 0; - template ListBase ListBase::instance; @@ -306,27 +271,19 @@ ListBase::setProtoShape(JSObject *obj, js::Shape *shape) js::SetProxyExtra(obj, JSPROXYSLOT_PROTOSHAPE, PrivateValue(shape)); } -static JSBool -UnwrapSecurityWrapper(JSContext *cx, JSObject *obj, JSObject *callee, JSObject **unwrapped) -{ - JS_ASSERT(XPCWrapper::IsSecurityWrapper(obj)); - - if (callee && JS_GetGlobalForObject(cx, obj) == JS_GetGlobalForObject(cx, callee)) { - *unwrapped = js::UnwrapObject(obj); - } else { - *unwrapped = XPCWrapper::Unwrap(cx, obj); - if (!*unwrapped) - return Throw(cx, NS_ERROR_XPC_SECURITY_MANAGER_VETO); - } - return true; -} - template bool ListBase::instanceIsListObject(JSContext *cx, JSObject *obj, JSObject *callee) { - if (XPCWrapper::IsSecurityWrapper(obj) && !UnwrapSecurityWrapper(cx, obj, callee, &obj)) - return false; + if (XPCWrapper::IsSecurityWrapper(obj)) { + if (callee && JS_GetGlobalForObject(cx, obj) == JS_GetGlobalForObject(cx, callee)) { + obj = js::UnwrapObject(obj); + } else { + obj = XPCWrapper::Unwrap(cx, obj); + if (!obj) + return Throw(cx, NS_ERROR_XPC_SECURITY_MANAGER_VETO); + } + } if (!objIsList(obj)) { // FIXME: Throw a proper DOM exception. @@ -447,38 +404,6 @@ ListBase::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope, bool *en return getPrototype(cx, scope); } -enum { - USE_CACHE = 0, - CHECK_CACHE = 1, - DONT_USE_CACHE = 2 -}; - -static JSBool -InvalidateProtoShape_add(JSContext *cx, JSObject *obj, jsid id, jsval *vp) -{ - if (JSID_IS_STRING(id)) - js::SetReservedSlot(obj, 0, PrivateUint32Value(CHECK_CACHE)); - return JS_TRUE; -} - -static JSBool -InvalidateProtoShape_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp) -{ - return InvalidateProtoShape_add(cx, obj, id, vp); -} - -js::Class sInterfacePrototypeClass = { - "Object", - JSCLASS_HAS_RESERVED_SLOTS(1), - InvalidateProtoShape_add, /* addProperty */ - JS_PropertyStub, /* delProperty */ - JS_PropertyStub, /* getProperty */ - InvalidateProtoShape_set, /* setProperty */ - JS_EnumerateStub, - JS_ResolveStub, - JS_ConvertStub -}; - template JSObject * ListBase::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope) @@ -499,11 +424,11 @@ ListBase::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope) return NULL; JSObject *global = scope->GetGlobalJSObject(); - interfacePrototype = JS_NewObject(cx, Jsvalify(&sInterfacePrototypeClass), proto, global); + interfacePrototype = JS_NewObject(cx, NULL, proto, global); if (!interfacePrototype) return NULL; - for (size_t n = 0; n < sProtoPropertiesCount; ++n) { + for (size_t n = 0; n < ArrayLength(sProtoProperties); ++n) { JS_ASSERT(sProtoProperties[n].getter); jsid id = sProtoProperties[n].id; uintN attrs = JSPROP_ENUMERATE | JSPROP_SHARED; @@ -514,7 +439,7 @@ ListBase::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope) return NULL; } - for (size_t n = 0; n < sProtoMethodsCount; ++n) { + for (size_t n = 0; n < ArrayLength(sProtoMethods); ++n) { jsid id = sProtoMethods[n].id; JSFunction *fun = JS_NewFunctionById(cx, sProtoMethods[n].native, sProtoMethods[n].nargs, 0, js::GetObjectParent(interfacePrototype), id); @@ -540,10 +465,6 @@ ListBase::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope) NULL, 0)) return NULL; - // This needs to happen after we've set all our own properties on interfacePrototype, to - // overwrite the value set by InvalidateProtoShape_add when we set our own properties. - js::SetReservedSlot(interfacePrototype, 0, PrivateUint32Value(USE_CACHE)); - if (!cache.Put(sInterfaceClass.name, interfacePrototype)) return NULL; @@ -918,48 +839,32 @@ ListBase::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp) template bool -ListBase::protoIsClean(JSContext *cx, JSObject *proto, bool *isClean) +ListBase::shouldCacheProtoShape(JSContext *cx, JSObject *proto, bool *shouldCache) { JSPropertyDescriptor desc; - for (size_t n = 0; n < sProtoPropertiesCount; ++n) { + for (size_t n = 0; n < ArrayLength(sProtoProperties); ++n) { jsid id = sProtoProperties[n].id; if (!JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, &desc)) return false; - JSStrictPropertyOp setter = - sProtoProperties[n].setter ? sProtoProperties[n].setter : InvalidateProtoShape_set; if (desc.obj != proto || desc.getter != sProtoProperties[n].getter || - desc.setter != setter) { - *isClean = false; + desc.setter != sProtoProperties[n].setter) { + *shouldCache = false; return true; } } - for (size_t n = 0; n < sProtoMethodsCount; ++n) { + for (size_t n = 0; n < ArrayLength(sProtoMethods); ++n) { jsid id = sProtoMethods[n].id; if (!JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, &desc)) return false; if (desc.obj != proto || desc.getter || JSVAL_IS_PRIMITIVE(desc.value) || - n >= js::GetObjectSlotSpan(proto) || js::GetObjectSlot(proto, n + 1) != desc.value || + n >= js::GetObjectSlotSpan(proto) || js::GetObjectSlot(proto, n) != desc.value || !JS_IsNativeFunction(JSVAL_TO_OBJECT(desc.value), sProtoMethods[n].native)) { - *isClean = false; + *shouldCache = false; return true; } } - *isClean = true; - return true; -} - -template -bool -ListBase::shouldCacheProtoShape(JSContext *cx, JSObject *proto, bool *shouldCache) -{ - bool ok = protoIsClean(cx, proto, shouldCache); - if (!ok || !*shouldCache) - return ok; - - js::SetReservedSlot(proto, 0, PrivateUint32Value(USE_CACHE)); - JSObject *protoProto = js::GetObjectProto(proto); if (!protoProto) { *shouldCache = false; @@ -975,7 +880,7 @@ ListBase::resolveNativeName(JSContext *cx, JSObject *proxy, jsid id, JSPrope { JS_ASSERT(xpc::WrapperFactory::IsXrayWrapper(proxy)); - for (size_t n = 0; n < sProtoPropertiesCount; ++n) { + for (size_t n = 0; n < ArrayLength(sProtoProperties); ++n) { if (id == sProtoProperties[n].id) { desc->attrs = JSPROP_ENUMERATE | JSPROP_SHARED; if (!sProtoProperties[n].setter) @@ -987,7 +892,7 @@ ListBase::resolveNativeName(JSContext *cx, JSObject *proxy, jsid id, JSPrope } } - for (size_t n = 0; n < sProtoMethodsCount; ++n) { + for (size_t n = 0; n < ArrayLength(sProtoMethods); ++n) { if (id == sProtoMethods[n].id) { JSFunction *fun = JS_NewFunctionById(cx, sProtoMethods[n].native, sProtoMethods[n].nargs, 0, proxy, id); @@ -1010,28 +915,12 @@ template bool ListBase::nativeGet(JSContext *cx, JSObject *proxy, JSObject *proto, jsid id, bool *found, Value *vp) { - uint32_t cache = js::GetReservedSlot(proto, 0).toPrivateUint32(); - if (cache == CHECK_CACHE) { - bool isClean; - if (!protoIsClean(cx, proto, &isClean)) - return false; - if (!isClean) { - js::SetReservedSlot(proto, 0, PrivateUint32Value(DONT_USE_CACHE)); - return true; - } - js::SetReservedSlot(proto, 0, PrivateUint32Value(USE_CACHE)); - } - else if (cache == DONT_USE_CACHE) { - return true; - } - else { #ifdef DEBUG - bool isClean; - JS_ASSERT(protoIsClean(cx, proto, &isClean) && isClean); + bool shouldCache; + JS_ASSERT(shouldCacheProtoShape(cx, proto, &shouldCache) && shouldCache); #endif - } - for (size_t n = 0; n < sProtoPropertiesCount; ++n) { + for (size_t n = 0; n < ArrayLength(sProtoProperties); ++n) { if (id == sProtoProperties[n].id) { *found = true; if (!vp) @@ -1040,13 +929,13 @@ ListBase::nativeGet(JSContext *cx, JSObject *proxy, JSObject *proto, jsid id return sProtoProperties[n].getter(cx, proxy, id, vp); } } - for (size_t n = 0; n < sProtoMethodsCount; ++n) { + for (size_t n = 0; n < ArrayLength(sProtoMethods); ++n) { if (id == sProtoMethods[n].id) { *found = true; if (!vp) return true; - *vp = js::GetObjectSlot(proto, n + 1); + *vp = js::GetObjectSlot(proto, n); JS_ASSERT(JS_IsNativeFunction(&vp->toObject(), sProtoMethods[n].native)); return true; } diff --git a/js/xpconnect/src/dombindings.h b/js/xpconnect/src/dombindings.h index 078a7cba9c5..cdf802d482d 100644 --- a/js/xpconnect/src/dombindings.h +++ b/js/xpconnect/src/dombindings.h @@ -183,9 +183,7 @@ private: }; static Properties sProtoProperties[]; - static size_t sProtoPropertiesCount; static Methods sProtoMethods[]; - static size_t sProtoMethodsCount; static JSObject *ensureExpandoObject(JSContext *cx, JSObject *obj); @@ -246,15 +244,14 @@ public: static bool objIsList(JSObject *obj) { return js::IsProxy(obj) && proxyHandlerIsList(js::GetProxyHandler(obj)); } - static inline bool instanceIsListObject(JSContext *cx, JSObject *obj, JSObject *callee); + static bool instanceIsListObject(JSContext *cx, JSObject *obj, JSObject *callee); virtual bool isInstanceOf(JSObject *prototype) { return js::GetObjectClass(prototype) == &sInterfaceClass; } - static inline ListType *getListObject(JSObject *obj); + static ListType *getListObject(JSObject *obj); static JSObject *getPrototype(JSContext *cx, XPCWrappedNativeScope *scope); - static inline bool protoIsClean(JSContext *cx, JSObject *proto, bool *isClean); static bool shouldCacheProtoShape(JSContext *cx, JSObject *proto, bool *shouldCache); static bool resolveNativeName(JSContext *cx, JSObject *proxy, jsid id, JSPropertyDescriptor *desc); diff --git a/js/xpconnect/src/dombindingsgen.py b/js/xpconnect/src/dombindingsgen.py index 8d84a2bce50..faa4fce97d5 100644 --- a/js/xpconnect/src/dombindingsgen.py +++ b/js/xpconnect/src/dombindingsgen.py @@ -443,7 +443,7 @@ listTemplate = ( " JS_EnumerateStub,\n" " JS_ResolveStub,\n" " JS_ConvertStub,\n" -" JS_FinalizeStub,\n" +" NULL, /* finalize */\n" " NULL, /* reserved0 */\n" " NULL, /* checkAccess */\n" " NULL, /* call */\n" @@ -527,27 +527,16 @@ nameSetterTemplate = ( "}\n" "\n") -propertiesTemplate = ( +listTemplateFooter = ( "template<>\n" "${name}Wrapper::Properties ${name}Wrapper::sProtoProperties[] = {\n" "${properties}\n" "};\n" -"\n" -"template<>\n" -"size_t ${name}Wrapper::sProtoPropertiesCount = ArrayLength(${name}Wrapper::sProtoProperties);\n" -"\n") - -methodsTemplate = ( -"template<>\n" +"\n""template<>\n" "${name}Wrapper::Methods ${name}Wrapper::sProtoMethods[] = {\n" "${methods}\n" "};\n" "\n" -"template<>\n" -"size_t ${name}Wrapper::sProtoMethodsCount = ArrayLength(${name}Wrapper::sProtoMethods);\n" -"\n") - -listTemplateFooter = ( "template class ListBase<${name}Class>;\n" "\n" "JSObject*\n" @@ -729,11 +718,7 @@ def writeStubFile(filename, config, interfaces): else: propertiesList.append(writeAttrStubs(f, clazz.name, member)) - if len(propertiesList) > 0: - f.write(string.Template(propertiesTemplate).substitute(clazz, properties=",\n".join(propertiesList))) - if len(methodsList) > 0: - f.write(string.Template(methodsTemplate).substitute(clazz, methods=",\n".join(methodsList))) - f.write(string.Template(listTemplateFooter).substitute(clazz)) + f.write(string.Template(listTemplateFooter).substitute(clazz, methods=",\n".join(methodsList), properties=",\n".join(propertiesList))) f.write("// Register prototypes\n\n")