author | coleenp |
Wed, 02 May 2018 11:28:49 -0400 | |
changeset 50416 | ef980b9ac191 |
parent 49890 | 29b94ed63a09 |
child 51333 | f6641fcf7b7e |
permissions | -rw-r--r-- |
42650 | 1 |
/* |
49480
d7df2dd501ce
8199809: Don't include frame.inline.hpp and other.inline.hpp from .hpp files
coleenp
parents:
47216
diff
changeset
|
2 |
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. |
42650 | 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 |
||
49480
d7df2dd501ce
8199809: Don't include frame.inline.hpp and other.inline.hpp from .hpp files
coleenp
parents:
47216
diff
changeset
|
120 |
address* orig_pc_addr(const frame* fr); |
42650 | 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 |
||
46364
00a21c0ff97e
8173795: AOT support in raw_exception_handler_for_return_address is broken
dlong
parents:
46329
diff
changeset
|
179 |
address exception_begin() const { return (address) _code + _meta->exception_handler_offset(); } |
42650 | 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 |
|
46329
53ccc37bda19
8155672: Remove instanceKlassHandles and KlassHandles
coleenp
parents:
43942
diff
changeset
|
243 |
void flush_evol_dependents_on(InstanceKlass* dependee); |
42650 | 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 |
// inlined and non-virtual for AOTCodeHeap::oops_do |
|
261 |
void do_oops(OopClosure* f) { |
|
262 |
assert(_is_alive(), ""); |
|
263 |
if (_oop != NULL) { |
|
264 |
f->do_oop(&_oop); |
|
265 |
} |
|
266 |
#if 0 |
|
267 |
metadata_oops_do(metadata_begin(), metadata_end(), f); |
|
268 |
#endif |
|
269 |
} |
|
270 |
||
271 |
||
272 |
protected: |
|
273 |
// AOT compiled methods are not flushed |
|
274 |
void flush() {}; |
|
275 |
||
276 |
NativeCallWrapper* call_wrapper_at(address call) const; |
|
277 |
NativeCallWrapper* call_wrapper_before(address return_pc) const; |
|
278 |
address call_instruction_address(address pc) const; |
|
279 |
||
280 |
CompiledStaticCall* compiledStaticCall_at(Relocation* call_site) const; |
|
281 |
CompiledStaticCall* compiledStaticCall_at(address addr) const; |
|
282 |
CompiledStaticCall* compiledStaticCall_before(address addr) const; |
|
283 |
private: |
|
284 |
bool is_aot_runtime_stub() const { return _method == NULL; } |
|
285 |
||
286 |
protected: |
|
50416
ef980b9ac191
8203837: Split nmethod unloading from inline cache cleaning
coleenp
parents:
49890
diff
changeset
|
287 |
virtual bool do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive); |
ef980b9ac191
8203837: Split nmethod unloading from inline cache cleaning
coleenp
parents:
49890
diff
changeset
|
288 |
virtual bool do_unloading_jvmci() { return false; } |
42650 | 289 |
|
290 |
}; |
|
291 |
||
292 |
class PltNativeCallWrapper: public NativeCallWrapper { |
|
293 |
private: |
|
294 |
NativePltCall* _call; |
|
295 |
||
296 |
public: |
|
297 |
PltNativeCallWrapper(NativePltCall* call) : _call(call) {} |
|
298 |
||
299 |
virtual address destination() const { return _call->destination(); } |
|
300 |
virtual address instruction_address() const { return _call->instruction_address(); } |
|
301 |
virtual address next_instruction_address() const { return _call->next_instruction_address(); } |
|
302 |
virtual address return_address() const { return _call->return_address(); } |
|
303 |
virtual address get_resolve_call_stub(bool is_optimized) const { return _call->plt_resolve_call(); } |
|
304 |
virtual void set_destination_mt_safe(address dest) { _call->set_destination_mt_safe(dest); } |
|
305 |
virtual void set_to_interpreted(const methodHandle& method, CompiledICInfo& info); |
|
306 |
virtual void verify() const { _call->verify(); } |
|
307 |
virtual void verify_resolve_call(address dest) const; |
|
308 |
||
309 |
virtual bool is_call_to_interpreted(address dest) const { return (dest == _call->plt_c2i_stub()); } |
|
310 |
// TODO: assume for now that patching of aot code (got cell) is safe. |
|
311 |
virtual bool is_safe_for_patching() const { return true; } |
|
312 |
||
313 |
virtual NativeInstruction* get_load_instruction(virtual_call_Relocation* r) const; |
|
314 |
||
315 |
virtual void *get_data(NativeInstruction* instruction) const { |
|
316 |
return (void*)((NativeLoadGot*) instruction)->data(); |
|
317 |
} |
|
318 |
||
319 |
virtual void set_data(NativeInstruction* instruction, intptr_t data) { |
|
320 |
((NativeLoadGot*) instruction)->set_data(data); |
|
321 |
} |
|
322 |
}; |
|
323 |
||
324 |
#endif //SHARE_VM_AOT_AOTCOMPILEDMETHOD_HPP |