Bug 905370 - Move SelfHostedClass list to JSRuntime. r=bhackett,shu, a=abillings
authorTill Schneidereit <till@tillschneidereit.net>
Sat, 24 Aug 2013 00:45:01 +0200
changeset 153865 83ae78484491e745ddf548770267654a5e434b95
parent 153864 23bb539f70001f6bc5e01c69e9a2b408e6946c81
child 153866 54dc957b3de8684ecaad007e5ef487f2234c8014
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett, shu, abillings
bugs905370
milestone25.0a2
Bug 905370 - Move SelfHostedClass list to JSRuntime. r=bhackett,shu, a=abillings
js/src/vm/Runtime.cpp
js/src/vm/Runtime.h
js/src/vm/SelfHosting.cpp
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -119,16 +119,17 @@ JSRuntime::JSRuntime(JSUseHelperThreads 
     ownerThread_(NULL),
 #endif
     tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
     freeLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
     execAlloc_(NULL),
     bumpAlloc_(NULL),
     ionRuntime_(NULL),
     selfHostingGlobal_(NULL),
+    selfHostedClasses_(NULL),
     nativeStackBase(0),
     nativeStackQuota(0),
     interpreterFrames(NULL),
     cxCallback(NULL),
     destroyCompartmentCallback(NULL),
     compartmentNameCallback(NULL),
     activityCallback(NULL),
     activityCallbackArg(NULL),
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -650,16 +650,17 @@ struct MallocProvider
 
 namespace gc {
 class MarkingValidator;
 } // namespace gc
 
 typedef Vector<JS::Zone *, 1, SystemAllocPolicy> ZoneVector;
 
 class AutoLockForExclusiveAccess;
+struct SelfHostedClass;
 
 } // namespace js
 
 struct JSRuntime : public JS::shadow::Runtime,
                    public js::MallocProvider<JSRuntime>
 {
     /*
      * Per-thread data for the main thread that is associated with
@@ -830,16 +831,17 @@ struct JSRuntime : public JS::shadow::Ru
      * Both of these allocators are used for regular expression code which is shared at the
      * thread-data level.
      */
     JSC::ExecutableAllocator *execAlloc_;
     WTF::BumpPointerAllocator *bumpAlloc_;
     js::ion::IonRuntime *ionRuntime_;
 
     JSObject *selfHostingGlobal_;
+    js::SelfHostedClass *selfHostedClasses_;
 
     /* Space for interpreter frames. */
     js::InterpreterStack interpreterStack_;
 
     JSC::ExecutableAllocator *createExecutableAllocator(JSContext *cx);
     WTF::BumpPointerAllocator *createBumpPointerAllocator(JSContext *cx);
     js::ion::IonRuntime *createIonRuntime(JSContext *cx);
 
@@ -875,16 +877,20 @@ struct JSRuntime : public JS::shadow::Ru
     //-------------------------------------------------------------------------
 
     bool initSelfHosting(JSContext *cx);
     void finishSelfHosting();
     void markSelfHostingGlobal(JSTracer *trc);
     bool isSelfHostingGlobal(js::HandleObject global) {
         return global == selfHostingGlobal_;
     }
+    js::SelfHostedClass *selfHostedClasses() {
+        return selfHostedClasses_;
+    }
+    void addSelfHostedClass(js::SelfHostedClass *shClass);
     bool cloneSelfHostedFunctionScript(JSContext *cx, js::Handle<js::PropertyName*> name,
                                        js::Handle<JSFunction*> targetFun);
     bool cloneSelfHostedValue(JSContext *cx, js::Handle<js::PropertyName*> name,
                               js::MutableHandleValue vp);
     bool maybeWrappedSelfHostedFunction(JSContext *cx, js::Handle<js::PropertyName*> name,
                                         js::MutableHandleValue funVal);
 
     //-------------------------------------------------------------------------
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -29,62 +29,56 @@ namespace js {
 
 /*
  * A linked-list container for self-hosted prototypes that have need of a
  * Class for reserved slots. These are freed when self-hosting is destroyed at
  * the destruction of the last context.
  */
 struct SelfHostedClass
 {
-    /* The head of the linked list. */
-    static SelfHostedClass *head;
-
     /* Next class in the list. */
     SelfHostedClass *next;
 
     /* Class of instances. */
     Class class_;
 
     /*
      * Create a new self-hosted proto with its class set to a new dynamically
      * allocated class with numSlots reserved slots.
      */
     static JSObject *newPrototype(JSContext *cx, uint32_t numSlots);
 
-    static bool is(Class *clasp);
+    static bool is(JSContext *cx, Class *clasp);
 
     SelfHostedClass(const char *name, uint32_t numSlots);
 };
 
 } /* namespace js */
 
-SelfHostedClass *SelfHostedClass::head = NULL;
-
 JSObject *
 SelfHostedClass::newPrototype(JSContext *cx, uint32_t numSlots)
 {
     /* Allocate a new self hosted class and prepend it to the list. */
     SelfHostedClass *shClass = cx->new_<SelfHostedClass>("Self-hosted Class", numSlots);
     if (!shClass)
         return NULL;
-    shClass->next = head;
-    head = shClass;
+    cx->runtime()->addSelfHostedClass(shClass);
 
     Rooted<GlobalObject *> global(cx, cx->global());
     RootedObject proto(cx, global->createBlankPrototype(cx, &shClass->class_));
     if (!proto)
         return NULL;
 
     return proto;
 }
 
 bool
-SelfHostedClass::is(Class *clasp)
+SelfHostedClass::is(JSContext *cx, Class *clasp)
 {
-    SelfHostedClass *shClass = head;
+    SelfHostedClass *shClass = cx->runtime()->selfHostedClasses();
     while (shClass) {
         if (clasp == &shClass->class_)
             return true;
         shClass = shClass->next;
     }
     return false;
 }
 
@@ -765,32 +759,39 @@ JSRuntime::initSelfHosting(JSContext *cx
     return ok;
 }
 
 void
 JSRuntime::finishSelfHosting()
 {
     selfHostingGlobal_ = NULL;
 
-    SelfHostedClass *head = SelfHostedClass::head;
-    while (head) {
-        SelfHostedClass *tmp = head;
-        head = head->next;
+    SelfHostedClass *shClass = selfHostedClasses_;
+    while (shClass) {
+        SelfHostedClass *tmp = shClass;
+        shClass = shClass->next;
         js_delete(tmp);
     }
-    SelfHostedClass::head = NULL;
+    selfHostedClasses_ = NULL;
 }
 
 void
 JSRuntime::markSelfHostingGlobal(JSTracer *trc)
 {
     if (selfHostingGlobal_)
         MarkObjectRoot(trc, &selfHostingGlobal_, "self-hosting global");
 }
 
+void
+JSRuntime::addSelfHostedClass(SelfHostedClass *shClass)
+{
+    shClass->next = selfHostedClasses_;
+    selfHostedClasses_ = shClass;
+}
+
 typedef AutoObjectObjectHashMap CloneMemory;
 static bool CloneValue(JSContext *cx, MutableHandleValue vp, CloneMemory &clonedObjects);
 
 static bool
 GetUnclonedValue(JSContext *cx, Handle<JSObject*> src, HandleId id, MutableHandleValue vp)
 {
     AutoCompartment ac(cx, src);
     return JSObject::getGeneric(cx, src, src, id, vp);
@@ -812,17 +813,17 @@ CloneProperties(JSContext *cx, HandleObj
         if (!GetUnclonedValue(cx, obj, id, &val) ||
             !CloneValue(cx, &val, clonedObjects) ||
             !JS_DefinePropertyById(cx, clone, id, val.get(), NULL, NULL, 0))
         {
             return false;
         }
     }
 
-    if (SelfHostedClass::is(obj->getClass())) {
+    if (SelfHostedClass::is(cx, obj->getClass())) {
         for (uint32_t i = 0; i < JSCLASS_RESERVED_SLOTS(obj->getClass()); i++) {
             val = obj->getReservedSlot(i);
             if (!CloneValue(cx, &val, clonedObjects))
                 return false;
             clone->setReservedSlot(i, val);
         }
 
         /* Privates are not cloned, so be careful! */