8297106: Remove the -Xcheck:jni local reference capacity checking

Reviewed-by: dcubed, kevinw
This commit is contained in:
David Holmes 2022-11-29 02:03:49 +00:00
parent 05128c2110
commit 692bedbc1d
8 changed files with 1 additions and 289 deletions
src
hotspot/share
java.base/share/man
test
hotspot/jtreg/runtime/jni/checked
jdk
ProblemList.txt
com/sun/management/DiagnosticCommandMBean

@ -46,9 +46,6 @@
#include "utilities/formatBuffer.hpp"
#include "utilities/utf8.hpp"
// Complain every extra number of unplanned local refs
#define CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD 32
// Heap objects are allowed to be directly referenced only in VM code,
// not in native code.
@ -202,17 +199,6 @@ check_pending_exception(JavaThread* thr) {
}
}
/**
* Add to the planned number of handles. I.e. plus current live & warning threshold
*/
static inline void
add_planned_handle_capacity(JNIHandleBlock* handles, size_t capacity) {
handles->set_planned_capacity(capacity +
handles->get_number_of_live_handles() +
CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
}
static inline void
functionEnterCritical(JavaThread* thr)
{
@ -244,18 +230,7 @@ functionEnterExceptionAllowed(JavaThread* thr)
static inline void
functionExit(JavaThread* thr)
{
JNIHandleBlock* handles = thr->active_handles();
size_t planned_capacity = handles->get_planned_capacity();
size_t live_handles = handles->get_number_of_live_handles();
if (live_handles > planned_capacity) {
IN_VM(
tty->print_cr("WARNING: JNI local refs: " SIZE_FORMAT ", exceeds capacity: " SIZE_FORMAT,
live_handles, planned_capacity);
thr->print_stack();
)
// Complain just the once, reset to current + warn threshold
add_planned_handle_capacity(handles, 0);
}
// No checks at this time
}
static inline void
@ -746,9 +721,6 @@ JNI_ENTRY_CHECKED(jint,
if (capacity < 0)
NativeReportJNIFatalError(thr, "negative capacity");
jint result = UNCHECKED()->PushLocalFrame(env, capacity);
if (result == JNI_OK) {
add_planned_handle_capacity(thr->active_handles(), capacity);
}
functionExit(thr);
return result;
JNI_END
@ -850,12 +822,6 @@ JNI_ENTRY_CHECKED(jint,
NativeReportJNIFatalError(thr, "negative capacity");
}
jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity);
if (result == JNI_OK) {
// increase local ref capacity if needed
if ((size_t)capacity > thr->active_handles()->get_planned_capacity()) {
add_planned_handle_capacity(thr->active_handles(), capacity);
}
}
functionExit(thr);
return result;
JNI_END

@ -356,7 +356,6 @@ JNIHandleBlock* JNIHandleBlock::allocate_block(JavaThread* thread, AllocFailType
block->_top = 0;
block->_next = NULL;
block->_pop_frame_link = NULL;
block->_planned_capacity = block_size_in_oops;
// _last, _free_list & _allocate_before_rebuild initialized in allocate_handle
debug_only(block->_last = NULL);
debug_only(block->_free_list = NULL);
@ -550,22 +549,6 @@ size_t JNIHandleBlock::length() const {
return result;
}
class CountJNIHandleClosure: public OopClosure {
private:
int _count;
public:
CountJNIHandleClosure(): _count(0) {}
virtual void do_oop(oop* ooph) { _count++; }
virtual void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
int count() { return _count; }
};
const size_t JNIHandleBlock::get_number_of_live_handles() {
CountJNIHandleClosure counter;
oops_do(&counter);
return counter.count();
}
// This method is not thread-safe, i.e., must be called while holding a lock on the
// structure.
size_t JNIHandleBlock::memory_usage() const {

@ -147,8 +147,6 @@ class JNIHandleBlock : public CHeapObj<mtInternal> {
JNIHandleBlock* _pop_frame_link; // Block to restore on PopLocalFrame call
uintptr_t* _free_list; // Handle free list
// Check JNI, "planned capacity" for current frame (or push/ensure)
size_t _planned_capacity;
static int _blocks_allocated; // For debugging/printing
// Fill block with bad_handle values
@ -179,11 +177,6 @@ class JNIHandleBlock : public CHeapObj<mtInternal> {
// Traversal of handles
void oops_do(OopClosure* f);
// Checked JNI support
void set_planned_capacity(size_t planned_capacity) { _planned_capacity = planned_capacity; }
const size_t get_planned_capacity() { return _planned_capacity; }
const size_t get_number_of_live_handles();
// Debugging
bool chain_contains(jobject handle) const; // Does this block or following blocks contain handle
bool contains(jobject handle) const; // Does this block contain handle

@ -816,10 +816,6 @@ A JNI call was made without checking for a pending exception from a
previous JNI call, and the current call is not safe when an exception
may be pending.
.IP \[bu] 2
The number of JNI local references existing when a JNI function
terminates exceeds the number guaranteed to be available.
See the \f[V]EnsureLocalcapacity\f[R] function.
.IP \[bu] 2
A class descriptor is in decorated format (\f[V]Lname;\f[R]) when it
should not be.
.IP \[bu] 2

@ -1,91 +0,0 @@
/*
* Copyright (c) 2017, 2021, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8193222
* @summary Check EnsureLocalCapacity doesn't shrink unexpectedly
* @library /test/lib
* @run main/native TestCheckedEnsureLocalCapacity launch
*/
import jdk.test.lib.Utils;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
public class TestCheckedEnsureLocalCapacity {
static {
System.loadLibrary("TestCheckedEnsureLocalCapacity");
}
// Calls EnsureLocalCapacity(capacity) and then creates "copies" number
// of LocalRefs to "o".
// If capacity > copies no warning should ensue (with the bug fixed).
// If copies > capacity + warning-threshold then we still get a warning.
private static native void ensureCapacity(Object o, int capacity, int copies);
private static int[][] testArgs = {
{ 60, 45 }, // good: capacity > copies
{ 1, 45 } // bad: copies >> capacity
};
// Patterns EXCEED_WARNING and WARNING are not anchored to the beginning
// of lines to allow matching interleaved output.
private static final String EXCEED_WARNING =
"WARNING: JNI local refs: \\d++, exceeds capacity:";
private static final String WARNING = "WARNING:";
public static void main(String[] args) throws Throwable {
if (args.length == 2) {
ensureCapacity(new Object(),
Integer.parseInt(args[0]),
Integer.parseInt(args[1]));
return;
}
// No warning
ProcessTools.executeTestJvm("-Xcheck:jni",
"-Djava.library.path=" + Utils.TEST_NATIVE_PATH,
"TestCheckedEnsureLocalCapacity",
Integer.toString(testArgs[0][0]),
Integer.toString(testArgs[0][1])).
shouldHaveExitValue(0).
// check no capacity warning
stdoutShouldNotMatch(EXCEED_WARNING).
// check no other warning
stdoutShouldNotMatch(WARNING).
reportDiagnosticSummary();
// Warning
ProcessTools.executeTestJvm("-Xcheck:jni",
"-Djava.library.path=" + Utils.TEST_NATIVE_PATH,
"TestCheckedEnsureLocalCapacity",
Integer.toString(testArgs[1][0]),
Integer.toString(testArgs[1][1])).
shouldHaveExitValue(0).
// check for capacity warning
stdoutShouldMatch(EXCEED_WARNING).
reportDiagnosticSummary();
}
}

@ -1,49 +0,0 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <jni.h>
#include <stdio.h>
void reduceLocalCapacity(JNIEnv* env) {
puts("reduceLocalCapacity: setting to 1");
(*env)->EnsureLocalCapacity(env,1);
}
JNIEXPORT void JNICALL
Java_TestCheckedEnsureLocalCapacity_ensureCapacity(JNIEnv *env,
jobject unused,
jobject target,
jint capacity,
jint copies) {
int i;
printf("ensureCapacity: setting to %d\n", capacity);
(*env)->EnsureLocalCapacity(env, capacity); // set high
reduceLocalCapacity(env); // sets low
printf("ensureCapacity: creating %d LocalRefs\n", copies);
for (i = 0; i < copies; i++) {
target = (*env)->NewLocalRef(env, target);
}
puts("ensureCapacity: done");
}

@ -690,7 +690,6 @@ sanity/client/SwingSet/src/ButtonDemoScreenshotTest.java 8265770 macosx-all
############################################################################
# core_svc
tools/launcher/TestXcheckJNIWarnings.java#jdwp-agent 8296936 generic-all
############################################################################

@ -1,85 +0,0 @@
/*
* Copyright (c) 2021, Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8258836
* @summary JNI local refs exceed capacity getDiagnosticCommandInfo
* @library /test/lib
* @run main/othervm DcmdMBeanTestCheckJni
*/
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.remote.JMXConnectorServer;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
public class DcmdMBeanTestCheckJni {
public static void main(String[] args) throws Exception {
OutputAnalyzer out = ProcessTools.executeTestJvm(
"-Xcheck:jni",
DcmdMBeanRunner.class.getName());
out.shouldNotMatch("WARNING: JNI local refs: \\d+, exceeds capacity: \\d+\\s+" +
"at com.sun.management.internal.DiagnosticCommandImpl.getDiagnosticCommandInfo")
.shouldContain("DcmdMBeanRunner COMPLETE")
.shouldHaveExitValue(0);
}
}
class DcmdMBeanRunner {
private static final String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
"com.sun.management:type=DiagnosticCommand";
public static void main(String[] args) throws Exception {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
JMXServiceURL url = new JMXServiceURL("rmi", null, 0);
JMXConnectorServer cs = null;
JMXConnector cc = null;
try {
cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
cs.start();
JMXServiceURL addr = cs.getAddress();
cc = JMXConnectorFactory.connect(addr);
MBeanServerConnection mbsc = cc.getMBeanServerConnection();
ObjectName name = new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME);
System.out.println("DiagnosticCommand MBean: " + name);
System.out.println("DcmdMBeanRunner COMPLETE");
} finally {
try {
cc.close();
cs.stop();
} catch (Exception e) { /* ignored */ }
}
}
}