mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 03:24:38 +02:00
Merge
This commit is contained in:
commit
ffb15fdb04
34 changed files with 378 additions and 857 deletions
|
@ -2541,9 +2541,6 @@ class CommandLineFlags {
|
|||
"Enable String cache capabilities on String.java") \
|
||||
\
|
||||
/* statistics */ \
|
||||
develop(bool, UseVTune, false, \
|
||||
"enable support for Intel's VTune profiler") \
|
||||
\
|
||||
develop(bool, CountCompiledCalls, false, \
|
||||
"counts method invocations") \
|
||||
\
|
||||
|
|
|
@ -34,7 +34,6 @@ void perfMemory_init();
|
|||
|
||||
// Initialization done by Java thread in init_globals()
|
||||
void management_init();
|
||||
void vtune_init();
|
||||
void bytecodes_init();
|
||||
void classLoader_init();
|
||||
void codeCache_init();
|
||||
|
@ -82,7 +81,6 @@ void vm_init_globals() {
|
|||
jint init_globals() {
|
||||
HandleMark hm;
|
||||
management_init();
|
||||
vtune_init();
|
||||
bytecodes_init();
|
||||
classLoader_init();
|
||||
codeCache_init();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2010, 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
|
||||
|
@ -432,8 +432,6 @@ void before_exit(JavaThread * thread) {
|
|||
print_statistics();
|
||||
Universe::heap()->print_tracing_info();
|
||||
|
||||
VTune::exit();
|
||||
|
||||
{ MutexLocker ml(BeforeExit_lock);
|
||||
_before_exit_status = BEFORE_EXIT_DONE;
|
||||
BeforeExit_lock->notify_all();
|
||||
|
|
|
@ -2251,7 +2251,6 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
|
|||
B->name(),
|
||||
fingerprint->as_string(),
|
||||
B->instructions_begin());
|
||||
VTune::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
|
||||
Forte::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
|
||||
|
||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2010, 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
|
||||
|
@ -132,7 +132,6 @@ StubCodeMark::~StubCodeMark() {
|
|||
_cdesc->set_end(_cgen->assembler()->pc());
|
||||
assert(StubCodeDesc::_list == _cdesc, "expected order on list");
|
||||
_cgen->stub_epilog(_cdesc);
|
||||
VTune::register_stub(_cdesc->name(), _cdesc->begin(), _cdesc->end());
|
||||
Forte::register_stub(_cdesc->name(), _cdesc->begin(), _cdesc->end());
|
||||
|
||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2010, 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
|
||||
|
@ -27,14 +27,15 @@
|
|||
|
||||
long NMethodSweeper::_traversals = 0; // No. of stack traversals performed
|
||||
nmethod* NMethodSweeper::_current = NULL; // Current nmethod
|
||||
int NMethodSweeper::_seen = 0 ; // No. of blobs we have currently processed in current pass of CodeCache
|
||||
int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass
|
||||
int NMethodSweeper::_seen = 0 ; // No. of nmethods we have currently processed in current pass of CodeCache
|
||||
|
||||
volatile int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass
|
||||
volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress.
|
||||
|
||||
jint NMethodSweeper::_locked_seen = 0;
|
||||
jint NMethodSweeper::_not_entrant_seen_on_stack = 0;
|
||||
bool NMethodSweeper::_rescan = false;
|
||||
bool NMethodSweeper::_do_sweep = false;
|
||||
jint NMethodSweeper::_sweep_started = 0;
|
||||
bool NMethodSweeper::_was_full = false;
|
||||
jint NMethodSweeper::_advise_to_sweep = 0;
|
||||
jlong NMethodSweeper::_last_was_full = 0;
|
||||
|
@ -108,23 +109,14 @@ void NMethodSweeper::scan_stacks() {
|
|||
// code cache is filling up
|
||||
_last_was_full = os::javaTimeMillis();
|
||||
|
||||
if (PrintMethodFlushing) {
|
||||
tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler",
|
||||
CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
|
||||
}
|
||||
if (LogCompilation && (xtty != NULL)) {
|
||||
ttyLocker ttyl;
|
||||
xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
|
||||
CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
|
||||
xtty->stamp();
|
||||
xtty->end_elem();
|
||||
}
|
||||
log_sweep("restart_compiler");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NMethodSweeper::possibly_sweep() {
|
||||
assert(JavaThread::current()->thread_state() == _thread_in_vm, "must run in vm mode");
|
||||
if ((!MethodFlushing) || (!_do_sweep)) return;
|
||||
|
||||
if (_invocations > 0) {
|
||||
|
@ -133,32 +125,31 @@ void NMethodSweeper::possibly_sweep() {
|
|||
if (old != 0) {
|
||||
return;
|
||||
}
|
||||
sweep_code_cache();
|
||||
if (_invocations > 0) {
|
||||
sweep_code_cache();
|
||||
_invocations--;
|
||||
}
|
||||
_sweep_started = 0;
|
||||
}
|
||||
_sweep_started = 0;
|
||||
}
|
||||
|
||||
void NMethodSweeper::sweep_code_cache() {
|
||||
#ifdef ASSERT
|
||||
jlong sweep_start;
|
||||
if(PrintMethodFlushing) {
|
||||
if (PrintMethodFlushing) {
|
||||
sweep_start = os::javaTimeMillis();
|
||||
}
|
||||
#endif
|
||||
if (PrintMethodFlushing && Verbose) {
|
||||
tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_blobs(), _invocations);
|
||||
tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations);
|
||||
}
|
||||
|
||||
// We want to visit all nmethods after NmethodSweepFraction invocations.
|
||||
// If invocation is 1 we do the rest
|
||||
int todo = CodeCache::nof_blobs();
|
||||
if (_invocations > 1) {
|
||||
todo = (CodeCache::nof_blobs() - _seen) / _invocations;
|
||||
}
|
||||
|
||||
// Compilers may check to sweep more often than stack scans happen,
|
||||
// don't keep trying once it is all scanned
|
||||
_invocations--;
|
||||
// We want to visit all nmethods after NmethodSweepFraction
|
||||
// invocations so divide the remaining number of nmethods by the
|
||||
// remaining number of invocations. This is only an estimate since
|
||||
// the number of nmethods changes during the sweep so the final
|
||||
// stage must iterate until it there are no more nmethods.
|
||||
int todo = (CodeCache::nof_nmethods() - _seen) / _invocations;
|
||||
|
||||
assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here");
|
||||
assert(!CodeCache_lock->owned_by_self(), "just checking");
|
||||
|
@ -166,11 +157,12 @@ void NMethodSweeper::sweep_code_cache() {
|
|||
{
|
||||
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||
|
||||
for(int i = 0; i < todo && _current != NULL; i++) {
|
||||
// The last invocation iterates until there are no more nmethods
|
||||
for (int i = 0; (i < todo || _invocations == 1) && _current != NULL; i++) {
|
||||
|
||||
// Since we will give up the CodeCache_lock, always skip ahead to an nmethod.
|
||||
// Other blobs can be deleted by other threads
|
||||
// Read next before we potentially delete current
|
||||
// Since we will give up the CodeCache_lock, always skip ahead
|
||||
// to the next nmethod. Other blobs can be deleted by other
|
||||
// threads but nmethods are only reclaimed by the sweeper.
|
||||
nmethod* next = CodeCache::next_nmethod(_current);
|
||||
|
||||
// Now ready to process nmethod and give up CodeCache_lock
|
||||
|
@ -183,6 +175,8 @@ void NMethodSweeper::sweep_code_cache() {
|
|||
}
|
||||
}
|
||||
|
||||
assert(_invocations > 1 || _current == NULL, "must have scanned the whole cache");
|
||||
|
||||
if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) {
|
||||
// we've completed a scan without making progress but there were
|
||||
// nmethods we were unable to process either because they were
|
||||
|
@ -201,6 +195,10 @@ void NMethodSweeper::sweep_code_cache() {
|
|||
tty->print_cr("### sweeper: sweep time(%d): " INT64_FORMAT, _invocations, sweep_end - sweep_start);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_invocations == 1) {
|
||||
log_sweep("finished");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -223,7 +221,7 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
|
|||
if (nm->is_zombie()) {
|
||||
// If it is first time, we see nmethod then we mark it. Otherwise,
|
||||
// we reclame it. When we have seen a zombie method twice, we know that
|
||||
// there are no inline caches that referes to it.
|
||||
// there are no inline caches that refer to it.
|
||||
if (nm->is_marked_for_reclamation()) {
|
||||
assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
|
||||
if (PrintMethodFlushing && Verbose) {
|
||||
|
@ -320,16 +318,8 @@ void NMethodSweeper::handle_full_code_cache(bool is_full) {
|
|||
jlong curr_interval = now - _last_was_full;
|
||||
if (curr_interval < max_interval) {
|
||||
_rescan = true;
|
||||
if (PrintMethodFlushing) {
|
||||
tty->print_cr("### handle full too often, turning off compiler");
|
||||
}
|
||||
if (LogCompilation && (xtty != NULL)) {
|
||||
ttyLocker ttyl;
|
||||
xtty->begin_elem("disable_compiler flushing_interval='" UINT64_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
|
||||
curr_interval/1000, CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
|
||||
xtty->stamp();
|
||||
xtty->end_elem();
|
||||
}
|
||||
log_sweep("disable_compiler", "flushing_interval='" UINT64_FORMAT "'",
|
||||
curr_interval/1000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -349,17 +339,7 @@ void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
|
|||
|
||||
if ((!was_full()) && (is_full)) {
|
||||
if (!CodeCache::needs_flushing()) {
|
||||
if (PrintMethodFlushing) {
|
||||
tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler",
|
||||
CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
|
||||
}
|
||||
if (LogCompilation && (xtty != NULL)) {
|
||||
ttyLocker ttyl;
|
||||
xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
|
||||
CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
|
||||
xtty->stamp();
|
||||
xtty->end_elem();
|
||||
}
|
||||
log_sweep("restart_compiler");
|
||||
CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation);
|
||||
return;
|
||||
}
|
||||
|
@ -368,17 +348,7 @@ void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
|
|||
// Traverse the code cache trying to dump the oldest nmethods
|
||||
uint curr_max_comp_id = CompileBroker::get_compilation_id();
|
||||
uint flush_target = ((curr_max_comp_id - _highest_marked) >> 1) + _highest_marked;
|
||||
if (PrintMethodFlushing && Verbose) {
|
||||
tty->print_cr("### Cleaning code cache: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes",
|
||||
CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
|
||||
}
|
||||
if (LogCompilation && (xtty != NULL)) {
|
||||
ttyLocker ttyl;
|
||||
xtty->begin_elem("start_cleaning_code_cache live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
|
||||
CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
|
||||
xtty->stamp();
|
||||
xtty->end_elem();
|
||||
}
|
||||
log_sweep("start_cleaning");
|
||||
|
||||
nmethod* nm = CodeCache::alive_nmethod(CodeCache::first());
|
||||
jint disconnected = 0;
|
||||
|
@ -411,13 +381,9 @@ void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
|
|||
nm = CodeCache::alive_nmethod(CodeCache::next(nm));
|
||||
}
|
||||
|
||||
if (LogCompilation && (xtty != NULL)) {
|
||||
ttyLocker ttyl;
|
||||
xtty->begin_elem("stop_cleaning_code_cache disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
|
||||
disconnected, made_not_entrant, CodeCache::nof_blobs(), CodeCache::unallocated_capacity());
|
||||
xtty->stamp();
|
||||
xtty->end_elem();
|
||||
}
|
||||
log_sweep("stop_cleaning",
|
||||
"disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "'",
|
||||
disconnected, made_not_entrant);
|
||||
|
||||
// Shut off compiler. Sweeper will start over with a new stack scan and
|
||||
// traversal cycle and turn it back on if it clears enough space.
|
||||
|
@ -435,3 +401,38 @@ void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Print out some state information about the current sweep and the
|
||||
// state of the code cache if it's requested.
|
||||
void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) {
|
||||
if (PrintMethodFlushing) {
|
||||
ttyLocker ttyl;
|
||||
tty->print("### sweeper: %s ", msg);
|
||||
if (format != NULL) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
tty->vprint(format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
tty->print_cr(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
|
||||
" adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
|
||||
CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity());
|
||||
}
|
||||
|
||||
if (LogCompilation && (xtty != NULL)) {
|
||||
ttyLocker ttyl;
|
||||
xtty->begin_elem("sweeper state='%s' traversals='" INTX_FORMAT "' ", msg, (intx)traversal_count());
|
||||
if (format != NULL) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
xtty->vprint(format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
xtty->print(" total_blobs='" UINT32_FORMAT "' nmethods='" UINT32_FORMAT "'"
|
||||
" adapters='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'",
|
||||
CodeCache::nof_blobs(), CodeCache::nof_nmethods(), CodeCache::nof_adapters(), CodeCache::unallocated_capacity());
|
||||
xtty->stamp();
|
||||
xtty->end_elem();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2010, 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
|
||||
|
@ -31,12 +31,13 @@ class NMethodSweeper : public AllStatic {
|
|||
static long _traversals; // Stack traversal count
|
||||
static nmethod* _current; // Current nmethod
|
||||
static int _seen; // Nof. nmethod we have currently processed in current pass of CodeCache
|
||||
static int _invocations; // No. of invocations left until we are completed with this pass
|
||||
|
||||
static volatile int _invocations; // No. of invocations left until we are completed with this pass
|
||||
static volatile int _sweep_started; // Flag to control conc sweeper
|
||||
|
||||
static bool _rescan; // Indicates that we should do a full rescan of the
|
||||
// of the code cache looking for work to do.
|
||||
static bool _do_sweep; // Flag to skip the conc sweep if no stack scan happened
|
||||
static jint _sweep_started; // Flag to control conc sweeper
|
||||
static int _locked_seen; // Number of locked nmethods encountered during the scan
|
||||
static int _not_entrant_seen_on_stack; // Number of not entrant nmethod were are still on stack
|
||||
|
||||
|
@ -47,6 +48,9 @@ class NMethodSweeper : public AllStatic {
|
|||
static long _was_full_traversal; // trav number at last emergency unloading
|
||||
|
||||
static void process_nmethod(nmethod *nm);
|
||||
|
||||
static void log_sweep(const char* msg, const char* format = NULL, ...);
|
||||
|
||||
public:
|
||||
static long traversal_count() { return _traversals; }
|
||||
|
||||
|
|
|
@ -614,7 +614,6 @@ static inline uint64_t cast_uint64_t(size_t x)
|
|||
/* NMethods (NOTE: incomplete, but only a little) */ \
|
||||
/**************************************************/ \
|
||||
\
|
||||
static_field(nmethod, _zombie_instruction_size, int) \
|
||||
nonstatic_field(nmethod, _method, methodOop) \
|
||||
nonstatic_field(nmethod, _entry_bci, int) \
|
||||
nonstatic_field(nmethod, _osr_link, nmethod*) \
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2007, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
// Interface to Intel's VTune profiler.
|
||||
|
||||
class VTune : AllStatic {
|
||||
public:
|
||||
static void create_nmethod(nmethod* nm); // register newly created nmethod
|
||||
static void delete_nmethod(nmethod* nm); // unregister nmethod before discarding it
|
||||
|
||||
static void register_stub(const char* name, address start, address end);
|
||||
// register internal VM stub
|
||||
static void start_GC(); // start/end of GC or scavenge
|
||||
static void end_GC();
|
||||
|
||||
static void start_class_load(); // start/end of class loading
|
||||
static void end_class_load();
|
||||
|
||||
static void exit(); // VM exit
|
||||
};
|
||||
|
||||
|
||||
// helper objects
|
||||
class VTuneGCMarker : StackObj {
|
||||
public:
|
||||
VTuneGCMarker() { VTune::start_GC(); }
|
||||
~VTuneGCMarker() { VTune::end_GC(); }
|
||||
};
|
||||
|
||||
class VTuneClassLoadMarker : StackObj {
|
||||
public:
|
||||
VTuneClassLoadMarker() { VTune::start_class_load(); }
|
||||
~VTuneClassLoadMarker() { VTune::end_class_load(); }
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue