changeset 5564:d9bbda3eef89

Merge
author asaha
date Wed, 07 Jan 2015 12:20:45 -0800
parents fddbf8bf7698 (current diff) 2b2682c6972e (diff)
children effb7f4183cf
files .hgtags src/share/vm/prims/jvm.cpp src/share/vm/runtime/arguments.cpp src/share/vm/runtime/vmStructs.cpp
diffstat 43 files changed, 979 insertions(+), 217 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Dec 23 13:53:21 2014 -0800
+++ b/.hgtags	Wed Jan 07 12:20:45 2015 -0800
@@ -790,3 +790,5 @@
 05fe7a87d14908eb3f21a0d29fc72cee2f996b7f jdk7u80-b00
 e2533d62ca887078e4b952a75a75680cfb7894b9 jdk7u80-b01
 bad107a5d096b070355c5a2d80aa50bc5576144b jdk7u80-b02
+9d2b485d2a58ea57ab2b3c06b2128f456ab39a38 jdk7u80-b03
+a89267b51c40cba0b26fe84831478389723c8321 jdk7u80-b04
--- a/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -26,8 +26,8 @@
 #include "runtime/os.hpp"
 #include "vm_version_sparc.hpp"
 
-static bool detect_niagara() {
-  char cpu[128];
+static bool cpuinfo_field_contains(const char* field, const char* value) {
+  char line[1024];
   bool rv = false;
 
   FILE* fp = fopen("/proc/cpuinfo", "r");
@@ -35,9 +35,10 @@
     return rv;
   }
 
-  while (!feof(fp)) {
-    if (fscanf(fp, "cpu\t\t: %100[^\n]", &cpu) == 1) {
-      if (strstr(cpu, "Niagara") != NULL) {
+  while (fgets(line, sizeof(line), fp) != NULL) {
+    assert(strlen(line) < sizeof(line) - 1, "buffer line[1024] is too small.");
+    if (strncmp(line, field, strlen(field)) == 0) {
+      if (strstr(line, value) != NULL) {
         rv = true;
       }
       break;
@@ -45,8 +46,15 @@
   }
 
   fclose(fp);
+  return rv;
+}
 
-  return rv;
+static bool detect_niagara() {
+  return cpuinfo_field_contains("cpu", "Niagara");
+}
+
+static bool detect_blkinit() {
+  return cpuinfo_field_contains("cpucaps", "blkinit");
 }
 
 int VM_Version::platform_features(int features) {
@@ -58,5 +66,9 @@
     features = niagara1_m | T_family_m;
   }
 
+  if (detect_blkinit()) {
+    features |= blk_init_instructions_m;
+  }
+
   return features;
 }
--- a/src/share/vm/c1/c1_globals.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/c1/c1_globals.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -269,9 +269,6 @@
   develop(bool, InstallMethods, true,                                       \
           "Install methods at the end of successful compilations")          \
                                                                             \
-  product(intx, CompilationRepeat, 0,                                       \
-          "Number of times to recompile method before returning result")    \
-                                                                            \
   develop(intx, NMethodSizeLimit, (64*K)*wordSize,                          \
           "Maximum size of a compiled method.")                             \
                                                                             \
--- a/src/share/vm/classfile/classLoader.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/classfile/classLoader.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -197,7 +197,7 @@
 }
 
 
-ClassFileStream* ClassPathDirEntry::open_stream(const char* name) {
+ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) {
   // construct full path name
   char path[JVM_MAXPATHLEN];
   if (jio_snprintf(path, sizeof(path), "%s%s%s", _dir, os::file_separator(), name) == -1) {
@@ -240,7 +240,7 @@
   FREE_C_HEAP_ARRAY(char, _zip_name, mtClass);
 }
 
-ClassFileStream* ClassPathZipEntry::open_stream(const char* name) {
+ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) {
   // enable call to C land
   JavaThread* thread = JavaThread::current();
   ThreadToNativeFromVM ttn(thread);
@@ -284,24 +284,24 @@
   }
 }
 
-LazyClassPathEntry::LazyClassPathEntry(char* path, struct stat st) : ClassPathEntry() {
+LazyClassPathEntry::LazyClassPathEntry(char* path, const struct stat* st) : ClassPathEntry() {
   _path = strdup(path);
-  _st = st;
+  _st = *st;
   _meta_index = NULL;
   _resolved_entry = NULL;
+  _has_error = false;
 }
 
 bool LazyClassPathEntry::is_jar_file() {
   return ((_st.st_mode & S_IFREG) == S_IFREG);
 }
 
-ClassPathEntry* LazyClassPathEntry::resolve_entry() {
+ClassPathEntry* LazyClassPathEntry::resolve_entry(TRAPS) {
   if (_resolved_entry != NULL) {
     return (ClassPathEntry*) _resolved_entry;
   }
   ClassPathEntry* new_entry = NULL;
-  ClassLoader::create_class_path_entry(_path, _st, &new_entry, false);
-  assert(new_entry != NULL, "earlier code should have caught this");
+  new_entry = ClassLoader::create_class_path_entry(_path, &_st, false, CHECK_NULL);
   {
     ThreadCritical tc;
     if (_resolved_entry == NULL) {
@@ -314,12 +314,21 @@
   return (ClassPathEntry*) _resolved_entry;
 }
 
-ClassFileStream* LazyClassPathEntry::open_stream(const char* name) {
+ClassFileStream* LazyClassPathEntry::open_stream(const char* name, TRAPS) {
   if (_meta_index != NULL &&
       !_meta_index->may_contain(name)) {
     return NULL;
   }
-  return resolve_entry()->open_stream(name);
+  if (_has_error) {
+    return NULL;
+  }
+  ClassPathEntry* cpe = resolve_entry(THREAD);
+  if (cpe == NULL) {
+    _has_error = true;
+    return NULL;
+  } else {
+    return cpe->open_stream(name, THREAD);
+  }
 }
 
 bool LazyClassPathEntry::is_lazy() {
@@ -465,20 +474,19 @@
   }
 }
 
-void ClassLoader::create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy) {
+ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct stat* st, bool lazy, TRAPS) {
   JavaThread* thread = JavaThread::current();
   if (lazy) {
-    *new_entry = new LazyClassPathEntry(path, st);
-    return;
+    return new LazyClassPathEntry(path, st);
   }
-  if ((st.st_mode & S_IFREG) == S_IFREG) {
+  ClassPathEntry* new_entry = NULL;
+  if ((st->st_mode & S_IFREG) == S_IFREG) {
     // Regular file, should be a zip file
     // Canonicalized filename
     char canonical_path[JVM_MAXPATHLEN];
     if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
       // This matches the classic VM
-      EXCEPTION_MARK;
-      THROW_MSG(vmSymbols::java_io_IOException(), "Bad pathname");
+      THROW_MSG_(vmSymbols::java_io_IOException(), "Bad pathname", NULL);
     }
     char* error_msg = NULL;
     jzfile* zip;
@@ -489,7 +497,7 @@
       zip = (*ZipOpen)(canonical_path, &error_msg);
     }
     if (zip != NULL && error_msg == NULL) {
-      *new_entry = new ClassPathZipEntry(zip, path);
+      new_entry = new ClassPathZipEntry(zip, path);
       if (TraceClassLoading) {
         tty->print_cr("[Opened %s]", path);
       }
@@ -504,16 +512,16 @@
         msg = NEW_RESOURCE_ARRAY(char, len); ;
         jio_snprintf(msg, len - 1, "error in opening JAR file <%s> %s", error_msg, path);
       }
-      EXCEPTION_MARK;
-      THROW_MSG(vmSymbols::java_lang_ClassNotFoundException(), msg);
+      THROW_MSG_(vmSymbols::java_lang_ClassNotFoundException(), msg, NULL);
     }
   } else {
     // Directory
-    *new_entry = new ClassPathDirEntry(path);
+    new_entry = new ClassPathDirEntry(path);
     if (TraceClassLoading) {
       tty->print_cr("[Path %s]", path);
     }
   }
+  return new_entry;
 }
 
 
@@ -572,13 +580,14 @@
   }
 }
 
-void ClassLoader::update_class_path_entry_list(const char *path,
+void ClassLoader::update_class_path_entry_list(char *path,
                                                bool check_for_duplicates) {
   struct stat st;
-  if (os::stat((char *)path, &st) == 0) {
+  if (os::stat(path, &st) == 0) {
     // File or directory found
     ClassPathEntry* new_entry = NULL;
-    create_class_path_entry((char *)path, st, &new_entry, LazyBootClassLoader);
+    Thread* THREAD = Thread::current();
+    new_entry = create_class_path_entry(path, &st, LazyBootClassLoader, CHECK);
     // The kernel VM adds dynamically to the end of the classloader path and
     // doesn't reorder the bootclasspath which would break java.lang.Package
     // (see PackageInfo).
@@ -895,7 +904,7 @@
                                PerfClassTraceTime::CLASS_LOAD);
     ClassPathEntry* e = _first_entry;
     while (e != NULL) {
-      stream = e->open_stream(name);
+      stream = e->open_stream(name, CHECK_(instanceKlassHandle()));
       if (stream != NULL) {
         break;
       }
@@ -1258,11 +1267,16 @@
 }
 
 void LazyClassPathEntry::compile_the_world(Handle loader, TRAPS) {
-  resolve_entry()->compile_the_world(loader, CHECK);
+  ClassPathEntry* cpe = resolve_entry(THREAD);
+  if (cpe != NULL) {
+    cpe->compile_the_world(loader, CHECK);
+  }
 }
 
 bool LazyClassPathEntry::is_rt_jar() {
-  return resolve_entry()->is_rt_jar();
+  Thread* THREAD = Thread::current();
+  ClassPathEntry* cpe = resolve_entry(THREAD);
+  return (cpe != NULL) ? cpe->is_jar_file() : false;
 }
 
 void ClassLoader::compile_the_world() {
--- a/src/share/vm/classfile/classLoader.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/classfile/classLoader.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -63,7 +63,7 @@
   ClassPathEntry();
   // Attempt to locate file_name through this class path entry.
   // Returns a class file parsing stream if successfull.
-  virtual ClassFileStream* open_stream(const char* name) = 0;
+  virtual ClassFileStream* open_stream(const char* name, TRAPS) = 0;
   // Debugging
   NOT_PRODUCT(virtual void compile_the_world(Handle loader, TRAPS) = 0;)
   NOT_PRODUCT(virtual bool is_rt_jar() = 0;)
@@ -77,7 +77,7 @@
   bool is_jar_file()  { return false;  }
   const char* name()  { return _dir; }
   ClassPathDirEntry(char* dir);
-  ClassFileStream* open_stream(const char* name);
+  ClassFileStream* open_stream(const char* name, TRAPS);
   // Debugging
   NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
   NOT_PRODUCT(bool is_rt_jar();)
@@ -107,7 +107,7 @@
   const char* name()  { return _zip_name; }
   ClassPathZipEntry(jzfile* zip, const char* zip_name);
   ~ClassPathZipEntry();
-  ClassFileStream* open_stream(const char* name);
+  ClassFileStream* open_stream(const char* name, TRAPS);
   void contents_do(void f(const char* name, void* context), void* context);
   // Debugging
   NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
@@ -125,13 +125,14 @@
   char* _path; // dir or file
   struct stat _st;
   MetaIndex* _meta_index;
+  bool _has_error;
   volatile ClassPathEntry* _resolved_entry;
-  ClassPathEntry* resolve_entry();
+  ClassPathEntry* resolve_entry(TRAPS);
  public:
   bool is_jar_file();
   const char* name()  { return _path; }
-  LazyClassPathEntry(char* path, struct stat st);
-  ClassFileStream* open_stream(const char* name);
+  LazyClassPathEntry(char* path, const struct stat* st);
+  ClassFileStream* open_stream(const char* name, TRAPS);
   void set_meta_index(MetaIndex* meta_index) { _meta_index = meta_index; }
   virtual bool is_lazy();
   // Debugging
@@ -207,14 +208,15 @@
   static void setup_meta_index();
   static void setup_bootstrap_search_path();
   static void load_zip_library();
-  static void create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy);
+  static ClassPathEntry* create_class_path_entry(char *path, const struct stat* st,
+                                                 bool lazy, TRAPS);
 
   // Canonicalizes path names, so strcmp will work properly. This is mainly
   // to avoid confusing the zip library
   static bool get_canonical_path(char* orig, char* out, int len);
  public:
   // Used by the kernel jvm.
-  static void update_class_path_entry_list(const char *path,
+  static void update_class_path_entry_list(char *path,
                                            bool check_for_duplicates);
   static void print_bootclasspath();
 
--- a/src/share/vm/classfile/javaClasses.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/classfile/javaClasses.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -575,6 +575,7 @@
       instanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
     }
     // set the classLoader field in the java_lang_Class instance
+    assert(class_loader() == k->class_loader(), "should be same");
     set_class_loader(mirror(), class_loader());
     return mirror();
   } else {
--- a/src/share/vm/compiler/compileBroker.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/compiler/compileBroker.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -1594,22 +1594,6 @@
       if (method()->number_of_breakpoints() == 0) {
         // Compile the method.
         if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) {
-#ifdef COMPILER1
-          // Allow repeating compilations for the purpose of benchmarking
-          // compile speed. This is not useful for customers.
-          if (CompilationRepeat != 0) {
-            int compile_count = CompilationRepeat;
-            while (compile_count > 0) {
-              invoke_compiler_on_method(task);
-              nmethod* nm = method->code();
-              if (nm != NULL) {
-                nm->make_zombie();
-                method->clear_code();
-              }
-              compile_count--;
-            }
-          }
-#endif /* COMPILER1 */
           invoke_compiler_on_method(task);
         } else {
           // After compilation is disabled, remove remaining methods from queue
--- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -492,7 +492,7 @@
         // heap remains parsable.
         const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
         const bool softrefs_clear = collector_policy()->all_soft_refs_clear();
-        assert(!limit_exceeded || softrefs_clear, "Should have been cleared");
+
         if (limit_exceeded && softrefs_clear) {
           *gc_overhead_limit_was_exceeded = true;
           size_policy()->set_gc_overhead_limit_exceeded(false);
--- a/src/share/vm/memory/collectorPolicy.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/memory/collectorPolicy.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -642,7 +642,7 @@
 
       const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
       const bool softrefs_clear = all_soft_refs_clear();
-      assert(!limit_exceeded || softrefs_clear, "Should have been cleared");
+
       if (limit_exceeded && softrefs_clear) {
         *gc_overhead_limit_was_exceeded = true;
         size_policy()->set_gc_overhead_limit_exceeded(false);
--- a/src/share/vm/oops/arrayKlass.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/oops/arrayKlass.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -124,7 +124,7 @@
   ResourceMark rm(THREAD);
   k->initialize_supers(super_klass(), CHECK);
   k->vtable()->initialize_vtable(false, CHECK);
-  java_lang_Class::create_mirror(k, CHECK);
+  java_lang_Class::create_mirror(k, Handle(THREAD, k->class_loader()), CHECK);
 }
 
 objArrayOop arrayKlass::compute_secondary_supers(int num_extra_slots, TRAPS) {
--- a/src/share/vm/oops/methodDataOop.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/oops/methodDataOop.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -1203,7 +1203,7 @@
   // Whole-method sticky bits and flags
 public:
   enum {
-    _trap_hist_limit    = 17,   // decoupled from Deoptimization::Reason_LIMIT
+    _trap_hist_limit    = 18,   // decoupled from Deoptimization::Reason_LIMIT
     _trap_hist_mask     = max_jubyte,
     _extra_data_count   = 4     // extra DataLayout headers, for trap history
   }; // Public flag values
--- a/src/share/vm/oops/objArrayKlass.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/oops/objArrayKlass.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -202,6 +202,15 @@
   }
 }
 
+// Protect against _bottom_klass being null, when called from Universe::fixup_mirrors
+oop objArrayKlass::class_loader() const {
+  if (bottom_klass() != NULL) {
+    return Klass::cast(bottom_klass())->class_loader();
+  } else {
+    return NULL;
+  }
+}
+
 
 klassOop objArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
   objArrayKlassHandle h_this(THREAD, as_klassOop());
--- a/src/share/vm/oops/objArrayKlass.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/oops/objArrayKlass.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -68,7 +68,7 @@
   // Compute protection domain
   oop protection_domain() { return Klass::cast(bottom_klass())->protection_domain(); }
   // Compute class loader
-  oop class_loader() const { return Klass::cast(bottom_klass())->class_loader(); }
+  oop class_loader() const;
 
  private:
   // Either oop or narrowOop depending on UseCompressedOops.
--- a/src/share/vm/opto/c2_globals.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/c2_globals.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -448,6 +448,9 @@
   product(bool, DoEscapeAnalysis, true,                                     \
           "Perform escape analysis")                                        \
                                                                             \
+  product(double, EscapeAnalysisTimeout, 20. DEBUG_ONLY(+40.),              \
+          "Abort EA when it reaches time limit (in sec)")                   \
+                                                                            \
   develop(bool, ExitEscapeAnalysisOnTimeout, true,                          \
           "Exit or throw assert in EA when it reaches time limit")          \
                                                                             \
--- a/src/share/vm/opto/connode.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/connode.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -439,6 +439,102 @@
   return this;
 }
 
+uint CastIINode::size_of() const {
+  return sizeof(*this);
+}
+
+uint CastIINode::cmp(const Node &n) const {
+  return TypeNode::cmp(n) && ((CastIINode&)n)._carry_dependency == _carry_dependency;
+}
+
+Node *CastIINode::Identity(PhaseTransform *phase) {
+  if (_carry_dependency) {
+    return this;
+  }
+  return ConstraintCastNode::Identity(phase);
+}
+
+const Type *CastIINode::Value(PhaseTransform *phase) const {
+  const Type *res = ConstraintCastNode::Value(phase);
+
+  // Try to improve the type of the CastII if we recognize a CmpI/If
+  // pattern.
+  if (_carry_dependency) {
+    if (in(0) != NULL && in(0)->in(0) != NULL && in(0)->in(0)->is_If()) {
+      assert(in(0)->is_IfFalse() || in(0)->is_IfTrue(), "should be If proj");
+      Node* proj = in(0);
+      if (proj->in(0)->in(1)->is_Bool()) {
+        Node* b = proj->in(0)->in(1);
+        if (b->in(1)->Opcode() == Op_CmpI) {
+          Node* cmp = b->in(1);
+          if (cmp->in(1) == in(1) && phase->type(cmp->in(2))->isa_int()) {
+            const TypeInt* in2_t = phase->type(cmp->in(2))->is_int();
+            const Type* t = TypeInt::INT;
+            BoolTest test = b->as_Bool()->_test;
+            if (proj->is_IfFalse()) {
+              test = test.negate();
+            }
+            BoolTest::mask m = test._test;
+            jlong lo_long = min_jint;
+            jlong hi_long = max_jint;
+            if (m == BoolTest::le || m == BoolTest::lt) {
+              hi_long = in2_t->_hi;
+              if (m == BoolTest::lt) {
+                hi_long -= 1;
+              }
+            } else if (m == BoolTest::ge || m == BoolTest::gt) {
+              lo_long = in2_t->_lo;
+              if (m == BoolTest::gt) {
+                lo_long += 1;
+              }
+            } else if (m == BoolTest::eq) {
+              lo_long = in2_t->_lo;
+              hi_long = in2_t->_hi;
+            } else if (m == BoolTest::ne) {
+              // can't do any better
+            } else {
+              stringStream ss;
+              test.dump_on(&ss);
+              fatal(err_msg_res("unexpected comparison %s", ss.as_string()));
+            }
+            int lo_int = (int)lo_long;
+            int hi_int = (int)hi_long;
+
+            if (lo_long != (jlong)lo_int) {
+              lo_int = min_jint;
+            }
+            if (hi_long != (jlong)hi_int) {
+              hi_int = max_jint;
+            }
+
+            t = TypeInt::make(lo_int, hi_int, Type::WidenMax);
+
+            res = res->filter(t);
+
+            return res;
+          }
+        }
+      }
+    }
+  }
+  return res;
+}
+
+Node *CastIINode::Ideal_DU_postCCP(PhaseCCP *ccp) {
+  if (_carry_dependency) {
+    return NULL;
+  }
+  return ConstraintCastNode::Ideal_DU_postCCP(ccp);
+}
+
+#ifndef PRODUCT
+void CastIINode::dump_spec(outputStream *st) const {
+  TypeNode::dump_spec(st);
+  if (_carry_dependency) {
+    st->print(" carry dependency");
+  }
+}
+#endif
 
 //=============================================================================
 
--- a/src/share/vm/opto/connode.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/connode.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -233,10 +233,25 @@
 //------------------------------CastIINode-------------------------------------
 // cast integer to integer (different range)
 class CastIINode: public ConstraintCastNode {
+  private:
+  // Can this node be removed post CCP or does it carry a required dependency?
+  const bool _carry_dependency;
+
+  protected:
+  virtual uint cmp( const Node &n ) const;
+  virtual uint size_of() const;
+
 public:
-  CastIINode (Node *n, const Type *t ): ConstraintCastNode(n,t) {}
+  CastIINode(Node *n, const Type *t, bool carry_dependency = false)
+    : ConstraintCastNode(n,t), _carry_dependency(carry_dependency) {}
   virtual int Opcode() const;
   virtual uint ideal_reg() const { return Op_RegI; }
+  virtual Node *Identity( PhaseTransform *phase );
+  virtual const Type *Value( PhaseTransform *phase ) const;
+  virtual Node *Ideal_DU_postCCP( PhaseCCP * );
+#ifndef PRODUCT
+  virtual void dump_spec(outputStream *st) const;
+#endif
 };
 
 //------------------------------CastPPNode-------------------------------------
--- a/src/share/vm/opto/doCall.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/doCall.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -735,10 +735,16 @@
     // each arm of the Phi.  If I know something clever about the exceptions
     // I'm loading the class from, I can replace the LoadKlass with the
     // klass constant for the exception oop.
-    if( ex_node->is_Phi() ) {
-      ex_klass_node = new (C) PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT );
-      for( uint i = 1; i < ex_node->req(); i++ ) {
-        Node* p = basic_plus_adr( ex_node->in(i), ex_node->in(i), oopDesc::klass_offset_in_bytes() );
+    if (ex_node->is_Phi()) {
+      ex_klass_node = new (C) PhiNode(ex_node->in(0), TypeKlassPtr::OBJECT);
+      for (uint i = 1; i < ex_node->req(); i++) {
+        Node* ex_in = ex_node->in(i);
+        if (ex_in == top() || ex_in == NULL) {
+          // This path was not taken.
+          ex_klass_node->init_req(i, top());
+          continue;
+        }
+        Node* p = basic_plus_adr(ex_in, ex_in, oopDesc::klass_offset_in_bytes());
         Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) );
         ex_klass_node->init_req( i, k );
       }
--- a/src/share/vm/opto/escape.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/escape.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -37,6 +37,8 @@
 
 ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) :
   _nodes(C->comp_arena(), C->unique(), C->unique(), NULL),
+  _in_worklist(C->comp_arena()),
+  _next_pidx(0),
   _collecting(true),
   _verify(false),
   _compile(C),
@@ -120,13 +122,19 @@
   if (C->root() != NULL) {
     ideal_nodes.push(C->root());
   }
+  // Processed ideal nodes are unique on ideal_nodes list
+  // but several ideal nodes are mapped to the phantom_obj.
+  // To avoid duplicated entries on the following worklists
+  // add the phantom_obj only once to them.
+  ptnodes_worklist.append(phantom_obj);
+  java_objects_worklist.append(phantom_obj);
   for( uint next = 0; next < ideal_nodes.size(); ++next ) {
     Node* n = ideal_nodes.at(next);
     // Create PointsTo nodes and add them to Connection Graph. Called
     // only once per ideal node since ideal_nodes is Unique_Node list.
     add_node_to_connection_graph(n, &delayed_worklist);
     PointsToNode* ptn = ptnode_adr(n->_idx);
-    if (ptn != NULL) {
+    if (ptn != NULL && ptn != phantom_obj) {
       ptnodes_worklist.append(ptn);
       if (ptn->is_JavaObject()) {
         java_objects_worklist.append(ptn->as_JavaObject());
@@ -395,7 +403,7 @@
     }
     case Op_CreateEx: {
       // assume that all exception objects globally escape
-      add_java_object(n, PointsToNode::GlobalEscape);
+      map_ideal_node(n, phantom_obj);
       break;
     }
     case Op_LoadKlass:
@@ -1016,13 +1024,8 @@
   // on graph complexity. Observed 8 passes in jvm2008 compiler.compiler.
   // Set limit to 20 to catch situation when something did go wrong and
   // bailout Escape Analysis.
-  // Also limit build time to 30 sec (60 in debug VM).
+  // Also limit build time to 20 sec (60 in debug VM), EscapeAnalysisTimeout flag.
 #define CG_BUILD_ITER_LIMIT 20
-#ifdef ASSERT
-#define CG_BUILD_TIME_LIMIT 60.0
-#else
-#define CG_BUILD_TIME_LIMIT 30.0
-#endif
 
   // Propagate GlobalEscape and ArgEscape escape states and check that
   // we still have non-escaping objects. The method pushs on _worklist
@@ -1033,12 +1036,13 @@
   // Now propagate references to all JavaObject nodes.
   int java_objects_length = java_objects_worklist.length();
   elapsedTimer time;
+  bool timeout = false;
   int new_edges = 1;
   int iterations = 0;
   do {
     while ((new_edges > 0) &&
-          (iterations++   < CG_BUILD_ITER_LIMIT) &&
-          (time.seconds() < CG_BUILD_TIME_LIMIT)) {
+           (iterations++ < CG_BUILD_ITER_LIMIT)) {
+      double start_time = time.seconds();
       time.start();
       new_edges = 0;
       // Propagate references to phantom_object for nodes pushed on _worklist
@@ -1047,7 +1051,26 @@
       for (int next = 0; next < java_objects_length; ++next) {
         JavaObjectNode* ptn = java_objects_worklist.at(next);
         new_edges += add_java_object_edges(ptn, true);
+
+#define SAMPLE_SIZE 4
+        if ((next % SAMPLE_SIZE) == 0) {
+          // Each 4 iterations calculate how much time it will take
+          // to complete graph construction.
+          time.stop();
+          double stop_time = time.seconds();
+          double time_per_iter = (stop_time - start_time) / (double)SAMPLE_SIZE;
+          double time_until_end = time_per_iter * (double)(java_objects_length - next);
+          if ((start_time + time_until_end) >= EscapeAnalysisTimeout) {
+            timeout = true;
+            break; // Timeout
+          }
+          start_time = stop_time;
+          time.start();
+        }
+#undef SAMPLE_SIZE
+
       }
+      if (timeout) break;
       if (new_edges > 0) {
         // Update escape states on each iteration if graph was updated.
         if (!find_non_escaped_objects(ptnodes_worklist, non_escaped_worklist)) {
@@ -1055,9 +1078,12 @@
         }
       }
       time.stop();
+      if (time.seconds() >= EscapeAnalysisTimeout) {
+        timeout = true;
+        break;
+      }
     }
-    if ((iterations     < CG_BUILD_ITER_LIMIT) &&
-        (time.seconds() < CG_BUILD_TIME_LIMIT)) {
+    if ((iterations < CG_BUILD_ITER_LIMIT) && !timeout) {
       time.start();
       // Find fields which have unknown value.
       int fields_length = oop_fields_worklist.length();
@@ -1070,18 +1096,21 @@
         }
       }
       time.stop();
+      if (time.seconds() >= EscapeAnalysisTimeout) {
+        timeout = true;
+        break;
+      }
     } else {
       new_edges = 0; // Bailout
     }
   } while (new_edges > 0);
 
   // Bailout if passed limits.
-  if ((iterations     >= CG_BUILD_ITER_LIMIT) ||
-      (time.seconds() >= CG_BUILD_TIME_LIMIT)) {
+  if ((iterations >= CG_BUILD_ITER_LIMIT) || timeout) {
     Compile* C = _compile;
     if (C->log() != NULL) {
       C->log()->begin_elem("connectionGraph_bailout reason='reached ");
-      C->log()->text("%s", (iterations >= CG_BUILD_ITER_LIMIT) ? "iterations" : "time");
+      C->log()->text("%s", timeout ? "time" : "iterations");
       C->log()->end_elem(" limit'");
     }
     assert(ExitEscapeAnalysisOnTimeout, err_msg_res("infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
@@ -1098,7 +1127,6 @@
 #endif
 
 #undef CG_BUILD_ITER_LIMIT
-#undef CG_BUILD_TIME_LIMIT
 
   // Find fields initialized by NULL for non-escaping Allocations.
   int non_escaped_length = non_escaped_worklist.length();
@@ -1222,8 +1250,8 @@
       }
     }
   }
-  while(_worklist.length() > 0) {
-    PointsToNode* use = _worklist.pop();
+  for (int l = 0; l < _worklist.length(); l++) {
+    PointsToNode* use = _worklist.at(l);
     if (PointsToNode::is_base_use(use)) {
       // Add reference from jobj to field and from field to jobj (field's base).
       use = PointsToNode::get_use_node(use)->as_Field();
@@ -1270,6 +1298,8 @@
       add_field_uses_to_worklist(use->as_Field());
     }
   }
+  _worklist.clear();
+  _in_worklist.Reset();
   return new_edges;
 }
 
@@ -1838,7 +1868,7 @@
     return;
   }
   Compile* C = _compile;
-  ptadr = new (C->comp_arena()) LocalVarNode(C, n, es);
+  ptadr = new (C->comp_arena()) LocalVarNode(this, n, es);
   _nodes.at_put(n->_idx, ptadr);
 }
 
@@ -1849,7 +1879,7 @@
     return;
   }
   Compile* C = _compile;
-  ptadr = new (C->comp_arena()) JavaObjectNode(C, n, es);
+  ptadr = new (C->comp_arena()) JavaObjectNode(this, n, es);
   _nodes.at_put(n->_idx, ptadr);
 }
 
@@ -1865,7 +1895,7 @@
     es = PointsToNode::GlobalEscape;
   }
   Compile* C = _compile;
-  FieldNode* field = new (C->comp_arena()) FieldNode(C, n, es, offset, is_oop);
+  FieldNode* field = new (C->comp_arena()) FieldNode(this, n, es, offset, is_oop);
   _nodes.at_put(n->_idx, field);
 }
 
