From e529d60a69e7063cb9a9bc7826bfdbe93d9a74ae Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 29 Jun 2007 10:42:39 -0600 Subject: [PATCH] hello, world --- classpath/java/lang/System.cpp | 7 +- makefile | 28 ++++---- src/amd64.S | 4 +- src/main.cpp | 42 +++++++----- src/vm.cpp | 119 +++++++++++++++++++++++++++++---- 5 files changed, 152 insertions(+), 48 deletions(-) diff --git a/classpath/java/lang/System.cpp b/classpath/java/lang/System.cpp index 5c7e7cfc29..6e8e5beabc 100644 --- a/classpath/java/lang/System.cpp +++ b/classpath/java/lang/System.cpp @@ -1,13 +1,16 @@ #include "stdio.h" #include "jni.h" +#undef JNIEXPORT +#define JNIEXPORT __attribute__ ((visibility("default"))) + extern "C" JNIEXPORT void JNICALL -Java_java_lang_System_Output_println(JNIEnv* e, jobject, jstring s) +Java_java_lang_System_00024Output_println(JNIEnv* e, jobject, jstring s) { jboolean isCopy; const char* chars = e->GetStringUTFChars(s, &isCopy); if (chars) { - printf("%s", chars); + printf("%s\n", chars); } e->ReleaseStringUTFChars(s, chars); } diff --git a/makefile b/makefile index 6ad338368a..016c7cf15e 100644 --- a/makefile +++ b/makefile @@ -1,17 +1,18 @@ #MAKEFLAGS = -s -bld = build +# arch = $(shell uname -m) +# ifeq ($(arch),i586) +# arch = i386 +# endif +# ifeq ($(arch),i686) +# arch = i386 +# endif +arch = i386 + +bld = build/$(arch) src = src classpath = classpath -arch = $(shell uname -m) -ifeq ($(arch),i586) - arch = i386 -endif -ifeq ($(arch),i686) - arch = i386 -endif - cxx = g++ cc = gcc vg = nice valgrind --leak-check=full --num-callers=32 --db-attach=yes \ @@ -43,9 +44,8 @@ stdcpp-cflags = $(fast) $(cflags) jni-sources = $(classpath)/java/lang/System.cpp jni-objects = $(call cpp-objects,$(jni-sources),$(classpath)) -jni-cflags = -I/usr/lib/jvm/java-6-sun-1.6.0.00/include \ - -I/usr/lib/jvm/java-6-sun-1.6.0.00/include/linux \ - $(cflags) +jni-cflags = -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux \ + $(slow) $(cflags) jni-library = $(bld)/libnatives.so generated-code = \ @@ -160,8 +160,8 @@ stress-all: $(stress-executable) .PHONY: clean clean: - @echo "removing $(bld)" - rm -rf $(bld) + @echo "removing build" + rm -rf build gen-arg = $(shell echo $(1) | sed -e 's:$(bld)/type-\(.*\)\.cpp:\1:') $(generated-code): %.cpp: $(src)/types.def $(generator-executable) diff --git a/src/amd64.S b/src/amd64.S index b97bc8c15d..6a5a422026 100644 --- a/src/amd64.S +++ b/src/amd64.S @@ -52,8 +52,8 @@ test: movq 24(%rbp),%rax movq 0(%rax),%rdi movq 8(%rax),%rsi - movq 16(%rax),%rcx - movq 24(%rax),%rdx + movq 16(%rax),%rdx + movq 24(%rax),%rcx movq 32(%rax),%r8 movq 40(%rax),%r9 diff --git a/src/main.cpp b/src/main.cpp index 19294850b3..6c54616694 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,6 +12,7 @@ using namespace vm; #ifdef __i386__ +#define LD "%d" extern "C" uint64_t cdeclCall(void* function, void* stack, unsigned stackSize, @@ -29,6 +30,7 @@ dynamicCall(void* function, uint32_t* arguments, uint8_t*, } // namespace #elif defined __x86_64__ +#define LD "%ld" extern "C" uint64_t amd64Call(void* function, void* stack, unsigned stackSize, @@ -84,6 +86,22 @@ dynamicCall(void* function, uint64_t* arguments, uint8_t* argumentTypes, namespace { +const char* +append(vm::System* s, const char* a, const char* b, const char* c, + const char* d) +{ + unsigned al = strlen(a); + unsigned bl = strlen(b); + unsigned cl = strlen(c); + unsigned dl = strlen(d); + char* p = static_cast(s->allocate(al + bl + cl + dl + 1)); + memcpy(p, a, al); + memcpy(p + al, b, bl); + memcpy(p + al + bl, c, cl); + memcpy(p + al + bl + cl, d, dl + 1); + return p; +} + const bool Verbose = false; class System: public vm::System { @@ -169,7 +187,7 @@ class System: public vm::System { count -= *up; if (Verbose) { - fprintf(stderr, "free %d; count: %d; limit: %d\n", + fprintf(stderr, "free " LD "; count: %d; limit: %d\n", *up, count, limit); } @@ -196,7 +214,11 @@ class System: public vm::System { const char* name, vm::System::Library* next) { - void* p = dlopen(name, RTLD_LAZY); + unsigned size = strlen(name) + 7; + char buffer[size]; + snprintf(buffer, size, "lib%s.so", name); + + void* p = dlopen(buffer, RTLD_LAZY); if (p) { *lib = new (vm::System::allocate(sizeof(Library))) Library(this, p, next); @@ -214,22 +236,6 @@ class System: public vm::System { unsigned count; }; -const char* -append(vm::System* s, const char* a, const char* b, const char* c, - const char* d) -{ - unsigned al = strlen(a); - unsigned bl = strlen(b); - unsigned cl = strlen(c); - unsigned dl = strlen(d); - char* p = static_cast(s->allocate(al + bl + cl + dl + 1)); - memcpy(p, a, al); - memcpy(p + al, b, bl); - memcpy(p + al + bl, c, cl); - memcpy(p + al + bl + cl, d, dl + 1); - return p; -} - class ClassFinder: public vm::ClassFinder { public: ClassFinder(vm::System* system, const char** path): diff --git a/src/vm.cpp b/src/vm.cpp index b53bd7cac7..6358cd1dc7 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -1574,23 +1574,118 @@ parameterCount(Thread* t, object spec) return count; } -object -makeJNIName(Thread* t, object method, bool /*decorate*/) +unsigned +mangledSize(int8_t c) { - object name = makeByteArray - (t, "Java_%s_%s", - &byteArrayBody(t, className(t, methodClass(t, method)), 0), - &byteArrayBody(t, methodName(t, method), 0)); + switch (c) { + case '_': + case ';': + case '[': + return 2; - for (unsigned i = 0; i < byteArrayLength(t, name) - 1; ++i) { - switch (byteArrayBody(t, name, i)) { - case '/': - byteArrayBody(t, name, i) = '_'; - break; + case '$': + return 6; + + default: + return 1; + } +} + +unsigned +mangle(int8_t c, int8_t* dst) +{ + switch (c) { + case '/': + dst[0] = '_'; + return 1; + + case '_': + dst[0] = '_'; + dst[1] = '1'; + return 2; + + case ';': + dst[0] = '_'; + dst[1] = '2'; + return 2; + + case '[': + dst[0] = '_'; + dst[1] = '3'; + return 2; + + case '$': + memcpy(dst, "_00024", 6); + return 6; + + default: + dst[0] = c; + return 1; + } +} + +object +makeJNIName(Thread* t, object method, bool decorate) +{ + unsigned size = 5; + object className = ::className(t, methodClass(t, method)); + PROTECT(t, className); + for (unsigned i = 0; i < byteArrayLength(t, className) - 1; ++i) { + size += mangledSize(byteArrayBody(t, className, i)); + } + + ++ size; + + object methodName = ::methodName(t, method); + PROTECT(t, methodName); + for (unsigned i = 0; i < byteArrayLength(t, methodName) - 1; ++i) { + size += mangledSize(byteArrayBody(t, methodName, i)); + } + + object methodSpec = ::methodSpec(t, method); + PROTECT(t, methodSpec); + if (decorate) { + size += 2; + for (unsigned i = 1; i < byteArrayLength(t, methodSpec) - 1 + and byteArrayBody(t, methodSpec, i) != ')'; ++i) + { + size += mangledSize(byteArrayBody(t, methodSpec, i)); } } - // todo: decorate and translate as needed + object name = makeByteArray(t, size + 1, false); + unsigned index = 0; + + memcpy(&byteArrayBody(t, name, index), "Java_", 5); + index += 5; + + for (unsigned i = 0; i < byteArrayLength(t, className) - 1; ++i) { + index += mangle(byteArrayBody(t, className, i), + &byteArrayBody(t, name, index)); + } + + byteArrayBody(t, name, index++) = '_'; + + for (unsigned i = 0; i < byteArrayLength(t, methodName) - 1; ++i) { + index += mangle(byteArrayBody(t, methodName, i), + &byteArrayBody(t, name, index)); + } + + if (decorate) { + byteArrayBody(t, name, index++) = '_'; + byteArrayBody(t, name, index++) = '_'; + for (unsigned i = 1; i < byteArrayLength(t, methodSpec) - 1 + and byteArrayBody(t, methodSpec, i) != ')'; ++i) + { + index += mangle(byteArrayBody(t, className, i), + &byteArrayBody(t, name, index)); + } + } + + byteArrayBody(t, name, index++) = 0; + + assert(t, index == size + 1); + return name; }