[llvm-commits] CVS: llvm-java/lib/Compiler/Compiler.cpp Class.h Class.cpp
Alkis Evlogimenos
alkis at cs.uiuc.edu
Sat Mar 26 20:20:33 PST 2005
Changes in directory llvm-java/lib/Compiler:
Compiler.cpp updated: 1.257 -> 1.258
Class.h updated: 1.10 -> 1.11
Class.cpp updated: 1.10 -> 1.11
---
Log message:
When dealing with VTableInfo's pass the Class around not the class
file. Also add an array of all implemented interfaces and all
superclasses in Class and use that when constructing a VTableInfo.
---
Diffs of the changes: (+102 -91)
Class.cpp | 51 +++++++++++++++++------
Class.h | 12 ++++-
Compiler.cpp | 130 ++++++++++++++++++++++++-----------------------------------
3 files changed, 102 insertions(+), 91 deletions(-)
Index: llvm-java/lib/Compiler/Compiler.cpp
diff -u llvm-java/lib/Compiler/Compiler.cpp:1.257 llvm-java/lib/Compiler/Compiler.cpp:1.258
--- llvm-java/lib/Compiler/Compiler.cpp:1.257 Sat Mar 26 21:48:21 2005
+++ llvm-java/lib/Compiler/Compiler.cpp Sat Mar 26 22:20:22 2005
@@ -93,7 +93,7 @@
static StructType* VTableTy;
static StructType* TypeInfoTy;
};
- typedef std::map<const ClassFile*, VTableInfo> Class2VTableInfoMap;
+ typedef std::map<const Class*, VTableInfo> Class2VTableInfoMap;
Class2VTableInfoMap c2viMap_;
public:
@@ -263,8 +263,8 @@
/// VTableInfo for java.lang.Object.
bool initializeVTableInfoMap() {
DEBUG(std::cerr << "Building VTableInfo for: java/lang/Object\n");
- const ClassFile* cf = ClassFile::get("java/lang/Object");
- VTableInfo& vi = c2viMap_[cf];
+ const Class* clazz = resolver_->getClass("java/lang/Object");
+ VTableInfo& vi = c2viMap_[clazz];
assert(!vi.vtable && vi.m2iMap.empty() &&
"java/lang/Object VTableInfo should not be initialized!");
@@ -310,7 +310,7 @@
// Add the typeinfo block for this class.
init.push_back(typeInfoInit);
- const Methods& methods = cf->getMethods();
+ const Methods& methods = clazz->getClassFile()->getMethods();
// Add member functions to the vtable.
for (unsigned i = 0, e = methods.size(); i != e; ++i) {
@@ -358,10 +358,10 @@
}
/// Builds the super classes' vtable array for this classfile and
- /// its corresponding VTable. The most generic class goes first in
+ /// its corresponding VTable. The direct superclass goes first in
/// the array.
- std::pair<unsigned,llvm::Constant*>
- buildSuperClassesVTables(const ClassFile* cf, const VTableInfo& vi) const {
+ llvm::Constant*
+ buildSuperClassesVTables(const Class* 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(
@@ -378,25 +378,23 @@
true,
GlobalVariable::ExternalLinkage,
init,
- cf->getThisClass()->getName()->str() + "<superclassesvtables>",
+ clazz->getClassFile()->getThisClass()->getName()->str() +
+ "<superclassesvtables>",
module_);
- return std::make_pair(
- vi.superVtables.size(),
- ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray));
+ return ConstantExpr::getPtrPtrFromArrayPtr(vtablesArray);
}
/// Builds an interface VTable for the specified <class,interface>
/// pair.
- llvm::Constant* buildInterfaceVTable(const ClassFile* cf,
- const ClassFile* interface) {
+ llvm::Constant* buildInterfaceVTable(const Class* clazz,
+ const Class* interface) {
DEBUG(std::cerr << "Building interface vtable: "
- << interface->getThisClass()->getName()->str() << " for: "
- << cf->getThisClass()->getName()->str() << '\n');
+ << interface->getName() << " for: " << clazz->getName() << '\n');
- const VTableInfo& classVI = getVTableInfo(cf);
+ const VTableInfo& classVI = getVTableInfo(clazz);
const VTableInfo& interfaceVI = getVTableInfo(interface);
- const Methods& methods = interface->getMethods();
+ 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
@@ -410,7 +408,7 @@
for (VTableInfo::Method2IndexMap::const_iterator
i = interfaceVI.m2iMap.begin(), e = interfaceVI.m2iMap.end();
i != e; ++i) {
- if (!cf->isAbstract()) {
+ 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;
@@ -425,8 +423,7 @@
llvm::Constant* vtable = ConstantStruct::get(init);
const std::string& globalName =
- cf->getThisClass()->getName()->str() + '+' +
- interface->getThisClass()->getName()->str() + "<vtable>";
+ clazz->getName() + '+' + interface->getName() + "<vtable>";
module_->addTypeName(globalName, vtable->getType());
GlobalVariable* gv = new GlobalVariable(
@@ -441,41 +438,31 @@
}
void insertVtablesForInterface(std::vector<llvm::Constant*>& vtables,
- const ClassFile* cf,
- const ClassFile* interfaceCf) {
+ const Class* clazz,
+ const Class* interface) {
static llvm::Constant* nullVTable =
llvm::Constant::getNullValue(PointerType::get(VTableInfo::VTableTy));
- assert(interfaceCf->isInterface() && "Classfile must be an interface!");
- const Class* interface =
- resolver_->getClass(interfaceCf->getThisClass()->getName()->str());
+ assert(interface->isInterface() && "Classfile must be an interface!");
unsigned index = interface->getInterfaceIndex();
if (index >= vtables.size())
vtables.resize(index+1, nullVTable);
- // Add this interface's vtable if it was not added before.
- if (vtables[index] == nullVTable) {
- vtables[index] = buildInterfaceVTable(cf, interfaceCf);
- unsigned numInterface = interfaceCf->getNumInterfaces();
- for (unsigned i = 0, e = interfaceCf->getNumInterfaces(); i != e; ++i) {
- const ClassFile* superInterface =
- ClassFile::get(interfaceCf->getInterface(i)->getName()->str());
- insertVtablesForInterface(vtables, cf, superInterface);
- }
- }
+ 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 ClassFile* cf, const VTableInfo& vi) {
+ buildInterfacesVTables(const Class* 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 (cf->isInterface())
+ if (clazz->isInterface())
return std::make_pair(
- resolver_->getClass(cf->getThisClass()->getName()->str())->getInterfaceIndex(),
+ clazz->getInterfaceIndex(),
ConstantExpr::getCast(
ConstantIntegral::getAllOnesValue(Type::LongTy),
PointerType::get(PointerType::get(VTableInfo::VTableTy))));
@@ -489,20 +476,10 @@
llvm::Constant* nullVTable =
llvm::Constant::getNullValue(PointerType::get(VTableInfo::VTableTy));
- const ClassFile* curCf = cf;
- while (true) {
- for (unsigned i = 0, e = curCf->getNumInterfaces(); i != e; ++i) {
- const ClassFile* ifaceCf =
- ClassFile::get(curCf->getInterface(i)->getName()->str());
- insertVtablesForInterface(vtables, cf, ifaceCf);
- }
- if (!curCf->getSuperClass())
- break;
- curCf = ClassFile::get(curCf->getSuperClass()->getName()->str());
- }
+ for (unsigned i = 0, e = clazz->getNumInterfaces(); i != e; ++i)
+ insertVtablesForInterface(vtables, clazz, clazz->getInterface(i));
- const std::string& globalName =
- cf->getThisClass()->getName()->str() + "<interfacesvtables>";
+ const std::string& globalName = clazz->getName() + "<interfacesvtables>";
llvm::Constant* init = ConstantArray::get(
ArrayType::get(PointerType::get(VTableInfo::VTableTy), vtables.size()),
@@ -524,22 +501,21 @@
/// Given the classfile and its corresponding VTableInfo,
/// construct the typeinfo constant for it.
- llvm::Constant* buildClassTypeInfo(const ClassFile* cf,
+ llvm::Constant* buildClassTypeInfo(const Class* clazz,
const VTableInfo& vi) {
std::vector<llvm::Constant*> typeInfoInit;
- unsigned depth;
- llvm::Constant* superClassesVTables;
- tie(depth, superClassesVTables) = buildSuperClassesVTables(cf, vi);
+ llvm::Constant* superClassesVTables = buildSuperClassesVTables(clazz, vi);
// The depth (java/lang/Object has depth 0).
- typeInfoInit.push_back(ConstantSInt::get(Type::IntTy, depth));
+ 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(cf, vi);
+ tie(lastInterface, interfacesVTables) = buildInterfacesVTables(clazz, vi);
// The last interface index or the interface index if this is an
// interface.
@@ -553,16 +529,17 @@
}
/// Returns the VTableInfo associated with this classfile.
- const VTableInfo& getVTableInfo(const ClassFile* cf) {
+ const VTableInfo& getVTableInfo(const Class* clazz) {
static bool initialized = initializeVTableInfoMap();
- Class2VTableInfoMap::iterator it = c2viMap_.lower_bound(cf);
- if (it != c2viMap_.end() && it->first == cf)
+ Class2VTableInfoMap::iterator it = c2viMap_.lower_bound(clazz);
+ if (it != c2viMap_.end() && it->first == clazz)
return it->second;
- const std::string& className = cf->getThisClass()->getName()->str();
+ const std::string& className =
+ clazz->getClassFile()->getThisClass()->getName()->str();
DEBUG(std::cerr << "Building VTableInfo for: " << className << '\n');
- VTableInfo& vi = c2viMap_[cf];
+ VTableInfo& vi = c2viMap_[clazz];
assert(!vi.vtable && vi.m2iMap.empty() &&
"got already initialized VTableInfo!");
@@ -573,11 +550,11 @@
// If this is an interface, add all methods from each interface
// this inherits from.
- if (cf->isInterface()) {
- for (unsigned i = 0, e = cf->getNumInterfaces(); i != e; ++i) {
- const ClassFile* ifaceCF =
- ClassFile::get(cf->getInterface(i)->getName()->str());
- const VTableInfo& ifaceVI = getVTableInfo(ifaceCF);
+ if (clazz->isInterface()) {
+ for (unsigned i = 0, e = clazz->getNumInterfaces(); i != e; ++i) {
+ const Class* 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(),
@@ -597,10 +574,9 @@
// Otherwise this is a class, so add all methods from its super
// class.
else {
- ConstantClass* super = cf->getSuperClass();
- assert(super && "Class does not have superclass!");
- const VTableInfo& superVI =
- getVTableInfo(ClassFile::get(super->getName()->str()));
+ const Class* 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);
@@ -620,7 +596,7 @@
}
// Add member functions to the vtable.
- const Methods& methods = cf->getMethods();
+ const Methods& methods = clazz->getClassFile()->getMethods();
for (unsigned i = 0, e = methods.size(); i != e; ++i) {
Method* method = methods[i];
@@ -637,7 +613,7 @@
const FunctionType* funcTy = cast<FunctionType>(
resolver_->getType(method->getDescriptor()->str(), true));
llvm::Constant* vfun = NULL;
- if (cf->isInterface() || method->isAbstract())
+ if (clazz->isInterface() || method->isAbstract())
vfun = llvm::Constant::getNullValue(PointerType::get(funcTy));
else {
vfun = module_->getOrInsertFunction(funcName, funcTy);
@@ -672,7 +648,7 @@
// 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(cf, vi);
+ init[0] = buildClassTypeInfo(clazz, vi);
vi.vtable->setInitializer(ConstantStruct::get(init));
DEBUG(std::cerr << "Built VTableInfo for: " << className << '\n');
@@ -682,7 +658,7 @@
VTableInfo buildArrayVTableInfo(const Type* elementTy) {
VTableInfo vi;
const VTableInfo& superVI =
- getVTableInfo(ClassFile::get("java/lang/Object"));
+ getVTableInfo(resolver_->getClass("java/lang/Object"));
// Add java/lang/Object as its superclass.
vi.superVtables.reserve(1);
@@ -1695,7 +1671,7 @@
return &getObjectArrayVTableInfo();
}
else
- return &getVTableInfo(clazz->getClassFile());
+ return &getVTableInfo(clazz);
}
void do_invokevirtual(unsigned index) {
@@ -1861,7 +1837,7 @@
void do_new(unsigned index) {
const Class* clazz = class_->getClass(index);
emitStaticInitializers(clazz->getClassFile());
- const VTableInfo& vi = getVTableInfo(clazz->getClassFile());
+ const VTableInfo& vi = getVTableInfo(clazz);
push(allocateObject(*clazz, vi, currentBB_));
}
Index: llvm-java/lib/Compiler/Class.h
diff -u llvm-java/lib/Compiler/Class.h:1.10 llvm-java/lib/Compiler/Class.h:1.11
--- llvm-java/lib/Compiler/Class.h:1.10 Sat Mar 26 18:04:10 2005
+++ llvm-java/lib/Compiler/Class.h Sat Mar 26 22:20:22 2005
@@ -33,7 +33,6 @@
const std::string name_;
Resolver* resolver_;
const ClassFile* classFile_;
- const Class* superClass_;
const Class* componentClass_;
Type* structType_;
const Type* type_;
@@ -43,6 +42,8 @@
typedef std::vector<const Type*> ElementTypes;
ElementTypes elementTypes_;
mutable std::vector<void*> resolvedConstantPool_;
+ std::vector<const Class*> superClasses_;
+ std::vector<const Class*> interfaces_;
void addField(const std::string& name, const Type* type);
void resolveType();
@@ -72,10 +73,17 @@
const Type* getStructType() const { return structType_; }
const Type* getType() const { return type_; }
const ClassFile* getClassFile() const { return classFile_; }
- const Class* getSuperClass() const { return superClass_; }
+ unsigned getNumSuperClasses() const { return superClasses_.size(); }
+ const Class* getSuperClass(unsigned i) const { return superClasses_[i]; }
+ const Class* getSuperClass() const {
+ return getNumSuperClasses() ? getSuperClass(0) : NULL;
+ }
+ unsigned getNumInterfaces() const { return interfaces_.size(); }
+ const Class* getInterface(unsigned i) const { return interfaces_[i]; }
const Class* getComponentClass() const { return componentClass_; }
bool isArray() const { return componentClass_; }
bool isPrimitive() const { return !structType_; }
+ bool isInterface() const { return classFile_ && !getSuperClass(); }
unsigned getInterfaceIndex() const { return interfaceIndex_; }
int getFieldIndex(const std::string& name) const;
Index: llvm-java/lib/Compiler/Class.cpp
diff -u llvm-java/lib/Compiler/Class.cpp:1.10 llvm-java/lib/Compiler/Class.cpp:1.11
--- llvm-java/lib/Compiler/Class.cpp:1.10 Sat Mar 26 18:04:10 2005
+++ llvm-java/lib/Compiler/Class.cpp Sat Mar 26 22:20:22 2005
@@ -30,7 +30,6 @@
: name_(Resolver::canonicalizeClassName(className)),
resolver_(resolver),
classFile_(ClassFile::get(className)),
- superClass_(NULL),
componentClass_(NULL),
structType_(OpaqueType::get()),
type_(PointerType::get(structType_)),
@@ -44,7 +43,6 @@
: name_('[' + componentClass->getName()),
resolver_(resolver),
classFile_(NULL),
- superClass_(NULL),
componentClass_(componentClass),
structType_(OpaqueType::get()),
type_(PointerType::get(structType_)),
@@ -64,7 +62,6 @@
type == Type::BoolTy ? "Z" : "V"),
resolver_(resolver),
classFile_(NULL),
- superClass_(NULL),
componentClass_(NULL),
structType_(NULL),
type_(type),
@@ -97,21 +94,48 @@
assert(!isPrimitive() && "Should not link primitive classes!");
if (isArray()) {
- superClass_ = resolver_->getClass("java/lang/Object");
- addField("super", superClass_->getStructType());
+ superClasses_.reserve(1);
+ superClasses_.push_back(resolver_->getClass("java/lang/Object"));
+ addField("super", superClasses_[0]->getStructType());
addField("<length>", Type::UIntTy);
addField("<data>", ArrayType::get(componentClass_->getType(), 0));
+
+ interfaces_.reserve(2);
+ interfaces_.push_back(resolver_->getClass("java/lang/Cloneable"));
+ interfaces_.push_back(resolver_->getClass("java/io/Serializable"));
}
else {
+ // This is java/lang/Object.
+ if (!classFile_->getSuperClass())
+ addField("base", resolver_->getObjectBaseType());
// This is any class but java/lang/Object.
- if (classFile_->getSuperClass()) {
+ else {
+ // Our direct super class.
const Class* superClass =
resolver_->getClass(classFile_->getSuperClass()->getName()->str());
+ // Add the interfaces of our direct superclass.
+ for (unsigned i = 0, e = superClass->getNumInterfaces(); i != e; ++i)
+ interfaces_.push_back(superClass->getInterface(i));
+
+ // For each of the interfaces we implement, load it and add that
+ // interface and all the interfaces it inherits from.
+ for (unsigned i = 0, e = classFile_->getNumInterfaces(); i != e; ++i) {
+ const Class* interface = getClass(classFile_->getInterfaceIndex(i));
+ interfaces_.push_back(interface);
+ for (unsigned j = 0, f = interface->getNumInterfaces(); j != f; ++j)
+ interfaces_.push_back(interface->getInterface(j));
+ }
+
+ // Sort the interfaces array and remove duplicates.
+ std::sort(interfaces_.begin(), interfaces_.end());
+ interfaces_.erase(std::unique(interfaces_.begin(), interfaces_.end()),
+ interfaces_.end());
+
// We first add the struct of the super class.
addField("super", superClass->getStructType());
- // Although we can safely assume that all interfaces inherits
+ // Although we can safely assume that all interfaces inherit
// from java/lang/Object, java/lang/Class.getSuperclass()
// returns null on interface types. So we only set the
// superClass_ field when the class is not an interface type,
@@ -119,12 +143,15 @@
// inherits java/lang/Object.
if (classFile_->isInterface())
interfaceIndex_ = resolver_->getNextInterfaceIndex();
- else
- superClass_ = superClass;
+ else {
+ // Build the super classes array. The first class is the
+ // direct super class of this class.
+ superClasses_.reserve(superClass->getNumSuperClasses() + 1);
+ superClasses_.push_back(superClass);
+ for (unsigned i = 0, e = superClass->getNumSuperClasses(); i != e; ++i)
+ superClasses_.push_back(superClass->getSuperClass(i));
+ }
}
- // This is java/lang/Object.
- else
- addField("base", resolver_->getObjectBaseType());
// Then we add the rest of the fields.
const Fields& fields = classFile_->getFields();
More information about the llvm-commits
mailing list