[vmkit-commits] [vmkit] r198282 - As MCJIT does not implement properly runFunction, generate a function

Gael Thomas gael.thomas at lip6.fr
Wed Jan 1 13:29:08 PST 2014


Author: gthomas
Date: Wed Jan  1 15:29:07 2014
New Revision: 198282

URL: http://llvm.org/viewvc/llvm-project?rev=198282&view=rev
Log:
As MCJIT does not implement properly runFunction, generate a function
gate to interact with JITted code from C++ code for each llvm
signature.

Basically, each J3MethodType as an associated J3LLVMSignature. The
J3LLVMSignature contains a llvm function type and a gate. When a
function f with a given signature S is JITted, verifies whether the
gate for S was already generated. If it is not the case, generate the
gate for S when we generate f. As now, a Java object is represented by
a J3Object*, whatever the type of the Java object, the number of gates
should not be too crazy.

The gate takes in charge the transformation between a J3ObjectHandle
and a J3Object and totally hides J3Object to the caller.



Added:
    vmkit/branches/mcjit/include/j3/j3signature.h
    vmkit/branches/mcjit/lib/j3/vm/j3signature.cc
Modified:
    vmkit/branches/mcjit/include/j3/j3.h
    vmkit/branches/mcjit/include/j3/j3class.h
    vmkit/branches/mcjit/include/j3/j3classloader.h
    vmkit/branches/mcjit/include/j3/j3codegen.h
    vmkit/branches/mcjit/include/j3/j3field.h
    vmkit/branches/mcjit/include/j3/j3meta.def
    vmkit/branches/mcjit/include/j3/j3method.h
    vmkit/branches/mcjit/include/j3/j3typesdef.h
    vmkit/branches/mcjit/lib/j3/openjdk/j3openjdk.cc
    vmkit/branches/mcjit/lib/j3/vm/j3.cc
    vmkit/branches/mcjit/lib/j3/vm/j3class.cc
    vmkit/branches/mcjit/lib/j3/vm/j3classloader.cc
    vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc
    vmkit/branches/mcjit/lib/j3/vm/j3field.cc
    vmkit/branches/mcjit/lib/j3/vm/j3jni.cc
    vmkit/branches/mcjit/lib/j3/vm/j3method.cc
    vmkit/branches/mcjit/lib/j3/vm/j3thread.cc

Modified: vmkit/branches/mcjit/include/j3/j3.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3.h?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3.h (original)
+++ vmkit/branches/mcjit/include/j3/j3.h Wed Jan  1 15:29:07 2014
@@ -8,6 +8,7 @@
 #include "vmkit/vmkit.h"
 #include "vmkit/allocator.h"
 
+#include "j3/j3signature.h"
 #include "j3/j3options.h"
 #include "j3/j3typesdef.h"
 #include "j3/j3jni.h"
