Bug 905370 - Move SelfHostedClass list to JSRuntime. r=bhackett,shu, a=abillings
--- 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! */