[llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp
Alkis Evlogimenos
alkis at cs.uiuc.edu
Sat Jul 24 16:56:05 PDT 2004
Changes in directory llvm-java/lib/Compiler:
Compiler.cpp updated: 1.68 -> 1.69
---
Log message:
Implement static initializers and the getstatic and putstatic java
opcodes.
---
Diffs of the changes: (+81 -18)
Index: llvm-java/lib/Compiler/Compiler.cpp
diff -u llvm-java/lib/Compiler/Compiler.cpp:1.68 llvm-java/lib/Compiler/Compiler.cpp:1.69
--- llvm-java/lib/Compiler/Compiler.cpp:1.68 Sat Jul 24 18:40:14 2004
+++ llvm-java/lib/Compiler/Compiler.cpp Sat Jul 24 18:55:54 2004
@@ -233,22 +233,7 @@
const Fields& fields = cf->getFields();
for (unsigned i = 0, e = fields.size(); i != e; ++i) {
Field* field = fields[i];
- if (field->isStatic()) {
- llvm::Constant* init = NULL;
- if (ConstantValueAttribute* cv =
- field->getConstantValueAttribute())
- init = getConstant(cv->getValue());
-
- new GlobalVariable(getType(field->getDescriptor()),
- field->isFinal(),
- (field->isPrivate() & bool(init) ?
- GlobalVariable::InternalLinkage :
- GlobalVariable::ExternalLinkage),
- init,
- className + '/' + field->getName()->str(),
- module_);
- }
- else
+ if (!field->isStatic())
elements.push_back(getType(field->getDescriptor()));
}
PATypeHolder holder = newType;
@@ -271,6 +256,21 @@
return locals_[index];
}
+ GlobalVariable* getStaticField(unsigned index) {
+ ConstantFieldRef* fieldRef =
+ (ConstantFieldRef*)(cf_->getConstantPool()[index]);
+ ConstantNameAndType* nameAndType = fieldRef->getNameAndType();
+
+ std::string globalName =
+ fieldRef->getClass()->getName()->str() + '/' +
+ nameAndType->getName()->str();
+
+ GlobalVariable* global = module_->getGlobalVariable
+ (globalName, getType(nameAndType->getDescriptor()));
+
+ return global;
+ }
+
Function* compileMethodOnly(const std::string& classMethodDesc) {
DEBUG(std::cerr << "Compiling method: " << classMethodDesc << '\n');
@@ -315,6 +315,53 @@
return function;
}
+ void emitStaticInitializers(const ClassFile* classfile) {
+ const Method* method = classfile->getMethod("<clinit>()V");
+ if (!method)
+ return;
+
+ std::string name = classfile->getThisClass()->getName()->str();
+ name += '/';
+ name += method->getName()->str();
+ name += method->getDescriptor()->str();
+
+ Function* hook =
+ module_->getOrInsertFunction("llvm_java_static_init",
+ Type::VoidTy, 0);
+ Function* init =
+ module_->getOrInsertFunction(name, Type::VoidTy, 0);
+
+ // if this is the first time we scheduled this function
+ // for compilation insert a call to it right before the
+ // terminator of the only basic block in
+ // llvm_java_static_init
+ if (toCompileFunctions_.insert(init)) {
+ assert(hook->front().getTerminator() &&
+ "llvm_java_static_init should have a terminator!");
+ new CallInst(init, "", hook->front().getTerminator());
+ // we also create the global variables of this class
+ const Fields& fields = classfile->getFields();
+ for (unsigned i = 0, e = fields.size(); i != e; ++i) {
+ Field* field = fields[i];
+ if (field->isStatic()) {
+ llvm::Constant* init = NULL;
+ if (ConstantValueAttribute* cv =
+ field->getConstantValueAttribute())
+ init = getConstant(cv->getValue());
+
+ new GlobalVariable(getType(field->getDescriptor()),
+ field->isFinal(),
+ (field->isPrivate() & bool(init) ?
+ GlobalVariable::InternalLinkage :
+ GlobalVariable::ExternalLinkage),
+ init,
+ classfile->getThisClass()->getName()->str() + '/' + field->getName()->str(),
+ module_);
+ }
+ }
+ }
+ }
+
std::pair<ClassFile*, Method*>
findClassAndMethod(const std::string& classMethodDesc) {
unsigned slash = classMethodDesc.find('/');
@@ -322,7 +369,9 @@
std::string methodNameAndDescr = classMethodDesc.substr(slash+1);
ClassFile* classfile = ClassFile::getClassFile(className);
+ emitStaticInitializers(classfile);
Method* method = classfile->getMethod(methodNameAndDescr);
+
if (!method)
throw InvocationTargetException(
"Method " + methodNameAndDescr +
@@ -336,10 +385,22 @@
Function* compileMethod(Module& module,
const std::string& classMethodDesc) {
module_ = &module;
+ // 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);
+
+ // insert an opaque type for java.lang.Object. This is
+ // defined in runtime.ll
c2tMap_.insert(std::make_pair("java/lang/Object",
OpaqueType::get()));
module.addTypeName("java/lang/Object", c2tMap_["java/lang/Object"]);
+
+ // compile the method requested
Function* function = compileMethodOnly(classMethodDesc);
+ // compile all other methods called by this method recursively
for (unsigned i = 0; i != toCompileFunctions_.size(); ++i) {
Function* f = toCompileFunctions_[i];
compileMethodOnly(f->getName());
@@ -695,11 +756,13 @@
}
void do_getstatic(unsigned bcI, unsigned index) {
- assert(0 && "not implemented");
+ Value* v = new LoadInst(getStaticField(index), TMP, getBBAt(bcI));
+ opStack_.push(v);
}
void do_putstatic(unsigned bcI, unsigned index) {
- assert(0 && "not implemented");
+ Value* v = opStack_.top(); opStack_.pop();
+ new StoreInst(v, getStaticField(index), getBBAt(bcI));
}
void do_getfield(unsigned bcI, unsigned index) {
More information about the llvm-commits
mailing list