@@ -1879,7 +1909,7 @@
     return;
   }
   Compile* C = _compile;
-  ptadr = new (C->comp_arena()) ArraycopyNode(C, n, es);
+  ptadr = new (C->comp_arena()) ArraycopyNode(this, n, es);
   _nodes.at_put(n->_idx, ptadr);
   // Add edge from arraycopy node to source object.
   (void)add_edge(ptadr, src);
--- a/src/share/vm/opto/escape.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/escape.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -125,6 +125,8 @@
 class FieldNode;
 class ArraycopyNode;
 
+class ConnectionGraph;
+
 // ConnectionGraph nodes
 class PointsToNode : public ResourceObj {
   GrowableArray<PointsToNode*> _edges; // List of nodes this node points to
@@ -137,6 +139,7 @@
 
   Node* const        _node;  // Ideal node corresponding to this PointsTo node.
   const int           _idx;  // Cached ideal node's _idx
+  const uint         _pidx;  // Index of this node
 
 public:
   typedef enum {
@@ -165,17 +168,9 @@
   } NodeFlags;
 
 
-  PointsToNode(Compile *C, Node* n, EscapeState es, NodeType type):
-    _edges(C->comp_arena(), 2, 0, NULL),
-    _uses (C->comp_arena(), 2, 0, NULL),
-    _node(n),
-    _idx(n->_idx),
-    _type((u1)type),
-    _escape((u1)es),
-    _fields_escape((u1)es),
-    _flags(ScalarReplaceable) {
-    assert(n != NULL && es != UnknownEscape, "sanity");
-  }
+  inline PointsToNode(ConnectionGraph* CG, Node* n, EscapeState es, NodeType type);
+
+  uint        pidx()   const { return _pidx; }
 
   Node* ideal_node()   const { return _node; }
   int          idx()   const { return _idx; }
@@ -243,14 +238,14 @@
 
 class LocalVarNode: public PointsToNode {
 public:
-  LocalVarNode(Compile *C, Node* n, EscapeState es):
-    PointsToNode(C, n, es, LocalVar) {}
+  LocalVarNode(ConnectionGraph *CG, Node* n, EscapeState es):
+    PointsToNode(CG, n, es, LocalVar) {}
 };
 
 class JavaObjectNode: public PointsToNode {
 public:
-  JavaObjectNode(Compile *C, Node* n, EscapeState es):
-    PointsToNode(C, n, es, JavaObject) {
+  JavaObjectNode(ConnectionGraph *CG, Node* n, EscapeState es):
+    PointsToNode(CG, n, es, JavaObject) {
       if (es > NoEscape)
         set_scalar_replaceable(false);
     }
@@ -262,8 +257,8 @@
   const bool  _is_oop; // Field points to object
         bool  _has_unknown_base; // Has phantom_object base
 public:
-  FieldNode(Compile *C, Node* n, EscapeState es, int offs, bool is_oop):
-    PointsToNode(C, n, es, Field),
+  FieldNode(ConnectionGraph *CG, Node* n, EscapeState es, int offs, bool is_oop):
+    PointsToNode(CG, n, es, Field),
     _offset(offs), _is_oop(is_oop),
     _has_unknown_base(false) {}
 
@@ -284,8 +279,8 @@
 
 class ArraycopyNode: public PointsToNode {
 public:
-  ArraycopyNode(Compile *C, Node* n, EscapeState es):
-    PointsToNode(C, n, es, Arraycopy) {}
+  ArraycopyNode(ConnectionGraph *CG, Node* n, EscapeState es):
+    PointsToNode(CG, n, es, Arraycopy) {}
 };
 
 // Iterators for PointsTo node's edges:
@@ -323,11 +318,14 @@
 
 
 class ConnectionGraph: public ResourceObj {
+  friend class PointsToNode;
 private:
   GrowableArray<PointsToNode*>  _nodes; // Map from ideal nodes to
                                         // ConnectionGraph nodes.
 
   GrowableArray<PointsToNode*>  _worklist; // Nodes to be processed
+  VectorSet                  _in_worklist;
+  uint                         _next_pidx;
 
   bool            _collecting; // Indicates whether escape information
                                // is still being collected. If false,
@@ -353,6 +351,8 @@
   }
   uint nodes_size() const { return _nodes.length(); }
 
+  uint next_pidx() { return _next_pidx++; }
+
   // Add nodes to ConnectionGraph.
   void add_local_var(Node* n, PointsToNode::EscapeState es);
   void add_java_object(Node* n, PointsToNode::EscapeState es);
@@ -396,15 +396,26 @@
   int add_java_object_edges(JavaObjectNode* jobj, bool populate_worklist);
 
   // Put node on worklist if it is (or was) not there.
-  void add_to_worklist(PointsToNode* pt) {
-    _worklist.push(pt);
-    return;
+  inline void add_to_worklist(PointsToNode* pt) {
+    PointsToNode* ptf = pt;
+    uint pidx_bias = 0;
+    if (PointsToNode::is_base_use(pt)) {
+      // Create a separate entry in _in_worklist for a marked base edge
+      // because _worklist may have an entry for a normal edge pointing
+      // to the same node. To separate them use _next_pidx as bias.
+      ptf = PointsToNode::get_use_node(pt)->as_Field();
+      pidx_bias = _next_pidx;
+    }
+    if (!_in_worklist.test_set(ptf->pidx() + pidx_bias)) {
+      _worklist.append(pt);
+    }
   }
 
   // Put on worklist all uses of this node.
-  void add_uses_to_worklist(PointsToNode* pt) {
-    for (UseIterator i(pt); i.has_next(); i.next())
-      _worklist.push(i.get());
+  inline void add_uses_to_worklist(PointsToNode* pt) {
+    for (UseIterator i(pt); i.has_next(); i.next()) {
+      add_to_worklist(i.get());
+    }
   }
 
   // Put on worklist all field's uses and related field nodes.
@@ -517,8 +528,8 @@
  }
   // Helper functions
   bool   is_oop_field(Node* n, int offset, bool* unsafe);
- static Node* get_addp_base(Node *addp);
- static Node* find_second_addp(Node* addp, Node* n);
+  static Node* get_addp_base(Node *addp);
+  static Node* find_second_addp(Node* addp, Node* n);
   // offset of a field reference
   int address_offset(Node* adr, PhaseTransform *phase);
 
@@ -587,4 +598,17 @@
 #endif
 };
 
+inline PointsToNode::PointsToNode(ConnectionGraph *CG, Node* n, EscapeState es, NodeType type):
+  _edges(CG->_compile->comp_arena(), 2, 0, NULL),
+  _uses (CG->_compile->comp_arena(), 2, 0, NULL),
+  _node(n),
+  _idx(n->_idx),
+  _pidx(CG->next_pidx()),
+  _type((u1)type),
+  _escape((u1)es),
+  _fields_escape((u1)es),
+  _flags(ScalarReplaceable) {
+  assert(n != NULL && es != UnknownEscape, "sanity");
+}
+
 #endif // SHARE_VM_OPTO_ESCAPE_HPP
--- a/src/share/vm/opto/ifg.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/ifg.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -571,15 +571,35 @@
           if( !n->is_Proj() ||
               // Could also be a flags-projection of a dead ADD or such.
               (n2lidx(def) && !liveout.member(n2lidx(def)) ) ) {
-            b->_nodes.remove(j - 1);
-            if( lrgs(r)._def == n ) lrgs(r)._def = 0;
-            n->disconnect_inputs(NULL, C);
-            _cfg._bbs.map(n->_idx,NULL);
-            n->replace_by(C->top());
-            // Since yanking a Node from block, high pressure moves up one
-            hrp_index[0]--;
-            hrp_index[1]--;
-            continue;
+            bool remove = true;
+            if (n->is_MachProj()) {
+              // Don't remove KILL projections if their "defining" nodes have
+              // memory effects (have SCMemProj projection node) -
+              // they are not dead even when their result is not used.
+              // For example, compareAndSwapL (and other CAS) and EncodeISOArray nodes.
+              // The method add_input_to_liveout() keeps such nodes alive (put them on liveout list)
+              // when it sees SCMemProj node in a block. Unfortunately SCMemProj node could be placed
+              // in block in such order that KILL MachProj nodes are processed first.
+              uint cnt = def->outcnt();
+              for (uint i = 0; i < cnt; i++) {
+                Node* proj = def->raw_out(i);
+                if (proj->Opcode() == Op_SCMemProj) {
+                  remove = false;
+                  break;
+                }
+              }
+            }
+            if (remove) {
+              b->_nodes.remove(j - 1);
+              if( lrgs(r)._def == n ) lrgs(r)._def = 0;
+              n->disconnect_inputs(NULL, C);
+              _cfg._bbs.map(n->_idx,NULL);
+              n->replace_by(C->top());
+              // Since yanking a Node from block, high pressure moves up one
+              hrp_index[0]--;
+              hrp_index[1]--;
+              continue;
+            }
           }
 
           // Fat-projections kill many registers which cannot be used to
--- a/src/share/vm/opto/loopTransform.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/loopTransform.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -863,6 +863,20 @@
   return n;
 }
 
+bool PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) {
+  Node* castii = new (C) CastIINode(incr, TypeInt::INT, true);
+  castii->set_req(0, ctrl);
+  register_new_node(castii, ctrl);
+  for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) {
+    Node* n = incr->fast_out(i);
+    if (n->is_Phi() && n->in(0) == loop) {
+      int nrep = n->replace_edge(incr, castii);
+      return true;
+    }
+  }
+  return false;
+}
+
 //------------------------------insert_pre_post_loops--------------------------
 // Insert pre and post loops.  If peel_only is set, the pre-loop can not have
 // more iterations added.  It acts as a 'peel' only, no lower-bound RCE, no
