[JAEGER] Added JSOP_DUP.
authorDavid Anderson <danderson@mozilla.com>
Sat, 05 Jun 2010 14:32:53 -0700
changeset 52714 73564de0e16723790343f9655e2c9b08329406c6
parent 52713 1aafa92a04fb052fdda6126d5cd4b8dc0156acec
child 52715 8655c6dde6076e4080a1e7123247e00b2636429e
push idunknown
push userunknown
push dateunknown
milestone1.9.3a5pre
[JAEGER] Added JSOP_DUP.
js/src/methodjit/Compiler.cpp
js/src/methodjit/FrameState-inl.h
js/src/methodjit/FrameState.cpp
js/src/methodjit/FrameState.h
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -347,16 +347,20 @@ mjit::Compiler::generateMethod()
                                             : Assembler::NonZero;
                 j = masm.branch32(cond, Registers::ReturnReg, Registers::ReturnReg);
                 frame.pop();
                 jumpInScript(j, PC + GET_JUMP_OFFSET(PC));
             }
           }
           END_CASE(JSOP_IFEQ)
 
+          BEGIN_CASE(JSOP_DUP)
+            frame.dup();
+          END_CASE(JSOP_DUP)
+
           BEGIN_CASE(JSOP_BITAND)
             jsop_bitop(op);
           END_CASE(JSOP_BITAND)
 
           BEGIN_CASE(JSOP_LT)
           BEGIN_CASE(JSOP_LE)
           BEGIN_CASE(JSOP_GT)
           BEGIN_CASE(JSOP_GE)
--- a/js/src/methodjit/FrameState-inl.h
+++ b/js/src/methodjit/FrameState-inl.h
@@ -439,13 +439,32 @@ FrameState::swapInTracker(FrameEntry *lh
     JS_ASSERT(tracker[li] == lhs);
     JS_ASSERT(tracker[ri] == rhs);
     tracker.entries[ri] = lhs;
     tracker.entries[li] = rhs;
     lhs->index_ = ri;
     rhs->index_ = li;
 }
 
+inline uint32
+FrameState::localIndex(uint32 n)
+{
+    return nargs + n;
+}
+
+inline void
+FrameState::dup()
+{
+    FrameEntry *fe = peek(-1);
+    pushCopyOf(indexOfFe(fe));
+}
+
+inline void
+FrameState::pushLocal(uint32 n)
+{
+    pushCopyOf(localIndex(n));
+}
+
 } /* namspace mjit */
 } /* namspace js */
 
 #endif /* include */
 
--- a/js/src/methodjit/FrameState.cpp
+++ b/js/src/methodjit/FrameState.cpp
@@ -465,41 +465,41 @@ FrameState::ownRegForData(FrameEntry *fe
         JS_ASSERT(fe->data.inMemory());
         reg = alloc();
         masm.loadData32(addressOf(fe), reg);
     }
     return reg;
 }
 
 void
-FrameState::pushLocal(uint32 n)
+FrameState::pushCopyOf(uint32 index)
 {
-    FrameEntry *localFe = getLocal(n);
+    FrameEntry *backing = entryFor(index);
     FrameEntry *fe = rawPush();
     fe->resetUnsynced();
-    if (localFe->isConstant()) {
-        fe->setConstant(Jsvalify(localFe->getValue()));
+    if (backing->isConstant()) {
+        fe->setConstant(Jsvalify(backing->getValue()));
     } else {
-        if (localFe->isTypeKnown())
-            fe->setTypeTag(localFe->getTypeTag());
+        if (backing->isTypeKnown())
+            fe->setTypeTag(backing->getTypeTag());
         else
             fe->type.invalidate();
         fe->data.invalidate();
-        if (localFe->isCopy()) {
-            localFe = localFe->copyOf();
-            fe->setCopyOf(localFe);
+        if (backing->isCopy()) {
+            backing = backing->copyOf();
+            fe->setCopyOf(backing);
         } else {
-            fe->setCopyOf(localFe);
-            localFe->setCopied();
+            fe->setCopyOf(backing);
+            backing->setCopied();
         }
 
         /* Maintain tracker ordering guarantees for copies. */
-        JS_ASSERT(localFe->isCopied());
-        if (fe->trackerIndex() < localFe->trackerIndex())
-            swapInTracker(fe, localFe);
+        JS_ASSERT(backing->isCopied());
+        if (fe->trackerIndex() < backing->trackerIndex())
+            swapInTracker(fe, backing);
     }
 }
 
 void
 FrameState::uncopy(FrameEntry *original)
 {
     JS_ASSERT(original->isCopied());
 
--- a/js/src/methodjit/FrameState.h
+++ b/js/src/methodjit/FrameState.h
@@ -333,16 +333,21 @@ class FrameState
     inline void pinReg(RegisterID reg);
 
     /*
      * Unpins a previously pinned register.
      */
     inline void unpinReg(RegisterID reg);
 
     /*
+     * Dups the top item on the stack.
+     */
+    inline void dup();
+
+    /*
      * Returns the current stack depth of the frame.
      */
     uint32 stackDepth() const { return sp - spBase; }
     uint32 frameDepth() const { return stackDepth() + script->nfixed; }
     inline FrameEntry *tosFe() const;
 
 #ifdef DEBUG
     void assertValidRegisterState() const;
@@ -358,29 +363,27 @@ class FrameState
     void evictReg(RegisterID reg);
     inline FrameEntry *rawPush();
     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 forgetRegs(FrameEntry *fe);
     inline void swapInTracker(FrameEntry *lhs, FrameEntry *rhs);
+    inline uint32 localIndex(uint32 n);
+    void pushCopyOf(uint32 index);
 
     /*
      * "Uncopies" the backing store of a FrameEntry that has been copied. The
      * original FrameEntry is not invalidated; this is the responsibility of
      * the caller. The caller can check isCopied() to see if the registers
      * were moved to a copy.
      */
     void uncopy(FrameEntry *original);
 
-    uint32 localIndex(uint32 n) {
-        return nargs + n;
-    }
-
     FrameEntry *entryFor(uint32 index) const {
         JS_ASSERT(base[index]);
         return &entries[index];
     }
 
     void moveOwnership(RegisterID reg, FrameEntry *newFe) {
         regstate[reg].fe = newFe;
     }