@@ -28,20 +29,24 @@ namespace j3 {
 		typedef std::map<J3ObjectHandle*, J3ObjectHandle*, vmkit::T_ptr_less_t<J3ObjectHandle*>, 
 										 vmkit::StdAllocator<std::pair<J3ObjectHandle*, J3ObjectHandle*> > > StringMap;
 
-		static vmkit::T_ptr_less_t<J3ObjectHandle*> charArrayLess;
+		typedef std::map<llvm::FunctionType*, J3LLVMSignature*, vmkit::T_ptr_less_t<llvm::FunctionType*>, 
+										 vmkit::StdAllocator<std::pair<llvm::FunctionType*, J3LLVMSignature*> > > SignatureMap;
 
-		J3Options                            _options;
+		static vmkit::T_ptr_less_t<J3ObjectHandle*>     charArrayLess;
+	  static vmkit::T_ptr_less_t<llvm::FunctionType*> llvmFunctionTypeLess;
 
-		pthread_mutex_t                      stringsMutex;
-		vmkit::NameMap<J3ObjectHandle*>::map nameToCharArrays;
-		StringMap                            charArrayToStrings;
-		vmkit::Names                         _names;
+		J3Options                             _options;
+	
+		pthread_mutex_t                       stringsMutex;
+		vmkit::NameMap<J3ObjectHandle*>::map  nameToCharArrays;
+		StringMap                             charArrayToStrings;
+		vmkit::Names                          _names;
 
 		void                       introspect();
 
 		J3(vmkit::BumpAllocator* allocator);
 	public:
-		J3InitialClassLoader*               initialClassLoader;
+		J3InitialClassLoader*                 initialClassLoader;
 
 		static J3*  create();
 
@@ -51,6 +56,7 @@ namespace j3 {
 #undef defPrimitive
 
 		J3MonitorManager monitorManager;
+	  SignatureMap     llvmSignatures; /* protected by the lock of the compiler */
 
 		void*            interfaceTrampoline;
 
@@ -60,17 +66,20 @@ namespace j3 {
 		J3ArrayClass*    charArrayClass;
 
 		J3Class*         stringClass;
-		J3Method*        stringInit;
-		J3Field*         stringValue;
+		J3Method*        stringClassInit;
+		J3Field*         stringClassValue;
 
 		J3Class*         classClass;
-		J3Method*        classInit;
-		J3Field*         classVMData;
+		J3Method*        classClassInit;
+		J3Field*         classClassVMData;
 
-		J3Field*         threadVMData;
-		J3Method*        threadRun;
+		J3Field*         threadClassVMData;
+		J3Method*        threadClassRun;
 
 		J3Class*         fieldClass;
+		J3Field*         fieldClassClass;
+		J3Field*         fieldClassSlot;
+		J3Method*        fieldClassInit;
 
 		const vmkit::Name* codeAttr;
 		const vmkit::Name* constantValueAttr;

Modified: vmkit/branches/mcjit/include/j3/j3class.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3class.h?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3class.h (original)
+++ vmkit/branches/mcjit/include/j3/j3class.h Wed Jan  1 15:29:07 2014
@@ -46,10 +46,11 @@ namespace j3 {
 	protected:
 		enum { LOADED, RESOLVED, INITED };
 
-		const vmkit::Name*     _name;
-		char*                  _nativeName;
-		uint32_t               _nativeNameLength;
-		J3VirtualTable*        _vt;
+		const vmkit::Name*        _name;
+		char*                     _nativeName;
+		uint32_t                  _nativeNameLength;
+		J3VirtualTable*           _vt; 
+		J3ObjectHandle* volatile  _javaClass;
 
 		volatile int           status;
 
@@ -60,6 +61,8 @@ namespace j3 {
 	public:
 		J3Type(J3ClassLoader* loader, const vmkit::Name* name);
 
+		J3ObjectHandle*             javaClass();
+
 		virtual uint32_t            logSize() = 0;
 		uint64_t                    getSizeInBits();
 
@@ -109,7 +112,6 @@ namespace j3 {
 	};
 
 	class J3ObjectType : public J3Type {
-		J3ObjectHandle* volatile  _javaClass;
 		J3InterfaceSlotDescriptor _interfaceSlotDescriptors[J3VirtualTable::nbInterfaceMethodTable];
 
 	public:
@@ -126,8 +128,6 @@ namespace j3 {
 
 		bool                       isObjectType() { return 1; }
 
-		J3ObjectHandle*            javaClass();
-
 		static J3ObjectType*       nativeClass(J3ObjectHandle* handle);
 
 		void                       dumpInterfaceSlotDescriptors();
@@ -241,8 +241,11 @@ namespace j3 {
 
 		J3Method*           findVirtualMethod(const vmkit::Name* name, const vmkit::Name* sign, bool error=1);
 		J3Method*           findStaticMethod(const vmkit::Name* name, const vmkit::Name* sign, bool error=1);
+
 		J3Field*            findVirtualField(const vmkit::Name* name, const J3Type* type, bool error=1);
 		J3Field*            findStaticField(const vmkit::Name* name, const J3Type* type, bool error=1);
+		J3Field*            findVirtualField(const wchar_t* name, const J3Type* type, bool error=1);
+		J3Field*            findStaticField(const wchar_t* name, const J3Type* type, bool error=1);
 	};
 
 	class J3ArrayClass : public J3ObjectType {
@@ -266,9 +269,9 @@ namespace j3 {
 	public:
 		J3Primitive(J3ClassLoader* loader, char id, llvm::Type* type, uint32_t logSize);
 
-		uint32_t    logSize() { return _logSize; }
+		uint32_t    logSize()     { return _logSize; }
 		bool        isPrimitive() { return 1; }
-		llvm::Type* llvmType() { return _llvmType; }
+		llvm::Type* llvmType()    { return _llvmType; }
 	};
 }
 

Modified: vmkit/branches/mcjit/include/j3/j3classloader.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3classloader.h?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3classloader.h (original)
+++ vmkit/branches/mcjit/include/j3/j3classloader.h Wed Jan  1 15:29:07 2014
@@ -84,14 +84,16 @@ namespace j3 {
 		J3*                           vm() const { return (J3*)vmkit::CompilationUnit::vm(); };
 
 		J3Method*                     method(uint16_t access, J3Class* cl, 
-																				 const vmkit::Name* name, const vmkit::Name* sign); /* find a method ref */
+																				 const vmkit::Name* name, const vmkit::Name* sign);
 		J3Method*                     method(uint16_t access, const vmkit::Name* clName, 
 																				 const vmkit::Name* name, const vmkit::Name* sign); 
+		J3Method*                     method(uint16_t access, J3Class* cl, const wchar_t* name, const wchar_t* sign); 
 		J3Method*                     method(uint16_t access, const wchar_t* clName, const wchar_t* name, const wchar_t* sign); 
 
 		J3Class*                      defineClass(const vmkit::Name* name, J3ClassBytes* bytes);
 		J3Class*                      findLoadedClass(const vmkit::Name* name);
 		virtual J3Class*              loadClass(const vmkit::Name* name);
+		J3Class*                      loadClass(const wchar_t* name);
 
 		J3Type*                       getType(J3Class* from, const vmkit::Name* type);       /* find a type */
 		J3MethodType*                 getMethodType(J3Class* from, const vmkit::Name* sign); /* get a method type */

Modified: vmkit/branches/mcjit/include/j3/j3codegen.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3codegen.h?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3codegen.h (original)
+++ vmkit/branches/mcjit/include/j3/j3codegen.h Wed Jan  1 15:29:07 2014
@@ -38,6 +38,7 @@ namespace j3 {
 		friend class J3CodeGenVar;
 		friend class J3ExceptionTable;
 		friend class J3ExceptionNode;
+		friend class J3LLVMSignature;
 
 		vmkit::BumpAllocator*  allocator;
 		llvm::Module*          module;

Modified: vmkit/branches/mcjit/include/j3/j3field.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3field.h?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3field.h (original)
+++ vmkit/branches/mcjit/include/j3/j3field.h Wed Jan  1 15:29:07 2014
@@ -23,11 +23,13 @@ namespace j3 {
 		J3Attributes*             _attributes;
 		uintptr_t                 _offset;
 		J3ObjectHandle* volatile  _javaField;
+		uint32_t                  _slot;
 
 	public:
 		J3Field() {}
 		J3Field(uint16_t access, const vmkit::Name* name, J3Type* type) { _access = access; _name = name; _type = type; }
 
+		uint32_t           slot() const { return _slot; }
 		J3ObjectHandle*    javaField();
 		J3Attributes*      attributes() const { return _attributes; }
 		uint16_t           access() { return _access; }

Modified: vmkit/branches/mcjit/include/j3/j3meta.def
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3meta.def?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3meta.def (original)
+++ vmkit/branches/mcjit/include/j3/j3meta.def Wed Jan  1 15:29:07 2014
@@ -5,7 +5,7 @@ _x(funcJ3TypeInitialise,         "j3::J3
 _x(funcJ3LayoutStructSize,       "j3::J3Layout::structSize()")
 _x(funcJ3ClassStaticInstance,    "j3::J3Class::staticInstance()")
 _x(funcJ3ClassStringAt,          "j3::J3Class::stringAt(unsigned short)")
-_x(funcJ3ObjectTypeJavaClass,    "j3::J3ObjectType::javaClass()")
+_x(funcJ3TypeJavaClass,          "j3::J3Type::javaClass()")
 _x(funcJniEnv,                   "j3::J3::jniEnv()")
 _x(funcJ3ObjectAllocate,         "j3::J3Object::allocate(j3::J3VirtualTable*, unsigned long)")
 _x(funcJ3ObjectMonitorEnter,     "j3::J3Object::monitorEnter(j3::J3Object*)")

Modified: vmkit/branches/mcjit/include/j3/j3method.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3method.h?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3method.h (original)
+++ vmkit/branches/mcjit/include/j3/j3method.h Wed Jan  1 15:29:07 2014
@@ -16,6 +16,7 @@ namespace vmkit {
 }
 
 namespace j3 {
+	class J3LLVMSignature;
 	class J3Type;
 	class J3Attributes;
 	class J3Class;
@@ -24,7 +25,7 @@ namespace j3 {
 	class J3ObjectHandle;
 
 	class J3MethodType : public vmkit::PermanentObject {
-		llvm::FunctionType* volatile _llvmFunctionType;
+		J3LLVMSignature*             _llvmSignature;
 		J3Type*                      _out;
 		uint32_t                     _nbIns;
 		J3Type*                      _ins[1];
@@ -32,8 +33,8 @@ namespace j3 {
 	public:
 		J3MethodType(J3Type** args, size_t nbArgs);
 
-		void                setFunctionType(llvm::FunctionType* functionType) { _llvmFunctionType = functionType; }
-		llvm::FunctionType* functionType() { return _llvmFunctionType; }
+		void                setLLVMSignature(J3LLVMSignature* llvmSignature) { _llvmSignature = llvmSignature; }
+		J3LLVMSignature*    llvmSignature() { return _llvmSignature; }
 		uint32_t            nbIns() { return _nbIns; }
 		J3Type*             out() { return _out; }
 		J3Type*             ins(uint32_t idx) { return _ins[idx]; }
@@ -71,6 +72,7 @@ namespace j3 {
 
 		J3Value            internalInvoke(bool statically, J3ObjectHandle* handle, va_list va);
 		J3Value            internalInvoke(bool statically, J3ObjectHandle* handle, J3Value* args);
+		J3Value            internalInvoke(bool statically, J3Value* args);
 		void               buildLLVMNames(J3Class* from);
 	public:
 		J3Method(uint16_t access, J3Class* cl, const vmkit::Name* name, const vmkit::Name* sign);

Added: vmkit/branches/mcjit/include/j3/j3signature.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3signature.h?rev=198282&view=auto
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3signature.h (added)
+++ vmkit/branches/mcjit/include/j3/j3signature.h Wed Jan  1 15:29:07 2014
@@ -0,0 +1,35 @@
+#ifndef _J3_SIGNATURE_H_
+#define _J3_SIGNATURE_H_
+
+#include "vmkit/allocator.h"
+
+namespace llvm {
+	class FunctionType;
+	class Module;
+}
+
+namespace j3 {
+	class J3MethodType;
+	class J3Type;
+	class J3Value;
+	class J3CodeGen;
+
+	class J3LLVMSignature : vmkit::PermanentObject {
+		friend class J3CodeGen;
+
+		typedef J3Value (*function_t)(void* fn, J3Value* args);
+
+		llvm::FunctionType* _functionType;
+		function_t          _caller;
+
+		void                generateCallerIR(J3CodeGen* vm, llvm::Module* module, const char* id);
+
+		J3LLVMSignature(llvm::FunctionType* functionType);
+
+		llvm::FunctionType* functionType() { return _functionType; }
+	public:
+		function_t          caller() { return _caller; }
+	};
+}
+
+#endif

Modified: vmkit/branches/mcjit/include/j3/j3typesdef.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3typesdef.h?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3typesdef.h (original)
+++ vmkit/branches/mcjit/include/j3/j3typesdef.h Wed Jan  1 15:29:07 2014
@@ -3,6 +3,7 @@
 
 namespace j3 {
 
+	/* name, ctype, llvmType, scale size */
 #define onJavaPrimitives(_)																							\
 	_(Boolean, bool,     Int1,   0)																				\
 	_(Byte,    int8_t,   Int8,   0)																				\
@@ -13,12 +14,12 @@ namespace j3 {
 	_(Float,   float,    Float,  2)																				\
 	_(Double,  double,   Double, 3)																				\
 
-#define onJavaObject(_)													\
-	_(Object,  J3ObjectHandle*, Fatal, 3)
-
 #define onJavaVoid(_)														\
 	_(Void, void,        Void, 0)																	
 
+#define onJavaObject(_)													\
+	_(Object,  J3ObjectHandle*, Fatal, 3)
+
 #define onJavaTypes(_)													\
 	onJavaPrimitives(_)														\
 	onJavaVoid(_)

Modified: vmkit/branches/mcjit/lib/j3/openjdk/j3openjdk.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/openjdk/j3openjdk.cc?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/openjdk/j3openjdk.cc (original)
+++ vmkit/branches/mcjit/lib/j3/openjdk/j3openjdk.cc Wed Jan  1 15:29:07 2014
@@ -387,6 +387,7 @@ jbyteArray JNICALL JVM_GetClassTypeAnnot
 
 jobjectArray JNICALL JVM_GetClassDeclaredMethods(JNIEnv* env, jclass ofClass, jboolean publicOnly) { enterJVM(); NYI(); leaveJVM(); }
 jobjectArray JNICALL JVM_GetClassDeclaredFields(JNIEnv* env, jclass ofClass, jboolean publicOnly) { 
+	NYI();
 	jobjectArray res;
 
 	enterJVM(); 

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=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3.cc Wed Jan  1 15:29:07 2014
@@ -21,13 +21,15 @@
 using namespace j3;
 
 vmkit::T_ptr_less_t<J3ObjectHandle*> J3::charArrayLess;
+vmkit::T_ptr_less_t<llvm::FunctionType*> J3::llvmFunctionTypeLess;
 
 J3::J3(vmkit::BumpAllocator* allocator) : 
 	VMKit(allocator),
 	nameToCharArrays(vmkit::Name::less, allocator),
 	charArrayToStrings(charArrayLess, allocator),
 	_names(allocator),
-	monitorManager(allocator) {
+	monitorManager(allocator),
+	llvmSignatures(llvmFunctionTypeLess, allocator) {
 	pthread_mutex_init(&stringsMutex, 0);
 	constantValueAttr = names()->get(J3Cst::constantValueAttr);
 	codeAttr =          names()->get(J3Cst::codeAttr);
@@ -92,29 +94,44 @@ void J3::run() {
 	onJavaTypes(defPrimitive)
 #undef defPrimitive
 
+#define z_class(clName)                      initialClassLoader->loadClass(names()->get(clName))
+#define z_method(access, cl, name, sign)     initialClassLoader->method(access, cl, name, sign)
+#define z_field(access, cl, name, type)      J3Cst::isStatic(access)	\
+			? cl->findStaticField(name, type)																\
+			: cl->findVirtualField(name, type);
+
+
 	nbArrayInterfaces    = 2;
 	arrayInterfaces      = (J3Type**)initialClassLoader->allocator()->allocate(2*sizeof(J3Type*));
-	arrayInterfaces[0]   = initialClassLoader->loadClass(names()->get(L"java/lang/Cloneable"));
-	arrayInterfaces[1]   = initialClassLoader->loadClass(names()->get(L"java/io/Serializable"));
+	arrayInterfaces[0]   = z_class(L"java/lang/Cloneable");
+	arrayInterfaces[1]   = z_class(L"java/io/Serializable");
 
 	charArrayClass           = typeChar->getArray();
-	objectClass              = initialClassLoader->loadClass(names()->get(L"java/lang/Object"));
+	objectClass              = z_class(L"java/lang/Object");
 	
-	stringClass              = initialClassLoader->loadClass(names()->get(L"java/lang/String"));
-	stringInit               = initialClassLoader->method(0, stringClass, initName, names()->get(L"([CZ)V"));
-	stringValue              = stringClass->findVirtualField(names()->get(L"value"), typeChar->getArray());
+	stringClass              = z_class(L"java/lang/String");
+	stringClassInit          = z_method(0, stringClass, J3Cst::initName, L"([CZ)V");
+	stringClassValue         = z_field(0, stringClass, L"value", charArrayClass);
 
-	classClass               = initialClassLoader->loadClass(names()->get(L"java/lang/Class"));
+	classClass               = z_class(L"java/lang/Class");
 	J3Field hf(J3Cst::ACC_PRIVATE, names()->get(L"** vmData **"), typeLong);
 	classClass->resolve(&hf, 1);
-	classInit                = initialClassLoader->method(0, classClass, initName, names()->get(L"()V"));
-	classVMData              = classClass->findVirtualField(hf.name(), hf.type());
+	classClassInit           = z_method(0, classClass, J3Cst::initName, L"()V");
+	classClassVMData         = z_field(0, classClass, hf.name(), hf.type());
 
-	threadVMData             = initialClassLoader->loadClass(names()->get("java/lang/Thread"))
+	threadClassRun           = z_method(0, z_class(L"java/lang/Thread"), L"run", L"()V");
+	threadClassVMData        = initialClassLoader->loadClass(names()->get("java/lang/Thread"))
 		->findVirtualField(names()->get(L"eetop"), typeLong);
-	threadRun                = initialClassLoader->method(0, L"java/lang/Thread", L"run", L"()V");
 
-	fieldClass               = initialClassLoader->loadClass(names()->get("java/lang/reflect/Field"));
+	fieldClass               = z_class(L"java/lang/reflect/Field");
+	fieldClassInit           = z_method(0, fieldClass, J3Cst::initName, 
+																			L"(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;IILjava/lang/String;[B)V");
+	fieldClassClass          = z_field(0, fieldClass, L"clazz", classClass);
+	fieldClassSlot           = z_field(0, fieldClass, L"slot", typeInteger);
+#if 0
+		J3Field*         fieldClassSlot;
+		J3Method*        fieldClassInit;
+#endif
 
 	J3Lib::bootstrap(this);
 }
@@ -131,7 +148,7 @@ J3ObjectHandle* J3::arrayToString(J3Obje
 		res = initialClassLoader->globalReferences()->add(J3ObjectHandle::doNewObject(stringClass));
 		J3Thread::get()->restore(prev);
 
-		stringInit->invokeSpecial(res, array, 0);
+		stringClassInit->invokeSpecial(res, array, 0);
 
 		charArrayToStrings[array] = res;
 	}
@@ -234,7 +251,9 @@ void J3::printStackTrace() {
 }
 
 void J3::forceSymbolDefinition() {
+	J3Value val;
 	J3ArrayObject a; a.length(); /* J3ArrayObject */
+	printf("---> %p\n", &val.valFloat);
 	J3LockRecord* l = new J3LockRecord(); /* J3LockRecord */
 	try {
 		throw (void*)0;

Modified: vmkit/branches/mcjit/lib/j3/vm/j3class.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3class.cc?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3class.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3class.cc Wed Jan  1 15:29:07 2014
@@ -49,6 +49,21 @@ void J3Type::dump() {
 	fprintf(stderr, "Type: %ls", name()->cStr());
 }
 
+J3ObjectHandle* J3Type::javaClass() {
+	if(!_javaClass) {
+		lock();
+		if(!_javaClass) {
+			J3ObjectHandle* prev = J3Thread::get()->tell();
+			_javaClass = loader()->globalReferences()->add(J3ObjectHandle::doNewObject(loader()->vm()->classClass));
+			J3Thread::get()->restore(prev);
+			javaClass()->setLong(loader()->vm()->classClassVMData, (int64_t)(uintptr_t)this);
+			loader()->vm()->classClassInit->invokeSpecial(javaClass());
+		}
+		unlock();
+	}
+	return _javaClass;
+}
+
 void J3Type::doNativeName() {
 	J3::internalError(L"should not happen");
 }
@@ -162,22 +177,7 @@ J3Method* J3ObjectType::findStaticMethod
 }
 
 J3ObjectType* J3ObjectType::nativeClass(J3ObjectHandle* handle) {
-	return (J3ObjectType*)(uintptr_t)handle->getLong(J3Thread::get()->vm()->classVMData);
-}
-
-J3ObjectHandle* J3ObjectType::javaClass() {
-	if(!_javaClass) {
-		lock();
-		if(!_javaClass) {
-			J3ObjectHandle* prev = J3Thread::get()->tell();
-			_javaClass = loader()->globalReferences()->add(J3ObjectHandle::doNewObject(loader()->vm()->classClass));
-			J3Thread::get()->restore(prev);
-			javaClass()->setLong(loader()->vm()->classVMData, (int64_t)(uintptr_t)this);
-			loader()->vm()->classInit->invokeSpecial(javaClass());
-		}
-		unlock();
-	}
-	return _javaClass;
+	return (J3ObjectType*)(uintptr_t)handle->getLong(J3Thread::get()->vm()->classClassVMData);
 }
 
 void J3ObjectType::prepareInterfaceTable() {
@@ -362,6 +362,14 @@ J3Field* J3Class::findStaticField(const
 	return res;
 }
 
+J3Field* J3Class::findVirtualField(const wchar_t* name, const J3Type* type, bool error) {
+	return findVirtualField(loader()->vm()->names()->get(name), type, error);
+}
+
+J3Field* J3Class::findStaticField(const wchar_t* name, const J3Type* type, bool error) {
+	return findStaticField(loader()->vm()->names()->get(name), type, error);
+}
+
 void J3Class::registerNative(const vmkit::Name* methName, const vmkit::Name* methSign, void* fnPtr) {
 	resolve();
 	J3Method* res = staticLayout()->findMethod(methName, methSign);
@@ -632,6 +640,7 @@ void J3Class::fillFields(J3Field** field
 			layout = this;
 		}
 		cur->_offset = layout->structSize();
+		cur->_slot = i;
 		layout->_structSize += 1 << fields[i]->type()->logSize();
 		layout->fields()[layout->_nbFields++] = *fields[i];
 

Modified: vmkit/branches/mcjit/lib/j3/vm/j3classloader.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3classloader.cc?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3classloader.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3classloader.cc Wed Jan  1 15:29:07 2014
@@ -87,6 +87,10 @@ J3Class* J3ClassLoader::loadClass(const
 	J3::internalError(L"implement me: loadClass from a Java class loader");
 }
 
+J3Class* J3ClassLoader::loadClass(const wchar_t* name) {
+	return loadClass(vm()->names()->get(name));
+}
+
 void J3ClassLoader::wrongType(J3Class* from, const vmkit::Name* type) {
 	J3::classFormatError(from, L"wrong type: %ls", type->cStr());
 }
@@ -226,6 +230,11 @@ J3Method* J3ClassLoader::method(uint16_t
 	return method(access, names->get(clName), names->get(name), names->get(sign));
 }
 
+J3Method* J3ClassLoader::method(uint16_t access, J3Class* cl, const wchar_t* name, const wchar_t* sign) {
+	vmkit::Names* names = vm()->names();
+	return method(access, cl, names->get(name), names->get(sign));
+}
+
 bool J3ClassLoader::J3InterfaceMethodLess::operator()(j3::J3Method const* lhs, j3::J3Method const* rhs) const {
 	return lhs->name() < rhs->name()
 		|| (lhs->name() == rhs->name()

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=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc Wed Jan  1 15:29:07 2014
@@ -102,9 +102,17 @@ J3CodeGen::J3CodeGen(vmkit::BumpAllocato
 	if(vm->options()->debugTranslate > 3)
 		llvmFunction->dump();
 
+	if(!methodType->llvmSignature()->caller())
+		methodType->llvmSignature()->generateCallerIR(this, module, "generic-caller");
+
 	loader->compileModule(module);
 	void* fnPtr = (void*)loader->ee()->getFunctionAddress(llvmFunction->getName().data());
 
+	if(!methodType->llvmSignature()->caller()) {
+		J3LLVMSignature::function_t caller = (J3LLVMSignature::function_t)loader->ee()->getFunctionAddress("generic-caller");
+		methodType->llvmSignature()->_caller = caller;
+	}
+
 	method->markCompiled(llvmFunction, fnPtr);
 }
 
@@ -176,16 +184,19 @@ llvm::Value* J3CodeGen::unflatten(llvm::
 }
 
 llvm::FunctionType* J3CodeGen::llvmFunctionType(J3MethodType* type) {
-	llvm::FunctionType* res = type->functionType();
+	J3LLVMSignature* res = type->llvmSignature();
 
 	if(!res) {
 		std::vector<llvm::Type*> in;
 		for(uint32_t i=0; i<type->nbIns(); i++)
 			in.push_back(type->ins(i)->llvmType());
-		res = llvm::FunctionType::get(type->out()->llvmType(), in, 0);
-		type->setFunctionType(res);
+		llvm::FunctionType* funcType = llvm::FunctionType::get(type->out()->llvmType(), in, 0);
+		res = vm->llvmSignatures[funcType];
+		if(!res)
+			vm->llvmSignatures[funcType] = res = new(vm->allocator()) J3LLVMSignature(funcType);
+		type->setLLVMSignature(res);
 	}
-	return res;
+	return res->functionType();
 }
 
 llvm::Function* J3CodeGen::buildFunction(J3Method* method, bool isStub) {
@@ -316,7 +327,7 @@ void J3CodeGen::initialiseJ3ObjectType(J
 }
 
 llvm::Value* J3CodeGen::javaClass(J3ObjectType* type) {
-	return builder->CreateCall(funcJ3ObjectTypeJavaClass, typeDescriptor(type, vm->typeJ3ObjectTypePtr));
+	return builder->CreateCall(funcJ3TypeJavaClass, typeDescriptor(type, vm->typeJ3TypePtr));
 }
 
 llvm::Value* J3CodeGen::handleToObject(llvm::Value* obj) {

Modified: vmkit/branches/mcjit/lib/j3/vm/j3field.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3field.cc?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3field.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3field.cc Wed Jan  1 15:29:07 2014
@@ -2,13 +2,31 @@
 #include "j3/j3class.h"
 #include "j3/j3classloader.h"
 #include "j3/j3.h"
+#include "j3/j3method.h"
+#include "j3/j3thread.h"
 
 using namespace j3;
 
 J3ObjectHandle* J3Field::javaField() {
 	if(!_javaField) {
 		layout()->lock();
-		_javaField = J3ObjectHandle::doNewObject(layout()->loader()->vm()->fieldClass);
+
+		J3ObjectHandle* prev = J3Thread::get()->tell();
+		_javaField = layout()->loader()->globalReferences()->add(J3ObjectHandle::doNewObject(layout()->loader()->vm()->fieldClass));
+
+		J3* vm = layout()->loader()->vm();
+
+		vm->fieldClassInit->invokeSpecial(_javaField,                       /* this */
+																			0,//layout()->javaClass(),            /* declaring class */
+																			0,//vm->nameToString(name()),         /* name */
+																			0,//type()->javaClass(),              /* type */
+																			0,//access(),                         /* access */
+																			0,//slot(),                           /* slot */
+																			0,//vm->nameToString(type()->name()), /* signature */
+																			0);                               /* annotations */
+
+
+		J3Thread::get()->restore(prev);
 		J3::internalError(L"implement me: javaField");
 		layout()->unlock();
 	}

Modified: vmkit/branches/mcjit/lib/j3/vm/j3jni.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3jni.cc?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3jni.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3jni.cc Wed Jan  1 15:29:07 2014
@@ -378,7 +378,7 @@ const char* JNICALL GetStringUTFChars(JN
 
 	enterJVM(); 
 	J3* vm = str->vt()->type()->loader()->vm();
-	jobject content = str->getObject(vm->stringValue);
+	jobject content = str->getObject(vm->stringClassValue);
 	uint32_t length = content->arrayLength();
 	res = new char[length+1];
 

Modified: vmkit/branches/mcjit/lib/j3/vm/j3method.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3method.cc?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3method.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3method.cc Wed Jan  1 15:29:07 2014
@@ -112,115 +112,62 @@ J3Method* J3Method::resolve(J3ObjectHand
 	return obj->vt()->type()->asObjectType()->findVirtualMethod(name(), sign());
 }
 
+J3Value J3Method::internalInvoke(bool statically, J3Value* inArgs) {
+	J3Method* target = statically ? this : resolve(inArgs[0].valObject);
 
-J3Value J3Method::internalInvoke(bool statically, J3ObjectHandle* handle, J3Value* inArgs) {
-	std::vector<llvm::GenericValue> args(methodType()->nbIns());
-	J3* vm = cl()->loader()->vm();
-	J3Type* cur;
-	uint32_t i = 0, d = 0;
-
-	if(handle) {
-		args[i++].PointerVal = handle->obj();
-		d = 1;
-	}
-
-	for(; i<methodType()->nbIns(); i++) {  /* have to avoid collection at this point */
-		cur = methodType()->ins(i);
-		
-		if(cur == vm->typeBoolean)
-			args[i].IntVal = inArgs[i-d].valBoolean;
-		else if(cur == vm->typeByte)
-			args[i].IntVal = inArgs[i-d].valByte;
-		else if(cur == vm->typeShort)
-			args[i].IntVal = inArgs[i-d].valShort;
-		else if(cur == vm->typeChar)
-			args[i].IntVal = inArgs[i-d].valChar;
-		else if(cur == vm->typeInteger)
-			args[i].IntVal = inArgs[i-d].valInteger;
-		else if(cur == vm->typeLong)
-			args[i].IntVal = inArgs[i-d].valLong;
-		else if(cur == vm->typeFloat)
-			args[i].FloatVal = inArgs[i-d].valFloat;
-		else if(cur == vm->typeDouble)
-			args[i].FloatVal = inArgs[i-d].valDouble;
-		else
-			args[i].PointerVal = inArgs[i-d].valObject->obj();
-	}
-
-	J3Method* target;
+	void* fn = fnPtr();
 
-	if(statically)
-		target = this;
-	else {
-		J3ObjectHandle* self = handle ? handle : inArgs[0].valObject;
-		target = resolve(self);
-	}
-
-	//fprintf(stderr, "invoke: %ls::%ls%ls\n", target->cl()->name()->cStr(), target->name()->cStr(), target->sign()->cStr());
-	target->fnPtr(); /* ensure that the function is compiled */
-	cl()->loader()->vm()->lockCompiler();
-	cl()->loader()->oldee()->updateGlobalMapping(target->_llvmFunction, target->fnPtr());
-	cl()->loader()->vm()->unlockCompiler();
-	llvm::GenericValue res = cl()->loader()->oldee()->runFunction(target->_llvmFunction, args);
-
-	J3Value holder;
-	cur = methodType()->out();
+	//fprintf(stderr, "Internal invoke %ls::%ls%ls\n", target->cl()->name()->cStr(), target->name()->cStr(), target->sign()->cStr());
 	
-	if(cur == vm->typeBoolean)
-		holder.valBoolean = (bool)res.IntVal.getZExtValue();
-	else if(cur == vm->typeByte)
-		holder.valByte = (int8_t)res.IntVal.getZExtValue();
-	else if(cur == vm->typeShort)
-		holder.valShort = (int16_t)res.IntVal.getZExtValue();
-	else if(cur == vm->typeChar)
-		holder.valChar = (uint16_t)res.IntVal.getZExtValue();
-	else if(cur == vm->typeInteger)
-		holder.valInteger = (int32_t)res.IntVal.getZExtValue();
-	else if(cur == vm->typeLong)
-		holder.valLong = res.IntVal.getZExtValue();
-	else if(cur == vm->typeFloat)
-		holder.valFloat = res.FloatVal;
-	else if(cur == vm->typeDouble)
-		holder.valDouble = res.FloatVal;
-	else if(cur != vm->typeVoid)
-		holder.valObject = J3Thread::get()->push((J3Object*)res.PointerVal);
+	J3Value res = methodType()->llvmSignature()->caller()(fn, inArgs);
+
+	return res;
+}
 
-	return holder;
+J3Value J3Method::internalInvoke(bool statically, J3ObjectHandle* handle, J3Value* inArgs) {
+	J3Value* reIn;
+	if(handle) {
+		reIn = (J3Value*)alloca(methodType()->nbIns()*sizeof(J3Value));
+		reIn[0].valObject = handle;
+		memcpy(reIn+1, inArgs, (methodType()->nbIns() - 1)*sizeof(J3Value));
+	} else
+		reIn = inArgs;
+	return internalInvoke(statically, reIn);
 }
 
 J3Value J3Method::internalInvoke(bool statically, J3ObjectHandle* handle, va_list va) {
 	J3Value* args = (J3Value*)alloca(sizeof(J3Value)*methodType()->nbIns());
 	J3* vm = cl()->loader()->vm();
 	J3Type* cur;
-	uint32_t i = 0, d = 0;
+	uint32_t i = 0;
 
 	if(handle)
-		i = d = 1;
+		args[i++].valObject = handle;
 
 	for(; i<methodType()->nbIns(); i++) {
 		cur = methodType()->ins(i);
 
 		if(cur == vm->typeBoolean)
-			args[i-d].valBoolean = va_arg(va, bool);
+			args[i].valBoolean = va_arg(va, bool);
 		else if(cur == vm->typeByte)
-			args[i-d].valByte = va_arg(va, int8_t);
+			args[i].valByte = va_arg(va, int8_t);
 		else if(cur == vm->typeShort)
-			args[i-d].valShort = va_arg(va, int16_t);
+			args[i].valShort = va_arg(va, int16_t);
 		else if(cur == vm->typeChar)
-			args[i-d].valChar = va_arg(va, uint16_t);
+			args[i].valChar = va_arg(va, uint16_t);
 		else if(cur == vm->typeInteger)
-			args[i-d].valInteger = va_arg(va, int32_t);
+			args[i].valInteger = va_arg(va, int32_t);
 		else if(cur == vm->typeLong)
-			args[i-d].valLong = va_arg(va, int64_t);
+			args[i].valLong = va_arg(va, int64_t);
 		else if(cur == vm->typeFloat)
-			args[i-d].valFloat = va_arg(va, float);
+			args[i].valFloat = va_arg(va, float);
 		else if(cur == vm->typeDouble)
-			args[i-d].valDouble = va_arg(va, double);
+			args[i].valDouble = va_arg(va, double);
 		else
-			args[i-d].valObject = va_arg(va, J3ObjectHandle*);
+			args[i].valObject = va_arg(va, J3ObjectHandle*);
 	}
 
-	return internalInvoke(statically, handle, args);
+	return internalInvoke(statically, args);
 }
 
 J3Value J3Method::invokeStatic(J3Value* args) {

Added: vmkit/branches/mcjit/lib/j3/vm/j3signature.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3signature.cc?rev=198282&view=auto
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3signature.cc (added)
+++ vmkit/branches/mcjit/lib/j3/vm/j3signature.cc Wed Jan  1 15:29:07 2014
@@ -0,0 +1,78 @@
+#include "j3/j3signature.h"
+#include "j3/j3object.h"
+#include "j3/j3codegen.h"
+#include "j3/j3.h"
+
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/IRBuilder.h"
+
+using namespace j3;
+
+J3LLVMSignature::J3LLVMSignature(llvm::FunctionType* functionType) {
+	_functionType = functionType;
+}
+
+void J3LLVMSignature::generateCallerIR(J3CodeGen* codeGen, llvm::Module* module, const char* id) {
+	llvm::Type* uint64Ty = llvm::Type::getInt64Ty(module->getContext());
+	llvm::Type* callerIn[] = { llvm::Type::getInt8Ty(module->getContext())->getPointerTo(),
+														 uint64Ty->getPointerTo() };
+	llvm::Function*   caller = (llvm::Function*)module->getOrInsertFunction(id, llvm::FunctionType::get(uint64Ty, callerIn, 0));
+	llvm::BasicBlock* bb = llvm::BasicBlock::Create(caller->getContext(), "entry", caller);
+	llvm::IRBuilder<> builder(bb);
+
+	llvm::Function::arg_iterator cur = caller->arg_begin();
+	llvm::Value* method = builder.CreateBitCast(cur++, _functionType->getPointerTo());
+	llvm::Value* ins = cur;
+
+	llvm::Value* one = builder.getInt32(1);
+	llvm::Value* gepHandle[] = { builder.getInt32(0), builder.getInt32(J3ObjectHandle::gepObj) };
+
+	std::vector<llvm::Value*> params;
+
+	for(llvm::FunctionType::param_iterator it=_functionType->param_begin(); it!=_functionType->param_end(); it++) {
+		llvm::Type*  t = *it;
+		llvm::Value* arg;
+
+		if(t->isPointerTy())
+			arg = builder.CreateLoad(builder.CreateGEP(builder.CreateIntToPtr(builder.CreateLoad(ins), 
+																																				codeGen->vm->typeJ3ObjectHandlePtr), gepHandle));
+		else {
+			arg = builder.CreateLoad(builder.CreateTruncOrBitCast(ins, t->getPointerTo()));
+		}
+
+		params.push_back(arg);
+		ins = builder.CreateGEP(ins, one);
+	}
+
+	llvm::Value* res = builder.CreateCall(method, params);
+	llvm::Type* ret = _functionType->getReturnType();
+
+	if(ret != builder.getVoidTy()) {
+		if(ret->isPointerTy()) {
+			codeGen->builder = &builder;
+
+			llvm::BasicBlock* ifnull = llvm::BasicBlock::Create(caller->getContext(), "ifnull", caller);
+			llvm::BasicBlock* ifnotnull = llvm::BasicBlock::Create(caller->getContext(), "ifnotnull", caller);
+			builder.CreateCondBr(builder.CreateIsNull(res), ifnull, ifnotnull);
+
+			builder.SetInsertPoint(ifnull);
+			builder.CreateRet(builder.getInt64(0));
+
+			builder.SetInsertPoint(ifnotnull);
+			codeGen->currentThread();
+			res = builder.CreatePtrToInt(builder.CreateCall2(codeGen->funcJ3ThreadPush, codeGen->currentThread(), res),
+																	 uint64Ty);
+		} else {
+			if(ret->isFloatTy()) {
+				llvm::Value* tmp = builder.CreateAlloca(ret);
+				builder.CreateStore(res, tmp);
+				res = builder.CreateLoad(builder.CreateBitCast(tmp, builder.getInt32Ty()->getPointerTo()));
+			} 
+			res = builder.CreateZExtOrBitCast(res, uint64Ty);
+		}
+	} else
+		res = builder.getInt64(0);
+
+	builder.CreateRet(res);
+}

Modified: vmkit/branches/mcjit/lib/j3/vm/j3thread.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3thread.cc?rev=198282&r1=198281&r2=198282&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3thread.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3thread.cc Wed Jan  1 15:29:07 2014
@@ -21,12 +21,12 @@ J3Thread::~J3Thread() {
 
 void J3Thread::doRun() {
 	J3ObjectHandle* handle = get()->javaThread();
-	get()->vm()->threadRun->invokeVirtual(handle);
+	get()->vm()->threadClassRun->invokeVirtual(handle);
 }
 
 void J3Thread::run() {
 	J3ObjectHandle* handle = javaThread();
-	vm()->threadRun->invokeVirtual(handle);
+	vm()->threadClassRun->invokeVirtual(handle);
 }
 
 void J3Thread::start(J3ObjectHandle* handle) {
@@ -62,12 +62,12 @@ void J3Thread::ensureCapacity(uint32_t c
 }
 
 J3Thread* J3Thread::nativeThread(J3ObjectHandle* handle) {
-	return (J3Thread*)handle->getLong(get()->vm()->threadVMData);
+	return (J3Thread*)handle->getLong(get()->vm()->threadClassVMData);
 }
 
 void J3Thread::assocJavaThread(J3ObjectHandle* javaThread) {
 	_javaThread = *javaThread;
-	_javaThread.setLong(vm()->threadVMData, (int64_t)(uintptr_t)this);
+	_javaThread.setLong(vm()->threadClassVMData, (int64_t)(uintptr_t)this);
 }
 
 J3ObjectHandle* J3Thread::push(J3ObjectHandle* handle) { 





More information about the vmkit-commits mailing list