112 describe_pending_exception(true);
113 fatal("Error in copy_saved_properties");
114 }
115 copy_bytes_from(serialized_properties, buf, 0, serialized_properties_len);
116 if (has_pending_exception()) {
117 describe_pending_exception(true);
118 fatal("Error in copy_saved_properties");
119 }
120
121 // Initialize saved properties in shared library
122 jclass servicesClass = JNIJVMCI::Services::clazz();
123 jmethodID initializeSavedProperties = JNIJVMCI::Services::initializeSavedProperties_method();
124 JNIAccessMark jni(this);
125 jni()->CallStaticVoidMethod(servicesClass, initializeSavedProperties, buf.as_jobject());
126 if (jni()->ExceptionCheck()) {
127 jni()->ExceptionDescribe();
128 fatal("Error calling jdk.vm.ci.services.Services.initializeSavedProperties");
129 }
130 }
131
132 JNIEnv* JVMCIEnv::attach_shared_library() {
133 if (_shared_library_javavm == NULL) {
134 MutexLocker locker(JVMCI_lock);
135 if (_shared_library_javavm == NULL) {
136
137 char path[JVM_MAXPATHLEN];
138 char ebuf[1024];
139 if (JVMCILibPath != NULL) {
140 if (!os::dll_locate_lib(path, sizeof(path), JVMCILibPath, JVMCI_SHARED_LIBRARY_NAME)) {
141 vm_exit_during_initialization("Unable to create JVMCI shared library path from -XX:JVMCILibPath value", JVMCILibPath);
142 }
143 } else {
144 if (!os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), JVMCI_SHARED_LIBRARY_NAME)) {
145 vm_exit_during_initialization("Unable to create path to JVMCI shared library");
146 }
147 }
148
149 void* handle = os::dll_load(path, ebuf, sizeof ebuf);
150 if (handle == NULL) {
151 vm_exit_during_initialization("Unable to load JVMCI shared library", ebuf);
152 }
153 _shared_library_handle = handle;
154 _shared_library_path = strdup(path);
155 jint (*JNI_CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
156 typedef jint (*JNI_CreateJavaVM_t)(JavaVM **pvm, void **penv, void *args);
162 }
163
164 ResourceMark rm;
165 JavaVMInitArgs vm_args;
166 vm_args.version = JNI_VERSION_1_2;
167 vm_args.ignoreUnrecognized = JNI_TRUE;
168 vm_args.options = NULL;
169 vm_args.nOptions = 0;
170
171 JavaVM* the_javavm = NULL;
172 int result = (*JNI_CreateJavaVM)(&the_javavm, (void**) &env, &vm_args);
173 if (result == JNI_OK) {
174 guarantee(env != NULL, "missing env");
175 _shared_library_javavm = the_javavm;
176 return env;
177 } else {
178 vm_exit_during_initialization(err_msg("JNI_CreateJavaVM failed with return value %d", result), path);
179 }
180 }
181 }
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;
189 }
190
191 void JVMCIEnv::init_env_mode_runtime(JNIEnv* parent_env) {
192 // By default there is only one runtime which is the compiler runtime.
193 _runtime = JVMCI::compiler_runtime();
194 if (!UseJVMCINativeLibrary) {
195 // In HotSpot mode, JNI isn't used at all.
196 _is_hotspot = true;
197 _env = NULL;
198 return;
199 }
200
201 if (parent_env != NULL) {
202 // 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.
204 JavaThread* thread = JavaThread::current();
205 if (thread->jni_environment() == parent_env) {
206 // Select the Java runtime
207 _runtime = JVMCI::java_runtime();
208 _is_hotspot = true;
209 _env = NULL;
210 return;
211 }
212 }
213
214 // Running in JVMCI shared library mode so get a shared library JNIEnv
215 _is_hotspot = false;
216 _env = attach_shared_library();
217 assert(parent_env == NULL || _env == parent_env, "must be");
218
219 if (parent_env == NULL) {
220 // There is no parent shared library JNI env so push
221 // a JNI local frame to release all local handles in
222 // this JVMCIEnv scope when it's closed.
223 assert(_throw_to_caller == false, "must be");
224 JNIAccessMark jni(this);
225 jint result = _env->PushLocalFrame(32);
226 if (result != JNI_OK) {
227 char message[256];
228 jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line);
229 JVMCIRuntime::exit_on_pending_exception(this, message);
230 }
231 }
232 }
233
234 JVMCIEnv::JVMCIEnv(JVMCICompileState* compile_state, const char* file, int line):
235 _throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) {
236 init_env_mode_runtime(NULL);
237 }
238
239 JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):
240 _throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) {
241 init_env_mode_runtime(NULL);
242 }
243
244 JVMCIEnv::JVMCIEnv(JNIEnv* parent_env, const char* file, int line):
245 _throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) {
246 init_env_mode_runtime(parent_env);
247 assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment");
248 }
249
250 void JVMCIEnv::init(bool is_hotspot, const char* file, int line) {
251 _compile_state = NULL;
252 _throw_to_caller = false;
253 _file = file;
254 _line = line;
255 if (is_hotspot) {
256 _env = NULL;
257 _is_hotspot = true;
258 _runtime = JVMCI::java_runtime();
259 } else {
260 init_env_mode_runtime(NULL);
261 }
262 }
263
264 // Prints a pending exception (if any) and its stack trace.
265 void JVMCIEnv::describe_pending_exception(bool clear) {
266 if (!is_hotspot()) {
267 JNIAccessMark jni(this);
268 if (jni()->ExceptionCheck()) {
269 jthrowable ex = !clear ? jni()->ExceptionOccurred() : NULL;
270 jni()->ExceptionDescribe();
271 if (ex != NULL) {
272 jni()->Throw(ex);
273 }
274 }
275 } else {
276 Thread* THREAD = Thread::current();
277 if (HAS_PENDING_EXCEPTION) {
278 JVMCIRuntime::describe_pending_hotspot_exception((JavaThread*) THREAD, clear);
279 }
280 }
307 JNIJVMCI::HotSpotJVMCIRuntime::decodeThrowable_method(),
308 jni_encoded_throwable_string);
309 jni()->Throw(jni_throwable);
310 }
311
312 JVMCIEnv::~JVMCIEnv() {
313 if (_throw_to_caller) {
314 if (is_hotspot()) {
315 // Nothing to do
316 } else {
317 if (Thread::current()->is_Java_thread()) {
318 JavaThread* THREAD = JavaThread::current();
319 if (HAS_PENDING_EXCEPTION) {
320 Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
321 CLEAR_PENDING_EXCEPTION;
322 translate_hotspot_exception_to_jni_exception(THREAD, throwable);
323 }
324 }
325 }
326 } else {
327 if (!is_hotspot()) {
328 // Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.
329 JNIAccessMark jni(this);
330 jni()->PopLocalFrame(NULL);
331 }
332
333 if (has_pending_exception()) {
334 char message[256];
335 jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);
336 JVMCIRuntime::exit_on_pending_exception(this, message);
337 }
338 }
339 }
340
341 jboolean JVMCIEnv::has_pending_exception() {
342 if (is_hotspot()) {
343 Thread* THREAD = Thread::current();
344 return HAS_PENDING_EXCEPTION;
345 } else {
346 JNIAccessMark jni(this);
347 return jni()->ExceptionCheck();
348 }
349 }
350
351 void JVMCIEnv::clear_pending_exception() {
352 if (is_hotspot()) {
353 Thread* THREAD = Thread::current();
354 CLEAR_PENDING_EXCEPTION;
355 } else {
356 JNIAccessMark jni(this);
357 jni()->ExceptionClear();
446
447 long JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) {
448 if (is_hotspot()) {
449 return HotSpotJVMCI::resolve(array)->long_at(index);
450 } else {
451 JNIAccessMark jni(this);
452 jlong result;
453 jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result);
454 return result;
455 }
456 }
457 void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) {
458 if (is_hotspot()) {
459 HotSpotJVMCI::resolve(array)->long_at_put(index, value);
460 } else {
461 JNIAccessMark jni(this);
462 jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value);
463 }
464 }
465
466 void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, int size_in_bytes) {
467 if (size_in_bytes == 0) {
468 return;
469 }
470 if (is_hotspot()) {
471 memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), size_in_bytes);
472 } else {
473 JNIAccessMark jni(this);
474 jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, size_in_bytes, dest);
475 }
476 }
477 void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, int size_in_bytes) {
478 if (size_in_bytes == 0) {
479 return;
480 }
481 if (is_hotspot()) {
482 memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, size_in_bytes);
483 } else {
484 JNIAccessMark jni(this);
485 jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, size_in_bytes, src);
486 }
487 }
488
489 jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) {
490 if (is_hotspot()) {
491 return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type);
492 } else {
493 JNIAccessMark jni(this);
494 return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type));
495 }
496 }
497
498 // Get the primitive value from a Java boxing object. It's hard error to
499 // pass a non-primitive BasicType.
500 jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) {
501 jvalue result;
502 if (is_hotspot()) {
503 if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) {
504 ShouldNotReachHere();
505 }
595 }
596
597 #define DO_THROW(name) \
598 void JVMCIEnv::throw_##name(const char* msg) { \
599 if (is_hotspot()) { \
600 JavaThread* THREAD = JavaThread::current(); \
601 THROW_MSG(HotSpotJVMCI::name::symbol(), msg); \
602 } else { \
603 JNIAccessMark jni(this); \
604 jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \
605 } \
606 }
607
608 DO_THROW(InternalError)
609 DO_THROW(ArrayIndexOutOfBoundsException)
610 DO_THROW(IllegalStateException)
611 DO_THROW(NullPointerException)
612 DO_THROW(IllegalArgumentException)
613 DO_THROW(InvalidInstalledCodeException)
614 DO_THROW(UnsatisfiedLinkError)
615
616 #undef DO_THROW
617
618 void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) {
619 const int max_msg_size = 1024;
620 va_list ap;
621 va_start(ap, format);
622 char msg[max_msg_size];
623 vsnprintf(msg, max_msg_size, format, ap);
624 msg[max_msg_size-1] = '\0';
625 va_end(ap);
626 if (is_hotspot()) {
627 JavaThread* THREAD = JavaThread::current();
628 Handle h_loader = Handle();
629 Handle h_protection_domain = Handle();
630 Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain);
631 } else {
632 JNIAccessMark jni(this);
633 jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg);
634 }
871 oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject()));
872 HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name);
873
874 if (file_name_sym != NULL) {
875 oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject()));
876 HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name);
877 }
878 HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number);
879 return wrap(obj());
880 } else {
881 JNIAccessMark jni(this);
882 jobject declaring_class = jni()->NewStringUTF(declaring_class_str);
883 if (jni()->ExceptionCheck()) {
884 return JVMCIObject();
885 }
886 jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());
887 if (jni()->ExceptionCheck()) {
888 return JVMCIObject();
889 }
890 jobject file_name = NULL;
891 if (file_name != NULL) {
892 file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
893 if (jni()->ExceptionCheck()) {
894 return JVMCIObject();
895 }
896 }
897
898 jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(),
899 JNIJVMCI::StackTraceElement::constructor(),
900 declaring_class, method_name, file_name, line_number);
901 return wrap(result);
902 }
903 }
904
905 JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {
906 JavaThread* THREAD = JavaThread::current();
907
908 JVMCIObject methodObject = get_jvmci_method(method(), JVMCI_CHECK_(JVMCIObject()));
909
910 if (is_hotspot()) {
911 InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass());
1306 } else {
1307 jlong handle = make_handle(obj);
1308 JNIAccessMark jni(this);
1309 jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(),
1310 JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(),
1311 handle, compressed, dont_register);
1312 return wrap(result);
1313 }
1314 }
1315
1316
1317 Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) {
1318 if (constant.is_null()) {
1319 return Handle();
1320 }
1321 JavaThread* THREAD = JavaThread::current();
1322 if (is_hotspot()) {
1323 assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type");
1324 oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant));
1325 return Handle(THREAD, obj);
1326 } else {
1327 assert(isa_IndirectHotSpotObjectConstantImpl(constant), "wrong type");
1328 jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);
1329 oop result = resolve_handle(object_handle);
1330 if (result == NULL) {
1331 JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle());
1332 }
1333 return Handle(THREAD, result);
1334 }
1335 }
1336
1337 JVMCIObject JVMCIEnv::wrap(jobject object) {
1338 return JVMCIObject::create(object, is_hotspot());
1339 }
1340
1341 jlong JVMCIEnv::make_handle(const Handle& obj) {
1342 assert(!obj.is_null(), "should only create handle for non-NULL oops");
1343 jobject handle = JVMCI::make_global(obj);
1344 return (jlong) handle;
1345 }
1346
1347 oop JVMCIEnv::resolve_handle(jlong objectHandle) {
1348 assert(objectHandle != 0, "should be a valid handle");
1349 oop obj = *((oopDesc**)objectHandle);
1350 if (obj != NULL) {
1351 oopDesc::verify(obj);
1352 }
1353 return obj;
|
112 describe_pending_exception(true);
113 fatal("Error in copy_saved_properties");
114 }
115 copy_bytes_from(serialized_properties, buf, 0, serialized_properties_len);
116 if (has_pending_exception()) {
117 describe_pending_exception(true);
118 fatal("Error in copy_saved_properties");
119 }
120
121 // Initialize saved properties in shared library
122 jclass servicesClass = JNIJVMCI::Services::clazz();
123 jmethodID initializeSavedProperties = JNIJVMCI::Services::initializeSavedProperties_method();
124 JNIAccessMark jni(this);
125 jni()->CallStaticVoidMethod(servicesClass, initializeSavedProperties, buf.as_jobject());
126 if (jni()->ExceptionCheck()) {
127 jni()->ExceptionDescribe();
128 fatal("Error calling jdk.vm.ci.services.Services.initializeSavedProperties");
129 }
130 }
131
132 JNIEnv* JVMCIEnv::init_shared_library(JavaThread* thread) {
133 if (_shared_library_javavm == NULL) {
134 MutexLocker locker(JVMCI_lock);
135 if (_shared_library_javavm == NULL) {
136 char path[JVM_MAXPATHLEN];
137 char ebuf[1024];
138 if (JVMCILibPath != NULL) {
139 if (!os::dll_locate_lib(path, sizeof(path), JVMCILibPath, JVMCI_SHARED_LIBRARY_NAME)) {
140 vm_exit_during_initialization("Unable to create JVMCI shared library path from -XX:JVMCILibPath value", JVMCILibPath);
141 }
142 } else {
143 if (!os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), JVMCI_SHARED_LIBRARY_NAME)) {
144 vm_exit_during_initialization("Unable to create path to JVMCI shared library");
145 }
146 }
147
148 void* handle = os::dll_load(path, ebuf, sizeof ebuf);
149 if (handle == NULL) {
150 vm_exit_during_initialization("Unable to load JVMCI shared library", ebuf);
151 }
152 _shared_library_handle = handle;
153 _shared_library_path = strdup(path);
154 jint (*JNI_CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
155 typedef jint (*JNI_CreateJavaVM_t)(JavaVM **pvm, void **penv, void *args);
161 }
162
163 ResourceMark rm;
164 JavaVMInitArgs vm_args;
165 vm_args.version = JNI_VERSION_1_2;
166 vm_args.ignoreUnrecognized = JNI_TRUE;
167 vm_args.options = NULL;
168 vm_args.nOptions = 0;
169
170 JavaVM* the_javavm = NULL;
171 int result = (*JNI_CreateJavaVM)(&the_javavm, (void**) &env, &vm_args);
172 if (result == JNI_OK) {
173 guarantee(env != NULL, "missing env");
174 _shared_library_javavm = the_javavm;
175 return env;
176 } else {
177 vm_exit_during_initialization(err_msg("JNI_CreateJavaVM failed with return value %d", result), path);
178 }
179 }
180 }
181 return NULL;
182 }
183
184 void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) {
185 assert(thread != NULL, "npe");
186 // By default there is only one runtime which is the compiler runtime.
187 _runtime = JVMCI::compiler_runtime();
188 _env = NULL;
189 _pop_frame_on_close = false;
190 _detach_on_close = false;
191 if (!UseJVMCINativeLibrary) {
192 // In HotSpot mode, JNI isn't used at all.
193 _is_hotspot = true;
194 return;
195 }
196
197 if (parent_env != NULL) {
198 // If the parent JNI environment is non-null then figure out whether it
199 // is a HotSpot or shared library JNIEnv and set the state appropriately.
200 _is_hotspot = thread->jni_environment() == parent_env;
201 if (_is_hotspot) {
202 // Select the Java runtime
203 _runtime = JVMCI::java_runtime();
204 return;
205 }
206 _env = parent_env;
207 return;
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
212 _is_hotspot = false;
213 _env = init_shared_library(thread);
214
215 if (_env != NULL) {
216 // Creating the JVMCI shared library VM also attaches the current thread
217 _detach_on_close = true;
218 } else {
219 _shared_library_javavm->GetEnv((void**)&parent_env, JNI_VERSION_1_2);
220 if (parent_env != NULL) {
221 // Even though there's a parent JNI env, there's no guarantee
222 // it was opened by a JVMCIEnv scope and thus may not have
223 // pushed a local JNI frame. As such, we use a new JNI local
224 // frame in this scope to ensure local JNI refs are collected
225 // in a timely manner after leaving this scope.
226 _env = parent_env;
227 } else {
228 ResourceMark rm; // Thread name is resource allocated
229 JavaVMAttachArgs attach_args;
230 attach_args.version = JNI_VERSION_1_2;
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):
254 _throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) {
255 init_env_mode_runtime(thread, NULL);
256 }
257
258 JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):
259 _throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) {
260 init_env_mode_runtime(thread, NULL);
261 }
262
263 JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line):
264 _throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) {
265 init_env_mode_runtime(thread, parent_env);
266 assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment");
267 }
268
269 void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int line) {
270 _compile_state = NULL;
271 _throw_to_caller = false;
272 _file = file;
273 _line = line;
274 if (is_hotspot) {
275 _env = NULL;
276 _pop_frame_on_close = false;
277 _detach_on_close = false;
278 _is_hotspot = true;
279 _runtime = JVMCI::java_runtime();
280 } else {
281 init_env_mode_runtime(thread, NULL);
282 }
283 }
284
285 // Prints a pending exception (if any) and its stack trace.
286 void JVMCIEnv::describe_pending_exception(bool clear) {
287 if (!is_hotspot()) {
288 JNIAccessMark jni(this);
289 if (jni()->ExceptionCheck()) {
290 jthrowable ex = !clear ? jni()->ExceptionOccurred() : NULL;
291 jni()->ExceptionDescribe();
292 if (ex != NULL) {
293 jni()->Throw(ex);
294 }
295 }
296 } else {
297 Thread* THREAD = Thread::current();
298 if (HAS_PENDING_EXCEPTION) {
299 JVMCIRuntime::describe_pending_hotspot_exception((JavaThread*) THREAD, clear);
300 }
301 }
328 JNIJVMCI::HotSpotJVMCIRuntime::decodeThrowable_method(),
329 jni_encoded_throwable_string);
330 jni()->Throw(jni_throwable);
331 }
332
333 JVMCIEnv::~JVMCIEnv() {
334 if (_throw_to_caller) {
335 if (is_hotspot()) {
336 // Nothing to do
337 } else {
338 if (Thread::current()->is_Java_thread()) {
339 JavaThread* THREAD = JavaThread::current();
340 if (HAS_PENDING_EXCEPTION) {
341 Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
342 CLEAR_PENDING_EXCEPTION;
343 translate_hotspot_exception_to_jni_exception(THREAD, throwable);
344 }
345 }
346 }
347 } else {
348 if (_pop_frame_on_close) {
349 // Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.
350 JNIAccessMark jni(this);
351 jni()->PopLocalFrame(NULL);
352 }
353
354 if (has_pending_exception()) {
355 char message[256];
356 jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);
357 JVMCIRuntime::exit_on_pending_exception(this, message);
358 }
359
360 if (_detach_on_close) {
361 get_shared_library_javavm()->DetachCurrentThread();
362 }
363 }
364 }
365
366 jboolean JVMCIEnv::has_pending_exception() {
367 if (is_hotspot()) {
368 Thread* THREAD = Thread::current();
369 return HAS_PENDING_EXCEPTION;
370 } else {
371 JNIAccessMark jni(this);
372 return jni()->ExceptionCheck();
373 }
374 }
375
376 void JVMCIEnv::clear_pending_exception() {
377 if (is_hotspot()) {
378 Thread* THREAD = Thread::current();
379 CLEAR_PENDING_EXCEPTION;
380 } else {
381 JNIAccessMark jni(this);
382 jni()->ExceptionClear();
471
472 long JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) {
473 if (is_hotspot()) {
474 return HotSpotJVMCI::resolve(array)->long_at(index);
475 } else {
476 JNIAccessMark jni(this);
477 jlong result;
478 jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result);
479 return result;
480 }
481 }
482 void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) {
483 if (is_hotspot()) {
484 HotSpotJVMCI::resolve(array)->long_at_put(index, value);
485 } else {
486 JNIAccessMark jni(this);
487 jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value);
488 }
489 }
490
491 void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) {
492 if (length == 0) {
493 return;
494 }
495 if (is_hotspot()) {
496 memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length);
497 } else {
498 JNIAccessMark jni(this);
499 jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest);
500 }
501 }
502 void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
503 if (length == 0) {
504 return;
505 }
506 if (is_hotspot()) {
507 memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length);
508 } else {
509 JNIAccessMark jni(this);
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);
523 }
524 }
525
526 jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) {
527 if (is_hotspot()) {
528 return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type);
529 } else {
530 JNIAccessMark jni(this);
531 return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type));
532 }
533 }
534
535 // Get the primitive value from a Java boxing object. It's hard error to
536 // pass a non-primitive BasicType.
537 jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) {
538 jvalue result;
539 if (is_hotspot()) {
540 if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) {
541 ShouldNotReachHere();
542 }
632 }
633
634 #define DO_THROW(name) \
635 void JVMCIEnv::throw_##name(const char* msg) { \
636 if (is_hotspot()) { \
637 JavaThread* THREAD = JavaThread::current(); \
638 THROW_MSG(HotSpotJVMCI::name::symbol(), msg); \
639 } else { \
640 JNIAccessMark jni(this); \
641 jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \
642 } \
643 }
644
645 DO_THROW(InternalError)
646 DO_THROW(ArrayIndexOutOfBoundsException)
647 DO_THROW(IllegalStateException)
648 DO_THROW(NullPointerException)
649 DO_THROW(IllegalArgumentException)
650 DO_THROW(InvalidInstalledCodeException)
651 DO_THROW(UnsatisfiedLinkError)
652 DO_THROW(UnsupportedOperationException)
653 DO_THROW(ClassNotFoundException)
654
655 #undef DO_THROW
656
657 void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) {
658 const int max_msg_size = 1024;
659 va_list ap;
660 va_start(ap, format);
661 char msg[max_msg_size];
662 vsnprintf(msg, max_msg_size, format, ap);
663 msg[max_msg_size-1] = '\0';
664 va_end(ap);
665 if (is_hotspot()) {
666 JavaThread* THREAD = JavaThread::current();
667 Handle h_loader = Handle();
668 Handle h_protection_domain = Handle();
669 Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain);
670 } else {
671 JNIAccessMark jni(this);
672 jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg);
673 }
910 oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject()));
911 HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name);
912
913 if (file_name_sym != NULL) {
914 oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject()));
915 HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name);
916 }
917 HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number);
918 return wrap(obj());
919 } else {
920 JNIAccessMark jni(this);
921 jobject declaring_class = jni()->NewStringUTF(declaring_class_str);
922 if (jni()->ExceptionCheck()) {
923 return JVMCIObject();
924 }
925 jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());
926 if (jni()->ExceptionCheck()) {
927 return JVMCIObject();
928 }
929 jobject file_name = NULL;
930 if (file_name_sym != NULL) {
931 file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
932 if (jni()->ExceptionCheck()) {
933 return JVMCIObject();
934 }
935 }
936
937 jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(),
938 JNIJVMCI::StackTraceElement::constructor(),
939 declaring_class, method_name, file_name, line_number);
940 return wrap(result);
941 }
942 }
943
944 JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {
945 JavaThread* THREAD = JavaThread::current();
946
947 JVMCIObject methodObject = get_jvmci_method(method(), JVMCI_CHECK_(JVMCIObject()));
948
949 if (is_hotspot()) {
950 InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass());
1345 } else {
1346 jlong handle = make_handle(obj);
1347 JNIAccessMark jni(this);
1348 jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(),
1349 JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(),
1350 handle, compressed, dont_register);
1351 return wrap(result);
1352 }
1353 }
1354
1355
1356 Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) {
1357 if (constant.is_null()) {
1358 return Handle();
1359 }
1360 JavaThread* THREAD = JavaThread::current();
1361 if (is_hotspot()) {
1362 assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type");
1363 oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant));
1364 return Handle(THREAD, obj);
1365 } else if (isa_IndirectHotSpotObjectConstantImpl(constant)) {
1366 jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);
1367 oop result = resolve_handle(object_handle);
1368 if (result == NULL) {
1369 JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle());
1370 }
1371 return Handle(THREAD, result);
1372 } else {
1373 JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle());
1374 }
1375 }
1376
1377 JVMCIObject JVMCIEnv::wrap(jobject object) {
1378 return JVMCIObject::create(object, is_hotspot());
1379 }
1380
1381 jlong JVMCIEnv::make_handle(const Handle& obj) {
1382 assert(!obj.is_null(), "should only create handle for non-NULL oops");
1383 jobject handle = JVMCI::make_global(obj);
1384 return (jlong) handle;
1385 }
1386
1387 oop JVMCIEnv::resolve_handle(jlong objectHandle) {
1388 assert(objectHandle != 0, "should be a valid handle");
1389 oop obj = *((oopDesc**)objectHandle);
1390 if (obj != NULL) {
1391 oopDesc::verify(obj);
1392 }
1393 return obj;
|