1 | /* |
2 | * Copyright (c) 2011, 2019, 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_JVMCI_JVMCICODEINSTALLER_HPP |
25 | #define SHARE_JVMCI_JVMCICODEINSTALLER_HPP |
26 | |
27 | #include "code/debugInfoRec.hpp" |
28 | #include "code/exceptionHandlerTable.hpp" |
29 | #include "code/nativeInst.hpp" |
30 | #include "jvmci/jvmci.hpp" |
31 | #include "jvmci/jvmciEnv.hpp" |
32 | |
33 | #if INCLUDE_AOT |
34 | class RelocBuffer : public StackObj { |
35 | enum { stack_size = 1024 }; |
36 | public: |
37 | RelocBuffer() : _size(0), _buffer(0) {} |
38 | ~RelocBuffer(); |
39 | void ensure_size(size_t bytes); |
40 | void set_size(size_t bytes); |
41 | address begin() const; |
42 | size_t size() const { return _size; } |
43 | private: |
44 | size_t _size; |
45 | char _static_buffer[stack_size]; |
46 | char *_buffer; |
47 | }; |
48 | |
49 | class CodeInstaller; |
50 | |
51 | class AOTOopRecorder : public OopRecorder { |
52 | public: |
53 | AOTOopRecorder(CodeInstaller* code_inst, Arena* arena = NULL, bool deduplicate = false); |
54 | |
55 | virtual int find_index(Metadata* h); |
56 | virtual int find_index(jobject h); |
57 | int nr_meta_refs() const; |
58 | jobject meta_element(int pos) const; |
59 | |
60 | private: |
61 | void record_meta_ref(jobject ref, int index); |
62 | |
63 | GrowableArray<jobject>* _meta_refs; |
64 | |
65 | CodeInstaller* _code_inst; |
66 | }; |
67 | #endif // INCLUDE_AOT |
68 | |
69 | class CodeMetadata { |
70 | public: |
71 | CodeMetadata() {} |
72 | |
73 | CodeBlob* get_code_blob() const { return _cb; } |
74 | |
75 | PcDesc* get_pc_desc() const { return _pc_desc; } |
76 | int get_nr_pc_desc() const { return _nr_pc_desc; } |
77 | |
78 | u_char* get_scopes_desc() const { return _scopes_desc; } |
79 | int get_scopes_size() const { return _nr_scopes_desc; } |
80 | |
81 | #if INCLUDE_AOT |
82 | RelocBuffer* get_reloc_buffer() { return &_reloc_buffer; } |
83 | AOTOopRecorder* get_oop_recorder() { return _oop_recorder; } |
84 | #endif |
85 | |
86 | ExceptionHandlerTable* get_exception_table() { return _exception_table; } |
87 | |
88 | ImplicitExceptionTable* get_implicit_exception_table() { return _implicit_exception_table; } |
89 | |
90 | void set_pc_desc(PcDesc* desc, int count) { |
91 | _pc_desc = desc; |
92 | _nr_pc_desc = count; |
93 | } |
94 | |
95 | void set_scopes(u_char* scopes, int size) { |
96 | _scopes_desc = scopes; |
97 | _nr_scopes_desc = size; |
98 | } |
99 | |
100 | #if INCLUDE_AOT |
101 | void set_oop_recorder(AOTOopRecorder* recorder) { |
102 | _oop_recorder = recorder; |
103 | } |
104 | #endif |
105 | |
106 | void set_exception_table(ExceptionHandlerTable* table) { |
107 | _exception_table = table; |
108 | } |
109 | |
110 | void set_implicit_exception_table(ImplicitExceptionTable* table) { |
111 | _implicit_exception_table = table; |
112 | } |
113 | |
114 | private: |
115 | CodeBlob* _cb; |
116 | PcDesc* _pc_desc; |
117 | int _nr_pc_desc; |
118 | |
119 | u_char* _scopes_desc; |
120 | int _nr_scopes_desc; |
121 | |
122 | #if INCLUDE_AOT |
123 | RelocBuffer _reloc_buffer; |
124 | AOTOopRecorder* _oop_recorder; |
125 | #endif |
126 | ExceptionHandlerTable* _exception_table; |
127 | ImplicitExceptionTable* _implicit_exception_table; |
128 | }; |
129 | |
130 | /* |
131 | * This class handles the conversion from a InstalledCode to a CodeBlob or an nmethod. |
132 | */ |
133 | class CodeInstaller : public StackObj { |
134 | friend class JVMCIVMStructs; |
135 | private: |
136 | enum MarkId { |
137 | VERIFIED_ENTRY = 1, |
138 | UNVERIFIED_ENTRY = 2, |
139 | OSR_ENTRY = 3, |
140 | EXCEPTION_HANDLER_ENTRY = 4, |
141 | DEOPT_HANDLER_ENTRY = 5, |
142 | INVOKEINTERFACE = 6, |
143 | INVOKEVIRTUAL = 7, |
144 | INVOKESTATIC = 8, |
145 | INVOKESPECIAL = 9, |
146 | INLINE_INVOKE = 10, |
147 | POLL_NEAR = 11, |
148 | POLL_RETURN_NEAR = 12, |
149 | POLL_FAR = 13, |
150 | POLL_RETURN_FAR = 14, |
151 | CARD_TABLE_ADDRESS = 15, |
152 | CARD_TABLE_SHIFT = 16, |
153 | HEAP_TOP_ADDRESS = 17, |
154 | HEAP_END_ADDRESS = 18, |
155 | NARROW_KLASS_BASE_ADDRESS = 19, |
156 | NARROW_OOP_BASE_ADDRESS = 20, |
157 | CRC_TABLE_ADDRESS = 21, |
158 | LOG_OF_HEAP_REGION_GRAIN_BYTES = 22, |
159 | INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED = 23, |
160 | INVOKE_INVALID = -1 |
161 | }; |
162 | |
163 | Arena _arena; |
164 | JVMCIEnv* _jvmci_env; |
165 | |
166 | JVMCIPrimitiveArray _data_section_handle; |
167 | JVMCIObjectArray _data_section_patches_handle; |
168 | JVMCIObjectArray _sites_handle; |
169 | #ifndef PRODUCT |
170 | JVMCIObjectArray _comments_handle; |
171 | #endif |
172 | JVMCIPrimitiveArray _code_handle; |
173 | JVMCIObject _word_kind_handle; |
174 | |
175 | CodeOffsets _offsets; |
176 | |
177 | jint _code_size; |
178 | jint _total_frame_size; |
179 | jint _orig_pc_offset; |
180 | jint _parameter_count; |
181 | jint _constants_size; |
182 | |
183 | bool _has_wide_vector; |
184 | |
185 | MarkId _next_call_type; |
186 | address _invoke_mark_pc; |
187 | |
188 | CodeSection* _instructions; |
189 | CodeSection* _constants; |
190 | |
191 | OopRecorder* _oop_recorder; |
192 | DebugInformationRecorder* _debug_recorder; |
193 | Dependencies* _dependencies; |
194 | ExceptionHandlerTable _exception_handler_table; |
195 | ImplicitExceptionTable _implicit_exception_table; |
196 | |
197 | bool _immutable_pic_compilation; // Installer is called for Immutable PIC compilation. |
198 | |
199 | static ConstantOopWriteValue* _oop_null_scope_value; |
200 | static ConstantIntValue* _int_m1_scope_value; |
201 | static ConstantIntValue* _int_0_scope_value; |
202 | static ConstantIntValue* _int_1_scope_value; |
203 | static ConstantIntValue* _int_2_scope_value; |
204 | static LocationValue* _illegal_value; |
205 | |
206 | jint pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCIObject method, JVMCI_TRAPS); |
207 | void pd_patch_OopConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS); |
208 | void pd_patch_MetaspaceConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS); |
209 | void pd_patch_DataSectionReference(int pc_offset, int data_offset, JVMCI_TRAPS); |
210 | void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, JVMCI_TRAPS); |
211 | void pd_relocate_JavaMethod(CodeBuffer &cbuf, JVMCIObject method, jint pc_offset, JVMCI_TRAPS); |
212 | void pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS); |
213 | |
214 | JVMCIObjectArray sites() { return _sites_handle; } |
215 | JVMCIPrimitiveArray code() { return _code_handle; } |
216 | JVMCIPrimitiveArray data_section() { return _data_section_handle; } |
217 | JVMCIObjectArray data_section_patches() { return _data_section_patches_handle; } |
218 | #ifndef PRODUCT |
219 | JVMCIObjectArray comments() { return _comments_handle; } |
220 | #endif |
221 | JVMCIObject word_kind() { return _word_kind_handle; } |
222 | |
223 | public: |
224 | |
225 | CodeInstaller(JVMCIEnv* jvmci_env, bool immutable_pic_compilation) : _arena(mtJVMCI), _jvmci_env(jvmci_env), _immutable_pic_compilation(immutable_pic_compilation) {} |
226 | |
227 | #if INCLUDE_AOT |
228 | JVMCI::CodeInstallResult gather_metadata(JVMCIObject target, JVMCIObject compiled_code, CodeMetadata& metadata, JVMCI_TRAPS); |
229 | #endif |
230 | JVMCI::CodeInstallResult install(JVMCICompiler* compiler, |
231 | JVMCIObject target, |
232 | JVMCIObject compiled_code, |
233 | CodeBlob*& cb, |
234 | JVMCIObject installed_code, |
235 | FailedSpeculation** failed_speculations, |
236 | char* speculations, |
237 | int speculations_len, |
238 | JVMCI_TRAPS); |
239 | |
240 | JVMCIEnv* jvmci_env() { return _jvmci_env; } |
241 | JVMCIRuntime* runtime() { return _jvmci_env->runtime(); } |
242 | |
243 | static address runtime_call_target_address(oop runtime_call); |
244 | static VMReg get_hotspot_reg(jint jvmciRegisterNumber, JVMCI_TRAPS); |
245 | static bool is_general_purpose_reg(VMReg hotspotRegister); |
246 | |
247 | const OopMapSet* oopMapSet() const { return _debug_recorder->_oopmaps; } |
248 | |
249 | protected: |
250 | Location::Type get_oop_type(JVMCIObject value); |
251 | ScopeValue* get_scope_value(JVMCIObject value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, JVMCI_TRAPS); |
252 | MonitorValue* get_monitor_value(JVMCIObject value, GrowableArray<ScopeValue*>* objects, JVMCI_TRAPS); |
253 | |
254 | void* record_metadata_reference(CodeSection* section, address dest, JVMCIObject constant, JVMCI_TRAPS); |
255 | #ifdef _LP64 |
256 | narrowKlass record_narrow_metadata_reference(CodeSection* section, address dest, JVMCIObject constant, JVMCI_TRAPS); |
257 | #endif |
258 | |
259 | // extract the fields of the HotSpotCompiledCode |
260 | void initialize_fields(JVMCIObject target, JVMCIObject compiled_code, JVMCI_TRAPS); |
261 | void initialize_dependencies(JVMCIObject compiled_code, OopRecorder* oop_recorder, JVMCI_TRAPS); |
262 | |
263 | int estimate_stubs_size(JVMCI_TRAPS); |
264 | |
265 | // perform data and call relocation on the CodeBuffer |
266 | JVMCI::CodeInstallResult initialize_buffer(CodeBuffer& buffer, bool check_size, JVMCI_TRAPS); |
267 | |
268 | void assumption_NoFinalizableSubclass(JVMCIObject assumption); |
269 | void assumption_ConcreteSubtype(JVMCIObject assumption); |
270 | void assumption_LeafType(JVMCIObject assumption); |
271 | void assumption_ConcreteMethod(JVMCIObject assumption); |
272 | void assumption_CallSiteTargetValue(JVMCIObject assumption, JVMCI_TRAPS); |
273 | |
274 | void site_Safepoint(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS); |
275 | void site_Infopoint(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS); |
276 | void site_Call(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS); |
277 | void site_DataPatch(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS); |
278 | void site_Mark(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS); |
279 | void site_ExceptionHandler(jint pc_offset, JVMCIObject site); |
280 | |
281 | OopMap* create_oop_map(JVMCIObject debug_info, JVMCI_TRAPS); |
282 | |
283 | VMReg getVMRegFromLocation(JVMCIObject location, int total_frame_size, JVMCI_TRAPS); |
284 | |
285 | /** |
286 | * Specifies the level of detail to record for a scope. |
287 | */ |
288 | enum ScopeMode { |
289 | // Only record a method and BCI |
290 | BytecodePosition, |
291 | // Record a method, bci and JVM frame state |
292 | FullFrame |
293 | }; |
294 | |
295 | int map_jvmci_bci(int bci); |
296 | |
297 | void record_scope(jint pc_offset, JVMCIObject debug_info, ScopeMode scope_mode, bool return_oop, JVMCI_TRAPS); |
298 | void record_scope(jint pc_offset, JVMCIObject debug_info, ScopeMode scope_mode, JVMCI_TRAPS) { |
299 | record_scope(pc_offset, debug_info, scope_mode, false /* return_oop */, JVMCIENV); |
300 | } |
301 | void record_scope(jint pc_offset, JVMCIObject position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, bool return_oop, JVMCI_TRAPS); |
302 | void record_object_value(ObjectValue* sv, JVMCIObject value, GrowableArray<ScopeValue*>* objects, JVMCI_TRAPS); |
303 | |
304 | GrowableArray<ScopeValue*>* record_virtual_objects(JVMCIObject debug_info, JVMCI_TRAPS); |
305 | |
306 | int estimateStubSpace(int static_call_stubs); |
307 | }; |
308 | |
309 | #endif // SHARE_JVMCI_JVMCICODEINSTALLER_HPP |
310 | |