changeset 6930:fc1f9b67fd8c jdk8u40-b17

Merge
author amurillo
date Tue, 02 Dec 2014 09:50:33 -0800
parents 3562db849018 01de5cfa06c1
children 0d749db61a36 ea6dbaa4bf8e
files
diffstat 25 files changed, 366 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Nov 26 13:58:01 2014 -0800
+++ b/.hgtags	Tue Dec 02 09:50:33 2014 -0800
@@ -557,3 +557,4 @@
 3a8a0fd171c5876023112941b1c7254262f9adfc hs25.40-b19
 aa2442f89230dc46147c721812f3b3bd4c612e83 hs25.40-b20
 5ea68fb91139081304357f9b937f32c5fdfeca6d jdk8u40-b16
+6bf89bfe8185747a57193efb6cec1f17ccc80414 hs25.40-b21
--- a/make/hotspot_version	Wed Nov 26 13:58:01 2014 -0800
+++ b/make/hotspot_version	Tue Dec 02 09:50:33 2014 -0800
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=25
 HS_MINOR_VER=40
-HS_BUILD_NUMBER=20
+HS_BUILD_NUMBER=21
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
--- a/src/share/vm/ci/ciMethod.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/ci/ciMethod.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -68,7 +68,10 @@
 // ciMethod::ciMethod
 //
 // Loaded method.
