177 } else { |
176 } else { |
178 vm_exit_during_initialization(err_msg("JNI_CreateJavaVM failed with return value %d", result), path); |
177 vm_exit_during_initialization(err_msg("JNI_CreateJavaVM failed with return value %d", result), path); |
179 } |
178 } |
180 } |
179 } |
181 } |
180 } |
182 JNIEnv* env; |
|
183 if (_shared_library_javavm->AttachCurrentThread((void**)&env, NULL) == JNI_OK) { |
|
184 guarantee(env != NULL, "missing env"); |
|
185 return env; |
|
186 } |
|
187 fatal("Error attaching current thread to JVMCI shared library JNI interface"); |
|
188 return NULL; |
181 return NULL; |
189 } |
182 } |
190 |
183 |
191 void JVMCIEnv::init_env_mode_runtime(JNIEnv* parent_env) { |
184 void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) { |
|
185 assert(thread != NULL, "npe"); |
192 // By default there is only one runtime which is the compiler runtime. |
186 // By default there is only one runtime which is the compiler runtime. |
193 _runtime = JVMCI::compiler_runtime(); |
187 _runtime = JVMCI::compiler_runtime(); |
|
188 _env = NULL; |
|
189 _pop_frame_on_close = false; |
|
190 _detach_on_close = false; |
194 if (!UseJVMCINativeLibrary) { |
191 if (!UseJVMCINativeLibrary) { |
195 // In HotSpot mode, JNI isn't used at all. |
192 // In HotSpot mode, JNI isn't used at all. |
196 _is_hotspot = true; |
193 _is_hotspot = true; |
197 _env = NULL; |
|
198 return; |
194 return; |
199 } |
195 } |
200 |
196 |
201 if (parent_env != NULL) { |
197 if (parent_env != NULL) { |
202 // If the parent JNI environment is non-null then figure out whether it |
198 // If the parent JNI environment is non-null then figure out whether it |
203 // is a HotSpot or shared library JNIEnv and set the state appropriately. |
199 // is a HotSpot or shared library JNIEnv and set the state appropriately. |
204 JavaThread* thread = JavaThread::current(); |
200 _is_hotspot = thread->jni_environment() == parent_env; |
205 if (thread->jni_environment() == parent_env) { |
201 if (_is_hotspot) { |
206 // Select the Java runtime |
202 // Select the Java runtime |
207 _runtime = JVMCI::java_runtime(); |
203 _runtime = JVMCI::java_runtime(); |
208 _is_hotspot = true; |
|
209 _env = NULL; |
|
210 return; |
204 return; |
211 } |
205 } |
212 } |
206 _env = parent_env; |
213 |
207 return; |
214 // Running in JVMCI shared library mode so get a shared library JNIEnv |
208 } |
|
209 |
|
210 // Running in JVMCI shared library mode so ensure the shared library |
|
211 // is loaded and initialized and get a shared library JNIEnv |
215 _is_hotspot = false; |
212 _is_hotspot = false; |
216 _env = attach_shared_library(); |
213 _env = init_shared_library(thread); |
217 assert(parent_env == NULL || _env == parent_env, "must be"); |
214 |
218 |
215 if (_env != NULL) { |
219 if (parent_env == NULL) { |
216 // Creating the JVMCI shared library VM also attaches the current thread |
220 // There is no parent shared library JNI env so push |
217 _detach_on_close = true; |
221 // a JNI local frame to release all local handles in |
218 } else { |
222 // this JVMCIEnv scope when it's closed. |
219 _shared_library_javavm->GetEnv((void**)&parent_env, JNI_VERSION_1_2); |
223 assert(_throw_to_caller == false, "must be"); |
220 if (parent_env != NULL) { |
224 JNIAccessMark jni(this); |
221 // Even though there's a parent JNI env, there's no guarantee |
225 jint result = _env->PushLocalFrame(32); |
222 // it was opened by a JVMCIEnv scope and thus may not have |
226 if (result != JNI_OK) { |
223 // pushed a local JNI frame. As such, we use a new JNI local |
227 char message[256]; |
224 // frame in this scope to ensure local JNI refs are collected |
228 jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line); |
225 // in a timely manner after leaving this scope. |
229 JVMCIRuntime::exit_on_pending_exception(this, message); |
226 _env = parent_env; |
230 } |
227 } else { |
231 } |
228 ResourceMark rm; // Thread name is resource allocated |
232 } |
229 JavaVMAttachArgs attach_args; |
233 |
230 attach_args.version = JNI_VERSION_1_2; |
234 JVMCIEnv::JVMCIEnv(JVMCICompileState* compile_state, const char* file, int line): |
231 attach_args.name = thread->name(); |
|
232 attach_args.group = NULL; |
|
233 if (_shared_library_javavm->AttachCurrentThread((void**)&_env, &attach_args) != JNI_OK) { |
|
234 fatal("Error attaching current thread (%s) to JVMCI shared library JNI interface", attach_args.name); |
|
235 } |
|
236 _detach_on_close = true; |
|
237 } |
|
238 } |
|
239 |
|
240 assert(_env != NULL, "missing env"); |
|
241 assert(_throw_to_caller == false, "must be"); |
|
242 |
|
243 JNIAccessMark jni(this); |
|
244 jint result = _env->PushLocalFrame(32); |
|
245 if (result != JNI_OK) { |
|
246 char message[256]; |
|
247 jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line); |
|
248 JVMCIRuntime::exit_on_pending_exception(this, message); |
|
249 } |
|
250 _pop_frame_on_close = true; |
|
251 } |
|
252 |
|
253 JVMCIEnv::JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line): |
235 _throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) { |
254 _throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) { |
236 init_env_mode_runtime(NULL); |
255 init_env_mode_runtime(thread, NULL); |
237 } |
256 } |
238 |
257 |
239 JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line): |
258 JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line): |
240 _throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) { |
259 _throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) { |
241 init_env_mode_runtime(NULL); |
260 init_env_mode_runtime(thread, NULL); |
242 } |
261 } |
243 |
262 |
244 JVMCIEnv::JVMCIEnv(JNIEnv* parent_env, const char* file, int line): |
263 JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line): |
245 _throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) { |
264 _throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) { |
246 init_env_mode_runtime(parent_env); |
265 init_env_mode_runtime(thread, parent_env); |
247 assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment"); |
266 assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment"); |
248 } |
267 } |
249 |
268 |
250 void JVMCIEnv::init(bool is_hotspot, const char* file, int line) { |
269 void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int line) { |
251 _compile_state = NULL; |
270 _compile_state = NULL; |
252 _throw_to_caller = false; |
271 _throw_to_caller = false; |
253 _file = file; |
272 _file = file; |
254 _line = line; |
273 _line = line; |
255 if (is_hotspot) { |
274 if (is_hotspot) { |
256 _env = NULL; |
275 _env = NULL; |
|
276 _pop_frame_on_close = false; |
|
277 _detach_on_close = false; |
257 _is_hotspot = true; |
278 _is_hotspot = true; |
258 _runtime = JVMCI::java_runtime(); |
279 _runtime = JVMCI::java_runtime(); |
259 } else { |
280 } else { |
260 init_env_mode_runtime(NULL); |
281 init_env_mode_runtime(thread, NULL); |
261 } |
282 } |
262 } |
283 } |
263 |
284 |
264 // Prints a pending exception (if any) and its stack trace. |
285 // Prints a pending exception (if any) and its stack trace. |
265 void JVMCIEnv::describe_pending_exception(bool clear) { |
286 void JVMCIEnv::describe_pending_exception(bool clear) { |
461 JNIAccessMark jni(this); |
486 JNIAccessMark jni(this); |
462 jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value); |
487 jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value); |
463 } |
488 } |
464 } |
489 } |
465 |
490 |
466 void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, int size_in_bytes) { |
491 void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) { |
467 if (size_in_bytes == 0) { |
492 if (length == 0) { |
468 return; |
493 return; |
469 } |
494 } |
470 if (is_hotspot()) { |
495 if (is_hotspot()) { |
471 memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), size_in_bytes); |
496 memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length); |
472 } else { |
497 } else { |
473 JNIAccessMark jni(this); |
498 JNIAccessMark jni(this); |
474 jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, size_in_bytes, dest); |
499 jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest); |
475 } |
500 } |
476 } |
501 } |
477 void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, int size_in_bytes) { |
502 void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) { |
478 if (size_in_bytes == 0) { |
503 if (length == 0) { |
479 return; |
504 return; |
480 } |
505 } |
481 if (is_hotspot()) { |
506 if (is_hotspot()) { |
482 memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, size_in_bytes); |
507 memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length); |
483 } else { |
508 } else { |
484 JNIAccessMark jni(this); |
509 JNIAccessMark jni(this); |
485 jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, size_in_bytes, src); |
510 jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, length, src); |
|
511 } |
|
512 } |
|
513 |
|
514 void JVMCIEnv::copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length) { |
|
515 if (length == 0) { |
|
516 return; |
|
517 } |
|
518 if (is_hotspot()) { |
|
519 memcpy(HotSpotJVMCI::resolve(dest)->long_at_addr(offset), src, length * sizeof(jlong)); |
|
520 } else { |
|
521 JNIAccessMark jni(this); |
|
522 jni()->SetLongArrayRegion(dest.as_jlongArray(), offset, length, src); |
486 } |
523 } |
487 } |
524 } |
488 |
525 |
489 jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) { |
526 jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) { |
490 if (is_hotspot()) { |
527 if (is_hotspot()) { |
1321 JavaThread* THREAD = JavaThread::current(); |
1360 JavaThread* THREAD = JavaThread::current(); |
1322 if (is_hotspot()) { |
1361 if (is_hotspot()) { |
1323 assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type"); |
1362 assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type"); |
1324 oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant)); |
1363 oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant)); |
1325 return Handle(THREAD, obj); |
1364 return Handle(THREAD, obj); |
1326 } else { |
1365 } else if (isa_IndirectHotSpotObjectConstantImpl(constant)) { |
1327 assert(isa_IndirectHotSpotObjectConstantImpl(constant), "wrong type"); |
|
1328 jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant); |
1366 jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant); |
1329 oop result = resolve_handle(object_handle); |
1367 oop result = resolve_handle(object_handle); |
1330 if (result == NULL) { |
1368 if (result == NULL) { |
1331 JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle()); |
1369 JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle()); |
1332 } |
1370 } |
1333 return Handle(THREAD, result); |
1371 return Handle(THREAD, result); |
|
1372 } else { |
|
1373 JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle()); |
1334 } |
1374 } |
1335 } |
1375 } |
1336 |
1376 |
1337 JVMCIObject JVMCIEnv::wrap(jobject object) { |
1377 JVMCIObject JVMCIEnv::wrap(jobject object) { |
1338 return JVMCIObject::create(object, is_hotspot()); |
1378 return JVMCIObject::create(object, is_hotspot()); |