8210012: Implement Unified Logging Option for -XX:+TraceMethodHandles and -XX:+TraceInvokeDynamic
Transition the tracing method handles command line options to unified logging, -Xlog:methodhandles. Reviewed-by: dholmes, iklam, jrose
This commit is contained in:
parent
ed18906c08
commit
d37985cd70
src/hotspot
cpu
arm
ppc
s390
sparc
x86
share
classfile
compiler
interpreter
logging
oops
prims
runtime
utilities
test/hotspot/jtreg/runtime/logging
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2020, 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,6 +31,7 @@
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/interpreterRuntime.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
@ -540,7 +541,7 @@ void trace_method_handle_stub(const char* adaptername,
|
||||
}
|
||||
|
||||
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
|
||||
if (!TraceMethodHandles) return;
|
||||
if (!log_is_enabled(Info, methodhandles)) return;
|
||||
BLOCK_COMMENT("trace_method_handle {");
|
||||
// register saving
|
||||
// must correspond to trace_mh_nregs and trace_mh_regs defined above
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2017 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -28,6 +28,7 @@
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
@ -264,7 +265,7 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
|
||||
DEBUG_ONLY(param_size = noreg);
|
||||
}
|
||||
|
||||
if (TraceMethodHandles) {
|
||||
if (log_is_enabled(Info, methodhandles)) {
|
||||
if (tmp_mh != noreg) {
|
||||
__ mr(R23_method_handle, tmp_mh); // make stub happy
|
||||
}
|
||||
@ -545,7 +546,7 @@ void trace_method_handle_stub(const char* adaptername,
|
||||
}
|
||||
|
||||
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
|
||||
if (!TraceMethodHandles) return;
|
||||
if (!log_is_enabled(Info, methodhandles)) return;
|
||||
|
||||
BLOCK_COMMENT("trace_method_handle {");
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2017, SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -28,6 +28,7 @@
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
@ -616,7 +617,7 @@ void trace_method_handle_stub(const char* adaptername,
|
||||
}
|
||||
|
||||
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
|
||||
if (!TraceMethodHandles) { return; }
|
||||
if (!log_is_enabled(Info, methodhandles)) { return; }
|
||||
|
||||
// If arg registers are contiguous, we can use STMG/LMG.
|
||||
assert((Z_ARG5->encoding() - Z_ARG1->encoding() + 1) == RegisterImpl::number_of_arg_registers, "Oops");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2020, 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
|
||||
@ -28,6 +28,7 @@
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/interp_masm.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
@ -274,7 +275,7 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler*
|
||||
|
||||
// O4_first_arg_addr is live!
|
||||
|
||||
if (TraceMethodHandles) {
|
||||
if (log_is_enabled(Info, methodhandles)) {
|
||||
if (O0_mh != noreg)
|
||||
__ mov(O0_mh, G3_method_handle); // make stub happy
|
||||
trace_method_handle_interpreter_entry(_masm, iid);
|
||||
@ -576,7 +577,7 @@ void trace_method_handle_stub(const char* adaptername,
|
||||
}
|
||||
|
||||
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
|
||||
if (!TraceMethodHandles) return;
|
||||
if (!log_is_enabled(Info, methodhandles)) return;
|
||||
BLOCK_COMMENT("trace_method_handle {");
|
||||
// save: Gargs, O5_savedSP
|
||||
__ save_frame(16); // need space for saving required FPU state
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, 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
|
||||
@ -29,6 +29,7 @@
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/interpreterRuntime.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
@ -594,7 +595,7 @@ void trace_method_handle_stub_wrapper(MethodHandleStubArguments* args) {
|
||||
}
|
||||
|
||||
void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
|
||||
if (!TraceMethodHandles) return;
|
||||
if (!log_is_enabled(Info, methodhandles)) return;
|
||||
BLOCK_COMMENT(err_msg("trace_method_handle %s {", adaptername));
|
||||
__ enter();
|
||||
__ andptr(rsp, -16); // align stack if needed for FPU state
|
||||
|
@ -2456,15 +2456,16 @@ static Method* unpack_method_and_appendix(Handle mname,
|
||||
Method* m = java_lang_invoke_MemberName::vmtarget(mname());
|
||||
if (m != NULL) {
|
||||
oop appendix = appendix_box->obj_at(0);
|
||||
if (TraceMethodHandles) {
|
||||
#ifndef PRODUCT
|
||||
ttyLocker ttyl;
|
||||
tty->print("Linked method=" INTPTR_FORMAT ": ", p2i(m));
|
||||
m->print();
|
||||
if (appendix != NULL) { tty->print("appendix = "); appendix->print(); }
|
||||
tty->cr();
|
||||
#endif //PRODUCT
|
||||
LogTarget(Info, methodhandles) lt;
|
||||
if (lt.develop_is_enabled()) {
|
||||
ResourceMark rm(THREAD);
|
||||
LogStream ls(lt);
|
||||
ls.print("Linked method=" INTPTR_FORMAT ": ", p2i(m));
|
||||
m->print_on(&ls);
|
||||
if (appendix != NULL) { ls.print("appendix = "); appendix->print_on(&ls); }
|
||||
ls.cr();
|
||||
}
|
||||
|
||||
(*appendix_result) = Handle(THREAD, appendix);
|
||||
// the target is stored in the cpCache and if a reference to this
|
||||
// MemberName is dropped we need a way to make sure the
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2020, 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
|
||||
@ -242,7 +242,7 @@ void CompileTask::print_impl(outputStream* st, Method* method, int compile_id, i
|
||||
jlong time_queued, jlong time_started) {
|
||||
if (!short_form) {
|
||||
// Print current time
|
||||
st->print("%7d ", (int)st->time_stamp().milliseconds());
|
||||
st->print("%7d ", (int)tty->time_stamp().milliseconds());
|
||||
if (Verbose && time_queued != 0) {
|
||||
// Print time in queue and time being processed by compiler thread
|
||||
jlong now = os::elapsed_counter();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, 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
|
||||
@ -65,7 +65,7 @@ bool BootstrapInfo::resolve_previously_linked_invokedynamic(CallInfo& result, TR
|
||||
methodHandle method( THREAD, cpce->f1_as_method());
|
||||
Handle appendix( THREAD, cpce->appendix_if_resolved(_pool));
|
||||
result.set_handle(method, appendix, THREAD);
|
||||
Exceptions::wrap_dynamic_exception(CHECK_false);
|
||||
Exceptions::wrap_dynamic_exception(/* is_indy */ true, CHECK_false);
|
||||
return true;
|
||||
} else if (cpce->indy_resolution_failed()) {
|
||||
int encoded_index = ResolutionErrorTable::encode_cpcache_index(_indy_index);
|
||||
@ -81,24 +81,28 @@ bool BootstrapInfo::resolve_previously_linked_invokedynamic(CallInfo& result, TR
|
||||
// - obtain the NameAndType description for the condy/indy
|
||||
// - prepare the BSM's static arguments
|
||||
Handle BootstrapInfo::resolve_bsm(TRAPS) {
|
||||
if (_bsm.not_null()) return _bsm;
|
||||
if (_bsm.not_null()) {
|
||||
return _bsm;
|
||||
}
|
||||
|
||||
bool is_indy = is_method_call();
|
||||
// The tag at the bootstrap method index must be a valid method handle or a method handle in error.
|
||||
// If it is a MethodHandleInError, a resolution error will be thrown which will be wrapped if necessary
|
||||
// with a BootstrapMethodError.
|
||||
assert(_pool->tag_at(bsm_index()).is_method_handle() ||
|
||||
_pool->tag_at(bsm_index()).is_method_handle_in_error(), "MH not present, classfile structural constraint");
|
||||
oop bsm_oop = _pool->resolve_possibly_cached_constant_at(bsm_index(), THREAD);
|
||||
Exceptions::wrap_dynamic_exception(CHECK_NH);
|
||||
Exceptions::wrap_dynamic_exception(is_indy, CHECK_NH);
|
||||
guarantee(java_lang_invoke_MethodHandle::is_instance(bsm_oop), "classfile must supply a valid BSM");
|
||||
_bsm = Handle(THREAD, bsm_oop);
|
||||
|
||||
// Obtain NameAndType information
|
||||
resolve_bss_name_and_type(THREAD);
|
||||
Exceptions::wrap_dynamic_exception(CHECK_NH);
|
||||
Exceptions::wrap_dynamic_exception(is_indy, CHECK_NH);
|
||||
|
||||
// Prepare static arguments
|
||||
resolve_args(THREAD);
|
||||
Exceptions::wrap_dynamic_exception(CHECK_NH);
|
||||
Exceptions::wrap_dynamic_exception(is_indy, CHECK_NH);
|
||||
|
||||
return _bsm;
|
||||
}
|
||||
@ -253,7 +257,7 @@ void BootstrapInfo::print_msg_on(outputStream* st, const char* msg) {
|
||||
st->print_cr(" argument indexes: {%s}", argbuf);
|
||||
}
|
||||
if (_bsm.not_null()) {
|
||||
st->print(" resolved BSM: "); _bsm->print();
|
||||
st->print(" resolved BSM: "); _bsm->print_on(st);
|
||||
}
|
||||
|
||||
// How the array of resolved arguments is printed depends highly
|
||||
@ -264,7 +268,7 @@ void BootstrapInfo::print_msg_on(outputStream* st, const char* msg) {
|
||||
objArrayOop static_args = (objArrayOop)_arg_values();
|
||||
if (!static_args->is_array()) {
|
||||
assert(_argc == 1, "Invalid BSM _arg_values for non-array");
|
||||
st->print(" resolved arg[0]: "); static_args->print();
|
||||
st->print(" resolved arg[0]: "); static_args->print_on(st);
|
||||
} else if (static_args->is_objArray()) {
|
||||
int lines = 0;
|
||||
for (int i = 0; i < _argc; i++) {
|
||||
@ -274,7 +278,7 @@ void BootstrapInfo::print_msg_on(outputStream* st, const char* msg) {
|
||||
st->print_cr(" resolved arg[%d]: ...", i);
|
||||
break;
|
||||
}
|
||||
st->print(" resolved arg[%d]: ", i); x->print();
|
||||
st->print(" resolved arg[%d]: ", i); x->print_on(st);
|
||||
}
|
||||
}
|
||||
} else if (static_args->is_typeArray()) {
|
||||
|
@ -436,17 +436,16 @@ Method* LinkResolver::lookup_method_in_interfaces(const LinkInfo& cp_info) {
|
||||
Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info,
|
||||
Handle *appendix_result_or_null,
|
||||
TRAPS) {
|
||||
ResourceMark rm(THREAD);
|
||||
Klass* klass = link_info.resolved_klass();
|
||||
Symbol* name = link_info.name();
|
||||
Symbol* full_signature = link_info.signature();
|
||||
LogTarget(Info, methodhandles) lt_mh;
|
||||
|
||||
vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name);
|
||||
if (TraceMethodHandles) {
|
||||
ResourceMark rm(THREAD);
|
||||
tty->print_cr("lookup_polymorphic_method iid=%s %s.%s%s",
|
||||
vmIntrinsics::name_at(iid), klass->external_name(),
|
||||
name->as_C_string(), full_signature->as_C_string());
|
||||
}
|
||||
log_info(methodhandles)("lookup_polymorphic_method iid=%s %s.%s%s",
|
||||
vmIntrinsics::name_at(iid), klass->external_name(),
|
||||
name->as_C_string(), full_signature->as_C_string());
|
||||
if ((klass == SystemDictionary::MethodHandle_klass() ||
|
||||
klass == SystemDictionary::VarHandle_klass()) &&
|
||||
iid != vmIntrinsics::_none) {
|
||||
@ -456,13 +455,10 @@ Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info,
|
||||
bool keep_last_arg = MethodHandles::is_signature_polymorphic_static(iid);
|
||||
TempNewSymbol basic_signature =
|
||||
MethodHandles::lookup_basic_type_signature(full_signature, keep_last_arg, CHECK_NULL);
|
||||
if (TraceMethodHandles) {
|
||||
ResourceMark rm(THREAD);
|
||||
tty->print_cr("lookup_polymorphic_method %s %s => basic %s",
|
||||
name->as_C_string(),
|
||||
full_signature->as_C_string(),
|
||||
basic_signature->as_C_string());
|
||||
}
|
||||
log_info(methodhandles)("lookup_polymorphic_method %s %s => basic %s",
|
||||
name->as_C_string(),
|
||||
full_signature->as_C_string(),
|
||||
basic_signature->as_C_string());
|
||||
Method* result = SystemDictionary::find_method_handle_intrinsic(iid,
|
||||
basic_signature,
|
||||
CHECK_NULL);
|
||||
@ -470,10 +466,10 @@ Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info,
|
||||
assert(result->is_method_handle_intrinsic(), "MH.invokeBasic or MH.linkTo* intrinsic");
|
||||
assert(result->intrinsic_id() != vmIntrinsics::_invokeGeneric, "wrong place to find this");
|
||||
assert(basic_signature == result->signature(), "predict the result signature");
|
||||
if (TraceMethodHandles) {
|
||||
ttyLocker ttyl;
|
||||
tty->print("lookup_polymorphic_method => intrinsic ");
|
||||
result->print_on(tty);
|
||||
if (lt_mh.is_enabled()) {
|
||||
LogStream ls(lt_mh);
|
||||
ls.print("lookup_polymorphic_method => intrinsic ");
|
||||
result->print_on(&ls);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -503,13 +499,12 @@ Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info,
|
||||
link_info.current_klass(),
|
||||
&appendix,
|
||||
CHECK_NULL);
|
||||
if (TraceMethodHandles) {
|
||||
ttyLocker ttyl;
|
||||
tty->print("lookup_polymorphic_method => (via Java) ");
|
||||
result->print_on(tty);
|
||||
tty->print(" lookup_polymorphic_method => appendix = ");
|
||||
if (appendix.is_null()) tty->print_cr("(none)");
|
||||
else appendix->print_on(tty);
|
||||
if (lt_mh.is_enabled()) {
|
||||
LogStream ls(lt_mh);
|
||||
ls.print("lookup_polymorphic_method => (via Java) ");
|
||||
result->print_on(&ls);
|
||||
ls.print(" lookup_polymorphic_method => appendix = ");
|
||||
appendix.is_null() ? ls.print_cr("(none)") : appendix->print_on(&ls);
|
||||
}
|
||||
if (result != NULL) {
|
||||
#ifdef ASSERT
|
||||
@ -1669,10 +1664,10 @@ void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, const
|
||||
void LinkResolver::resolve_invokehandle(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
|
||||
// This guy is reached from InterpreterRuntime::resolve_invokehandle.
|
||||
LinkInfo link_info(pool, index, CHECK);
|
||||
if (TraceMethodHandles) {
|
||||
if (log_is_enabled(Info, methodhandles)) {
|
||||
ResourceMark rm(THREAD);
|
||||
tty->print_cr("resolve_invokehandle %s %s", link_info.name()->as_C_string(),
|
||||
link_info.signature()->as_C_string());
|
||||
log_info(methodhandles)("resolve_invokehandle %s %s", link_info.name()->as_C_string(),
|
||||
link_info.signature()->as_C_string());
|
||||
}
|
||||
resolve_handle_call(result, link_info, CHECK);
|
||||
}
|
||||
@ -1713,8 +1708,10 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHan
|
||||
|
||||
resolve_dynamic_call(result, bootstrap_specifier, CHECK);
|
||||
|
||||
if (TraceMethodHandles) {
|
||||
bootstrap_specifier.print_msg_on(tty, "resolve_invokedynamic");
|
||||
LogTarget(Debug, methodhandles, indy) lt_indy;
|
||||
if (lt_indy.is_enabled()) {
|
||||
LogStream ls(lt_indy);
|
||||
bootstrap_specifier.print_msg_on(&ls, "resolve_invokedynamic");
|
||||
}
|
||||
|
||||
// The returned linkage result is provisional up to the moment
|
||||
@ -1735,7 +1732,7 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result,
|
||||
// or any other reference. The resolved_method as well as the appendix
|
||||
// are both recorded together via CallInfo::set_handle.
|
||||
SystemDictionary::invoke_bootstrap_method(bootstrap_specifier, THREAD);
|
||||
Exceptions::wrap_dynamic_exception(THREAD);
|
||||
Exceptions::wrap_dynamic_exception(/* is_indy */ true, THREAD);
|
||||
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2020, 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
|
||||
@ -189,6 +189,11 @@ public:
|
||||
return LogImpl<T0, T1, T2, T3, T4, GuardTag>::is_level(level);
|
||||
}
|
||||
|
||||
static bool develop_is_enabled() {
|
||||
NOT_PRODUCT(return is_enabled());
|
||||
PRODUCT_ONLY(return false);
|
||||
}
|
||||
|
||||
static void print(const char* fmt, ...) ATTRIBUTE_PRINTF(1, 2) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2020, 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
|
||||
@ -93,6 +93,10 @@ public:
|
||||
// LogStreamBase(level, tageset);
|
||||
LogStream(LogLevelType level, LogTagSet* tagset) : _log_handle(level, tagset) {}
|
||||
|
||||
bool is_enabled() const {
|
||||
return _log_handle.is_enabled();
|
||||
}
|
||||
|
||||
void write(const char* s, size_t len);
|
||||
};
|
||||
|
||||
|
@ -52,6 +52,7 @@
|
||||
LOG_TAG(codecache) \
|
||||
LOG_TAG(compaction) \
|
||||
LOG_TAG(compilation) \
|
||||
LOG_TAG(condy) \
|
||||
LOG_TAG(constraints) \
|
||||
LOG_TAG(constantpool) \
|
||||
LOG_TAG(container) \
|
||||
@ -80,6 +81,7 @@
|
||||
LOG_TAG(humongous) \
|
||||
LOG_TAG(ihop) \
|
||||
LOG_TAG(iklass) \
|
||||
LOG_TAG(indy) \
|
||||
LOG_TAG(init) \
|
||||
LOG_TAG(inlining) \
|
||||
LOG_TAG(install) \
|
||||
@ -102,6 +104,7 @@
|
||||
LOG_TAG(methodcomparator) \
|
||||
LOG_TAG(metadata) \
|
||||
LOG_TAG(metaspace) \
|
||||
LOG_TAG(methodhandles) \
|
||||
LOG_TAG(mmu) \
|
||||
LOG_TAG(module) \
|
||||
LOG_TAG(monitorinflation) \
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "interpreter/bootstrapInfo.hpp"
|
||||
#include "interpreter/linkResolver.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/heapShared.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
@ -941,7 +943,7 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp,
|
||||
// (invocation of the BSM), of JVMS Section 5.4.3.6 occur within invoke_bootstrap_method()
|
||||
// for the bootstrap_specifier created above.
|
||||
SystemDictionary::invoke_bootstrap_method(bootstrap_specifier, THREAD);
|
||||
Exceptions::wrap_dynamic_exception(THREAD);
|
||||
Exceptions::wrap_dynamic_exception(/* is_indy */ false, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
// Resolution failure of the dynamically-computed constant, save_and_throw_exception
|
||||
// will check for a LinkageError and store a DynamicConstantInError.
|
||||
@ -969,8 +971,10 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp,
|
||||
}
|
||||
}
|
||||
|
||||
if (TraceMethodHandles) {
|
||||
bootstrap_specifier.print_msg_on(tty, "resolve_constant_at_impl");
|
||||
LogTarget(Debug, methodhandles, condy) lt_condy;
|
||||
if (lt_condy.is_enabled()) {
|
||||
LogStream ls(lt_condy);
|
||||
bootstrap_specifier.print_msg_on(&ls, "resolve_constant_at_impl");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "interpreter/linkResolver.hpp"
|
||||
#include "interpreter/rewriter.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/heapShared.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/metaspaceClosure.hpp"
|
||||
@ -412,15 +413,18 @@ void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle&
|
||||
( 1 << is_final_shift ),
|
||||
adapter->size_of_parameters());
|
||||
|
||||
if (TraceInvokeDynamic) {
|
||||
ttyLocker ttyl;
|
||||
tty->print_cr("set_method_handle bc=%d appendix=" PTR_FORMAT "%s method=" PTR_FORMAT " (local signature) ",
|
||||
invoke_code,
|
||||
p2i(appendix()),
|
||||
(has_appendix ? "" : " (unused)"),
|
||||
p2i(adapter));
|
||||
adapter->print();
|
||||
if (has_appendix) appendix()->print();
|
||||
LogStream* log_stream = NULL;
|
||||
LogStreamHandle(Debug, methodhandles, indy) lsh_indy;
|
||||
if (lsh_indy.is_enabled()) {
|
||||
ResourceMark rm;
|
||||
log_stream = &lsh_indy;
|
||||
log_stream->print_cr("set_method_handle bc=%d appendix=" PTR_FORMAT "%s method=" PTR_FORMAT " (local signature) ",
|
||||
invoke_code,
|
||||
p2i(appendix()),
|
||||
(has_appendix ? "" : " (unused)"),
|
||||
p2i(adapter));
|
||||
adapter->print_on(log_stream);
|
||||
if (has_appendix) appendix()->print_on(log_stream);
|
||||
}
|
||||
|
||||
// Method handle invokes and invokedynamic sites use both cp cache words.
|
||||
@ -456,9 +460,9 @@ void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle&
|
||||
// but it is used by is_resolved, method_if_resolved, etc.
|
||||
set_bytecode_1(invoke_code);
|
||||
NOT_PRODUCT(verify(tty));
|
||||
if (TraceInvokeDynamic) {
|
||||
ttyLocker ttyl;
|
||||
this->print(tty, 0);
|
||||
|
||||
if (log_stream != NULL) {
|
||||
this->print(log_stream, 0);
|
||||
}
|
||||
|
||||
assert(has_appendix == this->has_appendix(), "proper storage of appendix flag");
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "interpreter/oopMapCache.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logTag.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/metaspaceClosure.hpp"
|
||||
@ -1417,9 +1418,8 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid,
|
||||
InstanceKlass* holder = SystemDictionary::MethodHandle_klass();
|
||||
Symbol* name = MethodHandles::signature_polymorphic_intrinsic_name(iid);
|
||||
assert(iid == MethodHandles::signature_polymorphic_name_id(name), "");
|
||||
if (TraceMethodHandles) {
|
||||
tty->print_cr("make_method_handle_intrinsic MH.%s%s", name->as_C_string(), signature->as_C_string());
|
||||
}
|
||||
|
||||
log_info(methodhandles)("make_method_handle_intrinsic MH.%s%s", name->as_C_string(), signature->as_C_string());
|
||||
|
||||
// invariant: cp->symbol_at_put is preceded by a refcount increment (more usually a lookup)
|
||||
name->increment_refcount();
|
||||
@ -1470,9 +1470,10 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid,
|
||||
m->set_vtable_index(Method::nonvirtual_vtable_index);
|
||||
m->link_method(m, CHECK_(empty));
|
||||
|
||||
if (TraceMethodHandles && (Verbose || WizardMode)) {
|
||||
ttyLocker ttyl;
|
||||
m->print_on(tty);
|
||||
if (log_is_enabled(Info, methodhandles) && (Verbose || WizardMode)) {
|
||||
LogTarget(Info, methodhandles) lt;
|
||||
LogStream ls(lt);
|
||||
m->print_on(&ls);
|
||||
}
|
||||
|
||||
return m;
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/oopMapCache.hpp"
|
||||
#include "interpreter/linkResolver.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
@ -228,6 +230,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
|
||||
assert(m_klass != NULL, "null holder for method handle");
|
||||
int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS );
|
||||
int vmindex = Method::invalid_vtable_index;
|
||||
LogTarget(Debug, methodhandles, indy) lt_indy;
|
||||
|
||||
switch (info.call_kind()) {
|
||||
case CallInfo::itable_call:
|
||||
@ -235,22 +238,22 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
|
||||
// More importantly, the itable index only works with the method holder.
|
||||
assert(m_klass->verify_itable_index(vmindex), "");
|
||||
flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
|
||||
if (TraceInvokeDynamic) {
|
||||
ttyLocker ttyl;
|
||||
if (lt_indy.is_enabled()) {
|
||||
ResourceMark rm;
|
||||
tty->print_cr("memberName: invokeinterface method_holder::method: %s, itableindex: %d, access_flags:",
|
||||
Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
|
||||
vmindex);
|
||||
m->access_flags().print_on(tty);
|
||||
LogStream ls(lt_indy);
|
||||
ls.print_cr("memberName: invokeinterface method_holder::method: %s, itableindex: %d, access_flags:",
|
||||
Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
|
||||
vmindex);
|
||||
m->access_flags().print_on(&ls);
|
||||
if (!m->is_abstract()) {
|
||||
if (!m->is_private()) {
|
||||
tty->print("default");
|
||||
ls.print("default");
|
||||
}
|
||||
else {
|
||||
tty->print("private-intf");
|
||||
ls.print("private-intf");
|
||||
}
|
||||
}
|
||||
tty->cr();
|
||||
ls.cr();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -282,17 +285,17 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
|
||||
assert(info.resolved_klass()->is_subtype_of(m_klass_non_interface), "virtual call must be type-safe");
|
||||
m_klass = m_klass_non_interface;
|
||||
}
|
||||
if (TraceInvokeDynamic) {
|
||||
ttyLocker ttyl;
|
||||
if (lt_indy.is_enabled()) {
|
||||
ResourceMark rm;
|
||||
tty->print_cr("memberName: invokevirtual method_holder::method: %s, receiver: %s, vtableindex: %d, access_flags:",
|
||||
Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
|
||||
m_klass->internal_name(), vmindex);
|
||||
m->access_flags().print_on(tty);
|
||||
LogStream ls(lt_indy);
|
||||
ls.print_cr("memberName: invokevirtual method_holder::method: %s, receiver: %s, vtableindex: %d, access_flags:",
|
||||
Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
|
||||
m_klass->internal_name(), vmindex);
|
||||
m->access_flags().print_on(&ls);
|
||||
if (m->is_default_method()) {
|
||||
tty->print("default");
|
||||
ls.print("default");
|
||||
}
|
||||
tty->cr();
|
||||
ls.cr();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1069,7 +1072,7 @@ void MethodHandles::flush_dependent_nmethods(Handle call_site, Handle target) {
|
||||
}
|
||||
|
||||
void MethodHandles::trace_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid) {
|
||||
if (TraceMethodHandles) {
|
||||
if (log_is_enabled(Info, methodhandles)) {
|
||||
const char* name = vmIntrinsics::name_at(iid);
|
||||
if (*name == '_') name += 1;
|
||||
const size_t len = strlen(name) + 50;
|
||||
@ -1555,9 +1558,7 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
|
||||
"register java.lang.invoke.MethodHandle natives");
|
||||
}
|
||||
|
||||
if (TraceInvokeDynamic) {
|
||||
tty->print_cr("MethodHandle support loaded (using LambdaForms)");
|
||||
}
|
||||
log_debug(methodhandles, indy)("MethodHandle support loaded (using LambdaForms)");
|
||||
|
||||
MethodHandles::set_enabled(true);
|
||||
}
|
||||
|
@ -586,7 +586,9 @@ static AliasedLoggingFlag const aliased_logging_flags[] = {
|
||||
{ "TraceClassResolution", LogLevel::Debug, true, LOG_TAGS(class, resolve) },
|
||||
{ "TraceClassUnloading", LogLevel::Info, true, LOG_TAGS(class, unload) },
|
||||
{ "TraceExceptions", LogLevel::Info, true, LOG_TAGS(exceptions) },
|
||||
{ "TraceInvokeDynamic", LogLevel::Debug, true, LOG_TAGS(methodhandles, indy) },
|
||||
{ "TraceLoaderConstraints", LogLevel::Info, true, LOG_TAGS(class, loader, constraints) },
|
||||
{ "TraceMethodHandles", LogLevel::Info, true, LOG_TAGS(methodhandles) },
|
||||
{ "TraceMonitorInflation", LogLevel::Trace, true, LOG_TAGS(monitorinflation) },
|
||||
{ "TraceSafepointCleanupTime", LogLevel::Info, true, LOG_TAGS(safepoint, cleanup) },
|
||||
{ "TraceJVMTIObjectTagging", LogLevel::Debug, true, LOG_TAGS(jvmti, objecttagging) },
|
||||
|
@ -2298,9 +2298,6 @@ const size_t minimumSymbolTableSize = 1024;
|
||||
diagnostic(bool, PrintMethodHandleStubs, false, \
|
||||
"Print generated stub code for method handles") \
|
||||
\
|
||||
develop(bool, TraceMethodHandles, false, \
|
||||
"trace internal method handle operations") \
|
||||
\
|
||||
diagnostic(bool, VerifyMethodHandles, trueInDebug, \
|
||||
"perform extra checks when constructing method handles") \
|
||||
\
|
||||
@ -2313,9 +2310,6 @@ const size_t minimumSymbolTableSize = 1024;
|
||||
diagnostic(bool, FoldStableValues, true, \
|
||||
"Optimize loads from stable fields (marked w/ @Stable)") \
|
||||
\
|
||||
develop(bool, TraceInvokeDynamic, false, \
|
||||
"trace internal invoke dynamic operations") \
|
||||
\
|
||||
diagnostic(int, UseBootstrapCallInfo, 1, \
|
||||
"0: when resolving InDy or ConDy, force all BSM arguments to be " \
|
||||
"resolved before the bootstrap method is called; 1: when a BSM " \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2020, 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
|
||||
@ -401,25 +401,36 @@ Handle Exceptions::new_exception(Thread* thread, Symbol* name,
|
||||
// dynamically computed constant uses wrap_dynamic_exception for:
|
||||
// - bootstrap method resolution
|
||||
// - post call to MethodHandleNatives::linkDynamicConstant
|
||||
void Exceptions::wrap_dynamic_exception(Thread* THREAD) {
|
||||
void Exceptions::wrap_dynamic_exception(bool is_indy, Thread* THREAD) {
|
||||
if (THREAD->has_pending_exception()) {
|
||||
bool log_indy = log_is_enabled(Debug, methodhandles, indy) && is_indy;
|
||||
bool log_condy = log_is_enabled(Debug, methodhandles, condy) && !is_indy;
|
||||
LogStreamHandle(Debug, methodhandles, indy) lsh_indy;
|
||||
LogStreamHandle(Debug, methodhandles, condy) lsh_condy;
|
||||
LogStream* ls = NULL;
|
||||
if (log_indy) {
|
||||
ls = &lsh_indy;
|
||||
} else if (log_condy) {
|
||||
ls = &lsh_condy;
|
||||
}
|
||||
oop exception = THREAD->pending_exception();
|
||||
|
||||
// See the "Linking Exceptions" section for the invokedynamic instruction
|
||||
// in JVMS 6.5.
|
||||
if (exception->is_a(SystemDictionary::Error_klass())) {
|
||||
// Pass through an Error, including BootstrapMethodError, any other form
|
||||
// of linkage error, or say ThreadDeath/OutOfMemoryError
|
||||
if (TraceMethodHandles) {
|
||||
tty->print_cr("bootstrap method invocation wraps BSME around " INTPTR_FORMAT, p2i((void *)exception));
|
||||
exception->print();
|
||||
if (ls != NULL) {
|
||||
ls->print_cr("bootstrap method invocation wraps BSME around " INTPTR_FORMAT, p2i((void *)exception));
|
||||
exception->print_on(ls);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise wrap the exception in a BootstrapMethodError
|
||||
if (TraceMethodHandles) {
|
||||
tty->print_cr("[constant/invoke]dynamic throws BSME for " INTPTR_FORMAT, p2i((void *)exception));
|
||||
exception->print();
|
||||
if (ls != NULL) {
|
||||
ls->print_cr("%s throws BSME for " INTPTR_FORMAT, is_indy ? "invokedynamic" : "dynamic constant", p2i((void *)exception));
|
||||
exception->print_on(ls);
|
||||
}
|
||||
Handle nested_exception(THREAD, exception);
|
||||
THREAD->clear_pending_exception();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2020, 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
|
||||
@ -170,7 +170,7 @@ class Exceptions {
|
||||
|
||||
static void throw_stack_overflow_exception(Thread* thread, const char* file, int line, const methodHandle& method);
|
||||
|
||||
static void wrap_dynamic_exception(Thread* thread);
|
||||
static void wrap_dynamic_exception(bool is_indy, Thread* thread);
|
||||
|
||||
// Exception counting for error files of interesting exceptions that may have
|
||||
// caused a problem for the jvm
|
||||
|
101
test/hotspot/jtreg/runtime/logging/CondyIndy.jasm
Normal file
101
test/hotspot/jtreg/runtime/logging/CondyIndy.jasm
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.
|
||||
*/
|
||||
|
||||
super public class CondyIndy
|
||||
version 59:0
|
||||
{
|
||||
|
||||
public static Field add1:"LCondyIndyMathOperation;";
|
||||
|
||||
public Method "<init>":"()V"
|
||||
stack 1 locals 1
|
||||
{
|
||||
aload_0;
|
||||
invokespecial Method java/lang/Object."<init>":"()V";
|
||||
return;
|
||||
}
|
||||
|
||||
public static Method condy_bsm:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Object;)Ljava/lang/Object;"
|
||||
stack 2 locals 4
|
||||
{
|
||||
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
|
||||
ldc String "In condy_bsm";
|
||||
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
|
||||
ldc String "1";
|
||||
areturn;
|
||||
}
|
||||
|
||||
public static Method operate:"(IILCondyIndyMathOperation;)I"
|
||||
stack 3 locals 3
|
||||
{
|
||||
aload_2;
|
||||
iload_0;
|
||||
iload_1;
|
||||
invokeinterface InterfaceMethod CondyIndyMathOperation.operation:"(II)I", 3;
|
||||
ireturn;
|
||||
}
|
||||
|
||||
public static Method main:"([Ljava/lang/String;)V"
|
||||
stack 4 locals 2
|
||||
{
|
||||
new class CondyIndy;
|
||||
dup;
|
||||
invokespecial Method "<init>":"()V";
|
||||
astore_1;
|
||||
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
|
||||
bipush 10;
|
||||
iconst_5;
|
||||
aload_1;
|
||||
pop;
|
||||
getstatic Field add1:"LCondyIndyMathOperation;";
|
||||
invokestatic Method operate:"(IILCondyIndyMathOperation;)I";
|
||||
invokevirtual Method java/io/PrintStream.println:"(I)V";
|
||||
ldc Dynamic REF_invokeStatic:CondyIndy.condy_bsm:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Object;)Ljava/lang/Object;":invoke:"Ljava/lang/Object;" {
|
||||
int 0
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
private static synthetic Method lambda$static$0:"(II)I"
|
||||
stack 2 locals 2
|
||||
{
|
||||
iload_0;
|
||||
iload_1;
|
||||
iadd;
|
||||
ireturn;
|
||||
}
|
||||
|
||||
static Method "<clinit>":"()V"
|
||||
stack 1 locals 0
|
||||
{
|
||||
invokedynamic InvokeDynamic REF_invokeStatic:java/lang/invoke/LambdaMetafactory.metafactory:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;":operation:"()LCondyIndyMathOperation;"
|
||||
MethodType "(II)I",
|
||||
MethodHandle REF_invokeStatic:CondyIndy.lambda$static$0:"(II)I",
|
||||
MethodType "(II)I";
|
||||
putstatic Field add1:"LCondyIndyMathOperation;";
|
||||
return;
|
||||
}
|
||||
|
||||
public static final InnerClass Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles;
|
||||
|
||||
} // end Class CondyIndy
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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 CondyIndyMathOperation
|
||||
version 59:0
|
||||
{
|
||||
|
||||
|
||||
public abstract Method operation:"(II)I";
|
||||
|
||||
} // end Class CondyIndyMathOperation
|
75
test/hotspot/jtreg/runtime/logging/CondyIndyTest.java
Normal file
75
test/hotspot/jtreg/runtime/logging/CondyIndyTest.java
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* @summary Test -Xlog:methodhandles with a test that contains both a condy and indy.
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @library /test/lib
|
||||
* @compile CondyIndyMathOperation.jasm
|
||||
* @compile CondyIndy.jasm
|
||||
* @run driver CondyIndyTest
|
||||
*/
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.compiler.InMemoryJavaCompiler;
|
||||
|
||||
public class CondyIndyTest {
|
||||
public static void main(String... args) throws Exception {
|
||||
|
||||
// (1) methodhandles should turn on, no indy, no condy
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xlog:methodhandles",
|
||||
"CondyIndy");
|
||||
OutputAnalyzer o = new OutputAnalyzer(pb.start());
|
||||
o.shouldContain("[info][methodhandles");
|
||||
o.shouldNotContain("[debug][methodhandles,indy");
|
||||
o.shouldNotContain("[debug][methodhandles,condy");
|
||||
|
||||
// (2) methodhandles+condy=debug only
|
||||
pb = ProcessTools.createJavaProcessBuilder("-Xlog:methodhandles+condy=debug",
|
||||
"CondyIndy");
|
||||
o = new OutputAnalyzer(pb.start());
|
||||
o.shouldNotContain("[info ][methodhandles");
|
||||
o.shouldNotContain("[debug][methodhandles,indy");
|
||||
o.shouldContain("[debug][methodhandles,condy");
|
||||
|
||||
// (3) methodhandles+indy=debug only
|
||||
pb = ProcessTools.createJavaProcessBuilder("-Xlog:methodhandles+indy=debug",
|
||||
"CondyIndy");
|
||||
o = new OutputAnalyzer(pb.start());
|
||||
o.shouldNotContain("[info ][methodhandles");
|
||||
o.shouldContain("[debug][methodhandles,indy");
|
||||
o.shouldNotContain("[debug][methodhandles,condy");
|
||||
|
||||
// (4) methodhandles, condy, indy all on
|
||||
pb = ProcessTools.createJavaProcessBuilder("-Xlog:methodhandles=info",
|
||||
"-Xlog:methodhandles+condy=debug",
|
||||
"-Xlog:methodhandles+indy=debug",
|
||||
"CondyIndy");
|
||||
o = new OutputAnalyzer(pb.start());
|
||||
o.shouldContain("[info ][methodhandles");
|
||||
o.shouldContain("[debug][methodhandles,indy");
|
||||
o.shouldContain("[debug][methodhandles,condy");
|
||||
};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user