8292890: Remove PrintTouchedMethodsAtExit and LogTouchedMethods

Reviewed-by: iklam, hseigel
This commit is contained in:
Coleen Phillimore 2022-08-25 21:12:35 +00:00
parent 95a33fe150
commit e353b572a5
19 changed files with 14 additions and 364 deletions

View file

@ -1112,7 +1112,7 @@ void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
// native method than the typical interpreter frame setup. // native method than the typical interpreter frame setup.
address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// determine code generation flags // determine code generation flags
bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; bool inc_counter = UseCompiler || CountCompiledCalls;
// r1: Method* // r1: Method*
// rscratch1: sender sp // rscratch1: sender sp
@ -1536,7 +1536,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// //
address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
// determine code generation flags // determine code generation flags
bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; bool inc_counter = UseCompiler || CountCompiledCalls;
// rscratch1: sender sp // rscratch1: sender sp
address entry_point = __ pc(); address entry_point = __ pc();

View file

@ -796,7 +796,7 @@ address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(Abstract
address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// determine code generation flags // determine code generation flags
bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; bool inc_counter = UseCompiler || CountCompiledCalls;
// Incoming registers: // Incoming registers:
// //
@ -1128,7 +1128,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// //
address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
// determine code generation flags // determine code generation flags
bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; bool inc_counter = UseCompiler || CountCompiledCalls;
// Rmethod: Method* // Rmethod: Method*
// Rthread: thread // Rthread: thread

View file

@ -2210,7 +2210,7 @@ void InterpreterMacroAssembler::get_method_counters(Register method,
void InterpreterMacroAssembler::increment_invocation_counter(Register Rcounters, void InterpreterMacroAssembler::increment_invocation_counter(Register Rcounters,
Register iv_be_count, Register iv_be_count,
Register Rtmp_r0) { Register Rtmp_r0) {
assert(UseCompiler || LogTouchedMethods, "incrementing must be useful"); assert(UseCompiler, "incrementing must be useful");
Register invocation_count = iv_be_count; Register invocation_count = iv_be_count;
Register backedge_count = Rtmp_r0; Register backedge_count = Rtmp_r0;
int delta = InvocationCounter::count_increment; int delta = InvocationCounter::count_increment;

View file

@ -1190,7 +1190,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
address entry = __ pc(); address entry = __ pc();
const bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; const bool inc_counter = UseCompiler || CountCompiledCalls;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Allocate a new frame that represents the native callee (i2n frame). // Allocate a new frame that represents the native callee (i2n frame).
@ -1614,7 +1614,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// Generic interpreted method entry to (asm) interpreter. // Generic interpreted method entry to (asm) interpreter.
// //
address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; bool inc_counter = UseCompiler || CountCompiledCalls;
address entry = __ pc(); address entry = __ pc();
// Generate the code to allocate the interpreter stack frame. // Generate the code to allocate the interpreter stack frame.
Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame. Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.

View file

@ -932,7 +932,7 @@ void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
// native method than the typical interpreter frame setup. // native method than the typical interpreter frame setup.
address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// determine code generation flags // determine code generation flags
bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; bool inc_counter = UseCompiler || CountCompiledCalls;
// x11: Method* // x11: Method*
// x30: sender sp // x30: sender sp
@ -1326,7 +1326,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
// determine code generation flags // determine code generation flags
const bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; const bool inc_counter = UseCompiler || CountCompiledCalls;
// t0: sender sp // t0: sender sp
address entry_point = __ pc(); address entry_point = __ pc();

View file

@ -1920,7 +1920,7 @@ void InterpreterMacroAssembler::get_method_counters(Register Rmethod,
// Return (invocation_counter+backedge_counter) as "result" in RctrSum. // Return (invocation_counter+backedge_counter) as "result" in RctrSum.
// Counter values are all unsigned. // Counter values are all unsigned.
void InterpreterMacroAssembler::increment_invocation_counter(Register Rcounters, Register RctrSum) { void InterpreterMacroAssembler::increment_invocation_counter(Register Rcounters, Register RctrSum) {
assert(UseCompiler || LogTouchedMethods, "incrementing must be useful"); assert(UseCompiler, "incrementing must be useful");
assert_different_registers(Rcounters, RctrSum); assert_different_registers(Rcounters, RctrSum);
int increment = InvocationCounter::count_increment; int increment = InvocationCounter::count_increment;

View file

@ -1301,7 +1301,7 @@ address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::M
// native method than the typical interpreter frame setup. // native method than the typical interpreter frame setup.
address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// Determine code generation flags. // Determine code generation flags.
bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; bool inc_counter = UseCompiler || CountCompiledCalls;
// Interpreter entry for ordinary Java methods. // Interpreter entry for ordinary Java methods.
// //
@ -1658,7 +1658,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
address entry_point = __ pc(); address entry_point = __ pc();
bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; bool inc_counter = UseCompiler || CountCompiledCalls;
// Interpreter entry for ordinary Java methods. // Interpreter entry for ordinary Java methods.
// //

View file

@ -790,7 +790,7 @@ void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) {
// native method than the typical interpreter frame setup. // native method than the typical interpreter frame setup.
address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// determine code generation flags // determine code generation flags
bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; bool inc_counter = UseCompiler || CountCompiledCalls;
// rbx: Method* // rbx: Method*
// rbcp: sender sp // rbcp: sender sp
@ -1327,7 +1327,7 @@ address TemplateInterpreterGenerator::generate_abstract_entry(void) {
// //
address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
// determine code generation flags // determine code generation flags
bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; bool inc_counter = UseCompiler || CountCompiledCalls;
// ebx: Method* // ebx: Method*
// rbcp: sender sp (set in InterpreterMacroAssembler::prepare_to_jump_from_interpreted / generate_call_stub) // rbcp: sender sp (set in InterpreterMacroAssembler::prepare_to_jump_from_interpreted / generate_call_stub)

View file

@ -73,9 +73,6 @@ ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) :
assert(h_m() != NULL, "no null method"); assert(h_m() != NULL, "no null method");
assert(_holder->get_instanceKlass() == h_m->method_holder(), ""); assert(_holder->get_instanceKlass() == h_m->method_holder(), "");
if (LogTouchedMethods) {
h_m->log_touched(Thread::current());
}
// These fields are always filled in in loaded methods. // These fields are always filled in in loaded methods.
_flags = ciFlags(h_m->access_flags()); _flags = ciFlags(h_m->access_flags());

View file

@ -639,10 +639,6 @@ MethodCounters* Method::build_method_counters(Thread* current, Method* m) {
MetadataFactory::free_metadata(mh->method_holder()->class_loader_data(), counters); MetadataFactory::free_metadata(mh->method_holder()->class_loader_data(), counters);
} }
if (LogTouchedMethods) {
mh->log_touched(current);
}
return mh->method_counters(); return mh->method_counters();
} }
@ -2445,85 +2441,6 @@ void Method::print_value_on(outputStream* st) const {
if (WizardMode && code() != NULL) st->print(" ((nmethod*)%p)", code()); if (WizardMode && code() != NULL) st->print(" ((nmethod*)%p)", code());
} }
// LogTouchedMethods and PrintTouchedMethods
// TouchedMethodRecord -- we can't use a HashtableEntry<Method*> because
// the Method may be garbage collected. Let's roll our own hash table.
class TouchedMethodRecord : CHeapObj<mtTracing> {
public:
// It's OK to store Symbols here because they will NOT be GC'ed if
// LogTouchedMethods is enabled.
TouchedMethodRecord* _next;
Symbol* _class_name;
Symbol* _method_name;
Symbol* _method_signature;
};
static const int TOUCHED_METHOD_TABLE_SIZE = 20011;
static TouchedMethodRecord** _touched_method_table = NULL;
void Method::log_touched(Thread* current) {
const int table_size = TOUCHED_METHOD_TABLE_SIZE;
Symbol* my_class = klass_name();
Symbol* my_name = name();
Symbol* my_sig = signature();
unsigned int hash = my_class->identity_hash() +
my_name->identity_hash() +
my_sig->identity_hash();
juint index = juint(hash) % table_size;
MutexLocker ml(current, TouchedMethodLog_lock);
if (_touched_method_table == NULL) {
_touched_method_table = NEW_C_HEAP_ARRAY2(TouchedMethodRecord*, table_size,
mtTracing, CURRENT_PC);
memset(_touched_method_table, 0, sizeof(TouchedMethodRecord*)*table_size);
}
TouchedMethodRecord* ptr = _touched_method_table[index];
while (ptr) {
if (ptr->_class_name == my_class &&
ptr->_method_name == my_name &&
ptr->_method_signature == my_sig) {
return;
}
if (ptr->_next == NULL) break;
ptr = ptr->_next;
}
TouchedMethodRecord* nptr = NEW_C_HEAP_OBJ(TouchedMethodRecord, mtTracing);
my_class->increment_refcount();
my_name->increment_refcount();
my_sig->increment_refcount();
nptr->_class_name = my_class;
nptr->_method_name = my_name;
nptr->_method_signature = my_sig;
nptr->_next = NULL;
if (ptr == NULL) {
// first
_touched_method_table[index] = nptr;
} else {
ptr->_next = nptr;
}
}
void Method::print_touched_methods(outputStream* out) {
MutexLocker ml(Thread::current()->is_VM_thread() ? NULL : TouchedMethodLog_lock);
out->print_cr("# Method::print_touched_methods version 1");
if (_touched_method_table) {
for (int i = 0; i < TOUCHED_METHOD_TABLE_SIZE; i++) {
TouchedMethodRecord* ptr = _touched_method_table[i];
while(ptr) {
ptr->_class_name->print_symbol_on(out); out->print(".");
ptr->_method_name->print_symbol_on(out); out->print(":");
ptr->_method_signature->print_symbol_on(out); out->cr();
ptr = ptr->_next;
}
}
}
}
// Verification // Verification
void Method::verify_on(outputStream* st) { void Method::verify_on(outputStream* st) {

View file

@ -4147,11 +4147,6 @@ jint Arguments::apply_ergo() {
#ifdef ZERO #ifdef ZERO
// Clear flags not supported on zero. // Clear flags not supported on zero.
FLAG_SET_DEFAULT(ProfileInterpreter, false); FLAG_SET_DEFAULT(ProfileInterpreter, false);
if (LogTouchedMethods) {
warning("LogTouchedMethods is not supported for Zero");
FLAG_SET_DEFAULT(LogTouchedMethods, false);
}
#endif // ZERO #endif // ZERO
if (PrintAssembly && FLAG_IS_DEFAULT(DebugNonSafepoints)) { if (PrintAssembly && FLAG_IS_DEFAULT(DebugNonSafepoints)) {

View file

@ -977,12 +977,6 @@ const int ObjectAlignmentInBytes = 8;
product(bool, UsePopCountInstruction, false, \ product(bool, UsePopCountInstruction, false, \
"Use population count instruction") \ "Use population count instruction") \
\ \
product(bool, LogTouchedMethods, false, DIAGNOSTIC, \
"Log methods which have been ever touched in runtime") \
\
product(bool, PrintTouchedMethodsAtExit, false, DIAGNOSTIC, \
"Print all methods that have been ever touched in runtime") \
\
develop(bool, TraceMethodReplacement, false, \ develop(bool, TraceMethodReplacement, false, \
"Print when methods are replaced do to recompilation") \ "Print when methods are replaced do to recompilation") \
\ \

View file

@ -320,10 +320,6 @@ void print_statistics() {
ClassLoaderDataGraph::print(); ClassLoaderDataGraph::print();
} }
if (LogTouchedMethods && PrintTouchedMethodsAtExit) {
Method::print_touched_methods(tty);
}
// Native memory tracking data // Native memory tracking data
if (PrintNMTStatistics) { if (PrintNMTStatistics) {
MemTracker::final_report(tty); MemTracker::final_report(tty);
@ -381,10 +377,6 @@ void print_statistics() {
MetaspaceUtils::print_basic_report(tty, 0); MetaspaceUtils::print_basic_report(tty, 0);
} }
if (LogTouchedMethods && PrintTouchedMethodsAtExit) {
Method::print_touched_methods(tty);
}
ThreadsSMRSupport::log_statistics(); ThreadsSMRSupport::log_statistics();
} }

View file

@ -96,7 +96,6 @@
template(ClassLoaderStatsOperation) \ template(ClassLoaderStatsOperation) \
template(ClassLoaderHierarchyOperation) \ template(ClassLoaderHierarchyOperation) \
template(DumpHashtable) \ template(DumpHashtable) \
template(DumpTouchedMethods) \
template(CleanClassLoaderDataMetaspaces) \ template(CleanClassLoaderDataMetaspaces) \
template(PrintCompileQueue) \ template(PrintCompileQueue) \
template(PrintClassHierarchy) \ template(PrintClassHierarchy) \

View file

@ -126,7 +126,6 @@ void DCmdRegistrant::register_dcmds(){
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PerfMapDCmd>(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PerfMapDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TrimCLibcHeapDCmd>(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TrimCLibcHeapDCmd>(full_export, true, false));
#endif // LINUX #endif // LINUX
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<TouchedMethodsDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeHeapAnalyticsDCmd>(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CodeHeapAnalyticsDCmd>(full_export, true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompilerDirectivesPrintDCmd>(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompilerDirectivesPrintDCmd>(full_export, true, false));
@ -933,30 +932,6 @@ void ClassHierarchyDCmd::execute(DCmdSource source, TRAPS) {
} }
#endif #endif
class VM_DumpTouchedMethods : public VM_Operation {
private:
outputStream* _out;
public:
VM_DumpTouchedMethods(outputStream* out) {
_out = out;
}
virtual VMOp_Type type() const { return VMOp_DumpTouchedMethods; }
virtual void doit() {
Method::print_touched_methods(_out);
}
};
void TouchedMethodsDCmd::execute(DCmdSource source, TRAPS) {
if (!LogTouchedMethods) {
output()->print_cr("VM.print_touched_methods command requires -XX:+LogTouchedMethods");
return;
}
VM_DumpTouchedMethods dumper(output());
VMThread::execute(&dumper);
}
ClassesDCmd::ClassesDCmd(outputStream* output, bool heap) : ClassesDCmd::ClassesDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap), DCmdWithParser(output, heap),
_verbose("-verbose", _verbose("-verbose",

View file

@ -386,21 +386,6 @@ public:
virtual void execute(DCmdSource source, TRAPS); virtual void execute(DCmdSource source, TRAPS);
}; };
class TouchedMethodsDCmd : public DCmd {
public:
TouchedMethodsDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
static const char* name() {
return "VM.print_touched_methods";
}
static const char* description() {
return "Print all methods that have ever been touched during the lifetime of this JVM.";
}
static const char* impact() {
return "Medium: Depends on Java content.";
}
virtual void execute(DCmdSource source, TRAPS);
};
#if INCLUDE_CDS #if INCLUDE_CDS
class DumpSharedArchiveDCmd: public DCmdWithParser { class DumpSharedArchiveDCmd: public DCmdWithParser {
protected: protected:

View file

@ -1,126 +0,0 @@
/*
* Copyright (c) 2015, 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 8025692 8273333
* @requires vm.flavor != "zero"
* @modules java.base/jdk.internal.misc
* java.management
* @library /test/lib
* @run driver PrintTouchedMethods
*/
import java.io.File;
import java.util.List;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.JDKToolFinder;
public class PrintTouchedMethods {
public static void main(String args[]) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:-UnlockDiagnosticVMOptions",
"-XX:+LogTouchedMethods",
"-XX:+PrintTouchedMethodsAtExit",
TestLogTouchedMethods.class.getName());
// UnlockDiagnostic turned off, should fail
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotHaveExitValue(0);
output.shouldContain("Error: VM option 'LogTouchedMethods' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.");
output.shouldContain("Error: Could not create the Java Virtual Machine.");
pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+LogTouchedMethods",
"-XX:+PrintTouchedMethodsAtExit",
TestLogTouchedMethods.class.getName());
output = new OutputAnalyzer(pb.start());
// check order:
// 1 "# Method::print_touched_methods version 1" is the first in first line
// 2 should contain TestLogMethods.methodA:()V
// 3 should not contain TestLogMethods.methodB:()V
// Repeat above for another run with -Xint
List<String> lines = output.asLines();
if (lines.size() < 1) {
throw new Exception("Empty output");
}
String first = lines.get(0);
if (!first.equals("# Method::print_touched_methods version 1")) {
throw new Exception("First line mismatch");
}
output.shouldContain("TestLogTouchedMethods.methodA:()V");
output.shouldNotContain("TestLogTouchedMethods.methodB:()V");
output.shouldHaveExitValue(0);
pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-Xint",
"-XX:+LogTouchedMethods",
"-XX:+PrintTouchedMethodsAtExit",
TestLogTouchedMethods.class.getName());
output = new OutputAnalyzer(pb.start());
lines = output.asLines();
if (lines.size() < 1) {
throw new Exception("Empty output");
}
first = lines.get(0);
if (!first.equals("# Method::print_touched_methods version 1")) {
throw new Exception("First line mismatch");
}
output.shouldContain("TestLogTouchedMethods.methodA:()V");
output.shouldNotContain("TestLogTouchedMethods.methodB:()V");
output.shouldHaveExitValue(0);
pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-Xint",
"-XX:+LogTouchedMethods",
"-XX:+PrintTouchedMethodsAtExit",
"-XX:-TieredCompilation",
TestLogTouchedMethods.class.getName());
output = new OutputAnalyzer(pb.start());
lines = output.asLines();
if (lines.size() < 1) {
throw new Exception("Empty output");
}
first = lines.get(0);
if (!first.equals("# Method::print_touched_methods version 1")) {
throw new Exception("First line mismatch");
}
output.shouldContain("TestLogTouchedMethods.methodA:()V");
output.shouldNotContain("TestLogTouchedMethods.methodB:()V");
output.shouldHaveExitValue(0);
}
}

View file

@ -1,46 +0,0 @@
/*
* Copyright (c) 2015, 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 8025692
* @summary Test jcmd PrintTouchedMethods VM.print_touched_methods
* @modules java.base/jdk.internal.misc
* java.management
* @library /test/lib
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+LogTouchedMethods PrintTouchedMethodsJcmd
*/
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.JDKToolFinder;
public class PrintTouchedMethodsJcmd {
public static void main(String args[]) throws Exception {
var pid = Long.toString(ProcessHandle.current().pid());
var pb = new ProcessBuilder();
pb.command(new String[] {JDKToolFinder.getJDKTool("jcmd"), pid, "VM.print_touched_methods"});
var output = new OutputAnalyzer(pb.start());
output.shouldContain("PrintTouchedMethodsJcmd.main:([Ljava/lang/String;)V");
}
}

View file

@ -1,32 +0,0 @@
/*
* Copyright (c) 2015, 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.
*/
/* used by PrintTouchedMethods.java */
public class TestLogTouchedMethods {
public static void main(String[] args) {
new TestLogTouchedMethods().methodA();
}
public void methodA() {} // called
public void methodB() {} // this should not be called
}