[llvm-commits] CVS: llvm-java/lib/Compiler/VMMethod.h VMMethod.cpp VMClass.h VMClass.cpp Compiler.cpp

Alkis Evlogimenos alkis at cs.uiuc.edu
Wed Mar 30 21:10:40 PST 2005



Changes in directory llvm-java/lib/Compiler:

VMMethod.h added (r1.1)
VMMethod.cpp added (r1.1)
VMClass.h updated: 1.23 -> 1.24
VMClass.cpp updated: 1.28 -> 1.29
Compiler.cpp updated: 1.268 -> 1.269
---
Log message:

Add VMMethod class. This class will behave for methods like VMField
does for fields This allows for the complete resolution of the
constant pool table and eventually will aid with the removal of the
VTableInfo class from Compiler.


---
Diffs of the changes:  (+184 -67)

 Compiler.cpp |   87 ++++++++++++++---------------------------------------------
 VMClass.cpp  |   63 ++++++++++++++++++++++++++++++++++++++++++
 VMClass.h    |    8 ++++-
 VMMethod.cpp |   39 ++++++++++++++++++++++++++
 VMMethod.h   |   54 ++++++++++++++++++++++++++++++++++++
 5 files changed, 184 insertions(+), 67 deletions(-)


Index: llvm-java/lib/Compiler/VMMethod.h
diff -c /dev/null llvm-java/lib/Compiler/VMMethod.h:1.1
*** /dev/null	Wed Mar 30 23:10:39 2005
--- llvm-java/lib/Compiler/VMMethod.h	Wed Mar 30 23:10:29 2005
***************
*** 0 ****
--- 1,54 ----
+ //===-- VMMethod.h - Compiler representation of a Java method ---*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file contains the declaration of the Method class that represents a
+ // compile time representation of a Java class method (java.lang.Method).
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef LLVM_JAVA_VMMETHOD_H
+ #define LLVM_JAVA_VMMETHOD_H
+ 
+ #include <llvm/Java/ClassFile.h>
+ 
+ namespace llvm {
+ 
+   class Function;
+   class FunctionType;
+ 
+ }
+ 
+ namespace llvm { namespace Java {
+ 
+   class VMClass;
+ 
+   class VMMethod {
+     const VMClass* parent_;
+     const Method* method_;
+     Function* function_;
+ 
+     friend class VMClass;
+     // Interface for VMClass.
+ 
+     // Create statically bound method reference.
+     VMMethod(const VMClass* parent, const Method* method);
+ 
+   public:
+     const VMClass* getParent() const { return parent_; }
+     Function* getFunction() const { return function_; }
+ 
+     // FIXME: remove when transition is complete.
+     std::string getNameAndDescriptor() const {
+       return method_->getName()->str() + method_->getDescriptor()->str();
+     }
+   };
+ 
+ } } // namespace llvm::Java
+ 
+ #endif//LLVM_JAVA_VMMETHOD_H


Index: llvm-java/lib/Compiler/VMMethod.cpp
diff -c /dev/null llvm-java/lib/Compiler/VMMethod.cpp:1.1
*** /dev/null	Wed Mar 30 23:10:40 2005
--- llvm-java/lib/Compiler/VMMethod.cpp	Wed Mar 30 23:10:29 2005
***************
*** 0 ****
--- 1,39 ----
+ //===-- VMMethod.cpp - Compiler representation of a Java method -*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file contains the implementation of the Method class that represents a
+ // compile time representation of a Java class method (java.lang.Method).
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "VMMethod.h"
+ #include "Resolver.h"
+ #include "VMClass.h"
+ #include <llvm/Function.h>
+ #include <llvm/DerivedTypes.h>
+ 
+ using namespace llvm;
+ using namespace llvm::Java;
+ 
+ VMMethod::VMMethod(const VMClass* parent, const Method* method)
+   : parent_(parent),
+     method_(method)
+ {
+   const std::string& methodName = method_->getName()->str();
+   const std::string& methodDescriptor = method_->getDescriptor()->str();
+   Resolver* resolver = parent_->getResolver();
+   const FunctionType* functionType = cast<FunctionType>(
+     resolver->getType(methodDescriptor, !method_->isStatic()));
+   const std::string& className =
+     parent_->getClassFile()->getThisClass()->getName()->str();
+   const std::string& functionName =
+     className + '/' + methodName + methodDescriptor;
+   Module* module = resolver->getModule();
+   function_ = module->getOrInsertFunction(functionName, functionType);
+ }


