changeset 6754:71d4b9b14f9f

Merge
author asaha
date Thu, 26 Jun 2014 08:29:41 -0700
parents 220eefb3609e 4af30e82ba9e
children acdb7e8e4982
files .hgtags make/hotspot_version
diffstat 10 files changed, 128 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Jun 18 13:30:11 2014 -0700
+++ b/.hgtags	Thu Jun 26 08:29:41 2014 -0700
@@ -438,6 +438,7 @@
 17a75e692af397532e2b296b24f6b9b6c239c633 jdk8u5-b11
 9b289963cb9a14636fbe8faaa2dd6d3678464a7b jdk8u5-b12
 8a67179106085689906732013a282efeeb9bd5f4 jdk8u5-b13
+5c7ef8e396835b82c0460b73f23cac86ba34846f jdk8u5-b31
 f0d759a6a2309a1c149d530b29db24eda885f267 jdk8u11-b01
 3c079aebb516765784dd8097887daadda5a76ac1 jdk8u11-b02
 0037e964ce486c009984171f004259263628079f jdk8u11-b03
@@ -488,6 +489,8 @@
 11159d7ec80462a422e39c9b3a39ae932923622d jdk8u20-b18
 3e1cec358ab95ef985f821219104141b9ffda83f hs25.20-b19
 b15553cde967dfd7781a4a5c669e4cb7db734317 jdk8u20-b19
+4f18dea0312d601d0515976bc0c643ea7acc829d hs25.20-b20
+9e4d27da4ac04c6e19291087f7c68a5c5803c7ca jdk8u20-b20
 a4d44dfb7d30eea54bc172e4429a655454ae0bbf jdk8u25-b00
 9a2152fbd929b0d8b2f5c326a5526214ae71731a jdk8u25-b01
 d3d5604ea0dea3812e87ba76ac199d0a8be6f49f jdk8u25-b02
--- a/agent/src/os/linux/libproc.h	Wed Jun 18 13:30:11 2014 -0700
+++ b/agent/src/os/linux/libproc.h	Thu Jun 26 08:29:41 2014 -0700
@@ -34,7 +34,7 @@
 #include "libproc_md.h"
 #endif
 
