You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2006/10/14 17:22:40 UTC

svn commit: r463954 - in /incubator/harmony/enhanced/drlvm/trunk/vm: include/jit_import_rt.h jitrino/src/codegenerator/ia32/Ia32GCMap.cpp jitrino/src/codegenerator/ia32/Ia32GCMap.h jitrino/src/vm/VMInterface.h jitrino/src/vm/drl/DrlVMInterface.h

Author: geirm
Date: Sat Oct 14 08:22:37 2006
New Revision: 463954

URL: http://svn.apache.org/viewvc?view=rev&rev=463954
Log:
HARMONY-1682

Jitrino.OPT performs incorrect GC enumeration in nested loop with array accesses

Patch applied.  smoke, c-unit, ~kernel passes.  Included testcase passes for -Xem:opt



Modified:
    incubator/harmony/enhanced/drlvm/trunk/vm/include/jit_import_rt.h
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCMap.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCMap.h
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.h
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlVMInterface.h

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/include/jit_import_rt.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/include/jit_import_rt.h?view=diff&rev=463954&r1=463953&r2=463954
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/include/jit_import_rt.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/include/jit_import_rt.h Sat Oct 14 08:22:37 2006
@@ -54,10 +54,6 @@
 // to a location that contains a pointer to an inside of an object.
 VMEXPORT void vm_enumerate_root_interior_pointer(void **slot, int offset, Boolean is_pinned);
 
-// The first argument is an interior pointer root, second argument is a pointer to the reference to the object
-// the first argument is in.  The function enumerates the interior pointer, but not the base.
-VMEXPORT void vm_enumerate_root_interior_pointer_with_base(void **slot_root, void **slot_base, Boolean is_pinned);
-
 // The JIT enumerates a managed pointer.  The pointer can be declared as
 // pinned.  The pointer can point to the managed heap or any other area
 // where data can be stored: stack or static fields.  It is the responsibility

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCMap.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCMap.cpp?view=diff&rev=463954&r1=463953&r2=463954
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCMap.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCMap.cpp Sat Oct 14 08:22:37 2006
@@ -341,6 +341,48 @@
     MemoryManager mm(256, "tmp");
     DrlVMTypeManager tm(mm);
 #endif
