Mercurial > hg > release > icedtea7-forest-2.6 > hotspot
changeset 6528:9fc0d63c2a74 icedtea-2.6.9
Merge jdk7u131-b00
author | andrew |
---|---|
date | Tue, 07 Feb 2017 04:06:40 +0000 |
parents | b0661240c3b0 (current diff) 457394dc689c (diff) |
children | b52d012bb1d4 |
files | .hgtags src/share/vm/classfile/classFileParser.cpp src/share/vm/classfile/stackMapTable.hpp src/share/vm/classfile/verifier.cpp src/share/vm/classfile/verifier.hpp |
diffstat | 8 files changed, 49 insertions(+), 88 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Mon Feb 06 22:14:36 2017 +0000 +++ b/.hgtags Tue Feb 07 04:06:40 2017 +0000 @@ -899,3 +899,4 @@ 17b40d99ea3665de2bfffe163b68f2dfcf675cba jdk7u121-b00 223f6c442d4987da3508893fb35e4419b33dc7f7 icedtea-2.6.8 1d30f5a7723eeeb8092eed80d305fe6cdf530b1f icedtea-2.6.9pre01 +95e4ea3d479ebdab9d78725776b6b11d4add6b0e jdk7u131-b00
--- a/src/share/vm/classfile/classFileParser.cpp Mon Feb 06 22:14:36 2017 +0000 +++ b/src/share/vm/classfile/classFileParser.cpp Tue Feb 07 04:06:40 2017 +0000 @@ -966,7 +966,8 @@ runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); - cfs->skip_u1(runtime_visible_annotations_length, CHECK); + cfs->guarantee_more(runtime_visible_annotations_length, CHECK); + cfs->skip_u1_fast(runtime_visible_annotations_length); } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { runtime_invisible_annotations_length = attribute_length; runtime_invisible_annotations = cfs->get_u1_buffer(); @@ -1658,6 +1659,11 @@ return index; } +// Safely increment index by val if does not pass limit +#define SAFE_ADD(index, limit, val) \ +if (index >= limit - val) return limit; \ +index += val; + // Skip an annotation value. Return >=limit if there is any problem. int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) { // value := switch (tag:u1) { @@ -1668,19 +1674,19 @@ // case @: annotation; // case s: s_con:u2; // } - if ((index += 1) >= limit) return limit; // read tag + SAFE_ADD(index, limit, 1); // read tag u1 tag = buffer[index-1]; switch (tag) { case 'B': case 'C': case 'I': case 'S': case 'Z': case 'D': case 'F': case 'J': case 'c': case 's': - index += 2; // skip con or s_con + SAFE_ADD(index, limit, 2); // skip con or s_con break; case 'e': - index += 4; // skip e_class, e_name + SAFE_ADD(index, limit, 4); // skip e_class, e_name break; case '[': { - if ((index += 2) >= limit) return limit; // read nval + SAFE_ADD(index, limit, 2); // read nval int nval = Bytes::get_Java_u2(buffer+index-2); while (--nval >= 0 && index < limit) { index = skip_annotation_value(buffer, limit, index); @@ -1704,8 +1710,8 @@ ClassFileParser::AnnotationCollector* coll, TRAPS) { // annotations := do(nann:u2) {annotation} - int index = 0; - if ((index += 2) >= limit) return; // read nann + int index = 2; + if (index >= limit) return; // read nann int nann = Bytes::get_Java_u2(buffer+index-2); enum { // initial annotation layout atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;' @@ -1721,7 +1727,8 @@ c_size = 9, // end of 'c' annotation min_size = 6 // smallest possible size (zero members) }; - while ((--nann) >= 0 && (index-2 + min_size <= limit)) { + // Cannot add min_size to index in case of overflow MAX_INT + while ((--nann) >= 0 && (index-2 <= limit - min_size)) { int index0 = index; index = skip_annotation(buffer, limit, index); u1* abase = buffer + index0; @@ -2138,8 +2145,9 @@ runtime_visible_annotations_length = method_attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); + cfs->guarantee_more(runtime_visible_annotations_length, CHECK_(nullHandle)); parse_annotations(class_loader, runtime_visible_annotations, runtime_visible_annotations_length, cp, &parsed_annotations, CHECK_(nullHandle)); - cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); + cfs->skip_u1_fast(runtime_visible_annotations_length); } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { runtime_invisible_annotations_length = method_attribute_length; runtime_invisible_annotations = cfs->get_u1_buffer(); @@ -2835,13 +2843,14 @@ runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); + cfs->guarantee_more(runtime_visible_annotations_length, CHECK); parse_annotations(class_loader, runtime_visible_annotations, runtime_visible_annotations_length, cp, parsed_annotations, CHECK); - cfs->skip_u1(runtime_visible_annotations_length, CHECK); + cfs->skip_u1_fast(runtime_visible_annotations_length); } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) { runtime_invisible_annotations_length = attribute_length; runtime_invisible_annotations = cfs->get_u1_buffer();
--- a/src/share/vm/classfile/stackMapFrame.cpp Mon Feb 06 22:14:36 2017 +0000 +++ b/src/share/vm/classfile/stackMapFrame.cpp Tue Feb 07 04:06:40 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -174,47 +174,8 @@ return i; } -bool StackMapFrame::has_flag_match_exception( - const StackMapFrame* target) const { - // We allow flags of {UninitThis} to assign to {} if-and-only-if the - // target frame does not depend upon the current type. - // This is slightly too strict, as we need only enforce that the - // slots that were initialized by the <init> (the things that were - // UninitializedThis before initialize_object() converted them) are unused. - // However we didn't save that information so we'll enforce this upon - // anything that might have been initialized. This is a rare situation - // and javac never generates code that would end up here, but some profilers - // (such as NetBeans) might, when adding exception handlers in <init> - // methods to cover the invokespecial instruction. See 7020118. - - assert(max_locals() == target->max_locals() && - stack_size() == target->stack_size(), "StackMap sizes must match"); - - VerificationType top = VerificationType::top_type(); - VerificationType this_type = verifier()->current_type(); - - if (!flag_this_uninit() || target->flags() != 0) { - return false; - } - - for (int i = 0; i < target->locals_size(); ++i) { - if (locals()[i] == this_type && target->locals()[i] != top) { - return false; - } - } - - for (int i = 0; i < target->stack_size(); ++i) { - if (stack()[i] == this_type && target->stack()[i] != top) { - return false; - } - } - - return true; -} - bool StackMapFrame::is_assignable_to( - const StackMapFrame* target, bool is_exception_handler, - ErrorContext* ctx, TRAPS) const { + const StackMapFrame* target, ErrorContext* ctx, TRAPS) const { if (_max_locals != target->max_locals()) { *ctx = ErrorContext::locals_size_mismatch( _offset, (StackMapFrame*)this, (StackMapFrame*)target); @@ -245,8 +206,7 @@ return false; } - bool match_flags = (_flags | target->flags()) == target->flags(); - if (match_flags || is_exception_handler && has_flag_match_exception(target)) { + if ((_flags | target->flags()) == target->flags()) { return true; } else { *ctx = ErrorContext::bad_flags(target->offset(),
--- a/src/share/vm/classfile/stackMapFrame.hpp Mon Feb 06 22:14:36 2017 +0000 +++ b/src/share/vm/classfile/stackMapFrame.hpp Tue Feb 07 04:06:40 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -172,8 +172,7 @@ // Return true if this stack map frame is assignable to target. bool is_assignable_to( - const StackMapFrame* target, bool is_exception_handler, - ErrorContext* ctx, TRAPS) const; + const StackMapFrame* target, ErrorContext* ctx, TRAPS) const; inline void set_mark() { #ifdef DEBUG @@ -295,8 +294,6 @@ int is_assignable_to( VerificationType* src, VerificationType* target, int32_t len, TRAPS) const; - bool has_flag_match_exception(const StackMapFrame* target) const; - TypeOrigin stack_top_ctx(); void print_on(outputStream* str) const;
--- a/src/share/vm/classfile/stackMapTable.cpp Mon Feb 06 22:14:36 2017 +0000 +++ b/src/share/vm/classfile/stackMapTable.cpp Tue Feb 07 04:06:40 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -70,26 +70,25 @@ bool StackMapTable::match_stackmap( StackMapFrame* frame, int32_t target, - bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const { + bool match, bool update, ErrorContext* ctx, TRAPS) const { int index = get_index_from_offset(target); - return match_stackmap(frame, target, index, match, update, handler, ctx, THREAD); + return match_stackmap(frame, target, index, match, update, ctx, THREAD); } // Match and/or update current_frame to the frame in stackmap table with // specified offset and frame index. Return true if the two frames match. -// handler is true if the frame in stackmap_table is for an exception handler. // -// The values of match and update are: _match__update__handler +// The values of match and update are: _match__update // -// checking a branch target: true false false -// checking an exception handler: true false true +// checking a branch target: true false +// checking an exception handler: true false // linear bytecode verification following an -// unconditional branch: false true false +// unconditional branch: false true // linear bytecode verification not following an -// unconditional branch: true true false +// unconditional branch: true true bool StackMapTable::match_stackmap( StackMapFrame* frame, int32_t target, int32_t frame_index, - bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const { + bool match, bool update, ErrorContext* ctx, TRAPS) const { if (frame_index < 0 || frame_index >= _frame_count) { *ctx = ErrorContext::missing_stackmap(frame->offset()); frame->verifier()->verify_error( @@ -102,7 +101,7 @@ if (match) { // Has direct control flow from last instruction, need to match the two // frames. - result = frame->is_assignable_to(stackmap_frame, handler, + result = frame->is_assignable_to(stackmap_frame, ctx, CHECK_VERIFY_(frame->verifier(), result)); } if (update) { @@ -126,7 +125,7 @@ StackMapFrame* frame, int32_t target, TRAPS) const { ErrorContext ctx; bool match = match_stackmap( - frame, target, true, false, false, &ctx, CHECK_VERIFY(frame->verifier())); + frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier())); if (!match || (target < 0 || target >= _code_length)) { frame->verifier()->verify_error(ctx, "Inconsistent stackmap frames at branch target %d", target);
--- a/src/share/vm/classfile/stackMapTable.hpp Mon Feb 06 22:14:36 2017 +0000 +++ b/src/share/vm/classfile/stackMapTable.hpp Tue Feb 07 04:06:40 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, 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 @@ -77,12 +77,12 @@ // specified offset. Return true if the two frames match. bool match_stackmap( StackMapFrame* current_frame, int32_t offset, - bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const; + bool match, bool update, ErrorContext* ctx, TRAPS) const; // Match and/or update current_frame to the frame in stackmap table with // specified offset and frame index. Return true if the two frames match. bool match_stackmap( StackMapFrame* current_frame, int32_t offset, int32_t frame_index, - bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const; + bool match, bool update, ErrorContext* ctx, TRAPS) const; // Check jump instructions. Make sure there are no uninitialized // instances on backward branch.
--- a/src/share/vm/classfile/verifier.cpp Mon Feb 06 22:14:36 2017 +0000 +++ b/src/share/vm/classfile/verifier.cpp Tue Feb 07 04:06:40 2017 +0000 @@ -506,19 +506,13 @@ stack_map_frame* sm_frame = sm_table->entries(); streamIndentor si2(ss); int current_offset = -1; - // Subtract two from StackMapAttribute length because the length includes - // two bytes for number of table entries. - size_t sm_table_space = method->stackmap_data()->length() - 2; + address end_of_sm_table = (address)sm_table + method->stackmap_data()->length(); for (u2 i = 0; i < sm_table->number_of_entries(); ++i) { ss->indent(); - size_t sm_frame_size = sm_frame->size(); - // If the size of the next stackmap exceeds the length of the entire - // stackmap table then print a truncated message and return. - if (sm_frame_size > sm_table_space) { + if (!sm_frame->verify((address)sm_frame, end_of_sm_table)) { sm_frame->print_truncated(ss, current_offset); return; } - sm_table_space -= sm_frame_size; sm_frame->print_on(ss, current_offset); ss->print_cr(""); current_offset += sm_frame->offset_delta(); @@ -1817,7 +1811,7 @@ // If matched, current_frame will be updated by this method. bool matches = stackmap_table->match_stackmap( current_frame, this_offset, stackmap_index, - !no_control_flow, true, false, &ctx, CHECK_VERIFY_(this, 0)); + !no_control_flow, true, &ctx, CHECK_VERIFY_(this, 0)); if (!matches) { // report type error verify_error(ctx, "Instruction type does not match stack map"); @@ -1864,7 +1858,7 @@ } ErrorContext ctx; bool matches = stackmap_table->match_stackmap( - new_frame, handler_pc, true, false, true, &ctx, CHECK_VERIFY(this)); + new_frame, handler_pc, true, false, &ctx, CHECK_VERIFY(this)); if (!matches) { verify_error(ctx, "Stack map does not match the one at " "exception handler %d", handler_pc);
--- a/test/runtime/handlerInTry/LoadHandlerInTry.java Mon Feb 06 22:14:36 2017 +0000 +++ b/test/runtime/handlerInTry/LoadHandlerInTry.java Tue Feb 07 04:06:40 2017 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, 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 @@ -24,7 +24,7 @@ /* * @test * @bug 8075118 - * @summary Allow a ctor to call super() from a switch bytecode. + * @summary JVM stuck in infinite loop during verification * @compile HandlerInTry.jasm * @compile IsolatedHandlerInTry.jasm * @run main/othervm -Xverify:all LoadHandlerInTry @@ -70,9 +70,10 @@ System.out.println("Regression test for bug 8075118"); try { Class newClass = Class.forName("HandlerInTry"); - } catch (Exception e) { - System.out.println("Failed: Exception was thrown: " + e.toString()); - throw e; + throw new RuntimeException( + "Failed to throw VerifyError for HandlerInTry"); + } catch (java.lang.VerifyError e) { + System.out.println("Passed: VerifyError exception was thrown"); } try {