Index: llvm-java/lib/Compiler/VMClass.h
diff -u llvm-java/lib/Compiler/VMClass.h:1.23 llvm-java/lib/Compiler/VMClass.h:1.24
--- llvm-java/lib/Compiler/VMClass.h:1.23	Wed Mar 30 21:19:27 2005
+++ llvm-java/lib/Compiler/VMClass.h	Wed Mar 30 23:10:29 2005
@@ -16,6 +16,7 @@
 #define LLVM_JAVA_VMCLASS_H
 
 #include "VMField.h"
+#include "VMMethod.h"
 #include <llvm/Constant.h>
 #include <llvm/Module.h>
 #include <llvm/Type.h>
@@ -40,14 +41,18 @@
     unsigned interfaceIndex_;
     typedef std::map<std::string, VMField> FieldMap;
     FieldMap fieldMap_;
+    typedef std::map<std::string, VMMethod> MethodMap;
+    MethodMap methodMap_;
     mutable std::vector<void*> resolvedConstantPool_;
     std::vector<const VMClass*> superClasses_;
     std::vector<const VMClass*> interfaces_;
     std::vector<const VMField*> memberFields_;
 
     void computeLayout();
+    void computeClassRecord();
     const VMField* lookupField(const std::string& name) const;
-
+    const VMMethod* lookupMethod(const std::string& name) const;
+    
     friend class Resolver;
 
     // Resolver interface.
@@ -90,6 +95,7 @@
     llvm::Constant* getConstant(unsigned index) const;
     const VMClass* getClass(unsigned index) const;
     const VMField* getField(unsigned index) const;
+    const VMMethod* getMethod(unsigned index) const;
   };
 
 } } // namespace llvm::Java


Index: llvm-java/lib/Compiler/VMClass.cpp
diff -u llvm-java/lib/Compiler/VMClass.cpp:1.28 llvm-java/lib/Compiler/VMClass.cpp:1.29
--- llvm-java/lib/Compiler/VMClass.cpp:1.28	Wed Mar 30 21:22:58 2005
+++ llvm-java/lib/Compiler/VMClass.cpp	Wed Mar 30 23:10:29 2005
@@ -90,7 +90,33 @@
       return &it->second;
   }
 
-  return NULL;
+  assert(0 && "Field not found!");
+  abort();
+}
+
+const VMMethod* VMClass::lookupMethod(const std::string& name) const
+{
+  MethodMap::const_iterator it = methodMap_.find(name);
+  if (it != methodMap_.end())
+    return &it->second;
+
+  if (isInterface())
+    for (unsigned i = 0, e = getNumInterfaces(); i != e; ++i) {
+      const VMClass* interface = getInterface(i);
+      it = interface->methodMap_.find(name);
+      if (it != interface->methodMap_.end())
+        return &it->second;
+    }
+  else
+    for (unsigned i = 0, e = getNumSuperClasses(); i != e; ++i) {
+      const VMClass* superClass = getSuperClass(i);
+      it = superClass->methodMap_.find(name);
+      if (it != superClass->methodMap_.end())
+        return &it->second;
+    }
+
+  assert(0 && "Method not found!");
+  abort();
 }
 
 void VMClass::computeLayout()
@@ -137,6 +163,19 @@
   type_ = PointerType::get(layoutType_);
 }
 
+void VMClass::computeClassRecord()
+{
+  if (classFile_) {
+    const Methods& methods = classFile_->getMethods();
+    for (unsigned i = 0, e = methods.size(); i != e; ++i) {
+      Method* method = methods[i];
+      const std::string& name =
+        method->getName()->str() + method->getDescriptor()->str();
+      methodMap_.insert(std::make_pair(name, VMMethod(this, method)));
+    }
+  }
+}
+
 void VMClass::link()
 {
   // Primitive classes require no linking.
@@ -195,6 +234,7 @@
   }
 
   computeLayout();
+  computeClassRecord();
 
   assert(!isa<OpaqueType>(getLayoutType()) &&"Class not initialized properly!");
 }
@@ -282,3 +322,24 @@
 
   return static_cast<const VMField*>(resolvedConstantPool_[index]);
 }
