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