< prev index next >

src/hotspot/share/prims/jvm.cpp

Print this page
@@ -1361,10 +1361,60 @@
    oop result = java_security_AccessControlContext::create(h_context, is_privileged, privileged_context, CHECK_NULL);
  
    return JNIHandles::make_local(THREAD, result);
  JVM_END
  
+ class ScopedValueBindingsResolver {
+ public:
+   InstanceKlass* Carrier_klass;
+   ScopedValueBindingsResolver(JavaThread* THREAD) {
+     Klass *k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_incubator_concurrent_ScopedValue_Carrier(), true, THREAD);
+     Carrier_klass = InstanceKlass::cast(k);
+   }
+ };
+ 
+ JVM_ENTRY(jobject, JVM_FindScopedValueBindings(JNIEnv *env, jclass cls))
+   ResourceMark rm(THREAD);
+   GrowableArray<Handle>* local_array = new GrowableArray<Handle>(12);
+   JvmtiVMObjectAllocEventCollector oam;
+ 
+   bool found = false;
+ 
+   static ScopedValueBindingsResolver resolver(THREAD);
+ 
+   // Iterate through Java frames
+   vframeStream vfst(thread);
+   for(; !vfst.at_end(); vfst.next()) {
+     int loc = 0;
+     // get method of frame
+     Method* method = vfst.method();
+ 
+     Symbol *name = method->name();
+ 
+     InstanceKlass* holder = method->method_holder();
+     if (name == vmSymbols::runWith_method_name()) {
+       if ((holder == resolver.Carrier_klass
+            || holder == vmClasses::VirtualThread_klass()
+            || holder == vmClasses::Thread_klass())) {
+         loc = 1;
+       }
+     }
+ 
+     if (loc != 0) {
+       javaVFrame *frame = vfst.asJavaVFrame();
+       StackValueCollection* locals = frame->locals();
+       StackValue* head_sv = locals->at(loc); // jdk/incubator/concurrent/ScopedValue$Snapshot
+       Handle result = head_sv->get_obj();
+       assert(!head_sv->obj_is_scalar_replaced(), "found scalar-replaced object");
+       if (result() != NULL) {
+         return JNIHandles::make_local(THREAD, result());
+       }
+     }
+   }
+ 
+   return NULL;
+ JVM_END
  
  JVM_ENTRY(jboolean, JVM_IsArrayClass(JNIEnv *env, jclass cls))
    Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
    return (k != NULL) && k->is_array_klass() ? true : false;
  JVM_END

@@ -3112,26 +3162,19 @@
      const char *thread_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
      os::set_native_thread_name(thread_name);
    }
  JVM_END
  
- JVM_ENTRY(jobject, JVM_ExtentLocalCache(JNIEnv* env, jclass threadClass))
-   oop theCache = thread->extentLocalCache();
-   if (theCache) {
-     arrayOop objs = arrayOop(theCache);
-     assert(objs->length() == ExtentLocalCacheSize * 2, "wrong length");
-   }
+ JVM_ENTRY(jobject, JVM_ScopedValueCache(JNIEnv* env, jclass threadClass))
+   oop theCache = thread->scopedValueCache();
    return JNIHandles::make_local(THREAD, theCache);
  JVM_END
  
- JVM_ENTRY(void, JVM_SetExtentLocalCache(JNIEnv* env, jclass threadClass,
+ JVM_ENTRY(void, JVM_SetScopedValueCache(JNIEnv* env, jclass threadClass,
                                         jobject theCache))
    arrayOop objs = arrayOop(JNIHandles::resolve(theCache));
-   if (objs != NULL) {
-     assert(objs->length() == ExtentLocalCacheSize * 2, "wrong length");
-   }
-   thread->set_extentLocalCache(objs);
+   thread->set_scopedValueCache(objs);
  JVM_END
  
  // java.lang.SecurityManager ///////////////////////////////////////////////////////////////////////
  
  JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env))

@@ -4017,5 +4060,14 @@
    Klass* c = java_lang_Class::as_Klass(mirror);
    assert(c->is_instance_klass(), "must be");
    InstanceKlass* ik = InstanceKlass::cast(c);
    return (ik->minor_version() << 16) | ik->major_version();
  JVM_END
+ 
+ /*
+  * Ensure that code doing a stackwalk and using javaVFrame::locals() to
+  * get the value will see a materialized value and not a scalar-replaced
+  * null value.
+  */
+ JVM_ENTRY(void, JVM_EnsureMaterializedForStackWalk_func(JNIEnv* env, jobject vthread, jobject value))
+   JVM_EnsureMaterializedForStackWalk(env, value);
+ JVM_END
< prev index next >