Skip to content

Commit e5b65c4

Browse files
author
David Holmes
committed
8290482: Update JNI Specification of DestroyJavaVM for better alignment with JLS, JVMS, and Java SE API Specifications
Reviewed-by: rehn, coleenp
1 parent f8d9fa8 commit e5b65c4

File tree

6 files changed

+111
-4
lines changed

6 files changed

+111
-4
lines changed

src/hotspot/share/prims/jni.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
#include "jvmci/jvmciCompiler.hpp"
102102
#endif
103103

104-
static jint CurrentVersion = JNI_VERSION_19;
104+
static jint CurrentVersion = JNI_VERSION_20;
105105

106106
#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING)
107107
extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* );
@@ -3754,9 +3754,16 @@ static jint JNICALL jni_DestroyJavaVM_inner(JavaVM *vm) {
37543754
return res;
37553755
}
37563756

3757-
// Since this is not a JVM_ENTRY we have to set the thread state manually before entering.
37583757
JavaThread* thread = JavaThread::current();
37593758

3759+
// Make sure we are actually in a newly attached thread, with no
3760+
// existing Java frame.
3761+
if (thread->has_last_Java_frame()) {
3762+
return JNI_ERR;
3763+
}
3764+
3765+
// Since this is not a JVM_ENTRY we have to set the thread state manually before entering.
3766+
37603767
// We are going to VM, change W^X state to the expected one.
37613768
MACOS_AARCH64_ONLY(WXMode oldmode = thread->enable_wx(WXWrite));
37623769

src/hotspot/share/runtime/threads.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,7 @@ jboolean Threads::is_supported_jni_version(jint version) {
11661166
if (version == JNI_VERSION_9) return JNI_TRUE;
11671167
if (version == JNI_VERSION_10) return JNI_TRUE;
11681168
if (version == JNI_VERSION_19) return JNI_TRUE;
1169+
if (version == JNI_VERSION_20) return JNI_TRUE;
11691170
return JNI_FALSE;
11701171
}
11711172

src/java.base/share/native/include/jni.h

+1
Original file line numberDiff line numberDiff line change
@@ -1991,6 +1991,7 @@ JNI_OnUnload(JavaVM *vm, void *reserved);
19911991
#define JNI_VERSION_9 0x00090000
19921992
#define JNI_VERSION_10 0x000a0000
19931993
#define JNI_VERSION_19 0x00130000
1994+
#define JNI_VERSION_20 0x00140000
19941995

19951996
#ifdef __cplusplus
19961997
} /* extern "C" */

test/hotspot/jtreg/native_sanity/JniVersion.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@
2727
*/
2828
public class JniVersion {
2929

30-
public static final int JNI_VERSION_19 = 0x00130000;
30+
public static final int JNI_VERSION_20 = 0x00140000;
3131

3232
public static void main(String... args) throws Exception {
3333
System.loadLibrary("JniVersion");
3434
int res = getJniVersion();
35-
if (res != JNI_VERSION_19) {
35+
if (res != JNI_VERSION_20) {
3636
throw new Exception("Unexpected value returned from getJniVersion(): 0x" + Integer.toHexString(res));
3737
}
3838
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8290482
27+
* @summary Tests that DestroyJavaVM from an active thread fails.
28+
* @run main/native TestActiveDestroy
29+
*/
30+
31+
public class TestActiveDestroy {
32+
33+
static native boolean tryDestroyJavaVM();
34+
35+
static {
36+
System.loadLibrary("activeDestroy");
37+
}
38+
39+
public static void main(String[] args) throws Throwable {
40+
if (tryDestroyJavaVM()) {
41+
throw new Error("DestroyJavaVM succeeded when it should not!");
42+
}
43+
}
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
#include <stdio.h>
25+
#include <stdlib.h>
26+
27+
#include "jni.h"
28+
29+
static const char* jni_error_code(int ret) {
30+
switch(ret) {
31+
case JNI_OK: return "JNI_OK";
32+
case JNI_ERR: return "JNI_ERR";
33+
case JNI_EDETACHED: return "JNI_EDETACHED";
34+
case JNI_EVERSION: return "JNI_EVERSION";
35+
case JNI_ENOMEM: return "JNI_ENOMEM";
36+
case JNI_EEXIST: return "JNI_EEXIST";
37+
case JNI_EINVAL: return "JNI_EINVAL";
38+
default: return "Invalid JNI error code";
39+
}
40+
}
41+
42+
JNIEXPORT jboolean JNICALL
43+
Java_TestActiveDestroy_tryDestroyJavaVM(JNIEnv *env, jclass cls) {
44+
JavaVM* jvm;
45+
int res = (*env)->GetJavaVM(env, &jvm);
46+
if (res != JNI_OK) {
47+
fprintf(stderr, "GetJavaVM failed: %s\n", jni_error_code(res));
48+
exit(1);
49+
}
50+
printf("Calling DestroyJavaVM from active thread\n");
51+
res = (*jvm)->DestroyJavaVM(jvm);
52+
printf("DestroyJavaVM returned: %s\n", jni_error_code(res));
53+
return res == JNI_OK;
54+
}

0 commit comments

Comments
 (0)