00001 /* Copyright 1994, LongView Technologies L.L.C. $Revision: 1.28 $ */ 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 # ifdef DELTA_COMPILER 00025 // These hold enough information to read or write a value embedded 00026 // in the instructions of an nmethod. They're used to update: 00027 // 1) embedded oops (isOop() == true) 00028 // 2) inline caches (isIC() == true) 00029 // 3) primitive caches (isPrimitive() == true) 00030 // 4) uncommom traps (isUncommonTrap() == true) 00031 // 5) runtime calls (isRuntimeCall() == true) 00032 // 6) internal word ref (isInternalWord() == true) 00033 // 7) external word ref (isExternalWord() == true) 00034 // when objects move (GC) or if code moves (compacting the code heap) 00035 // 00036 // A relocInfo is represented in 16 bits: 00037 // 3 bits indicating the relocation type 00038 // 13 bits indicating the byte offset from the previous relocInfo address 00039 00040 const int reloc_type_width = 3; 00041 const int reloc_offset_width = 13; 00042 00043 class relocInfo : ValueObj { 00044 protected: 00045 unsigned short _value; 00046 public: 00047 00048 // constructor 00049 relocInfo(int type, int offset); 00050 00051 enum relocType { 00052 none = -1, 00053 oop_type = 0, // embedded oop (non-smi) 00054 ic_type = 1, // inline cache 00055 prim_type = 2, // primitive call 00056 runtime_call_type = 3, // Relative reference to external segment 00057 external_word_type = 4, // Absolute reference to external segment 00058 internal_word_type = 5, // Absolute reference to local segment 00059 uncommon_type = 6, // uncommon branch 00060 dll_type = 7 // DLL call 00061 }; 00062 00063 // accessors 00064 int offset() const { 00065 return get_unsigned_bitfield((int)_value, 0, reloc_offset_width); 00066 } 00067 int type() const { 00068 return get_unsigned_bitfield((int)_value, reloc_offset_width, reloc_type_width); 00069 } 00070 00071 // marks inline cache? 00072 bool isIC() const { return type() == ic_type; } 00073 // marks primitive call? 00074 bool isPrimitive() const { return type() == prim_type; } 00075 // marks uncommon trap? 00076 bool isUncommonTrap() const { return type() == uncommon_type; } 00077 // is oop encoded in instruction? 00078 bool isOop() const { return type() == oop_type; } 00079 // is runtime call? 00080 bool isRuntimeCall() const { return type() == runtime_call_type; } 00081 // is internal word reference? 00082 bool isInternalWord() const { return type() == internal_word_type; } 00083 // is external word reference? 00084 bool isExternalWord() const { return type() == internal_word_type; } 00085 // is external word reference? 00086 bool isDLL() const { return type() == dll_type; } 00087 00088 // marks any call? 00089 bool isCall() const { return !isOop(); } 00090 00091 // If the offset is 0 the relocInfo is invalid. 00092 // Only used for padding (relocInfo array is oop aligned in nmethod). 00093 bool isValid() const { return offset() != 0; } 00094 00095 // prints the relocation with retrieved information from the nmethod. 00096 int print(nmethod* c, int last_offset); 00097 }; 00098 00099 // A relocIterator iterates through the relocation information of a nmethod. 00100 // Usage: 00101 // relocIterator iter(nm); 00102 // while (iter.next()) { 00103 // switch (iter.type()) { 00104 // case relocInfo::oop_type: 00105 // case relocInfo::ic_type: 00106 // case relocInfo::prim_type: 00107 // case relocInfo::uncommon_type: 00108 // case relocInfo::runtime_call_type: 00109 // case relocInfo::internal_word_type: 00110 // case relocInfo::external_word_type: 00111 // } 00112 // } 00113 00114 class relocIterator : StackObj { 00115 private: 00116 char* addr; // this is the first instance variable comment -Lars 00117 relocInfo* current; // this is the 2nd instance variable comment -Lars 00118 relocInfo* end; 00119 public: 00120 00121 // constructor 00122 relocIterator(const nmethod* nm); 00123 00124 // get next reloc info, return !eos 00125 bool next() { 00126 current++; 00127 if (current == end) return false; 00128 addr += current->offset(); 00129 return current->isValid(); 00130 } 00131 00132 // accessors 00133 int type() const { return current->type(); } 00134 00135 bool is_call() const { return current->isCall(); } 00136 00137 int* word_addr() const { return (int*) addr; } 00138 00139 oop* oop_addr() const { 00140 assert(type() == relocInfo::oop_type, "must be oop"); 00141 return (oop*) addr; 00142 } 00143 00144 CompiledIC* ic() const { 00145 assert(type() == relocInfo::ic_type, "must be inline cache"); 00146 return CompiledIC_from_relocInfo(addr); 00147 } 00148 00149 PrimitiveIC* primIC() const { 00150 assert(type() == relocInfo::prim_type, "must be inline cache"); 00151 return PrimitiveIC_from_relocInfo(addr); 00152 } 00153 00154 /* 00155 CompiledDLL_Cache* DLLIC() const { 00156 assert(type() == relocInfo::dll_type, "must be inline cache"); 00157 return compiledDLL_Cache_from_relocInfo(addr); 00158 } 00159 */ 00160 00161 char* call_end() const { 00162 assert(type() != relocInfo::oop_type, "must be call"); 00163 return addr + 4; // INTEL-SPECIFIC 00164 } 00165 00166 char* callDestination() const { 00167 assert(type() != relocInfo::oop_type, "must be call"); 00168 return *(char**)addr + int(addr) + 4; // INTEL-SPECIFIC 00169 } 00170 00171 // for uncommon traps only: was it ever executed? 00172 bool wasUncommonTrapExecuted() const; 00173 00174 // is current reloc position dependent 00175 bool is_position_dependent() const; 00176 }; 00177 00178 #endif