Merge backout.
authorDavid Anderson <danderson@mozilla.com>
Mon, 06 Sep 2010 18:25:20 -0700
changeset 74566 dca27a8bc82fc871cd2c54f0c149408ca424dae7
parent 74564 0d06f0c22e437821c94a632967080f755e197211 (current diff)
parent 74565 307e6b88abc1034a8f85ec4c9b60732a78d60cf3 (diff)
child 74567 ca32ed513371555a77ee4ecad6e4987310d10d1a
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
milestone2.0b6pre
Merge backout.
js/src/methodjit/FrameState-inl.h
js/src/methodjit/FrameState.cpp
js/src/methodjit/FrameState.h
--- a/js/src/methodjit/FrameEntry.h
+++ b/js/src/methodjit/FrameEntry.h
@@ -123,17 +123,16 @@ class FrameEntry
 #endif
         knownType = type_;
         JS_ASSERT(!isNumber);
     }
 
     void track(uint32 index) {
         clear();
         index_ = index;
-        tracked = true;
     }
 
     void clear() {
         copied = false;
         copy = NULL;
         isNumber = false;
     }
 
@@ -206,34 +205,25 @@ class FrameEntry
      * Set copy index.
      */
     void setCopyOf(FrameEntry *fe) {
         JS_ASSERT_IF(fe, !fe->isConstant());
         JS_ASSERT(!isCopied());
         copy = fe;
     }
 
-    inline bool isTracked() const {
-        return tracked;
-    }
-
-    inline void untrack() {
-        tracked = false;
-    }
-
   private:
     JSValueType knownType;
     jsval_layout v_;
     RematInfo  type;
     RematInfo  data;
     uint32     index_;
     FrameEntry *copy;
     bool       copied;
     bool       isNumber;
-    bool       tracked;
-    char       padding[1];
+    char       padding[2];
 };
 
 } /* namespace mjit */
 } /* namespace js */
 
 #endif /* jsjaeger_valueinfo_h__ */
 
