Bug 1113744 - Trace type descriptors attached to type objects, r=nmatsakis.
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 07 Jan 2015 10:25:57 -0700
changeset 235494 3d2cbf625d1cff443957dca61e85a78917b5dc56
parent 235493 69814624bb027225c02da63ab5a6d37940fe64fb
child 235495 180ffdfd2d27a68c45f712b3673203bbe8622ad4
push id366
push usercmanchester@mozilla.com
push dateThu, 08 Jan 2015 16:40:24 +0000
reviewersnmatsakis
bugs1113744
milestone37.0a1
Bug 1113744 - Trace type descriptors attached to type objects, r=nmatsakis.
js/src/gc/Marking.cpp
js/src/jsinfer.cpp
js/src/jsinfer.h
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -1444,16 +1444,19 @@ ScanTypeObject(GCMarker *gcmarker, types
         PushMarkStack(gcmarker, type->proto().toObject());
 
     if (type->singleton() && !type->lazy())
         PushMarkStack(gcmarker, type->singleton());
 
     if (type->newScript())
         type->newScript()->trace(gcmarker);
 
+    if (TypeDescr *descr = type->maybeTypeDescr())
+        PushMarkStack(gcmarker, descr);
+
     if (type->interpretedFunction)
         PushMarkStack(gcmarker, type->interpretedFunction);
 }
 
 static void
 gc::MarkChildren(JSTracer *trc, types::TypeObject *type)
 {
     unsigned count = type->getPropertyCount();
@@ -1467,16 +1470,21 @@ gc::MarkChildren(JSTracer *trc, types::T
         MarkObject(trc, &type->protoRaw(), "type_proto");
 
     if (type->singleton() && !type->lazy())
         MarkObject(trc, &type->singletonRaw(), "type_singleton");
 
     if (type->newScript())
         type->newScript()->trace(trc);
 
+    if (JSObject *descr = type->maybeTypeDescr()) {
+        MarkObjectUnbarriered(trc, &descr, "type_descr");
+        type->setTypeDescr(&descr->as<TypeDescr>());
+    }
+
     if (type->interpretedFunction)
         MarkObject(trc, &type->interpretedFunction, "type_function");
 }
 
 static void
 gc::MarkChildren(JSTracer *trc, jit::JitCode *code)
 {
     code->trace(trc);
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -5262,20 +5262,20 @@ TypeScript::printTypes(JSContext *cx, Ha
 }
 #endif /* DEBUG */
 
 void
 TypeObject::setAddendum(AddendumKind kind, void *addendum)
 {
     MOZ_ASSERT(!needsSweep());
     MOZ_ASSERT(kind <= (OBJECT_FLAG_ADDENDUM_MASK >> OBJECT_FLAG_ADDENDUM_SHIFT));
-    MOZ_ASSERT(!(flags_ & OBJECT_FLAG_ADDENDUM_MASK));
+    MOZ_ASSERT(addendumKind() == 0 || addendumKind() == kind);
 
     // Manually trigger barriers if we are clearing a TypeNewScript. Other
     // kinds of addendums are immutable.
-    if (addendum_) {
+    if (newScript()) {
         MOZ_ASSERT(kind == Addendum_NewScript);
         TypeNewScript::writeBarrierPre(newScript());
     }
 
     flags_ |= kind << OBJECT_FLAG_ADDENDUM_SHIFT;
     addendum_ = addendum;
 }
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -1150,21 +1150,27 @@ struct TypeObject : public gc::TenuredCe
         maybeSweep(nullptr);
         return newScriptDontCheckGeneration();
     }
 
     void setNewScript(TypeNewScript *newScript) {
         setAddendum(Addendum_NewScript, newScript);
     }
 
-    TypeDescr &typeDescr() {
+    TypeDescr *maybeTypeDescr() {
         // Note: there is no need to sweep when accessing the type descriptor
         // of an object, as it is strongly held and immutable.
+        if (addendumKind() == Addendum_TypeDescr)
+            return reinterpret_cast<TypeDescr *>(addendum_);
+        return nullptr;
+    }
+
+    TypeDescr &typeDescr() {
         MOZ_ASSERT(addendumKind() == Addendum_TypeDescr);
-        return *reinterpret_cast<TypeDescr *>(addendum_);
+        return *maybeTypeDescr();
     }
 
     void setTypeDescr(TypeDescr *descr) {
         setAddendum(Addendum_TypeDescr, descr);
     }
 
   private:
     /*