[llvm-commits] CVS: llvm-java/lib/Compiler/VMMethod.h Compiler.cpp
Alkis Evlogimenos
alkis at cs.uiuc.edu
Thu Mar 31 11:33:48 PST 2005
Changes in directory llvm-java/lib/Compiler:
VMMethod.h updated: 1.1 -> 1.2
Compiler.cpp updated: 1.271 -> 1.272
---
Log message:
Use VMMethod in Compiler and simplify a lot of code in it (eliminate
recursive method lookups for example).
---
Diffs of the changes: (+111 -165)
Compiler.cpp | 265 ++++++++++++++++++++++-------------------------------------
VMMethod.h | 11 ++
2 files changed, 111 insertions(+), 165 deletions(-)
Index: llvm-java/lib/Compiler/VMMethod.h
diff -u llvm-java/lib/Compiler/VMMethod.h:1.1 llvm-java/lib/Compiler/VMMethod.h:1.2
--- llvm-java/lib/Compiler/VMMethod.h:1.1 Wed Mar 30 23:10:29 2005
+++ llvm-java/lib/Compiler/VMMethod.h Thu Mar 31 13:33:37 2005
@@ -41,12 +41,21 @@
public:
const VMClass* getParent() const { return parent_; }
+ const Method* getMethod() const { return method_; }
Function* getFunction() const { return function_; }
+ bool isAbstract() const { return method_->isAbstract(); }
+ bool isNative() const { return method_->isNative(); }
+ bool isStatic() const { return method_->isStatic(); }
// FIXME: remove when transition is complete.
+ const std::string& getName() const { return method_->getName()->str(); }
+ const std::string& getDescriptor() const {
+ return method_->getDescriptor()->str();
+ }
std::string getNameAndDescriptor() const {
- return method_->getName()->str() + method_->getDescriptor()->str();
+ return getName() + getDescriptor();
}
+
};
} } // namespace llvm::Java
Index: llvm-java/lib/Compiler/Compiler.cpp
diff -u llvm-java/lib/Compiler/Compiler.cpp:1.271 llvm-java/lib/Compiler/Compiler.cpp:1.272
--- llvm-java/lib/Compiler/Compiler.cpp:1.271 Thu Mar 31 11:42:28 2005
+++ llvm-java/lib/Compiler/Compiler.cpp Thu Mar 31 13:33:37 2005
@@ -64,10 +64,9 @@
Locals locals_;
OperandStack opStack_;
Function *getVtable_, *setVtable_, *throw_, *isInstanceOf_,
- *memcpy_, *memset_;
+ *memcpy_, *memset_, *staticInit_;
- typedef SetVector<Function*> FunctionSet;
- FunctionSet toCompileFunctions_;
+ SetVector<const VMMethod*> toCompileMethods_;
/// This class contains the vtable of a class, a vector with the
/// vtables of its super classes (with the class higher in the
@@ -121,6 +120,10 @@
"llvm.memset", Type::VoidTy,
PointerType::get(Type::SByteTy),
Type::UByteTy, Type::ULongTy, Type::UIntTy, NULL);
+ staticInit_ =
+ module_->getOrInsertFunction(LLVM_JAVA_STATIC_INIT, Type::VoidTy, NULL);
+ BasicBlock* staticInitBB = new BasicBlock("entry", staticInit_);
+ new ReturnInst(NULL, staticInitBB);
}
private:
@@ -134,10 +137,10 @@
/// Schedule a method for compilation. Returns true if this is the
/// first time this function was scheduled.
- bool scheduleFunction(Function* function) {
- if (toCompileFunctions_.insert(function)) {
- DEBUG(std::cerr << "Scheduling function: " << function->getName()
- << " for compilation\n");
+ bool scheduleMethod(const VMMethod* method) {
+ if (toCompileMethods_.insert(method)) {
+ DEBUG(std::cerr << "Scheduling function: "
+ << method->getFunction()->getName() << " for compilation\n");
return true;
}
return false;
@@ -181,6 +184,8 @@
// Get class information for java/lang/String.
const VMClass* clazz = resolver_->getClass("java/lang/String");
+ emitStaticInitializers(clazz);
+
const VTableInfo* vi = getVTableInfoGeneric(clazz);
// Install the vtable pointer.
@@ -191,22 +196,21 @@
new CallInst(setVtable_, objBase, vtable, "", ip);
// Initialize it: call java/lang/String/<init>(byte[],int)
- Method* method = getMethod("java/lang/String/<init>([BI)V");
- Function* function = getFunction(method);
- scheduleFunction(function);
+ const VMMethod* method = clazz->getMethod("<init>([BI)V");
+ scheduleMethod(method);
params.reserve(3);
params.clear();
params.push_back(objBase);
params.push_back(new CastInst(arrayRef, resolver_->getObjectBaseType(), TMP, ip));
params.push_back(ConstantSInt::get(Type::IntTy, 0));
- new CallInst(function, params, "", ip);
+ new CallInst(method->getFunction(), params, "", ip);
}
/// Returns the type of the Java string descriptor for JNI.
- const Type* getJNIType(ConstantUtf8* descr) {
+ const Type* getJNIType(const std::string& descr) {
unsigned i = 0;
- return getJNITypeHelper(descr->str(), i);
+ return getJNITypeHelper(descr, i);
}
const Type* getJNITypeHelper(const std::string& descr, unsigned& i) {
@@ -303,16 +307,11 @@
if (!method->isStatic() &&
!method->isPrivate() &&
method->getName()->str()[0] != '<') {
- std::string methodDescr =
- method->getName()->str() +
- method->getDescriptor()->str();
-
- std::string funcName = "java/lang/Object/" + methodDescr;
- const FunctionType* funcTy = cast<FunctionType>(
- resolver_->getType(method->getDescriptor()->str(), true));
+ const std::string& methodDescr =
+ method->getName()->str() + method->getDescriptor()->str();
- Function* vfun = module_->getOrInsertFunction(funcName, funcTy);
- scheduleFunction(vfun);
+ const VMMethod* method = clazz->getMethod(methodDescr);
+ scheduleMethod(method);
unsigned& index = vi.m2iMap[methodDescr];
if (!index) {
@@ -320,8 +319,8 @@
elements.resize(index + 1, NULL);
init.resize(index + 1, NULL);
}
- elements[index] = vfun->getType();
- init[index] = vfun;
+ elements[index] = method->getFunction()->getType();
+ init[index] = method->getFunction();
}
}
@@ -588,24 +587,19 @@
const std::string& methodDescr =
method->getName()->str() + method->getDescriptor()->str();
- std::string funcName = className + '/' + methodDescr;
-
- const FunctionType* funcTy = cast<FunctionType>(
- resolver_->getType(method->getDescriptor()->str(), true));
- llvm::Constant* vfun = NULL;
+ const VMMethod* method = clazz->getMethod(methodDescr);
+ llvm::Constant* vf = method->getFunction();
if (clazz->isInterface() || method->isAbstract())
- vfun = llvm::Constant::getNullValue(PointerType::get(funcTy));
- else {
- vfun = module_->getOrInsertFunction(funcName, funcTy);
- scheduleFunction(cast<Function>(vfun));
- }
+ vf = llvm::Constant::getNullValue(method->getFunction()->getType());
+ else
+ scheduleMethod(method);
unsigned& index = vi.m2iMap[methodDescr];
if (!index) {
index = init.size();
init.resize(index + 1);
}
- init[index] = vfun;
+ init[index] = vf;
}
}
@@ -790,38 +784,40 @@
/// Compiles the passed method only (it does not compile any
/// callers or methods of objects it creates).
- Function* compileMethodOnly(const std::string& classMethodDesc) {
- Method* method = getMethod(classMethodDesc);
- const std::string& className =
- method->getParent()->getThisClass()->getName()->str();
- class_ = resolver_->getClass(className);
+ void compileMethodOnly(const VMMethod* method) {
+ class_ = method->getParent();
- Function* function = getFunction(method);
+ Function* function = method->getFunction();
if (!function->empty()) {
- DEBUG(std::cerr << "Function: " << function->getName() << " is already compiled!\n");
- return function;
+ DEBUG(std::cerr << "Function: " << function->getName()
+ << " is already compiled!\n");
+ return;
}
+ const std::string& className =
+ class_->getClassFile()->getThisClass()->getName()->str();
+
if (method->isNative()) {
DEBUG(std::cerr << "Adding stub for natively implemented method: "
- << classMethodDesc << '\n');
+ << function->getName() << '\n');
const FunctionType* jniFuncTy =
cast<FunctionType>(getJNIType(method->getDescriptor()));
std::string funcName =
"Java_" +
getMangledString(className) + '_' +
- getMangledString(method->getName()->str());
- if (class_->getClassFile()->isNativeMethodOverloaded(*method)) {
+ getMangledString(method->getName());
+ if (class_->getClassFile()->isNativeMethodOverloaded(*method->getMethod())) {
// We need to add two underscores and a mangled argument signature
funcName += "__";
- const std::string descr = method->getDescriptor()->str();
+ const std::string descr = method->getDescriptor();
funcName += getMangledString(
std::string(descr.begin() + descr.find('(') + 1,
descr.begin() + descr.find(')')));
}
- Function* jniFunction = module_->getOrInsertFunction(funcName,jniFuncTy);
+ Function* jniFunction =
+ module_->getOrInsertFunction(funcName, jniFuncTy);
BasicBlock* bb = new BasicBlock("entry", function);
std::vector<Value*> params;
@@ -838,46 +834,47 @@
result = new CastInst(result, function->getReturnType(), TMP,bb);
new ReturnInst(result, bb);
- return function;
+ return;
}
assert (!method->isAbstract() && "Trying to compile an abstract method!");
// HACK: skip most of the class libraries.
- if ((classMethodDesc.find("java/") == 0 &&
- classMethodDesc.find("java/lang/Object") != 0 &&
- (classMethodDesc.find("java/lang/Throwable") != 0 ||
- classMethodDesc.find("java/lang/Throwable$StaticData/<cl") == 0) &&
- classMethodDesc.find("java/lang/Exception") != 0 &&
- classMethodDesc.find("java/lang/IllegalArgumentException") != 0 &&
- classMethodDesc.find("java/lang/IllegalStateException") != 0 &&
- classMethodDesc.find("java/lang/IndexOutOfBoundsException") != 0 &&
- classMethodDesc.find("java/lang/RuntimeException") != 0 &&
- classMethodDesc.find("java/lang/Math") != 0 &&
- classMethodDesc.find("java/lang/Number") != 0 &&
- classMethodDesc.find("java/lang/Byte") != 0 &&
- classMethodDesc.find("java/lang/Float") != 0 &&
- classMethodDesc.find("java/lang/Integer") != 0 &&
- classMethodDesc.find("java/lang/Long") != 0 &&
- classMethodDesc.find("java/lang/Short") != 0 &&
- (classMethodDesc.find("java/lang/String") != 0 ||
- classMethodDesc.find("java/lang/String/<cl") == 0) &&
- classMethodDesc.find("java/lang/StringBuffer") != 0 &&
- classMethodDesc.find("java/lang/System") != 0 &&
- classMethodDesc.find("java/lang/VMSystem") != 0 &&
- (classMethodDesc.find("java/util/") != 0 ||
- classMethodDesc.find("java/util/Locale/<cl") == 0 ||
- classMethodDesc.find("java/util/ResourceBundle/<cl") == 0 ||
- classMethodDesc.find("java/util/Calendar/<cl") == 0)) ||
- (classMethodDesc.find("gnu/") == 0)) {
+ const std::string& funcName = function->getName();
+ if ((funcName.find("java/") == 0 &&
+ funcName.find("java/lang/Object") != 0 &&
+ (funcName.find("java/lang/Throwable") != 0 ||
+ funcName.find("java/lang/Throwable$StaticData/<cl") == 0) &&
+ funcName.find("java/lang/Exception") != 0 &&
+ funcName.find("java/lang/IllegalArgumentException") != 0 &&
+ funcName.find("java/lang/IllegalStateException") != 0 &&
+ funcName.find("java/lang/IndexOutOfBoundsException") != 0 &&
+ funcName.find("java/lang/RuntimeException") != 0 &&
+ funcName.find("java/lang/Math") != 0 &&
+ funcName.find("java/lang/Number") != 0 &&
+ funcName.find("java/lang/Byte") != 0 &&
+ funcName.find("java/lang/Float") != 0 &&
+ funcName.find("java/lang/Integer") != 0 &&
+ funcName.find("java/lang/Long") != 0 &&
+ funcName.find("java/lang/Short") != 0 &&
+ (funcName.find("java/lang/String") != 0 ||
+ funcName.find("java/lang/String/<cl") == 0) &&
+ funcName.find("java/lang/StringBuffer") != 0 &&
+ funcName.find("java/lang/System") != 0 &&
+ funcName.find("java/lang/VMSystem") != 0 &&
+ (funcName.find("java/util/") != 0 ||
+ funcName.find("java/util/Locale/<cl") == 0 ||
+ funcName.find("java/util/ResourceBundle/<cl") == 0 ||
+ funcName.find("java/util/Calendar/<cl") == 0)) ||
+ (funcName.find("gnu/") == 0)) {
DEBUG(std::cerr << "Skipping compilation of method: "
- << classMethodDesc << '\n');
- return function;
+ << funcName << '\n');
+ return;
}
- DEBUG(std::cerr << "Compiling method: " << classMethodDesc << '\n');
+ DEBUG(std::cerr << "Compiling method: " << funcName << '\n');
- Java::CodeAttribute* codeAttr = method->getCodeAttribute();
+ Java::CodeAttribute* codeAttr = method->getMethod()->getCodeAttribute();
opStackDepthMap_.clear();
bbBuilder_.reset(new BasicBlockBuilder(function, codeAttr));
@@ -962,11 +959,8 @@
else
++bb;
- DEBUG(std::cerr << "Finished compilation of method: "
- << classMethodDesc << '\n');
+ DEBUG(std::cerr << "Finished compilation of method: "<< funcName << '\n');
// DEBUG(function->dump());
-
- return function;
}
/// Emits static initializers for this class if not done already.
@@ -982,9 +976,7 @@
if (const VMClass* superClass = clazz->getSuperClass())
emitStaticInitializers(superClass);
- Function* hook = module_->getOrInsertFunction(LLVM_JAVA_STATIC_INIT,
- Type::VoidTy, 0);
- Instruction* I = hook->front().getTerminator();
+ Instruction* I = staticInit_->front().getTerminator();
assert(I && LLVM_JAVA_STATIC_INIT " should have a terminator!");
// Create constant strings for this class.
@@ -993,95 +985,38 @@
initializeString(clazz->getConstant(i), s->getValue()->str(), I);
// Call its class initialization method if it exists.
- if (const Method* method = classfile->getMethod("<clinit>()V")) {
- const std::string& functionName =
- classfile->getThisClass()->getName()->str() + '/' +
- method->getName()->str() + method->getDescriptor()->str();
- Function* init =
- module_->getOrInsertFunction(functionName, Type::VoidTy, 0);
-
+ if (const VMMethod* method = clazz->getMethod("<clinit>()V")) {
// Insert a call to it right before the terminator of the only
// basic block in llvm_java_static_init.
- bool inserted = scheduleFunction(init);
+ bool inserted = scheduleMethod(method);
assert(inserted && "Class initialization method already called!");
- new CallInst(init, "", I);
+ new CallInst(method->getFunction(), "", I);
}
}
}
- /// Returns the llvm::Function corresponding to the specified
- /// llvm::Java::Method.
- Function* getFunction(Method* method) {
- const ClassFile* clazz = method->getParent();
-
- const FunctionType* funcTy = cast<FunctionType>(
- resolver_->getType(method->getDescriptor()->str(),
- !method->isStatic()));
- std::string funcName =
- clazz->getThisClass()->getName()->str() + '/' +
- method->getName()->str() + method->getDescriptor()->str();
-
- Function* function = module_->getOrInsertFunction(funcName, funcTy);
-
- return function;
- }
-
- /// Returns the llvm::Java::Method given a
- /// llvm::Java::ClassMethodRef.
- Method* getMethod(ConstantMethodRef* methodRef) {
- return getMethod(methodRef->getClass()->getName()->str() + '/' +
- methodRef->getNameAndType()->getName()->str() +
- methodRef->getNameAndType()->getDescriptor()->str());
- }
-
- /// Returns the llvm::Java::Method given a <class,method>
- /// descriptor.
- Method* getMethod(const std::string& classMethodDesc) {
- unsigned slash = classMethodDesc.rfind('/', classMethodDesc.find('('));
- std::string className = classMethodDesc.substr(0, slash);
- std::string methodNameAndDescr = classMethodDesc.substr(slash+1);
-
- while (true) {
- const ClassFile* classfile = ClassFile::get(className);
- emitStaticInitializers(resolver_->getClass(className));
-
- Method* method = classfile->getMethod(methodNameAndDescr);
- if (method)
- return method;
-
- if (!classfile->getSuperClass())
- break;
-
- className = classfile->getSuperClass()->getName()->str();
- }
-
- throw InvocationTargetException("Method " + methodNameAndDescr +
- " not found in class " + className);
- }
-
public:
/// Compiles the specified method given a <class,method>
/// descriptor and the transitive closure of all methods
/// (possibly) called by it.
- Function* compileMethod(const std::string& classMethodDesc) {
- // Initialize the static initializer function.
- Function* staticInit =
- module_->getOrInsertFunction(LLVM_JAVA_STATIC_INIT, Type::VoidTy, 0);
- BasicBlock* staticInitBB = new BasicBlock("entry", staticInit);
- new ReturnInst(NULL, staticInitBB);
+ const VMMethod* compileMethod(const std::string& className,
+ const std::string& methodDesc) {
+ // Load the class.
+ const VMClass* clazz = resolver_->getClass(className);
+ emitStaticInitializers(clazz);
- // Create the method requested.
- Function* function = getFunction(getMethod(classMethodDesc));
- scheduleFunction(function);
+ // Find the method.
+ const VMMethod* method = clazz->getMethod(methodDesc);
+ scheduleMethod(method);
// Compile the transitive closure of methods called by this method.
- for (unsigned i = 0; i != toCompileFunctions_.size(); ++i) {
- Function* f = toCompileFunctions_[i];
- compileMethodOnly(f->getName());
- DEBUG(std::cerr << i+1 << '/' << toCompileFunctions_.size()
+ for (unsigned i = 0; i != toCompileMethods_.size(); ++i) {
+ const VMMethod* m = toCompileMethods_[i];
+ compileMethodOnly(m);
+ DEBUG(std::cerr << i+1 << '/' << toCompileMethods_.size()
<< " functions compiled\n");
}
- return function;
+ return method;
}
void do_aconst_null() {
@@ -1573,8 +1508,8 @@
void do_invokespecial(unsigned index) {
const VMMethod* method = class_->getMethod(index);
+ scheduleMethod(method);
Function* function = method->getFunction();
- scheduleFunction(function);
makeCall(function, getParams(function->getFunctionType()));
}
@@ -1594,7 +1529,7 @@
new ReturnInst(NULL, new BasicBlock("entry", function));
}
else
- scheduleFunction(function);
+ scheduleMethod(method);
makeCall(function, getParams(function->getFunctionType()));
}
@@ -1831,14 +1766,16 @@
m->addLibrary("jrt");
Compiler c(m.get());
- Function* main = c.compileMethod(className + "/main([Ljava/lang/String;)V");
+ const VMMethod* main =
+ c.compileMethod(className, "main([Ljava/lang/String;)V");
+
Function* javaMain = m->getOrInsertFunction
("llvm_java_main", Type::VoidTy,
Type::IntTy, PointerType::get(PointerType::get(Type::SByteTy)), NULL);
BasicBlock* bb = new BasicBlock("entry", javaMain);
- const FunctionType* mainTy = main->getFunctionType();
- new CallInst(main,
+ const FunctionType* mainTy = main->getFunction()->getFunctionType();
+ new CallInst(main->getFunction(),
// FIXME: Forward correct params from llvm_java_main
llvm::Constant::getNullValue(mainTy->getParamType(0)),
"",
More information about the llvm-commits
mailing list