diff --git a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp index 95a58dfd3bc..893e8dc728e 100644 --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp @@ -497,16 +497,32 @@ void LIR_Assembler::add_debug_info_for_branch(address adr, CodeEmitInfo* info) { void LIR_Assembler::return_op(LIR_Opr result, C1SafepointPollStub* code_stub) { assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == r0, "word returns are in r0,"); - ciMethod* method = compilation()->method(); - if (InlineTypeReturnedAsFields && method->return_type()->is_inlinetype()) { - ciInlineKlass* vk = method->return_type()->as_inline_klass(); - if (vk->can_be_returned_as_fields()) { - address unpack_handler = vk->unpack_handler(); - assert(unpack_handler != NULL, "must be"); - __ far_call(RuntimeAddress(unpack_handler)); - // At this point, r0 points to the value object (for interpreter or C1 caller). - // The fields of the object are copied into registers (for C2 caller). - } + if (InlineTypeReturnedAsFields) { + // Check if we are returning an non-null inline type and load its fields into registers + ciType* return_type = compilation()->method()->return_type(); + if (return_type->is_inlinetype()) { + ciInlineKlass* vk = return_type->as_inline_klass(); + if (vk->can_be_returned_as_fields()) { + address unpack_handler = vk->unpack_handler(); + assert(unpack_handler != NULL, "must be"); + __ far_call(RuntimeAddress(unpack_handler)); + } + } else if (return_type->is_instance_klass() && (!return_type->is_loaded() || StressCallingConvention)) { + Label skip; + __ test_oop_is_not_inline_type(r0, rscratch2, skip); + + // Load fields from a buffered value with an inline class specific handler + __ load_klass(rscratch1 /*dst*/, r0 /*src*/); + __ ldr(rscratch1, Address(rscratch1, InstanceKlass::adr_inlineklass_fixed_block_offset())); + __ ldr(rscratch1, Address(rscratch1, InlineKlass::unpack_handler_offset())); + // Unpack handler can be null if inline type is not scalarizable in returns + __ cbz(rscratch1, skip); + __ blr(rscratch1); + + __ bind(skip); + } + // At this point, r0 points to the value object (for interpreter or C1 caller). + // The fields of the object are copied into registers (for C2 caller). } // Pop the stack before the safepoint code diff --git a/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp index f248b75c2d5..0302167f831 100644 --- a/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp @@ -361,8 +361,8 @@ int C1_MacroAssembler::scalarized_entry(const CompiledEntrySignature* ces, int f assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect"); generate_stack_overflow_check(bang_size_in_bytes); - GrowableArray* sig = &ces->sig(); - GrowableArray* sig_cc = is_inline_ro_entry ? &ces->sig_cc_ro() : &ces->sig_cc(); + GrowableArray* sig = ces->sig(); + GrowableArray* sig_cc = is_inline_ro_entry ? ces->sig_cc_ro() : ces->sig_cc(); VMRegPair* regs = ces->regs(); VMRegPair* regs_cc = is_inline_ro_entry ? ces->regs_cc_ro() : ces->regs_cc(); int args_on_stack = ces->args_on_stack(); diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp index 8ebd0000084..21260c42a0c 100644 --- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp @@ -777,7 +777,6 @@ void InterpreterMacroAssembler::remove_activation( bind(no_reserved_zone_enabling); } - if (state == atos && InlineTypeReturnedAsFields) { // Check if we are returning an non-null inline type and load its fields into registers Label skip; @@ -792,14 +791,13 @@ void InterpreterMacroAssembler::remove_activation( blr(rscratch1); #ifdef ASSERT - if (StressInlineTypeReturnedAsFields) { - // TODO 8284443 Enable this for value class returns (L-type descriptor) + // TODO 8284443 Enable + if (StressCallingConvention && false) { Label skip_stress; ldr(rscratch1, Address(rfp, frame::interpreter_frame_method_offset * wordSize)); - ldr(rscratch1, Address(rscratch1, Method::const_offset())); - ldrb(rscratch1, Address(rscratch1, ConstMethod::result_type_offset())); - cmpw(rscratch1, (u1) T_PRIMITIVE_OBJECT); - br(Assembler::NE, skip_stress); + ldrw(rscratch1, Address(rscratch1, Method::flags_offset())); + tstw(rscratch1, Method::scalarized_return_flag()); + br(Assembler::EQ, skip_stress); load_klass(r0, r0); orr(r0, r0, 1); bind(skip_stress); diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp index 374b0a7a954..8de1ecfa962 100644 --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp @@ -518,21 +518,36 @@ void LIR_Assembler::return_op(LIR_Opr result, C1SafepointPollStub* code_stub) { if (!result->is_illegal() && result->is_float_kind() && !result->is_xmm_register()) { assert(result->fpu() == 0, "result must already be on TOS"); } - - ciMethod* method = compilation()->method(); - if (InlineTypeReturnedAsFields && method->return_type()->is_inlinetype()) { - ciInlineKlass* vk = method->return_type()->as_inline_klass(); - if (vk->can_be_returned_as_fields()) { -#ifndef _LP64 - Unimplemented(); -#else - address unpack_handler = vk->unpack_handler(); - assert(unpack_handler != NULL, "must be"); - __ call(RuntimeAddress(unpack_handler)); - // At this point, rax points to the value object (for interpreter or C1 caller). - // The fields of the object are copied into registers (for C2 caller). -#endif + if (InlineTypeReturnedAsFields) { + #ifndef _LP64 + Unimplemented(); + #endif + // Check if we are returning an non-null inline type and load its fields into registers + ciType* return_type = compilation()->method()->return_type(); + if (return_type->is_inlinetype()) { + ciInlineKlass* vk = return_type->as_inline_klass(); + if (vk->can_be_returned_as_fields()) { + address unpack_handler = vk->unpack_handler(); + assert(unpack_handler != NULL, "must be"); + __ call(RuntimeAddress(unpack_handler)); + } + } else if (return_type->is_instance_klass() && (!return_type->is_loaded() || StressCallingConvention)) { + Label skip; + __ test_oop_is_not_inline_type(rax, rscratch1, skip); + + // Load fields from a buffered value with an inline class specific handler + __ load_klass(rdi, rax, rscratch1); + __ movptr(rdi, Address(rdi, InstanceKlass::adr_inlineklass_fixed_block_offset())); + __ movptr(rdi, Address(rdi, InlineKlass::unpack_handler_offset())); + // Unpack handler can be null if inline type is not scalarizable in returns + __ testptr(rdi, rdi); + __ jcc(Assembler::zero, skip); + __ call(rdi); + + __ bind(skip); } + // At this point, rax points to the value object (for interpreter or C1 caller). + // The fields of the object are copied into registers (for C2 caller). } // Pop the stack before the safepoint code diff --git a/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp index 71f6ff24226..eca979e6bb9 100644 --- a/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp @@ -379,8 +379,8 @@ int C1_MacroAssembler::scalarized_entry(const CompiledEntrySignature* ces, int f assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect"); generate_stack_overflow_check(bang_size_in_bytes); - GrowableArray* sig = &ces->sig(); - GrowableArray* sig_cc = is_inline_ro_entry ? &ces->sig_cc_ro() : &ces->sig_cc(); + GrowableArray* sig = ces->sig(); + GrowableArray* sig_cc = is_inline_ro_entry ? ces->sig_cc_ro() : ces->sig_cc(); VMRegPair* regs = ces->regs(); VMRegPair* regs_cc = is_inline_ro_entry ? ces->regs_cc_ro() : ces->regs_cc(); int args_on_stack = ces->args_on_stack(); diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp index ed96ca3576d..24fbcdf0201 100644 --- a/src/hotspot/cpu/x86/interp_masm_x86.cpp +++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp @@ -1192,14 +1192,13 @@ void InterpreterMacroAssembler::remove_activation( call(rdi); #endif #ifdef ASSERT - if (StressInlineTypeReturnedAsFields) { - // TODO 8284443 Enable this for value class returns (L-type descriptor) + // TODO 8284443 Enable + if (StressCallingConvention && false) { Label skip_stress; movptr(rscratch1, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); - movptr(rscratch1, Address(rscratch1, Method::const_offset())); - load_unsigned_byte(rscratch1, Address(rscratch1, ConstMethod::result_type_offset())); - cmpl(rscratch1, T_PRIMITIVE_OBJECT); - jcc(Assembler::notEqual, skip_stress); + movl(rscratch1, Address(rscratch1, Method::flags_offset())); + testl(rcx, Method::scalarized_return_flag()); + jcc(Assembler::zero, skip_stress); load_klass(rax, rax, rscratch1); orptr(rax, 1); bind(skip_stress); diff --git a/src/hotspot/share/c1/c1_Compilation.cpp b/src/hotspot/share/c1/c1_Compilation.cpp index 7ffc0f1a545..e8ace5369b6 100644 --- a/src/hotspot/share/c1/c1_Compilation.cpp +++ b/src/hotspot/share/c1/c1_Compilation.cpp @@ -598,6 +598,7 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho #endif { ResetNoHandleMark rnhm; // Huh? Required when doing class lookup of the Q-types + // TODO 8284443 Should only be computed once _compiled_entry_signature.compute_calling_conventions(false); } compile_method(); diff --git a/src/hotspot/share/c1/c1_LIR.cpp b/src/hotspot/share/c1/c1_LIR.cpp index af8a8cd3bef..c3601058342 100644 --- a/src/hotspot/share/c1/c1_LIR.cpp +++ b/src/hotspot/share/c1/c1_LIR.cpp @@ -1095,16 +1095,16 @@ bool LIR_OpJavaCall::maybe_return_as_fields(ciInlineKlass** vk_ret) const { return true; } } else if (return_type->is_instance_klass() && - (method()->is_method_handle_intrinsic() || - (!return_type->is_loaded() && !method()->holder()->is_loaded()))) { + (method()->is_method_handle_intrinsic() || !return_type->is_loaded() || + StressCallingConvention)) { // An inline type might be returned from the call but we don't know its type. - // This can happen with method handle intrinsics or when both the return type - // and the method holder are unloaded (and therefore the preload logic did not - // get a chance to load the return type). If an inline type is returned, we - // either get an oop to a buffer and nothing needs to be done or one of the - // values being returned is the klass of the inline type (RAX on x64, with LSB - // set to 1) and we need to allocate an inline type instance of that type and - // initialize it with other values being returned (in other registers). + // This can happen with method handle intrinsics or when the return type is + // not loaded (method holder is not loaded or preload attribute is missing). + // If an inline type is returned, we either get an oop to a buffer and nothing + // needs to be done or one of the values being returned is the klass of the + // inline type (RAX on x64, with LSB set to 1) and we need to allocate an inline + // type instance of that type and initialize it with the fields values being + // returned in other registers. return true; } } diff --git a/src/hotspot/share/ci/ciTypeFlow.cpp b/src/hotspot/share/ci/ciTypeFlow.cpp index 6271a706edf..f35b84a6675 100644 --- a/src/hotspot/share/ci/ciTypeFlow.cpp +++ b/src/hotspot/share/ci/ciTypeFlow.cpp @@ -767,7 +767,17 @@ void ciTypeFlow::StateVector::do_invoke(ciBytecodeStream* str, // ever sees a non-null value, loading has occurred. // // See do_getstatic() for similar explanation, as well as bug 4684993. - do_null_assert(return_type->as_klass()); + if (InlineTypeReturnedAsFields) { + // Return might be in scalarized form but we can't handle it because we + // don't know the type. This can happen due to a missing preload attribute. + // TODO 8284443 Use PhaseMacroExpand::expand_mh_intrinsic_return for this + trap(str, NULL, + Deoptimization::make_trap_request + (Deoptimization::Reason_uninitialized, + Deoptimization::Action_reinterpret)); + } else { + do_null_assert(return_type->as_klass()); + } } else { if (sigstr.is_null_free()) { return_type = outer()->mark_as_null_free(return_type); diff --git a/src/hotspot/share/code/compiledIC.cpp b/src/hotspot/share/code/compiledIC.cpp index 12555df500d..d4faa17bccc 100644 --- a/src/hotspot/share/code/compiledIC.cpp +++ b/src/hotspot/share/code/compiledIC.cpp @@ -634,6 +634,7 @@ void CompiledStaticCall::set(const StaticCallInfo& info) { // Compute settings for a CompiledStaticCall. Since we might have to set // the stub when calling to the interpreter, we need to return arguments. void CompiledStaticCall::compute_entry(const methodHandle& m, CompiledMethod* caller_nm, StaticCallInfo& info) { + assert(!m->mismatch(), "Mismatch for static call"); bool caller_is_nmethod = caller_nm->is_nmethod(); CompiledMethod* m_code = m->code(); info._callee = m; @@ -649,7 +650,6 @@ void CompiledStaticCall::compute_entry(const methodHandle& m, CompiledMethod* ca // puts a converter-frame on the stack to save arguments. assert(!m->is_method_handle_intrinsic(), "Compiled code should never call interpreter MH intrinsics"); info._to_interpreter = true; - if (caller_nm->is_compiled_by_c1()) { // C1 -> interp: values passed as oops info._entry = m()->get_c2i_inline_entry(); diff --git a/src/hotspot/share/code/dependencies.cpp b/src/hotspot/share/code/dependencies.cpp index 6909aa6b2d0..0a535279f88 100644 --- a/src/hotspot/share/code/dependencies.cpp +++ b/src/hotspot/share/code/dependencies.cpp @@ -1702,7 +1702,8 @@ Klass* Dependencies::check_evol_method(Method* m) { // Or is there a now a breakpoint? // (Assumes compiled code cannot handle bkpts; change if UseFastBreakpoints.) if (m->is_old() - || m->number_of_breakpoints() > 0) { + || m->number_of_breakpoints() > 0 + || m->mismatch()) { return m->method_holder(); } else { return NULL; diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index c305818384e..90bfa1b2408 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -3065,17 +3065,17 @@ void nmethod::print_nmethod_labels(outputStream* stream, address block_begin, bo // Print the arguments for the 3 types of verified entry points CompiledEntrySignature ces(m); - ces.compute_calling_conventions(); + ces.compute_calling_conventions(false); const GrowableArray* sig_cc; const VMRegPair* regs; if (block_begin == verified_entry_point()) { - sig_cc = &ces.sig_cc(); + sig_cc = ces.sig_cc(); regs = ces.regs_cc(); } else if (block_begin == verified_inline_entry_point()) { - sig_cc = &ces.sig(); + sig_cc = ces.sig(); regs = ces.regs(); } else if (block_begin == verified_inline_ro_entry_point()) { - sig_cc = &ces.sig_cc_ro(); + sig_cc = ces.sig_cc_ro(); regs = ces.regs_cc_ro(); } else { return; diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp index b0ad2020bcd..53de13a68f3 100644 --- a/src/hotspot/share/oops/method.hpp +++ b/src/hotspot/share/oops/method.hpp @@ -98,6 +98,7 @@ class Method : public Metadata { _scoped = 1 << 11, _changes_current_thread = 1 << 12, _jvmti_mount_transition = 1 << 13, + _mismatch = 1 << 14 }; mutable u2 _flags; @@ -931,13 +932,17 @@ class Method : public Metadata { _flags = x ? (_flags | _scalarized_return) : (_flags & ~_scalarized_return); } + static u2 scalarized_return_flag() { + return _scalarized_return; + } + bool is_scalarized_arg(int idx) const; - bool c1_needs_stack_repair() { + bool c1_needs_stack_repair() const { return (_flags & _c1_needs_stack_repair) != 0; } - bool c2_needs_stack_repair() { + bool c2_needs_stack_repair() const { return (_flags & _c2_needs_stack_repair) != 0; } @@ -949,6 +954,14 @@ class Method : public Metadata { _flags = x ? (_flags | _c2_needs_stack_repair) : (_flags & ~_c2_needs_stack_repair); } + bool mismatch() const { + return (_flags & _mismatch) != 0; + } + + void set_mismatch(bool x) { + _flags = x ? (_flags | _mismatch) : (_flags & ~_mismatch); + } + JFR_ONLY(DEFINE_TRACE_FLAG_ACCESSOR;) ConstMethod::MethodType method_type() const { diff --git a/src/hotspot/share/opto/callGenerator.cpp b/src/hotspot/share/opto/callGenerator.cpp index 4a9dc0ad329..3eead47b196 100644 --- a/src/hotspot/share/opto/callGenerator.cpp +++ b/src/hotspot/share/opto/callGenerator.cpp @@ -710,7 +710,7 @@ void CallGenerator::do_late_inline_helper() { int arg_num = 0; for (uint i1 = 0; i1 < nargs; i1++) { const Type* t = domain_sig->field_at(TypeFunc::Parms + i1); - if (t->is_inlinetypeptr() && method()->is_scalarized_arg(arg_num)) { + if (t->is_inlinetypeptr() && !method()->get_Method()->mismatch() && method()->is_scalarized_arg(arg_num)) { // Inline type arguments are not passed by reference: we get an argument per // field of the inline type. Build InlineTypeNodes from the inline type arguments. GraphKit arg_kit(jvms, &gvn); diff --git a/src/hotspot/share/opto/doCall.cpp b/src/hotspot/share/opto/doCall.cpp index 3dd000402dd..076d468205c 100644 --- a/src/hotspot/share/opto/doCall.cpp +++ b/src/hotspot/share/opto/doCall.cpp @@ -776,7 +776,7 @@ void Parse::do_call() { if (is_reference_type(ct)) { record_profiled_return_for_speculation(); } - if (rtype->basic_type() == T_PRIMITIVE_OBJECT && !peek()->is_InlineType()) { + if (rtype->is_inlinetype() && !peek()->is_InlineType()) { Node* retnode = pop(); retnode = InlineTypeNode::make_from_oop(this, retnode, rtype->as_inline_klass(), !gvn().type(retnode)->maybe_null()); push_node(T_PRIMITIVE_OBJECT, retnode); diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index 84345e0f8b3..8868cb628c5 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -1836,7 +1836,8 @@ void GraphKit::set_arguments_for_java_call(CallJavaNode* call, bool is_late_inli for (uint i = TypeFunc::Parms, idx = TypeFunc::Parms; i < nargs; i++) { Node* arg = argument(i-TypeFunc::Parms); const Type* t = domain->field_at(i); - if (t->is_inlinetypeptr() && call->method()->is_scalarized_arg(arg_num)) { + // TODO 8284443 A static call to a mismatched method should still be scalarized + if (t->is_inlinetypeptr() && !call->method()->get_Method()->mismatch() && call->method()->is_scalarized_arg(arg_num)) { // We don't pass inline type arguments by reference but instead pass each field of the inline type if (!arg->is_InlineType()) { assert(_gvn.type(arg)->is_zero_type() && !t->inline_klass()->is_null_free(), "Unexpected argument type"); @@ -1848,6 +1849,9 @@ void GraphKit::set_arguments_for_java_call(CallJavaNode* call, bool is_late_inli // to be able to access the extended signature later via attached_method_before_pc(). // For example, see CompiledMethod::preserve_callee_argument_oops(). call->set_override_symbolic_info(true); + // Register an evol dependency on the callee method to make sure that this method is deoptimized and + // re-compiled with a non-scalarized calling convention if the callee method is later marked as mismatched. + C->dependencies()->assert_evol_method(call->method()); arg_num++; continue; } else if (arg->is_InlineType()) { @@ -1923,6 +1927,9 @@ Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_p ret = InlineTypeNode::make_from_multi(this, call, vk, base_input, false, call->method()->signature()->returns_null_free_inline_type()); } else { ret = _gvn.transform(new ProjNode(call, TypeFunc::Parms)); + if (call->method()->return_type()->is_inlinetype()) { + ret = InlineTypeNode::make_from_oop(this, ret, call->method()->return_type()->as_inline_klass(), call->method()->signature()->returns_null_free_inline_type()); + } } return ret; diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index 17cd6dcf017..9addc205663 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp @@ -703,6 +703,10 @@ Node *PhaseIdealLoop::conditional_move( Node *region ) { for (uint j = 1; j < region->req(); j++) { Node *proj = region->in(j); Node *inp = phi->in(j); + if (inp->isa_InlineType()) { + // TODO 8302217 This prevents PhiNode::push_inline_types_through + return NULL; + } if (get_ctrl(inp) == proj) { // Found local op cost++; // Check for a chain of dependent ops; these will all become diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp index e9a2cafd3fe..ed18678b8f2 100644 --- a/src/hotspot/share/opto/macro.cpp +++ b/src/hotspot/share/opto/macro.cpp @@ -2452,7 +2452,7 @@ void PhaseMacroExpand::expand_unlock_node(UnlockNode *unlock) { // An inline type might be returned from the call but we don't know its // type. Either we get a buffered inline type (and nothing needs to be done) -// or one of the inlines being returned is the klass of the inline type +// or one of the values being returned is the klass of the inline type // and we need to allocate an inline type instance of that type and // initialize it with other values being returned. In that case, we // first try a fast path allocation and initialize the value with the diff --git a/src/hotspot/share/opto/parse1.cpp b/src/hotspot/share/opto/parse1.cpp index 08f809935d9..b6941a97ac9 100644 --- a/src/hotspot/share/opto/parse1.cpp +++ b/src/hotspot/share/opto/parse1.cpp @@ -921,7 +921,7 @@ void Compile::return_values(JVMState* jvms) { // to the Return node as returned values. InlineTypeNode* vt = res->as_InlineType(); ret->add_req_batch(NULL, tf()->range_cc()->cnt() - TypeFunc::Parms); - if (vt->is_allocated(&kit.gvn()) && !StressInlineTypeReturnedAsFields) { + if (vt->is_allocated(&kit.gvn()) && !StressCallingConvention) { ret->init_req(TypeFunc::Parms, vt->get_oop()); } else { // Return the tagged klass pointer to signal scalarization to the caller diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp index f02ef99abc7..7a7b50b4c2e 100644 --- a/src/hotspot/share/opto/type.cpp +++ b/src/hotspot/share/opto/type.cpp @@ -6931,6 +6931,10 @@ const TypeFunc* TypeFunc::make(ciMethod* method, bool is_osr_compilation) { // type argument/return as a single slot), one based on the actual calling // convention (with an inline type argument/return as a list of its fields). bool has_scalar_args = method->has_scalarized_args() && !is_osr_compilation; + // Fall back to the non-scalarized calling convention when compiling a call via a mismatching method + if (method != C->method() && method->get_Method()->mismatch()) { + has_scalar_args = false; + } const TypeTuple* domain_sig = is_osr_compilation ? osr_domain() : TypeTuple::make_domain(method, ignore_interfaces, false); const TypeTuple* domain_cc = has_scalar_args ? TypeTuple::make_domain(method, ignore_interfaces, true) : domain_sig; ciSignature* sig = method->signature(); diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index 7d39151a144..57204e8dd87 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -2002,8 +2002,8 @@ const int ObjectAlignmentInBytes = 8; product_pd(bool, InlineTypeReturnedAsFields, \ "Return fields instead of an inline type reference") \ \ - develop(bool, StressInlineTypeReturnedAsFields, false, \ - "Stress return of fields instead of an inline type reference") \ + develop(bool, StressCallingConvention, false, \ + "Stress the scalarized calling convention.") \ \ product(bool, UseArrayMarkWordCheck, NOT_LP64(false) LP64_ONLY(true), \ "Use bits in the mark word to check for flat/null-free arrays") \ diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index d82a6745832..e2f7ede4717 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -1267,11 +1267,6 @@ Handle SharedRuntime::find_callee_info_helper(vframeStream& vfst, Bytecodes::Cod frame stubFrame = current->last_frame(); // Caller-frame is a compiled frame frame callerFrame = stubFrame.sender(®_map2); - bool caller_is_c1 = false; - - if (callerFrame.is_compiled_frame()) { - caller_is_c1 = callerFrame.cb()->is_compiled_by_c1(); - } Method* callee = attached_method(); if (callee == NULL) { @@ -1280,9 +1275,11 @@ Handle SharedRuntime::find_callee_info_helper(vframeStream& vfst, Bytecodes::Cod THROW_(vmSymbols::java_lang_NoSuchMethodException(), nullHandle); } } + bool caller_is_c1 = callerFrame.is_compiled_frame() && callerFrame.cb()->is_compiled_by_c1(); if (!caller_is_c1 && callee->is_scalarized_arg(0)) { // If the receiver is an inline type that is passed as fields, no oop is available // Resolve the call without receiver null checking. + assert(!callee->mismatch(), "calls with inline type receivers should never mismatch"); assert(attached_method.not_null() && !attached_method->is_abstract(), "must have non-abstract attached method"); if (bc == Bytecodes::_invokeinterface) { bc = Bytecodes::_invokevirtual; // C2 optimistically replaces interface calls by virtual calls @@ -1338,7 +1335,7 @@ Handle SharedRuntime::find_callee_info_helper(vframeStream& vfst, Bytecodes::Cod return receiver; } -methodHandle SharedRuntime::find_callee_method(TRAPS) { +methodHandle SharedRuntime::find_callee_method(bool is_optimized, bool& caller_is_c1, TRAPS) { JavaThread* current = THREAD; ResourceMark rm(current); // We need first to check if any Java activations (compiled, interpreted) @@ -1364,6 +1361,10 @@ methodHandle SharedRuntime::find_callee_method(TRAPS) { Bytecodes::Code bc; CallInfo callinfo; find_callee_info_helper(vfst, bc, callinfo, CHECK_(methodHandle())); + // Calls via mismatching methods are always non-scalarized + if (callinfo.resolved_method()->mismatch() && !is_optimized) { + caller_is_c1 = true; + } callee_method = methodHandle(current, callinfo.selected_method()); } assert(callee_method()->is_method(), "must be"); @@ -1371,7 +1372,7 @@ methodHandle SharedRuntime::find_callee_method(TRAPS) { } // Resolves a call. -methodHandle SharedRuntime::resolve_helper(bool is_virtual, bool is_optimized, bool* caller_is_c1, TRAPS) { +methodHandle SharedRuntime::resolve_helper(bool is_virtual, bool is_optimized, bool& caller_is_c1, TRAPS) { methodHandle callee_method; callee_method = resolve_sub_helper(is_virtual, is_optimized, caller_is_c1, THREAD); if (JvmtiExport::can_hotswap_or_post_breakpoint()) { @@ -1398,7 +1399,7 @@ methodHandle SharedRuntime::resolve_helper(bool is_virtual, bool is_optimized, b // This fails if resolution required refilling of IC stubs bool SharedRuntime::resolve_sub_helper_internal(methodHandle callee_method, const frame& caller_frame, - CompiledMethod* caller_nm, bool is_virtual, bool is_optimized, + CompiledMethod* caller_nm, bool is_virtual, bool is_optimized, bool& caller_is_c1, Handle receiver, CallInfo& call_info, Bytecodes::Code invoke_code, TRAPS) { StaticCallInfo static_call_info; CompiledICInfo virtual_call_info; @@ -1420,7 +1421,6 @@ bool SharedRuntime::resolve_sub_helper_internal(methodHandle callee_method, cons #endif bool is_nmethod = caller_nm->is_nmethod(); - bool caller_is_c1 = caller_nm->is_compiled_by_c1(); if (is_virtual) { Klass* receiver_klass = NULL; @@ -1490,7 +1490,7 @@ bool SharedRuntime::resolve_sub_helper_internal(methodHandle callee_method, cons // Resolves a call. The compilers generate code for calls that go here // and are patched with the real destination of the call. -methodHandle SharedRuntime::resolve_sub_helper(bool is_virtual, bool is_optimized, bool* caller_is_c1, TRAPS) { +methodHandle SharedRuntime::resolve_sub_helper(bool is_virtual, bool is_optimized, bool& caller_is_c1, TRAPS) { JavaThread* current = THREAD; ResourceMark rm(current); RegisterMap cbl_map(current, @@ -1502,7 +1502,6 @@ methodHandle SharedRuntime::resolve_sub_helper(bool is_virtual, bool is_optimize CodeBlob* caller_cb = caller_frame.cb(); guarantee(caller_cb != NULL && caller_cb->is_compiled(), "must be called from compiled method"); CompiledMethod* caller_nm = caller_cb->as_compiled_method_or_null(); - *caller_is_c1 = caller_nm->is_compiled_by_c1(); // determine call info & receiver // note: a) receiver is NULL for static calls @@ -1511,6 +1510,10 @@ methodHandle SharedRuntime::resolve_sub_helper(bool is_virtual, bool is_optimize Bytecodes::Code invoke_code = Bytecodes::_illegal; Handle receiver = find_callee_info(invoke_code, call_info, CHECK_(methodHandle())); methodHandle callee_method(current, call_info.selected_method()); + // Calls via mismatching methods are always non-scalarized + if (caller_nm->is_compiled_by_c1() || (call_info.resolved_method()->mismatch() && !is_optimized)) { + caller_is_c1 = true; + } assert((!is_virtual && invoke_code == Bytecodes::_invokestatic ) || (!is_virtual && invoke_code == Bytecodes::_invokespecial) || @@ -1575,7 +1578,7 @@ methodHandle SharedRuntime::resolve_sub_helper(bool is_virtual, bool is_optimize for (;;) { ICRefillVerifier ic_refill_verifier; bool successful = resolve_sub_helper_internal(callee_method, caller_frame, caller_nm, - is_virtual, is_optimized, receiver, + is_virtual, is_optimized, caller_is_c1, receiver, call_info, invoke_code, CHECK_(methodHandle())); if (successful) { return callee_method; @@ -1710,10 +1713,10 @@ JRT_END // resolve a static call and patch code JRT_BLOCK_ENTRY(address, SharedRuntime::resolve_static_call_C(JavaThread* current )) methodHandle callee_method; - bool caller_is_c1; + bool caller_is_c1 = false; bool enter_special = false; JRT_BLOCK - callee_method = SharedRuntime::resolve_helper(false, false, &caller_is_c1, CHECK_NULL); + callee_method = SharedRuntime::resolve_helper(false, false, caller_is_c1, CHECK_NULL); current->set_vm_result_2(callee_method()); if (current->is_interp_only_mode()) { @@ -1751,9 +1754,9 @@ JRT_END // resolve virtual call and update inline cache to monomorphic JRT_BLOCK_ENTRY(address, SharedRuntime::resolve_virtual_call_C(JavaThread* current)) methodHandle callee_method; - bool caller_is_c1; + bool caller_is_c1 = false; JRT_BLOCK - callee_method = SharedRuntime::resolve_helper(true, false, &caller_is_c1, CHECK_NULL); + callee_method = SharedRuntime::resolve_helper(true, false, caller_is_c1, CHECK_NULL); current->set_vm_result_2(callee_method()); JRT_BLOCK_END // return compiled code entry point after potential safepoints @@ -1768,9 +1771,9 @@ JRT_END // monomorphic, so it has no inline cache). Patch code to resolved target. JRT_BLOCK_ENTRY(address, SharedRuntime::resolve_opt_virtual_call_C(JavaThread* current)) methodHandle callee_method; - bool caller_is_c1; + bool caller_is_c1 = false; JRT_BLOCK - callee_method = SharedRuntime::resolve_helper(true, true, &caller_is_c1, CHECK_NULL); + callee_method = SharedRuntime::resolve_helper(true, true, caller_is_c1, CHECK_NULL); current->set_vm_result_2(callee_method()); JRT_BLOCK_END // return compiled code entry point after potential safepoints @@ -1837,7 +1840,7 @@ bool SharedRuntime::handle_ic_miss_helper_internal(Handle receiver, CompiledMeth receiver_klass, inline_cache->is_optimized(), false, caller_nm->is_nmethod(), - caller_nm->is_compiled_by_c1(), + caller_is_c1, info, CHECK_false); if (!inline_cache->set_to_monomorphic(info)) { needs_ic_stub_refill = true; @@ -1943,7 +1946,10 @@ methodHandle SharedRuntime::handle_ic_miss_helper(bool& is_optimized, bool& call frame caller_frame = current->last_frame().sender(®_map); CodeBlob* cb = caller_frame.cb(); CompiledMethod* caller_nm = cb->as_compiled_method(); - caller_is_c1 = caller_nm->is_compiled_by_c1(); + // Calls via mismatching methods are always non-scalarized + if (caller_nm->is_compiled_by_c1() || call_info.resolved_method()->mismatch()) { + caller_is_c1 = true; + } for (;;) { ICRefillVerifier ic_refill_verifier; @@ -2073,7 +2079,7 @@ methodHandle SharedRuntime::reresolve_call_site(bool& is_static_call, bool& is_o } } - methodHandle callee_method = find_callee_method(CHECK_(methodHandle())); + methodHandle callee_method = find_callee_method(is_optimized, caller_is_c1, CHECK_(methodHandle())); #ifndef PRODUCT Atomic::inc(&_wrong_method_ctr); @@ -2870,24 +2876,24 @@ void AdapterHandlerLibrary::initialize() { _no_arg_handler = create_adapter(no_arg_blob, no_args, true); CompiledEntrySignature obj_args; - SigEntry::add_entry(&obj_args.sig(), T_OBJECT, NULL); + SigEntry::add_entry(obj_args.sig(), T_OBJECT, NULL); obj_args.compute_calling_conventions(); _obj_arg_handler = create_adapter(obj_arg_blob, obj_args, true); CompiledEntrySignature int_args; - SigEntry::add_entry(&int_args.sig(), T_INT, NULL); + SigEntry::add_entry(int_args.sig(), T_INT, NULL); int_args.compute_calling_conventions(); _int_arg_handler = create_adapter(int_arg_blob, int_args, true); CompiledEntrySignature obj_int_args; - SigEntry::add_entry(&obj_int_args.sig(), T_OBJECT, NULL); - SigEntry::add_entry(&obj_int_args.sig(), T_INT, NULL); + SigEntry::add_entry(obj_int_args.sig(), T_OBJECT, NULL); + SigEntry::add_entry(obj_int_args.sig(), T_INT, NULL); obj_int_args.compute_calling_conventions(); _obj_int_arg_handler = create_adapter(obj_int_arg_blob, obj_int_args, true); CompiledEntrySignature obj_obj_args; - SigEntry::add_entry(&obj_obj_args.sig(), T_OBJECT, NULL); - SigEntry::add_entry(&obj_obj_args.sig(), T_OBJECT, NULL); + SigEntry::add_entry(obj_obj_args.sig(), T_OBJECT, NULL); + SigEntry::add_entry(obj_obj_args.sig(), T_OBJECT, NULL); obj_obj_args.compute_calling_conventions(); _obj_obj_arg_handler = create_adapter(obj_obj_arg_blob, obj_obj_args, true); @@ -2983,7 +2989,7 @@ CompiledEntrySignature::CompiledEntrySignature(Method* method) : _method(method), _num_inline_args(0), _has_inline_recv(false), _regs(NULL), _regs_cc(NULL), _regs_cc_ro(NULL), _args_on_stack(0), _args_on_stack_cc(0), _args_on_stack_cc_ro(0), - _c1_needs_stack_repair(false), _c2_needs_stack_repair(false) { + _c1_needs_stack_repair(false), _c2_needs_stack_repair(false), _supers(nullptr) { _sig = new GrowableArray((method != NULL) ? method->size_of_parameters() : 1); _sig_cc = new GrowableArray((method != NULL) ? method->size_of_parameters() : 1); _sig_cc_ro = new GrowableArray((method != NULL) ? method->size_of_parameters() : 1); @@ -3028,8 +3034,51 @@ CodeOffsets::Entries CompiledEntrySignature::c1_inline_ro_entry_type() const { } } +// Returns all super methods (transitive) in classes and interfaces that are overridden by the current method. +GrowableArray* CompiledEntrySignature::get_supers() { + if (_supers != nullptr) { + return _supers; + } + _supers = new GrowableArray(); + // Skip private, static, and methods + if (_method->is_private() || _method->is_static() || _method->is_object_constructor()) { + return _supers; + } + Symbol* name = _method->name(); + Symbol* signature = _method->signature(); + const Klass* holder = _method->method_holder()->super(); + Symbol* holder_name = holder->name(); + ThreadInVMfromUnknown tiv; + JavaThread* current = JavaThread::current(); + HandleMark hm(current); + Handle loader(current, _method->method_holder()->class_loader()); + + // Walk up the class hierarchy and search for super methods + while (holder != NULL) { + Method* super_method = holder->lookup_method(name, signature); + if (super_method == NULL) { + break; + } + if (!super_method->is_static() && !super_method->is_private() && + (!super_method->is_package_private() || + super_method->method_holder()->is_same_class_package(loader(), holder_name))) { + _supers->push(super_method); + } + holder = super_method->method_holder()->super(); + } + // Search interfaces for super methods + Array* interfaces = _method->method_holder()->transitive_interfaces(); + for (int i = 0; i < interfaces->length(); ++i) { + Method* m = interfaces->at(i)->lookup_method(name, signature); + if (m != NULL && !m->is_static() && m->is_public()) { + _supers->push(m); + } + } + return _supers; +} + +// Iterate over arguments and compute scalarized and non-scalarized signatures void CompiledEntrySignature::compute_calling_conventions(bool init) { - // Iterate over arguments and compute scalarized and non-scalarized signatures bool has_scalarized = false; if (_method != NULL) { InstanceKlass* holder = _method->method_holder(); @@ -3052,18 +3101,61 @@ void CompiledEntrySignature::compute_calling_conventions(bool init) { BasicType bt = ss.type(); if (bt == T_OBJECT || bt == T_PRIMITIVE_OBJECT) { InlineKlass* vk = ss.as_inline_klass(holder); - // TODO 8301007 Mismatch handling, we need to check parent method args (look at klassVtable::needs_new_vtable_entry) if (vk != NULL && vk->can_be_passed_as_fields() && (init || _method->is_scalarized_arg(arg_num))) { - _num_inline_args++; - has_scalarized = true; - int last = _sig_cc->length(); - int last_ro = _sig_cc_ro->length(); - _sig_cc->appendAll(vk->extended_sig()); - _sig_cc_ro->appendAll(vk->extended_sig()); - if (bt == T_OBJECT) { - // Nullable inline type argument, insert InlineTypeNode::IsInit field right after T_PRIMITIVE_OBJECT - _sig_cc->insert_before(last+1, SigEntry(T_BOOLEAN, -1, NULL)); - _sig_cc_ro->insert_before(last_ro+1, SigEntry(T_BOOLEAN, -1, NULL)); + // Check for a calling convention mismatch with super method(s) + bool scalar_super = false; + bool non_scalar_super = false; + GrowableArray* supers = get_supers(); + for (int i = 0; i < supers->length(); ++i) { + Method* super_method = supers->at(i); + if (super_method->is_scalarized_arg(arg_num)) { + scalar_super = true; + } else { + non_scalar_super = true; + } + } +#ifdef ASSERT + // Randomly enable below code paths for stress testing + bool stress = init && StressCallingConvention; + if (stress && (os::random() & 1) == 1) { + non_scalar_super = true; + if ((os::random() & 1) == 1) { + scalar_super = true; + } + } +#endif + if (non_scalar_super) { + // Found a super method with a non-scalarized argument. Fall back to the non-scalarized calling convention. + if (scalar_super) { + // Found non-scalar *and* scalar super methods. We can't handle both. + // Mark the scalar method as mismatch and re-compile call sites to use non-scalarized calling convention. + for (int i = 0; i < supers->length(); ++i) { + Method* super_method = supers->at(i); + if (super_method->is_scalarized_arg(arg_num) debug_only(|| (stress && (os::random() & 1) == 1))) { + super_method->set_mismatch(true); + MutexLocker ml(Compile_lock, Mutex::_safepoint_check_flag); + JavaThread* thread = JavaThread::current(); + HandleMark hm(thread); + methodHandle mh(thread, super_method); + CodeCache::flush_dependents_on_method(mh); + } + } + } + // Fall back to non-scalarized calling convention + SigEntry::add_entry(_sig_cc, T_OBJECT, ss.as_symbol()); + SigEntry::add_entry(_sig_cc_ro, T_OBJECT, ss.as_symbol()); + } else { + _num_inline_args++; + has_scalarized = true; + int last = _sig_cc->length(); + int last_ro = _sig_cc_ro->length(); + _sig_cc->appendAll(vk->extended_sig()); + _sig_cc_ro->appendAll(vk->extended_sig()); + if (bt == T_OBJECT) { + // Nullable inline type argument, insert InlineTypeNode::IsInit field right after T_PRIMITIVE_OBJECT + _sig_cc->insert_before(last+1, SigEntry(T_BOOLEAN, -1, NULL)); + _sig_cc_ro->insert_before(last_ro+1, SigEntry(T_BOOLEAN, -1, NULL)); + } } } else { SigEntry::add_entry(_sig_cc, T_OBJECT, ss.as_symbol()); @@ -3149,14 +3241,14 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& meth StubRoutines::throw_AbstractMethodError_entry(), wrong_method_abstract, wrong_method_abstract, wrong_method_abstract, wrong_method_abstract, wrong_method_abstract); - GrowableArray* heap_sig = new (mtInternal) GrowableArray(ces.sig_cc_ro().length(), mtInternal); - heap_sig->appendAll(&ces.sig_cc_ro()); + GrowableArray* heap_sig = new (mtInternal) GrowableArray(ces.sig_cc_ro()->length(), mtInternal); + heap_sig->appendAll(ces.sig_cc_ro()); entry->set_sig_cc(heap_sig); return entry; } // Lookup method signature's fingerprint - entry = lookup(&ces.sig_cc(), ces.has_inline_recv()); + entry = lookup(ces.sig_cc(), ces.has_inline_recv()); if (entry != NULL) { #ifdef ASSERT @@ -3199,15 +3291,15 @@ AdapterHandlerEntry* AdapterHandlerLibrary::create_adapter(AdapterBlob*& new_ada sizeof(buffer_locs)/sizeof(relocInfo)); // Make a C heap allocated version of the fingerprint to store in the adapter - AdapterFingerPrint* fingerprint = new AdapterFingerPrint(&ces.sig_cc(), ces.has_inline_recv()); + AdapterFingerPrint* fingerprint = new AdapterFingerPrint(ces.sig_cc(), ces.has_inline_recv()); MacroAssembler _masm(&buffer); AdapterHandlerEntry* entry = SharedRuntime::generate_i2c2i_adapters(&_masm, ces.args_on_stack(), - &ces.sig(), + ces.sig(), ces.regs(), - &ces.sig_cc(), + ces.sig_cc(), ces.regs_cc(), - &ces.sig_cc_ro(), + ces.sig_cc_ro(), ces.regs_cc_ro(), fingerprint, new_adapter, @@ -3215,8 +3307,8 @@ AdapterHandlerEntry* AdapterHandlerLibrary::create_adapter(AdapterBlob*& new_ada if (ces.has_scalarized_args()) { // Save a C heap allocated version of the scalarized signature and store it in the adapter - GrowableArray* heap_sig = new (mtInternal) GrowableArray(ces.sig_cc().length(), mtInternal); - heap_sig->appendAll(&ces.sig_cc()); + GrowableArray* heap_sig = new (mtInternal) GrowableArray(ces.sig_cc()->length(), mtInternal); + heap_sig->appendAll(ces.sig_cc()); entry->set_sig_cc(heap_sig); } diff --git a/src/hotspot/share/runtime/sharedRuntime.hpp b/src/hotspot/share/runtime/sharedRuntime.hpp index 84b36d25423..f2a2736c703 100644 --- a/src/hotspot/share/runtime/sharedRuntime.hpp +++ b/src/hotspot/share/runtime/sharedRuntime.hpp @@ -50,9 +50,9 @@ class SharedRuntime: AllStatic { private: static bool resolve_sub_helper_internal(methodHandle callee_method, const frame& caller_frame, - CompiledMethod* caller_nm, bool is_virtual, bool is_optimized, + CompiledMethod* caller_nm, bool is_virtual, bool is_optimized, bool& caller_is_c1, Handle receiver, CallInfo& call_info, Bytecodes::Code invoke_code, TRAPS); - static methodHandle resolve_sub_helper(bool is_virtual, bool is_optimized, bool* caller_is_c1, TRAPS); + static methodHandle resolve_sub_helper(bool is_virtual, bool is_optimized, bool& caller_is_c1, TRAPS); // Shared stub locations @@ -320,7 +320,7 @@ class SharedRuntime: AllStatic { // Resolves a call site- may patch in the destination of the call into the // compiled code. - static methodHandle resolve_helper(bool is_virtual, bool is_optimized, bool* caller_is_c1, TRAPS); + static methodHandle resolve_helper(bool is_virtual, bool is_optimized, bool& caller_is_c1, TRAPS); private: // deopt blob @@ -341,7 +341,7 @@ class SharedRuntime: AllStatic { static methodHandle handle_ic_miss_helper(bool& is_optimized, bool& caller_is_c1, TRAPS); // Find the method that called us. - static methodHandle find_callee_method(TRAPS); + static methodHandle find_callee_method(bool is_optimized, bool& caller_is_c1, TRAPS); static void monitor_enter_helper(oopDesc* obj, BasicLock* lock, JavaThread* thread); @@ -757,9 +757,9 @@ class CompiledEntrySignature : public StackObj { Method* _method; int _num_inline_args; bool _has_inline_recv; - GrowableArray *_sig; - GrowableArray *_sig_cc; - GrowableArray *_sig_cc_ro; + GrowableArray* _sig; + GrowableArray* _sig_cc; + GrowableArray* _sig_cc_ro; VMRegPair* _regs; VMRegPair* _regs_cc; VMRegPair* _regs_cc_ro; @@ -771,17 +771,19 @@ class CompiledEntrySignature : public StackObj { bool _c1_needs_stack_repair; bool _c2_needs_stack_repair; + GrowableArray* _supers; + public: Method* method() const { return _method; } // Used by Method::_from_compiled_inline_entry - GrowableArray& sig() const { return *_sig; } + GrowableArray* sig() const { return _sig; } // Used by Method::_from_compiled_entry - GrowableArray& sig_cc() const { return *_sig_cc; } + GrowableArray* sig_cc() const { return _sig_cc; } // Used by Method::_from_compiled_inline_ro_entry - GrowableArray& sig_cc_ro() const { return *_sig_cc_ro; } + GrowableArray* sig_cc_ro() const { return _sig_cc_ro; } VMRegPair* regs() const { return _regs; } VMRegPair* regs_cc() const { return _regs_cc; } @@ -799,6 +801,8 @@ class CompiledEntrySignature : public StackObj { bool c2_needs_stack_repair() const { return _c2_needs_stack_repair; } CodeOffsets::Entries c1_inline_ro_entry_type() const; + GrowableArray* get_supers(); + CompiledEntrySignature(Method* method = NULL); void compute_calling_conventions(bool init = true); }; diff --git a/src/hotspot/share/runtime/signature.cpp b/src/hotspot/share/runtime/signature.cpp index 975e9988695..8da3852c8e7 100644 --- a/src/hotspot/share/runtime/signature.cpp +++ b/src/hotspot/share/runtime/signature.cpp @@ -504,8 +504,9 @@ Symbol* SignatureStream::find_symbol() { } InlineKlass* SignatureStream::as_inline_klass(InstanceKlass* holder) { - ThreadInVMfromUnknown __tiv; + ThreadInVMfromUnknown tiv; JavaThread* THREAD = JavaThread::current(); + HandleMark hm(THREAD); Handle class_loader(THREAD, holder->class_loader()); Handle protection_domain(THREAD, holder->protection_domain()); Klass* k = as_klass(class_loader, protection_domain, SignatureStream::CachedOrNull, THREAD); diff --git a/test/hotspot/jtreg/compiler/c2/unloaded/TestInlineUnloaded.java b/test/hotspot/jtreg/compiler/c2/unloaded/TestInlineUnloaded.java index fe8047b9b62..6a547f9ab03 100644 --- a/test/hotspot/jtreg/compiler/c2/unloaded/TestInlineUnloaded.java +++ b/test/hotspot/jtreg/compiler/c2/unloaded/TestInlineUnloaded.java @@ -186,6 +186,7 @@ static void run(String testCaseName, Consumer processor) throws "-cp", "launcher.jar", "-XX:+IgnoreUnrecognizedVMOptions", "-showversion", "-XX:-TieredCompilation", "-Xbatch", + "-XX:-InlineTypeReturnedAsFields", // TODO Remove this once 8284443 fixed handling of unloaded return types "-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining", "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly,*TestNull::run", Launcher.class.getName(), testCaseName); diff --git a/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java b/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java index f2cad243325..da9ab34beb0 100644 --- a/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java +++ b/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java @@ -51,6 +51,7 @@ public TestInliningProtectionDomain(Class testClass, boolean compileBar) { if (compileBar) { commandLineNormal.add("-XX:CompileCommand=compileonly," + testClass.getName() + "::bar"); } + commandLineNormal.add("-XX:-InlineTypeReturnedAsFields"); // TODO Remove this once 8284443 fixed handling of unloaded return types runTest(); } diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMismatchHandling.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMismatchHandling.java new file mode 100644 index 00000000000..0c07d2f129a --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMismatchHandling.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2023, 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 8301007 + * @key randomness + * @summary Verify that mismatches of the preload attribute are properly handled in the calling convention. + * @library /test/lib /compiler/whitebox / + * @compile -XDenablePrimitiveClasses TestMismatchHandling.jcod TestMismatchHandling.java + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EnableValhalla -XX:+EnablePrimitiveClasses -Xbatch + * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:-Inline -XX:-InlineAccessors -XX:-UseBimorphicInlining -XX:-UseCHA -XX:-UseTypeProfile + * -XX:CompileCommand=compileonly,TestMismatchHandling::test* + * TestMismatchHandling + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EnableValhalla -XX:+EnablePrimitiveClasses -Xbatch + * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:-Inline -XX:-InlineAccessors -XX:-UseBimorphicInlining -XX:-UseCHA -XX:-UseTypeProfile + * -XX:CompileCommand=compileonly,*::method + * TestMismatchHandling + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EnableValhalla -XX:+EnablePrimitiveClasses -Xbatch + * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:-Inline -XX:-InlineAccessors -XX:-UseBimorphicInlining -XX:-UseCHA -XX:-UseTypeProfile + * TestMismatchHandling + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EnableValhalla -XX:+EnablePrimitiveClasses -Xbatch + * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:-Inline -XX:-InlineAccessors -XX:-UseBimorphicInlining -XX:-UseCHA -XX:-UseTypeProfile + * -XX:-InlineTypePassFieldsAsArgs + * TestMismatchHandling + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EnableValhalla -XX:+EnablePrimitiveClasses -Xbatch + * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:-Inline -XX:-InlineAccessors -XX:-UseBimorphicInlining -XX:-UseCHA -XX:-UseTypeProfile + * -XX:-InlineTypeReturnedAsFields + * TestMismatchHandling + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EnableValhalla -XX:+EnablePrimitiveClasses -Xbatch + * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:+DeoptimizeNMethodBarriersALot + * TestMismatchHandling + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+EnableValhalla -XX:+EnablePrimitiveClasses -Xbatch + * -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * TestMismatchHandling + */ + +// ##################################### WARNING ###################################### +// Use below script to re-generate TestMismatchHandling.jcod, don't modify it manually. +// Be careful when changing anything (even the order) in this test and related files. +// ##################################### WARNING ###################################### + +/* + #!/bin/bash + export PATH=/oracle/valhalla/build/fastdebug/jdk/bin/:$PATH + ASMTOOLS=/oracle/valhalla/open/test/lib + + # With preload attribute + javac TestMismatchHandlingGenerator.java + java -cp $ASMTOOLS org.openjdk.asmtools.Main jdec MyValue1.class MyValue2.class MyValue3.class MyValue4.class MyValue5.class MyValue6.class MyValue7.class Verifiable.class B.class I3.class I4.class E.class G.class J.class K.class L.class P.class Q.class R.class S.class TestMismatchHandlingHelper.class > TestMismatchHandling.jcod + + # Without preload attribute + sed -i 's/value class MyValue/class MyValue/g' TestMismatchHandlingGenerator.java + javac TestMismatchHandlingGenerator.java + java -cp $ASMTOOLS org.openjdk.asmtools.Main jdec A.class C.class I1.class I2.class D.class F.class H.class I5.class M.class N.class O.class I6.class P.class >> TestMismatchHandling.jcod + + sed -i 's/class MyValue/value class MyValue/g' TestMismatchHandlingGenerator.java +*/ + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; + +import jdk.test.lib.Utils; +import jdk.test.whitebox.WhiteBox; + +public class TestMismatchHandling { + public static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + + public static void main(String[] args) throws Exception { + M m = new M(); + // Make sure M::method is C1 compiled once with unloaded MyValue4 and not re-compiled + for (int i = 0; i < 1000; ++i) { + TestMismatchHandlingHelper.test4(m, true); + } + Method disable = M.class.getDeclaredMethod("method", boolean.class); + WHITE_BOX.makeMethodNotCompilable(disable, 1, false); + WHITE_BOX.makeMethodNotCompilable(disable, 2, false); + WHITE_BOX.makeMethodNotCompilable(disable, 3, false); + WHITE_BOX.makeMethodNotCompilable(disable, 4, false); + + // Sometimes, exclude some methods from compilation with C2 to stress test the calling convention + // WARNING: This triggers class loading of argument/return types of all methods! + if (Utils.getRandomInstance().nextBoolean()) { + ArrayList methods = new ArrayList(); + Collections.addAll(methods, TestMismatchHandlingHelper.class.getDeclaredMethods()); + Collections.addAll(methods, A.class.getDeclaredMethods()); + Collections.addAll(methods, B.class.getDeclaredMethods()); + Collections.addAll(methods, C.class.getDeclaredMethods()); + Collections.addAll(methods, E.class.getDeclaredMethods()); + Collections.addAll(methods, F.class.getDeclaredMethods()); + Collections.addAll(methods, G.class.getDeclaredMethods()); + Collections.addAll(methods, H.class.getDeclaredMethods()); + Collections.addAll(methods, J.class.getDeclaredMethods()); + Collections.addAll(methods, K.class.getDeclaredMethods()); + Collections.addAll(methods, L.class.getDeclaredMethods()); + // Don't do this because it would load MyValue5 + // Collections.addAll(methods, N.class.getDeclaredMethods()); + System.out.println("Excluding methods from C2 compilation:"); + for (Method method : methods) { + if (Utils.getRandomInstance().nextBoolean()) { + System.out.println(method); + WHITE_BOX.makeMethodNotCompilable(method, 4, false); + } + } + } + + A a = new A(); + B b = new B(); + C c = new C(); + D d = new D(); + E e = new E(); + H h = new H(); + J j = new J(); + K k = new K(); + N n = new N(); + O o = new O(); + P p = new P(); + Q q = new Q(); + R r = new R(); + + // Warmup + for (int i = 0; i < 50_000; ++i) { + TestMismatchHandlingHelper.test1(a, a, a, b, c, b, b, c); + TestMismatchHandlingHelper.test1(b, a, a, b, c, b, b, c); + TestMismatchHandlingHelper.test1(c, b, a, b, c, c, b, c); + TestMismatchHandlingHelper.test2(d, d, d, d, d, d, d, d, d, d, d, d, e, e, e, e, e, e, e, e, e, e, e, e, d, e); + TestMismatchHandlingHelper.test2(d, d, d, d, d, d, d, d, d, d, d, d, e, e, e, e, e, e, e, e, e, e, e, e, d, e); + TestMismatchHandlingHelper.test3(h, h, h, j, k, j, k, j, h, k); + TestMismatchHandlingHelper.test3(h, h, h, j, k, j, k, k, h, k); + TestMismatchHandlingHelper.test4(m, true); + TestMismatchHandlingHelper.test5(n, true); + TestMismatchHandlingHelper.test7(o, true); + TestMismatchHandlingHelper.test8(p, p, p, q, r, q, r, q, p, r); + TestMismatchHandlingHelper.test8(p, p, p, q, r, q, r, r, p, r); + } + + // Only load these now + F f = new F(); + G g = new G(); + L l = new L(); + S s = new S(); + + for (int i = 0; i < 50_000; ++i) { + TestMismatchHandlingHelper.test1(a, a, a, b, c, b, b, c); + TestMismatchHandlingHelper.test1(b, a, a, b, c, b, b, c); + TestMismatchHandlingHelper.test1(c, b, a, b, c, c, b, c); + TestMismatchHandlingHelper.test2(d, f, g, d, f, d, d, f, g, d, f, d, e, f, g, e, f, g, e, f, g, e, f, g, d, e); + TestMismatchHandlingHelper.test2(d, f, g, d, f, f, d, f, g, d, f, f, e, f, g, e, f, f, e, f, g, e, f, f, d, e); + TestMismatchHandlingHelper.test2(d, f, g, f, g, g, d, f, g, f, g, g, e, f, g, f, g, g, e, f, g, f, g, g, d, e); + TestMismatchHandlingHelper.test3(h, l, h, j, k, j, k, j, h, k); + TestMismatchHandlingHelper.test3(h, l, h, j, k, k, k, k, h, k); + TestMismatchHandlingHelper.test3(h, l, l, j, k, k, l, l, h, l); + TestMismatchHandlingHelper.test4(m, false); + TestMismatchHandlingHelper.test5(n, false); + TestMismatchHandlingHelper.test6(f, g, l); + TestMismatchHandlingHelper.test7TriggerCalleeCompilation(o); + TestMismatchHandlingHelper.test8(p, s, p, q, r, q, r, q, p, r); + TestMismatchHandlingHelper.test8(p, s, p, q, r, r, r, r, p, r); + TestMismatchHandlingHelper.test8(p, s, s, q, r, r, s, s, p, s); + } + TestMismatchHandlingHelper.test7(o, false).verify(); + + switch (Utils.getRandomInstance().nextInt() % 3) { + case 0: + TestMismatchHandlingHelper.test2(d, d, d, d, d, d, d, d, d, d, d, d, e, e, e, e, e, e, e, e, e, e, e, e, d, e); + TestMismatchHandlingHelper.test3(l, h, l, k, l, l, j, j, h, l); + TestMismatchHandlingHelper.test8(s, p, s, r, s, s, q, q, p, s); + break; + case 1: + TestMismatchHandlingHelper.test2(f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, f, d, e); + TestMismatchHandlingHelper.test3(l, h, l, l, j, j, k, l, h, l); + TestMismatchHandlingHelper.test8(s, p, s, s, q, q, r, s, p, s); + break; + case 2: + TestMismatchHandlingHelper.test2(g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, g, d, e); + TestMismatchHandlingHelper.test3(l, h, l, j, k, k, l, j, h, l); + TestMismatchHandlingHelper.test8(s, p, s, q, r, r, s, q, p, s); + break; + } + } +} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMismatchHandling.jcod b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMismatchHandling.jcod new file mode 100644 index 00000000000..f136002c7fa --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMismatchHandling.jcod @@ -0,0 +1,3812 @@ +/* + * Copyright (c) 2023, 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. + */ + +// ##################################### WARNING ######################################## +// Generated file, don't modify manually. See TestMismatchHandling.java for instructions. +// ##################################### WARNING ######################################## + +class MyValue1 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "MyValue1"; // #2 + Field #1 #4; // #3 + NameAndType #5 #6; // #4 + Utf8 "x"; // #5 + Utf8 "I"; // #6 + class #8; // #7 + Utf8 "java/lang/RuntimeException"; // #8 + String #10; // #9 + Utf8 "Verification failed"; // #10 + Method #7 #12; // #11 + NameAndType #13 #14; // #12 + Utf8 ""; // #13 + Utf8 "(Ljava/lang/String;)V"; // #14 + class #16; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "verify"; // #17 + Utf8 "()V"; // #18 + Utf8 "Code"; // #19 + Utf8 "LineNumberTable"; // #20 + Utf8 "StackMapTable"; // #21 + Utf8 ""; // #22 + Utf8 "()LMyValue1;"; // #23 + Utf8 "SourceFile"; // #24 + Utf8 "TestMismatchHandlingGenerator.java"; // #25 + } // Constant Pool + + 0x0050; // access + #1;// this_cpx + #15;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + { // field + 0x0010; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #17; // name_index + #18; // descriptor_index + [] { // Attributes + Attr(#19) { // Code + 3; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB40003102A9F00; + 0x0DBB0007591209B7; + 0x000BBFB1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // line_number_table + 0 28; + 9 29; + 19 31; + } + } // end LineNumberTable + ; + Attr(#21) { // StackMapTable + [] { // + 19b; // same_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0008; // access + #22; // name_index + #23; // descriptor_index + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xCB00014B102A2A5F; + 0xCC00034B2AB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // line_number_table + 0 24; + 4 25; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#24) { // SourceFile + #25; + } // end SourceFile + } // Attributes +} // end class MyValue1 +class MyValue2 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "MyValue2"; // #2 + Field #1 #4; // #3 + NameAndType #5 #6; // #4 + Utf8 "x"; // #5 + Utf8 "I"; // #6 + class #8; // #7 + Utf8 "java/lang/RuntimeException"; // #8 + String #10; // #9 + Utf8 "Verification failed"; // #10 + Method #7 #12; // #11 + NameAndType #13 #14; // #12 + Utf8 ""; // #13 + Utf8 "(Ljava/lang/String;)V"; // #14 + class #16; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "verify"; // #17 + Utf8 "()V"; // #18 + Utf8 "Code"; // #19 + Utf8 "LineNumberTable"; // #20 + Utf8 "StackMapTable"; // #21 + Utf8 ""; // #22 + Utf8 "()LMyValue2;"; // #23 + Utf8 "SourceFile"; // #24 + Utf8 "TestMismatchHandlingGenerator.java"; // #25 + } // Constant Pool + + 0x0050; // access + #1;// this_cpx + #15;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + { // field + 0x0010; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #17; // name_index + #18; // descriptor_index + [] { // Attributes + Attr(#19) { // Code + 3; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB40003102A9F00; + 0x0DBB0007591209B7; + 0x000BBFB1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // line_number_table + 0 38; + 9 39; + 19 41; + } + } // end LineNumberTable + ; + Attr(#21) { // StackMapTable + [] { // + 19b; // same_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0008; // access + #22; // name_index + #23; // descriptor_index + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xCB00014B102A2A5F; + 0xCC00034B2AB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // line_number_table + 0 34; + 4 35; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#24) { // SourceFile + #25; + } // end SourceFile + } // Attributes +} // end class MyValue2 +class MyValue3 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "MyValue3"; // #2 + Field #1 #4; // #3 + NameAndType #5 #6; // #4 + Utf8 "x"; // #5 + Utf8 "I"; // #6 + class #8; // #7 + Utf8 "java/lang/RuntimeException"; // #8 + String #10; // #9 + Utf8 "Verification failed"; // #10 + Method #7 #12; // #11 + NameAndType #13 #14; // #12 + Utf8 ""; // #13 + Utf8 "(Ljava/lang/String;)V"; // #14 + class #16; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "verify"; // #17 + Utf8 "()V"; // #18 + Utf8 "Code"; // #19 + Utf8 "LineNumberTable"; // #20 + Utf8 "StackMapTable"; // #21 + Utf8 ""; // #22 + Utf8 "()LMyValue3;"; // #23 + Utf8 "SourceFile"; // #24 + Utf8 "TestMismatchHandlingGenerator.java"; // #25 + } // Constant Pool + + 0x0050; // access + #1;// this_cpx + #15;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + { // field + 0x0010; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #17; // name_index + #18; // descriptor_index + [] { // Attributes + Attr(#19) { // Code + 3; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB40003102A9F00; + 0x0DBB0007591209B7; + 0x000BBFB1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // line_number_table + 0 48; + 9 49; + 19 51; + } + } // end LineNumberTable + ; + Attr(#21) { // StackMapTable + [] { // + 19b; // same_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0008; // access + #22; // name_index + #23; // descriptor_index + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xCB00014B102A2A5F; + 0xCC00034B2AB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // line_number_table + 0 44; + 4 45; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#24) { // SourceFile + #25; + } // end SourceFile + } // Attributes +} // end class MyValue3 +class MyValue4 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "MyValue4"; // #2 + Field #1 #4; // #3 + NameAndType #5 #6; // #4 + Utf8 "x"; // #5 + Utf8 "I"; // #6 + class #8; // #7 + Utf8 "java/lang/RuntimeException"; // #8 + String #10; // #9 + Utf8 "Verification failed"; // #10 + Method #7 #12; // #11 + NameAndType #13 #14; // #12 + Utf8 ""; // #13 + Utf8 "(Ljava/lang/String;)V"; // #14 + Method #1 #16; // #15 + NameAndType #17 #18; // #16 + Utf8 ""; // #17 + Utf8 "()LMyValue4;"; // #18 + class #20; // #19 + Utf8 "java/lang/Object"; // #20 + Utf8 "verify"; // #21 + Utf8 "()V"; // #22 + Utf8 "Code"; // #23 + Utf8 "LineNumberTable"; // #24 + Utf8 "StackMapTable"; // #25 + Utf8 "make"; // #26 + Utf8 "SourceFile"; // #27 + Utf8 "TestMismatchHandlingGenerator.java"; // #28 + } // Constant Pool + + 0x0050; // access + #1;// this_cpx + #19;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + { // field + 0x0010; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Fields + + [] { // Methods + { // method + 0x0001; // access + #21; // name_index + #22; // descriptor_index + [] { // Attributes + Attr(#23) { // Code + 3; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB40003102A9F00; + 0x0DBB0007591209B7; + 0x000BBFB1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // line_number_table + 0 58; + 9 59; + 19 61; + } + } // end LineNumberTable + ; + Attr(#25) { // StackMapTable + [] { // + 19b; // same_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0008; // access + #26; // name_index + #18; // descriptor_index + [] { // Attributes + Attr(#23) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0xB8000FB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // line_number_table + 0 64; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0008; // access + #17; // name_index + #18; // descriptor_index + [] { // Attributes + Attr(#23) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xCB00014B102A2A5F; + 0xCC00034B2AB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#24) { // LineNumberTable + [] { // line_number_table + 0 54; + 4 55; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#27) { // SourceFile + #28; + } // end SourceFile + } // Attributes +} // end class MyValue4 +class MyValue5 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "MyValue5"; // #2 + Field #1 #4; // #3 + NameAndType #5 #6; // #4 + Utf8 "x"; // #5 + Utf8 "I"; // #6 + class #8; // #7 + Utf8 "java/lang/RuntimeException"; // #8 + String #10; // #9 + Utf8 "Verification failed"; // #10 + Method #7 #12; // #11 + NameAndType #13 #14; // #12 + Utf8 ""; // #13 + Utf8 "(Ljava/lang/String;)V"; // #14 + Method #1 #16; // #15 + NameAndType #17 #18; // #16 + Utf8 ""; // #17 + Utf8 "()LMyValue5;"; // #18 + class #20; // #19 + Utf8 "java/lang/Object"; // #20 + class #22; // #21 + Utf8 "Verifiable"; // #22 + Utf8 "verify"; // #23 + Utf8 "()V"; // #24 + Utf8 "Code"; // #25 + Utf8 "LineNumberTable"; // #26 + Utf8 "StackMapTable"; // #27 + Utf8 "make"; // #28 + Utf8 "SourceFile"; // #29 + Utf8 "TestMismatchHandlingGenerator.java"; // #30 + } // Constant Pool + + 0x0050; // access + #1;// this_cpx + #19;// super_cpx + + [] { // Interfaces + #21; + } // Interfaces + + [] { // Fields + { // field + 0x0010; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Fields + + [] { // Methods + { // method + 0x0001; // access + #23; // name_index + #24; // descriptor_index + [] { // Attributes + Attr(#25) { // Code + 3; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB40003102A9F00; + 0x0DBB0007591209B7; + 0x000BBFB1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#26) { // LineNumberTable + [] { // line_number_table + 0 77; + 9 78; + 19 80; + } + } // end LineNumberTable + ; + Attr(#27) { // StackMapTable + [] { // + 19b; // same_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0008; // access + #28; // name_index + #18; // descriptor_index + [] { // Attributes + Attr(#25) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0xB8000FB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#26) { // LineNumberTable + [] { // line_number_table + 0 83; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0008; // access + #17; // name_index + #18; // descriptor_index + [] { // Attributes + Attr(#25) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xCB00014B102A2A5F; + 0xCC00034B2AB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#26) { // LineNumberTable + [] { // line_number_table + 0 72; + 4 73; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#29) { // SourceFile + #30; + } // end SourceFile + } // Attributes +} // end class MyValue5 +class MyValue6 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "MyValue6"; // #2 + Field #1 #4; // #3 + NameAndType #5 #6; // #4 + Utf8 "x"; // #5 + Utf8 "I"; // #6 + class #8; // #7 + Utf8 "java/lang/RuntimeException"; // #8 + String #10; // #9 + Utf8 "Verification failed"; // #10 + Method #7 #12; // #11 + NameAndType #13 #14; // #12 + Utf8 ""; // #13 + Utf8 "(Ljava/lang/String;)V"; // #14 + Method #1 #16; // #15 + NameAndType #17 #18; // #16 + Utf8 ""; // #17 + Utf8 "()LMyValue6;"; // #18 + class #20; // #19 + Utf8 "java/lang/Object"; // #20 + class #22; // #21 + Utf8 "Verifiable"; // #22 + Utf8 "verify"; // #23 + Utf8 "()V"; // #24 + Utf8 "Code"; // #25 + Utf8 "LineNumberTable"; // #26 + Utf8 "StackMapTable"; // #27 + Utf8 "make"; // #28 + Utf8 "SourceFile"; // #29 + Utf8 "TestMismatchHandlingGenerator.java"; // #30 + } // Constant Pool + + 0x0050; // access + #1;// this_cpx + #19;// super_cpx + + [] { // Interfaces + #21; + } // Interfaces + + [] { // Fields + { // field + 0x0010; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Fields + + [] { // Methods + { // method + 0x0001; // access + #23; // name_index + #24; // descriptor_index + [] { // Attributes + Attr(#25) { // Code + 3; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB40003102A9F00; + 0x0DBB0007591209B7; + 0x000BBFB1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#26) { // LineNumberTable + [] { // line_number_table + 0 92; + 9 93; + 19 95; + } + } // end LineNumberTable + ; + Attr(#27) { // StackMapTable + [] { // + 19b; // same_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0008; // access + #28; // name_index + #18; // descriptor_index + [] { // Attributes + Attr(#25) { // Code + 1; // max_stack + 0; // max_locals + Bytes[]{ + 0xB8000FB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#26) { // LineNumberTable + [] { // line_number_table + 0 98; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0008; // access + #17; // name_index + #18; // descriptor_index + [] { // Attributes + Attr(#25) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xCB00014B102A2A5F; + 0xCC00034B2AB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#26) { // LineNumberTable + [] { // line_number_table + 0 87; + 4 88; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#29) { // SourceFile + #30; + } // end SourceFile + } // Attributes +} // end class MyValue6 +class MyValue7 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "MyValue7"; // #2 + Field #1 #4; // #3 + NameAndType #5 #6; // #4 + Utf8 "x"; // #5 + Utf8 "I"; // #6 + class #8; // #7 + Utf8 "java/lang/RuntimeException"; // #8 + String #10; // #9 + Utf8 "Verification failed"; // #10 + Method #7 #12; // #11 + NameAndType #13 #14; // #12 + Utf8 ""; // #13 + Utf8 "(Ljava/lang/String;)V"; // #14 + class #16; // #15 + Utf8 "java/lang/Object"; // #16 + Utf8 "verify"; // #17 + Utf8 "()V"; // #18 + Utf8 "Code"; // #19 + Utf8 "LineNumberTable"; // #20 + Utf8 "StackMapTable"; // #21 + Utf8 ""; // #22 + Utf8 "()LMyValue7;"; // #23 + Utf8 "SourceFile"; // #24 + Utf8 "TestMismatchHandlingGenerator.java"; // #25 + } // Constant Pool + + 0x0050; // access + #1;// this_cpx + #15;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + { // field + 0x0010; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #17; // name_index + #18; // descriptor_index + [] { // Attributes + Attr(#19) { // Code + 3; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB40003102A9F00; + 0x0DBB0007591209B7; + 0x000BBFB1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // line_number_table + 0 106; + 9 107; + 19 109; + } + } // end LineNumberTable + ; + Attr(#21) { // StackMapTable + [] { // + 19b; // same_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0008; // access + #22; // name_index + #23; // descriptor_index + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0xCB00014B102A2A5F; + 0xCC00034B2AB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // line_number_table + 0 102; + 4 103; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#24) { // SourceFile + #25; + } // end SourceFile + } // Attributes +} // end class MyValue7 +class Verifiable { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "Verifiable"; // #2 + class #4; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 "verify"; // #5 + Utf8 "()V"; // #6 + Utf8 "SourceFile"; // #7 + Utf8 "TestMismatchHandlingGenerator.java"; // #8 + } // Constant Pool + + 0x0600; // access + #1;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0401; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#7) { // SourceFile + #8; + } // end SourceFile + } // Attributes +} // end class Verifiable +file "B.class" { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "A"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue1"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "B"; // #13 + Utf8 "Code"; // #14 + Utf8 "LineNumberTable"; // #15 + Utf8 "method"; // #16 + Utf8 "(LMyValue1;)LMyValue1;"; // #17 + Utf8 "SourceFile"; // #18 + Utf8 "TestMismatchHandlingGenerator.java"; // #19 + Utf8 "Preload"; // #20 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 119; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #16; // name_index + #17; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 122; + 4 123; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#18) { // SourceFile + #19; + } // end SourceFile + ; + Attr(#20) { // Preload + [] { // classes + #8; + } + } // end Preload + } // Attributes +} // end class B +class I3 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "I3"; // #2 + class #4; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 "method"; // #5 + Utf8 "(LMyValue2;)LMyValue2;"; // #6 + Utf8 "SourceFile"; // #7 + Utf8 "TestMismatchHandlingGenerator.java"; // #8 + Utf8 "Preload"; // #9 + class #11; // #10 + Utf8 "MyValue2"; // #11 + } // Constant Pool + + 0x0600; // access + #1;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0401; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#7) { // SourceFile + #8; + } // end SourceFile + ; + Attr(#9) { // Preload + [] { // classes + #10; + } + } // end Preload + } // Attributes +} // end class I3 +class I4 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "I4"; // #2 + class #4; // #3 + Utf8 "java/lang/Object"; // #4 + class #6; // #5 + Utf8 "I3"; // #6 + Utf8 "method"; // #7 + Utf8 "(LMyValue2;)LMyValue2;"; // #8 + Utf8 "SourceFile"; // #9 + Utf8 "TestMismatchHandlingGenerator.java"; // #10 + Utf8 "Preload"; // #11 + class #13; // #12 + Utf8 "MyValue2"; // #13 + } // Constant Pool + + 0x0600; // access + #1;// this_cpx + #3;// super_cpx + + [] { // Interfaces + #5; + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0401; // access + #7; // name_index + #8; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#9) { // SourceFile + #10; + } // end SourceFile + ; + Attr(#11) { // Preload + [] { // classes + #12; + } + } // end Preload + } // Attributes +} // end class I4 +class E { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue2"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "E"; // #13 + class #15; // #14 + Utf8 "I4"; // #15 + Utf8 "Code"; // #16 + Utf8 "LineNumberTable"; // #17 + Utf8 "method"; // #18 + Utf8 "(LMyValue2;)LMyValue2;"; // #19 + Utf8 "SourceFile"; // #20 + Utf8 "TestMismatchHandlingGenerator.java"; // #21 + Utf8 "Preload"; // #22 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + #14; + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 160; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #18; // name_index + #19; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 163; + 4 164; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#20) { // SourceFile + #21; + } // end SourceFile + ; + Attr(#22) { // Preload + [] { // classes + #8; + } + } // end Preload + } // Attributes +} // end class E +class G { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue2"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "G"; // #13 + class #15; // #14 + Utf8 "I2"; // #15 + class #17; // #16 + Utf8 "I4"; // #17 + Utf8 "Code"; // #18 + Utf8 "LineNumberTable"; // #19 + Utf8 "method"; // #20 + Utf8 "(LMyValue2;)LMyValue2;"; // #21 + Utf8 "SourceFile"; // #22 + Utf8 "TestMismatchHandlingGenerator.java"; // #23 + Utf8 "Preload"; // #24 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + #14; + #16; + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#18) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#19) { // LineNumberTable + [] { // line_number_table + 0 177; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #20; // name_index + #21; // descriptor_index + [] { // Attributes + Attr(#18) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#19) { // LineNumberTable + [] { // line_number_table + 0 180; + 4 181; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#22) { // SourceFile + #23; + } // end SourceFile + ; + Attr(#24) { // Preload + [] { // classes + #8; + } + } // end Preload + } // Attributes +} // end class G +class J { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue3"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "J"; // #13 + Utf8 "Code"; // #14 + Utf8 "LineNumberTable"; // #15 + Utf8 "method"; // #16 + Utf8 "(LMyValue3;)LMyValue3;"; // #17 + Utf8 "SourceFile"; // #18 + Utf8 "TestMismatchHandlingGenerator.java"; // #19 + Utf8 "Preload"; // #20 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 197; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #16; // name_index + #17; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 199; + 4 200; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#18) { // SourceFile + #19; + } // end SourceFile + ; + Attr(#20) { // Preload + [] { // classes + #8; + } + } // end Preload + } // Attributes +} // end class J +class K { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "J"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue3"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "K"; // #13 + Utf8 "Code"; // #14 + Utf8 "LineNumberTable"; // #15 + Utf8 "method"; // #16 + Utf8 "(LMyValue3;)LMyValue3;"; // #17 + Utf8 "SourceFile"; // #18 + Utf8 "TestMismatchHandlingGenerator.java"; // #19 + Utf8 "Preload"; // #20 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 204; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #16; // name_index + #17; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 207; + 4 208; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#18) { // SourceFile + #19; + } // end SourceFile + ; + Attr(#20) { // Preload + [] { // classes + #8; + } + } // end Preload + } // Attributes +} // end class K +file "L.class" { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "K"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue3"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "L"; // #13 + class #15; // #14 + Utf8 "I5"; // #15 + Utf8 "Code"; // #16 + Utf8 "LineNumberTable"; // #17 + Utf8 "method"; // #18 + Utf8 "(LMyValue3;)LMyValue3;"; // #19 + Utf8 "SourceFile"; // #20 + Utf8 "TestMismatchHandlingGenerator.java"; // #21 + Utf8 "Preload"; // #22 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + #14; + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 212; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #18; // name_index + #19; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 215; + 4 216; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#20) { // SourceFile + #21; + } // end SourceFile + ; + Attr(#22) { // Preload + [] { // classes + #8; + } + } // end Preload + } // Attributes +} // end class L +class P { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue7"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "P"; // #13 + class #15; // #14 + Utf8 "I6"; // #15 + Utf8 "Code"; // #16 + Utf8 "LineNumberTable"; // #17 + Utf8 "method"; // #18 + Utf8 "(LMyValue7;)LMyValue7;"; // #19 + Utf8 "SourceFile"; // #20 + Utf8 "TestMismatchHandlingGenerator.java"; // #21 + Utf8 "Preload"; // #22 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + #14; + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 263; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #18; // name_index + #19; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 266; + 4 267; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#20) { // SourceFile + #21; + } // end SourceFile + ; + Attr(#22) { // Preload + [] { // classes + #8; + } + } // end Preload + } // Attributes +} // end class P +class Q { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue7"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "Q"; // #13 + Utf8 "Code"; // #14 + Utf8 "LineNumberTable"; // #15 + Utf8 "method"; // #16 + Utf8 "(LMyValue7;)LMyValue7;"; // #17 + Utf8 "SourceFile"; // #18 + Utf8 "TestMismatchHandlingGenerator.java"; // #19 + Utf8 "Preload"; // #20 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 271; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0000; // access + #16; // name_index + #17; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 273; + 4 274; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#18) { // SourceFile + #19; + } // end SourceFile + ; + Attr(#20) { // Preload + [] { // classes + #8; + } + } // end Preload + } // Attributes +} // end class Q +class R { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "Q"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue7"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "R"; // #13 + Utf8 "Code"; // #14 + Utf8 "LineNumberTable"; // #15 + Utf8 "method"; // #16 + Utf8 "(LMyValue7;)LMyValue7;"; // #17 + Utf8 "SourceFile"; // #18 + Utf8 "TestMismatchHandlingGenerator.java"; // #19 + Utf8 "Preload"; // #20 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 278; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0000; // access + #16; // name_index + #17; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 281; + 4 282; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#18) { // SourceFile + #19; + } // end SourceFile + ; + Attr(#20) { // Preload + [] { // classes + #8; + } + } // end Preload + } // Attributes +} // end class R +class S { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "R"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue7"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "S"; // #13 + class #15; // #14 + Utf8 "I6"; // #15 + Utf8 "Code"; // #16 + Utf8 "LineNumberTable"; // #17 + Utf8 "method"; // #18 + Utf8 "(LMyValue7;)LMyValue7;"; // #19 + Utf8 "SourceFile"; // #20 + Utf8 "TestMismatchHandlingGenerator.java"; // #21 + Utf8 "Preload"; // #22 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + #14; + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 286; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #18; // name_index + #19; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 289; + 4 290; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#20) { // SourceFile + #21; + } // end SourceFile + ; + Attr(#22) { // Preload + [] { // classes + #8; + } + } // end Preload + } // Attributes +} // end class S +class TestMismatchHandlingHelper { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #12; // #9 + Utf8 "MyValue1"; // #10 + Utf8 ""; // #11 + Utf8 "()LMyValue1;"; // #12 + Method #14 #15; // #13 + class #16; // #14 + NameAndType #17 #18; // #15 + Utf8 "A"; // #16 + Utf8 "method"; // #17 + Utf8 "(LMyValue1;)LMyValue1;"; // #18 + Method #8 #20; // #19 + NameAndType #21 #6; // #20 + Utf8 "verify"; // #21 + Method #23 #15; // #22 + class #24; // #23 + Utf8 "B"; // #24 + Method #26 #15; // #25 + class #27; // #26 + Utf8 "C"; // #27 + Method #29 #30; // #28 + class #31; // #29 + NameAndType #11 #32; // #30 + Utf8 "MyValue2"; // #31 + Utf8 "()LMyValue2;"; // #32 + InterfaceMethod #34 #35; // #33 + class #36; // #34 + NameAndType #17 #37; // #35 + Utf8 "I1"; // #36 + Utf8 "(LMyValue2;)LMyValue2;"; // #37 + Method #29 #20; // #38 + InterfaceMethod #40 #35; // #39 + class #41; // #40 + Utf8 "I2"; // #41 + Method #43 #35; // #42 + class #44; // #43 + Utf8 "D"; // #44 + InterfaceMethod #46 #35; // #45 + class #47; // #46 + Utf8 "I3"; // #47 + InterfaceMethod #49 #35; // #48 + class #50; // #49 + Utf8 "I4"; // #50 + Method #52 #35; // #51 + class #53; // #52 + Utf8 "E"; // #53 + Method #55 #56; // #54 + class #57; // #55 + NameAndType #11 #58; // #56 + Utf8 "MyValue3"; // #57 + Utf8 "()LMyValue3;"; // #58 + InterfaceMethod #60 #61; // #59 + class #62; // #60 + NameAndType #17 #63; // #61 + Utf8 "I5"; // #62 + Utf8 "(LMyValue3;)LMyValue3;"; // #63 + Method #55 #20; // #64 + Method #66 #61; // #65 + class #67; // #66 + Utf8 "H"; // #67 + Method #69 #61; // #68 + class #70; // #69 + Utf8 "J"; // #70 + Method #72 #61; // #71 + class #73; // #72 + Utf8 "K"; // #73 + Method #75 #76; // #74 + class #77; // #75 + NameAndType #17 #78; // #76 + Utf8 "M"; // #77 + Utf8 "(Z)LMyValue4;"; // #78 + Field #80 #81; // #79 + class #82; // #80 + NameAndType #83 #84; // #81 + Utf8 "MyValue4"; // #82 + Utf8 "x"; // #83 + Utf8 "I"; // #84 + class #86; // #85 + Utf8 "java/lang/RuntimeException"; // #86 + String #88; // #87 + Utf8 "Verification failed"; // #88 + Method #85 #90; // #89 + NameAndType #5 #91; // #90 + Utf8 "(Ljava/lang/String;)V"; // #91 + Method #93 #94; // #92 + class #95; // #93 + NameAndType #17 #96; // #94 + Utf8 "N"; // #95 + Utf8 "(Z)LMyValue5;"; // #96 + InterfaceMethod #98 #20; // #97 + class #99; // #98 + Utf8 "Verifiable"; // #99 + Method #101 #35; // #100 + class #102; // #101 + Utf8 "F"; // #102 + Method #104 #35; // #103 + class #105; // #104 + Utf8 "G"; // #105 + Method #107 #61; // #106 + class #108; // #107 + Utf8 "L"; // #108 + Method #110 #111; // #109 + class #112; // #110 + NameAndType #17 #113; // #111 + Utf8 "O"; // #112 + Utf8 "(Z)LMyValue6;"; // #113 + Method #115 #20; // #114 + class #116; // #115 + Utf8 "MyValue6"; // #116 + Method #118 #119; // #117 + class #120; // #118 + NameAndType #11 #121; // #119 + Utf8 "MyValue7"; // #120 + Utf8 "()LMyValue7;"; // #121 + InterfaceMethod #123 #124; // #122 + class #125; // #123 + NameAndType #17 #126; // #124 + Utf8 "I6"; // #125 + Utf8 "(LMyValue7;)LMyValue7;"; // #126 + Method #118 #20; // #127 + Method #129 #124; // #128 + class #130; // #129 + Utf8 "P"; // #130 + Method #132 #124; // #131 + class #133; // #132 + Utf8 "Q"; // #133 + Method #135 #124; // #134 + class #136; // #135 + Utf8 "R"; // #136 + class #138; // #137 + Utf8 "TestMismatchHandlingHelper"; // #138 + Utf8 "Code"; // #139 + Utf8 "LineNumberTable"; // #140 + Utf8 "test1"; // #141 + Utf8 "(LA;LA;LA;LA;LA;LB;LB;LC;)V"; // #142 + Utf8 "test2"; // #143 + Utf8 "(LI1;LI1;LI1;LI1;LI1;LI1;LI2;LI2;LI2;LI2;LI2;LI2;LI3;LI3;LI3;LI3;LI3;LI3;LI4;LI4;LI4;LI4;LI4;LI4;LD;LE;)V"; // #144 + Utf8 "test3"; // #145 + Utf8 "(LI5;LI5;LI5;LJ;LJ;LJ;LJ;LJ;LH;LK;)V"; // #146 + Utf8 "test4"; // #147 + Utf8 "(LM;Z)V"; // #148 + Utf8 "StackMapTable"; // #149 + Utf8 "test5"; // #150 + Utf8 "(LN;Z)V"; // #151 + Utf8 "test6"; // #152 + Utf8 "(LF;LG;LL;)V"; // #153 + Utf8 "test7"; // #154 + Utf8 "(LO;Z)LVerifiable;"; // #155 + Utf8 "test7TriggerCalleeCompilation"; // #156 + Utf8 "(LO;)V"; // #157 + Utf8 "test8"; // #158 + Utf8 "(LI6;LI6;LI6;LQ;LQ;LQ;LQ;LQ;LP;LR;)V"; // #159 + Utf8 "SourceFile"; // #160 + Utf8 "TestMismatchHandlingGenerator.java"; // #161 + } // Constant Pool + + 0x0020; // access + #137;// this_cpx + #2;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#139) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#140) { // LineNumberTable + [] { // line_number_table + 0 294; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0009; // access + #141; // name_index + #142; // descriptor_index + [] { // Attributes + Attr(#139) { // Code + 2; // max_stack + 8; // max_locals + Bytes[]{ + 0x2AB80007B6000DB6; + 0x00132BB80007B600; + 0x0DB600132CB80007; + 0xB6000DB600132DB8; + 0x0007B6000DB60013; + 0x1904B80007B6000D; + 0xB600131905B80007; + 0xB60016B600131906; + 0xB80007B60016B600; + 0x131907B80007B600; + 0x19B60013B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#140) { // LineNumberTable + [] { // line_number_table + 0 300; + 10 301; + 20 302; + 30 303; + 40 304; + 51 306; + 62 307; + 73 308; + 84 309; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0009; // access + #143; // name_index + #144; // descriptor_index + [] { // Attributes + Attr(#139) { // Code + 2; // max_stack + 26; // max_locals + Bytes[]{ + 0x2AB8001CB9002102; + 0x00B600262BB8001C; + 0xB900210200B60026; + 0x2CB8001CB9002102; + 0x00B600262DB8001C; + 0xB900210200B60026; + 0x1904B8001CB90021; + 0x0200B600261905B8; + 0x001CB900210200B6; + 0x00261906B8001CB9; + 0x00270200B6002619; + 0x07B8001CB9002702; + 0x00B600261908B800; + 0x1CB900270200B600; + 0x261909B8001CB900; + 0x270200B60026190A; + 0xB8001CB900270200; + 0xB60026190BB8001C; + 0xB900270200B60026; + 0x1918B8001CB6002A; + 0xB60026190CB8001C; + 0xB9002D0200B60026; + 0x190DB8001CB9002D; + 0x0200B60026190EB8; + 0x001CB9002D0200B6; + 0x0026190FB8001CB9; + 0x002D0200B6002619; + 0x10B8001CB9002D02; + 0x00B600261911B800; + 0x1CB9002D0200B600; + 0x261912B8001CB900; + 0x300200B600261913; + 0xB8001CB900300200; + 0xB600261914B8001C; + 0xB900300200B60026; + 0x1915B8001CB90030; + 0x0200B600261916B8; + 0x001CB900300200B6; + 0x00261917B8001CB9; + 0x00300200B6002619; + 0x19B8001CB60033B6; + 0x0026B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#140) { // LineNumberTable + [] { // line_number_table + 0 318; + 12 319; + 24 320; + 36 321; + 48 322; + 61 323; + 74 324; + 87 325; + 100 326; + 113 327; + 126 328; + 139 329; + 152 330; + 163 332; + 176 333; + 189 334; + 202 335; + 215 336; + 228 337; + 241 338; + 254 339; + 267 340; + 280 341; + 293 342; + 306 343; + 319 344; + 330 345; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0009; // access + #145; // name_index + #146; // descriptor_index + [] { // Attributes + Attr(#139) { // Code + 2; // max_stack + 10; // max_locals + Bytes[]{ + 0x2AB80036B9003B02; + 0x00B600402BB80036; + 0xB9003B0200B60040; + 0x2CB80036B9003B02; + 0x00B600401908B800; + 0x36B60041B600402D; + 0xB80036B60044B600; + 0x401904B80036B600; + 0x44B600401905B800; + 0x36B60044B6004019; + 0x06B80036B60044B6; + 0x00401907B80036B6; + 0x0044B600401909B8; + 0x0036B60047B60040; + 0xB1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#140) { // LineNumberTable + [] { // line_number_table + 0 353; + 12 354; + 24 355; + 36 356; + 47 358; + 57 359; + 68 360; + 79 361; + 90 362; + 101 363; + 112 364; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0009; // access + #147; // name_index + #148; // descriptor_index + [] { // Attributes + Attr(#139) { // Code + 3; // max_stack + 2; // max_locals + Bytes[]{ + 0x1B99000C2A1BB600; + 0x4A57A7001A2A1BB6; + 0x004AB4004F102A9F; + 0x000DBB0055591257; + 0xB70059BFB1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#140) { // LineNumberTable + [] { // line_number_table + 0 369; + 4 370; + 13 372; + 26 373; + 36 376; + } + } // end LineNumberTable + ; + Attr(#149) { // StackMapTable + [] { // + 13b; // same_frame + 22b; // same_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0009; // access + #150; // name_index + #151; // descriptor_index + [] { // Attributes + Attr(#139) { // Code + 2; // max_stack + 3; // max_locals + Bytes[]{ + 0x2A1BB6005C4D1B9A; + 0x00092CB900610100; + 0xB1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#140) { // LineNumberTable + [] { // line_number_table + 0 381; + 6 382; + 10 383; + 16 385; + } + } // end LineNumberTable + ; + Attr(#149) { // StackMapTable + [] { // + 252b, 16, []z{O,98}; // append_frame 1 + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0009; // access + #152; // name_index + #153; // descriptor_index + [] { // Attributes + Attr(#139) { // Code + 2; // max_stack + 3; // max_locals + Bytes[]{ + 0x2AB8001CB6006457; + 0x2BB8001CB6006757; + 0x2CB80036B6006A57; + 0xB1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#140) { // LineNumberTable + [] { // line_number_table + 0 389; + 8 390; + 16 391; + 24 392; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0009; // access + #154; // name_index + #155; // descriptor_index + [] { // Attributes + Attr(#139) { // Code + 2; // max_stack + 2; // max_locals + Bytes[]{ + 0x2A1BB6006DB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#140) { // LineNumberTable + [] { // line_number_table + 0 397; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0009; // access + #156; // name_index + #157; // descriptor_index + [] { // Attributes + Attr(#139) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0x2A04B6006D572A03; + 0xB6006DB60072B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#140) { // LineNumberTable + [] { // line_number_table + 0 401; + 6 402; + 14 403; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0009; // access + #158; // name_index + #159; // descriptor_index + [] { // Attributes + Attr(#139) { // Code + 2; // max_stack + 10; // max_locals + Bytes[]{ + 0x2AB80075B9007A02; + 0x00B6007F2BB80075; + 0xB9007A0200B6007F; + 0x2CB80075B9007A02; + 0x00B6007F1908B800; + 0x75B60080B6007F2D; + 0xB80075B60083B600; + 0x7F1904B80075B600; + 0x83B6007F1905B800; + 0x75B60083B6007F19; + 0x06B80075B60083B6; + 0x007F1907B80075B6; + 0x0083B6007F1909B8; + 0x0075B60086B6007F; + 0xB1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#140) { // LineNumberTable + [] { // line_number_table + 0 412; + 12 413; + 24 414; + 36 415; + 47 417; + 57 418; + 68 419; + 79 420; + 90 421; + 101 422; + 112 423; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#160) { // SourceFile + #161; + } // end SourceFile + } // Attributes +} // end class TestMismatchHandlingHelper +class A { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue1"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "A"; // #13 + Utf8 "Code"; // #14 + Utf8 "LineNumberTable"; // #15 + Utf8 "method"; // #16 + Utf8 "(LMyValue1;)LMyValue1;"; // #17 + Utf8 "SourceFile"; // #18 + Utf8 "TestMismatchHandlingGenerator.java"; // #19 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 112; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #16; // name_index + #17; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 114; + 4 115; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#18) { // SourceFile + #19; + } // end SourceFile + } // Attributes +} // end class A +class C { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "B"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue1"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "C"; // #13 + Utf8 "Code"; // #14 + Utf8 "LineNumberTable"; // #15 + Utf8 "method"; // #16 + Utf8 "(LMyValue1;)LMyValue1;"; // #17 + Utf8 "SourceFile"; // #18 + Utf8 "TestMismatchHandlingGenerator.java"; // #19 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 127; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #16; // name_index + #17; // descriptor_index + [] { // Attributes + Attr(#14) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#15) { // LineNumberTable + [] { // line_number_table + 0 130; + 4 131; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#18) { // SourceFile + #19; + } // end SourceFile + } // Attributes +} // end class C +class I1 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "I1"; // #2 + class #4; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 "method"; // #5 + Utf8 "(LMyValue2;)LMyValue2;"; // #6 + Utf8 "SourceFile"; // #7 + Utf8 "TestMismatchHandlingGenerator.java"; // #8 + } // Constant Pool + + 0x0600; // access + #1;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0401; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#7) { // SourceFile + #8; + } // end SourceFile + } // Attributes +} // end class I1 +class I2 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "I2"; // #2 + class #4; // #3 + Utf8 "java/lang/Object"; // #4 + class #6; // #5 + Utf8 "I1"; // #6 + Utf8 "method"; // #7 + Utf8 "(LMyValue2;)LMyValue2;"; // #8 + Utf8 "SourceFile"; // #9 + Utf8 "TestMismatchHandlingGenerator.java"; // #10 + } // Constant Pool + + 0x0600; // access + #1;// this_cpx + #3;// super_cpx + + [] { // Interfaces + #5; + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0401; // access + #7; // name_index + #8; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#9) { // SourceFile + #10; + } // end SourceFile + } // Attributes +} // end class I2 +file "D.class" { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue2"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "D"; // #13 + class #15; // #14 + Utf8 "I2"; // #15 + Utf8 "Code"; // #16 + Utf8 "LineNumberTable"; // #17 + Utf8 "method"; // #18 + Utf8 "(LMyValue2;)LMyValue2;"; // #19 + Utf8 "SourceFile"; // #20 + Utf8 "TestMismatchHandlingGenerator.java"; // #21 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + #14; + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 152; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #18; // name_index + #19; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 155; + 4 156; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#20) { // SourceFile + #21; + } // end SourceFile + } // Attributes +} // end class D +file "F.class" { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue2"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "F"; // #13 + class #15; // #14 + Utf8 "I2"; // #15 + class #17; // #16 + Utf8 "I4"; // #17 + Utf8 "Code"; // #18 + Utf8 "LineNumberTable"; // #19 + Utf8 "method"; // #20 + Utf8 "(LMyValue2;)LMyValue2;"; // #21 + Utf8 "SourceFile"; // #22 + Utf8 "TestMismatchHandlingGenerator.java"; // #23 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + #14; + #16; + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#18) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#19) { // LineNumberTable + [] { // line_number_table + 0 169; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #20; // name_index + #21; // descriptor_index + [] { // Attributes + Attr(#18) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#19) { // LineNumberTable + [] { // line_number_table + 0 172; + 4 173; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#22) { // SourceFile + #23; + } // end SourceFile + } // Attributes +} // end class F +class H { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue3"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "H"; // #13 + class #15; // #14 + Utf8 "I5"; // #15 + Utf8 "Code"; // #16 + Utf8 "LineNumberTable"; // #17 + Utf8 "method"; // #18 + Utf8 "(LMyValue3;)LMyValue3;"; // #19 + Utf8 "SourceFile"; // #20 + Utf8 "TestMismatchHandlingGenerator.java"; // #21 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + #14; + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 189; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #18; // name_index + #19; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 192; + 4 193; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#20) { // SourceFile + #21; + } // end SourceFile + } // Attributes +} // end class H +class I5 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "I5"; // #2 + class #4; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 "method"; // #5 + Utf8 "(LMyValue3;)LMyValue3;"; // #6 + Utf8 "SourceFile"; // #7 + Utf8 "TestMismatchHandlingGenerator.java"; // #8 + } // Constant Pool + + 0x0600; // access + #1;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0401; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#7) { // SourceFile + #8; + } // end SourceFile + } // Attributes +} // end class I5 +class M { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Field #8 #9; // #7 + class #10; // #8 + NameAndType #11 #12; // #9 + Utf8 "M"; // #10 + Utf8 "val"; // #11 + Utf8 "I"; // #12 + Method #14 #15; // #13 + class #16; // #14 + NameAndType #17 #18; // #15 + Utf8 "MyValue4"; // #16 + Utf8 "make"; // #17 + Utf8 "()LMyValue4;"; // #18 + Utf8 "Code"; // #19 + Utf8 "LineNumberTable"; // #20 + Utf8 "method"; // #21 + Utf8 "(Z)LMyValue4;"; // #22 + Utf8 "StackMapTable"; // #23 + Utf8 "SourceFile"; // #24 + Utf8 "TestMismatchHandlingGenerator.java"; // #25 + } // Constant Pool + + 0x0020; // access + #8;// this_cpx + #2;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + { // field + 0x0000; // access + #11; // name_index + #12; // descriptor_index + [] { // Attributes + } // Attributes + } + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#19) { // Code + 2; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB700012A03B500; + 0x07B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // line_number_table + 0 220; + 4 221; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #21; // name_index + #22; // descriptor_index + [] { // Attributes + Attr(#19) { // Code + 3; // max_stack + 4; // max_locals + Bytes[]{ + 0x1B99000501B0B800; + 0x0D4D033E1D100AA2; + 0x00132A59B4000704; + 0x60B50007840301A7; + 0xFFED2CB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#20) { // LineNumberTable + [] { // line_number_table + 0 224; + 4 225; + 6 227; + 10 229; + 18 230; + 28 229; + 34 232; + } + } // end LineNumberTable + ; + Attr(#23) { // StackMapTable + [] { // + 6b; // same_frame + 253b, 5, []z{O,14; I}; // append_frame 2 + 250b, 21; // chop_frame 1 + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#24) { // SourceFile + #25; + } // end SourceFile + } // Attributes +} // end class M +file "N.class" { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #12; // #9 + Utf8 "MyValue5"; // #10 + Utf8 "make"; // #11 + Utf8 "()LMyValue5;"; // #12 + class #14; // #13 + Utf8 "N"; // #14 + Utf8 "Code"; // #15 + Utf8 "LineNumberTable"; // #16 + Utf8 "method"; // #17 + Utf8 "(Z)LMyValue5;"; // #18 + Utf8 "StackMapTable"; // #19 + Utf8 "SourceFile"; // #20 + Utf8 "TestMismatchHandlingGenerator.java"; // #21 + } // Constant Pool + + 0x0020; // access + #13;// this_cpx + #2;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#15) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#16) { // LineNumberTable + [] { // line_number_table + 0 237; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #17; // name_index + #18; // descriptor_index + [] { // Attributes + Attr(#15) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x1B99000501B0B800; + 0x07B0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#16) { // LineNumberTable + [] { // line_number_table + 0 239; + 4 240; + 6 242; + } + } // end LineNumberTable + ; + Attr(#19) { // StackMapTable + [] { // + 6b; // same_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#20) { // SourceFile + #21; + } // end SourceFile + } // Attributes +} // end class N +file "O.class" { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #12; // #9 + Utf8 "MyValue6"; // #10 + Utf8 "make"; // #11 + Utf8 "()LMyValue6;"; // #12 + class #14; // #13 + Utf8 "O"; // #14 + Utf8 "Code"; // #15 + Utf8 "LineNumberTable"; // #16 + Utf8 "method"; // #17 + Utf8 "(Z)LMyValue6;"; // #18 + Utf8 "StackMapTable"; // #19 + Utf8 "SourceFile"; // #20 + Utf8 "TestMismatchHandlingGenerator.java"; // #21 + } // Constant Pool + + 0x0020; // access + #13;// this_cpx + #2;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#15) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#16) { // LineNumberTable + [] { // line_number_table + 0 247; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #17; // name_index + #18; // descriptor_index + [] { // Attributes + Attr(#15) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x1B99000501B0B800; + 0x07B0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#16) { // LineNumberTable + [] { // line_number_table + 0 249; + 4 250; + 6 252; + } + } // end LineNumberTable + ; + Attr(#19) { // StackMapTable + [] { // + 6b; // same_frame + } + } // end StackMapTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#20) { // SourceFile + #21; + } // end SourceFile + } // Attributes +} // end class O +class I6 { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + class #2; // #1 + Utf8 "I6"; // #2 + class #4; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 "method"; // #5 + Utf8 "(LMyValue7;)LMyValue7;"; // #6 + Utf8 "Code"; // #7 + Utf8 "LineNumberTable"; // #8 + Utf8 "SourceFile"; // #9 + Utf8 "TestMismatchHandlingGenerator.java"; // #10 + } // Constant Pool + + 0x0600; // access + #1;// this_cpx + #3;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0001; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x01B0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // line_number_table + 0 259; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#9) { // SourceFile + #10; + } // end SourceFile + } // Attributes +} // end class I6 +class P { + 0xCAFEBABE; + 0; // minor version + 65; // version + [] { // Constant Pool + ; // first element is empty + Method #2 #3; // #1 + class #4; // #2 + NameAndType #5 #6; // #3 + Utf8 "java/lang/Object"; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Method #8 #9; // #7 + class #10; // #8 + NameAndType #11 #6; // #9 + Utf8 "MyValue7"; // #10 + Utf8 "verify"; // #11 + class #13; // #12 + Utf8 "P"; // #13 + class #15; // #14 + Utf8 "I6"; // #15 + Utf8 "Code"; // #16 + Utf8 "LineNumberTable"; // #17 + Utf8 "method"; // #18 + Utf8 "(LMyValue7;)LMyValue7;"; // #19 + Utf8 "SourceFile"; // #20 + Utf8 "TestMismatchHandlingGenerator.java"; // #21 + } // Constant Pool + + 0x0020; // access + #12;// this_cpx + #2;// super_cpx + + [] { // Interfaces + #14; + } // Interfaces + + [] { // Fields + } // Fields + + [] { // Methods + { // method + 0x0000; // access + #5; // name_index + #6; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 263; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + ; + { // method + 0x0001; // access + #18; // name_index + #19; // descriptor_index + [] { // Attributes + Attr(#16) { // Code + 1; // max_stack + 2; // max_locals + Bytes[]{ + 0x2BB600072BB0; + } + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#17) { // LineNumberTable + [] { // line_number_table + 0 266; + 4 267; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } + } // Methods + + [] { // Attributes + Attr(#20) { // SourceFile + #21; + } // end SourceFile + } // Attributes +} // end class P diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMismatchHandlingGenerator.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMismatchHandlingGenerator.java new file mode 100644 index 00000000000..0b76c546649 --- /dev/null +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestMismatchHandlingGenerator.java @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2023, 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. + */ + +value class MyValue1 { + int x = 42; + + void verify() { + if (x != 42) { + throw new RuntimeException("Verification failed"); + } + } +} + +value class MyValue2 { + int x = 42; + + void verify() { + if (x != 42) { + throw new RuntimeException("Verification failed"); + } + } +} + +value class MyValue3 { + int x = 42; + + void verify() { + if (x != 42) { + throw new RuntimeException("Verification failed"); + } + } +} + +value class MyValue4 { + int x = 42; + + public void verify() { + if (x != 42) { + throw new RuntimeException("Verification failed"); + } + } + + static MyValue4 make() { + return new MyValue4(); + } +} + +interface Verifiable { + public void verify(); +} + +value class MyValue5 implements Verifiable { + int x = 42; + + @Override + public void verify() { + if (x != 42) { + throw new RuntimeException("Verification failed"); + } + } + + static MyValue5 make() { + return new MyValue5(); + } +} + +value class MyValue6 implements Verifiable { + int x = 42; + + @Override + public void verify() { + if (x != 42) { + throw new RuntimeException("Verification failed"); + } + } + + static MyValue6 make() { + return new MyValue6(); + } +} + +value class MyValue7 { + int x = 42; + + void verify() { + if (x != 42) { + throw new RuntimeException("Verification failed"); + } + } +} + +class A { + public MyValue1 method(MyValue1 arg) { + arg.verify(); + return arg; + } +} + +class B extends A { + @Override + public MyValue1 method(MyValue1 arg) { + arg.verify(); + return arg; + } +} + +class C extends B { + @Override + public MyValue1 method(MyValue1 arg) { + arg.verify(); + return arg; + } +} + +interface I1 { + public MyValue2 method(MyValue2 arg); +} + +interface I2 extends I1 { + public MyValue2 method(MyValue2 arg); +} + +interface I3 { + public MyValue2 method(MyValue2 arg); +} + +interface I4 extends I3 { + public MyValue2 method(MyValue2 arg); +} + + +class D implements I2 { + @Override + public MyValue2 method(MyValue2 arg) { + arg.verify(); + return arg; + } +} + +class E implements I4 { + @Override + public MyValue2 method(MyValue2 arg) { + arg.verify(); + return arg; + } +} + + +class F implements I2, I4 { + @Override + public MyValue2 method(MyValue2 arg) { + arg.verify(); + return arg; + } +} + +class G implements I2, I4 { + @Override + public MyValue2 method(MyValue2 arg) { + arg.verify(); + return arg; + } +} + +interface I5 { + public MyValue3 method(MyValue3 arg); +} + +class H implements I5 { + @Override + public MyValue3 method(MyValue3 arg) { + arg.verify(); + return arg; + } +} + +class J { + public MyValue3 method(MyValue3 arg) { + arg.verify(); + return arg; + } +} + +class K extends J { + @Override + public MyValue3 method(MyValue3 arg) { + arg.verify(); + return arg; + } +} + +class L extends K implements I5 { + @Override + public MyValue3 method(MyValue3 arg) { + arg.verify(); + return arg; + } +} + +class M { + int val = 0; + + public MyValue4 method(boolean warmup) { + if (warmup) { + return null; + } else { + MyValue4 res = MyValue4.make(); + // Do something here to "corrupt" registers + for (int i = 0; i < 10; ++i) { + val++; + } + return res; + } + } +} + +class N { + public MyValue5 method(boolean warmup) { + if (warmup) { + return null; + } else { + return MyValue5.make(); + } + } +} + +class O { + public MyValue6 method(boolean warmup) { + if (warmup) { + return null; + } else { + return MyValue6.make(); + } + } +} + +interface I6 { + default MyValue7 method(MyValue7 arg) { + return null; + } +} + +class P implements I6 { + @Override + public MyValue7 method(MyValue7 arg) { + arg.verify(); + return arg; + } +} + +class Q { + MyValue7 method(MyValue7 arg) { + arg.verify(); + return arg; + } +} + +class R extends Q { + @Override + MyValue7 method(MyValue7 arg) { + arg.verify(); + return arg; + } +} + +class S extends R implements I6 { + @Override + public MyValue7 method(MyValue7 arg) { + arg.verify(); + return arg; + } +} + +class TestMismatchHandlingHelper { + // * = has preload attribute for MyValue* + + // With C <: B* <: A + public static void test1(A a1, A a2, A a3, A a4, A a5, B b1, B b2, C c) { + // Non-scalarized virtual call site, mismatching on B + a1.method(new MyValue1()).verify(); + a2.method(new MyValue1()).verify(); + a3.method(new MyValue1()).verify(); + a4.method(new MyValue1()).verify(); + a5.method(new MyValue1()).verify(); + // Scalarized virtual call sites, mismatching on C + b1.method(new MyValue1()).verify(); + b2.method(new MyValue1()).verify(); + c.method(new MyValue1()).verify(); + } + + // D <: I2 <: I1 + // E* <: I4* <: I3* + // Loaded later, combine both hierachies and introduce a mismatch: + // F <: I2, I4* + // G* <: I2, I4* + public static void test2(I1 i11, I1 i12, I1 i13, I1 i14, I1 i15, I1 i16, I2 i21, I2 i22, I2 i23, I2 i24, I2 i25, I2 i26, I3 i31, I3 i32, I3 i33, I3 i34, I3 i35, I3 i36, I4 i41, I4 i42, I4 i43, I4 i44, I4 i45, I4 i46, D d, E e) { + // Non-scalarized virtual call sites, mismatching on E + i11.method(new MyValue2()).verify(); + i12.method(new MyValue2()).verify(); + i13.method(new MyValue2()).verify(); + i14.method(new MyValue2()).verify(); + i15.method(new MyValue2()).verify(); + i16.method(new MyValue2()).verify(); + i21.method(new MyValue2()).verify(); + i22.method(new MyValue2()).verify(); + i23.method(new MyValue2()).verify(); + i24.method(new MyValue2()).verify(); + i25.method(new MyValue2()).verify(); + i26.method(new MyValue2()).verify(); + d.method(new MyValue2()).verify(); + // Scalarized virtual call sites, mismatching on D + i31.method(new MyValue2()).verify(); + i32.method(new MyValue2()).verify(); + i33.method(new MyValue2()).verify(); + i34.method(new MyValue2()).verify(); + i35.method(new MyValue2()).verify(); + i36.method(new MyValue2()).verify(); + i41.method(new MyValue2()).verify(); + i42.method(new MyValue2()).verify(); + i43.method(new MyValue2()).verify(); + i44.method(new MyValue2()).verify(); + i45.method(new MyValue2()).verify(); + i46.method(new MyValue2()).verify(); + e.method(new MyValue2()).verify(); + } + + // H <: I5 + // K* <: J* + // Loaded later, combines both hierachies and introduces a mismatch: + // L* <: K*, I5 + public static void test3(I5 i51, I5 i52, I5 i53, J j1, J j2, J j3, J j4, J j5, H h, K k) { + // Non-scalarized virtual call sites, mismatching on L + i51.method(new MyValue3()).verify(); + i52.method(new MyValue3()).verify(); + i53.method(new MyValue3()).verify(); + h.method(new MyValue3()).verify(); + // Scalarized virtual call sites + j1.method(new MyValue3()).verify(); + j2.method(new MyValue3()).verify(); + j3.method(new MyValue3()).verify(); + j4.method(new MyValue3()).verify(); + j5.method(new MyValue3()).verify(); + k.method(new MyValue3()).verify(); + } + + // Test that a C1 compiled method returns in scalarized form if the method holder class M + // is loaded but the value class return type is not due to a missing preload attribute. + public static void test4(M m, boolean warmup) { + if (warmup) { + m.method(warmup); + } else { + if (m.method(warmup).x != 42) { + throw new RuntimeException("Verification failed"); + } + } + } + + // Test that C1 correctly handles scalarized returns at calls if the method holder class N + // is loaded but the value class return type is not due to a missing preload attribute. + public static void test5(N n, boolean warmup) { + Verifiable res = n.method(warmup); + if (!warmup) { + res.verify(); + } + } + + // Test direct calls + public static void test6(F f, G g, L l) { + f.method(new MyValue2()); + g.method(new MyValue2()); + l.method(new MyValue3()); + } + + // Test scalarized return from C2 compiled callee to C2 compiled caller with an unloaded + // return type at caller compile time due to a missing preload attribute. + public static Verifiable test7(O o, boolean warmup) { + return o.method(warmup); + } + + public static void test7TriggerCalleeCompilation(O o) { + o.method(true); + o.method(false).verify(); + } + + // Same as test3 but with default method in interface and package private methods + // P <: I6 + // R* <: Q* + // Loaded later, combines both hierachies and introduces a mismatch: + // S* <: R*, I6 + public static void test8(I6 i61, I6 i62, I6 i63, Q q1, Q q2, Q q3, Q q4, Q q5, P p, R r) { + // Non-scalarized virtual call sites, mismatching on S + i61.method(new MyValue7()).verify(); + i62.method(new MyValue7()).verify(); + i63.method(new MyValue7()).verify(); + p.method(new MyValue7()).verify(); + // Scalarized virtual call sites + q1.method(new MyValue7()).verify(); + q2.method(new MyValue7()).verify(); + q3.method(new MyValue7()).verify(); + q4.method(new MyValue7()).verify(); + q5.method(new MyValue7()).verify(); + r.method(new MyValue7()).verify(); + } +} diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestTrivialMethods.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestTrivialMethods.java index bb5946df929..e6c9f1d1c8e 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestTrivialMethods.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestTrivialMethods.java @@ -34,6 +34,7 @@ * @run main/othervm -Xbootclasspath/a:. -XX:+EnableValhalla -XX:+EnablePrimitiveClasses * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbatch * -XX:+InlineTypePassFieldsAsArgs -XX:+InlineTypeReturnedAsFields + * -XX:+IgnoreUnrecognizedVMOptions -XX:-StressCallingConvention * -XX:CompileCommand=dontinline,*::getter* -XX:CompileCommand=dontinline,*::setter* * -XX:CompileCommand=dontinline,*::constantGetter* * compiler.valhalla.inlinetypes.TestTrivialMethods