1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #ifndef SHARE_VM_AOT_AOTCOMPILEDMETHOD_HPP 25 #define SHARE_VM_AOT_AOTCOMPILEDMETHOD_HPP 26 27 #include "code/codeCache.hpp" 28 #include "code/compiledIC.hpp" 29 #include "code/compiledMethod.hpp" 30 #include "code/pcDesc.hpp" 31 #include "code/relocInfo.hpp" 32 33 class AOTCodeHeap; 34 35 class aot_metadata { 36 private: 37 int _size; 38 int _code_size; 39 int _entry; 40 int _verified_entry; 41 int _exception_handler_offset; 42 int _deopt_handler_offset; 43 int _stubs_offset; 44 int _frame_size; 45 // location in frame (offset for sp) that deopt can store the original 46 // pc during a deopt. 47 int _orig_pc_offset; 48 int _unsafe_access; 49 50 int _pc_desc_begin; 51 int _scopes_begin; 52 int _reloc_begin; 53 int _exception_table_begin; 54 int _oopmap_begin; 55 address at_offset(size_t offset) const { return ((address) this) + offset; } 56 public: 57 int code_size() const { return _code_size; } 58 int frame_size() const { return _frame_size / HeapWordSize; } 59 PcDesc *scopes_pcs_begin() const { return (PcDesc *) at_offset(_pc_desc_begin); } 60 PcDesc *scopes_pcs_end() const { return (PcDesc *) at_offset(_scopes_begin); } 61 address scopes_data_begin() const { return at_offset(_scopes_begin); } 62 address scopes_data_end() const { return at_offset(_reloc_begin); } 63 relocInfo* relocation_begin() const { return (relocInfo*) at_offset(_reloc_begin); } 64 relocInfo* relocation_end() const { return (relocInfo*) at_offset(_exception_table_begin); } 65 address handler_table_begin () const { return at_offset(_exception_table_begin); } 66 address handler_table_end() const { return at_offset(_oopmap_begin); } 67 68 address nul_chk_table_begin() const { return at_offset(_oopmap_begin); } 69 address nul_chk_table_end() const { return at_offset(_oopmap_begin); } 70 71 ImmutableOopMapSet* oopmap_set() const { return (ImmutableOopMapSet*) at_offset(_oopmap_begin); } 72 73 address consts_begin() const { return at_offset(_size); } 74 address consts_end() const { return at_offset(_size); } 75 int stub_offset() const { return _stubs_offset; } 76 int entry_offset() const { return _entry; } 77 int verified_entry_offset() const { return _verified_entry; } 78 int exception_handler_offset() const { return _exception_handler_offset; } 79 int deopt_handler_offset() const { return _deopt_handler_offset; } 80 int orig_pc_offset() const { return _orig_pc_offset; } 81 82 int handler_table_size() const { return handler_table_end() - handler_table_begin(); } 83 int nul_chk_table_size() const { return nul_chk_table_end() - nul_chk_table_begin(); } 84 bool has_unsafe_access() const { return _unsafe_access != 0; } 85 86 }; 87 88 /* 89 * Use this for AOTCompiledMethods since a lot of the fields in CodeBlob gets the same 90 * value when they come from AOT. code_begin == content_begin, etc... */ 91 class AOTCompiledMethodLayout : public CodeBlobLayout { 92 public: 93 AOTCompiledMethodLayout(address code_begin, address code_end, address relocation_begin, address relocation_end) : 94 CodeBlobLayout( 95 code_begin, // code_begin 96 code_end, // code_end 97 code_begin, // content_begin 98 code_end, // content_end 99 code_end, // data_end 100 relocation_begin, // relocation_begin 101 relocation_end 102 ) { 103 } 104 }; 105 106 class AOTCompiledMethod : public CompiledMethod, public CHeapObj<mtCode> { 107 private: 108 address _code; 109 aot_metadata* _meta; 110 Metadata** _metadata_got; 111 jlong* _state_adr; // Address of cell to indicate aot method state (in_use or not_entrant) 112 AOTCodeHeap* _heap; // code heap which has this method 113 const char* _name; // For stub: "AOT Stub<name>" for stub, 114 // For nmethod: "<u2_size>Ljava/lang/ThreadGroup;<u2_size>addUnstarted<u2_size>()V" 115 const int _metadata_size; // size of _metadata_got 116 const int _aot_id; 117 const int _method_index; 118 oop _oop; // method()->method_holder()->klass_holder() 119 120 address* orig_pc_addr(const frame* fr) { return (address*) ((address)fr->unextended_sp() + _meta->orig_pc_offset()); } 121 bool make_not_entrant_helper(int new_state); 122 123 public: 124 using CHeapObj<mtCode>::operator new; 125 using CHeapObj<mtCode>::operator delete; 126 127 int method_index() const { return _method_index; } 128 void set_oop(oop o) { _oop = o; } 129 130 AOTCompiledMethod(address code, Method* method, aot_metadata* meta, address metadata_got, int metadata_size, jlong* state_adr, AOTCodeHeap* heap, const char* name, int method_index, int aot_id) : 131 CompiledMethod(method, name, compiler_jvmci, // AOT code is generated by JVMCI compiler 132 AOTCompiledMethodLayout(code, code + meta->code_size(), (address) meta->relocation_begin(), (address) meta->relocation_end()), 133 0 /* frame_complete_offset */, meta->frame_size() /* frame_size */, meta->oopmap_set(), false /* caller_must_gc_arguments */), 134 _code(code), 135 _meta(meta), 136 _metadata_got((Metadata**) metadata_got), 137 _state_adr(state_adr), 138 _heap(heap), 139 _name(name), 140 _metadata_size(metadata_size), 141 _method_index(method_index), 142 _aot_id(aot_id) { 143 144 _is_far_code = CodeCache::is_far_target(code) || 145 CodeCache::is_far_target(code + meta->code_size()); 146 _exception_cache = NULL; 147 148 _scopes_data_begin = (address) _meta->scopes_data_begin(); 149 _deopt_handler_begin = (address) _code + _meta->deopt_handler_offset(); 150 _deopt_mh_handler_begin = (address) this; 151 152 _pc_desc_container.reset_to(scopes_pcs_begin()); 153 154 // Mark the AOTCompiledMethod as in_use 155 *_state_adr = nmethod::in_use; 156 set_has_unsafe_access(_meta->has_unsafe_access()); 157 _oop = NULL; 158 } 159 160 virtual bool is_aot() const { return true; } 161 virtual bool is_runtime_stub() const { return is_aot_runtime_stub(); } 162 163 virtual bool is_compiled() const { return !is_aot_runtime_stub(); } 164 165 virtual bool is_locked_by_vm() const { return false; } 166 167 int state() const { return *_state_adr; } 168 169 // Non-virtual for speed 170 bool _is_alive() const { return state() < zombie; } 171 172 virtual bool is_zombie() const { return state() == zombie; } 173 virtual bool is_unloaded() const { return state() == unloaded; } 174 virtual bool is_not_entrant() const { return state() == not_entrant || 175 state() == not_used; } 176 virtual bool is_alive() const { return _is_alive(); } 177 virtual bool is_in_use() const { return state() == in_use; } 178 179 address exception_begin() { return (address) _code + _meta->exception_handler_offset(); } 180 181 virtual const char* name() const { return _name; } 182 183 virtual int compile_id() const { return _aot_id; } 184 185 void print_on(outputStream* st) const; 186 void print_on(outputStream* st, const char* msg) const; 187 void print() const; 188 189 virtual void print_value_on(outputStream *stream) const; 190 virtual void print_block_comment(outputStream *stream, address block_begin) const { } 191 virtual void verify() {} 192 193 virtual int comp_level() const { return CompLevel_aot; } 194 virtual address verified_entry_point() const { return _code + _meta->verified_entry_offset(); } 195 virtual void log_identity(xmlStream* stream) const; 196 virtual void log_state_change() const; 197 virtual bool make_entrant(); 198 virtual bool make_not_entrant() { return make_not_entrant_helper(not_entrant); } 199 virtual bool make_not_used() { return make_not_entrant_helper(not_used); } 200 virtual address entry_point() const { return _code + _meta->entry_offset(); } 201 virtual bool make_zombie() { ShouldNotReachHere(); return false; } 202 virtual bool is_osr_method() const { return false; } 203 virtual int osr_entry_bci() const { ShouldNotReachHere(); return -1; } 204 // AOT compiled methods do not get into zombie state 205 virtual bool can_convert_to_zombie() { return false; } 206 207 virtual bool is_evol_dependent_on(Klass* dependee); 208 virtual bool is_dependent_on_method(Method* dependee) { return true; } 209 210 virtual void clear_inline_caches(); 211 212 virtual void print_pcs() {} 213 214 virtual address scopes_data_end() const { return _meta->scopes_data_end(); } 215 216 virtual oop oop_at(int index) const; 217 virtual Metadata* metadata_at(int index) const; 218 219 virtual PcDesc* scopes_pcs_begin() const { return _meta->scopes_pcs_begin(); } 220 virtual PcDesc* scopes_pcs_end() const { return _meta->scopes_pcs_end(); } 221 222 virtual address handler_table_begin() const { return _meta->handler_table_begin(); } 223 virtual address handler_table_end() const { return _meta->handler_table_end(); } 224 225 virtual address nul_chk_table_begin() const { return _meta->nul_chk_table_begin(); } 226 virtual address nul_chk_table_end() const { return _meta->nul_chk_table_end(); } 227 228 virtual address consts_begin() const { return _meta->consts_begin(); } 229 virtual address consts_end() const { return _meta->consts_end(); } 230 231 virtual address stub_begin() const { return code_begin() + _meta->stub_offset(); } 232 virtual address stub_end() const { return code_end(); } 233 234 virtual oop* oop_addr_at(int index) const { ShouldNotReachHere(); return NULL; } 235 virtual Metadata** metadata_addr_at(int index) const { ShouldNotReachHere(); return NULL; } 236 237 // Accessor/mutator for the original pc of a frame before a frame was deopted. 238 address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); } 239 void set_original_pc(const frame* fr, address pc) { *orig_pc_addr(fr) = pc; } 240 241 #ifdef HOTSWAP 242 // Flushing and deoptimization in case of evolution 243 void flush_evol_dependents_on(instanceKlassHandle dependee); 244 #endif // HOTSWAP 245 246 virtual void metadata_do(void f(Metadata*)); 247 248 bool metadata_got_contains(Metadata **p) { 249 return p >= &_metadata_got[0] && p < &_metadata_got[_metadata_size]; 250 } 251 252 Metadata** metadata_begin() const { return &_metadata_got[0] ; } 253 Metadata** metadata_end() const { return &_metadata_got[_metadata_size] ; } 254 const char* compile_kind() const { return "AOT"; } 255 256 int get_state() const { 257 return (int) (*_state_adr); 258 } 259 260 virtual void oops_do(OopClosure* f); 261 262 // inlined and non-virtual for AOTCodeHeap::oops_do 263 void do_oops(OopClosure* f) { 264 assert(_is_alive(), ""); 265 if (_oop != NULL) { 266 f->do_oop(&_oop); 267 } 268 #if 0 269 metadata_oops_do(metadata_begin(), metadata_end(), f); 270 #endif 271 } 272 273 274 protected: 275 // AOT compiled methods are not flushed 276 void flush() {}; 277 278 NativeCallWrapper* call_wrapper_at(address call) const; 279 NativeCallWrapper* call_wrapper_before(address return_pc) const; 280 address call_instruction_address(address pc) const; 281 282 CompiledStaticCall* compiledStaticCall_at(Relocation* call_site) const; 283 CompiledStaticCall* compiledStaticCall_at(address addr) const; 284 CompiledStaticCall* compiledStaticCall_before(address addr) const; 285 private: 286 bool is_aot_runtime_stub() const { return _method == NULL; } 287 288 protected: 289 virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive, bool unloading_occurred); 290 virtual bool do_unloading_jvmci(BoolObjectClosure* is_alive, bool unloading_occurred) { return false; } 291 292 }; 293 294 class PltNativeCallWrapper: public NativeCallWrapper { 295 private: 296 NativePltCall* _call; 297 298 public: 299 PltNativeCallWrapper(NativePltCall* call) : _call(call) {} 300 301 virtual address destination() const { return _call->destination(); } 302 virtual address instruction_address() const { return _call->instruction_address(); } 303 virtual address next_instruction_address() const { return _call->next_instruction_address(); } 304 virtual address return_address() const { return _call->return_address(); } 305 virtual address get_resolve_call_stub(bool is_optimized) const { return _call->plt_resolve_call(); } 306 virtual void set_destination_mt_safe(address dest) { _call->set_destination_mt_safe(dest); } 307 virtual void set_to_interpreted(const methodHandle& method, CompiledICInfo& info); 308 virtual void verify() const { _call->verify(); } 309 virtual void verify_resolve_call(address dest) const; 310 311 virtual bool is_call_to_interpreted(address dest) const { return (dest == _call->plt_c2i_stub()); } 312 // TODO: assume for now that patching of aot code (got cell) is safe. 313 virtual bool is_safe_for_patching() const { return true; } 314 315 virtual NativeInstruction* get_load_instruction(virtual_call_Relocation* r) const; 316 317 virtual void *get_data(NativeInstruction* instruction) const { 318 return (void*)((NativeLoadGot*) instruction)->data(); 319 } 320 321 virtual void set_data(NativeInstruction* instruction, intptr_t data) { 322 ((NativeLoadGot*) instruction)->set_data(data); 323 } 324 }; 325 326 #endif //SHARE_VM_AOT_AOTCOMPILEDMETHOD_HPP