+
+const VMMethod* VMClass::getMethod(unsigned index) const
+{
+  assert(classFile_ && "No constant pool!");
+  assert((dynamic_cast<ConstantMethodRef*>(classFile_->getConstant(index)) ||
+          dynamic_cast<ConstantInterfaceMethodRef*>(classFile_->getConstant(index))) &&
+         "Not an index to a method reference!");
+
+  // If we haven't resolved this constant already, do so now.
+  if (!resolvedConstantPool_[index]) {
+    ConstantMemberRef* jc = classFile_->getConstantMemberRef(index);
+    const VMClass* clazz = getClass(jc->getClassIndex());
+    ConstantNameAndType* ntc = jc->getNameAndType();
+    const std::string& name = ntc->getName()->str();
+    const std::string& descriptor = ntc->getDescriptor()->str();
+    resolvedConstantPool_[index] =
+      const_cast<VMMethod*>(clazz->lookupMethod(name + descriptor));
+  }
+
+  return static_cast<const VMMethod*>(resolvedConstantPool_[index]);
+}


Index: llvm-java/lib/Compiler/Compiler.cpp
diff -u llvm-java/lib/Compiler/Compiler.cpp:1.268 llvm-java/lib/Compiler/Compiler.cpp:1.269
--- llvm-java/lib/Compiler/Compiler.cpp:1.268	Wed Mar 30 23:08:47 2005
+++ llvm-java/lib/Compiler/Compiler.cpp	Wed Mar 30 23:10:29 2005
@@ -1564,24 +1564,12 @@
     }
 
     void do_invokevirtual(unsigned index) {
-      ConstantMethodRef* methodRef =
-        class_->getClassFile()->getConstantMethodRef(index);
-      ConstantNameAndType* nameAndType = methodRef->getNameAndType();
-
-      const std::string& className = methodRef->getClass()->getName()->str();
-
-      const VMClass* clazz =
-        class_->getClass(methodRef->getClassIndex());
+      const VMMethod* method = class_->getMethod(index);
+      const VMClass* clazz = method->getParent();
       const VTableInfo* vi = getVTableInfoGeneric(clazz);
 
-      const std::string& methodDescr =
-        nameAndType->getName()->str() +
-        nameAndType->getDescriptor()->str();
-
-      const FunctionType* funTy = cast<FunctionType>(
-        resolver_->getType(nameAndType->getDescriptor()->str(), true));
-
-      std::vector<Value*> params(getParams(funTy));
+      Function* function = method->getFunction();
+      std::vector<Value*> params(getParams(function->getFunctionType()));
 
       Value* objRef = params.front();
       objRef = new CastInst(objRef, clazz->getType(), "this", currentBB_);
@@ -1589,48 +1577,30 @@
         new CastInst(objRef, resolver_->getObjectBaseType(), TMP, currentBB_);
       Value* vtable = new CallInst(getVtable_, objBase, TMP, currentBB_);
       vtable = new CastInst(vtable, vi->vtable->getType(),
-                            className + ".vtable", currentBB_);
+                            clazz->getName() + ".vtable", currentBB_);
       std::vector<Value*> indices(1, ConstantUInt::get(Type::UIntTy, 0));
