[INFER] Remove cx->newTypeObject, bug 657412.
authorBrian Hackett <bhackett1024@gmail.com>
Thu, 19 May 2011 09:15:12 -0700
changeset 75078 00a1518d640a25d505c27dc121e341345394415f
parent 75077 4dff743ec04d8058507115006bb93a35c990fa1a
child 75079 176ee6b37ad0de72cb84125ea0b8eb3538b0b8c2
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs657412
milestone6.0a1
[INFER] Remove cx->newTypeObject, bug 657412.
js/src/jsapi.cpp
js/src/jscntxt.h
js/src/jsfun.cpp
js/src/jsinfer.cpp
js/src/jsinfer.h
js/src/jsmath.cpp
js/src/jsobj.cpp
js/src/json.cpp
js/src/jsparse.cpp
js/src/jsproxy.cpp
js/src/jsreflect.cpp
js/src/jsregexp.cpp
js/src/jsstr.cpp
js/src/vm/GlobalObject.cpp
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -3084,17 +3084,18 @@ JS_NewObject(JSContext *cx, JSClass *jsc
 
 JS_PUBLIC_API(JSObject *)
 JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
 {
     JSObject *obj = JS_NewObject(cx, clasp, proto, parent);
     if (!obj)
         return NULL;
 
-    types::TypeObject *type = cx->newTypeObject("Unique", proto);
+    TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL, "Unique", "",
+                                                            false, false, proto);
     if (!type)
         return NULL;
     if (obj->hasSpecialEquality())
         cx->markTypeObjectFlags(type, OBJECT_FLAG_SPECIAL_EQUALITY);
     if (!obj->setTypeAndUniqueShape(cx, type))
         return NULL;
     type->singleton = obj;
 
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1354,24 +1354,16 @@ struct JSContext
      * a boolean flag to minimize the amount of code in its inlined callers.
      */
     JS_FRIEND_API(void) checkMallocGCPressure(void *p);
 
   public:
 
     inline bool typeInferenceEnabled();
 
-    /* Make a type function or object with the specified name. */
-    js::types::TypeFunction *newTypeFunction(const char *name, JSObject *proto);
-    js::types::TypeObject   *newTypeObject(const char *name, JSObject *proto);
-
-    /* Make a type object whose name is that of base followed by postfix. */
-    js::types::TypeObject *newTypeObject(const char *base, const char *postfix,
-                                         JSObject *proto, bool isFunction = false);
-
     /*
      * Get the default 'new' object for a given standard class, per the currently
      * active global.
      */
     inline js::types::TypeObject *getTypeNewObject(JSProtoKey key);
 
     /* Get a type object for the immediate allocation site in this context. */
     inline js::types::TypeObject *
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1775,17 +1775,21 @@ ResolveInterpretedFunctionPrototype(JSCo
     JSObject *objProto;
     if (!js_GetClassPrototype(cx, parent, JSProto_Object, &objProto))
         return NULL;
     JSObject *proto = NewNativeClassInstance(cx, &js_ObjectClass, objProto, parent);
     if (!proto)
         return NULL;
 
     /* Make a new type for the prototype object. */
-    TypeObject *protoType = cx->newTypeObject(obj->getType()->name(), "prototype", objProto);
+
+    TypeObject *protoType = cx->compartment->types.newTypeObject(cx, NULL,
+                                                                 obj->getType()->name(),
+                                                                 "prototype",
+                                                                 false, false, objProto);
     if (!protoType || !proto->setTypeAndUniqueShape(cx, protoType))
         return NULL;
 
     /*
      * ECMA (15.3.5.2) says that a user-defined function's .prototype property
      * is non-configurable, non-enumerable, and (initially) writable. Hence
      * JSPROP_PERMANENT below. By contrast, the built-in constructors, such as
      * Object (15.2.3.1) and Function (15.3.3.1), have non-writable
@@ -2776,21 +2780,23 @@ js_NewFunction(JSContext *cx, JSObject *
     if (funobj) {
         JS_ASSERT(funobj->isFunction());
         funobj->setParent(parent);
     } else {
         funobj = NewFunction(cx, parent);
         if (!funobj)
             return NULL;
         if (handler) {
-            TypeFunction *type = cx->newTypeFunction(fullName, funobj->getProto());
+            TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL, fullName, "",
+                                                                    true, false,
+                                                                    funobj->getProto());
             if (!type || !funobj->setTypeAndUniqueShape(cx, type))
                 return NULL;
-            type->handler = handler;
-            type->singleton = funobj;
+            type->asFunction()->handler = handler;
+            type->asFunction()->singleton = funobj;
         }
     }
     JS_ASSERT(!funobj->getPrivate());
     fun = (JSFunction *) funobj;
 
     /* Initialize all function members. */
     fun->nargs = uint16(nargs);
     fun->flags = flags & (JSFUN_FLAGS_MASK | JSFUN_KINDMASK | JSFUN_TRCINFO);
@@ -2889,23 +2895,25 @@ js_CloneFunctionObject(JSContext *cx, JS
             if (!cfun->u.i.script->typeSetFunction(cx, cfun))
                 return NULL;
 
 #ifdef CHECK_SCRIPT_OWNER
             cfun->script()->owner = NULL;
 #endif
             js_CallNewScriptHook(cx, cfun->script(), cfun);
         } else {
-            TypeFunction *type = cx->newTypeFunction("ClonedFunction", clone->getProto());
+            TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL, "ClonedFunction", "",
+                                                                    true, false,
+                                                                    clone->getProto());
             if (!type || !clone->setTypeAndUniqueShape(cx, type))
                 return NULL;
             if (fun->getType()->unknownProperties())
                 cx->markTypeObjectUnknownProperties(type);
             else
-                type->handler = fun->getType()->asFunction()->handler;
+                type->asFunction()->handler = fun->getType()->asFunction()->handler;
         }
     }
     return clone;
 }
 
 #ifdef JS_TRACER
 JS_DEFINE_CALLINFO_4(extern, OBJECT, js_CloneFunctionObject, CONTEXT, FUNCTION, OBJECT, OBJECT, 0,
                      nanojit::ACCSET_STORE_ANY)
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -1595,20 +1595,27 @@ TypeCompartment::init(JSContext *cx)
 #endif
     typeEmpty.flags = OBJECT_FLAG_UNKNOWN_MASK;
 
     if (cx && cx->getRunOptions() & JSOPTION_TYPE_INFERENCE)
         inferenceEnabled = true;
 }
 
 TypeObject *
