Merge
authorroland
Wed, 09 Jul 2014 02:50:46 -0700
changeset 25497 96466aeaee66
parent 25381 dc89e2c8bda5 (current diff)
parent 25496 a829ea1310b5 (diff)
child 25498 52d596882831
Merge
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Jul 03 13:17:29 2014 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Wed Jul 09 02:50:46 2014 -0700
@@ -1997,7 +1997,13 @@
   if (!UseInlineCaches && is_loaded && code == Bytecodes::_invokevirtual
       && !target->can_be_statically_bound()) {
     // Find a vtable index if one is available
-    vtable_index = target->resolve_vtable_index(calling_klass, callee_holder);
+    // For arrays, callee_holder is Object. Resolving the call with
+    // Object would allow an illegal call to finalize() on an
+    // array. We use holder instead: illegal calls to finalize() won't
+    // be compiled as vtable calls (IC call resolution will catch the
+    // illegal call) and the few legal calls on array types won't be
+    // either.
+    vtable_index = target->resolve_vtable_index(calling_klass, holder);
   }
 #endif
 
--- a/hotspot/src/share/vm/code/vtableStubs.cpp	Thu Jul 03 13:17:29 2014 -0700
+++ b/hotspot/src/share/vm/code/vtableStubs.cpp	Wed Jul 09 02:50:46 2014 -0700
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "code/vtableStubs.hpp"
+#include "compiler/compileBroker.hpp"
 #include "compiler/disassembler.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
@@ -62,6 +63,7 @@
    // If changing the name, update the other file accordingly.
     BufferBlob* blob = BufferBlob::create("vtable chunks", bytes);
     if (blob == NULL) {
+      CompileBroker::handle_full_code_cache();
       return NULL;
     }
     _chunk = blob->content_begin();
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Jul 03 13:17:29 2014 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Wed Jul 09 02:50:46 2014 -0700
@@ -1093,6 +1093,7 @@
 address SignatureHandlerLibrary::set_handler_blob() {
   BufferBlob* handler_blob = BufferBlob::create("native signature handlers", blob_size);
   if (handler_blob == NULL) {
+    CompileBroker::handle_full_code_cache();
     return NULL;
   }
   address handler = handler_blob->code_begin();
--- a/hotspot/src/share/vm/opto/callGenerator.cpp	Thu Jul 03 13:17:29 2014 -0700
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp	Wed Jul 09 02:50:46 2014 -0700
@@ -871,8 +871,11 @@
           Node*             receiver_node = kit.argument(0);
           const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr();
           // call_does_dispatch and vtable_index are out-parameters.  They might be changed.
-          target = C->optimize_virtual_call(caller, jvms->bci(), klass, target, receiver_type,
-                                            is_virtual,
+          // optimize_virtual_call() takes 2 different holder
+          // arguments for a corner case that doesn't apply here (see
+          // Parse::do_call())
+          target = C->optimize_virtual_call(caller, jvms->bci(), klass, klass,
+                                            target, receiver_type, is_virtual,
                                             call_does_dispatch, vtable_index);  // out-parameters
           // We lack profiling at this call but type speculation may
           // provide us with a type
--- a/hotspot/src/share/vm/opto/compile.cpp	Thu Jul 03 13:17:29 2014 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 09 02:50:46 2014 -0700
@@ -29,6 +29,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "code/exceptionHandlerTable.hpp"
 #include "code/nmethod.hpp"
+#include "compiler/compileBroker.hpp"
 #include "compiler/compileLog.hpp"
 #include "compiler/disassembler.hpp"
 #include "compiler/oopMap.hpp"
@@ -555,6 +556,7 @@
     if (scratch_buffer_blob() == NULL) {
       // Let CompilerBroker disable further compilations.
       record_failure("Not enough space for scratch buffer in CodeCache");
+      CompileBroker::handle_full_code_cache();
       return;
     }
   }
--- a/hotspot/src/share/vm/opto/compile.hpp	Thu Jul 03 13:17:29 2014 -0700
+++ b/hotspot/src/share/vm/opto/compile.hpp	Wed Jul 09 02:50:46 2014 -0700
@@ -852,8 +852,8 @@
 
   // Helper functions to identify inlining potential at call-site
   ciMethod* optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass,
-                                  ciMethod* callee, const TypeOopPtr* receiver_type,
-                                  bool is_virtual,
+                                  ciKlass* holder, ciMethod* callee,
+                                  const TypeOopPtr* receiver_type, bool is_virtual,
                                   bool &call_does_dispatch, int &vtable_index);
   ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass,
                               ciMethod* callee, const TypeOopPtr* receiver_type);
