Bug 706885 - Do not store singletons in the Nursery; r=bhackett

--HG--
extra : rebase_source : 0f6fe8fd6954c60a25b7180e503afd124956ec1c
This commit is contained in:
Terrence Cole 2013-01-28 11:01:54 -08:00
parent 74249f548e
commit 030387b163
42 changed files with 515 additions and 374 deletions

View File

@ -582,9 +582,9 @@ bool
GlobalObject::initIntlObject(JSContext *cx, Handle<GlobalObject*> global)
{
RootedObject Intl(cx);
Intl = NewObjectWithGivenProto(cx, &IntlClass,
global->getOrCreateObjectPrototype(cx), global);
if (!Intl || !JSObject::setSingletonType(cx, Intl))
Intl = NewObjectWithGivenProto(cx, &IntlClass, global->getOrCreateObjectPrototype(cx),
global, SingletonObject);
if (!Intl)
return false;
global->setReservedSlot(JSProto_Intl, ObjectValue(*Intl));

View File

@ -1006,10 +1006,10 @@ ParallelArrayObject::initClass(JSContext *cx, JSObject *obj)
RootedId shapeId(cx, AtomToId(cx->names().shape));
unsigned flags = JSPROP_PERMANENT | JSPROP_SHARED | JSPROP_GETTER;
RootedObject scriptedLength(cx, js_NewFunction(cx, NullPtr(), NonGenericMethod<lengthGetter>,
0, JSFunction::NATIVE_FUN, global, NullPtr()));
RootedObject scriptedShape(cx, js_NewFunction(cx, NullPtr(), NonGenericMethod<dimensionsGetter>,
0, JSFunction::NATIVE_FUN, global, NullPtr()));
RootedObject scriptedLength(cx, NewFunction(cx, NullPtr(), NonGenericMethod<lengthGetter>,
0, JSFunction::NATIVE_FUN, global, NullPtr()));
RootedObject scriptedShape(cx, NewFunction(cx, NullPtr(), NonGenericMethod<dimensionsGetter>,
0, JSFunction::NATIVE_FUN, global, NullPtr()));
RootedValue value(cx, UndefinedValue());
if (!scriptedLength || !scriptedShape ||

View File

@ -1086,7 +1086,8 @@ Parser::newFunction(ParseContext *pc, HandleAtom atom, FunctionSyntaxKind kind)
JSFunction::Flags flags = (kind == Expression)
? JSFunction::INTERPRETED_LAMBDA
: JSFunction::INTERPRETED;
fun = js_NewFunction(context, NullPtr(), NULL, 0, flags, parent, atom);
fun = NewFunction(context, NullPtr(), NULL, 0, flags, parent, atom,
JSFunction::FinalizeKind, MaybeSingletonObject);
if (selfHostingMode)
fun->setIsSelfHostedBuiltin();
if (fun && !compileAndGo) {

View File

@ -34,6 +34,16 @@ struct Arena;
struct ArenaHeader;
struct Chunk;
/*
* This flag allows an allocation site to request a specific heap based upon the
* estimated lifetime or lifetime requirements of objects allocated from that
* site.
*/
enum InitialHeap {
DefaultHeap,
TenuredHeap
};
/* The GC allocation kinds. */
enum AllocKind {
FINALIZE_OBJECT0,

View File

@ -2047,9 +2047,15 @@ CodeGenerator::visitCreateThis(LCreateThis *lir)
return callVM(CreateThisInfo, lir);
}
static JSObject *
CreateThisForFunctionWithProtoWrapper(JSContext *cx, js::HandleObject callee, JSObject *proto)
{
return CreateThisForFunctionWithProto(cx, callee, proto);
}
typedef JSObject *(*CreateThisWithProtoFn)(JSContext *cx, HandleObject callee, JSObject *proto);
static const VMFunction CreateThisWithProtoInfo =
FunctionInfo<CreateThisWithProtoFn>(js_CreateThisForFunctionWithProto);
FunctionInfo<CreateThisWithProtoFn>(CreateThisForFunctionWithProtoWrapper);
bool
CodeGenerator::visitCreateThisWithProto(LCreateThisWithProto *lir)

View File

@ -331,7 +331,7 @@ IonCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutableP
{
AssertCanGC();
IonCode *codeObj = gc::NewGCThing<IonCode, CanGC>(cx, gc::FINALIZE_IONCODE, sizeof(IonCode));
IonCode *codeObj = gc::NewGCThing<IonCode, CanGC>(cx, gc::FINALIZE_IONCODE, sizeof(IonCode), gc::DefaultHeap);
if (!codeObj) {
pool->release();
return NULL;
@ -1466,7 +1466,7 @@ ion::CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp,
if (isConstructing && fp.thisValue().isPrimitive()) {
RootedScript scriptRoot(cx, script);
RootedObject callee(cx, &fp.callee());
RootedObject obj(cx, js_CreateThisForFunction(cx, callee, newType));
RootedObject obj(cx, CreateThisForFunction(cx, callee, newType));
if (!obj)
return Method_Skipped;
fp.thisValue().setObject(*obj);

View File

@ -3775,7 +3775,7 @@ IonBuilder::createThisScriptedSingleton(HandleFunction target, MDefinition *call
if (!types::TypeScript::ThisTypes(target->nonLazyScript())->hasType(types::Type::ObjectType(type)))
return NULL;
RootedObject templateObject(cx, js_CreateThisForFunctionWithProto(cx, target, proto));
RootedObject templateObject(cx, CreateThisForFunctionWithProto(cx, target, proto));
if (!templateObject)
return NULL;
@ -4351,15 +4351,13 @@ IonBuilder::jsop_compare(JSOp op)
JSObject *
IonBuilder::getNewArrayTemplateObject(uint32_t count)
{
RootedObject templateObject(cx, NewDenseUnallocatedArray(cx, count));
RootedScript scriptRoot(cx, script());
NewObjectKind newKind = types::UseNewTypeForInitializer(cx, scriptRoot, pc, JSProto_Array);
RootedObject templateObject(cx, NewDenseUnallocatedArray(cx, count, NULL, newKind));
if (!templateObject)
return NULL;
RootedScript scriptRoot(cx, script());
if (types::UseNewTypeForInitializer(cx, scriptRoot, pc, JSProto_Array)) {
if (!JSObject::setSingletonType(cx, templateObject))
return NULL;
} else {
if (newKind != SingletonObject) {
types::TypeObject *type = types::TypeScript::InitObject(cx, scriptRoot, pc, JSProto_Array);
if (!type)
return NULL;
@ -4397,21 +4395,19 @@ IonBuilder::jsop_newobject(HandleObject baseObj)
RootedObject templateObject(cx);
RootedScript scriptRoot(cx, script());
NewObjectKind newKind = types::UseNewTypeForInitializer(cx, scriptRoot, pc, JSProto_Object);
if (baseObj) {
templateObject = CopyInitializerObject(cx, baseObj);
templateObject = CopyInitializerObject(cx, baseObj, newKind);
} else {
gc::AllocKind kind = GuessObjectGCKind(0);
templateObject = NewBuiltinClassInstance(cx, &ObjectClass, kind);
gc::AllocKind allocKind = GuessObjectGCKind(0);
templateObject = NewBuiltinClassInstance(cx, &ObjectClass, allocKind, newKind);
}
if (!templateObject)
return false;
RootedScript scriptRoot(cx, script());
if (types::UseNewTypeForInitializer(cx, scriptRoot, pc, JSProto_Object)) {
if (!JSObject::setSingletonType(cx, templateObject))
return false;
} else {
if (newKind != SingletonObject) {
types::TypeObject *type = types::TypeScript::InitObject(cx, scriptRoot, pc, JSProto_Object);
if (!type)
return false;

View File

@ -116,7 +116,7 @@ InvokeFunction(JSContext *cx, HandleFunction fun0, uint32_t argc, Value *argv, V
JSObject *
NewGCThing(JSContext *cx, gc::AllocKind allocKind, size_t thingSize)
{
return gc::NewGCThing<JSObject, CanGC>(cx, allocKind, thingSize);
return gc::NewGCThing<JSObject, CanGC>(cx, allocKind, thingSize, gc::DefaultHeap);
}
bool
@ -269,18 +269,15 @@ JSObject*
NewInitArray(JSContext *cx, uint32_t count, types::TypeObject *typeArg)
{
RootedTypeObject type(cx, typeArg);
RootedObject obj(cx, NewDenseAllocatedArray(cx, count));
NewObjectKind newKind = !type ? SingletonObject : GenericObject;
RootedObject obj(cx, NewDenseAllocatedArray(cx, count, NULL, newKind));
if (!obj)
return NULL;
if (!type) {
if (!JSObject::setSingletonType(cx, obj))
return NULL;
if (!type)
types::TypeScript::Monitor(cx, ObjectValue(*obj));
} else {
else
obj->setType(type);
}
return obj;
}
@ -288,19 +285,16 @@ NewInitArray(JSContext *cx, uint32_t count, types::TypeObject *typeArg)
JSObject*
NewInitObject(JSContext *cx, HandleObject templateObject)
{
RootedObject obj(cx, CopyInitializerObject(cx, templateObject));
NewObjectKind newKind = templateObject->hasSingletonType() ? SingletonObject : GenericObject;
RootedObject obj(cx, CopyInitializerObject(cx, templateObject, newKind));
if (!obj)
return NULL;
if (templateObject->hasSingletonType()) {
if (!JSObject::setSingletonType(cx, obj))
return NULL;
if (templateObject->hasSingletonType())
types::TypeScript::Monitor(cx, ObjectValue(*obj));
} else {
else
obj->setType(templateObject->type());
}
return obj;
}
@ -499,7 +493,7 @@ CreateThis(JSContext *cx, HandleObject callee, MutableHandleValue rval)
if (callee->isFunction()) {
JSFunction *fun = callee->toFunction();
if (fun->isInterpreted())
rval.set(ObjectValue(*js_CreateThisForFunction(cx, callee, false)));
rval.set(ObjectValue(*CreateThisForFunction(cx, callee, false)));
}
return true;

View File

@ -3375,7 +3375,7 @@ JS_NewObjectForConstructor(JSContext *cx, JSClass *clasp, const jsval *vp)
assertSameCompartment(cx, *vp);
RootedObject obj(cx, JSVAL_TO_OBJECT(*vp));
return js_CreateThis(cx, Valueify(clasp), obj);
return CreateThis(cx, Valueify(clasp), obj);
}
JS_PUBLIC_API(JSBool)
@ -4760,7 +4760,7 @@ JS_NewFunction(JSContext *cx, JSNative native, unsigned nargs, unsigned flags,
}
JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags);
return js_NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom);
return NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom);
}
JS_PUBLIC_API(JSFunction *)
@ -4776,7 +4776,7 @@ JS_NewFunctionById(JSContext *cx, JSNative native, unsigned nargs, unsigned flag
RootedAtom atom(cx, JSID_TO_ATOM(id));
JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags);
return js_NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom);
return NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom);
}
JS_PUBLIC_API(JSObject *)
@ -4934,9 +4934,10 @@ JS_DefineFunctions(JSContext *cx, JSObject *objArg, JSFunctionSpec *fs)
}
flags &= ~JSFUN_GENERIC_NATIVE;
JSFunction *fun = js_DefineFunction(cx, ctor, id, js_generic_native_method_dispatcher,
fs->nargs + 1, flags,
JSFunction::ExtendedFinalizeKind);
JSFunction *fun = DefineFunction(cx, ctor, id,
js_generic_native_method_dispatcher,
fs->nargs + 1, flags,
JSFunction::ExtendedFinalizeKind);
if (!fun)
return JS_FALSE;
@ -4959,16 +4960,15 @@ JS_DefineFunctions(JSContext *cx, JSObject *objArg, JSFunctionSpec *fs)
/*
* Delay cloning self-hosted functions until they are called. This is
* achieved by passing js_DefineFunction a NULL JSNative which
* achieved by passing DefineFunction a NULL JSNative which
* produces an interpreted JSFunction where !hasScript. Interpreted
* call paths then call InitializeLazyFunctionScript if !hasScript.
*/
if (fs->selfHostedName) {
RootedFunction fun(cx, js_DefineFunction(cx, obj, id, /* native = */ NULL, fs->nargs, 0,
JSFunction::ExtendedFinalizeKind));
RootedFunction fun(cx, DefineFunction(cx, obj, id, /* native = */ NULL, fs->nargs, 0,
JSFunction::ExtendedFinalizeKind, SingletonObject));
if (!fun)
return JS_FALSE;
JSFunction::setSingletonType(cx, fun);
fun->setIsSelfHostedBuiltin();
fun->setExtendedSlot(0, PrivateValue(fs));
RootedAtom shAtom(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName)));
@ -4981,7 +4981,7 @@ JS_DefineFunctions(JSContext *cx, JSObject *objArg, JSFunctionSpec *fs)
return JS_FALSE;
}
} else {
JSFunction *fun = js_DefineFunction(cx, obj, id, fs->call.op, fs->nargs, flags);
JSFunction *fun = DefineFunction(cx, obj, id, fs->call.op, fs->nargs, flags);
if (!fun)
return JS_FALSE;
if (fs->call.info)
@ -5004,7 +5004,7 @@ JS_DefineFunction(JSContext *cx, JSObject *objArg, const char *name, JSNative ca
if (!atom)
return NULL;
Rooted<jsid> id(cx, AtomToId(atom));
return js_DefineFunction(cx, obj, id, call, nargs, attrs);
return DefineFunction(cx, obj, id, call, nargs, attrs);
}
JS_PUBLIC_API(JSFunction *)
@ -5021,7 +5021,7 @@ JS_DefineUCFunction(JSContext *cx, JSObject *objArg,
if (!atom)
return NULL;
Rooted<jsid> id(cx, AtomToId(atom));
return js_DefineFunction(cx, obj, id, call, nargs, attrs);
return DefineFunction(cx, obj, id, call, nargs, attrs);
}
extern JS_PUBLIC_API(JSFunction *)
@ -5034,7 +5034,7 @@ JS_DefineFunctionById(JSContext *cx, JSObject *objArg, jsid id_, JSNative call,
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
return js_DefineFunction(cx, obj, id, call, nargs, attrs);
return DefineFunction(cx, obj, id, call, nargs, attrs);
}
struct AutoLastFrameCheck
@ -5350,7 +5350,7 @@ JS::CompileFunction(JSContext *cx, HandleObject obj, CompileOptions options,
return NULL;
}
RootedFunction fun(cx, js_NewFunction(cx, NullPtr(), NULL, 0, JSFunction::INTERPRETED, obj, funAtom));
RootedFunction fun(cx, NewFunction(cx, NullPtr(), NULL, 0, JSFunction::INTERPRETED, obj, funAtom));
if (!fun)
return NULL;

View File

@ -2456,7 +2456,7 @@ js_InitArrayClass(JSContext *cx, HandleObject obj)
RootedShape shape(cx, EmptyShape::getInitialShape(cx, &ArrayClass, TaggedProto(proto), proto->getParent(),
gc::FINALIZE_OBJECT0));
RootedObject arrayProto(cx, JSObject::createArray(cx, gc::FINALIZE_OBJECT4, shape, type, 0));
RootedObject arrayProto(cx, JSObject::createArray(cx, gc::FINALIZE_OBJECT4, gc::TenuredHeap, shape, type, 0));
if (!arrayProto || !JSObject::setSingletonType(cx, arrayProto) || !AddLengthProperty(cx, arrayProto))
return NULL;
@ -2512,17 +2512,19 @@ EnsureNewArrayElements(JSContext *cx, JSObject *obj, uint32_t length)
template<bool allocateCapacity>
static JS_ALWAYS_INLINE JSObject *
NewArray(JSContext *cx, uint32_t length, RawObject protoArg)
NewArray(JSContext *cx, uint32_t length, RawObject protoArg, NewObjectKind newKind = GenericObject)
{
gc::AllocKind kind = GuessArrayGCKind(length);
JS_ASSERT(CanBeFinalizedInBackground(kind, &ArrayClass));
kind = GetBackgroundAllocKind(kind);
gc::AllocKind allocKind = GuessArrayGCKind(length);
JS_ASSERT(CanBeFinalizedInBackground(allocKind, &ArrayClass));
allocKind = GetBackgroundAllocKind(allocKind);
NewObjectCache &cache = cx->runtime->newObjectCache;
NewObjectCache::EntryIndex entry = -1;
if (cache.lookupGlobal(&ArrayClass, cx->global(), kind, &entry)) {
RootedObject obj(cx, cache.newObjectFromHit(cx, entry));
if (newKind != SingletonObject &&
cache.lookupGlobal(&ArrayClass, cx->global(), allocKind, &entry))
{
RootedObject obj(cx, cache.newObjectFromHit(cx, entry, InitialHeapForNewKind(newKind)));
if (obj) {
/* Fixup the elements pointer and length, which may be incorrect. */
obj->setFixedElements();
@ -2553,7 +2555,7 @@ NewArray(JSContext *cx, uint32_t length, RawObject protoArg)
if (!shape)
return NULL;
RootedObject obj(cx, JSObject::createArray(cx, kind, shape, type, length));
RootedObject obj(cx, JSObject::createArray(cx, allocKind, gc::DefaultHeap, shape, type, length));
if (!obj)
return NULL;
@ -2564,8 +2566,11 @@ NewArray(JSContext *cx, uint32_t length, RawObject protoArg)
EmptyShape::insertInitialShape(cx, shape, proto);
}
if (newKind == SingletonObject && !JSObject::setSingletonType(cx, obj))
return NULL;
if (entry != -1)
cache.fillGlobal(entry, &ArrayClass, cx->global(), kind, obj);
cache.fillGlobal(entry, &ArrayClass, cx->global(), allocKind, obj);
if (allocateCapacity && !EnsureNewArrayElements(cx, obj, length))
return NULL;
@ -2575,19 +2580,22 @@ NewArray(JSContext *cx, uint32_t length, RawObject protoArg)
}
JSObject * JS_FASTCALL
js::NewDenseEmptyArray(JSContext *cx, RawObject proto /* = NULL */)
js::NewDenseEmptyArray(JSContext *cx, RawObject proto /* = NULL */,
NewObjectKind newKind /* = GenericObject */)
{
return NewArray<false>(cx, 0, proto);
}
JSObject * JS_FASTCALL
js::NewDenseAllocatedArray(JSContext *cx, uint32_t length, RawObject proto /* = NULL */)
js::NewDenseAllocatedArray(JSContext *cx, uint32_t length, RawObject proto /* = NULL */,
NewObjectKind newKind /* = GenericObject */)
{
return NewArray<true>(cx, length, proto);
return NewArray<true>(cx, length, proto, newKind);
}
JSObject * JS_FASTCALL
js::NewDenseUnallocatedArray(JSContext *cx, uint32_t length, RawObject proto /* = NULL */)
js::NewDenseUnallocatedArray(JSContext *cx, uint32_t length, RawObject proto /* = NULL */,
NewObjectKind newKind /* = GenericObject */)
{
return NewArray<false>(cx, length, proto);
}
@ -2628,7 +2636,7 @@ js::NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32
// values must point at already-rooted Value objects
JSObject *
js::NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values,
RawObject proto /* = NULL */)
RawObject proto /* = NULL */, NewObjectKind newKind /* = GenericObject */)
{
JSObject* obj = NewArray<true>(cx, length, proto);
if (!obj)

View File

@ -46,18 +46,21 @@ namespace js {
/* Create a dense array with no capacity allocated, length set to 0. */
extern JSObject * JS_FASTCALL
NewDenseEmptyArray(JSContext *cx, RawObject proto = NULL);
NewDenseEmptyArray(JSContext *cx, RawObject proto = NULL,
NewObjectKind newKind = GenericObject);
/* Create a dense array with length and capacity == 'length', initialized length set to 0. */
extern JSObject * JS_FASTCALL
NewDenseAllocatedArray(JSContext *cx, uint32_t length, RawObject proto = NULL);
NewDenseAllocatedArray(JSContext *cx, uint32_t length, RawObject proto = NULL,
NewObjectKind newKind = GenericObject);
/*
* Create a dense array with a set length, but without allocating space for the
* contents. This is useful, e.g., when accepting length from the user.
*/
extern JSObject * JS_FASTCALL
NewDenseUnallocatedArray(JSContext *cx, uint32_t length, RawObject proto = NULL);
NewDenseUnallocatedArray(JSContext *cx, uint32_t length, RawObject proto = NULL,
NewObjectKind newKind = GenericObject);
/* Create a dense array with a copy of the dense array elements in src. */
extern JSObject *
@ -65,7 +68,8 @@ NewDenseCopiedArray(JSContext *cx, uint32_t length, HandleObject src, uint32_t e
/* Create a dense array from the given array values, which must be rooted */
extern JSObject *
NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values, RawObject proto = NULL);
NewDenseCopiedArray(JSContext *cx, uint32_t length, const Value *values, RawObject proto = NULL,
NewObjectKind newKind = GenericObject);
/* Get the common shape used by all dense arrays with a prototype at globalObj. */
extern UnrootedShape

View File

@ -167,8 +167,8 @@ js_InitBooleanClass(JSContext *cx, HandleObject obj)
Handle<PropertyName*> valueOfName = cx->names().valueOf;
RootedFunction
valueOf(cx, js_NewFunction(cx, NullPtr(), bool_valueOf, 0, JSFunction::NATIVE_FUN,
global, valueOfName));
valueOf(cx, NewFunction(cx, NullPtr(), bool_valueOf, 0, JSFunction::NATIVE_FUN,
global, valueOfName));
if (!valueOf)
return NULL;

View File

@ -341,7 +341,7 @@ class NewObjectCache
* NULL if returning the object could possibly trigger GC (does not
* indicate failure).
*/
inline JSObject *newObjectFromHit(JSContext *cx, EntryIndex entry);
inline JSObject *newObjectFromHit(JSContext *cx, EntryIndex entry, js::gc::InitialHeap heap);
/* Fill an entry after a cache miss. */
inline void fillProto(EntryIndex entry, Class *clasp, js::TaggedProto proto, gc::AllocKind kind, JSObject *obj);

View File

@ -100,12 +100,12 @@ NewObjectCache::fillType(EntryIndex entry, Class *clasp, js::types::TypeObject *
}
inline JSObject *
NewObjectCache::newObjectFromHit(JSContext *cx, EntryIndex entry_)
NewObjectCache::newObjectFromHit(JSContext *cx, EntryIndex entry_, js::gc::InitialHeap heap)
{
JS_ASSERT(unsigned(entry_) < mozilla::ArrayLength(entries));
Entry *entry = &entries[entry_];
JSObject *obj = js_NewGCObject<NoGC>(cx, entry->kind);
JSObject *obj = js_NewGCObject<NoGC>(cx, entry->kind, heap);
if (obj) {
copyCachedToObject(obj, reinterpret_cast<JSObject *>(&entry->templateObject));
Probes::createObject(cx, obj);

View File

@ -392,8 +392,7 @@ struct JSCompartment : private JS::shadow::Zone, public js::gc::GraphNodeBase<JS
js::types::TypeObject *getNewType(JSContext *cx, js::Class *clasp, js::TaggedProto proto,
JSFunction *fun = NULL);
js::types::TypeObject *getLazyType(JSContext *cx, js::Class *clasp,
js::Handle<js::TaggedProto> proto);
js::types::TypeObject *getLazyType(JSContext *cx, js::Class *clasp, js::TaggedProto proto);
/*
* Hash table of all manually call site-cloned functions from within

View File

@ -119,8 +119,8 @@ JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *protoArg, JS
* TypeObject attached to our proto with information about our object, since
* we're not going to be using that TypeObject anyway.
*/
RootedObject obj(cx, JS_NewObjectWithGivenProto(cx, clasp, NULL, parent));
if (!obj || !JSObject::setSingletonType(cx, obj))
RootedObject obj(cx, NewObjectWithGivenProto(cx, (js::Class *)clasp, NULL, parent, SingletonObject));
if (!obj)
return NULL;
if (!JS_SplicePrototype(cx, obj, proto))
return NULL;
@ -276,7 +276,7 @@ JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *objArg, const JSFunctionSpec
return false;
Rooted<jsid> id(cx, AtomToId(atom));
RootedFunction fun(cx, js_DefineFunction(cx, obj, id, fs->call, fs->nargs, fs->flags));
RootedFunction fun(cx, DefineFunction(cx, obj, id, fs->call, fs->nargs, fs->flags));
if (!fun)
return false;
@ -401,7 +401,7 @@ js::DefineFunctionWithReserved(JSContext *cx, JSObject *objArg, const char *name
if (!atom)
return NULL;
Rooted<jsid> id(cx, AtomToId(atom));
return js_DefineFunction(cx, obj, id, call, nargs, attrs, JSFunction::ExtendedFinalizeKind);
return DefineFunction(cx, obj, id, call, nargs, attrs, JSFunction::ExtendedFinalizeKind);
}
JS_FRIEND_API(JSFunction *)
@ -422,8 +422,8 @@ js::NewFunctionWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsi
}
JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags);
return js_NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom,
JSFunction::ExtendedFinalizeKind);
return NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom,
JSFunction::ExtendedFinalizeKind);
}
JS_FRIEND_API(JSFunction *)
@ -438,8 +438,8 @@ js::NewFunctionByIdWithReserved(JSContext *cx, JSNative native, unsigned nargs,
RootedAtom atom(cx, JSID_TO_ATOM(id));
JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags);
return js_NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom,
JSFunction::ExtendedFinalizeKind);
return NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom,
JSFunction::ExtendedFinalizeKind);
}
JS_FRIEND_API(JSObject *)

