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 {