[vmkit-commits] [vmkit] r69885 - in /vmkit/trunk/lib/JnJVM: Compiler/JnjvmModule.cpp Compiler/LowerConstantCalls.cpp LLVMRuntime/runtime-default.ll VMCore/JavaClass.h VMCore/JavaRuntimeJIT.cpp
Nicolas Geoffray
nicolas.geoffray at lip6.fr
Thu Apr 23 04:23:13 PDT 2009
Author: geoffray
Date: Thu Apr 23 06:22:53 2009
New Revision: 69885
URL: http://llvm.org/viewvc/llvm-project?rev=69885&view=rev
Log:
Inline dynamic runtime checks.
Modified:
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/VMCore/JavaClass.h
vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
Modified: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp?rev=69885&r1=69884&r2=69885&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp Thu Apr 23 06:22:53 2009
@@ -349,7 +349,7 @@
GetClassDelegateeFunction = module->getFunction("getClassDelegatee");
RuntimeDelegateeFunction = module->getFunction("jnjvmRuntimeDelegatee");
- IsAssignableFromFunction = module->getFunction("jnjvmIsAssignableFrom");
+ IsAssignableFromFunction = module->getFunction("isAssignableFrom");
IsSecondaryClassFunction = module->getFunction("isSecondaryClass");
GetDepthFunction = module->getFunction("getDepth");
GetStaticInstanceFunction = module->getFunction("getStaticInstance");
Modified: vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp?rev=69885&r1=69884&r2=69885&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/LowerConstantCalls.cpp Thu Apr 23 06:22:53 2009
@@ -523,16 +523,165 @@
Value* res = new LoadInst(val, "", CI);
CI->replaceAllUsesWith(res);
CI->eraseFromParent();
+ } else if (V == module->IsAssignableFromFunction) {
+ Changed = true;
+ Value* VT1 = Call.getArgument(0);
+ Value* VT2 = Call.getArgument(1);
+
+ BasicBlock* EndBlock = II->getParent()->splitBasicBlock(II);
+ I->getParent()->getTerminator()->eraseFromParent();
+
+ BasicBlock* CurEndBlock = BasicBlock::Create("", &F);
+ BasicBlock* FailedBlock = BasicBlock::Create("", &F);
+ PHINode* node = PHINode::Create(Type::Int1Ty, "", CurEndBlock);
+
+ ConstantInt* CC = ConstantInt::get(Type::Int32Ty,
+ JavaVirtualTable::getOffsetIndex());
+ Value* indices[2] = { module->constantZero, CC };
+ Value* Offset = GetElementPtrInst::Create(VT2, indices, indices + 2,
+ "", CI);
+ Offset = new LoadInst(Offset, "", false, CI);
+ Offset = new PtrToIntInst(Offset, Type::Int32Ty, "", CI);
+ indices[1] = Offset;
+ Value* CurVT = GetElementPtrInst::Create(VT1, indices, indices + 2,
+ "", CI);
+ CurVT = new LoadInst(CurVT, "", false, CI);
+ CurVT = new BitCastInst(CurVT, module->VTType, "", CI);
+
+ Value* res = new ICmpInst(ICmpInst::ICMP_EQ, CurVT, VT2, "", CI);
+
+ node->addIncoming(ConstantInt::getTrue(), CI->getParent());
+ BranchInst::Create(CurEndBlock, FailedBlock, res, CI);
+
+ Value* Args[2] = { VT1, VT2 };
+ res = CallInst::Create(module->IsSecondaryClassFunction, Args,
+ Args + 2, "", FailedBlock);
+
+ node->addIncoming(res, FailedBlock);
+ BranchInst::Create(CurEndBlock, FailedBlock);
+
+ // Branch to the next block.
+ BranchInst::Create(EndBlock, CurEndBlock);
+
+ // We can now replace the previous instruction.
+ CI->replaceAllUsesWith(node);
+ CI->eraseFromParent();
+
+ // Reanalyse the current block.
+ break;
+
} else if (V == module->IsSecondaryClassFunction) {
Changed = true;
Value* VT1 = Call.getArgument(0);
Value* VT2 = Call.getArgument(1);
+
+ BasicBlock* EndBlock = II->getParent()->splitBasicBlock(II);
+ I->getParent()->getTerminator()->eraseFromParent();
- Value* args[2] = { VT1, VT2 };
- CallInst* res = CallInst::Create(module->IsAssignableFromFunction,
- args, args + 2, "", CI);
- CI->replaceAllUsesWith(res);
+
+ BasicBlock* Preheader = BasicBlock::Create("preheader", &F);
+ BasicBlock* BB4 = BasicBlock::Create("BB4", &F);
+ BasicBlock* BB5 = BasicBlock::Create("BB5", &F);
+ BasicBlock* BB6 = BasicBlock::Create("BB6", &F);
+ BasicBlock* BB7 = BasicBlock::Create("BB7", &F);
+ BasicBlock* BB9 = BasicBlock::Create("BB9", &F);
+ const Type* Ty = PointerType::getUnqual(module->VTType);
+
+ PHINode* resFwd = PHINode::Create(Type::Int32Ty, "", BB7);
+
+ // This corresponds to:
+ // if (VT1.cache == VT2 || VT1 == VT2) goto end with true;
+ // else goto headerLoop;
+ ConstantInt* cacheIndex =
+ ConstantInt::get(Type::Int32Ty, JavaVirtualTable::getCacheIndex());
+ Value* indices[2] = { module->constantZero, cacheIndex };
+ Instruction* CachePtr =
+ GetElementPtrInst::Create(VT1, indices, indices + 2, "", CI);
+ CachePtr = new BitCastInst(CachePtr, Ty, "", CI);
+ Value* Cache = new LoadInst(CachePtr, "", false, CI);
+ ICmpInst* cmp1 = new ICmpInst(ICmpInst::ICMP_EQ, Cache, VT2, "", CI);
+ ICmpInst* cmp2 = new ICmpInst(ICmpInst::ICMP_EQ, VT1, VT2, "", CI);
+ BinaryOperator* Or = BinaryOperator::Create(Instruction::Or, cmp1,
+ cmp2, "", CI);
+ BranchInst::Create(BB9, Preheader, Or, CI);
+
+ // First test failed. Go into the loop. The Preheader looks like this:
+ // headerLoop:
+ // types = VT1->secondaryTypes;
+ // size = VT1->nbSecondaryTypes;
+ // i = 0;
+ // goto test;
+ ConstantInt* sizeIndex = ConstantInt::get(Type::Int32Ty,
+ JavaVirtualTable::getNumSecondaryTypesIndex());
+ indices[1] = sizeIndex;
+ Instruction* Size = GetElementPtrInst::Create(VT1, indices,
+ indices + 2, "",
+ Preheader);
+ Size = new LoadInst(Size, "", false, Preheader);
+ Size = new PtrToIntInst(Size, Type::Int32Ty, "", Preheader);
+
+ ConstantInt* secondaryTypesIndex = ConstantInt::get(Type::Int32Ty,
+ JavaVirtualTable::getSecondaryTypesIndex());
+ indices[1] = secondaryTypesIndex;
+ Instruction* secondaryTypes =
+ GetElementPtrInst::Create(VT1, indices, indices + 2, "", Preheader);
+ secondaryTypes = new LoadInst(secondaryTypes, "", false, Preheader);
+ secondaryTypes = new BitCastInst(secondaryTypes, Ty, "", Preheader);
+ BranchInst::Create(BB7, Preheader);
+
+ // Here is the test if the current secondary type is VT2.
+ // test:
+ // CurVT = types[i];
+ // if (CurVT == VT2) goto update cache;
+ // est goto inc;
+ Instruction* CurVT = GetElementPtrInst::Create(secondaryTypes, resFwd,
+ "", BB4);
+ CurVT = new LoadInst(CurVT, "", false, BB4);
+ cmp1 = new ICmpInst(ICmpInst::ICMP_EQ, CurVT, VT2, "", BB4);
+ BranchInst::Create(BB5, BB6, cmp1, BB4);
+
+ // Increment i if the previous test failed
+ // inc:
+ // ++i;
+ // goto endLoopTest;
+ BinaryOperator* IndVar =
+ BinaryOperator::CreateAdd(resFwd, module->constantOne, "", BB6);
+ BranchInst::Create(BB7, BB6);
+
+ // Verify that we haven't reached the end of the loop:
+ // endLoopTest:
+ // if (i < size) goto test
+ // else goto end with false
+ resFwd->reserveOperandSpace(2);
+ resFwd->addIncoming(module->constantZero, Preheader);
+ resFwd->addIncoming(IndVar, BB6);
+
+ cmp1 = new ICmpInst(ICmpInst::ICMP_SGT, Size, resFwd, "", BB7);
+ BranchInst::Create(BB4, BB9, cmp1, BB7);
+
+ // Update the cache if the result is found.
+ // updateCache:
+ // VT1->cache = result
+ // goto end with true
+ new StoreInst(VT2, CachePtr, false, BB5);
+ BranchInst::Create(BB9, BB5);
+
+ // Final block, that gets the result.
+ PHINode* node = PHINode::Create(Type::Int1Ty, "", BB9);
+ node->reserveOperandSpace(3);
+ node->addIncoming(ConstantInt::getTrue(), CI->getParent());
+ node->addIncoming(ConstantInt::getFalse(), BB7);
+ node->addIncoming(ConstantInt::getTrue(), BB5);
+
+ // Don't forget to jump to the next block.
+ BranchInst::Create(EndBlock, BB9);
+
+ // We can now replace the previous instruction
+ CI->replaceAllUsesWith(node);
CI->eraseFromParent();
+
+ // And reanalyse the current block.
+ break;
}
#ifdef ISOLATE_SHARING
else if (V == module->GetCtpClassFunction) {
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=69885&r1=69884&r2=69885&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll (original)
+++ vmkit/trunk/lib/JnJVM/LLVMRuntime/runtime-default.ll Thu Apr 23 06:22:53 2009
@@ -178,9 +178,9 @@
declare void @overflowThinLock(%JavaObject*)
;;; isAssignableFrom - Returns if a type is a subtype of another type.
-declare i1 @jnjvmIsAssignableFrom(%VT*, %VT*) readnone
+declare i1 @isAssignableFrom(%VT*, %VT*) readnone
-;;; isAssignableFrom - Returns if a type is a secondary super type of
+;;; isSecondaryClass - Returns if a type is a secondary super type of
;;; another type.
declare i1 @isSecondaryClass(%VT*, %VT*) readnone
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h?rev=69885&r1=69884&r2=69885&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaClass.h Thu Apr 23 06:22:53 2009
@@ -98,7 +98,7 @@
JavaVirtualTable** secondaryTypes;
/// baseClass - Holds the base class VT of an array, or the array class VT
- /// of a regular class.
+ /// of a regular class. Used for AASTORE checks.
///
JavaVirtualTable* baseClassVT;
@@ -181,7 +181,14 @@
/// list.
///
static uint32_t getSecondaryTypesIndex() {
- return 5;
+ return 16;
+ }
+
+ /// getNumSecondaryTypesIndex - Get the word offset of the number of
+ /// secondary types.
+ ///
+ static uint32_t getNumSecondaryTypesIndex() {
+ return 15;
}
/// isSubtypeOf - Returns true if the given VT is a subtype of the this
Modified: vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp?rev=69885&r1=69884&r2=69885&view=diff
==============================================================================
--- vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/VMCore/JavaRuntimeJIT.cpp Thu Apr 23 06:22:53 2009
@@ -408,12 +408,6 @@
obj->release();
}
-// Never throws.
-extern "C" bool jnjvmIsAssignableFrom(JavaVirtualTable* VT1,
- JavaVirtualTable* VT2) {
- return VT1->isSubtypeOf(VT2);
-}
-
// Does not call any Java code.
extern "C" void JavaThreadThrowException(JavaObject* obj) {
return JavaThread::get()->throwException(obj);
More information about the vmkit-commits
mailing list