< prev index next >

src/hotspot/share/prims/jvmtiEnv.cpp

Print this page
@@ -449,10 +449,22 @@
        return JVMTI_ERROR_INVALID_CLASS;
      }
  
      InstanceKlass* ik = InstanceKlass::cast(klass);
      if (ik->get_cached_class_file_bytes() == nullptr) {
+       // Link the class to avoid races with the rewriter. This will call the verifier also
+       // on the class. Linking is also done in VM_RedefineClasses below, but we need
+       // to keep that for other VM_RedefineClasses callers.
+       JavaThread* THREAD = current_thread;
+       ik->link_class(THREAD);
+       if (HAS_PENDING_EXCEPTION) {
+         // Retransform/JVMTI swallows error messages. Using this class will rerun the verifier in a context
+         // that propagates the VerifyError, if thrown.
+         CLEAR_PENDING_EXCEPTION;
+         return JVMTI_ERROR_INVALID_CLASS;
+       }
+ 
        // Not cached, we need to reconstitute the class file from the
        // VM representation. We don't attach the reconstituted class
        // bytes to the InstanceKlass here because they have not been
        // validated and we're not at a safepoint.
        JvmtiClassFileReconstituter reconstituter(ik);

@@ -3426,19 +3438,27 @@
  // bytecodes_ptr - pre-checked for null
  jvmtiError
  JvmtiEnv::GetBytecodes(Method* method, jint* bytecode_count_ptr, unsigned char** bytecodes_ptr) {
    NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID);
  
-   methodHandle mh(Thread::current(), method);
+   JavaThread* current_thread = JavaThread::current();
+   methodHandle mh(current_thread, method);
    jint size = (jint)mh->code_size();
    jvmtiError err = allocate(size, bytecodes_ptr);
    if (err != JVMTI_ERROR_NONE) {
      return err;
    }
  
    (*bytecode_count_ptr) = size;
    // get byte codes
+   // Make sure the class is verified and rewritten first.
+   JavaThread* THREAD = current_thread;
+   mh->method_holder()->link_class(THREAD);
+   if (HAS_PENDING_EXCEPTION) {
+     CLEAR_PENDING_EXCEPTION;
+     return JVMTI_ERROR_INVALID_CLASS;
+   }
    JvmtiClassFileReconstituter::copy_bytecodes(mh, *bytecodes_ptr);
  
    return JVMTI_ERROR_NONE;
  } /* end GetBytecodes */
  
< prev index next >