@@ -1060,6 +1074,24 @@
     }
   }
 
+  // Nodes inside the loop may be control dependent on a predicate
+  // that was moved before the preloop. If the back branch of the main
+  // or post loops becomes dead, those nodes won't be dependent on the
+  // test that guards that loop nest anymore which could lead to an
+  // incorrect array access because it executes independently of the
+  // test that was guarding the loop nest. We add a special CastII on
+  // the if branch that enters the loop, between the input induction
+  // variable value and the induction variable Phi to preserve correct
+  // dependencies.
+
+  // CastII for the post loop:
+  bool inserted = cast_incr_before_loop(zer_opaq->in(1), zer_taken, post_head);
+  assert(inserted, "no castII inserted");
+
+  // CastII for the main loop:
+  inserted = cast_incr_before_loop(pre_incr, min_taken, main_head);
+  assert(inserted, "no castII inserted");
+
   // Step B4: Shorten the pre-loop to run only 1 iteration (for now).
   // RCE and alignment may change this later.
   Node *cmp_end = pre_end->cmp_node();
--- a/src/share/vm/opto/loopnode.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/loopnode.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -602,6 +602,8 @@
     return ctrl;
   }
 
+  bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop);
+
 public:
   bool has_node( Node* n ) const { return _nodes[n->_idx] != NULL; }
   // check if transform created new nodes that need _ctrl recorded
