Wed, 02 Nov 2016 14:54:53 -0700
8167104: Additional class construction refinements
Reviewed-by: hseigel
1.1 --- a/src/share/vm/classfile/stackMapFrame.cpp Tue Nov 01 16:13:45 2016 -0700 1.2 +++ b/src/share/vm/classfile/stackMapFrame.cpp Wed Nov 02 14:54:53 2016 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -155,47 +155,8 @@ 1.11 return i; 1.12 } 1.13 1.14 -bool StackMapFrame::has_flag_match_exception( 1.15 - const StackMapFrame* target) const { 1.16 - // We allow flags of {UninitThis} to assign to {} if-and-only-if the 1.17 - // target frame does not depend upon the current type. 1.18 - // This is slightly too strict, as we need only enforce that the 1.19 - // slots that were initialized by the <init> (the things that were 1.20 - // UninitializedThis before initialize_object() converted them) are unused. 1.21 - // However we didn't save that information so we'll enforce this upon 1.22 - // anything that might have been initialized. This is a rare situation 1.23 - // and javac never generates code that would end up here, but some profilers 1.24 - // (such as NetBeans) might, when adding exception handlers in <init> 1.25 - // methods to cover the invokespecial instruction. See 7020118. 1.26 - 1.27 - assert(max_locals() == target->max_locals() && 1.28 - stack_size() == target->stack_size(), "StackMap sizes must match"); 1.29 - 1.30 - VerificationType top = VerificationType::top_type(); 1.31 - VerificationType this_type = verifier()->current_type(); 1.32 - 1.33 - if (!flag_this_uninit() || target->flags() != 0) { 1.34 - return false; 1.35 - } 1.36 - 1.37 - for (int i = 0; i < target->locals_size(); ++i) { 1.38 - if (locals()[i] == this_type && target->locals()[i] != top) { 1.39 - return false; 1.40 - } 1.41 - } 1.42 - 1.43 - for (int i = 0; i < target->stack_size(); ++i) { 1.44 - if (stack()[i] == this_type && target->stack()[i] != top) { 1.45 - return false; 1.46 - } 1.47 - } 1.48 - 1.49 - return true; 1.50 -} 1.51 - 1.52 bool StackMapFrame::is_assignable_to( 1.53 - const StackMapFrame* target, bool is_exception_handler, 1.54 - ErrorContext* ctx, TRAPS) const { 1.55 + const StackMapFrame* target, ErrorContext* ctx, TRAPS) const { 1.56 if (_max_locals != target->max_locals()) { 1.57 *ctx = ErrorContext::locals_size_mismatch( 1.58 _offset, (StackMapFrame*)this, (StackMapFrame*)target); 1.59 @@ -226,8 +187,7 @@ 1.60 return false; 1.61 } 1.62 1.63 - bool match_flags = (_flags | target->flags()) == target->flags(); 1.64 - if (match_flags || is_exception_handler && has_flag_match_exception(target)) { 1.65 + if ((_flags | target->flags()) == target->flags()) { 1.66 return true; 1.67 } else { 1.68 *ctx = ErrorContext::bad_flags(target->offset(),
2.1 --- a/src/share/vm/classfile/stackMapFrame.hpp Tue Nov 01 16:13:45 2016 -0700 2.2 +++ b/src/share/vm/classfile/stackMapFrame.hpp Wed Nov 02 14:54:53 2016 -0700 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -167,8 +167,7 @@ 2.11 2.12 // Return true if this stack map frame is assignable to target. 2.13 bool is_assignable_to( 2.14 - const StackMapFrame* target, bool is_exception_handler, 2.15 - ErrorContext* ctx, TRAPS) const; 2.16 + const StackMapFrame* target, ErrorContext* ctx, TRAPS) const; 2.17 2.18 inline void set_mark() { 2.19 #ifdef ASSERT 2.20 @@ -290,8 +289,6 @@ 2.21 int is_assignable_to( 2.22 VerificationType* src, VerificationType* target, int32_t len, TRAPS) const; 2.23 2.24 - bool has_flag_match_exception(const StackMapFrame* target) const; 2.25 - 2.26 TypeOrigin stack_top_ctx(); 2.27 2.28 void print_on(outputStream* str) const;
3.1 --- a/src/share/vm/classfile/stackMapTable.cpp Tue Nov 01 16:13:45 2016 -0700 3.2 +++ b/src/share/vm/classfile/stackMapTable.cpp Wed Nov 02 14:54:53 2016 -0700 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -70,26 +70,25 @@ 3.11 3.12 bool StackMapTable::match_stackmap( 3.13 StackMapFrame* frame, int32_t target, 3.14 - bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const { 3.15 + bool match, bool update, ErrorContext* ctx, TRAPS) const { 3.16 int index = get_index_from_offset(target); 3.17 - return match_stackmap(frame, target, index, match, update, handler, ctx, THREAD); 3.18 + return match_stackmap(frame, target, index, match, update, ctx, THREAD); 3.19 } 3.20 3.21 // Match and/or update current_frame to the frame in stackmap table with 3.22 // specified offset and frame index. Return true if the two frames match. 3.23 -// handler is true if the frame in stackmap_table is for an exception handler. 3.24 // 3.25 -// The values of match and update are: _match__update__handler 3.26 +// The values of match and update are: _match__update 3.27 // 3.28 -// checking a branch target: true false false 3.29 -// checking an exception handler: true false true 3.30 +// checking a branch target: true false 3.31 +// checking an exception handler: true false 3.32 // linear bytecode verification following an 3.33 -// unconditional branch: false true false 3.34 +// unconditional branch: false true 3.35 // linear bytecode verification not following an 3.36 -// unconditional branch: true true false 3.37 +// unconditional branch: true true 3.38 bool StackMapTable::match_stackmap( 3.39 StackMapFrame* frame, int32_t target, int32_t frame_index, 3.40 - bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const { 3.41 + bool match, bool update, ErrorContext* ctx, TRAPS) const { 3.42 if (frame_index < 0 || frame_index >= _frame_count) { 3.43 *ctx = ErrorContext::missing_stackmap(frame->offset()); 3.44 frame->verifier()->verify_error( 3.45 @@ -102,7 +101,7 @@ 3.46 if (match) { 3.47 // Has direct control flow from last instruction, need to match the two 3.48 // frames. 3.49 - result = frame->is_assignable_to(stackmap_frame, handler, 3.50 + result = frame->is_assignable_to(stackmap_frame, 3.51 ctx, CHECK_VERIFY_(frame->verifier(), result)); 3.52 } 3.53 if (update) { 3.54 @@ -126,7 +125,7 @@ 3.55 StackMapFrame* frame, int32_t target, TRAPS) const { 3.56 ErrorContext ctx; 3.57 bool match = match_stackmap( 3.58 - frame, target, true, false, false, &ctx, CHECK_VERIFY(frame->verifier())); 3.59 + frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier())); 3.60 if (!match || (target < 0 || target >= _code_length)) { 3.61 frame->verifier()->verify_error(ctx, 3.62 "Inconsistent stackmap frames at branch target %d", target);
4.1 --- a/src/share/vm/classfile/stackMapTable.hpp Tue Nov 01 16:13:45 2016 -0700 4.2 +++ b/src/share/vm/classfile/stackMapTable.hpp Wed Nov 02 14:54:53 2016 -0700 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -74,12 +74,12 @@ 4.11 // specified offset. Return true if the two frames match. 4.12 bool match_stackmap( 4.13 StackMapFrame* current_frame, int32_t offset, 4.14 - bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const; 4.15 + bool match, bool update, ErrorContext* ctx, TRAPS) const; 4.16 // Match and/or update current_frame to the frame in stackmap table with 4.17 // specified offset and frame index. Return true if the two frames match. 4.18 bool match_stackmap( 4.19 StackMapFrame* current_frame, int32_t offset, int32_t frame_index, 4.20 - bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const; 4.21 + bool match, bool update, ErrorContext* ctx, TRAPS) const; 4.22 4.23 // Check jump instructions. Make sure there are no uninitialized 4.24 // instances on backward branch.
5.1 --- a/src/share/vm/classfile/verifier.cpp Tue Nov 01 16:13:45 2016 -0700 5.2 +++ b/src/share/vm/classfile/verifier.cpp Wed Nov 02 14:54:53 2016 -0700 5.3 @@ -1814,7 +1814,7 @@ 5.4 // If matched, current_frame will be updated by this method. 5.5 bool matches = stackmap_table->match_stackmap( 5.6 current_frame, this_offset, stackmap_index, 5.7 - !no_control_flow, true, false, &ctx, CHECK_VERIFY_(this, 0)); 5.8 + !no_control_flow, true, &ctx, CHECK_VERIFY_(this, 0)); 5.9 if (!matches) { 5.10 // report type error 5.11 verify_error(ctx, "Instruction type does not match stack map"); 5.12 @@ -1861,7 +1861,7 @@ 5.13 } 5.14 ErrorContext ctx; 5.15 bool matches = stackmap_table->match_stackmap( 5.16 - new_frame, handler_pc, true, false, true, &ctx, CHECK_VERIFY(this)); 5.17 + new_frame, handler_pc, true, false, &ctx, CHECK_VERIFY(this)); 5.18 if (!matches) { 5.19 verify_error(ctx, "Stack map does not match the one at " 5.20 "exception handler %d", handler_pc);
6.1 --- a/test/runtime/handlerInTry/LoadHandlerInTry.java Tue Nov 01 16:13:45 2016 -0700 6.2 +++ b/test/runtime/handlerInTry/LoadHandlerInTry.java Wed Nov 02 14:54:53 2016 -0700 6.3 @@ -1,5 +1,5 @@ 6.4 /* 6.5 - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 6.6 + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. 6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 * 6.9 * This code is free software; you can redistribute it and/or modify it 6.10 @@ -24,7 +24,7 @@ 6.11 /* 6.12 * @test 6.13 * @bug 8075118 6.14 - * @summary Allow a ctor to call super() from a switch bytecode. 6.15 + * @summary JVM stuck in infinite loop during verification 6.16 * @compile HandlerInTry.jasm 6.17 * @compile IsolatedHandlerInTry.jasm 6.18 * @run main/othervm -Xverify:all LoadHandlerInTry 6.19 @@ -70,9 +70,10 @@ 6.20 System.out.println("Regression test for bug 8075118"); 6.21 try { 6.22 Class newClass = Class.forName("HandlerInTry"); 6.23 - } catch (Exception e) { 6.24 - System.out.println("Failed: Exception was thrown: " + e.toString()); 6.25 - throw e; 6.26 + throw new RuntimeException( 6.27 + "Failed to throw VerifyError for HandlerInTry"); 6.28 + } catch (java.lang.VerifyError e) { 6.29 + System.out.println("Passed: VerifyError exception was thrown"); 6.30 } 6.31 6.32 try {