--- a/hotspot/src/share/vm/opto/doCall.cpp	Thu Jul 03 13:17:29 2014 -0700
+++ b/hotspot/src/share/vm/opto/doCall.cpp	Wed Jul 09 02:50:46 2014 -0700
@@ -468,8 +468,14 @@
     Node* receiver_node             = stack(sp() - nargs);
     const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr();
     // call_does_dispatch and vtable_index are out-parameters.  They might be changed.
-    callee = C->optimize_virtual_call(method(), bci(), klass, orig_callee, receiver_type,
-                                      is_virtual,
+    // For arrays, klass below is Object. When vtable calls are used,
+    // resolving the call with Object would allow an illegal call to
+    // finalize() on an array. We use holder instead: illegal calls to
+    // finalize() won't be compiled as vtable calls (IC call
+    // resolution will catch the illegal call) and the few legal calls
+    // on array types won't be either.
+    callee = C->optimize_virtual_call(method(), bci(), klass, holder, orig_callee,
+                                      receiver_type, is_virtual,
                                       call_does_dispatch, vtable_index);  // out-parameters
     speculative_receiver_type = receiver_type != NULL ? receiver_type->speculative_type() : NULL;
   }
@@ -940,8 +946,8 @@
 
 
 ciMethod* Compile::optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass,
-                                         ciMethod* callee, const TypeOopPtr* receiver_type,
-                                         bool is_virtual,
+                                         ciKlass* holder, ciMethod* callee,
+                                         const TypeOopPtr* receiver_type, bool is_virtual,
                                          bool& call_does_dispatch, int& vtable_index) {
   // Set default values for out-parameters.
   call_does_dispatch = true;
@@ -956,7 +962,7 @@
     call_does_dispatch = false;
   } else if (!UseInlineCaches && is_virtual && callee->is_loaded()) {
     // We can make a vtable call at this site
-    vtable_index = callee->resolve_vtable_index(caller->holder(), klass);
+    vtable_index = callee->resolve_vtable_index(caller->holder(), holder);
   }
   return callee;
 }
@@ -979,8 +985,10 @@
   ciInstanceKlass* actual_receiver = klass;
   if (receiver_type != NULL) {
     // Array methods are all inherited from Object, and are monomorphic.
+    // finalize() call on array is not allowed.
     if (receiver_type->isa_aryptr() &&
-        callee->holder() == env()->Object_klass()) {
+        callee->holder() == env()->Object_klass() &&
+        callee->name() != ciSymbol::finalize_method_name()) {
       return callee;
     }
 
--- a/hotspot/src/share/vm/opto/output.cpp	Thu Jul 03 13:17:29 2014 -0700
+++ b/hotspot/src/share/vm/opto/output.cpp	Wed Jul 09 02:50:46 2014 -0700
@@ -1163,6 +1163,7 @@
   // Have we run out of code space?
   if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) {
     C->record_failure("CodeCache is full");
+    CompileBroker::handle_full_code_cache();
     return NULL;
   }
   // Configure the code buffer.
@@ -1487,6 +1488,7 @@
       cb->insts()->maybe_expand_to_ensure_remaining(MAX_inst_size);
       if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) {
         C->record_failure("CodeCache is full");
+        CompileBroker::handle_full_code_cache();
         return;
       }
 