View File

@ -266,8 +266,8 @@ ResolveInterpretedFunctionPrototype(JSContext *cx, HandleObject obj)
RawObject objProto = obj->global().getOrCreateObjectPrototype(cx);
if (!objProto)
return NULL;
RootedObject proto(cx, NewObjectWithGivenProto(cx, &ObjectClass, objProto, NULL));
if (!proto || !JSObject::setSingletonType(cx, proto))
RootedObject proto(cx, NewObjectWithGivenProto(cx, &ObjectClass, objProto, NULL, SingletonObject));
if (!proto)
return NULL;
/*
@ -407,7 +407,7 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
atom = fun->atom();
script = fun->nonLazyScript();
} else {
fun = js_NewFunction(cx, NullPtr(), NULL, 0, JSFunction::INTERPRETED, NullPtr(), NullPtr());
fun = NewFunction(cx, NullPtr(), NULL, 0, JSFunction::INTERPRETED, NullPtr(), NullPtr());
if (!fun)
return false;
atom = NULL;
@ -454,8 +454,8 @@ js::CloneInterpretedFunction(JSContext *cx, HandleObject enclosingScope, HandleF
/* NB: Keep this in sync with XDRInterpretedFunction. */
RootedFunction clone(cx, js_NewFunction(cx, NullPtr(), NULL, 0,
JSFunction::INTERPRETED, NullPtr(), NullPtr()));
RootedFunction clone(cx, NewFunction(cx, NullPtr(), NULL, 0,
JSFunction::INTERPRETED, NullPtr(), NullPtr()));
if (!clone)
return NULL;
@ -1177,8 +1177,8 @@ js_fun_bind(JSContext *cx, HandleObject target, HandleValue thisArg,
/* Step 4-6, 10-11. */
RootedAtom name(cx, target->isFunction() ? target->toFunction()->atom() : NULL);
RootedObject funobj(cx, js_NewFunction(cx, NullPtr(), CallOrConstructBoundFunction, length,
JSFunction::NATIVE_CTOR, target, name));
RootedObject funobj(cx, NewFunction(cx, NullPtr(), CallOrConstructBoundFunction, length,
JSFunction::NATIVE_CTOR, target, name));
if (!funobj)
return NULL;
@ -1403,8 +1403,8 @@ js::Function(JSContext *cx, unsigned argc, Value *vp)
* and so would a call to f from another top-level's script or function.
*/
RootedAtom anonymousAtom(cx, cx->names().anonymous);
RootedFunction fun(cx, js_NewFunction(cx, NullPtr(), NULL, 0, JSFunction::INTERPRETED_LAMBDA,
global, anonymousAtom));
RootedFunction fun(cx, NewFunction(cx, NullPtr(), NULL, 0, JSFunction::INTERPRETED_LAMBDA,
global, anonymousAtom));
if (!fun)
return false;
@ -1423,11 +1423,12 @@ js::IsBuiltinFunctionConstructor(JSFunction *fun)
}
JSFunction *
js_NewFunction(JSContext *cx, HandleObject funobjArg, Native native, unsigned nargs,
JSFunction::Flags flags, HandleObject parent, HandleAtom atom,
js::gc::AllocKind kind)
js::NewFunction(JSContext *cx, HandleObject funobjArg, Native native, unsigned nargs,
JSFunction::Flags flags, HandleObject parent, HandleAtom atom,
gc::AllocKind allocKind /* = JSFunction::FinalizeKind */,
NewObjectKind newKind /* = GenericObject */)
{
JS_ASSERT(kind == JSFunction::FinalizeKind || kind == JSFunction::ExtendedFinalizeKind);
JS_ASSERT(allocKind == JSFunction::FinalizeKind || allocKind == JSFunction::ExtendedFinalizeKind);
JS_ASSERT(sizeof(JSFunction) <= gc::Arena::thingSize(JSFunction::FinalizeKind));
JS_ASSERT(sizeof(FunctionExtended) <= gc::Arena::thingSize(JSFunction::ExtendedFinalizeKind));
@ -1435,8 +1436,11 @@ js_NewFunction(JSContext *cx, HandleObject funobjArg, Native native, unsigned na
if (funobj) {
JS_ASSERT(funobj->isFunction());
JS_ASSERT(funobj->getParent() == parent);
JS_ASSERT_IF(native && cx->typeInferenceEnabled(), funobj->hasSingletonType());
} else {
funobj = NewObjectWithClassProto(cx, &FunctionClass, NULL, SkipScopeParent(parent), kind);
if (native)
newKind = SingletonObject;
funobj = NewObjectWithClassProto(cx, &FunctionClass, NULL, SkipScopeParent(parent), allocKind, newKind);
if (!funobj)
return NULL;
}
@ -1454,28 +1458,28 @@ js_NewFunction(JSContext *cx, HandleObject funobjArg, Native native, unsigned na
JS_ASSERT(native);
fun->initNative(native, NULL);
}
if (kind == JSFunction::ExtendedFinalizeKind) {
if (allocKind == JSFunction::ExtendedFinalizeKind) {
fun->flags |= JSFunction::EXTENDED;
fun->initializeExtended();
}
fun->initAtom(atom);
if (native && !JSObject::setSingletonType(cx, fun))
return NULL;
return fun;
}
JSFunction *
js::CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
gc::AllocKind kind)
js::CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent, gc::AllocKind allocKind)
{
AssertCanGC();
JS_ASSERT(parent);
JS_ASSERT(!fun->isBoundFunction());
JSObject *cloneobj =
NewObjectWithClassProto(cx, &FunctionClass, NULL, SkipScopeParent(parent), kind);
bool useSameScript = cx->compartment == fun->compartment() &&
!fun->hasSingletonType() &&
!types::UseNewTypeForClone(fun);
NewObjectKind newKind = useSameScript ? GenericObject : SingletonObject;
JSObject *cloneobj = NewObjectWithClassProto(cx, &FunctionClass, NULL, SkipScopeParent(parent),
allocKind, newKind);
if (!cloneobj)
return NULL;
JSFunction *clone = cloneobj->toFunction();
@ -1497,15 +1501,12 @@ js::CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
}
clone->initAtom(fun->displayAtom());
if (kind == JSFunction::ExtendedFinalizeKind) {
if (allocKind == JSFunction::ExtendedFinalizeKind) {
clone->flags |= JSFunction::EXTENDED;
clone->initializeExtended();
}
if (cx->compartment == fun->compartment() &&
!fun->hasSingletonType() &&
!types::UseNewTypeForClone(fun))
{
if (useSameScript) {
/*
* Clone the function, reusing its script. We can use the same type as
* the original function provided that its prototype is correct.
@ -1517,9 +1518,6 @@ js::CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
RootedFunction cloneRoot(cx, clone);
if (!JSObject::setSingletonType(cx, cloneRoot))
return NULL;
/*
* Across compartments we have to clone the script for interpreted
* functions. Cross-compartment cloning only happens via JSAPI
@ -1533,8 +1531,9 @@ js::CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent,
}
JSFunction *
js_DefineFunction(JSContext *cx, HandleObject obj, HandleId id, Native native,
unsigned nargs, unsigned flags, AllocKind kind)
js::DefineFunction(JSContext *cx, HandleObject obj, HandleId id, Native native,
unsigned nargs, unsigned flags, AllocKind allocKind /* = FinalizeKind */,
NewObjectKind newKind /* = GenericObject */)
{
PropertyOp gop;
StrictPropertyOp sop;
@ -1562,7 +1561,7 @@ js_DefineFunction(JSContext *cx, HandleObject obj, HandleId id, Native native,
else
funFlags = JSAPIToJSFunctionFlags(flags);
RootedAtom atom(cx, JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : NULL);
fun = js_NewFunction(cx, NullPtr(), native, nargs, funFlags, obj, atom, kind);
fun = NewFunction(cx, NullPtr(), native, nargs, funFlags, obj, atom, allocKind, newKind);
if (!fun)
return NULL;

View File

@ -331,18 +331,20 @@ JSAPIToJSFunctionFlags(unsigned flags)
: JSFunction::NATIVE_FUN;
}
extern JSFunction *
js_NewFunction(JSContext *cx, js::HandleObject funobj, JSNative native, unsigned nargs,
JSFunction::Flags flags, js::HandleObject parent, js::HandleAtom atom,
js::gc::AllocKind kind = JSFunction::FinalizeKind);
extern JSFunction *
js_DefineFunction(JSContext *cx, js::HandleObject obj, js::HandleId id, JSNative native,
unsigned nargs, unsigned flags,
js::gc::AllocKind kind = JSFunction::FinalizeKind);
namespace js {
extern JSFunction *
NewFunction(JSContext *cx, HandleObject funobj, JSNative native, unsigned nargs,
JSFunction::Flags flags, HandleObject parent, HandleAtom atom,
gc::AllocKind allocKind = JSFunction::FinalizeKind,
NewObjectKind newKind = GenericObject);
extern JSFunction *
DefineFunction(JSContext *cx, HandleObject obj, HandleId id, JSNative native,
unsigned nargs, unsigned flags,
gc::AllocKind allocKind = JSFunction::FinalizeKind,
NewObjectKind newKind = GenericObject);
/*
* Function extended with reserved slots for use by various kinds of functions.
* Most functions do not have these extensions, but enough are that efficient

View File

@ -480,7 +480,7 @@ typedef GCCompartmentGroupIter GCZoneGroupIter;
template <typename T, AllowGC allowGC>
inline T *
NewGCThing(JSContext *cx, js::gc::AllocKind kind, size_t thingSize)
NewGCThing(JSContext *cx, AllocKind kind, size_t thingSize, InitialHeap heap)
{
if (allowGC)
AssertCanGC();
@ -513,8 +513,10 @@ NewGCThing(JSContext *cx, js::gc::AllocKind kind, size_t thingSize)
t->arenaHeader()->allocatedDuringIncremental);
#if defined(JSGC_GENERATIONAL) && defined(JS_GC_ZEAL)
if (cx->runtime->gcVerifyPostData && IsNurseryAllocable(kind)
&& !IsAtomsCompartment(cx->compartment))
if (cx->runtime->gcVerifyPostData &&
IsNurseryAllocable(kind) &&
!IsAtomsCompartment(cx->compartment) &&
heap != TenuredHeap)
{
zone->gcNursery.insertPointer(t);
}
@ -557,50 +559,55 @@ class AutoSuppressGC
template <js::AllowGC allowGC>
inline JSObject *
js_NewGCObject(JSContext *cx, js::gc::AllocKind kind)
js_NewGCObject(JSContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap)
{
JS_ASSERT(kind >= js::gc::FINALIZE_OBJECT0 && kind <= js::gc::FINALIZE_OBJECT_LAST);
return js::gc::NewGCThing<JSObject, allowGC>(cx, kind, js::gc::Arena::thingSize(kind));
return js::gc::NewGCThing<JSObject, allowGC>(cx, kind, js::gc::Arena::thingSize(kind), heap);
}
template <js::AllowGC allowGC>
inline JSString *
js_NewGCString(JSContext *cx)
{
return js::gc::NewGCThing<JSString, allowGC>(cx, js::gc::FINALIZE_STRING, sizeof(JSString));
return js::gc::NewGCThing<JSString, allowGC>(cx, js::gc::FINALIZE_STRING,
sizeof(JSString), js::gc::TenuredHeap);
}
template <js::AllowGC allowGC>
inline JSShortString *
js_NewGCShortString(JSContext *cx)
{
return js::gc::NewGCThing<JSShortString, allowGC>(cx, js::gc::FINALIZE_SHORT_STRING, sizeof(JSShortString));
return js::gc::NewGCThing<JSShortString, allowGC>(cx, js::gc::FINALIZE_SHORT_STRING,
sizeof(JSShortString), js::gc::TenuredHeap);
}
inline JSExternalString *
js_NewGCExternalString(JSContext *cx)
{
return js::gc::NewGCThing<JSExternalString, js::CanGC>(cx, js::gc::FINALIZE_EXTERNAL_STRING,
sizeof(JSExternalString));
sizeof(JSExternalString), js::gc::TenuredHeap);
}
inline JSScript *
js_NewGCScript(JSContext *cx)
{
return js::gc::NewGCThing<JSScript, js::CanGC>(cx, js::gc::FINALIZE_SCRIPT, sizeof(JSScript));
return js::gc::NewGCThing<JSScript, js::CanGC>(cx, js::gc::FINALIZE_SCRIPT,
sizeof(JSScript), js::gc::TenuredHeap);
}
inline js::UnrootedShape
js_NewGCShape(JSContext *cx)
{
return js::gc::NewGCThing<js::Shape, js::CanGC>(cx, js::gc::FINALIZE_SHAPE, sizeof(js::Shape));
return js::gc::NewGCThing<js::Shape, js::CanGC>(cx, js::gc::FINALIZE_SHAPE,
sizeof(js::Shape), js::gc::TenuredHeap);
}
template <js::AllowGC allowGC>
inline js::UnrootedBaseShape
js_NewGCBaseShape(JSContext *cx)
{
return js::gc::NewGCThing<js::BaseShape, allowGC>(cx, js::gc::FINALIZE_BASE_SHAPE, sizeof(js::BaseShape));
return js::gc::NewGCThing<js::BaseShape, allowGC>(cx, js::gc::FINALIZE_BASE_SHAPE,
sizeof(js::BaseShape), js::gc::TenuredHeap);
}
#endif /* jsgcinlines_h___ */

View File

@ -2389,7 +2389,8 @@ TypeCompartment::newTypeObject(JSContext *cx, Class *clasp, Handle<TaggedProto>
{
JS_ASSERT_IF(proto.isObject(), cx->compartment == proto.toObject()->compartment());
TypeObject *object = gc::NewGCThing<TypeObject, CanGC>(cx, gc::FINALIZE_TYPE_OBJECT, sizeof(TypeObject));
TypeObject *object = gc::NewGCThing<TypeObject, CanGC>(cx, gc::FINALIZE_TYPE_OBJECT,
sizeof(TypeObject), gc::TenuredHeap);
if (!object)
return NULL;
new(object) TypeObject(clasp, proto, clasp == &FunctionClass, unknown);
@ -2584,7 +2585,7 @@ types::UseNewType(JSContext *cx, JSScript *script, jsbytecode *pc)
return false;
}
bool
NewObjectKind
types::UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc, JSProtoKey key)
{
/*
@ -2594,17 +2595,26 @@ types::UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc,
*/
if (!cx->typeInferenceEnabled() || (script->function() && !script->treatAsRunOnce))
return false;
return GenericObject;
if (key != JSProto_Object && !(key >= JSProto_Int8Array && key <= JSProto_Uint8ClampedArray))
return false;
return GenericObject;
AutoEnterAnalysis enter(cx);
if (!script->ensureRanAnalysis(cx))
return false;
return GenericObject;
return !script->analysis()->getCode(pc).inLoop;
if (script->analysis()->getCode(pc).inLoop)
return GenericObject;
return SingletonObject;
}
NewObjectKind
types::UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc, Class *clasp)
{
return UseNewTypeForInitializer(cx, script, pc, JSCLASS_CACHED_PROTO_KEY(clasp));
}
static inline bool
@ -5823,7 +5833,7 @@ JSScript::makeAnalysis(JSContext *cx)
}
/* static */ bool
JSFunction::setTypeForScriptedFunction(JSContext *cx, HandleFunction fun, bool singleton)
JSFunction::setTypeForScriptedFunction(JSContext *cx, HandleFunction fun, bool singleton /* = false */)
{
JS_ASSERT(fun->nonLazyScript());
JS_ASSERT(fun->nonLazyScript()->function() == fun);
@ -6190,12 +6200,12 @@ JSObject::getNewType(JSContext *cx, Class *clasp, JSFunction *fun)
}
TypeObject *
JSCompartment::getLazyType(JSContext *cx, Class *clasp, Handle<TaggedProto> proto)
JSCompartment::getLazyType(JSContext *cx, Class *clasp, TaggedProto proto)
{
JS_ASSERT(cx->compartment == this);
JS_ASSERT_IF(proto.isObject(), cx->compartment == proto.toObject()->compartment());
MaybeCheckStackRoots(cx);
AutoEnterAnalysis enter(cx);
TypeObjectSet &table = cx->compartment->lazyTypeObjects;
@ -6210,7 +6220,8 @@ JSCompartment::getLazyType(JSContext *cx, Class *clasp, Handle<TaggedProto> prot
return type;
}
TypeObject *type = cx->compartment->types.newTypeObject(cx, clasp, proto, false);
Rooted<TaggedProto> protoRoot(cx, proto);
TypeObject *type = cx->compartment->types.newTypeObject(cx, clasp, protoRoot, false);
if (!type)
return NULL;

View File

@ -1122,10 +1122,6 @@ typedef HashSet<ReadBarriered<TypeObject>, TypeObjectEntry, SystemAllocPolicy> T
bool
UseNewType(JSContext *cx, JSScript *script, jsbytecode *pc);
/* Whether to use a new type object for an initializer opcode at script/pc. */
bool
UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc, JSProtoKey key);
/*
* Whether Array.prototype, or an object on its proto chain, has an
* indexed property.

View File

@ -868,6 +868,13 @@ struct AllocationSiteKey {
}
};
/* Whether to use a new type object for an initializer opcode at script/pc. */
js::NewObjectKind
UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc, JSProtoKey key);
js::NewObjectKind
UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc, Class *clasp);
/* static */ inline TypeObject *
TypeScript::InitObject(JSContext *cx, JSScript *script, jsbytecode *pc, JSProtoKey kind)
{
@ -896,17 +903,17 @@ TypeScript::InitObject(JSContext *cx, JSScript *script, jsbytecode *pc, JSProtoK
/* Set the type to use for obj according to the site it was allocated at. */
static inline bool
SetInitializerObjectType(JSContext *cx, HandleScript script, jsbytecode *pc, HandleObject obj)
SetInitializerObjectType(JSContext *cx, HandleScript script, jsbytecode *pc, HandleObject obj, NewObjectKind kind)
{
if (!cx->typeInferenceEnabled())
return true;
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(obj->getClass());
JS_ASSERT(key != JSProto_Null);
JS_ASSERT(kind == UseNewTypeForInitializer(cx, script, pc, key));
if (UseNewTypeForInitializer(cx, script, pc, key)) {
if (!JSObject::setSingletonType(cx, obj))
return false;
if (kind == SingletonObject) {
JS_ASSERT(obj->hasSingletonType());
/*
* Inference does not account for types of run-once initializer

View File

@ -2625,8 +2625,12 @@ BEGIN_CASE(JSOP_REST)
if (!rest)
goto error;
PUSH_COPY(ObjectValue(*rest));
if (!SetInitializerObjectType(cx, script, regs.pc, rest))
if (!SetInitializerObjectType(cx, script, regs.pc, rest, GenericObject))
goto error;
rootType0 = GetTypeCallerInitObject(cx, JSProto_Array);
if (!rootType0)
goto error;
rest->setType(rootType0);
}
END_CASE(JSOP_REST)
@ -2851,13 +2855,16 @@ BEGIN_CASE(JSOP_NEWINIT)
JS_ASSERT(i == JSProto_Array || i == JSProto_Object);
RootedObject &obj = rootObject0;
NewObjectKind newKind;
if (i == JSProto_Array) {
obj = NewDenseEmptyArray(cx);
newKind = UseNewTypeForInitializer(cx, script, regs.pc, &ArrayClass);
obj = NewDenseEmptyArray(cx, NULL, newKind);
} else {
gc::AllocKind kind = GuessObjectGCKind(0);
obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
gc::AllocKind allocKind = GuessObjectGCKind(0);
newKind = UseNewTypeForInitializer(cx, script, regs.pc, &ObjectClass);
obj = NewBuiltinClassInstance(cx, &ObjectClass, allocKind, newKind);
}
if (!obj || !SetInitializerObjectType(cx, script, regs.pc, obj))
if (!obj || !SetInitializerObjectType(cx, script, regs.pc, obj, newKind))
goto error;
PUSH_OBJECT(*obj);
@ -2869,8 +2876,9 @@ BEGIN_CASE(JSOP_NEWARRAY)
{
unsigned count = GET_UINT24(regs.pc);
RootedObject &obj = rootObject0;
obj = NewDenseAllocatedArray(cx, count);
if (!obj || !SetInitializerObjectType(cx, script, regs.pc, obj))
NewObjectKind newKind = UseNewTypeForInitializer(cx, script, regs.pc, &ArrayClass);
obj = NewDenseAllocatedArray(cx, count, NULL, newKind);
if (!obj || !SetInitializerObjectType(cx, script, regs.pc, obj, newKind))
goto error;
PUSH_OBJECT(*obj);
@ -2884,8 +2892,9 @@ BEGIN_CASE(JSOP_NEWOBJECT)
baseobj = script->getObject(regs.pc);
RootedObject &obj = rootObject1;
obj = CopyInitializerObject(cx, baseobj);
if (!obj || !SetInitializerObjectType(cx, script, regs.pc, obj))
NewObjectKind newKind = UseNewTypeForInitializer(cx, script, regs.pc, baseobj->getClass());
obj = CopyInitializerObject(cx, baseobj, newKind);
if (!obj || !SetInitializerObjectType(cx, script, regs.pc, obj, newKind))
goto error;
PUSH_OBJECT(*obj);

View File

@ -390,7 +390,7 @@ NewPropertyIteratorObject(JSContext *cx, unsigned flags)
if (!shape)
return NULL;
RawObject obj = JSObject::create(cx, ITERATOR_FINALIZE_KIND, shape, type, NULL);
RawObject obj = JSObject::create(cx, ITERATOR_FINALIZE_KIND, gc::DefaultHeap, shape, type, NULL);
if (!obj)
return NULL;

View File

@ -713,8 +713,8 @@ static JSFunctionSpec math_static_methods[] = {
JSObject *
js_InitMathClass(JSContext *cx, HandleObject obj)
{
RootedObject Math(cx, NewObjectWithClassProto(cx, &MathClass, NULL, obj));
if (!Math || !JSObject::setSingletonType(cx, Math))
RootedObject Math(cx, NewObjectWithClassProto(cx, &MathClass, NULL, obj, SingletonObject));
if (!Math)
return NULL;
if (!JS_DefineProperty(cx, obj, js_Math_str, OBJECT_TO_JSVAL(Math),

View File

@ -1178,7 +1178,7 @@ NewObjectGCKind(js::Class *clasp)
static inline JSObject *
NewObject(JSContext *cx, Class *clasp, types::TypeObject *type_, JSObject *parent,
gc::AllocKind kind)
gc::AllocKind kind, NewObjectKind newKind)
{
AssertCanGC();
JS_ASSERT(clasp != &ArrayClass);
@ -1197,12 +1197,22 @@ NewObject(JSContext *cx, Class *clasp, types::TypeObject *type_, JSObject *paren
if (!PreallocateObjectDynamicSlots(cx, shape, &slots))
return NULL;
JSObject *obj = JSObject::create(cx, kind, shape, type, slots);
gc::InitialHeap heap = InitialHeapForNewKind(newKind);
JSObject *obj = JSObject::create(cx, kind, heap, shape, type, slots);
if (!obj) {
js_free(slots);
return NULL;
}
if (newKind == SingletonObject) {
RootedObject nobj(cx, obj);
if (!JSObject::setSingletonType(cx, nobj)) {
js_free(slots);
return NULL;
}
obj = nobj;
}
/*
* This will cancel an already-running incremental GC from doing any more
* slices, and it will prevent any future incremental GCs.
@ -1217,22 +1227,22 @@ NewObject(JSContext *cx, Class *clasp, types::TypeObject *type_, JSObject *paren
JSObject *
js::NewObjectWithGivenProto(JSContext *cx, js::Class *clasp,
js::TaggedProto proto_, JSObject *parent_,
gc::AllocKind kind)
gc::AllocKind allocKind, NewObjectKind newKind)
{
Rooted<TaggedProto> proto(cx, proto_);
RootedObject parent(cx, parent_);
if (CanBeFinalizedInBackground(kind, clasp))
kind = GetBackgroundAllocKind(kind);
if (CanBeFinalizedInBackground(allocKind, clasp))
allocKind = GetBackgroundAllocKind(allocKind);
NewObjectCache &cache = cx->runtime->newObjectCache;
NewObjectCache::EntryIndex entry = -1;
if (proto.isObject() &&
if (proto.isObject() && newKind != SingletonObject &&
(!parent || parent == proto.toObject()->getParent()) && !proto.toObject()->isGlobal())
{
if (cache.lookupProto(clasp, proto.toObject(), kind, &entry)) {
JSObject *obj = cache.newObjectFromHit(cx, entry);
if (cache.lookupProto(clasp, proto.toObject(), allocKind, &entry)) {
JSObject *obj = cache.newObjectFromHit(cx, entry, InitialHeapForNewKind(newKind));
if (obj)
return obj;
}
@ -1249,25 +1259,25 @@ js::NewObjectWithGivenProto(JSContext *cx, js::Class *clasp,
if (!parent && proto.isObject())
parent = proto.toObject()->getParent();
JSObject *obj = NewObject(cx, clasp, type, parent, kind);
RootedObject obj(cx, NewObject(cx, clasp, type, parent, allocKind, newKind));
if (!obj)
return NULL;
if (entry != -1 && !obj->hasDynamicSlots())
cache.fillProto(entry, clasp, proto, kind, obj);
cache.fillProto(entry, clasp, proto, allocKind, obj);
return obj;
}
JSObject *
js::NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *protoArg, JSObject *parentArg,
gc::AllocKind kind)
js::NewObjectWithClassProtoCommon(JSContext *cx, js::Class *clasp, JSObject *protoArg, JSObject *parentArg,
gc::AllocKind allocKind, NewObjectKind newKind)
{
if (protoArg)
return NewObjectWithGivenProto(cx, clasp, protoArg, parentArg, kind);
return NewObjectWithGivenProto(cx, clasp, protoArg, parentArg, allocKind, newKind);
if (CanBeFinalizedInBackground(kind, clasp))
kind = GetBackgroundAllocKind(kind);
if (CanBeFinalizedInBackground(allocKind, clasp))
allocKind = GetBackgroundAllocKind(allocKind);
if (!parentArg)
parentArg = cx->global();
@ -1286,9 +1296,9 @@ js::NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *protoArg,
NewObjectCache &cache = cx->runtime->newObjectCache;
NewObjectCache::EntryIndex entry = -1;
if (parentArg->isGlobal() && protoKey != JSProto_Null) {
if (cache.lookupGlobal(clasp, &parentArg->asGlobal(), kind, &entry)) {
JSObject *obj = cache.newObjectFromHit(cx, entry);
if (parentArg->isGlobal() && protoKey != JSProto_Null && newKind != SingletonObject) {
if (cache.lookupGlobal(clasp, &parentArg->asGlobal(), allocKind, &entry)) {
JSObject *obj = cache.newObjectFromHit(cx, entry, InitialHeapForNewKind(newKind));
if (obj)
return obj;
}
@ -1304,43 +1314,44 @@ js::NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *protoArg,
if (!type)
return NULL;
JSObject *obj = NewObject(cx, clasp, type, parent, kind);
JSObject *obj = NewObject(cx, clasp, type, parent, allocKind, newKind);
if (!obj)
return NULL;
if (entry != -1 && !obj->hasDynamicSlots())
cache.fillGlobal(entry, clasp, &parent->asGlobal(), kind, obj);
cache.fillGlobal(entry, clasp, &parent->asGlobal(), allocKind, obj);
return obj;
}
JSObject *
js::NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind kind)
js::NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind allocKind,
NewObjectKind newKind /* = GenericObject */)
{
JS_ASSERT(type->proto->hasNewType(&ObjectClass, type));
JS_ASSERT(parent);
JS_ASSERT(kind <= gc::FINALIZE_OBJECT_LAST);
if (CanBeFinalizedInBackground(kind, &ObjectClass))
kind = GetBackgroundAllocKind(kind);
JS_ASSERT(allocKind <= gc::FINALIZE_OBJECT_LAST);
if (CanBeFinalizedInBackground(allocKind, &ObjectClass))
allocKind = GetBackgroundAllocKind(allocKind);
NewObjectCache &cache = cx->runtime->newObjectCache;
NewObjectCache::EntryIndex entry = -1;
if (parent == type->proto->getParent()) {
if (cache.lookupType(&ObjectClass, type, kind, &entry)) {
JSObject *obj = cache.newObjectFromHit(cx, entry);
if (parent == type->proto->getParent() && newKind != SingletonObject) {
if (cache.lookupType(&ObjectClass, type, allocKind, &entry)) {
JSObject *obj = cache.newObjectFromHit(cx, entry, InitialHeapForNewKind(newKind));
if (obj)
return obj;
}
}
JSObject *obj = NewObject(cx, &ObjectClass, type, parent, kind);
JSObject *obj = NewObject(cx, &ObjectClass, type, parent, allocKind, newKind);
if (!obj)
return NULL;
if (entry != -1 && !obj->hasDynamicSlots())
cache.fillType(entry, &ObjectClass, type, kind, obj);
cache.fillType(entry, &ObjectClass, type, allocKind, obj);
return obj;
}
@ -1348,16 +1359,19 @@ js::NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc
bool
js::NewObjectScriptedCall(JSContext *cx, MutableHandleObject pobj)
{
gc::AllocKind kind = NewObjectGCKind(&ObjectClass);
RootedObject obj(cx, NewBuiltinClassInstance(cx, &ObjectClass, kind));
jsbytecode *pc;
RootedScript script(cx, cx->stack.currentScript(&pc));
gc::AllocKind allocKind = NewObjectGCKind(&ObjectClass);
NewObjectKind newKind = script
? UseNewTypeForInitializer(cx, script, pc, &ObjectClass)
: GenericObject;
RootedObject obj(cx, NewBuiltinClassInstance(cx, &ObjectClass, allocKind, newKind));
if (!obj)
return false;
jsbytecode *pc;
RootedScript script(cx, cx->stack.currentScript(&pc));
if (script) {
/* Try to specialize the type of the object to the scripted call site. */
if (!types::SetInitializerObjectType(cx, script, pc, obj))
if (!types::SetInitializerObjectType(cx, script, pc, obj, newKind))
return false;
}
@ -1406,7 +1420,7 @@ js::NewReshapedObject(JSContext *cx, HandleTypeObject type, JSObject *parent,
}
JSObject*
js_CreateThis(JSContext *cx, Class *newclasp, HandleObject callee)
js::CreateThis(JSContext *cx, Class *newclasp, HandleObject callee)
{
RootedValue protov(cx);
if (!JSObject::getProperty(cx, callee, callee, cx->names().classPrototype, &protov))
@ -1419,7 +1433,8 @@ js_CreateThis(JSContext *cx, Class *newclasp, HandleObject callee)
}
static inline JSObject *
CreateThisForFunctionWithType(JSContext *cx, HandleTypeObject type, JSObject *parent)
CreateThisForFunctionWithType(JSContext *cx, HandleTypeObject type, JSObject *parent,
NewObjectKind newKind)
{
if (type->newScript) {
/*
@ -1436,12 +1451,13 @@ CreateThisForFunctionWithType(JSContext *cx, HandleTypeObject type, JSObject *pa
return res;
}
gc::AllocKind kind = NewObjectGCKind(&ObjectClass);
return NewObjectWithType(cx, type, parent, kind);
gc::AllocKind allocKind = NewObjectGCKind(&ObjectClass);
return NewObjectWithType(cx, type, parent, allocKind, newKind);
}
JSObject *
js_CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject *proto)
js::CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject *proto,
NewObjectKind newKind /* = GenericObject */)
{
JSObject *res;
@ -1449,10 +1465,10 @@ js_CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject *
RootedTypeObject type(cx, proto->getNewType(cx, &ObjectClass, callee->toFunction()));
if (!type)
return NULL;
res = CreateThisForFunctionWithType(cx, type, callee->getParent());
res = CreateThisForFunctionWithType(cx, type, callee->getParent(), newKind);
} else {
gc::AllocKind kind = NewObjectGCKind(&ObjectClass);
res = NewObjectWithClassProto(cx, &ObjectClass, proto, callee->getParent(), kind);
gc::AllocKind allocKind = NewObjectGCKind(&ObjectClass);
res = NewObjectWithClassProto(cx, &ObjectClass, proto, callee->getParent(), allocKind, newKind);
}
if (res && cx->typeInferenceEnabled()) {
@ -1464,7 +1480,7 @@ js_CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject *
}
JSObject *
js_CreateThisForFunction(JSContext *cx, HandleObject callee, bool newType)
js::CreateThisForFunction(JSContext *cx, HandleObject callee, bool newType)
{
RootedValue protov(cx);
if (!JSObject::getProperty(cx, callee, callee, cx->names().classPrototype, &protov))
@ -1474,18 +1490,14 @@ js_CreateThisForFunction(JSContext *cx, HandleObject callee, bool newType)
proto = &protov.toObject();
else
proto = NULL;
JSObject *obj = js_CreateThisForFunctionWithProto(cx, callee, proto);
NewObjectKind newKind = newType ? SingletonObject : GenericObject;
JSObject *obj = CreateThisForFunctionWithProto(cx, callee, proto, newKind);
if (obj && newType) {
RootedObject nobj(cx, obj);
/*
* Reshape the object and give it a (lazily instantiated) singleton
* type before passing it as the 'this' value for the call.
*/
/* Reshape the singleton before passing it as the 'this' value. */
JSObject::clear(cx, nobj);
if (!JSObject::setSingletonType(cx, nobj))
return NULL;
RootedScript calleeScript(cx, callee->toFunction()->nonLazyScript());
TypeScript::SetThis(cx, calleeScript, types::Type::ObjectType(nobj));
@ -1690,8 +1702,7 @@ js::CloneObject(JSContext *cx, HandleObject obj, Handle<js::TaggedProto> proto,
JSMSG_CANT_CLONE_OBJECT);
return NULL;
}
RootedObject clone(cx, NewObjectWithGivenProto(cx, obj->getClass(),
proto, parent, obj->getAllocKind()));
RootedObject clone(cx, NewObjectWithGivenProto(cx, obj->getClass(), proto, parent));
if (!clone)
return NULL;
if (obj->isNative()) {
@ -2117,13 +2128,10 @@ js::DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey ke
* [which already needs to happen for bug 638316], figure out nicer
* semantics for null-protoProto, and use createBlankPrototype.)
*/
RootedObject proto(cx, NewObjectWithClassProto(cx, clasp, protoProto, obj));
RootedObject proto(cx, NewObjectWithClassProto(cx, clasp, protoProto, obj, SingletonObject));
if (!proto)
return NULL;
if (!JSObject::setSingletonType(cx, proto))
return NULL;
/* After this point, control must exit via label bad or out. */
RootedObject ctor(cx);
bool named = false;
@ -2152,8 +2160,8 @@ js::DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey ke
* (FIXME: remove this dependency on the exact identity of the parent,
* perhaps as part of bug 638316.)
*/
RootedFunction fun(cx, js_NewFunction(cx, NullPtr(), constructor, nargs,
JSFunction::NATIVE_CTOR, obj, atom, ctorKind));
RootedFunction fun(cx, NewFunction(cx, NullPtr(), constructor, nargs,
JSFunction::NATIVE_CTOR, obj, atom, ctorKind));
if (!fun)
goto bad;

View File

@ -20,7 +20,6 @@
#include "jsatom.h"
#include "jsclass.h"
#include "jsfriendapi.h"
#include "jsinfer.h"
#include "gc/Barrier.h"
#include "gc/Heap.h"
@ -300,6 +299,7 @@ class JSObject : public js::ObjectImpl
/* Make a non-array object with the specified initial state. */
static inline JSObject *create(JSContext *cx,
js::gc::AllocKind kind,
js::gc::InitialHeap heap,
js::HandleShape shape,
js::HandleTypeObject type,
js::HeapSlot *slots);
@ -307,6 +307,7 @@ class JSObject : public js::ObjectImpl
/* Make an array object with the specified initial state. */
static inline JSObject *createArray(JSContext *cx,
js::gc::AllocKind kind,
js::gc::InitialHeap heap,
js::HandleShape shape,
js::HandleTypeObject type,
uint32_t length);
@ -1160,19 +1161,6 @@ bool
js_FindClassObject(JSContext *cx, JSProtoKey protoKey, js::MutableHandleValue vp,
js::Class *clasp = NULL);
// Specialized call for constructing |this| with a known function callee,
// and a known prototype.
extern JSObject *
js_CreateThisForFunctionWithProto(JSContext *cx, js::HandleObject callee, JSObject *proto);
// Specialized call for constructing |this| with a known function callee.
extern JSObject *
js_CreateThisForFunction(JSContext *cx, js::HandleObject callee, bool newType);
// Generic call for constructing |this|.
extern JSObject *
js_CreateThis(JSContext *cx, js::Class *clasp, js::HandleObject callee);
/*
* Find or create a property named by id in obj's scope, with the given getter
* and setter, slot, attributes, and other members.
@ -1188,7 +1176,50 @@ js_DefineOwnProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
namespace js {
JSObject *
/*
* The NewObjectKind allows an allocation site to specify the type properties
* and lifetime requirements that must be fixed at allocation time.
*/
enum NewObjectKind {
/* This is the default. Most objects are generic. */
GenericObject,
/*
* Singleton objects are treated specially by the type system. This flag
* ensures that the new object is automatically set up correctly as a
* singleton and is allocated in the correct heap.
*/
SingletonObject,
/*
* Objects which may be marked as a singleton after allocation must still
* be allocated on the correct heap, but are not automatically setup as a
* singleton after allocation.
*/
MaybeSingletonObject
};
inline gc::InitialHeap
InitialHeapForNewKind(NewObjectKind newKind)
{
return newKind == GenericObject ? gc::DefaultHeap : gc::TenuredHeap;
}
// Specialized call for constructing |this| with a known function callee,
// and a known prototype.
extern JSObject *
CreateThisForFunctionWithProto(JSContext *cx, js::HandleObject callee, JSObject *proto,
NewObjectKind newKind = GenericObject);
// Specialized call for constructing |this| with a known function callee.
extern JSObject *
CreateThisForFunction(JSContext *cx, js::HandleObject callee, bool newType);
// Generic call for constructing |this|.
extern JSObject *
CreateThis(JSContext *cx, js::Class *clasp, js::HandleObject callee);
extern JSObject *
CloneObject(JSContext *cx, HandleObject obj, Handle<js::TaggedProto> proto, HandleObject parent);
/*

View File

@ -751,6 +751,9 @@ JSObject::setDateUTCTime(const js::Value &time)
/* static */ inline bool
JSObject::setSingletonType(JSContext *cx, js::HandleObject obj)
{
#if defined(JSGC_GENERATIONAL)
JS_ASSERT(!obj->runtime()->gcNursery.isInside(obj.get()));
#endif
if (!cx->typeInferenceEnabled())
return true;
@ -758,8 +761,7 @@ JSObject::setSingletonType(JSContext *cx, js::HandleObject obj)
JS_ASSERT_IF(obj->getTaggedProto().isObject(),
obj->type() == obj->getTaggedProto().toObject()->getNewType(cx, obj->getClass()));
js::Rooted<js::TaggedProto> objProto(cx, obj->getTaggedProto());
js::types::TypeObject *type = cx->compartment->getLazyType(cx, obj->getClass(), objProto);
js::types::TypeObject *type = cx->compartment->getLazyType(cx, obj->getClass(), obj->getTaggedProto());
if (!type)
return false;
@ -941,7 +943,7 @@ JSObject::isDebugScope() const
}
/* static */ inline JSObject *
JSObject::create(JSContext *cx, js::gc::AllocKind kind,
JSObject::create(JSContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
js::HandleShape shape, js::HandleTypeObject type, js::HeapSlot *slots)
{
/*
@ -956,7 +958,7 @@ JSObject::create(JSContext *cx, js::gc::AllocKind kind,
JS_ASSERT(js::gc::GetGCKindSlots(kind, type->clasp) == shape->numFixedSlots());
JS_ASSERT(cx->compartment == type->compartment());
JSObject *obj = js_NewGCObject<js::CanGC>(cx, kind);
JSObject *obj = js_NewGCObject<js::CanGC>(cx, kind, heap);
if (!obj)
return NULL;
@ -977,7 +979,7 @@ JSObject::create(JSContext *cx, js::gc::AllocKind kind,
}
/* static */ inline JSObject *
JSObject::createArray(JSContext *cx, js::gc::AllocKind kind,
JSObject::createArray(JSContext *cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
js::HandleShape shape, js::HandleTypeObject type,
uint32_t length)
{
@ -1001,7 +1003,7 @@ JSObject::createArray(JSContext *cx, js::gc::AllocKind kind,
uint32_t capacity = js::gc::GetGCKindSlots(kind) - js::ObjectElements::VALUES_PER_HEADER;
JSObject *obj = js_NewGCObject<js::CanGC>(cx, kind);
JSObject *obj = js_NewGCObject<js::CanGC>(cx, kind, heap);
if (!obj) {
js_ReportOutOfMemory(cx);
return NULL;
@ -1587,19 +1589,21 @@ CanBeFinalizedInBackground(gc::AllocKind kind, Class *clasp)
*/
JSObject *
NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, TaggedProto proto, JSObject *parent,
gc::AllocKind kind);
gc::AllocKind allocKind, NewObjectKind newKind);
inline JSObject *
NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, TaggedProto proto, JSObject *parent)
NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, TaggedProto proto, JSObject *parent,
NewObjectKind newKind = GenericObject)
{
gc::AllocKind kind = gc::GetGCObjectKind(clasp);
return NewObjectWithGivenProto(cx, clasp, proto, parent, kind);
gc::AllocKind allocKind = gc::GetGCObjectKind(clasp);
return NewObjectWithGivenProto(cx, clasp, proto, parent, allocKind, newKind);
}
inline JSObject *
NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent)
NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
NewObjectKind newKind = GenericObject)
{
return NewObjectWithGivenProto(cx, clasp, TaggedProto(proto), parent);
return NewObjectWithGivenProto(cx, clasp, TaggedProto(proto), parent, newKind);
}
inline JSProtoKey
@ -1642,14 +1646,22 @@ FindProto(JSContext *cx, js::Class *clasp, MutableHandleObject proto)
* parent will be that global.
*/
JSObject *
NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
gc::AllocKind kind);
NewObjectWithClassProtoCommon(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
gc::AllocKind allocKind, NewObjectKind newKind);
inline JSObject *
NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent)
NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
gc::AllocKind allocKind, NewObjectKind newKind = GenericObject)
{
gc::AllocKind kind = gc::GetGCObjectKind(clasp);
return NewObjectWithClassProto(cx, clasp, proto, parent, kind);
return NewObjectWithClassProtoCommon(cx, clasp, proto, parent, allocKind, newKind);
}
inline JSObject *
NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
NewObjectKind newKind = GenericObject)
{
gc::AllocKind allocKind = gc::GetGCObjectKind(clasp);
return NewObjectWithClassProto(cx, clasp, proto, parent, allocKind, newKind);
}
/*
@ -1657,16 +1669,17 @@ NewObjectWithClassProto(JSContext *cx, js::Class *clasp, JSObject *proto, JSObje
* according to the context's active global.
*/
inline JSObject *
NewBuiltinClassInstance(JSContext *cx, Class *clasp, gc::AllocKind kind)
NewBuiltinClassInstance(JSContext *cx, Class *clasp, gc::AllocKind allocKind,
NewObjectKind newKind = GenericObject)
{
return NewObjectWithClassProto(cx, clasp, NULL, NULL, kind);
return NewObjectWithClassProto(cx, clasp, NULL, NULL, allocKind, newKind);
}
inline JSObject *
NewBuiltinClassInstance(JSContext *cx, Class *clasp)
NewBuiltinClassInstance(JSContext *cx, Class *clasp, NewObjectKind newKind = GenericObject)
{
gc::AllocKind kind = gc::GetGCObjectKind(clasp);
return NewBuiltinClassInstance(cx, clasp, kind);
gc::AllocKind allocKind = gc::GetGCObjectKind(clasp);
return NewBuiltinClassInstance(cx, clasp, allocKind, newKind);
}
bool
@ -1678,7 +1691,8 @@ FindClassPrototype(JSContext *cx, HandleObject scope, JSProtoKey protoKey,
* avoid losing creation site information for objects made by scripted 'new'.
*/
JSObject *
NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind kind);
NewObjectWithType(JSContext *cx, HandleTypeObject type, JSObject *parent, gc::AllocKind allocKind,
NewObjectKind newKind = GenericObject);
// Used to optimize calls to (new Object())
bool
@ -1686,16 +1700,16 @@ NewObjectScriptedCall(JSContext *cx, MutableHandleObject obj);
/* Make an object with pregenerated shape from a NEWOBJECT bytecode. */
static inline JSObject *
CopyInitializerObject(JSContext *cx, HandleObject baseobj)
CopyInitializerObject(JSContext *cx, HandleObject baseobj, NewObjectKind newKind = GenericObject)
{
JS_ASSERT(baseobj->getClass() == &ObjectClass);
JS_ASSERT(!baseobj->inDictionaryMode());
gc::AllocKind kind = gc::GetGCObjectFixedSlotsKind(baseobj->numFixedSlots());
kind = gc::GetBackgroundAllocKind(kind);
JS_ASSERT(kind == baseobj->getAllocKind());
RootedObject obj(cx, NewBuiltinClassInstance(cx, &ObjectClass, kind));
gc::AllocKind allocKind = gc::GetGCObjectFixedSlotsKind(baseobj->numFixedSlots());
allocKind = gc::GetBackgroundAllocKind(allocKind);
JS_ASSERT(allocKind == baseobj->getAllocKind());
RootedObject obj(cx);
obj = NewBuiltinClassInstance(cx, &ObjectClass, allocKind, newKind);
if (!obj)
return NULL;

View File

@ -902,8 +902,8 @@ js_InitJSONClass(JSContext *cx, HandleObject obj)
if (!global->getOrCreateBooleanPrototype(cx))
return NULL;
RootedObject JSON(cx, NewObjectWithClassProto(cx, &JSONClass, NULL, global));
if (!JSON || !JSObject::setSingletonType(cx, JSON))
RootedObject JSON(cx, NewObjectWithClassProto(cx, &JSONClass, NULL, global, SingletonObject));
if (!JSON)
return NULL;
if (!JS_DefineProperty(cx, global, js_JSON_str, OBJECT_TO_JSVAL(JSON),

View File

@ -3105,7 +3105,8 @@ NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv_, Tag
return NULL;
}
RootedObject obj(cx, NewObjectWithGivenProto(cx, clasp, proto, parent));
NewObjectKind newKind = clasp == &OuterWindowProxyClass ? SingletonObject : GenericObject;
RootedObject obj(cx, NewObjectWithGivenProto(cx, clasp, proto, parent, newKind));
if (!obj)
return NULL;
obj->initSlot(JSSLOT_PROXY_HANDLER, PrivateValue(handler));
@ -3118,11 +3119,8 @@ NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv_, Tag
}
/* Don't track types of properties of proxies. */
MarkTypeObjectUnknownProperties(cx, obj->type());
/* Mark the new proxy as having singleton type. */
if (clasp == &OuterWindowProxyClass && !JSObject::setSingletonType(cx, obj))
return NULL;
if (newKind != SingletonObject)
MarkTypeObjectUnknownProperties(cx, obj->type());
return obj;
}
@ -3274,8 +3272,8 @@ static JSFunctionSpec static_methods[] = {
JS_FRIEND_API(JSObject *)
js_InitProxyClass(JSContext *cx, HandleObject obj)
{
RootedObject module(cx, NewObjectWithClassProto(cx, &ProxyClass, NULL, obj));
if (!module || !JSObject::setSingletonType(cx, module))
RootedObject module(cx, NewObjectWithClassProto(cx, &ProxyClass, NULL, obj, SingletonObject));
if (!module)
return NULL;
if (!JS_DefineProperty(cx, obj, "Proxy", OBJECT_TO_JSVAL(module),

View File

@ -3061,8 +3061,8 @@ JS_PUBLIC_API(JSObject *)
JS_InitReflect(JSContext *cx, JSObject *objArg)
{
RootedObject obj(cx, objArg);
RootedObject Reflect(cx, NewObjectWithClassProto(cx, &ObjectClass, NULL, obj));
if (!Reflect || !JSObject::setSingletonType(cx, Reflect))
RootedObject Reflect(cx, NewObjectWithClassProto(cx, &ObjectClass, NULL, obj, SingletonObject));
if (!Reflect)
return NULL;
if (!JS_DefineProperty(cx, obj, "Reflect", OBJECT_TO_JSVAL(Reflect),

View File

@ -1537,34 +1537,59 @@ class TypedArrayTemplate
return true;
}
static JSObject *
makeProtoInstance(JSContext *cx, HandleObject proto)
{
JS_ASSERT(proto);
JSObject *obj = NewBuiltinClassInstance(cx, fastClass());
if (!obj)
return NULL;
types::TypeObject *type = proto->getNewType(cx, obj->getClass());
if (!type)
return NULL;
obj->setType(type);
return obj;
}
static JSObject *
makeTypedInstance(JSContext *cx, uint32_t len)
{
if (len * sizeof(NativeType) >= TypedArray::SINGLETON_TYPE_BYTE_LENGTH)
return NewBuiltinClassInstance(cx, fastClass(), SingletonObject);
jsbytecode *pc;
RootedScript script(cx, cx->stack.currentScript(&pc));
NewObjectKind newKind = script
? UseNewTypeForInitializer(cx, script, pc, fastClass())
: GenericObject;
RootedObject obj(cx, NewBuiltinClassInstance(cx, fastClass(), newKind));
if (script) {
if (!types::SetInitializerObjectType(cx, script, pc, obj, newKind))
return NULL;
}
return obj;
}
static JSObject *
makeInstance(JSContext *cx, HandleObject bufobj, uint32_t byteOffset, uint32_t len,
HandleObject proto)
{
RootedObject obj(cx, NewBuiltinClassInstance(cx, fastClass()));
RootedObject obj(cx);
if (proto)
obj = makeProtoInstance(cx, proto);
else if (cx->typeInferenceEnabled())
obj = makeTypedInstance(cx, len);
else
obj = NewBuiltinClassInstance(cx, fastClass());
if (!obj)
return NULL;
JS_ASSERT(obj->getAllocKind() == gc::FINALIZE_OBJECT8_BACKGROUND);
if (proto) {
types::TypeObject *type = proto->getNewType(cx, obj->getClass());
if (!type)
return NULL;
obj->setType(type);
} else if (cx->typeInferenceEnabled()) {
if (len * sizeof(NativeType) >= TypedArray::SINGLETON_TYPE_BYTE_LENGTH) {
if (!JSObject::setSingletonType(cx, obj))
return NULL;
} else {
jsbytecode *pc;
RootedScript script(cx, cx->stack.currentScript(&pc));
if (script) {
if (!types::SetInitializerObjectType(cx, script, pc, obj))
return NULL;
}
}
}
obj->setSlot(TYPE_SLOT, Int32Value(ArrayTypeID()));
obj->setSlot(BUFFER_SLOT, ObjectValue(*bufobj));
@ -1724,8 +1749,8 @@ class TypedArrayTemplate
unsigned flags = JSPROP_SHARED | JSPROP_GETTER | JSPROP_PERMANENT;
Rooted<GlobalObject*> global(cx, cx->compartment->maybeGlobal());
RawObject getter = js_NewFunction(cx, NullPtr(), Getter<ValueGetter>, 0,
JSFunction::NATIVE_FUN, global, NullPtr());
RawObject getter = NewFunction(cx, NullPtr(), Getter<ValueGetter>, 0,
JSFunction::NATIVE_FUN, global, NullPtr());
if (!getter)
return false;
@ -3376,9 +3401,9 @@ InitTypedArrayClass(JSContext *cx)
RootedFunction fun(cx);
fun =
js_NewFunction(cx, NullPtr(),
ArrayBufferObject::createTypedArrayFromBuffer<typename ArrayType::ThisType>,
0, JSFunction::NATIVE_FUN, global, NullPtr());
NewFunction(cx, NullPtr(),
ArrayBufferObject::createTypedArrayFromBuffer<typename ArrayType::ThisType>,
0, JSFunction::NATIVE_FUN, global, NullPtr());
if (!fun)
return NULL;
@ -3459,8 +3484,8 @@ InitArrayBufferClass(JSContext *cx)
RootedId byteLengthId(cx, NameToId(cx->names().byteLength));
unsigned flags = JSPROP_SHARED | JSPROP_GETTER | JSPROP_PERMANENT;
RawObject getter = js_NewFunction(cx, NullPtr(), ArrayBufferObject::byteLengthGetter, 0,
JSFunction::NATIVE_FUN, global, NullPtr());
RawObject getter = NewFunction(cx, NullPtr(), ArrayBufferObject::byteLengthGetter, 0,
JSFunction::NATIVE_FUN, global, NullPtr());
if (!getter)
return NULL;
@ -3561,8 +3586,8 @@ DataViewObject::defineGetter(JSContext *cx, PropertyName *name, HandleObject pro
unsigned flags = JSPROP_SHARED | JSPROP_GETTER | JSPROP_PERMANENT;
Rooted<GlobalObject*> global(cx, cx->compartment->maybeGlobal());
JSObject *getter = js_NewFunction(cx, NullPtr(), DataViewObject::getter<ValueGetter>, 0,
JSFunction::NATIVE_FUN, global, NullPtr());
JSObject *getter = NewFunction(cx, NullPtr(), DataViewObject::getter<ValueGetter>, 0,
JSFunction::NATIVE_FUN, global, NullPtr());
if (!getter)
return false;
@ -3605,8 +3630,8 @@ DataViewObject::initClass(JSContext *cx)
* |new DataView(new otherWindow.ArrayBuffer())|, and install it in the
* global for use by the DataView constructor.
*/
RootedFunction fun(cx, js_NewFunction(cx, NullPtr(), ArrayBufferObject::createDataViewForThis,
0, JSFunction::NATIVE_FUN, global, NullPtr()));
RootedFunction fun(cx, NewFunction(cx, NullPtr(), ArrayBufferObject::createDataViewForThis,
0, JSFunction::NATIVE_FUN, global, NullPtr()));
if (!fun)
return NULL;

View File

@ -212,6 +212,16 @@ InitTypedArrayDataPointer(JSObject *obj, ArrayBufferObject *buffer, size_t byteO
#endif
}
static NewObjectKind
DataViewNewObjectKind(JSContext *cx, uint32_t byteLength, JSObject *proto)
{
jsbytecode *pc;
JSScript *script = cx->stack.currentScript(&pc);
if (!proto && byteLength >= TypedArray::SINGLETON_TYPE_BYTE_LENGTH)
return types::UseNewTypeForInitializer(cx, script, pc, &DataViewClass);
return GenericObject;
}
inline DataViewObject *
DataViewObject::create(JSContext *cx, uint32_t byteOffset, uint32_t byteLength,
Handle<ArrayBufferObject*> arrayBuffer, JSObject *protoArg)
@ -220,7 +230,10 @@ DataViewObject::create(JSContext *cx, uint32_t byteOffset, uint32_t byteLength,
JS_ASSERT(byteLength <= INT32_MAX);
RootedObject proto(cx, protoArg);
RootedObject obj(cx, NewBuiltinClassInstance(cx, &DataViewClass));
RootedObject obj(cx);
NewObjectKind newKind = DataViewNewObjectKind(cx, byteLength, proto);
obj = NewBuiltinClassInstance(cx, &DataViewClass, newKind);
if (!obj)
return NULL;
@ -231,13 +244,12 @@ DataViewObject::create(JSContext *cx, uint32_t byteOffset, uint32_t byteLength,
obj->setType(type);
} else if (cx->typeInferenceEnabled()) {
if (byteLength >= TypedArray::SINGLETON_TYPE_BYTE_LENGTH) {
if (!JSObject::setSingletonType(cx, obj))
return NULL;
JS_ASSERT(obj->hasSingletonType());
} else {
jsbytecode *pc;
RootedScript script(cx, cx->stack.currentScript(&pc));
if (script) {
if (!types::SetInitializerObjectType(cx, script, pc, obj))
if (!types::SetInitializerObjectType(cx, script, pc, obj, newKind))
return NULL;
}
}

View File

@ -6968,7 +6968,8 @@ mjit::Compiler::jsop_newinit()
!type ||
(isArray && count > maxArraySlots) ||
(!isArray && !baseobj) ||
(!isArray && baseobj->hasDynamicSlots())) {
(!isArray && baseobj->hasDynamicSlots()))
{
prepareStubCall(Uses(0));
masm.storePtr(ImmPtr(type), FrameAddress(offsetof(VMFrame, scratch)));
masm.move(ImmPtr(stubArg), Registers::ArgReg1);
@ -7407,7 +7408,7 @@ mjit::Compiler::leaveBlock()
// GETPROP "prototype"
// IFPRIMTOP:
// NULL
// call js_CreateThisFromFunctionWithProto(...)
// call CreateThisFromFunctionWithProto(...)
//
bool
mjit::Compiler::constructThis()
@ -7442,7 +7443,7 @@ mjit::Compiler::constructThis()
if (!types::TypeScript::ThisTypes(script_)->hasType(types::Type::ObjectType(type)))
break;
JSObject *templateObject = js_CreateThisForFunctionWithProto(cx, fun, proto);
JSObject *templateObject = CreateThisForFunctionWithProto(cx, fun, proto);
if (!templateObject)
return false;

View File

@ -686,7 +686,7 @@ stubs::CreateThis(VMFrame &f, JSObject *proto)
JSContext *cx = f.cx;
StackFrame *fp = f.fp();
RootedObject callee(cx, &fp->callee());
JSObject *obj = js_CreateThisForFunctionWithProto(cx, callee, proto);
JSObject *obj = CreateThisForFunctionWithProto(cx, callee, proto);
if (!obj)
THROW();
fp->thisValue() = ObjectValue(*obj);
@ -897,7 +897,7 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
case REJOIN_THIS_PROTOTYPE: {
RootedObject callee(cx, &fp->callee());
JSObject *proto = f.regs.sp[0].isObject() ? &f.regs.sp[0].toObject() : NULL;
JSObject *obj = js_CreateThisForFunctionWithProto(cx, callee, proto);
JSObject *obj = CreateThisForFunctionWithProto(cx, callee, proto);
if (!obj)
return js_InternalThrow(f);
fp->thisValue() = ObjectValue(*obj);
@ -958,7 +958,7 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
case REJOIN_FUNCTION_PROLOGUE:
if (fp->isConstructing()) {
RootedObject callee(cx, &fp->callee());
JSObject *obj = js_CreateThisForFunction(cx, callee, types::UseNewTypeAtEntry(cx, fp));
JSObject *obj = CreateThisForFunction(cx, callee, types::UseNewTypeAtEntry(cx, fp));
if (!obj)
return js_InternalThrow(f);
fp->functionThis() = ObjectValue(*obj);

View File

@ -935,15 +935,17 @@ void JS_FASTCALL
stubs::NewInitArray(VMFrame &f, uint32_t count)
{
Rooted<TypeObject*> type(f.cx, (TypeObject *) f.scratch);
RootedObject obj(f.cx, NewDenseAllocatedArray(f.cx, count));
RootedScript fscript(f.cx, f.script());
NewObjectKind newKind = UseNewTypeForInitializer(f.cx, fscript, f.pc(), &ArrayClass);
RootedObject obj(f.cx, NewDenseAllocatedArray(f.cx, count, NULL, newKind));
if (!obj)
THROW();
if (type) {
obj->setType(type);
} else {
RootedScript fscript(f.cx, f.script());
if (!SetInitializerObjectType(f.cx, fscript, f.pc(), obj))
if (!SetInitializerObjectType(f.cx, fscript, f.pc(), obj, newKind))
THROW();
}
@ -955,14 +957,16 @@ stubs::NewInitObject(VMFrame &f, JSObject *baseobj)
{
JSContext *cx = f.cx;
Rooted<TypeObject*> type(f.cx, (TypeObject *) f.scratch);
RootedScript fscript(f.cx, f.script());
NewObjectKind newKind = UseNewTypeForInitializer(f.cx, fscript, f.pc(), &ObjectClass);
RootedObject obj(cx);
if (baseobj) {
Rooted<JSObject*> base(cx, baseobj);
obj = CopyInitializerObject(cx, base);
obj = CopyInitializerObject(cx, base, newKind);
} else {
gc::AllocKind kind = GuessObjectGCKind(0);
obj = NewBuiltinClassInstance(cx, &ObjectClass, kind);
gc::AllocKind allocKind = GuessObjectGCKind(0);
obj = NewBuiltinClassInstance(cx, &ObjectClass, allocKind, newKind);
}
if (!obj)
@ -971,8 +975,7 @@ stubs::NewInitObject(VMFrame &f, JSObject *baseobj)
if (type) {
obj->setType(type);
} else {
RootedScript fscript(f.cx, f.script());
if (!SetInitializerObjectType(cx, fscript, f.pc(), obj))
if (!SetInitializerObjectType(cx, fscript, f.pc(), obj, newKind))
THROW();
}

View File

@ -160,7 +160,7 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle
data->deletedBits = reinterpret_cast<size_t *>(dstEnd);
ClearAllBitArrayElements(data->deletedBits, numDeletedWords);
RawObject obj = JSObject::create(cx, FINALIZE_KIND, shape, type, NULL);
RawObject obj = JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, shape, type, NULL);
if (!obj) {
js_free(data);
return NULL;

View File

@ -3531,9 +3531,9 @@ DebuggerFrame_getArguments(JSContext *cx, unsigned argc, Value *vp)
RootedValue undefinedValue(cx, UndefinedValue());
for (unsigned i = 0; i < fargc; i++) {
RootedFunction getobj(cx);
getobj = js_NewFunction(cx, NullPtr(), DebuggerArguments_getArg, 0,
JSFunction::NATIVE_FUN, global, NullPtr(),
JSFunction::ExtendedFinalizeKind);
getobj = NewFunction(cx, NullPtr(), DebuggerArguments_getArg, 0,
JSFunction::NATIVE_FUN, global, NullPtr(),
JSFunction::ExtendedFinalizeKind);
if (!getobj)
return false;
id = INT_TO_JSID(i);

View File

@ -191,8 +191,8 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
* Create |Object.prototype| first, mirroring CreateBlankProto but for the
* prototype of the created object.
*/
objectProto = NewObjectWithGivenProto(cx, &ObjectClass, NULL, self);
if (!objectProto || !JSObject::setSingletonType(cx, objectProto))
objectProto = NewObjectWithGivenProto(cx, &ObjectClass, NULL, self, SingletonObject);
if (!objectProto)
return NULL;
/*
@ -206,7 +206,8 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
/* Create |Function.prototype| next so we can create other functions. */
RootedFunction functionProto(cx);
{
RawObject functionProto_ = NewObjectWithGivenProto(cx, &FunctionClass, objectProto, self);
RawObject functionProto_ = NewObjectWithGivenProto(cx, &FunctionClass, objectProto, self,
SingletonObject);
if (!functionProto_)
return NULL;
functionProto = functionProto_->toFunction();
@ -216,8 +217,8 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
* give it the guts to be one.
*/
{
RawObject proto = js_NewFunction(cx, functionProto, NULL, 0, JSFunction::INTERPRETED,
self, NullPtr());
RawObject proto = NewFunction(cx, functionProto, NULL, 0, JSFunction::INTERPRETED,
self, NullPtr());
if (!proto)
return NULL;
JS_ASSERT(proto == functionProto);
@ -255,9 +256,6 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
functionProto->getType(cx)->interpretedFunction = functionProto;
script->setFunction(functionProto);
if (!JSObject::setSingletonType(cx, functionProto))
return NULL;
/*
* The default 'new' type of Function.prototype is required by type
* inference to have unknown properties, to simplify handling of e.g.
@ -270,12 +268,13 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
/* Create the Object function now that we have a [[Prototype]] for it. */
RootedFunction objectCtor(cx);
{
RootedObject ctor(cx, NewObjectWithGivenProto(cx, &FunctionClass, functionProto, self));
RootedObject ctor(cx, NewObjectWithGivenProto(cx, &FunctionClass, functionProto, self,
SingletonObject));
if (!ctor)
return NULL;
RootedAtom objectAtom(cx, cx->names().Object);
objectCtor = js_NewFunction(cx, ctor, obj_construct, 1, JSFunction::NATIVE_CTOR, self,
objectAtom);
objectCtor = NewFunction(cx, ctor, obj_construct, 1, JSFunction::NATIVE_CTOR, self,
objectAtom);
if (!objectCtor)
return NULL;
}
@ -290,12 +289,13 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
RootedFunction functionCtor(cx);
{
// Note that ctor is rooted purely for the JS_ASSERT at the end
RootedObject ctor(cx, NewObjectWithGivenProto(cx, &FunctionClass, functionProto, self));
RootedObject ctor(cx, NewObjectWithGivenProto(cx, &FunctionClass, functionProto, self,
SingletonObject));
if (!ctor)
return NULL;
RootedAtom functionAtom(cx, cx->names().Function);
functionCtor = js_NewFunction(cx, ctor, Function, 1, JSFunction::NATIVE_CTOR, self,
functionAtom);
functionCtor = NewFunction(cx, ctor, Function, 1, JSFunction::NATIVE_CTOR, self,
functionAtom);
if (!functionCtor)
return NULL;
JS_ASSERT(ctor == functionCtor);
@ -323,13 +323,13 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
* function so that cross-compartment [[Prototype]]-getting is implemented
* in one place.
*/
RootedFunction getter(cx, js_NewFunction(cx, NullPtr(), ProtoGetter, 0, JSFunction::NATIVE_FUN,
self, NullPtr()));
RootedFunction getter(cx, NewFunction(cx, NullPtr(), ProtoGetter, 0, JSFunction::NATIVE_FUN,
self, NullPtr()));
if (!getter)
return NULL;
#if JS_HAS_OBJ_PROTO_PROP
RootedFunction setter(cx, js_NewFunction(cx, NullPtr(), ProtoSetter, 0, JSFunction::NATIVE_FUN,
self, NullPtr()));
RootedFunction setter(cx, NewFunction(cx, NullPtr(), ProtoSetter, 0, JSFunction::NATIVE_FUN,
self, NullPtr()));
if (!setter)
return NULL;
RootedValue undefinedValue(cx, UndefinedValue());
@ -363,14 +363,14 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
/* ES5 15.1.2.1. */
RootedId evalId(cx, NameToId(cx->names().eval));
RawObject evalobj = js_DefineFunction(cx, self, evalId, IndirectEval, 1, JSFUN_STUB_GSOPS);
RawObject evalobj = DefineFunction(cx, self, evalId, IndirectEval, 1, JSFUN_STUB_GSOPS);
if (!evalobj)
return NULL;
self->setOriginalEval(evalobj);
/* ES5 13.2.3: Construct the unique [[ThrowTypeError]] function object. */
RootedFunction throwTypeError(cx, js_NewFunction(cx, NullPtr(), ThrowTypeError, 0,
JSFunction::NATIVE_FUN, self, NullPtr()));
RootedFunction throwTypeError(cx, NewFunction(cx, NullPtr(), ThrowTypeError, 0,
JSFunction::NATIVE_FUN, self, NullPtr()));
if (!throwTypeError)
return NULL;
if (!throwTypeError->preventExtensions(cx))
@ -421,7 +421,7 @@ GlobalObject::create(JSContext *cx, Class *clasp)
{
JS_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL);
JSObject *obj = NewObjectWithGivenProto(cx, clasp, NULL, NULL);
JSObject *obj = NewObjectWithGivenProto(cx, clasp, NULL, NULL, SingletonObject);
if (!obj)
return NULL;
@ -429,7 +429,7 @@ GlobalObject::create(JSContext *cx, Class *clasp)
cx->compartment->initGlobal(*global);
if (!JSObject::setSingletonType(cx, global) || !global->setVarObj(cx))
if (!global->setVarObj(cx))
return NULL;
if (!global->setDelegate(cx))
return NULL;
@ -502,7 +502,7 @@ GlobalObject::createConstructor(JSContext *cx, Native ctor, JSAtom *nameArg, uns
{
RootedAtom name(cx, nameArg);
RootedObject self(cx, this);
return js_NewFunction(cx, NullPtr(), ctor, length, JSFunction::NATIVE_CTOR, self, name, kind);
return NewFunction(cx, NullPtr(), ctor, length, JSFunction::NATIVE_CTOR, self, name, kind);
}
static JSObject *
@ -511,8 +511,8 @@ CreateBlankProto(JSContext *cx, Class *clasp, JSObject &proto, GlobalObject &glo
JS_ASSERT(clasp != &ObjectClass);
JS_ASSERT(clasp != &FunctionClass);
RootedObject blankProto(cx, NewObjectWithGivenProto(cx, clasp, &proto, &global));
if (!blankProto || !JSObject::setSingletonType(cx, blankProto))
RootedObject blankProto(cx, NewObjectWithGivenProto(cx, clasp, &proto, &global, SingletonObject));
if (!blankProto)
return NULL;
return blankProto;

View File

@ -146,7 +146,7 @@ CallObject::create(JSContext *cx, HandleShape shape, HandleTypeObject type, Heap
JS_ASSERT(CanBeFinalizedInBackground(kind, &CallClass));
kind = gc::GetBackgroundAllocKind(kind);
JSObject *obj = JSObject::create(cx, kind, shape, type, slots);
JSObject *obj = JSObject::create(cx, kind, gc::DefaultHeap, shape, type, slots);
if (!obj)
return NULL;
return &obj->asCall();
@ -299,7 +299,7 @@ DeclEnvObject::createTemplateObject(JSContext *cx, HandleFunction fun)
if (!emptyDeclEnvShape)
return NULL;
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, emptyDeclEnvShape, type, NULL));
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, emptyDeclEnvShape, type, NULL));
if (!obj)
return NULL;
@ -341,7 +341,7 @@ WithObject::create(JSContext *cx, HandleObject proto, HandleObject enclosing, ui
if (!shape)
return NULL;
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, shape, type, NULL));
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, shape, type, NULL));
if (!obj)
return NULL;
@ -628,7 +628,7 @@ ClonedBlockObject::create(JSContext *cx, Handle<StaticBlockObject *> block, Abst
RootedShape shape(cx, block->lastProperty());
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, shape, type, slots));
RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, shape, type, slots));
if (!obj)
return NULL;
@ -687,7 +687,7 @@ StaticBlockObject::create(JSContext *cx)
if (!emptyBlockShape)
return NULL;
JSObject *obj = JSObject::create(cx, FINALIZE_KIND, emptyBlockShape, type, NULL);
JSObject *obj = JSObject::create(cx, FINALIZE_KIND, gc::DefaultHeap, emptyBlockShape, type, NULL);
if (!obj)
return NULL;

View File

@ -202,7 +202,7 @@ StackFrame::createRestParameter(JSContext *cx)
JS_ASSERT(fun()->hasRest());
unsigned nformal = fun()->nargs - 1, nactual = numActualArgs();
unsigned nrest = (nactual > nformal) ? nactual - nformal : 0;
return NewDenseCopiedArray(cx, nrest, actuals() + nformal);
return NewDenseCopiedArray(cx, nrest, actuals() + nformal, NULL);
}
inline Value &

View File

@ -321,7 +321,7 @@ StackFrame::prologue(JSContext *cx, bool newType)
if (isConstructing()) {
RootedObject callee(cx, &this->callee());
JSObject *obj = js_CreateThisForFunction(cx, callee, newType);
JSObject *obj = CreateThisForFunction(cx, callee, newType);
if (!obj)
return false;
functionThis() = ObjectValue(*obj);