22 */ |
22 */ |
23 |
23 |
24 #ifndef SHARE_JVMCI_JVMCIRUNTIME_HPP |
24 #ifndef SHARE_JVMCI_JVMCIRUNTIME_HPP |
25 #define SHARE_JVMCI_JVMCIRUNTIME_HPP |
25 #define SHARE_JVMCI_JVMCIRUNTIME_HPP |
26 |
26 |
27 #include "interpreter/interpreter.hpp" |
27 #include "code/nmethod.hpp" |
28 #include "memory/allocation.hpp" |
28 #include "jvmci/jvmci.hpp" |
29 #include "runtime/arguments.hpp" |
29 #include "jvmci/jvmciExceptions.hpp" |
30 #include "runtime/deoptimization.hpp" |
30 #include "jvmci/jvmciObject.hpp" |
31 |
31 |
32 #define JVMCI_ERROR(...) \ |
32 class JVMCIEnv; |
33 { Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::jdk_vm_ci_common_JVMCIError(), __VA_ARGS__); return; } |
33 class JVMCICompiler; |
34 |
34 class JVMCICompileState; |
35 #define JVMCI_ERROR_(ret, ...) \ |
35 |
36 { Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::jdk_vm_ci_common_JVMCIError(), __VA_ARGS__); return ret; } |
36 // Encapsulates the JVMCI metadata for an nmethod. |
37 |
37 // JVMCINMethodData objects are inlined into nmethods |
38 #define JVMCI_ERROR_0(...) JVMCI_ERROR_(0, __VA_ARGS__) |
38 // at nmethod::_jvmci_data_offset. |
39 #define JVMCI_ERROR_NULL(...) JVMCI_ERROR_(NULL, __VA_ARGS__) |
39 class JVMCINMethodData { |
40 #define JVMCI_ERROR_OK(...) JVMCI_ERROR_(JVMCIEnv::ok, __VA_ARGS__) |
40 // Index for the HotSpotNmethod mirror in the nmethod's oops table. |
41 #define CHECK_OK CHECK_(JVMCIEnv::ok) |
41 // This is -1 if there is no mirror in the oops table. |
42 |
42 int _nmethod_mirror_index; |
43 class JVMCIRuntime: public AllStatic { |
43 |
|
44 // Is HotSpotNmethod.name non-null? If so, the value is |
|
45 // embedded in the end of this object. |
|
46 bool _has_name; |
|
47 |
|
48 // Address of the failed speculations list to which a speculation |
|
49 // is appended when it causes a deoptimization. |
|
50 FailedSpeculation** _failed_speculations; |
|
51 |
|
52 public: |
|
53 // Computes the size of a JVMCINMethodData object |
|
54 static int compute_size(const char* nmethod_mirror_name) { |
|
55 int size = sizeof(JVMCINMethodData); |
|
56 if (nmethod_mirror_name != NULL) { |
|
57 size += (int) strlen(nmethod_mirror_name) + 1; |
|
58 } |
|
59 return size; |
|
60 } |
|
61 |
|
62 void initialize(int nmethod_mirror_index, |
|
63 const char* name, |
|
64 FailedSpeculation** failed_speculations); |
|
65 |
|
66 // Adds `speculation` to the failed speculations list. |
|
67 void add_failed_speculation(nmethod* nm, jlong speculation); |
|
68 |
|
69 // Gets the JVMCI name of the nmethod (which may be NULL). |
|
70 const char* name() { return _has_name ? (char*)(((address) this) + sizeof(JVMCINMethodData)) : NULL; } |
|
71 |
|
72 // Clears the HotSpotNmethod.address field in the mirror. If nm |
|
73 // is dead, the HotSpotNmethod.entryPoint field is also cleared. |
|
74 void invalidate_nmethod_mirror(nmethod* nm); |
|
75 |
|
76 // Gets the mirror from nm's oops table. |
|
77 oop get_nmethod_mirror(nmethod* nm); |
|
78 |
|
79 // Sets the mirror in nm's oops table. |
|
80 void set_nmethod_mirror(nmethod* nm, oop mirror); |
|
81 |
|
82 // Clears the mirror in nm's oops table. |
|
83 void clear_nmethod_mirror(nmethod* nm); |
|
84 }; |
|
85 |
|
86 // A top level class that represents an initialized JVMCI runtime. |
|
87 // There is one instance of this class per HotSpotJVMCIRuntime object. |
|
88 class JVMCIRuntime: public CHeapObj<mtJVMCI> { |
44 public: |
89 public: |
45 // Constants describing whether JVMCI wants to be able to adjust the compilation |
90 // Constants describing whether JVMCI wants to be able to adjust the compilation |
46 // level selected for a method by the VM compilation policy and if so, based on |
91 // level selected for a method by the VM compilation policy and if so, based on |
47 // what information about the method being schedule for compilation. |
92 // what information about the method being schedule for compilation. |
48 enum CompLevelAdjustment { |
93 enum CompLevelAdjustment { |
50 by_holder = 1, // adjust based on declaring class of method |
95 by_holder = 1, // adjust based on declaring class of method |
51 by_full_signature = 2 // adjust based on declaring class, name and signature of method |
96 by_full_signature = 2 // adjust based on declaring class, name and signature of method |
52 }; |
97 }; |
53 |
98 |
54 private: |
99 private: |
55 static jobject _HotSpotJVMCIRuntime_instance; |
100 volatile bool _being_initialized; |
56 static bool _well_known_classes_initialized; |
101 volatile bool _initialized; |
57 |
102 |
58 static bool _shutdown_called; |
103 JVMCIObject _HotSpotJVMCIRuntime_instance; |
|
104 |
|
105 bool _shutdown_called; |
|
106 |
|
107 JVMCIObject create_jvmci_primitive_type(BasicType type, JVMCI_TRAPS); |
|
108 |
|
109 // Implementation methods for loading and constant pool access. |
|
110 static Klass* get_klass_by_name_impl(Klass*& accessing_klass, |
|
111 const constantPoolHandle& cpool, |
|
112 Symbol* klass_name, |
|
113 bool require_local); |
|
114 static Klass* get_klass_by_index_impl(const constantPoolHandle& cpool, |
|
115 int klass_index, |
|
116 bool& is_accessible, |
|
117 Klass* loading_klass); |
|
118 static void get_field_by_index_impl(InstanceKlass* loading_klass, fieldDescriptor& fd, |
|
119 int field_index); |
|
120 static methodHandle get_method_by_index_impl(const constantPoolHandle& cpool, |
|
121 int method_index, Bytecodes::Code bc, |
|
122 InstanceKlass* loading_klass); |
|
123 |
|
124 // Helper methods |
|
125 static bool check_klass_accessibility(Klass* accessing_klass, Klass* resolved_klass); |
|
126 static methodHandle lookup_method(InstanceKlass* accessor, |
|
127 Klass* holder, |
|
128 Symbol* name, |
|
129 Symbol* sig, |
|
130 Bytecodes::Code bc, |
|
131 constantTag tag); |
59 |
132 |
60 public: |
133 public: |
61 static bool is_HotSpotJVMCIRuntime_initialized() { |
134 JVMCIRuntime() { |
62 return _HotSpotJVMCIRuntime_instance != NULL; |
135 _initialized = false; |
|
136 _being_initialized = false; |
|
137 _shutdown_called = false; |
63 } |
138 } |
64 |
139 |
65 /** |
140 /** |
|
141 * Compute offsets and construct any state required before executing JVMCI code. |
|
142 */ |
|
143 void initialize(JVMCIEnv* jvmciEnv); |
|
144 |
|
145 /** |
66 * Gets the singleton HotSpotJVMCIRuntime instance, initializing it if necessary |
146 * Gets the singleton HotSpotJVMCIRuntime instance, initializing it if necessary |
67 */ |
147 */ |
68 static Handle get_HotSpotJVMCIRuntime(TRAPS); |
148 JVMCIObject get_HotSpotJVMCIRuntime(JVMCI_TRAPS); |
69 |
149 |
70 static jobject get_HotSpotJVMCIRuntime_jobject(TRAPS) { |
150 bool is_HotSpotJVMCIRuntime_initialized() { |
71 initialize_JVMCI(CHECK_NULL); |
151 return _HotSpotJVMCIRuntime_instance.is_non_null(); |
72 assert(_HotSpotJVMCIRuntime_instance != NULL, "must be"); |
|
73 return _HotSpotJVMCIRuntime_instance; |
|
74 } |
152 } |
75 |
153 |
76 static Handle callStatic(const char* className, const char* methodName, const char* returnType, JavaCallArguments* args, TRAPS); |
|
77 |
|
78 /** |
|
79 * Determines if the VM is sufficiently booted to initialize JVMCI. |
|
80 */ |
|
81 static bool can_initialize_JVMCI(); |
|
82 |
|
83 /** |
154 /** |
84 * Trigger initialization of HotSpotJVMCIRuntime through JVMCI.getRuntime() |
155 * Trigger initialization of HotSpotJVMCIRuntime through JVMCI.getRuntime() |
85 */ |
156 */ |
86 static void initialize_JVMCI(TRAPS); |
157 void initialize_JVMCI(JVMCI_TRAPS); |
87 |
158 |
88 /** |
159 /** |
89 * Explicitly initialize HotSpotJVMCIRuntime itself |
160 * Explicitly initialize HotSpotJVMCIRuntime itself |
90 */ |
161 */ |
91 static void initialize_HotSpotJVMCIRuntime(TRAPS); |
162 void initialize_HotSpotJVMCIRuntime(JVMCI_TRAPS); |
92 |
163 |
93 static void initialize_well_known_classes(TRAPS); |
164 void call_getCompiler(TRAPS); |
94 |
165 |
95 static void metadata_do(void f(Metadata*)); |
166 void shutdown(); |
96 |
167 |
97 static void shutdown(TRAPS); |
168 bool shutdown_called() { |
98 |
|
99 static void bootstrap_finished(TRAPS); |
|
100 |
|
101 static bool shutdown_called() { |
|
102 return _shutdown_called; |
169 return _shutdown_called; |
103 } |
170 } |
104 |
171 |
105 static BasicType kindToBasicType(Handle kind, TRAPS); |
172 void bootstrap_finished(TRAPS); |
|
173 |
|
174 // Look up a klass by name from a particular class loader (the accessor's). |
|
175 // If require_local, result must be defined in that class loader, or NULL. |
|
176 // If !require_local, a result from remote class loader may be reported, |
|
177 // if sufficient class loader constraints exist such that initiating |
|
178 // a class loading request from the given loader is bound to return |
|
179 // the class defined in the remote loader (or throw an error). |
|
180 // |
|
181 // Return an unloaded klass if !require_local and no class at all is found. |
|
182 // |
|
183 // The CI treats a klass as loaded if it is consistently defined in |
|
184 // another loader, even if it hasn't yet been loaded in all loaders |
|
185 // that could potentially see it via delegation. |
|
186 static Klass* get_klass_by_name(Klass* accessing_klass, |
|
187 Symbol* klass_name, |
|
188 bool require_local); |
|
189 |
|
190 // Constant pool access. |
|
191 static Klass* get_klass_by_index(const constantPoolHandle& cpool, |
|
192 int klass_index, |
|
193 bool& is_accessible, |
|
194 Klass* loading_klass); |
|
195 static void get_field_by_index(InstanceKlass* loading_klass, fieldDescriptor& fd, |
|
196 int field_index); |
|
197 static methodHandle get_method_by_index(const constantPoolHandle& cpool, |
|
198 int method_index, Bytecodes::Code bc, |
|
199 InstanceKlass* loading_klass); |
|
200 |
|
201 // converts the Klass* representing the holder of a method into a |
|
202 // InstanceKlass*. This is needed since the holder of a method in |
|
203 // the bytecodes could be an array type. Basically this converts |
|
204 // array types into java/lang/Object and other types stay as they are. |
|
205 static InstanceKlass* get_instance_klass_for_declared_method_holder(Klass* klass); |
|
206 |
|
207 // Helper routine for determining the validity of a compilation |
|
208 // with respect to concurrent class loading. |
|
209 static JVMCI::CodeInstallResult validate_compile_task_dependencies(Dependencies* target, JVMCICompileState* task, char** failure_detail); |
|
210 |
|
211 // Compiles `target` with the JVMCI compiler. |
|
212 void compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, const methodHandle& target, int entry_bci); |
|
213 |
|
214 // Register the result of a compilation. |
|
215 JVMCI::CodeInstallResult register_method(JVMCIEnv* JVMCIENV, |
|
216 const methodHandle& target, |
|
217 nmethod*& nm, |
|
218 int entry_bci, |
|
219 CodeOffsets* offsets, |
|
220 int orig_pc_offset, |
|
221 CodeBuffer* code_buffer, |
|
222 int frame_words, |
|
223 OopMapSet* oop_map_set, |
|
224 ExceptionHandlerTable* handler_table, |
|
225 AbstractCompiler* compiler, |
|
226 DebugInformationRecorder* debug_info, |
|
227 Dependencies* dependencies, |
|
228 int compile_id, |
|
229 bool has_unsafe_access, |
|
230 bool has_wide_vector, |
|
231 JVMCIObject compiled_code, |
|
232 JVMCIObject nmethod_mirror, |
|
233 FailedSpeculation** failed_speculations, |
|
234 char* speculations, |
|
235 int speculations_len); |
|
236 |
|
237 /** |
|
238 * Exits the VM due to an unexpected exception. |
|
239 */ |
|
240 static void exit_on_pending_exception(JVMCIEnv* JVMCIENV, const char* message); |
|
241 |
|
242 static void describe_pending_hotspot_exception(JavaThread* THREAD, bool clear); |
|
243 |
|
244 #define CHECK_EXIT THREAD); \ |
|
245 if (HAS_PENDING_EXCEPTION) { \ |
|
246 char buf[256]; \ |
|
247 jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
|
248 JVMCIRuntime::exit_on_pending_exception(NULL, buf); \ |
|
249 return; \ |
|
250 } \ |
|
251 (void)(0 |
|
252 |
|
253 #define CHECK_EXIT_(v) THREAD); \ |
|
254 if (HAS_PENDING_EXCEPTION) { \ |
|
255 char buf[256]; \ |
|
256 jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
|
257 JVMCIRuntime::exit_on_pending_exception(NULL, buf); \ |
|
258 return v; \ |
|
259 } \ |
|
260 (void)(0 |
|
261 |
|
262 #define JVMCI_CHECK_EXIT JVMCIENV); \ |
|
263 if (JVMCIENV->has_pending_exception()) { \ |
|
264 char buf[256]; \ |
|
265 jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
|
266 JVMCIRuntime::exit_on_pending_exception(JVMCIENV, buf); \ |
|
267 return; \ |
|
268 } \ |
|
269 (void)(0 |
|
270 |
|
271 #define JVMCI_CHECK_EXIT_(result) JVMCIENV); \ |
|
272 if (JVMCIENV->has_pending_exception()) { \ |
|
273 char buf[256]; \ |
|
274 jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
|
275 JVMCIRuntime::exit_on_pending_exception(JVMCIENV, buf); \ |
|
276 return result; \ |
|
277 } \ |
|
278 (void)(0 |
|
279 |
|
280 static BasicType kindToBasicType(const Handle& kind, TRAPS); |
106 |
281 |
107 static void new_instance_common(JavaThread* thread, Klass* klass, bool null_on_fail); |
282 static void new_instance_common(JavaThread* thread, Klass* klass, bool null_on_fail); |
108 static void new_array_common(JavaThread* thread, Klass* klass, jint length, bool null_on_fail); |
283 static void new_array_common(JavaThread* thread, Klass* klass, jint length, bool null_on_fail); |
109 static void new_multi_array_common(JavaThread* thread, Klass* klass, int rank, jint* dims, bool null_on_fail); |
284 static void new_multi_array_common(JavaThread* thread, Klass* klass, int rank, jint* dims, bool null_on_fail); |
110 static void dynamic_new_array_common(JavaThread* thread, oopDesc* element_mirror, jint length, bool null_on_fail); |
285 static void dynamic_new_array_common(JavaThread* thread, oopDesc* element_mirror, jint length, bool null_on_fail); |
160 static void throw_and_post_jvmti_exception(JavaThread* thread, const char* exception, const char* message); |
335 static void throw_and_post_jvmti_exception(JavaThread* thread, const char* exception, const char* message); |
161 // helper methods to throw exception with complex messages |
336 // helper methods to throw exception with complex messages |
162 static void throw_klass_external_name_exception(JavaThread* thread, const char* exception, Klass* klass); |
337 static void throw_klass_external_name_exception(JavaThread* thread, const char* exception, Klass* klass); |
163 static void throw_class_cast_exception(JavaThread* thread, const char* exception, Klass* caster_klass, Klass* target_klass); |
338 static void throw_class_cast_exception(JavaThread* thread, const char* exception, Klass* caster_klass, Klass* target_klass); |
164 |
339 |
165 // Forces initialization of the JVMCI runtime. |
|
166 static void force_initialization(TRAPS); |
|
167 |
|
168 // Test only function |
340 // Test only function |
169 static int test_deoptimize_call_int(JavaThread* thread, int value); |
341 static jint test_deoptimize_call_int(JavaThread* thread, int value); |
170 }; |
342 }; |
171 |
343 |
172 // Tracing macros. |
344 // Tracing macros. |
173 |
345 |
174 #define IF_TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1)) ; else |
346 #define IF_TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1)) ; else |
175 #define IF_TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2)) ; else |
347 #define IF_TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2)) ; else |
176 #define IF_TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3)) ; else |
348 #define IF_TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3)) ; else |
177 #define IF_TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4)) ; else |
349 #define IF_TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4)) ; else |
178 #define IF_TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5)) ; else |
350 #define IF_TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5)) ; else |
179 |
351 |
180 #define TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1 && (tty->print("JVMCITrace-1: "), true))) ; else tty->print_cr |
352 #define TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1 && (tty->print(PTR_FORMAT " JVMCITrace-1: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
181 #define TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2 && (tty->print(" JVMCITrace-2: "), true))) ; else tty->print_cr |
353 #define TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2 && (tty->print(PTR_FORMAT " JVMCITrace-2: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
182 #define TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3 && (tty->print(" JVMCITrace-3: "), true))) ; else tty->print_cr |
354 #define TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3 && (tty->print(PTR_FORMAT " JVMCITrace-3: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
183 #define TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4 && (tty->print(" JVMCITrace-4: "), true))) ; else tty->print_cr |
355 #define TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4 && (tty->print(PTR_FORMAT " JVMCITrace-4: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
184 #define TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5 && (tty->print(" JVMCITrace-5: "), true))) ; else tty->print_cr |
356 #define TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5 && (tty->print(PTR_FORMAT " JVMCITrace-5: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
185 |
357 |
186 #endif // SHARE_JVMCI_JVMCIRUNTIME_HPP |
358 #endif // SHARE_JVMCI_JVMCIRUNTIME_HPP |