mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 989503 - Recover cleanly after OOM while adding type object properties, r=jandem.
This commit is contained in:
parent
5043e365c5
commit
6a6f9ba4bd
@ -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_<Property>(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
|
||||
|
@ -1108,7 +1108,7 @@ struct TypeObject : gc::BarrieredCell<TypeObject>
|
||||
|
||||
/* 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);
|
||||
|
@ -1238,6 +1238,12 @@ TypeObject::getProperty(ExclusiveContext *cx, jsid id)
|
||||
if (HeapTypeSet *types = maybeGetProperty(id))
|
||||
return types;
|
||||
|
||||
Property *base = cx->typeLifoAlloc().new_<Property>(id);
|
||||
if (!base) {
|
||||
markUnknown(cx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t propertyCount = basePropertyCount();
|
||||
Property **pprop = HashSetInsert<jsid,Property,Property>
|
||||
(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 *
|
||||
|
Loading…
Reference in New Issue
Block a user