harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfur...@apache.org
Subject svn commit: r549835 - in /harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet: cg.h cg_fld_arr.cpp cg_regs.cpp enc.h enc_ia32.cpp
Date Fri, 22 Jun 2007 15:06:02 GMT
Author: mfursov
Date: Fri Jun 22 08:06:01 2007
New Revision: 549835

URL: http://svn.apache.org/viewvc?view=rev&rev=549835
Log:
fix for HARMONY-4250

Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_regs.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h?view=diff&rev=549835&r1=549834&r2=549835
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h Fri Jun 22 08:06:01 2007
@@ -636,10 +636,7 @@
      * to memory.
      */
     AR      valloc(jtype jt);
-    /**
-     * @brief spills ar register. after the call ar is free for use. 
-     */
-    void    freeReg(AR ar);
+
     /**
      * @brief Ensures operand stack item at the given \c depth resides in 
      * the memory.

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp?view=diff&rev=549835&r1=549834&r2=549835
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp Fri Jun 22 08:06:01 2007
@@ -345,30 +345,12 @@
                 // if in lazy resolution mode the field may be not resolved
                 // it is pessimistically considered as a volatile one.
                 if ( (!fieldOp.fld) || field_is_volatile(fieldOp.fld) ) {
-                    // prepare address
-                    freeReg(gr4); // ESI
-                    lea(gr4,where);
-
-                    // release gp regs used by cmpxchg8b
-                    freeReg(gr0); // EAX
-                    freeReg(gr1); // EBX
-                    freeReg(gr2); // ECX
-                    freeReg(gr3); // EDX
-
-                    // place for loading value (EDX:EAX)
-                    Opnd eax = Opnd(jt, gr0);
-                    Opnd edx = Opnd(jt, gr3);
-
-                    // read the field
-                    cmpxchg8b(true, gr4);
-                    vpush2(eax, edx);
-                    
-                    //TODO: do not mark registers as global, restore old value here!
-                    if (is_callee_save(gr0)) m_global_rusage.set(ar_idx(gr0));
-                    if (is_callee_save(gr1)) m_global_rusage.set(ar_idx(gr1));
-                    if (is_callee_save(gr2)) m_global_rusage.set(ar_idx(gr2));
-                    if (is_callee_save(gr3)) m_global_rusage.set(ar_idx(gr3));
-                    if (is_callee_save(gr4)) m_global_rusage.set(ar_idx(gr4));
+                    Opnd hi_part(jt, valloc(jt));
+                    rlock(hi_part.reg());
+                    Opnd lo_part(jt, valloc(jt));
+                    volatile64_get(where, hi_part.reg(), lo_part.reg());
+                    vpush2(lo_part, hi_part);
+                    runlock(hi_part.reg());
                 } else {
                     Opnd where_hi(jt, where.base(), where.disp()+4, 
                                       where.index(), where.scale());
@@ -423,37 +405,11 @@
         // it is pessimistically considered as a volatile one.
         if (is_big(jt) &&
            ((!fieldOp.fld) || field_is_volatile(fieldOp.fld))) {
-            Val& val = vstack(0);
-            Val& val_hi = vstack(1);
-            // prepare address
-            freeReg(gr4); // ESI
-            lea(gr4,where);
-
-            // prepare the value being stored
-            Opnd ecx = Opnd(i32, gr2);
-            Opnd ebx = Opnd(i32, gr1);
-            freeReg(gr1); // EBX
-            freeReg(gr2); // ECX
-            mov(ecx, val_hi.as_opnd());
-            mov(ebx, val.as_opnd());
-
-            // release EDX:EAX (they are rewritten by cmpxchg8b)
-            freeReg(gr0); // EAX
-            freeReg(gr3); // EDX
-
-            // the loop to write value to the field
-            unsigned _loop = ipoff();
-            cmpxchg8b(true, gr4);
-            unsigned br_off = br(nz, 0, 0);
-            patch(br_off, ip(_loop));
-
-            //TODO: do not mark registers as global, restore old value here!
-            if (is_callee_save(gr0)) m_global_rusage.set(ar_idx(gr0));
-            if (is_callee_save(gr1)) m_global_rusage.set(ar_idx(gr1));
-            if (is_callee_save(gr2)) m_global_rusage.set(ar_idx(gr2));
-            if (is_callee_save(gr3)) m_global_rusage.set(ar_idx(gr3));
-            if (is_callee_save(gr4)) m_global_rusage.set(ar_idx(gr4));
-
+            Opnd val_lo = vstack(0, true).as_opnd();
+            rlock(val_lo.reg());
+            Opnd val_hi = vstack(1, true).as_opnd();
+            volatile64_set(where, val_hi.reg(), val_lo.reg());
+            runlock(val_lo.reg());
         } else {
             Val& val = vstack(0, vis_mem(0));
             do_mov(where, val, fieldIsMagic);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_regs.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_regs.cpp?view=diff&rev=549835&r1=549834&r2=549835
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_regs.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_regs.cpp Fri Jun 22 08:06:01 2007
@@ -135,13 +135,6 @@
 
     // Ugh... No way out, have to spill to the memory...
 
-    freeReg(ar);
-    
-    return ar;
-}
-
-void CodeGen::freeReg(AR ar)
-{
     if (is_set(DBG_TRACE_CG)) { dbg(";;>spill %s\n", to_str(ar).c_str()); }
      
     // First, free out the stack items, which are the register
@@ -189,6 +182,8 @@
         pop(stk);
     }
     if (is_set(DBG_TRACE_CG)) { dbg(";;>~spill\n"); }
+
+    return ar;
 }
 
 Val& CodeGen::vstack(unsigned depth, bool toReg)

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h?view=diff&rev=549835&r1=549834&r2=549835
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h Fri Jun 22 08:06:01 2007
@@ -1031,14 +1031,25 @@
     }
 
     /**
-    * Generates CMPXCHG8B operation.
+    * Generates write for 64-bit volatile value
     */
