Bug 791611 (part 1) - Exactly root most JSObjects in jsinfer.cpp. r=terrence.

--HG--
extra : rebase_source : 1b39f0220a1f0ec0f8633b6a0aa5685f1d3a2c02
This commit is contained in:
Nicholas Nethercote 2012-09-16 16:32:02 -07:00
parent c658c872ec
commit cc1fa77fc3
16 changed files with 275 additions and 259 deletions

View File

@ -135,18 +135,18 @@ NewDenseCopiedArrayWithType(JSContext *cx, uint32_t length, HandleObject source)
Value elem;
for (uint32_t i = 0; i < copyUpTo; i++) {
elem = srcvp[i].isMagic(JS_ARRAY_HOLE) ? UndefinedValue() : srcvp[i];
buffer->initDenseArrayElementWithType(cx, i, elem);
JSObject::initDenseArrayElementWithType(cx, buffer, i, elem);
}
// Fill the rest with undefineds.
for (uint32_t i = copyUpTo; i < length; i++)
buffer->initDenseArrayElementWithType(cx, i, UndefinedValue());
JSObject::initDenseArrayElementWithType(cx, buffer, i, UndefinedValue());
} else {
// This path might GC. The GC expects an object's slots to be
// initialized, so we have to make sure all the array's slots are
// initialized.
for (uint32_t i = 0; i < length; i++)
buffer->initDenseArrayElementWithType(cx, i, UndefinedValue());
JSObject::initDenseArrayElementWithType(cx, buffer, i, UndefinedValue());
IndexInfo siv(cx);
RootedParallelArrayObject sourcePA(cx);
@ -160,7 +160,7 @@ NewDenseCopiedArrayWithType(JSContext *cx, uint32_t length, HandleObject source)
for (uint32_t i = 0; i < copyUpTo; i++) {
if (!GetElementFromArrayLikeObject(cx, source, sourcePA, siv, i, &elem))
return NULL;
buffer->setDenseArrayElementWithType(cx, i, elem);
JSObject::setDenseArrayElementWithType(cx, buffer, i, elem);
}
}
@ -324,7 +324,7 @@ ParallelArrayObject::SequentialMode::build(JSContext *cx, IndexInfo &iv,
if (!Invoke(cx, args))
return ExecutionFailed;
buffer->setDenseArrayElementWithType(cx, i, args.rval());
JSObject::setDenseArrayElementWithType(cx, buffer, i, args.rval());
}
return ExecutionSucceeded;
@ -364,7 +364,7 @@ ParallelArrayObject::SequentialMode::map(JSContext *cx, HandleParallelArrayObjec
if (!Invoke(cx, args))
return ExecutionFailed;
buffer->setDenseArrayElementWithType(cx, i, args.rval());
JSObject::setDenseArrayElementWithType(cx, buffer, i, args.rval());
}
return ExecutionSucceeded;
@ -396,7 +396,7 @@ ParallelArrayObject::SequentialMode::reduce(JSContext *cx, HandleParallelArrayOb
return ExecutionFailed;
if (buffer)
buffer->setDenseArrayElementWithType(cx, 0, acc);
JSObject::setDenseArrayElementWithType(cx, buffer, 0, acc);
InvokeArgsGuard args;
if (!cx->stack.pushInvokeArgs(cx, 2, &args))
@ -420,7 +420,7 @@ ParallelArrayObject::SequentialMode::reduce(JSContext *cx, HandleParallelArrayOb
// Update the accumulator.
acc = args.rval();
if (buffer)
buffer->setDenseArrayElementWithType(cx, i, args.rval());
JSObject::setDenseArrayElementWithType(cx, buffer, i, args.rval());
}
vp.set(acc);
@ -501,13 +501,13 @@ ParallelArrayObject::SequentialMode::scatter(JSContext *cx, HandleParallelArrayO
}
}
buffer->setDenseArrayElementWithType(cx, targetIndex, elem);
JSObject::setDenseArrayElementWithType(cx, buffer, targetIndex, elem);
}
// Fill holes with the default value.
for (uint32_t i = 0; i < length; i++) {
if (buffer->getDenseArrayElement(i).isMagic(JS_ARRAY_HOLE))
buffer->setDenseArrayElementWithType(cx, i, defaultValue);
JSObject::setDenseArrayElementWithType(cx, buffer, i, defaultValue);
}
return ExecutionSucceeded;
@ -554,7 +554,7 @@ ParallelArrayObject::SequentialMode::filter(JSContext *cx, HandleParallelArrayOb
return ExecutionFailed;
if (i >= buffer->getArrayLength())
buffer->setDenseArrayLength(pos + 1);
buffer->setDenseArrayElementWithType(cx, pos, elem);
JSObject::setDenseArrayElementWithType(cx, buffer, pos, elem);
// We didn't filter this element out, so bump the position.
pos++;
@ -1017,7 +1017,8 @@ ParallelArrayObject::create(JSContext *cx, HandleObject buffer, uint32_t offset,
return false;
for (uint32_t i = 0; i < dims.length(); i++)
dimArray->setDenseArrayElementWithType(cx, i, Int32Value(static_cast<int32_t>(dims[i])));
JSObject::setDenseArrayElementWithType(cx, dimArray, i,
Int32Value(static_cast<int32_t>(dims[i])));
result->setSlot(SLOT_DIMENSIONS, ObjectValue(*dimArray));

View File

@ -552,7 +552,7 @@ JS_FRIEND_API(bool) InNoGCScope();
/*
* The scoped guard object AutoAssertNoGC forces the GC to assert if a GC is
* attempted while the guard object is live. If you have a GC-unsafe operation
* to perform, use this guard object to protect your opertion.
* to perform, use this guard object to protect your operation.
*/
class AutoAssertNoGC
{

View File

@ -1014,7 +1014,7 @@ class ScriptAnalysis
void addTypeBarrier(JSContext *cx, const jsbytecode *pc,
types::TypeSet *target, types::Type type);
void addSingletonTypeBarrier(JSContext *cx, const jsbytecode *pc,
types::TypeSet *target, JSObject *singleton, jsid singletonId);
types::TypeSet *target, HandleObject singleton, jsid singletonId);
/* Remove obsolete type barriers at the given offset. */
void pruneTypeBarriers(JSContext *cx, uint32_t offset);

View File

@ -407,7 +407,7 @@ SetArrayElement(JSContext *cx, HandleObject obj, double index, HandleValue v)
break;
if (idx >= obj->getArrayLength())
obj->setDenseArrayLength(idx + 1);
obj->setDenseArrayElementWithType(cx, idx, v);
JSObject::setDenseArrayElementWithType(cx, obj, idx, v);
return true;
} while (false);
@ -541,7 +541,7 @@ array_length_setter(JSContext *cx, HandleObject obj, HandleId id, JSBool strict,
vp.setNumber(newlen);
if (oldlen < newlen) {
obj->setArrayLength(cx, newlen);
JSObject::setArrayLength(cx, obj, newlen);
return true;
}
@ -562,12 +562,12 @@ array_length_setter(JSContext *cx, HandleObject obj, HandleId id, JSBool strict,
do {
--oldlen;
if (!JS_CHECK_OPERATION_LIMIT(cx)) {
obj->setArrayLength(cx, oldlen + 1);
JSObject::setArrayLength(cx, obj, oldlen + 1);
return false;
}
int deletion = DeleteArrayElement(cx, obj, oldlen, strict);
if (deletion <= 0) {
obj->setArrayLength(cx, oldlen + 1);
JSObject::setArrayLength(cx, obj, oldlen + 1);
return deletion >= 0;
}
} while (oldlen != newlen);
@ -599,7 +599,7 @@ array_length_setter(JSContext *cx, HandleObject obj, HandleId id, JSBool strict,
}
}
obj->setArrayLength(cx, newlen);
JSObject::setArrayLength(cx, obj, newlen);
return true;
}
@ -800,7 +800,7 @@ slowarray_addProperty(JSContext *cx, HandleObject obj, HandleId id,
return JS_TRUE;
length = obj->getArrayLength();
if (index >= length)
obj->setArrayLength(cx, index + 1);
JSObject::setArrayLength(cx, obj, index + 1);
return JS_TRUE;
}
@ -831,7 +831,7 @@ array_setGeneric(JSContext *cx, HandleObject obj, HandleId id,
if (i >= obj->getArrayLength())
obj->setDenseArrayLength(i + 1);
obj->setDenseArrayElementWithType(cx, i, vp);
JSObject::setDenseArrayElementWithType(cx, obj, i, vp);
return true;
} while (false);
@ -879,7 +879,7 @@ array_setElement(JSContext *cx, HandleObject obj, uint32_t index,
if (index >= obj->getArrayLength())
obj->setDenseArrayLength(index + 1);
obj->setDenseArrayElementWithType(cx, index, vp);
JSObject::setDenseArrayElementWithType(cx, obj, index, vp);
return true;
} while (false);
@ -944,7 +944,7 @@ array_defineGeneric(JSContext *cx, HandleObject obj, HandleId id, HandleValue va
if (i >= obj->getArrayLength())
obj->setDenseArrayLength(i + 1);
obj->setDenseArrayElementWithType(cx, i, value);
JSObject::setDenseArrayElementWithType(cx, obj, i, value);
return true;
} while (false);
@ -991,7 +991,7 @@ array_defineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue
if (index >= obj->getArrayLength())
obj->setDenseArrayLength(index + 1);
obj->setDenseArrayElementWithType(cx, index, value);
JSObject::setDenseArrayElementWithType(cx, obj, index, value);
return true;
} while (false);
@ -2231,7 +2231,7 @@ array_push1_dense(JSContext* cx, HandleObject obj, CallArgs &args)
}
obj->setDenseArrayLength(length + 1);
obj->setDenseArrayElementWithType(cx, length, args[0]);
JSObject::setDenseArrayElementWithType(cx, obj, length, args[0]);
args.rval().setNumber(obj->getArrayLength());
return true;
}
@ -2258,7 +2258,7 @@ NewbornArrayPushImpl(JSContext *cx, HandleObject obj, const Value &v)
obj->setDenseArrayInitializedLength(length + 1);
obj->setDenseArrayLength(length + 1);
obj->initDenseArrayElementWithType(cx, length, v);
JSObject::initDenseArrayElementWithType(cx, obj, length, v);
return true;
}
@ -2336,7 +2336,7 @@ array_pop_dense(JSContext *cx, HandleObject obj, CallArgs &args)
if (obj->getDenseArrayInitializedLength() > index)
obj->setDenseArrayInitializedLength(index);
obj->setArrayLength(cx, index);
JSObject::setArrayLength(cx, obj, index);
return true;
}
@ -2403,7 +2403,7 @@ js::array_shift(JSContext *cx, unsigned argc, Value *vp)
args.rval().setUndefined();
obj->moveDenseArrayElements(0, 1, obj->getDenseArrayInitializedLength() - 1);
obj->setDenseArrayInitializedLength(obj->getDenseArrayInitializedLength() - 1);
obj->setArrayLength(cx, length);
JSObject::setArrayLength(cx, obj, length);
if (!js_SuppressDeletedProperty(cx, obj, INT_TO_JSID(length)))
return JS_FALSE;
return JS_TRUE;
@ -2795,7 +2795,7 @@ js::array_concat(JSContext *cx, unsigned argc, Value *vp)
if (!nobj)
return JS_FALSE;
TryReuseArrayType(aobj, nobj);
nobj->setArrayLength(cx, length);
JSObject::setArrayLength(cx, nobj, length);
args.rval().setObject(*nobj);
if (argc == 0)
return JS_TRUE;
@ -3525,7 +3525,7 @@ js_Array(JSContext *cx, unsigned argc, Value *vp)
}
}
JSObject *obj = NewDenseUnallocatedArray(cx, length);
RootedObject obj(cx, NewDenseUnallocatedArray(cx, length));
if (!obj)
return false;
@ -3533,7 +3533,7 @@ js_Array(JSContext *cx, unsigned argc, Value *vp)
/* If the length calculation overflowed, make sure that is marked for the new type. */
if (obj->getArrayLength() > INT32_MAX)
obj->setArrayLength(cx, obj->getArrayLength());
JSObject::setArrayLength(cx, obj, obj->getArrayLength());
args.rval().setObject(*obj);
return true;
@ -3549,7 +3549,7 @@ js_InitArrayClass(JSContext *cx, JSObject *obj)
RootedObject arrayProto(cx, global->createBlankPrototype(cx, &SlowArrayClass));
if (!arrayProto || !AddLengthProperty(cx, arrayProto))
return NULL;
arrayProto->setArrayLength(cx, 0);
JSObject::setArrayLength(cx, arrayProto, 0);
RootedFunction ctor(cx);
ctor = global->createConstructor(cx, js_Array, cx->names().Array, 1);
@ -3614,11 +3614,11 @@ NewArray(JSContext *cx, uint32_t length, RawObject protoArg)
NewObjectCache::EntryIndex entry = -1;
if (cache.lookupGlobal(&ArrayClass, cx->global(), kind, &entry)) {
JSObject *obj = cache.newObjectFromHit(cx, entry);
RootedObject obj(cx, cache.newObjectFromHit(cx, entry));
if (obj) {
/* Fixup the elements pointer and length, which may be incorrect. */
obj->setFixedElements();
obj->setArrayLength(cx, length);
JSObject::setArrayLength(cx, obj, length);
if (allocateCapacity && !EnsureNewArrayElements(cx, obj, length))
return NULL;
return obj;
@ -3716,7 +3716,7 @@ NewSlowEmptyArray(JSContext *cx)
if (!obj || !AddLengthProperty(cx, obj))
return NULL;
obj->setArrayLength(cx, 0);
JSObject::setArrayLength(cx, obj, 0);
return obj;
}

View File

@ -304,7 +304,7 @@ struct JSCompartment
/* Get the default 'new' type for objects with a NULL prototype. */
inline js::types::TypeObject *getEmptyType(JSContext *cx);
js::types::TypeObject *getLazyType(JSContext *cx, JSObject *proto);
js::types::TypeObject *getLazyType(JSContext *cx, js::HandleObject proto);
/*
* Keeps track of the total number of malloc bytes connected to a

View File

@ -80,7 +80,7 @@ fun_getProperty(JSContext *cx, HandleObject obj_, HandleId id, MutableHandleValu
if (!obj)
return true;
}
JSFunction *fun = obj->toFunction();
RootedFunction fun(cx, obj->toFunction());
/*
* Mark the function's script as uninlineable, to expand any of its
@ -152,7 +152,7 @@ fun_getProperty(JSContext *cx, HandleObject obj_, HandleId id, MutableHandleValu
jsbytecode *prevpc = fp->prevpc(&inlined);
if (inlined) {
mjit::JITChunk *chunk = fp->prev()->jit()->chunk(prevpc);
JSFunction *fun = chunk->inlineFrames()[inlined->inlineIndex].fun;
RawFunction fun = chunk->inlineFrames()[inlined->inlineIndex].fun;
fun->script()->uninlineable = true;
MarkTypeObjectFlags(cx, fun, OBJECT_FLAG_UNINLINEABLE);
}

View File

@ -795,7 +795,7 @@ HeapTypeSet::addFilterPrimitives(JSContext *cx, TypeSet *target)
/* If id is a normal slotful 'own' property of an object, get its shape. */
static inline Shape *
GetSingletonShape(JSContext *cx, JSObject *obj, jsid id)
GetSingletonShape(JSContext *cx, HandleObject obj, jsid id)
{
if (!obj->isNative())
return NULL;
@ -818,7 +818,8 @@ ScriptAnalysis::pruneTypeBarriers(JSContext *cx, uint32_t offset)
}
if (barrier->singleton) {
JS_ASSERT(barrier->type.isPrimitive(JSVAL_TYPE_UNDEFINED));
Shape *shape = GetSingletonShape(cx, barrier->singleton, barrier->singletonId);
RootedObject barrierSingleton(cx, barrier->singleton);
Shape *shape = GetSingletonShape(cx, barrierSingleton, barrier->singletonId);
if (shape && !barrier->singleton->nativeGetSlot(shape->slot()).isUndefined()) {
/*
* When we analyzed the script the singleton had an 'own'
@ -1007,11 +1008,11 @@ MarkPropertyAccessUnknown(JSContext *cx, JSScript *script, jsbytecode *pc, TypeS
* property.
*/
static inline Type
GetSingletonPropertyType(JSContext *cx, JSObject *objArg, jsid id)
GetSingletonPropertyType(JSContext *cx, RawObject rawObjArg, jsid id)
{
JS_ASSERT(id == MakeTypeId(cx, id));
RootedObject obj(cx, rawObjArg); // Root this locally because it's assigned to.
RootedObject obj(cx, objArg);
JS_ASSERT(id == MakeTypeId(cx, id));
if (JSID_IS_VOID(id))
return Type::UnknownType();
@ -1094,7 +1095,7 @@ PropertyAccess(JSContext *cx, JSScript *script, jsbytecode *pc, TypeObject *obje
* object or prototype will not change between analysis and execution.
*/
if (access != PROPERTY_WRITE) {
JSObject *singleton = object->singleton;
RootedObject singleton(cx, object->singleton);
/*
* Don't eagerly resolve reads from the prototype if the instance type
@ -1132,9 +1133,10 @@ PropertyAccess(JSContext *cx, JSScript *script, jsbytecode *pc, TypeObject *obje
* to remove the barrier after the property becomes defined,
* even if no undefined value is ever observed at pc.
*/
Shape *shape = GetSingletonShape(cx, object->singleton, id);
if (shape && object->singleton->nativeGetSlot(shape->slot()).isUndefined())
script->analysis()->addSingletonTypeBarrier(cx, pc, target, object->singleton, id);
RootedObject singleton(cx, object->singleton);
RootedShape shape(cx, GetSingletonShape(cx, singleton, id));
if (shape && singleton->nativeGetSlot(shape->slot()).isUndefined())
script->analysis()->addSingletonTypeBarrier(cx, pc, target, singleton, id);
}
} else {
JS_ASSERT(access == PROPERTY_READ);
@ -1251,7 +1253,7 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
JSFunction *callee = NULL;
if (type.isSingleObject()) {
JSObject *obj = type.singleObject();
RootedObject obj(cx, type.singleObject());
if (!obj->isFunction()) {
/* Calls on non-functions are dynamically monitored. */
@ -1375,7 +1377,7 @@ TypeConstraintPropagateThis::newType(JSContext *cx, TypeSet *source, Type type)
JSFunction *callee = NULL;
if (type.isSingleObject()) {
JSObject *object = type.singleObject();
RootedObject object(cx, type.singleObject());
if (!object->isFunction() || !object->toFunction()->isInterpreted())
return;
callee = object->toFunction();
@ -1652,7 +1654,7 @@ StackTypeSet::hasObjectFlags(JSContext *cx, TypeObjectFlags flags)
for (unsigned i = 0; i < count; i++) {
TypeObject *object = getTypeObject(i);
if (!object) {
JSObject *obj = getSingleObject(i);
RootedObject obj(cx, getSingleObject(i));
if (!obj)
continue;
object = obj->getType(cx);
@ -1840,12 +1842,14 @@ HeapTypeSet::knownSubset(JSContext *cx, TypeSet *other)
int
StackTypeSet::getTypedArrayType()
{
AutoAssertNoGC nogc;
int arrayType = TypedArray::TYPE_MAX;
unsigned count = getObjectCount();
for (unsigned i = 0; i < count; i++) {
JSObject *proto = NULL;
if (JSObject *object = getSingleObject(i)) {
RawObject proto = NULL;
if (RawObject object = getSingleObject(i)) {
proto = object->getProto();
} else if (TypeObject *object = getTypeObject(i)) {
JS_ASSERT(!object->hasAnyFlags(OBJECT_FLAG_NON_TYPED_ARRAY));
@ -1877,7 +1881,7 @@ StackTypeSet::getTypedArrayType()
return arrayType;
}
JSObject *
RawObject
StackTypeSet::getSingleton()
{
if (baseFlags() != 0 || baseObjectCount() != 1)
@ -1886,13 +1890,13 @@ StackTypeSet::getSingleton()
return getSingleObject(0);
}
JSObject *
RawObject
HeapTypeSet::getSingleton(JSContext *cx)
{
if (baseFlags() != 0 || baseObjectCount() != 1)
return NULL;
JSObject *obj = getSingleObject(0);
RootedObject obj(cx, getSingleObject(0));
if (obj)
addFreeze(cx);
@ -2060,13 +2064,12 @@ TypeCompartment::init(JSContext *cx)
TypeObject *
TypeCompartment::newTypeObject(JSContext *cx, JSScript *script,
JSProtoKey key, JSObject *proto_, bool unknown,
JSProtoKey key, HandleObject proto, bool unknown,
bool isDOM)
{
JS_ASSERT_IF(script, cx->compartment == script->compartment());
JS_ASSERT_IF(proto_, cx->compartment == proto_->compartment());
JS_ASSERT_IF(proto, cx->compartment == proto->compartment());
RootedObject proto(cx, proto_);
TypeObject *object = gc::NewGCThing<TypeObject>(cx, gc::FINALIZE_TYPE_OBJECT, sizeof(TypeObject));
if (!object)
return NULL;
@ -2232,7 +2235,7 @@ TypeCompartment::addAllocationSiteTypeObject(JSContext *cx, AllocationSiteKey ke
* observed by other code before all properties have been added. Mark
* all the properties as definite properties of the object.
*/
JSObject *baseobj = key.script->getObject(GET_UINT32_INDEX(pc));
RootedObject baseobj(cx, key.script->getObject(GET_UINT32_INDEX(pc)));
if (!res->addDefiniteProperties(cx, baseobj))
return NULL;
@ -2316,7 +2319,7 @@ types::ArrayPrototypeHasIndexedProperty(JSContext *cx, JSScript *script)
if (!cx->typeInferenceEnabled() || !script->compileAndGo)
return true;
JSObject *proto = script->global().getOrCreateArrayPrototype(cx);
RootedObject proto(cx, script->global().getOrCreateArrayPrototype(cx));
if (!proto)
return true;
@ -2685,7 +2688,8 @@ ScriptAnalysis::addTypeBarrier(JSContext *cx, const jsbytecode *pc, TypeSet *tar
}
void
ScriptAnalysis::addSingletonTypeBarrier(JSContext *cx, const jsbytecode *pc, TypeSet *target, JSObject *singleton, jsid singletonId)
ScriptAnalysis::addSingletonTypeBarrier(JSContext *cx, const jsbytecode *pc, TypeSet *target,
HandleObject singleton, jsid singletonId)
{
JS_ASSERT(singletonId == MakeTypeId(cx, singletonId) && !JSID_IS_VOID(singletonId));
@ -2699,7 +2703,7 @@ ScriptAnalysis::addSingletonTypeBarrier(JSContext *cx, const jsbytecode *pc, Typ
InferSpew(ISpewOps, "singletonTypeBarrier: #%u:%05u: %sT%p%s %p %s",
script->id(), pc - script->code,
InferSpewColor(target), target, InferSpewColorReset(),
(void *) singleton, TypeIdString(singletonId));
(void *) singleton.get(), TypeIdString(singletonId));
TypeBarrier *barrier = cx->analysisLifoAlloc().new_<TypeBarrier>(target, Type::UndefinedType(),
singleton, singletonId);
@ -2803,9 +2807,8 @@ struct types::ArrayTableKey
};
void
TypeCompartment::fixArrayType(JSContext *cx, JSObject *obj_)
TypeCompartment::fixArrayType(JSContext *cx, HandleObject obj)
{
RootedObject obj(cx, obj_);
AutoEnterTypeInference enter(cx);
if (!arrayTypeTable) {
@ -2851,7 +2854,8 @@ TypeCompartment::fixArrayType(JSContext *cx, JSObject *obj_)
} else {
Rooted<Type> origType(cx, type);
/* Make a new type to use for future arrays with the same elements. */
Rooted<TypeObject*> objType(cx, newTypeObject(cx, NULL, JSProto_Array, obj->getProto()));
RootedObject objProto(cx, obj->getProto());
Rooted<TypeObject*> objType(cx, newTypeObject(cx, NULL, JSProto_Array, objProto));
if (!objType) {
cx->compartment->types.setPendingNukeTypes(cx);
return;
@ -2922,9 +2926,8 @@ struct types::ObjectTableEntry
};
void
TypeCompartment::fixObjectType(JSContext *cx, JSObject *obj_)
TypeCompartment::fixObjectType(JSContext *cx, HandleObject obj)
{
RootedObject obj(cx, obj_);
AutoEnterTypeInference enter(cx);
if (!objectTypeTable) {
@ -2981,7 +2984,8 @@ TypeCompartment::fixObjectType(JSContext *cx, JSObject *obj_)
obj->setType(p->value.object);
} else {
/* Make a new type to use for the object and similar future ones. */
TypeObject *objType = newTypeObject(cx, NULL, JSProto_Object, obj->getProto());
RootedObject objProto(cx, obj->getProto());
TypeObject *objType = newTypeObject(cx, NULL, JSProto_Object, objProto);
if (!objType || !objType->addDefiniteProperties(cx, obj)) {
cx->compartment->types.setPendingNukeTypes(cx);
return;
@ -3061,7 +3065,7 @@ TypeObject::getFromPrototypes(JSContext *cx, jsid id, TypeSet *types, bool force
}
static inline void
UpdatePropertyType(JSContext *cx, TypeSet *types, JSObject *obj, Shape *shape, bool force)
UpdatePropertyType(JSContext *cx, TypeSet *types, HandleObject obj, Shape *shape, bool force)
{
types->setOwnProperty(cx, false);
if (!shape->writable())
@ -3103,18 +3107,19 @@ TypeObject::addProperty(JSContext *cx, jsid id, Property **pprop)
* these are not (yet) singletons.
*/
RootedObject rSingleton(cx, singleton);
if (JSID_IS_VOID(id)) {
/* Go through all shapes on the object to get integer-valued properties. */
Shape *shape = singleton->lastProperty();
while (!shape->isEmptyShape()) {
if (JSID_IS_VOID(MakeTypeId(cx, shape->propid())))
UpdatePropertyType(cx, &base->types, singleton, shape, true);
UpdatePropertyType(cx, &base->types, rSingleton, shape, true);
shape = shape->previous();
}
} else if (!JSID_IS_EMPTY(id) && singleton->isNative()) {
Shape *shape = singleton->nativeLookup(cx, id);
if (shape)
UpdatePropertyType(cx, &base->types, singleton, shape, false);
UpdatePropertyType(cx, &base->types, rSingleton, shape, false);
}
if (singleton->watched()) {
@ -3136,7 +3141,7 @@ TypeObject::addProperty(JSContext *cx, jsid id, Property **pprop)
}
bool
TypeObject::addDefiniteProperties(JSContext *cx, JSObject *obj)
TypeObject::addDefiniteProperties(JSContext *cx, HandleObject obj)
{
if (unknownProperties())
return true;
@ -3161,7 +3166,7 @@ TypeObject::addDefiniteProperties(JSContext *cx, JSObject *obj)
}
bool
TypeObject::matchDefiniteProperties(JSObject *obj)
TypeObject::matchDefiniteProperties(HandleObject obj)
{
unsigned count = getPropertyCount();
for (unsigned i = 0; i < count; i++) {
@ -3377,7 +3382,7 @@ TypeObject::clearNewScript(JSContext *cx)
!iter.thisv().toObject().hasLazyType() &&
iter.thisv().toObject().type() == this)
{
JSObject *obj = &iter.thisv().toObject();
RootedObject obj(cx, &iter.thisv().toObject());
/* Whether all identified 'new' properties have been initialized. */
bool finished = false;
@ -3685,11 +3690,9 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
}
break;
case JSOP_OBJECT: {
JSObject *obj = script->getObject(GET_UINT32_INDEX(pc));
pushed[0].addType(cx, Type::ObjectType(obj));
case JSOP_OBJECT:
pushed[0].addType(cx, Type::ObjectType(script->getObject(GET_UINT32_INDEX(pc))));
break;
}
case JSOP_STOP:
/* If a stop is reachable then the return type may be void. */
@ -4009,7 +4012,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
case JSOP_LAMBDA:
case JSOP_DEFFUN: {
JSObject *obj = script->getObject(GET_UINT32_INDEX(pc));
RootedObject obj(cx, script->getObject(GET_UINT32_INDEX(pc)));
TypeSet *res = NULL;
if (op == JSOP_LAMBDA)
@ -4263,7 +4266,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset,
case JSOP_GENERATOR:
if (script->function()) {
if (script->compileAndGo) {
JSObject *proto = script->global().getOrCreateGeneratorPrototype(cx);
RawObject proto = script->global().getOrCreateGeneratorPrototype(cx);
if (!proto)
return false;
TypeObject *object = proto->getNewType(cx);
@ -4533,11 +4536,12 @@ public:
static bool
AnalyzePoppedThis(JSContext *cx, Vector<SSAUseChain *> *pendingPoppedThis,
TypeObject *type, JSFunction *fun, JSObject **pbaseobj,
TypeObject *type, JSFunction *fun, MutableHandleObject pbaseobj,
Vector<TypeNewScript::Initializer> *initializerList);
static bool
AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, JSObject **pbaseobj,
AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun,
MutableHandleObject pbaseobj,
Vector<TypeNewScript::Initializer> *initializerList)
{
/*
@ -4560,7 +4564,7 @@ AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, JSO
JSScript *script = fun->script();
if (!script->ensureRanAnalysis(cx) || !script->ensureRanInference(cx)) {
*pbaseobj = NULL;
pbaseobj.set(NULL);
cx->compartment->types.setPendingNukeTypes(cx);
return false;
}
@ -4605,7 +4609,7 @@ AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, JSO
*/
if (op == JSOP_RETURN || op == JSOP_STOP || op == JSOP_RETRVAL) {
if (offset < lastThisPopped) {
*pbaseobj = NULL;
pbaseobj.set(NULL);
entirelyAnalyzed = false;
break;
}
@ -4617,7 +4621,7 @@ AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, JSO
/* 'this' can escape through a call to eval. */
if (op == JSOP_EVAL) {
if (offset < lastThisPopped)
*pbaseobj = NULL;
pbaseobj.set(NULL);
entirelyAnalyzed = false;
break;
}
@ -4693,7 +4697,7 @@ AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, JSO
static bool
AnalyzePoppedThis(JSContext *cx, Vector<SSAUseChain *> *pendingPoppedThis,
TypeObject *type, JSFunction *fun, JSObject **pbaseobj,
TypeObject *type, JSFunction *fun, MutableHandleObject pbaseobj,
Vector<TypeNewScript::Initializer> *initializerList)
{
JSScript *script = fun->script();
@ -4706,8 +4710,6 @@ AnalyzePoppedThis(JSContext *cx, Vector<SSAUseChain *> *pendingPoppedThis,
jsbytecode *pc = script->code + uses->offset;
JSOp op = JSOp(*pc);
RootedObject obj(cx, *pbaseobj);
if (op == JSOP_SETPROP && uses->u.which == 1) {
/*
* Don't use GetAtomId here, we need to watch for SETPROP on
@ -4725,7 +4727,7 @@ AnalyzePoppedThis(JSContext *cx, Vector<SSAUseChain *> *pendingPoppedThis,
* a permanent property in any transitive prototype, the definite
* properties get cleared from the shape.
*/
JSObject *parent = type->proto;
RootedObject parent(cx, type->proto);
while (parent) {
TypeObject *parentObject = parent->getType(cx);
if (parentObject->unknownProperties())
@ -4737,21 +4739,21 @@ AnalyzePoppedThis(JSContext *cx, Vector<SSAUseChain *> *pendingPoppedThis,
parent = parent->getProto();
}
unsigned slotSpan = obj->slotSpan();
unsigned slotSpan = pbaseobj->slotSpan();
RootedValue value(cx, UndefinedValue());
if (!DefineNativeProperty(cx, obj, id, value, NULL, NULL,
if (!DefineNativeProperty(cx, pbaseobj, id, value, NULL, NULL,
JSPROP_ENUMERATE, 0, 0, DNP_SKIP_TYPE)) {
cx->compartment->types.setPendingNukeTypes(cx);
*pbaseobj = NULL;
pbaseobj.set(NULL);
return false;
}
if (obj->inDictionaryMode()) {
*pbaseobj = NULL;
if (pbaseobj->inDictionaryMode()) {
pbaseobj.set(NULL);
return false;
}
if (obj->slotSpan() == slotSpan) {
if (pbaseobj->slotSpan() == slotSpan) {
/* Set a duplicate property. */
return false;
}
@ -4759,11 +4761,11 @@ AnalyzePoppedThis(JSContext *cx, Vector<SSAUseChain *> *pendingPoppedThis,
TypeNewScript::Initializer setprop(TypeNewScript::Initializer::SETPROP, uses->offset);
if (!initializerList->append(setprop)) {
cx->compartment->types.setPendingNukeTypes(cx);
*pbaseobj = NULL;
pbaseobj.set(NULL);
return false;
}
if (obj->slotSpan() >= (TYPE_FLAG_DEFINITE_MASK >> TYPE_FLAG_DEFINITE_SHIFT)) {
if (pbaseobj->slotSpan() >= (TYPE_FLAG_DEFINITE_MASK >> TYPE_FLAG_DEFINITE_SHIFT)) {
/* Maximum number of definite properties added. */
return false;
}
@ -4799,15 +4801,17 @@ AnalyzePoppedThis(JSContext *cx, Vector<SSAUseChain *> *pendingPoppedThis,
StackTypeSet *scriptTypes = analysis->poppedTypes(pc, GET_ARGC(pc));
/* Need to definitely be calling Function.call on a specific script. */
JSObject *funcallObj = funcallTypes->getSingleton();
JSObject *scriptObj = scriptTypes->getSingleton();
if (!funcallObj || !scriptObj || !scriptObj->isFunction() ||
!scriptObj->toFunction()->isInterpreted()) {
return false;
JSFunction *function;
{
RawObject funcallObj = funcallTypes->getSingleton();
RawObject scriptObj = scriptTypes->getSingleton();
if (!funcallObj || !scriptObj || !scriptObj->isFunction() ||
!scriptObj->toFunction()->isInterpreted()) {
return false;
}
function = scriptObj->toFunction();
}
JSFunction *function = scriptObj->toFunction();
/*
* Generate constraints to clear definite properties from the type
* should the Function.call or callee itself change in the future.
@ -4820,7 +4824,7 @@ AnalyzePoppedThis(JSContext *cx, Vector<SSAUseChain *> *pendingPoppedThis,
TypeNewScript::Initializer pushframe(TypeNewScript::Initializer::FRAME_PUSH, uses->offset);
if (!initializerList->append(pushframe)) {
cx->compartment->types.setPendingNukeTypes(cx);
*pbaseobj = NULL;
pbaseobj.set(NULL);
return false;
}
@ -4832,7 +4836,7 @@ AnalyzePoppedThis(JSContext *cx, Vector<SSAUseChain *> *pendingPoppedThis,
TypeNewScript::Initializer popframe(TypeNewScript::Initializer::FRAME_POP, 0);
if (!initializerList->append(popframe)) {
cx->compartment->types.setPendingNukeTypes(cx);
*pbaseobj = NULL;
pbaseobj.set(NULL);
return false;
}
@ -4869,7 +4873,7 @@ CheckNewScriptProperties(JSContext *cx, HandleTypeObject type, JSFunction *fun)
}
Vector<TypeNewScript::Initializer> initializerList(cx);
AnalyzeNewScriptProperties(cx, type, fun, baseobj.address(), &initializerList);
AnalyzeNewScriptProperties(cx, type, fun, &baseobj, &initializerList);
if (!baseobj || baseobj->slotSpan() == 0 || !!(type->flags & OBJECT_FLAG_NEW_SCRIPT_CLEARED)) {
if (type->newScript)
type->clearNewScript(cx);
@ -5130,8 +5134,7 @@ MarkIteratorUnknownSlow(JSContext *cx)
}
void
TypeMonitorCallSlow(JSContext *cx, JSObject *callee,
const CallArgs &args, bool constructing)
TypeMonitorCallSlow(JSContext *cx, HandleObject callee, const CallArgs &args, bool constructing)
{
unsigned nargs = callee->toFunction()->nargs;
JSScript *script = callee->toFunction()->script();
@ -5513,8 +5516,9 @@ JSFunction::setTypeForScriptedFunction(JSContext *cx, HandleFunction fun, bool s
* should not be used by scripts or appear in type sets.
*/
} else {
RootedObject funProto(cx, fun->getProto());
TypeObject *type = cx->compartment->types.newTypeObject(cx, fun->script(),
JSProto_Function, fun->getProto());
JSProto_Function, funProto);
if (!type)
return false;
@ -5581,11 +5585,10 @@ JSObject::shouldSplicePrototype(JSContext *cx)
}
bool
JSObject::splicePrototype(JSContext *cx, JSObject *proto_)
JSObject::splicePrototype(JSContext *cx, HandleObject proto)
{
JS_ASSERT(cx->compartment == compartment());
RootedObject proto(cx, proto_);
RootedObject self(cx, this);
/*
@ -5649,7 +5652,8 @@ JSObject::makeLazyType(JSContext *cx)
RootedObject self(cx, this);
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(getClass());
TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL, key, getProto());
RootedObject proto(cx, getProto());
TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL, key, proto);
AutoAssertNoGC nogc;
if (!type) {
if (cx->typeInferenceEnabled())
@ -5708,13 +5712,13 @@ JSObject::makeLazyType(JSContext *cx)
}
/* static */ inline HashNumber
TypeObjectEntry::hash(JSObject *proto)
TypeObjectEntry::hash(RawObject proto)
{
return PointerHasher<JSObject *, 3>::hash(proto);
}
/* static */ inline bool
TypeObjectEntry::match(TypeObject *key, JSObject *lookup)
TypeObjectEntry::match(TypeObject *key, RawObject lookup)
{
return key->proto == lookup;
}
@ -5844,12 +5848,11 @@ JSObject::getNewType(JSContext *cx, JSFunction *fun_, bool isDOM)
}
TypeObject *
JSCompartment::getLazyType(JSContext *cx, JSObject *proto_)
JSCompartment::getLazyType(JSContext *cx, HandleObject proto)
{
JS_ASSERT(cx->compartment == this);
JS_ASSERT_IF(proto_, cx->compartment == proto_->compartment());
JS_ASSERT_IF(proto, cx->compartment == proto->compartment());
RootedObject proto(cx, proto_);
MaybeCheckStackRoots(cx);
TypeObjectSet &table = cx->compartment->lazyTypeObjects;

View File

@ -96,7 +96,7 @@ class Type
return isObject() && !!(data & 1);
}
inline JSObject *singleObject() const;
inline RawObject singleObject() const;
/* Accessors for TypeObject types */
@ -124,7 +124,7 @@ class Type
return Type(type);
}
static inline Type ObjectType(JSObject *obj);
static inline Type ObjectType(RawObject obj);
static inline Type ObjectType(TypeObject *obj);
static inline Type ObjectType(TypeObjectKey *obj);
};
@ -408,7 +408,7 @@ class TypeSet
*/
inline unsigned getObjectCount();
inline TypeObjectKey *getObject(unsigned i);
inline JSObject *getSingleObject(unsigned i);
inline RawObject getSingleObject(unsigned i);
inline TypeObject *getTypeObject(unsigned i);
void setOwnProperty(bool configurable) {
@ -503,7 +503,7 @@ class StackTypeSet : public TypeSet
int getTypedArrayType();
/* Get the single value which can appear in this type set, otherwise NULL. */
JSObject *getSingleton();
RawObject getSingleton();
/* Whether any objects in the type set needs a barrier on id. */
bool propertyNeedsBarrier(JSContext *cx, jsid id);
@ -566,7 +566,7 @@ class HeapTypeSet : public TypeSet
bool knownSubset(JSContext *cx, TypeSet *other);
/* Get the single value which can appear in this type set, otherwise NULL. */
JSObject *getSingleton(JSContext *cx);
RawObject getSingleton(JSContext *cx);
/*
* Whether a location with this TypeSet needs a write barrier (i.e., whether
@ -806,7 +806,7 @@ struct TypeObject : gc::Cell
* object whose type has not been constructed yet.
*/
static const size_t LAZY_SINGLETON = 1;
bool lazy() const { return singleton == (JSObject *) LAZY_SINGLETON; }
bool lazy() const { return singleton == (RawObject) LAZY_SINGLETON; }
/* Flags for this object. */
TypeObjectFlags flags;
@ -871,7 +871,7 @@ struct TypeObject : gc::Cell
void *padding;
#endif
inline TypeObject(JSObject *proto, bool isFunction, bool unknown);
inline TypeObject(RawObject proto, bool isFunction, bool unknown);
bool isFunction() { return !!(flags & OBJECT_FLAG_FUNCTION); }
@ -916,8 +916,8 @@ struct TypeObject : gc::Cell
/* Helpers */
bool addProperty(JSContext *cx, jsid id, Property **pprop);
bool addDefiniteProperties(JSContext *cx, JSObject *obj);
bool matchDefiniteProperties(JSObject *obj);
bool addDefiniteProperties(JSContext *cx, HandleObject obj);
bool matchDefiniteProperties(HandleObject obj);
void addPrototype(JSContext *cx, TypeObject *proto);
void addPropertyType(JSContext *cx, jsid id, Type type);
void addPropertyType(JSContext *cx, jsid id, const Value &value);
@ -969,8 +969,8 @@ struct TypeObjectEntry
{
typedef JSObject *Lookup;
static inline HashNumber hash(JSObject *base);
static inline bool match(TypeObject *key, JSObject *lookup);
static inline HashNumber hash(RawObject base);
static inline bool match(TypeObject *key, RawObject lookup);
};
typedef HashSet<ReadBarriered<TypeObject>, TypeObjectEntry, SystemAllocPolicy> TypeObjectSet;
@ -1084,7 +1084,7 @@ class TypeScript
static inline void Monitor(JSContext *cx, const js::Value &rval);
/* Monitor an assignment at a SETELEM on a non-integer identifier. */
static inline void MonitorAssign(JSContext *cx, JSObject *obj, jsid id);
static inline void MonitorAssign(JSContext *cx, HandleObject obj, jsid id);
/* Add a type for a variable in a script. */
static inline void SetThis(JSContext *cx, JSScript *script, Type type);
@ -1224,8 +1224,8 @@ struct TypeCompartment
ArrayTypeTable *arrayTypeTable;
ObjectTypeTable *objectTypeTable;
void fixArrayType(JSContext *cx, JSObject *obj);
void fixObjectType(JSContext *cx, JSObject *obj);
void fixArrayType(JSContext *cx, HandleObject obj);
void fixObjectType(JSContext *cx, HandleObject obj);
/* Logging fields */
@ -1256,7 +1256,7 @@ struct TypeCompartment
* js_ObjectClass).
*/
TypeObject *newTypeObject(JSContext *cx, JSScript *script,
JSProtoKey kind, JSObject *proto,
JSProtoKey kind, HandleObject proto,
bool unknown = false, bool isDOM = false);
/* Get or make an object for an allocation site, and add to the allocation site table. */

View File

@ -108,7 +108,7 @@ RecompileInfo::compilerOutput(JSContext *cx) const
/////////////////////////////////////////////////////////////////////
/* static */ inline Type
Type::ObjectType(JSObject *obj)
Type::ObjectType(RawObject obj)
{
if (obj->hasSingletonType())
return Type(uintptr_t(obj) | 1);
@ -451,7 +451,7 @@ MarkIteratorUnknown(JSContext *cx)
inline bool
TypeMonitorCall(JSContext *cx, const js::CallArgs &args, bool constructing)
{
extern void TypeMonitorCallSlow(JSContext *cx, JSObject *callee,
extern void TypeMonitorCallSlow(JSContext *cx, HandleObject callee,
const CallArgs &args, bool constructing);
RootedObject callee(cx, &args.callee());
@ -470,7 +470,7 @@ TypeMonitorCall(JSContext *cx, const js::CallArgs &args, bool constructing)
}
inline bool
TrackPropertyTypes(JSContext *cx, JSObject *obj, jsid id)
TrackPropertyTypes(JSContext *cx, HandleObject obj, jsid id)
{
if (!cx->typeInferenceEnabled() || obj->hasLazyType() || obj->type()->unknownProperties())
return false;
@ -483,7 +483,7 @@ TrackPropertyTypes(JSContext *cx, JSObject *obj, jsid id)
/* Add a possible type for a property of obj. */
inline void
AddTypePropertyId(JSContext *cx, JSObject *obj, jsid id, Type type)
AddTypePropertyId(JSContext *cx, HandleObject obj, jsid id, Type type)
{
if (cx->typeInferenceEnabled())
id = MakeTypeId(cx, id);
@ -492,7 +492,7 @@ AddTypePropertyId(JSContext *cx, JSObject *obj, jsid id, Type type)
}
inline void
AddTypePropertyId(JSContext *cx, JSObject *obj, jsid id, const Value &value)
AddTypePropertyId(JSContext *cx, HandleObject obj, jsid id, const Value &value)
{
if (cx->typeInferenceEnabled())
id = MakeTypeId(cx, id);
@ -516,7 +516,7 @@ AddTypeProperty(JSContext *cx, TypeObject *obj, const char *name, const Value &v
/* Set one or more dynamic flags on a type object. */
inline void
MarkTypeObjectFlags(JSContext *cx, JSObject *obj, TypeObjectFlags flags)
MarkTypeObjectFlags(JSContext *cx, RawObject obj, TypeObjectFlags flags)
{
if (cx->typeInferenceEnabled() && !obj->hasLazyType() && !obj->type()->hasAllFlags(flags))
obj->type()->setFlags(cx, flags);
@ -545,7 +545,7 @@ MarkTypeObjectUnknownProperties(JSContext *cx, TypeObject *obj,
* have a getter/setter.
*/
inline void
MarkTypePropertyConfigured(JSContext *cx, JSObject *obj, jsid id)
MarkTypePropertyConfigured(JSContext *cx, HandleObject obj, jsid id)
{
if (cx->typeInferenceEnabled())
id = MakeTypeId(cx, id);
@ -555,7 +555,7 @@ MarkTypePropertyConfigured(JSContext *cx, JSObject *obj, jsid id)
/* Mark a state change on a particular object. */
inline void
MarkObjectStateChange(JSContext *cx, JSObject *obj)
MarkObjectStateChange(JSContext *cx, HandleObject obj)
{
if (cx->typeInferenceEnabled() && !obj->hasLazyType() && !obj->type()->unknownProperties())
obj->type()->markStateChange(cx);
@ -567,14 +567,14 @@ MarkObjectStateChange(JSContext *cx, JSObject *obj)
*/
inline void
FixArrayType(JSContext *cx, JSObject *obj)
FixArrayType(JSContext *cx, HandleObject obj)
{
if (cx->typeInferenceEnabled())
cx->compartment->types.fixArrayType(cx, obj);
}
inline void
FixObjectType(JSContext *cx, JSObject *obj)
FixObjectType(JSContext *cx, HandleObject obj)
{
if (cx->typeInferenceEnabled())
cx->compartment->types.fixObjectType(cx, obj);
@ -863,7 +863,7 @@ TypeScript::Monitor(JSContext *cx, const js::Value &rval)
}
/* static */ inline void
TypeScript::MonitorAssign(JSContext *cx, JSObject *obj, jsid id)
TypeScript::MonitorAssign(JSContext *cx, HandleObject obj, jsid id)
{
if (cx->typeInferenceEnabled() && !obj->hasSingletonType()) {
/*
@ -1194,7 +1194,7 @@ Type::objectKey() const
return (TypeObjectKey *) data;
}
inline JSObject *
inline RawObject
Type::singleObject() const
{
JS_ASSERT(isSingleObject());
@ -1368,7 +1368,7 @@ TypeSet::getObject(unsigned i)
return objectSet[i];
}
inline JSObject *
inline RawObject
TypeSet::getSingleObject(unsigned i)
{
TypeObjectKey *key = getObject(i);
@ -1400,7 +1400,7 @@ TypeCallsite::TypeCallsite(JSContext *cx, JSScript *script, jsbytecode *pc,
// TypeObject
/////////////////////////////////////////////////////////////////////
inline TypeObject::TypeObject(JSObject *proto, bool function, bool unknown)
inline TypeObject::TypeObject(RawObject proto, bool function, bool unknown)
{
PodZero(this);

View File

@ -334,7 +334,7 @@ SetPropertyOperation(JSContext *cx, jsbytecode *pc, HandleValue lval, HandleValu
if (shape->hasDefaultSetter() && shape->hasSlot()) {
/* Fast path for, e.g., plain Object instance properties. */
obj->nativeSetSlotWithType(cx, shape, rval);
JSObject::nativeSetSlotWithType(cx, obj, shape, rval);
} else {
RootedValue rref(cx, rval);
bool strict = cx->stack.currentScript()->strictModeCode;
@ -803,9 +803,9 @@ SetObjectElementOperation(JSContext *cx, Handle<JSObject*> obj, HandleId id, con
if (js_PrototypeHasIndexedProperties(cx, obj))
break;
if ((uint32_t)i >= obj->getArrayLength())
obj->setArrayLength(cx, i + 1);
JSObject::setArrayLength(cx, obj, i + 1);
}
obj->setDenseArrayElementWithType(cx, i, value);
JSObject::setDenseArrayElementWithType(cx, obj, i, value);
return true;
} else {
if (!cx->fp()->beginsIonActivation()) {

View File

@ -1591,7 +1591,7 @@ DefinePropertyOnArray(JSContext *cx, HandleObject obj, HandleId id, const PropDe
if (index >= oldLen) {
JS_ASSERT(index != UINT32_MAX);
obj->setArrayLength(cx, index + 1);
JSObject::setArrayLength(cx, obj, index + 1);
}
*rval = true;
@ -1920,7 +1920,7 @@ JSObject::sealOrFreeze(JSContext *cx, HandleObject obj, ImmutabilityType it)
}
JS_ASSERT(obj->lastProperty()->slotSpan() == last->slotSpan());
JS_ALWAYS_TRUE(obj->setLastProperty(cx, last));
JS_ALWAYS_TRUE(setLastProperty(cx, obj, last));
} else {
RootedId id(cx);
for (size_t i = 0; i < props.length(); i++) {
@ -2332,9 +2332,10 @@ CreateThisForFunctionWithType(JSContext *cx, HandleTypeObject type, JSObject *pa
* object before it is read from.
*/
gc::AllocKind kind = type->newScript->allocKind;
JSObject *res = NewObjectWithType(cx, type, parent, kind);
RootedObject res(cx, NewObjectWithType(cx, type, parent, kind));
if (res)
JS_ALWAYS_TRUE(res->setLastProperty(cx, (Shape *) type->newScript->shape.get()));
JS_ALWAYS_TRUE(JSObject::setLastProperty(cx, res,
(Shape *) type->newScript->shape.get()));
return res;
}
@ -2383,7 +2384,7 @@ js_CreateThisForFunction(JSContext *cx, HandleObject callee, bool newType)
* Reshape the object and give it a (lazily instantiated) singleton
* type before passing it as the 'this' value for the call.
*/
nobj->clear(cx);
JSObject::clear(cx, nobj);
if (!JSObject::setSingletonType(cx, nobj))
return NULL;
@ -3185,54 +3186,54 @@ js_InitClass(JSContext *cx, HandleObject obj, JSObject *protoProto_,
ps, fs, static_ps, static_fs, ctorp, ctorKind);
}
inline bool
JSObject::updateSlotsForSpan(JSContext *cx, size_t oldSpan, size_t newSpan)
/* static */ inline bool
JSObject::updateSlotsForSpan(JSContext *cx, HandleObject obj, size_t oldSpan, size_t newSpan)
{
JS_ASSERT(oldSpan != newSpan);
size_t oldCount = dynamicSlotsCount(numFixedSlots(), oldSpan);
size_t newCount = dynamicSlotsCount(numFixedSlots(), newSpan);
size_t oldCount = dynamicSlotsCount(obj->numFixedSlots(), oldSpan);
size_t newCount = dynamicSlotsCount(obj->numFixedSlots(), newSpan);
if (oldSpan < newSpan) {
if (oldCount < newCount && !growSlots(cx, oldCount, newCount))
if (oldCount < newCount && !JSObject::growSlots(cx, obj, oldCount, newCount))
return false;
if (newSpan == oldSpan + 1)
initSlotUnchecked(oldSpan, UndefinedValue());
obj->initSlotUnchecked(oldSpan, UndefinedValue());
else
initializeSlotRange(oldSpan, newSpan - oldSpan);
obj->initializeSlotRange(oldSpan, newSpan - oldSpan);
} else {
/* Trigger write barriers on the old slots before reallocating. */
prepareSlotRangeForOverwrite(newSpan, oldSpan);
invalidateSlotRange(newSpan, oldSpan - newSpan);
obj->prepareSlotRangeForOverwrite(newSpan, oldSpan);
obj->invalidateSlotRange(newSpan, oldSpan - newSpan);
if (oldCount > newCount)
shrinkSlots(cx, oldCount, newCount);
JSObject::shrinkSlots(cx, obj, oldCount, newCount);
}
return true;
}
bool
JSObject::setLastProperty(JSContext *cx, js::Shape *shape)
/* static */ bool
JSObject::setLastProperty(JSContext *cx, HandleObject obj, js::Shape *shape)
{
JS_ASSERT(!inDictionaryMode());
JS_ASSERT(!obj->inDictionaryMode());
JS_ASSERT(!shape->inDictionary());
JS_ASSERT(shape->compartment() == compartment());
JS_ASSERT(shape->numFixedSlots() == numFixedSlots());
JS_ASSERT(shape->compartment() == obj->compartment());
JS_ASSERT(shape->numFixedSlots() == obj->numFixedSlots());
size_t oldSpan = lastProperty()->slotSpan();
size_t oldSpan = obj->lastProperty()->slotSpan();
size_t newSpan = shape->slotSpan();
if (oldSpan == newSpan) {
shape_ = shape;
obj->shape_ = shape;
return true;
}
if (!updateSlotsForSpan(cx, oldSpan, newSpan))
if (!updateSlotsForSpan(cx, obj, oldSpan, newSpan))
return false;
shape_ = shape;
obj->shape_ = shape;
return true;
}
@ -3247,19 +3248,20 @@ JSObject::setSlotSpan(JSContext *cx, uint32_t span)
if (oldSpan == span)
return true;
if (!updateSlotsForSpan(cx, oldSpan, span))
RootedObject self(cx, this);
if (!JSObject::updateSlotsForSpan(cx, self, oldSpan, span))
return false;
base->setSlotSpan(span);
return true;
}
bool
JSObject::growSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount)
/* static */ bool
JSObject::growSlots(JSContext *cx, HandleObject obj, uint32_t oldCount, uint32_t newCount)
{
JS_ASSERT(newCount > oldCount);
JS_ASSERT(newCount >= SLOT_CAPACITY_MIN);
JS_ASSERT(!isDenseArray());
JS_ASSERT(!obj->isDenseArray());
/*
* Slot capacities are determined by the span of allocated objects. Due to
@ -3268,7 +3270,7 @@ JSObject::growSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount)
*/
JS_ASSERT(newCount < NELEMENTS_LIMIT);
size_t oldSize = Probes::objectResizeActive() ? computedSizeOfThisSlotsElements() : 0;
size_t oldSize = Probes::objectResizeActive() ? obj->computedSizeOfThisSlotsElements() : 0;
size_t newSize = oldSize + (newCount - oldCount) * sizeof(Value);
/*
@ -3277,60 +3279,59 @@ JSObject::growSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount)
* type to give these objects a larger number of fixed slots when future
* objects are constructed.
*/
if (!hasLazyType() && !oldCount && type()->newScript) {
gc::AllocKind kind = type()->newScript->allocKind;
if (!obj->hasLazyType() && !oldCount && obj->type()->newScript) {
gc::AllocKind kind = obj->type()->newScript->allocKind;
unsigned newScriptSlots = gc::GetGCKindSlots(kind);
if (newScriptSlots == numFixedSlots() && gc::TryIncrementAllocKind(&kind)) {
if (newScriptSlots == obj->numFixedSlots() && gc::TryIncrementAllocKind(&kind)) {
AutoEnterTypeInference enter(cx);
Rooted<TypeObject*> typeObj(cx, type());
Rooted<TypeObject*> typeObj(cx, obj->type());
RootedShape shape(cx, typeObj->newScript->shape);
JSObject *obj = NewReshapedObject(cx, typeObj,
getParent(), kind, shape);
if (!obj)
JSObject *reshapedObj = NewReshapedObject(cx, typeObj, obj->getParent(), kind, shape);
if (!reshapedObj)
return false;
typeObj->newScript->allocKind = kind;
typeObj->newScript->shape = obj->lastProperty();
typeObj->newScript->shape = reshapedObj->lastProperty();
typeObj->markStateChange(cx);
}
}
if (!oldCount) {
slots = cx->pod_malloc<HeapSlot>(newCount);
if (!slots)
obj->slots = cx->pod_malloc<HeapSlot>(newCount);
if (!obj->slots)
return false;
Debug_SetSlotRangeToCrashOnTouch(slots, newCount);
Debug_SetSlotRangeToCrashOnTouch(obj->slots, newCount);
if (Probes::objectResizeActive())
Probes::resizeObject(cx, this, oldSize, newSize);
Probes::resizeObject(cx, obj, oldSize, newSize);
return true;
}
HeapSlot *newslots = (HeapSlot*) cx->realloc_(slots, oldCount * sizeof(HeapSlot),
HeapSlot *newslots = (HeapSlot*) cx->realloc_(obj->slots, oldCount * sizeof(HeapSlot),
newCount * sizeof(HeapSlot));
if (!newslots)
return false; /* Leave slots at its old size. */
bool changed = slots != newslots;
slots = newslots;
bool changed = obj->slots != newslots;
obj->slots = newslots;
Debug_SetSlotRangeToCrashOnTouch(slots + oldCount, newCount - oldCount);
Debug_SetSlotRangeToCrashOnTouch(obj->slots + oldCount, newCount - oldCount);
/* Changes in the slots of global objects can trigger recompilation. */
if (changed && isGlobal())
types::MarkObjectStateChange(cx, this);
if (changed && obj->isGlobal())
types::MarkObjectStateChange(cx, obj);
if (Probes::objectResizeActive())
Probes::resizeObject(cx, this, oldSize, newSize);
Probes::resizeObject(cx, obj, oldSize, newSize);
return true;
}
void
JSObject::shrinkSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount)
/* static */ void
JSObject::shrinkSlots(JSContext *cx, HandleObject obj, uint32_t oldCount, uint32_t newCount)
{
JS_ASSERT(newCount < oldCount);
JS_ASSERT(!isDenseArray());
JS_ASSERT(!obj->isDenseArray());
/*
* Refuse to shrink slots for call objects. This only happens in a very
@ -3338,35 +3339,35 @@ JSObject::shrinkSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount)
* allowing the slots pointer to change may require updating pointers in
* the function's active args/vars information.
*/
if (isCall())
if (obj->isCall())
return;
size_t oldSize = Probes::objectResizeActive() ? computedSizeOfThisSlotsElements() : 0;
size_t oldSize = Probes::objectResizeActive() ? obj->computedSizeOfThisSlotsElements() : 0;
size_t newSize = oldSize - (oldCount - newCount) * sizeof(Value);
if (newCount == 0) {
js_free(slots);
slots = NULL;
js_free(obj->slots);
obj->slots = NULL;
if (Probes::objectResizeActive())
Probes::resizeObject(cx, this, oldSize, newSize);
Probes::resizeObject(cx, obj, oldSize, newSize);
return;
}
JS_ASSERT(newCount >= SLOT_CAPACITY_MIN);
HeapSlot *newslots = (HeapSlot *) cx->realloc_(slots, newCount * sizeof(HeapSlot));
HeapSlot *newslots = (HeapSlot *) cx->realloc_(obj->slots, newCount * sizeof(HeapSlot));
if (!newslots)
return; /* Leave slots at its old size. */
bool changed = slots != newslots;
slots = newslots;
bool changed = obj->slots != newslots;
obj->slots = newslots;
/* Watch for changes in global object slots, as for growSlots. */
if (changed && isGlobal())
types::MarkObjectStateChange(cx, this);
if (changed && obj->isGlobal())
types::MarkObjectStateChange(cx, obj);
if (Probes::objectResizeActive())
Probes::resizeObject(cx, this, oldSize, newSize);
Probes::resizeObject(cx, obj, oldSize, newSize);
}
bool
@ -3856,7 +3857,7 @@ CallAddPropertyHook(JSContext *cx, Class *clasp, HandleObject obj, HandleShape s
return false;
if (value.get() != nominal) {
if (shape->hasSlot())
obj->nativeSetSlotWithType(cx, shape, value);
JSObject::nativeSetSlotWithType(cx, obj, shape, value);
}
}
return true;

View File

@ -279,7 +279,7 @@ struct JSObject : public js::ObjectImpl
* Update the last property, keeping the number of allocated slots in sync
* with the object's new slot span.
*/
bool setLastProperty(JSContext *cx, js::Shape *shape);
static bool setLastProperty(JSContext *cx, js::HandleObject obj, js::Shape *shape);
/* As above, but does not change the slot span. */
inline void setLastPropertyInfallible(js::Shape *shape);
@ -394,13 +394,16 @@ struct JSObject : public js::ObjectImpl
* The number of allocated slots is not stored explicitly, and changes to
* the slots must track changes in the slot span.
*/
bool growSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount);
void shrinkSlots(JSContext *cx, uint32_t oldCount, uint32_t newCount);
static bool growSlots(JSContext *cx, js::HandleObject obj, uint32_t oldCount,
uint32_t newCount);
static void shrinkSlots(JSContext *cx, js::HandleObject obj, uint32_t oldCount,
uint32_t newCount);
bool hasDynamicSlots() const { return slots != NULL; }
protected:
inline bool updateSlotsForSpan(JSContext *cx, size_t oldSpan, size_t newSpan);
static inline bool updateSlotsForSpan(JSContext *cx, js::HandleObject obj, size_t oldSpan,
size_t newSpan);
public:
/*
@ -413,7 +416,8 @@ struct JSObject : public js::ObjectImpl
void rollbackProperties(JSContext *cx, uint32_t slotSpan);
inline void nativeSetSlot(unsigned slot, const js::Value &value);
inline void nativeSetSlotWithType(JSContext *cx, js::Shape *shape, const js::Value &value);
static inline void nativeSetSlotWithType(JSContext *cx, js::HandleObject, js::Shape *shape,
const js::Value &value);
inline const js::Value &getReservedSlot(unsigned index) const;
inline js::HeapSlot &getReservedSlotRef(unsigned index);
@ -456,7 +460,7 @@ struct JSObject : public js::ObjectImpl
bool setNewTypeUnknown(JSContext *cx);
/* Set a new prototype for an object with a singleton type. */
bool splicePrototype(JSContext *cx, JSObject *proto);
bool splicePrototype(JSContext *cx, js::HandleObject proto);
/*
* For bootstrapping, whether to splice a prototype for Function.prototype
@ -555,7 +559,7 @@ struct JSObject : public js::ObjectImpl
bool allocateSlowArrayElements(JSContext *cx);
inline uint32_t getArrayLength() const;
inline void setArrayLength(JSContext *cx, uint32_t length);
static inline void setArrayLength(JSContext *cx, js::HandleObject obj, uint32_t length);
inline uint32_t getDenseArrayCapacity();
inline void setDenseArrayLength(uint32_t length);
@ -563,8 +567,10 @@ struct JSObject : public js::ObjectImpl
inline void ensureDenseArrayInitializedLength(JSContext *cx, unsigned index, unsigned extra);
inline void setDenseArrayElement(unsigned idx, const js::Value &val);
inline void initDenseArrayElement(unsigned idx, const js::Value &val);
inline void setDenseArrayElementWithType(JSContext *cx, unsigned idx, const js::Value &val);
inline void initDenseArrayElementWithType(JSContext *cx, unsigned idx, const js::Value &val);
static inline void setDenseArrayElementWithType(JSContext *cx, js::HandleObject obj,
unsigned idx, const js::Value &val);
static inline void initDenseArrayElementWithType(JSContext *cx, js::HandleObject obj,
unsigned idx, const js::Value &val);
inline void copyDenseArrayElements(unsigned dstStart, const js::Value *src, unsigned count);
inline void initDenseArrayElements(unsigned dstStart, const js::Value *src, unsigned count);
inline void moveDenseArrayElements(unsigned dstStart, unsigned srcStart, unsigned count);
@ -782,7 +788,7 @@ struct JSObject : public js::ObjectImpl
bool removeProperty(JSContext *cx, jsid id);
/* Clear the scope, making it empty. */
void clear(JSContext *cx);
static void clear(JSContext *cx, js::HandleObject obj);
static inline JSBool lookupGeneric(JSContext *cx, js::HandleObject obj,
js::HandleId id,

View File

@ -284,7 +284,8 @@ inline void
JSObject::removeLastProperty(JSContext *cx)
{
JS_ASSERT(canRemoveLastProperty());
JS_ALWAYS_TRUE(setLastProperty(cx, lastProperty()->previous()));
js::RootedObject self(cx, this);
JS_ALWAYS_TRUE(setLastProperty(cx, self, lastProperty()->previous()));
}
inline bool
@ -361,25 +362,25 @@ JSObject::getArrayLength() const
return getElementsHeader()->length;
}
inline void
JSObject::setArrayLength(JSContext *cx, uint32_t length)
/* static */ inline void
JSObject::setArrayLength(JSContext *cx, js::HandleObject obj, uint32_t length)
{
JS_ASSERT(isArray());
JS_ASSERT(obj->isArray());
if (length > INT32_MAX) {
/*
* Mark the type of this object as possibly not a dense array, per the
* requirements of OBJECT_FLAG_NON_DENSE_ARRAY.
*/
js::types::MarkTypeObjectFlags(cx, this,
js::types::MarkTypeObjectFlags(cx, obj,
js::types::OBJECT_FLAG_NON_PACKED_ARRAY |
js::types::OBJECT_FLAG_NON_DENSE_ARRAY);
jsid lengthId = js::NameToId(cx->names().length);
js::types::AddTypePropertyId(cx, this, lengthId,
js::types::AddTypePropertyId(cx, obj, lengthId,
js::types::Type::DoubleType());
}
getElementsHeader()->length = length;
obj->getElementsHeader()->length = length;
}
inline void
@ -437,18 +438,20 @@ JSObject::initDenseArrayElement(unsigned idx, const js::Value &val)
elements[idx].init(this, idx, val);
}
inline void
JSObject::setDenseArrayElementWithType(JSContext *cx, unsigned idx, const js::Value &val)
/* static */ inline void
JSObject::setDenseArrayElementWithType(JSContext *cx, js::HandleObject obj, unsigned idx,
const js::Value &val)
{
js::types::AddTypePropertyId(cx, this, JSID_VOID, val);
setDenseArrayElement(idx, val);
js::types::AddTypePropertyId(cx, obj, JSID_VOID, val);
obj->setDenseArrayElement(idx, val);
}
inline void
JSObject::initDenseArrayElementWithType(JSContext *cx, unsigned idx, const js::Value &val)
/* static */ inline void
JSObject::initDenseArrayElementWithType(JSContext *cx, js::HandleObject obj, unsigned idx,
const js::Value &val)
{
js::types::AddTypePropertyId(cx, this, JSID_VOID, val);
initDenseArrayElement(idx, val);
js::types::AddTypePropertyId(cx, obj, JSID_VOID, val);
obj->initDenseArrayElement(idx, val);
}
inline void
@ -652,7 +655,8 @@ JSObject::setSingletonType(JSContext *cx, js::HandleObject obj)
JS_ASSERT(!obj->hasLazyType());
JS_ASSERT_IF(obj->getProto(), obj->type() == obj->getProto()->getNewType(cx, NULL));
js::types::TypeObject *type = cx->compartment->getLazyType(cx, obj->getProto());
js::RootedObject objProto(cx, obj->getProto());
js::types::TypeObject *type = cx->compartment->getLazyType(cx, objProto);
if (!type)
return false;
@ -923,11 +927,12 @@ JSObject::nativeSetSlot(unsigned slot, const js::Value &value)
return setSlot(slot, value);
}
inline void
JSObject::nativeSetSlotWithType(JSContext *cx, js::Shape *shape, const js::Value &value)
/* static */ inline void
JSObject::nativeSetSlotWithType(JSContext *cx, js::HandleObject obj, js::Shape *shape,
const js::Value &value)
{
nativeSetSlot(shape->slot(), value);
js::types::AddTypePropertyId(cx, this, shape->propid(), value);
obj->nativeSetSlot(shape->slot(), value);
js::types::AddTypePropertyId(cx, obj, shape->propid(), value);
}
inline bool
@ -1473,12 +1478,12 @@ CopyInitializerObject(JSContext *cx, HandleObject baseobj)
gc::AllocKind kind = gc::GetGCObjectFixedSlotsKind(baseobj->numFixedSlots());
kind = gc::GetBackgroundAllocKind(kind);
JS_ASSERT(kind == baseobj->getAllocKind());
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
RootedObject obj(cx, NewBuiltinClassInstance(cx, &ObjectClass, kind));
if (!obj)
return NULL;
if (!obj->setLastProperty(cx, baseobj->lastProperty()))
if (!JSObject::setLastProperty(cx, obj, baseobj->lastProperty()))
return NULL;
return obj;
@ -1542,7 +1547,7 @@ PreallocateObjectDynamicSlots(JSContext *cx, Shape *shape, HeapSlot **slots)
}
inline bool
DefineConstructorAndPrototype(JSContext *cx, GlobalObject *global,
DefineConstructorAndPrototype(JSContext *cx, Handle<GlobalObject*> global,
JSProtoKey key, JSObject *ctor, JSObject *proto)
{
JS_ASSERT(!global->nativeEmpty()); /* reserved slots already allocated */

View File

@ -362,7 +362,7 @@ JSObject::getChildProperty(JSContext *cx, Shape *parent, StackShape &child)
return NULL;
//JS_ASSERT(shape->parent == parent);
//JS_ASSERT_IF(parent != lastProperty(), parent == lastProperty()->parent);
if (!self->setLastProperty(cx, shape))
if (!JSObject::setLastProperty(cx, self, shape))
return NULL;
}
@ -889,25 +889,25 @@ JSObject::removeProperty(JSContext *cx, jsid id_)
return true;
}
void
JSObject::clear(JSContext *cx)
/* static */ void
JSObject::clear(JSContext *cx, HandleObject obj)
{
Shape *shape = lastProperty();
JS_ASSERT(inDictionaryMode() == shape->inDictionary());
Shape *shape = obj->lastProperty();
JS_ASSERT(obj->inDictionaryMode() == shape->inDictionary());
while (shape->parent) {
shape = shape->parent;
JS_ASSERT(inDictionaryMode() == shape->inDictionary());
JS_ASSERT(obj->inDictionaryMode() == shape->inDictionary());
}
JS_ASSERT(shape->isEmptyShape());
if (inDictionaryMode())
shape->listp = &shape_;
if (obj->inDictionaryMode())
shape->listp = &obj->shape_;
JS_ALWAYS_TRUE(setLastProperty(cx, shape));
JS_ALWAYS_TRUE(JSObject::setLastProperty(cx, obj, shape));
JS_ATOMIC_INCREMENT(&cx->runtime->propertyRemovals);
checkShapeConsistency();
obj->checkShapeConsistency();
}
void

View File

@ -138,9 +138,9 @@ stubs::SetElem(VMFrame &f)
if (js_PrototypeHasIndexedProperties(cx, obj))
break;
if ((uint32_t)i >= obj->getArrayLength())
obj->setArrayLength(cx, i + 1);
JSObject::setArrayLength(cx, obj, i + 1);
}
obj->setDenseArrayElementWithType(cx, i, rval);
JSObject::setDenseArrayElementWithType(cx, obj, i, rval);
goto end_setelem;
} else {
if (f.script()->hasAnalysis())

View File

@ -904,7 +904,7 @@ ContextStack::ensureOnTop(JSContext *cx, MaybeReportError report, unsigned nvars
* runtime->ionTop.
*/
if (regs && report != DONT_REPORT_ERROR) {
JSFunction *fun = NULL;
RootedFunction fun(cx);
if (InlinedSite *site = regs->inlined()) {
mjit::JITChunk *chunk = regs->fp()->jit()->chunk(regs->pc);
fun = chunk->inlineFrames()[site->inlineIndex].fun;