--- a/js/src/methodjit/FrameState-inl.h
+++ b/js/src/methodjit/FrameState-inl.h
@@ -38,33 +38,36 @@
  * ***** END LICENSE BLOCK ***** */
 
 #if !defined jsjaeger_framestate_inl_h__ && defined JS_METHODJIT
 #define jsjaeger_framestate_inl_h__
 
 namespace js {
 namespace mjit {
 
-inline void
-FrameState::addToTracker(FrameEntry *fe)
+inline FrameEntry *
+FrameState::addToTracker(uint32 index)
 {
-    JS_ASSERT(!fe->isTracked());
+    JS_ASSERT(!base[index]);
+    FrameEntry *fe = &entries[index];
+    base[index] = fe;
     fe->track(tracker.nentries);
     tracker.add(fe);
     JS_ASSERT(tracker.nentries <= script->nslots);
+    return fe;
 }
 
 inline FrameEntry *
 FrameState::peek(int32 depth)
 {
     JS_ASSERT(depth < 0);
     JS_ASSERT(sp + depth >= spBase);
-    FrameEntry *fe = &sp[depth];
-    if (!fe->isTracked()) {
-        addToTracker(fe);
+    FrameEntry *fe = sp[depth];
+    if (!fe) {
+        fe = addToTracker(indexOf(depth));
         fe->resetSynced();
     }
     return fe;
 }
 
 inline void
 FrameState::popn(uint32 n)
 {
@@ -154,18 +157,18 @@ FrameState::peekTypeInRegister(FrameEntr
     return fe->type.inRegister();
 }
 
 inline void
 FrameState::pop()
 {
     JS_ASSERT(sp > spBase);
 
-    FrameEntry *fe = --sp;
-    if (!fe->isTracked())
+    FrameEntry *fe = *--sp;
+    if (!fe)
         return;
 
     forgetAllRegs(fe);
 }
 
 inline void
 FrameState::freeReg(RegisterID reg)
 {
@@ -189,37 +192,40 @@ FrameState::forgetEverything(uint32 newS
 {
     forgetEverything();
     sp = spBase + newStackDepth;
 }
 
 inline FrameEntry *
 FrameState::rawPush()
 {
-    JS_ASSERT(unsigned(sp - entries) < nargs + script->nslots);
+    JS_ASSERT(unsigned(sp - base) < nargs + script->nslots);
+
+    sp++;
 
-    if (!sp->isTracked())
-        addToTracker(sp);
+    if (FrameEntry *fe = sp[-1])
+        return fe;
 
-    return sp++;
+    return addToTracker(&sp[-1] - base);
 }
 
 inline void
 FrameState::push(const Value &v)
 {
     FrameEntry *fe = rawPush();
     fe->setConstant(Jsvalify(v));
 }
 
 inline void
 FrameState::pushSynced()
 {
-    if (sp->isTracked())
-        sp->resetSynced();
     sp++;
+
+    if (FrameEntry *fe = sp[-1])
+        fe->resetSynced();
 }
 
 inline void
 FrameState::pushSyncedType(JSValueType type)
 {
     FrameEntry *fe = rawPush();
 
     fe->resetSynced();
@@ -607,21 +613,20 @@ FrameState::testString(Assembler::Condit
         return masm.testString(cond, addressOf(fe));
     return masm.testString(cond, tempRegForType(fe));
 }
 
 inline FrameEntry *
 FrameState::getLocal(uint32 slot)
 {
     uint32 index = nargs + slot;
-    FrameEntry *fe = &entries[index];
-    if (!fe->isTracked()) {
-        addToTracker(fe);
-        fe->resetSynced();
-    }
+    if (FrameEntry *fe = base[index])
+        return fe;
+    FrameEntry *fe = addToTracker(index);
+    fe->resetSynced();
     return fe;
 }
 
 inline void
 FrameState::pinReg(RegisterID reg)
 {
     JS_ASSERT(regstate[reg].fe);
     regstate[reg].save = regstate[reg].fe;
@@ -642,17 +647,17 @@ FrameState::forgetAllRegs(FrameEntry *fe
         forgetReg(fe->type.reg());
     if (fe->data.inRegister())
         forgetReg(fe->data.reg());
 }
 
 inline FrameEntry *
 FrameState::tosFe() const
 {
-    return sp;
+    return &entries[uint32(sp - base)];
 }
 
 inline void
 FrameState::swapInTracker(FrameEntry *lhs, FrameEntry *rhs)
 {
     uint32 li = lhs->trackerIndex();
     uint32 ri = rhs->trackerIndex();
     JS_ASSERT(tracker[li] == lhs);
@@ -699,18 +704,18 @@ FrameState::pushLocal(uint32 n)
         pushCopyOf(indexOfFe(getLocal(n)));
     } else {
 #ifdef DEBUG
         /*
          * We really want to assert on local variables, but in the presence of
          * SETLOCAL equivocation of stack slots, and let expressions, just
          * weakly assert on the fixed local vars.
          */
-        FrameEntry *fe = &locals[n];
-        if (fe->isTracked() && n < script->nfixed) {
+        FrameEntry *fe = base[localIndex(n)];
+        if (fe && n < script->nfixed) {
             JS_ASSERT(fe->type.inMemory());
             JS_ASSERT(fe->data.inMemory());
         }
 #endif
         push(Address(JSFrameReg, sizeof(JSStackFrame) + n * sizeof(Value)));
     }
 }
 
--- a/js/src/methodjit/FrameState.cpp
+++ b/js/src/methodjit/FrameState.cpp
@@ -59,54 +59,54 @@ FrameState::~FrameState()
 
 bool
 FrameState::init(uint32 nargs)
 {
     this->nargs = nargs;
 
     uint32 nslots = script->nslots + nargs;
     if (!nslots) {
-        sp = spBase = locals = args = NULL;
+        sp = spBase = locals = args = base = NULL;
         return true;
     }
 
     uint32 nlocals = script->nslots;
     if ((eval = script->usesEval || cx->compartment->debugMode))
         nlocals = 0;
 
-    size_t totalBytes = sizeof(FrameEntry) * nslots +       // entries[]
-                        sizeof(FrameEntry *) * nslots +     // tracker.entries[]
-                        sizeof(uint32) * nlocals;           // escaping[]
-
-    uint8 *cursor = (uint8 *)cx->calloc(totalBytes);
+    uint8 *cursor = (uint8 *)cx->malloc(sizeof(FrameEntry) * nslots +       // entries[]
+                                        sizeof(FrameEntry *) * nslots +     // base[]
+                                        sizeof(FrameEntry *) * nslots +     // tracker.entries[]
+                                        sizeof(uint32) * nlocals            // escaping[]
+                                        );
     if (!cursor)
         return false;
 
     if (!reifier.init(nslots))
         return false;
 
     entries = (FrameEntry *)cursor;
     cursor += sizeof(FrameEntry) * nslots;
 
-    args = entries;
-    locals = args + nargs;
+    base = (FrameEntry **)cursor;
+    args = base;
+    locals = base + nargs;
     spBase = locals + script->nfixed;
     sp = spBase;
+    memset(base, 0, sizeof(FrameEntry *) * nslots);
+    cursor += sizeof(FrameEntry *) * nslots;
 
     tracker.entries = (FrameEntry **)cursor;
     cursor += sizeof(FrameEntry *) * nslots;
 
     if (nlocals) {
         escaping = (uint32 *)cursor;
         memset(escaping, 0, sizeof(uint32) * nlocals);
-        cursor += sizeof(uint32) * nlocals;
     }
 
-    JS_ASSERT(reinterpret_cast<uint8 *>(entries) + totalBytes == cursor);
-
     return true;
 }
 
 void
 FrameState::takeReg(RegisterID reg)
 {
     if (freeRegs.hasReg(reg)) {
         freeRegs.takeReg(reg);
@@ -188,17 +188,17 @@ FrameState::forgetEverything()
     throwaway();
 }
 
 
 void
 FrameState::throwaway()
 {
     for (uint32 i = 0; i < tracker.nentries; i++)
-        tracker[i]->untrack();
+        base[indexOfFe(tracker[i])] = NULL;
 
     tracker.reset();
     freeRegs.reset();
 }
 
 void
 FrameState::storeTo(FrameEntry *fe, Address address, bool popped)
 {
@@ -856,19 +856,19 @@ FrameState::uncopy(FrameEntry *original)
 
 void
 FrameState::storeLocal(uint32 n, bool popGuaranteed, bool typeChange)
 {
     FrameEntry *localFe = getLocal(n);
     bool cacheable = !eval && !escaping[n];
 
     if (!popGuaranteed && !cacheable) {
-        JS_ASSERT_IF(locals[n].isTracked() && (!eval || n < script->nfixed),
-                     locals[n].type.inMemory() &&
-                     locals[n].data.inMemory());
+        JS_ASSERT_IF(base[localIndex(n)] && (!eval || n < script->nfixed),
+                     entries[localIndex(n)].type.inMemory() &&
+                     entries[localIndex(n)].data.inMemory());
         Address local(JSFrameReg, sizeof(JSStackFrame) + n * sizeof(Value));
         storeTo(peek(-1), local, false);
         forgetAllRegs(getLocal(n));
         localFe->resetSynced();
         return;
     }
 
     bool wasSynced = localFe->type.synced();
@@ -912,17 +912,17 @@ FrameState::storeLocal(uint32 n, bool po
      * condition does not hold, force it to hold by swapping in-place.
      */
     FrameEntry *backing = top;
     if (top->isCopy()) {
         backing = top->copyOf();
         JS_ASSERT(backing->trackerIndex() < top->trackerIndex());
 
         uint32 backingIndex = indexOfFe(backing);
-        uint32 tol = uint32(spBase - entries);
+        uint32 tol = uint32(spBase - base);
         if (backingIndex < tol || backingIndex < localIndex(n)) {
             /* local.idx < backing.idx means local cannot be a copy yet */
             if (localFe->trackerIndex() < backing->trackerIndex())
                 swapInTracker(backing, localFe);
             localFe->setNotCopied();
             localFe->setCopyOf(backing);
             if (backing->isTypeKnown())
                 localFe->setType(backing->getKnownType());
--- a/js/src/methodjit/FrameState.h
+++ b/js/src/methodjit/FrameState.h
@@ -669,17 +669,17 @@ class FrameState
     }
 
   private:
     inline RegisterID allocReg(FrameEntry *fe, RematInfo::RematType type);
     inline void forgetReg(RegisterID reg);
     RegisterID evictSomeReg(uint32 mask);
     void evictReg(RegisterID reg);
     inline FrameEntry *rawPush();
-    inline void addToTracker(FrameEntry *fe);
+    inline FrameEntry *addToTracker(uint32 index);
     inline void syncType(const FrameEntry *fe, Address to, Assembler &masm) const;
     inline void syncData(const FrameEntry *fe, Address to, Assembler &masm) const;
     inline FrameEntry *getLocal(uint32 slot);
     inline void forgetAllRegs(FrameEntry *fe);
     inline void swapInTracker(FrameEntry *lhs, FrameEntry *rhs);
     inline uint32 localIndex(uint32 n);
     void pushCopyOf(uint32 index);
     void syncFancy(Assembler &masm, Registers avail, uint32 resumeAt,
@@ -692,30 +692,30 @@ class FrameState
      * the caller. The caller can check isCopied() to see if the registers
      * were moved to a copy.
      *
      * Later addition: uncopy() returns the first copy found.
      */
     FrameEntry *uncopy(FrameEntry *original);
 
     FrameEntry *entryFor(uint32 index) const {
-        JS_ASSERT(entries[index].isTracked());
+        JS_ASSERT(base[index]);
         return &entries[index];
     }
 
     void moveOwnership(RegisterID reg, FrameEntry *newFe) {
         regstate[reg].fe = newFe;
     }
 
     RegisterID evictSomeReg() {
         return evictSomeReg(Registers::AvailRegs);
     }
 
     uint32 indexOf(int32 depth) {
-        return uint32((sp + depth) - entries);
+        return uint32((sp + depth) - base);
     }
 
     uint32 indexOfFe(FrameEntry *fe) {
         return uint32(fe - entries);
     }
 
   private:
     JSContext *cx;
@@ -724,27 +724,30 @@ class FrameState
     Assembler &masm;
 
     /* All allocated registers. */
     Registers freeRegs;
 
     /* Cache of FrameEntry objects. */
     FrameEntry *entries;
 
+    /* Base pointer of the FrameEntry vector. */
+    FrameEntry **base;
+
     /* Base pointer for arguments. */
-    FrameEntry *args;
+    FrameEntry **args;
 
     /* Base pointer for local variables. */
-    FrameEntry *locals;
+    FrameEntry **locals;
 
     /* Base pointer for the stack. */
-    FrameEntry *spBase;
+    FrameEntry **spBase;
 
     /* Dynamic stack pointer. */
-    FrameEntry *sp;
+    FrameEntry **sp;
 
     /* Vector of tracked slot indexes. */
     Tracker tracker;
 
     /*
      * Register ownership state. This can't be used alone; to find whether an
      * entry is active, you must check the allocated registers.
      */