src/hotspot/share/jvmci/jvmciEnv.cpp
changeset 54732 2d012a75d35c
parent 54669 ad45b3802d4e
child 54786 ebf733a324d4
equal deleted inserted replaced
54731:81de17a33575 54732:2d012a75d35c
   127     jni()->ExceptionDescribe();
   127     jni()->ExceptionDescribe();
   128     fatal("Error calling jdk.vm.ci.services.Services.initializeSavedProperties");
   128     fatal("Error calling jdk.vm.ci.services.Services.initializeSavedProperties");
   129   }
   129   }
   130 }
   130 }
   131 
   131 
   132 JNIEnv* JVMCIEnv::attach_shared_library() {
   132 JNIEnv* JVMCIEnv::init_shared_library(JavaThread* thread) {
   133   if (_shared_library_javavm == NULL) {
   133   if (_shared_library_javavm == NULL) {
   134     MutexLocker locker(JVMCI_lock);
   134     MutexLocker locker(JVMCI_lock);
   135     if (_shared_library_javavm == NULL) {
   135     if (_shared_library_javavm == NULL) {
   136 
       
   137       char path[JVM_MAXPATHLEN];
   136       char path[JVM_MAXPATHLEN];
   138       char ebuf[1024];
   137       char ebuf[1024];
   139       if (JVMCILibPath != NULL) {
   138       if (JVMCILibPath != NULL) {
   140         if (!os::dll_locate_lib(path, sizeof(path), JVMCILibPath, JVMCI_SHARED_LIBRARY_NAME)) {
   139         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);
   140           vm_exit_during_initialization("Unable to create JVMCI shared library path from -XX:JVMCILibPath value", JVMCILibPath);
   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) {
   322           translate_hotspot_exception_to_jni_exception(THREAD, throwable);
   343           translate_hotspot_exception_to_jni_exception(THREAD, throwable);
   323         }
   344         }
   324       }
   345       }
   325     }
   346     }
   326   } else {
   347   } else {
   327     if (!is_hotspot()) {
   348     if (_pop_frame_on_close) {
   328       // Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.
   349       // Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.
   329       JNIAccessMark jni(this);
   350       JNIAccessMark jni(this);
   330       jni()->PopLocalFrame(NULL);
   351       jni()->PopLocalFrame(NULL);
   331     }
   352     }
   332 
   353 
   333     if (has_pending_exception()) {
   354     if (has_pending_exception()) {
   334       char message[256];
   355       char message[256];
   335       jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);
   356       jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);
   336       JVMCIRuntime::exit_on_pending_exception(this, message);
   357       JVMCIRuntime::exit_on_pending_exception(this, message);
   337     }
   358     }
       
   359 
       
   360     if (_detach_on_close) {
       
   361       get_shared_library_javavm()->DetachCurrentThread();
       
   362     }
   338   }
   363   }
   339 }
   364 }
   340 
   365 
   341 jboolean JVMCIEnv::has_pending_exception() {
   366 jboolean JVMCIEnv::has_pending_exception() {
   342   if (is_hotspot()) {
   367   if (is_hotspot()) {
   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()) {
   610 DO_THROW(IllegalStateException)
   647 DO_THROW(IllegalStateException)
   611 DO_THROW(NullPointerException)
   648 DO_THROW(NullPointerException)
   612 DO_THROW(IllegalArgumentException)
   649 DO_THROW(IllegalArgumentException)
   613 DO_THROW(InvalidInstalledCodeException)
   650 DO_THROW(InvalidInstalledCodeException)
   614 DO_THROW(UnsatisfiedLinkError)
   651 DO_THROW(UnsatisfiedLinkError)
       
   652 DO_THROW(UnsupportedOperationException)
       
   653 DO_THROW(ClassNotFoundException)
   615 
   654 
   616 #undef DO_THROW
   655 #undef DO_THROW
   617 
   656 
   618 void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) {
   657 void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) {
   619   const int max_msg_size = 1024;
   658   const int max_msg_size = 1024;
   886     jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());
   925     jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());
   887     if (jni()->ExceptionCheck()) {
   926     if (jni()->ExceptionCheck()) {
   888       return JVMCIObject();
   927       return JVMCIObject();
   889     }
   928     }
   890     jobject file_name = NULL;
   929     jobject file_name = NULL;
   891     if (file_name != NULL) {
   930     if (file_name_sym != NULL) {
   892       file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
   931       file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
   893       if (jni()->ExceptionCheck()) {
   932       if (jni()->ExceptionCheck()) {
   894         return JVMCIObject();
   933         return JVMCIObject();
   895       }
   934       }
   896     }
   935     }
  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());