-      assert(vi->m2iMap.find(methodDescr) != vi->m2iMap.end() &&
+      assert(vi->m2iMap.find(method->getNameAndDescriptor()) != vi->m2iMap.end() &&
              "could not find slot for virtual function!");
-      unsigned vSlot = vi->m2iMap.find(methodDescr)->second;
+      unsigned vSlot = vi->m2iMap.find(method->getNameAndDescriptor())->second;
       indices.push_back(ConstantUInt::get(Type::UIntTy, vSlot));
       Value* vfunPtr =
         new GetElementPtrInst(vtable, indices, TMP, currentBB_);
-      Value* vfun = new LoadInst(vfunPtr, className + '/' + methodDescr,
-                                 currentBB_);
+      Value* vfun = new LoadInst(vfunPtr, function->getName(), currentBB_);
 
       makeCall(vfun, params);
     }
 
     void do_invokespecial(unsigned index) {
-      ConstantMethodRef* methodRef =
-        class_->getClassFile()->getConstantMethodRef(index);
-      ConstantNameAndType* nameAndType = methodRef->getNameAndType();
-
-      const std::string& className = methodRef->getClass()->getName()->str();
-      const std::string& methodName = nameAndType->getName()->str();
-      const std::string& methodDescr =
-        methodName + nameAndType->getDescriptor()->str();
-      std::string funcName = className + '/' + methodDescr;
-      const VMClass* clazz =
-        class_->getClass(methodRef->getClassIndex());
-
-      const FunctionType* funcTy = cast<FunctionType>(
-        resolver_->getType(nameAndType->getDescriptor()->str(), true));
-      Function* function = module_->getOrInsertFunction(funcName, funcTy);
+      const VMMethod* method = class_->getMethod(index);
+      Function* function = method->getFunction();
       scheduleFunction(function);
-      makeCall(function, getParams(funcTy));
+      makeCall(function, getParams(function->getFunctionType()));
     }
 
     void do_invokestatic(unsigned index) {
-      ConstantMethodRef* methodRef =
-        class_->getClassFile()->getConstantMethodRef(index);
-      const VMClass* clazz =
-        class_->getClass(methodRef->getClassIndex());
-      emitStaticInitializers(clazz->getClassFile());
-      Method* method = getMethod(methodRef);
-      Function* function = getFunction(method);
+      const VMMethod* method = class_->getMethod(index);
+      emitStaticInitializers(method->getParent()->getClassFile());
+      Function* function = method->getFunction();
       // Intercept java/lang/System/loadLibrary() calls and add
       // library deps to the module
       if (function->getName().find(
@@ -1648,24 +1618,12 @@
     }
 
     void do_invokeinterface(unsigned index) {
-      ConstantInterfaceMethodRef* methodRef =
-        class_->getClassFile()->getConstantInterfaceMethodRef(index);
-      ConstantNameAndType* nameAndType = methodRef->getNameAndType();
-
-      const std::string& className = methodRef->getClass()->getName()->str();
-
-      const VMClass* clazz =
-        class_->getClass(methodRef->getClassIndex());
+      const VMMethod* method = class_->getMethod(index);
+      const VMClass* clazz = method->getParent();
       const VTableInfo* vi = getVTableInfoGeneric(clazz);
 
-      const std::string& methodDescr =
-        nameAndType->getName()->str() +
-        nameAndType->getDescriptor()->str();
-
-      const FunctionType* funTy = cast<FunctionType>(
-        resolver_->getType(nameAndType->getDescriptor()->str(), true));
-
-      std::vector<Value*> params(getParams(funTy));
+      Function* function = method->getFunction();
+      std::vector<Value*> params(getParams(function->getFunctionType()));
 
       Value* objRef = params.front();
       objRef = new CastInst(objRef, clazz->getType(), "this", currentBB_);
@@ -1687,20 +1645,19 @@
       Value* interfaceVTable =
         new GetElementPtrInst(interfaceVTables, indices, TMP, currentBB_);
       interfaceVTable =
-        new LoadInst(interfaceVTable, className + ".vtable", currentBB_);
+        new LoadInst(interfaceVTable, clazz->getName() + ".vtable", currentBB_);
       interfaceVTable =
         new CastInst(interfaceVTable, vi->vtable->getType(), TMP, currentBB_);
       // Get the function pointer.
-      assert(vi->m2iMap.find(methodDescr) != vi->m2iMap.end() &&
+      assert(vi->m2iMap.find(method->getNameAndDescriptor()) != vi->m2iMap.end() &&
              "could not find slot for virtual function!");
-      unsigned vSlot = vi->m2iMap.find(methodDescr)->second;
+      unsigned vSlot = vi->m2iMap.find(method->getNameAndDescriptor())->second;
       indices.resize(2);
       indices[0] = ConstantUInt::get(Type::UIntTy, 0);
       indices[1] = ConstantUInt::get(Type::UIntTy, vSlot);
       Value* vfunPtr =
         new GetElementPtrInst(interfaceVTable, indices, TMP, currentBB_);
-      Value* vfun = new LoadInst(vfunPtr, className + '/' + methodDescr,
-                                 currentBB_);
+      Value* vfun = new LoadInst(vfunPtr, function->getName(), currentBB_);
 
       makeCall(vfun, params);
     }






More information about the llvm-commits mailing list