@@ -1643,6 +1645,7 @@
   // One last check for failed CodeBuffer::expand:
   if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) {
     C->record_failure("CodeCache is full");
+    CompileBroker::handle_full_code_cache();
     return;
   }
 
--- a/hotspot/src/share/vm/opto/parse.hpp	Thu Jul 03 13:17:29 2014 -0700
+++ b/hotspot/src/share/vm/opto/parse.hpp	Wed Jul 09 02:50:46 2014 -0700
@@ -557,8 +557,9 @@
 
   float   dynamic_branch_prediction(float &cnt);
   float   branch_prediction(float &cnt, BoolTest::mask btest, int target_bci);
-  bool    seems_never_taken(float prob);
-  bool    seems_stable_comparison(BoolTest::mask btest, Node* c);
+  bool    seems_never_taken(float prob) const;
+  bool    path_is_suitable_for_uncommon_trap(float prob) const;
+  bool    seems_stable_comparison() const;
 
   void    do_ifnull(BoolTest::mask btest, Node* c);
   void    do_if(BoolTest::mask btest, Node* c);
--- a/hotspot/src/share/vm/opto/parse2.cpp	Thu Jul 03 13:17:29 2014 -0700
+++ b/hotspot/src/share/vm/opto/parse2.cpp	Wed Jul 09 02:50:46 2014 -0700
@@ -886,7 +886,7 @@
 // some branches (e.g., _213_javac.Assembler.eliminate) validly produce
 // very small but nonzero probabilities, which if confused with zero
 // counts would keep the program recompiling indefinitely.
-bool Parse::seems_never_taken(float prob) {
+bool Parse::seems_never_taken(float prob) const {
   return prob < PROB_MIN;
 }
 
@@ -898,7 +898,7 @@
 // already acting in a stable fashion.  If the comparison
 // seems stable, we will put an expensive uncommon trap
 // on the untaken path.
-bool Parse::seems_stable_comparison(BoolTest::mask btest, Node* cmp) {
+bool Parse::seems_stable_comparison() const {
   if (C->too_many_traps(method(), bci(), Deoptimization::Reason_unstable_if)) {
     return false;
   }
@@ -1127,6 +1127,14 @@
   }
 }
 
+bool Parse::path_is_suitable_for_uncommon_trap(float prob) const {
+  // Don't want to speculate on uncommon traps when running with -Xcomp
+  if (!UseInterpreter) {
+    return false;
+  }
+  return (seems_never_taken(prob) && seems_stable_comparison());
+}
+
 //----------------------------adjust_map_after_if------------------------------
 // Adjust the JVM state to reflect the result of taking this path.
 // Basically, it means inspecting the CmpNode controlling this
@@ -1140,7 +1148,7 @@
 
   bool is_fallthrough = (path == successor_for_bci(iter().next_bci()));
 
-  if (seems_never_taken(prob) && seems_stable_comparison(btest, c)) {
+  if (path_is_suitable_for_uncommon_trap(prob)) {
     repush_if_args();
     uncommon_trap(Deoptimization::Reason_unstable_if,
                   Deoptimization::Action_reinterpret,
--- a/hotspot/src/share/vm/runtime/icache.cpp	Thu Jul 03 13:17:29 2014 -0700
+++ b/hotspot/src/share/vm/runtime/icache.cpp	Wed Jul 09 02:50:46 2014 -0700
@@ -34,6 +34,9 @@
   ResourceMark rm;
 
   BufferBlob* b = BufferBlob::create("flush_icache_stub", ICache::stub_size);
+  if (b == NULL) {
+    vm_exit_out_of_memory(ICache::stub_size, OOM_MALLOC_ERROR, "CodeCache: no space for flush_icache_stub");
+  }
   CodeBuffer c(b);
 
   ICacheStubGenerator g(&c);