diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 1efe71d34e0..f49af9131a5 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -2730,62 +2730,54 @@ UpdatePropertyType(ExclusiveContext *cx, HeapTypeSet *types, JSObject *obj, Shap } } -bool -TypeObject::addProperty(ExclusiveContext *cx, jsid id, Property **pprop) +void +TypeObject::updateNewPropertyTypes(ExclusiveContext *cx, jsid id, HeapTypeSet *types) { - JS_ASSERT(!*pprop); - Property *base = cx->typeLifoAlloc().new_(id); - if (!base) - return false; - - if (singleton() && singleton()->isNative()) { - /* - * Fill the property in with any type the object already has in an own - * property. We are only interested in plain native properties and - * dense elements which don't go through a barrier when read by the VM - * or jitcode. - */ - - if (JSID_IS_VOID(id)) { - /* Go through all shapes on the object to get integer-valued properties. */ - RootedShape shape(cx, singleton()->lastProperty()); - while (!shape->isEmptyShape()) { - if (JSID_IS_VOID(IdToTypeId(shape->propid()))) - UpdatePropertyType(cx, &base->types, singleton(), shape, true); - shape = shape->previous(); - } - - /* Also get values of any dense elements in the object. */ - for (size_t i = 0; i < singleton()->getDenseInitializedLength(); i++) { - const Value &value = singleton()->getDenseElement(i); - if (!value.isMagic(JS_ELEMENTS_HOLE)) { - Type type = GetValueType(value); - base->types.TypeSet::addType(type, &cx->typeLifoAlloc()); - } - } - } else if (!JSID_IS_EMPTY(id)) { - RootedId rootedId(cx, id); - Shape *shape = singleton()->nativeLookup(cx, rootedId); - if (shape) - UpdatePropertyType(cx, &base->types, singleton(), shape, false); - } - - if (singleton()->watched()) { - /* - * Mark the property as non-data, to inhibit optimizations on it - * and avoid bypassing the watchpoint handler. - */ - base->types.setNonDataProperty(cx); - } - } - - *pprop = base; - InferSpew(ISpewOps, "typeSet: %sT%p%s property %s %s", - InferSpewColor(&base->types), &base->types, InferSpewColorReset(), + InferSpewColor(types), types, InferSpewColorReset(), TypeObjectString(this), TypeIdString(id)); - return true; + if (!singleton() || !singleton()->isNative()) + return; + + /* + * Fill the property in with any type the object already has in an own + * property. We are only interested in plain native properties and + * dense elements which don't go through a barrier when read by the VM + * or jitcode. + */ + + if (JSID_IS_VOID(id)) { + /* Go through all shapes on the object to get integer-valued properties. */ + RootedShape shape(cx, singleton()->lastProperty()); + while (!shape->isEmptyShape()) { + if (JSID_IS_VOID(IdToTypeId(shape->propid()))) + UpdatePropertyType(cx, types, singleton(), shape, true); + shape = shape->previous(); + } + + /* Also get values of any dense elements in the object. */ + for (size_t i = 0; i < singleton()->getDenseInitializedLength(); i++) { + const Value &value = singleton()->getDenseElement(i); + if (!value.isMagic(JS_ELEMENTS_HOLE)) { + Type type = GetValueType(value); + types->TypeSet::addType(type, &cx->typeLifoAlloc()); + } + } + } else if (!JSID_IS_EMPTY(id)) { + RootedId rootedId(cx, id); + Shape *shape = singleton()->nativeLookup(cx, rootedId); + if (shape) + UpdatePropertyType(cx, types, singleton(), shape, false); + } + + if (singleton()->watched()) { + /* + * Mark the property as non-data, to inhibit optimizations on it + * and avoid bypassing the watchpoint handler. + */ + types->setNonDataProperty(cx); + } } bool diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index 5c7c0bba876..5046734ce69 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -1108,7 +1108,7 @@ struct TypeObject : gc::BarrieredCell /* Helpers */ - bool addProperty(ExclusiveContext *cx, jsid id, Property **pprop); + void updateNewPropertyTypes(ExclusiveContext *cx, jsid id, HeapTypeSet *types); bool addDefiniteProperties(ExclusiveContext *cx, JSObject *obj); bool matchDefiniteProperties(HandleObject obj); void addPrototype(JSContext *cx, TypeObject *proto); diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index 9208e82d5f2..de4e176d3b2 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -1238,6 +1238,12 @@ TypeObject::getProperty(ExclusiveContext *cx, jsid id) if (HeapTypeSet *types = maybeGetProperty(id)) return types; + Property *base = cx->typeLifoAlloc().new_(id); + if (!base) { + markUnknown(cx); + return nullptr; + } + uint32_t propertyCount = basePropertyCount(); Property **pprop = HashSetInsert (cx->typeLifoAlloc(), propertySet, propertyCount, id); @@ -1249,28 +1255,18 @@ TypeObject::getProperty(ExclusiveContext *cx, jsid id) JS_ASSERT(!*pprop); setBasePropertyCount(propertyCount); - if (!addProperty(cx, id, pprop)) { - markUnknown(cx); - return nullptr; - } + *pprop = base; + + updateNewPropertyTypes(cx, id, &base->types); if (propertyCount == OBJECT_FLAG_PROPERTY_COUNT_LIMIT) { + // We hit the maximum number of properties the object can have, mark + // the object unknown so that new properties will not be added in the + // future. markUnknown(cx); - - /* - * Return an arbitrary property in the object, as all have unknown - * type and are treated as non-data properties. - */ - unsigned count = getPropertyCount(); - for (unsigned i = 0; i < count; i++) { - if (Property *prop = getProperty(i)) - return &prop->types; - } - - MOZ_ASSUME_UNREACHABLE("Missing property"); } - return &(*pprop)->types; + return &base->types; } inline HeapTypeSet *