[vmkit-commits] [vmkit] r69533 - in /vmkit/trunk: include/jnjvm/ lib/JnJVM/Classpath/ lib/JnJVM/Compiler/ lib/JnJVM/LLVMRuntime/ lib/JnJVM/VMCore/
Nicolas Geoffray
nicolas.geoffray at lip6.fr
Sun Apr 19 12:09:19 PDT 2009
Author: geoffray
Date: Sun Apr 19 14:09:19 2009
New Revision: 69533
URL: http://llvm.org/viewvc/llvm-project?rev=69533&view=rev
Log:
Move to the new subtype checking implementation when jitting
Java code (the function call still needs to be lowered) and
finally implement the long-awaiting array-store check!
Modified:
vmkit/trunk/include/jnjvm/JnjvmModule.h
vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp
vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp
vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp
vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp
vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp
vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp
vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp
vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp
vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll
vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-isolate.ll
vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-single.ll
vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
Modified: vmkit/trunk/include/jnjvm/JnjvmModule.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/jnjvm/JnjvmModule.h?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/include/jnjvm/JnjvmModule.h (original)
+++ vmkit/trunk/include/jnjvm/JnjvmModule.h Sun Apr 19 14:09:19 2009
@@ -66,6 +66,7 @@
class LLVMClassInfo : public mvm::JITInfo {
+ friend class JavaJITCompiler;
friend class JavaLLVMCompiler;
private:
Class* classDef;
@@ -253,10 +254,7 @@
#ifndef WITHOUT_VTABLE
llvm::Function* VirtualLookupFunction;
#endif
- llvm::Function* InstanceOfFunction;
llvm::Function* IsAssignableFromFunction;
- llvm::Function* ImplementsFunction;
- llvm::Function* InstantiationOfArrayFunction;
llvm::Function* GetDepthFunction;
llvm::Function* GetClassInDisplayFunction;
llvm::Function* GetStaticInstanceFunction;
@@ -293,7 +291,9 @@
llvm::Function* JavaObjectAllocateFunction;
llvm::Function* GetVTFromClassFunction;
llvm::Function* GetVTFromClassArrayFunction;
+ llvm::Function* GetVTFromCommonClassFunction;
llvm::Function* GetObjectSizeFromClassFunction;
+ llvm::Function* GetBaseClassVTFromVTFunction;
llvm::Function* GetLockFunction;
llvm::Function* OverflowThinLockFunction;
@@ -308,7 +308,6 @@
static llvm::ConstantInt* OffsetObjectSizeInClassConstant;
static llvm::ConstantInt* OffsetVTInClassConstant;
- static llvm::ConstantInt* OffsetVTInClassArrayConstant;
static llvm::ConstantInt* OffsetDepthInClassConstant;
static llvm::ConstantInt* OffsetDisplayInClassConstant;
static llvm::ConstantInt* OffsetTaskClassMirrorInClassConstant;
@@ -322,6 +321,7 @@
static llvm::ConstantInt* OffsetClassInVTConstant;
static llvm::ConstantInt* OffsetDepthInVTConstant;
static llvm::ConstantInt* OffsetDisplayInVTConstant;
+ static llvm::ConstantInt* OffsetBaseClassVTInVTConstant;
static llvm::ConstantInt* ClassReadyConstant;
@@ -335,6 +335,7 @@
llvm::Function* ClassCastExceptionFunction;
llvm::Function* OutOfMemoryErrorFunction;
llvm::Function* NegativeArraySizeExceptionFunction;
+ llvm::Function* ArrayStoreExceptionFunction;
JnjvmModule(llvm::Module*);
@@ -360,8 +361,6 @@
}
#endif
- void internalMakeVT(Class* cl);
-
void addJavaPasses();
private:
Modified: vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Classpath/ClasspathVMThrowable.cpp Sun Apr 19 14:09:19 2009
@@ -109,7 +109,7 @@
while (i != e) {
JavaMethod* meth = vm->IPToMethod<JavaMethod>(*i);
assert(meth && "Wrong stack trace");
- if (meth->classDef->subclassOf(vm->upcalls->newThrowable)) {
+ if (meth->classDef->isAssignableFrom(vm->upcalls->newThrowable)) {
++i;
++index;
} else break;
Modified: vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JITInfo.cpp Sun Apr 19 14:09:19 2009
@@ -73,26 +73,7 @@
classDef->virtualSize = (uint32)size;
virtualSizeConstant = ConstantInt::get(Type::Int32Ty, size);
- if (!Mod->isStaticCompiling()) {
- if (!classDef->virtualVT) {
- Mod->makeVT(classDef);
- } else {
-#ifdef WITH_TRACER
- // So the class is vmjc'ed. Create the virtual tracer.
- Function* func = Function::Create(JnjvmModule::MarkAndTraceType,
- GlobalValue::ExternalLinkage,
- "markAndTraceObject",
- Mod->getLLVMModule());
-
- uintptr_t ptr = classDef->virtualVT->tracer;
- JnjvmModule::executionEngine->addGlobalMapping(func, (void*)ptr);
- virtualTracerFunction = func;
-#endif
- }
- } else {
- Mod->makeVT(classDef);
- }
-
+ Mod->makeVT(classDef);
}
return virtualType;
Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaAOTCompiler.cpp Sun Apr 19 14:09:19 2009
@@ -364,11 +364,8 @@
std::vector<Constant*> Elmts;
- if (cl->isClass()) {
- Elmts.push_back(getVirtualTable(cl->asClass()->virtualVT));
- } else {
- Elmts.push_back(getVirtualTable(cl->asArrayClass()->virtualVT));
- }
+ // VT
+ Elmts.push_back(getVirtualTable(cl->virtualVT));
// lock
Constant* L = ConstantInt::get(Type::Int64Ty, 0);
@@ -666,7 +663,14 @@
Constant* loader = ConstantExpr::getBitCast(StaticInitializer,
JnjvmModule::ptrType);
CommonClassElts.push_back(loader);
-
+
+ // virtualTable
+ if (cl->virtualVT) {
+ CommonClassElts.push_back(getVirtualTable(cl->virtualVT));
+ } else {
+ TempTy = JnjvmModule::VTType;
+ CommonClassElts.push_back(Constant::getNullValue(TempTy));
+ }
return ConstantStruct::get(STy, CommonClassElts);
}
@@ -836,9 +840,6 @@
ClassElts.push_back(Cl);
- // virtualTable
- ClassElts.push_back(getVirtualTable(cl->virtualVT));
-
return ConstantStruct::get(STy, ClassElts);
}
@@ -855,11 +856,8 @@
// virtualSize
ClassElts.push_back(ConstantInt::get(Type::Int32Ty, cl->virtualSize));
- // virtualTable
- ClassElts.push_back(getVirtualTable(cl->virtualVT));
-
// IsolateInfo
- const ArrayType* ATy = dyn_cast<ArrayType>(STy->getContainedType(3));
+ const ArrayType* ATy = dyn_cast<ArrayType>(STy->getContainedType(2));
assert(ATy && "Malformed type");
const StructType* TCMTy = dyn_cast<StructType>(ATy->getContainedType(0));
@@ -1201,8 +1199,7 @@
ConstantInt::get(Type::Int64Ty, VT->offset), PTy));
// cache
- Elemts.push_back(ConstantExpr::getIntToPtr(
- ConstantInt::get(Type::Int64Ty, VT->cache), PTy));
+ Elemts.push_back(N);
// display
for (uint32 i = 0; i < JavaVirtualTable::getDisplayLength(); ++i) {
@@ -1210,8 +1207,9 @@
Constant* Temp = getVirtualTable(VT->display[i]);
Temp = ConstantExpr::getBitCast(Temp, PTy);
Elemts.push_back(Temp);
- } else
+ } else {
Elemts.push_back(Constant::getNullValue(PTy));
+ }
}
// nbSecondaryTypes
@@ -1236,6 +1234,15 @@
display = ConstantExpr::getCast(Instruction::BitCast, display, PTy);
Elemts.push_back(display);
+
+ // baseClassVT
+ if (VT->baseClassVT) {
+ Constant* Temp = getVirtualTable(VT->baseClassVT);
+ Temp = ConstantExpr::getBitCast(Temp, PTy);
+ Elemts.push_back(Temp);
+ } else {
+ Elemts.push_back(Constant::getNullValue(PTy));
+ }
// methods
@@ -1455,8 +1462,16 @@
}
void JavaAOTCompiler::makeVT(Class* cl) {
- internalMakeVT(cl);
- VirtualTable* VT = cl->virtualVT;
+ JavaVirtualTable* VT = cl->virtualVT;
+
+ if (cl->super) {
+ // Copy the super VT into the current VT.
+ uint32 size = cl->super->virtualTableSize -
+ JavaVirtualTable::getFirstJavaMethodIndex();
+ memcpy(VT->getFirstJavaMethod(), cl->super->virtualVT->getFirstJavaMethod(),
+ size * sizeof(uintptr_t));
+ }
+
for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
JavaMethod& meth = cl->virtualMethods[i];
((void**)VT)[meth.offset] = &meth;
Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Sun Apr 19 14:09:19 2009
@@ -49,7 +49,7 @@
return true;
#else
- if (cl->isReadyForCompilation() || compilingClass->subclassOf(cl)) {
+ if (cl->isReadyForCompilation() || compilingClass->isAssignableFrom(cl)) {
return false;
}
Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJITCompiler.cpp Sun Apr 19 14:09:19 2009
@@ -134,11 +134,37 @@
#endif
void JavaJITCompiler::makeVT(Class* cl) {
- internalMakeVT(cl);
-
JavaVirtualTable* VT = cl->virtualVT;
assert(VT && "No VT was allocated!");
+#ifdef WITH_TRACER
+ if (VT->init) {
+ // So the class is vmjc'ed. Create the virtual tracer.
+ Function* func = Function::Create(JnjvmModule::MarkAndTraceType,
+ GlobalValue::ExternalLinkage,
+ "markAndTraceObject",
+ getLLVMModule());
+
+ uintptr_t ptr = VT->tracer;
+ JnjvmModule::executionEngine->addGlobalMapping(func, (void*)ptr);
+ LLVMClassInfo* LCI = getClassInfo(cl);
+ LCI->virtualTracerFunction = func;
+
+ // The VT hash already been filled by the AOT compiler so there
+ // is nothing left to do!
+ return;
+ }
+#endif
+
+ if (cl->super) {
+ // Copy the super VT into the current VT.
+ uint32 size = cl->super->virtualTableSize -
+ JavaVirtualTable::getFirstJavaMethodIndex();
+ memcpy(VT->getFirstJavaMethod(), cl->super->virtualVT->getFirstJavaMethod(),
+ size * sizeof(uintptr_t));
+ }
+
+
// Fill the virtual table with function pointers.
ExecutionEngine* EE = mvm::MvmModule::executionEngine;
for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp Sun Apr 19 14:09:19 2009
@@ -654,6 +654,41 @@
Value* obj = pop();
Value* ptr = verifyAndComputePtr(obj, index,
module->JavaArrayObjectType);
+
+ if (TheCompiler->hasExceptionsEnabled()) {
+
+ Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, val,
+ module->JavaObjectNullConstant,
+ "", currentBlock);
+
+ BasicBlock* endBlock = createBasicBlock("end array store check");
+ BasicBlock* checkBlock = createBasicBlock("array store check");
+ BasicBlock* exceptionBlock =
+ createBasicBlock("array store exception");
+ BranchInst::Create(endBlock, checkBlock, cmp, currentBlock);
+ currentBlock = checkBlock;
+
+ Value* valVT = CallInst::Create(module->GetVTFunction, val, "",
+ currentBlock);
+
+ Value* objVT = CallInst::Create(module->GetVTFunction, obj, "",
+ currentBlock);
+ objVT = CallInst::Create(module->GetBaseClassVTFromVTFunction, objVT,
+ "", currentBlock);
+
+ Value* VTArgs[2] = { valVT, objVT };
+
+ Value* res = CallInst::Create(module->IsAssignableFromFunction,
+ VTArgs, VTArgs + 2, "", currentBlock);
+
+ BranchInst::Create(endBlock, exceptionBlock, res, currentBlock);
+
+ currentBlock = exceptionBlock;
+ throwException(module->ArrayStoreExceptionFunction, VTArgs, 1);
+
+ currentBlock = endBlock;
+ }
+
new StoreInst(val, ptr, false, currentBlock);
break;
}
@@ -1978,7 +2013,6 @@
BasicBlock* exceptionCheckcast = 0;
BasicBlock* endCheckcast = 0;
- Value* result = 0;
uint16 index = readU2(bytecodes, i);
UserCommonClass* cl = 0;
@@ -1988,6 +2022,8 @@
Value* cmp = new ICmpInst(ICmpInst::ICMP_EQ, obj,
module->JavaObjectNullConstant,
"", currentBlock);
+ BasicBlock* endBlock = createBasicBlock("end type compare");
+ PHINode* node = PHINode::Create(Type::Int1Ty, "", endBlock);
if (checkcast) {
exceptionCheckcast = createBasicBlock("false checkcast");
@@ -2000,91 +2036,41 @@
currentBlock = exceptionCheckcast;
throwException(module->ClassCastExceptionFunction, args, 2);
currentBlock = ifFalse;
- }
-
- if (cl) {
-
- BasicBlock* ifTrue = createBasicBlock("true type compare");
+ } else {
BasicBlock* ifFalse = createBasicBlock("false type compare");
- BranchInst::Create(ifTrue, ifFalse, cmp, currentBlock);
- PHINode* node = PHINode::Create(Type::Int1Ty, "", ifTrue);
+ BranchInst::Create(endBlock, ifFalse, cmp, currentBlock);
node->addIncoming(ConstantInt::getFalse(), currentBlock);
- Value* objCl = CallInst::Create(module->GetClassFunction, obj, "",
- ifFalse);
- Value* classArgs[2] = { objCl, clVar };
-
- if (isInterface(cl->access)) {
- Value* res = CallInst::Create(module->ImplementsFunction,
- classArgs, classArgs + 2, "",
- ifFalse);
- node->addIncoming(res, ifFalse);
- BranchInst::Create(ifTrue, ifFalse);
- } else {
- cmp = new ICmpInst(ICmpInst::ICMP_EQ, objCl, clVar, "", ifFalse);
- BasicBlock* notEquals = createBasicBlock("false compare");
- BranchInst::Create(ifTrue, notEquals, cmp, ifFalse);
- node->addIncoming(ConstantInt::getTrue(), ifFalse);
-
- if (cl->isPrimitive()) {
- fprintf(stderr, "implement me");
- abort();
- } else if (cl->isArray()) {
- Value* res =
- CallInst::Create(module->InstantiationOfArrayFunction,
- classArgs, classArgs + 2, "", notEquals);
- node->addIncoming(res, notEquals);
- BranchInst::Create(ifTrue, notEquals);
- } else {
- Value* depthCl;
- if (cl->asClass()->isResolved()) {
- depthCl = ConstantInt::get(Type::Int32Ty, cl->depth);
- } else {
- depthCl = CallInst::Create(module->GetDepthFunction,
- clVar, "", notEquals);
- }
-
- Value* depthClObj = CallInst::Create(module->GetDepthFunction,
- objCl, "", notEquals);
- Value* cmp = new ICmpInst(ICmpInst::ICMP_ULE, depthCl, depthClObj,
- "", notEquals);
-
- BasicBlock* supDepth = createBasicBlock("superior depth");
-
- BranchInst::Create(supDepth, ifTrue, cmp, notEquals);
- node->addIncoming(ConstantInt::getFalse(), notEquals);
-
- Value* inDisplay = CallInst::Create(module->GetDisplayFunction,
- objCl, "", supDepth);
-
- Value* displayArgs[2] = { inDisplay, depthCl };
- Value* clInDisplay =
- CallInst::Create(module->GetClassInDisplayFunction, displayArgs,
- displayArgs + 2, "", supDepth);
-
- cmp = new ICmpInst(ICmpInst::ICMP_EQ, clInDisplay, clVar, "",
- supDepth);
- BranchInst::Create(ifTrue, supDepth);
-
- node->addIncoming(cmp, supDepth);
- }
- }
-
- currentBlock = ifTrue;
- result = node;
+ currentBlock = ifFalse;
+ }
+ Value* TheVT = 0;
+ if (!cl) {
+ TheVT = CallInst::Create(module->GetVTFromCommonClassFunction,
+ clVar, "", currentBlock);
} else {
- result = CallInst::Create(module->InstanceOfFunction, args,
- args + 2, "", currentBlock);
-
+ TheVT = TheCompiler->getVirtualTable(cl->virtualVT);
}
+
+ Value* objVT = CallInst::Create(module->GetVTFunction, obj, "",
+ currentBlock);
+ Value* classArgs[2] = { objVT, TheVT };
+
+ Value* res = CallInst::Create(module->IsAssignableFromFunction,
+ classArgs, classArgs + 2, "",
+ currentBlock);
+
+ node->addIncoming(res, currentBlock);
+ BranchInst::Create(endBlock, currentBlock);
+ currentBlock = endBlock;
+
if (checkcast) {
- BranchInst::Create(endCheckcast, exceptionCheckcast, result,
+ BranchInst::Create(endCheckcast, exceptionCheckcast, node,
currentBlock);
currentBlock = endCheckcast;
} else {
pop();
- push(new ZExtInst(result, Type::Int32Ty, "", currentBlock),
+ push(new ZExtInst(node, Type::Int32Ty, "", currentBlock),
false);
}
Modified: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp Sun Apr 19 14:09:19 2009
@@ -62,7 +62,6 @@
llvm::Constant* JnjvmModule::JavaArraySizeConstant;
llvm::ConstantInt* JnjvmModule::OffsetObjectSizeInClassConstant;
llvm::ConstantInt* JnjvmModule::OffsetVTInClassConstant;
-llvm::ConstantInt* JnjvmModule::OffsetVTInClassArrayConstant;
llvm::ConstantInt* JnjvmModule::OffsetDepthInClassConstant;
llvm::ConstantInt* JnjvmModule::OffsetDisplayInClassConstant;
llvm::ConstantInt* JnjvmModule::OffsetTaskClassMirrorInClassConstant;
@@ -84,6 +83,7 @@
llvm::ConstantInt* JnjvmModule::OffsetClassInVTConstant;
llvm::ConstantInt* JnjvmModule::OffsetDepthInVTConstant;
llvm::ConstantInt* JnjvmModule::OffsetDisplayInVTConstant;
+llvm::ConstantInt* JnjvmModule::OffsetBaseClassVTInVTConstant;
JavaLLVMCompiler::JavaLLVMCompiler(const std::string& str) :
@@ -176,43 +176,6 @@
}
#endif
-
-void JavaLLVMCompiler::internalMakeVT(Class* cl) {
-
- for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
- JavaMethod& meth = cl->virtualMethods[i];
- if (meth.name->equals(cl->classLoader->bootstrapLoader->finalize)) {
- meth.offset = 0;
- } else {
- JavaMethod* parent = cl->super?
- cl->super->lookupMethodDontThrow(meth.name, meth.type, false, true,
- 0) :
- 0;
-
- uint64_t offset = 0;
- if (!parent) {
- offset = cl->virtualTableSize++;
- meth.offset = offset;
- } else {
- offset = parent->offset;
- meth.offset = parent->offset;
- }
- }
- }
-
- uint32 size = cl->virtualTableSize;
- if (cl->super) {
- if (!(cl->virtualTableSize >= cl->super->virtualTableSize)) {
- fprintf(stderr, "cl = %s et super = %s\n", cl->printString(), cl->super->printString());
- }
- assert(cl->virtualTableSize >= cl->super->virtualTableSize &&
- "Size of virtual table less than super!");
- }
-
- mvm::BumpPtrAllocator& allocator = cl->classLoader->allocator;
- cl->virtualVT = new(allocator, size) JavaVirtualTable(cl);
-}
-
void JavaLLVMCompiler::resolveVirtualClass(Class* cl) {
// Lock here because we may be called by a class resolver
mvm::MvmModule::protectIR();
@@ -319,14 +282,14 @@
OffsetClassInVTConstant = mvm::MvmModule::constantThree;
OffsetDepthInVTConstant = mvm::MvmModule::constantFour;
OffsetDisplayInVTConstant = mvm::MvmModule::constantFive;
+ OffsetBaseClassVTInVTConstant = ConstantInt::get(Type::Int32Ty, 17);
OffsetDisplayInClassConstant = mvm::MvmModule::constantZero;
OffsetDepthInClassConstant = mvm::MvmModule::constantOne;
OffsetObjectSizeInClassConstant = mvm::MvmModule::constantOne;
- OffsetVTInClassConstant = mvm::MvmModule::constantTwo;
- OffsetVTInClassArrayConstant = mvm::MvmModule::constantTwo;
- OffsetTaskClassMirrorInClassConstant = mvm::MvmModule::constantThree;
+ OffsetVTInClassConstant = ConstantInt::get(Type::Int32Ty, 9);
+ OffsetTaskClassMirrorInClassConstant = mvm::MvmModule::constantTwo;
OffsetStaticInstanceInTaskClassMirrorConstant = mvm::MvmModule::constantTwo;
OffsetStatusInTaskClassMirrorConstant = mvm::MvmModule::constantZero;
OffsetInitializedInTaskClassMirrorConstant = mvm::MvmModule::constantOne;
@@ -384,15 +347,14 @@
ClassLookupFunction = module->getFunction("classLookup");
GetVTFromClassFunction = module->getFunction("getVTFromClass");
GetVTFromClassArrayFunction = module->getFunction("getVTFromClassArray");
+ GetVTFromCommonClassFunction = module->getFunction("getVTFromCommonClass");
+ GetBaseClassVTFromVTFunction = module->getFunction("getBaseClassVTFromVT");
GetObjectSizeFromClassFunction =
module->getFunction("getObjectSizeFromClass");
GetClassDelegateeFunction = module->getFunction("getClassDelegatee");
RuntimeDelegateeFunction = module->getFunction("jnjvmRuntimeDelegatee");
- InstanceOfFunction = module->getFunction("instanceOf");
- IsAssignableFromFunction = module->getFunction("isAssignableFrom");
- ImplementsFunction = module->getFunction("implements");
- InstantiationOfArrayFunction = module->getFunction("instantiationOfArray");
+ IsAssignableFromFunction = module->getFunction("jnjvmIsAssignableFrom");
GetDepthFunction = module->getFunction("getDepth");
GetStaticInstanceFunction = module->getFunction("getStaticInstance");
GetDisplayFunction = module->getFunction("getDisplay");
@@ -416,6 +378,7 @@
NegativeArraySizeExceptionFunction =
module->getFunction("negativeArraySizeException");
OutOfMemoryErrorFunction = module->getFunction("outOfMemoryError");
+ ArrayStoreExceptionFunction = module->getFunction("jnjvmArrayStoreException");
JavaObjectAllocateFunction = module->getFunction("gcmalloc");
Modified: vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp Sun Apr 19 14:09:19 2009
@@ -195,6 +195,18 @@
Changed = true;
Value* val = Call.getArgument(0);
+ Value* indexes[3] = { module->constantZero,
+ module->constantZero,
+ module->OffsetVTInClassConstant };
+ Value* VTPtr = GetElementPtrInst::Create(val, indexes, indexes + 3,
+ "", CI);
+ Value* VT = new LoadInst(VTPtr, "", CI);
+ CI->replaceAllUsesWith(VT);
+ CI->eraseFromParent();
+ } else if (V == module->GetVTFromCommonClassFunction) {
+ Changed = true;
+
+ Value* val = Call.getArgument(0);
Value* indexes[2] = { module->constantZero,
module->OffsetVTInClassConstant };
Value* VTPtr = GetElementPtrInst::Create(val, indexes, indexes + 2,
@@ -206,11 +218,24 @@
Changed = true;
Value* val = Call.getArgument(0);
- Value* indexes[2] = { module->constantZero,
- module->OffsetVTInClassArrayConstant };
+ Value* indexes[3] = { module->constantZero,
+ module->constantZero,
+ module->OffsetVTInClassConstant };
+ Value* VTPtr = GetElementPtrInst::Create(val, indexes, indexes + 3,
+ "", CI);
+ Value* VT = new LoadInst(VTPtr, "", CI);
+ CI->replaceAllUsesWith(VT);
+ CI->eraseFromParent();
+ } else if (V == module->GetBaseClassVTFromVTFunction) {
+ Changed = true;
+
+ Value* val = Call.getArgument(0);
+ Value* indexes[2] = { module->constantZero,
+ module->OffsetBaseClassVTInVTConstant };
Value* VTPtr = GetElementPtrInst::Create(val, indexes, indexes + 2,
"", CI);
Value* VT = new LoadInst(VTPtr, "", CI);
+ VT = new BitCastInst(VT, module->VTType, "", CI);
CI->replaceAllUsesWith(VT);
CI->eraseFromParent();
} else if (V == module->GetObjectSizeFromClassFunction) {
Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original)
+++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Sun Apr 19 14:09:19 2009
@@ -61,7 +61,7 @@
%UTF8*, %UTF8*, i8, i8*, i32, i8* }
%JavaClassPrimitive = type { %JavaCommonClass, i32 }
-%JavaClassArray = type { %JavaCommonClass, %JavaCommonClass*, %VT* }
+%JavaClassArray = type { %JavaCommonClass, %JavaCommonClass* }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; Constant calls for Jnjvm runtime internal objects field accesses ;;;;;;;;;
@@ -82,6 +82,10 @@
;;; getLock - Get the lock of an object.
declare i8* @getLock(%JavaObject*)
+;;; getVTFromCommonClass - Get the VT of a class from its runtime
+;;; representation.
+declare %VT* @getVTFromCommonClass(%JavaCommonClass*) readnone
+
;;; getVTFromClass - Get the VT of a class from its runtime representation.
declare %VT* @getVTFromClass(%JavaClass*) readnone
@@ -93,6 +97,10 @@
;;; representation.
declare i32 @getObjectSizeFromClass(%JavaClass*) readnone
+;;; getBaseClassVTFromVT - Get the VT of the base class of an array, or the
+;;; VT of the array class of a regular class.
+declare %VT* @getBaseClassVTFromVT(%VT*) readnone
+
;;; getDisplay - Get the display array of this class.
declare %JavaCommonClass** @getDisplay(%JavaCommonClass*) readnone
@@ -169,17 +177,8 @@
;;; overflows
declare void @overflowThinLock(%JavaObject*)
-;;; isAssignableFrom - Returns if the objet's class implements the given class.
-declare i1 @instanceOf(%JavaObject*, %JavaCommonClass*) readnone
-
-;;; isAssignableFrom - Returns if the class implements the given class.
-declare i1 @isAssignableFrom(%JavaCommonClass*, %JavaCommonClass*) readnone
-
-;;; implements - Returns if the class implements the given interface.
-declare i1 @implements(%JavaCommonClass*, %JavaCommonClass*) readnone
-
-;;; instantiationOfArray - Returns if the class implements the given array.
-declare i1 @instantiationOfArray(%JavaCommonClass*, %JavaCommonClass*) readnone
+;;; isAssignableFrom - Returns if a type is a subtype of another type.
+declare i1 @jnjvmIsAssignableFrom(%VT*, %VT*) readnone
;;; getClassDelegatee - Returns the java/lang/Class representation of the
;;; class. This method is lowered to the GEP to the class delegatee in
@@ -212,6 +211,7 @@
declare %JavaObject* @indexOutOfBoundsException(%JavaObject*, i32)
declare %JavaObject* @negativeArraySizeException(i32)
declare %JavaObject* @outOfMemoryError(i32)
+declare %JavaObject* @jnjvmArrayStoreException(%VT*)
declare void @JavaThreadThrowException(%JavaObject*)
declare void @jniProceedPendingException()
Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-isolate.ll
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-isolate.ll?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-isolate.ll (original)
+++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-isolate.ll Sun Apr 19 14:09:19 2009
@@ -5,10 +5,11 @@
%Jnjvm = type { %VT*, %JavaClass*, [9 x %JavaClass*] }
%JavaCommonClass = type { %JavaCommonClass**, i32, [32 x %JavaObject*],
- i16, %JavaClass**, i16, %UTF8*, %JavaClass*, i8* }
+ i16, %JavaClass**, i16, %UTF8*, %JavaClass*, i8*,
+ %VT* }
-%JavaClass = type { %JavaCommonClass, i32, %VT*, [32 x %TaskClassMirror], i8*,
+%JavaClass = type { %JavaCommonClass, i32, [32 x %TaskClassMirror], i8*,
%JavaField*, i16, %JavaField*, i16, %JavaMethod*, i16,
%JavaMethod*, i16, i8*, %ArrayUInt8*, i8*, %Attribut*,
i16, %JavaClass**, i16, %JavaClass*, i16, i8, i32, i32, i8*,
Modified: vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-single.ll
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-single.ll?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-single.ll (original)
+++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-single.ll Sun Apr 19 14:09:19 2009
@@ -3,11 +3,11 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%JavaCommonClass = type { %JavaCommonClass**, i32, [1 x %JavaObject*], i16,
- %JavaClass**, i16, %UTF8*, %JavaClass*, i8* }
+ %JavaClass**, i16, %UTF8*, %JavaClass*, i8*, %VT* }
-%JavaClass = type { %JavaCommonClass, i32, %VT*, [1 x %TaskClassMirror], i8*,
- %JavaField*, i16, %JavaField*, i16, %JavaMethod*, i16,
- %JavaMethod*, i16, i8*, %ArrayUInt8*, i8*, %Attribut*,
+%JavaClass = type { %JavaCommonClass, i32, [1 x %TaskClassMirror], i8*,
+ %JavaField*, i16, %JavaField*, i16, %JavaMethod*, i16,
+ %JavaMethod*, i16, i8*, %ArrayUInt8*, i8*, %Attribut*,
i16, %JavaClass**, i16, %JavaClass*, i16, i8, i32, i32, i8*,
void (i8*)* }
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.cpp Sun Apr 19 14:09:19 2009
@@ -253,6 +253,8 @@
display = (CommonClass**)loader->allocator.Allocate(sizeof(CommonClass*));
display[0] = this;
depth = 0;
+ uint32 size = JavaVirtualTable::getBaseSize();
+ virtualVT = new(loader->allocator, size) JavaVirtualTable(this);
access = ACC_ABSTRACT | ACC_FINAL | ACC_PUBLIC | JNJVM_PRIMITIVE;
primSize = nb;
}
@@ -290,7 +292,7 @@
interfaces = ClassArray::InterfacesArray;
nbInterfaces = 2;
- uint32 size = JavaVirtualTable::getNumMethods();
+ uint32 size = JavaVirtualTable::getBaseSize();
virtualVT = new(loader->allocator, size) JavaVirtualTable(this);
depth = 1;
@@ -604,15 +606,43 @@
}
bool UserCommonClass::isAssignableFrom(UserCommonClass* cl) {
+ bool res = false;
if (this == cl) {
- return true;
+ res = true;
} else if (cl->isInterface()) {
- return this->implements(cl);
+ res = this->implements(cl);
} else if (cl->isArray()) {
- return this->instantiationOfArray((UserClassArray*)cl);
+ res = this->instantiationOfArray((UserClassArray*)cl);
} else {
- return this->subclassOf(cl);
+ res = this->subclassOf(cl);
}
+ if(virtualVT && cl->virtualVT && res != virtualVT->isSubtypeOf(cl->virtualVT)) {
+ fprintf(stderr, "wrong result for %s and %s\n", printString(), cl->printString());
+ fprintf(stderr, "I have offset = %d\n", cl->virtualVT->offset);
+ fprintf(stderr, "I have secondary types = %d\n", virtualVT->nbSecondaryTypes);
+ fprintf(stderr, "I have secondary types = %s\n", virtualVT->secondaryTypes[0]->cl->printString());
+ fprintf(stderr, "I have secondary types = %d\n", virtualVT->secondaryTypes[0]->cl->super->virtualVT->nbSecondaryTypes);
+ fprintf(stderr, "I have secondary types = %s\n", virtualVT->secondaryTypes[0]->cl->super->printString());
+ fprintf(stderr, "I have secondary types = %d\n", virtualVT->secondaryTypes[0]->cl->nbInterfaces);
+ abort();
+ }
+ return res;
+}
+
+bool JavaVirtualTable::isSubtypeOf(JavaVirtualTable* otherVT) {
+
+ if (otherVT == ((JavaVirtualTable**)this)[otherVT->offset]) return true;
+ else if (otherVT->offset != getCacheIndex()) return false;
+ else if (this == otherVT) return true;
+ else {
+ for (uint32 i = 0; i < nbSecondaryTypes; ++i) {
+ if (secondaryTypes[i] == otherVT) {
+ cache = otherVT;
+ return true;
+ }
+ }
+ }
+ return false;
}
void JavaField::InitField(void* obj, uint64 val) {
@@ -730,11 +760,13 @@
allocator.Allocate(sizeof(CommonClass*) * (depth + 1));
memcpy(display, super->display, depth * sizeof(UserCommonClass*));
display[depth] = this;
+ virtualTableSize = super->virtualTableSize;
} else {
depth = 0;
display = (CommonClass**)
classLoader->allocator.Allocate(sizeof(CommonClass*));
display[0] = this;
+ virtualTableSize = JavaVirtualTable::getFirstJavaMethodIndex();
}
uint16 nbI = reader.readU2();
@@ -753,12 +785,8 @@
}
void UserClass::loadParents() {
- if (super) {
+ if (super)
super->resolveClass();
- virtualTableSize = super->virtualTableSize;
- } else {
- virtualTableSize = JavaVirtualTable::getFirstJavaMethodIndex();
- }
for (unsigned i = 0; i < nbInterfaces; i++)
interfaces[i]->resolveClass();
@@ -846,6 +874,38 @@
}
}
+void Class::makeVT() {
+
+ for (uint32 i = 0; i < nbVirtualMethods; ++i) {
+ JavaMethod& meth = virtualMethods[i];
+ if (meth.name->equals(classLoader->bootstrapLoader->finalize)) {
+ meth.offset = 0;
+ } else {
+ JavaMethod* parent = super?
+ super->lookupMethodDontThrow(meth.name, meth.type, false, true, 0) :
+ 0;
+
+ uint64_t offset = 0;
+ if (!parent) {
+ offset = virtualTableSize++;
+ meth.offset = offset;
+ } else {
+ offset = parent->offset;
+ meth.offset = parent->offset;
+ }
+ }
+ }
+
+ if (super) {
+ assert(virtualTableSize >= super->virtualTableSize &&
+ "Size of virtual table less than super!");
+ }
+
+ mvm::BumpPtrAllocator& allocator = classLoader->allocator;
+ virtualVT = new(allocator, virtualTableSize) JavaVirtualTable(this);
+}
+
+
void Class::readMethods(Reader& reader) {
uint16 nbMethods = reader.readU2();
virtualMethods = new(classLoader->allocator) JavaMethod[nbMethods];
@@ -901,6 +961,7 @@
readParents(reader);
readFields(reader);
readMethods(reader);
+ makeVT();
attributs = readAttributs(reader, nbAttributs);
setIsRead();
}
@@ -1258,13 +1319,12 @@
// Load base array classes that JnJVM internally uses. Now that the interfaces
// have been loaded, the secondary type can be safely created.
+ upcalls->ArrayOfObject =
+ JCL->constructArray(JCL->asciizConstructUTF8("[Ljava/lang/Object;"));
+
upcalls->ArrayOfString =
JCL->constructArray(JCL->asciizConstructUTF8("[Ljava/lang/String;"));
- upcalls->ArrayOfObject =
- JCL->constructArray(JCL->asciizConstructUTF8("[Ljava/lang/Object;"));
-
-
// Update native array classes. A few things have not been set properly
// when loading these classes because java.lang.Object and java.lang.Object[]
// were not loaded yet. Correct that now by updating these classes.
@@ -1295,10 +1355,6 @@
JavaVirtualTable::JavaVirtualTable(Class* C) {
if (C->super) {
- // Copy the super VT into the current VT.
- uint32 size = C->super->virtualTableSize * sizeof(uintptr_t);
- memcpy(this, C->super->virtualVT, size);
-
// Set the class of this VT.
cl = C;
@@ -1306,11 +1362,17 @@
JavaVirtualTable* superVT = C->super->virtualVT;
depth = superVT->depth + 1;
nbSecondaryTypes = superVT->nbSecondaryTypes + cl->nbInterfaces;
+
+ for (uint32 i = 0; i < cl->nbInterfaces; ++i) {
+ nbSecondaryTypes += cl->interfaces[i]->virtualVT->nbSecondaryTypes;
+ }
uint32 length = getDisplayLength() < depth ? getDisplayLength() : depth;
memcpy(display, superVT->display, length * sizeof(JavaVirtualTable*));
uint32 outOfDepth = 0;
- if (depth < getDisplayLength()) {
+ if (C->isInterface()) {
+ offset = getCacheIndex();
+ } else if (depth < getDisplayLength()) {
display[depth] = this;
offset = getCacheIndex() + depth + 1;
} else {
@@ -1338,6 +1400,15 @@
uint32 index = superVT->nbSecondaryTypes + outOfDepth + i;
secondaryTypes[index] = cur;
}
+
+ uint32 lastIndex = superVT->nbSecondaryTypes + cl->nbInterfaces +
+ outOfDepth;
+
+ for (uint32 i = 0; i < cl->nbInterfaces; ++i) {
+ JavaVirtualTable* cur = cl->interfaces[i]->virtualVT;
+ memcpy(secondaryTypes + lastIndex, cur->secondaryTypes,
+ sizeof(JavaVirtualTable*) * cur->nbSecondaryTypes);
+ }
} else {
// Set the tracer, destructor and delete
@@ -1361,11 +1432,16 @@
}
JavaVirtualTable::JavaVirtualTable(ClassArray* C) {
-
+
+ baseClassVT = C->baseClass()->virtualVT;
+ assert(baseClassVT && "Not base VT when creating an array");
+
if (!C->baseClass()->isPrimitive()) {
// Copy the super VT into the current VT.
- uint32 size = getNumMethods() * sizeof(uintptr_t);
- memcpy(this, C->super->virtualVT, size);
+ uint32 size = (getBaseSize() - getFirstJavaMethodIndex());
+ memcpy(this->getFirstJavaMethod(),
+ C->super->virtualVT->getFirstJavaMethod(),
+ size * sizeof(uintptr_t));
tracer = (uintptr_t)ArrayObjectTracer;
// Set the class of this VT.
@@ -1401,7 +1477,12 @@
uint32 length = getDisplayLength() < depth ? getDisplayLength() : depth;
memcpy(display, superVT->display, length * sizeof(JavaVirtualTable*));
- if (depth < getDisplayLength()) display[depth] = this;
+ if (depth < getDisplayLength()) {
+ display[depth] = this;
+ offset = getCacheIndex() + depth + 1;
+ } else {
+ offset = getCacheIndex();
+ }
mvm::BumpPtrAllocator& allocator = JCL->allocator;
@@ -1484,7 +1565,8 @@
depth = 1;
display[0] = C->super->virtualVT;
display[1] = this;
- nbSecondaryTypes = 2;
+ offset = getCacheIndex() + 2;
+ nbSecondaryTypes = 2;
mvm::BumpPtrAllocator& allocator = JCL->allocator;
secondaryTypes = (JavaVirtualTable**)
@@ -1510,6 +1592,7 @@
display[0] = 0;
display[1] = this;
nbSecondaryTypes = 2;
+ offset = getCacheIndex() + 2;
// The list of secondary types has not been allocated yet by
// java.lang.Object[]. The initialiseVT function will update the current
@@ -1517,3 +1600,11 @@
}
}
+
+JavaVirtualTable::JavaVirtualTable(ClassPrimitive* C) {
+ // Only used for subtype checking
+ depth = 0;
+ display[0] = this;
+ nbSecondaryTypes = 0;
+ offset = getCacheIndex() + 1;
+}
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Sun Apr 19 14:09:19 2009
@@ -187,6 +187,11 @@
/// classLoader - The Jnjvm class loader that loaded the class.
///
JnjvmClassLoader* classLoader;
+
+ /// virtualVT - The virtual table of instances of this class.
+ ///
+ JavaVirtualTable* virtualVT;
+
//===----------------------------------------------------------------------===//
//
@@ -454,10 +459,6 @@
///
uint32 virtualSize;
- /// virtualVT - The virtual table of instances of this class.
- ///
- JavaVirtualTable* virtualVT;
-
/// IsolateInfo - Per isolate informations for static instances and
/// initialization state.
///
@@ -900,7 +901,13 @@
/// needsInitialisationCheck - Does the method need an initialisation check?
///
bool needsInitialisationCheck();
-
+
+private:
+
+ /// makeVT - Create the virtual table of this class.
+ ///
+ void makeVT();
+
};
/// ClassArray - This class represents Java array classes.
@@ -918,10 +925,6 @@
///
CommonClass* _baseClass;
- /// virtualVT - The virtual table of this array class.
- ///
- JavaVirtualTable* virtualVT;
-
/// baseClass - Get the base class of this array class.
///
CommonClass* baseClass() const {
@@ -1339,16 +1342,52 @@
};
+/// JavaVirtualTable - This class is the virtual table of instances of
+/// Java classes. Besides holding function pointers for virtual calls,
+/// it contains a bunch of information useful for fast dynamic type checking.
+/// These are placed here for fast access of information from a Java object
+/// (that only points to the VT, not the class).
+///
class JavaVirtualTable : public VirtualTable {
public:
+
+ /// cl - The class which defined this virtual table.
+ ///
CommonClass* cl;
+
+ /// depth - The super hierarchy depth of the class.
+ ///
size_t depth;
+
+ /// offset - Offset in the virtual table where this virtual
+ /// table may be pointed. The offset is the cache if the class
+ /// is an interface or depth is too big, or an offset in the display.
+ ///
size_t offset;
- size_t cache;
+
+ /// cache - The cached result for better type checks on secondary types.
+ ///
+ JavaVirtualTable* cache;
+
+ /// display - Array of super classes.
+ ///
JavaVirtualTable* display[8];
+
+ /// nbSecondaryTypes - The length of the secondary type list.
+ ///
size_t nbSecondaryTypes;
+
+ /// secondaryTypes - The list of secondary types of this type. These
+ /// are the interface and all the supers whose depth is too big.
+ ///
JavaVirtualTable** secondaryTypes;
+ /// baseClass - Holds the base class VT of an array, or the array class VT
+ /// of a regular class.
+ ///
+ JavaVirtualTable* baseClassVT;
+
+ /// Java methods for the virtual table functions.
uintptr_t init;
uintptr_t equals;
uintptr_t hashCode;
@@ -1362,40 +1401,67 @@
uintptr_t waitMsNs;
uintptr_t virtualMethods[1];
+ /// operator new - Allocates a JavaVirtualTable with the given size. The
+ /// size must contain the additional information for type checking, as well
+ /// as the function pointers.
+ ///
void* operator new(size_t sz, mvm::BumpPtrAllocator& allocator,
uint32 nbMethods) {
return allocator.Allocate(sizeof(uintptr_t) * (nbMethods));
}
+ /// JavaVirtualTable - Create JavaVirtualTable objects for classes, array
+ /// classes and primitive classes.
+ ///
JavaVirtualTable(Class* C);
-
JavaVirtualTable(ClassArray* C);
+ JavaVirtualTable(ClassPrimitive* C);
+
+ /// getFirstJavaMethod - Get the byte offset of the first Java method
+ /// (<init>).
+ ///
uintptr_t* getFirstJavaMethod() {
return &init;
}
+ /// getFirstJavaMethodIndex - Get the word offset of the first Java method.
+ ///
static uint32_t getFirstJavaMethodIndex() {
- return 17;
+ return 18;
}
- static uint32_t getNumMethods() {
- return 28;
+ /// getBaseSize - Get the size of the java.lang.Object virtual table.
+ ///
+ static uint32_t getBaseSize() {
+ return 29;
}
+ /// getNumJavaMethods - Get the number of methods of the java.lang.Object
+ /// class.
+ ///
static uint32_t getNumJavaMethods() {
return 11;
}
+ /// getDisplayLength - Get the length of the display (primary type) array.
+ ///
static uint32_t getDisplayLength() {
return 8;
}
-private:
+ /// getCacheIndex - Get the word offset of the type cache.
+ ///
static uint32_t getCacheIndex() {
return 6;
}
+ /// isSubtypeOf - Returns true if the given VT is a subtype of the this
+ /// VT.
+ ///
+ bool isSubtypeOf(JavaVirtualTable* VT);
+
+
};
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Sun Apr 19 14:09:19 2009
@@ -409,24 +409,9 @@
}
// Never throws.
-extern "C" bool instanceOf(JavaObject* obj, UserCommonClass* cl) {
- return obj->instanceOf(cl);
-}
-
-// Never throws.
-extern "C" bool instantiationOfArray(UserCommonClass* cl1,
- UserClassArray* cl2) {
- return cl1->instantiationOfArray(cl2);
-}
-
-// Never throws.
-extern "C" bool implements(UserCommonClass* cl1, UserCommonClass* cl2) {
- return cl1->implements(cl2);
-}
-
-// Never throws.
-extern "C" bool isAssignableFrom(UserCommonClass* cl1, UserCommonClass* cl2) {
- return cl1->isAssignableFrom(cl2);
+extern "C" bool jnjvmIsAssignableFrom(JavaVirtualTable* VT1,
+ JavaVirtualTable* VT2) {
+ return VT1->isSubtypeOf(VT2);
}
// Does not call any Java code.
@@ -542,22 +527,39 @@
return exc;
}
+// Creates a Java object and then throws it.
+extern "C" JavaObject* jnjvmArrayStoreException(JavaVirtualTable* VT) {
+ JavaObject *exc = 0;
+ JavaThread *th = JavaThread::get();
+
+ BEGIN_NATIVE_EXCEPTION(1)
+
+ exc = th->getJVM()->CreateArrayStoreException(VT);
+
+ END_NATIVE_EXCEPTION
+
+#ifdef DWARF_EXCEPTIONS
+ th->throwException(exc);
+#else
+ th->pendingException = exc;
+#endif
+
+ return exc;
+}
+
extern "C" void printMethodStart(JavaMethod* meth) {
- printf("[%p] executing %s\n", (void*)mvm::Thread::get(),
+ fprintf(stderr, "[%p] executing %s\n", (void*)mvm::Thread::get(),
meth->printString());
- fflush(stdout);
}
extern "C" void printMethodEnd(JavaMethod* meth) {
- printf("[%p] return from %s\n", (void*)mvm::Thread::get(),
+ fprintf(stderr, "[%p] return from %s\n", (void*)mvm::Thread::get(),
meth->printString());
- fflush(stdout);
}
extern "C" void printExecution(uint32 opcode, uint32 index, JavaMethod* meth) {
- printf("[%p] executing %s %s at %d\n", (void*)mvm::Thread::get(),
+ fprintf(stderr, "[%p] executing %s %s at %d\n", (void*)mvm::Thread::get(),
meth->printString(), OpcodeNames[opcode], index);
- fflush(stdout);
}
#ifdef SERVICE
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.cpp Sun Apr 19 14:09:19 2009
@@ -325,6 +325,12 @@
"Java heap space");
}
+JavaObject* Jnjvm::CreateArrayStoreException(JavaVirtualTable* VT) {
+ return CreateError(upcalls->ArrayStoreException,
+ upcalls->InitArrayStoreException,
+ VT->cl->printString());
+}
+
JavaObject* Jnjvm::CreateClassCastException(JavaObject* obj,
UserCommonClass* cl) {
return CreateError(upcalls->ClassCastException,
Modified: vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h?rev=69533&r1=69532&r2=69533&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/Jnjvm.h Sun Apr 19 14:09:19 2009
@@ -252,6 +252,7 @@
JavaObject* CreateNegativeArraySizeException();
JavaObject* CreateClassCastException(JavaObject* obj, UserCommonClass* cl);
JavaObject* CreateLinkageError(const char* msg = "");
+ JavaObject* CreateArrayStoreException(JavaVirtualTable* VT);
/// Exceptions - These are the only exceptions VMKit will make.
///
More information about the vmkit-commits
mailing list