-ciMethod::ciMethod(methodHandle h_m) : ciMetadata(h_m()) {
+ciMethod::ciMethod(methodHandle h_m, ciInstanceKlass* holder) :
+  ciMetadata(h_m()),
+  _holder(holder)
+{
   assert(h_m() != NULL, "no null method");
 
   // These fields are always filled in in loaded methods.
@@ -124,7 +127,6 @@
   // generating _signature may allow GC and therefore move m.
   // These fields are always filled in.
   _name = env->get_symbol(h_m()->name());
-  _holder = env->get_instance_klass(h_m()->method_holder());
   ciSymbol* sig_symbol = env->get_symbol(h_m()->signature());
   constantPoolHandle cpool = h_m()->constants();
   _signature = new (env->arena()) ciSignature(_holder, cpool, sig_symbol);
--- a/src/share/vm/ci/ciMethod.hpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/ci/ciMethod.hpp	Tue Dec 02 09:50:33 2014 -0800
@@ -90,7 +90,7 @@
   BCEscapeAnalyzer*   _bcea;
 #endif
 
-  ciMethod(methodHandle h_m);
+  ciMethod(methodHandle h_m, ciInstanceKlass* holder);
   ciMethod(ciInstanceKlass* holder, ciSymbol* name, ciSymbol* signature, ciInstanceKlass* accessor);
 
   Method* get_Method() const {
--- a/src/share/vm/ci/ciObjectFactory.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/ci/ciObjectFactory.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -239,7 +239,7 @@
 ciObject* ciObjectFactory::get(oop key) {
   ASSERT_IN_VM;
 
-  assert(key == NULL || Universe::heap()->is_in_reserved(key), "must be");
+  assert(Universe::heap()->is_in_reserved(key), "must be");
 
   NonPermObject* &bucket = find_non_perm(key);
   if (bucket != NULL) {
@@ -260,10 +260,10 @@
 }
 
 // ------------------------------------------------------------------
-// ciObjectFactory::get
+// ciObjectFactory::get_metadata
 //
-// Get the ciObject corresponding to some oop.  If the ciObject has
-// already been created, it is returned.  Otherwise, a new ciObject
+// Get the ciMetadata corresponding to some Metadata. If the ciMetadata has
+// already been created, it is returned. Otherwise, a new ciMetadata
 // is created.
 ciMetadata* ciObjectFactory::get_metadata(Metadata* key) {
   ASSERT_IN_VM;
@@ -290,9 +290,9 @@
   }
 #endif
   if (!is_found_at(index, key, _ci_metadata)) {
-    // The ciObject does not yet exist.  Create it and insert it
+    // The ciMetadata does not yet exist. Create it and insert it
     // into the cache.
-    ciMetadata* new_object = create_new_object(key);
+    ciMetadata* new_object = create_new_metadata(key);
     init_ident_of(new_object);
     assert(new_object->is_metadata(), "must be");
 
@@ -344,15 +344,28 @@
 }
 
 // ------------------------------------------------------------------
-// ciObjectFactory::create_new_object
+// ciObjectFactory::create_new_metadata
 //
-// Create a new ciObject from a Metadata*.
+// Create a new ciMetadata from a Metadata*.
 //
-// Implementation note: this functionality could be virtual behavior
-// of the oop itself.  For now, we explicitly marshal the object.
-ciMetadata* ciObjectFactory::create_new_object(Metadata* o) {
+// Implementation note: in order to keep Metadata live, an auxiliary ciObject
+// is used, which points to it's holder.
+ciMetadata* ciObjectFactory::create_new_metadata(Metadata* o) {
   EXCEPTION_CONTEXT;
 
+  // Hold metadata from unloading by keeping it's holder alive.
+  if (_initialized && o->is_klass()) {
+    Klass* holder = ((Klass*)o);
+    if (holder->oop_is_instance() && InstanceKlass::cast(holder)->is_anonymous()) {
+      // Though ciInstanceKlass records class loader oop, it's not enough to keep
+      // VM anonymous classes alive (loader == NULL). Klass holder should be used instead.
+      // It is enough to record a ciObject, since cached elements are never removed
+      // during ciObjectFactory lifetime. ciObjectFactory itself is created for
+      // every compilation and lives for the whole duration of the compilation.
+      ciObject* h = get(holder->klass_holder());
+    }
+  }
+
   if (o->is_klass()) {
     KlassHandle h_k(THREAD, (Klass*)o);
     Klass* k = (Klass*)o;
@@ -365,14 +378,16 @@
     }
   } else if (o->is_method()) {
     methodHandle h_m(THREAD, (Method*)o);
-    return new (arena()) ciMethod(h_m);
+    ciEnv *env = CURRENT_THREAD_ENV;
+    ciInstanceKlass* holder = env->get_instance_klass(h_m()->method_holder());
+    return new (arena()) ciMethod(h_m, holder);
   } else if (o->is_methodData()) {
     // Hold methodHandle alive - might not be necessary ???
     methodHandle h_m(THREAD, ((MethodData*)o)->method());
     return new (arena()) ciMethodData((MethodData*)o);
   }
 
-  // The oop is of some type not supported by the compiler interface.
+  // The Metadata* is of some type not supported by the compiler interface.
   ShouldNotReachHere();
   return NULL;
 }
@@ -701,7 +716,7 @@
 // If there is no entry in the cache corresponding to this oop, return
 // the null tail of the bucket into which the oop should be inserted.
 ciObjectFactory::NonPermObject* &ciObjectFactory::find_non_perm(oop key) {
-  assert(Universe::heap()->is_in_reserved_or_null(key), "must be");
+  assert(Universe::heap()->is_in_reserved(key), "must be");
   ciMetadata* klass = get_metadata(key->klass());
   NonPermObject* *bp = &_non_perm_bucket[(unsigned) klass->hash() % NON_PERM_BUCKETS];
   for (NonPermObject* p; (p = (*bp)) != NULL; bp = &p->next()) {
--- a/src/share/vm/ci/ciObjectFactory.hpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/ci/ciObjectFactory.hpp	Tue Dec 02 09:50:33 2014 -0800
@@ -73,7 +73,7 @@
   void insert(int index, ciMetadata* obj, GrowableArray<ciMetadata*>* objects);
 
   ciObject* create_new_object(oop o);
-  ciMetadata* create_new_object(Metadata* o);
+  ciMetadata* create_new_metadata(Metadata* o);
 
   void ensure_metadata_alive(ciMetadata* m);
 
--- a/src/share/vm/ci/ciTypeFlow.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/ci/ciTypeFlow.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -35,6 +35,7 @@
 #include "interpreter/bytecode.hpp"
 #include "interpreter/bytecodes.hpp"
 #include "memory/allocation.inline.hpp"
+#include "opto/compile.hpp"
 #include "runtime/deoptimization.hpp"
 #include "utilities/growableArray.hpp"
 
@@ -2646,7 +2647,7 @@
       assert (!blk->has_pre_order(), "");
       blk->set_next_pre_order();
 
-      if (_next_pre_order >= MaxNodeLimit / 2) {
+      if (_next_pre_order >= (int)Compile::current()->max_node_limit() / 2) {
         // Too many basic blocks.  Bail out.
         // This can happen when try/finally constructs are nested to depth N,
         // and there is O(2**N) cloning of jsr bodies.  See bug 4697245!
--- a/src/share/vm/classfile/classLoaderExt.hpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/classfile/classLoaderExt.hpp	Tue Dec 02 09:50:33 2014 -0800
@@ -63,6 +63,9 @@
                                    ClassPathEntry* new_entry) {
     ClassLoader::add_to_list(new_entry);
   }
+  static void append_boot_classpath(ClassPathEntry* new_entry) {
+    ClassLoader::add_to_list(new_entry);
+  }
   static void setup_search_paths() {}
 
   static void init_lookup_cache(TRAPS) {}
--- a/src/share/vm/code/dependencies.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/code/dependencies.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -879,6 +879,8 @@
   bool is_witness(Klass* k) {
     if (doing_subtype_search()) {
       return Dependencies::is_concrete_klass(k);
+    } else if (!k->oop_is_instance()) {
+      return false; // no methods to find in an array type
     } else {
       Method* m = InstanceKlass::cast(k)->find_method(_name, _signature);
       if (m == NULL || !Dependencies::is_concrete_method(m))  return false;
@@ -1085,7 +1087,7 @@
   Klass* chain;       // scratch variable
 #define ADD_SUBCLASS_CHAIN(k)                     {  \
     assert(chaini < CHAINMAX, "oob");                \
-    chain = InstanceKlass::cast(k)->subklass();      \
+    chain = k->subklass();                           \
     if (chain != NULL)  chains[chaini++] = chain;    }
 
   // Look for non-abstract subclasses.
@@ -1096,35 +1098,37 @@
   // (Their subclasses are additional indirect implementors.
   // See InstanceKlass::add_implementor.)
   // (Note:  nof_implementors is always zero for non-interfaces.)
-  int nof_impls = InstanceKlass::cast(context_type)->nof_implementors();
-  if (nof_impls > 1) {
-    // Avoid this case: *I.m > { A.m, C }; B.m > C
-    // Here, I.m has 2 concrete implementations, but m appears unique
-    // as A.m, because the search misses B.m when checking C.
-    // The inherited method B.m was getting missed by the walker
-    // when interface 'I' was the starting point.
-    // %%% Until this is fixed more systematically, bail out.
-    // (Old CHA had the same limitation.)
-    return context_type;
-  }
-  if (nof_impls > 0) {
-    Klass* impl = InstanceKlass::cast(context_type)->implementor();
-    assert(impl != NULL, "just checking");
-    // If impl is the same as the context_type, then more than one
-    // implementor has seen. No exact info in this case.
-    if (impl == context_type) {
-      return context_type;  // report an inexact witness to this sad affair
+  if (top_level_call) {
+    int nof_impls = InstanceKlass::cast(context_type)->nof_implementors();
+    if (nof_impls > 1) {
+      // Avoid this case: *I.m > { A.m, C }; B.m > C
+      // Here, I.m has 2 concrete implementations, but m appears unique
+      // as A.m, because the search misses B.m when checking C.
+      // The inherited method B.m was getting missed by the walker
+      // when interface 'I' was the starting point.
+      // %%% Until this is fixed more systematically, bail out.
+      // (Old CHA had the same limitation.)
+      return context_type;
     }
-    if (do_counts)
-      { NOT_PRODUCT(deps_find_witness_steps++); }
-    if (is_participant(impl)) {
-      if (!participants_hide_witnesses) {
+    if (nof_impls > 0) {
+      Klass* impl = InstanceKlass::cast(context_type)->implementor();
+      assert(impl != NULL, "just checking");
+      // If impl is the same as the context_type, then more than one
+      // implementor has seen. No exact info in this case.
+      if (impl == context_type) {
+        return context_type;  // report an inexact witness to this sad affair
+      }
+      if (do_counts)
+        { NOT_PRODUCT(deps_find_witness_steps++); }
+      if (is_participant(impl)) {
+        if (!participants_hide_witnesses) {
+          ADD_SUBCLASS_CHAIN(impl);
+        }
+      } else if (is_witness(impl) && !ignore_witness(impl)) {
+        return impl;
+      } else {
         ADD_SUBCLASS_CHAIN(impl);
       }
-    } else if (is_witness(impl) && !ignore_witness(impl)) {
-      return impl;
-    } else {
-      ADD_SUBCLASS_CHAIN(impl);
     }
   }
 
--- a/src/share/vm/opto/c2_globals.hpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/opto/c2_globals.hpp	Tue Dec 02 09:50:33 2014 -0800
@@ -647,7 +647,7 @@
   develop(bool, AlwaysIncrementalInline, false,                             \
           "do all inlining incrementally")                                  \
                                                                             \
-  product(intx, LiveNodeCountInliningCutoff, 20000,                         \
+  product(intx, LiveNodeCountInliningCutoff, 40000,                         \
           "max number of live nodes in a method")                           \
                                                                             \
   diagnostic(bool, OptimizeExpensiveOps, true,                              \
--- a/src/share/vm/opto/compile.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/opto/compile.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -679,7 +679,8 @@
                   _inlining_incrementally(false),
                   _print_inlining_list(NULL),
                   _print_inlining_idx(0),
-                  _interpreter_frame_size(0) {
+                  _interpreter_frame_size(0),
+                  _max_node_limit(MaxNodeLimit) {
   C = this;
 
   CompileWrapper cw(this);
@@ -990,7 +991,8 @@
     _print_inlining_list(NULL),
     _print_inlining_idx(0),
     _allowed_reasons(0),
-    _interpreter_frame_size(0) {
+    _interpreter_frame_size(0),
+    _max_node_limit(MaxNodeLimit) {
   C = this;
 
 #ifndef PRODUCT
@@ -1100,6 +1102,7 @@
   set_do_count_invocations(false);
   set_do_method_data_update(false);
   set_rtm_state(NoRTM); // No RTM lock eliding by default
+  method_has_option_value("MaxNodeLimit", _max_node_limit);
 #if INCLUDE_RTM_OPT
   if (UseRTMLocking && has_method() && (method()->method_data_or_null() != NULL)) {
     int rtm_state = method()->method_data()->rtm_state();
--- a/src/share/vm/opto/compile.hpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/opto/compile.hpp	Tue Dec 02 09:50:33 2014 -0800
@@ -290,6 +290,7 @@
   int                   _freq_inline_size;      // Max hot method inline size for this compilation
   int                   _fixed_slots;           // count of frame slots not allocated by the register
                                                 // allocator i.e. locks, original deopt pc, etc.
+  uintx                 _max_node_limit;        // Max unique node count during a single compilation.
   // For deopt
   int                   _orig_pc_slot;
   int                   _orig_pc_slot_offset_in_bytes;
@@ -594,6 +595,9 @@
   void          set_rtm_state(RTMState s)        { _rtm_state = s; }
   bool              use_rtm() const              { return (_rtm_state & NoRTM) == 0; }
   bool          profile_rtm() const              { return _rtm_state == ProfileRTM; }
+  uint              max_node_limit() const       { return (uint)_max_node_limit; }
+  void          set_max_node_limit(uint n)       { _max_node_limit = n; }
+
   // check the CompilerOracle for special behaviours for this compile
   bool          method_has_option(const char * option) {
     return method() != NULL && method()->has_option(option);
@@ -723,7 +727,7 @@
     record_method_not_compilable(reason, true);
   }
   bool check_node_count(uint margin, const char* reason) {
-    if (live_nodes() + margin > (uint)MaxNodeLimit) {
+    if (live_nodes() + margin > max_node_limit()) {
       record_method_not_compilable(reason);
       return true;
     } else {
--- a/src/share/vm/opto/doCall.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/opto/doCall.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -410,6 +410,11 @@
   ciInstanceKlass* klass = ciEnv::get_instance_klass_for_declared_method_holder(holder);
   assert(declared_signature != NULL, "cannot be null");
 
+  // Bump max node limit for JSR292 users
+  if (bc() == Bytecodes::_invokedynamic || orig_callee->is_method_handle_intrinsic()) {
+    C->set_max_node_limit(3*MaxNodeLimit);
+  }
+
   // uncommon-trap when callee is unloaded, uninitialized or will not link
   // bailout when too many arguments for register representation
   if (!will_link || can_not_compile_call_site(orig_callee, klass)) {
--- a/src/share/vm/opto/escape.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/opto/escape.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -2409,7 +2409,7 @@
       }
     }
   }
-  if ((int) (C->live_nodes() + 2*NodeLimitFudgeFactor) > MaxNodeLimit) {
+  if (C->live_nodes() + 2*NodeLimitFudgeFactor > C->max_node_limit()) {
     if (C->do_escape_analysis() == true && !C->failing()) {
       // Retry compilation without escape analysis.
       // If this is the first failure, the sentinel string will "stick"
--- a/src/share/vm/opto/loopTransform.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/opto/loopTransform.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -269,10 +269,9 @@
 bool IdealLoopTree::policy_peeling( PhaseIdealLoop *phase ) const {
   Node *test = ((IdealLoopTree*)this)->tail();
   int  body_size = ((IdealLoopTree*)this)->_body.size();
-  int  live_node_count = phase->C->live_nodes();
   // Peeling does loop cloning which can result in O(N^2) node construction
   if( body_size > 255 /* Prevent overflow for large body_size */
-      || (body_size * body_size + live_node_count > MaxNodeLimit) ) {
+      || (body_size * body_size + phase->C->live_nodes()) > phase->C->max_node_limit() ) {
     return false;           // too large to safely clone
   }
   while( test != _head ) {      // Scan till run off top of loop
@@ -601,7 +600,7 @@
     return false;
   if (new_body_size > unroll_limit ||
       // Unrolling can result in a large amount of node construction
-      new_body_size >= MaxNodeLimit - (uint) phase->C->live_nodes()) {
+      new_body_size >= phase->C->max_node_limit() - phase->C->live_nodes()) {
     return false;
   }
 
@@ -2287,8 +2286,8 @@
 
   // Skip next optimizations if running low on nodes. Note that
   // policy_unswitching and policy_maximally_unroll have this check.
-  uint nodes_left = MaxNodeLimit - (uint) phase->C->live_nodes();
-  if ((2 * _body.size()) > nodes_left) {
+  int nodes_left = phase->C->max_node_limit() - phase->C->live_nodes();
+  if ((int)(2 * _body.size()) > nodes_left) {
     return true;
   }
 
--- a/src/share/vm/opto/loopUnswitch.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/opto/loopUnswitch.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -59,8 +59,8 @@
   if (!_head->is_Loop()) {
     return false;
   }
-  uint nodes_left = MaxNodeLimit - phase->C->live_nodes();
-  if (2 * _body.size() > nodes_left) {
+  int nodes_left = phase->C->max_node_limit() - phase->C->live_nodes();
+  if ((int)(2 * _body.size()) > nodes_left) {
     return false; // Too speculative if running low on nodes.
   }
   LoopNode* head = _head->as_Loop();
--- a/src/share/vm/opto/loopopts.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/opto/loopopts.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -734,7 +734,7 @@
   for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
     weight += region->fast_out(i)->outcnt();
   }
-  int nodes_left = MaxNodeLimit - C->live_nodes();
+  int nodes_left = C->max_node_limit() - C->live_nodes();
   if (weight * 8 > nodes_left) {
 #ifndef PRODUCT
     if (PrintOpto)
--- a/src/share/vm/opto/memnode.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/opto/memnode.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -1255,6 +1255,16 @@
               result = new (phase->C) ConvI2LNode(phase->transform(result));
             }
 #endif
+            // Boxing/unboxing can be done from signed & unsigned loads (e.g. LoadUB -> ... -> LoadB pair).
+            // Need to preserve unboxing load type if it is unsigned.
+            switch(this->Opcode()) {
+              case Op_LoadUB:
+                result = new (phase->C) AndINode(phase->transform(result), phase->intcon(0xFF));
+                break;
+              case Op_LoadUS:
+                result = new (phase->C) AndINode(phase->transform(result), phase->intcon(0xFFFF));
+                break;
+            }
             return result;
           }
         }
--- a/src/share/vm/opto/node.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/opto/node.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -69,7 +69,7 @@
   Compile::set_debug_idx(new_debug_idx);
   set_debug_idx( new_debug_idx );
   assert(Compile::current()->unique() < (INT_MAX - 1), "Node limit exceeded INT_MAX");
-  assert(Compile::current()->live_nodes() < (uint)MaxNodeLimit, "Live Node limit exceeded limit");
+  assert(Compile::current()->live_nodes() < Compile::current()->max_node_limit(), "Live Node limit exceeded limit");
   if (BreakAtNode != 0 && (_debug_idx == BreakAtNode || (int)_idx == BreakAtNode)) {
     tty->print_cr("BreakAtNode: _idx=%d _debug_idx=%d", _idx, _debug_idx);
     BREAKPOINT;
@@ -326,7 +326,7 @@
 Node::Node(uint req)
   : _idx(IDX_INIT(req))
 {
-  assert( req < (uint)(MaxNodeLimit - NodeLimitFudgeFactor), "Input limit exceeded" );
+  assert( req < Compile::current()->max_node_limit() - NodeLimitFudgeFactor, "Input limit exceeded" );
   debug_only( verify_construction() );
   NOT_PRODUCT(nodes_created++);
   if (req == 0) {
--- a/src/share/vm/prims/jvmtiEnv.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/prims/jvmtiEnv.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classLoaderExt.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "interpreter/bytecodeStream.hpp"
@@ -475,7 +476,7 @@
     if (TraceClassLoading) {
       tty->print_cr("[Opened %s]", zip_entry->name());
     }
-    ClassLoader::add_to_list(zip_entry);
+    ClassLoaderExt::append_boot_classpath(zip_entry);
     return JVMTI_ERROR_NONE;
   } else {
     return JVMTI_ERROR_WRONG_PHASE;
--- a/src/share/vm/prims/whitebox.cpp	Wed Nov 26 13:58:01 2014 -0800
+++ b/src/share/vm/prims/whitebox.cpp	Tue Dec 02 09:50:33 2014 -0800
@@ -56,6 +56,7 @@
 #endif // INCLUDE_NMT
 
 #include "compiler/compileBroker.hpp"
+#include "jvmtifiles/jvmtiEnv.hpp"
 #include "runtime/compilationPolicy.hpp"
 
 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
@@ -126,6 +127,29 @@
   return result;
 WB_END
 
+WB_ENTRY(void, WB_AddToBootstrapClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) {
+#if INCLUDE_JVMTI
+  ResourceMark rm;
+  const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment));
+  JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION);
+  jvmtiError err = jvmti_env->AddToBootstrapClassLoaderSearch(seg);
+  assert(err == JVMTI_ERROR_NONE, "must not fail");
+#endif
+}
+WB_END
+
+WB_ENTRY(void, WB_AddToSystemClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) {
+#if INCLUDE_JVMTI
+  ResourceMark rm;
+  const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment));
+  JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION);
+  jvmtiError err = jvmti_env->AddToSystemClassLoaderSearch(seg);
+  assert(err == JVMTI_ERROR_NONE, "must not fail");
+#endif
+}
+WB_END
+
+
 WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) {
   return (jlong)Arguments::max_heap_for_compressed_oops();
 }
@@ -958,6 +982,10 @@
       CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
       (void*) &WB_ParseCommandLine
   },
+  {CC"addToBootstrapClassLoaderSearch", CC"(Ljava/lang/String;)V",
+                                                      (void*)&WB_AddToBootstrapClassLoaderSearch},
+  {CC"addToSystemClassLoaderSearch",    CC"(Ljava/lang/String;)V",
+                                                      (void*)&WB_AddToSystemClassLoaderSearch},
   {CC"getCompressedOopsMaxHeapSize", CC"()J",
       (void*)&WB_GetCompressedOopsMaxHeapSize},
   {CC"printHeapSizes",     CC"()V",                   (void*)&WB_PrintHeapSizes    },
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/EliminateAutoBox/UnsignedLoads.java	Tue Dec 02 09:50:33 2014 -0800
@@ -0,0 +1,63 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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
+ * @library /testlibrary
+ * @run main/othervm -Xbatch -XX:+EliminateAutoBox
+ *                   -XX:CompileOnly=::valueOf,::byteValue,::shortValue,::testUnsignedByte,::testUnsignedShort
+ *                   UnsignedLoads
+ */
+import static com.oracle.java.testlibrary.Asserts.assertEQ;
+
+public class UnsignedLoads {
+    public static int testUnsignedByte() {
+        byte[] bytes = new byte[] {-1};
+        int res = 0;
+        for (int i = 0; i < 100000; i++) {
+            for (Byte b : bytes) {
+                res = b & 0xff;
+            }
+        }
+        return res;
+    }
+
+    public static int testUnsignedShort() {
+        int res = 0;
+        short[] shorts = new short[] {-1};
+        for (int i = 0; i < 100000; i++) {
+            for (Short s : shorts) {
+                res = s & 0xffff;
+            }
+        }
+        return res;
+    }
+
+    public static void main(String[] args) {
+        assertEQ(testUnsignedByte(),    255);
+        assertEQ(testUnsignedShort(), 65535);
+        System.out.println("TEST PASSED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java	Tue Dec 02 09:50:33 2014 -0800
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import com.oracle.java.testlibrary.*;
+
+/*
+ * @test
+ * @bug 8050079
+ * @summary Compiles a monomorphic call to finalizeObject() on a modified java.lang.Object to test C1 CHA.
+ * @library /testlibrary
+ * @compile -XDignore.symbol.file java/lang/Object.java TestMonomorphicObjectCall.java
+ * @run main TestMonomorphicObjectCall
+ */
+public class TestMonomorphicObjectCall {
+    final static String testClasses = System.getProperty("test.classes") + File.separator;
+
+    private static void callFinalize(Object object) throws Throwable {
+        // Call modified version of java.lang.Object::finalize() that is
+        // not overridden by any subclass. C1 CHA should mark the call site
+        // as monomorphic and inline the method.
+        object.finalizeObject();
+    }
+
+    public static void main(String[] args) throws Throwable {
+        if (args.length == 0) {
+            // Execute new instance with modified java.lang.Object
+            executeTestJvm();
+        } else {
+            // Trigger compilation of 'callFinalize'
+            callFinalize(new Object());
+        }
+    }
+
+    public static void executeTestJvm() throws Throwable {
+        // Execute test with modified version of java.lang.Object
+        // in -Xbootclasspath.
+        String[] vmOpts = new String[] {
+                "-Xbootclasspath/p:" + testClasses,
+                "-Xcomp",
+                "-XX:-VerifyDependencies",
+                "-XX:CompileOnly=TestMonomorphicObjectCall::callFinalize",
+                "-XX:CompileOnly=Object::finalizeObject",
+                "-XX:TieredStopAtLevel=1",
+                TestMonomorphicObjectCall.class.getName(),
+                "true"};
+        OutputAnalyzer output = ProcessTools.executeTestJvm(vmOpts);
+        output.shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/dependencies/MonomorphicObjectCall/java/lang/Object.java	Tue Dec 02 09:50:33 2014 -0800
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1994, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package java.lang;
+
+/**
+ * Slightly modified version of java.lang.Object that replaces
+ * finalize() by finalizeObject() to avoid overriding in subclasses.
+ */
+public class Object {
+
+    private static native void registerNatives();
+    static {
+        registerNatives();
+    }
+
+    public final native Class<?> getClass();
+
+    public native int hashCode();
+
+    public boolean equals(Object obj) {
+        return (this == obj);
+    }
+
+    protected native Object clone() throws CloneNotSupportedException;
+
+    public String toString() {
+        return getClass().getName() + "@" + Integer.toHexString(hashCode());
+    }
+
+    public final native void notify();
+
+    public final native void notifyAll();
+
+    public final native void wait(long timeout) throws InterruptedException;
+
+    public final void wait(long timeout, int nanos) throws InterruptedException {
+        if (timeout < 0) {
+            throw new IllegalArgumentException("timeout value is negative");
+        }
+
+        if (nanos < 0 || nanos > 999999) {
+            throw new IllegalArgumentException(
+                                "nanosecond timeout value out of range");
+        }
+
+        if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
+            timeout++;
+        }
+
+        wait(timeout);
+    }
+
+    public final void wait() throws InterruptedException {
+        wait(0);
+    }
+
+    /**
+     * Replaces original finalize() method and is therefore not
+     * overridden by any subclasses of Object.
+     * @throws Throwable
+     */
+    // protected void finalize() throws Throwable { }
+    public void finalizeObject() throws Throwable { }
+}
--- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Wed Nov 26 13:58:01 2014 -0800
+++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Tue Dec 02 09:50:33 2014 -0800
@@ -90,6 +90,10 @@
   public native URL[] getLookupCacheURLs(ClassLoader loader);
   public native int[] getLookupCacheMatches(ClassLoader loader, String name);
 
+  // JVMTI
+  public native void addToBootstrapClassLoaderSearch(String segment);
+  public native void addToSystemClassLoaderSearch(String segment);
+
   // G1
   public native boolean g1InConcurrentMark();
   public native boolean g1IsHumongous(Object o);