[vmkit-commits] [vmkit] r197924 - Generate an invoke interface with the IMT algorithm. Not yet resolved.

Gael Thomas gael.thomas at lip6.fr
Mon Dec 23 14:41:02 PST 2013


Author: gthomas
Date: Mon Dec 23 16:41:01 2013
New Revision: 197924

URL: http://llvm.org/viewvc/llvm-project?rev=197924&view=rev
Log:
Generate an invoke interface with the IMT algorithm. Not yet resolved.

Modified:
    vmkit/branches/mcjit/include/j3/j3.h
    vmkit/branches/mcjit/include/j3/j3object.h
    vmkit/branches/mcjit/include/j3/j3thread.h
    vmkit/branches/mcjit/include/j3/j3trampoline.h
    vmkit/branches/mcjit/lib/j3/vm/j3.cc
    vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc
    vmkit/branches/mcjit/lib/j3/vm/j3object.cc
    vmkit/branches/mcjit/lib/j3/vm/j3trampoline.cc

Modified: vmkit/branches/mcjit/include/j3/j3.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3.h?rev=197924&r1=197923&r2=197924&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3.h (original)
+++ vmkit/branches/mcjit/include/j3/j3.h Mon Dec 23 16:41:01 2013
@@ -50,6 +50,8 @@ namespace j3 {
 		onJavaTypes(defPrimitive)
 #undef defPrimitive
 
+		void*            interfaceTrampoline;
+
 		J3Type**         arrayInterfaces;
 		uint32_t         nbArrayInterfaces;
 		J3Class*         objectClass;

Modified: vmkit/branches/mcjit/include/j3/j3object.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3object.h?rev=197924&r1=197923&r2=197924&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3object.h (original)
+++ vmkit/branches/mcjit/include/j3/j3object.h Mon Dec 23 16:41:01 2013
@@ -42,11 +42,14 @@ namespace j3 {
 	public:
 		static const uint32_t nbInterfaceMethodTable = 23;
 		static const uint32_t gepObjectClass = 0;
+		static const uint32_t gepInterfaceMethods = 2;
 		static const uint32_t gepVirtualMethods = 4;
 
 	private:
 		J3Type*               _type;
 		J3TypeChecker         checker;
+		// see: Bowen Alpern, Anthony Cocchi, Stephen Fink, and David Grove. 2001. 
+		// Efficient implementation of Java interfaces: Invokeinterface considered harmless. OOPSLA 2001.
 		void*                 _interfaceMethodTable[nbInterfaceMethodTable];
 		size_t                _nbVirtualMethods;
 		void*                 _virtualMethods[1];

Modified: vmkit/branches/mcjit/include/j3/j3thread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3thread.h?rev=197924&r1=197923&r2=197924&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3thread.h (original)
+++ vmkit/branches/mcjit/include/j3/j3thread.h Mon Dec 23 16:41:01 2013
@@ -14,6 +14,11 @@ namespace j3 {
 	class J3;
 
 	class J3Thread : public vmkit::Thread {
+	public:
+		static const uint32_t gepInterfaceMethodIndex = 1;
+
+	private:
+		uint32_t                   _interfaceMethodIndex;
 		vmkit::BumpAllocator*      allocator;
 		JNIEnv                     _jniEnv;
 		J3LocalReferences          _localReferences;
@@ -23,7 +28,9 @@ namespace j3 {
 	public:
 		static J3Thread*  create(J3* j3);
 
-		J3Method*         getJavaCaller(uint32_t level=0);
+		J3Method*          getJavaCaller(uint32_t level=0);
+
+		uint32_t           interfaceMethodIndex() { return _interfaceMethodIndex; }
 
 		void               ensureCapacity(uint32_t capacity);
 		J3ObjectHandle*    pendingException();

Modified: vmkit/branches/mcjit/include/j3/j3trampoline.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3trampoline.h?rev=197924&r1=197923&r2=197924&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3trampoline.h (original)
+++ vmkit/branches/mcjit/include/j3/j3trampoline.h Mon Dec 23 16:41:01 2013
@@ -10,6 +10,7 @@ namespace j3 {
 	class J3Object;
 
 	class J3Trampoline {
+		static void* interfaceTrampoline(J3Object* obj);
 		static void* staticTrampoline(J3Object* obj, J3Method* ref);
 		static void* virtualTrampoline(J3Object* obj, J3Method* ref);
 
@@ -17,6 +18,7 @@ namespace j3 {
 	public:
 		static void* buildStaticTrampoline(vmkit::BumpAllocator* allocator, J3Method* target);
 		static void* buildVirtualTrampoline(vmkit::BumpAllocator* allocator, J3Method* target);
+		static void* buildInterfaceTrampoline(vmkit::BumpAllocator* allocator);
 	};
 };
 

Modified: vmkit/branches/mcjit/lib/j3/vm/j3.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3.cc?rev=197924&r1=197923&r2=197924&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3.cc Mon Dec 23 16:41:01 2013
@@ -8,6 +8,7 @@
 #include "j3/j3constants.h"
 #include "j3/j3method.h"
 #include "j3/j3thread.h"
+#include "j3/j3trampoline.h"
 
 #include "llvm/IR/Type.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -30,6 +31,7 @@ J3::J3(vmkit::BumpAllocator* allocator)
 	clinitName =        names()->get(J3Cst::clinitName);
 	clinitSign =        names()->get(J3Cst::clinitSign);
 	initName =          names()->get(J3Cst::initName);
+	interfaceTrampoline = J3Trampoline::buildInterfaceTrampoline(allocator);
 }
 
 J3* J3::create() {

Modified: vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc?rev=197924&r1=197923&r2=197924&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc Mon Dec 23 16:41:01 2013
@@ -263,9 +263,22 @@ void J3CodeGen::invoke(J3Method* target,
 }
 
 void J3CodeGen::invokeInterface(uint32_t idx) {
-	J3Method*     target = cl->interfaceMethodAt(idx, 0);
-	fprintf(stderr, "---> %d\n", target->interfaceIndex());
-	J3::internalError(L"implement me: invokeInterface");
+	J3Method* target = cl->interfaceMethodAt(idx, 0);
+	J3MethodType* type = target->methodType(cl);
+
+	uint32_t     index = target->interfaceIndex();
+	llvm::Value* thread = builder->CreateCall(funcJ3ThreadGet);
+	llvm::Value* gep[] = { builder->getInt32(0), builder->getInt32(J3Thread::gepInterfaceMethodIndex) };
+	builder->CreateStore(builder->getInt32(index), builder->CreateGEP(thread, gep));
+
+	llvm::Value*  obj = nullCheck(stack.top(type->nbIns() - 1));
+	llvm::Value*  gepFunc[] = { builder->getInt32(0),
+															builder->getInt32(J3VirtualTable::gepInterfaceMethods),
+															builder->getInt32(index % J3VirtualTable::nbInterfaceMethodTable) };
+	llvm::Value* func = builder->CreateBitCast(builder->CreateLoad(builder->CreateGEP(vt(obj), gepFunc)), 
+																						 type->llvmType()->getPointerTo());
+
+	invoke(target, func);
 }
 
 void J3CodeGen::invokeVirtual(uint32_t idx) {

Modified: vmkit/branches/mcjit/lib/j3/vm/j3object.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3object.cc?rev=197924&r1=197923&r2=197924&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3object.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3object.cc Mon Dec 23 16:41:01 2013
@@ -65,14 +65,32 @@ J3VirtualTable* J3VirtualTable::create(J
 	J3VirtualTable* res = new(cl->loader()->allocator(), n) 
 		J3VirtualTable(cl, cl->super(), (J3Type**)cl->interfaces(), cl->nbInterfaces(), J3Cst::isInterface(cl->access()) ? 1 : 0);
 
-
 	/* virtual table */
 	res->_nbVirtualMethods = n;
 	if(super != cl)  /* super->vt() is not yet allocated for Object */
 		memcpy(res->_virtualMethods, super->vt()->_virtualMethods, sizeof(void*)*super->vt()->nbVirtualMethods());
 
-	//	for(uint32_t i=0; i<nbInterfaceMethodTable; i++)
-	//		res->_interfaceMethodTable[i] = 
+	struct {
+		uint32_t   nbSlots;
+		J3Method** slots;
+	} slots[nbInterfaceMethodTable];
+	
+	for(uint32_t i=0; i<nbInterfaceMethodTable; i++)
+		slots[i].nbSlots = 0;
+
+	for(uint32_t i=0; i<res->checker.nbSecondaryTypes; i++) {
+		J3Class* cl = res->checker.secondaryTypes[i]->type()->asClass();
+		if(J3Cst::isInterface(cl->access())) {
+			for(uint32_t j=0; j<cl->nbMethods(); j++) {
+				J3Method* m = cl->methods()[j];
+				fprintf(stderr, "[%d] method: %ls::%ls\n", i, cl->name()->cStr(), m->name()->cStr());
+			}
+		}
+	}
+
+	void* interfaceTrampoline = cl->loader()->vm()->interfaceTrampoline;
+	for(uint32_t i=0; i<nbInterfaceMethodTable; i++)
+		res->_interfaceMethodTable[i] = interfaceTrampoline;
 
 	for(uint32_t i=0; i<cl->nbMethods(); i++) 
 		res->_virtualMethods[pm[i]->index()] = pm[i]->functionPointerOrVirtualTrampoline();
@@ -187,16 +205,16 @@ J3VirtualTable::J3VirtualTable(J3Type* t
 			checker.display[checker.offset] = this;
 		} 
 
-		for(uint32_t i=0; i<nbInterfaces; i++) {
+		memcpy(checker.secondaryTypes + isSecondary, 
+					 super->vt()->checker.secondaryTypes, 
+					 super->vt()->checker.nbSecondaryTypes*sizeof(J3VirtualTable*));
+
+		for(uint32_t i=0, n=isSecondary+super->vt()->checker.nbSecondaryTypes; i<nbInterfaces; i++) {
 			J3Type* sec = interfaces[i];
 			//printf("In %ls - adding %ls at %d\n", type->name()->cStr(), sec->name()->cStr(), isSecondary+i);
 			sec->resolve();
-			checker.secondaryTypes[isSecondary+i] = sec->vt();
+			checker.secondaryTypes[n++] = sec->vt();
 		}
-		
-		memcpy(checker.secondaryTypes + nbInterfaces + isSecondary, 
-					 super->vt()->checker.secondaryTypes, 
-					 super->vt()->checker.nbSecondaryTypes*sizeof(J3VirtualTable*));
 	}
 
 	//dump();

Modified: vmkit/branches/mcjit/lib/j3/vm/j3trampoline.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3trampoline.cc?rev=197924&r1=197923&r2=197924&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3trampoline.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3trampoline.cc Mon Dec 23 16:41:01 2013
@@ -7,6 +7,16 @@
 
 using namespace j3;
 
+void* J3Trampoline::interfaceTrampoline(J3Object* obj) {
+	J3ObjectHandle* prev = J3Thread::get()->tell();
+	J3ObjectHandle* handle = J3Thread::get()->push(obj);
+	uint32_t index = J3Thread::get()->interfaceMethodIndex();
+	fprintf(stderr, "%d - %ls\n", index, handle->vt()->type()->name()->cStr());
+
+	J3Thread::get()->restore(prev);
+	J3::internalError(L"implement me: interface Trampoline");
+}
+
 void* J3Trampoline::staticTrampoline(J3Object* obj, J3Method* target) {
 	return target->fnPtr();
 }
@@ -81,3 +91,7 @@ void* J3Trampoline::buildStaticTrampolin
 void* J3Trampoline::buildVirtualTrampoline(vmkit::BumpAllocator* allocator, J3Method* method) {
 	return buildTrampoline(allocator, method, (void*)virtualTrampoline);
 }
+
+void* J3Trampoline::buildInterfaceTrampoline(vmkit::BumpAllocator* allocator) {
+	return buildTrampoline(allocator, 0, (void*)interfaceTrampoline);
+}





More information about the vmkit-commits mailing list