-TypeCompartment::newTypeObject(JSContext *cx, JSScript *script, const char *name,
+TypeCompartment::newTypeObject(JSContext *cx, JSScript *script,
+                               const char *name, const char *postfix,
                                bool isFunction, bool isArray, JSObject *proto)
 {
 #ifdef DEBUG
+    if (*postfix) {
+        unsigned len = strlen(name) + strlen(postfix) + 2;
+        char *newName = (char *) alloca(len);
+        JS_snprintf(newName, len, "%s:%s", name, postfix);
+        name = newName;
+    }
 #if 0
     /* Add a unique counter to the name, to distinguish objects from different globals. */
     static unsigned nameCount = 0;
     unsigned len = strlen(name) + 15;
     char *newName = (char *) alloca(len);
     JS_snprintf(newName, len, "%u:%s", ++nameCount, name);
     name = newName;
 #endif
@@ -1657,17 +1664,17 @@ TypeCompartment::newInitializerTypeObjec
     JS_snprintf(name, 40, "#%lu:%lu:%s", script->id(), offset, isArray ? "Array" : "Object");
 #endif
 
     JSObject *proto;
     JSProtoKey key = isArray ? JSProto_Array : JSProto_Object;
     if (!js_GetClassPrototype(cx, script->getGlobal(), key, &proto, NULL))
         return NULL;
 
-    TypeObject *res = newTypeObject(cx, script, name, false, isArray, proto);
+    TypeObject *res = newTypeObject(cx, script, name, "", false, isArray, proto);
     if (!res)
         return NULL;
 
     if (isArray)
         res->initializerArray = true;
     else
         res->initializerObject = true;
     res->initializerOffset = offset;
@@ -2282,21 +2289,24 @@ TypeCompartment::fixArrayType(JSContext 
     ArrayTableKey key;
     key.type = type;
     key.proto = obj->getProto();
     ArrayTypeTable::AddPtr p = arrayTypeTable->lookupForAdd(key);
 
     if (p) {
         obj->setType(p->value);
     } else {
+        char *name = NULL;
+#ifdef DEBUG
         static unsigned count = 0;
-        char *name = (char *) alloca(20);
+        name = (char *) alloca(20);
         JS_snprintf(name, 20, "TableArray:%u", ++count);
-
-        TypeObject *objType = newTypeObject(cx, NULL, name, false, true, obj->getProto());
+#endif
+
+        TypeObject *objType = newTypeObject(cx, NULL, name, "", false, true, obj->getProto());
         if (!objType) {
             cx->compartment->types.setPendingNukeTypes(cx);
             return;
         }
         obj->setType(objType);
 
         cx->addTypePropertyId(objType, JSID_VOID, type);
 
@@ -2413,21 +2423,24 @@ TypeCompartment::fixObjectType(JSContext
         JSObject *xobj = NewBuiltinClassInstance(cx, &js_ObjectClass,
                                                  (gc::FinalizeKind) obj->finalizeKind());
         if (!xobj) {
             cx->compartment->types.setPendingNukeTypes(cx);
             return;
         }
         AutoObjectRooter xvr(cx, xobj);
 
+        char *name = NULL;
+#ifdef DEBUG
         static unsigned count = 0;
-        char *name = (char *) alloca(20);
+        name = (char *) alloca(20);
         JS_snprintf(name, 20, "TableObject:%u", ++count);
-
-        TypeObject *objType = newTypeObject(cx, NULL, name, false, false, obj->getProto());
+#endif
+
+        TypeObject *objType = newTypeObject(cx, NULL, name, "", false, false, obj->getProto());
         if (!objType) {
             cx->compartment->types.setPendingNukeTypes(cx);
             return;
         }
         xobj->setType(objType);
 
         jsid *ids = (jsid *) cx->calloc_(obj->slotSpan() * sizeof(jsid));
         if (!ids) {
@@ -2532,40 +2545,35 @@ TypeObject::splicePrototype(JSContext *c
     if (this->proto) {
         /* Unlink from existing proto. */
         TypeObject **plist = &this->proto->getType()->instanceList;
         while (*plist != this)
             plist = &(*plist)->instanceNext;
         *plist = this->instanceNext;
     }
 
-    /*
-     * Make sure this is not the shared 'empty' type object. :TODO: once we
-     * can mark type objects as singletons, assert that instead.
-     */
-    JS_ASSERT(this != &cx->compartment->types.typeEmpty);
-
     this->proto = proto;
+
+    /* Link with the new proto. */
     this->instanceNext = proto->getType()->instanceList;
     proto->getType()->instanceList = this;
 
     if (!cx->typeInferenceEnabled())
         return;
 
     AutoEnterTypeInference enter(cx);
 
     if (proto->getType()->unknownProperties()) {
         markUnknown(cx);
         return;
     }
 
     /*
-     * Note: we require (but do not assert) that any property in the prototype
-     * or its own prototypes must not share a name with a property already
-     * added to an instance of this object.
+     * Update properties on this type with any shared with the prototype.
+     * :FIXME: do this for instances of this object too.
      */
     unsigned count = getPropertyCount();
     for (unsigned i = 0; i < count; i++) {
         Property *prop = getProperty(i);
         if (prop && !JSID_IS_EMPTY(prop->id))
             getFromPrototypes(cx, prop);
     }
 }
@@ -4275,45 +4283,16 @@ ScriptAnalysis::printTypes(JSContext *cx
 
     printf("\n");
 
 #endif /* DEBUG */
 
 }
 
 /////////////////////////////////////////////////////////////////////
-// JSContext
-/////////////////////////////////////////////////////////////////////
-
-TypeFunction *
-JSContext::newTypeFunction(const char *name, JSObject *proto)
-{
-    return (TypeFunction *)
-        compartment->types.newTypeObject(this, NULL, name, true, false, proto);
-}
-
-TypeObject *
-JSContext::newTypeObject(const char *name, JSObject *proto)
-{
-    return compartment->types.newTypeObject(this, NULL, name, false, false, proto);
-}
-
-TypeObject *
-JSContext::newTypeObject(const char *base, const char *postfix, JSObject *proto, bool isFunction)
-{
-    char *name = NULL;
-#ifdef DEBUG
-    unsigned len = strlen(base) + strlen(postfix) + 5;
-    name = (char *)alloca(len);
-    JS_snprintf(name, len, "%s:%s", base, postfix);
-#endif
-    return compartment->types.newTypeObject(this, NULL, name, isFunction, false, proto);
-}
-
-/////////////////////////////////////////////////////////////////////
 // JSScript
 /////////////////////////////////////////////////////////////////////
 
 /*
  * Returns true if we don't expect to compute the correct types for some value
  * pushed by the specified bytecode.
  */
 static inline bool
@@ -4428,17 +4407,19 @@ JSScript::typeSetFunction(JSContext *cx,
     if (!cx->typeInferenceEnabled())
         return true;
 
     char *name = NULL;
 #ifdef DEBUG
     name = (char *) alloca(10);
     JS_snprintf(name, 10, "#%u", id());
 #endif
-    TypeObject *type = cx->newTypeFunction(name, fun->getProto());
+
+    TypeObject *type = cx->compartment->types.newTypeObject(cx, this, name, "",
+                                                            true, false, fun->getProto());
     if (!type)
         return false;
 
     if (!fun->setTypeAndUniqueShape(cx, type))
         return false;
     type->asFunction()->script = this;
     this->fun = fun;
 
@@ -4499,17 +4480,18 @@ JSScript::typeCheckBytecode(JSContext *c
 // JSObject
 /////////////////////////////////////////////////////////////////////
 
 void
 JSObject::makeNewType(JSContext *cx, JSScript *newScript)
 {
     JS_ASSERT(!newType);
 
-    TypeObject *type = cx->newTypeObject(getType()->name(), "new", this);
+    TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL, getType()->name(), "new",
+                                                            false, false, this);
     if (!type)
         return;
 
     if (!cx->typeInferenceEnabled()) {
         newType = type;
         setDelegate();
         return;
     }
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -866,17 +866,18 @@ struct TypeCompartment
     /* Resolve pending type registrations, excluding delayed ones. */
     inline void resolvePending(JSContext *cx);
 
     /* Prints results of this compartment if spew is enabled, checks for warnings. */
     void print(JSContext *cx, JSCompartment *compartment);
 
     /* Make a function or non-function object associated with an optional script. */
     TypeObject *newTypeObject(JSContext *cx, JSScript *script,
-                              const char *name, bool isFunction, bool isArray, JSObject *proto);
+                              const char *base, const char *postfix,
+                              bool isFunction, bool isArray, JSObject *proto);
 
     /* Make an initializer object. */
     TypeObject *newInitializerTypeObject(JSContext *cx, JSScript *script,
                                          uint32 offset, bool isArray);
 
     /*
      * Add the specified type to the specified set, do any necessary reanalysis
      * stemming from the change and recompile any affected scripts.
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -915,17 +915,19 @@ js_IsMathFunction(JSNative native)
 
 JSObject *
 js_InitMathClass(JSContext *cx, JSObject *obj)
 {
     JSObject *Math = NewNonFunction<WithProto::Class>(cx, &js_MathClass, NULL, obj);
     if (!Math)
         return NULL;
 
-    types::TypeObject *type = cx->newTypeObject(js_Math_str, Math->getProto());
+    types::TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL, js_Math_str, "",
+                                                                   false, false,
+                                                                   Math->getProto());
     if (!type || !Math->setTypeAndUniqueShape(cx, type))
         return NULL;
     type->singleton = Math;
 
     if (!JS_DefineProperty(cx, obj, js_Math_str, OBJECT_TO_JSVAL(Math),
                            JS_PropertyStub, JS_StrictPropertyStub, 0)) {
         return NULL;
     }
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -2997,21 +2997,27 @@ js_CreateThisForFunction(JSContext *cx, 
 
     if (obj && newType) {
         /*
          * Make a new type and a new object with the type, reshaped according
          * to any properties already added by CreateThisForFunctionWithProto.
          */
         JS_ASSERT(cx->typeInferenceEnabled());
 
+#ifdef DEBUG
         static unsigned count = 0;
         char *name = (char *) alloca(30);
         JS_snprintf(name, 30, "SpecializedThis:%u", ++count);
-
-        types::TypeObject *type = cx->newTypeObject(name, obj->getProto());
+#else
+        char *name = NULL;
+#endif
+
+        types::TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL, name, "",
+                                                                       false, false,
+                                                                       obj->getProto());
         types::AutoTypeRooter root(cx, type);
 
         obj = NewReshapedObject(cx, type, obj->getParent(), gc::FinalizeKind(obj->finalizeKind()),
                                 obj->lastProperty());
         if (!obj)
             return NULL;
         callee->getFunctionPrivate()->script()->typeSetThis(cx, (types::jstype) type);
     }
@@ -4023,18 +4029,20 @@ DefineConstructorAndPrototype(JSContext 
      * be &js_FunctionClass (we could break compatibility easily). But fixing
      * (3) is not enough without addressing the bootstrapping dependency on (1)
      * and (2).
      */
     JSObject *proto = NewObject<WithProto::Class>(cx, clasp, protoProto, obj);
     if (!proto)
         return NULL;
 
-    TypeObject *protoType = cx->newTypeObject(clasp->name, "prototype", proto->getProto(),
-                                              clasp == &js_FunctionClass);
+    TypeObject *protoType = cx->compartment->types.newTypeObject(cx, NULL,
+                                                                 clasp->name, "prototype",
+                                                                 clasp == &js_FunctionClass, false,
+                                                                 proto->getProto());
     if (!protoType || !proto->setTypeAndUniqueShape(cx, protoType))
         return NULL;
     protoType->singleton = proto;
 
     if (clasp == &js_ArrayClass && !proto->makeDenseArraySlow(cx))
         return NULL;
 
     TypeObject *type = proto->getNewType(cx);
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -1554,17 +1554,19 @@ static JSFunctionSpec json_static_method
 
 JSObject *
 js_InitJSONClass(JSContext *cx, JSObject *obj)
 {
     JSObject *JSON = NewNonFunction<WithProto::Class>(cx, &js_JSONClass, NULL, obj);
     if (!JSON)
         return NULL;
 
-    TypeObject *type = cx->newTypeObject(js_JSON_str, JSON->getProto());
+    TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL, js_JSON_str, "",
+                                                            false, false,
+                                                            JSON->getProto());
     if (!type || !JSON->setTypeAndUniqueShape(cx, type))
         return NULL;
 
     if (!JS_DefineProperty(cx, obj, js_JSON_str, OBJECT_TO_JSVAL(JSON),
                            JS_PropertyStub, JS_StrictPropertyStub, 0))
         return NULL;
 
     if (!JS_DefineFunctions(cx, JSON, json_static_methods))
--- a/js/src/jsparse.cpp
+++ b/js/src/jsparse.cpp
@@ -1155,16 +1155,19 @@ Compiler::compileScript(JSContext *cx, J
         script = NULL;
     }
     goto out;
 }
 
 bool
 Compiler::defineGlobals(JSContext *cx, GlobalScope &globalScope, JSScript *script)
 {
+    if (!globalScope.defs.length())
+        return true;
+
     JSObject *globalObj = globalScope.globalObj;
 
     /* Define and update global properties. */
     for (size_t i = 0; i < globalScope.defs.length(); i++) {
         GlobalScope::GlobalDef &def = globalScope.defs[i];
 
         /* Names that could be resolved ahead of time can be skipped. */
         if (!def.atom)
@@ -1212,21 +1215,17 @@ Compiler::defineGlobals(JSContext *cx, G
      * object.
      */
     while (worklist.length()) {
         JSScript *inner = worklist.back();
         worklist.popBack();
 
         if (JSScript::isValidOffset(inner->objectsOffset)) {
             JSObjectArray *arr = inner->objects();
-
-            /* Skip any caller function entrained in the first object. */
-            size_t start = inner->savedCallerFun ? 1 : 0;
-
-            for (size_t i = start; i < arr->length; i++) {
+            for (size_t i = 0; i < arr->length; i++) {
                 JSObject *obj = arr->vector[i];
                 if (!obj->isFunction())
                     continue;
                 JSFunction *fun = obj->getFunctionPrivate();
                 JS_ASSERT(fun->isInterpreted());
                 JSScript *inner = fun->u.i.script;
                 if (!JSScript::isValidOffset(inner->globalsOffset) &&
                     !JSScript::isValidOffset(inner->objectsOffset)) {
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -1455,17 +1455,20 @@ Class js_ProxyClass = {
 
 JS_FRIEND_API(JSObject *)
 js_InitProxyClass(JSContext *cx, JSObject *obj)
 {
     JSObject *module = NewNonFunction<WithProto::Class>(cx, &js_ProxyClass, NULL, obj);
     if (!module)
         return NULL;
 
-    types::TypeObject *type = cx->newTypeObject(js_ProxyClass.name, module->getProto());
+    types::TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL,
+                                                                   js_ProxyClass.name, "",
+                                                                   false, false,
+                                                                   module->getProto());
     if (!type || !module->setTypeAndUniqueShape(cx, type))
         return NULL;
 
     if (!JS_DefineProperty(cx, obj, "Proxy", OBJECT_TO_JSVAL(module),
                            JS_PropertyStub, JS_StrictPropertyStub, 0)) {
         return NULL;
     }
     if (!JS_DefineFunctions(cx, module, static_methods))
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -3302,17 +3302,20 @@ static JSFunctionSpec static_methods[] =
 
 JSObject *
 js_InitReflectClass(JSContext *cx, JSObject *obj)
 {
     JSObject *Reflect = NewNonFunction<WithProto::Class>(cx, &js_ReflectClass, NULL, obj);
     if (!Reflect)
         return NULL;
 
-    types::TypeObject *type = cx->newTypeObject(js_ReflectClass.name, Reflect->getProto());
+    types::TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL,
+                                                                   js_ReflectClass.name, "",
+                                                                   false, false,
+                                                                   Reflect->getProto());
     if (!type || !Reflect->setTypeAndUniqueShape(cx, type))
         return NULL;
 
     if (!JS_DefineProperty(cx, obj, js_Reflect_str, OBJECT_TO_JSVAL(Reflect),
                            JS_PropertyStub, JS_StrictPropertyStub, 0)) {
         return NULL;
     }
 
--- a/js/src/jsregexp.cpp
+++ b/js/src/jsregexp.cpp
@@ -864,17 +864,20 @@ js_InitRegExpClass(JSContext *cx, JSObje
     if (!js_GetClassPrototype(cx, global, JSProto_Object, &objectProto))
         return NULL;
     JS_ASSERT(objectProto);
 
     JSObject *proto = NewObject<WithProto::Class>(cx, &js_RegExpClass, objectProto, global);
     if (!proto)
         return NULL;
 
-    TypeObject *protoType = cx->newTypeObject("RegExp", "prototype", proto->getProto(), false);
+    types::TypeObject *protoType = cx->compartment->types.newTypeObject(cx, NULL,
+                                                                        "RegExp", "prototype",
+                                                                        false, false,
+                                                                        proto->getProto());
     if (!protoType || !proto->setTypeAndUniqueShape(cx, protoType))
         return NULL;
 
     AlreadyIncRefed<RegExp> re = RegExp::create(cx, cx->runtime->emptyString, 0);
     if (!re)
         return NULL;
 #ifdef DEBUG
     assertSameCompartment(cx, proto, re->compartment);
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -3580,17 +3580,20 @@ js_InitStringClass(JSContext *cx, JSObje
     JSObject *objectProto;
     if (!js_GetClassPrototype(cx, global, JSProto_Object, &objectProto))
         return NULL;
 
     JSObject *proto = NewObject<WithProto::Class>(cx, &js_StringClass, objectProto, global);
     if (!proto)
         return NULL;
 
-    types::TypeObject *protoType = cx->newTypeObject("String", "prototype", proto->getProto(), false);
+    types::TypeObject *protoType = cx->compartment->types.newTypeObject(cx, NULL,
+                                                                        "String", "prototype",
+                                                                        false, false,
+                                                                        proto->getProto());
     if (!protoType || !proto->setTypeAndUniqueShape(cx, protoType))
         return NULL;
 
     if (!proto->asString()->init(cx, cx->runtime->emptyString))
         return NULL;
 
     /* Now create the String function. */
     JSAtom *atom = CLASS_ATOM(cx, String);
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -109,17 +109,18 @@ GlobalObject *
 GlobalObject::create(JSContext *cx, Class *clasp)
 {
     JS_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL);
 
     JSObject *obj = NewNonFunction<WithProto::Given>(cx, clasp, NULL, NULL);
     if (!obj)
         return NULL;
 
-    types::TypeObject *type = cx->newTypeObject("Global", NULL);
+    types::TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL, "Global", "",
+                                                                   false, false, NULL);
     if (!type || !obj->setTypeAndUniqueShape(cx, type))
         return NULL;
     if (clasp->ext.equality)
         cx->markTypeObjectFlags(type, types::OBJECT_FLAG_SPECIAL_EQUALITY);
     type->singleton = obj;
 
     GlobalObject *globalObj = obj->asGlobal();