[INFER] Fix uses of cx->getTypeEmpty during GC, bug 619433.
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 07 Mar 2011 20:10:57 -0800
changeset 74730 559b9da69fcb6f18265d928b0b067e31a7c4c31c
parent 74729 38c06cbd699335a5914f936dd946cd33804defaa
child 74731 511f51584aad04478fbf1febe7b8fbbc17d7304f
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs619433
milestone2.0b12pre
[INFER] Fix uses of cx->getTypeEmpty during GC, bug 619433.
js/src/jsinfer.cpp
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -3861,16 +3861,27 @@ types::TypeObject::trace(JSTracer *trc)
                 emptyShapes[i]->trace(trc);
         }
     }
 
     if (proto)
         gc::MarkObject(trc, *proto, "type_proto");
 }
 
+static inline TypeObject *
+GetTypeEmpty(JSContext *cx, TypeCompartment *compartment)
+{
+    if (!compartment->typeEmpty) {
+        compartment->typeEmpty = compartment->newTypeObject(cx, NULL, "Empty", false, NULL);
+        if (compartment->typeEmpty)
+            compartment->typeEmpty->unknownProperties = true;
+    }
+    return compartment->typeEmpty;
+}
+
 /*
  * Condense any constraints on a type set which were generated during analysis
  * of a script, and sweep all type objects and references to type objects
  * which no longer exist.
  */
 void
 CondenseSweepTypeSet(JSContext *cx, TypeCompartment *compartment,
                      HashSet<JSScript*> *pcondensed, TypeSet *types)
@@ -3887,17 +3898,17 @@ CondenseSweepTypeSet(JSContext *cx, Type
                  * If the object has unknown properties, instead of removing it
                  * replace it with the compartment's empty type object. This is
                  * needed to handle mutable __proto__ --- the type object in
                  * the set may no longer be used but there could be a JSObject
                  * which originally had the type and was changed to a different
                  * type object with unknown properties.
                  */
                 if (object->unknownProperties) {
-                    types->objectSet[i] = cx->getTypeEmpty();
+                    types->objectSet[i] = GetTypeEmpty(cx, compartment);
                     if (!types->objectSet[i])
                         compartment->setPendingNukeTypes(cx);
                 } else {
                     types->objectSet[i] = NULL;
                 }
                 removed = true;
             }
         }
@@ -3916,17 +3927,17 @@ CondenseSweepTypeSet(JSContext *cx, Type
                 }
             }
             cx->free(oldArray);
         }
     } else if (types->objectCount == 1) {
         TypeObject *object = (TypeObject*) types->objectSet;
         if (!object->marked) {
             if (object->unknownProperties) {
-                types->objectSet = (TypeObject**) cx->getTypeEmpty();
+                types->objectSet = (TypeObject**) GetTypeEmpty(cx, compartment);
                 if (!types->objectSet)
                     compartment->setPendingNukeTypes(cx);
             } else {
                 types->objectSet = NULL;
                 types->objectCount = 0;
             }
         }
     }