1 /*
  2  * Copyright (c) 2016, 2018, 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);
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     _aot_id(aot_id),
142     _method_index(method_index) {
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   virtual bool is_unloading() { return false; }
180 
181   address exception_begin() const { return (address) _code + _meta->exception_handler_offset(); }
182 
183   virtual const char* name() const { return _name; }
184 
185   virtual int compile_id() const { return _aot_id; }
186 
187   void print_on(outputStream* st) const;
188   void print_on(outputStream* st, const char* msg) const;
189   void print() const;
190 
191   virtual void print_value_on(outputStream *stream) const;
192   virtual void print_block_comment(outputStream *stream, address block_begin) const { }
193   virtual void verify() {}
194 
195   virtual int comp_level() const { return CompLevel_aot; }
196   virtual address verified_entry_point() const { return _code + _meta->verified_entry_offset(); }
197   virtual void log_identity(xmlStream* stream) const;
198   virtual void log_state_change() const;
199   virtual bool make_entrant() NOT_TIERED({ ShouldNotReachHere(); return false; });
200   virtual bool make_not_entrant() { return make_not_entrant_helper(not_entrant); }
201   virtual bool make_not_used() { return make_not_entrant_helper(not_used); }
202   virtual address entry_point() const { return _code + _meta->entry_offset(); }
203   virtual bool make_zombie() { ShouldNotReachHere(); return false; }
204   virtual bool is_osr_method() const { return false; }
205   virtual int osr_entry_bci() const { ShouldNotReachHere(); return -1; }
206   // AOT compiled methods do not get into zombie state
207   virtual bool can_convert_to_zombie() { return false; }
208 
209   virtual bool is_evol_dependent_on(Klass* dependee);
210   virtual bool is_dependent_on_method(Method* dependee) { return true; }
211 
212   virtual void clear_inline_caches();
213 
214   virtual void print_pcs() {}
215 
216   virtual address scopes_data_end() const { return _meta->scopes_data_end(); }
217 
218   virtual oop oop_at(int index) const;
219   virtual Metadata* metadata_at(int index) const;
220 
221   virtual PcDesc* scopes_pcs_begin() const { return _meta->scopes_pcs_begin(); }
222   virtual PcDesc* scopes_pcs_end() const { return _meta->scopes_pcs_end(); }
223 
224   virtual address handler_table_begin() const { return _meta->handler_table_begin(); }
225   virtual address handler_table_end() const { return _meta->handler_table_end(); }
226 
227   virtual address nul_chk_table_begin() const { return _meta->nul_chk_table_begin(); }
228   virtual address nul_chk_table_end() const { return _meta->nul_chk_table_end(); }
229 
230   virtual address consts_begin() const { return _meta->consts_begin(); }
231   virtual address consts_end() const { return _meta->consts_end(); }
232 
233   virtual address stub_begin() const { return code_begin() + _meta->stub_offset(); }
234   virtual address stub_end() const { return code_end(); }
235 
236   virtual oop* oop_addr_at(int index) const { ShouldNotReachHere(); return NULL; }
237   virtual Metadata** metadata_addr_at(int index) const { ShouldNotReachHere(); return NULL; }
238 
239   // Accessor/mutator for the original pc of a frame before a frame was deopted.
240   address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); }
241   void    set_original_pc(const frame* fr, address pc) { *orig_pc_addr(fr) = pc; }
242 
243   virtual void metadata_do(void f(Metadata*));
244 
245   bool metadata_got_contains(Metadata **p) {
246     return p >= &_metadata_got[0] && p < &_metadata_got[_metadata_size];
247   }
248 
249   Metadata** metadata_begin() const { return &_metadata_got[0] ; }
250   Metadata** metadata_end()   const { return &_metadata_got[_metadata_size] ; }
251   const char* compile_kind() const { return "AOT"; }
252 
253   int get_state() const {
254     return (int) (*_state_adr);
255   }
256 
257   // inlined and non-virtual for AOTCodeHeap::oops_do
258   void do_oops(OopClosure* f) {
259     assert(_is_alive(), "");
260     if (_oop != NULL) {
261       f->do_oop(&_oop);
262     }
263 #if 0
264     metadata_oops_do(metadata_begin(), metadata_end(), f);
265 #endif
266   }
267 
268 
269 protected:
270   // AOT compiled methods are not flushed
271   void flush() {};
272 
273   NativeCallWrapper* call_wrapper_at(address call) const;
274   NativeCallWrapper* call_wrapper_before(address return_pc) const;
275   address call_instruction_address(address pc) const;
276 
277   CompiledStaticCall* compiledStaticCall_at(Relocation* call_site) const;
278   CompiledStaticCall* compiledStaticCall_at(address addr) const;
279   CompiledStaticCall* compiledStaticCall_before(address addr) const;
280 private:
281   bool is_aot_runtime_stub() const { return _method == NULL; }
282 };
283 
284 class PltNativeCallWrapper: public NativeCallWrapper {
285 private:
286   NativePltCall* _call;
287 
288 public:
289   PltNativeCallWrapper(NativePltCall* call) : _call(call) {}
290 
291   virtual address destination() const { return _call->destination(); }
292   virtual address instruction_address() const { return _call->instruction_address(); }
293   virtual address next_instruction_address() const { return _call->next_instruction_address(); }
294   virtual address return_address() const { return _call->return_address(); }
295   virtual address get_resolve_call_stub(bool is_optimized) const { return _call->plt_resolve_call(); }
296   virtual void set_destination_mt_safe(address dest) { _call->set_destination_mt_safe(dest); }
297   virtual void set_to_interpreted(const methodHandle& method, CompiledICInfo& info);
298   virtual void verify() const { _call->verify(); }
299   virtual void verify_resolve_call(address dest) const;
300 
301   virtual bool is_call_to_interpreted(address dest) const { return (dest == _call->plt_c2i_stub()); }
302   // TODO: assume for now that patching of aot code (got cell) is safe.
303   virtual bool is_safe_for_patching() const { return true; }
304 
305   virtual NativeInstruction* get_load_instruction(virtual_call_Relocation* r) const;
306 
307   virtual void *get_data(NativeInstruction* instruction) const {
308     return (void*)((NativeLoadGot*) instruction)->data();
309   }
310 
311   virtual void set_data(NativeInstruction* instruction, intptr_t data) {
312     ((NativeLoadGot*) instruction)->set_data(data);
313   }
314 };
315 
316 #endif //SHARE_VM_AOT_AOTCOMPILEDMETHOD_HPP