X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fnative%2Fnative.cpp;h=5515218363e8f88cbeac21682ac5d3dd05734205;hb=735bdda890a385d1fa9cc532faadbbc96f2d1218;hp=7f0f078ba55f0bd3cfb029a05def1836b3408198;hpb=9a310463406909b85dbed961b2265b7a383f8ad3;p=cacao.git diff --git a/src/native/native.cpp b/src/native/native.cpp index 7f0f078ba..551521836 100644 --- a/src/native/native.cpp +++ b/src/native/native.cpp @@ -1,6 +1,6 @@ /* src/native/native.cpp - native library support - Copyright (C) 1996-2005, 2006, 2007, 2008 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2009 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -34,19 +34,20 @@ #include #include -#include "mm/memory.h" +#include "mm/memory.hpp" #include "native/jni.hpp" #include "native/native.hpp" #include "threads/mutex.hpp" -#include "toolbox/logging.h" +#include "toolbox/logging.hpp" #include "vm/jit/builtin.hpp" #include "vm/exceptions.hpp" #include "vm/global.h" #include "vm/globals.hpp" +#include "vm/hook.hpp" #include "vm/loader.hpp" #include "vm/options.h" #include "vm/os.hpp" @@ -57,10 +58,6 @@ #include "vm/jit/asmpart.h" #include "vm/jit/jit.hpp" -#if defined(ENABLE_JVMTI) -#include "native/jvmti/cacaodbg.h" -#endif - /* native_make_overloaded_function ********************************************* @@ -391,18 +388,30 @@ void* NativeMethods::resolve_method(methodinfo* m) utf* newname = native_make_overloaded_function(name, m->descriptor); // Try to find the symbol. - void* symbol = NULL; + void* symbol; + + // Try to find the native method symbol in the native methods registered + // with the VM. + symbol = find_registered_method(m); + + if (symbol != NULL) + if (opt_verbosejni) + printf("internal ]\n"); #if defined(ENABLE_DL) - // Get the classloader. - classloader_t* classloader = class_get_classloader(m->clazz); + classloader_t* classloader; + if (symbol == NULL) { + // Get the classloader. + classloader = class_get_classloader(m->clazz); - // Resolve the native method name from the native libraries. - NativeLibraries& libraries = VM::get_current()->get_nativelibraries(); - symbol = libraries.resolve_symbol(name, classloader); + // Resolve the native method name from the native libraries. + NativeLibraries& libraries = VM::get_current()->get_nativelibraries(); - if (symbol == NULL) - symbol = libraries.resolve_symbol(newname, classloader); + symbol = libraries.resolve_symbol(name, classloader); + + if (symbol == NULL) + symbol = libraries.resolve_symbol(newname, classloader); + } # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) if (symbol == NULL) { @@ -417,17 +426,16 @@ void* NativeMethods::resolve_method(methodinfo* m) class_java_lang_ClassLoader, true); - if (method_findNative == NULL) - return NULL; - - // Try the normal name. - java_handle_t* s = javastring_new(name); - symbol = (void*) vm_call_method_long(method_findNative, NULL, classloader, s); - - // If not found, try the mangled name. - if (symbol == NULL) { - s = javastring_new(newname); + if (method_findNative != NULL) { + // Try the normal name. + java_handle_t* s = javastring_new(name); symbol = (void*) vm_call_method_long(method_findNative, NULL, classloader, s); + + // If not found, try the mangled name. + if (symbol == NULL) { + s = javastring_new(newname); + symbol = (void*) vm_call_method_long(method_findNative, NULL, classloader, s); + } } } # endif @@ -437,21 +445,6 @@ void* NativeMethods::resolve_method(methodinfo* m) printf("JNI ]\n"); #endif - // If not found already, try to find the native method symbol in - // the native methods registered with the VM. - if (symbol == NULL) { - symbol = find_registered_method(m); - - if (symbol != NULL) - if (opt_verbosejni) - printf("internal ]\n"); - } - -#if defined(ENABLE_JVMTI) - /* fire Native Method Bind event */ - if (jvmti) jvmti_NativeMethodBind(m, f, &f); -#endif - // Symbol not found? Throw an exception. if (symbol == NULL) { if (opt_verbosejni) @@ -460,6 +453,9 @@ void* NativeMethods::resolve_method(methodinfo* m) exceptions_throw_unsatisfiedlinkerror(m->name); } + // Hook point just after method resolving finished. + Hook::native_resolved(m, symbol, &symbol); + return symbol; } @@ -508,12 +504,8 @@ void* NativeLibrary::open() if (opt_verbosejni) printf("failed ]\n"); - if (opt_verbose) { - log_start(); - log_print("NativeLibrary::open: os::dlopen failed: "); - log_print(os::dlerror()); - log_finish(); - } + if (opt_PrintWarnings) + log_println("NativeLibrary::open: os::dlopen failed: %s", os::dlerror()); return NULL; } @@ -548,12 +540,8 @@ void NativeLibrary::close() if (opt_verbosejni) printf("failed ]\n"); - if (opt_verbose) { - log_start(); - log_print("NativeLibrary::close: os::dlclose failed: "); - log_print(os::dlerror()); - log_finish(); - } + if (opt_PrintWarnings) + log_println("NativeLibrary::close: os::dlclose failed: %s", os::dlerror()); } if (opt_verbosejni) @@ -727,6 +715,110 @@ void* NativeLibraries::resolve_symbol(utf* symbolname, classloader_t* classloade } +/** + * Registers a new native agent by specified by it's library name + * and with an optional options string. + * + * @param library Name of the native agent library. + * @param options The options string or NULL if not specified. + */ +#if defined(ENABLE_JVMTI) +void NativeAgents::register_agent_library(char* library, char* options) +{ + NativeAgent na(library, options); + + // Insert native agent into list of agents. + _agents.push_back(na); +} +#endif + + +/** + * Registers a new native agent by specified by a path to it's library + * and with an optional options string. + * + * @param path Path of the native agent library. + * @param options The options string or NULL if not specified. + */ +#if defined(ENABLE_JVMTI) +void NativeAgents::register_agent_path(char* path, char* options) +{ + os::abort("NativeAgents::register_agent_library: Implement me!"); +} +#endif + + +/** + * Loads all registered native agents and in turn calls their exported + * start-up functions (Agent_OnLoad). If one of the agents reports an + * error during start-up, the loading is stopped. + * + * @return True if all agents were loaded successfully, false if + * one of them was not found or reported an error. + */ +#if defined(ENABLE_JVMTI) +bool NativeAgents::load_agents() +{ + // Iterate over all registered agents. + for (std::vector::iterator it = _agents.begin(); it != _agents.end(); ++it) { + NativeAgent& na = *(it); + + // Construct agent library name. + size_t len = + os::strlen(NATIVE_LIBRARY_PREFIX) + + os::strlen(na.get_library()) + + os::strlen(NATIVE_LIBRARY_SUFFIX) + + os::strlen("0"); + + char* p = MNEW(char, len); + + os::strcpy(p, NATIVE_LIBRARY_PREFIX); + os::strcat(p, na.get_library()); + os::strcat(p, NATIVE_LIBRARY_SUFFIX); + + utf* u = utf_new_char(p); + + MFREE(p, char, len); + + // Construct new native library. + NativeLibrary nl(u); + + // Try to open the library. + if (nl.open() == NULL) + return false; + + // Resolve Agent_OnLoad function. + void* onload = os::dlsym(nl.get_handle(), "Agent_OnLoad"); + + // Call Agent_OnLoad function if present. + if (onload != NULL) { + JNIEXPORT jint (JNICALL *Agent_OnLoad) (JavaVM*, char*, void*); + JavaVM* vm = VM::get_current()->get_javavm(); + + Agent_OnLoad = (JNIEXPORT jint (JNICALL *)(JavaVM*, char*, void*)) (uintptr_t) onload; + + jint result = Agent_OnLoad(vm, na.get_options(), NULL); + + // Check for error in Agent_OnLoad. + if (result != 0) { + nl.close(); + return false; + } + } + + // According to the interface spec, the library _must_ export + // a start-up function. + else { + log_println("NativeAgents::load_agents: Native agent library does not export Agent_OnLoad"); + return false; + } + } + + return true; +} +#endif + + /* native_new_and_init ********************************************************* Creates a new object on the heap and calls the initializer.