Merge.
authorDavid Anderson <danderson@mozilla.com>
Wed, 29 Aug 2012 17:58:13 -0700
changeset 105830 003feda8a0b3914c625acc784a1a441a3eeffaec
parent 105829 7bf95bb092331b1db96ba9d561400fcdfb9f09d6 (current diff)
parent 105034 630296b1c46db466378f21ae09ea179f730cd422 (diff)
child 105831 8f2d38db4b56d48e15ecac40f8303a869a07db9f
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
milestone18.0a1
Merge.
js/src/ion/CodeGenerator.cpp
js/src/ion/IonBuilder.cpp
js/src/ion/IonBuilder.h
js/src/ion/MIR.h
js/src/jsscript.h
js/src/vm/ScopeObject.cpp
js/src/vm/ScopeObject.h
--- a/js/src/ion/CodeGenerator.cpp
+++ b/js/src/ion/CodeGenerator.cpp
@@ -1450,37 +1450,35 @@ CodeGenerator::visitOutOfLineNewObject(O
     return true;
 }
 
 bool
 CodeGenerator::visitNewCallObject(LNewCallObject *lir)
 {
     Register obj = ToRegister(lir->output());
 
-    typedef JSObject *(*pf)(JSContext *, HandleShape, HandleTypeObject, HeapSlot *, HandleObject);
+    typedef JSObject *(*pf)(JSContext *, HandleShape, HandleTypeObject, HeapSlot *);
     static const VMFunction NewCallObjectInfo = FunctionInfo<pf>(NewCallObject);
 
     JSObject *templateObj = lir->mir()->templateObj();
     JSObject *global = &templateObj->global();
 
     // If we have a template object, we can inline call object creation.
     OutOfLineCode *ool;
     if (lir->slots()->isRegister()) {
         ool = oolCallVM(NewCallObjectInfo, lir,
                         (ArgList(), ImmGCPtr(templateObj->lastProperty()),
                                     ImmGCPtr(templateObj->type()),
-                                    ToRegister(lir->slots()),
-                                    ImmGCPtr(global)),
+                                    ToRegister(lir->slots())),
                         StoreRegisterTo(obj));
     } else {
         ool = oolCallVM(NewCallObjectInfo, lir,
                         (ArgList(), ImmGCPtr(templateObj->lastProperty()),
                                     ImmGCPtr(templateObj->type()),
-                                    ImmWord((void *)NULL),
-                                    ImmGCPtr(global)),
+                                    ImmWord((void *)NULL)),
                         StoreRegisterTo(obj));
     }
     if (!ool)
         return false;
 
     masm.newGCThing(obj, templateObj, ool->entry());
     masm.initGCThing(obj, templateObj);
 
