[vmkit-commits] [vmkit] r102929 - in /vmkit/trunk/lib/J3: Compiler/JavaJIT.cpp VMCore/JavaClass.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Mon May 3 11:14:14 PDT 2010


Author: geoffray
Date: Mon May  3 13:14:14 2010
New Revision: 102929

URL: http://llvm.org/viewvc/llvm-project?rev=102929&view=rev
Log:
Implement miranda methods.


Modified:
    vmkit/trunk/lib/J3/Compiler/JavaJIT.cpp
    vmkit/trunk/lib/J3/VMCore/JavaClass.cpp

Modified: vmkit/trunk/lib/J3/Compiler/JavaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/J3/Compiler/JavaJIT.cpp?rev=102929&r1=102928&r2=102929&view=diff
==============================================================================
--- vmkit/trunk/lib/J3/Compiler/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/J3/Compiler/JavaJIT.cpp Mon May  3 13:14:14 2010
@@ -87,11 +87,8 @@
     canBeDirect = true;
   }
 
-  // If the method is in fact a method defined in an interface,
-  // call invokeInterface instead.
-  if (meth && isInterface(meth->classDef->access)) {
-    return invokeInterface(index, true);
-  }
+  assert((!meth || !isInterface(meth->classDef->access)) &&
+          "invokevirtual on an interface");
  
   const UTF8* name = 0;
   Signdef* signature = ctpInfo->infoOfInterfaceOrVirtualMethod(index, name);

Modified: vmkit/trunk/lib/J3/VMCore/JavaClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/J3/VMCore/JavaClass.cpp?rev=102929&r1=102928&r2=102929&view=diff
==============================================================================
--- vmkit/trunk/lib/J3/VMCore/JavaClass.cpp (original)
+++ vmkit/trunk/lib/J3/VMCore/JavaClass.cpp Mon May  3 13:14:14 2010
@@ -827,10 +827,29 @@
   virtualVT = new(allocator, virtualTableSize) JavaVirtualTable(this);
 }
 
+static void computeMirandaMethods(Class* current,
+    Class* baseClass, std::vector<JavaMethod*>& mirandaMethods) {
+  for (uint32 i = 0; i < current->nbInterfaces; i++) {
+    Class* I = current->interfaces[i];
+    for (uint32 j = 0; j < I->nbVirtualMethods; j++) {
+      JavaMethod& orig = I->virtualMethods[j];
+      JavaMethod* meth = baseClass->lookupMethodDontThrow(orig.name, orig.type,
+                                                          false, true, 0);
+      if (meth == NULL) {
+        mirandaMethods.push_back(&orig);
+      }
+    }
+    computeMirandaMethods(I, baseClass, mirandaMethods);
+  }
+}
 
 void Class::readMethods(Reader& reader) {
   uint16 nbMethods = reader.readU2();
-  virtualMethods = new(classLoader->allocator, "Methods") JavaMethod[nbMethods];
+  if (isAbstract(access)) {
+    virtualMethods = new JavaMethod[nbMethods];
+  } else {
+    virtualMethods = new(classLoader->allocator, "Methods") JavaMethod[nbMethods];
+  }
   staticMethods = virtualMethods + nbMethods;
   for (int i = 0; i < nbMethods; i++) {
     uint16 access = reader.readU2();
@@ -849,6 +868,29 @@
     }
     meth->attributs = readAttributs(reader, meth->nbAttributs);
   }
+
+  if (isAbstract(access)) {
+    std::vector<JavaMethod*> mirandaMethods;
+    computeMirandaMethods(this, this, mirandaMethods);
+    uint32 size = mirandaMethods.size();
+    nbMethods += size;
+    JavaMethod* realMethods =
+      new(classLoader->allocator, "Methods") JavaMethod[nbMethods];
+    memcpy(realMethods + size, virtualMethods,
+           sizeof(JavaMethod) * (nbMethods - size));
+    nbVirtualMethods += size;
+    staticMethods = realMethods + nbVirtualMethods;
+    if (size != 0) {
+      int j = 0;
+      for (std::vector<JavaMethod*>::iterator i = mirandaMethods.begin(),
+           e = mirandaMethods.end(); i != e; i++) {
+        JavaMethod* cur = *i;
+        realMethods[j++].initialise(this, cur->name, cur->type, cur->access);
+      }
+    }
+    delete[] virtualMethods;
+    virtualMethods = realMethods;
+  }
 }
 
 void Class::readClass() {





More information about the vmkit-commits mailing list