| 1 | /* |
| 2 | * Copyright (c) 2012, 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_JVMCIRUNTIME_HPP |
| 25 | #define SHARE_JVMCI_JVMCIRUNTIME_HPP |
| 26 | |
| 27 | #include "code/nmethod.hpp" |
| 28 | #include "jvmci/jvmci.hpp" |
| 29 | #include "jvmci/jvmciExceptions.hpp" |
| 30 | #include "jvmci/jvmciObject.hpp" |
| 31 | |
| 32 | class JVMCIEnv; |
| 33 | class JVMCICompiler; |
| 34 | class JVMCICompileState; |
| 35 | |
| 36 | // Encapsulates the JVMCI metadata for an nmethod. |
| 37 | // JVMCINMethodData objects are inlined into nmethods |
| 38 | // at nmethod::_jvmci_data_offset. |
| 39 | class JVMCINMethodData { |
| 40 | // Index for the HotSpotNmethod mirror in the nmethod's oops table. |
| 41 | // This is -1 if there is no mirror in the oops table. |
| 42 | int _nmethod_mirror_index; |
| 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, bool phantom_ref); |
| 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> { |
| 89 | public: |
| 90 | // Constants describing whether JVMCI wants to be able to adjust the compilation |
| 91 | // level selected for a method by the VM compilation policy and if so, based on |
| 92 | // what information about the method being schedule for compilation. |
| 93 | enum CompLevelAdjustment { |
| 94 | none = 0, // no adjustment |
| 95 | by_holder = 1, // adjust based on declaring class of method |
| 96 | by_full_signature = 2 // adjust based on declaring class, name and signature of method |
| 97 | }; |
| 98 | |
| 99 | private: |
| 100 | volatile bool _being_initialized; |
| 101 | volatile bool _initialized; |
| 102 | |
| 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); |
| 132 | |
| 133 | public: |
| 134 | JVMCIRuntime() { |
| 135 | _initialized = false; |
| 136 | _being_initialized = false; |
| 137 | _shutdown_called = false; |
| 138 | } |
| 139 | |
| 140 | /** |
| 141 | * Compute offsets and construct any state required before executing JVMCI code. |
| 142 | */ |
| 143 | void initialize(JVMCIEnv* jvmciEnv); |
| 144 | |
| 145 | /** |
| 146 | * Gets the singleton HotSpotJVMCIRuntime instance, initializing it if necessary |
| 147 | */ |
| 148 | JVMCIObject get_HotSpotJVMCIRuntime(JVMCI_TRAPS); |
| 149 | |
| 150 | bool is_HotSpotJVMCIRuntime_initialized() { |
| 151 | return _HotSpotJVMCIRuntime_instance.is_non_null(); |
| 152 | } |
| 153 | |
| 154 | /** |
| 155 | * Trigger initialization of HotSpotJVMCIRuntime through JVMCI.getRuntime() |
| 156 | */ |
| 157 | void initialize_JVMCI(JVMCI_TRAPS); |
| 158 | |
| 159 | /** |
| 160 | * Explicitly initialize HotSpotJVMCIRuntime itself |
| 161 | */ |
| 162 | void initialize_HotSpotJVMCIRuntime(JVMCI_TRAPS); |
| 163 | |
| 164 | void call_getCompiler(TRAPS); |
| 165 | |
| 166 | void shutdown(); |
| 167 | |
| 168 | bool shutdown_called() { |
| 169 | return _shutdown_called; |
| 170 | } |
| 171 | |
| 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 | ImplicitExceptionTable* implicit_exception_table, |
| 226 | AbstractCompiler* compiler, |
| 227 | DebugInformationRecorder* debug_info, |
| 228 | Dependencies* dependencies, |
| 229 | int compile_id, |
| 230 | bool has_unsafe_access, |
| 231 | bool has_wide_vector, |
| 232 | JVMCIObject compiled_code, |
| 233 | JVMCIObject nmethod_mirror, |
| 234 | FailedSpeculation** failed_speculations, |
| 235 | char* speculations, |
| 236 | int speculations_len); |
| 237 | |
| 238 | /** |
| 239 | * Exits the VM due to an unexpected exception. |
| 240 | */ |
| 241 | static void exit_on_pending_exception(JVMCIEnv* JVMCIENV, const char* message); |
| 242 | |
| 243 | static void describe_pending_hotspot_exception(JavaThread* THREAD, bool clear); |
| 244 | |
| 245 | #define CHECK_EXIT THREAD); \ |
| 246 | if (HAS_PENDING_EXCEPTION) { \ |
| 247 | char buf[256]; \ |
| 248 | jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
| 249 | JVMCIRuntime::exit_on_pending_exception(NULL, buf); \ |
| 250 | return; \ |
| 251 | } \ |
| 252 | (void)(0 |
| 253 | |
| 254 | #define CHECK_EXIT_(v) THREAD); \ |
| 255 | if (HAS_PENDING_EXCEPTION) { \ |
| 256 | char buf[256]; \ |
| 257 | jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
| 258 | JVMCIRuntime::exit_on_pending_exception(NULL, buf); \ |
| 259 | return v; \ |
| 260 | } \ |
| 261 | (void)(0 |
| 262 | |
| 263 | #define JVMCI_CHECK_EXIT JVMCIENV); \ |
| 264 | if (JVMCIENV->has_pending_exception()) { \ |
| 265 | char buf[256]; \ |
| 266 | jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
| 267 | JVMCIRuntime::exit_on_pending_exception(JVMCIENV, buf); \ |
| 268 | return; \ |
| 269 | } \ |
| 270 | (void)(0 |
| 271 | |
| 272 | #define JVMCI_CHECK_EXIT_(result) JVMCIENV); \ |
| 273 | if (JVMCIENV->has_pending_exception()) { \ |
| 274 | char buf[256]; \ |
| 275 | jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ |
| 276 | JVMCIRuntime::exit_on_pending_exception(JVMCIENV, buf); \ |
| 277 | return result; \ |
| 278 | } \ |
| 279 | (void)(0 |
| 280 | |
| 281 | static BasicType kindToBasicType(const Handle& kind, TRAPS); |
| 282 | |
| 283 | static void new_instance_common(JavaThread* thread, Klass* klass, bool null_on_fail); |
| 284 | static void new_array_common(JavaThread* thread, Klass* klass, jint length, bool null_on_fail); |
| 285 | static void new_multi_array_common(JavaThread* thread, Klass* klass, int rank, jint* dims, bool null_on_fail); |
| 286 | static void dynamic_new_array_common(JavaThread* thread, oopDesc* element_mirror, jint length, bool null_on_fail); |
| 287 | static void dynamic_new_instance_common(JavaThread* thread, oopDesc* type_mirror, bool null_on_fail); |
| 288 | |
| 289 | // The following routines are called from compiled JVMCI code |
| 290 | |
| 291 | // When allocation fails, these stubs: |
| 292 | // 1. Exercise -XX:+HeapDumpOnOutOfMemoryError and -XX:OnOutOfMemoryError handling and also |
| 293 | // post a JVMTI_EVENT_RESOURCE_EXHAUSTED event if the failure is an OutOfMemroyError |
| 294 | // 2. Return NULL with a pending exception. |
| 295 | // Compiled code must ensure these stubs are not called twice for the same allocation |
| 296 | // site due to the non-repeatable side effects in the case of OOME. |
| 297 | static void new_instance(JavaThread* thread, Klass* klass) { new_instance_common(thread, klass, false); } |
| 298 | static void new_array(JavaThread* thread, Klass* klass, jint length) { new_array_common(thread, klass, length, false); } |
| 299 | static void new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims) { new_multi_array_common(thread, klass, rank, dims, false); } |
| 300 | static void dynamic_new_array(JavaThread* thread, oopDesc* element_mirror, jint length) { dynamic_new_array_common(thread, element_mirror, length, false); } |
| 301 | static void dynamic_new_instance(JavaThread* thread, oopDesc* type_mirror) { dynamic_new_instance_common(thread, type_mirror, false); } |
| 302 | |
| 303 | // When allocation fails, these stubs return NULL and have no pending exception. Compiled code |
| 304 | // can use these stubs if a failed allocation will be retried (e.g., by deoptimizing and |
| 305 | // re-executing in the interpreter). |
| 306 | static void new_instance_or_null(JavaThread* thread, Klass* klass) { new_instance_common(thread, klass, true); } |
| 307 | static void new_array_or_null(JavaThread* thread, Klass* klass, jint length) { new_array_common(thread, klass, length, true); } |
| 308 | static void new_multi_array_or_null(JavaThread* thread, Klass* klass, int rank, jint* dims) { new_multi_array_common(thread, klass, rank, dims, true); } |
| 309 | static void dynamic_new_array_or_null(JavaThread* thread, oopDesc* element_mirror, jint length) { dynamic_new_array_common(thread, element_mirror, length, true); } |
| 310 | static void dynamic_new_instance_or_null(JavaThread* thread, oopDesc* type_mirror) { dynamic_new_instance_common(thread, type_mirror, true); } |
| 311 | |
| 312 | static jboolean thread_is_interrupted(JavaThread* thread, oopDesc* obj, jboolean clear_interrupted); |
| 313 | static void vm_message(jboolean vmError, jlong format, jlong v1, jlong v2, jlong v3); |
| 314 | static jint identity_hash_code(JavaThread* thread, oopDesc* obj); |
| 315 | static address exception_handler_for_pc(JavaThread* thread); |
| 316 | static void monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock); |
| 317 | static void monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock); |
| 318 | static jboolean object_notify(JavaThread* thread, oopDesc* obj); |
| 319 | static jboolean object_notifyAll(JavaThread* thread, oopDesc* obj); |
| 320 | static void vm_error(JavaThread* thread, jlong where, jlong format, jlong value); |
| 321 | static oopDesc* load_and_clear_exception(JavaThread* thread); |
| 322 | static void log_printf(JavaThread* thread, const char* format, jlong v1, jlong v2, jlong v3); |
| 323 | static void log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline); |
| 324 | // Print the passed in object, optionally followed by a newline. If |
| 325 | // as_string is true and the object is a java.lang.String then it |
| 326 | // printed as a string, otherwise the type of the object is printed |
| 327 | // followed by its address. |
| 328 | static void log_object(JavaThread* thread, oopDesc* object, bool as_string, bool newline); |
| 329 | #if INCLUDE_G1GC |
| 330 | static void write_barrier_pre(JavaThread* thread, oopDesc* obj); |
| 331 | static void write_barrier_post(JavaThread* thread, void* card); |
| 332 | #endif |
| 333 | static jboolean validate_object(JavaThread* thread, oopDesc* parent, oopDesc* child); |
| 334 | |
| 335 | // used to throw exceptions from compiled JVMCI code |
| 336 | static void throw_and_post_jvmti_exception(JavaThread* thread, const char* exception, const char* message); |
| 337 | // helper methods to throw exception with complex messages |
| 338 | static void throw_klass_external_name_exception(JavaThread* thread, const char* exception, Klass* klass); |
| 339 | static void throw_class_cast_exception(JavaThread* thread, const char* exception, Klass* caster_klass, Klass* target_klass); |
| 340 | |
| 341 | // Test only function |
| 342 | static jint test_deoptimize_call_int(JavaThread* thread, int value); |
| 343 | }; |
| 344 | |
| 345 | // Tracing macros. |
| 346 | |
| 347 | #define IF_TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1)) ; else |
| 348 | #define IF_TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2)) ; else |
| 349 | #define IF_TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3)) ; else |
| 350 | #define IF_TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4)) ; else |
| 351 | #define IF_TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5)) ; else |
| 352 | |
| 353 | #define TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1 && (tty->print(PTR_FORMAT " JVMCITrace-1: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
| 354 | #define TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2 && (tty->print(PTR_FORMAT " JVMCITrace-2: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
| 355 | #define TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3 && (tty->print(PTR_FORMAT " JVMCITrace-3: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
| 356 | #define TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4 && (tty->print(PTR_FORMAT " JVMCITrace-4: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
| 357 | #define TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5 && (tty->print(PTR_FORMAT " JVMCITrace-5: ", p2i(JavaThread::current())), true))) ; else tty->print_cr |
| 358 | |
| 359 | #endif // SHARE_JVMCI_JVMCIRUNTIME_HPP |
| 360 | |