8297106: Remove the -Xcheck:jni local reference capacity checking
Reviewed-by: dcubed, kevinw
This commit is contained in:
parent
05128c2110
commit
692bedbc1d
src
test
hotspot/jtreg/runtime/jni/checked
jdk
@ -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 */ }
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user