-#include <linux/ptrace.h>
+#include <sys/ptrace.h>
 
 /************************************************************************************
 
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Jun 18 13:30:11 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Jun 26 08:29:41 2014 -0700
@@ -432,14 +432,6 @@
   return hr;
 }
 
-void G1CollectedHeap::stop_conc_gc_threads() {
-  _cg1r->stop();
-  _cmThread->stop();
-  if (G1StringDedup::is_enabled()) {
-    G1StringDedup::stop();
-  }
-}
-
 #ifdef ASSERT
 // A region is added to the collection set as it is retired
 // so an address p can point to a region which will be in the
@@ -2186,20 +2178,14 @@
 }
 
 void G1CollectedHeap::stop() {
-#if 0
-  // Stopping concurrent worker threads is currently disabled until
-  // some bugs in concurrent mark has been resolve. Without fixing
-  // those bugs first we risk haning during VM exit when trying to
-  // stop these threads.
-
-  // Abort any ongoing concurrent root region scanning and stop all
-  // concurrent threads. We do this to make sure these threads do
-  // not continue to execute and access resources (e.g. gclog_or_tty)
+  // Stop all concurrent threads. We do this to make sure these threads
+  // do not continue to execute and access resources (e.g. gclog_or_tty)
   // that are destroyed during shutdown.
-  _cm->root_regions()->abort();
-  _cm->root_regions()->wait_until_scan_finished();
-  stop_conc_gc_threads();
-#endif
+  _cg1r->stop();
+  _cmThread->stop();
+  if (G1StringDedup::is_enabled()) {
+    G1StringDedup::stop();
+  }
 }
 
 size_t G1CollectedHeap::conservative_max_heap_alignment() {
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Jun 18 13:30:11 2014 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Jun 26 08:29:41 2014 -0700
@@ -1699,8 +1699,6 @@
   void print_all_rsets() PRODUCT_RETURN;
 
 public:
-  void stop_conc_gc_threads();
-
   size_t pending_card_num();
   size_t cards_scanned();
 
--- a/src/share/vm/opto/graphKit.cpp	Wed Jun 18 13:30:11 2014 -0700
+++ b/src/share/vm/opto/graphKit.cpp	Thu Jun 26 08:29:41 2014 -0700
@@ -2458,7 +2458,7 @@
 
 //------------------------------make_slow_call_ex------------------------------
 // Make the exception handler hookups for the slow call
-void GraphKit::make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj) {
+void GraphKit::make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj, bool deoptimize) {
   if (stopped())  return;
 
   // Make a catch node with just two handlers:  fall-through and catch-all
@@ -2472,11 +2472,17 @@
     set_i_o(i_o);
 
     if (excp != top()) {
-      // Create an exception state also.
-      // Use an exact type if the caller has specified a specific exception.
-      const Type* ex_type = TypeOopPtr::make_from_klass_unique(ex_klass)->cast_to_ptr_type(TypePtr::NotNull);
-      Node*       ex_oop  = new (C) CreateExNode(ex_type, control(), i_o);
-      add_exception_state(make_exception_state(_gvn.transform(ex_oop)));
+      if (deoptimize) {
+        // Deoptimize if an exception is caught. Don't construct exception state in this case.
+        uncommon_trap(Deoptimization::Reason_unhandled,
+                      Deoptimization::Action_none);
+      } else {
+        // Create an exception state also.
+        // Use an exact type if the caller has specified a specific exception.
+        const Type* ex_type = TypeOopPtr::make_from_klass_unique(ex_klass)->cast_to_ptr_type(TypePtr::NotNull);
+        Node*       ex_oop  = new (C) CreateExNode(ex_type, control(), i_o);
+        add_exception_state(make_exception_state(_gvn.transform(ex_oop)));
+      }
     }
   }
 
@@ -3290,7 +3296,8 @@
 
 //---------------------------set_output_for_allocation-------------------------
 Node* GraphKit::set_output_for_allocation(AllocateNode* alloc,
-                                          const TypeOopPtr* oop_type) {
+                                          const TypeOopPtr* oop_type,
+                                          bool deoptimize_on_exception) {
   int rawidx = Compile::AliasIdxRaw;
   alloc->set_req( TypeFunc::FramePtr, frameptr() );
   add_safepoint_edges(alloc);
@@ -3298,7 +3305,7 @@
   set_control( _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Control) ) );
   // create memory projection for i_o
   set_memory ( _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Memory, true) ), rawidx );
-  make_slow_call_ex(allocx, env()->Throwable_klass(), true);
+  make_slow_call_ex(allocx, env()->Throwable_klass(), true, deoptimize_on_exception);
 
   // create a memory projection as for the normal control path
   Node* malloc = _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Memory));
@@ -3376,9 +3383,11 @@
 // The optional arguments are for specialized use by intrinsics:
 //  - If 'extra_slow_test' if not null is an extra condition for the slow-path.
 //  - If 'return_size_val', report the the total object size to the caller.
+//  - deoptimize_on_exception controls how Java exceptions are handled (rethrow vs deoptimize)
 Node* GraphKit::new_instance(Node* klass_node,
                              Node* extra_slow_test,
-                             Node* *return_size_val) {
+                             Node* *return_size_val,
+                             bool deoptimize_on_exception) {
   // Compute size in doublewords
   // The size is always an integral number of doublewords, represented
   // as a positive bytewise size stored in the klass's layout_helper.
@@ -3447,7 +3456,7 @@
                            size, klass_node,
                            initial_slow_test);
 
-  return set_output_for_allocation(alloc, oop_type);
+  return set_output_for_allocation(alloc, oop_type, deoptimize_on_exception);
 }
 
 //-------------------------------new_array-------------------------------------
@@ -3457,7 +3466,8 @@
 Node* GraphKit::new_array(Node* klass_node,     // array klass (maybe variable)
                           Node* length,         // number of array elements
                           int   nargs,          // number of arguments to push back for uncommon trap
-                          Node* *return_size_val) {
+                          Node* *return_size_val,
+                          bool deoptimize_on_exception) {
   jint  layout_con = Klass::_lh_neutral_value;
   Node* layout_val = get_layout_helper(klass_node, layout_con);
   int   layout_is_con = (layout_val == NULL);
@@ -3600,7 +3610,7 @@
     ary_type = ary_type->is_aryptr()->cast_to_size(length_type);
   }
 
-  Node* javaoop = set_output_for_allocation(alloc, ary_type);
+  Node* javaoop = set_output_for_allocation(alloc, ary_type, deoptimize_on_exception);
 
   // Cast length on remaining path to be as narrow as possible
   if (map()->find_edge(length) >= 0) {
--- a/src/share/vm/opto/graphKit.hpp	Wed Jun 18 13:30:11 2014 -0700
+++ b/src/share/vm/opto/graphKit.hpp	Thu Jun 26 08:29:41 2014 -0700
@@ -802,7 +802,7 @@
 
   // merge in all memory slices from new_mem, along the given path
   void merge_memory(Node* new_mem, Node* region, int new_path);
-  void make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj);
+  void make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj, bool deoptimize = false);
 
   // Helper functions to build synchronizations
   int next_monitor();
@@ -844,13 +844,16 @@
 
   // implementation of object creation
   Node* set_output_for_allocation(AllocateNode* alloc,
-                                  const TypeOopPtr* oop_type);
+                                  const TypeOopPtr* oop_type,
+                                  bool deoptimize_on_exception=false);
   Node* get_layout_helper(Node* klass_node, jint& constant_value);
   Node* new_instance(Node* klass_node,
                      Node* slow_test = NULL,
-                     Node* *return_size_val = NULL);
+                     Node* *return_size_val = NULL,
+                     bool deoptimize_on_exception = false);
   Node* new_array(Node* klass_node, Node* count_val, int nargs,
-                  Node* *return_size_val = NULL);
+                  Node* *return_size_val = NULL,
+                  bool deoptimize_on_exception = false);
 
   // java.lang.String helpers
   Node* load_String_offset(Node* ctrl, Node* str);
--- a/src/share/vm/opto/library_call.cpp	Wed Jun 18 13:30:11 2014 -0700
+++ b/src/share/vm/opto/library_call.cpp	Thu Jun 26 08:29:41 2014 -0700
@@ -4576,7 +4576,10 @@
       // It's an instance, and it passed the slow-path tests.
       PreserveJVMState pjvms(this);
       Node* obj_size  = NULL;
-      Node* alloc_obj = new_instance(obj_klass, NULL, &obj_size);
+      // Need to deoptimize on exception from allocation since Object.clone intrinsic
+      // is reexecuted if deoptimization occurs and there could be problems when merging
+      // exception state between multiple Object.clone versions (reexecute=true vs reexecute=false).
+      Node* alloc_obj = new_instance(obj_klass, NULL, &obj_size, /*deoptimize_on_exception=*/true);
 
       copy_to_clone(obj, alloc_obj, obj_size, false, !use_ReduceInitialCardMarks());
 
