< prev index next >

src/hotspot/share/runtime/jniHandles.cpp

Print this page
@@ -21,19 +21,21 @@
   * questions.
   *
   */
  
  #include "precompiled.hpp"
+ #include "classfile/vmSymbols.hpp"
  #include "gc/shared/collectedHeap.hpp"
  #include "gc/shared/oopStorage.inline.hpp"
  #include "gc/shared/oopStorageSet.hpp"
  #include "logging/log.hpp"
  #include "memory/iterator.hpp"
  #include "memory/universe.hpp"
  #include "oops/access.inline.hpp"
  #include "oops/oop.inline.hpp"
  #include "runtime/handles.inline.hpp"
+ #include "runtime/javaCalls.hpp"
  #include "runtime/jniHandles.inline.hpp"
  #include "runtime/mutexLocker.hpp"
  #include "runtime/thread.inline.hpp"
  #include "utilities/align.hpp"
  #include "utilities/debug.hpp"

@@ -303,10 +305,47 @@
    Thread* thread = Thread::current();
    return (thread->is_Java_thread() &&
            JavaThread::cast(thread)->thread_state() == _thread_in_native);
  }
  
+ bool JNIHandles::is_same_object(jobject handle1, jobject handle2) {
+   oop obj1 = resolve_no_keepalive(handle1);
+   oop obj2 = resolve_no_keepalive(handle2);
+ 
+   bool ret = obj1 == obj2;
+ 
+   if (EnableValhalla) {
+     if (!ret && obj1 != NULL && obj2 != NULL && obj1->klass() == obj2->klass() && obj1->klass()->is_inline_klass()) {
+       // The two references are different, they are not null and they are both inline types,
+       // a full substitutability test is required, calling PrimitiveObjectMethods.isSubstitutable()
+       // (similarly to InterpreterRuntime::is_substitutable)
+       JavaThread* THREAD = JavaThread::current();
+       Handle ha(THREAD, obj1);
+       Handle hb(THREAD, obj2);
+       JavaValue result(T_BOOLEAN);
+       JavaCallArguments args;
+       args.push_oop(ha);
+       args.push_oop(hb);
+       methodHandle method(THREAD, Universe::is_substitutable_method());
+       JavaCalls::call(&result, method, &args, THREAD);
+       if (HAS_PENDING_EXCEPTION) {
+         // Something really bad happened because isSubstitutable() should not throw exceptions
+         // If it is an error, just let it propagate
+         // If it is an exception, wrap it into an InternalError
+         if (!PENDING_EXCEPTION->is_a(vmClasses::Error_klass())) {
+           Handle e(THREAD, PENDING_EXCEPTION);
+           CLEAR_PENDING_EXCEPTION;
+           THROW_MSG_CAUSE_(vmSymbols::java_lang_InternalError(), "Internal error in substitutability test", e, false);
+         }
+       }
+       ret = result.get_jboolean();
+     }
+   }
+ 
+   return ret;
+ }
+ 
  
  int             JNIHandleBlock::_blocks_allocated     = 0;
  JNIHandleBlock* JNIHandleBlock::_block_free_list      = NULL;
  #ifndef PRODUCT
  JNIHandleBlock* JNIHandleBlock::_block_list           = NULL;
< prev index next >