dll.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.19 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 # include "incls/_precompiled.incl"
00025 # include "incls/_dll.cpp.incl"
00026 
00027 
00028 // InterpretedDLL_Cache implementation
00029 
00030 void InterpretedDLL_Cache::verify() {
00031   // check oops
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 // CompiledDLL_Cache implementation
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   // check layout
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   // check oops
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   // check destination
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 // DLLs implementation
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   // Call backs to Delta
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   // get DLL call info
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   // do lookup, patch & return entry point
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   // get DLL call info
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   // do lookup, patch & return entry point
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; // proc will be retrieved in dll_enter_async_call
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   // nothing to do here for now
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   }

Generated on Mon Oct 9 13:37:08 2006 for Strongtalk VM by  doxygen 1.4.7