+    //The algorithm of enumeration is
+    //1. Derive all offsets for MPTRs with offsets unknown during compile time.
+    //2. Report to VM
+    //We need this 2 steps behavior because some GCs move objects during enumeration.
+    //In this case it's impossible to derive valid base for mptr with unknown offset.
+
+    //1. Derive all offsets. Use GCSafePointOpnd.mptrOffset to store the result.
+    for (uint32 i=0, n = gcOpnds.size(); i<n; i++) {
+        GCSafePointOpnd* gcOpnd = gcOpnds[i];
+        POINTER_SIZE_INT valPtrAddr = getOpndSaveAddr(context, stackInfo, gcOpnd);
+        if (gcOpnd->isObject() || gcOpnd->getMPtrOffset()!=MPTR_OFFSET_UNKNOWN) {
+            continue;
+        }
+
+        POINTER_SIZE_INT mptrAddr = *((POINTER_SIZE_INT*)valPtrAddr); 
+        //we looking for a base that  a) located before mptr in memory b) nearest to mptr
+        GCSafePointOpnd* baseOpnd = NULL;
+        POINTER_SIZE_INT basePtrAddr = 0, baseAddr = 0;
+        for (uint32 j=0; j<n; j++) {
+            GCSafePointOpnd* tmpOpnd = gcOpnds[j];   
+            if (tmpOpnd->isObject()) {
+                POINTER_SIZE_INT tmpPtrAddr = getOpndSaveAddr(context, stackInfo, tmpOpnd);
+                POINTER_SIZE_INT tmpBaseAddr = *((POINTER_SIZE_INT*)tmpPtrAddr);
+                if (tmpBaseAddr <= mptrAddr) {
+                    if (baseOpnd == NULL || tmpBaseAddr > baseAddr) {
+                        baseOpnd = tmpOpnd;
+                        basePtrAddr = tmpPtrAddr;
+                        baseAddr = tmpBaseAddr;
+                    } 
+                }
+            }
+        }
+        assert(baseOpnd!=NULL);
+#ifdef ENABLE_GC_RT_CHECKS
+        GCMap::checkObject(tm,  *(void**)basePtrAddr);
+#endif 
+        int offset = (int)(mptrAddr-baseAddr);
+        assert(offset>=0);
+        gcOpnd->getMPtrOffset(offset);
+    }
+
+    //2. Report the results
     for (uint32 i=0, n = gcOpnds.size(); i<n; i++) {
         GCSafePointOpnd* gcOpnd = gcOpnds[i];
         POINTER_SIZE_INT valPtrAddr = getOpndSaveAddr(context, stackInfo, gcOpnd);
@@ -354,42 +396,15 @@
             else
 #endif
                 gcInterface->enumerateRootReference((void**)valPtrAddr);
-        } else {
+        } else { //mptr with offset
             assert(gcOpnd->isMPtr());
-            POINTER_SIZE_INT mptrAddr = *((POINTER_SIZE_INT*)valPtrAddr); //
-            //find base, calculate offset and report to GC
-            if (gcOpnd->getMPtrOffset() == MPTR_OFFSET_UNKNOWN) {
-                //we looking for a base that  a) located before mptr in memory b) nearest to mptr
-                GCSafePointOpnd* baseOpnd = NULL;
-                POINTER_SIZE_INT basePtrAddr = 0, baseAddr = 0;
-                for (uint32 j =0; j<n; j++) {
-                    GCSafePointOpnd* tmpOpnd = gcOpnds[j];   
-                    if (tmpOpnd->isObject()) {
-                        POINTER_SIZE_INT tmpPtrAddr = getOpndSaveAddr(context, stackInfo, tmpOpnd);
-                        POINTER_SIZE_INT tmpBaseAddr = *((POINTER_SIZE_INT*)tmpPtrAddr);
-                        if (tmpBaseAddr <= mptrAddr) {
-                            if (baseOpnd == NULL || tmpBaseAddr > baseAddr) {
-                                baseOpnd = tmpOpnd;
-                                basePtrAddr = tmpPtrAddr;
-                                baseAddr = tmpBaseAddr;
-                            } 
-                        }
-                    }
-                }
-                assert(baseOpnd!=NULL);
+            int offset = gcOpnd->getMPtrOffset();
+            assert(offset>=0);
 #ifdef ENABLE_GC_RT_CHECKS
-                GCMap::checkObject(tm,  *(void**)basePtrAddr);
-#endif 
-                gcInterface->enumerateRootManagedReferenceWithBase((void**)valPtrAddr, (void**)basePtrAddr);
-            } else { // mptr - base == static_offset
-                POINTER_SIZE_INT offset = gcOpnd->getMPtrOffset();
-                //assert(offset>=0);
-#ifdef ENABLE_GC_RT_CHECKS
-                char* mptrAddr = *(char**)valPtrAddr;
-                GCMap::checkObject(tm, mptrAddr - offset);
+            char* mptrAddr = *(char**)valPtrAddr;
+            GCMap::checkObject(tm, mptrAddr - offset);
 #endif
-                gcInterface->enumerateRootManagedReference((void**)valPtrAddr, offset);
-            }
+            gcInterface->enumerateRootManagedReference((void**)valPtrAddr, offset);
         }
     }
 }

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCMap.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCMap.h?view=diff&rev=463954&r1=463953&r2=463954
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCMap.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCMap.h Sat Oct 14 08:22:37 2006
@@ -145,6 +145,7 @@
         int32 getDistFromInstESP() const { assert(isOnStack()); return val;}
 
         int32 getMPtrOffset() const {return mptrOffset;}
+        void getMPtrOffset(int newOffset) {mptrOffset = newOffset;}
 
 #ifdef _DEBUG
         uint32 firstId;

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.h?view=diff&rev=463954&r1=463953&r2=463954
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.h Sat Oct 14 08:22:37 2006
@@ -591,8 +591,6 @@
     virtual void enumerateRootReference(void** reference) = 0;
     virtual void enumerateCompressedRootReference(uint32* reference) = 0;
     virtual void enumerateRootManagedReference(void** slotReference, int slotOffset) = 0;
-    virtual void enumerateRootManagedReferenceWithBase(void** slotReference, void** baseReference) = 0;
-    virtual void enumerateRootManagedReferenceWithUnknownOffset(void** slotReference) = 0;
 };
 
 

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlVMInterface.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlVMInterface.h?view=diff&rev=463954&r1=463953&r2=463954
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlVMInterface.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlVMInterface.h Sat Oct 14 08:22:37 2006
@@ -652,14 +652,6 @@
         vm_enumerate_root_interior_pointer(slotReference, slotOffset, FALSE);
     }
 
-    virtual void enumerateRootManagedReferenceWithBase(void** slotReference, void** baseReference) {
-        vm_enumerate_root_interior_pointer_with_base(slotReference, baseReference, FALSE);
-    }
-
-    virtual void enumerateRootManagedReferenceWithUnknownOffset(void** slotReference) {
-        assert(0);
-    }
-
 private:
     GC_Enumeration_Handle gcHandle;
 };
@@ -679,14 +671,6 @@
 
     virtual void enumerateRootManagedReference(void** slotReference, int slotOffset) {
         vm_check_if_monitor(slotReference, 0, 0, slotOffset, FALSE, 3);
-    }
-
-    virtual void enumerateRootManagedReferenceWithBase(void** slotReference, void** baseReference) {
-        vm_check_if_monitor(slotReference, baseReference, 0, 0, FALSE, 4);
-    }
-
-    virtual void enumerateRootManagedReferenceWithUnknownOffset(void** slotReference) {
-        assert(0);
     }
 };