提交 951e3d7c 编写于 作者: C coleenp

Merge

...@@ -45,11 +45,11 @@ MemPointer* SequencedRecordIterator::next_record() { ...@@ -45,11 +45,11 @@ MemPointer* SequencedRecordIterator::next_record() {
} }
debug_only(volatile jint MemRecorder::_instance_count = 0;) volatile jint MemRecorder::_instance_count = 0;
MemRecorder::MemRecorder() { MemRecorder::MemRecorder() {
assert(MemTracker::is_on(), "Native memory tracking is off"); assert(MemTracker::is_on(), "Native memory tracking is off");
debug_only(Atomic::inc(&_instance_count);) Atomic::inc(&_instance_count);
debug_only(set_generation();) debug_only(set_generation();)
if (MemTracker::track_callsite()) { if (MemTracker::track_callsite()) {
...@@ -83,9 +83,7 @@ MemRecorder::~MemRecorder() { ...@@ -83,9 +83,7 @@ MemRecorder::~MemRecorder() {
delete _next; delete _next;
} }
#ifdef ASSERT
Atomic::dec(&_instance_count); Atomic::dec(&_instance_count);
#endif
} }
// Sorting order: // Sorting order:
......
...@@ -249,9 +249,9 @@ class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> { ...@@ -249,9 +249,9 @@ class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
SequencedRecordIterator pointer_itr(); SequencedRecordIterator pointer_itr();
public: protected:
// number of MemRecorder instance // number of MemRecorder instance
debug_only(static volatile jint _instance_count;) static volatile jint _instance_count;
private: private:
// sorting function, sort records into following order // sorting function, sort records into following order
......
...@@ -173,7 +173,7 @@ MemSnapshot::MemSnapshot() { ...@@ -173,7 +173,7 @@ MemSnapshot::MemSnapshot() {
_staging_area = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>(); _staging_area = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>();
} }
_lock = new (std::nothrow) Mutex(Monitor::native, "memSnapshotLock"); _lock = new (std::nothrow) Mutex(Monitor::max_nonleaf - 1, "memSnapshotLock");
NOT_PRODUCT(_untracked_count = 0;) NOT_PRODUCT(_untracked_count = 0;)
} }
......
...@@ -67,7 +67,7 @@ class MemTrackWorker : public NamedThread { ...@@ -67,7 +67,7 @@ class MemTrackWorker : public NamedThread {
NOT_PRODUCT(int _last_gen_in_use;) NOT_PRODUCT(int _last_gen_in_use;)
inline int generations_in_use() const { inline int generations_in_use() const {
return (_tail <= _head ? (_head - _tail + 1) : (MAX_GENERATIONS - (_tail - _head) + 1)); return (_tail >= _head ? (_tail - _head + 1) : (MAX_GENERATIONS - (_head - _tail) + 1));
} }
}; };
......
...@@ -54,7 +54,7 @@ void SyncThreadRecorderClosure::do_thread(Thread* thread) { ...@@ -54,7 +54,7 @@ void SyncThreadRecorderClosure::do_thread(Thread* thread) {
MemRecorder* MemTracker::_global_recorder = NULL; MemRecorder* MemTracker::_global_recorder = NULL;
MemSnapshot* MemTracker::_snapshot = NULL; MemSnapshot* MemTracker::_snapshot = NULL;
MemBaseline MemTracker::_baseline; MemBaseline MemTracker::_baseline;
Mutex MemTracker::_query_lock(Monitor::native, "NMT_queryLock"); Mutex* MemTracker::_query_lock = NULL;
volatile MemRecorder* MemTracker::_merge_pending_queue = NULL; volatile MemRecorder* MemTracker::_merge_pending_queue = NULL;
volatile MemRecorder* MemTracker::_pooled_recorders = NULL; volatile MemRecorder* MemTracker::_pooled_recorders = NULL;
MemTrackWorker* MemTracker::_worker_thread = NULL; MemTrackWorker* MemTracker::_worker_thread = NULL;
...@@ -89,6 +89,12 @@ void MemTracker::bootstrap_single_thread() { ...@@ -89,6 +89,12 @@ void MemTracker::bootstrap_single_thread() {
return; return;
} }
_query_lock = new (std::nothrow) Mutex(Monitor::max_nonleaf, "NMT_queryLock");
if (_query_lock == NULL) {
shutdown(NMT_out_of_memory);
return;
}
debug_only(_main_thread_tid = os::current_thread_id();) debug_only(_main_thread_tid = os::current_thread_id();)
_state = NMT_bootstrapping_single_thread; _state = NMT_bootstrapping_single_thread;
NMT_track_callsite = (_tracking_level == NMT_detail && can_walk_stack()); NMT_track_callsite = (_tracking_level == NMT_detail && can_walk_stack());
...@@ -164,7 +170,7 @@ void MemTracker::final_shutdown() { ...@@ -164,7 +170,7 @@ void MemTracker::final_shutdown() {
{ {
// shared baseline and snapshot are the only objects needed to // shared baseline and snapshot are the only objects needed to
// create query results // create query results
MutexLockerEx locker(&_query_lock, true); MutexLockerEx locker(_query_lock, true);
// cleanup baseline data and snapshot // cleanup baseline data and snapshot
_baseline.clear(); _baseline.clear();
delete _snapshot; delete _snapshot;
...@@ -351,21 +357,17 @@ void MemTracker::create_memory_record(address addr, MEMFLAGS flags, ...@@ -351,21 +357,17 @@ void MemTracker::create_memory_record(address addr, MEMFLAGS flags,
} }
if (thread != NULL) { if (thread != NULL) {
#ifdef ASSERT
// cause assertion on stack base. This ensures that threads call
// Thread::record_stack_base_and_size() method, which will create
// thread native stack records.
thread->stack_base();
#endif
// for a JavaThread, if it is running in native state, we need to transition it to
// VM state, so it can stop at safepoint. JavaThread running in VM state does not
// need lock to write records.
if (thread->is_Java_thread() && ((JavaThread*)thread)->is_safepoint_visible()) { if (thread->is_Java_thread() && ((JavaThread*)thread)->is_safepoint_visible()) {
if (((JavaThread*)thread)->thread_state() == _thread_in_native) { JavaThread* java_thread = static_cast<JavaThread*>(thread);
ThreadInVMfromNative trans((JavaThread*)thread); JavaThreadState state = java_thread->thread_state();
create_record_in_recorder(addr, flags, size, pc, thread); if (SafepointSynchronize::safepoint_safe(java_thread, state)) {
// JavaThreads that are safepoint safe, can run through safepoint,
// so ThreadCritical is needed to ensure no threads at safepoint create
// new records while the records are being gathered and the sequence number is changing
ThreadCritical tc;
create_record_in_recorder(addr, flags, size, pc, java_thread);
} else { } else {
create_record_in_recorder(addr, flags, size, pc, thread); create_record_in_recorder(addr, flags, size, pc, java_thread);
} }
} else { } else {
// other threads, such as worker and watcher threads, etc. need to // other threads, such as worker and watcher threads, etc. need to
...@@ -390,10 +392,9 @@ void MemTracker::create_memory_record(address addr, MEMFLAGS flags, ...@@ -390,10 +392,9 @@ void MemTracker::create_memory_record(address addr, MEMFLAGS flags,
// write a record to proper recorder. No lock can be taken from this method // write a record to proper recorder. No lock can be taken from this method
// down. // down.
void MemTracker::create_record_in_recorder(address addr, MEMFLAGS flags, void MemTracker::create_record_in_recorder(address addr, MEMFLAGS flags,
size_t size, address pc, Thread* thread) { size_t size, address pc, JavaThread* thread) {
assert(thread == NULL || thread->is_Java_thread(), "wrong thread");
MemRecorder* rc = get_thread_recorder((JavaThread*)thread); MemRecorder* rc = get_thread_recorder(thread);
if (rc != NULL) { if (rc != NULL) {
rc->record(addr, flags, size, pc); rc->record(addr, flags, size, pc);
} }
...@@ -460,6 +461,11 @@ void MemTracker::sync() { ...@@ -460,6 +461,11 @@ void MemTracker::sync() {
} }
} }
_sync_point_skip_count = 0; _sync_point_skip_count = 0;
{
// This method is running at safepoint, with ThreadCritical lock,
// it should guarantee that NMT is fully sync-ed.
ThreadCritical tc;
// walk all JavaThreads to collect recorders // walk all JavaThreads to collect recorders
SyncThreadRecorderClosure stc; SyncThreadRecorderClosure stc;
Threads::threads_do(&stc); Threads::threads_do(&stc);
...@@ -467,10 +473,6 @@ void MemTracker::sync() { ...@@ -467,10 +473,6 @@ void MemTracker::sync() {
_thread_count = stc.get_thread_count(); _thread_count = stc.get_thread_count();
MemRecorder* pending_recorders = get_pending_recorders(); MemRecorder* pending_recorders = get_pending_recorders();
{
// This method is running at safepoint, with ThreadCritical lock,
// it should guarantee that NMT is fully sync-ed.
ThreadCritical tc;
if (_global_recorder != NULL) { if (_global_recorder != NULL) {
_global_recorder->set_next(pending_recorders); _global_recorder->set_next(pending_recorders);
pending_recorders = _global_recorder; pending_recorders = _global_recorder;
...@@ -486,8 +488,6 @@ void MemTracker::sync() { ...@@ -486,8 +488,6 @@ void MemTracker::sync() {
// now, it is the time to shut whole things off // now, it is the time to shut whole things off
if (_state == NMT_final_shutdown) { if (_state == NMT_final_shutdown) {
_tracking_level = NMT_off;
// walk all JavaThreads to delete all recorders // walk all JavaThreads to delete all recorders
SyncThreadRecorderClosure stc; SyncThreadRecorderClosure stc;
Threads::threads_do(&stc); Threads::threads_do(&stc);
...@@ -499,8 +499,16 @@ void MemTracker::sync() { ...@@ -499,8 +499,16 @@ void MemTracker::sync() {
_global_recorder = NULL; _global_recorder = NULL;
} }
} }
MemRecorder* pending_recorders = get_pending_recorders();
if (pending_recorders != NULL) {
delete pending_recorders;
}
// try at a later sync point to ensure MemRecorder instance drops to zero to
// completely shutdown NMT
if (MemRecorder::_instance_count == 0) {
_state = NMT_shutdown; _state = NMT_shutdown;
_tracking_level = NMT_off;
}
} }
} }
...@@ -534,7 +542,7 @@ void MemTracker::thread_exiting(JavaThread* thread) { ...@@ -534,7 +542,7 @@ void MemTracker::thread_exiting(JavaThread* thread) {
// baseline current memory snapshot // baseline current memory snapshot
bool MemTracker::baseline() { bool MemTracker::baseline() {
MutexLockerEx lock(&_query_lock, true); MutexLockerEx lock(_query_lock, true);
MemSnapshot* snapshot = get_snapshot(); MemSnapshot* snapshot = get_snapshot();
if (snapshot != NULL) { if (snapshot != NULL) {
return _baseline.baseline(*snapshot, false); return _baseline.baseline(*snapshot, false);
...@@ -545,7 +553,7 @@ bool MemTracker::baseline() { ...@@ -545,7 +553,7 @@ bool MemTracker::baseline() {
// print memory usage from current snapshot // print memory usage from current snapshot
bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) { bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
MemBaseline baseline; MemBaseline baseline;
MutexLockerEx lock(&_query_lock, true); MutexLockerEx lock(_query_lock, true);
MemSnapshot* snapshot = get_snapshot(); MemSnapshot* snapshot = get_snapshot();
if (snapshot != NULL && baseline.baseline(*snapshot, summary_only)) { if (snapshot != NULL && baseline.baseline(*snapshot, summary_only)) {
BaselineReporter reporter(out, unit); BaselineReporter reporter(out, unit);
...@@ -557,7 +565,7 @@ bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool sum ...@@ -557,7 +565,7 @@ bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool sum
// compare memory usage between current snapshot and baseline // compare memory usage between current snapshot and baseline
bool MemTracker::compare_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) { bool MemTracker::compare_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
MutexLockerEx lock(&_query_lock, true); MutexLockerEx lock(_query_lock, true);
if (_baseline.baselined()) { if (_baseline.baselined()) {
MemBaseline baseline; MemBaseline baseline;
MemSnapshot* snapshot = get_snapshot(); MemSnapshot* snapshot = get_snapshot();
......
...@@ -126,6 +126,8 @@ class MemTracker : AllStatic { ...@@ -126,6 +126,8 @@ class MemTracker : AllStatic {
return "Native memory tracking has been shutdown by user"; return "Native memory tracking has been shutdown by user";
case NMT_normal: case NMT_normal:
return "Native memory tracking has been shutdown due to process exiting"; return "Native memory tracking has been shutdown due to process exiting";
case NMT_out_of_memory:
return "Native memory tracking has been shutdown due to out of native memory";
case NMT_initialization: case NMT_initialization:
return "Native memory tracking failed to initialize"; return "Native memory tracking failed to initialize";
case NMT_error_reporting: case NMT_error_reporting:
...@@ -326,7 +328,7 @@ class MemTracker : AllStatic { ...@@ -326,7 +328,7 @@ class MemTracker : AllStatic {
static void create_memory_record(address addr, MEMFLAGS type, static void create_memory_record(address addr, MEMFLAGS type,
size_t size, address pc, Thread* thread); size_t size, address pc, Thread* thread);
static void create_record_in_recorder(address addr, MEMFLAGS type, static void create_record_in_recorder(address addr, MEMFLAGS type,
size_t size, address pc, Thread* thread); size_t size, address pc, JavaThread* thread);
private: private:
// global memory snapshot // global memory snapshot
...@@ -336,7 +338,7 @@ class MemTracker : AllStatic { ...@@ -336,7 +338,7 @@ class MemTracker : AllStatic {
static MemBaseline _baseline; static MemBaseline _baseline;
// query lock // query lock
static Mutex _query_lock; static Mutex* _query_lock;
// a thread can start to allocate memory before it is attached // a thread can start to allocate memory before it is attached
// to VM 'Thread', those memory activities are recorded here. // to VM 'Thread', those memory activities are recorded here.
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
* @test * @test
* @bug 6294277 * @bug 6294277
* @summary java -Xdebug crashes on SourceDebugExtension attribute larger than 64K * @summary java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
* @run main/othervm -Xdebug -Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n SourceDebugExtension
*/ */
import java.io.*; import java.io.*;
......
#
# Copyright (c) 2012, 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 Test6294277.sh
# @bug 6294277
# @summary java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
# @run shell Test6294277.sh
#
if [ "${TESTSRC}" = "" ]
then TESTSRC=.
fi
if [ "${TESTJAVA}" = "" ]
then
PARENT=`dirname \`which java\``
TESTJAVA=`dirname ${PARENT}`
echo "TESTJAVA not set, selecting " ${TESTJAVA}
echo "If this is incorrect, try setting the variable manually."
fi
BIT_FLAG=""
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
SunOS | Linux )
NULL=/dev/null
PS=":"
FS="/"
## for solaris, linux it's HOME
FILE_LOCATION=$HOME
if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" -a `uname -p`='sparc' ]
then
BIT_FLAG="-d64"
fi
;;
Windows_* | Darwin )
NULL=NUL
PS=";"
FS="\\"
echo "Test skipped"
exit 0
;;
* )
echo "Unrecognized system!"
exit 1;
;;
esac
cp ${TESTSRC}${FS}*.java .
${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -fullversion
${TESTJAVA}${FS}bin${FS}javac *.java
${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -classpath . -Xdebug -Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n SourceDebugExtension > test.out 2>&1 &
P_PID=$!
sleep 60
STATUS=1
grep "Test PASSES" test.out > ${NULL}
if [ $? = 0 ]; then
cat test.out
STATUS=0
fi
exit $STATUS
...@@ -2,10 +2,9 @@ ...@@ -2,10 +2,9 @@
## ##
## @test ## @test
## @bug 7020373 7055247 ## @bug 7020373 7055247 7053586
## @key cte_test ## @key cte_test
## @summary JSR rewriting can overflow memory address size variables ## @summary JSR rewriting can overflow memory address size variables
## @ignore Ignore it until 7053586 fixed
## @run shell Test7020373.sh ## @run shell Test7020373.sh
## ##
...@@ -30,7 +29,7 @@ fi ...@@ -30,7 +29,7 @@ fi
# set platform-dependent variables # set platform-dependent variables
OS=`uname -s` OS=`uname -s`
case "$OS" in case "$OS" in
SunOS | Linux ) SunOS | Linux | Darwin )
NULL=/dev/null NULL=/dev/null
PS=":" PS=":"
FS="/" FS="/"
...@@ -66,7 +65,7 @@ then ...@@ -66,7 +65,7 @@ then
echo "Test Failed" echo "Test Failed"
exit 1 exit 1
else else
grep "java.lang.LinkageError" test.out egrep "java.lang.LinkageError|java.lang.NoSuchMethodError|Main method not found in class OOMCrashClass4000_1|insufficient memory" test.out
if [ $? = 0 ] if [ $? = 0 ]
then then
echo "Test Passed" echo "Test Passed"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册