--- a/src/share/vm/runtime/java.cpp	Wed Jun 18 13:30:11 2014 -0700
+++ b/src/share/vm/runtime/java.cpp	Thu Jun 26 08:29:41 2014 -0700
@@ -497,9 +497,6 @@
     os::infinite_sleep();
   }
 
-  // Stop any ongoing concurrent GC work
-  Universe::heap()->stop();
-
   // Terminate watcher thread - must before disenrolling any periodic task
   if (PeriodicTask::num_tasks() > 0)
     WatcherThread::stop();
@@ -514,10 +511,8 @@
   StatSampler::disengage();
   StatSampler::destroy();
 
-  // We do not need to explicitly stop concurrent GC threads because the
-  // JVM will be taken down at a safepoint when such threads are inactive --
-  // except for some concurrent G1 threads, see (comment in)
-  // Threads::destroy_vm().
+  // Stop concurrent GC threads
+  Universe::heap()->stop();
 
   // Print GC/heap related information.
   if (PrintGCDetails) {
--- a/src/share/vm/runtime/thread.cpp	Wed Jun 18 13:30:11 2014 -0700
+++ b/src/share/vm/runtime/thread.cpp	Thu Jun 26 08:29:41 2014 -0700
@@ -4013,14 +4013,8 @@
     // GC vm_operations can get caught at the safepoint, and the
     // heap is unparseable if they are caught. Grab the Heap_lock
     // to prevent this. The GC vm_operations will not be able to
-    // queue until after the vm thread is dead.
-    // After this point, we'll never emerge out of the safepoint before
-    // the VM exits, so concurrent GC threads do not need to be explicitly
-    // stopped; they remain inactive until the process exits.
-    // Note: some concurrent G1 threads may be running during a safepoint,
-    // but these will not be accessing the heap, just some G1-specific side
-    // data structures that are not accessed by any other threads but them
-    // after this point in a terminal safepoint.
+    // queue until after the vm thread is dead. After this point,
+    // we'll never emerge out of the safepoint before the VM exits.
 
     MutexLocker ml(Heap_lock);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/intrinsics/clone/TestObjectClone.java	Thu Jun 26 08:29:41 2014 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014, 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 8033626
+ * @summary assert(ex_map->jvms()->same_calls_as(_exceptions->jvms())) failed: all collected exceptions must come from the same place
+ * @library /testlibrary
+ * @run main/othervm -XX:-TieredCompilation -Xbatch -XX:CompileOnly=TestObjectClone::f TestObjectClone
+ */
+import com.oracle.java.testlibrary.Asserts;
+
+public class TestObjectClone implements Cloneable {
+    static class A extends TestObjectClone {}
+    static class B extends TestObjectClone {
+        public B clone() {
+            return (B)TestObjectClone.b;
+        }
+    }
+    static class C extends TestObjectClone {
+        public C clone() {
+            return (C)TestObjectClone.c;
+        }
+    }
+    static class D extends TestObjectClone {
+        public D clone() {
+            return (D)TestObjectClone.d;
+        }
+    }
+    static TestObjectClone a = new A(), b = new B(), c = new C(), d = new D();
+
+    public static Object f(TestObjectClone o) throws CloneNotSupportedException {
+        // Polymorphic call site: >90% Object::clone / <10% other methods
+        return o.clone();
+    }
+
+    public static void main(String[] args) throws Exception {
+        TestObjectClone[] params1 = {a, a, a, a, a, a, a, a, a, a, a,
+                          a, a, a, a, a, a, a, a, a, a, a,
+                          a, a, a, a, a, a, a, a, a, a, a,
+                          b, c, d};
+
+        for (int i = 0; i < 15000; i++) {
+            f(params1[i % params1.length]);
+        }
+
+        Asserts.assertTrue(f(a) != a);
+        Asserts.assertTrue(f(b) == b);
+        Asserts.assertTrue(f(c) == c);
+        Asserts.assertTrue(f(d) == d);
+
+        try {
+            f(null);
+            throw new AssertionError("");
+        } catch (NullPointerException e) { /* expected */ }
+
+        System.out.println("TEST PASSED");
+    }
+}