author | Steve Fink <sfink@mozilla.com> |
Thu, 02 May 2013 13:55:54 -0700 | |
changeset 130683 | e2dc6cdc1c02a124c0afe27a6123580b486a2cad |
parent 130682 | e728bef882df351c8f5e7b2705c98bb4d558a2de |
child 130684 | 898891617618b587075590f003ac28ef554a3a9a |
push id | 27488 |
push user | sfink@mozilla.com |
push date | Thu, 02 May 2013 23:23:57 +0000 |
treeherder | mozilla-inbound@e2dc6cdc1c02 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | terrence |
bugs | 867341 |
milestone | 23.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/ipc/ObjectWrapperChild.cpp +++ b/js/ipc/ObjectWrapperChild.cpp @@ -411,20 +411,19 @@ ObjectWrapperChild::AnswerNewEnumerateIn { *idp = 0; JSContext* cx = Manager()->GetContext(); AutoContextPusher acp(cx); AutoCheckOperation aco(this, status); JSClass* clasp = const_cast<JSClass*>(&sCPOW_NewEnumerateState_JSClass); - JSObject* state = JS_NewObjectWithGivenProto(cx, clasp, NULL, NULL); + JS::Rooted<JSObject*> state(cx, JS_NewObjectWithGivenProto(cx, clasp, NULL, NULL)); if (!state) return false; - AutoObjectRooter tvr(cx, state); for (JSObject* proto = mObj; proto; ) { AutoIdArray ids(cx, JS_Enumerate(cx, proto)); for (size_t i = 0; i < ids.length(); ++i) JS_DefinePropertyById(cx, state, ids[i], JSVAL_VOID, NULL, NULL, JSPROP_ENUMERATE | JSPROP_SHARED); if (!JS_GetPrototype(cx, proto, &proto))
--- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -4329,19 +4329,16 @@ ArrayType::ConstructData(JSContext* cx, } // Construct a new ArrayType of defined length, for the new CData object. obj = CreateInternal(cx, baseType, length, true); if (!obj) return JS_FALSE; } - // Root the CType object, in case we created one above. - js::AutoObjectRooter root(cx, obj); - JSObject* result = CData::Create(cx, obj, NullPtr(), NULL, true); if (!result) return JS_FALSE; args.rval().setObject(*result); if (convertObject) { if (!ExplicitConvert(cx, args.handleAt(0), obj, CData::GetData(result))) @@ -4615,17 +4612,16 @@ ExtractStructField(JSContext* cx, jsval JS_ReportError(cx, "struct field descriptors require a valid name and type"); return NULL; } RootedObject obj(cx, JSVAL_TO_OBJECT(val)); RootedObject iter(cx, JS_NewPropertyIterator(cx, obj)); if (!iter) return NULL; - js::AutoObjectRooter iterroot(cx, iter); RootedId nameid(cx); if (!JS_NextProperty(cx, iter, nameid.address())) return NULL; if (JSID_IS_VOID(nameid)) { JS_ReportError(cx, "struct field descriptors require a valid name and type"); return NULL; } @@ -4643,26 +4639,25 @@ ExtractStructField(JSContext* cx, jsval JS_ReportError(cx, "struct field descriptors must contain one property"); return NULL; } RootedValue propVal(cx); if (!JS_GetPropertyById(cx, obj, nameid, propVal.address())) return NULL; - if (propVal.isPrimitive() || - !CType::IsCType(propVal.toObjectOrNull())) { + if (propVal.isPrimitive() || !CType::IsCType(&propVal.toObject())) { JS_ReportError(cx, "struct field descriptors require a valid name and type"); return NULL; } // Undefined size or zero size struct members are illegal. // (Zero-size arrays are legal as struct members in C++, but libffi will // choke on a zero-size struct, so we disallow them.) - *typeObj = propVal.toObjectOrNull(); + *typeObj = &propVal.toObject(); size_t size; if (!CType::GetSafeSize(*typeObj, &size) || size == 0) { JS_ReportError(cx, "struct field types must have defined and nonzero size"); return NULL; } return JSID_TO_FLAT_STRING(nameid); } @@ -5615,17 +5610,16 @@ FunctionType::CreateInternal(JSContext* if (!dataProto) return NULL; // Create a new CType object with the common properties and slots. JSObject* typeObj = CType::Create(cx, typeProto, dataProto, TYPE_function, NULL, JSVAL_VOID, JSVAL_VOID, NULL); if (!typeObj) return NULL; - js::AutoObjectRooter root(cx, typeObj); // Stash the FunctionInfo in a reserved slot. JS_SetReservedSlot(typeObj, SLOT_FNINFO, PRIVATE_TO_JSVAL(fninfo.forget())); return typeObj; } // Construct a function pointer to a JS function (see CClosure::Create()). @@ -5649,20 +5643,19 @@ FunctionType::ConstructData(JSContext* c return JS_FALSE; } if (GetABICode(fninfo->mABI) == ABI_WINAPI) { JS_ReportError(cx, "Can't declare a ctypes.winapi_abi callback function, " "use ctypes.stdcall_abi instead"); return JS_FALSE; } - JSObject* closureObj = CClosure::Create(cx, typeObj, fnObj, thisObj, errVal, data); + RootedObject closureObj(cx, CClosure::Create(cx, typeObj, fnObj, thisObj, errVal, data)); if (!closureObj) return JS_FALSE; - js::AutoObjectRooter root(cx, closureObj); // Set the closure object as the referent of the new CData object. JS_SetReservedSlot(dataObj, SLOT_REFERENT, OBJECT_TO_JSVAL(closureObj)); // Seal the CData object, to prevent modification of the function pointer. // This permanently associates this object with the closure, and avoids // having to do things like reset SLOT_REFERENT when someone tries to // change the pointer value. @@ -6152,19 +6145,16 @@ CClosure::ClosureStub(ffi_cif* cif, void rvSize = Align(rvSize, sizeof(ffi_arg)); break; default: break; } memset(result, 0, rvSize); } - // Get a death grip on 'closureObj'. - js::AutoObjectRooter root(cx, cinfo->closureObj); - // Set up an array for converted arguments. Array<jsval, 16> argv; if (!argv.appendN(JSVAL_VOID, cif->nargs)) { JS_ReportOutOfMemory(cx); return; } js::AutoArrayRooter roots(cx, argv.length(), argv.begin());
--- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -411,22 +411,16 @@ AutoGCRooter::trace(JSTracer *trc) } case DESCRIPTOR : { PropertyDescriptor &desc = *static_cast<AutoPropertyDescriptorRooter *>(this); desc.trace(trc); return; } - case OBJECT: - if (static_cast<AutoObjectRooter *>(this)->obj_) - MarkObjectRoot(trc, &static_cast<AutoObjectRooter *>(this)->obj_, - "JS::AutoObjectRooter.obj_"); - return; - case ID: MarkIdRoot(trc, &static_cast<AutoIdRooter *>(this)->id_, "JS::AutoIdRooter.id_"); return; case VALVECTOR: { AutoValueVector::VectorImpl &vector = static_cast<AutoValueVector *>(this)->vector; MarkValueRootRange(trc, vector.length(), vector.begin(), "js::AutoValueVector.vector"); return;
--- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -112,17 +112,16 @@ class JS_PUBLIC_API(AutoGCRooter) { ptrdiff_t tag_; enum { VALARRAY = -2, /* js::AutoValueArray */ PARSER = -3, /* js::frontend::Parser */ SHAPEVECTOR = -4, /* js::AutoShapeVector */ IDARRAY = -6, /* js::AutoIdArray */ DESCRIPTORS = -7, /* js::AutoPropDescArrayRooter */ - OBJECT = -8, /* js::AutoObjectRooter */ ID = -9, /* js::AutoIdRooter */ VALVECTOR = -10, /* js::AutoValueVector */ DESCRIPTOR = -11, /* js::AutoPropertyDescriptorRooter */ STRING = -12, /* js::AutoStringRooter */ IDVECTOR = -13, /* js::AutoIdVector */ OBJVECTOR = -14, /* js::AutoObjectVector */ STRINGVECTOR =-15, /* js::AutoStringVector */ SCRIPTVECTOR =-16, /* js::AutoScriptVector */ @@ -142,45 +141,16 @@ class JS_PUBLIC_API(AutoGCRooter) { private: AutoGCRooter ** const stackTop; /* No copy or assignment semantics. */ AutoGCRooter(AutoGCRooter &ida) MOZ_DELETE; void operator=(AutoGCRooter &ida) MOZ_DELETE; }; -class AutoObjectRooter : private AutoGCRooter -{ - public: - AutoObjectRooter(JSContext *cx, JSObject *obj = NULL - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : AutoGCRooter(cx, OBJECT), obj_(obj) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - void setObject(JSObject *obj) { - obj_ = obj; - } - - JSObject * object() const { - return obj_; - } - - JSObject ** addr() { - return &obj_; - } - - friend void AutoGCRooter::trace(JSTracer *trc); - - private: - JSObject *obj_; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - class AutoStringRooter : private AutoGCRooter { public: AutoStringRooter(JSContext *cx, JSString *str = NULL MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : AutoGCRooter(cx, STRING), str_(str) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; } @@ -5050,17 +5020,16 @@ using JS::TwoByteChars; using JS::Latin1CharsZ; using JS::AutoIdVector; using JS::AutoValueVector; using JS::AutoScriptVector; using JS::AutoIdArray; using JS::AutoGCRooter; -using JS::AutoObjectRooter; using JS::AutoArrayRooter; using JS::AutoVectorRooter; using JS::AutoHashMapRooter; using JS::AutoHashSetRooter; using JS::CallArgs; using JS::IsAcceptableThis; using JS::NativeImpl;
--- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -52,16 +52,21 @@ static const gc::AllocKind ITERATOR_FINA void NativeIterator::mark(JSTracer *trc) { for (HeapPtr<JSFlatString> *str = begin(); str < end(); str++) MarkString(trc, str, "prop"); if (obj) MarkObject(trc, &obj, "obj"); + + // The SuppressDeletedPropertyHelper loop can GC, so make sure that if the + // GC removes any elements from the list, it won't remove this one. + if (iterObj_) + MarkObjectUnbarriered(trc, &iterObj_, "iterObj"); } struct IdHashPolicy { typedef jsid Lookup; static HashNumber hash(jsid id) { return JSID_BITS(id); } static bool match(jsid id1, jsid id2) { @@ -1064,29 +1069,23 @@ template<typename StringPredicate> static bool SuppressDeletedPropertyHelper(JSContext *cx, HandleObject obj, StringPredicate predicate) { NativeIterator *enumeratorList = cx->compartment->enumerators; NativeIterator *ni = enumeratorList->next(); while (ni != enumeratorList) { again: - /* This only works for identified surpressed keys, not values. */ + /* This only works for identified suppressed keys, not values. */ if (ni->isKeyIter() && ni->obj == obj && ni->props_cursor < ni->props_end) { /* Check whether id is still to come. */ HeapPtr<JSFlatString> *props_cursor = ni->current(); HeapPtr<JSFlatString> *props_end = ni->end(); for (HeapPtr<JSFlatString> *idp = props_cursor; idp < props_end; ++idp) { if (predicate(*idp)) { - /* - * Root the iterobj. This loop can GC, so we want to make sure that if - * the GC removes any elements from the list, it won't remove this one. - */ - AutoObjectRooter iterRoot(cx, ni->iterObj()); - /* * Check whether another property along the prototype chain * became visible as a result of this deletion. */ RootedObject proto(cx); if (!JSObject::getProto(cx, obj, &proto)) return false; if (proto) {