8169467: GetLocalInstance returns JVMTI_ERROR_TYPE_MISMATCH (rather than JVMTI_ERROR_INVALID_SLOT) on static method
authorsspitsyn
Fri, 22 Nov 2019 10:07:21 +0000
changeset 59223 f16e4154dd7b
parent 59222 f4f60bb75ee4
child 59224 55fdee124e89
8169467: GetLocalInstance returns JVMTI_ERROR_TYPE_MISMATCH (rather than JVMTI_ERROR_INVALID_SLOT) on static method Summary: Add necessary check to GetLocalInstance implementation Reviewed-by: amenkov, cjplummer
src/hotspot/share/prims/jvmtiImpl.cpp
test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetLocalVariable/getlocal003.java
test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetLocalVariable/getlocal003/getlocal003.cpp
--- a/src/hotspot/share/prims/jvmtiImpl.cpp	Fri Nov 22 10:03:38 2019 +0100
+++ b/src/hotspot/share/prims/jvmtiImpl.cpp	Fri Nov 22 10:07:21 2019 +0000
@@ -724,13 +724,17 @@
   NULL_CHECK(_jvf, false);
 
   Method* method_oop = _jvf->method();
-  if (method_oop->is_native()) {
-    if (getting_receiver() && !method_oop->is_static()) {
-      return true;
-    } else {
-      _result = JVMTI_ERROR_OPAQUE_FRAME;
+  if (getting_receiver()) {
+    if (method_oop->is_static()) {
+      _result = JVMTI_ERROR_INVALID_SLOT;
       return false;
     }
+    return true;
+  }
+
+  if (method_oop->is_native()) {
+    _result = JVMTI_ERROR_OPAQUE_FRAME;
+    return false;
   }
 
   if (!check_slot_type_no_lvt(_jvf)) {
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetLocalVariable/getlocal003.java	Fri Nov 22 10:03:38 2019 +0100
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetLocalVariable/getlocal003.java	Fri Nov 22 10:07:21 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -203,9 +203,11 @@
     public double meth01() {
         float f = 6.0f;
         double d = 7.0;
+        instMeth();
         return d + f;
     }
 
+    native void instMeth();
     native static void getMeth();
     native static void checkLoc(Thread thr);
     native static int getRes();
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetLocalVariable/getlocal003/getlocal003.cpp	Fri Nov 22 10:03:38 2019 +0100
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetLocalVariable/getlocal003/getlocal003.cpp	Fri Nov 22 10:07:21 2019 +0000
@@ -231,8 +231,44 @@
 }
 
 JNIEXPORT void JNICALL
+Java_nsk_jvmti_unit_GetLocalVariable_getlocal003_instMeth(JNIEnv *env, jobject inst) {
+    jvmtiError err;
+    jobject obj = NULL;
+
+    printf("\n Native instMeth: started\n");
+
+    // Test GetLocalInstance with native instance method instMeth() frame
+    err = jvmti->GetLocalInstance(NULL, 0, &obj);
+    printf(" Native instMeth: GetLocalInstance: %s (%d)\n", TranslateError(err), err);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("FAIL: GetLocalInstance failed to get instance for native instance method frame\n");
+        result = STATUS_FAILED;
+    }
+    if (env->IsSameObject(inst, obj) == JNI_FALSE) {
+        printf("FAIL: GetLocalInstance returned unexpected instance for native instance method frame\n");
+        result = STATUS_FAILED;
+    }
+
+    // Test GetLocalInstance with java instance method meth01() frame
+    err = jvmti->GetLocalInstance(NULL, 1, &obj);
+    printf(" Native instMeth: GetLocalInstance: %s (%d)\n", TranslateError(err), err);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("FAIL: GetLocalInstance failed to get instance for java instance method frame\n");
+        result = STATUS_FAILED;
+    }
+    if (env->IsSameObject(inst, obj) == JNI_FALSE) {
+        printf("FAIL: GetLocalInstance returned unexpected instance for java instance method frame\n");
+        result = STATUS_FAILED;
+    }
+    printf(" Native instMeth: finished\n\n");
+}
+
+JNIEXPORT void JNICALL
 Java_nsk_jvmti_unit_GetLocalVariable_getlocal003_getMeth(JNIEnv *env, jclass cls) {
     jvmtiError err;
+    jobject obj = NULL;
+
+    printf("\n Native getMeth: started\n");
 
     if (jvmti == NULL) {
         printf("JVMTI client was not properly loaded!\n");
@@ -261,6 +297,24 @@
                TranslateError(err), err);
         result = STATUS_FAILED;
     }
+
+    // Test GetLocalInstance with native static method getMeth() frame
+    err = jvmti->GetLocalInstance(NULL, 0, &obj);
+    printf(" Native getMeth: GetLocalInstance: %s (%d)\n", TranslateError(err), err);
+    if (err != JVMTI_ERROR_INVALID_SLOT) {
+        printf("FAIL: GetLocalInstance failed to return JVMTI_ERROR_INVALID_SLOT for native static method frame\n");
+        result = STATUS_FAILED;
+    }
+
+    // Test GetLocalInstance with java static method run() frame
+    err = jvmti->GetLocalInstance(NULL, 1, &obj);
+    printf(" Native getMeth: GetLocalInstance: %s (%d)\n", TranslateError(err), err);
+    if (err != JVMTI_ERROR_INVALID_SLOT) {
+        printf("FAIL: GetLocalInstance failed to return JVMTI_ERROR_INVALID_SLOT for java static method frame\n");
+        result = STATUS_FAILED;
+    }
+
+    printf(" Native getMeth: finished\n\n");
     fflush(stdout);
 }