1 /* 2 * Copyright (c) 1999, 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 25 #include "precompiled.hpp" 26 #include "classfile/stringTable.hpp" 27 #include "code/codeCache.hpp" 28 #include "memory/oopFactory.hpp" 29 #include "memory/resourceArea.hpp" 30 #include "oops/objArrayOop.inline.hpp" 31 #include "oops/typeArrayOop.inline.hpp" 32 #include "runtime/jniHandles.inline.hpp" 33 #include "runtime/javaCalls.hpp" 34 #include "jvmci/jniAccessMark.inline.hpp" 35 #include "jvmci/jvmciRuntime.hpp" 36 37 JVMCICompileState::JVMCICompileState(CompileTask* task, int system_dictionary_modification_counter): 38 _task(task), 39 _system_dictionary_modification_counter(system_dictionary_modification_counter), 40 _retryable(true), 41 _failure_reason(NULL), 42 _failure_reason_on_C_heap(false) { 43 // Get Jvmti capabilities under lock to get consistent values. 44 MutexLocker mu(JvmtiThreadState_lock); 45 _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0; 46 _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables() ? 1 : 0; 47 _jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions() ? 1 : 0; 48 _jvmti_can_pop_frame = JvmtiExport::can_pop_frame() ? 1 : 0; 49 } 50 51 bool JVMCICompileState::jvmti_state_changed() const { 52 if (!jvmti_can_access_local_variables() && 53 JvmtiExport::can_access_local_variables()) { 54 return true; 55 } 56 if (!jvmti_can_hotswap_or_post_breakpoint() && 57 JvmtiExport::can_hotswap_or_post_breakpoint()) { 58 return true; 59 } 60 if (!jvmti_can_post_on_exceptions() && 61 JvmtiExport::can_post_on_exceptions()) { 62 return true; 63 } 64 if (!jvmti_can_pop_frame() && 65 JvmtiExport::can_pop_frame()) { 66 return true; 67 } 68 return false; 69 } 70 71 void JVMCIEnv::copy_saved_properties() { 72 assert(!is_hotspot(), "can only copy saved properties from HotSpot to native image"); 73 74 JavaThread* THREAD = JavaThread::current(); 75 76 Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_services_Services(), Handle(), Handle(), true, THREAD); 77 if (HAS_PENDING_EXCEPTION) { 78 JVMCIRuntime::exit_on_pending_exception(NULL, "Error initializing jdk.vm.ci.services.Services"); 79 } 80 InstanceKlass* ik = InstanceKlass::cast(k); 81 if (ik->should_be_initialized()) { 82 ik->initialize(THREAD); 83 if (HAS_PENDING_EXCEPTION) { 84 JVMCIRuntime::exit_on_pending_exception(NULL, "Error initializing jdk.vm.ci.services.Services"); 85 } 86 } 87 88 // Get the serialized saved properties from HotSpot 89 TempNewSymbol serializeSavedProperties = SymbolTable::new_symbol("serializeSavedProperties", CHECK_EXIT); 90 JavaValue result(T_OBJECT); 91 JavaCallArguments args; 92 JavaCalls::call_static(&result, ik, serializeSavedProperties, vmSymbols::serializePropertiesToByteArray_signature(), &args, THREAD); 93 if (HAS_PENDING_EXCEPTION) { 94 JVMCIRuntime::exit_on_pending_exception(NULL, "Error calling jdk.vm.ci.services.Services.serializeSavedProperties"); 95 } 96 oop res = (oop) result.get_jobject(); 97 assert(res->is_typeArray(), "must be"); 98 assert(TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "must be"); 99 typeArrayOop ba = typeArrayOop(res); 100 int serialized_properties_len = ba->length(); 101 102 // Copy serialized saved properties from HotSpot object into native buffer 103 jbyte* serialized_properties = NEW_RESOURCE_ARRAY(jbyte, serialized_properties_len); 104 memcpy(serialized_properties, ba->byte_at_addr(0), serialized_properties_len); 105 106 // Copy native buffer into shared library object 107 JVMCIPrimitiveArray buf = new_byteArray(serialized_properties_len, this); 108 if (has_pending_exception()) { 109 describe_pending_exception(true); 110 fatal("Error in copy_saved_properties"); 111 } 112 copy_bytes_from(serialized_properties, buf, 0, serialized_properties_len); 113 if (has_pending_exception()) { 114 describe_pending_exception(true); 115 fatal("Error in copy_saved_properties"); 116 } 117 118 // Initialize saved properties in shared library 119 jclass servicesClass = JNIJVMCI::Services::clazz(); 120 jmethodID initializeSavedProperties = JNIJVMCI::Services::initializeSavedProperties_method(); 121 JNIAccessMark jni(this, THREAD); 122 jni()->CallStaticVoidMethod(servicesClass, initializeSavedProperties, buf.as_jobject()); 123 if (jni()->ExceptionCheck()) { 124 jni()->ExceptionDescribe(); 125 fatal("Error calling jdk.vm.ci.services.Services.initializeSavedProperties"); 126 } 127 } 128 129 void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) { 130 assert(thread != NULL, "npe"); 131 _env = NULL; 132 _pop_frame_on_close = false; 133 _detach_on_close = false; 134 if (!UseJVMCINativeLibrary) { 135 // In HotSpot mode, JNI isn't used at all. 136 _runtime = JVMCI::java_runtime(); 137 _is_hotspot = true; 138 return; 139 } 140 141 if (parent_env != NULL) { 142 // If the parent JNI environment is non-null then figure out whether it 143 // is a HotSpot or shared library JNIEnv and set the state appropriately. 144 _is_hotspot = thread->jni_environment() == parent_env; 145 if (_is_hotspot) { 146 // Select the Java runtime 147 _runtime = JVMCI::java_runtime(); 148 return; 149 } 150 _runtime = JVMCI::compiler_runtime(); 151 assert(_runtime != NULL, "npe"); 152 _env = parent_env; 153 return; 154 } 155 156 // Running in JVMCI shared library mode so ensure the shared library 157 // is loaded and initialized and get a shared library JNIEnv 158 _is_hotspot = false; 159 160 _runtime = JVMCI::compiler_runtime(); 161 _env = _runtime->init_shared_library_javavm(); 162 163 if (_env != NULL) { 164 // Creating the JVMCI shared library VM also attaches the current thread 165 _detach_on_close = true; 166 } else { 167 _runtime->GetEnv(thread, (void**)&parent_env, JNI_VERSION_1_2); 168 if (parent_env != NULL) { 169 // Even though there's a parent JNI env, there's no guarantee 170 // it was opened by a JVMCIEnv scope and thus may not have 171 // pushed a local JNI frame. As such, we use a new JNI local 172 // frame in this scope to ensure local JNI refs are collected 173 // in a timely manner after leaving this scope. 174 _env = parent_env; 175 } else { 176 ResourceMark rm; // Thread name is resource allocated 177 JavaVMAttachArgs attach_args; 178 attach_args.version = JNI_VERSION_1_2; 179 attach_args.name = thread->name(); 180 attach_args.group = NULL; 181 if (_runtime->AttachCurrentThread(thread, (void**) &_env, &attach_args) != JNI_OK) { 182 fatal("Error attaching current thread (%s) to JVMCI shared library JNI interface", attach_args.name); 183 } 184 _detach_on_close = true; 185 } 186 } 187 188 assert(_env != NULL, "missing env"); 189 assert(_throw_to_caller == false, "must be"); 190 191 JNIAccessMark jni(this, thread); 192 jint result = _env->PushLocalFrame(32); 193 if (result != JNI_OK) { 194 char message[256]; 195 jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line); 196 JVMCIRuntime::exit_on_pending_exception(this, message); 197 } 198 _pop_frame_on_close = true; 199 } 200 201 JVMCIEnv::JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line): 202 _throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) { 203 init_env_mode_runtime(thread, NULL); 204 } 205 206 JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line): 207 _throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) { 208 init_env_mode_runtime(thread, NULL); 209 } 210 211 JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line): 212 _throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) { 213 init_env_mode_runtime(thread, parent_env); 214 assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment"); 215 } 216 217 void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int line) { 218 _compile_state = NULL; 219 _throw_to_caller = false; 220 _file = file; 221 _line = line; 222 if (is_hotspot) { 223 _env = NULL; 224 _pop_frame_on_close = false; 225 _detach_on_close = false; 226 _is_hotspot = true; 227 _runtime = JVMCI::java_runtime(); 228 } else { 229 init_env_mode_runtime(thread, NULL); 230 } 231 } 232 233 // Prints a pending exception (if any) and its stack trace. 234 void JVMCIEnv::describe_pending_exception(bool clear) { 235 Thread* THREAD = Thread::current(); 236 if (!is_hotspot()) { 237 JNIAccessMark jni(this); 238 if (jni()->ExceptionCheck()) { 239 jthrowable ex = !clear ? jni()->ExceptionOccurred() : NULL; 240 jni()->ExceptionDescribe(); 241 if (ex != NULL) { 242 jni()->Throw(ex); 243 } 244 } 245 } else { 246 if (HAS_PENDING_EXCEPTION) { 247 JVMCIRuntime::describe_pending_hotspot_exception((JavaThread*) THREAD, clear); 248 } 249 } 250 } 251 252 void JVMCIEnv::translate_hotspot_exception_to_jni_exception(JavaThread* THREAD, const Handle& throwable) { 253 assert(!is_hotspot(), "must_be"); 254 // Resolve HotSpotJVMCIRuntime class explicitly as HotSpotJVMCI::compute_offsets 255 // may not have been called. 256 Klass* runtimeKlass = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_hotspot_HotSpotJVMCIRuntime(), true, CHECK); 257 JavaCallArguments jargs; 258 jargs.push_oop(throwable); 259 JavaValue result(T_OBJECT); 260 JavaCalls::call_static(&result, 261 runtimeKlass, 262 vmSymbols::encodeThrowable_name(), 263 vmSymbols::encodeThrowable_signature(), &jargs, THREAD); 264 if (HAS_PENDING_EXCEPTION) { 265 JVMCIRuntime::exit_on_pending_exception(this, "HotSpotJVMCIRuntime.encodeThrowable should not throw an exception"); 266 } 267 268 oop encoded_throwable_string = (oop) result.get_jobject(); 269 270 ResourceMark rm; 271 const char* encoded_throwable_chars = java_lang_String::as_utf8_string(encoded_throwable_string); 272 273 JNIAccessMark jni(this, THREAD); 274 jobject jni_encoded_throwable_string = jni()->NewStringUTF(encoded_throwable_chars); 275 jthrowable jni_throwable = (jthrowable) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), 276 JNIJVMCI::HotSpotJVMCIRuntime::decodeThrowable_method(), 277 jni_encoded_throwable_string); 278 jni()->Throw(jni_throwable); 279 } 280 281 JVMCIEnv::~JVMCIEnv() { 282 if (_throw_to_caller) { 283 if (is_hotspot()) { 284 // Nothing to do 285 } else { 286 if (Thread::current()->is_Java_thread()) { 287 JavaThread* THREAD = JavaThread::current(); 288 if (HAS_PENDING_EXCEPTION) { 289 Handle throwable = Handle(THREAD, PENDING_EXCEPTION); 290 CLEAR_PENDING_EXCEPTION; 291 translate_hotspot_exception_to_jni_exception(THREAD, throwable); 292 } 293 } 294 } 295 } else { 296 if (_pop_frame_on_close) { 297 // Pop the JNI local frame that was pushed when entering this JVMCIEnv scope. 298 JNIAccessMark jni(this); 299 jni()->PopLocalFrame(NULL); 300 } 301 302 if (has_pending_exception()) { 303 char message[256]; 304 jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line); 305 JVMCIRuntime::exit_on_pending_exception(this, message); 306 } 307 308 if (_detach_on_close) { 309 _runtime->DetachCurrentThread(JavaThread::current()); 310 } 311 } 312 } 313 314 jboolean JVMCIEnv::has_pending_exception() { 315 if (is_hotspot()) { 316 Thread* THREAD = Thread::current(); 317 return HAS_PENDING_EXCEPTION; 318 } else { 319 JNIAccessMark jni(this); 320 return jni()->ExceptionCheck(); 321 } 322 } 323 324 void JVMCIEnv::clear_pending_exception() { 325 if (is_hotspot()) { 326 Thread* THREAD = Thread::current(); 327 CLEAR_PENDING_EXCEPTION; 328 } else { 329 JNIAccessMark jni(this); 330 jni()->ExceptionClear(); 331 } 332 } 333 334 int JVMCIEnv::get_length(JVMCIArray array) { 335 if (is_hotspot()) { 336 return HotSpotJVMCI::resolve(array)->length(); 337 } else { 338 JNIAccessMark jni(this); 339 return jni()->GetArrayLength(get_jarray(array)); 340 } 341 } 342 343 JVMCIObject JVMCIEnv::get_object_at(JVMCIObjectArray array, int index) { 344 if (is_hotspot()) { 345 oop result = HotSpotJVMCI::resolve(array)->obj_at(index); 346 return wrap(result); 347 } else { 348 JNIAccessMark jni(this); 349 jobject result = jni()->GetObjectArrayElement(get_jobjectArray(array), index); 350 return wrap(result); 351 } 352 } 353 354 void JVMCIEnv::put_object_at(JVMCIObjectArray array, int index, JVMCIObject value) { 355 if (is_hotspot()) { 356 HotSpotJVMCI::resolve(array)->obj_at_put(index, HotSpotJVMCI::resolve(value)); 357 } else { 358 JNIAccessMark jni(this); 359 jni()->SetObjectArrayElement(get_jobjectArray(array), index, get_jobject(value)); 360 } 361 } 362 363 jboolean JVMCIEnv::get_bool_at(JVMCIPrimitiveArray array, int index) { 364 if (is_hotspot()) { 365 return HotSpotJVMCI::resolve(array)->bool_at(index); 366 } else { 367 JNIAccessMark jni(this); 368 jboolean result; 369 jni()->GetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &result); 370 return result; 371 } 372 } 373 void JVMCIEnv::put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value) { 374 if (is_hotspot()) { 375 HotSpotJVMCI::resolve(array)->bool_at_put(index, value); 376 } else { 377 JNIAccessMark jni(this); 378 jni()->SetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &value); 379 } 380 } 381 382 jbyte JVMCIEnv::get_byte_at(JVMCIPrimitiveArray array, int index) { 383 if (is_hotspot()) { 384 return HotSpotJVMCI::resolve(array)->byte_at(index); 385 } else { 386 JNIAccessMark jni(this); 387 jbyte result; 388 jni()->GetByteArrayRegion(array.as_jbyteArray(), index, 1, &result); 389 return result; 390 } 391 } 392 void JVMCIEnv::put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value) { 393 if (is_hotspot()) { 394 HotSpotJVMCI::resolve(array)->byte_at_put(index, value); 395 } else { 396 JNIAccessMark jni(this); 397 jni()->SetByteArrayRegion(array.as_jbyteArray(), index, 1, &value); 398 } 399 } 400 401 jint JVMCIEnv::get_int_at(JVMCIPrimitiveArray array, int index) { 402 if (is_hotspot()) { 403 return HotSpotJVMCI::resolve(array)->int_at(index); 404 } else { 405 JNIAccessMark jni(this); 406 jint result; 407 jni()->GetIntArrayRegion(array.as_jintArray(), index, 1, &result); 408 return result; 409 } 410 } 411 void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) { 412 if (is_hotspot()) { 413 HotSpotJVMCI::resolve(array)->int_at_put(index, value); 414 } else { 415 JNIAccessMark jni(this); 416 jni()->SetIntArrayRegion(array.as_jintArray(), index, 1, &value); 417 } 418 } 419 420 long JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) { 421 if (is_hotspot()) { 422 return HotSpotJVMCI::resolve(array)->long_at(index); 423 } else { 424 JNIAccessMark jni(this); 425 jlong result; 426 jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result); 427 return result; 428 } 429 } 430 void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) { 431 if (is_hotspot()) { 432 HotSpotJVMCI::resolve(array)->long_at_put(index, value); 433 } else { 434 JNIAccessMark jni(this); 435 jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value); 436 } 437 } 438 439 void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) { 440 if (length == 0) { 441 return; 442 } 443 if (is_hotspot()) { 444 memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length); 445 } else { 446 JNIAccessMark jni(this); 447 jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest); 448 } 449 } 450 void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) { 451 if (length == 0) { 452 return; 453 } 454 if (is_hotspot()) { 455 memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length); 456 } else { 457 JNIAccessMark jni(this); 458 jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, length, src); 459 } 460 } 461 462 void JVMCIEnv::copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length) { 463 if (length == 0) { 464 return; 465 } 466 if (is_hotspot()) { 467 memcpy(HotSpotJVMCI::resolve(dest)->long_at_addr(offset), src, length * sizeof(jlong)); 468 } else { 469 JNIAccessMark jni(this); 470 jni()->SetLongArrayRegion(dest.as_jlongArray(), offset, length, src); 471 } 472 } 473 474 jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) { 475 if (is_hotspot()) { 476 return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type); 477 } else { 478 JNIAccessMark jni(this); 479 return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type)); 480 } 481 } 482 483 // Get the primitive value from a Java boxing object. It's hard error to 484 // pass a non-primitive BasicType. 485 jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) { 486 jvalue result; 487 if (is_hotspot()) { 488 if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) { 489 ShouldNotReachHere(); 490 } 491 } else { 492 JNIAccessMark jni(this); 493 jfieldID field = JNIJVMCI::box_field(type); 494 switch (type) { 495 case T_BOOLEAN: result.z = jni()->GetBooleanField(get_jobject(object), field); break; 496 case T_BYTE: result.b = jni()->GetByteField(get_jobject(object), field); break; 497 case T_SHORT: result.s = jni()->GetShortField(get_jobject(object), field); break; 498 case T_CHAR: result.c = jni()->GetCharField(get_jobject(object), field); break; 499 case T_INT: result.i = jni()->GetIntField(get_jobject(object), field); break; 500 case T_LONG: result.j = jni()->GetLongField(get_jobject(object), field); break; 501 case T_FLOAT: result.f = jni()->GetFloatField(get_jobject(object), field); break; 502 case T_DOUBLE: result.d = jni()->GetDoubleField(get_jobject(object), field); break; 503 default: 504 ShouldNotReachHere(); 505 } 506 } 507 return result; 508 } 509 510 // Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL. 511 BasicType JVMCIEnv::get_box_type(JVMCIObject object) { 512 if (is_hotspot()) { 513 return java_lang_boxing_object::basic_type(HotSpotJVMCI::resolve(object)); 514 } else { 515 JNIAccessMark jni(this); 516 jclass clazz = jni()->GetObjectClass(get_jobject(object)); 517 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BOOLEAN))) return T_BOOLEAN; 518 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BYTE))) return T_BYTE; 519 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_SHORT))) return T_SHORT; 520 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_CHAR))) return T_CHAR; 521 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_INT))) return T_INT; 522 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_LONG))) return T_LONG; 523 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_FLOAT))) return T_FLOAT; 524 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_DOUBLE))) return T_DOUBLE; 525 return T_ILLEGAL; 526 } 527 } 528 529 // Create a boxing object of the appropriate primitive type. 530 JVMCIObject JVMCIEnv::create_box(BasicType type, jvalue* value, JVMCI_TRAPS) { 531 switch (type) { 532 case T_BOOLEAN: 533 case T_BYTE: 534 case T_CHAR: 535 case T_SHORT: 536 case T_INT: 537 case T_LONG: 538 case T_FLOAT: 539 case T_DOUBLE: 540 break; 541 default: 542 JVMCI_THROW_MSG_(IllegalArgumentException, "Only boxes for primitive values can be created", JVMCIObject()); 543 } 544 JavaThread* THREAD = JavaThread::current(); 545 if (is_hotspot()) { 546 oop box = java_lang_boxing_object::create(type, value, CHECK_(JVMCIObject())); 547 return HotSpotJVMCI::wrap(box); 548 } else { 549 JNIAccessMark jni(this, THREAD); 550 jobject box = jni()->NewObjectA(JNIJVMCI::box_class(type), JNIJVMCI::box_constructor(type), value); 551 assert(box != NULL, ""); 552 return wrap(box); 553 } 554 } 555 556 const char* JVMCIEnv::as_utf8_string(JVMCIObject str) { 557 if (is_hotspot()) { 558 return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str)); 559 } else { 560 JNIAccessMark jni(this); 561 int length = jni()->GetStringLength(str.as_jstring()); 562 char* result = NEW_RESOURCE_ARRAY(char, length + 1); 563 jni()->GetStringUTFRegion(str.as_jstring(), 0, length, result); 564 return result; 565 } 566 } 567 568 char* JVMCIEnv::as_utf8_string(JVMCIObject str, char* buf, int buflen) { 569 if (is_hotspot()) { 570 return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str), buf, buflen); 571 } else { 572 JNIAccessMark jni(this); 573 int length = jni()->GetStringLength(str.as_jstring()); 574 if (length >= buflen) { 575 length = buflen; 576 } 577 jni()->GetStringUTFRegion(str.as_jstring(), 0, length, buf); 578 return buf; 579 } 580 } 581 582 #define DO_THROW(name) \ 583 void JVMCIEnv::throw_##name(const char* msg) { \ 584 if (is_hotspot()) { \ 585 JavaThread* THREAD = JavaThread::current(); \ 586 THROW_MSG(HotSpotJVMCI::name::symbol(), msg); \ 587 } else { \ 588 JNIAccessMark jni(this); \ 589 jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \ 590 } \ 591 } 592 593 DO_THROW(InternalError) 594 DO_THROW(ArrayIndexOutOfBoundsException) 595 DO_THROW(IllegalStateException) 596 DO_THROW(NullPointerException) 597 DO_THROW(IllegalArgumentException) 598 DO_THROW(InvalidInstalledCodeException) 599 DO_THROW(UnsatisfiedLinkError) 600 DO_THROW(UnsupportedOperationException) 601 DO_THROW(ClassNotFoundException) 602 603 #undef DO_THROW 604 605 void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) { 606 const int max_msg_size = 1024; 607 va_list ap; 608 va_start(ap, format); 609 char msg[max_msg_size]; 610 vsnprintf(msg, max_msg_size, format, ap); 611 msg[max_msg_size-1] = '\0'; 612 va_end(ap); 613 JavaThread* THREAD = JavaThread::current(); 614 if (is_hotspot()) { 615 Handle h_loader = Handle(); 616 Handle h_protection_domain = Handle(); 617 Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain); 618 } else { 619 JNIAccessMark jni(this, THREAD); 620 jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg); 621 } 622 } 623 624 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci, 625 jlong compile_state, int id) { 626 if (is_hotspot()) { 627 Thread* THREAD = Thread::current(); 628 JavaCallArguments jargs; 629 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 630 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method))); 631 jargs.push_int(entry_bci); 632 jargs.push_long(compile_state); 633 jargs.push_int(id); 634 JavaValue result(T_OBJECT); 635 JavaCalls::call_special(&result, 636 HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), 637 vmSymbols::compileMethod_name(), 638 vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject())); 639 return wrap((oop) result.get_jobject()); 640 } else { 641 JNIAccessMark jni(this); 642 jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(), 643 JNIJVMCI::HotSpotJVMCIRuntime::clazz(), 644 JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(), 645 method.as_jobject(), entry_bci, compile_state, id); 646 if (jni()->ExceptionCheck()) { 647 return JVMCIObject(); 648 } 649 return wrap(result); 650 } 651 } 652 653 void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) { 654 if (is_hotspot()) { 655 Thread* THREAD = Thread::current(); 656 JavaCallArguments jargs; 657 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 658 JavaValue result(T_VOID); 659 JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK); 660 } else { 661 JNIAccessMark jni(this); 662 jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method()); 663 664 } 665 } 666 667 void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) { 668 HandleMark hm; 669 JavaThread* THREAD = JavaThread::current(); 670 if (is_hotspot()) { 671 JavaCallArguments jargs; 672 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 673 JavaValue result(T_VOID); 674 JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::shutdown_name(), vmSymbols::void_method_signature(), &jargs, THREAD); 675 } else { 676 JNIAccessMark jni(this, THREAD); 677 jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::shutdown_method()); 678 } 679 if (has_pending_exception()) { 680 // This should never happen as HotSpotJVMCIRuntime.shutdown() should 681 // handle all exceptions. 682 describe_pending_exception(true); 683 } 684 } 685 686 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) { 687 JavaThread* THREAD = JavaThread::current(); 688 if (is_hotspot()) { 689 JavaCallArguments jargs; 690 JavaValue result(T_OBJECT); 691 JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::runtime_name(), vmSymbols::runtime_signature(), &jargs, CHECK_(JVMCIObject())); 692 return wrap((oop) result.get_jobject()); 693 } else { 694 JNIAccessMark jni(this, THREAD); 695 jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::runtime_method()); 696 if (jni()->ExceptionCheck()) { 697 return JVMCIObject(); 698 } 699 return wrap(result); 700 } 701 } 702 703 JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) { 704 JavaThread* THREAD = JavaThread::current(); 705 if (is_hotspot()) { 706 JavaCallArguments jargs; 707 JavaValue result(T_OBJECT); 708 JavaCalls::call_static(&result, HotSpotJVMCI::JVMCI::klass(), vmSymbols::getRuntime_name(), vmSymbols::getRuntime_signature(), &jargs, CHECK_(JVMCIObject())); 709 return wrap((oop) result.get_jobject()); 710 } else { 711 JNIAccessMark jni(this, THREAD); 712 jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::JVMCI::clazz(), JNIJVMCI::JVMCI::getRuntime_method()); 713 if (jni()->ExceptionCheck()) { 714 return JVMCIObject(); 715 } 716 return wrap(result); 717 } 718 } 719 720 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) { 721 JavaThread* THREAD = JavaThread::current(); 722 if (is_hotspot()) { 723 JavaCallArguments jargs; 724 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 725 JavaValue result(T_OBJECT); 726 JavaCalls::call_virtual(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::getCompiler_name(), vmSymbols::getCompiler_signature(), &jargs, CHECK_(JVMCIObject())); 727 return wrap((oop) result.get_jobject()); 728 } else { 729 JNIAccessMark jni(this, THREAD); 730 jobject result = jni()->CallObjectMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::getCompiler_method()); 731 if (jni()->ExceptionCheck()) { 732 return JVMCIObject(); 733 } 734 return wrap(result); 735 } 736 } 737 738 739 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) { 740 JavaThread* THREAD = JavaThread::current(); 741 if (is_hotspot()) { 742 JavaCallArguments jargs; 743 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object))); 744 JavaValue result(T_OBJECT); 745 JavaCalls::call_static(&result, 746 HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), 747 vmSymbols::callToString_name(), 748 vmSymbols::callToString_signature(), &jargs, CHECK_(JVMCIObject())); 749 return wrap((oop) result.get_jobject()); 750 } else { 751 JNIAccessMark jni(this, THREAD); 752 jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), 753 JNIJVMCI::HotSpotJVMCIRuntime::callToString_method(), 754 object.as_jobject()); 755 if (jni()->ExceptionCheck()) { 756 return JVMCIObject(); 757 } 758 return wrap(result); 759 } 760 } 761 762 763 JVMCIObject JVMCIEnv::call_PrimitiveConstant_forTypeChar(jchar kind, jlong value, JVMCI_TRAPS) { 764 JavaThread* THREAD = JavaThread::current(); 765 if (is_hotspot()) { 766 JavaCallArguments jargs; 767 jargs.push_int(kind); 768 jargs.push_long(value); 769 JavaValue result(T_OBJECT); 770 JavaCalls::call_static(&result, 771 HotSpotJVMCI::PrimitiveConstant::klass(), 772 vmSymbols::forTypeChar_name(), 773 vmSymbols::forTypeChar_signature(), &jargs, CHECK_(JVMCIObject())); 774 return wrap((oop) result.get_jobject()); 775 } else { 776 JNIAccessMark jni(this, THREAD); 777 jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::PrimitiveConstant::clazz(), 778 JNIJVMCI::PrimitiveConstant::forTypeChar_method(), 779 kind, value); 780 if (jni()->ExceptionCheck()) { 781 return JVMCIObject(); 782 } 783 return wrap(result); 784 } 785 } 786 787 JVMCIObject JVMCIEnv::call_JavaConstant_forFloat(float value, JVMCI_TRAPS) { 788 JavaThread* THREAD = JavaThread::current(); 789 if (is_hotspot()) { 790 JavaCallArguments jargs; 791 jargs.push_float(value); 792 JavaValue result(T_OBJECT); 793 JavaCalls::call_static(&result, 794 HotSpotJVMCI::JavaConstant::klass(), 795 vmSymbols::forFloat_name(), 796 vmSymbols::forFloat_signature(), &jargs, CHECK_(JVMCIObject())); 797 return wrap((oop) result.get_jobject()); 798 } else { 799 JNIAccessMark jni(this, THREAD); 800 jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(), 801 JNIJVMCI::JavaConstant::forFloat_method(), 802 value); 803 if (jni()->ExceptionCheck()) { 804 return JVMCIObject(); 805 } 806 return wrap(result); 807 } 808 } 809 810 JVMCIObject JVMCIEnv::call_JavaConstant_forDouble(double value, JVMCI_TRAPS) { 811 JavaThread* THREAD = JavaThread::current(); 812 if (is_hotspot()) { 813 JavaCallArguments jargs; 814 jargs.push_double(value); 815 JavaValue result(T_OBJECT); 816 JavaCalls::call_static(&result, 817 HotSpotJVMCI::JavaConstant::klass(), 818 vmSymbols::forDouble_name(), 819 vmSymbols::forDouble_signature(), &jargs, CHECK_(JVMCIObject())); 820 return wrap((oop) result.get_jobject()); 821 } else { 822 JNIAccessMark jni(this, THREAD); 823 jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(), 824 JNIJVMCI::JavaConstant::forDouble_method(), 825 value); 826 if (jni()->ExceptionCheck()) { 827 return JVMCIObject(); 828 } 829 return wrap(result); 830 } 831 } 832 833 JVMCIObject JVMCIEnv::get_jvmci_primitive_type(BasicType type) { 834 JVMCIObjectArray primitives = get_HotSpotResolvedPrimitiveType_primitives(); 835 JVMCIObject result = get_object_at(primitives, type); 836 return result; 837 } 838 839 JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS) { 840 JavaThread* THREAD = JavaThread::current(); 841 Symbol* file_name_sym; 842 int line_number; 843 java_lang_StackTraceElement::decode(method, bci, file_name_sym, line_number, CHECK_(JVMCIObject())); 844 845 Symbol* method_name_sym = method->name(); 846 InstanceKlass* holder = method->method_holder(); 847 const char* declaring_class_str = holder->external_name(); 848 849 if (is_hotspot()) { 850 HotSpotJVMCI::StackTraceElement::klass()->initialize(CHECK_(JVMCIObject())); 851 oop objOop = HotSpotJVMCI::StackTraceElement::klass()->allocate_instance(CHECK_(JVMCIObject())); 852 Handle obj = Handle(THREAD, objOop); 853 854 oop declaring_class = StringTable::intern((char*) declaring_class_str, CHECK_(JVMCIObject())); 855 HotSpotJVMCI::StackTraceElement::set_declaringClass(this, obj(), declaring_class); 856 857 oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject())); 858 HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name); 859 860 if (file_name_sym != NULL) { 861 oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject())); 862 HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name); 863 } 864 HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number); 865 return wrap(obj()); 866 } else { 867 JNIAccessMark jni(this, THREAD); 868 jobject declaring_class = jni()->NewStringUTF(declaring_class_str); 869 if (jni()->ExceptionCheck()) { 870 return JVMCIObject(); 871 } 872 jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string()); 873 if (jni()->ExceptionCheck()) { 874 return JVMCIObject(); 875 } 876 jobject file_name = NULL; 877 if (file_name_sym != NULL) { 878 file_name = jni()->NewStringUTF(file_name_sym->as_C_string()); 879 if (jni()->ExceptionCheck()) { 880 return JVMCIObject(); 881 } 882 } 883 884 jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(), 885 JNIJVMCI::StackTraceElement::constructor(), 886 declaring_class, method_name, file_name, line_number); 887 return wrap(result); 888 } 889 } 890 891 JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) { 892 JavaThread* THREAD = JavaThread::current(); 893 894 JVMCIObject methodObject = get_jvmci_method(method(), JVMCI_CHECK_(JVMCIObject())); 895 896 if (is_hotspot()) { 897 InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass()); 898 if (ik->should_be_initialized()) { 899 ik->initialize(CHECK_(JVMCIObject())); 900 } 901 oop obj = ik->allocate_instance(CHECK_(JVMCIObject())); 902 Handle obj_h(THREAD, obj); 903 Handle nameStr = java_lang_String::create_from_str(name, CHECK_(JVMCIObject())); 904 905 // Call constructor 906 JavaCallArguments jargs; 907 jargs.push_oop(obj_h); 908 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject))); 909 jargs.push_oop(nameStr); 910 jargs.push_int(isDefault); 911 jargs.push_long(compileId); 912 JavaValue result(T_VOID); 913 JavaCalls::call_special(&result, ik, 914 vmSymbols::object_initializer_name(), 915 vmSymbols::method_string_bool_long_signature(), 916 &jargs, CHECK_(JVMCIObject())); 917 return wrap(obj_h()); 918 } else { 919 JNIAccessMark jni(this, THREAD); 920 jobject nameStr = name == NULL ? NULL : jni()->NewStringUTF(name); 921 if (jni()->ExceptionCheck()) { 922 return JVMCIObject(); 923 } 924 925 jobject result = jni()->NewObject(JNIJVMCI::HotSpotNmethod::clazz(), 926 JNIJVMCI::HotSpotNmethod::constructor(), 927 methodObject.as_jobject(), nameStr, isDefault); 928 return wrap(result); 929 } 930 } 931 932 JVMCIObject JVMCIEnv::make_local(JVMCIObject object) { 933 if (object.is_null()) { 934 return JVMCIObject(); 935 } 936 if (is_hotspot()) { 937 return wrap(JNIHandles::make_local(HotSpotJVMCI::resolve(object))); 938 } else { 939 JNIAccessMark jni(this); 940 return wrap(jni()->NewLocalRef(object.as_jobject())); 941 } 942 } 943 944 JVMCIObject JVMCIEnv::make_global(JVMCIObject object) { 945 if (object.is_null()) { 946 return JVMCIObject(); 947 } 948 if (is_hotspot()) { 949 return wrap(JNIHandles::make_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object)))); 950 } else { 951 JNIAccessMark jni(this); 952 return wrap(jni()->NewGlobalRef(object.as_jobject())); 953 } 954 } 955 956 void JVMCIEnv::destroy_local(JVMCIObject object) { 957 if (is_hotspot()) { 958 JNIHandles::destroy_local(object.as_jobject()); 959 } else { 960 JNIAccessMark jni(this); 961 jni()->DeleteLocalRef(object.as_jobject()); 962 } 963 } 964 965 void JVMCIEnv::destroy_global(JVMCIObject object) { 966 if (is_hotspot()) { 967 JNIHandles::destroy_global(object.as_jobject()); 968 } else { 969 JNIAccessMark jni(this); 970 jni()->DeleteGlobalRef(object.as_jobject()); 971 } 972 } 973 974 const char* JVMCIEnv::klass_name(JVMCIObject object) { 975 if (is_hotspot()) { 976 return HotSpotJVMCI::resolve(object)->klass()->signature_name(); 977 } else { 978 JVMCIObject name; 979 { 980 JNIAccessMark jni(this); 981 jclass jcl = jni()->GetObjectClass(object.as_jobject()); 982 jobject result = jni()->CallObjectMethod(jcl, JNIJVMCI::Class_getName_method()); 983 name = JVMCIObject::create(result, is_hotspot()); 984 } 985 return as_utf8_string(name); 986 } 987 } 988 989 JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) { 990 JVMCIObject method_object; 991 if (method() == NULL) { 992 return method_object; 993 } 994 995 Thread* THREAD = Thread::current(); 996 jmetadata handle = _runtime->allocate_handle(method); 997 jboolean exception = false; 998 if (is_hotspot()) { 999 JavaValue result(T_OBJECT); 1000 JavaCallArguments args; 1001 args.push_long((jlong) handle); 1002 JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(), 1003 vmSymbols::fromMetaspace_name(), 1004 vmSymbols::method_fromMetaspace_signature(), &args, THREAD); 1005 if (HAS_PENDING_EXCEPTION) { 1006 exception = true; 1007 } else { 1008 method_object = wrap((oop)result.get_jobject()); 1009 } 1010 } else { 1011 JNIAccessMark jni(this); 1012 method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(), 1013 JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(), 1014 (jlong) handle)); 1015 exception = jni()->ExceptionCheck(); 1016 } 1017 1018 if (exception) { 1019 _runtime->release_handle(handle); 1020 return JVMCIObject(); 1021 } 1022 1023 assert(asMethod(method_object) == method(), "must be"); 1024 if (get_HotSpotResolvedJavaMethodImpl_metadataHandle(method_object) != (jlong) handle) { 1025 _runtime->release_handle(handle); 1026 } 1027 assert(!method_object.is_null(), "must be"); 1028 return method_object; 1029 } 1030 1031 JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS) { 1032 JVMCIObject type; 1033 if (klass.is_null()) { 1034 return type; 1035 } 1036 1037 jlong pointer = (jlong) klass(); 1038 JavaThread* THREAD = JavaThread::current(); 1039 JVMCIObject signature = create_string(klass->signature_name(), JVMCI_CHECK_(JVMCIObject())); 1040 jboolean exception = false; 1041 if (is_hotspot()) { 1042 JavaValue result(T_OBJECT); 1043 JavaCallArguments args; 1044 args.push_long(pointer); 1045 args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(signature))); 1046 JavaCalls::call_static(&result, 1047 HotSpotJVMCI::HotSpotResolvedObjectTypeImpl::klass(), 1048 vmSymbols::fromMetaspace_name(), 1049 vmSymbols::klass_fromMetaspace_signature(), &args, THREAD); 1050 1051 if (HAS_PENDING_EXCEPTION) { 1052 exception = true; 1053 } else { 1054 type = wrap((oop)result.get_jobject()); 1055 } 1056 } else { 1057 JNIAccessMark jni(this, THREAD); 1058 1059 HandleMark hm(THREAD); 1060 type = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedObjectTypeImpl::clazz(), 1061 JNIJVMCI::HotSpotResolvedObjectTypeImpl_fromMetaspace_method(), 1062 pointer, signature.as_jstring())); 1063 exception = jni()->ExceptionCheck(); 1064 } 1065 if (exception) { 1066 return JVMCIObject(); 1067 } 1068 1069 assert(type.is_non_null(), "must have result"); 1070 return type; 1071 } 1072 1073 JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS) { 1074 JVMCIObject cp_object; 1075 jmetadata handle = _runtime->allocate_handle(cp); 1076 jboolean exception = false; 1077 JavaThread* THREAD = JavaThread::current(); 1078 if (is_hotspot()) { 1079 JavaValue result(T_OBJECT); 1080 JavaCallArguments args; 1081 args.push_long((jlong) handle); 1082 JavaCalls::call_static(&result, 1083 HotSpotJVMCI::HotSpotConstantPool::klass(), 1084 vmSymbols::fromMetaspace_name(), 1085 vmSymbols::constantPool_fromMetaspace_signature(), &args, THREAD); 1086 if (HAS_PENDING_EXCEPTION) { 1087 exception = true; 1088 } else { 1089 cp_object = wrap((oop)result.get_jobject()); 1090 } 1091 } else { 1092 JNIAccessMark jni(this, THREAD); 1093 cp_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotConstantPool::clazz(), 1094 JNIJVMCI::HotSpotConstantPool_fromMetaspace_method(), 1095 (jlong) handle)); 1096 exception = jni()->ExceptionCheck(); 1097 } 1098 1099 if (exception) { 1100 _runtime->release_handle(handle); 1101 return JVMCIObject(); 1102 } 1103 1104 assert(!cp_object.is_null(), "must be"); 1105 // Constant pools aren't cached so this is always a newly created object using the handle 1106 assert(get_HotSpotConstantPool_metadataHandle(cp_object) == (jlong) handle, "must use same handle"); 1107 return cp_object; 1108 } 1109 1110 JVMCIPrimitiveArray JVMCIEnv::new_booleanArray(int length, JVMCI_TRAPS) { 1111 JavaThread* THREAD = JavaThread::current(); 1112 if (is_hotspot()) { 1113 typeArrayOop result = oopFactory::new_boolArray(length, CHECK_(JVMCIObject())); 1114 return wrap(result); 1115 } else { 1116 JNIAccessMark jni(this, THREAD); 1117 jbooleanArray result = jni()->NewBooleanArray(length); 1118 return wrap(result); 1119 } 1120 } 1121 1122 JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) { 1123 JavaThread* THREAD = JavaThread::current(); 1124 if (is_hotspot()) { 1125 typeArrayOop result = oopFactory::new_byteArray(length, CHECK_(JVMCIObject())); 1126 return wrap(result); 1127 } else { 1128 JNIAccessMark jni(this, THREAD); 1129 jbyteArray result = jni()->NewByteArray(length); 1130 return wrap(result); 1131 } 1132 } 1133 1134 JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) { 1135 JavaThread* THREAD = JavaThread::current(); 1136 if (is_hotspot()) { 1137 Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlassObj ())->array_klass(CHECK_(JVMCIObject())); 1138 objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject())); 1139 return wrap(result); 1140 } else { 1141 JNIAccessMark jni(this, THREAD); 1142 jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::byte_array(), NULL); 1143 return wrap(result); 1144 } 1145 } 1146 1147 JVMCIPrimitiveArray JVMCIEnv::new_intArray(int length, JVMCI_TRAPS) { 1148 JavaThread* THREAD = JavaThread::current(); 1149 if (is_hotspot()) { 1150 typeArrayOop result = oopFactory::new_intArray(length, CHECK_(JVMCIObject())); 1151 return wrap(result); 1152 } else { 1153 JNIAccessMark jni(this, THREAD); 1154 jintArray result = jni()->NewIntArray(length); 1155 return wrap(result); 1156 } 1157 } 1158 1159 JVMCIPrimitiveArray JVMCIEnv::new_longArray(int length, JVMCI_TRAPS) { 1160 JavaThread* THREAD = JavaThread::current(); 1161 if (is_hotspot()) { 1162 typeArrayOop result = oopFactory::new_longArray(length, CHECK_(JVMCIObject())); 1163 return wrap(result); 1164 } else { 1165 JNIAccessMark jni(this, THREAD); 1166 jlongArray result = jni()->NewLongArray(length); 1167 return wrap(result); 1168 } 1169 } 1170 1171 JVMCIObject JVMCIEnv::new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS) { 1172 JavaThread* THREAD = JavaThread::current(); 1173 if (is_hotspot()) { 1174 HotSpotJVMCI::VMField::klass()->initialize(CHECK_(JVMCIObject())); 1175 oop obj = HotSpotJVMCI::VMField::klass()->allocate_instance(CHECK_(JVMCIObject())); 1176 HotSpotJVMCI::VMField::set_name(this, obj, HotSpotJVMCI::resolve(name)); 1177 HotSpotJVMCI::VMField::set_type(this, obj, HotSpotJVMCI::resolve(type)); 1178 HotSpotJVMCI::VMField::set_offset(this, obj, offset); 1179 HotSpotJVMCI::VMField::set_address(this, obj, address); 1180 HotSpotJVMCI::VMField::set_value(this, obj, HotSpotJVMCI::resolve(value)); 1181 return wrap(obj); 1182 } else { 1183 JNIAccessMark jni(this, THREAD); 1184 jobject result = jni()->NewObject(JNIJVMCI::VMField::clazz(), 1185 JNIJVMCI::VMField::constructor(), 1186 get_jobject(name), get_jobject(type), offset, address, get_jobject(value)); 1187 return wrap(result); 1188 } 1189 } 1190 1191 JVMCIObject JVMCIEnv::new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS) { 1192 JavaThread* THREAD = JavaThread::current(); 1193 if (is_hotspot()) { 1194 HotSpotJVMCI::VMFlag::klass()->initialize(CHECK_(JVMCIObject())); 1195 oop obj = HotSpotJVMCI::VMFlag::klass()->allocate_instance(CHECK_(JVMCIObject())); 1196 HotSpotJVMCI::VMFlag::set_name(this, obj, HotSpotJVMCI::resolve(name)); 1197 HotSpotJVMCI::VMFlag::set_type(this, obj, HotSpotJVMCI::resolve(type)); 1198 HotSpotJVMCI::VMFlag::set_value(this, obj, HotSpotJVMCI::resolve(value)); 1199 return wrap(obj); 1200 } else { 1201 JNIAccessMark jni(this, THREAD); 1202 jobject result = jni()->NewObject(JNIJVMCI::VMFlag::clazz(), 1203 JNIJVMCI::VMFlag::constructor(), 1204 get_jobject(name), get_jobject(type), get_jobject(value)); 1205 return wrap(result); 1206 } 1207 } 1208 1209 JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS) { 1210 JavaThread* THREAD = JavaThread::current(); 1211 if (is_hotspot()) { 1212 HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject())); 1213 oop obj = HotSpotJVMCI::VMIntrinsicMethod::klass()->allocate_instance(CHECK_(JVMCIObject())); 1214 HotSpotJVMCI::VMIntrinsicMethod::set_declaringClass(this, obj, HotSpotJVMCI::resolve(declaringClass)); 1215 HotSpotJVMCI::VMIntrinsicMethod::set_name(this, obj, HotSpotJVMCI::resolve(name)); 1216 HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor)); 1217 HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id); 1218 return wrap(obj); 1219 } else { 1220 JNIAccessMark jni(this, THREAD); 1221 jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(), 1222 JNIJVMCI::VMIntrinsicMethod::constructor(), 1223 get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id); 1224 return wrap(result); 1225 } 1226 } 1227 1228 JVMCIObject JVMCIEnv::new_HotSpotStackFrameReference(JVMCI_TRAPS) { 1229 if (is_hotspot()) { 1230 JavaThread* THREAD = JavaThread::current(); 1231 HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_(JVMCIObject())); 1232 oop obj = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance(CHECK_(JVMCIObject())); 1233 return wrap(obj); 1234 } else { 1235 ShouldNotReachHere(); 1236 return JVMCIObject(); 1237 } 1238 } 1239 JVMCIObject JVMCIEnv::new_JVMCIError(JVMCI_TRAPS) { 1240 if (is_hotspot()) { 1241 JavaThread* THREAD = JavaThread::current(); 1242 HotSpotJVMCI::JVMCIError::klass()->initialize(CHECK_(JVMCIObject())); 1243 oop obj = HotSpotJVMCI::JVMCIError::klass()->allocate_instance(CHECK_(JVMCIObject())); 1244 return wrap(obj); 1245 } else { 1246 ShouldNotReachHere(); 1247 return JVMCIObject(); 1248 } 1249 } 1250 1251 1252 JVMCIObject JVMCIEnv::get_object_constant(oop objOop, bool compressed, bool dont_register) { 1253 JavaThread* THREAD = JavaThread::current(); 1254 Handle obj = Handle(THREAD, objOop); 1255 if (obj.is_null()) { 1256 return JVMCIObject(); 1257 } 1258 if (is_hotspot()) { 1259 HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->initialize(CHECK_(JVMCIObject())); 1260 oop constant = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->allocate_instance(CHECK_(JVMCIObject())); 1261 HotSpotJVMCI::DirectHotSpotObjectConstantImpl::set_object(this, constant, obj()); 1262 HotSpotJVMCI::HotSpotObjectConstantImpl::set_compressed(this, constant, compressed); 1263 return wrap(constant); 1264 } else { 1265 jlong handle = make_handle(obj); 1266 JNIAccessMark jni(this, THREAD); 1267 jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(), 1268 JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(), 1269 handle, compressed, dont_register); 1270 return wrap(result); 1271 } 1272 } 1273 1274 1275 Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) { 1276 if (constant.is_null()) { 1277 return Handle(); 1278 } 1279 JavaThread* THREAD = JavaThread::current(); 1280 if (is_hotspot()) { 1281 assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type"); 1282 oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant)); 1283 return Handle(THREAD, obj); 1284 } else if (isa_IndirectHotSpotObjectConstantImpl(constant)) { 1285 jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant); 1286 if (object_handle == 0L) { 1287 JVMCI_THROW_MSG_(NullPointerException, "Foreign object reference has been cleared", Handle()); 1288 } 1289 oop result = resolve_handle(object_handle); 1290 if (result == NULL) { 1291 JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle()); 1292 } 1293 return Handle(THREAD, result); 1294 } else { 1295 JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle()); 1296 } 1297 } 1298 1299 JVMCIObject JVMCIEnv::wrap(jobject object) { 1300 return JVMCIObject::create(object, is_hotspot()); 1301 } 1302 1303 jlong JVMCIEnv::make_handle(const Handle& obj) { 1304 assert(!obj.is_null(), "should only create handle for non-NULL oops"); 1305 jobject handle = _runtime->make_global(obj); 1306 return (jlong) handle; 1307 } 1308 1309 oop JVMCIEnv::resolve_handle(jlong objectHandle) { 1310 assert(objectHandle != 0, "should be a valid handle"); 1311 oop obj = *((oopDesc**)objectHandle); 1312 if (obj != NULL) { 1313 obj->verify(); 1314 } 1315 return obj; 1316 } 1317 1318 JVMCIObject JVMCIEnv::create_string(const char* str, JVMCI_TRAPS) { 1319 JavaThread* THREAD = JavaThread::current(); 1320 if (is_hotspot()) { 1321 Handle result = java_lang_String::create_from_str(str, CHECK_(JVMCIObject())); 1322 return HotSpotJVMCI::wrap(result()); 1323 } else { 1324 jobject result; 1325 jboolean exception = false; 1326 { 1327 JNIAccessMark jni(this, THREAD); 1328 result = jni()->NewStringUTF(str); 1329 exception = jni()->ExceptionCheck(); 1330 } 1331 return wrap(result); 1332 } 1333 } 1334 1335 bool JVMCIEnv::equals(JVMCIObject a, JVMCIObject b) { 1336 if (is_hotspot()) { 1337 return HotSpotJVMCI::resolve(a) == HotSpotJVMCI::resolve(b); 1338 } else { 1339 JNIAccessMark jni(this); 1340 return jni()->IsSameObject(a.as_jobject(), b.as_jobject()) != 0; 1341 } 1342 } 1343 1344 BasicType JVMCIEnv::kindToBasicType(JVMCIObject kind, JVMCI_TRAPS) { 1345 if (kind.is_null()) { 1346 JVMCI_THROW_(NullPointerException, T_ILLEGAL); 1347 } 1348 jchar ch = get_JavaKind_typeChar(kind); 1349 switch(ch) { 1350 case 'Z': return T_BOOLEAN; 1351 case 'B': return T_BYTE; 1352 case 'S': return T_SHORT; 1353 case 'C': return T_CHAR; 1354 case 'I': return T_INT; 1355 case 'F': return T_FLOAT; 1356 case 'J': return T_LONG; 1357 case 'D': return T_DOUBLE; 1358 case 'A': return T_OBJECT; 1359 case '-': return T_ILLEGAL; 1360 default: 1361 JVMCI_ERROR_(T_ILLEGAL, "unexpected Kind: %c", ch); 1362 } 1363 } 1364 1365 void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS) { 1366 // Ensure that all updates to the InstalledCode fields are consistent. 1367 if (get_InstalledCode_address(installed_code) != 0) { 1368 JVMCI_THROW_MSG(InternalError, "InstalledCode instance already in use"); 1369 } 1370 if (!isa_HotSpotInstalledCode(installed_code)) { 1371 JVMCI_THROW_MSG(InternalError, "InstalledCode instance must be a subclass of HotSpotInstalledCode"); 1372 } 1373 1374 // Ignore the version which can stay at 0 1375 if (cb->is_nmethod()) { 1376 nmethod* nm = cb->as_nmethod_or_null(); 1377 if (!nm->is_alive()) { 1378 JVMCI_THROW_MSG(InternalError, "nmethod has been reclaimed"); 1379 } 1380 if (nm->is_in_use()) { 1381 set_InstalledCode_entryPoint(installed_code, (jlong) nm->verified_entry_point()); 1382 } 1383 } else { 1384 set_InstalledCode_entryPoint(installed_code, (jlong) cb->code_begin()); 1385 } 1386 set_InstalledCode_address(installed_code, (jlong) cb); 1387 set_HotSpotInstalledCode_size(installed_code, cb->size()); 1388 set_HotSpotInstalledCode_codeStart(installed_code, (jlong) cb->code_begin()); 1389 set_HotSpotInstalledCode_codeSize(installed_code, cb->code_size()); 1390 } 1391 1392 1393 void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS) { 1394 if (mirror.is_null()) { 1395 JVMCI_THROW(NullPointerException); 1396 } 1397 1398 nmethodLocker locker; 1399 nmethod* nm = JVMCIENV->get_nmethod(mirror, locker); 1400 if (nm == NULL) { 1401 // Nothing to do 1402 return; 1403 } 1404 1405 Thread* THREAD = Thread::current(); 1406 if (!mirror.is_hotspot() && !THREAD->is_Java_thread()) { 1407 // Calling back into native might cause the execution to block, so only allow this when calling 1408 // from a JavaThread, which is the normal case anyway. 1409 JVMCI_THROW_MSG(IllegalArgumentException, 1410 "Cannot invalidate HotSpotNmethod object in shared library VM heap from non-JavaThread"); 1411 } 1412 1413 VM_DeoptimizeNMethod::invalidate(nm); 1414 1415 // A HotSpotNmethod instance can only reference a single nmethod 1416 // during its lifetime so simply clear it here. 1417 set_InstalledCode_address(mirror, 0); 1418 } 1419 1420 Klass* JVMCIEnv::asKlass(JVMCIObject obj) { 1421 return (Klass*) get_HotSpotResolvedObjectTypeImpl_metadataPointer(obj); 1422 } 1423 1424 Method* JVMCIEnv::asMethod(JVMCIObject obj) { 1425 Method** metadataHandle = (Method**) get_HotSpotResolvedJavaMethodImpl_metadataHandle(obj); 1426 return *metadataHandle; 1427 } 1428 1429 ConstantPool* JVMCIEnv::asConstantPool(JVMCIObject obj) { 1430 ConstantPool** metadataHandle = (ConstantPool**) get_HotSpotConstantPool_metadataHandle(obj); 1431 return *metadataHandle; 1432 } 1433 1434 CodeBlob* JVMCIEnv::get_code_blob(JVMCIObject obj, nmethodLocker& locker) { 1435 address code = (address) get_InstalledCode_address(obj); 1436 if (code == NULL) { 1437 return NULL; 1438 } 1439 if (isa_HotSpotNmethod(obj)) { 1440 nmethod* nm = NULL; 1441 { 1442 // Lookup the CodeBlob while holding the CodeCache_lock to ensure the nmethod can't be freed 1443 // by nmethod::flush while we're interrogating it. 1444 MutexLockerEx cm_lock(CodeCache_lock, Mutex::_no_safepoint_check_flag); 1445 CodeBlob* cb = CodeCache::find_blob_unsafe(code); 1446 if (cb == (CodeBlob*) code) { 1447 nmethod* the_nm = cb->as_nmethod_or_null(); 1448 if (the_nm != NULL && the_nm->is_alive()) { 1449 // Lock the nmethod to stop any further transitions by the sweeper. It's still possible 1450 // for this code to execute in the middle of the sweeping of the nmethod but that will be 1451 // handled below. 1452 locker.set_code(nm, true); 1453 nm = the_nm; 1454 } 1455 } 1456 } 1457 1458 if (nm != NULL) { 1459 // We found the nmethod but it could be in the process of being freed. Check the state of the 1460 // nmethod while holding the Patching_lock. This ensures that any transitions by other 1461 // threads have seen the is_locked_by_vm() update above. 1462 MutexLockerEx cm_lock(Patching_lock, Mutex::_no_safepoint_check_flag); 1463 if (!nm->is_alive()) { 1464 // It was alive when we looked it up but it's no longer alive so release it. 1465 locker.set_code(NULL); 1466 nm = NULL; 1467 } 1468 } 1469 1470 jlong compile_id_snapshot = get_HotSpotNmethod_compileIdSnapshot(obj); 1471 if (compile_id_snapshot != 0L) { 1472 // Found a live nmethod with the same address, make sure it's the same nmethod 1473 if (nm == (nmethod*) code && nm->compile_id() == compile_id_snapshot && nm->is_alive()) { 1474 if (nm->is_not_entrant()) { 1475 // Zero the entry point so that the nmethod 1476 // cannot be invoked by the mirror but can 1477 // still be deoptimized. 1478 set_InstalledCode_entryPoint(obj, 0); 1479 } 1480 return nm; 1481 } 1482 // The HotSpotNmethod no longer refers to a valid nmethod so clear the state 1483 locker.set_code(NULL); 1484 nm = NULL; 1485 } 1486 1487 if (nm == NULL) { 1488 // The HotSpotNmethod was pointing at some nmethod but the nmethod is no longer valid, so 1489 // clear the InstalledCode fields of this HotSpotNmethod so that it no longer refers to a 1490 // nmethod in the code cache. 1491 set_InstalledCode_address(obj, 0); 1492 set_InstalledCode_entryPoint(obj, 0); 1493 } 1494 return nm; 1495 } 1496 1497 CodeBlob* cb = (CodeBlob*) code; 1498 assert(!cb->is_nmethod(), "unexpected nmethod"); 1499 return cb; 1500 } 1501 1502 nmethod* JVMCIEnv::get_nmethod(JVMCIObject obj, nmethodLocker& locker) { 1503 CodeBlob* cb = get_code_blob(obj, locker); 1504 if (cb != NULL) { 1505 return cb->as_nmethod_or_null(); 1506 } 1507 return NULL; 1508 } 1509 1510 // Generate implementations for the initialize, new, isa, get and set methods for all the types and 1511 // fields declared in the JVMCI_CLASSES_DO macro. 1512 1513 #define START_CLASS(className, fullClassName) \ 1514 void JVMCIEnv::className##_initialize(JVMCI_TRAPS) { \ 1515 if (is_hotspot()) { \ 1516 HotSpotJVMCI::className::initialize(JVMCI_CHECK); \ 1517 } else { \ 1518 JNIJVMCI::className::initialize(JVMCI_CHECK); \ 1519 } \ 1520 } \ 1521 JVMCIObjectArray JVMCIEnv::new_##className##_array(int length, JVMCI_TRAPS) { \ 1522 if (is_hotspot()) { \ 1523 Thread* THREAD = Thread::current(); \ 1524 objArrayOop array = oopFactory::new_objArray(HotSpotJVMCI::className::klass(), length, CHECK_(JVMCIObject())); \ 1525 return (JVMCIObjectArray) wrap(array); \ 1526 } else { \ 1527 JNIAccessMark jni(this); \ 1528 jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::className::clazz(), NULL); \ 1529 return wrap(result); \ 1530 } \ 1531 } \ 1532 bool JVMCIEnv::isa_##className(JVMCIObject object) { \ 1533 if (is_hotspot()) { \ 1534 return HotSpotJVMCI::className::is_instance(this, object); \ 1535 } else { \ 1536 return JNIJVMCI::className::is_instance(this, object); \ 1537 } \ 1538 } 1539 1540 #define END_CLASS 1541 1542 #define FIELD(className, name, type, accessor, cast) \ 1543 type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \ 1544 if (is_hotspot()) { \ 1545 return HotSpotJVMCI::className::get_##name(this, obj); \ 1546 } else { \ 1547 return JNIJVMCI::className::get_##name(this, obj); \ 1548 } \ 1549 } \ 1550 void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \ 1551 if (is_hotspot()) { \ 1552 HotSpotJVMCI::className::set_##name(this, obj, x); \ 1553 } else { \ 1554 JNIJVMCI::className::set_##name(this, obj, x); \ 1555 } \ 1556 } 1557 1558 #define EMPTY_CAST 1559 #define CHAR_FIELD(className, name) FIELD(className, name, jchar, Char, EMPTY_CAST) 1560 #define INT_FIELD(className, name) FIELD(className, name, jint, Int, EMPTY_CAST) 1561 #define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, Boolean, EMPTY_CAST) 1562 #define LONG_FIELD(className, name) FIELD(className, name, jlong, Long, EMPTY_CAST) 1563 #define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, Float, EMPTY_CAST) 1564 1565 #define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST) 1566 #define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray)) 1567 #define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray)) 1568 1569 #define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject)) 1570 #define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray)) 1571 1572 #define OOPISH_FIELD(className, name, type, accessor, cast) \ 1573 type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \ 1574 if (is_hotspot()) { \ 1575 return HotSpotJVMCI::className::get_##name(this, obj); \ 1576 } else { \ 1577 return JNIJVMCI::className::get_##name(this, obj); \ 1578 } \ 1579 } \ 1580 void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \ 1581 if (is_hotspot()) { \ 1582 HotSpotJVMCI::className::set_##name(this, obj, x); \ 1583 } else { \ 1584 JNIJVMCI::className::set_##name(this, obj, x); \ 1585 } \ 1586 } 1587 1588 #define STATIC_OOPISH_FIELD(className, name, type, accessor, cast) \ 1589 type JVMCIEnv::get_##className##_##name() { \ 1590 if (is_hotspot()) { \ 1591 return HotSpotJVMCI::className::get_##name(this); \ 1592 } else { \ 1593 return JNIJVMCI::className::get_##name(this); \ 1594 } \ 1595 } \ 1596 void JVMCIEnv::set_##className##_##name(type x) { \ 1597 if (is_hotspot()) { \ 1598 HotSpotJVMCI::className::set_##name(this, x); \ 1599 } else { \ 1600 JNIJVMCI::className::set_##name(this, x); \ 1601 } \ 1602 } 1603 1604 #define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \ 1605 type JVMCIEnv::get_##className##_##name() { \ 1606 if (is_hotspot()) { \ 1607 return HotSpotJVMCI::className::get_##name(this); \ 1608 } else { \ 1609 return JNIJVMCI::className::get_##name(this); \ 1610 } \ 1611 } \ 1612 void JVMCIEnv::set_##className##_##name(type x) { \ 1613 if (is_hotspot()) { \ 1614 HotSpotJVMCI::className::set_##name(this, x); \ 1615 } else { \ 1616 JNIJVMCI::className::set_##name(this, x); \ 1617 } \ 1618 } 1619 #define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST) 1620 #define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST) 1621 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) 1622 #define CONSTRUCTOR(className, signature) 1623 1624 JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR) 1625 1626 #undef START_CLASS 1627 #undef END_CLASS 1628 #undef METHOD 1629 #undef CONSTRUCTOR 1630 #undef FIELD 1631 #undef CHAR_FIELD 1632 #undef INT_FIELD 1633 #undef BOOLEAN_FIELD 1634 #undef LONG_FIELD 1635 #undef FLOAT_FIELD 1636 #undef OBJECT_FIELD 1637 #undef PRIMARRAY_FIELD 1638 #undef OBJECTARRAY_FIELD 1639 #undef STATIC_OOPISH_FIELD 1640 #undef STATIC_OBJECT_FIELD 1641 #undef STATIC_OBJECTARRAY_FIELD 1642 #undef STATIC_INT_FIELD 1643 #undef STATIC_BOOLEAN_FIELD 1644 #undef EMPTY_CAST --- EOF ---