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 222521 3d2cbf625d1cff443957dca61e85a78917b5dc56
parent 222520 69814624bb027225c02da63ab5a6d37940fe64fb
child 222522 180ffdfd2d27a68c45f712b3673203bbe8622ad4
push id28067
push userkwierso@gmail.com
push dateWed, 07 Jan 2015 23:41:38 +0000
treeherdermozilla-central@70de2960aa87 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnmatsakis
bugs1113744
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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:
     /*