--- a/js/src/ion/Ion.cpp
+++ b/js/src/ion/Ion.cpp
@@ -716,16 +716,17 @@ IonScript::purgeCaches(JSCompartment *c)
     AutoFlushCache afc("purgeCaches");
     for (size_t i = 0; i < numCaches(); i++)
         getCache(i).reset();
 }
 
 void
 ion::ToggleBarriers(JSCompartment *comp, bool needs)
 {
+    IonContext ictx(NULL, comp, NULL);
     AutoFlushCache afc("ToggleBarriers");
     for (gc::CellIterUnderGC i(comp, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
         JSScript *script = i.get<JSScript>();
         if (script->hasIonScript())
             script->ion->toggleBarriers(needs);
     }
 }
 
@@ -1675,17 +1676,20 @@ ion::UsesBeforeIonRecompile(JSScript *sc
     // To accomplish this, we use a slightly higher threshold for inner loops.
     // Note that we use +1 to prefer non-OSR over OSR.
     return minUses + (loop->depth + 1) * 100;
 }
 
 void
 AutoFlushCache::updateTop(uintptr_t p, size_t len)
 {
-    GetIonContext()->compartment->ionCompartment()->flusher()->update(p, len);
+    IonContext *ictx = GetIonContext();
+    IonCompartment *icmp = ictx->compartment->ionCompartment();
+    AutoFlushCache *afc = icmp->flusher();
+    afc->update(p, len);
 }
 
 AutoFlushCache::AutoFlushCache(const char *nonce, IonCompartment *comp)
   : start_(0),
     stop_(0),
     name_(nonce),
     used_(false)
 {
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -3401,40 +3401,26 @@ IonBuilder::inlineScriptedCall(AutoObjec
     return true;
 }
 
 MInstruction *
 IonBuilder::createCallObject(MDefinition *callee, MDefinition *scope)
 {
     // Create a template CallObject that we'll use to generate inline object
     // creation.
-    RootedObject templateObj(cx);
-    RootedShape shape(cx, script->bindings.callObjShape());
-    {
-        RootedTypeObject type(cx, cx->compartment->getEmptyType(cx));
-        if (!type)
-            return NULL;
-        gc::AllocKind kind = gc::GetGCObjectKind(shape->numFixedSlots());
-
-        HeapSlot *slots;
-        if (!PreallocateObjectDynamicSlots(cx, shape, &slots))
-            return NULL;
-
-        templateObj = JSObject::create(cx, kind, shape, type, slots);
-        if (!templateObj) {
-            cx->free_(slots);
-            return NULL;
-        }
-    }
+
+    RootedObject templateObj(cx, CallObject::createTemplateObject(cx, script));
+    if (!templateObj)
+        return NULL;
 
     // If the CallObject needs dynamic slots, allocate those now.
     MInstruction *slots;
     if (templateObj->hasDynamicSlots()) {
-        size_t nslots = JSObject::dynamicSlotsCount(templateObj->lastProperty()->numFixedSlots(),
-                                                    templateObj->lastProperty()->slotSpan());
+        size_t nslots = JSObject::dynamicSlotsCount(templateObj->numFixedSlots(),
+                                                    templateObj->slotSpan());
         slots = MNewSlots::New(nslots);
     } else {
         slots = MConstant::New(NullValue());
     }
     current->add(slots);
 
     // Allocate the actual object. It is important that no intervening
     // instructions could potentially bailout, thus leaking the dynamic slots
@@ -3447,17 +3433,17 @@ IonBuilder::createCallObject(MDefinition
     current->add(MStoreFixedSlot::New(callObj, CallObject::enclosingScopeSlot(), scope));
 
     // Initialize argument slots.
     for (AliasedFormalIter i(script); i; i++) {
         unsigned slot = i.scopeSlot();
         unsigned formal = i.frameIndex();
         MDefinition *param = current->getSlot(info().argSlot(formal));
         if (slots->type() == MIRType_Slots)
-            current->add(MStoreSlot::New(slots, slot - shape->numFixedSlots(), param));
+            current->add(MStoreSlot::New(slots, slot - templateObj->numFixedSlots(), param));
         else
             current->add(MStoreFixedSlot::New(callObj, slot, param));
     }
 
     return callObj;
 }
 
 MDefinition *
--- a/js/src/ion/VMFunctions.cpp
+++ b/js/src/ion/VMFunctions.cpp
@@ -356,20 +356,19 @@ NewSlots(JSRuntime *rt, unsigned nslots)
 
     for (unsigned i = 0; i < nslots; i++)
         slots[i] = UndefinedValue();
 
     return reinterpret_cast<HeapSlot *>(slots);
 }
 
 JSObject *
-NewCallObject(JSContext *cx, HandleShape shape, HandleTypeObject type, HeapSlot *slots,
-              HandleObject global)
+NewCallObject(JSContext *cx, HandleShape shape, HandleTypeObject type, HeapSlot *slots)
 {
-    return CallObject::create(cx, shape, type, slots, global);
+    return CallObject::create(cx, shape, type, slots);
 }
 
 bool SPSEnter(JSContext *cx, HandleScript script)
 {
     return cx->runtime->spsProfiler.enter(cx, script, script->function());
 }
 
 bool SPSExit(JSContext *cx, HandleScript script)
--- a/js/src/ion/VMFunctions.h
+++ b/js/src/ion/VMFunctions.h
@@ -431,18 +431,17 @@ bool ArrayPushDense(JSContext *cx, JSObj
 bool ArrayShiftDense(JSContext *cx, JSObject *obj, Value *rval);
 
 bool SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValue value,
                  bool strict, bool isSetName);
 
 bool InterruptCheck(JSContext *cx);
 
 HeapSlot *NewSlots(JSRuntime *rt, unsigned nslots);
-JSObject *NewCallObject(JSContext *cx, HandleShape shape, HandleTypeObject type, HeapSlot *slots,
-                        HandleObject global);
+JSObject *NewCallObject(JSContext *cx, HandleShape shape, HandleTypeObject type, HeapSlot *slots);
 
 bool SPSEnter(JSContext *cx, HandleScript script);
 bool SPSExit(JSContext *cx, HandleScript script);
 
 
 } // namespace ion
 } // namespace js
 
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -133,61 +133,71 @@ js::ScopeCoordinateName(JSRuntime *rt, J
 
 /*****************************************************************************/
 
 /*
  * Construct a bare-bones call object given a shape, type, and slots pointer.
  * The call object must be further initialized to be usable.
  */
 CallObject *
-CallObject::create(JSContext *cx, HandleShape shape, HandleTypeObject type, HeapSlot *slots,
-                   HandleObject global)
+CallObject::create(JSContext *cx, HandleShape shape, HandleTypeObject type, HeapSlot *slots)
 {
     gc::AllocKind kind = gc::GetGCObjectKind(shape->numFixedSlots());
     JS_ASSERT(CanBeFinalizedInBackground(kind, &CallClass));
     kind = gc::GetBackgroundAllocKind(kind);
 
-    RootedObject obj(cx, JSObject::create(cx, kind, shape, type, slots));
+    JSObject *obj = JSObject::create(cx, kind, shape, type, slots);
     if (!obj)
         return NULL;
+    return &obj->asCall();
+}
+
+/*
+ * Create a CallObject for a JSScript that is not initialized to any particular
+ * callsite. This object can either be initialized (with an enclosing scope and
+ * callee) or used as a template for jit compilation.
+ */
+CallObject *
+CallObject::createTemplateObject(JSContext *cx, JSScript *script)
+{
+    RootedShape shape(cx, script->bindings.callObjShape());
+
+    RootedTypeObject type(cx, cx->compartment->getEmptyType(cx));
+    if (!type)
+        return NULL;
 
-    JS_ASSERT(obj->isDelegate());
+    HeapSlot *slots;
+    if (!PreallocateObjectDynamicSlots(cx, shape, &slots))
+        return NULL;
 
-    return &obj->asCall();
+    CallObject *callobj = CallObject::create(cx, shape, type, slots);
+    if (!callobj) {
+        cx->free_(slots);
+        return NULL;
+    }
+
+    return callobj;
 }
 
 /*
  * Construct a call object for the given bindings.  If this is a call object
  * for a function invocation, callee should be the function being called.
  * Otherwise it must be a call object for eval of strict mode code, and callee
  * must be null.
  */
 CallObject *
 CallObject::create(JSContext *cx, JSScript *script, HandleObject enclosing, HandleFunction callee)
 {
-    RootedShape shape(cx, script->bindings.callObjShape());
-
-    RootedTypeObject type(cx, cx->compartment->getEmptyType(cx));
-    if (!type)
-        return NULL;
-
-    HeapSlot *slots;
-    if (!PreallocateObjectDynamicSlots(cx, shape, &slots))
+    CallObject *callobj = CallObject::createTemplateObject(cx, script);
+    if (!callobj)
         return NULL;
 
-    RootedObject global(cx, &enclosing->global());
-    RootedObject obj(cx, CallObject::create(cx, shape, type, slots, global));
-    if (!obj)
-        return NULL;
-
-    JS_ASSERT(enclosing->global() == obj->global());
-
-    obj->asScope().setEnclosingScope(enclosing);
-    obj->initFixedSlot(CALLEE_SLOT, ObjectOrNullValue(callee));
-    return &obj->asCall();
+    callobj->asScope().setEnclosingScope(enclosing);
+    callobj->initFixedSlot(CALLEE_SLOT, ObjectOrNullValue(callee));
+    return callobj;
 }
 
 CallObject *
 CallObject::createForFunction(JSContext *cx, StackFrame *fp)
 {
     JS_ASSERT(fp->isNonEvalFunctionFrame());
     assertSameCompartment(cx, fp);
 
--- a/js/src/vm/ScopeObject.h
+++ b/js/src/vm/ScopeObject.h
@@ -181,18 +181,20 @@ class CallObject : public ScopeObject
     static const uint32_t CALLEE_SLOT = 1;
 
     static CallObject *
     create(JSContext *cx, JSScript *script, HandleObject enclosing, HandleFunction callee);
 
   public:
     /* These functions are internal and are exposed only for JITs. */
     static CallObject *
-    create(JSContext *cx, HandleShape shape, HandleTypeObject type, HeapSlot *slots,
-           HandleObject enclosing);
+    create(JSContext *cx, HandleShape shape, HandleTypeObject type, HeapSlot *slots);
+
+    static CallObject *
+    createTemplateObject(JSContext *cx, JSScript *script);
 
     static const uint32_t RESERVED_SLOTS = 2;
 
     static CallObject *createForFunction(JSContext *cx, StackFrame *fp);
     static CallObject *createForStrictEval(JSContext *cx, StackFrame *fp);
 
     /* True if this is for a strict mode eval frame. */
     inline bool isForEval() const;