[llvm-commits] CVS: llvm-java/lib/Compiler/VMClass.h VMClass.cpp Resolver.cpp Compiler.cpp
Alkis Evlogimenos
alkis at cs.uiuc.edu
Fri Apr 1 10:31:37 PST 2005
Changes in directory llvm-java/lib/Compiler:
VMClass.h updated: 1.26 -> 1.27
VMClass.cpp updated: 1.34 -> 1.35
Resolver.cpp updated: 1.11 -> 1.12
Compiler.cpp updated: 1.273 -> 1.274
---
Log message:
Merge VTableInfo in VMClass and update the compiler to use it. Now all
classes have a class record (what we previously called vtable). As a
result a lot of code is greatly simplified in the compiler and the
internals of building the class record are now in VMClass.
---
Diffs of the changes: (+310 -642)
Compiler.cpp | 718 +++++++----------------------------------------------------
Resolver.cpp | 8
VMClass.cpp | 211 ++++++++++++++++-
VMClass.h | 15 +
4 files changed, 310 insertions(+), 642 deletions(-)
Index: llvm-java/lib/Compiler/VMClass.h
diff -u llvm-java/lib/Compiler/VMClass.h:1.26 llvm-java/lib/Compiler/VMClass.h:1.27
--- llvm-java/lib/Compiler/VMClass.h:1.26 Fri Apr 1 01:25:17 2005
+++ llvm-java/lib/Compiler/VMClass.h Fri Apr 1 12:31:25 2005
@@ -47,9 +47,17 @@
std::vector<const VMClass*> superClasses_;
std::vector<const VMClass*> interfaces_;
std::vector<const VMField*> memberFields_;
+ std::vector<const VMMethod*> dynamicallyBoundMethods_;
+ llvm::Constant* classRecord_;
void computeLayout();
void computeClassRecord();
+
+ llvm::Constant* buildSuperClassRecords() const;
+ llvm::Constant* buildInterfaceClassRecord(const VMClass* interface) const;
+ llvm::Constant* buildInterfaceClassRecords() const;
+ llvm::Constant* buildClassTypeInfo() const;
+
const VMField* lookupField(const std::string& name) const;
const VMMethod* lookupMethod(const std::string& nameAndType) const;
@@ -91,6 +99,13 @@
bool isPrimitive() const { return getType() == getLayoutType(); }
bool isInterface() const { return classFile_ && classFile_->isInterface(); }
int getInterfaceIndex() const { return interfaceIndex_; }
+ unsigned getNumDynamicallyBoundMethods() const {
+ return dynamicallyBoundMethods_.size();
+ }
+ const VMMethod* getDynamicallyBoundMethod(unsigned i) const {
+ return dynamicallyBoundMethods_[i];
+ }
+ llvm::Constant* getClassRecord() const { return classRecord_; }
llvm::Constant* getConstant(unsigned index) const;
const VMClass* getClass(unsigned index) const;
Index: llvm-java/lib/Compiler/VMClass.cpp
diff -u llvm-java/lib/Compiler/VMClass.cpp:1.34 llvm-java/lib/Compiler/VMClass.cpp:1.35
--- llvm-java/lib/Compiler/VMClass.cpp:1.34 Thu Mar 31 23:00:06 2005
+++ llvm-java/lib/Compiler/VMClass.cpp Fri Apr 1 12:31:25 2005
@@ -34,7 +34,8 @@
layoutType_(OpaqueType::get()),
type_(PointerType::get(layoutType_)),
interfaceIndex_(INVALID_INTERFACE_INDEX),
- resolvedConstantPool_(classFile_->getNumConstants())
+ resolvedConstantPool_(classFile_->getNumConstants()),
+ classRecord_(NULL)
{
}
@@ -46,7 +47,8 @@
componentClass_(componentClass),
layoutType_(OpaqueType::get()),
type_(PointerType::get(layoutType_)),
- interfaceIndex_(INVALID_INTERFACE_INDEX)
+ interfaceIndex_(INVALID_INTERFACE_INDEX),
+ classRecord_(NULL)
{
}
@@ -65,7 +67,8 @@
componentClass_(NULL),
layoutType_(const_cast<Type*>(type)),
type_(type),
- interfaceIndex_(INVALID_INTERFACE_INDEX)
+ interfaceIndex_(INVALID_INTERFACE_INDEX),
+ classRecord_(NULL)
{
}
@@ -87,8 +90,7 @@
return field;
}
- assert(0 && "Field not found!");
- abort();
+ return NULL;
}
const VMMethod* VMClass::lookupMethod(const std::string& nameAndType) const
@@ -109,8 +111,7 @@
return method;
}
- assert(0 && "Method not found!");
- abort();
+ return NULL;
}
void VMClass::computeLayout()
@@ -162,17 +163,199 @@
type_ = PointerType::get(layoutType_);
}
+llvm::Constant* VMClass::buildSuperClassRecords() const
+{
+ std::vector<llvm::Constant*> init;
+ init.reserve(getNumSuperClasses());
+ for (unsigned i = 0, e = getNumSuperClasses(); i != e; ++i)
+ init.push_back(ConstantExpr::getCast(
+ getSuperClass(i)->getClassRecord(),
+ resolver_->getClassRecordPtrType()));
+
+ const ArrayType* superClassRecordsType =
+ ArrayType::get(resolver_->getClassRecordPtrType(), init.size());
+
+ return ConstantExpr::getPtrPtrFromArrayPtr(
+ new GlobalVariable(
+ superClassRecordsType,
+ true,
+ GlobalVariable::ExternalLinkage,
+ ConstantArray::get(superClassRecordsType, init),
+ getName() + "<superClassRecords>",
+ resolver_->getModule()));
+}
+
+llvm::Constant*
+VMClass::buildInterfaceClassRecord(const VMClass* interface) const
+{
+ assert(interface->isInterface() && "Must be passed an interface!");
+
+ std::vector<llvm::Constant*> init;
+ init.reserve(interface->dynamicallyBoundMethods_.size()+1);
+ // Insert a null type info for this interface.
+ init.push_back(llvm::Constant::getNullValue(resolver_->getTypeInfoType()));
+ // For each method this interface declares, find the corresponding
+ // method in this class and put it in its slot.
+ for (unsigned i = 0, e = interface->dynamicallyBoundMethods_.size();
+ i != e; ++i) {
+ assert(init.size() == i+1 && "Interface method not found in class!");
+ const VMMethod* interfaceMethod = interface->dynamicallyBoundMethods_[i];
+ for (unsigned j = 0, f = dynamicallyBoundMethods_.size(); j != f; ++j) {
+ const VMMethod* method = dynamicallyBoundMethods_[j];
+ if (method->getName() == interfaceMethod->getName() &&
+ method->getDescriptor() == interfaceMethod->getDescriptor()) {
+ init.push_back(method->getFunction());
+ break;
+ }
+ }
+ }
+
+ llvm::Constant* classRecordInit = ConstantStruct::get(init);
+
+ return ConstantExpr::getCast(
+ new GlobalVariable(
+ classRecordInit->getType(),
+ true,
+ GlobalVariable::ExternalLinkage,
+ classRecordInit,
+ getName() + '+' + interface->getName() + "<classRecord>",
+ resolver_->getModule()),
+ resolver_->getClassRecordPtrType());
+}
+
+llvm::Constant* VMClass::buildInterfaceClassRecords() const
+{
+ // This is an interface or primitive class record so it doesn't
+ // implement any interfaces. Thus the pointer to the array of
+ // implemented interfaces is null.
+ if (isInterface() || isPrimitive()) {
+ const Type* classRecordPtrPtrType =
+ PointerType::get(resolver_->getClassRecordPtrType());
+
+ return llvm::Constant::getNullValue(classRecordPtrPtrType);
+ }
+
+ // Otherwise this is a class or array class record so we have to
+ // fill in the array of implemented interfaces up the max interface
+ // index and build each individual interface class record for this
+ // class.
+ llvm::Constant* nullClassRecord =
+ llvm::Constant::getNullValue(resolver_->getClassRecordPtrType());
+ std::vector<llvm::Constant*> init(getInterfaceIndex()+1, nullClassRecord);
+
+ for (unsigned i = 0, e = getNumInterfaces(); i != e; ++i) {
+ const VMClass* interface = getInterface(i);
+ init[interface->getInterfaceIndex()] = buildInterfaceClassRecord(interface);
+ }
+
+ const ArrayType* interfaceClassRecordsType =
+ ArrayType::get(resolver_->getClassRecordPtrType(), init.size());
+
+ return ConstantExpr::getPtrPtrFromArrayPtr(
+ new GlobalVariable(
+ interfaceClassRecordsType,
+ true,
+ GlobalVariable::ExternalLinkage,
+ ConstantArray::get(interfaceClassRecordsType, init),
+ getName() + "<interfaceClassRecords>",
+ resolver_->getModule()));
+}
+
+llvm::Constant* VMClass::buildClassTypeInfo() const
+{
+ std::vector<llvm::Constant*> init;
+ init.reserve(5);
+
+ init.push_back(ConstantSInt::get(Type::IntTy, getNumSuperClasses()));
+ init.push_back(buildSuperClassRecords());
+ init.push_back(ConstantSInt::get(Type::IntTy, getInterfaceIndex()));
+ init.push_back(buildInterfaceClassRecords());
+ if (isArray())
+ init.push_back(
+ ConstantExpr::getCast(
+ ConstantExpr::getSizeOf(getComponentClass()->getType()), Type::IntTy));
+ else if (isPrimitive())
+ init.push_back(ConstantSInt::get(Type::IntTy, -2));
+ else if (isInterface())
+ init.push_back(ConstantSInt::get(Type::IntTy, -1));
+ else // A class.
+ init.push_back(ConstantSInt::get(Type::IntTy, 0));
+
+ return ConstantStruct::get(init);
+}
+
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)));
+ // Find dynamically bound methods.
+ if (!isPrimitive()) {
+ if (const VMClass* superClass = getSuperClass())
+ dynamicallyBoundMethods_ = superClass->dynamicallyBoundMethods_;
+
+ if (getClassFile()) {
+ 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();
+ const std::string& descriptor = method->getDescriptor()->str();
+
+ // If method is statically bound just create it.
+ if (method->isPrivate() || method->isStatic() || name[0] == '<')
+ methodMap_.insert(
+ std::make_pair(name + descriptor, VMMethod(this, method)));
+ // Otherwise we need to assign an index for it and update the
+ // dynamicallyBoundMethods_ vector.
+ else {
+ const VMMethod* overridenMethod = NULL;
+ for (unsigned i = 0, e = getNumDynamicallyBoundMethods();
+ i != e; ++i) {
+ const VMMethod* m = getDynamicallyBoundMethod(i);
+ if (m->getName() == name && m->getDescriptor() == descriptor)
+ overridenMethod = m;
+ }
+
+ // If this is an overriden method reuse the method index
+ // with the overriding one.
+ if (overridenMethod) {
+ int index = overridenMethod->getMethodIndex();
+ MethodMap::iterator i = methodMap_.insert(
+ std::make_pair(name + descriptor,
+ VMMethod(this, method, index))).first;
+ dynamicallyBoundMethods_[index] = &i->second;
+ }
+ // Otherwise assign it a new index.
+ else {
+ int index = dynamicallyBoundMethods_.size();
+ MethodMap::iterator i = methodMap_.insert(
+ std::make_pair(
+ name + descriptor, VMMethod(this, method, index))).first;
+ dynamicallyBoundMethods_.push_back(&i->second);
+ }
+ }
+ }
}
}
+
+ std::vector<llvm::Constant*> init;
+ init.reserve(1 + getNumDynamicallyBoundMethods());
+ init.push_back(buildClassTypeInfo());
+ for (unsigned i = 0, e = getNumDynamicallyBoundMethods(); i != e; ++i) {
+ const VMMethod* method = getDynamicallyBoundMethod(i);
+ init.push_back(
+ method->isAbstract() ?
+ llvm::Constant::getNullValue(method->getFunction()->getType()) :
+ method->getFunction());
+ }
+
+ llvm::Constant* classRecordInit = ConstantStruct::get(init);
+ resolver_->getModule()->addTypeName("classRecord." + getName(),
+ classRecordInit->getType());
+ classRecord_ = new GlobalVariable(
+ classRecordInit->getType(),
+ true,
+ GlobalVariable::ExternalLinkage,
+ classRecordInit,
+ getName() + "<classRecord>",
+ resolver_->getModule());
}
void VMClass::link()
Index: llvm-java/lib/Compiler/Resolver.cpp
diff -u llvm-java/lib/Compiler/Resolver.cpp:1.11 llvm-java/lib/Compiler/Resolver.cpp:1.12
--- llvm-java/lib/Compiler/Resolver.cpp:1.11 Thu Mar 31 01:56:28 2005
+++ llvm-java/lib/Compiler/Resolver.cpp Fri Apr 1 12:31:25 2005
@@ -66,7 +66,8 @@
StructType::get(std::vector<const Type*>(1, getTypeInfoType())));
classRecordType_ = holder.get();
- module_->addTypeName("struct.llvm_java_object_vtable", getClassRecordType());
+ module_->addTypeName("struct.llvm_java_object_class_record",
+ getClassRecordType());
classRecordPtrType_ = PointerType::get(classRecordType_);
}
@@ -169,8 +170,9 @@
}
it->second.link();
if (!it->second.isPrimitive() && !it->second.isInterface())
- module_->addTypeName(descriptor, it->second.getLayoutType());
- DEBUG(std::cerr << "Loaded class: " << descriptor << '\n');
+ module_->addTypeName("struct." + descriptor, it->second.getLayoutType());
+ DEBUG(std::cerr << "Loaded class: " << descriptor);
+ DEBUG(std::cerr << " (" << it->second.getInterfaceIndex() << ")\n");
}
return &it->second;
Index: llvm-java/lib/Compiler/Compiler.cpp
diff -u llvm-java/lib/Compiler/Compiler.cpp:1.273 llvm-java/lib/Compiler/Compiler.cpp:1.274
--- llvm-java/lib/Compiler/Compiler.cpp:1.273 Thu Mar 31 19:56:36 2005
+++ llvm-java/lib/Compiler/Compiler.cpp Fri Apr 1 12:31:25 2005
@@ -61,28 +61,12 @@
BasicBlock* currentBB_;
Locals locals_;
OperandStack opStack_;
- Function *getVtable_, *setVtable_, *throw_, *isInstanceOf_,
+ Function *getClassRecord_, *setClassRecord_, *throw_, *isInstanceOf_,
*memcpy_, *memset_;
std::vector<llvm::Constant*> classInitializers_;
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
- /// hierarchy first). It also contains a map from methods to
- /// struct indices for this class (used to index into the vtable).
- struct VTableInfo {
- VTableInfo() : vtable(NULL) { }
- GlobalVariable* vtable;
- std::vector<llvm::Constant*> superVtables;
- typedef std::map<std::string, unsigned> Method2IndexMap;
- typedef Method2IndexMap::iterator iterator;
- typedef Method2IndexMap::const_iterator const_iterator;
- Method2IndexMap m2iMap;
- };
- typedef std::map<const VMClass*, VTableInfo> Class2VTableInfoMap;
- Class2VTableInfoMap c2viMap_;
-
public:
Compiler(Module* m)
: module_(m),
@@ -97,19 +81,19 @@
NULL,
"llvm_java_JNIEnv",
module_);
- const Type* vtablePtrType = resolver_->getClassRecordPtrType();
- getVtable_ = module_->getOrInsertFunction(
- "llvm_java_get_vtable", vtablePtrType,
+ const Type* classRecordPtrType = resolver_->getClassRecordPtrType();
+ getClassRecord_ = module_->getOrInsertFunction(
+ "llvm_java_get_class_record", classRecordPtrType,
resolver_->getObjectBaseType(), NULL);
- setVtable_ = module_->getOrInsertFunction(
- "llvm_java_set_vtable", Type::VoidTy,
- resolver_->getObjectBaseType(), vtablePtrType, NULL);
+ setClassRecord_ = module_->getOrInsertFunction(
+ "llvm_java_set_class_record", Type::VoidTy,
+ resolver_->getObjectBaseType(), classRecordPtrType, NULL);
throw_ = module_->getOrInsertFunction(
"llvm_java_throw", Type::IntTy,
resolver_->getObjectBaseType(), NULL);
isInstanceOf_ = module_->getOrInsertFunction(
"llvm_java_is_instance_of", Type::IntTy,
- resolver_->getObjectBaseType(), vtablePtrType, NULL);
+ resolver_->getObjectBaseType(), classRecordPtrType, NULL);
memcpy_ = module_->getOrInsertFunction(
"llvm.memcpy", Type::VoidTy,
PointerType::get(Type::SByteTy),
@@ -148,10 +132,7 @@
// Create a new byte[] object and initialize it with the
// contents of this string constant.
Value* count = ConstantUInt::get(Type::UIntTy, str.size());
- Value* arrayRef = allocateArray(resolver_->getClass("[B"),
- &getPrimitiveArrayVTableInfo(BYTE),
- count,
- ip);
+ Value* arrayRef = allocateArray(resolver_->getClass("[B"), count, ip);
// Copy string data.
std::vector<Value*> indices;
indices.reserve(3);
@@ -181,14 +162,13 @@
const VMClass* clazz = resolver_->getClass("java/lang/String");
emitClassInitializers(clazz);
- const VTableInfo* vi = getVTableInfoGeneric(clazz);
-
- // Install the vtable pointer.
+ // Install the class record.
Value* objBase =
new CastInst(globalString, resolver_->getObjectBaseType(), TMP, ip);
- const Type* vtablePtrType = resolver_->getClassRecordPtrType();
- Value* vtable = new CastInst(vi->vtable, vtablePtrType, TMP, ip);
- new CallInst(setVtable_, objBase, vtable, "", ip);
+ const Type* classRecordPtrType = resolver_->getClassRecordPtrType();
+ Value* classRecord =
+ new CastInst(clazz->getClassRecord(), classRecordPtrType, TMP, ip);
+ new CallInst(setClassRecord_, objBase, classRecord, "", ip);
// Initialize it: call java/lang/String/<init>(byte[],int)
const VMMethod* method = clazz->getMethod("<init>([BI)V");
@@ -197,7 +177,8 @@
params.reserve(3);
params.clear();
params.push_back(objBase);
- params.push_back(new CastInst(arrayRef, resolver_->getObjectBaseType(), TMP, ip));
+ params.push_back(
+ new CastInst(arrayRef, resolver_->getObjectBaseType(), TMP, ip));
params.push_back(ConstantSInt::get(Type::IntTy, 0));
new CallInst(method->getFunction(), params, "", ip);
}
@@ -248,517 +229,6 @@
return 0; // not reached
}
- /// Initializes the VTableInfo map; in other words it adds the
- /// VTableInfo for java.lang.Object.
- bool initializeVTableInfoMap() {
- DEBUG(std::cerr << "Building VTableInfo for: java/lang/Object\n");
- const VMClass* clazz = resolver_->getClass("java/lang/Object");
- VTableInfo& vi = c2viMap_[clazz];
-
- assert(!vi.vtable && vi.m2iMap.empty() &&
- "java/lang/Object VTableInfo should not be initialized!");
-
- Type* VTtype = OpaqueType::get();
-
- std::vector<llvm::Constant*> init;
-
- // This is java/lang/Object so we must add a typeinfo struct
- // first.
-
- const Type* vtablePtrPtrType =
- PointerType::get(resolver_->getClassRecordPtrType());
- // depth
- init.push_back(llvm::ConstantSInt::get(Type::IntTy, 0));
- // superclasses vtable pointers
- init.push_back(llvm::Constant::getNullValue(vtablePtrPtrType));
- // last interface index
- init.push_back(llvm::ConstantSInt::get(Type::IntTy, -1));
- // interfaces vtable pointers
- init.push_back(llvm::Constant::getNullValue(vtablePtrPtrType));
- // the element size (0 for classes)
- init.push_back(llvm::ConstantSInt::get(Type::IntTy, 0));
-
- llvm::Constant* typeInfoInit = ConstantStruct::get(init);
- assert(typeInfoInit->getType() == resolver_->getTypeInfoType() &&
- "TypeInfo types mismatch!");
-
- // Now that we have both the type and initializer for the
- // typeinfo struct we can start adding the function pointers.
- std::vector<const Type*> elements;
- init.clear();
-
- /// First add the typeinfo struct itself.
- elements.push_back(typeInfoInit->getType());
- // Add the typeinfo block for this class.
- init.push_back(typeInfoInit);
-
- const Methods& methods = clazz->getClassFile()->getMethods();
-
- // Add member functions to the vtable.
- for (unsigned i = 0, e = methods.size(); i != e; ++i) {
- Method* method = methods[i];
- // Static methods, private instance methods and the contructor
- // are statically bound so we don't add them to the vtable.
- if (!method->isStatic() &&
- !method->isPrivate() &&
- method->getName()->str()[0] != '<') {
- const std::string& methodDescr =
- method->getName()->str() + method->getDescriptor()->str();
-
- const VMMethod* method = clazz->getMethod(methodDescr);
- scheduleMethod(method);
-
- unsigned& index = vi.m2iMap[methodDescr];
- if (!index) {
- index = elements.size();
- elements.resize(index + 1, NULL);
- init.resize(index + 1, NULL);
- }
- elements[index] = method->getFunction()->getType();
- init[index] = method->getFunction();
- }
- }
-
- PATypeHolder holder = VTtype;
- cast<OpaqueType>(VTtype)->refineAbstractTypeTo(StructType::get(elements));
-
- VTtype = holder.get();
- module_->addTypeName("java/lang/Object<vtable>", VTtype);
-
- vi.vtable = new GlobalVariable(VTtype,
- true, GlobalVariable::ExternalLinkage,
- ConstantStruct::get(init),
- "java/lang/Object<vtable>",
- module_);
- DEBUG(std::cerr << "Built VTableInfo for: java/lang/Object\n");
- return true;
- }
-
- /// Builds the super classes' vtable array for this classfile and
- /// its corresponding VTable. The direct superclass goes first in
- /// the array.
- llvm::Constant*
- buildSuperClassesVTables(const VMClass* clazz, const VTableInfo& vi) const {
- std::vector<llvm::Constant*> superVtables(vi.superVtables.size());
- for (unsigned i = 0, e = vi.superVtables.size(); i != e; ++i)
- superVtables[i] = ConstantExpr::getCast(
- vi.superVtables[i], resolver_->getClassRecordPtrType());
-
- llvm::Constant* init = ConstantArray::get(
- ArrayType::get(resolver_->getClassRecordPtrType(), superVtables.size()),
- superVtables);
-
- GlobalVariable* vtablesArray = new GlobalVariable(
- init->getType(),
- true,
- GlobalVariable::ExternalLinkage,
- init,
- clazz->getClassFile()->getThisClass()->getName()->str() +
- "<superclassesvtables>",
- module_);
-
- return ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray);
- }
-
- /// Builds an interface VTable for the specified <class,interface>
- /// pair.
- llvm::Constant* buildInterfaceVTable(const VMClass* clazz,
- const VMClass* interface) {
- DEBUG(std::cerr << "Building interface vtable: "
- << interface->getName() << " for: " << clazz->getName() << '\n');
-
- const VTableInfo& classVI = getVTableInfo(clazz);
- const VTableInfo& interfaceVI = getVTableInfo(interface);
- const Methods& methods = interface->getClassFile()->getMethods();
-
- // The size of the initializer will be 1 greater than the number
- // of methods for this interface (the first slot is the typeinfo
- // struct.
- std::vector<llvm::Constant*> init(interfaceVI.m2iMap.size()+1, NULL);
- init[0] = llvm::Constant::getNullValue(resolver_->getTypeInfoType());
-
- // For each method in this interface find the implementing
- // method in the class' VTable and add it to the appropriate
- // slot.
- for (VTableInfo::Method2IndexMap::const_iterator
- i = interfaceVI.m2iMap.begin(), e = interfaceVI.m2iMap.end();
- i != e; ++i) {
- if (!clazz->getClassFile()->isAbstract()) {
- assert(classVI.m2iMap.find(i->first) != classVI.m2iMap.end() &&
- "Interface method not found in class definition!");
- unsigned classMethodIdx = classVI.m2iMap.find(i->first)->second;
- init[i->second] = cast<ConstantStruct>(
- classVI.vtable->getInitializer())->getOperand(classMethodIdx);
- }
- else
- init[i->second] =
- llvm::Constant::getNullValue(resolver_->getClassRecordPtrType());
- }
-
- llvm::Constant* vtable = ConstantStruct::get(init);
- const std::string& globalName =
- clazz->getName() + '+' + interface->getName() + "<vtable>";
- module_->addTypeName(globalName, vtable->getType());
-
- GlobalVariable* gv = new GlobalVariable(
- vtable->getType(),
- true,
- GlobalVariable::ExternalLinkage,
- vtable,
- globalName,
- module_);
-
- return ConstantExpr::getCast(gv, resolver_->getClassRecordPtrType());
- }
-
- void insertVtablesForInterface(std::vector<llvm::Constant*>& vtables,
- const VMClass* clazz,
- const VMClass* interface) {
- static llvm::Constant* nullVTable =
- llvm::Constant::getNullValue(resolver_->getClassRecordPtrType());
-
- assert(interface->isInterface() && "Classfile must be an interface!");
- unsigned index = interface->getInterfaceIndex();
- if (index >= vtables.size())
- vtables.resize(index+1, nullVTable);
- assert(vtables[index] == nullVTable && "Interface vtable already added!");
- vtables[index] = buildInterfaceVTable(clazz, interface);
- }
-
- /// Builds the interfaces vtable array for this classfile and its
- /// corresponding VTableInfo. If this classfile is an interface we
- /// return a pointer to 0xFFFFFFFF.
- std::pair<int, llvm::Constant*>
- buildInterfacesVTables(const VMClass* clazz, const VTableInfo& vi) {
- // If this is an interface then we are not implementing any
- // interfaces so the lastInterface field is our index and the
- // pointer to the array of interface vtables is an all-ones
- // value.
- if (clazz->isInterface())
- return std::make_pair(
- clazz->getInterfaceIndex(),
- ConstantExpr::getCast(
- ConstantIntegral::getAllOnesValue(Type::LongTy),
- PointerType::get(resolver_->getClassRecordPtrType())));
-
- // Otherwise we must fill in the interfaces vtables array. For
- // each implemented interface we insert a pointer to the
- // <class,interface> vtable for this class. Note that we only
- // fill in up to the highest index of the implemented
- // interfaces.
- std::vector<llvm::Constant*> vtables;
- llvm::Constant* nullVTable =
- llvm::Constant::getNullValue(resolver_->getClassRecordPtrType());
-
- for (unsigned i = 0, e = clazz->getNumInterfaces(); i != e; ++i)
- insertVtablesForInterface(vtables, clazz, clazz->getInterface(i));
-
- const std::string& globalName = clazz->getName() + "<interfacesvtables>";
-
- llvm::Constant* init = ConstantArray::get(
- ArrayType::get(resolver_->getClassRecordPtrType(), vtables.size()),
- vtables);
- module_->addTypeName(globalName, init->getType());
-
- GlobalVariable* interfacesArray = new GlobalVariable(
- init->getType(),
- true,
- GlobalVariable::ExternalLinkage,
- init,
- globalName,
- module_);
-
- return std::make_pair(
- int(vtables.size())-1,
- ConstantExpr::getPtrPtrFromArrayPtr(interfacesArray));
- }
-
- /// Given the classfile and its corresponding VTableInfo,
- /// construct the typeinfo constant for it.
- llvm::Constant* buildClassTypeInfo(const VMClass* clazz,
- const VTableInfo& vi) {
- std::vector<llvm::Constant*> typeInfoInit;
-
- llvm::Constant* superClassesVTables = buildSuperClassesVTables(clazz, vi);
-
- // The depth (java/lang/Object has depth 0).
- typeInfoInit.push_back(
- ConstantSInt::get(Type::IntTy, clazz->getNumSuperClasses()));
- // The super classes' vtables.
- typeInfoInit.push_back(superClassesVTables);
-
- int lastInterface;
- llvm::Constant* interfacesVTables;
- tie(lastInterface, interfacesVTables) = buildInterfacesVTables(clazz, vi);
-
- // The last interface index or the interface index if this is an
- // interface.
- typeInfoInit.push_back(ConstantSInt::get(Type::IntTy, lastInterface));
- // The interfaces' vtables.
- typeInfoInit.push_back(interfacesVTables);
- // the element size (0 for classes)
- typeInfoInit.push_back(llvm::ConstantSInt::get(Type::IntTy, 0));
-
- return ConstantStruct::get(typeInfoInit);
- }
-
- /// Returns the VTableInfo associated with this classfile.
- const VTableInfo& getVTableInfo(const VMClass* clazz) {
- static bool initialized = initializeVTableInfoMap();
-
- Class2VTableInfoMap::iterator it = c2viMap_.lower_bound(clazz);
- if (it != c2viMap_.end() && it->first == clazz)
- return it->second;
-
- const std::string& className =
- clazz->getClassFile()->getThisClass()->getName()->str();
- DEBUG(std::cerr << "Building VTableInfo for: " << className << '\n');
- VTableInfo& vi = c2viMap_[clazz];
-
- assert(!vi.vtable && vi.m2iMap.empty() &&
- "got already initialized VTableInfo!");
-
- std::vector<llvm::Constant*> init(1);
- // Use a null typeinfo struct for now.
- init[0] = llvm::Constant::getNullValue(resolver_->getTypeInfoType());
-
- // If this is an interface, add all methods from each interface
- // this inherits from.
- if (clazz->isInterface()) {
- for (unsigned i = 0, e = clazz->getNumInterfaces(); i != e; ++i) {
- const VMClass* interface = clazz->getInterface(i);
- const VTableInfo& ifaceVI = getVTableInfo(interface);
- const ClassFile* ifaceCF = interface->getClassFile();
- ConstantStruct* ifaceInit =
- cast<ConstantStruct>(ifaceVI.vtable->getInitializer());
- for (VTableInfo::const_iterator MI = ifaceVI.m2iMap.begin(),
- ME = ifaceVI.m2iMap.end(); MI != ME; ++MI) {
- const std::string& methodDescr = MI->first;
- unsigned slot = MI->second;
-
- unsigned& index = vi.m2iMap[methodDescr];
- if (!index) {
- index = init.size();
- init.resize(index + 1);
- }
- init[index] = ifaceInit->getOperand(slot);
- }
- }
- }
- // Otherwise this is a class, so add all methods from its super
- // class.
- else {
- const VMClass* superClass = clazz->getSuperClass();
- assert(superClass && "Class does not have superclass!");
- const VTableInfo& superVI = getVTableInfo(superClass);
-
- // Copy the super vtables array.
- vi.superVtables.reserve(superVI.superVtables.size() + 1);
- vi.superVtables.push_back(superVI.vtable);
- std::copy(superVI.superVtables.begin(), superVI.superVtables.end(),
- std::back_inserter(vi.superVtables));
-
- assert(superVI.vtable && "No vtable found for super class!");
- ConstantStruct* superInit =
- cast<ConstantStruct>(superVI.vtable->getInitializer());
- // Fill in the function pointers as they are in the super
- // class. Overriden methods will be replaced later.
- init.resize(superInit->getNumOperands());
- for (unsigned i = 1, e = superInit->getNumOperands(); i != e; ++i)
- init[i] = superInit->getOperand(i);
- vi.m2iMap = superVI.m2iMap;
- }
-
- // Add member functions to the vtable.
- const Methods& methods = clazz->getClassFile()->getMethods();
-
- for (unsigned i = 0, e = methods.size(); i != e; ++i) {
- Method* method = methods[i];
- // Static methods, private instance methods and the contructor
- // are statically bound so we don't add them to the vtable.
- if (!method->isStatic() &&
- !method->isPrivate() &&
- method->getName()->str()[0] != '<') {
- const std::string& methodDescr =
- method->getName()->str() + method->getDescriptor()->str();
-
- const VMMethod* method = clazz->getMethod(methodDescr);
- llvm::Constant* vf = method->getFunction();
- if (clazz->isInterface() || method->isAbstract())
- 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] = vf;
- }
- }
-
-#ifndef NDEBUG
- for (unsigned i = 0, e = init.size(); i != e; ++i)
- assert(init[i] && "No elements in the initializer should be NULL!");
-#endif
-
- const std::string& globalName = className + "<vtable>";
-
- llvm::Constant* vtable = ConstantStruct::get(init);
- module_->addTypeName(globalName, vtable->getType());
- vi.vtable = new GlobalVariable(vtable->getType(),
- true,
- GlobalVariable::ExternalLinkage,
- vtable,
- globalName,
- module_);
-
- // Now the vtable is complete, install the new typeinfo block
- // for this class: we install it last because we need the vtable
- // to exist in order to build it.
- init[0] = buildClassTypeInfo(clazz, vi);
- vi.vtable->setInitializer(ConstantStruct::get(init));
-
- DEBUG(std::cerr << "Built VTableInfo for: " << className << '\n');
- return vi;
- }
-
- VTableInfo buildArrayVTableInfo(const Type* elementTy) {
- VTableInfo vi;
- const VTableInfo& superVI =
- getVTableInfo(resolver_->getClass("java/lang/Object"));
-
- // Add java/lang/Object as its superclass.
- vi.superVtables.reserve(1);
- vi.superVtables.push_back(
- ConstantExpr::getCast(
- superVI.vtable, resolver_->getClassRecordPtrType()));
-
- // Copy the constants from java/lang/Object vtable.
- ConstantStruct* superInit =
- cast<ConstantStruct>(superVI.vtable->getInitializer());
- std::vector<llvm::Constant*> init(superInit->getNumOperands());
- // Use a null typeinfo struct for now.
- init[0] = llvm::Constant::getNullValue(resolver_->getTypeInfoType());
-
- // Fill in the function pointers as they are in
- // java/lang/Object. There are no overriden methods.
- for (unsigned i = 1, e = superInit->getNumOperands(); i != e; ++i)
- init[i] = superInit->getOperand(i);
- vi.m2iMap = superVI.m2iMap;
-
-#ifndef NDEBUG
- for (unsigned i = 0, e = init.size(); i != e; ++i)
- assert(init[i] && "No elements in the initializer should be NULL!");
-#endif
-
- const std::string& globalName =
- elementTy->getDescription() + "[]<vtable>";
-
- llvm::Constant* vtable = ConstantStruct::get(init);
- module_->addTypeName(globalName, vtable->getType());
- vi.vtable = new GlobalVariable(vtable->getType(),
- true,
- GlobalVariable::ExternalLinkage,
- vtable,
- globalName,
- module_);
-
- // Construct the typeinfo now.
- std::vector<llvm::Constant*> typeInfoInit;
- typeInfoInit.push_back(ConstantSInt::get(Type::IntTy, 1));
- // Build the super classes' vtable array.
- ArrayType* vtablesArrayTy =
- ArrayType::get(resolver_->getClassRecordPtrType(),
- vi.superVtables.size());
-
- GlobalVariable* vtablesArray = new GlobalVariable(
- vtablesArrayTy,
- true,
- GlobalVariable::ExternalLinkage,
- ConstantArray::get(vtablesArrayTy, vi.superVtables),
- elementTy->getDescription() + "[]<superclassesvtables>",
- module_);
-
- typeInfoInit.push_back(ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray));
- typeInfoInit.push_back(ConstantSInt::get(Type::IntTy, 0));
- typeInfoInit.push_back(
- llvm::Constant::getNullValue(
- PointerType::get(resolver_->getClassRecordPtrType())));
- // the element size
- typeInfoInit.push_back(
- ConstantExpr::getCast(
- ConstantExpr::getSizeOf(elementTy), Type::IntTy));
-
- init[0] = ConstantStruct::get(typeInfoInit);
- vi.vtable->setInitializer(ConstantStruct::get(init));
-
- return vi;
- }
-
- const VTableInfo& getPrimitiveArrayVTableInfo(const Type* type) {
- if (Type::BoolTy == type) return getPrimitiveArrayVTableInfo(BOOLEAN);
- else if (Type::UShortTy == type) return getPrimitiveArrayVTableInfo(CHAR);
- else if (Type::FloatTy == type) return getPrimitiveArrayVTableInfo(FLOAT);
- else if (Type::DoubleTy == type) return getPrimitiveArrayVTableInfo(DOUBLE);
- else if (Type::SByteTy == type) return getPrimitiveArrayVTableInfo(BYTE);
- else if (Type::ShortTy == type) return getPrimitiveArrayVTableInfo(SHORT);
- else if (Type::IntTy == type) return getPrimitiveArrayVTableInfo(INT);
- else if (Type::LongTy == type) return getPrimitiveArrayVTableInfo(LONG);
- else abort();
- }
-
- // Returns the VTableInfo object for an array of the specified
- // element type.
- const VTableInfo& getPrimitiveArrayVTableInfo(JType type) {
- switch (type) {
- case BOOLEAN: {
- // Because baload/bastore is used to load/store to both byte
- // arrays and boolean arrays we use sbyte for java boolean
- // arrays as well.
- static VTableInfo arrayInfo = buildArrayVTableInfo(Type::SByteTy);
- return arrayInfo;
- }
- case CHAR: {
- static VTableInfo arrayInfo = buildArrayVTableInfo(Type::UShortTy);
- return arrayInfo;
- }
- case FLOAT: {
- static VTableInfo arrayInfo = buildArrayVTableInfo(Type::FloatTy);
- return arrayInfo;
- }
- case DOUBLE: {
- static VTableInfo arrayInfo = buildArrayVTableInfo(Type::DoubleTy);
- return arrayInfo;
- }
- case BYTE: {
- static VTableInfo arrayInfo = buildArrayVTableInfo(Type::SByteTy);
- return arrayInfo;
- }
- case SHORT: {
- static VTableInfo arrayInfo = buildArrayVTableInfo(Type::ShortTy);
- return arrayInfo;
- }
- case INT: {
- static VTableInfo arrayInfo = buildArrayVTableInfo(Type::IntTy);
- return arrayInfo;
- }
- case LONG: {
- static VTableInfo arrayInfo = buildArrayVTableInfo(Type::LongTy);
- return arrayInfo;
- }
- }
- abort();
- }
-
- const VTableInfo& getObjectArrayVTableInfo() {
- static VTableInfo arrayInfo =
- buildArrayVTableInfo(resolver_->getObjectBaseType());
-
- return arrayInfo;
- }
-
std::string getMangledString(const std::string& str) {
std::string mangledStr;
@@ -971,6 +441,15 @@
if (const VMClass* superClass = clazz->getSuperClass())
emitClassInitializers(superClass);
+ // Schedule all its dynamically bound non abstract methods for
+ // compilation.
+ for (unsigned i = 0, e = clazz->getNumDynamicallyBoundMethods();
+ i != e; ++i) {
+ const VMMethod* method = clazz->getDynamicallyBoundMethod(i);
+ if (!method->isAbstract())
+ scheduleMethod(method);
+ }
+
// Create constant strings for this class.
Function* stringConstructors = module_->getOrInsertFunction(
clazz->getName() + "<strinit>",
@@ -1481,24 +960,9 @@
return params;
}
- const VTableInfo* getVTableInfoGeneric(const VMClass* clazz) {
- assert(!clazz->isPrimitive() &&
- "Cannot get VTableInfo for primitive class!");
- if (clazz->isArray()) {
- const VMClass* componentClass = clazz->getComponentClass();
- if (componentClass->isPrimitive())
- return &getPrimitiveArrayVTableInfo(componentClass->getType());
- else
- return &getObjectArrayVTableInfo();
- }
- else
- return &getVTableInfo(clazz);
- }
-
void do_invokevirtual(unsigned index) {
const VMMethod* method = class_->getMethod(index);
const VMClass* clazz = method->getParent();
- const VTableInfo* vi = getVTableInfoGeneric(clazz);
Function* function = method->getFunction();
std::vector<Value*> params(getParams(function->getFunctionType()));
@@ -1507,19 +971,21 @@
objRef = new CastInst(objRef, clazz->getType(), "this", currentBB_);
Value* objBase =
new CastInst(objRef, resolver_->getObjectBaseType(), TMP, currentBB_);
- Value* vtable = new CallInst(getVtable_, objBase, TMP, currentBB_);
- vtable = new CastInst(vtable, vi->vtable->getType(),
- clazz->getName() + ".vtable", currentBB_);
+ Value* classRecord =
+ new CallInst(getClassRecord_, objBase, TMP, currentBB_);
+ classRecord = new CastInst(classRecord,
+ clazz->getClassRecord()->getType(),
+ clazz->getName() + ".classRecord", currentBB_);
std::vector<Value*> indices(1, ConstantUInt::get(Type::UIntTy, 0));
- assert(vi->m2iMap.find(method->getNameAndDescriptor()) != vi->m2iMap.end() &&
- "could not find slot for virtual function!");
- 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, function->getName(), currentBB_);
+ assert(method->getMethodIndex() != -1 &&
+ "Method index not found for dynamically bound method!");
+ indices.push_back(
+ ConstantUInt::get(Type::UIntTy, method->getMethodIndex()+1));
+ Value* funPtr =
+ new GetElementPtrInst(classRecord, indices, TMP, currentBB_);
+ Value* fun = new LoadInst(funPtr, function->getName(), currentBB_);
- makeCall(vfun, params);
+ makeCall(fun, params);
}
void do_invokespecial(unsigned index) {
@@ -1552,7 +1018,7 @@
void do_invokeinterface(unsigned index) {
const VMMethod* method = class_->getMethod(index);
const VMClass* clazz = method->getParent();
- const VTableInfo* vi = getVTableInfoGeneric(clazz);
+ assert(clazz->isInterface() && "Class must be an interface!");
Function* function = method->getFunction();
std::vector<Value*> params(getParams(function->getFunctionType()));
@@ -1561,43 +1027,45 @@
objRef = new CastInst(objRef, clazz->getType(), "this", currentBB_);
Value* objBase =
new CastInst(objRef, resolver_->getObjectBaseType(), TMP, currentBB_);
- Value* vtable = new CallInst(getVtable_, objBase, TMP, currentBB_);
- vtable = new CastInst(vtable, resolver_->getClassRecordPtrType(),
- TMP, currentBB_);
- // get the interfaces array of vtables
+ Value* classRecord =
+ new CallInst(getClassRecord_, objBase, TMP, currentBB_);
+ classRecord = new CastInst(classRecord,
+ resolver_->getClassRecordPtrType(),
+ TMP, currentBB_);
+ // get the interfaces array of class records
std::vector<Value*> indices(2, ConstantUInt::get(Type::UIntTy, 0));
indices.push_back(ConstantUInt::get(Type::UIntTy, 3));
- Value* interfaceVTables =
- new GetElementPtrInst(vtable, indices, TMP, currentBB_);
- interfaceVTables = new LoadInst(interfaceVTables, TMP, currentBB_);
- // Get the actual interface vtable.
+ Value* interfaceClassRecords =
+ new GetElementPtrInst(classRecord, indices, TMP, currentBB_);
+ interfaceClassRecords =
+ new LoadInst(interfaceClassRecords, TMP, currentBB_);
+ // Get the actual interface class record.
indices.clear();
- indices.push_back(ConstantUInt::get(Type::UIntTy,
- clazz->getInterfaceIndex()));
- Value* interfaceVTable =
- new GetElementPtrInst(interfaceVTables, indices, TMP, currentBB_);
- interfaceVTable =
- new LoadInst(interfaceVTable, clazz->getName() + ".vtable", currentBB_);
- interfaceVTable =
- new CastInst(interfaceVTable, vi->vtable->getType(), TMP, currentBB_);
+ indices.push_back(
+ ConstantUInt::get(Type::UIntTy, clazz->getInterfaceIndex()));
+ Value* interfaceClassRecord =
+ new GetElementPtrInst(interfaceClassRecords, indices, TMP, currentBB_);
+ interfaceClassRecord =
+ new LoadInst(interfaceClassRecord,
+ clazz->getName() + ".classRecord", currentBB_);
+ interfaceClassRecord =
+ new CastInst(interfaceClassRecord,
+ clazz->getClassRecord()->getType(), TMP, currentBB_);
// Get the function pointer.
- assert(vi->m2iMap.find(method->getNameAndDescriptor()) != vi->m2iMap.end() &&
- "could not find slot for virtual function!");
- unsigned vSlot = vi->m2iMap.find(method->getNameAndDescriptor())->second;
+ assert(method->getMethodIndex() != -1 &&
+ "Method index not found for dynamically bound method!");
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, function->getName(), currentBB_);
+ indices[1] = ConstantUInt::get(Type::UIntTy, method->getMethodIndex()+1);
+ Value* funPtr =
+ new GetElementPtrInst(interfaceClassRecord, indices, TMP, currentBB_);
+ Value* fun = new LoadInst(funPtr, function->getName(), currentBB_);
- makeCall(vfun, params);
+ makeCall(fun, params);
}
template<typename InsertionPointTy>
- Value* allocateObject(const VMClass& clazz,
- const VTableInfo& vi,
- InsertionPointTy* ip) {
+ Value* allocateObject(const VMClass& clazz, InsertionPointTy* ip) {
static std::vector<Value*> params(4);
Value* objRef = new MallocInst(clazz.getLayoutType(), NULL, TMP, ip);
@@ -1608,11 +1076,13 @@
params[3] = ConstantUInt::get(Type::UIntTy, 0); // alignment
new CallInst(memset_, params, "", ip);
- // Install the vtable pointer.
- Value* objBase = new CastInst(objRef, resolver_->getObjectBaseType(), TMP, ip);
- const Type* vtablePtrType = resolver_->getClassRecordPtrType();
- Value* vtable = new CastInst(vi.vtable, vtablePtrType, TMP, ip);
- new CallInst(setVtable_, objBase, vtable, "", ip);
+ // Install the class record.
+ Value* objBase =
+ new CastInst(objRef, resolver_->getObjectBaseType(), TMP, ip);
+ const Type* classRecordPtrType = resolver_->getClassRecordPtrType();
+ Value* classRecord =
+ new CastInst(clazz.getClassRecord(), classRecordPtrType, TMP, ip);
+ new CallInst(setClassRecord_, objBase, classRecord, "", ip);
return objRef;
}
@@ -1620,9 +1090,7 @@
void do_new(unsigned index) {
const VMClass* clazz = class_->getClass(index);
emitClassInitializers(clazz);
- const VTableInfo& vi = getVTableInfo(clazz);
-
- push(allocateObject(*clazz, vi, currentBB_));
+ push(allocateObject(*clazz, currentBB_));
}
template <typename InsertionPointTy>
@@ -1647,7 +1115,6 @@
template<typename InsertionPointTy>
Value* allocateArray(const VMClass* clazz,
- const VTableInfo* vi,
Value* count,
InsertionPointTy* ip) {
static std::vector<Value*> params(4);
@@ -1686,11 +1153,12 @@
Value* lengthPtr = getArrayLengthPtr(objRef, ip);
new StoreInst(count, lengthPtr, ip);
- // Install the vtable pointer.
+ // Install the class record.
Value* objBase = new CastInst(objRef, resolver_->getObjectBaseType(), TMP, ip);
- const Type* vtablePtrType = resolver_->getClassRecordPtrType();
- Value* vtable = new CastInst(vi->vtable, vtablePtrType, TMP, ip);
- new CallInst(setVtable_, objBase, vtable, "", ip);
+ const Type* classRecordPtrType = resolver_->getClassRecordPtrType();
+ Value* classRecord =
+ new CastInst(clazz->getClassRecord(), classRecordPtrType, TMP, ip);
+ new CallInst(setClassRecord_, objBase, classRecord, "", ip);
return objRef;
}
@@ -1700,9 +1168,8 @@
const VMClass* clazz = resolver_->getClass(type);
const VMClass* arrayClass = resolver_->getArrayClass(clazz);
- const VTableInfo* vi = getVTableInfoGeneric(arrayClass);
- push(allocateArray(arrayClass, vi, count, currentBB_));
+ push(allocateArray(arrayClass, count, currentBB_));
}
void do_anewarray(unsigned index) {
@@ -1710,9 +1177,8 @@
const VMClass* clazz = class_->getClass(index);
const VMClass* arrayClass = resolver_->getArrayClass(clazz);
- const VTableInfo* vi = getVTableInfoGeneric(arrayClass);
- push(allocateArray(arrayClass, vi, count, currentBB_));
+ push(allocateArray(arrayClass, count, currentBB_));
}
void do_arraylength() {
@@ -1731,12 +1197,13 @@
void do_checkcast(unsigned index) {
const VMClass* clazz = class_->getClass(index);
- const VTableInfo* vi = getVTableInfoGeneric(clazz);
Value* objRef = pop(resolver_->getObjectBaseType());
- const Type* vtablePtrType = resolver_->getClassRecordPtrType();
- Value* vtable = new CastInst(vi->vtable, vtablePtrType, TMP, currentBB_);
- Value* r = new CallInst(isInstanceOf_, objRef, vtable, TMP, currentBB_);
+ const Type* classRecordPtrType = resolver_->getClassRecordPtrType();
+ Value* classRecord = new CastInst(clazz->getClassRecord(),
+ classRecordPtrType, TMP, currentBB_);
+ Value* r =
+ new CallInst(isInstanceOf_, objRef, classRecord, TMP, currentBB_);
Value* b = new SetCondInst(Instruction::SetEQ,
r, ConstantSInt::get(Type::IntTy, 1),
@@ -1747,12 +1214,13 @@
void do_instanceof(unsigned index) {
const VMClass* clazz = class_->getClass(index);
- const VTableInfo* vi = getVTableInfoGeneric(clazz);
Value* objRef = pop(resolver_->getObjectBaseType());
- const Type* vtablePtrType = resolver_->getClassRecordPtrType();
- Value* vtable = new CastInst(vi->vtable, vtablePtrType, TMP, currentBB_);
- Value* r = new CallInst(isInstanceOf_, objRef, vtable, TMP, currentBB_);
+ const Type* classRecordPtrType = resolver_->getClassRecordPtrType();
+ Value* classRecord = new CastInst(clazz->getClassRecord(),
+ classRecordPtrType, TMP, currentBB_);
+ Value* r =
+ new CallInst(isInstanceOf_, objRef, classRecord, TMP, currentBB_);
push(r);
}
More information about the llvm-commits
mailing list