00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 # include "incls/_precompiled.incl"
00025 # include "incls/_dll.cpp.incl"
00026
00027
00028
00029
00030 void InterpretedDLL_Cache::verify() {
00031
00032 if (!dll_name()->is_symbol()) fatal("dll name is not a symbolOop");
00033 if (!funct_name()->is_symbol()) fatal("function name is not a symbolOop");
00034 if (number_of_arguments() < 0) fatal("illegal number of arguments");
00035 }
00036
00037
00038 void InterpretedDLL_Cache::print() {
00039 std->print("DLL call ");
00040 dll_name()->print_value();
00041 std->print("::");
00042 funct_name()->print_value();
00043 std->print(" (0x%x, %s, interpreted)\n", entry_point(), async() ? "asynchronous" : "synchronous");
00044 }
00045
00046
00047
00048
00049 bool CompiledDLL_Cache::async() const {
00050 char* d = destination();
00051 return
00052 d == StubRoutines::lookup_DLL_entry(true) ||
00053 d == StubRoutines::call_DLL_entry(true);
00054 }
00055
00056
00057 void CompiledDLL_Cache::verify() {
00058
00059 mov_at(mov_edx_instruction_offset)->verify();
00060 test_at(test_1_instruction_offset)->verify();
00061 test_at(test_2_instruction_offset)->verify();
00062 NativeCall::verify();
00063
00064 if (!dll_name()->is_symbol()) fatal("dll name is not a symbolOop");
00065 if (!function_name()->is_symbol()) fatal("function name is not a symbolOop");
00066
00067 char* d = destination();
00068 if (d != StubRoutines::lookup_DLL_entry(true) &&
00069 d != StubRoutines::lookup_DLL_entry(false) &&
00070 d != StubRoutines::call_DLL_entry(true) &&
00071 d != StubRoutines::call_DLL_entry(false)) {
00072 fatal1("CompiledDLL_Cache destination 0x%x incorrect", d);
00073 }
00074 }
00075
00076
00077 void CompiledDLL_Cache::print() {
00078 std->print("DLL call ");
00079 dll_name()->print_value();
00080 std->print("::");
00081 function_name()->print_value();
00082 std->print(" (0x%x, %s, compiled)\n", entry_point(), async() ? "asynchronous" : "synchronous");
00083 }
00084
00085
00086
00087
00088 dll_func DLLs::lookup(symbolOop name, DLL* library) {
00089 char buffer[200];
00090 name->copy_null_terminated(buffer, 200);
00091 return os::dll_lookup(buffer, library);
00092 }
00093
00094
00095 DLL* DLLs::load(symbolOop name) {
00096 char buffer[200];
00097 name->copy_null_terminated(buffer, 200);
00098 return os::dll_load(buffer);
00099 }
00100
00101
00102 bool DLLs::unload(DLL* library) {
00103 return os::dll_unload(library);
00104 }
00105
00106
00107 extern Compiler* theCompiler;
00108
00109 dll_func DLLs::lookup_fail(symbolOop dll_name, symbolOop function_name) {
00110
00111 if (Universe::dll_lookup_receiver()->is_nil()) {
00112 warning("dll lookup receiver is not set");
00113 }
00114 assert(theCompiler == NULL, "Cannot handle call back during compilation");
00115
00116 oop res = Delta::call(Universe::dll_lookup_receiver(), Universe::dll_lookup_selector(), function_name, dll_name);
00117
00118 return res->is_proxy()
00119 ? (dll_func) proxyOop(res)->get_pointer()
00120 : NULL;
00121 }
00122
00123
00124 dll_func DLLs::lookup(symbolOop dll_name, symbolOop function_name) {
00125 dll_func result = lookup_fail(dll_name, function_name);
00126 if (result) {
00127 if (TraceDLLLookup) {
00128 std->print("DLL looking for ");
00129 dll_name->print_symbol_on(std);
00130 std->print("::");
00131 function_name->print_symbol_on(std);
00132 std->print_cr(" -> 0x%lx", result);
00133 }
00134 return result;
00135 }
00136
00137 std->print("DLL lookup ");
00138 function_name->print_symbol_on(std);
00139 std->print(" in ");
00140 dll_name->print_symbol_on(std);
00141 std->print(" failed.");
00142 std->cr();
00143
00144 DeltaProcess::active()->suspend(DLL_lookup_error);
00145 return NULL;
00146 }
00147
00148
00149 dll_func DLLs::lookup_and_patch_InterpretedDLL_Cache() {
00150
00151 frame f = DeltaProcess::active()->last_frame();
00152 methodOop m = f.method();
00153 CodeIterator it(m, m->bci_from(f.hp()));
00154 InterpretedDLL_Cache* cache = it.dll_cache();
00155 assert(cache->entry_point() == NULL, "should not be set yet");
00156
00157 dll_func function = lookup(cache->dll_name(), cache->funct_name());
00158 cache->set_entry_point(function);
00159 return function;
00160 }
00161
00162
00163 dll_func DLLs::lookup_and_patch_CompiledDLL_Cache() {
00164
00165 frame f = DeltaProcess::active()->last_frame();
00166 CompiledDLL_Cache* cache = compiledDLL_Cache_from_return_address(f.pc());
00167 assert(cache->entry_point() == NULL, "should not be set yet");
00168
00169 dll_func function = lookup(cache->dll_name(), cache->function_name());
00170 cache->set_entry_point(function);
00171 cache->set_destination(StubRoutines::call_DLL_entry(cache->async()));
00172 return function;
00173 }
00174
00175
00176 void DLLs::enter_async_call(DeltaProcess** addr) {
00177 DeltaProcess* proc = DeltaProcess::active();
00178 *addr = proc;
00179 proc->transfer_and_continue();
00180 }
00181
00182
00183 void DLLs::exit_async_call(DeltaProcess** addr) {
00184 DeltaProcess* proc = *addr;
00185 proc->wait_for_control();
00186 }
00187
00188
00189 void DLLs::exit_sync_call(DeltaProcess** addr) {
00190
00191 }
00192
00193 CompiledDLL_Cache* compiledDLL_Cache_from_return_address(char* return_address) {
00194 CompiledDLL_Cache* cache = (CompiledDLL_Cache*)(nativeCall_from_return_address(return_address));
00195 #ifdef ASSERT
00196 cache->verify();
00197 #endif
00198 return cache;
00199 }
00200
00201 CompiledDLL_Cache* compiledDLL_Cache_from_relocInfo(char* displacement_address) {
00202 return (CompiledDLL_Cache*)nativeCall_from_relocInfo(displacement_address);
00203 }