--- a/src/share/vm/opto/loopopts.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/loopopts.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -1393,7 +1393,8 @@
         // loop.  Happens if people set a loop-exit flag; then test the flag
         // in the loop to break the loop, then test is again outside of the
         // loop to determine which way the loop exited.
-        if( use->is_If() || use->is_CMove() ) {
+        // Loop predicate If node connects to Bool node through Opaque1 node.
+        if (use->is_If() || use->is_CMove() || C->is_predicate_opaq(use)) {
           // Since this code is highly unlikely, we lazily build the worklist
           // of such Nodes to go split.
           if( !split_if_set )
--- a/src/share/vm/opto/parse.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/parse.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -528,8 +528,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/src/share/vm/opto/parse2.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/parse2.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -884,7 +884,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;
 }
 
@@ -895,53 +895,12 @@
 // if a path is never taken, its controlling comparison is
 // already acting in a stable fashion.  If the comparison
 // seems stable, we will put an expensive uncommon trap
-// on the untaken path.  To be conservative, and to allow
-// partially executed counted loops to be compiled fully,
-// we will plant uncommon traps only after pointer comparisons.
-bool Parse::seems_stable_comparison(BoolTest::mask btest, Node* cmp) {
-  for (int depth = 4; depth > 0; depth--) {
-    // The following switch can find CmpP here over half the time for
-    // dynamic language code rich with type tests.
-    // Code using counted loops or array manipulations (typical
-    // of benchmarks) will have many (>80%) CmpI instructions.
-    switch (cmp->Opcode()) {
-    case Op_CmpP:
-      // A never-taken null check looks like CmpP/BoolTest::eq.
-      // These certainly should be closed off as uncommon traps.
-      if (btest == BoolTest::eq)
-        return true;
-      // A never-failed type check looks like CmpP/BoolTest::ne.
-      // Let's put traps on those, too, so that we don't have to compile
-      // unused paths with indeterminate dynamic type information.
-      if (ProfileDynamicTypes)
-        return true;
-      return false;
-
-    case Op_CmpI:
-      // A small minority (< 10%) of CmpP are masked as CmpI,
-      // as if by boolean conversion ((p == q? 1: 0) != 0).
-      // Detect that here, even if it hasn't optimized away yet.
-      // Specifically, this covers the 'instanceof' operator.
-      if (btest == BoolTest::ne || btest == BoolTest::eq) {
-        if (_gvn.type(cmp->in(2))->singleton() &&
-            cmp->in(1)->is_Phi()) {
-          PhiNode* phi = cmp->in(1)->as_Phi();
-          int true_path = phi->is_diamond_phi();
-          if (true_path > 0 &&
-              _gvn.type(phi->in(1))->singleton() &&
-              _gvn.type(phi->in(2))->singleton()) {
-            // phi->region->if_proj->ifnode->bool->cmp
-            BoolNode* bol = phi->in(0)->in(1)->in(0)->in(1)->as_Bool();
-            btest = bol->_test._test;
-            cmp = bol->in(1);
-            continue;
-          }
-        }
-      }
-      return false;
-    }
+// on the untaken path.
+bool Parse::seems_stable_comparison() const {
+  if (C->too_many_traps(method(), bci(), Deoptimization::Reason_unstable_if)) {
+    return false;
   }
-  return false;
+  return true;
 }
 
 //-------------------------------repush_if_args--------------------------------
@@ -1166,6 +1125,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
@@ -1179,33 +1146,9 @@
 
   bool is_fallthrough = (path == successor_for_bci(iter().next_bci()));
 
-  if (seems_never_taken(prob) && seems_stable_comparison(btest, c)) {
-    // If this might possibly turn into an implicit null check,
-    // and the null has never yet been seen, we need to generate
-    // an uncommon trap, so as to recompile instead of suffering
-    // with very slow branches.  (We'll get the slow branches if
-    // the program ever changes phase and starts seeing nulls here.)
-    //
-    // We do not inspect for a null constant, since a node may
-    // optimize to 'null' later on.
-    //
-    // Null checks, and other tests which expect inequality,
-    // show btest == BoolTest::eq along the non-taken branch.
-    // On the other hand, type tests, must-be-null tests,
-    // and other tests which expect pointer equality,
-    // show btest == BoolTest::ne along the non-taken branch.
-    // We prune both types of branches if they look unused.
+  if (path_is_suitable_for_uncommon_trap(prob)) {
     repush_if_args();
-    // We need to mark this branch as taken so that if we recompile we will
-    // see that it is possible. In the tiered system the interpreter doesn't
-    // do profiling and by the time we get to the lower tier from the interpreter
-    // the path may be cold again. Make sure it doesn't look untaken
-    if (is_fallthrough) {
-      profile_not_taken_branch(!ProfileInterpreter);
-    } else {
-      profile_taken_branch(iter().get_dest(), !ProfileInterpreter);
-    }
-    uncommon_trap(Deoptimization::Reason_unreached,
+    uncommon_trap(Deoptimization::Reason_unstable_if,
                   Deoptimization::Action_reinterpret,
                   NULL,
                   (is_fallthrough ? "taken always" : "taken never"));
--- a/src/share/vm/opto/phaseX.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/phaseX.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -1323,15 +1323,27 @@
       }
     }
 
-    if( use->is_Cmp() ) {       // Enable CMP/BOOL optimization
+    uint use_op = use->Opcode();
+    if(use->is_Cmp()) {       // Enable CMP/BOOL optimization
       add_users_to_worklist(use); // Put Bool on worklist
-      // Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the
-      // phi merging either 0 or 1 onto the worklist
       if (use->outcnt() > 0) {
         Node* bol = use->raw_out(0);
         if (bol->outcnt() > 0) {
           Node* iff = bol->raw_out(0);
-          if (iff->outcnt() == 2) {
+          if (use_op == Op_CmpI &&
+              iff->is_CountedLoopEnd()) {
+            CountedLoopEndNode* cle = iff->as_CountedLoopEnd();
+            if (cle->limit() == n && cle->phi() != NULL) {
+              // If an opaque node feeds into the limit condition of a
+              // CountedLoop, we need to process the Phi node for the
+              // induction variable when the opaque node is removed:
+              // the range of values taken by the Phi is now known and
+              // so its type is also known.
+              _worklist.push(cle->phi());
+            }
+          } else if (iff->outcnt() == 2) {
+            // Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the
+            // phi merging either 0 or 1 onto the worklist
             Node* ifproj0 = iff->raw_out(0);
             Node* ifproj1 = iff->raw_out(1);
             if (ifproj0->outcnt() > 0 && ifproj1->outcnt() > 0) {
@@ -1343,9 +1355,26 @@
           }
         }
       }
+      if (use_op == Op_CmpI) {
+        Node* in1 = use->in(1);
+        for (uint i = 0; i < in1->outcnt(); i++) {
+          if (in1->raw_out(i)->Opcode() == Op_CastII) {
+            Node* castii = in1->raw_out(i);
+            if (castii->in(0) != NULL && castii->in(0)->in(0) != NULL && castii->in(0)->in(0)->is_If()) {
+              Node* ifnode = castii->in(0)->in(0);
+              if (ifnode->in(1) != NULL && ifnode->in(1)->is_Bool() && ifnode->in(1)->in(1) == use) {
+                // Reprocess a CastII node that may depend on an
+                // opaque node value when the opaque node is
+                // removed. In case it carries a dependency we can do
+                // a better job of computing its type.
+                _worklist.push(castii);
+              }
+            }
+          }
+        }
+      }
     }
 
-    uint use_op = use->Opcode();
     // If changed Cast input, check Phi users for simple cycles
     if( use->is_ConstraintCast() || use->is_CheckCastPP() ) {
       for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) {
--- a/src/share/vm/opto/subnode.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/subnode.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -1066,12 +1066,10 @@
 
 //------------------------------dump_spec-------------------------------------
 // Print special per-node info
-#ifndef PRODUCT
 void BoolTest::dump_on(outputStream *st) const {
   const char *msg[] = {"eq","gt","??","lt","ne","le","??","ge"};
   st->print(msg[_test]);
 }
-#endif
 
 //=============================================================================
 uint BoolNode::hash() const { return (Node::hash() << 3)|(_test._test+1); }
--- a/src/share/vm/opto/subnode.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/opto/subnode.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -273,9 +273,7 @@
   mask commute( ) const { return mask("038147858"[_test]-'0'); }
   mask negate( ) const { return mask(_test^4); }
   bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le); }
-#ifndef PRODUCT
   void dump_on(outputStream *st) const;
-#endif
 };
 
 //------------------------------BoolNode---------------------------------------
--- a/src/share/vm/prims/jvm.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/prims/jvm.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -4611,7 +4611,7 @@
 
 JVM_ENTRY(void, JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size))
 {
-  memset(info, 0, sizeof(info_size));
+  memset(info, 0, info_size);
 
   info->jvm_version = Abstract_VM_Version::jvm_version();
   info->update_version = 0;          /* 0 in HotSpot Express VM */
--- a/src/share/vm/runtime/arguments.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/runtime/arguments.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -266,6 +266,7 @@
   { "Tier1MaxInlineSize",  JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
   { "Tier1LoopOptsCount",  JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
   { "UseSpinning",         JDK_Version::jdk_update(7,40), JDK_Version::jdk(8) },
+  { "CompilationRepeat",   JDK_Version::jdk_update(7,80), JDK_Version::jdk(9) },
 #ifdef PRODUCT
   { "DesiredMethodLimit",
                            JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) },
@@ -2485,6 +2486,23 @@
 #endif
     // -D
     } else if (match_option(option, "-D", &tail)) {
+      if (CheckEndorsedAndExtDirs) {
+        if (match_option(option, "-Djava.endorsed.dirs=", &tail)) {
+          // abort if -Djava.endorsed.dirs is set
+          jio_fprintf(defaultStream::output_stream(),
+            "-Djava.endorsed.dirs will not be supported in a future release.\n"
+            "Refer to JEP 220 for details (http://openjdk.java.net/jeps/220).\n");
+          return JNI_EINVAL;
+        }
+        if (match_option(option, "-Djava.ext.dirs=", &tail)) {
+          // abort if -Djava.ext.dirs is set
+          jio_fprintf(defaultStream::output_stream(),
+            "-Djava.ext.dirs will not be supported in a future release.\n"
+            "Refer to JEP 220 for details (http://openjdk.java.net/jeps/220).\n");
+          return JNI_EINVAL;
+        }
+      }
+
       if (!add_property(tail)) {
         return JNI_ENOMEM;
       }
@@ -2874,6 +2892,146 @@
   return JNI_OK;
 }
 
+static bool has_jar_files(const char* directory) {
+  DIR* dir = os::opendir(directory);
+  if (dir == NULL) return false;
+
+  struct dirent *entry;
+  char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtInternal);
+  bool hasJarFile = false;
+  while (!hasJarFile && (entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
+    const char* name = entry->d_name;
+    const char* ext = name + strlen(name) - 4;
+    hasJarFile = ext > name && (os::file_name_strcmp(ext, ".jar") == 0);
+  }
+  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+  os::closedir(dir);
+  return hasJarFile ;
+}
+
+// returns the number of directories in the given path containing JAR files
+// If the skip argument is not NULL, it will skip that directory
+static int check_non_empty_dirs(const char* path, const char* type, const char* skip) {
+  const char separator = *os::path_separator();
+  const char* const end = path + strlen(path);
+  int nonEmptyDirs = 0;
+  while (path < end) {
+    const char* tmp_end = strchr(path, separator);
+    if (tmp_end == NULL) {
+      if ((skip == NULL || strcmp(path, skip) != 0) && has_jar_files(path)) {
+        nonEmptyDirs++;
+        jio_fprintf(defaultStream::output_stream(),
+          "Non-empty %s directory: %s\n", type, path);
+      }
+      path = end;
+    } else {
+      char* dirpath = NEW_C_HEAP_ARRAY(char, tmp_end - path + 1, mtInternal);
+      memcpy(dirpath, path, tmp_end - path);
+      dirpath[tmp_end - path] = '\0';
+      if ((skip == NULL || strcmp(dirpath, skip) != 0) && has_jar_files(dirpath)) {
+        nonEmptyDirs++;
+        jio_fprintf(defaultStream::output_stream(),
+          "Non-empty %s directory: %s\n", type, dirpath);
+      }
+      FREE_C_HEAP_ARRAY(char, dirpath, mtInternal);
+      path = tmp_end + 1;
+    }
+  }
+  return nonEmptyDirs;
+}
+
+// Returns true if endorsed standards override mechanism and extension mechanism
+// are not used.
+static bool check_endorsed_and_ext_dirs() {
+  if (!CheckEndorsedAndExtDirs)
+    return true;
+
+  char endorsedDir[JVM_MAXPATHLEN];
+  char extDir[JVM_MAXPATHLEN];
+  const char* fileSep = os::file_separator();
+  jio_snprintf(endorsedDir, sizeof(endorsedDir), "%s%slib%sendorsed",
+               Arguments::get_java_home(), fileSep, fileSep);
+  jio_snprintf(extDir, sizeof(extDir), "%s%slib%sext",
+               Arguments::get_java_home(), fileSep, fileSep);
+
+  // check endorsed directory
+  int nonEmptyDirs = check_non_empty_dirs(Arguments::get_endorsed_dir(), "endorsed", NULL);
+
+  // check the extension directories but skip the default lib/ext directory
+  nonEmptyDirs += check_non_empty_dirs(Arguments::get_ext_dirs(), "extension", extDir);
+
+  // List of JAR files installed in the default lib/ext directory.
+  // -XX:+CheckEndorsedAndExtDirs checks if any non-JDK file installed
+  static const char* jdk_ext_jars[] = {
+      "access-bridge-32.jar",
+      "access-bridge-64.jar",
+      "access-bridge.jar",
+      "cldrdata.jar",
+      "dnsns.jar",
+      "jaccess.jar",
+      "jfxrt.jar",
+      "localedata.jar",
+      "nashorn.jar",
+      "sunec.jar",
+      "sunjce_provider.jar",
+      "sunmscapi.jar",
+      "sunpkcs11.jar",
+      "ucrypto.jar",
+      "zipfs.jar",
+      NULL
+  };
+
+  // check if the default lib/ext directory has any non-JDK jar files; if so, error
+  DIR* dir = os::opendir(extDir);
+  if (dir != NULL) {
+    int num_ext_jars = 0;
+    struct dirent *entry;
+    char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(extDir), mtInternal);
+    while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
+      const char* name = entry->d_name;
+      const char* ext = name + strlen(name) - 4;
+      if (ext > name && (os::file_name_strcmp(ext, ".jar") == 0)) {
+        bool is_jdk_jar = false;
+        const char* jarfile = NULL;
+        for (int i=0; (jarfile = jdk_ext_jars[i]) != NULL; i++) {
+          if (os::file_name_strcmp(name, jarfile) == 0) {
+            is_jdk_jar = true;
+            break;
+          }
+        }
+        if (!is_jdk_jar) {
+          jio_fprintf(defaultStream::output_stream(),
+            "%s installed in <JAVA_HOME>/lib/ext\n", name);
+          num_ext_jars++;
+        }
+      }
+    }
+    FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
+    os::closedir(dir);
+    if (num_ext_jars > 0) {
+      nonEmptyDirs += 1;
+    }
+  }
+
+  // check if the default lib/endorsed directory exists; if so, error
+  dir = os::opendir(endorsedDir);
+  if (dir != NULL) {
+    jio_fprintf(defaultStream::output_stream(), "<JAVA_HOME>/lib/endorsed exists\n");
+    os::closedir(dir);
+    nonEmptyDirs += 1;
+  }
+
+  if (nonEmptyDirs > 0) {
+    jio_fprintf(defaultStream::output_stream(),
+      "Endorsed standards override mechanism and extension mechanism "
+      "will not be supported in a future release.\n"
+      "Refer to JEP 220 for details (http://openjdk.java.net/jeps/220).\n");
+    return false;
+  }
+
+  return true;
+}
+
 jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_required) {
   // This must be done after all -D arguments have been processed.
   scp_p->expand_endorsed();
@@ -2883,6 +3041,10 @@
     Arguments::set_sysclasspath(scp_p->combined_path());
   }
 
+  if (!check_endorsed_and_ext_dirs()) {
+    return JNI_ERR;
+  }
+
   // This must be done after all arguments have been processed.
   // java_compiler() true means set to "NONE" or empty.
   if (java_compiler() && !xdebug_mode()) {
--- a/src/share/vm/runtime/arguments.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/runtime/arguments.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -543,6 +543,7 @@
   static char *get_sysclasspath() { return _sun_boot_class_path->value(); }
   static char* get_meta_index_path() { return _meta_index_path; }
   static char* get_meta_index_dir()  { return _meta_index_dir;  }
+  static char* get_ext_dirs() { return _java_ext_dirs->value(); }
 
   // Operation modi
   static Mode mode()                        { return _mode; }
--- a/src/share/vm/runtime/deoptimization.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/runtime/deoptimization.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -1796,7 +1796,8 @@
   "div0_check",
   "age",
   "predicate",
-  "loop_limit_check"
+  "loop_limit_check",
+  "unstable_if"
 };
 const char* Deoptimization::_trap_action_name[Action_LIMIT] = {
   // Note:  Keep this in sync. with enum DeoptAction.
--- a/src/share/vm/runtime/deoptimization.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/runtime/deoptimization.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -59,6 +59,7 @@
     Reason_age,                   // nmethod too old; tier threshold reached
     Reason_predicate,             // compiler generated predicate failed
     Reason_loop_limit_check,      // compiler generated loop limits check failed
+    Reason_unstable_if,           // a branch predicted always false was taken
     Reason_LIMIT,
     // Note:  Keep this enum in sync. with _trap_reason_name.
     Reason_RECORDED_LIMIT = Reason_bimorphic  // some are not recorded per bc
@@ -311,6 +312,8 @@
       return reason;
     else if (reason == Reason_div0_check) // null check due to divide-by-zero?
       return Reason_null_check;           // recorded per BCI as a null check
+    else if (reason == Reason_unstable_if)
+      return Reason_intrinsic;
     else
       return Reason_none;
   }
--- a/src/share/vm/runtime/globals.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/runtime/globals.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -1154,6 +1154,9 @@
   product(bool, CheckJNICalls, false,                                       \
           "Verify all arguments to JNI calls")                              \
                                                                             \
+  product(bool, CheckEndorsedAndExtDirs, false,                             \
+          "Verify the endorsed and extension directories are not used")     \
+                                                                            \
   product(bool, UseFastJNIAccessors, true,                                  \
           "Use optimized versions of Get<Primitive>Field")                  \
                                                                             \
--- a/src/share/vm/runtime/vmStructs.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/runtime/vmStructs.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -2433,6 +2433,7 @@
   declare_constant(Deoptimization::Reason_age)                            \
   declare_constant(Deoptimization::Reason_predicate)                      \
   declare_constant(Deoptimization::Reason_loop_limit_check)               \
+  declare_constant(Deoptimization::Reason_unstable_if)                    \
   declare_constant(Deoptimization::Reason_LIMIT)                          \
   declare_constant(Deoptimization::Reason_RECORDED_LIMIT)                 \
                                                                           \
--- a/src/share/vm/services/runtimeService.cpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/services/runtimeService.cpp	Wed Jan 07 12:20:45 2015 -0800
@@ -44,6 +44,7 @@
 PerfCounter*  RuntimeService::_thread_interrupt_signaled_count = NULL;
 PerfCounter*  RuntimeService::_interrupted_before_count = NULL;
 PerfCounter*  RuntimeService::_interrupted_during_count = NULL;
+double RuntimeService::_last_safepoint_sync_time_sec = 0.0;
 
 void RuntimeService::init() {
   // Make sure the VM version is initialized
@@ -123,6 +124,7 @@
 
   // update the time stamp to begin recording safepoint time
   _safepoint_timer.update();
+  _last_safepoint_sync_time_sec = 0.0;
   if (UsePerfData) {
     _total_safepoints->inc();
     if (_app_timer.is_updated()) {
@@ -135,6 +137,9 @@
   if (UsePerfData) {
     _sync_time_ticks->inc(_safepoint_timer.ticks_since_update());
   }
+  if (PrintGCApplicationStoppedTime) {
+    _last_safepoint_sync_time_sec = last_safepoint_time_sec();
+  }
 }
 
 void RuntimeService::record_safepoint_end() {
@@ -150,8 +155,10 @@
     gclog_or_tty->date_stamp(PrintGCDateStamps);
     gclog_or_tty->stamp(PrintGCTimeStamps);
     gclog_or_tty->print_cr("Total time for which application threads "
-                           "were stopped: %3.7f seconds",
-                           last_safepoint_time_sec());
+                           "were stopped: %3.7f seconds, "
+                           "Stopping threads took: %3.7f seconds",
+                           last_safepoint_time_sec(),
+                           _last_safepoint_sync_time_sec);
   }
 
   // update the time stamp to begin recording app time
--- a/src/share/vm/services/runtimeService.hpp	Tue Dec 23 13:53:21 2014 -0800
+++ b/src/share/vm/services/runtimeService.hpp	Wed Jan 07 12:20:45 2015 -0800
@@ -40,6 +40,7 @@
 
   static TimeStamp _safepoint_timer;
   static TimeStamp _app_timer;
+  static double _last_safepoint_sync_time_sec;
 
 public:
   static void init();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/exceptions/CatchInlineExceptions.java	Wed Jan 07 12:20:45 2015 -0800
@@ -0,0 +1,81 @@
+/*
+ * 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 8059299
+ * @summary assert(adr_type != NULL) failed: expecting TypeKlassPtr
+ * @run main/othervm -Xbatch CatchInlineExceptions
+ */
+
+class Exception1 extends Exception {};
+class Exception2 extends Exception {};
+
+public class CatchInlineExceptions {
+    private static int counter0;
+    private static int counter1;
+    private static int counter2;
+    private static int counter;
+
+    static void foo(int i) throws Exception {
+        if ((i & 1023) == 2) {
+            counter0++;
+            throw new Exception2();
+        }
+    }
+
+    static void test(int i) throws Exception {
+        try {
+           foo(i);
+        }
+        catch (Exception e) {
+            if (e instanceof Exception1) {
+                counter1++;
+            } else if (e instanceof Exception2) {
+                counter2++;
+            }
+            counter++;
+            throw e;
+        }
+    }
+
+    public static void main(String[] args) throws Throwable {
+        for (int i = 0; i < 15000; i++) {
+            try {
+                test(i);
+            } catch (Exception e) {
+                // expected
+            }
+        }
+        if (counter1 != 0) {
+            throw new RuntimeException("Failed: counter1(" + counter1  + ") != 0");
+        }
+        if (counter2 != counter0) {
+            throw new RuntimeException("Failed: counter2(" + counter2  + ") != counter0(" + counter0  + ")");
+        }
+        if (counter2 != counter) {
+            throw new RuntimeException("Failed: counter2(" + counter2  + ") != counter(" + counter  + ")");
+        }
+        System.out.println("TEST PASSED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/loopopts/TestDeadBackbranchArrayAccess.java	Wed Jan 07 12:20:45 2015 -0800
@@ -0,0 +1,58 @@
+/*
+ * 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 8054478
+ * @summary dead backbranch in main loop results in erroneous array access
+ * @run main/othervm -XX:CompileOnly=TestDeadBackbranchArrayAccess -XX:+TieredCompilation -Xcomp TestDeadBackbranchArrayAccess
+ *
+ */
+
+public class TestDeadBackbranchArrayAccess {
+    static char[] pattern0 = {0};
+    static char[] pattern1 = {1};
+
+    static void test(char[] array) {
+        if (pattern1 == null) return;
+
+        int i = 0;
+        int pos = 0;
+        char c = array[pos];
+
+        while (i >= 0 && (c == pattern0[i] || c == pattern1[i])) {
+            i--;
+            pos--;
+            if (pos != -1) {
+                c = array[pos];
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        for (int i = 0; i < 1000000; i++) {
+            test(new char[1]);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/CheckEndorsedAndExtDirs/EndorsedExtDirs.java	Wed Jan 07 12:20:45 2015 -0800
@@ -0,0 +1,96 @@
+/*
+ * 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 8064667
+ * @summary Sanity test for -XX:+CheckEndorsedAndExtDirs
+ * @library /testlibrary
+ * @run main/othervm EndorsedExtDirs
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+public class EndorsedExtDirs {
+    static final String cpath = System.getProperty("test.classes", ".");
+    public static void main(String arg[]) throws Exception {
+        fatalError("-XX:+CheckEndorsedAndExtDirs", "-Djava.endorsed.dirs=foo");
+        fatalError("-XX:+CheckEndorsedAndExtDirs", "-Djava.ext.dirs=bar");
+        testNonEmptySystemExtDirs();
+    }
+
+    static void testNonEmptySystemExtDirs() throws Exception {
+        String home = System.getProperty("java.home");
+        Path ext = Paths.get(home, "lib", "ext");
+        String extDirs = System.getProperty("java.ext.dirs");
+        String[] dirs = extDirs.split(File.pathSeparator);
+        long count = 0;
+        for (String d : dirs) {
+            Path path = Paths.get(d);
+            if (Files.notExists(path) || path.equals(ext)) continue;
+            try (DirectoryStream<Path> jars =
+                    Files.newDirectoryStream(path, "*.jar"))
+            {
+                for (Path j : jars) {
+                    count++;
+                }
+            }
+        }
+        if (count > 0) {
+            fatalError("-XX:+CheckEndorsedAndExtDirs");
+        }
+    }
+
+    static ProcessBuilder newProcessBuilder(String... args) {
+        List<String> commands = new ArrayList<>();
+        String java = System.getProperty("java.home") + "/bin/java";
+        commands.add(java);
+        for (String s : args) {
+            commands.add(s);
+        }
+        commands.add("-cp");
+        commands.add(cpath);
+        commands.add("EndorsedExtDirs");
+
+        System.out.println("Process " + commands);
+        return new ProcessBuilder(commands);
+    }
+
+    static void fatalError(String... args) throws Exception {
+        fatalError(newProcessBuilder(args));
+    }
+
+    static void fatalError(ProcessBuilder pb) throws Exception {
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("Could not create the Java Virtual Machine");
+        output.shouldHaveExitValue(1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/LoadClass/LoadClassNegative.java	Wed Jan 07 12:20:45 2015 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013, 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
+ * @key regression
+ * @bug 8020675
+ * @summary make sure there is no fatal error if a class is loaded from an invalid jar file which is in the bootclasspath
+ * @library /testlibrary
+ * @build TestForName
+ * @build LoadClassNegative
+ * @run main LoadClassNegative
+ */
+
+import java.io.File;
+import com.oracle.java.testlibrary.*;
+
+public class LoadClassNegative {
+
+  public static void main(String args[]) throws Exception {
+    String bootCP = "-Xbootclasspath/a:" + System.getProperty("test.src")
+                       + File.separator + "dummy.jar";
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+        bootCP,
+        "TestForName");
+
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldContain("ClassNotFoundException");
+    output.shouldHaveExitValue(0);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/LoadClass/ShowClassLoader.java	Wed Jan 07 12:20:45 2015 -0800
@@ -0,0 +1,45 @@
+/*
+ * 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
+ * @key regression
+ * @bug 8058927
+ * @summary Make sure array class has the right class loader
+ * @run main ShowClassLoader
+ */
+
+public class ShowClassLoader {
+
+    public static void main(String[] args) {
+        Object[] oa = new Object[0];
+        ShowClassLoader[] sa = new ShowClassLoader[0];
+
+        System.out.println("Classloader for Object[] is " + oa.getClass().getClassLoader());
+        System.out.println("Classloader for SCL[] is " + sa.getClass().getClassLoader() );
+
+        if (sa.getClass().getClassLoader() == null) {
+            throw new RuntimeException("Wrong class loader");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/LoadClass/TestForName.java	Wed Jan 07 12:20:45 2015 -0800
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+public class TestForName {
+    public static void main(String[] args) {
+        try {
+            Class cls = Class.forName("xxx");
+            System.out.println("Class = " + cls.getName());
+        } catch (ClassNotFoundException cnfe) {
+            cnfe.printStackTrace();
+        }
+    }
+}