[vmkit-commits] [vmkit] r70200 - /vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Mon Apr 27 01:33:03 PDT 2009


Author: geoffray
Date: Mon Apr 27 03:33:02 2009
New Revision: 70200

URL: http://llvm.org/viewvc/llvm-project?rev=70200&view=rev
Log:
Bugfix when creating secondary types.


Modified:
    vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp

Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp?rev=70200&r1=70199&r2=70200&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp Mon Apr 27 03:33:02 2009
@@ -1303,8 +1303,12 @@
       offset = getCacheIndex() + depth + 1;
     } else {
       offset = getCacheIndex();
-      ++nbSecondaryTypes;
-      outOfDepth = 1;
+      // Add the super in the list of secondary types only if it is
+      // out of depth.
+      if (depth > getDisplayLength()) {
+        ++nbSecondaryTypes;
+        outOfDepth = 1;
+      }
     }
 
     mvm::BumpPtrAllocator& allocator = C->classLoader->allocator;
@@ -1379,29 +1383,45 @@
     Classpath* upcalls = JCL->bootstrapLoader->upcalls;
     
     if (upcalls->ArrayOfObject) {
-      UserCommonClass* temp = C->baseClass();
+      UserCommonClass* base = C->baseClass();
       uint32 dim = 1;
-      while (temp->isArray()) {
-        temp = temp->asArrayClass()->baseClass();
+      while (base->isArray()) {
+        base = base->asArrayClass()->baseClass();
         ++dim;
       }
      
       bool newSecondaryTypes = false;
-      bool intf = temp->isInterface();
-      if (temp->isPrimitive()) {
+      bool intf = base->isInterface();
+      const UTF8* superName = 0;
+
+      if (base->isPrimitive()) {
+        // If the base class is primitive, then the super is one
+        // dimension below, e.g. the super of int[][] is Object[].
         --dim;
-        temp = C->super;
-      } else if (temp == C->super) {
+        superName = JCL->constructArrayName(dim, C->super->name);
+      } else if (base == C->super) {
+        // If the base class is java.lang.Object, then the super is one
+        // dimension below, e.g. the super of Object[][] is Object[].
+        // Also, the class is the first class in the dimension hierarchy,
+        // so it must create a new secondary type list.
         --dim;
         newSecondaryTypes = true;
+        superName = JCL->constructArrayName(dim, C->super->name);
       } else {
-        temp = temp->super;
+        // If the base class is any other class, interface or not,
+        // the super is of the dimension of the current array class,
+        // and whose base class is the super of this base class.
+        superName = JCL->constructArrayName(dim, base->super->name);
       }
-      
-      const UTF8* name = JCL->constructArrayName(dim, temp->name);
-      ClassArray* super = JCL->constructArray(name);
+     
+      // Construct the super array class, e.g. java.lang.Object[] for
+      // java.lang.Class[].
+      ClassArray* super = JCL->constructArray(superName);
       JavaVirtualTable* superVT = super->virtualVT;
       depth = superVT->depth + 1;
+      
+      // Record if we need to add the super in the list of secondary types.
+      uint32 addSuper = 0;
 
       uint32 length = getDisplayLength() < depth ? getDisplayLength() : depth;
       memcpy(display, superVT->display, length * sizeof(JavaVirtualTable*)); 
@@ -1410,27 +1430,51 @@
         offset = getCacheIndex() + depth + 1;
       } else {
         offset = getCacheIndex();
+        // We add the super if the current class is an interface or if the super
+        // class is out of depth.
+        if (intf || depth != getDisplayLength()) addSuper = 1;
       }
         
       mvm::BumpPtrAllocator& allocator = JCL->allocator;
 
       if (!newSecondaryTypes) {
-        if (depth < getDisplayLength()) {
-          nbSecondaryTypes = superVT->nbSecondaryTypes;
-          secondaryTypes = superVT->secondaryTypes;
-        } else {
-          nbSecondaryTypes = superVT->nbSecondaryTypes + 1;
+        if (base->nbInterfaces || addSuper) {
+          // If the base class implements interfaces, we must also add the
+          // arrays of these interfaces, of the same dimension than this array
+          // class and add them to the secondary types list.
+          nbSecondaryTypes = base->nbInterfaces + superVT->nbSecondaryTypes +
+                                addSuper;
           secondaryTypes = (JavaVirtualTable**)
             allocator.Allocate(sizeof(JavaVirtualTable*) * nbSecondaryTypes);
-          secondaryTypes[0] = this;
-          memcpy(secondaryTypes + 1 , superVT->secondaryTypes,
+         
+          // Put the super in the list of secondary types.
+          if (addSuper) secondaryTypes[0] = superVT;
+
+          // Copy the list of secondary types of the super.
+          memcpy(secondaryTypes + addSuper, superVT->secondaryTypes,
                  superVT->nbSecondaryTypes * sizeof(JavaVirtualTable*));
+        
+          // Add our own secondary types: the interfaces of the base class put
+          // in the dimension of the current array class.
+          for (uint32 i = 0; i < base->nbInterfaces; ++i) {
+            const UTF8* name = 
+              JCL->constructArrayName(dim, base->interfaces[i]->name);
+            ClassArray* interface = JCL->constructArray(name);
+            JavaVirtualTable* CurVT = interface->virtualVT;
+            secondaryTypes[i + superVT->nbSecondaryTypes + addSuper] = CurVT;
+          }
+        } else {
+          // If the super is not a secondary type and the base class does not
+          // implement any interface, we can reuse the list of secondary types
+          // of super.
+          nbSecondaryTypes = superVT->nbSecondaryTypes;
+          secondaryTypes = superVT->secondaryTypes;
         }
       } else {
 
         // This is an Object[....] array class. It will create the list of
-        // secondary types and all array classes of the same dimension will
-        // point to this array.
+        // secondary types and all array classes of the same dimension whose
+        // base class does not have interfaces point to this array.
 
         // If we're superior than the display limit, we must make room for one
         // slot that will contain the current VT.





More information about the vmkit-commits mailing list