-    void cmpxchg8b(bool lockPrefix, AR addrBaseReg)
+    void volatile64_set(Opnd& where, AR hi_part, AR lo_part)
     {
         if (is_trace_on()) {
-            trace(string("cmpxchg8b:"), string(lockPrefix ? "(locked) ":""),  to_str(addrBaseReg));
+            trace(string("volatile64_set:") + to_str(where), to_str(hi_part), to_str(lo_part));
         }
-        cmpxchg8b_impl(lockPrefix,addrBaseReg);
+        volatile64_op_impl(where, hi_part, lo_part, true);
+    }
+
+    /**
+    * Generates read for 64-bit volatile value
+    */
+    void volatile64_get(Opnd& where, AR hi_part, AR lo_part)
+    {
+        if (is_trace_on()) {
+            trace(string("volatile64_get:") + to_str(where), to_str(hi_part), to_str(lo_part));
+        }
+        volatile64_op_impl(where, hi_part, lo_part, false);
     }
 
     /**
@@ -1470,8 +1481,8 @@
     void cmovcc_impl(COND c, const Opnd& op0, const Opnd& op1);
     /// Implementation of cmpxchg().
     void cmpxchg_impl(bool lockPrefix, AR addrReg, AR newReg, AR oldReg);
-    /// Implementation of cmpxchg8b().
-    void cmpxchg8b_impl(bool lockPrefix, AR addrReg);
+    /// Implementation of volatile64 get and set ops().
+    void volatile64_op_impl(Opnd& where, AR hi_part, AR lo_part, bool is_put);
     /// Implementation of lea().
     void lea_impl(const Opnd& reg, const Opnd& mem);
     /// Implementation of movp().

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp?view=diff&rev=549835&r1=549834&r2=549835
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp Fri Jun 22 08:06:01 2007
@@ -728,17 +728,97 @@
 
 }
 
-void Encoder::cmpxchg8b_impl(bool lockPrefix, AR addrReg) {
+static void mov_regs(Encoder* enc, RegName r_dst, RegName r_src) {
+    EncoderBase::Operands args;
+    args.add(r_dst);
+    args.add(r_src);
+    enc->ip(EncoderBase::encode(enc->ip(), Mnemonic_MOV, args));
+}
 
-    if (lockPrefix) {
-        ip(EncoderBase::prefix(ip(), InstPrefix_LOCK));
+void Encoder::volatile64_op_impl(Opnd& where, AR hi_part, AR lo_part, bool is_put) {
+    int regSize=sizeof(void*);
+    RegName regs[] = {RegName_EAX, RegName_EBX, RegName_ECX, RegName_EDX, RegName_ESI};
+    {//free EAX,EBX,ECX,EDX and ESI registers to use cmpxchg8b
+        { //SUB ESP 20 -> protect spill area from OS
+            EncoderBase::Operands args;
+            args.add(RegName_ESP);
+            args.add(EncoderBase::Operand(OpndSize_32, (long long)5*regSize));
+            ip(EncoderBase::encode(ip(), Mnemonic_SUB, args));
+        }
+        for (int i=0;i<5;i++) {
+            EncoderBase::Operands args;
+            args.add(EncoderBase::Operand(OpndSize_32, RegName_ESP, i*regSize));
+            args.add(regs[i]);
+            ip(EncoderBase::encode(ip(), Mnemonic_MOV, args));
+        }
     }
 
-    RegName dAddrReg = devirt(addrReg);
-    EncoderBase::Operands args;
-    args.add(EncoderBase::Operand(OpndSize_64, dAddrReg, 0));
-    ip(EncoderBase::encode(ip(), Mnemonic_CMPXCHG8B, args));
+    //load address to ESI
+    lea_impl(virt(RegName_ESI), where);
+    
+    
+
+    RegName r_hi = devirt(hi_part);
+    RegName r_lo = devirt(lo_part);
 
+    if (is_put) {
+        //load value to ECX/EBX.
+        RegName r_lo2=r_lo;
+        if (r_lo2 == RegName_ECX) {
+            RegName r_free = r_lo2!=RegName_EAX ? RegName_EAX : RegName_EDX;
+            mov_regs(this, r_free, r_lo2);
+            r_lo2 = r_free;
+        }
+        mov_regs(this, RegName_ECX, r_hi);
+        mov_regs(this, RegName_EBX, r_lo2);
+    }
+
+    //3. set lock prefix
+    unsigned loop_ip = ipoff();
+    ip(EncoderBase::prefix(ip(), InstPrefix_LOCK));
+     
+    //do cmpxchg8b
+    {
+        EncoderBase::Operands args;
+        args.add(EncoderBase::Operand(OpndSize_64, RegName_ESI, 0));
+        ip(EncoderBase::encode(ip(), Mnemonic_CMPXCHG8B, args));
+    }
+
+    if (is_put) {
+        //loop until not successful
+        unsigned br_off = br(nz, 0, 0);
+        patch(br_off, ip(loop_ip));
+    } else {
+        //store result of get to lo_part and hi_part
+        RegName lo_res = RegName_EAX;
+        if (r_hi == lo_res) {
+            mov_regs(this, RegName_EBX, lo_res);
+            lo_res = RegName_EBX;
+        }
+        mov_regs(this, r_hi, RegName_EDX);
+        mov_regs(this, r_lo, lo_res);
+    }
+
+    //restore initial regs values
+    {
+        for (int i=0;i<5;i++) {
+            RegName r = regs[i];
+            if (!is_put && (r == r_hi || r == r_lo)) { 
+                continue;
+            }
+            EncoderBase::Operands args;
+            args.add(regs[i]);
+            args.add(EncoderBase::Operand(OpndSize_32, RegName_ESP, i*regSize));
+            ip(EncoderBase::encode(ip(), Mnemonic_MOV, args));
+        }
+        { //ADD ESP 20 -> restore ESP
+            EncoderBase::Operands args;
+            args.add(RegName_ESP);
+            args.add(EncoderBase::Operand(OpndSize_32, (long long)5*regSize));
+            ip(EncoderBase::encode(ip(), Mnemonic_ADD, args));
+        }
+
+    }
 }
 
 void Encoder::lea_impl(const Opnd& reg, const Opnd& mem)



Mime
View raw message