Merge
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index 01c9382..026ae46 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -314,6 +314,25 @@
 1710841b0229403f4af85eac8b68ea5065a26c81 jdk8u20-b24
 1710841b0229403f4af85eac8b68ea5065a26c81 jdk8u20-b25
 d1a7ea2c3e1091e0df1285963328a96f475f240d jdk8u20-b26
+97c6d6a8e5bb3dfc24b9a32711aa0906ea110e23 jdk8u25-b00
+c4cfb4376f5916c5d7eb1f39a0e23402de0d9818 jdk8u25-b01
+b4d29a751077e5500e766b8104dd1cb7148a550f jdk8u25-b02
+d3df54be114a5c41d4881b61cd42fbb0e52aaf4a jdk8u25-b03
+64e7567a8539078a678853a384340eee469168b0 jdk8u25-b04
+6de13ae93be20b97f53e3837739947d59fb4fd65 jdk8u25-b05
+69d17ee59c0e77033aca293501a642d0abc20c85 jdk8u25-b06
+561d066eaa6428088b4f7e273a8caed90e8f6073 jdk8u25-b07
+c2a5ad21d01c5d921c4e928edcb14cc3d61eb62b jdk8u25-b08
+1249614d7f1d9bf8443f0abd0622b4d2a3ab0638 jdk8u25-b09
+0c5d41165be3f4bb989bd84283c2df3e37b9845d jdk8u25-b10
+cc5ab3e0fe815ae80bb52fa5affcb35ee0f51cff jdk8u25-b11
+c35e73e4acd8ed03e77e8e20023bac115c7dfe38 jdk8u25-b12
+5d990a43c996ef039c6619e55215d589e09d1022 jdk8u25-b13
+4429ea47ee6eca6b8a1dbda1950566ee821ba19d jdk8u25-b14
+09eaef69f384ecf8ec0342b87a8b150740941140 jdk8u25-b15
+f0a48c214c46b7351ff8e6d6b6dc533463a4be21 jdk8u25-b16
+d117f01bfb4f34668ac216c9837e88acead14dce jdk8u25-b17
+efac90a2da447c2b2d43ee1b1e20c0828659f9c5 jdk8u25-b18
 0dccc4aca1859b1ff7dca9db214f7f38c4ddbbce jdk8u40-b00
 f8736a40a35df0c8055c8a94b96e5381b381ad33 jdk8u40-b01
 b6a148730f2b14193c308bc9c866c36ee6c08ed3 jdk8u40-b02
@@ -323,3 +342,4 @@
 8881a63f7f00a4a5611800db7715aecc8f6b3601 jdk8u40-b06
 cf9afcfcb7a41b892fc896c1dbf245d5dcc42395 jdk8u40-b07
 515a912fb5a9a61774fa2afa10f4472589be5602 jdk8u40-b08
+0958d0a9f44efcebe30b17b07240abaa42a2112b jdk8u40-b09
diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh
index 4adfbfe..609d91f 100644
--- a/common/autoconf/generated-configure.sh
+++ b/common/autoconf/generated-configure.sh
@@ -3868,7 +3868,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1405022087
+DATE_WHEN_GENERATED=1411155242
 
 ###############################################################################
 #
diff --git a/corba/.hgtags b/corba/.hgtags
index 50190db..8abfcb5 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -312,6 +312,25 @@
 34c930eaa6b591621afde05ca2e24571c91cdc9b jdk8u20-b24
 34c930eaa6b591621afde05ca2e24571c91cdc9b jdk8u20-b25
 37bde23c96f66912c44b1b893c08d4ad4cff5f4e jdk8u20-b26
+08aa9f55fe5bce1f04cfd2958f71e8df18643e29 jdk8u25-b00
+31f50e3c0dcbdfa7f11a895179065e6888c2cf3c jdk8u25-b01
+162703b7c2f16ce00d1b54a8f95d12eda9753eba jdk8u25-b02
+ddaa2a3e452c8fbb1a7046e743096d0f9489290e jdk8u25-b03
+a76e6e02711edbfab4931dc679cbd3df6169ec84 jdk8u25-b04
+2fab01326282ee9033c089933b2dc46aef127abd jdk8u25-b05
+76068779ea16c40a9d3c14751a3bbd6c21f09cfd jdk8u25-b06
+db4d845d6a4d71ef5e48a8888f71375b0e21959f jdk8u25-b07
+afd9d9e1bbb5ab77c95a8750d2df164e05088d09 jdk8u25-b08
+1322b445ab39930c50c3901f6c439aad99a62fe8 jdk8u25-b09
+2e6da97d338ad5a65bf07f9d9648dcb74b5776b4 jdk8u25-b10
+11f77cdff0b2a07fd89f439b044d9f10a15f8fd5 jdk8u25-b11
+f560274aec4f42283c10070921afae403a153de2 jdk8u25-b12
+987bd55824c4794c8784a47fc45ecd18a9c2a5c8 jdk8u25-b13
+7e9a2027d0214019d66325fa7ca59cf8281fb43e jdk8u25-b14
+5b2cb4935667cd02d7974b3b6fb6bf4092b5acae jdk8u25-b15
+28d7f90e04e46ce8c633a2fbf0157d9e77db17c3 jdk8u25-b16
+f46df0af2ca8c7d896de375c8edac8ce09318318 jdk8u25-b17
+ee069d67c12df902cdb06ecf1747f8ff9d495a61 jdk8u25-b18
 7d1e0f0b63f1d66c77924d8b2a1accdf8f7480db jdk8u40-b00
 c5d9822a3c18cd9e274dfe99e91c33e02bd8f8f4 jdk8u40-b01
 504b4455570e14b7fc0a837a09c6401c603516d9 jdk8u40-b02
@@ -321,3 +340,4 @@
 ced787f7545f26c3b1fdd35119ff41aa79fe6e03 jdk8u40-b06
 0d09cb188d39b5abb759977b9020ef957a0374ed jdk8u40-b07
 8d4971881c6661c51276ddb84b8e314b37d8d742 jdk8u40-b08
+bf87d71911661f583b9300795c9472179b4b3506 jdk8u40-b09
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index be1e1b6..cb2dd33 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -523,3 +523,24 @@
 5c1b5be2c69bcae610a790e9438da446c61d3361 hs25.40-b12
 905a16825d2931345a7d6dba9e427f98eb51761a jdk8u40-b08
 d96716f6cbba9f000dfb1da39d2b81264f4cdea7 hs25.40-b13
+7ff8d51e0d8fc71f3ad31fd15817083341416ca8 jdk8u40-b09
+e193bbae24effeaf476f688d8d840787db53d74e hs25.40-b14
+a4d44dfb7d30eea54bc172e4429a655454ae0bbf jdk8u25-b00
+9a2152fbd929b0d8b2f5c326a5526214ae71731a jdk8u25-b01
+d3d5604ea0dea3812e87ba76ac199d0a8be6f49f jdk8u25-b02
+27348de6239bb527c37c0bf59e938ed127b619a7 jdk8u25-b03
+220eefb3609e250a0bb0ed26236c1213b8000050 jdk8u25-b04
+db8383148bc9417dd4c38fa4cea39510f17325f3 jdk8u25-b05
+605df8463453628df49351fa63632666f18698cd jdk8u25-b06
+520188d4bade17dbe75163d1f635c08168ea560c jdk8u25-b07
+f3f50c4f9ea5d3af40cb794b6f3f2a337c8873db jdk8u25-b08
+4f209b7a580c78bac255e69f4724c42584c32a7d jdk8u25-b09
+19c692f1e4c571a9285e33e7d3d15948769fcbdd jdk8u25-b10
+9e2bb00a81910776d5b16c49a3f4c5264ceab522 jdk8u25-b11
+2993491d47df8c4b096ea7fa534162bde8b53dcf jdk8u25-b12
+ca6d25be853b5c428c6228871316671843264666 jdk8u25-b13
+c77d5db189422e2eef0443ee212644e497113b18 jdk8u25-b14
+e62c06b887310b5bd23be9b817a9a6f0daf0d0e1 jdk8u25-b15
+6467bdd4d22d8b140844dc847c43b9ba7cb0bbd1 jdk8u25-b16
+28b50d07f6f8c5a567b6a25e95a423948114a004 jdk8u25-b17
+639abc668bfe995dba811dd35411b9ea8a9041cd jdk8u25-b18
diff --git a/hotspot/make/bsd/makefiles/mapfile-vers-debug b/hotspot/make/bsd/makefiles/mapfile-vers-debug
index ddab6a2..44991d2 100644
--- a/hotspot/make/bsd/makefiles/mapfile-vers-debug
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 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
@@ -82,6 +82,7 @@
                 _JVM_EnableCompiler
                 _JVM_Exit
                 _JVM_FillInStackTrace
+                _JVM_FindClassFromCaller
                 _JVM_FindClassFromClass
                 _JVM_FindClassFromClassLoader
                 _JVM_FindClassFromBootLoader
diff --git a/hotspot/make/bsd/makefiles/mapfile-vers-product b/hotspot/make/bsd/makefiles/mapfile-vers-product
index db8c276..ed15428 100644
--- a/hotspot/make/bsd/makefiles/mapfile-vers-product
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-product
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 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
@@ -82,6 +82,7 @@
                 _JVM_EnableCompiler
                 _JVM_Exit
                 _JVM_FillInStackTrace
+                _JVM_FindClassFromCaller
                 _JVM_FindClassFromClass
                 _JVM_FindClassFromClassLoader
                 _JVM_FindClassFromBootLoader
diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version
index 0bf2de5..4aa5395 100644
--- a/hotspot/make/hotspot_version
+++ b/hotspot/make/hotspot_version
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=25
 HS_MINOR_VER=40
-HS_BUILD_NUMBER=13
+HS_BUILD_NUMBER=14
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
diff --git a/hotspot/make/linux/makefiles/mapfile-vers-debug b/hotspot/make/linux/makefiles/mapfile-vers-debug
index 41d5e9c..d20eb1e 100644
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 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
@@ -84,6 +84,7 @@
                 JVM_EnableCompiler;
                 JVM_Exit;
                 JVM_FillInStackTrace;
+                JVM_FindClassFromCaller;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromClassLoader;
                 JVM_FindClassFromBootLoader;
diff --git a/hotspot/make/linux/makefiles/mapfile-vers-product b/hotspot/make/linux/makefiles/mapfile-vers-product
index df433ad..976ea1b 100644
--- a/hotspot/make/linux/makefiles/mapfile-vers-product
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 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
@@ -84,6 +84,7 @@
                 JVM_EnableCompiler;
                 JVM_Exit;
                 JVM_FillInStackTrace;
+                JVM_FindClassFromCaller;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromClassLoader;
                 JVM_FindClassFromBootLoader;
diff --git a/hotspot/make/solaris/makefiles/mapfile-vers b/hotspot/make/solaris/makefiles/mapfile-vers
index d2a3d5c6..f25b061 100644
--- a/hotspot/make/solaris/makefiles/mapfile-vers
+++ b/hotspot/make/solaris/makefiles/mapfile-vers
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 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
@@ -84,6 +84,7 @@
                 JVM_EnableCompiler;
                 JVM_Exit;
                 JVM_FillInStackTrace;
+                JVM_FindClassFromCaller;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromClassLoader;
                 JVM_FindClassFromBootLoader;
diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
index aefc138..22a018b 100644
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
@@ -2066,14 +2066,14 @@
   LIR_Opr base_op = base.result();
   LIR_Opr index_op = idx.result();
 #ifndef _LP64
-  if (x->base()->type()->tag() == longTag) {
+  if (base_op->type() == T_LONG) {
     base_op = new_register(T_INT);
     __ convert(Bytecodes::_l2i, base.result(), base_op);
   }
   if (x->has_index()) {
-    if (x->index()->type()->tag() == longTag) {
+    if (index_op->type() == T_LONG) {
       LIR_Opr long_index_op = index_op;
-      if (x->index()->type()->is_constant()) {
+      if (index_op->is_constant()) {
         long_index_op = new_register(T_LONG);
         __ move(index_op, long_index_op);
       }
@@ -2088,14 +2088,14 @@
   assert(!x->has_index() || index_op->type() == T_INT, "index should be an int");
 #else
   if (x->has_index()) {
-    if (x->index()->type()->tag() == intTag) {
-      if (!x->index()->type()->is_constant()) {
+    if (index_op->type() == T_INT) {
+      if (!index_op->is_constant()) {
         index_op = new_register(T_LONG);
         __ convert(Bytecodes::_i2l, idx.result(), index_op);
       }
     } else {
-      assert(x->index()->type()->tag() == longTag, "must be");
-      if (x->index()->type()->is_constant()) {
+      assert(index_op->type() == T_LONG, "must be");
+      if (index_op->is_constant()) {
         index_op = new_register(T_LONG);
         __ move(idx.result(), index_op);
       }
@@ -2176,12 +2176,12 @@
   LIR_Opr index_op = idx.result();
 
 #ifndef _LP64
-  if (x->base()->type()->tag() == longTag) {
+  if (base_op->type() == T_LONG) {
     base_op = new_register(T_INT);
     __ convert(Bytecodes::_l2i, base.result(), base_op);
   }
   if (x->has_index()) {
-    if (x->index()->type()->tag() == longTag) {
+    if (index_op->type() == T_LONG) {
       index_op = new_register(T_INT);
       __ convert(Bytecodes::_l2i, idx.result(), index_op);
     }
@@ -2191,7 +2191,7 @@
   assert(!x->has_index() || (index_op->type() == T_INT && !index_op->is_constant()), "index should be an non-constant int");
 #else
   if (x->has_index()) {
-    if (x->index()->type()->tag() == intTag) {
+    if (index_op->type() == T_INT) {
       index_op = new_register(T_LONG);
       __ convert(Bytecodes::_i2l, idx.result(), index_op);
     }
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index ede2631..ea817cd 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -2830,6 +2830,11 @@
       "bootstrap_method_index %u has bad constant type in class file %s",
       bootstrap_method_index,
       CHECK);
+
+    guarantee_property((operand_fill_index + 1 + argument_count) < operands->length(),
+      "Invalid BootstrapMethods num_bootstrap_methods or num_bootstrap_arguments value in class file %s",
+      CHECK);
+
     operands->at_put(operand_fill_index++, bootstrap_method_index);
     operands->at_put(operand_fill_index++, argument_count);
 
@@ -2847,7 +2852,6 @@
   }
 
   assert(operand_fill_index == operands->length(), "exact fill");
-  assert(ConstantPool::operand_array_length(operands) == attribute_array_length, "correct decode");
 
   u1* current_end = cfs->current();
   guarantee_property(current_end == current_start + attribute_byte_length,
diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp
index 4071e7e..eab1470 100644
--- a/hotspot/src/share/vm/classfile/classLoader.cpp
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp
@@ -90,6 +90,7 @@
 typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf);
 typedef jboolean (JNICALL *ReadMappedEntry_t)(jzfile *zip, jzentry *entry, unsigned char **buf, char *namebuf);
 typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n);
+typedef jint     (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len);
 
 static ZipOpen_t         ZipOpen            = NULL;
 static ZipClose_t        ZipClose           = NULL;
@@ -98,6 +99,7 @@
 static ReadMappedEntry_t ReadMappedEntry    = NULL;
 static GetNextEntry_t    GetNextEntry       = NULL;
 static canonicalize_fn_t CanonicalizeEntry  = NULL;
+static Crc32_t           Crc32              = NULL;
 
 // Globals
 
@@ -810,9 +812,11 @@
   ReadEntry    = CAST_TO_FN_PTR(ReadEntry_t, os::dll_lookup(handle, "ZIP_ReadEntry"));
   ReadMappedEntry = CAST_TO_FN_PTR(ReadMappedEntry_t, os::dll_lookup(handle, "ZIP_ReadMappedEntry"));
   GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, os::dll_lookup(handle, "ZIP_GetNextEntry"));
+  Crc32        = CAST_TO_FN_PTR(Crc32_t, os::dll_lookup(handle, "ZIP_CRC32"));
 
   // ZIP_Close is not exported on Windows in JDK5.0 so don't abort if ZIP_Close is NULL
-  if (ZipOpen == NULL || FindEntry == NULL || ReadEntry == NULL || GetNextEntry == NULL) {
+  if (ZipOpen == NULL || FindEntry == NULL || ReadEntry == NULL ||
+      GetNextEntry == NULL || Crc32 == NULL) {
     vm_exit_during_initialization("Corrupted ZIP library", path);
   }
 
@@ -822,6 +826,11 @@
   // This lookup only works on 1.3. Do not check for non-null here
 }
 
+int ClassLoader::crc32(int crc, const char* buf, int len) {
+  assert(Crc32 != NULL, "ZIP_CRC32 is not found");
+  return (*Crc32)(crc, (const jbyte*)buf, len);
+}
+
 // PackageInfo data exists in order to support the java.lang.Package
 // class.  A Package object provides information about a java package
 // (version, vendor, etc.) which originates in the manifest of the jar
diff --git a/hotspot/src/share/vm/classfile/classLoader.hpp b/hotspot/src/share/vm/classfile/classLoader.hpp
index e5a22e7..7c12f84 100644
--- a/hotspot/src/share/vm/classfile/classLoader.hpp
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp
@@ -228,6 +228,7 @@
   // to avoid confusing the zip library
   static bool get_canonical_path(const char* orig, char* out, int len);
  public:
+  static int crc32(int crc, const char* buf, int len);
   static bool update_class_path_entry_list(const char *path,
                                            bool check_for_duplicates,
                                            bool throw_exception=true);
diff --git a/hotspot/src/share/vm/classfile/stackMapFrame.cpp b/hotspot/src/share/vm/classfile/stackMapFrame.cpp
index 9cb1d30..1332a08 100644
--- a/hotspot/src/share/vm/classfile/stackMapFrame.cpp
+++ b/hotspot/src/share/vm/classfile/stackMapFrame.cpp
@@ -148,7 +148,7 @@
     VerificationType* from, VerificationType* to, int32_t len, TRAPS) const {
   int32_t i = 0;
   for (i = 0; i < len; i++) {
-    if (!to[i].is_assignable_from(from[i], verifier(), THREAD)) {
+    if (!to[i].is_assignable_from(from[i], verifier(), false, THREAD)) {
       break;
     }
   }
@@ -245,7 +245,7 @@
   }
   VerificationType top = _stack[--_stack_size];
   bool subtype = type.is_assignable_from(
-    top, verifier(), CHECK_(VerificationType::bogus_type()));
+    top, verifier(), false, CHECK_(VerificationType::bogus_type()));
   if (!subtype) {
     verifier()->verify_error(
         ErrorContext::bad_type(_offset, stack_top_ctx(),
@@ -265,7 +265,7 @@
     return VerificationType::bogus_type();
   }
   bool subtype = type.is_assignable_from(_locals[index],
-    verifier(), CHECK_(VerificationType::bogus_type()));
+    verifier(), false, CHECK_(VerificationType::bogus_type()));
   if (!subtype) {
     verifier()->verify_error(
         ErrorContext::bad_type(_offset,
@@ -288,14 +288,14 @@
         "get long/double overflows locals");
     return;
   }
-  bool subtype = type1.is_assignable_from(_locals[index], verifier(), CHECK);
+  bool subtype = type1.is_assignable_from(_locals[index], verifier(), false, CHECK);
   if (!subtype) {
     verifier()->verify_error(
         ErrorContext::bad_type(_offset,
             TypeOrigin::local(index, this), TypeOrigin::implicit(type1)),
         "Bad local variable type");
   } else {
-    subtype = type2.is_assignable_from(_locals[index + 1], verifier(), CHECK);
+    subtype = type2.is_assignable_from(_locals[index + 1], verifier(), false, CHECK);
     if (!subtype) {
       /* Unreachable? All local store routines convert a split long or double
        * into a TOP during the store.  So we should never end up seeing an
diff --git a/hotspot/src/share/vm/classfile/stackMapFrame.hpp b/hotspot/src/share/vm/classfile/stackMapFrame.hpp
index 53582c1..24cbae3 100644
--- a/hotspot/src/share/vm/classfile/stackMapFrame.hpp
+++ b/hotspot/src/share/vm/classfile/stackMapFrame.hpp
@@ -234,7 +234,7 @@
     if (_stack_size != 0) {
       VerificationType top = _stack[_stack_size - 1];
       bool subtype = type.is_assignable_from(
-        top, verifier(), CHECK_(VerificationType::bogus_type()));
+        top, verifier(), false, CHECK_(VerificationType::bogus_type()));
       if (subtype) {
         --_stack_size;
         return top;
@@ -249,9 +249,9 @@
     assert(type2.is_long() || type2.is_double(), "must be long/double_2");
     if (_stack_size >= 2) {
       VerificationType top1 = _stack[_stack_size - 1];
-      bool subtype1 = type1.is_assignable_from(top1, verifier(), CHECK);
+      bool subtype1 = type1.is_assignable_from(top1, verifier(), false, CHECK);
       VerificationType top2 = _stack[_stack_size - 2];
-      bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK);
+      bool subtype2 = type2.is_assignable_from(top2, verifier(), false, CHECK);
       if (subtype1 && subtype2) {
         _stack_size -= 2;
         return;
diff --git a/hotspot/src/share/vm/classfile/verificationType.cpp b/hotspot/src/share/vm/classfile/verificationType.cpp
index 561618b..120d9a3 100644
--- a/hotspot/src/share/vm/classfile/verificationType.cpp
+++ b/hotspot/src/share/vm/classfile/verificationType.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -42,7 +42,8 @@
 }
 
 bool VerificationType::is_reference_assignable_from(
-    const VerificationType& from, ClassVerifier* context, TRAPS) const {
+    const VerificationType& from, ClassVerifier* context,
+    bool from_field_is_protected, TRAPS) const {
   instanceKlassHandle klass = context->current_class();
   if (from.is_null()) {
     // null is assignable to any reference
@@ -62,9 +63,11 @@
         Handle(THREAD, klass->protection_domain()), true, CHECK_false);
     KlassHandle this_class(THREAD, obj);
 
-    if (this_class->is_interface()) {
-      // We treat interfaces as java.lang.Object, including
-      // java.lang.Cloneable and java.io.Serializable
+    if (this_class->is_interface() && (!from_field_is_protected ||
+        from.name() != vmSymbols::java_lang_Object())) {
+      // If we are not trying to access a protected field or method in
+      // java.lang.Object then we treat interfaces as java.lang.Object,
+      // including java.lang.Cloneable and java.io.Serializable.
       return true;
     } else if (from.is_object()) {
       Klass* from_class = SystemDictionary::resolve_or_fail(
@@ -76,7 +79,8 @@
     VerificationType comp_this = get_component(context, CHECK_false);
     VerificationType comp_from = from.get_component(context, CHECK_false);
     if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
-      return comp_this.is_assignable_from(comp_from, context, CHECK_false);
+      return comp_this.is_assignable_from(comp_from, context,
+                                          from_field_is_protected, CHECK_false);
     }
   }
   return false;
diff --git a/hotspot/src/share/vm/classfile/verificationType.hpp b/hotspot/src/share/vm/classfile/verificationType.hpp
index 1626647..43bd79e 100644
--- a/hotspot/src/share/vm/classfile/verificationType.hpp
+++ b/hotspot/src/share/vm/classfile/verificationType.hpp
@@ -265,7 +265,8 @@
   // is assignable to another.  Returns true if one can assign 'from' to
   // this.
   bool is_assignable_from(
-      const VerificationType& from, ClassVerifier* context, TRAPS) const {
+      const VerificationType& from, ClassVerifier* context,
+      bool from_field_is_protected, TRAPS) const {
     if (equals(from) || is_bogus()) {
       return true;
     } else {
@@ -286,7 +287,9 @@
           return from.is_integer();
         default:
           if (is_reference() && from.is_reference()) {
-            return is_reference_assignable_from(from, context, CHECK_false);
+            return is_reference_assignable_from(from, context,
+                                                from_field_is_protected,
+                                                CHECK_false);
           } else {
             return false;
           }
@@ -308,7 +311,8 @@
  private:
 
   bool is_reference_assignable_from(
-    const VerificationType&, ClassVerifier*, TRAPS) const;
+    const VerificationType&, ClassVerifier*, bool from_field_is_protected,
+    TRAPS) const;
 };
 
 #endif // SHARE_VM_CLASSFILE_VERIFICATIONTYPE_HPP
diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp
index a45ce20..6eeff55 100644
--- a/hotspot/src/share/vm/classfile/verifier.cpp
+++ b/hotspot/src/share/vm/classfile/verifier.cpp
@@ -1734,7 +1734,7 @@
       VerificationType throwable =
         VerificationType::reference_type(vmSymbols::java_lang_Throwable());
       bool is_subclass = throwable.is_assignable_from(
-        catch_type, this, CHECK_VERIFY(this));
+        catch_type, this, false, CHECK_VERIFY(this));
       if (!is_subclass) {
         // 4286534: should throw VerifyError according to recent spec change
         verify_error(ErrorContext::bad_type(handler_pc,
@@ -2189,7 +2189,7 @@
         stack_object_type = current_type();
       }
       is_assignable = target_class_type.is_assignable_from(
-        stack_object_type, this, CHECK_VERIFY(this));
+        stack_object_type, this, false, CHECK_VERIFY(this));
       if (!is_assignable) {
         verify_error(ErrorContext::bad_type(bci,
             current_frame->stack_top_ctx(),
@@ -2216,7 +2216,7 @@
         // It's protected access, check if stack object is assignable to
         // current class.
         is_assignable = current_type().is_assignable_from(
-          stack_object_type, this, CHECK_VERIFY(this));
+          stack_object_type, this, true, CHECK_VERIFY(this));
         if (!is_assignable) {
           verify_error(ErrorContext::bad_type(bci,
               current_frame->stack_top_ctx(),
@@ -2489,7 +2489,7 @@
         instanceKlassHandle mh(THREAD, m->method_holder());
         if (m->is_protected() && !mh->is_same_class_package(_klass())) {
           bool assignable = current_type().is_assignable_from(
-            objectref_type, this, CHECK_VERIFY(this));
+            objectref_type, this, true, CHECK_VERIFY(this));
           if (!assignable) {
             verify_error(ErrorContext::bad_type(bci,
                 TypeOrigin::cp(new_class_index, objectref_type),
@@ -2664,11 +2664,11 @@
     bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref;
     if (!current_class()->is_anonymous()) {
       subtype = ref_class_type.is_assignable_from(
-                 current_type(), this, CHECK_VERIFY(this));
+                 current_type(), this, false, CHECK_VERIFY(this));
     } else {
       VerificationType host_klass_type =
                         VerificationType::reference_type(current_class()->host_klass()->name());
-      subtype = ref_class_type.is_assignable_from(host_klass_type, this, CHECK_VERIFY(this));
+      subtype = ref_class_type.is_assignable_from(host_klass_type, this, false, CHECK_VERIFY(this));
 
       // If invokespecial of IMR, need to recheck for same or
       // direct interface relative to the host class
@@ -2712,7 +2712,7 @@
           VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this));
           VerificationType hosttype =
             VerificationType::reference_type(current_class()->host_klass()->name());
-          bool subtype = hosttype.is_assignable_from(top, this, CHECK_VERIFY(this));
+          bool subtype = hosttype.is_assignable_from(top, this, false, CHECK_VERIFY(this));
           if (!subtype) {
             verify_error( ErrorContext::bad_type(current_frame->offset(),
               current_frame->stack_top_ctx(),
@@ -2737,7 +2737,7 @@
               // It's protected access, check if stack object is
               // assignable to current class.
               bool is_assignable = current_type().is_assignable_from(
-                stack_object_type, this, CHECK_VERIFY(this));
+                stack_object_type, this, true, CHECK_VERIFY(this));
               if (!is_assignable) {
                 if (ref_class_type.name() == vmSymbols::java_lang_Object()
                     && stack_object_type.is_array()
@@ -2920,7 +2920,7 @@
         "Method expects a return value");
     return;
   }
-  bool match = return_type.is_assignable_from(type, this, CHECK_VERIFY(this));
+  bool match = return_type.is_assignable_from(type, this, false, CHECK_VERIFY(this));
   if (!match) {
     verify_error(ErrorContext::bad_type(bci,
         current_frame->stack_top_ctx(), TypeOrigin::signature(return_type)),
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
index f153ad7..50528ac 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
@@ -2733,10 +2733,12 @@
   }
 }
 
-void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
-  assert(fl->count() == 0, "Precondition.");
-  assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
-         "Precondition");
+// Used by par_get_chunk_of_blocks() for the chunks from the
+// indexed_free_lists.  Looks for a chunk with size that is a multiple
+// of "word_sz" and if found, splits it into "word_sz" chunks and add
+// to the free list "fl".  "n" is the maximum number of chunks to
+// be added to "fl".
+bool CompactibleFreeListSpace:: par_get_chunk_of_blocks_IFL(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
 
   // We'll try all multiples of word_sz in the indexed set, starting with
   // word_sz itself and, if CMSSplitIndexedFreeListBlocks, try larger multiples,
@@ -2817,11 +2819,15 @@
                         Mutex::_no_safepoint_check_flag);
         ssize_t births = _indexedFreeList[word_sz].split_births() + num;
         _indexedFreeList[word_sz].set_split_births(births);
-        return;
+        return true;
       }
     }
+    return found;
   }
-  // Otherwise, we'll split a block from the dictionary.
+}
+
+FreeChunk* CompactibleFreeListSpace::get_n_way_chunk_to_split(size_t word_sz, size_t n) {
+
   FreeChunk* fc = NULL;
   FreeChunk* rem_fc = NULL;
   size_t rem;
@@ -2832,16 +2838,12 @@
       fc = dictionary()->get_chunk(MAX2(n * word_sz, _dictionary->min_size()),
                                   FreeBlockDictionary<FreeChunk>::atLeast);
       if (fc != NULL) {
-        _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */);  // update _unallocated_blk
-        dictionary()->dict_census_update(fc->size(),
-                                       true /*split*/,
-                                       false /*birth*/);
         break;
       } else {
         n--;
       }
     }
-    if (fc == NULL) return;
+    if (fc == NULL) return NULL;
     // Otherwise, split up that block.
     assert((ssize_t)n >= 1, "Control point invariant");
     assert(fc->is_free(), "Error: should be a free block");
@@ -2863,10 +2865,14 @@
     // dictionary and return, leaving "fl" empty.
     if (n == 0) {
       returnChunkToDictionary(fc);
-      assert(fl->count() == 0, "We never allocated any blocks");
-      return;
+      return NULL;
     }
 
+    _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */);  // update _unallocated_blk
+    dictionary()->dict_census_update(fc->size(),
+                                     true /*split*/,
+                                     false /*birth*/);
+
     // First return the remainder, if any.
     // Note that we hold the lock until we decide if we're going to give
     // back the remainder to the dictionary, since a concurrent allocation
@@ -2899,7 +2905,24 @@
     _indexedFreeList[rem].return_chunk_at_head(rem_fc);
     smallSplitBirth(rem);
   }
-  assert((ssize_t)n > 0 && fc != NULL, "Consistency");
+  assert(n * word_sz == fc->size(),
+    err_msg("Chunk size " SIZE_FORMAT " is not exactly splittable by "
+    SIZE_FORMAT " sized chunks of size " SIZE_FORMAT,
+    fc->size(), n, word_sz));
+  return fc;
+}
+
+void CompactibleFreeListSpace:: par_get_chunk_of_blocks_dictionary(size_t word_sz, size_t targetted_number_of_chunks, AdaptiveFreeList<FreeChunk>* fl) {
+
+  FreeChunk* fc = get_n_way_chunk_to_split(word_sz, targetted_number_of_chunks);
+
+  if (fc == NULL) {
+    return;
+  }
+
+  size_t n = fc->size() / word_sz;
+
+  assert((ssize_t)n > 0, "Consistency");
   // Now do the splitting up.
   // Must do this in reverse order, so that anybody attempting to
   // access the main chunk sees it as a single free block until we
@@ -2947,6 +2970,20 @@
   assert(fl->tail()->next() == NULL, "List invariant.");
 }
 
+void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
+  assert(fl->count() == 0, "Precondition.");
+  assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
+         "Precondition");
+
+  if (par_get_chunk_of_blocks_IFL(word_sz, n, fl)) {
+    // Got it
+    return;
+  }
+
+  // Otherwise, we'll split a block from the dictionary.
+  par_get_chunk_of_blocks_dictionary(word_sz, n, fl);
+}
+
 // Set up the space's par_seq_tasks structure for work claiming
 // for parallel rescan. See CMSParRemarkTask where this is currently used.
 // XXX Need to suitably abstract and generalize this and the next
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
index e79ba69..7269068 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
@@ -172,6 +172,20 @@
   // list of size "word_sz", and must now be decremented.
   void par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl);
 
+  // Used by par_get_chunk_of_blocks() for the chunks from the
+  // indexed_free_lists.
+  bool par_get_chunk_of_blocks_IFL(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl);
+
+  // Used by par_get_chunk_of_blocks_dictionary() to get a chunk
+  // evenly splittable into "n" "word_sz" chunks.  Returns that
+  // evenly splittable chunk.  May split a larger chunk to get the
+  // evenly splittable chunk.
+  FreeChunk* get_n_way_chunk_to_split(size_t word_sz, size_t n);
+
+  // Used by par_get_chunk_of_blocks() for the chunks from the
+  // dictionary.
+  void par_get_chunk_of_blocks_dictionary(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl);
+
   // Allocation helper functions
   // Allocate using a strategy that takes from the indexed free lists
   // first.  This allocation strategy assumes a companion sweeping
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index 2fa28d9..c4f97d8 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -2343,6 +2343,7 @@
     case GCCause::_gc_locker:               return GCLockerInvokesConcurrent;
     case GCCause::_java_lang_system_gc:     return ExplicitGCInvokesConcurrent;
     case GCCause::_g1_humongous_allocation: return true;
+    case GCCause::_update_allocation_context_stats_inc: return true;
     default:                                return false;
   }
 }
diff --git a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
index c3847e0..9b50ae6 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
@@ -95,8 +95,9 @@
   assert(!_should_initiate_conc_mark ||
   ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) ||
    (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent) ||
-    _gc_cause == GCCause::_g1_humongous_allocation),
-         "only a GC locker, a System.gc() or a hum allocation induced GC should start a cycle");
+    _gc_cause == GCCause::_g1_humongous_allocation ||
+    _gc_cause == GCCause::_update_allocation_context_stats_inc),
+      "only a GC locker, a System.gc(), stats update or a hum allocation induced GC should start a cycle");
 
   if (_word_size > 0) {
     // An allocation has been requested. So, try to do that first.
diff --git a/hotspot/src/share/vm/gc_interface/gcCause.cpp b/hotspot/src/share/vm/gc_interface/gcCause.cpp
index ff94025..4778d8a 100644
--- a/hotspot/src/share/vm/gc_interface/gcCause.cpp
+++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp
@@ -54,7 +54,8 @@
     case _wb_young_gc:
       return "WhiteBox Initiated Young GC";
 
-    case _update_allocation_context_stats:
+    case _update_allocation_context_stats_inc:
+    case _update_allocation_context_stats_full:
       return "Update Allocation Context Stats";
 
     case _no_gc:
diff --git a/hotspot/src/share/vm/gc_interface/gcCause.hpp b/hotspot/src/share/vm/gc_interface/gcCause.hpp
index 3c7b6bc..cb8dddd 100644
--- a/hotspot/src/share/vm/gc_interface/gcCause.hpp
+++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp
@@ -47,7 +47,8 @@
     _heap_inspection,
     _heap_dump,
     _wb_young_gc,
-    _update_allocation_context_stats,
+    _update_allocation_context_stats_inc,
+    _update_allocation_context_stats_full,
 
     /* implementation independent, but reserved for GC use */
     _no_gc,
diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp
index ef7e428..ec8d933 100644
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp
@@ -246,6 +246,12 @@
   // Ignore overpasses so statics can be found during resolution
   Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::skip_overpass);
 
+  if (klass->oop_is_array()) {
+    // Only consider klass and super klass for arrays
+    result = methodHandle(THREAD, result_oop);
+    return;
+  }
+
   // JDK 8, JVMS 5.4.3.4: Interface method resolution should
   // ignore static and non-public methods of java.lang.Object,
   // like clone, finalize, registerNatives.
@@ -290,6 +296,11 @@
     result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal));
   }
 
+  if (klass->oop_is_array()) {
+    // Only consider klass and super klass for arrays
+    return;
+  }
+
   if (result.is_null()) {
     Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
     if (default_methods != NULL) {
@@ -546,7 +557,7 @@
   // 2. lookup method in resolved klass and its super klasses
   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, false, CHECK);
 
-  if (resolved_method.is_null()) { // not found in the class hierarchy
+  if (resolved_method.is_null() && !resolved_klass->oop_is_array()) { // not found in the class hierarchy
     // 3. lookup method in all the interfaces implemented by the resolved klass
     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
 
@@ -559,16 +570,16 @@
         CLEAR_PENDING_EXCEPTION;
       }
     }
+  }
 
-    if (resolved_method.is_null()) {
-      // 4. method lookup failed
-      ResourceMark rm(THREAD);
-      THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
-                      Method::name_and_sig_as_C_string(resolved_klass(),
-                                                              method_name,
-                                                              method_signature),
-                      nested_exception);
-    }
+  if (resolved_method.is_null()) {
+    // 4. method lookup failed
+    ResourceMark rm(THREAD);
+    THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
+                    Method::name_and_sig_as_C_string(resolved_klass(),
+                                                            method_name,
+                                                            method_signature),
+                    nested_exception);
   }
 
   // 5. access checks, access checking may be turned off when calling from within the VM.
@@ -634,17 +645,18 @@
   // JDK8: also look for static methods
   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK);
 
-  if (resolved_method.is_null()) {
+  if (resolved_method.is_null() && !resolved_klass->oop_is_array()) {
     // lookup method in all the super-interfaces
     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
-    if (resolved_method.is_null()) {
-      // no method found
-      ResourceMark rm(THREAD);
-      THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
-                Method::name_and_sig_as_C_string(resolved_klass(),
-                                                        method_name,
-                                                        method_signature));
-    }
+  }
+
+  if (resolved_method.is_null()) {
+    // no method found
+    ResourceMark rm(THREAD);
+    THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
+              Method::name_and_sig_as_C_string(resolved_klass(),
+                                                      method_name,
+                                                      method_signature));
   }
 
   if (check_access) {
@@ -776,7 +788,7 @@
   }
 
   // Resolve instance field
-  KlassHandle sel_klass(THREAD, InstanceKlass::cast(resolved_klass())->find_field(field, sig, &fd));
+  KlassHandle sel_klass(THREAD, resolved_klass->find_field(field, sig, &fd));
   // check if field exists; i.e., if a klass containing the field def has been selected
   if (sel_klass.is_null()) {
     ResourceMark rm(THREAD);
diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp
index 02fb735..d817e7b 100644
--- a/hotspot/src/share/vm/memory/filemap.cpp
+++ b/hotspot/src/share/vm/memory/filemap.cpp
@@ -314,7 +314,6 @@
     fail_continue("The shared archive file has the wrong version.");
     return false;
   }
-  _file_offset = (long)n;
 
   size_t info_size = _header->_paths_misc_info_size;
   _paths_misc_info = NEW_C_HEAP_ARRAY_RETURN_NULL(char, info_size, mtClass);
@@ -330,6 +329,14 @@
     return false;
   }
 
+  size_t len = lseek(fd, 0, SEEK_END);
+  struct FileMapInfo::FileMapHeader::space_info* si =
+    &_header->_space[MetaspaceShared::mc];
+  if (si->_file_offset >= len || len - si->_file_offset < si->_used) {
+    fail_continue("The shared archive file has been truncated.");
+    return false;
+  }
+
   _file_offset += (long)n;
   return true;
 }
@@ -430,6 +437,7 @@
   si->_capacity = capacity;
   si->_read_only = read_only;
   si->_allow_exec = allow_exec;
+  si->_crc = ClassLoader::crc32(0, base, (jint)size);
   write_bytes_aligned(base, (int)size);
 }
 
@@ -454,14 +462,15 @@
 // Align file position to an allocation unit boundary.
 
 void FileMapInfo::align_file_position() {
-  long new_file_offset = align_size_up(_file_offset, os::vm_allocation_granularity());
+  size_t new_file_offset = align_size_up(_file_offset,
+                                         os::vm_allocation_granularity());
   if (new_file_offset != _file_offset) {
     _file_offset = new_file_offset;
     if (_file_open) {
       // Seek one byte back from the target and write a byte to insure
       // that the written file is the correct length.
       _file_offset -= 1;
-      if (lseek(_fd, _file_offset, SEEK_SET) < 0) {
+      if (lseek(_fd, (long)_file_offset, SEEK_SET) < 0) {
         fail_stop("Unable to seek.", NULL);
       }
       char zero = 0;
@@ -568,6 +577,19 @@
   return base;
 }
 
+bool FileMapInfo::verify_region_checksum(int i) {
+  if (!VerifySharedSpaces) {
+    return true;
+  }
+  const char* buf = _header->_space[i]._base;
+  size_t sz = _header->_space[i]._used;
+  int crc = ClassLoader::crc32(0, buf, (jint)sz);
+  if (crc != _header->_space[i]._crc) {
+    fail_continue("Checksum verification failed.");
+    return false;
+  }
+  return true;
+}
 
 // Unmap a memory region in the address space.
 
@@ -628,15 +650,33 @@
   return true;
 }
 
+int FileMapInfo::FileMapHeader::compute_crc() {
+  char* header = data();
+  // start computing from the field after _crc
+  char* buf = (char*)&_crc + sizeof(int);
+  size_t sz = data_size() - (buf - header);
+  int crc = ClassLoader::crc32(0, buf, (jint)sz);
+  return crc;
+}
+
+int FileMapInfo::compute_header_crc() {
+  return _header->compute_crc();
+}
+
 bool FileMapInfo::FileMapHeader::validate() {
-  if (_version != current_version()) {
-    FileMapInfo::fail_continue("The shared archive file is the wrong version.");
-    return false;
-  }
   if (_magic != (int)0xf00baba2) {
     FileMapInfo::fail_continue("The shared archive file has a bad magic number.");
     return false;
   }
+  if (VerifySharedSpaces && compute_crc() != _crc) {
+    fail_continue("Header checksum verification failed.");
+    return false;
+  }
+  if (_version != current_version()) {
+    FileMapInfo::fail_continue("The shared archive file is the wrong version.");
+
+    return false;
+  }
   char header_version[JVM_IDENT_MAX];
   get_header_version(header_version);
   if (strncmp(_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
diff --git a/hotspot/src/share/vm/memory/filemap.hpp b/hotspot/src/share/vm/memory/filemap.hpp
index 9fdde39..acff6c9 100644
--- a/hotspot/src/share/vm/memory/filemap.hpp
+++ b/hotspot/src/share/vm/memory/filemap.hpp
@@ -61,7 +61,7 @@
 
   bool  _file_open;
   int   _fd;
-  long  _file_offset;
+  size_t  _file_offset;
 
 private:
   static SharedClassPathEntry* _classpath_entry_table;
@@ -87,12 +87,14 @@
     }
 
     int    _magic;                    // identify file type.
+    int    _crc;                      // header crc checksum.
     int    _version;                  // (from enum, above.)
     size_t _alignment;                // how shared archive should be aligned
     int    _obj_alignment;            // value of ObjectAlignmentInBytes
 
     struct space_info {
-      int    _file_offset;   // sizeof(this) rounded to vm page size
+      int    _crc;           // crc checksum of the current space
+      size_t _file_offset;   // sizeof(this) rounded to vm page size
       char*  _base;          // copy-on-write base address
       size_t _capacity;      // for validity checking
       size_t _used;          // for setting space top on read
@@ -135,6 +137,7 @@
 
     virtual bool validate();
     virtual void populate(FileMapInfo* info, size_t alignment);
+    int compute_crc();
   };
 
   FileMapHeader * _header;
@@ -153,6 +156,8 @@
   ~FileMapInfo();
 
   static int current_version()        { return _current_version; }
+  int    compute_header_crc();
+  void   set_header_crc(int crc)      { _header->_crc = crc; }
   void   populate_header(size_t alignment);
   bool   validate_header();
   void   invalidate();
@@ -181,6 +186,7 @@
   void  write_bytes_aligned(const void* buffer, int count);
   char* map_region(int i);
   void  unmap_region(int i);
+  bool  verify_region_checksum(int i);
   void  close();
   bool  is_open() { return _file_open; }
   ReservedSpace reserve_shared_memory();
diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp
index fb2986b..4f9d4c3 100644
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp
@@ -607,6 +607,7 @@
 
   // Pass 2 - write data.
   mapinfo->open_for_write();
+  mapinfo->set_header_crc(mapinfo->compute_header_crc());
   mapinfo->write_header();
   mapinfo->write_space(MetaspaceShared::ro, _loader_data->ro_metaspace(), true);
   mapinfo->write_space(MetaspaceShared::rw, _loader_data->rw_metaspace(), false);
@@ -936,9 +937,13 @@
 
   // Map each shared region
   if ((_ro_base = mapinfo->map_region(ro)) != NULL &&
+       mapinfo->verify_region_checksum(ro) &&
       (_rw_base = mapinfo->map_region(rw)) != NULL &&
+       mapinfo->verify_region_checksum(rw) &&
       (_md_base = mapinfo->map_region(md)) != NULL &&
+       mapinfo->verify_region_checksum(md) &&
       (_mc_base = mapinfo->map_region(mc)) != NULL &&
+       mapinfo->verify_region_checksum(mc) &&
       (image_alignment == (size_t)max_alignment()) &&
       mapinfo->validate_classpath_entry_table()) {
     // Success (no need to do anything)
diff --git a/hotspot/src/share/vm/oops/arrayKlass.cpp b/hotspot/src/share/vm/oops/arrayKlass.cpp
index 09f1bb5..1c381bb 100644
--- a/hotspot/src/share/vm/oops/arrayKlass.cpp
+++ b/hotspot/src/share/vm/oops/arrayKlass.cpp
@@ -64,6 +64,13 @@
   return NULL;
 }
 
+// find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined
+Klass* ArrayKlass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
+  // There are no fields in an array klass but look to the super class (Object)
+  assert(super(), "super klass must be present");
+  return super()->find_field(name, sig, fd);
+}
+
 Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const {
   // There are no methods in an array klass but the super class (Object) has some
   assert(super(), "super klass must be present");
diff --git a/hotspot/src/share/vm/oops/arrayKlass.hpp b/hotspot/src/share/vm/oops/arrayKlass.hpp
index 3b55e03..d697cac 100644
--- a/hotspot/src/share/vm/oops/arrayKlass.hpp
+++ b/hotspot/src/share/vm/oops/arrayKlass.hpp
@@ -28,6 +28,7 @@
 #include "memory/universe.hpp"
 #include "oops/klass.hpp"
 
+class fieldDescriptor;
 class klassVtable;
 
 // ArrayKlass is the abstract baseclass for all array classes
@@ -85,6 +86,9 @@
   virtual oop multi_allocate(int rank, jint* sizes, TRAPS);
   objArrayOop allocate_arrayArray(int n, int length, TRAPS);
 
+  // find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined
+  Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const;
+
   // Lookup operations
   Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
 
diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp
index 8211073..d8279df 100644
--- a/hotspot/src/share/vm/oops/klass.cpp
+++ b/hotspot/src/share/vm/oops/klass.cpp
@@ -130,6 +130,15 @@
   return is_subclass_of(k);
 }
 
+Klass* Klass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const {
+#ifdef ASSERT
+  tty->print_cr("Error: find_field called on a klass oop."
+                " Likely error: reflection method does not correctly"
+                " wrap return value in a mirror object.");
+#endif
+  ShouldNotReachHere();
+  return NULL;
+}
 
 Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const {
 #ifdef ASSERT
diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp
index dec916a..19e8204 100644
--- a/hotspot/src/share/vm/oops/klass.hpp
+++ b/hotspot/src/share/vm/oops/klass.hpp
@@ -90,6 +90,7 @@
 class klassVtable;
 class ParCompactionManager;
 class KlassSizeStats;
+class fieldDescriptor;
 
 class Klass : public Metadata {
   friend class VMStructs;
@@ -441,6 +442,7 @@
   virtual void initialize(TRAPS);
   // lookup operation for MethodLookupCache
   friend class MethodLookupCache;
+  virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const;
   virtual Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
  public:
   Method* lookup_method(Symbol* name, Symbol* signature) const {
diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp
index 9a2f262..acbbfc9 100644
--- a/hotspot/src/share/vm/prims/jvm.cpp
+++ b/hotspot/src/share/vm/prims/jvm.cpp
@@ -808,6 +808,7 @@
   return (jclass) JNIHandles::make_local(env, k->java_mirror());
 JVM_END
 
+// Not used; JVM_FindClassFromCaller replaces this.
 JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
                                                jboolean init, jobject loader,
                                                jboolean throwError))
@@ -834,6 +835,42 @@
   return result;
 JVM_END
 
+// Find a class with this name in this loader, using the caller's protection domain.
+JVM_ENTRY(jclass, JVM_FindClassFromCaller(JNIEnv* env, const char* name,
+                                          jboolean init, jobject loader,
+                                          jclass caller))
+  JVMWrapper2("JVM_FindClassFromCaller %s throws ClassNotFoundException", name);
+  // Java libraries should ensure that name is never null...
+  if (name == NULL || (int)strlen(name) > Symbol::max_length()) {
+    // It's impossible to create this class;  the name cannot fit
+    // into the constant pool.
+    THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);
+  }
+
+  TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL);
+
+  oop loader_oop = JNIHandles::resolve(loader);
+  oop from_class = JNIHandles::resolve(caller);
+  oop protection_domain = NULL;
+  // If loader is null, shouldn't call ClassLoader.checkPackageAccess; otherwise get
+  // NPE. Put it in another way, the bootstrap class loader has all permission and
+  // thus no checkPackageAccess equivalence in the VM class loader.
+  // The caller is also passed as NULL by the java code if there is no security
+  // manager to avoid the performance cost of getting the calling class.
+  if (from_class != NULL && loader_oop != NULL) {
+    protection_domain = java_lang_Class::as_Klass(from_class)->protection_domain();
+  }
+
+  Handle h_loader(THREAD, loader_oop);
+  Handle h_prot(THREAD, protection_domain);
+  jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
+                                               h_prot, false, THREAD);
+
+  if (TraceClassResolution && result != NULL) {
+    trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
+  }
+  return result;
+JVM_END
 
 JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,
                                          jboolean init, jclass from))
@@ -3997,10 +4034,15 @@
 
 // Shared JNI/JVM entry points //////////////////////////////////////////////////////////////
 
-jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS) {
+jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init,
+                                    Handle loader, Handle protection_domain,
+                                    jboolean throwError, TRAPS) {
   // Security Note:
   //   The Java level wrapper will perform the necessary security check allowing
-  //   us to pass the NULL as the initiating class loader.
+  //   us to pass the NULL as the initiating class loader.  The VM is responsible for
+  //   the checkPackageAccess relative to the initiating class loader via the
+  //   protection_domain. The protection_domain is passed as NULL by the java code
+  //   if there is no security manager in 3-arg Class.forName().
   Klass* klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL);
 
   KlassHandle klass_handle(THREAD, klass);
diff --git a/hotspot/src/share/vm/prims/jvm.h b/hotspot/src/share/vm/prims/jvm.h
index eb8be0e..5da3e25 100644
--- a/hotspot/src/share/vm/prims/jvm.h
+++ b/hotspot/src/share/vm/prims/jvm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -420,6 +420,19 @@
 JVM_FindClassFromBootLoader(JNIEnv *env, const char *name);
 
 /*
+ * Find a class from a given class loader.  Throws ClassNotFoundException.
+ *  name:   name of class
+ *  init:   whether initialization is done
+ *  loader: class loader to look up the class. This may not be the same as the caller's
+ *          class loader.
+ *  caller: initiating class. The initiating class may be null when a security
+ *          manager is not installed.
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init,
+                        jobject loader, jclass caller);
+
+/*
  * Find a class from a given class.
  */
 JNIEXPORT jclass JNICALL
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index 3a77d80..b3a1383 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -2454,6 +2454,10 @@
     warning("The VM option CICompilerCountPerCPU overrides CICompilerCount.");
   }
 
+#ifdef COMPILER1
+  status &= verify_interval(SafepointPollOffset, 0, os::vm_page_size() - BytesPerWord, "SafepointPollOffset");
+#endif
+
   return status;
 }
 
@@ -3707,6 +3711,11 @@
     return JNI_ENOMEM;
   }
 
+  // Set up VerifySharedSpaces
+  if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) {
+    VerifySharedSpaces = true;
+  }
+
   // Delay warning until here so that we've had a chance to process
   // the -XX:-PrintWarnings flag
   if (needs_hotspotrc_warning) {
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index 1e5807d..c7cc5b3 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -1154,11 +1154,11 @@
           "Prevent spurious or premature wakeups from object.wait "         \
           "(Solaris only)")                                                 \
                                                                             \
-  product(intx, NativeMonitorTimeout, -1, "(Unstable)")                     \
+  experimental(intx, NativeMonitorTimeout, -1, "(Unstable)")                \
                                                                             \
-  product(intx, NativeMonitorFlags, 0, "(Unstable)")                        \
+  experimental(intx, NativeMonitorFlags, 0, "(Unstable)")                   \
                                                                             \
-  product(intx, NativeMonitorSpinLimit, 20, "(Unstable)")                   \
+  experimental(intx, NativeMonitorSpinLimit, 20, "(Unstable)")              \
                                                                             \
   develop(bool, UsePthreads, false,                                         \
           "Use pthread-based instead of libthread-based synchronization "   \
@@ -3775,6 +3775,10 @@
   product(bool, UseSharedSpaces, true,                                      \
           "Use shared spaces for metadata")                                 \
                                                                             \
+  product(bool, VerifySharedSpaces, false,                                  \
+          "Verify shared spaces (false for default archive, true for "      \
+          "archive specified by -XX:SharedArchiveFile)")                    \
+                                                                            \
   product(bool, RequireSharedSpaces, false,                                 \
           "Require shared spaces for metadata")                             \
                                                                             \
diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp
index a8d24fa..f0df88c 100644
--- a/hotspot/src/share/vm/runtime/reflection.cpp
+++ b/hotspot/src/share/vm/runtime/reflection.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -482,7 +482,7 @@
     ik = InstanceKlass::cast(hc);
 
     // There's no way to make a host class loop short of patching memory.
-    // Therefore there cannot be a loop here unles there's another bug.
+    // Therefore there cannot be a loop here unless there's another bug.
     // Still, let's check for it.
     assert(--inf_loop_check > 0, "no host_klass loop");
   }
@@ -551,7 +551,8 @@
   if (access.is_protected()) {
     if (!protected_restriction) {
       // See if current_class (or outermost host class) is a subclass of field_class
-      if (host_class->is_subclass_of(field_class)) {
+      // An interface may not access protected members of j.l.Object
+      if (!host_class->is_interface() && host_class->is_subclass_of(field_class)) {
         if (access.is_static() || // static fields are ok, see 6622385
             current_class == resolved_class ||
             field_class == resolved_class ||
diff --git a/hotspot/test/compiler/osr/TestRangeCheck.java b/hotspot/test/compiler/osr/TestRangeCheck.java
new file mode 100644
index 0000000..6079cb9
--- /dev/null
+++ b/hotspot/test/compiler/osr/TestRangeCheck.java
@@ -0,0 +1,52 @@
+/*
+ * 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 TestRangeCheck
+ * @bug 8054883
+ * @summary Tests that range check is not skipped
+ */
+
+public class TestRangeCheck {
+    public static void main(String args[]) {
+        try {
+            test();
+            throw new AssertionError("Expected ArrayIndexOutOfBoundsException was not thrown");
+        } catch (ArrayIndexOutOfBoundsException e) {
+            System.out.println("Expected ArrayIndexOutOfBoundsException was thrown");
+        }
+    }
+
+    private static void test() {
+        int arr[] = new int[1];
+        int result = 1;
+
+        // provoke OSR compilation
+        for (int i = 0; i < Integer.MAX_VALUE; i++) {
+        }
+
+        if (result > 0 && arr[~result] > 0) {
+            arr[~result] = 0;
+        }
+    }
+}
diff --git a/hotspot/test/gc/class_unloading/AllocateBeyondMetaspaceSize.java b/hotspot/test/gc/class_unloading/AllocateBeyondMetaspaceSize.java
deleted file mode 100644
index 4998fa8..0000000
--- a/hotspot/test/gc/class_unloading/AllocateBeyondMetaspaceSize.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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 sun.hotspot.WhiteBox;
-
-class AllocateBeyondMetaspaceSize {
-  public static Object dummy;
-
-  public static void main(String [] args) {
-    if (args.length != 2) {
-      throw new IllegalArgumentException("Usage: <MetaspaceSize> <YoungGenSize>");
-    }
-
-    long metaspaceSize = Long.parseLong(args[0]);
-    long youngGenSize = Long.parseLong(args[1]);
-
-    run(metaspaceSize, youngGenSize);
-  }
-
-  private static void run(long metaspaceSize, long youngGenSize) {
-    WhiteBox wb = WhiteBox.getWhiteBox();
-
-    long allocationBeyondMetaspaceSize  = metaspaceSize * 2;
-    long metaspace = wb.allocateMetaspace(null, allocationBeyondMetaspaceSize);
-
-    triggerYoungGC(youngGenSize);
-
-    wb.freeMetaspace(null, metaspace, metaspace);
-  }
-
-  private static void triggerYoungGC(long youngGenSize) {
-    long approxAllocSize = 32 * 1024;
-    long numAllocations  = 2 * youngGenSize / approxAllocSize;
-
-    for (long i = 0; i < numAllocations; i++) {
-      dummy = new byte[(int)approxAllocSize];
-    }
-  }
-}
diff --git a/hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java b/hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java
index 906ac0f..d832d69 100644
--- a/hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java
+++ b/hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java
@@ -26,7 +26,7 @@
  * @key gc
  * @bug 8049831
  * @library /testlibrary /testlibrary/whitebox
- * @build TestCMSClassUnloadingEnabledHWM AllocateBeyondMetaspaceSize
+ * @build TestCMSClassUnloadingEnabledHWM
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  * @run driver TestCMSClassUnloadingEnabledHWM
  * @summary Test that -XX:-CMSClassUnloadingEnabled will trigger a Full GC when more than MetaspaceSize metadata is allocated.
@@ -34,9 +34,11 @@
 
 import com.oracle.java.testlibrary.OutputAnalyzer;
 import com.oracle.java.testlibrary.ProcessTools;
-
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
 import java.util.ArrayList;
 import java.util.Arrays;
+import sun.hotspot.WhiteBox;
 
 public class TestCMSClassUnloadingEnabledHWM {
   private static long MetaspaceSize = 32 * 1024 * 1024;
@@ -47,15 +49,18 @@
       "-Xbootclasspath/a:.",
       "-XX:+UnlockDiagnosticVMOptions",
       "-XX:+WhiteBoxAPI",
+      "-Xmx128m",
+      "-XX:CMSMaxAbortablePrecleanTime=1",
+      "-XX:CMSWaitDuration=50",
       "-XX:MetaspaceSize=" + MetaspaceSize,
       "-Xmn" + YoungGenSize,
       "-XX:+UseConcMarkSweepGC",
       "-XX:" + (enableUnloading ? "+" : "-") + "CMSClassUnloadingEnabled",
       "-XX:+PrintHeapAtGC",
       "-XX:+PrintGCDetails",
-      "AllocateBeyondMetaspaceSize",
-      "" + MetaspaceSize,
-      "" + YoungGenSize);
+      "-XX:+PrintGCTimeStamps",
+      TestCMSClassUnloadingEnabledHWM.AllocateBeyondMetaspaceSize.class.getName(),
+      "" + MetaspaceSize);
     return new OutputAnalyzer(pb.start());
   }
 
@@ -87,5 +92,37 @@
     testWithCMSClassUnloading();
     testWithoutCMSClassUnloading();
   }
+
+  public static class AllocateBeyondMetaspaceSize {
+    public static void main(String [] args) throws Exception {
+      if (args.length != 1) {
+        throw new IllegalArgumentException("Usage: <MetaspaceSize>");
+      }
+
+      WhiteBox wb = WhiteBox.getWhiteBox();
+
+      // Allocate past the MetaspaceSize limit.
+      long metaspaceSize = Long.parseLong(args[0]);
+      long allocationBeyondMetaspaceSize  = metaspaceSize * 2;
+      long metaspace = wb.allocateMetaspace(null, allocationBeyondMetaspaceSize);
+
+      // Wait for at least one GC to occur. The caller will parse the log files produced.
+      GarbageCollectorMXBean cmsGCBean = getCMSGCBean();
+      while (cmsGCBean.getCollectionCount() == 0) {
+        Thread.sleep(100);
+      }
+
+      wb.freeMetaspace(null, metaspace, metaspace);
+    }
+
+    private static GarbageCollectorMXBean getCMSGCBean() {
+      for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) {
+        if (gcBean.getObjectName().toString().equals("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep")) {
+          return gcBean;
+        }
+      }
+      return null;
+    }
+  }
 }
 
diff --git a/hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java b/hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java
index f4c830a..7992114 100644
--- a/hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java
+++ b/hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java
@@ -26,7 +26,7 @@
  * @key gc
  * @bug 8049831
  * @library /testlibrary /testlibrary/whitebox
- * @build TestG1ClassUnloadingHWM AllocateBeyondMetaspaceSize
+ * @build TestG1ClassUnloadingHWM
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  * @run driver TestG1ClassUnloadingHWM
  * @summary Test that -XX:-ClassUnloadingWithConcurrentMark will trigger a Full GC when more than MetaspaceSize metadata is allocated.
@@ -34,9 +34,9 @@
 
 import com.oracle.java.testlibrary.OutputAnalyzer;
 import com.oracle.java.testlibrary.ProcessTools;
-
 import java.util.ArrayList;
 import java.util.Arrays;
+import sun.hotspot.WhiteBox;
 
 public class TestG1ClassUnloadingHWM {
   private static long MetaspaceSize = 32 * 1024 * 1024;
@@ -53,7 +53,7 @@
       "-XX:" + (enableUnloading ? "+" : "-") + "ClassUnloadingWithConcurrentMark",
       "-XX:+PrintHeapAtGC",
       "-XX:+PrintGCDetails",
-      "AllocateBeyondMetaspaceSize",
+      TestG1ClassUnloadingHWM.AllocateBeyondMetaspaceSize.class.getName(),
       "" + MetaspaceSize,
       "" + YoungGenSize);
     return new OutputAnalyzer(pb.start());
@@ -87,5 +87,36 @@
     testWithG1ClassUnloading();
     testWithoutG1ClassUnloading();
   }
+
+  public static class AllocateBeyondMetaspaceSize {
+    public static Object dummy;
+
+    public static void main(String [] args) throws Exception {
+      if (args.length != 2) {
+        throw new IllegalArgumentException("Usage: <MetaspaceSize> <YoungGenSize>");
+      }
+
+      WhiteBox wb = WhiteBox.getWhiteBox();
+
+      // Allocate past the MetaspaceSize limit
+      long metaspaceSize = Long.parseLong(args[0]);
+      long allocationBeyondMetaspaceSize  = metaspaceSize * 2;
+      long metaspace = wb.allocateMetaspace(null, allocationBeyondMetaspaceSize);
+
+      long youngGenSize = Long.parseLong(args[1]);
+      triggerYoungGCs(youngGenSize);
+
+      wb.freeMetaspace(null, metaspace, metaspace);
+    }
+
+    public static void triggerYoungGCs(long youngGenSize) {
+      long approxAllocSize = 32 * 1024;
+      long numAllocations  = 2 * youngGenSize / approxAllocSize;
+
+      for (long i = 0; i < numAllocations; i++) {
+        dummy = new byte[(int)approxAllocSize];
+      }
+    }
+  }
 }
 
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index 6ce4ddc..69e5cac 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -314,6 +314,25 @@
 dd09d8b9edefb5684941941e5d9b35c84ee066f3 jdk8u20-b24
 dd09d8b9edefb5684941941e5d9b35c84ee066f3 jdk8u20-b25
 938b9d502c2b0f9684151e1b1f47cf7052db1502 jdk8u20-b26
+65e5ee249ebc81c0ccfff23946a0a2a6d4becdcc jdk8u25-b00
+b29277565edfdece4e3928b135d4fd86ae141e4f jdk8u25-b01
+09df5bda467090041090873f71d418eebcadf516 jdk8u25-b02
+f3567e6bed22eaf89c3c7d64e0b1fa308707260f jdk8u25-b03
+a4d0f11cf08d5dae91c5e9ad387b1ff88388503d jdk8u25-b04
+0c4917cea678dc2a3745baca74016f0d6f169012 jdk8u25-b05
+e84d78dd9e0533eb11c26b69727c044898d19f60 jdk8u25-b06
+7aaaec31a0331ad091abedf81c928b47a982222d jdk8u25-b07
+e48a4594f19ad119bc27d89c53dd35d11ed6da7d jdk8u25-b08
+a09893b8f617912569196d7bd64a96c349796be0 jdk8u25-b09
+85de91b6e953c8c21ac5e6d9a5e284f86d759680 jdk8u25-b10
+5c1ac461fef7fe0f810bd9d6051db5a24247de1d jdk8u25-b11
+c078e904db0a7be650e4ba2d665277785e2216b0 jdk8u25-b12
+24184cfe0f8b0da0f349933ae7b5cc16455a52b8 jdk8u25-b13
+90f3b8b970a8bb3173083111248372afdc61652d jdk8u25-b14
+f5ac2e242bb95be0a3deddf37362178202086137 jdk8u25-b15
+df68b132a471ed1e825a79bd1d8acb47d2bcc04f jdk8u25-b16
+7a721e57b38ff6c1d34af0b86f6482540a815d90 jdk8u25-b17
+fddbc00bde281d7d437b052262e921ed51de8b9a jdk8u25-b18
 3a1bba8076da4e54882123e98e219eab1c31ccef jdk8u40-b00
 f219da378d0768ff042d77221e5d20676ecc16f0 jdk8u40-b01
 16ef2134c32a4e60b5a60105b371163aa5936278 jdk8u40-b02
@@ -323,3 +342,4 @@
 50a2adfa57fcbbe1587991d53f58d227070a24db jdk8u40-b06
 b2210de1587b16ca1d1d781b55e19bc70724c62b jdk8u40-b07
 641eb6543c7186d1c2c26eaf96803b1e6b411d9a jdk8u40-b08
+c45c0ee4160026207cef1850c215c2691d43a97d jdk8u40-b09
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java
index bc38185..e63c4a6 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java
@@ -679,7 +679,7 @@
          * documentation.
          */
         {ErrorMsg.COMPILE_USAGE_STR,
-        "SYNOPSIS\n   java com.sun.org.apache.xalan.internal.xsltc.cmdline.Compile [-o <output>]\n      [-d <directory>] [-j <jarfile>] [-p <package>]\n      [-n] [-x] [-u] [-v] [-h] { <stylesheet> | -i }\n\nOPTIONS\n   -o <output>    \u540D\u524D<output>\u3092\u751F\u6210\u6E08translet\u306B\n                  \u5272\u308A\u5F53\u3066\u308B\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001translet\u540D\u306F\n                  <stylesheet>\u540D\u306B\u7531\u6765\u3057\u307E\u3059\u3002\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\n                  \u8907\u6570\u306E\u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8\u3092\u30B3\u30F3\u30D1\u30A4\u30EB\u3059\u308B\u5834\u5408\u306F\u7121\u8996\u3055\u308C\u307E\u3059\u3002\n   -d <directory> translet\u306E\u5B9B\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u6307\u5B9A\u3059\u308B\n   -j <jarfile>   <jarfile>\u3067\u6307\u5B9A\u3055\u308C\u308B\u540D\u524D\u306Ejar\u30D5\u30A1\u30A4\u30EB\u306Btranslet\u30AF\u30E9\u30B9\u3092\n                  \u30D1\u30C3\u30B1\u30FC\u30B8\u3059\u308B\n   -p <package>   \u751F\u6210\u3055\u308C\u308B\u3059\u3079\u3066\u306Etranslet\u30AF\u30E9\u30B9\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\n                  \u63A5\u982D\u8F9E\u3092\u6307\u5B9A\u3059\u308B\u3002\n   -n             \u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u306E\u30A4\u30F3\u30E9\u30A4\u30F3\u5316\u3092\u6709\u52B9\u306B\u3059\u308B(\u5E73\u5747\u3057\u3066\u30C7\u30D5\u30A9\u30EB\u30C8\u52D5\u4F5C\u306E\u65B9\u304C\n                  \u512A\u308C\u3066\u3044\u307E\u3059)\u3002\n   -x             \u8FFD\u52A0\u306E\u30C7\u30D0\u30C3\u30B0\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u51FA\u529B\u3092\u30AA\u30F3\u306B\u3059\u308B\n   -u             <stylesheet>\u5F15\u6570\u3092URL\u3068\u3057\u3066\u89E3\u91C8\u3059\u308B\n   -i             \u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8\u3092stdin\u304B\u3089\u8AAD\u307F\u8FBC\u3080\u3053\u3068\u3092\u30B3\u30F3\u30D1\u30A4\u30E9\u306B\u5F37\u5236\u3059\u308B\n   -v             \u30B3\u30F3\u30D1\u30A4\u30E9\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3059\u308B\n   -h             \u3053\u306E\u4F7F\u7528\u65B9\u6CD5\u306E\u6587\u3092\u51FA\u529B\u3059\u308B\n"},
+        "\u5F62\u5F0F\n   java com.sun.org.apache.xalan.internal.xsltc.cmdline.Compile [-o <output>]\n      [-d <directory>] [-j <jarfile>] [-p <package>]\n      [-n] [-x] [-u] [-v] [-h] { <stylesheet> | -i }\n\nOPTIONS\n   -o <output>    \u540D\u524D<output>\u3092\u751F\u6210\u6E08translet\u306B\n                  \u5272\u308A\u5F53\u3066\u308B\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001translet\u540D\u306F\n                  <stylesheet>\u540D\u306B\u7531\u6765\u3057\u307E\u3059\u3002\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\n                  \u8907\u6570\u306E\u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8\u3092\u30B3\u30F3\u30D1\u30A4\u30EB\u3059\u308B\u5834\u5408\u306F\u7121\u8996\u3055\u308C\u307E\u3059\u3002\n   -d <directory> translet\u306E\u5B9B\u5148\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u6307\u5B9A\u3059\u308B\n   -j <jarfile>   <jarfile>\u3067\u6307\u5B9A\u3055\u308C\u308B\u540D\u524D\u306Ejar\u30D5\u30A1\u30A4\u30EB\u306Btranslet\u30AF\u30E9\u30B9\u3092\n                  \u30D1\u30C3\u30B1\u30FC\u30B8\u3059\u308B\n   -p <package>   \u751F\u6210\u3055\u308C\u308B\u3059\u3079\u3066\u306Etranslet\u30AF\u30E9\u30B9\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\n                  \u63A5\u982D\u8F9E\u3092\u6307\u5B9A\u3059\u308B\u3002\n   -n             \u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u306E\u30A4\u30F3\u30E9\u30A4\u30F3\u5316\u3092\u6709\u52B9\u306B\u3059\u308B(\u5E73\u5747\u3057\u3066\u30C7\u30D5\u30A9\u30EB\u30C8\u52D5\u4F5C\u306E\u65B9\u304C\n                  \u512A\u308C\u3066\u3044\u307E\u3059)\u3002\n   -x             \u8FFD\u52A0\u306E\u30C7\u30D0\u30C3\u30B0\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u51FA\u529B\u3092\u30AA\u30F3\u306B\u3059\u308B\n   -u             <stylesheet>\u5F15\u6570\u3092URL\u3068\u3057\u3066\u89E3\u91C8\u3059\u308B\n   -i             \u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8\u3092stdin\u304B\u3089\u8AAD\u307F\u8FBC\u3080\u3053\u3068\u3092\u30B3\u30F3\u30D1\u30A4\u30E9\u306B\u5F37\u5236\u3059\u308B\n   -v             \u30B3\u30F3\u30D1\u30A4\u30E9\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3059\u308B\n   -h             \u3053\u306E\u4F7F\u7528\u65B9\u6CD5\u306E\u6587\u3092\u51FA\u529B\u3059\u308B\n"},
 
         /*
          * Note to translators:  This message contains usage information for a
@@ -691,7 +691,7 @@
          * documentation.
          */
         {ErrorMsg.TRANSFORM_USAGE_STR,
-        "SYNOPSIS \n   java com.sun.org.apache.xalan.internal.xsltc.cmdline.Transform [-j <jarfile>]\n      [-x] [-n <iterations>] {-u <document_url> | <document>}\n      <class> [<param1>=<value1> ...]\n\n   translet <class>\u3092\u4F7F\u7528\u3057\u3066\u3001<document>\u3067\u6307\u5B9A\u3055\u308C\u308B\n   XML\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u5909\u63DB\u3059\u308B\u3002translet <class>\u306F\n   \u30E6\u30FC\u30B6\u30FC\u306ECLASSPATH\u5185\u304B\u3001\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u6307\u5B9A\u3055\u308C\u305F<jarfile>\u5185\u306B\u3042\u308A\u307E\u3059\u3002\nOPTIONS\n   -j <jarfile>    translet\u3092\u30ED\u30FC\u30C9\u3059\u308Bjarfile\u3092\u6307\u5B9A\u3059\u308B\n   -x              \u8FFD\u52A0\u306E\u30C7\u30D0\u30C3\u30B0\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u51FA\u529B\u3092\u30AA\u30F3\u306B\u3059\u308B\n   -n <iterations> \u5909\u63DB\u3092<iterations>\u56DE\u5B9F\u884C\u3057\u3001\n                   \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u60C5\u5831\u3092\u8868\u793A\u3059\u308B\n   -u <document_url> XML\u5165\u529B\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092URL\u3068\u3057\u3066\u6307\u5B9A\u3059\u308B\n"},
+        "\u5F62\u5F0F \n   java com.sun.org.apache.xalan.internal.xsltc.cmdline.Transform [-j <jarfile>]\n      [-x] [-n <iterations>] {-u <document_url> | <document>}\n      <class> [<param1>=<value1> ...]\n\n   translet <class>\u3092\u4F7F\u7528\u3057\u3066\u3001<document>\u3067\u6307\u5B9A\u3055\u308C\u308B\n   XML\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u5909\u63DB\u3059\u308B\u3002translet <class>\u306F\n   \u30E6\u30FC\u30B6\u30FC\u306ECLASSPATH\u5185\u304B\u3001\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u6307\u5B9A\u3055\u308C\u305F<jarfile>\u5185\u306B\u3042\u308A\u307E\u3059\u3002\nOPTIONS\n   -j <jarfile>    translet\u3092\u30ED\u30FC\u30C9\u3059\u308Bjarfile\u3092\u6307\u5B9A\u3059\u308B\n   -x              \u8FFD\u52A0\u306E\u30C7\u30D0\u30C3\u30B0\u30FB\u30E1\u30C3\u30BB\u30FC\u30B8\u51FA\u529B\u3092\u30AA\u30F3\u306B\u3059\u308B\n   -n <iterations> \u5909\u63DB\u3092<iterations>\u56DE\u5B9F\u884C\u3057\u3001\n                   \u30D7\u30ED\u30D5\u30A1\u30A4\u30EA\u30F3\u30B0\u60C5\u5831\u3092\u8868\u793A\u3059\u308B\n   -u <document_url> XML\u5165\u529B\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092URL\u3068\u3057\u3066\u6307\u5B9A\u3059\u308B\n"},
 
 
 
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
index aa0bfa3..d7080ca 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
@@ -612,9 +612,9 @@
         //fElementStack2.clear();
         //fReplaceEntityReferences = true;
         //fSupportExternalEntities = true;
-        Boolean bo = (Boolean)propertyManager.getProperty(XMLInputFactoryImpl.IS_REPLACING_ENTITY_REFERENCES);
+        Boolean bo = (Boolean)propertyManager.getProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES);
         fReplaceEntityReferences = bo.booleanValue();
-        bo = (Boolean)propertyManager.getProperty(XMLInputFactoryImpl.IS_SUPPORTING_EXTERNAL_ENTITIES);
+        bo = (Boolean)propertyManager.getProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES);
         fSupportExternalEntities = bo.booleanValue();
         Boolean cdata = (Boolean)propertyManager.getProperty(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.STAX_REPORT_CDATA_EVENT) ;
         if(cdata != null)
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
index 09a8260..d0f036f 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
@@ -53,6 +53,7 @@
 import java.util.Map;
 import java.util.Stack;
 import javax.xml.XMLConstants;
+import javax.xml.stream.XMLInputFactory;
 
 
 /**
@@ -305,6 +306,11 @@
     /** Property Manager. This is used from Stax */
     protected PropertyManager fPropertyManager ;
 
+    /** StAX properties */
+    boolean fSupportDTD = true;
+    boolean fReplaceEntityReferences = true;
+    boolean fSupportExternalEntities = true;
+
     /** used to restrict external access */
     protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT;
 
@@ -1136,7 +1142,8 @@
             boolean parameter = entityName.startsWith("%");
             boolean general = !parameter;
             if (unparsed || (general && !fExternalGeneralEntities) ||
-                    (parameter && !fExternalParameterEntities)) {
+                    (parameter && !fExternalParameterEntities) ||
+                    !fSupportDTD || !fSupportExternalEntities) {
 
                 if (fEntityHandler != null) {
                     fResourceIdentifier.clear();
@@ -1431,6 +1438,10 @@
             fStaxEntityResolver = null;
         }
 
+        fSupportDTD = ((Boolean)propertyManager.getProperty(XMLInputFactory.SUPPORT_DTD)).booleanValue();
+        fReplaceEntityReferences = ((Boolean)propertyManager.getProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES)).booleanValue();
+        fSupportExternalEntities = ((Boolean)propertyManager.getProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES)).booleanValue();
+
         // Zephyr feature ignore-external-dtd is the opposite of Xerces' load-external-dtd
         fLoadExternalDTD = !((Boolean)propertyManager.getProperty(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD)).booleanValue();
 
@@ -1502,6 +1513,11 @@
         fSecurityManager = (XMLSecurityManager)componentManager.getProperty(SECURITY_MANAGER, null);
         entityExpansionIndex = fSecurityManager.getIndex(Constants.JDK_ENTITY_EXPANSION_LIMIT);
 
+        //StAX Property
+        fSupportDTD = true;
+        fReplaceEntityReferences = true;
+        fSupportExternalEntities = true;
+
         // JAXP 1.5 feature
         XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER, null);
         if (spm == null) {
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/DOMMessages_de.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/DOMMessages_de.properties
index 7dbeeaa..7108439 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/DOMMessages_de.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/DOMMessages_de.properties
@@ -26,7 +26,7 @@
 SYNTAX_ERR = Ung\u00FCltige Zeichenfolge angegeben. 
 VALIDATION_ERR = Aufruf einer Methode wie insertBefore oder removeChild w\u00FCrde die Dokumentgrammatik des Knotens ung\u00FCltig machen.
 WRONG_DOCUMENT_ERR = Ein Knoten wird in einem anderen Dokument verwendet als dem, von dem er erstellt wurde.
-TYPE_MISMATCH_ERR = Der Wertetyp f\u00FCr diesen Parameternamen ist nicht mit dem erwarteten Wertetyp kompatibel. 
+TYPE_MISMATCH_ERR = Der Werttyp f\u00FCr diesen Parameternamen ist nicht mit dem erwarteten Werttyp kompatibel. 
  
 #error messages or exceptions
 FEATURE_NOT_SUPPORTED = Parameter {0} wird erkannt, aber der angeforderte Wert kann nicht festgelegt werden.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_de.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_de.properties
index f03fed9..2a3f7d7 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_de.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XIncludeMessages_de.properties
@@ -27,7 +27,7 @@
 UnexpandedEntityReferenceIllegal = Der Ersatz eines "include"-Elements, das als Dokumentelement im Quell-Infoset der obersten Ebene angezeigt wird, darf keine nicht erweiterten Entit\u00E4tsreferenzen enthalten.
 HrefFragmentIdentifierIllegal = Fragment-IDs d\u00FCrfen nicht verwendet werden. Der "href"-Attributwert "{0}" ist nicht zul\u00E4ssig.
 HrefSyntacticallyInvalid = "href"-Attributwert "{0}" hat eine ung\u00FCltige Syntax. Nach Anwenden der Escape-Regeln ist der Wert kein syntaktisch korrekter URI oder IRI.
-XPointerStreamability = Es wurde ein xpointer angegeben, der auf eine Stelle im Quell-Infoset verweist. Auf diese Stelle kann aufgrund des Streaming-Charakters des Prozessors nicht zugegriffen werden.
+XPointerStreamability = Es wurde ein xpointer angegeben, der auf eine Stelle im Quell-Infoset verweist. Auf diese Stelle kann aufgrund des Streamingcharakters des Prozessors nicht zugegriffen werden.
 
 XPointerResolutionUnsuccessful = XPointer-Aufl\u00F6sung nicht erfolgreich.
 
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/res/XMLErrorResources_ja.java b/jaxp/src/com/sun/org/apache/xml/internal/res/XMLErrorResources_ja.java
index 7264524..dfa387b 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/res/XMLErrorResources_ja.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/res/XMLErrorResources_ja.java
@@ -227,7 +227,7 @@
       "\u4E0D\u660E\u306A\u8EF8\u30C8\u30E9\u30D0\u30FC\u30B9\u30FB\u30BF\u30A4\u30D7\u3067\u3059: {0}"},
 
     { ER_AXIS_NOT_SUPPORTED,
-      "\u8EF8traverser\u6A5F\u80FD\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093: {0}"},
+      "\u8EF8\u30C8\u30E9\u30D0\u30FC\u30B5\u6A5F\u80FD\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093: {0}"},
 
     { ER_NO_DTMIDS_AVAIL,
       "DTM ID\u306F\u3053\u308C\u4EE5\u4E0A\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093"},
@@ -326,7 +326,7 @@
       "XMLReader\u306FstartParse\u30EA\u30AF\u30A8\u30B9\u30C8\u3088\u308A\u524D\u306B\u3067\u304D\u307E\u305B\u3093"},
 
     { ER_AXIS_TRAVERSER_NOT_SUPPORTED,
-      "\u8EF8traverser\u6A5F\u80FD\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093: {0}"},
+      "\u8EF8\u30C8\u30E9\u30D0\u30FC\u30B5\u6A5F\u80FD\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093: {0}"},
 
     { ER_ERRORHANDLER_CREATED_WITH_NULL_PRINTWRITER,
       "null PrintWriter\u306B\u3088\u3063\u3066ListingErrorHandler\u304C\u4F5C\u6210\u3055\u308C\u307E\u3057\u305F\u3002"},
diff --git a/jaxp/src/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_de.java b/jaxp/src/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_de.java
index 69991d4..b837e6f 100644
--- a/jaxp/src/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_de.java
+++ b/jaxp/src/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_de.java
@@ -3,7 +3,7 @@
  * DO NOT REMOVE OR ALTER!
  */
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2005 The Apache Software Foundation.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -878,7 +878,7 @@
   { "optionIN", "   [-in inputXMLURL]"},
   { "optionSelect", "   [-select xpath expression]"},
   { "optionMatch", "   [-match match pattern (f\u00FCr Vergleichsdiagnose)]"},
-  { "optionAnyExpr", "Oder nur ein XPath-Ausdruck f\u00FChrt einen Diagnose-Dump aus"},
+  { "optionAnyExpr", "Oder nur ein XPath-Ausdruck f\u00FChrt einen Diagnosedump aus"},
   { "noParsermsg1", "XSL-Prozess war nicht erfolgreich."},
   { "noParsermsg2", "** Parser konnte nicht gefunden werden **"},
   { "noParsermsg3", "Pr\u00FCfen Sie den Classpath."},
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index b8dbe55..91c972d 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -312,6 +312,25 @@
 1277c0d492fd9253f1ea2730eb160953397bd939 jdk8u20-b24
 1277c0d492fd9253f1ea2730eb160953397bd939 jdk8u20-b25
 7025a2c10ea4116ce8f31bb1e305f732aa1025f0 jdk8u20-b26
+efc85d318f4697f40bdd1f3757677be97f1758d9 jdk8u25-b00
+a76779e1b0376650dfc29a1f3b14760f05e0fc6d jdk8u25-b01
+3d31955043b9f1807c9d695c7b5d604d11c132cf jdk8u25-b02
+c67cb85b249c69a96d7ac72734c35bc18644befe jdk8u25-b03
+81129354f0e821f3d41dbcf8a68ce82f9d776127 jdk8u25-b04
+5f78130b0a64df9568a827f9ea589fdc3a7c080c jdk8u25-b05
+433da54f73257545d95edbc356fdb0e37a9d95eb jdk8u25-b06
+cccfc3f8dec888c8fe86c212a51af2fba1e11aef jdk8u25-b07
+c758be4c3cac65a2744bf4e7ed9bdabb85234de2 jdk8u25-b08
+73423d29fe362e843cdccad510e2e44e2899bc9e jdk8u25-b09
+391b45e0081afcf3db709878916063a63dca7b05 jdk8u25-b10
+57cd66833abf44f499faaaed2c16bdf94b258ca9 jdk8u25-b11
+56b97127afa66fa01eec0fcf467a77cd2e445b4f jdk8u25-b12
+0ebb9d8c3dd49559b716f02825924801be55b3e7 jdk8u25-b13
+392a9579cc95d27806c1dde16eee776524a49761 jdk8u25-b14
+d3a96bbb88521188a3af1a34dd9523f13afa521d jdk8u25-b15
+4570a7d00aa9bd3df028f52d6f9d8c434163b689 jdk8u25-b16
+d47a47f961ee423ce03623098f62d79254c6f328 jdk8u25-b17
+cb0ad90bfe3c497c7236c5480447c4bde110934f jdk8u25-b18
 31d43d250c836c13fcc87025837783788c5cd0de jdk8u40-b00
 262fb5353ffa661f88b4a9cf2581fcad8c2a43f7 jdk8u40-b01
 8043f77ef8a4ded9505269a356c4e2f4f9604cd9 jdk8u40-b02
@@ -321,3 +340,4 @@
 52ae3094de1ec6974ff0250b8cabc13f110290d1 jdk8u40-b06
 3857b4b27e22cfd3f970cd77ed1a41d44444202f jdk8u40-b07
 304ea93428f83d55a558a76ebbcc318d07c03fbe jdk8u40-b08
+26529be4ae77192acf99c867f0c2a75a7ad71f28 jdk8u40-b09
diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/ContentHandlerAdaptor.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/ContentHandlerAdaptor.java
index f399c81..7b7081d 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/ContentHandlerAdaptor.java
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/ContentHandlerAdaptor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -25,10 +25,6 @@
 
 package com.sun.xml.internal.bind.v2.runtime;
 
-import java.io.IOException;
-
-import javax.xml.stream.XMLStreamException;
-
 import com.sun.istack.internal.FinalArrayList;
 import com.sun.istack.internal.SAXException2;
 
@@ -36,6 +32,9 @@
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;
 
+import javax.xml.stream.XMLStreamException;
+import java.io.IOException;
+
 /**
  * Receives SAX2 events and send the equivalent events to
  * {@link XMLSerializer}
@@ -70,14 +69,14 @@
     private boolean containsPrefixMapping(String prefix, String uri) {
         for( int i=0; i<prefixMap.size(); i+=2 ) {
             if(prefixMap.get(i).equals(prefix)
-            && prefixMap.get(i+1).equals(uri))
+                    && prefixMap.get(i+1).equals(uri))
                 return true;
         }
         return false;
     }
 
     public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
-        throws SAXException {
+            throws SAXException {
         try {
             flushText();
 
@@ -92,13 +91,13 @@
                 serializer.startElement(namespaceURI,localName, p,null);
 
             // declare namespace events
-            for( int i=0; i<prefixMap.size(); i+=2 ) {
+            for (int i = 0; i < prefixMap.size(); i += 2) {
                 // forcibly set this binding, instead of using declareNsUri.
                 // this guarantees that namespaces used in DOM will show up
                 // as-is in the marshalled output (instead of reassigned to something else,
                 // which may happen if you'd use declareNsUri.)
                 serializer.getNamespaceContext().force(
-                    prefixMap.get(i+1), prefixMap.get(i) );
+                        prefixMap.get(i + 1), prefixMap.get(i));
             }
             // make sure namespaces needed by attributes are bound
             for( int i=0; i<len; i++ ) {
@@ -108,7 +107,7 @@
                 String prefix = getPrefix(qname);
 
                 serializer.getNamespaceContext().declareNamespace(
-                    atts.getURI(i), prefix, true );
+                        atts.getURI(i), prefix, true );
             }
 
             serializer.endNamespaceDecls(null);
@@ -128,9 +127,10 @@
         }
     }
 
+    // make sure namespaces needed by attributes are bound
     private String getPrefix(String qname) {
         int idx = qname.indexOf(':');
-        String prefix = (idx==-1)?qname:qname.substring(0,idx);
+        String prefix = (idx == -1) ? "" : qname.substring(0, idx);
         return prefix;
     }
 
diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java
index 3b6af48..a3b51b0 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/unmarshaller/StAXStreamConnector.java
@@ -70,7 +70,7 @@
         // Quick hack until SJSXP fixes 6270116
         boolean isZephyr = readerClass.getName().equals("com.sun.xml.internal.stream.XMLReaderImpl");
         if (getBoolProp(reader,"org.codehaus.stax2.internNames") &&
-            getBoolProp(reader,"org.codehaus.stax2.internNsUris"))
+                getBoolProp(reader,"org.codehaus.stax2.internNsUris"))
             ; // no need for interning
         else
         if (isZephyr)
@@ -219,8 +219,8 @@
         int nsCount = staxStreamReader.getNamespaceCount();
         for (int i = 0; i < nsCount; i++) {
             visitor.startPrefixMapping(
-                fixNull(staxStreamReader.getNamespacePrefix(i)),
-                fixNull(staxStreamReader.getNamespaceURI(i)));
+                    fixNull(staxStreamReader.getNamespacePrefix(i)),
+                    fixNull(staxStreamReader.getNamespaceURI(i)));
         }
 
         // fire startElement
@@ -310,13 +310,13 @@
     protected void handleCharacters() throws XMLStreamException, SAXException {
         if( predictor.expectText() )
             buffer.append(
-                staxStreamReader.getTextCharacters(),
-                staxStreamReader.getTextStart(),
-                staxStreamReader.getTextLength() );
+                    staxStreamReader.getTextCharacters(),
+                    staxStreamReader.getTextStart(),
+                    staxStreamReader.getTextLength() );
     }
 
     private void processText( boolean ignorable ) throws SAXException {
-        if( predictor.expectText() && (!ignorable || !WhiteSpaceProcessor.isWhiteSpace(buffer))) {
+        if( predictor.expectText() && (!ignorable || !WhiteSpaceProcessor.isWhiteSpace(buffer) || context.getCurrentState().isMixed())) {
             if(textReported) {
                 textReported = false;
             } else {
diff --git a/jdk/.hgtags b/jdk/.hgtags
index 1785a44..e46f300 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -312,6 +312,28 @@
 dfb9f24d56b51e5a2ca26e77fc69a2464d51a4d3 jdk8u20-b24
 dfb9f24d56b51e5a2ca26e77fc69a2464d51a4d3 jdk8u20-b25
 dd229c5f57bff4e75a70908294a13072b9a48385 jdk8u20-b26
+abca9f6f1a10e9f91b2538bbe7870f54f550d986 jdk8u25-b00
+7d0627679c9fdeaaaa9fe15c7cc11af0763621ec jdk8u25-b01
+b0277ec994b751ebb761814675352506cd56bcd6 jdk8u25-b02
+5606d84f30bab5ed4bc5776572edd469fb013e13 jdk8u25-b03
+40630cd55da8a2db7980249dc31af285965cb5e9 jdk8u25-b04
+75b48287a1b3fc5757ac473f72c8918c7f345ffc jdk8u25-b05
+5b80b4b22b4ca0b630c7f1cec3605da7694168e2 jdk8u25-b06
+0e0a35b0bf0ff5852026c50038d5c2ecb26c075c jdk8u25-b07
+d7d221f56fd17b96bab4440448641a844f9e92cd jdk8u25-b08
+0c6cf43c5bcf0917d07a1bc94adb7a091f18f32c jdk8u25-b09
+1317d94e95861a47fee8258903b652af70a3493c jdk8u25-b10
+2104dfd9a4c2b519cdca019aec938db539bf4f3f jdk8u25-b11
+eaaa9a04b9fdcfa4a830b811ed209eb2c45a4a6b jdk8u25-b12
+c3a855402b923d3ba819b05292a971953fc8ed0b jdk8u25-b13
+2a6df63ca0f0f59bb730638b05c72d77a23f93c8 jdk8u25-b14
+412d9ade90401d098f3662bd688ab393008423bd jdk8u25-b15
+f07bc5dab84c67f5d1dccbab318ee1c5485c852d jdk8u25-b16
+0000000000000000000000000000000000000000 jdk8u25-b16
+0000000000000000000000000000000000000000 jdk8u25-b16
+d067890f970f3a712f870f6311d20f3359b6eaf0 jdk8u25-b16
+67b22a82345bfa1ae1492679bdf3c4d54f4eacde jdk8u25-b17
+a4e88eaf15ea0569f3275a807a976fe0e04a086c jdk8u25-b18
 e6ed015afbbf3459ba3297e270b4f3170e989c80 jdk8u40-b00
 6e223d48080ef40f4ec11ecbcd19b4a20813b9eb jdk8u40-b01
 4797cd0713b44b009525f1276d571ade7e24f3f5 jdk8u40-b02
@@ -321,3 +343,4 @@
 25788892a6723c0742a24050cc25ab103d9804de jdk8u40-b06
 07f0e22b5c238dd7b89fedbed35f02ac6b392c96 jdk8u40-b07
 0f0d70abca09b4ddb0981204ad5a427d4ce935e9 jdk8u40-b08
+064adeb65ce82f9ff3cc7898e59d19eb64743c63 jdk8u40-b09
diff --git a/jdk/make/data/jdwp/jdwp.spec b/jdk/make/data/jdwp/jdwp.spec
index 7ddbaf4..aadede2 100644
--- a/jdk/make/data/jdwp/jdwp.spec
+++ b/jdk/make/data/jdwp/jdwp.spec
@@ -1147,7 +1147,8 @@
         (ErrorSet
             (Error INVALID_CLASS     "clazz is not the ID of a class.")
             (Error INVALID_OBJECT    "clazz is not a known ID.")
-            (Error INVALID_METHODID  "methodID is not the ID of a method.")
+            (Error INVALID_METHODID  "methodID is not the ID of a static method in "
+                                     "this class type or one of its superclasses.")
             (Error INVALID_THREAD)
             (Error THREAD_NOT_SUSPENDED)
             (Error VM_DEAD)
@@ -1250,6 +1251,83 @@
     )
 )
 (CommandSet InterfaceType=5
+    (Command InvokeMethod=1
+        "Invokes a static method. "
+        "The method must not be a static initializer. "
+        "The method must be a member of the interface type. "
+        "<p>Since JDWP version 1.8 "
+        "<p>"
+        "The method invocation will occur in the specified thread. "
+        "Method invocation can occur only if the specified thread "
+        "has been suspended by an event. "
+        "Method invocation is not supported "
+        "when the target VM has been suspended by the front-end. "
+        "<p>"
+        "The specified method is invoked with the arguments in the specified "
+        "argument list. "
+        "The method invocation is synchronous; the reply packet is not "
+        "sent until the invoked method returns in the target VM. "
+        "The return value (possibly the void value) is "
+        "included in the reply packet. "
+        "If the invoked method throws an exception, the "
+        "exception object ID is set in the reply packet; otherwise, the "
+        "exception object ID is null. "
+        "<p>"
+        "For primitive arguments, the argument value's type must match the "
+        "argument's type exactly. For object arguments, there must exist a "
+        "widening reference conversion from the argument value's type to the "
+        "argument's type and the argument's type must be loaded. "
+        "<p>"
+        "By default, all threads in the target VM are resumed while "
+        "the method is being invoked if they were previously "
+        "suspended by an event or by a command. "
+        "This is done to prevent the deadlocks "
+        "that will occur if any of the threads own monitors "
+        "that will be needed by the invoked method. It is possible that "
+        "breakpoints or other events might occur during the invocation. "
+        "Note, however, that this implicit resume acts exactly like "
+        "the ThreadReference resume command, so if the thread's suspend "
+        "count is greater than 1, it will remain in a suspended state "
+        "during the invocation. By default, when the invocation completes, "
+        "all threads in the target VM are suspended, regardless their state "
+        "before the invocation. "
+        "<p>"
+        "The resumption of other threads during the invoke can be prevented "
+        "by specifying the INVOKE_SINGLE_THREADED "
+        "bit flag in the <code>options</code> field; however, "
+        "there is no protection against or recovery from the deadlocks "
+        "described above, so this option should be used with great caution. "
+        "Only the specified thread will be resumed (as described for all "
+        "threads above). Upon completion of a single threaded invoke, the invoking thread "
+        "will be suspended once again. Note that any threads started during "
+        "the single threaded invocation will not be suspended when the "
+        "invocation completes. "
+        "<p>"
+        "If the target VM is disconnected during the invoke (for example, through "
+        "the VirtualMachine dispose command) the method invocation continues. "
+        (Out
+            (interfaceType clazz "The interface type ID.")
+            (threadObject thread "The thread in which to invoke.")
+            (method methodID "The method to invoke.")
+            (Repeat arguments
+                (value arg "The argument value.")
+            )
+            (int options "Invocation <a href=\"#JDWP_InvokeOptions\">options</a>")
+        )
+        (Reply
+            (value returnValue "The returned value.")
+            (tagged-object exception "The thrown exception.")
+        )
+        (ErrorSet
+            (Error INVALID_CLASS     "clazz is not the ID of an interface.")
+            (Error INVALID_OBJECT    "clazz is not a known ID.")
+            (Error INVALID_METHODID  "methodID is not the ID of a static method in this "
+                                     "interface type or is the ID of a static initializer.")
+            (Error INVALID_THREAD)
+            (Error THREAD_NOT_SUSPENDED)
+            (Error VM_DEAD)
+        )
+    )
 )
 (CommandSet Method=6
     (Command LineTable=1
@@ -1543,7 +1621,7 @@
         "<p>"
         "By default, all threads in the target VM are resumed while "
         "the method is being invoked if they were previously "
-        "suspended by an event or by command. "
+        "suspended by an event or by a command. "
         "This is done to prevent the deadlocks "
         "that will occur if any of the threads own monitors "
         "that will be needed by the invoked method. It is possible that "
@@ -1586,7 +1664,9 @@
             (Error INVALID_OBJECT)
             (Error INVALID_CLASS     "clazz is not the ID of a reference "
                                      "type.")
-            (Error INVALID_METHODID  "methodID is not the ID of a method.")
+            (Error INVALID_METHODID  "methodID is not the ID of an instance method "
+                                     "in this object's type or one of its superclasses, "
+                                     "superinterfaces, or implemented interfaces.")
             (Error INVALID_THREAD)
             (Error THREAD_NOT_SUSPENDED)
             (Error VM_DEAD)
diff --git a/jdk/make/lib/CoreLibraries.gmk b/jdk/make/lib/CoreLibraries.gmk
index 0a27734..a36bf90 100644
--- a/jdk/make/lib/CoreLibraries.gmk
+++ b/jdk/make/lib/CoreLibraries.gmk
@@ -264,7 +264,7 @@
         $(call SET_SHARED_LIBRARY_ORIGIN) \
         $(EXPORT_ZIP_FUNCS), \
     LDFLAGS_windows := -export:ZIP_Open -export:ZIP_Close -export:ZIP_FindEntry \
-        -export:ZIP_ReadEntry -export:ZIP_GetNextEntry jvm.lib \
+        -export:ZIP_ReadEntry -export:ZIP_GetNextEntry -export:ZIP_CRC32 jvm.lib \
         $(WIN_JAVA_LIB), \
     LDFLAGS_SUFFIX_linux := -ljvm -ljava $(LIBZ), \
     LDFLAGS_SUFFIX_solaris := -ljvm -ljava $(LIBZ) -lc, \
diff --git a/jdk/make/mapfiles/libnet/mapfile-vers b/jdk/make/mapfiles/libnet/mapfile-vers
index 1b6a148..9e07f44 100644
--- a/jdk/make/mapfiles/libnet/mapfile-vers
+++ b/jdk/make/mapfiles/libnet/mapfile-vers
@@ -28,6 +28,8 @@
 SUNWprivate_1.1 {
 	global:
 		JNI_OnLoad;
+		Java_java_net_AbstractPlainDatagramSocketImpl_init;
+		Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable;
 		Java_java_net_PlainSocketImpl_socketListen;
 		Java_java_net_PlainDatagramSocketImpl_getTTL;
 		Java_java_net_PlainDatagramSocketImpl_init;
diff --git a/jdk/src/share/back/InterfaceTypeImpl.c b/jdk/src/share/back/InterfaceTypeImpl.c
new file mode 100644
index 0000000..f25d353
--- /dev/null
+++ b/jdk/src/share/back/InterfaceTypeImpl.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1998, 2005, 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.
+ */
+
+#include "util.h"
+#include "InterfaceTypeImpl.h"
+#include "inStream.h"
+#include "outStream.h"
+
+static jboolean
+invokeStatic(PacketInputStream *in, PacketOutputStream *out)
+{
+    return sharedInvoke(in, out);
+}
+
+void *InterfaceType_Cmds[] = { (void *)0x1
+    , (void *)invokeStatic
+};
diff --git a/jdk/src/share/back/InterfaceTypeImpl.h b/jdk/src/share/back/InterfaceTypeImpl.h
new file mode 100644
index 0000000..ff29000
--- /dev/null
+++ b/jdk/src/share/back/InterfaceTypeImpl.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 1998, 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.
+ */
+extern void *InterfaceType_Cmds[];
diff --git a/jdk/src/share/back/VirtualMachineImpl.c b/jdk/src/share/back/VirtualMachineImpl.c
index 34c4a17..e856392 100644
--- a/jdk/src/share/back/VirtualMachineImpl.c
+++ b/jdk/src/share/back/VirtualMachineImpl.c
@@ -36,7 +36,7 @@
 
 static char *versionName = "Java Debug Wire Protocol (Reference Implementation)";
 static int majorVersion = 1;  /* JDWP major version */
-static int minorVersion = 6;  /* JDWP minor version */
+static int minorVersion = 8;  /* JDWP minor version */
 
 static jboolean
 version(PacketInputStream *in, PacketOutputStream *out)
diff --git a/jdk/src/share/back/debugDispatch.c b/jdk/src/share/back/debugDispatch.c
index 1b1c782..e9e8c0e 100644
--- a/jdk/src/share/back/debugDispatch.c
+++ b/jdk/src/share/back/debugDispatch.c
@@ -29,6 +29,7 @@
 #include "VirtualMachineImpl.h"
 #include "ReferenceTypeImpl.h"
 #include "ClassTypeImpl.h"
+#include "InterfaceTypeImpl.h"
 #include "ArrayTypeImpl.h"
 #include "FieldImpl.h"
 #include "MethodImpl.h"
@@ -67,6 +68,7 @@
     l1Array[JDWP_COMMAND_SET(VirtualMachine)] = (void *)VirtualMachine_Cmds;
     l1Array[JDWP_COMMAND_SET(ReferenceType)] = (void *)ReferenceType_Cmds;
     l1Array[JDWP_COMMAND_SET(ClassType)] = (void *)ClassType_Cmds;
+    l1Array[JDWP_COMMAND_SET(InterfaceType)] = (void *)InterfaceType_Cmds;
     l1Array[JDWP_COMMAND_SET(ArrayType)] = (void *)ArrayType_Cmds;
 
     l1Array[JDWP_COMMAND_SET(Field)] = (void *)Field_Cmds;
diff --git a/jdk/src/share/back/util.c b/jdk/src/share/back/util.c
index a043201..84f9b6e 100644
--- a/jdk/src/share/back/util.c
+++ b/jdk/src/share/back/util.c
@@ -591,6 +591,8 @@
         invokeType = INVOKE_CONSTRUCTOR;
     } else if (inStream_command(in) == JDWP_COMMAND(ClassType, InvokeMethod)) {
         invokeType = INVOKE_STATIC;
+    } else if (inStream_command(in) == JDWP_COMMAND(InterfaceType, InvokeMethod)) {
+        invokeType = INVOKE_STATIC;
     } else if (inStream_command(in) == JDWP_COMMAND(ObjectReference, InvokeMethod)) {
         invokeType = INVOKE_INSTANCE;
     } else {
diff --git a/jdk/src/share/classes/com/sun/jarsigner/ContentSigner.java b/jdk/src/share/classes/com/sun/jarsigner/ContentSigner.java
index 1a29bf7..0446ab4 100644
--- a/jdk/src/share/classes/com/sun/jarsigner/ContentSigner.java
+++ b/jdk/src/share/classes/com/sun/jarsigner/ContentSigner.java
@@ -37,6 +37,7 @@
  * @author Vincent Ryan
  */
 
+@jdk.Exported
 public abstract class ContentSigner {
 
     /**
diff --git a/jdk/src/share/classes/com/sun/jarsigner/package-info.java b/jdk/src/share/classes/com/sun/jarsigner/package-info.java
new file mode 100644
index 0000000..554d4c7
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/jarsigner/package-info.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+/**
+ * This package comprises the interfaces and classes used to define the
+ * signing mechanism used by the <tt>jarsigner</tt> tool.
+ * <p>
+ * Clients may override the default signing mechanism of the <tt>jarsigner</tt>
+ * tool by supplying an alternative implementation of
+ * {@link com.sun.jarsigner.ContentSigner}.
+ */
+
+@jdk.Exported
+package com.sun.jarsigner;
diff --git a/jdk/src/share/classes/com/sun/jarsigner/package.html b/jdk/src/share/classes/com/sun/jarsigner/package.html
deleted file mode 100644
index b00d655..0000000
--- a/jdk/src/share/classes/com/sun/jarsigner/package.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<html>
-<!--
- 
-Copyright (c) 2003, 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.
--->
-  <head>
-    <title>Jarsigner Signing Mechanism Package</title>
-  </head>   
-  <body>
-This package comprises the interfaces and classes used to define the
-signing mechanism used by the <tt>jarsigner</tt> tool.
-<p>
-Clients may override the default signing mechanism of the <tt>jarsigner</tt>
-tool by supplying an alternative implementation of 
-{@link com.sun.jarsigner.ContentSigner}.
-  </body>
-</html>
diff --git a/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java
index f22c34a..022b2be 100644
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource_ja.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -84,7 +84,7 @@
                 "  -V\u3001--version                   \u30D7\u30ED\u30B0\u30E9\u30E0\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u51FA\u529B\u3057\u307E\u3059",
                 "  -J{X}                           \u30AA\u30D7\u30B7\u30E7\u30F3X\u3092\u57FA\u790E\u3068\u306A\u308BJava VM\u306B\u6E21\u3057\u307E\u3059",
                 "",
-                "\u6CE8\u610F:",
+                "\u6CE8:",
                 "  -P\u3001-C\u3001-F\u3001-M\u304A\u3088\u3073-D\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u7D2F\u7A4D\u3055\u308C\u307E\u3059\u3002",
                 "  \u5C5E\u6027\u5B9A\u7FA9\u306E\u4F8B:  -C SourceFile=RUH .",
                 "  Config.\u30D5\u30A1\u30A4\u30EB\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u306F\u3001Pack200 API\u306B\u3088\u3063\u3066\u5B9A\u7FA9\u3055\u308C\u307E\u3059\u3002",
diff --git a/jdk/src/share/classes/com/sun/jdi/ClassType.java b/jdk/src/share/classes/com/sun/jdi/ClassType.java
index 919f3ab..296f2e7 100644
--- a/jdk/src/share/classes/com/sun/jdi/ClassType.java
+++ b/jdk/src/share/classes/com/sun/jdi/ClassType.java
@@ -103,7 +103,7 @@
      * <p>
      * Object values must be assignment compatible with the field type
      * (This implies that the field type must be loaded through the
-     * enclosing class's class loader). Primitive values must be
+     * enclosing class' class loader). Primitive values must be
      * either assignment compatible with the field type or must be
      * convertible to the field type without loss of information.
      * See JLS section 5.2 for more information on assignment
@@ -153,7 +153,7 @@
      * <p>
      * Object arguments must be assignment compatible with the argument type
      * (This implies that the argument type must be loaded through the
-     * enclosing class's class loader). Primitive arguments must be
+     * enclosing class' class loader). Primitive arguments must be
      * either assignment compatible with the argument type or must be
      * convertible to the argument type without loss of information.
      * If the method being called accepts a variable number of arguments,
@@ -216,7 +216,7 @@
      * @return a {@link Value} mirror of the invoked method's return value.
      * @throws java.lang.IllegalArgumentException if the method is not
      * a member of this class or a superclass, if the size of the argument list
-     * does not match the number of declared arguemnts for the method, or
+     * does not match the number of declared arguments for the method, or
      * if the method is an initializer, constructor or static intializer.
      * @throws {@link InvalidTypeException} if any argument in the
      * argument list is not assignable to the corresponding method argument
@@ -230,7 +230,7 @@
      * @throws InvalidTypeException If the arguments do not meet this requirement --
      *         Object arguments must be assignment compatible with the argument
      *         type.  This implies that the argument type must be
-     *         loaded through the enclosing class's class loader.
+     *         loaded through the enclosing class' class loader.
      *         Primitive arguments must be either assignment compatible with the
      *         argument type or must be convertible to the argument type without loss
      *         of information. See JLS section 5.2 for more information on assignment
@@ -267,7 +267,7 @@
      * <p>
      * Object arguments must be assignment compatible with the argument type
      * (This implies that the argument type must be loaded through the
-     * enclosing class's class loader). Primitive arguments must be
+     * enclosing class' class loader). Primitive arguments must be
      * either assignment compatible with the argument type or must be
      * convertible to the argument type without loss of information.
      * If the method being called accepts a variable number of arguments,
@@ -335,7 +335,7 @@
      * @throws InvalidTypeException If the arguments do not meet this requirement --
      *         Object arguments must be assignment compatible with the argument
      *         type.  This implies that the argument type must be
-     *         loaded through the enclosing class's class loader.
+     *         loaded through the enclosing class' class loader.
      *         Primitive arguments must be either assignment compatible with the
      *         argument type or must be convertible to the argument type without loss
      *         of information. See JLS section 5.2 for more information on assignment
diff --git a/jdk/src/share/classes/com/sun/jdi/InterfaceType.java b/jdk/src/share/classes/com/sun/jdi/InterfaceType.java
index 3b2790a..9436e48 100644
--- a/jdk/src/share/classes/com/sun/jdi/InterfaceType.java
+++ b/jdk/src/share/classes/com/sun/jdi/InterfaceType.java
@@ -79,4 +79,123 @@
      * If none exist, returns a zero length List.
      */
     List<ClassType> implementors();
+
+    /**
+     * Invokes the specified static {@link Method} in the
+     * target VM. The
+     * specified method must be defined in this interface.
+     * The method must be a static method
+     * but not a static initializer.
+     * <p>
+     * The method invocation will occur in the specified thread.
+     * Method invocation can occur only if the specified thread
+     * has been suspended by an event which occurred in that thread.
+     * Method invocation is not supported
+     * when the target VM has been suspended through
+     * {@link VirtualMachine#suspend} or when the specified thread
+     * is suspended through {@link ThreadReference#suspend}.
+     * <p>
+     * The specified method is invoked with the arguments in the specified
+     * argument list.  The method invocation is synchronous; this method
+     * does not return until the invoked method returns in the target VM.
+     * If the invoked method throws an exception, this method will throw
+     * an {@link InvocationException} which contains a mirror to the exception
+     * object thrown.
+     * <p>
+     * Object arguments must be assignment compatible with the argument type
+     * (This implies that the argument type must be loaded through the
+     * enclosing class' class loader). Primitive arguments must be
+     * either assignment compatible with the argument type or must be
+     * convertible to the argument type without loss of information.
+     * If the method being called accepts a variable number of arguments,
+     * then the last argument type is an array of some component type.
+     * The argument in the matching position can be omitted, or can be null,
+     * an array of the same component type, or an argument of the
+     * component type followed by any number of other arguments of the same
+     * type. If the argument is omitted, then a 0 length array of the
+     * component type is passed.  The component type can be a primitive type.
+     * Autoboxing is not supported.
+     *
+     * See Section 5.2 of
+     * <cite>The Java&trade; Language Specification</cite>
+     * for more information on assignment compatibility.
+     * <p>
+     * By default, all threads in the target VM are resumed while
+     * the method is being invoked if they were previously
+     * suspended by an event or by {@link VirtualMachine#suspend} or
+     * {@link ThreadReference#suspend}. This is done to prevent the deadlocks
+     * that will occur if any of the threads own monitors
+     * that will be needed by the invoked method.
+     * Note, however, that this implicit resume acts exactly like
+     * {@link ThreadReference#resume}, so if the thread's suspend
+     * count is greater than 1, it will remain in a suspended state
+     * during the invocation and thus a deadlock could still occur.
+     * By default, when the invocation completes,
+     * all threads in the target VM are suspended, regardless their state
+     * before the invocation.
+     * It is possible that
+     * breakpoints or other events might occur during the invocation.
+     * This can cause deadlocks as described above. It can also cause a deadlock
+     * if invokeMethod is called from the client's event handler thread.  In this
+     * case, this thread will be waiting for the invokeMethod to complete and
+     * won't read the EventSet that comes in for the new event.  If this
+     * new EventSet is SUSPEND_ALL, then a deadlock will occur because no
+     * one will resume the EventSet.  To avoid this, all EventRequests should
+     * be disabled before doing the invokeMethod, or the invokeMethod should
+     * not be done from the client's event handler thread.
+     * <p>
+     * The resumption of other threads during the invocation can be prevented
+     * by specifying the {@link #INVOKE_SINGLE_THREADED}
+     * bit flag in the <code>options</code> argument; however,
+     * there is no protection against or recovery from the deadlocks
+     * described above, so this option should be used with great caution.
+     * Only the specified thread will be resumed (as described for all
+     * threads above). Upon completion of a single threaded invoke, the invoking thread
+     * will be suspended once again. Note that any threads started during
+     * the single threaded invocation will not be suspended when the
+     * invocation completes.
+     * <p>
+     * If the target VM is disconnected during the invoke (for example, through
+     * {@link VirtualMachine#dispose}) the method invocation continues.
+     *
+     * @param thread the thread in which to invoke.
+     * @param method the {@link Method} to invoke.
+     * @param arguments the list of {@link Value} arguments bound to the
+     * invoked method. Values from the list are assigned to arguments
+     * in the order they appear in the method signature.
+     * @param options the integer bit flag options.
+     * @return a {@link Value} mirror of the invoked method's return value.
+     * @throws java.lang.IllegalArgumentException if the method is not
+     * a member of this interface, if the size of the argument list
+     * does not match the number of declared arguments for the method, or
+     * if the method is not static or is a static initializer.
+     * @throws {@link InvalidTypeException} if any argument in the
+     * argument list is not assignable to the corresponding method argument
+     * type.
+     * @throws ClassNotLoadedException if any argument type has not yet been loaded
+     * through the appropriate class loader.
+     * @throws IncompatibleThreadStateException if the specified thread has not
+     * been suspended by an event.
+     * @throws InvocationException if the method invocation resulted in
+     * an exception in the target VM.
+     * @throws InvalidTypeException If the arguments do not meet this requirement --
+     *         Object arguments must be assignment compatible with the argument
+     *         type.  This implies that the argument type must be
+     *         loaded through the enclosing class' class loader.
+     *         Primitive arguments must be either assignment compatible with the
+     *         argument type or must be convertible to the argument type without loss
+     *         of information. See JLS section 5.2 for more information on assignment
+     *         compatibility.
+     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
+     *
+     * @since 1.8
+     */
+    default Value invokeMethod(ThreadReference thread, Method method,
+                       List<? extends Value> arguments, int options)
+            throws InvalidTypeException,
+            ClassNotLoadedException,
+            IncompatibleThreadStateException,
+            InvocationException {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/jdk/src/share/classes/com/sun/jdi/Method.java b/jdk/src/share/classes/com/sun/jdi/Method.java
index 19b13e0..eb81b05 100644
--- a/jdk/src/share/classes/com/sun/jdi/Method.java
+++ b/jdk/src/share/classes/com/sun/jdi/Method.java
@@ -138,6 +138,18 @@
     boolean isAbstract();
 
     /**
+     * Determine if this method is a default method
+     *
+     * @return <code>true</code> if the method is declared default;
+     * false otherwise
+     *
+     * @since 1.8
+     */
+    default boolean isDefault() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
      * Determine if this method is synchronized.
      *
      * @return <code>true</code> if the method is declared synchronized;
diff --git a/jdk/src/share/classes/com/sun/jdi/ObjectReference.java b/jdk/src/share/classes/com/sun/jdi/ObjectReference.java
index 797d5ad..b6bf5a3 100644
--- a/jdk/src/share/classes/com/sun/jdi/ObjectReference.java
+++ b/jdk/src/share/classes/com/sun/jdi/ObjectReference.java
@@ -194,10 +194,10 @@
      * {@link #INVOKE_NONVIRTUAL} bit flag in the <code>options</code>
      * argument. If this flag is set, the specified method is invoked
      * whether or not it is overridden for this object's runtime type.
-     * The method, in this case, must not belong to an interface and
-     * must not be abstract. This option is useful for performing method
-     * invocations like those done with the <code>super</code> keyword in
-     * the Java programming language.
+     * The method, in this case, must have an implementation, either in a class
+     * or an interface. This option is useful for performing method invocations
+     * like those done with the <code>super</code> keyword in the Java programming
+     * language.
      * <p>
      * By default, all threads in the target VM are resumed while
      * the method is being invoked if they were previously
@@ -246,10 +246,10 @@
      * @return a {@link Value} mirror of the invoked method's return value.
      * @throws java.lang.IllegalArgumentException if the method is not
      * a member of this object's class, if the size of the argument list
-     * does not match the number of declared arguemnts for the method,
+     * does not match the number of declared arguments for the method,
      * if the method is a constructor or static intializer, or
      * if {@link #INVOKE_NONVIRTUAL} is specified and the method is
-     * either abstract or an interface member.
+     * either abstract or a non-default interface member.
      * @throws {@link InvalidTypeException} if any argument in the
      * argument list is not assignable to the corresponding method argument
      * type.
diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/Init.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/Init.java
index 6176370..5f3b9f5 100644
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/Init.java
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/Init.java
@@ -25,6 +25,8 @@
 import java.io.InputStream;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -35,6 +37,7 @@
 import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
 import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm;
 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
+import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolver;
 import com.sun.org.apache.xml.internal.security.transforms.Transform;
 import com.sun.org.apache.xml.internal.security.utils.ElementProxy;
@@ -118,43 +121,50 @@
             log.log(java.util.logging.Level.FINE, "Registering default algorithms");
         }
         try {
-            //
-            // Bind the default prefixes
-            //
-            ElementProxy.registerDefaultPrefixes();
+            AccessController.doPrivileged(new PrivilegedExceptionAction<Void>(){
+                @Override public Void run() throws XMLSecurityException {
+                    //
+                    // Bind the default prefixes
+                    //
+                    ElementProxy.registerDefaultPrefixes();
 
-            //
-            // Set the default Transforms
-            //
-            Transform.registerDefaultAlgorithms();
+                    //
+                    // Set the default Transforms
+                    //
+                    Transform.registerDefaultAlgorithms();
 
-            //
-            // Set the default signature algorithms
-            //
-            SignatureAlgorithm.registerDefaultAlgorithms();
+                    //
+                    // Set the default signature algorithms
+                    //
+                    SignatureAlgorithm.registerDefaultAlgorithms();
 
-            //
-            // Set the default JCE algorithms
-            //
-            JCEMapper.registerDefaultAlgorithms();
+                    //
+                    // Set the default JCE algorithms
+                    //
+                    JCEMapper.registerDefaultAlgorithms();
 
-            //
-            // Set the default c14n algorithms
-            //
-            Canonicalizer.registerDefaultAlgorithms();
+                    //
+                    // Set the default c14n algorithms
+                    //
+                    Canonicalizer.registerDefaultAlgorithms();
 
-            //
-            // Register the default resolvers
-            //
-            ResourceResolver.registerDefaultResolvers();
+                    //
+                    // Register the default resolvers
+                    //
+                    ResourceResolver.registerDefaultResolvers();
 
-            //
-            // Register the default key resolvers
-            //
-            KeyResolver.registerDefaultResolvers();
-        } catch (Exception ex) {
-            log.log(java.util.logging.Level.SEVERE, ex.getMessage(), ex);
-            ex.printStackTrace();
+                    //
+                    // Register the default key resolvers
+                    //
+                    KeyResolver.registerDefaultResolvers();
+
+                    return null;
+                }
+           });
+        } catch (PrivilegedActionException ex) {
+            XMLSecurityException xse = (XMLSecurityException)ex.getException();
+            log.log(java.util.logging.Level.SEVERE, xse.getMessage(), xse);
+            xse.printStackTrace();
         }
     }
 
diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java
index ca7d42a..9fc3525 100644
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java
@@ -27,6 +27,7 @@
 
 import com.sun.org.apache.xml.internal.security.encryption.XMLCipher;
 import com.sun.org.apache.xml.internal.security.signature.XMLSignature;
+import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
 import org.w3c.dom.Element;
 
 
@@ -49,8 +50,11 @@
      *
      * @param id
      * @param algorithm
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register the JCE algorithm
      */
     public static void register(String id, Algorithm algorithm) {
+        JavaUtils.checkRegisterPermission();
         algorithmsMap.put(id, algorithm);
     }
 
@@ -292,8 +296,11 @@
     /**
      * Sets the default Provider for obtaining the security algorithms
      * @param provider the default providerId.
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to set the JCE provider
      */
     public static void setProviderId(String provider) {
+        JavaUtils.checkRegisterPermission();
         providerName = provider;
     }
 
diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java
index 4748a6b..ada9ea5 100644
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java
@@ -37,6 +37,7 @@
 import com.sun.org.apache.xml.internal.security.signature.XMLSignature;
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;
 import com.sun.org.apache.xml.internal.security.utils.Constants;
+import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -314,18 +315,21 @@
     }
 
     /**
-     * Registers implementing class of the Transform algorithm with algorithmURI
+     * Registers implementing class of the SignatureAlgorithm with algorithmURI
      *
-     * @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code>.
+     * @param algorithmURI algorithmURI URI representation of <code>SignatureAlgorithm</code>.
      * @param implementingClass <code>implementingClass</code> the implementing class of
      * {@link SignatureAlgorithmSpi}
      * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI is already registered
      * @throws XMLSignatureException
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register the signature algorithm
      */
     @SuppressWarnings("unchecked")
     public static void register(String algorithmURI, String implementingClass)
        throws AlgorithmAlreadyRegisteredException, ClassNotFoundException,
            XMLSignatureException {
+        JavaUtils.checkRegisterPermission();
         if (log.isLoggable(java.util.logging.Level.FINE)) {
             log.log(java.util.logging.Level.FINE, "Try to register " + algorithmURI + " " + implementingClass);
         }
@@ -352,15 +356,18 @@
     /**
      * Registers implementing class of the Transform algorithm with algorithmURI
      *
-     * @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code>.
+     * @param algorithmURI algorithmURI URI representation of <code>SignatureAlgorithm</code>.
      * @param implementingClass <code>implementingClass</code> the implementing class of
      * {@link SignatureAlgorithmSpi}
      * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI is already registered
      * @throws XMLSignatureException
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register the signature algorithm
      */
     public static void register(String algorithmURI, Class<? extends SignatureAlgorithmSpi> implementingClass)
        throws AlgorithmAlreadyRegisteredException, ClassNotFoundException,
            XMLSignatureException {
+        JavaUtils.checkRegisterPermission();
         if (log.isLoggable(java.util.logging.Level.FINE)) {
             log.log(java.util.logging.Level.FINE, "Try to register " + algorithmURI + " " + implementingClass);
         }
diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java
index 2f0b31f..ae33b72 100644
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java
@@ -41,6 +41,7 @@
 import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315WithComments;
 import com.sun.org.apache.xml.internal.security.c14n.implementations.CanonicalizerPhysical;
 import com.sun.org.apache.xml.internal.security.exceptions.AlgorithmAlreadyRegisteredException;
+import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -142,10 +143,13 @@
      * @param algorithmURI
      * @param implementingClass
      * @throws AlgorithmAlreadyRegisteredException
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register the canonicalizer
      */
     @SuppressWarnings("unchecked")
     public static void register(String algorithmURI, String implementingClass)
         throws AlgorithmAlreadyRegisteredException, ClassNotFoundException {
+        JavaUtils.checkRegisterPermission();
         // check whether URI is already registered
         Class<? extends CanonicalizerSpi> registeredClass =
             canonicalizerHash.get(algorithmURI);
@@ -166,9 +170,12 @@
      * @param algorithmURI
      * @param implementingClass
      * @throws AlgorithmAlreadyRegisteredException
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register the canonicalizer
      */
-    public static void register(String algorithmURI, Class<CanonicalizerSpi> implementingClass)
+    public static void register(String algorithmURI, Class<? extends CanonicalizerSpi> implementingClass)
         throws AlgorithmAlreadyRegisteredException, ClassNotFoundException {
+        JavaUtils.checkRegisterPermission();
         // check whether URI is already registered
         Class<? extends CanonicalizerSpi> registeredClass = canonicalizerHash.get(algorithmURI);
 
diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java
index fe541ff..e8622d9 100644
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java
@@ -42,6 +42,7 @@
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509SKIResolver;
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509SubjectNameResolver;
 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver;
+import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
@@ -175,9 +176,12 @@
      * @throws InstantiationException
      * @throws IllegalAccessException
      * @throws ClassNotFoundException
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register the key resolver
      */
     public static void register(String className, boolean globalResolver)
         throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+        JavaUtils.checkRegisterPermission();
         KeyResolverSpi keyResolverSpi =
             (KeyResolverSpi) Class.forName(className).newInstance();
         keyResolverSpi.setGlobalResolver(globalResolver);
@@ -195,8 +199,11 @@
      *
      * @param className
      * @param globalResolver Whether the KeyResolverSpi is a global resolver or not
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register the key resolver
      */
     public static void registerAtStart(String className, boolean globalResolver) {
+        JavaUtils.checkRegisterPermission();
         KeyResolverSpi keyResolverSpi = null;
         Exception ex = null;
         try {
@@ -228,11 +235,14 @@
      *
      * @param keyResolverSpi a KeyResolverSpi instance to register
      * @param start whether to register the KeyResolverSpi at the start of the list or not
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register the key resolver
      */
     public static void register(
         KeyResolverSpi keyResolverSpi,
         boolean start
     ) {
+        JavaUtils.checkRegisterPermission();
         KeyResolver resolver = new KeyResolver(keyResolverSpi);
         if (start) {
             resolverVector.add(0, resolver);
@@ -254,9 +264,12 @@
      * @throws InstantiationException
      * @throws IllegalAccessException
      * @throws ClassNotFoundException
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register the key resolver
      */
     public static void registerClassNames(List<String> classNames)
         throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+        JavaUtils.checkRegisterPermission();
         List<KeyResolver> keyResolverList = new ArrayList<KeyResolver>(classNames.size());
         for (String className : classNames) {
             KeyResolverSpi keyResolverSpi =
diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java
index 37d67ba..3fc1d21 100644
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java
@@ -46,6 +46,7 @@
 import com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT;
 import com.sun.org.apache.xml.internal.security.utils.Constants;
 import com.sun.org.apache.xml.internal.security.utils.HelperNodeList;
+import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
 import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy;
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Document;
@@ -181,11 +182,14 @@
      * class of {@link TransformSpi}
      * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI
      * is already registered
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register the transform
      */
     @SuppressWarnings("unchecked")
     public static void register(String algorithmURI, String implementingClass)
         throws AlgorithmAlreadyRegisteredException, ClassNotFoundException,
             InvalidTransformException {
+        JavaUtils.checkRegisterPermission();
         // are we already registered?
         Class<? extends TransformSpi> transformSpi = transformSpiHash.get(algorithmURI);
         if (transformSpi != null) {
@@ -206,9 +210,12 @@
      * class of {@link TransformSpi}
      * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI
      * is already registered
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register the transform
      */
     public static void register(String algorithmURI, Class<? extends TransformSpi> implementingClass)
         throws AlgorithmAlreadyRegisteredException {
+        JavaUtils.checkRegisterPermission();
         // are we already registered?
         Class<? extends TransformSpi> transformSpi = transformSpiHash.get(algorithmURI);
         if (transformSpi != null) {
diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java
index ac7a53e..fe8bdb1 100644
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java
@@ -468,9 +468,12 @@
      * @param namespace
      * @param prefix
      * @throws XMLSecurityException
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to set the default prefix
      */
     public static void setDefaultPrefix(String namespace, String prefix)
         throws XMLSecurityException {
+        JavaUtils.checkRegisterPermission();
         if (prefixMappings.containsValue(prefix)) {
             String storedPrefix = prefixMappings.get(namespace);
             if (!storedPrefix.equals(prefix)) {
diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java
index cf55f40..ee3dfbe 100644
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java
@@ -28,6 +28,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.security.SecurityPermission;
 
 /**
  * A collection of different, general-purpose methods for JAVA-specific things
@@ -39,6 +40,10 @@
     private static java.util.logging.Logger log =
         java.util.logging.Logger.getLogger(JavaUtils.class.getName());
 
+    private static final SecurityPermission REGISTER_PERMISSION =
+        new SecurityPermission(
+            "com.sun.org.apache.xml.internal.security.register");
+
     private JavaUtils() {
         // we don't allow instantiation
     }
@@ -145,4 +150,21 @@
 
         return retBytes;
     }
+
+    /**
+     * Throws a {@code SecurityException} if a security manager is installed
+     * and the caller is not allowed to register an implementation of an
+     * algorithm, transform, or other security sensitive XML Signature function.
+     *
+     * @throws SecurityException if a security manager is installed and the
+     *    caller has not been granted the
+     *    {@literal "com.sun.org.apache.xml.internal.security.register"}
+     *    {@code SecurityPermission}
+     */
+    public static void checkRegisterPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(REGISTER_PERMISSION);
+        }
+    }
 }
diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java
index 620b673..585f7f6 100644
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java
@@ -80,32 +80,44 @@
     /**
      * Set the prefix for the digital signature namespace
      * @param prefix the new prefix for the digital signature namespace
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to set the prefix
      */
     public static void setDsPrefix(String prefix) {
+        JavaUtils.checkRegisterPermission();
         dsPrefix = prefix;
     }
 
     /**
      * Set the prefix for the digital signature 1.1 namespace
      * @param prefix the new prefix for the digital signature 1.1 namespace
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to set the prefix
      */
     public static void setDs11Prefix(String prefix) {
+        JavaUtils.checkRegisterPermission();
         ds11Prefix = prefix;
     }
 
     /**
      * Set the prefix for the encryption namespace
      * @param prefix the new prefix for the encryption namespace
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to set the prefix
      */
     public static void setXencPrefix(String prefix) {
+        JavaUtils.checkRegisterPermission();
         xencPrefix = prefix;
     }
 
     /**
      * Set the prefix for the encryption namespace 1.1
      * @param prefix the new prefix for the encryption namespace 1.1
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to set the prefix
      */
     public static void setXenc11Prefix(String prefix) {
+        JavaUtils.checkRegisterPermission();
         xenc11Prefix = prefix;
     }
 
diff --git a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java
index 7570a01..012d2fb 100644
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java
+++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java
@@ -27,6 +27,7 @@
 import java.util.Map;
 
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
+import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
 import com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverDirectHTTP;
 import com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment;
 import com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverLocalFilesystem;
@@ -199,9 +200,12 @@
      * the class cannot be registered.
      *
      * @param className the name of the ResourceResolverSpi class to be registered
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register a resource resolver
      */
     @SuppressWarnings("unchecked")
     public static void register(String className) {
+        JavaUtils.checkRegisterPermission();
         try {
             Class<ResourceResolverSpi> resourceResolverClass =
                 (Class<ResourceResolverSpi>) Class.forName(className);
@@ -216,9 +220,12 @@
      * list. This method logs a warning if the class cannot be registered.
      *
      * @param className the name of the ResourceResolverSpi class to be registered
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register a resource resolver
      */
     @SuppressWarnings("unchecked")
     public static void registerAtStart(String className) {
+        JavaUtils.checkRegisterPermission();
         try {
             Class<ResourceResolverSpi> resourceResolverClass =
                 (Class<ResourceResolverSpi>) Class.forName(className);
@@ -233,8 +240,11 @@
      * cannot be registered.
      * @param className
      * @param start
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register a resource resolver
      */
     public static void register(Class<? extends ResourceResolverSpi> className, boolean start) {
+        JavaUtils.checkRegisterPermission();
         try {
             ResourceResolverSpi resourceResolverSpi = className.newInstance();
             register(resourceResolverSpi, start);
@@ -250,8 +260,11 @@
      * cannot be registered.
      * @param resourceResolverSpi
      * @param start
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register a resource resolver
      */
     public static void register(ResourceResolverSpi resourceResolverSpi, boolean start) {
+        JavaUtils.checkRegisterPermission();
         synchronized(resolverList) {
             if (start) {
                 resolverList.add(0, new ResourceResolver(resourceResolverSpi));
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties
index cf95074..c5314fa 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties
@@ -42,13 +42,13 @@
 FileChooser.renameErrorFileExists.textAndMnemonic={0}\u306E\u540D\u524D\u3092\u5909\u66F4\u3067\u304D\u307E\u305B\u3093: \u6307\u5B9A\u3057\u305F\u540D\u524D\u306E\u30D5\u30A1\u30A4\u30EB\u306F\u3059\u3067\u306B\u5B58\u5728\u3057\u307E\u3059\u3002\u5225\u306E\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002 
 FileChooser.acceptAllFileFilter.textAndMnemonic=\u3059\u3079\u3066\u306E\u30D5\u30A1\u30A4\u30EB
 FileChooser.cancelButton.textAndMnemonic=\u53D6\u6D88
-FileChooser.saveButton.textAndMnemonic=\u4FDD\u5B58
-FileChooser.openButton.textAndMnemonic=\u958B\u304F
+FileChooser.saveButton.textAndMnemonic=\u4FDD\u5B58(&S)
+FileChooser.openButton.textAndMnemonic=\u958B\u304F(&O)
 FileChooser.saveDialogTitle.textAndMnemonic=\u4FDD\u5B58
 FileChooser.openDialogTitle.textAndMnemonic=\u958B\u304F
 FileChooser.updateButton.textAndMnemonic=\u66F4\u65B0(&U)
 FileChooser.helpButton.textAndMnemonic=\u30D8\u30EB\u30D7(&H)
-FileChooser.directoryOpenButton.textAndMnemonic=\u958B\u304F
+FileChooser.directoryOpenButton.textAndMnemonic=\u958B\u304F(&O)
 
 # File Size Units
 FileChooser.fileSizeKiloBytes={0} KB
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties
index c8e67df..7f31303 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties
@@ -42,13 +42,13 @@
 FileChooser.renameErrorFileExists.textAndMnemonic={0}\uC758 \uC774\uB984\uC744 \uBC14\uAFC0 \uC218 \uC5C6\uC74C: \uC9C0\uC815\uD55C \uC774\uB984\uC744 \uC0AC\uC6A9\uD558\uB294 \uD30C\uC77C\uC774 \uC874\uC7AC\uD569\uB2C8\uB2E4. \uB2E4\uB978 \uD30C\uC77C \uC774\uB984\uC744 \uC9C0\uC815\uD558\uC2ED\uC2DC\uC624.
 FileChooser.acceptAllFileFilter.textAndMnemonic=\uBAA8\uB4E0 \uD30C\uC77C
 FileChooser.cancelButton.textAndMnemonic=\uCDE8\uC18C
-FileChooser.saveButton.textAndMnemonic=\uC800\uC7A5
-FileChooser.openButton.textAndMnemonic=\uC5F4\uAE30
+FileChooser.saveButton.textAndMnemonic=\uC800\uC7A5(&S)
+FileChooser.openButton.textAndMnemonic=\uC5F4\uAE30(&O)
 FileChooser.saveDialogTitle.textAndMnemonic=\uC800\uC7A5
 FileChooser.openDialogTitle.textAndMnemonic=\uC5F4\uAE30
 FileChooser.updateButton.textAndMnemonic=\uC5C5\uB370\uC774\uD2B8(&U)
 FileChooser.helpButton.textAndMnemonic=\uB3C4\uC6C0\uB9D0(&H)
-FileChooser.directoryOpenButton.textAndMnemonic=\uC5F4\uAE30
+FileChooser.directoryOpenButton.textAndMnemonic=\uC5F4\uAE30(&O)
 
 # File Size Units
 FileChooser.fileSizeKiloBytes={0} KB
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties
index ab3bb26..d4c3572 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties
@@ -42,13 +42,13 @@
 FileChooser.renameErrorFileExists.textAndMnemonic=\u65E0\u6CD5\u91CD\u547D\u540D{0}: \u5DF2\u5B58\u5728\u5177\u6709\u6240\u6307\u5B9A\u540D\u79F0\u7684\u6587\u4EF6\u3002\u8BF7\u6307\u5B9A\u5176\u4ED6\u6587\u4EF6\u540D\u3002
 FileChooser.acceptAllFileFilter.textAndMnemonic=\u6240\u6709\u6587\u4EF6
 FileChooser.cancelButton.textAndMnemonic=\u53D6\u6D88
-FileChooser.saveButton.textAndMnemonic=\u4FDD\u5B58
-FileChooser.openButton.textAndMnemonic=\u6253\u5F00
+FileChooser.saveButton.textAndMnemonic=\u4FDD\u5B58(&S)
+FileChooser.openButton.textAndMnemonic=\u6253\u5F00(&O)
 FileChooser.saveDialogTitle.textAndMnemonic=\u4FDD\u5B58
 FileChooser.openDialogTitle.textAndMnemonic=\u6253\u5F00
 FileChooser.updateButton.textAndMnemonic=\u66F4\u65B0(&U)
 FileChooser.helpButton.textAndMnemonic=\u5E2E\u52A9(&H)
-FileChooser.directoryOpenButton.textAndMnemonic=\u6253\u5F00
+FileChooser.directoryOpenButton.textAndMnemonic=\u6253\u5F00(&O)
 
 # File Size Units
 FileChooser.fileSizeKiloBytes={0} KB
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties
index d4b4795..6541661 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties
@@ -42,13 +42,13 @@
 FileChooser.renameErrorFileExists.textAndMnemonic=\u7121\u6CD5\u91CD\u65B0\u547D\u540D {0}: \u5DF2\u7D93\u5B58\u5728\u60A8\u6240\u6307\u5B9A\u540D\u7A31\u7684\u6A94\u6848\u3002\u8ACB\u6307\u5B9A\u4E0D\u540C\u7684\u540D\u7A31\u3002
 FileChooser.acceptAllFileFilter.textAndMnemonic=\u6240\u6709\u6A94\u6848
 FileChooser.cancelButton.textAndMnemonic=\u53D6\u6D88
-FileChooser.saveButton.textAndMnemonic=\u5132\u5B58
-FileChooser.openButton.textAndMnemonic=\u958B\u555F
+FileChooser.saveButton.textAndMnemonic=\u5132\u5B58(&S)
+FileChooser.openButton.textAndMnemonic=\u958B\u555F(&O)
 FileChooser.saveDialogTitle.textAndMnemonic=\u5132\u5B58
 FileChooser.openDialogTitle.textAndMnemonic=\u958B\u555F
 FileChooser.updateButton.textAndMnemonic=\u66F4\u65B0(&U)
 FileChooser.helpButton.textAndMnemonic=\u8AAA\u660E(&H)
-FileChooser.directoryOpenButton.textAndMnemonic=\u958B\u555F
+FileChooser.directoryOpenButton.textAndMnemonic=\u958B\u555F(&O)
 
 # File Size Units
 FileChooser.fileSizeKiloBytes={0} KB
diff --git a/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java b/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java
index 97794c5..1737137 100644
--- a/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java
+++ b/jdk/src/share/classes/com/sun/tools/example/debug/expr/LValue.java
@@ -559,6 +559,9 @@
             } else if (refType instanceof ClassType) {
                 ClassType clazz = (ClassType)refType;
                 return jdiValue = clazz.invokeMethod(thread, matchingMethod, methodArguments, 0);
+            } else if (refType instanceof InterfaceType) {
+                InterfaceType iface = (InterfaceType)refType;
+                return jdiValue = iface.invokeMethod(thread, matchingMethod, methodArguments, 0);
             } else {
                 throw new InvalidTypeException("Cannot invoke static method on " +
                                          refType.name());
diff --git a/jdk/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java
index 4116c5e..0c83e4d 100644
--- a/jdk/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java
+++ b/jdk/src/share/classes/com/sun/tools/jdi/ArrayTypeImpl.java
@@ -31,6 +31,7 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 public class ArrayTypeImpl extends ReferenceTypeImpl
     implements ArrayType
@@ -61,7 +62,8 @@
         return findType(componentSignature());
     }
 
-    void addVisibleMethods(Map<String, Method> map) {
+    @Override
+    void addVisibleMethods(Map<String, Method> map, Set<InterfaceType> seenInterfaces) {
         // arrays don't have methods
     }
 
diff --git a/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java
index 2b2c0ee..b815d1a 100644
--- a/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java
+++ b/jdk/src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java
@@ -29,9 +29,27 @@
 
 import java.util.*;
 
-public class ClassTypeImpl extends ReferenceTypeImpl
+final public class ClassTypeImpl extends InvokableTypeImpl
     implements ClassType
 {
+    private static class IResult implements InvocationResult {
+        final private JDWP.ClassType.InvokeMethod rslt;
+
+        public IResult(JDWP.ClassType.InvokeMethod rslt) {
+            this.rslt = rslt;
+        }
+
+        @Override
+        public ObjectReferenceImpl getException() {
+            return rslt.exception;
+        }
+
+        @Override
+        public ValueImpl getResult() {
+            return rslt.returnValue;
+        }
+    }
+
     private boolean cachedSuperclass = false;
     private ClassType superclass = null;
     private int lastLine = -1;
@@ -65,6 +83,7 @@
         return superclass;
     }
 
+    @Override
     public List<InterfaceType> interfaces()  {
         if (interfaces == null) {
             interfaces = getInterfaces();
@@ -72,26 +91,9 @@
         return interfaces;
     }
 
-    void addInterfaces(List<InterfaceType> list) {
-        List<InterfaceType> immediate = interfaces();
-        list.addAll(interfaces());
-
-        Iterator<InterfaceType> iter = immediate.iterator();
-        while (iter.hasNext()) {
-            InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
-            interfaze.addSuperinterfaces(list);
-        }
-
-        ClassTypeImpl superclass = (ClassTypeImpl)superclass();
-        if (superclass != null) {
-            superclass.addInterfaces(list);
-        }
-    }
-
-    public List<InterfaceType> allInterfaces()  {
-        List<InterfaceType> all = new ArrayList<InterfaceType>();
-        addInterfaces(all);
-        return all;
+    @Override
+    public List<InterfaceType> allInterfaces() {
+        return getAllInterfaces();
     }
 
     public List<ClassType> subclasses() {
@@ -159,28 +161,6 @@
         }
     }
 
-    PacketStream sendInvokeCommand(final ThreadReferenceImpl thread,
-                                   final MethodImpl method,
-                                   final ValueImpl[] args,
-                                   final int options) {
-        CommandSender sender =
-            new CommandSender() {
-                public PacketStream send() {
-                    return JDWP.ClassType.InvokeMethod.enqueueCommand(
-                                          vm, ClassTypeImpl.this, thread,
-                                          method.ref(), args, options);
-                }
-        };
-
-        PacketStream stream;
-        if ((options & INVOKE_SINGLE_THREADED) != 0) {
-            stream = thread.sendResumingCommand(sender);
-        } else {
-            stream = vm.sendResumingCommand(sender);
-        }
-        return stream;
-    }
-
     PacketStream sendNewInstanceCommand(final ThreadReferenceImpl thread,
                                    final MethodImpl method,
                                    final ValueImpl[] args,
@@ -203,52 +183,6 @@
         return stream;
     }
 
-    public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
-                              List<? extends Value> origArguments, int options)
-                                   throws InvalidTypeException,
-                                          ClassNotLoadedException,
-                                          IncompatibleThreadStateException,
-                                          InvocationException {
-        validateMirror(threadIntf);
-        validateMirror(methodIntf);
-        validateMirrorsOrNulls(origArguments);
-
-        MethodImpl method = (MethodImpl)methodIntf;
-        ThreadReferenceImpl thread = (ThreadReferenceImpl)threadIntf;
-
-        validateMethodInvocation(method);
-
-        List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
-
-        ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
-        JDWP.ClassType.InvokeMethod ret;
-        try {
-            PacketStream stream =
-                sendInvokeCommand(thread, method, args, options);
-            ret = JDWP.ClassType.InvokeMethod.waitForReply(vm, stream);
-        } catch (JDWPException exc) {
-            if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
-                throw new IncompatibleThreadStateException();
-            } else {
-                throw exc.toJDIException();
-            }
-        }
-
-        /*
-         * There is an implict VM-wide suspend at the conclusion
-         * of a normal (non-single-threaded) method invoke
-         */
-        if ((options & INVOKE_SINGLE_THREADED) == 0) {
-            vm.notifySuspend();
-        }
-
-        if (ret.exception != null) {
-            throw new InvocationException(ret.exception);
-        } else {
-            return ret.returnValue;
-        }
-    }
-
     public ObjectReference newInstance(ThreadReference threadIntf,
                                        Method methodIntf,
                                        List<? extends Value> origArguments,
@@ -311,58 +245,6 @@
        return method;
    }
 
-   public List<Method> allMethods() {
-        ArrayList<Method> list = new ArrayList<Method>(methods());
-
-        ClassType clazz = superclass();
-        while (clazz != null) {
-            list.addAll(clazz.methods());
-            clazz = clazz.superclass();
-        }
-
-        /*
-         * Avoid duplicate checking on each method by iterating through
-         * duplicate-free allInterfaces() rather than recursing
-         */
-        for (InterfaceType interfaze : allInterfaces()) {
-            list.addAll(interfaze.methods());
-        }
-
-        return list;
-    }
-
-    List<ReferenceType> inheritedTypes() {
-        List<ReferenceType> inherited = new ArrayList<ReferenceType>();
-        if (superclass() != null) {
-            inherited.add(0, (ReferenceType)superclass()); /* insert at front */
-        }
-        for (ReferenceType rt : interfaces()) {
-            inherited.add(rt);
-        }
-        return inherited;
-    }
-
-    void validateMethodInvocation(Method method)
-                                   throws InvalidTypeException,
-                                          InvocationException {
-        /*
-         * Method must be in this class or a superclass.
-         */
-        ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType();
-        if (!declType.isAssignableFrom(this)) {
-            throw new IllegalArgumentException("Invalid method");
-        }
-
-        /*
-         * Method must be a static and not a static initializer
-         */
-        if (!method.isStatic()) {
-            throw new IllegalArgumentException("Cannot invoke instance method on a class type");
-        } else if (method.isStaticInitializer()) {
-            throw new IllegalArgumentException("Cannot invoke static initializer");
-        }
-    }
-
     void validateConstructorInvocation(Method method)
                                    throws InvalidTypeException,
                                           InvocationException {
@@ -382,47 +264,33 @@
         }
     }
 
-    void addVisibleMethods(Map<String, Method> methodMap) {
-        /*
-         * Add methods from
-         * parent types first, so that the methods in this class will
-         * overwrite them in the hash table
-         */
-
-        Iterator<InterfaceType> iter = interfaces().iterator();
-        while (iter.hasNext()) {
-            InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
-            interfaze.addVisibleMethods(methodMap);
-        }
-
-        ClassTypeImpl clazz = (ClassTypeImpl)superclass();
-        if (clazz != null) {
-            clazz.addVisibleMethods(methodMap);
-        }
-
-        addToMethodMap(methodMap, methods());
-    }
-
-    boolean isAssignableTo(ReferenceType type) {
-        ClassTypeImpl superclazz = (ClassTypeImpl)superclass();
-        if (this.equals(type)) {
-            return true;
-        } else if ((superclazz != null) && superclazz.isAssignableTo(type)) {
-            return true;
-        } else {
-            List<InterfaceType> interfaces = interfaces();
-            Iterator<InterfaceType> iter = interfaces.iterator();
-            while (iter.hasNext()) {
-                InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
-                if (interfaze.isAssignableTo(type)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
 
     public String toString() {
        return "class " + name() + " (" + loaderString() + ")";
     }
+
+    @Override
+    CommandSender getInvokeMethodSender(ThreadReferenceImpl thread,
+                                        MethodImpl method,
+                                        ValueImpl[] args,
+                                        int options) {
+        return () ->
+            JDWP.ClassType.InvokeMethod.enqueueCommand(vm,
+                                                       ClassTypeImpl.this,
+                                                       thread,
+                                                       method.ref(),
+                                                       args,
+                                                       options);
+    }
+
+    @Override
+    InvocationResult waitForReply(PacketStream stream) throws JDWPException {
+        return new IResult(JDWP.ClassType.InvokeMethod.waitForReply(vm, stream));
+    }
+
+    @Override
+    boolean canInvoke(Method method) {
+        // Method must be in this class or a superclass.
+        return ((ReferenceTypeImpl)method.declaringType()).isAssignableFrom(this);
+    }
 }
diff --git a/jdk/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java
index 8fa7670..da7e55a 100644
--- a/jdk/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java
+++ b/jdk/src/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java
@@ -29,13 +29,31 @@
 
 import java.util.List;
 import java.util.ArrayList;
-import java.util.Map;
-import java.util.Iterator;
 import java.util.Collections;
+import java.util.Set;
 import java.lang.ref.SoftReference;
 
-public class InterfaceTypeImpl extends ReferenceTypeImpl
-                               implements InterfaceType {
+final public class InterfaceTypeImpl extends InvokableTypeImpl
+                                     implements InterfaceType {
+
+    private static class IResult implements InvocationResult {
+        final private JDWP.InterfaceType.InvokeMethod rslt;
+
+        public IResult(JDWP.InterfaceType.InvokeMethod rslt) {
+            this.rslt = rslt;
+        }
+
+        @Override
+        public ObjectReferenceImpl getException() {
+            return rslt.exception;
+        }
+
+        @Override
+        public ValueImpl getResult() {
+            return rslt.returnValue;
+        }
+
+    }
 
     private SoftReference<List<InterfaceType>> superinterfacesRef = null;
 
@@ -80,98 +98,6 @@
         return implementors;
     }
 
-    void addVisibleMethods(Map<String, Method> methodMap) {
-        /*
-         * Add methods from
-         * parent types first, so that the methods in this class will
-         * overwrite them in the hash table
-         */
-
-        for (InterfaceType interfaze : superinterfaces()) {
-            ((InterfaceTypeImpl)interfaze).addVisibleMethods(methodMap);
-        }
-
-        addToMethodMap(methodMap, methods());
-    }
-
-    public List<Method> allMethods() {
-        ArrayList<Method> list = new ArrayList<Method>(methods());
-
-        /*
-         * It's more efficient if don't do this
-         * recursively.
-         */
-        for (InterfaceType interfaze : allSuperinterfaces()) {
-            list.addAll(interfaze.methods());
-        }
-
-        return list;
-    }
-
-    List<InterfaceType> allSuperinterfaces() {
-        ArrayList<InterfaceType> list = new ArrayList<InterfaceType>();
-        addSuperinterfaces(list);
-        return list;
-    }
-
-    void addSuperinterfaces(List<InterfaceType> list) {
-        /*
-         * This code is a little strange because it
-         * builds the list with a more suitable order than the
-         * depth-first approach a normal recursive solution would
-         * take. Instead, all direct superinterfaces precede all
-         * indirect ones.
-         */
-
-        /*
-         * Get a list of direct superinterfaces that's not already in the
-         * list being built.
-         */
-        List<InterfaceType> immediate = new ArrayList<InterfaceType>(superinterfaces());
-        Iterator<InterfaceType> iter = immediate.iterator();
-        while (iter.hasNext()) {
-            InterfaceType interfaze = iter.next();
-            if (list.contains(interfaze)) {
-                iter.remove();
-            }
-        }
-
-        /*
-         * Add all new direct superinterfaces
-         */
-        list.addAll(immediate);
-
-        /*
-         * Recurse for all new direct superinterfaces.
-         */
-        iter = immediate.iterator();
-        while (iter.hasNext()) {
-            InterfaceTypeImpl interfaze = (InterfaceTypeImpl)iter.next();
-            interfaze.addSuperinterfaces(list);
-        }
-    }
-
-    boolean isAssignableTo(ReferenceType type) {
-
-        // Exact match?
-        if (this.equals(type)) {
-            return true;
-        } else {
-            // Try superinterfaces.
-            for (InterfaceType interfaze : superinterfaces()) {
-                if (((InterfaceTypeImpl)interfaze).isAssignableTo(type)) {
-                    return true;
-                }
-            }
-
-            return false;
-        }
-    }
-
-    List<InterfaceType> inheritedTypes() {
-        return superinterfaces();
-    }
-
     public boolean isInitialized() {
         return isPrepared();
     }
@@ -179,4 +105,39 @@
     public String toString() {
        return "interface " + name() + " (" + loaderString() + ")";
     }
-}
+
+    @Override
+    InvocationResult waitForReply(PacketStream stream) throws JDWPException {
+        return new IResult(JDWP.InterfaceType.InvokeMethod.waitForReply(vm, stream));
+    }
+
+    @Override
+    CommandSender getInvokeMethodSender(final ThreadReferenceImpl thread,
+                                        final MethodImpl method,
+                                        final ValueImpl[] args,
+                                        final int options) {
+        return () ->
+            JDWP.InterfaceType.InvokeMethod.enqueueCommand(vm,
+                                                           InterfaceTypeImpl.this,
+                                                           thread,
+                                                           method.ref(),
+                                                           args,
+                                                           options);
+    }
+
+    @Override
+    ClassType superclass() {
+        return null;
+    }
+
+    @Override
+    List<InterfaceType> interfaces() {
+        return superinterfaces();
+    }
+
+    @Override
+    boolean canInvoke(Method method) {
+        // method must be directly in this interface
+        return this.equals(method.declaringType());
+    }
+}
\ No newline at end of file
diff --git a/jdk/src/share/classes/com/sun/tools/jdi/InvokableTypeImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/InvokableTypeImpl.java
new file mode 100644
index 0000000..61a2330
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/tools/jdi/InvokableTypeImpl.java
@@ -0,0 +1,305 @@
+/*
+ * 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.
+ */
+
+package com.sun.tools.jdi;
+
+import com.sun.jdi.ClassNotLoadedException;
+import com.sun.jdi.ClassType;
+import com.sun.jdi.IncompatibleThreadStateException;
+import com.sun.jdi.InterfaceType;
+import com.sun.jdi.InvalidTypeException;
+import com.sun.jdi.InvocationException;
+import com.sun.jdi.Method;
+import com.sun.jdi.ReferenceType;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.Value;
+import com.sun.jdi.VirtualMachine;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A supertype for ReferenceTypes allowing method invocations
+ */
+abstract class InvokableTypeImpl extends ReferenceTypeImpl {
+    /**
+     * The invocation result wrapper
+     * It is necessary because both ClassType and InterfaceType
+     * use their own type to represent the invocation result
+     */
+    static interface InvocationResult {
+        ObjectReferenceImpl getException();
+        ValueImpl getResult();
+    }
+
+    InvokableTypeImpl(VirtualMachine aVm, long aRef) {
+        super(aVm, aRef);
+    }
+
+    /**
+     * Method invocation support.
+     * Shared by ClassType and InterfaceType
+     * @param threadIntf the thread in which to invoke.
+     * @param methodIntf method the {@link Method} to invoke.
+     * @param origArguments the list of {@link Value} arguments bound to the
+     * invoked method. Values from the list are assigned to arguments
+     * in the order they appear in the method signature.
+     * @param options the integer bit flag options.
+     * @return a {@link Value} mirror of the invoked method's return value.
+     * @throws java.lang.IllegalArgumentException if the method is not
+     * a member of this type, if the size of the argument list
+     * does not match the number of declared arguments for the method, or
+     * if the method is not static or is a static initializer.
+     * @throws {@link InvalidTypeException} if any argument in the
+     * argument list is not assignable to the corresponding method argument
+     * type.
+     * @throws ClassNotLoadedException if any argument type has not yet been loaded
+     * through the appropriate class loader.
+     * @throws IncompatibleThreadStateException if the specified thread has not
+     * been suspended by an event.
+     * @throws InvocationException if the method invocation resulted in
+     * an exception in the target VM.
+     * @throws InvalidTypeException If the arguments do not meet this requirement --
+     *         Object arguments must be assignment compatible with the argument
+     *         type.  This implies that the argument type must be
+     *         loaded through the enclosing class's class loader.
+     *         Primitive arguments must be either assignment compatible with the
+     *         argument type or must be convertible to the argument type without loss
+     *         of information. See JLS section 5.2 for more information on assignment
+     *         compatibility.
+     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
+     */
+    final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
+                                    List<? extends Value> origArguments, int options)
+                                        throws InvalidTypeException,
+                                               ClassNotLoadedException,
+                                               IncompatibleThreadStateException,
+                                               InvocationException {
+        validateMirror(threadIntf);
+        validateMirror(methodIntf);
+        validateMirrorsOrNulls(origArguments);
+        MethodImpl method = (MethodImpl) methodIntf;
+        ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
+        validateMethodInvocation(method);
+        List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
+        ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
+        InvocationResult ret;
+        try {
+            PacketStream stream = sendInvokeCommand(thread, method, args, options);
+            ret = waitForReply(stream);
+        } catch (JDWPException exc) {
+            if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
+                throw new IncompatibleThreadStateException();
+            } else {
+                throw exc.toJDIException();
+            }
+        }
+        /*
+         * There is an implict VM-wide suspend at the conclusion
+         * of a normal (non-single-threaded) method invoke
+         */
+        if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
+            vm.notifySuspend();
+        }
+        if (ret.getException() != null) {
+            throw new InvocationException(ret.getException());
+        } else {
+            return ret.getResult();
+        }
+    }
+
+    @Override
+    boolean isAssignableTo(ReferenceType type) {
+        ClassTypeImpl superclazz = (ClassTypeImpl) superclass();
+        if (this.equals(type)) {
+            return true;
+        } else if ((superclazz != null) && superclazz.isAssignableTo(type)) {
+            return true;
+        } else {
+            List<InterfaceType> interfaces = interfaces();
+            Iterator<InterfaceType> iter = interfaces.iterator();
+            while (iter.hasNext()) {
+                InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next();
+                if (interfaze.isAssignableTo(type)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    @Override
+    final void addVisibleMethods(Map<String, Method> methodMap, Set<InterfaceType> seenInterfaces) {
+        /*
+         * Add methods from
+         * parent types first, so that the methods in this class will
+         * overwrite them in the hash table
+         */
+        Iterator<InterfaceType> iter = interfaces().iterator();
+        while (iter.hasNext()) {
+            InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next();
+            if (!seenInterfaces.contains(interfaze)) {
+                interfaze.addVisibleMethods(methodMap, seenInterfaces);
+                seenInterfaces.add(interfaze);
+            }
+        }
+        ClassTypeImpl clazz = (ClassTypeImpl) superclass();
+        if (clazz != null) {
+            clazz.addVisibleMethods(methodMap, seenInterfaces);
+        }
+        addToMethodMap(methodMap, methods());
+    }
+
+    final void addInterfaces(List<InterfaceType> list) {
+        List<InterfaceType> immediate = interfaces();
+        list.addAll(interfaces());
+        Iterator<InterfaceType> iter = immediate.iterator();
+        while (iter.hasNext()) {
+            InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next();
+            interfaze.addInterfaces(list);
+        }
+        ClassTypeImpl superclass = (ClassTypeImpl) superclass();
+        if (superclass != null) {
+            superclass.addInterfaces(list);
+        }
+    }
+
+    /**
+     * Returns all the implemented interfaces recursively
+     * @return A list of all the implemented interfaces (recursively)
+     */
+    final List<InterfaceType> getAllInterfaces() {
+        List<InterfaceType> all = new ArrayList<>();
+        addInterfaces(all);
+        return all;
+    }
+
+    /**
+     * Shared implementation of {@linkplain ClassType#allMethods()} and
+     * {@linkplain InterfaceType#allMethods()}
+     * @return A list of all methods (recursively)
+     */
+    public final List<Method> allMethods() {
+        ArrayList<Method> list = new ArrayList<>(methods());
+        ClassType clazz = superclass();
+        while (clazz != null) {
+            list.addAll(clazz.methods());
+            clazz = clazz.superclass();
+        }
+        /*
+         * Avoid duplicate checking on each method by iterating through
+         * duplicate-free allInterfaces() rather than recursing
+         */
+        for (InterfaceType interfaze : getAllInterfaces()) {
+            list.addAll(interfaze.methods());
+        }
+        return list;
+    }
+
+    @Override
+    final List<ReferenceType> inheritedTypes() {
+        List<ReferenceType> inherited = new ArrayList<>();
+        if (superclass() != null) {
+            inherited.add(0, superclass()); /* insert at front */
+        }
+        for (ReferenceType rt : interfaces()) {
+            inherited.add(rt);
+        }
+        return inherited;
+    }
+
+    private PacketStream sendInvokeCommand(final ThreadReferenceImpl thread,
+                                           final MethodImpl method,
+                                           final ValueImpl[] args,
+                                           final int options) {
+        CommandSender sender = getInvokeMethodSender(thread, method, args, options);
+        PacketStream stream;
+        if ((options & ClassType.INVOKE_SINGLE_THREADED) != 0) {
+            stream = thread.sendResumingCommand(sender);
+        } else {
+            stream = vm.sendResumingCommand(sender);
+        }
+        return stream;
+    }
+
+    private void validateMethodInvocation(Method method)
+                                            throws InvalidTypeException,
+                                                   InvocationException {
+        if (!canInvoke(method)) {
+            throw new IllegalArgumentException("Invalid method");
+        }
+        /*
+         * Method must be a static and not a static initializer
+         */
+        if (!method.isStatic()) {
+            throw new IllegalArgumentException("Cannot invoke instance method on a class/interface type");
+        } else if (method.isStaticInitializer()) {
+            throw new IllegalArgumentException("Cannot invoke static initializer");
+        }
+    }
+
+    /**
+     * A subclass will provide specific {@linkplain CommandSender}
+     * @param thread the current invocation thread
+     * @param method the method to invoke
+     * @param args the arguments to pass to the method
+     * @param options the integer bit flag options
+     * @return the specific {@literal CommandSender} instance
+     */
+    abstract CommandSender getInvokeMethodSender(ThreadReferenceImpl thread,
+                                                 MethodImpl method,
+                                                 ValueImpl[] args,
+                                                 int options);
+
+    /**
+     * Waits for the reply to the last sent command
+     * @param stream the stream to listen for the reply on
+     * @return the {@linkplain InvocationResult} instance
+     * @throws JDWPException when something goes wrong in JDWP
+     */
+    abstract InvocationResult waitForReply(PacketStream stream) throws JDWPException;
+
+    /**
+     * Get the {@linkplain ReferenceType} superclass
+     * @return the superclass or null
+     */
+    abstract ClassType superclass();
+
+    /**
+     * Get the implemented/extended interfaces
+     * @return the list of implemented/extended interfaces
+     */
+    abstract List<InterfaceType> interfaces();
+
+    /**
+     * Checks the provided method whether it can be invoked
+     * @param method the method to check
+     * @return {@code TRUE} if the implementation knows how to invoke the method,
+     *         {@code FALSE} otherwise
+     */
+    abstract boolean canInvoke(Method method);
+}
diff --git a/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java
index f63ad68..1d93f4c 100644
--- a/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java
+++ b/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java
@@ -187,6 +187,13 @@
         return isModifierSet(VMModifiers.ABSTRACT);
     }
 
+    public boolean isDefault() {
+        return !isModifierSet(VMModifiers.ABSTRACT) &&
+               !isModifierSet(VMModifiers.STATIC) &&
+               !isModifierSet(VMModifiers.PRIVATE) &&
+               declaringType() instanceof InterfaceType;
+    }
+
     public boolean isSynchronized() {
         return isModifierSet(VMModifiers.SYNCHRONIZED);
     }
diff --git a/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java
index 2b1b058..1d5a6c9 100644
--- a/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java
+++ b/jdk/src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java
@@ -277,7 +277,6 @@
     void validateMethodInvocation(Method method, int options)
                                          throws InvalidTypeException,
                                          InvocationException {
-
         /*
          * Method must be in this object's class, a superclass, or
          * implemented interface
@@ -287,6 +286,19 @@
             throw new IllegalArgumentException("Invalid method");
         }
 
+        if (declType instanceof ClassTypeImpl) {
+            validateClassMethodInvocation(method, options);
+        } else if (declType instanceof InterfaceTypeImpl) {
+            validateIfaceMethodInvocation(method, options);
+        } else {
+            throw new InvalidTypeException();
+        }
+    }
+
+    void validateClassMethodInvocation(Method method, int options)
+                                         throws InvalidTypeException,
+                                         InvocationException {
+
         ClassTypeImpl clazz = invokableReferenceType(method);
 
         /*
@@ -300,9 +312,7 @@
          * For nonvirtual invokes, method must have a body
          */
         if ((options & INVOKE_NONVIRTUAL) != 0) {
-            if (method.declaringType() instanceof InterfaceType) {
-                throw new IllegalArgumentException("Interface method");
-            } else if (method.isAbstract()) {
+            if (method.isAbstract()) {
                 throw new IllegalArgumentException("Abstract method");
             }
         }
@@ -324,7 +334,7 @@
              */
             Method invoker = clazz.concreteMethodByName(method.name(),
                                                         method.signature());
-            //  isAssignableFrom check above guarantees non-null
+            //  invoker is supposed to be non-null under normal circumstances
             invokedClass = (ClassTypeImpl)invoker.declaringType();
         }
         /* The above code is left over from previous versions.
@@ -332,6 +342,17 @@
          */
     }
 
+    void validateIfaceMethodInvocation(Method method, int options)
+                                         throws InvalidTypeException,
+                                         InvocationException {
+        /*
+         * Only default methods allowed for nonvirtual invokes
+         */
+        if (!method.isDefault()) {
+            throw new IllegalArgumentException("Not a default method");
+        }
+    }
+
     PacketStream sendInvokeCommand(final ThreadReferenceImpl thread,
                                    final ClassTypeImpl refType,
                                    final MethodImpl method,
@@ -370,7 +391,10 @@
         ThreadReferenceImpl thread = (ThreadReferenceImpl)threadIntf;
 
         if (method.isStatic()) {
-            if (referenceType() instanceof ClassType) {
+            if (referenceType() instanceof InterfaceType) {
+                InterfaceType type = (InterfaceType)referenceType();
+                return type.invokeMethod(thread, method, origArguments, options);
+            } else if (referenceType() instanceof ClassType) {
                 ClassType type = (ClassType)referenceType();
                 return type.invokeMethod(thread, method, origArguments, options);
             } else {
diff --git a/jdk/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java
index 29da75d..be98d5e 100644
--- a/jdk/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java
+++ b/jdk/src/share/classes/com/sun/tools/jdi/ReferenceTypeImpl.java
@@ -511,7 +511,7 @@
             methodMap.put(method.name().concat(method.signature()), method);
         }
 
-    abstract void addVisibleMethods(Map<String, Method> methodMap);
+    abstract void addVisibleMethods(Map<String, Method> methodMap, Set<InterfaceType> seenInterfaces);
 
     public List<Method> visibleMethods() {
         /*
@@ -520,7 +520,7 @@
          * concatenation of name and signature.
          */
         Map<String, Method> map = new HashMap<String, Method>();
-        addVisibleMethods(map);
+        addVisibleMethods(map, new HashSet<InterfaceType>());
 
         /*
          * ... but the hash map destroys order. Methods should be
diff --git a/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java b/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java
index e41b295..3704b41 100644
--- a/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java
+++ b/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java
@@ -48,7 +48,7 @@
     private ResourceBundle messages = null;
     private int vmSequenceNumber = 0;
     private static final int majorVersion = 1;
-    private static final int minorVersion = 6;
+    private static final int minorVersion = 8;
 
     private static final Object lock = new Object();
     private static VirtualMachineManagerImpl vmm;
diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java
index 2440baa..43c8c0e 100644
--- a/jdk/src/share/classes/java/lang/Class.java
+++ b/jdk/src/share/classes/java/lang/Class.java
@@ -260,8 +260,8 @@
     @CallerSensitive
     public static Class<?> forName(String className)
                 throws ClassNotFoundException {
-        return forName0(className, true,
-                        ClassLoader.getClassLoader(Reflection.getCallerClass()));
+        Class<?> caller = Reflection.getCallerClass();
+        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
     }
 
 
@@ -331,22 +331,27 @@
                                    ClassLoader loader)
         throws ClassNotFoundException
     {
-        if (sun.misc.VM.isSystemDomainLoader(loader)) {
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null) {
-                ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass());
+        Class<?> caller = null;
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            // Reflective call to get caller class is only needed if a security manager
+            // is present.  Avoid the overhead of making this call otherwise.
+            caller = Reflection.getCallerClass();
+            if (sun.misc.VM.isSystemDomainLoader(loader)) {
+                ClassLoader ccl = ClassLoader.getClassLoader(caller);
                 if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
                     sm.checkPermission(
                         SecurityConstants.GET_CLASSLOADER_PERMISSION);
                 }
             }
         }
-        return forName0(name, initialize, loader);
+        return forName0(name, initialize, loader, caller);
     }
 
-    /** Called after security checks have been made. */
+    /** Called after security check for system loader access checks have been made. */
     private static native Class<?> forName0(String name, boolean initialize,
-                                            ClassLoader loader)
+                                            ClassLoader loader,
+                                            Class<?> caller)
         throws ClassNotFoundException;
 
     /**
diff --git a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
index da78e44..cdbbebc 100644
--- a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
+++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
@@ -62,7 +62,7 @@
     private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";";
 
     /** Name of its super class*/
-    private static final String superName = LF;
+    private static final String superName = OBJ;
 
     /** Name of new class */
     private final String className;
@@ -97,7 +97,7 @@
         if (DUMP_CLASS_FILES) {
             className = makeDumpableClassName(className);
         }
-        this.className  = superName + "$" + className;
+        this.className  = LF + "$" + className;
         this.sourceFile = "LambdaForm$" + className;
         this.lambdaForm = lambdaForm;
         this.invokerName = invokerName;
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodType.java b/jdk/src/share/classes/java/lang/invoke/MethodType.java
index e96b70e..96d692f 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodType.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodType.java
@@ -726,7 +726,7 @@
      * @return the parameter types (as an immutable list)
      */
     public List<Class<?>> parameterList() {
-        return Collections.unmodifiableList(Arrays.asList(ptypes));
+        return Collections.unmodifiableList(Arrays.asList(ptypes.clone()));
     }
 
     /*non-public*/ Class<?> lastParameterType() {
diff --git a/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java b/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java
index 555ca84..1793cfc 100644
--- a/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java
+++ b/jdk/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java
@@ -68,6 +68,7 @@
                     return null;
                 }
             });
+        init();
     }
 
     /**
@@ -362,4 +363,7 @@
     protected boolean nativeConnectDisabled() {
         return connectDisabled;
     }
+
+    native int dataAvailable();
+    private static native void init();
 }
diff --git a/jdk/src/share/classes/java/net/DatagramSocket.java b/jdk/src/share/classes/java/net/DatagramSocket.java
index 54799a8..2fdabb5 100644
--- a/jdk/src/share/classes/java/net/DatagramSocket.java
+++ b/jdk/src/share/classes/java/net/DatagramSocket.java
@@ -83,6 +83,17 @@
      */
     boolean oldImpl = false;
 
+    /**
+     * Set when a socket is ST_CONNECTED until we are certain
+     * that any packets which might have been received prior
+     * to calling connect() but not read by the application
+     * have been read. During this time we check the source
+     * address of all packets received to be sure they are from
+     * the connected destination. Other packets are read but
+     * silently dropped.
+     */
+    private boolean explicitFilter = false;
+    private int bytesLeftToFilter;
     /*
      * Connection state:
      * ST_NOT_CONNECTED = socket not connected
@@ -142,6 +153,15 @@
 
                 // socket is now connected by the impl
                 connectState = ST_CONNECTED;
+                // Do we need to filter some packets?
+                int avail = getImpl().dataAvailable();
+                if (avail == -1) {
+                    throw new SocketException();
+                }
+                explicitFilter = avail > 0;
+                if (explicitFilter) {
+                    bytesLeftToFilter = getReceiveBufferSize();
+                }
             } catch (SocketException se) {
 
                 // connection will be emulated by DatagramSocket
@@ -490,6 +510,7 @@
             connectedAddress = null;
             connectedPort = -1;
             connectState = ST_NOT_CONNECTED;
+            explicitFilter = false;
         }
     }
 
@@ -748,10 +769,13 @@
                     } // end of while
                 }
             }
-            if (connectState == ST_CONNECTED_NO_IMPL) {
+            DatagramPacket tmp = null;
+            if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) {
                 // We have to do the filtering the old fashioned way since
                 // the native impl doesn't support connect or the connect
-                // via the impl failed.
+                // via the impl failed, or .. "explicitFilter" may be set when
+                // a socket is connected via the impl, for a period of time
+                // when packets from other sources might be queued on socket.
                 boolean stop = false;
                 while (!stop) {
                     InetAddress peekAddress = null;
@@ -770,8 +794,14 @@
                     if ((!connectedAddress.equals(peekAddress)) ||
                         (connectedPort != peekPort)) {
                         // throw the packet away and silently continue
-                        DatagramPacket tmp = new DatagramPacket(new byte[1], 1);
+                        tmp = new DatagramPacket(
+                                                new byte[1024], 1024);
                         getImpl().receive(tmp);
+                        if (explicitFilter) {
+                            if (checkFiltering(tmp)) {
+                                stop = true;
+                            }
+                        }
                     } else {
                         stop = true;
                     }
@@ -780,9 +810,22 @@
             // If the security check succeeds, or the datagram is
             // connected then receive the packet
             getImpl().receive(p);
+            if (explicitFilter && tmp == null) {
+                // packet was not filtered, account for it here
+                checkFiltering(p);
+            }
         }
     }
 
+    private boolean checkFiltering(DatagramPacket p) throws SocketException {
+        bytesLeftToFilter -= p.getLength();
+        if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) {
+            explicitFilter = false;
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Gets the local address to which the socket is bound.
      *
diff --git a/jdk/src/share/classes/java/net/DatagramSocketImpl.java b/jdk/src/share/classes/java/net/DatagramSocketImpl.java
index c2b1158..537edfe 100644
--- a/jdk/src/share/classes/java/net/DatagramSocketImpl.java
+++ b/jdk/src/share/classes/java/net/DatagramSocketImpl.java
@@ -47,6 +47,12 @@
      */
     protected FileDescriptor fd;
 
+    int dataAvailable() {
+        // default impl returns zero, which disables the calling
+        // functionality
+        return 0;
+    }
+
     /**
      * The DatagramSocket or MulticastSocket
      * that owns this impl
diff --git a/jdk/src/share/classes/java/net/URLClassLoader.java b/jdk/src/share/classes/java/net/URLClassLoader.java
index c88c707..a75ac30 100644
--- a/jdk/src/share/classes/java/net/URLClassLoader.java
+++ b/jdk/src/share/classes/java/net/URLClassLoader.java
@@ -354,10 +354,11 @@
      * @exception NullPointerException if {@code name} is {@code null}.
      */
     protected Class<?> findClass(final String name)
-         throws ClassNotFoundException
+        throws ClassNotFoundException
     {
+        final Class<?> result;
         try {
-            return AccessController.doPrivileged(
+            result = AccessController.doPrivileged(
                 new PrivilegedExceptionAction<Class<?>>() {
                     public Class<?> run() throws ClassNotFoundException {
                         String path = name.replace('.', '/').concat(".class");
@@ -369,13 +370,17 @@
                                 throw new ClassNotFoundException(name, e);
                             }
                         } else {
-                            throw new ClassNotFoundException(name);
+                            return null;
                         }
                     }
                 }, acc);
         } catch (java.security.PrivilegedActionException pae) {
             throw (ClassNotFoundException) pae.getException();
         }
+        if (result == null) {
+            throw new ClassNotFoundException(name);
+        }
+        return result;
     }
 
     /*
diff --git a/jdk/src/share/classes/java/security/KeyPairGenerator.java b/jdk/src/share/classes/java/security/KeyPairGenerator.java
index c09d251..2056768 100644
--- a/jdk/src/share/classes/java/security/KeyPairGenerator.java
+++ b/jdk/src/share/classes/java/security/KeyPairGenerator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -33,6 +33,7 @@
 
 import sun.security.jca.*;
 import sun.security.jca.GetInstance.Instance;
+import sun.security.util.Debug;
 
 /**
  * The KeyPairGenerator class is used to generate pairs of
@@ -126,6 +127,11 @@
 
 public abstract class KeyPairGenerator extends KeyPairGeneratorSpi {
 
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("keypairgenerator");
+
     private final String algorithm;
 
     // The provider
@@ -167,6 +173,12 @@
             kpg = new Delegate(spi, algorithm);
         }
         kpg.provider = instance.provider;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("KeyPairGenerator." + algorithm +
+                " algorithm from: " + kpg.provider.getName());
+        }
+
         return kpg;
     }
 
@@ -557,6 +569,11 @@
             provider = instance.provider;
             this.serviceIterator = serviceIterator;
             initType = I_NONE;
+
+            if (!skipDebug && pdebug != null) {
+                pdebug.println("KeyPairGenerator." + algorithm +
+                    " algorithm from: " + provider.getName());
+            }
         }
 
         /**
diff --git a/jdk/src/share/classes/java/security/KeyStore.java b/jdk/src/share/classes/java/security/KeyStore.java
index 80bf17d..4278369 100644
--- a/jdk/src/share/classes/java/security/KeyStore.java
+++ b/jdk/src/share/classes/java/security/KeyStore.java
@@ -37,6 +37,8 @@
 import javax.security.auth.DestroyFailedException;
 import javax.security.auth.callback.*;
 
+import sun.security.util.Debug;
+
 /**
  * This class represents a storage facility for cryptographic
  * keys and certificates.
@@ -177,6 +179,11 @@
 
 public class KeyStore {
 
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("keystore");
+
     /*
      * Constant to lookup in the Security properties file to determine
      * the default keystore type.
@@ -801,6 +808,11 @@
         this.keyStoreSpi = keyStoreSpi;
         this.provider = provider;
         this.type = type;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("KeyStore." + type.toUpperCase() + " type from: " +
+                this.provider.getName());
+        }
     }
 
     /**
diff --git a/jdk/src/share/classes/java/security/MessageDigest.java b/jdk/src/share/classes/java/security/MessageDigest.java
index 60d41ff..cf3e3a3 100644
--- a/jdk/src/share/classes/java/security/MessageDigest.java
+++ b/jdk/src/share/classes/java/security/MessageDigest.java
@@ -35,6 +35,8 @@
 
 import java.nio.ByteBuffer;
 
+import sun.security.util.Debug;
+
 /**
  * This MessageDigest class provides applications the functionality of a
  * message digest algorithm, such as SHA-1 or SHA-256.
@@ -103,6 +105,11 @@
 
 public abstract class MessageDigest extends MessageDigestSpi {
 
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("messagedigest");
+
     private String algorithm;
 
     // The state of this digest
@@ -156,18 +163,23 @@
     public static MessageDigest getInstance(String algorithm)
     throws NoSuchAlgorithmException {
         try {
+            MessageDigest md;
             Object[] objs = Security.getImpl(algorithm, "MessageDigest",
                                              (String)null);
             if (objs[0] instanceof MessageDigest) {
-                MessageDigest md = (MessageDigest)objs[0];
-                md.provider = (Provider)objs[1];
-                return md;
+                md = (MessageDigest)objs[0];
             } else {
-                MessageDigest delegate =
-                    new Delegate((MessageDigestSpi)objs[0], algorithm);
-                delegate.provider = (Provider)objs[1];
-                return delegate;
+                md = new Delegate((MessageDigestSpi)objs[0], algorithm);
             }
+            md.provider = (Provider)objs[1];
+
+            if (!skipDebug && pdebug != null) {
+                pdebug.println("MessageDigest." + algorithm +
+                    " algorithm from: " + md.provider.getName());
+            }
+
+            return md;
+
         } catch(NoSuchProviderException e) {
             throw new NoSuchAlgorithmException(algorithm + " not found");
         }
diff --git a/jdk/src/share/classes/java/security/SecureRandom.java b/jdk/src/share/classes/java/security/SecureRandom.java
index b9ae722..3481e21 100644
--- a/jdk/src/share/classes/java/security/SecureRandom.java
+++ b/jdk/src/share/classes/java/security/SecureRandom.java
@@ -32,6 +32,7 @@
 
 import sun.security.jca.*;
 import sun.security.jca.GetInstance.Instance;
+import sun.security.util.Debug;
 
 /**
  * This class provides a cryptographically strong random number
@@ -92,6 +93,11 @@
 
 public class SecureRandom extends java.util.Random {
 
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("securerandom");
+
     /**
      * The provider.
      *
@@ -234,6 +240,11 @@
         this.secureRandomSpi = secureRandomSpi;
         this.provider = provider;
         this.algorithm = algorithm;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("SecureRandom." + algorithm +
+                " algorithm from: " + this.provider.getName());
+        }
     }
 
     /**
diff --git a/jdk/src/share/classes/java/security/Signature.java b/jdk/src/share/classes/java/security/Signature.java
index 7c5bd96..dccbe0b 100644
--- a/jdk/src/share/classes/java/security/Signature.java
+++ b/jdk/src/share/classes/java/security/Signature.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -121,6 +121,11 @@
     private static final Debug debug =
                         Debug.getInstance("jca", "Signature");
 
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("signature");
+
     /*
      * The algorithm for this signature object.
      * This value is used to map an OID to the particular algorithm.
@@ -451,6 +456,11 @@
             throws InvalidKeyException {
         engineInitVerify(publicKey);
         state = VERIFY;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Signature." + algorithm +
+                " verification algorithm from: " + this.provider.getName());
+        }
     }
 
     /**
@@ -495,6 +505,11 @@
         PublicKey publicKey = certificate.getPublicKey();
         engineInitVerify(publicKey);
         state = VERIFY;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Signature." + algorithm +
+                " verification algorithm from: " + this.provider.getName());
+        }
     }
 
     /**
@@ -511,6 +526,11 @@
             throws InvalidKeyException {
         engineInitSign(privateKey);
         state = SIGN;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Signature." + algorithm +
+                " signing algorithm from: " + this.provider.getName());
+        }
     }
 
     /**
@@ -529,6 +549,11 @@
             throws InvalidKeyException {
         engineInitSign(privateKey, random);
         state = SIGN;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Signature." + algorithm +
+                " signing algorithm from: " + this.provider.getName());
+        }
     }
 
     /**
@@ -590,6 +615,9 @@
         if (outbuf == null) {
             throw new IllegalArgumentException("No output buffer given");
         }
+        if (offset < 0 || len < 0) {
+            throw new IllegalArgumentException("offset or len is less than 0");
+        }
         if (outbuf.length - offset < len) {
             throw new IllegalArgumentException
                 ("Output buffer too small for specified offset and length");
@@ -658,9 +686,16 @@
     public final boolean verify(byte[] signature, int offset, int length)
         throws SignatureException {
         if (state == VERIFY) {
-            if ((signature == null) || (offset < 0) || (length < 0) ||
-                (length > signature.length - offset)) {
-                throw new IllegalArgumentException("Bad arguments");
+            if (signature == null) {
+                throw new IllegalArgumentException("signature is null");
+            }
+            if (offset < 0 || length < 0) {
+                throw new IllegalArgumentException
+                    ("offset or length is less than 0");
+            }
+            if (signature.length - offset < length) {
+                throw new IllegalArgumentException
+                    ("signature too small for specified offset and length");
             }
 
             return engineVerify(signature, offset, length);
@@ -713,6 +748,16 @@
     public final void update(byte[] data, int off, int len)
             throws SignatureException {
         if (state == SIGN || state == VERIFY) {
+            if (data == null) {
+                throw new IllegalArgumentException("data is null");
+            }
+            if (off < 0 || len < 0) {
+                throw new IllegalArgumentException("off or len is less than 0");
+            }
+            if (data.length - off < len) {
+                throw new IllegalArgumentException
+                    ("data too small for specified offset and length");
+            }
             engineUpdate(data, off, len);
         } else {
             throw new SignatureException("object not initialized for "
diff --git a/jdk/src/share/classes/java/security/cert/CertificateRevokedException.java b/jdk/src/share/classes/java/security/cert/CertificateRevokedException.java
index a545627..505a007 100644
--- a/jdk/src/share/classes/java/security/cert/CertificateRevokedException.java
+++ b/jdk/src/share/classes/java/security/cert/CertificateRevokedException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -94,7 +94,10 @@
         this.revocationDate = new Date(revocationDate.getTime());
         this.reason = reason;
         this.authority = authority;
-        this.extensions = new HashMap<String, Extension>(extensions);
+        // make sure Map only contains correct types
+        this.extensions = Collections.checkedMap(new HashMap<>(),
+                                                 String.class, Extension.class);
+        this.extensions.putAll(extensions);
     }
 
     /**
@@ -172,7 +175,8 @@
     public String getMessage() {
         return "Certificate has been revoked, reason: "
                + reason + ", revocation date: " + revocationDate
-               + ", authority: " + authority + ", extensions: " + extensions;
+               + ", authority: " + authority + ", extension OIDs: "
+               + extensions.keySet();
     }
 
     /**
diff --git a/jdk/src/share/classes/java/util/ResourceBundle.java b/jdk/src/share/classes/java/util/ResourceBundle.java
index d70b61a..134894c 100644
--- a/jdk/src/share/classes/java/util/ResourceBundle.java
+++ b/jdk/src/share/classes/java/util/ResourceBundle.java
@@ -2650,7 +2650,10 @@
                 } catch (ClassNotFoundException e) {
                 }
             } else if (format.equals("java.properties")) {
-                final String resourceName = toResourceName(bundleName, "properties");
+                final String resourceName = toResourceName0(bundleName, "properties");
+                if (resourceName == null) {
+                    return bundle;
+                }
                 final ClassLoader classLoader = loader;
                 final boolean reloadFlag = reload;
                 InputStream stream = null;
@@ -2804,7 +2807,10 @@
             }
             boolean result = false;
             try {
-                String resourceName = toResourceName(toBundleName(baseName, locale), format);
+                String resourceName = toResourceName0(toBundleName(baseName, locale), format);
+                if (resourceName == null) {
+                    return result;
+                }
                 URL url = loader.getResource(resourceName);
                 if (url != null) {
                     long lastModified = 0;
@@ -2938,6 +2944,15 @@
             sb.append(bundleName.replace('.', '/')).append('.').append(suffix);
             return sb.toString();
         }
+
+        private String toResourceName0(String bundleName, String suffix) {
+            // application protocol check
+            if (bundleName.contains("://")) {
+                return null;
+            } else {
+                return toResourceName(bundleName, suffix);
+            }
+        }
     }
 
     private static class SingleFormatControl extends Control {
diff --git a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java
index 9f5e149..8b6ed6d 100644
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinPool.java
@@ -49,6 +49,7 @@
 import java.util.concurrent.RunnableFuture;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
 import java.security.AccessControlContext;
 import java.security.ProtectionDomain;
 import java.security.Permissions;
@@ -80,9 +81,9 @@
  *
  * <p>For applications that require separate or custom pools, a {@code
  * ForkJoinPool} may be constructed with a given target parallelism
- * level; by default, equal to the number of available processors. The
- * pool attempts to maintain enough active (or available) threads by
- * dynamically adding, suspending, or resuming internal worker
+ * level; by default, equal to the number of available processors.
+ * The pool attempts to maintain enough active (or available) threads
+ * by dynamically adding, suspending, or resuming internal worker
  * threads, even if some tasks are stalled waiting to join others.
  * However, no such adjustments are guaranteed in the face of blocked
  * I/O or other unmanaged synchronization. The nested {@link
@@ -178,7 +179,14 @@
      * that may be stolen by other workers.  Preference rules give
      * first priority to processing tasks from their own queues (LIFO
      * or FIFO, depending on mode), then to randomized FIFO steals of
-     * tasks in other queues.
+     * tasks in other queues.  This framework began as vehicle for
+     * supporting tree-structured parallelism using work-stealing.
+     * Over time, its scalability advantages led to extensions and
+     * changes to better support more diverse usage contexts.  Because
+     * most internal methods and nested classes are interrelated,
+     * their main rationale and descriptions are presented here;
+     * individual methods and nested classes contain only brief
+     * comments about details.
      *
      * WorkQueues
      * ==========
@@ -198,201 +206,318 @@
      * (http://research.sun.com/scalable/pubs/index.html) and
      * "Idempotent work stealing" by Michael, Saraswat, and Vechev,
      * PPoPP 2009 (http://portal.acm.org/citation.cfm?id=1504186).
-     * See also "Correct and Efficient Work-Stealing for Weak Memory
-     * Models" by Le, Pop, Cohen, and Nardelli, PPoPP 2013
-     * (http://www.di.ens.fr/~zappa/readings/ppopp13.pdf) for an
-     * analysis of memory ordering (atomic, volatile etc) issues.  The
-     * main differences ultimately stem from GC requirements that we
-     * null out taken slots as soon as we can, to maintain as small a
-     * footprint as possible even in programs generating huge numbers
-     * of tasks. To accomplish this, we shift the CAS arbitrating pop
-     * vs poll (steal) from being on the indices ("base" and "top") to
-     * the slots themselves.  So, both a successful pop and poll
-     * mainly entail a CAS of a slot from non-null to null.  Because
-     * we rely on CASes of references, we do not need tag bits on base
-     * or top.  They are simple ints as used in any circular
+     * The main differences ultimately stem from GC requirements that
+     * we null out taken slots as soon as we can, to maintain as small
+     * a footprint as possible even in programs generating huge
+     * numbers of tasks. To accomplish this, we shift the CAS
+     * arbitrating pop vs poll (steal) from being on the indices
+     * ("base" and "top") to the slots themselves.
+     *
+     * Adding tasks then takes the form of a classic array push(task):
+     *    q.array[q.top] = task; ++q.top;
+     *
+     * (The actual code needs to null-check and size-check the array,
+     * properly fence the accesses, and possibly signal waiting
+     * workers to start scanning -- see below.)  Both a successful pop
+     * and poll mainly entail a CAS of a slot from non-null to null.
+     *
+     * The pop operation (always performed by owner) is:
+     *   if ((base != top) and
+     *        (the task at top slot is not null) and
+     *        (CAS slot to null))
+     *           decrement top and return task;
+     *
+     * And the poll operation (usually by a stealer) is
+     *    if ((base != top) and
+     *        (the task at base slot is not null) and
+     *        (base has not changed) and
+     *        (CAS slot to null))
+     *           increment base and return task;
+     *
+     * Because we rely on CASes of references, we do not need tag bits
+     * on base or top.  They are simple ints as used in any circular
      * array-based queue (see for example ArrayDeque).  Updates to the
-     * indices must still be ordered in a way that guarantees that top
-     * == base means the queue is empty, but otherwise may err on the
-     * side of possibly making the queue appear nonempty when a push,
-     * pop, or poll have not fully committed. Note that this means
-     * that the poll operation, considered individually, is not
-     * wait-free. One thief cannot successfully continue until another
-     * in-progress one (or, if previously empty, a push) completes.
-     * However, in the aggregate, we ensure at least probabilistic
+     * indices guarantee that top == base means the queue is empty,
+     * but otherwise may err on the side of possibly making the queue
+     * appear nonempty when a push, pop, or poll have not fully
+     * committed. (Method isEmpty() checks the case of a partially
+     * completed removal of the last element.)  Because of this, the
+     * poll operation, considered individually, is not wait-free. One
+     * thief cannot successfully continue until another in-progress
+     * one (or, if previously empty, a push) completes.  However, in
+     * the aggregate, we ensure at least probabilistic
      * non-blockingness.  If an attempted steal fails, a thief always
      * chooses a different random victim target to try next. So, in
      * order for one thief to progress, it suffices for any
      * in-progress poll or new push on any empty queue to
      * complete. (This is why we normally use method pollAt and its
      * variants that try once at the apparent base index, else
-     * consider alternative actions, rather than method poll.)
+     * consider alternative actions, rather than method poll, which
+     * retries.)
      *
-     * This approach also enables support of a user mode in which local
-     * task processing is in FIFO, not LIFO order, simply by using
-     * poll rather than pop.  This can be useful in message-passing
-     * frameworks in which tasks are never joined.  However neither
-     * mode considers affinities, loads, cache localities, etc, so
-     * rarely provide the best possible performance on a given
-     * machine, but portably provide good throughput by averaging over
-     * these factors.  (Further, even if we did try to use such
-     * information, we do not usually have a basis for exploiting it.
-     * For example, some sets of tasks profit from cache affinities,
-     * but others are harmed by cache pollution effects.)
+     * This approach also enables support of a user mode in which
+     * local task processing is in FIFO, not LIFO order, simply by
+     * using poll rather than pop.  This can be useful in
+     * message-passing frameworks in which tasks are never joined.
+     * However neither mode considers affinities, loads, cache
+     * localities, etc, so rarely provide the best possible
+     * performance on a given machine, but portably provide good
+     * throughput by averaging over these factors.  Further, even if
+     * we did try to use such information, we do not usually have a
+     * basis for exploiting it.  For example, some sets of tasks
+     * profit from cache affinities, but others are harmed by cache
+     * pollution effects. Additionally, even though it requires
+     * scanning, long-term throughput is often best using random
+     * selection rather than directed selection policies, so cheap
+     * randomization of sufficient quality is used whenever
+     * applicable.  Various Marsaglia XorShifts (some with different
+     * shift constants) are inlined at use points.
      *
      * WorkQueues are also used in a similar way for tasks submitted
      * to the pool. We cannot mix these tasks in the same queues used
-     * for work-stealing (this would contaminate lifo/fifo
-     * processing). Instead, we randomly associate submission queues
+     * by workers. Instead, we randomly associate submission queues
      * with submitting threads, using a form of hashing.  The
      * ThreadLocalRandom probe value serves as a hash code for
      * choosing existing queues, and may be randomly repositioned upon
      * contention with other submitters.  In essence, submitters act
      * like workers except that they are restricted to executing local
      * tasks that they submitted (or in the case of CountedCompleters,
-     * others with the same root task).  However, because most
-     * shared/external queue operations are more expensive than
-     * internal, and because, at steady state, external submitters
-     * will compete for CPU with workers, ForkJoinTask.join and
-     * related methods disable them from repeatedly helping to process
-     * tasks if all workers are active.  Insertion of tasks in shared
+     * others with the same root task).  Insertion of tasks in shared
      * mode requires a lock (mainly to protect in the case of
-     * resizing) but we use only a simple spinlock (using bits in
-     * field qlock), because submitters encountering a busy queue move
-     * on to try or create other queues -- they block only when
-     * creating and registering new queues.
+     * resizing) but we use only a simple spinlock (using field
+     * qlock), because submitters encountering a busy queue move on to
+     * try or create other queues -- they block only when creating and
+     * registering new queues. Additionally, "qlock" saturates to an
+     * unlockable value (-1) at shutdown. Unlocking still can be and
+     * is performed by cheaper ordered writes of "qlock" in successful
+     * cases, but uses CAS in unsuccessful cases.
      *
      * Management
      * ==========
      *
      * The main throughput advantages of work-stealing stem from
      * decentralized control -- workers mostly take tasks from
-     * themselves or each other. We cannot negate this in the
-     * implementation of other management responsibilities. The main
-     * tactic for avoiding bottlenecks is packing nearly all
-     * essentially atomic control state into two volatile variables
-     * that are by far most often read (not written) as status and
-     * consistency checks.
+     * themselves or each other, at rates that can exceed a billion
+     * per second.  The pool itself creates, activates (enables
+     * scanning for and running tasks), deactivates, blocks, and
+     * terminates threads, all with minimal central information.
+     * There are only a few properties that we can globally track or
+     * maintain, so we pack them into a small number of variables,
+     * often maintaining atomicity without blocking or locking.
+     * Nearly all essentially atomic control state is held in two
+     * volatile variables that are by far most often read (not
+     * written) as status and consistency checks. (Also, field
+     * "config" holds unchanging configuration state.)
      *
-     * Field "ctl" contains 64 bits holding all the information needed
-     * to atomically decide to add, inactivate, enqueue (on an event
+     * Field "ctl" contains 64 bits holding information needed to
+     * atomically decide to add, inactivate, enqueue (on an event
      * queue), dequeue, and/or re-activate workers.  To enable this
      * packing, we restrict maximum parallelism to (1<<15)-1 (which is
      * far in excess of normal operating range) to allow ids, counts,
      * and their negations (used for thresholding) to fit into 16bit
-     * fields.
+     * subfields.
      *
-     * Field "plock" is a form of sequence lock with a saturating
-     * shutdown bit (similarly for per-queue "qlocks"), mainly
-     * protecting updates to the workQueues array, as well as to
-     * enable shutdown.  When used as a lock, it is normally only very
-     * briefly held, so is nearly always available after at most a
-     * brief spin, but we use a monitor-based backup strategy to
-     * block when needed.
+     * Field "runState" holds lockable state bits (STARTED, STOP, etc)
+     * also protecting updates to the workQueues array.  When used as
+     * a lock, it is normally held only for a few instructions (the
+     * only exceptions are one-time array initialization and uncommon
+     * resizing), so is nearly always available after at most a brief
+     * spin. But to be extra-cautious, after spinning, method
+     * awaitRunStateLock (called only if an initial CAS fails), uses a
+     * wait/notify mechanics on a builtin monitor to block when
+     * (rarely) needed. This would be a terrible idea for a highly
+     * contended lock, but most pools run without the lock ever
+     * contending after the spin limit, so this works fine as a more
+     * conservative alternative. Because we don't otherwise have an
+     * internal Object to use as a monitor, the "stealCounter" (an
+     * AtomicLong) is used when available (it too must be lazily
+     * initialized; see externalSubmit).
+     *
+     * Usages of "runState" vs "ctl" interact in only one case:
+     * deciding to add a worker thread (see tryAddWorker), in which
+     * case the ctl CAS is performed while the lock is held.
      *
      * Recording WorkQueues.  WorkQueues are recorded in the
-     * "workQueues" array that is created upon first use and expanded
-     * if necessary.  Updates to the array while recording new workers
-     * and unrecording terminated ones are protected from each other
-     * by a lock but the array is otherwise concurrently readable, and
-     * accessed directly.  To simplify index-based operations, the
-     * array size is always a power of two, and all readers must
-     * tolerate null slots. Worker queues are at odd indices. Shared
-     * (submission) queues are at even indices, up to a maximum of 64
-     * slots, to limit growth even if array needs to expand to add
-     * more workers. Grouping them together in this way simplifies and
-     * speeds up task scanning.
+     * "workQueues" array. The array is created upon first use (see
+     * externalSubmit) and expanded if necessary.  Updates to the
+     * array while recording new workers and unrecording terminated
+     * ones are protected from each other by the runState lock, but
+     * the array is otherwise concurrently readable, and accessed
+     * directly. We also ensure that reads of the array reference
+     * itself never become too stale. To simplify index-based
+     * operations, the array size is always a power of two, and all
+     * readers must tolerate null slots. Worker queues are at odd
+     * indices. Shared (submission) queues are at even indices, up to
+     * a maximum of 64 slots, to limit growth even if array needs to
+     * expand to add more workers. Grouping them together in this way
+     * simplifies and speeds up task scanning.
      *
      * All worker thread creation is on-demand, triggered by task
      * submissions, replacement of terminated workers, and/or
      * compensation for blocked workers. However, all other support
      * code is set up to work with other policies.  To ensure that we
-     * do not hold on to worker references that would prevent GC, ALL
+     * do not hold on to worker references that would prevent GC, All
      * accesses to workQueues are via indices into the workQueues
      * array (which is one source of some of the messy code
      * constructions here). In essence, the workQueues array serves as
-     * a weak reference mechanism. Thus for example the wait queue
-     * field of ctl stores indices, not references.  Access to the
-     * workQueues in associated methods (for example signalWork) must
-     * both index-check and null-check the IDs. All such accesses
-     * ignore bad IDs by returning out early from what they are doing,
-     * since this can only be associated with termination, in which
-     * case it is OK to give up.  All uses of the workQueues array
-     * also check that it is non-null (even if previously
-     * non-null). This allows nulling during termination, which is
-     * currently not necessary, but remains an option for
-     * resource-revocation-based shutdown schemes. It also helps
-     * reduce JIT issuance of uncommon-trap code, which tends to
-     * unnecessarily complicate control flow in some methods.
+     * a weak reference mechanism. Thus for example the stack top
+     * subfield of ctl stores indices, not references.
      *
-     * Event Queuing. Unlike HPC work-stealing frameworks, we cannot
-     * let workers spin indefinitely scanning for tasks when none can
-     * be found immediately, and we cannot start/resume workers unless
-     * there appear to be tasks available.  On the other hand, we must
-     * quickly prod them into action when new tasks are submitted or
-     * generated. In many usages, ramp-up time to activate workers is
-     * the main limiting factor in overall performance (this is
-     * compounded at program start-up by JIT compilation and
-     * allocation). So we try to streamline this as much as possible.
-     * We park/unpark workers after placing in an event wait queue
-     * when they cannot find work. This "queue" is actually a simple
-     * Treiber stack, headed by the "id" field of ctl, plus a 15bit
-     * counter value (that reflects the number of times a worker has
-     * been inactivated) to avoid ABA effects (we need only as many
-     * version numbers as worker threads). Successors are held in
-     * field WorkQueue.nextWait.  Queuing deals with several intrinsic
-     * races, mainly that a task-producing thread can miss seeing (and
-     * signalling) another thread that gave up looking for work but
-     * has not yet entered the wait queue. We solve this by requiring
-     * a full sweep of all workers (via repeated calls to method
-     * scan()) both before and after a newly waiting worker is added
-     * to the wait queue.  Because enqueued workers may actually be
-     * rescanning rather than waiting, we set and clear the "parker"
+     * Queuing Idle Workers. Unlike HPC work-stealing frameworks, we
+     * cannot let workers spin indefinitely scanning for tasks when
+     * none can be found immediately, and we cannot start/resume
+     * workers unless there appear to be tasks available.  On the
+     * other hand, we must quickly prod them into action when new
+     * tasks are submitted or generated. In many usages, ramp-up time
+     * to activate workers is the main limiting factor in overall
+     * performance, which is compounded at program start-up by JIT
+     * compilation and allocation. So we streamline this as much as
+     * possible.
+     *
+     * The "ctl" field atomically maintains active and total worker
+     * counts as well as a queue to place waiting threads so they can
+     * be located for signalling. Active counts also play the role of
+     * quiescence indicators, so are decremented when workers believe
+     * that there are no more tasks to execute. The "queue" is
+     * actually a form of Treiber stack.  A stack is ideal for
+     * activating threads in most-recently used order. This improves
+     * performance and locality, outweighing the disadvantages of
+     * being prone to contention and inability to release a worker
+     * unless it is topmost on stack.  We park/unpark workers after
+     * pushing on the idle worker stack (represented by the lower
+     * 32bit subfield of ctl) when they cannot find work.  The top
+     * stack state holds the value of the "scanState" field of the
+     * worker: its index and status, plus a version counter that, in
+     * addition to the count subfields (also serving as version
+     * stamps) provide protection against Treiber stack ABA effects.
+     *
+     * Field scanState is used by both workers and the pool to manage
+     * and track whether a worker is INACTIVE (possibly blocked
+     * waiting for a signal), or SCANNING for tasks (when neither hold
+     * it is busy running tasks).  When a worker is inactivated, its
+     * scanState field is set, and is prevented from executing tasks,
+     * even though it must scan once for them to avoid queuing
+     * races. Note that scanState updates lag queue CAS releases so
+     * usage requires care. When queued, the lower 16 bits of
+     * scanState must hold its pool index. So we place the index there
+     * upon initialization (see registerWorker) and otherwise keep it
+     * there or restore it when necessary.
+     *
+     * Memory ordering.  See "Correct and Efficient Work-Stealing for
+     * Weak Memory Models" by Le, Pop, Cohen, and Nardelli, PPoPP 2013
+     * (http://www.di.ens.fr/~zappa/readings/ppopp13.pdf) for an
+     * analysis of memory ordering requirements in work-stealing
+     * algorithms similar to the one used here.  We usually need
+     * stronger than minimal ordering because we must sometimes signal
+     * workers, requiring Dekker-like full-fences to avoid lost
+     * signals.  Arranging for enough ordering without expensive
+     * over-fencing requires tradeoffs among the supported means of
+     * expressing access constraints. The most central operations,
+     * taking from queues and updating ctl state, require full-fence
+     * CAS.  Array slots are read using the emulation of volatiles
+     * provided by Unsafe.  Access from other threads to WorkQueue
+     * base, top, and array requires a volatile load of the first of
+     * any of these read.  We use the convention of declaring the
+     * "base" index volatile, and always read it before other fields.
+     * The owner thread must ensure ordered updates, so writes use
+     * ordered intrinsics unless they can piggyback on those for other
+     * writes.  Similar conventions and rationales hold for other
+     * WorkQueue fields (such as "currentSteal") that are only written
+     * by owners but observed by others.
+     *
+     * Creating workers. To create a worker, we pre-increment total
+     * count (serving as a reservation), and attempt to construct a
+     * ForkJoinWorkerThread via its factory. Upon construction, the
+     * new thread invokes registerWorker, where it constructs a
+     * WorkQueue and is assigned an index in the workQueues array
+     * (expanding the array if necessary). The thread is then
+     * started. Upon any exception across these steps, or null return
+     * from factory, deregisterWorker adjusts counts and records
+     * accordingly.  If a null return, the pool continues running with
+     * fewer than the target number workers. If exceptional, the
+     * exception is propagated, generally to some external caller.
+     * Worker index assignment avoids the bias in scanning that would
+     * occur if entries were sequentially packed starting at the front
+     * of the workQueues array. We treat the array as a simple
+     * power-of-two hash table, expanding as needed. The seedIndex
+     * increment ensures no collisions until a resize is needed or a
+     * worker is deregistered and replaced, and thereafter keeps
+     * probability of collision low. We cannot use
+     * ThreadLocalRandom.getProbe() for similar purposes here because
+     * the thread has not started yet, but do so for creating
+     * submission queues for existing external threads.
+     *
+     * Deactivation and waiting. Queuing encounters several intrinsic
+     * races; most notably that a task-producing thread can miss
+     * seeing (and signalling) another thread that gave up looking for
+     * work but has not yet entered the wait queue.  When a worker
+     * cannot find a task to steal, it deactivates and enqueues. Very
+     * often, the lack of tasks is transient due to GC or OS
+     * scheduling. To reduce false-alarm deactivation, scanners
+     * compute checksums of queue states during sweeps.  (The
+     * stability checks used here and elsewhere are probabilistic
+     * variants of snapshot techniques -- see Herlihy & Shavit.)
+     * Workers give up and try to deactivate only after the sum is
+     * stable across scans. Further, to avoid missed signals, they
+     * repeat this scanning process after successful enqueuing until
+     * again stable.  In this state, the worker cannot take/run a task
+     * it sees until it is released from the queue, so the worker
+     * itself eventually tries to release itself or any successor (see
+     * tryRelease).  Otherwise, upon an empty scan, a deactivated
+     * worker uses an adaptive local spin construction (see awaitWork)
+     * before blocking (via park). Note the unusual conventions about
+     * Thread.interrupts surrounding parking and other blocking:
+     * Because interrupts are used solely to alert threads to check
+     * termination, which is checked anyway upon blocking, we clear
+     * status (using Thread.interrupted) before any call to park, so
+     * that park does not immediately return due to status being set
+     * via some other unrelated call to interrupt in user code.
+     *
+     * Signalling and activation.  Workers are created or activated
+     * only when there appears to be at least one task they might be
+     * able to find and execute.  Upon push (either by a worker or an
+     * external submission) to a previously (possibly) empty queue,
+     * workers are signalled if idle, or created if fewer exist than
+     * the given parallelism level.  These primary signals are
+     * buttressed by others whenever other threads remove a task from
+     * a queue and notice that there are other tasks there as well.
+     * On most platforms, signalling (unpark) overhead time is
+     * noticeably long, and the time between signalling a thread and
+     * it actually making progress can be very noticeably long, so it
+     * is worth offloading these delays from critical paths as much as
+     * possible. Also, because inactive workers are often rescanning
+     * or spinning rather than blocking, we set and clear the "parker"
      * field of WorkQueues to reduce unnecessary calls to unpark.
      * (This requires a secondary recheck to avoid missed signals.)
-     * Note the unusual conventions about Thread.interrupts
-     * surrounding parking and other blocking: Because interrupts are
-     * used solely to alert threads to check termination, which is
-     * checked anyway upon blocking, we clear status (using
-     * Thread.interrupted) before any call to park, so that park does
-     * not immediately return due to status being set via some other
-     * unrelated call to interrupt in user code.
-     *
-     * Signalling.  We create or wake up workers only when there
-     * appears to be at least one task they might be able to find and
-     * execute.  When a submission is added or another worker adds a
-     * task to a queue that has fewer than two tasks, they signal
-     * waiting workers (or trigger creation of new ones if fewer than
-     * the given parallelism level -- signalWork).  These primary
-     * signals are buttressed by others whenever other threads remove
-     * a task from a queue and notice that there are other tasks there
-     * as well.  So in general, pools will be over-signalled. On most
-     * platforms, signalling (unpark) overhead time is noticeably
-     * long, and the time between signalling a thread and it actually
-     * making progress can be very noticeably long, so it is worth
-     * offloading these delays from critical paths as much as
-     * possible. Additionally, workers spin-down gradually, by staying
-     * alive so long as they see the ctl state changing.  Similar
-     * stability-sensing techniques are also used before blocking in
-     * awaitJoin and helpComplete.
      *
      * Trimming workers. To release resources after periods of lack of
      * use, a worker starting to wait when the pool is quiescent will
-     * time out and terminate if the pool has remained quiescent for a
-     * given period -- a short period if there are more threads than
-     * parallelism, longer as the number of threads decreases. This
-     * will slowly propagate, eventually terminating all workers after
-     * periods of non-use.
+     * time out and terminate (see awaitWork) if the pool has remained
+     * quiescent for period IDLE_TIMEOUT, increasing the period as the
+     * number of threads decreases, eventually removing all workers.
+     * Also, when more than two spare threads exist, excess threads
+     * are immediately terminated at the next quiescent point.
+     * (Padding by two avoids hysteresis.)
      *
-     * Shutdown and Termination. A call to shutdownNow atomically sets
-     * a plock bit and then (non-atomically) sets each worker's
-     * qlock status, cancels all unprocessed tasks, and wakes up
-     * all waiting workers.  Detecting whether termination should
-     * commence after a non-abrupt shutdown() call requires more work
-     * and bookkeeping. We need consensus about quiescence (i.e., that
-     * there is no more work). The active count provides a primary
-     * indication but non-abrupt shutdown still requires a rechecking
-     * scan for any workers that are inactive but not queued.
+     * Shutdown and Termination. A call to shutdownNow invokes
+     * tryTerminate to atomically set a runState bit. The calling
+     * thread, as well as every other worker thereafter terminating,
+     * helps terminate others by setting their (qlock) status,
+     * cancelling their unprocessed tasks, and waking them up, doing
+     * so repeatedly until stable (but with a loop bounded by the
+     * number of workers).  Calls to non-abrupt shutdown() preface
+     * this by checking whether termination should commence. This
+     * relies primarily on the active count bits of "ctl" maintaining
+     * consensus -- tryTerminate is called from awaitWork whenever
+     * quiescent. However, external submitters do not take part in
+     * this consensus.  So, tryTerminate sweeps through queues (until
+     * stable) to ensure lack of in-flight submissions and workers
+     * about to process them before triggering the "STOP" phase of
+     * termination. (Note: there is an intrinsic conflict if
+     * helpQuiescePool is called when shutdown is enabled. Both wait
+     * for quiescence, but tryTerminate is biased to not trigger until
+     * helpQuiescePool completes.)
+     *
      *
      * Joining Tasks
      * =============
@@ -403,9 +528,9 @@
      * just let them block (as in Thread.join).  We also cannot just
      * reassign the joiner's run-time stack with another and replace
      * it later, which would be a form of "continuation", that even if
-     * possible is not necessarily a good idea since we sometimes need
-     * both an unblocked task and its continuation to progress.
-     * Instead we combine two tactics:
+     * possible is not necessarily a good idea since we may need both
+     * an unblocked task and its continuation to progress.  Instead we
+     * combine two tactics:
      *
      *   Helping: Arranging for the joiner to execute some task that it
      *      would be running if the steal had not occurred.
@@ -425,16 +550,16 @@
      * The ManagedBlocker extension API can't use helping so relies
      * only on compensation in method awaitBlocker.
      *
-     * The algorithm in tryHelpStealer entails a form of "linear"
-     * helping: Each worker records (in field currentSteal) the most
-     * recent task it stole from some other worker. Plus, it records
-     * (in field currentJoin) the task it is currently actively
-     * joining. Method tryHelpStealer uses these markers to try to
-     * find a worker to help (i.e., steal back a task from and execute
-     * it) that could hasten completion of the actively joined task.
-     * In essence, the joiner executes a task that would be on its own
-     * local deque had the to-be-joined task not been stolen. This may
-     * be seen as a conservative variant of the approach in Wagner &
+     * The algorithm in helpStealer entails a form of "linear
+     * helping".  Each worker records (in field currentSteal) the most
+     * recent task it stole from some other worker (or a submission).
+     * It also records (in field currentJoin) the task it is currently
+     * actively joining. Method helpStealer uses these markers to try
+     * to find a worker to help (i.e., steal back a task from and
+     * execute it) that could hasten completion of the actively joined
+     * task.  Thus, the joiner executes a task that would be on its
+     * own local deque had the to-be-joined task not been stolen. This
+     * is a conservative variant of the approach described in Wagner &
      * Calder "Leapfrogging: a portable technique for implementing
      * efficient futures" SIGPLAN Notices, 1993
      * (http://portal.acm.org/citation.cfm?id=155354). It differs in
@@ -452,37 +577,40 @@
      * which means that we miss links in the chain during long-lived
      * tasks, GC stalls etc (which is OK since blocking in such cases
      * is usually a good idea).  (4) We bound the number of attempts
-     * to find work (see MAX_HELP) and fall back to suspending the
+     * to find work using checksums and fall back to suspending the
      * worker and if necessary replacing it with another.
      *
-     * Helping actions for CountedCompleters are much simpler: Method
-     * helpComplete can take and execute any task with the same root
-     * as the task being waited on. However, this still entails some
-     * traversal of completer chains, so is less efficient than using
-     * CountedCompleters without explicit joins.
+     * Helping actions for CountedCompleters do not require tracking
+     * currentJoins: Method helpComplete takes and executes any task
+     * with the same root as the task being waited on (preferring
+     * local pops to non-local polls). However, this still entails
+     * some traversal of completer chains, so is less efficient than
+     * using CountedCompleters without explicit joins.
      *
-     * It is impossible to keep exactly the target parallelism number
-     * of threads running at any given time.  Determining the
-     * existence of conservatively safe helping targets, the
-     * availability of already-created spares, and the apparent need
-     * to create new spares are all racy, so we rely on multiple
-     * retries of each.  Compensation in the apparent absence of
-     * helping opportunities is challenging to control on JVMs, where
-     * GC and other activities can stall progress of tasks that in
-     * turn stall out many other dependent tasks, without us being
-     * able to determine whether they will ever require compensation.
-     * Even though work-stealing otherwise encounters little
-     * degradation in the presence of more threads than cores,
-     * aggressively adding new threads in such cases entails risk of
-     * unwanted positive feedback control loops in which more threads
-     * cause more dependent stalls (as well as delayed progress of
-     * unblocked threads to the point that we know they are available)
-     * leading to more situations requiring more threads, and so
-     * on. This aspect of control can be seen as an (analytically
-     * intractable) game with an opponent that may choose the worst
-     * (for us) active thread to stall at any time.  We take several
-     * precautions to bound losses (and thus bound gains), mainly in
-     * methods tryCompensate and awaitJoin.
+     * Compensation does not aim to keep exactly the target
+     * parallelism number of unblocked threads running at any given
+     * time. Some previous versions of this class employed immediate
+     * compensations for any blocked join. However, in practice, the
+     * vast majority of blockages are transient byproducts of GC and
+     * other JVM or OS activities that are made worse by replacement.
+     * Currently, compensation is attempted only after validating that
+     * all purportedly active threads are processing tasks by checking
+     * field WorkQueue.scanState, which eliminates most false
+     * positives.  Also, compensation is bypassed (tolerating fewer
+     * threads) in the most common case in which it is rarely
+     * beneficial: when a worker with an empty queue (thus no
+     * continuation tasks) blocks on a join and there still remain
+     * enough threads to ensure liveness.
+     *
+     * The compensation mechanism may be bounded.  Bounds for the
+     * commonPool (see commonMaxSpares) better enable JVMs to cope
+     * with programming errors and abuse before running out of
+     * resources to do so. In other cases, users may supply factories
+     * that limit thread construction. The effects of bounding in this
+     * pool (like all others) is imprecise.  Total worker counts are
+     * decremented when threads deregister, not when they exit and
+     * resources are reclaimed by the JVM and OS. So the number of
+     * simultaneously live threads may transiently exceed bounds.
      *
      * Common Pool
      * ===========
@@ -492,34 +620,52 @@
      * never be used, we minimize initial construction overhead and
      * footprint to the setup of about a dozen fields, with no nested
      * allocation. Most bootstrapping occurs within method
-     * fullExternalPush during the first submission to the pool.
+     * externalSubmit during the first submission to the pool.
      *
      * When external threads submit to the common pool, they can
-     * perform subtask processing (see externalHelpJoin and related
-     * methods).  This caller-helps policy makes it sensible to set
-     * common pool parallelism level to one (or more) less than the
-     * total number of available cores, or even zero for pure
-     * caller-runs.  We do not need to record whether external
-     * submissions are to the common pool -- if not, externalHelpJoin
-     * returns quickly (at the most helping to signal some common pool
-     * workers). These submitters would otherwise be blocked waiting
-     * for completion, so the extra effort (with liberally sprinkled
-     * task status checks) in inapplicable cases amounts to an odd
-     * form of limited spin-wait before blocking in ForkJoinTask.join.
+     * perform subtask processing (see externalHelpComplete and
+     * related methods) upon joins.  This caller-helps policy makes it
+     * sensible to set common pool parallelism level to one (or more)
+     * less than the total number of available cores, or even zero for
+     * pure caller-runs.  We do not need to record whether external
+     * submissions are to the common pool -- if not, external help
+     * methods return quickly. These submitters would otherwise be
+     * blocked waiting for completion, so the extra effort (with
+     * liberally sprinkled task status checks) in inapplicable cases
+     * amounts to an odd form of limited spin-wait before blocking in
+     * ForkJoinTask.join.
      *
      * As a more appropriate default in managed environments, unless
      * overridden by system properties, we use workers of subclass
      * InnocuousForkJoinWorkerThread when there is a SecurityManager
      * present. These workers have no permissions set, do not belong
      * to any user-defined ThreadGroup, and erase all ThreadLocals
-     * after executing any top-level task (see WorkQueue.runTask). The
-     * associated mechanics (mainly in ForkJoinWorkerThread) may be
-     * JVM-dependent and must access particular Thread class fields to
-     * achieve this effect.
+     * after executing any top-level task (see WorkQueue.runTask).
+     * The associated mechanics (mainly in ForkJoinWorkerThread) may
+     * be JVM-dependent and must access particular Thread class fields
+     * to achieve this effect.
      *
      * Style notes
      * ===========
      *
+     * Memory ordering relies mainly on Unsafe intrinsics that carry
+     * the further responsibility of explicitly performing null- and
+     * bounds- checks otherwise carried out implicitly by JVMs.  This
+     * can be awkward and ugly, but also reflects the need to control
+     * outcomes across the unusual cases that arise in very racy code
+     * with very few invariants. So these explicit checks would exist
+     * in some form anyway.  All fields are read into locals before
+     * use, and null-checked if they are references.  This is usually
+     * done in a "C"-like style of listing declarations at the heads
+     * of methods or blocks, and using inline assignments on first
+     * encounter.  Array bounds-checks are usually performed by
+     * masking with array.length-1, which relies on the invariant that
+     * these arrays are created with positive lengths, which is itself
+     * paranoically checked. Nearly all explicit checks lead to
+     * bypass/return, not exception throws, because they may
+     * legitimately arise due to cancellation/revocation during
+     * shutdown.
+     *
      * There is a lot of representation-level coupling among classes
      * ForkJoinPool, ForkJoinWorkerThread, and ForkJoinTask.  The
      * fields of WorkQueue maintain data structures managed by
@@ -527,22 +673,13 @@
      * trying to reduce this, since any associated future changes in
      * representations will need to be accompanied by algorithmic
      * changes anyway. Several methods intrinsically sprawl because
-     * they must accumulate sets of consistent reads of volatiles held
-     * in local variables.  Methods signalWork() and scan() are the
-     * main bottlenecks, so are especially heavily
-     * micro-optimized/mangled.  There are lots of inline assignments
-     * (of form "while ((local = field) != 0)") which are usually the
-     * simplest way to ensure the required read orderings (which are
-     * sometimes critical). This leads to a "C"-like style of listing
-     * declarations of these locals at the heads of methods or blocks.
-     * There are several occurrences of the unusual "do {} while
-     * (!cas...)"  which is the simplest way to force an update of a
-     * CAS'ed variable. There are also other coding oddities (including
-     * several unnecessary-looking hoisted null checks) that help
-     * some methods perform reasonably even when interpreted (not
-     * compiled).
+     * they must accumulate sets of consistent reads of fields held in
+     * local variables.  There are also other coding oddities
+     * (including several unnecessary-looking hoisted null checks)
+     * that help some methods perform reasonably even when interpreted
+     * (not compiled).
      *
-     * The order of declarations in this file is:
+     * The order of declarations in this file is (with a few exceptions):
      * (1) Static utility functions
      * (2) Nested (static) classes
      * (3) Static fields
@@ -609,56 +746,37 @@
         public final boolean exec() { return true; }
     }
 
+    // Constants shared across ForkJoinPool and WorkQueue
+
+    // Bounds
+    static final int SMASK        = 0xffff;        // short bits == max index
+    static final int MAX_CAP      = 0x7fff;        // max #workers - 1
+    static final int EVENMASK     = 0xfffe;        // even short bits
+    static final int SQMASK       = 0x007e;        // max 64 (even) slots
+
+    // Masks and units for WorkQueue.scanState and ctl sp subfield
+    static final int SCANNING     = 1;             // false when running tasks
+    static final int INACTIVE     = 1 << 31;       // must be negative
+    static final int SS_SEQ       = 1 << 16;       // version count
+
+    // Mode bits for ForkJoinPool.config and WorkQueue.config
+    static final int MODE_MASK    = 0xffff << 16;  // top half of int
+    static final int LIFO_QUEUE   = 0;
+    static final int FIFO_QUEUE   = 1 << 16;
+    static final int SHARED_QUEUE = 1 << 31;       // must be negative
+
     /**
      * Queues supporting work-stealing as well as external task
-     * submission. See above for main rationale and algorithms.
-     * Implementation relies heavily on "Unsafe" intrinsics
-     * and selective use of "volatile":
-     *
-     * Field "base" is the index (mod array.length) of the least valid
-     * queue slot, which is always the next position to steal (poll)
-     * from if nonempty. Reads and writes require volatile orderings
-     * but not CAS, because updates are only performed after slot
-     * CASes.
-     *
-     * Field "top" is the index (mod array.length) of the next queue
-     * slot to push to or pop from. It is written only by owner thread
-     * for push, or under lock for external/shared push, and accessed
-     * by other threads only after reading (volatile) base.  Both top
-     * and base are allowed to wrap around on overflow, but (top -
-     * base) (or more commonly -(base - top) to force volatile read of
-     * base before top) still estimates size. The lock ("qlock") is
-     * forced to -1 on termination, causing all further lock attempts
-     * to fail. (Note: we don't need CAS for termination state because
-     * upon pool shutdown, all shared-queues will stop being used
-     * anyway.)  Nearly all lock bodies are set up so that exceptions
-     * within lock bodies are "impossible" (modulo JVM errors that
-     * would cause failure anyway.)
-     *
-     * The array slots are read and written using the emulation of
-     * volatiles/atomics provided by Unsafe. Insertions must in
-     * general use putOrderedObject as a form of releasing store to
-     * ensure that all writes to the task object are ordered before
-     * its publication in the queue.  All removals entail a CAS to
-     * null.  The array is always a power of two. To ensure safety of
-     * Unsafe array operations, all accesses perform explicit null
-     * checks and implicit bounds checks via power-of-two masking.
-     *
-     * In addition to basic queuing support, this class contains
-     * fields described elsewhere to control execution. It turns out
-     * to work better memory-layout-wise to include them in this class
-     * rather than a separate class.
-     *
+     * submission. See above for descriptions and algorithms.
      * Performance on most platforms is very sensitive to placement of
      * instances of both WorkQueues and their arrays -- we absolutely
      * do not want multiple WorkQueue instances or multiple queue
-     * arrays sharing cache lines. (It would be best for queue objects
-     * and their arrays to share, but there is nothing available to
-     * help arrange that). The @Contended annotation alerts JVMs to
-     * try to keep instances apart.
+     * arrays sharing cache lines. The @Contended annotation alerts
+     * JVMs to try to keep instances apart.
      */
     @sun.misc.Contended
     static final class WorkQueue {
+
         /**
          * Capacity of work-stealing queue array upon initialization.
          * Must be a power of two; at least 4, but should be larger to
@@ -679,13 +797,13 @@
          */
         static final int MAXIMUM_QUEUE_CAPACITY = 1 << 26; // 64M
 
-        volatile int eventCount;   // encoded inactivation count; < 0 if inactive
-        int nextWait;              // encoded record of next event waiter
+        // Instance fields
+        volatile int scanState;    // versioned, <0: inactive; odd:scanning
+        int stackPred;             // pool stack (ctl) predecessor
         int nsteals;               // number of steals
-        int hint;                  // steal index hint
-        short poolIndex;           // index of this queue in pool
-        final short mode;          // 0: lifo, > 0: fifo, < 0: shared
-        volatile int qlock;        // 1: locked, -1: terminate; else 0
+        int hint;                  // randomization and stealer index hint
+        int config;                // pool index and mode
+        volatile int qlock;        // 1: locked, < 0: terminate; else 0
         volatile int base;         // index of next slot for poll
         int top;                   // index of next slot for push
         ForkJoinTask<?>[] array;   // the elements (initially unallocated)
@@ -693,19 +811,23 @@
         final ForkJoinWorkerThread owner; // owning thread or null if shared
         volatile Thread parker;    // == owner during call to park; else null
         volatile ForkJoinTask<?> currentJoin;  // task being joined in awaitJoin
-        ForkJoinTask<?> currentSteal; // current non-local task being executed
+        volatile ForkJoinTask<?> currentSteal; // mainly used by helpStealer
 
-        WorkQueue(ForkJoinPool pool, ForkJoinWorkerThread owner, int mode,
-                  int seed) {
+        WorkQueue(ForkJoinPool pool, ForkJoinWorkerThread owner) {
             this.pool = pool;
             this.owner = owner;
-            this.mode = (short)mode;
-            this.hint = seed; // store initial seed for runWorker
             // Place indices in the center of array (that is not yet allocated)
             base = top = INITIAL_QUEUE_CAPACITY >>> 1;
         }
 
         /**
+         * Returns an exportable index (used by ForkJoinWorkerThread).
+         */
+        final int getPoolIndex() {
+            return (config & 0xffff) >>> 1; // ignore odd/even tag bit
+        }
+
+        /**
          * Returns the approximate number of tasks in the queue.
          */
         final int queueSize() {
@@ -719,12 +841,10 @@
          * near-empty queue has at least one unclaimed task.
          */
         final boolean isEmpty() {
-            ForkJoinTask<?>[] a; int m, s;
-            int n = base - (s = top);
-            return (n >= 0 ||
-                    (n == -1 &&
-                     ((a = array) == null ||
-                      (m = a.length - 1) < 0 ||
+            ForkJoinTask<?>[] a; int n, m, s;
+            return ((n = base - (s = top)) >= 0 ||
+                    (n == -1 &&           // possibly one task
+                     ((a = array) == null || (m = a.length - 1) < 0 ||
                       U.getObject
                       (a, (long)((m & (s - 1)) << ASHIFT) + ABASE) == null)));
         }
@@ -738,12 +858,15 @@
          */
         final void push(ForkJoinTask<?> task) {
             ForkJoinTask<?>[] a; ForkJoinPool p;
-            int s = top, n;
+            int b = base, s = top, n;
             if ((a = array) != null) {    // ignore if queue removed
-                int m = a.length - 1;
+                int m = a.length - 1;     // fenced write for task visibility
                 U.putOrderedObject(a, ((m & s) << ASHIFT) + ABASE, task);
-                if ((n = (top = s + 1) - base) <= 2)
-                    (p = pool).signalWork(p.workQueues, this);
+                U.putOrderedInt(this, QTOP, s + 1);
+                if ((n = s - b) <= 1) {
+                    if ((p = pool) != null)
+                        p.signalWork(p.workQueues, this);
+                }
                 else if (n >= m)
                     growArray();
             }
@@ -764,7 +887,7 @@
             if (oldA != null && (oldMask = oldA.length - 1) >= 0 &&
                 (t = top) - (b = base) > 0) {
                 int mask = size - 1;
-                do {
+                do { // emulate poll from old array, push to new array
                     ForkJoinTask<?> x;
                     int oldj = ((b & oldMask) << ASHIFT) + ABASE;
                     int j    = ((b &    mask) << ASHIFT) + ABASE;
@@ -789,7 +912,7 @@
                     if ((t = (ForkJoinTask<?>)U.getObject(a, j)) == null)
                         break;
                     if (U.compareAndSwapObject(a, j, t, null)) {
-                        top = s;
+                        U.putOrderedInt(this, QTOP, s);
                         return t;
                     }
                 }
@@ -800,7 +923,7 @@
         /**
          * Takes a task in FIFO order if b is base of queue and a task
          * can be claimed without contention. Specialized versions
-         * appear in ForkJoinPool methods scan and tryHelpStealer.
+         * appear in ForkJoinPool methods scan and helpStealer.
          */
         final ForkJoinTask<?> pollAt(int b) {
             ForkJoinTask<?> t; ForkJoinTask<?>[] a;
@@ -808,7 +931,7 @@
                 int j = (((a.length - 1) & b) << ASHIFT) + ABASE;
                 if ((t = (ForkJoinTask<?>)U.getObjectVolatile(a, j)) != null &&
                     base == b && U.compareAndSwapObject(a, j, t, null)) {
-                    U.putOrderedInt(this, QBASE, b + 1);
+                    base = b + 1;
                     return t;
                 }
             }
@@ -823,16 +946,15 @@
             while ((b = base) - top < 0 && (a = array) != null) {
                 int j = (((a.length - 1) & b) << ASHIFT) + ABASE;
                 t = (ForkJoinTask<?>)U.getObjectVolatile(a, j);
-                if (t != null) {
-                    if (U.compareAndSwapObject(a, j, t, null)) {
-                        U.putOrderedInt(this, QBASE, b + 1);
-                        return t;
+                if (base == b) {
+                    if (t != null) {
+                        if (U.compareAndSwapObject(a, j, t, null)) {
+                            base = b + 1;
+                            return t;
+                        }
                     }
-                }
-                else if (base == b) {
-                    if (b + 1 == top)
+                    else if (b + 1 == top) // now empty
                         break;
-                    Thread.yield(); // wait for lagging update (very rare)
                 }
             }
             return null;
@@ -842,7 +964,7 @@
          * Takes next task, if one exists, in order specified by mode.
          */
         final ForkJoinTask<?> nextLocalTask() {
-            return mode == 0 ? pop() : poll();
+            return (config & FIFO_QUEUE) == 0 ? pop() : poll();
         }
 
         /**
@@ -852,7 +974,7 @@
             ForkJoinTask<?>[] a = array; int m;
             if (a == null || (m = a.length - 1) < 0)
                 return null;
-            int i = mode == 0 ? top - 1 : base;
+            int i = (config & FIFO_QUEUE) == 0 ? top - 1 : base;
             int j = ((i & m) << ASHIFT) + ABASE;
             return (ForkJoinTask<?>)U.getObjectVolatile(a, j);
         }
@@ -860,13 +982,13 @@
         /**
          * Pops the given task only if it is at the current top.
          * (A shared version is available only via FJP.tryExternalUnpush)
-         */
+        */
         final boolean tryUnpush(ForkJoinTask<?> t) {
             ForkJoinTask<?>[] a; int s;
             if ((a = array) != null && (s = top) != base &&
                 U.compareAndSwapObject
                 (a, (((a.length - 1) & --s) << ASHIFT) + ABASE, t, null)) {
-                top = s;
+                U.putOrderedInt(this, QTOP, s);
                 return true;
             }
             return false;
@@ -876,9 +998,16 @@
          * Removes and cancels all known tasks, ignoring any exceptions.
          */
         final void cancelAll() {
-            ForkJoinTask.cancelIgnoringExceptions(currentJoin);
-            ForkJoinTask.cancelIgnoringExceptions(currentSteal);
-            for (ForkJoinTask<?> t; (t = poll()) != null; )
+            ForkJoinTask<?> t;
+            if ((t = currentJoin) != null) {
+                currentJoin = null;
+                ForkJoinTask.cancelIgnoringExceptions(t);
+            }
+            if ((t = currentSteal) != null) {
+                currentSteal = null;
+                ForkJoinTask.cancelIgnoringExceptions(t);
+            }
+            while ((t = poll()) != null)
                 ForkJoinTask.cancelIgnoringExceptions(t);
         }
 
@@ -893,167 +1022,186 @@
         }
 
         /**
-         * Executes a top-level task and any local tasks remaining
-         * after execution.
+         * Removes and executes all local tasks. If LIFO, invokes
+         * pollAndExecAll. Otherwise implements a specialized pop loop
+         * to exec until empty.
          */
-        final void runTask(ForkJoinTask<?> task) {
-            if ((currentSteal = task) != null) {
-                ForkJoinWorkerThread thread;
-                task.doExec();
-                ForkJoinTask<?>[] a = array;
-                int md = mode;
-                ++nsteals;
-                currentSteal = null;
-                if (md != 0)
-                    pollAndExecAll();
-                else if (a != null) {
-                    int s, m = a.length - 1;
-                    ForkJoinTask<?> t;
-                    while ((s = top - 1) - base >= 0 &&
-                           (t = (ForkJoinTask<?>)U.getAndSetObject
-                            (a, ((m & s) << ASHIFT) + ABASE, null)) != null) {
-                        top = s;
+        final void execLocalTasks() {
+            int b = base, m, s;
+            ForkJoinTask<?>[] a = array;
+            if (b - (s = top - 1) <= 0 && a != null &&
+                (m = a.length - 1) >= 0) {
+                if ((config & FIFO_QUEUE) == 0) {
+                    for (ForkJoinTask<?> t;;) {
+                        if ((t = (ForkJoinTask<?>)U.getAndSetObject
+                             (a, ((m & s) << ASHIFT) + ABASE, null)) == null)
+                            break;
+                        U.putOrderedInt(this, QTOP, s);
                         t.doExec();
+                        if (base - (s = top - 1) > 0)
+                            break;
                     }
                 }
-                if ((thread = owner) != null) // no need to do in finally clause
+                else
+                    pollAndExecAll();
+            }
+        }
+
+        /**
+         * Executes the given task and any remaining local tasks.
+         */
+        final void runTask(ForkJoinTask<?> task) {
+            if (task != null) {
+                scanState &= ~SCANNING; // mark as busy
+                (currentSteal = task).doExec();
+                U.putOrderedObject(this, QCURRENTSTEAL, null); // release for GC
+                execLocalTasks();
+                ForkJoinWorkerThread thread = owner;
+                if (++nsteals < 0)      // collect on overflow
+                    transferStealCount(pool);
+                scanState |= SCANNING;
+                if (thread != null)
                     thread.afterTopLevelExec();
             }
         }
 
         /**
+         * Adds steal count to pool stealCounter if it exists, and resets.
+         */
+        final void transferStealCount(ForkJoinPool p) {
+            AtomicLong sc;
+            if (p != null && (sc = p.stealCounter) != null) {
+                int s = nsteals;
+                nsteals = 0;            // if negative, correct for overflow
+                sc.getAndAdd((long)(s < 0 ? Integer.MAX_VALUE : s));
+            }
+        }
+
+        /**
          * If present, removes from queue and executes the given task,
-         * or any other cancelled task. Returns (true) on any CAS
-         * or consistency check failure so caller can retry.
+         * or any other cancelled task. Used only by awaitJoin.
          *
-         * @return false if no progress can be made, else true
+         * @return true if queue empty and task not known to be done
          */
         final boolean tryRemoveAndExec(ForkJoinTask<?> task) {
-            boolean stat;
             ForkJoinTask<?>[] a; int m, s, b, n;
-            if (task != null && (a = array) != null && (m = a.length - 1) >= 0 &&
-                (n = (s = top) - (b = base)) > 0) {
-                boolean removed = false, empty = true;
-                stat = true;
-                for (ForkJoinTask<?> t;;) {           // traverse from s to b
-                    long j = ((--s & m) << ASHIFT) + ABASE;
-                    t = (ForkJoinTask<?>)U.getObject(a, j);
-                    if (t == null)                    // inconsistent length
-                        break;
-                    else if (t == task) {
-                        if (s + 1 == top) {           // pop
-                            if (!U.compareAndSwapObject(a, j, task, null))
-                                break;
-                            top = s;
-                            removed = true;
+            if ((a = array) != null && (m = a.length - 1) >= 0 &&
+                task != null) {
+                while ((n = (s = top) - (b = base)) > 0) {
+                    for (ForkJoinTask<?> t;;) {      // traverse from s to b
+                        long j = ((--s & m) << ASHIFT) + ABASE;
+                        if ((t = (ForkJoinTask<?>)U.getObject(a, j)) == null)
+                            return s + 1 == top;     // shorter than expected
+                        else if (t == task) {
+                            boolean removed = false;
+                            if (s + 1 == top) {      // pop
+                                if (U.compareAndSwapObject(a, j, task, null)) {
+                                    U.putOrderedInt(this, QTOP, s);
+                                    removed = true;
+                                }
+                            }
+                            else if (base == b)      // replace with proxy
+                                removed = U.compareAndSwapObject(
+                                    a, j, task, new EmptyTask());
+                            if (removed)
+                                task.doExec();
+                            break;
                         }
-                        else if (base == b)           // replace with proxy
-                            removed = U.compareAndSwapObject(a, j, task,
-                                                             new EmptyTask());
-                        break;
+                        else if (t.status < 0 && s + 1 == top) {
+                            if (U.compareAndSwapObject(a, j, t, null))
+                                U.putOrderedInt(this, QTOP, s);
+                            break;                  // was cancelled
+                        }
+                        if (--n == 0)
+                            return false;
                     }
-                    else if (t.status >= 0)
-                        empty = false;
-                    else if (s + 1 == top) {          // pop and throw away
-                        if (U.compareAndSwapObject(a, j, t, null))
-                            top = s;
-                        break;
-                    }
-                    if (--n == 0) {
-                        if (!empty && base == b)
-                            stat = false;
-                        break;
-                    }
+                    if (task.status < 0)
+                        return false;
                 }
-                if (removed)
-                    task.doExec();
             }
-            else
-                stat = false;
-            return stat;
+            return true;
         }
 
         /**
-         * Tries to poll for and execute the given task or any other
-         * task in its CountedCompleter computation.
+         * Pops task if in the same CC computation as the given task,
+         * in either shared or owned mode. Used only by helpComplete.
          */
-        final boolean pollAndExecCC(CountedCompleter<?> root) {
-            ForkJoinTask<?>[] a; int b; Object o; CountedCompleter<?> t, r;
-            if ((b = base) - top < 0 && (a = array) != null) {
+        final CountedCompleter<?> popCC(CountedCompleter<?> task, int mode) {
+            int s; ForkJoinTask<?>[] a; Object o;
+            if (base - (s = top) < 0 && (a = array) != null) {
+                long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
+                if ((o = U.getObjectVolatile(a, j)) != null &&
+                    (o instanceof CountedCompleter)) {
+                    CountedCompleter<?> t = (CountedCompleter<?>)o;
+                    for (CountedCompleter<?> r = t;;) {
+                        if (r == task) {
+                            if (mode < 0) { // must lock
+                                if (U.compareAndSwapInt(this, QLOCK, 0, 1)) {
+                                    if (top == s && array == a &&
+                                        U.compareAndSwapObject(a, j, t, null)) {
+                                        U.putOrderedInt(this, QTOP, s - 1);
+                                        U.putOrderedInt(this, QLOCK, 0);
+                                        return t;
+                                    }
+                                    U.compareAndSwapInt(this, QLOCK, 1, 0);
+                                }
+                            }
+                            else if (U.compareAndSwapObject(a, j, t, null)) {
+                                U.putOrderedInt(this, QTOP, s - 1);
+                                return t;
+                            }
+                            break;
+                        }
+                        else if ((r = r.completer) == null) // try parent
+                            break;
+                    }
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Steals and runs a task in the same CC computation as the
+         * given task if one exists and can be taken without
+         * contention. Otherwise returns a checksum/control value for
+         * use by method helpComplete.
+         *
+         * @return 1 if successful, 2 if retryable (lost to another
+         * stealer), -1 if non-empty but no matching task found, else
+         * the base index, forced negative.
+         */
+        final int pollAndExecCC(CountedCompleter<?> task) {
+            int b, h; ForkJoinTask<?>[] a; Object o;
+            if ((b = base) - top >= 0 || (a = array) == null)
+                h = b | Integer.MIN_VALUE;  // to sense movement on re-poll
+            else {
                 long j = (((a.length - 1) & b) << ASHIFT) + ABASE;
                 if ((o = U.getObjectVolatile(a, j)) == null)
-                    return true; // retry
-                if (o instanceof CountedCompleter) {
-                    for (t = (CountedCompleter<?>)o, r = t;;) {
-                        if (r == root) {
+                    h = 2;                  // retryable
+                else if (!(o instanceof CountedCompleter))
+                    h = -1;                 // unmatchable
+                else {
+                    CountedCompleter<?> t = (CountedCompleter<?>)o;
+                    for (CountedCompleter<?> r = t;;) {
+                        if (r == task) {
                             if (base == b &&
                                 U.compareAndSwapObject(a, j, t, null)) {
-                                U.putOrderedInt(this, QBASE, b + 1);
+                                base = b + 1;
                                 t.doExec();
+                                h = 1;      // success
                             }
-                            return true;
-                        }
-                        else if ((r = r.completer) == null)
-                            break; // not part of root computation
-                    }
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Tries to pop and execute the given task or any other task
-         * in its CountedCompleter computation.
-         */
-        final boolean externalPopAndExecCC(CountedCompleter<?> root) {
-            ForkJoinTask<?>[] a; int s; Object o; CountedCompleter<?> t, r;
-            if (base - (s = top) < 0 && (a = array) != null) {
-                long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
-                if ((o = U.getObject(a, j)) instanceof CountedCompleter) {
-                    for (t = (CountedCompleter<?>)o, r = t;;) {
-                        if (r == root) {
-                            if (U.compareAndSwapInt(this, QLOCK, 0, 1)) {
-                                if (top == s && array == a &&
-                                    U.compareAndSwapObject(a, j, t, null)) {
-                                    top = s - 1;
-                                    qlock = 0;
-                                    t.doExec();
-                                }
-                                else
-                                    qlock = 0;
-                            }
-                            return true;
-                        }
-                        else if ((r = r.completer) == null)
+                            else
+                                h = 2;      // lost CAS
                             break;
-                    }
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Internal version
-         */
-        final boolean internalPopAndExecCC(CountedCompleter<?> root) {
-            ForkJoinTask<?>[] a; int s; Object o; CountedCompleter<?> t, r;
-            if (base - (s = top) < 0 && (a = array) != null) {
-                long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
-                if ((o = U.getObject(a, j)) instanceof CountedCompleter) {
-                    for (t = (CountedCompleter<?>)o, r = t;;) {
-                        if (r == root) {
-                            if (U.compareAndSwapObject(a, j, t, null)) {
-                                top = s - 1;
-                                t.doExec();
-                            }
-                            return true;
                         }
-                        else if ((r = r.completer) == null)
+                        else if ((r = r.completer) == null) {
+                            h = -1;         // unmatched
                             break;
+                        }
                     }
                 }
             }
-            return false;
+            return h;
         }
 
         /**
@@ -1061,28 +1209,31 @@
          */
         final boolean isApparentlyUnblocked() {
             Thread wt; Thread.State s;
-            return (eventCount >= 0 &&
+            return (scanState >= 0 &&
                     (wt = owner) != null &&
                     (s = wt.getState()) != Thread.State.BLOCKED &&
                     s != Thread.State.WAITING &&
                     s != Thread.State.TIMED_WAITING);
         }
 
-        // Unsafe mechanics
+        // Unsafe mechanics. Note that some are (and must be) the same as in FJP
         private static final sun.misc.Unsafe U;
-        private static final long QBASE;
+        private static final int  ABASE;
+        private static final int  ASHIFT;
+        private static final long QTOP;
         private static final long QLOCK;
-        private static final int ABASE;
-        private static final int ASHIFT;
+        private static final long QCURRENTSTEAL;
         static {
             try {
                 U = sun.misc.Unsafe.getUnsafe();
-                Class<?> k = WorkQueue.class;
+                Class<?> wk = WorkQueue.class;
                 Class<?> ak = ForkJoinTask[].class;
-                QBASE = U.objectFieldOffset
-                    (k.getDeclaredField("base"));
+                QTOP = U.objectFieldOffset
+                    (wk.getDeclaredField("top"));
                 QLOCK = U.objectFieldOffset
-                    (k.getDeclaredField("qlock"));
+                    (wk.getDeclaredField("qlock"));
+                QCURRENTSTEAL = U.objectFieldOffset
+                    (wk.getDeclaredField("currentSteal"));
                 ABASE = U.arrayBaseOffset(ak);
                 int scale = U.arrayIndexScale(ak);
                 if ((scale & (scale - 1)) != 0)
@@ -1126,6 +1277,11 @@
     static final int commonParallelism;
 
     /**
+     * Limit on spare thread construction in tryCompensate.
+     */
+    private static int commonMaxSpares;
+
+    /**
      * Sequence number for creating workerNamePrefix.
      */
     private static int poolNumberSequence;
@@ -1138,7 +1294,7 @@
         return ++poolNumberSequence;
     }
 
-    // static constants
+    // static configuration constants
 
     /**
      * Initial timeout value (in nanoseconds) for the thread
@@ -1148,27 +1304,32 @@
      * aggressive shrinkage during most transient stalls (long GCs
      * etc).
      */
-    private static final long IDLE_TIMEOUT      = 2000L * 1000L * 1000L; // 2sec
-
-    /**
-     * Timeout value when there are more threads than parallelism level
-     */
-    private static final long FAST_IDLE_TIMEOUT =  200L * 1000L * 1000L;
+    private static final long IDLE_TIMEOUT = 2000L * 1000L * 1000L; // 2sec
 
     /**
      * Tolerance for idle timeouts, to cope with timer undershoots
      */
-    private static final long TIMEOUT_SLOP = 2000000L;
+    private static final long TIMEOUT_SLOP = 20L * 1000L * 1000L;  // 20ms
 
     /**
-     * The maximum stolen->joining link depth allowed in method
-     * tryHelpStealer.  Must be a power of two.  Depths for legitimate
-     * chains are unbounded, but we use a fixed constant to avoid
-     * (otherwise unchecked) cycles and to bound staleness of
-     * traversal parameters at the expense of sometimes blocking when
-     * we could be helping.
+     * The initial value for commonMaxSpares during static
+     * initialization. The value is far in excess of normal
+     * requirements, but also far short of MAX_CAP and typical
+     * OS thread limits, so allows JVMs to catch misuse/abuse
+     * before running out of resources needed to do so.
      */
-    private static final int MAX_HELP = 64;
+    private static final int DEFAULT_COMMON_MAX_SPARES = 256;
+
+    /**
+     * Number of times to spin-wait before blocking. The spins (in
+     * awaitRunStateLock and awaitWork) currently use randomized
+     * spins. If/when MWAIT-like intrinsics becomes available, they
+     * may allow quieter spinning. The value of SPINS must be a power
+     * of two, at least 4. The current value causes spinning for a
+     * small fraction of typical context-switch times, well worthwhile
+     * given the typical likelihoods that blocking is not necessary.
+     */
+    private static final int SPINS  = 1 << 11;
 
     /**
      * Increment for seed generators. See class ThreadLocal for
@@ -1177,209 +1338,212 @@
     private static final int SEED_INCREMENT = 0x9e3779b9;
 
     /*
-     * Bits and masks for control variables
+     * Bits and masks for field ctl, packed with 4 16 bit subfields:
+     * AC: Number of active running workers minus target parallelism
+     * TC: Number of total workers minus target parallelism
+     * SS: version count and status of top waiting thread
+     * ID: poolIndex of top of Treiber stack of waiters
      *
-     * Field ctl is a long packed with:
-     * AC: Number of active running workers minus target parallelism (16 bits)
-     * TC: Number of total workers minus target parallelism (16 bits)
-     * ST: true if pool is terminating (1 bit)
-     * EC: the wait count of top waiting thread (15 bits)
-     * ID: poolIndex of top of Treiber stack of waiters (16 bits)
+     * When convenient, we can extract the lower 32 stack top bits
+     * (including version bits) as sp=(int)ctl.  The offsets of counts
+     * by the target parallelism and the positionings of fields makes
+     * it possible to perform the most common checks via sign tests of
+     * fields: When ac is negative, there are not enough active
+     * workers, when tc is negative, there are not enough total
+     * workers.  When sp is non-zero, there are waiting workers.  To
+     * deal with possibly negative fields, we use casts in and out of
+     * "short" and/or signed shifts to maintain signedness.
      *
-     * When convenient, we can extract the upper 32 bits of counts and
-     * the lower 32 bits of queue state, u = (int)(ctl >>> 32) and e =
-     * (int)ctl.  The ec field is never accessed alone, but always
-     * together with id and st. The offsets of counts by the target
-     * parallelism and the positionings of fields makes it possible to
-     * perform the most common checks via sign tests of fields: When
-     * ac is negative, there are not enough active workers, when tc is
-     * negative, there are not enough total workers, and when e is
-     * negative, the pool is terminating.  To deal with these possibly
-     * negative fields, we use casts in and out of "short" and/or
-     * signed shifts to maintain signedness.
-     *
-     * When a thread is queued (inactivated), its eventCount field is
-     * set negative, which is the only way to tell if a worker is
-     * prevented from executing tasks, even though it must continue to
-     * scan for them to avoid queuing races. Note however that
-     * eventCount updates lag releases so usage requires care.
-     *
-     * Field plock is an int packed with:
-     * SHUTDOWN: true if shutdown is enabled (1 bit)
-     * SEQ:  a sequence lock, with PL_LOCK bit set if locked (30 bits)
-     * SIGNAL: set when threads may be waiting on the lock (1 bit)
-     *
-     * The sequence number enables simple consistency checks:
-     * Staleness of read-only operations on the workQueues array can
-     * be checked by comparing plock before vs after the reads.
+     * Because it occupies uppermost bits, we can add one active count
+     * using getAndAddLong of AC_UNIT, rather than CAS, when returning
+     * from a blocked join.  Other updates entail multiple subfields
+     * and masking, requiring CAS.
      */
 
-    // bit positions/shifts for fields
+    // Lower and upper word masks
+    private static final long SP_MASK    = 0xffffffffL;
+    private static final long UC_MASK    = ~SP_MASK;
+
+    // Active counts
     private static final int  AC_SHIFT   = 48;
+    private static final long AC_UNIT    = 0x0001L << AC_SHIFT;
+    private static final long AC_MASK    = 0xffffL << AC_SHIFT;
+
+    // Total counts
     private static final int  TC_SHIFT   = 32;
-    private static final int  ST_SHIFT   = 31;
-    private static final int  EC_SHIFT   = 16;
+    private static final long TC_UNIT    = 0x0001L << TC_SHIFT;
+    private static final long TC_MASK    = 0xffffL << TC_SHIFT;
+    private static final long ADD_WORKER = 0x0001L << (TC_SHIFT + 15); // sign
 
-    // bounds
-    private static final int  SMASK      = 0xffff;  // short bits
-    private static final int  MAX_CAP    = 0x7fff;  // max #workers - 1
-    private static final int  EVENMASK   = 0xfffe;  // even short bits
-    private static final int  SQMASK     = 0x007e;  // max 64 (even) slots
-    private static final int  SHORT_SIGN = 1 << 15;
-    private static final int  INT_SIGN   = 1 << 31;
-
-    // masks
-    private static final long STOP_BIT   = 0x0001L << ST_SHIFT;
-    private static final long AC_MASK    = ((long)SMASK) << AC_SHIFT;
-    private static final long TC_MASK    = ((long)SMASK) << TC_SHIFT;
-
-    // units for incrementing and decrementing
-    private static final long TC_UNIT    = 1L << TC_SHIFT;
-    private static final long AC_UNIT    = 1L << AC_SHIFT;
-
-    // masks and units for dealing with u = (int)(ctl >>> 32)
-    private static final int  UAC_SHIFT  = AC_SHIFT - 32;
-    private static final int  UTC_SHIFT  = TC_SHIFT - 32;
-    private static final int  UAC_MASK   = SMASK << UAC_SHIFT;
-    private static final int  UTC_MASK   = SMASK << UTC_SHIFT;
-    private static final int  UAC_UNIT   = 1 << UAC_SHIFT;
-    private static final int  UTC_UNIT   = 1 << UTC_SHIFT;
-
-    // masks and units for dealing with e = (int)ctl
-    private static final int E_MASK      = 0x7fffffff; // no STOP_BIT
-    private static final int E_SEQ       = 1 << EC_SHIFT;
-
-    // plock bits
-    private static final int SHUTDOWN    = 1 << 31;
-    private static final int PL_LOCK     = 2;
-    private static final int PL_SIGNAL   = 1;
-    private static final int PL_SPINS    = 1 << 8;
-
-    // access mode for WorkQueue
-    static final int LIFO_QUEUE          =  0;
-    static final int FIFO_QUEUE          =  1;
-    static final int SHARED_QUEUE        = -1;
+    // runState bits: SHUTDOWN must be negative, others arbitrary powers of two
+    private static final int  RSLOCK     = 1;
+    private static final int  RSIGNAL    = 1 << 1;
+    private static final int  STARTED    = 1 << 2;
+    private static final int  STOP       = 1 << 29;
+    private static final int  TERMINATED = 1 << 30;
+    private static final int  SHUTDOWN   = 1 << 31;
 
     // Instance fields
-    volatile long stealCount;                  // collects worker counts
-    volatile long ctl;                         // main pool control
-    volatile int plock;                        // shutdown status and seqLock
-    volatile int indexSeed;                    // worker/submitter index seed
-    final short parallelism;                   // parallelism level
-    final short mode;                          // LIFO/FIFO
-    WorkQueue[] workQueues;                    // main registry
+    volatile long ctl;                   // main pool control
+    volatile int runState;               // lockable status
+    final int config;                    // parallelism, mode
+    int indexSeed;                       // to generate worker index
+    volatile WorkQueue[] workQueues;     // main registry
     final ForkJoinWorkerThreadFactory factory;
-    final UncaughtExceptionHandler ueh;        // per-worker UEH
-    final String workerNamePrefix;             // to create worker name string
+    final UncaughtExceptionHandler ueh;  // per-worker UEH
+    final String workerNamePrefix;       // to create worker name string
+    volatile AtomicLong stealCounter;    // also used as sync monitor
 
     /**
-     * Acquires the plock lock to protect worker array and related
-     * updates. This method is called only if an initial CAS on plock
-     * fails. This acts as a spinlock for normal cases, but falls back
-     * to builtin monitor to block when (rarely) needed. This would be
-     * a terrible idea for a highly contended lock, but works fine as
-     * a more conservative alternative to a pure spinlock.
+     * Acquires the runState lock; returns current (locked) runState.
      */
-    private int acquirePlock() {
-        int spins = PL_SPINS, ps, nps;
-        for (;;) {
-            if (((ps = plock) & PL_LOCK) == 0 &&
-                U.compareAndSwapInt(this, PLOCK, ps, nps = ps + PL_LOCK))
-                return nps;
-            else if (spins >= 0) {
-                if (ThreadLocalRandom.nextSecondarySeed() >= 0)
+    private int lockRunState() {
+        int rs;
+        return ((((rs = runState) & RSLOCK) != 0 ||
+                 !U.compareAndSwapInt(this, RUNSTATE, rs, rs |= RSLOCK)) ?
+                awaitRunStateLock() : rs);
+    }
+
+    /**
+     * Spins and/or blocks until runstate lock is available.  See
+     * above for explanation.
+     */
+    private int awaitRunStateLock() {
+        Object lock;
+        boolean wasInterrupted = false;
+        for (int spins = SPINS, r = 0, rs, ns;;) {
+            if (((rs = runState) & RSLOCK) == 0) {
+                if (U.compareAndSwapInt(this, RUNSTATE, rs, ns = rs | RSLOCK)) {
+                    if (wasInterrupted) {
+                        try {
+                            Thread.currentThread().interrupt();
+                        } catch (SecurityException ignore) {
+                        }
+                    }
+                    return ns;
+                }
+            }
+            else if (r == 0)
+                r = ThreadLocalRandom.nextSecondarySeed();
+            else if (spins > 0) {
+                r ^= r << 6; r ^= r >>> 21; r ^= r << 7; // xorshift
+                if (r >= 0)
                     --spins;
             }
-            else if (U.compareAndSwapInt(this, PLOCK, ps, ps | PL_SIGNAL)) {
-                synchronized (this) {
-                    if ((plock & PL_SIGNAL) != 0) {
+            else if ((rs & STARTED) == 0 || (lock = stealCounter) == null)
+                Thread.yield();   // initialization race
+            else if (U.compareAndSwapInt(this, RUNSTATE, rs, rs | RSIGNAL)) {
+                synchronized (lock) {
+                    if ((runState & RSIGNAL) != 0) {
                         try {
-                            wait();
+                            lock.wait();
                         } catch (InterruptedException ie) {
-                            try {
-                                Thread.currentThread().interrupt();
-                            } catch (SecurityException ignore) {
-                            }
+                            if (!(Thread.currentThread() instanceof
+                                  ForkJoinWorkerThread))
+                                wasInterrupted = true;
                         }
                     }
                     else
-                        notifyAll();
+                        lock.notifyAll();
                 }
             }
         }
     }
 
     /**
-     * Unlocks and signals any thread waiting for plock. Called only
-     * when CAS of seq value for unlock fails.
+     * Unlocks and sets runState to newRunState.
+     *
+     * @param oldRunState a value returned from lockRunState
+     * @param newRunState the next value (must have lock bit clear).
      */
-    private void releasePlock(int ps) {
-        plock = ps;
-        synchronized (this) { notifyAll(); }
-    }
-
-    /**
-     * Tries to create and start one worker if fewer than target
-     * parallelism level exist. Adjusts counts etc on failure.
-     */
-    private void tryAddWorker() {
-        long c; int u, e;
-        while ((u = (int)((c = ctl) >>> 32)) < 0 &&
-               (u & SHORT_SIGN) != 0 && (e = (int)c) >= 0) {
-            long nc = ((long)(((u + UTC_UNIT) & UTC_MASK) |
-                              ((u + UAC_UNIT) & UAC_MASK)) << 32) | (long)e;
-            if (U.compareAndSwapLong(this, CTL, c, nc)) {
-                ForkJoinWorkerThreadFactory fac;
-                Throwable ex = null;
-                ForkJoinWorkerThread wt = null;
-                try {
-                    if ((fac = factory) != null &&
-                        (wt = fac.newThread(this)) != null) {
-                        wt.start();
-                        break;
-                    }
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-                deregisterWorker(wt, ex);
-                break;
-            }
+    private void unlockRunState(int oldRunState, int newRunState) {
+        if (!U.compareAndSwapInt(this, RUNSTATE, oldRunState, newRunState)) {
+            Object lock = stealCounter;
+            runState = newRunState;              // clears RSIGNAL bit
+            if (lock != null)
+                synchronized (lock) { lock.notifyAll(); }
         }
     }
 
-    //  Registering and deregistering workers
+    // Creating, registering and deregistering workers
 
     /**
-     * Callback from ForkJoinWorkerThread to establish and record its
-     * WorkQueue. To avoid scanning bias due to packing entries in
-     * front of the workQueues array, we treat the array as a simple
-     * power-of-two hash table using per-thread seed as hash,
-     * expanding as needed.
+     * Tries to construct and start one worker. Assumes that total
+     * count has already been incremented as a reservation.  Invokes
+     * deregisterWorker on any failure.
+     *
+     * @return true if successful
+     */
+    private boolean createWorker() {
+        ForkJoinWorkerThreadFactory fac = factory;
+        Throwable ex = null;
+        ForkJoinWorkerThread wt = null;
+        try {
+            if (fac != null && (wt = fac.newThread(this)) != null) {
+                wt.start();
+                return true;
+            }
+        } catch (Throwable rex) {
+            ex = rex;
+        }
+        deregisterWorker(wt, ex);
+        return false;
+    }
+
+    /**
+     * Tries to add one worker, incrementing ctl counts before doing
+     * so, relying on createWorker to back out on failure.
+     *
+     * @param c incoming ctl value, with total count negative and no
+     * idle workers.  On CAS failure, c is refreshed and retried if
+     * this holds (otherwise, a new worker is not needed).
+     */
+    private void tryAddWorker(long c) {
+        boolean add = false;
+        do {
+            long nc = ((AC_MASK & (c + AC_UNIT)) |
+                       (TC_MASK & (c + TC_UNIT)));
+            if (ctl == c) {
+                int rs, stop;                 // check if terminating
+                if ((stop = (rs = lockRunState()) & STOP) == 0)
+                    add = U.compareAndSwapLong(this, CTL, c, nc);
+                unlockRunState(rs, rs & ~RSLOCK);
+                if (stop != 0)
+                    break;
+                if (add) {
+                    createWorker();
+                    break;
+                }
+            }
+        } while (((c = ctl) & ADD_WORKER) != 0L && (int)c == 0);
+    }
+
+    /**
+     * Callback from ForkJoinWorkerThread constructor to establish and
+     * record its WorkQueue.
      *
      * @param wt the worker thread
      * @return the worker's queue
      */
     final WorkQueue registerWorker(ForkJoinWorkerThread wt) {
-        UncaughtExceptionHandler handler; WorkQueue[] ws; int s, ps;
-        wt.setDaemon(true);
+        UncaughtExceptionHandler handler;
+        wt.setDaemon(true);                           // configure thread
         if ((handler = ueh) != null)
             wt.setUncaughtExceptionHandler(handler);
-        do {} while (!U.compareAndSwapInt(this, INDEXSEED, s = indexSeed,
-                                          s += SEED_INCREMENT) ||
-                     s == 0); // skip 0
-        WorkQueue w = new WorkQueue(this, wt, mode, s);
-        if (((ps = plock) & PL_LOCK) != 0 ||
-            !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
-            ps = acquirePlock();
-        int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
+        WorkQueue w = new WorkQueue(this, wt);
+        int i = 0;                                    // assign a pool index
+        int mode = config & MODE_MASK;
+        int rs = lockRunState();
         try {
-            if ((ws = workQueues) != null) {    // skip if shutting down
-                int n = ws.length, m = n - 1;
-                int r = (s << 1) | 1;           // use odd-numbered indices
-                if (ws[r &= m] != null) {       // collision
-                    int probes = 0;             // step by approx half size
+            WorkQueue[] ws; int n;                    // skip if no array
+            if ((ws = workQueues) != null && (n = ws.length) > 0) {
+                int s = indexSeed += SEED_INCREMENT;  // unlikely to collide
+                int m = n - 1;
+                i = ((s << 1) | 1) & m;               // odd-numbered indices
+                if (ws[i] != null) {                  // collision
+                    int probes = 0;                   // step by approx half n
                     int step = (n <= 4) ? 2 : ((n >>> 1) & EVENMASK) + 2;
-                    while (ws[r = (r + step) & m] != null) {
+                    while (ws[i = (i + step) & m] != null) {
                         if (++probes >= n) {
                             workQueues = ws = Arrays.copyOf(ws, n <<= 1);
                             m = n - 1;
@@ -1387,15 +1551,15 @@
                         }
                     }
                 }
-                w.poolIndex = (short)r;
-                w.eventCount = r; // volatile write orders
-                ws[r] = w;
+                w.hint = s;                           // use as random seed
+                w.config = i | mode;
+                w.scanState = i;                      // publication fence
+                ws[i] = w;
             }
         } finally {
-            if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
-                releasePlock(nps);
+            unlockRunState(rs, rs & ~RSLOCK);
         }
-        wt.setName(workerNamePrefix.concat(Integer.toString(w.poolIndex >>> 1)));
+        wt.setName(workerNamePrefix.concat(Integer.toString(i >>> 1)));
         return w;
     }
 
@@ -1411,384 +1575,322 @@
     final void deregisterWorker(ForkJoinWorkerThread wt, Throwable ex) {
         WorkQueue w = null;
         if (wt != null && (w = wt.workQueue) != null) {
-            int ps;
-            w.qlock = -1;                // ensure set
-            U.getAndAddLong(this, STEALCOUNT, w.nsteals); // collect steals
-            if (((ps = plock) & PL_LOCK) != 0 ||
-                !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
-                ps = acquirePlock();
-            int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
-            try {
-                int idx = w.poolIndex;
-                WorkQueue[] ws = workQueues;
-                if (ws != null && idx >= 0 && idx < ws.length && ws[idx] == w)
-                    ws[idx] = null;
-            } finally {
-                if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
-                    releasePlock(nps);
-            }
+            WorkQueue[] ws;                           // remove index from array
+            int idx = w.config & SMASK;
+            int rs = lockRunState();
+            if ((ws = workQueues) != null && ws.length > idx && ws[idx] == w)
+                ws[idx] = null;
+            unlockRunState(rs, rs & ~RSLOCK);
         }
-
-        long c;                          // adjust ctl counts
+        long c;                                       // decrement counts
         do {} while (!U.compareAndSwapLong
-                     (this, CTL, c = ctl, (((c - AC_UNIT) & AC_MASK) |
-                                           ((c - TC_UNIT) & TC_MASK) |
-                                           (c & ~(AC_MASK|TC_MASK)))));
-
-        if (!tryTerminate(false, false) && w != null && w.array != null) {
-            w.cancelAll();               // cancel remaining tasks
-            WorkQueue[] ws; WorkQueue v; Thread p; int u, i, e;
-            while ((u = (int)((c = ctl) >>> 32)) < 0 && (e = (int)c) >= 0) {
-                if (e > 0) {             // activate or create replacement
-                    if ((ws = workQueues) == null ||
-                        (i = e & SMASK) >= ws.length ||
-                        (v = ws[i]) == null)
-                        break;
-                    long nc = (((long)(v.nextWait & E_MASK)) |
-                               ((long)(u + UAC_UNIT) << 32));
-                    if (v.eventCount != (e | INT_SIGN))
-                        break;
-                    if (U.compareAndSwapLong(this, CTL, c, nc)) {
-                        v.eventCount = (e + E_SEQ) & E_MASK;
-                        if ((p = v.parker) != null)
-                            U.unpark(p);
-                        break;
-                    }
-                }
-                else {
-                    if ((short)u < 0)
-                        tryAddWorker();
-                    break;
-                }
-            }
+                     (this, CTL, c = ctl, ((AC_MASK & (c - AC_UNIT)) |
+                                           (TC_MASK & (c - TC_UNIT)) |
+                                           (SP_MASK & c))));
+        if (w != null) {
+            w.qlock = -1;                             // ensure set
+            w.transferStealCount(this);
+            w.cancelAll();                            // cancel remaining tasks
         }
-        if (ex == null)                     // help clean refs on way out
+        for (;;) {                                    // possibly replace
+            WorkQueue[] ws; int m, sp;
+            if (tryTerminate(false, false) || w == null || w.array == null ||
+                (runState & STOP) != 0 || (ws = workQueues) == null ||
+                (m = ws.length - 1) < 0)              // already terminating
+                break;
+            if ((sp = (int)(c = ctl)) != 0) {         // wake up replacement
+                if (tryRelease(c, ws[sp & m], AC_UNIT))
+                    break;
+            }
+            else if (ex != null && (c & ADD_WORKER) != 0L) {
+                tryAddWorker(c);                      // create replacement
+                break;
+            }
+            else                                      // don't need replacement
+                break;
+        }
+        if (ex == null)                               // help clean on way out
             ForkJoinTask.helpExpungeStaleExceptions();
-        else                                // rethrow
+        else                                          // rethrow
             ForkJoinTask.rethrow(ex);
     }
 
-    // Submissions
-
-    /**
-     * Unless shutting down, adds the given task to a submission queue
-     * at submitter's current queue index (modulo submission
-     * range). Only the most common path is directly handled in this
-     * method. All others are relayed to fullExternalPush.
-     *
-     * @param task the task. Caller must ensure non-null.
-     */
-    final void externalPush(ForkJoinTask<?> task) {
-        WorkQueue q; int m, s, n, am; ForkJoinTask<?>[] a;
-        int r = ThreadLocalRandom.getProbe();
-        int ps = plock;
-        WorkQueue[] ws = workQueues;
-        if (ps > 0 && ws != null && (m = (ws.length - 1)) >= 0 &&
-            (q = ws[m & r & SQMASK]) != null && r != 0 &&
-            U.compareAndSwapInt(q, QLOCK, 0, 1)) { // lock
-            if ((a = q.array) != null &&
-                (am = a.length - 1) > (n = (s = q.top) - q.base)) {
-                int j = ((am & s) << ASHIFT) + ABASE;
-                U.putOrderedObject(a, j, task);
-                q.top = s + 1;                     // push on to deque
-                q.qlock = 0;
-                if (n <= 1)
-                    signalWork(ws, q);
-                return;
-            }
-            q.qlock = 0;
-        }
-        fullExternalPush(task);
-    }
-
-    /**
-     * Full version of externalPush. This method is called, among
-     * other times, upon the first submission of the first task to the
-     * pool, so must perform secondary initialization.  It also
-     * detects first submission by an external thread by looking up
-     * its ThreadLocal, and creates a new shared queue if the one at
-     * index if empty or contended. The plock lock body must be
-     * exception-free (so no try/finally) so we optimistically
-     * allocate new queues outside the lock and throw them away if
-     * (very rarely) not needed.
-     *
-     * Secondary initialization occurs when plock is zero, to create
-     * workQueue array and set plock to a valid value.  This lock body
-     * must also be exception-free. Because the plock seq value can
-     * eventually wrap around zero, this method harmlessly fails to
-     * reinitialize if workQueues exists, while still advancing plock.
-     */
-    private void fullExternalPush(ForkJoinTask<?> task) {
-        int r;
-        if ((r = ThreadLocalRandom.getProbe()) == 0) {
-            ThreadLocalRandom.localInit();
-            r = ThreadLocalRandom.getProbe();
-        }
-        for (;;) {
-            WorkQueue[] ws; WorkQueue q; int ps, m, k;
-            boolean move = false;
-            if ((ps = plock) < 0)
-                throw new RejectedExecutionException();
-            else if (ps == 0 || (ws = workQueues) == null ||
-                     (m = ws.length - 1) < 0) { // initialize workQueues
-                int p = parallelism;            // find power of two table size
-                int n = (p > 1) ? p - 1 : 1;    // ensure at least 2 slots
-                n |= n >>> 1; n |= n >>> 2;  n |= n >>> 4;
-                n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1;
-                WorkQueue[] nws = ((ws = workQueues) == null || ws.length == 0 ?
-                                   new WorkQueue[n] : null);
-                if (((ps = plock) & PL_LOCK) != 0 ||
-                    !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
-                    ps = acquirePlock();
-                if (((ws = workQueues) == null || ws.length == 0) && nws != null)
-                    workQueues = nws;
-                int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
-                if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
-                    releasePlock(nps);
-            }
-            else if ((q = ws[k = r & m & SQMASK]) != null) {
-                if (q.qlock == 0 && U.compareAndSwapInt(q, QLOCK, 0, 1)) {
-                    ForkJoinTask<?>[] a = q.array;
-                    int s = q.top;
-                    boolean submitted = false;
-                    try {                      // locked version of push
-                        if ((a != null && a.length > s + 1 - q.base) ||
-                            (a = q.growArray()) != null) {   // must presize
-                            int j = (((a.length - 1) & s) << ASHIFT) + ABASE;
-                            U.putOrderedObject(a, j, task);
-                            q.top = s + 1;
-                            submitted = true;
-                        }
-                    } finally {
-                        q.qlock = 0;  // unlock
-                    }
-                    if (submitted) {
-                        signalWork(ws, q);
-                        return;
-                    }
-                }
-                move = true; // move on failure
-            }
-            else if (((ps = plock) & PL_LOCK) == 0) { // create new queue
-                q = new WorkQueue(this, null, SHARED_QUEUE, r);
-                q.poolIndex = (short)k;
-                if (((ps = plock) & PL_LOCK) != 0 ||
-                    !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
-                    ps = acquirePlock();
-                if ((ws = workQueues) != null && k < ws.length && ws[k] == null)
-                    ws[k] = q;
-                int nps = (ps & SHUTDOWN) | ((ps + PL_LOCK) & ~SHUTDOWN);
-                if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
-                    releasePlock(nps);
-            }
-            else
-                move = true; // move if busy
-            if (move)
-                r = ThreadLocalRandom.advanceProbe(r);
-        }
-    }
-
-    // Maintaining ctl counts
-
-    /**
-     * Increments active count; mainly called upon return from blocking.
-     */
-    final void incrementActiveCount() {
-        long c;
-        do {} while (!U.compareAndSwapLong
-                     (this, CTL, c = ctl, ((c & ~AC_MASK) |
-                                           ((c & AC_MASK) + AC_UNIT))));
-    }
+    // Signalling
 
     /**
      * Tries to create or activate a worker if too few are active.
      *
      * @param ws the worker array to use to find signallees
-     * @param q if non-null, the queue holding tasks to be processed
+     * @param q a WorkQueue --if non-null, don't retry if now empty
      */
     final void signalWork(WorkQueue[] ws, WorkQueue q) {
-        for (;;) {
-            long c; int e, u, i; WorkQueue w; Thread p;
-            if ((u = (int)((c = ctl) >>> 32)) >= 0)
-                break;
-            if ((e = (int)c) <= 0) {
-                if ((short)u < 0)
-                    tryAddWorker();
+        long c; int sp, i; WorkQueue v; Thread p;
+        while ((c = ctl) < 0L) {                       // too few active
+            if ((sp = (int)c) == 0) {                  // no idle workers
+                if ((c & ADD_WORKER) != 0L)            // too few workers
+                    tryAddWorker(c);
                 break;
             }
-            if (ws == null || ws.length <= (i = e & SMASK) ||
-                (w = ws[i]) == null)
+            if (ws == null)                            // unstarted/terminated
                 break;
-            long nc = (((long)(w.nextWait & E_MASK)) |
-                       ((long)(u + UAC_UNIT)) << 32);
-            int ne = (e + E_SEQ) & E_MASK;
-            if (w.eventCount == (e | INT_SIGN) &&
-                U.compareAndSwapLong(this, CTL, c, nc)) {
-                w.eventCount = ne;
-                if ((p = w.parker) != null)
+            if (ws.length <= (i = sp & SMASK))         // terminated
+                break;
+            if ((v = ws[i]) == null)                   // terminating
+                break;
+            int vs = (sp + SS_SEQ) & ~INACTIVE;        // next scanState
+            int d = sp - v.scanState;                  // screen CAS
+            long nc = (UC_MASK & (c + AC_UNIT)) | (SP_MASK & v.stackPred);
+            if (d == 0 && U.compareAndSwapLong(this, CTL, c, nc)) {
+                v.scanState = vs;                      // activate v
+                if ((p = v.parker) != null)
                     U.unpark(p);
                 break;
             }
-            if (q != null && q.base >= q.top)
+            if (q != null && q.base == q.top)          // no more work
                 break;
         }
     }
 
+    /**
+     * Signals and releases worker v if it is top of idle worker
+     * stack.  This performs a one-shot version of signalWork only if
+     * there is (apparently) at least one idle worker.
+     *
+     * @param c incoming ctl value
+     * @param v if non-null, a worker
+     * @param inc the increment to active count (zero when compensating)
+     * @return true if successful
+     */
+    private boolean tryRelease(long c, WorkQueue v, long inc) {
+        int sp = (int)c, vs = (sp + SS_SEQ) & ~INACTIVE; Thread p;
+        if (v != null && v.scanState == sp) {          // v is at top of stack
+            long nc = (UC_MASK & (c + inc)) | (SP_MASK & v.stackPred);
+            if (U.compareAndSwapLong(this, CTL, c, nc)) {
+                v.scanState = vs;
+                if ((p = v.parker) != null)
+                    U.unpark(p);
+                return true;
+            }
+        }
+        return false;
+    }
+
     // Scanning for tasks
 
     /**
      * Top-level runloop for workers, called by ForkJoinWorkerThread.run.
      */
     final void runWorker(WorkQueue w) {
-        w.growArray(); // allocate queue
-        for (int r = w.hint; scan(w, r) == 0; ) {
+        w.growArray();                   // allocate queue
+        int seed = w.hint;               // initially holds randomization hint
+        int r = (seed == 0) ? 1 : seed;  // avoid 0 for xorShift
+        for (ForkJoinTask<?> t;;) {
+            if ((t = scan(w, r)) != null)
+                w.runTask(t);
+            else if (!awaitWork(w, r))
+                break;
             r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // xorshift
         }
     }
 
     /**
-     * Scans for and, if found, runs one task, else possibly
-     * inactivates the worker. This method operates on single reads of
-     * volatile state and is designed to be re-invoked continuously,
-     * in part because it returns upon detecting inconsistencies,
-     * contention, or state changes that indicate possible success on
-     * re-invocation.
-     *
-     * The scan searches for tasks across queues starting at a random
-     * index, checking each at least twice.  The scan terminates upon
-     * either finding a non-empty queue, or completing the sweep. If
-     * the worker is not inactivated, it takes and runs a task from
-     * this queue. Otherwise, if not activated, it tries to activate
-     * itself or some other worker by signalling. On failure to find a
-     * task, returns (for retry) if pool state may have changed during
-     * an empty scan, or tries to inactivate if active, else possibly
-     * blocks or terminates via method awaitWork.
+     * Scans for and tries to steal a top-level task. Scans start at a
+     * random location, randomly moving on apparent contention,
+     * otherwise continuing linearly until reaching two consecutive
+     * empty passes over all queues with the same checksum (summing
+     * each base index of each queue, that moves on each steal), at
+     * which point the worker tries to inactivate and then re-scans,
+     * attempting to re-activate (itself or some other worker) if
+     * finding a task; otherwise returning null to await work.  Scans
+     * otherwise touch as little memory as possible, to reduce
+     * disruption on other scanning threads.
      *
      * @param w the worker (via its WorkQueue)
      * @param r a random seed
-     * @return worker qlock status if would have waited, else 0
+     * @return a task, or null if none found
      */
-    private final int scan(WorkQueue w, int r) {
+    private ForkJoinTask<?> scan(WorkQueue w, int r) {
         WorkQueue[] ws; int m;
-        long c = ctl;                            // for consistency check
-        if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 && w != null) {
-            for (int j = m + m + 1, ec = w.eventCount;;) {
-                WorkQueue q; int b, e; ForkJoinTask<?>[] a; ForkJoinTask<?> t;
-                if ((q = ws[(r - j) & m]) != null &&
-                    (b = q.base) - q.top < 0 && (a = q.array) != null) {
-                    long i = (((a.length - 1) & b) << ASHIFT) + ABASE;
-                    if ((t = ((ForkJoinTask<?>)
-                              U.getObjectVolatile(a, i))) != null) {
-                        if (ec < 0)
-                            helpRelease(c, ws, w, q, b);
-                        else if (q.base == b &&
-                                 U.compareAndSwapObject(a, i, t, null)) {
-                            U.putOrderedInt(q, QBASE, b + 1);
-                            if ((b + 1) - q.top < 0)
-                                signalWork(ws, q);
-                            w.runTask(t);
+        if ((ws = workQueues) != null && (m = ws.length - 1) > 0 && w != null) {
+            int ss = w.scanState;                     // initially non-negative
+            for (int origin = r & m, k = origin, oldSum = 0, checkSum = 0;;) {
+                WorkQueue q; ForkJoinTask<?>[] a; ForkJoinTask<?> t;
+                int b, n; long c;
+                if ((q = ws[k]) != null) {
+                    if ((n = (b = q.base) - q.top) < 0 &&
+                        (a = q.array) != null) {      // non-empty
+                        long i = (((a.length - 1) & b) << ASHIFT) + ABASE;
+                        if ((t = ((ForkJoinTask<?>)
+                                  U.getObjectVolatile(a, i))) != null &&
+                            q.base == b) {
+                            if (ss >= 0) {
+                                if (U.compareAndSwapObject(a, i, t, null)) {
+                                    q.base = b + 1;
+                                    if (n < -1)       // signal others
+                                        signalWork(ws, q);
+                                    return t;
+                                }
+                            }
+                            else if (oldSum == 0 &&   // try to activate
+                                     w.scanState < 0)
+                                tryRelease(c = ctl, ws[m & (int)c], AC_UNIT);
                         }
+                        if (ss < 0)                   // refresh
+                            ss = w.scanState;
+                        r ^= r << 1; r ^= r >>> 3; r ^= r << 10;
+                        origin = k = r & m;           // move and rescan
+                        oldSum = checkSum = 0;
+                        continue;
                     }
-                    break;
+                    checkSum += b;
                 }
-                else if (--j < 0) {
-                    if ((ec | (e = (int)c)) < 0) // inactive or terminating
-                        return awaitWork(w, c, ec);
-                    else if (ctl == c) {         // try to inactivate and enqueue
-                        long nc = (long)ec | ((c - AC_UNIT) & (AC_MASK|TC_MASK));
-                        w.nextWait = e;
-                        w.eventCount = ec | INT_SIGN;
-                        if (!U.compareAndSwapLong(this, CTL, c, nc))
-                            w.eventCount = ec;   // back out
+                if ((k = (k + 1) & m) == origin) {    // continue until stable
+                    if ((ss >= 0 || (ss == (ss = w.scanState))) &&
+                        oldSum == (oldSum = checkSum)) {
+                        if (ss < 0 || w.qlock < 0)    // already inactive
+                            break;
+                        int ns = ss | INACTIVE;       // try to inactivate
+                        long nc = ((SP_MASK & ns) |
+                                   (UC_MASK & ((c = ctl) - AC_UNIT)));
+                        w.stackPred = (int)c;         // hold prev stack top
+                        U.putInt(w, QSCANSTATE, ns);
+                        if (U.compareAndSwapLong(this, CTL, c, nc))
+                            ss = ns;
+                        else
+                            w.scanState = ss;         // back out
                     }
-                    break;
+                    checkSum = 0;
                 }
             }
         }
-        return 0;
+        return null;
     }
 
     /**
-     * A continuation of scan(), possibly blocking or terminating
-     * worker w. Returns without blocking if pool state has apparently
-     * changed since last invocation.  Also, if inactivating w has
-     * caused the pool to become quiescent, checks for pool
+     * Possibly blocks worker w waiting for a task to steal, or
+     * returns false if the worker should terminate.  If inactivating
+     * w has caused the pool to become quiescent, checks for pool
      * termination, and, so long as this is not the only worker, waits
-     * for event for up to a given duration.  On timeout, if ctl has
-     * not changed, terminates the worker, which will in turn wake up
+     * for up to a given duration.  On timeout, if ctl has not
+     * changed, terminates the worker, which will in turn wake up
      * another worker to possibly repeat this process.
      *
      * @param w the calling worker
-     * @param c the ctl value on entry to scan
-     * @param ec the worker's eventCount on entry to scan
+     * @param r a random seed (for spins)
+     * @return false if the worker should terminate
      */
-    private final int awaitWork(WorkQueue w, long c, int ec) {
-        int stat, ns; long parkTime, deadline;
-        if ((stat = w.qlock) >= 0 && w.eventCount == ec && ctl == c &&
-            !Thread.interrupted()) {
-            int e = (int)c;
-            int u = (int)(c >>> 32);
-            int d = (u >> UAC_SHIFT) + parallelism; // active count
-
-            if (e < 0 || (d <= 0 && tryTerminate(false, false)))
-                stat = w.qlock = -1;          // pool is terminating
-            else if ((ns = w.nsteals) != 0) { // collect steals and retry
-                w.nsteals = 0;
-                U.getAndAddLong(this, STEALCOUNT, (long)ns);
+    private boolean awaitWork(WorkQueue w, int r) {
+        if (w == null || w.qlock < 0)                 // w is terminating
+            return false;
+        for (int pred = w.stackPred, spins = SPINS, ss;;) {
+            if ((ss = w.scanState) >= 0)
+                break;
+            else if (spins > 0) {
+                r ^= r << 6; r ^= r >>> 21; r ^= r << 7;
+                if (r >= 0 && --spins == 0) {         // randomize spins
+                    WorkQueue v; WorkQueue[] ws; int s, j; AtomicLong sc;
+                    if (pred != 0 && (ws = workQueues) != null &&
+                        (j = pred & SMASK) < ws.length &&
+                        (v = ws[j]) != null &&        // see if pred parking
+                        (v.parker == null || v.scanState >= 0))
+                        spins = SPINS;                // continue spinning
+                }
             }
-            else {
-                long pc = ((d > 0 || ec != (e | INT_SIGN)) ? 0L :
-                           ((long)(w.nextWait & E_MASK)) | // ctl to restore
-                           ((long)(u + UAC_UNIT)) << 32);
-                if (pc != 0L) {               // timed wait if last waiter
-                    int dc = -(short)(c >>> TC_SHIFT);
-                    parkTime = (dc < 0 ? FAST_IDLE_TIMEOUT:
-                                (dc + 1) * IDLE_TIMEOUT);
+            else if (w.qlock < 0)                     // recheck after spins
+                return false;
+            else if (!Thread.interrupted()) {
+                long c, prevctl, parkTime, deadline;
+                int ac = (int)((c = ctl) >> AC_SHIFT) + (config & SMASK);
+                if ((ac <= 0 && tryTerminate(false, false)) ||
+                    (runState & STOP) != 0)           // pool terminating
+                    return false;
+                if (ac <= 0 && ss == (int)c) {        // is last waiter
+                    prevctl = (UC_MASK & (c + AC_UNIT)) | (SP_MASK & pred);
+                    int t = (short)(c >>> TC_SHIFT);  // shrink excess spares
+                    if (t > 2 && U.compareAndSwapLong(this, CTL, c, prevctl))
+                        return false;                 // else use timed wait
+                    parkTime = IDLE_TIMEOUT * ((t >= 0) ? 1 : 1 - t);
                     deadline = System.nanoTime() + parkTime - TIMEOUT_SLOP;
                 }
                 else
-                    parkTime = deadline = 0L;
-                if (w.eventCount == ec && ctl == c) {
-                    Thread wt = Thread.currentThread();
-                    U.putObject(wt, PARKBLOCKER, this);
-                    w.parker = wt;            // emulate LockSupport.park
-                    if (w.eventCount == ec && ctl == c)
-                        U.park(false, parkTime);  // must recheck before park
-                    w.parker = null;
-                    U.putObject(wt, PARKBLOCKER, null);
-                    if (parkTime != 0L && ctl == c &&
-                        deadline - System.nanoTime() <= 0L &&
-                        U.compareAndSwapLong(this, CTL, c, pc))
-                        stat = w.qlock = -1;  // shrink pool
+                    prevctl = parkTime = deadline = 0L;
+                Thread wt = Thread.currentThread();
+                U.putObject(wt, PARKBLOCKER, this);   // emulate LockSupport
+                w.parker = wt;
+                if (w.scanState < 0 && ctl == c)      // recheck before park
+                    U.park(false, parkTime);
+                U.putOrderedObject(w, QPARKER, null);
+                U.putObject(wt, PARKBLOCKER, null);
+                if (w.scanState >= 0)
+                    break;
+                if (parkTime != 0L && ctl == c &&
+                    deadline - System.nanoTime() <= 0L &&
+                    U.compareAndSwapLong(this, CTL, c, prevctl))
+                    return false;                     // shrink pool
+            }
+        }
+        return true;
+    }
+
+    // Joining tasks
+
+    /**
+     * Tries to steal and run tasks within the target's computation.
+     * Uses a variant of the top-level algorithm, restricted to tasks
+     * with the given task as ancestor: It prefers taking and running
+     * eligible tasks popped from the worker's own queue (via
+     * popCC). Otherwise it scans others, randomly moving on
+     * contention or execution, deciding to give up based on a
+     * checksum (via return codes frob pollAndExecCC). The maxTasks
+     * argument supports external usages; internal calls use zero,
+     * allowing unbounded steps (external calls trap non-positive
+     * values).
+     *
+     * @param w caller
+     * @param maxTasks if non-zero, the maximum number of other tasks to run
+     * @return task status on exit
+     */
+    final int helpComplete(WorkQueue w, CountedCompleter<?> task,
+                           int maxTasks) {
+        WorkQueue[] ws; int s = 0, m;
+        if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 &&
+            task != null && w != null) {
+            int mode = w.config;                 // for popCC
+            int r = w.hint ^ w.top;              // arbitrary seed for origin
+            int origin = r & m;                  // first queue to scan
+            int h = 1;                           // 1:ran, >1:contended, <0:hash
+            for (int k = origin, oldSum = 0, checkSum = 0;;) {
+                CountedCompleter<?> p; WorkQueue q;
+                if ((s = task.status) < 0)
+                    break;
+                if (h == 1 && (p = w.popCC(task, mode)) != null) {
+                    p.doExec();                  // run local task
+                    if (maxTasks != 0 && --maxTasks == 0)
+                        break;
+                    origin = k;                  // reset
+                    oldSum = checkSum = 0;
+                }
+                else {                           // poll other queues
+                    if ((q = ws[k]) == null)
+                        h = 0;
+                    else if ((h = q.pollAndExecCC(task)) < 0)
+                        checkSum += h;
+                    if (h > 0) {
+                        if (h == 1 && maxTasks != 0 && --maxTasks == 0)
+                            break;
+                        r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // xorshift
+                        origin = k = r & m;      // move and restart
+                        oldSum = checkSum = 0;
+                    }
+                    else if ((k = (k + 1) & m) == origin) {
+                        if (oldSum == (oldSum = checkSum))
+                            break;
+                        checkSum = 0;
+                    }
                 }
             }
         }
-        return stat;
-    }
-
-    /**
-     * Possibly releases (signals) a worker. Called only from scan()
-     * when a worker with apparently inactive status finds a non-empty
-     * queue. This requires revalidating all of the associated state
-     * from caller.
-     */
-    private final void helpRelease(long c, WorkQueue[] ws, WorkQueue w,
-                                   WorkQueue q, int b) {
-        WorkQueue v; int e, i; Thread p;
-        if (w != null && w.eventCount < 0 && (e = (int)c) > 0 &&
-            ws != null && ws.length > (i = e & SMASK) &&
-            (v = ws[i]) != null && ctl == c) {
-            long nc = (((long)(v.nextWait & E_MASK)) |
-                       ((long)((int)(c >>> 32) + UAC_UNIT)) << 32);
-            int ne = (e + E_SEQ) & E_MASK;
-            if (q != null && q.base == b && w.eventCount < 0 &&
-                v.eventCount == (e | INT_SIGN) &&
-                U.compareAndSwapLong(this, CTL, c, nc)) {
-                v.eventCount = ne;
-                if ((p = v.parker) != null)
-                    U.unpark(p);
-            }
-        }
+        return s;
     }
 
     /**
@@ -1799,268 +1901,167 @@
      * execute tasks from. The first call to this method upon a
      * waiting join will often entail scanning/search, (which is OK
      * because the joiner has nothing better to do), but this method
-     * leaves hints in workers to speed up subsequent calls. The
-     * implementation is very branchy to cope with potential
-     * inconsistencies or loops encountering chains that are stale,
-     * unknown, or so long that they are likely cyclic.
+     * leaves hints in workers to speed up subsequent calls.
      *
-     * @param joiner the joining worker
+     * @param w caller
      * @param task the task to join
-     * @return 0 if no progress can be made, negative if task
-     * known complete, else positive
      */
-    private int tryHelpStealer(WorkQueue joiner, ForkJoinTask<?> task) {
-        int stat = 0, steps = 0;                    // bound to avoid cycles
-        if (task != null && joiner != null &&
-            joiner.base - joiner.top >= 0) {        // hoist checks
-            restart: for (;;) {
-                ForkJoinTask<?> subtask = task;     // current target
-                for (WorkQueue j = joiner, v;;) {   // v is stealer of subtask
-                    WorkQueue[] ws; int m, s, h;
-                    if ((s = task.status) < 0) {
-                        stat = s;
-                        break restart;
-                    }
-                    if ((ws = workQueues) == null || (m = ws.length - 1) <= 0)
-                        break restart;              // shutting down
-                    if ((v = ws[h = (j.hint | 1) & m]) == null ||
-                        v.currentSteal != subtask) {
-                        for (int origin = h;;) {    // find stealer
-                            if (((h = (h + 2) & m) & 15) == 1 &&
-                                (subtask.status < 0 || j.currentJoin != subtask))
-                                continue restart;   // occasional staleness check
-                            if ((v = ws[h]) != null &&
-                                v.currentSteal == subtask) {
-                                j.hint = h;        // save hint
+    private void helpStealer(WorkQueue w, ForkJoinTask<?> task) {
+        WorkQueue[] ws = workQueues;
+        int oldSum = 0, checkSum, m;
+        if (ws != null && (m = ws.length - 1) >= 0 && w != null &&
+            task != null) {
+            do {                                       // restart point
+                checkSum = 0;                          // for stability check
+                ForkJoinTask<?> subtask;
+                WorkQueue j = w, v;                    // v is subtask stealer
+                descent: for (subtask = task; subtask.status >= 0; ) {
+                    for (int h = j.hint | 1, k = 0, i; ; k += 2) {
+                        if (k > m)                     // can't find stealer
+                            break descent;
+                        if ((v = ws[i = (h + k) & m]) != null) {
+                            if (v.currentSteal == subtask) {
+                                j.hint = i;
                                 break;
                             }
-                            if (h == origin)
-                                break restart;      // cannot find stealer
+                            checkSum += v.base;
                         }
                     }
-                    for (;;) { // help stealer or descend to its stealer
+                    for (;;) {                         // help v or descend
                         ForkJoinTask<?>[] a; int b;
-                        if (subtask.status < 0)     // surround probes with
-                            continue restart;       //   consistency checks
-                        if ((b = v.base) - v.top < 0 && (a = v.array) != null) {
-                            int i = (((a.length - 1) & b) << ASHIFT) + ABASE;
-                            ForkJoinTask<?> t =
-                                (ForkJoinTask<?>)U.getObjectVolatile(a, i);
-                            if (subtask.status < 0 || j.currentJoin != subtask ||
-                                v.currentSteal != subtask)
-                                continue restart;   // stale
-                            stat = 1;               // apparent progress
-                            if (v.base == b) {
-                                if (t == null)
-                                    break restart;
-                                if (U.compareAndSwapObject(a, i, t, null)) {
-                                    U.putOrderedInt(v, QBASE, b + 1);
-                                    ForkJoinTask<?> ps = joiner.currentSteal;
-                                    int jt = joiner.top;
-                                    do {
-                                        joiner.currentSteal = t;
-                                        t.doExec(); // clear local tasks too
-                                    } while (task.status >= 0 &&
-                                             joiner.top != jt &&
-                                             (t = joiner.pop()) != null);
-                                    joiner.currentSteal = ps;
-                                    break restart;
-                                }
-                            }
+                        checkSum += (b = v.base);
+                        ForkJoinTask<?> next = v.currentJoin;
+                        if (subtask.status < 0 || j.currentJoin != subtask ||
+                            v.currentSteal != subtask) // stale
+                            break descent;
+                        if (b - v.top >= 0 || (a = v.array) == null) {
+                            if ((subtask = next) == null)
+                                break descent;
+                            j = v;
+                            break;
                         }
-                        else {                      // empty -- try to descend
-                            ForkJoinTask<?> next = v.currentJoin;
-                            if (subtask.status < 0 || j.currentJoin != subtask ||
-                                v.currentSteal != subtask)
-                                continue restart;   // stale
-                            else if (next == null || ++steps == MAX_HELP)
-                                break restart;      // dead-end or maybe cyclic
-                            else {
-                                subtask = next;
-                                j = v;
-                                break;
+                        int i = (((a.length - 1) & b) << ASHIFT) + ABASE;
+                        ForkJoinTask<?> t = ((ForkJoinTask<?>)
+                                             U.getObjectVolatile(a, i));
+                        if (v.base == b) {
+                            if (t == null)             // stale
+                                break descent;
+                            if (U.compareAndSwapObject(a, i, t, null)) {
+                                v.base = b + 1;
+                                ForkJoinTask<?> ps = w.currentSteal;
+                                int top = w.top;
+                                do {
+                                    U.putOrderedObject(w, QCURRENTSTEAL, t);
+                                    t.doExec();        // clear local tasks too
+                                } while (task.status >= 0 &&
+                                         w.top != top &&
+                                         (t = w.pop()) != null);
+                                U.putOrderedObject(w, QCURRENTSTEAL, ps);
+                                if (w.base != w.top)
+                                    return;            // can't further help
                             }
                         }
                     }
                 }
-            }
+            } while (task.status >= 0 && oldSum != (oldSum = checkSum));
         }
-        return stat;
-    }
-
-    /**
-     * Analog of tryHelpStealer for CountedCompleters. Tries to steal
-     * and run tasks within the target's computation.
-     *
-     * @param task the task to join
-     * @param maxTasks the maximum number of other tasks to run
-     */
-    final int helpComplete(WorkQueue joiner, CountedCompleter<?> task,
-                           int maxTasks) {
-        WorkQueue[] ws; int m;
-        int s = 0;
-        if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 &&
-            joiner != null && task != null) {
-            int j = joiner.poolIndex;
-            int scans = m + m + 1;
-            long c = 0L;              // for stability check
-            for (int k = scans; ; j += 2) {
-                WorkQueue q;
-                if ((s = task.status) < 0)
-                    break;
-                else if (joiner.internalPopAndExecCC(task)) {
-                    if (--maxTasks <= 0) {
-                        s = task.status;
-                        break;
-                    }
-                    k = scans;
-                }
-                else if ((s = task.status) < 0)
-                    break;
-                else if ((q = ws[j & m]) != null && q.pollAndExecCC(task)) {
-                    if (--maxTasks <= 0) {
-                        s = task.status;
-                        break;
-                    }
-                    k = scans;
-                }
-                else if (--k < 0) {
-                    if (c == (c = ctl))
-                        break;
-                    k = scans;
-                }
-            }
-        }
-        return s;
     }
 
     /**
      * Tries to decrement active count (sometimes implicitly) and
      * possibly release or create a compensating worker in preparation
-     * for blocking. Fails on contention or termination. Otherwise,
-     * adds a new thread if no idle workers are available and pool
-     * may become starved.
+     * for blocking. Returns false (retryable by caller), on
+     * contention, detected staleness, instability, or termination.
      *
-     * @param c the assumed ctl value
+     * @param w caller
      */
-    final boolean tryCompensate(long c) {
-        WorkQueue[] ws = workQueues;
-        int pc = parallelism, e = (int)c, m, tc;
-        if (ws != null && (m = ws.length - 1) >= 0 && e >= 0 && ctl == c) {
-            WorkQueue w = ws[e & m];
-            if (e != 0 && w != null) {
-                Thread p;
-                long nc = ((long)(w.nextWait & E_MASK) |
-                           (c & (AC_MASK|TC_MASK)));
-                int ne = (e + E_SEQ) & E_MASK;
-                if (w.eventCount == (e | INT_SIGN) &&
-                    U.compareAndSwapLong(this, CTL, c, nc)) {
-                    w.eventCount = ne;
-                    if ((p = w.parker) != null)
-                        U.unpark(p);
-                    return true;   // replace with idle worker
+    private boolean tryCompensate(WorkQueue w) {
+        boolean canBlock;
+        WorkQueue[] ws; long c; int m, pc, sp;
+        if (w == null || w.qlock < 0 ||           // caller terminating
+            (ws = workQueues) == null || (m = ws.length - 1) <= 0 ||
+            (pc = config & SMASK) == 0)           // parallelism disabled
+            canBlock = false;
+        else if ((sp = (int)(c = ctl)) != 0)      // release idle worker
+            canBlock = tryRelease(c, ws[sp & m], 0L);
+        else {
+            int ac = (int)(c >> AC_SHIFT) + pc;
+            int tc = (short)(c >> TC_SHIFT) + pc;
+            int nbusy = 0;                        // validate saturation
+            for (int i = 0; i <= m; ++i) {        // two passes of odd indices
+                WorkQueue v;
+                if ((v = ws[((i << 1) | 1) & m]) != null) {
+                    if ((v.scanState & SCANNING) != 0)
+                        break;
+                    ++nbusy;
                 }
             }
-            else if ((tc = (short)(c >>> TC_SHIFT)) >= 0 &&
-                     (int)(c >> AC_SHIFT) + pc > 1) {
-                long nc = ((c - AC_UNIT) & AC_MASK) | (c & ~AC_MASK);
-                if (U.compareAndSwapLong(this, CTL, c, nc))
-                    return true;   // no compensation
+            if (nbusy != (tc << 1) || ctl != c)
+                canBlock = false;                 // unstable or stale
+            else if (tc >= pc && ac > 1 && w.isEmpty()) {
+                long nc = ((AC_MASK & (c - AC_UNIT)) |
+                           (~AC_MASK & c));       // uncompensated
+                canBlock = U.compareAndSwapLong(this, CTL, c, nc);
             }
-            else if (tc + pc < MAX_CAP) {
-                long nc = ((c + TC_UNIT) & TC_MASK) | (c & ~TC_MASK);
-                if (U.compareAndSwapLong(this, CTL, c, nc)) {
-                    ForkJoinWorkerThreadFactory fac;
-                    Throwable ex = null;
-                    ForkJoinWorkerThread wt = null;
-                    try {
-                        if ((fac = factory) != null &&
-                            (wt = fac.newThread(this)) != null) {
-                            wt.start();
-                            return true;
-                        }
-                    } catch (Throwable rex) {
-                        ex = rex;
-                    }
-                    deregisterWorker(wt, ex); // clean up and return false
-                }
+            else if (tc >= MAX_CAP ||
+                     (this == common && tc >= pc + commonMaxSpares))
+                throw new RejectedExecutionException(
+                    "Thread limit exceeded replacing blocked worker");
+            else {                                // similar to tryAddWorker
+                boolean add = false; int rs;      // CAS within lock
+                long nc = ((AC_MASK & c) |
+                           (TC_MASK & (c + TC_UNIT)));
+                if (((rs = lockRunState()) & STOP) == 0)
+                    add = U.compareAndSwapLong(this, CTL, c, nc);
+                unlockRunState(rs, rs & ~RSLOCK);
+                canBlock = add && createWorker(); // throws on exception
             }
         }
-        return false;
+        return canBlock;
     }
 
     /**
-     * Helps and/or blocks until the given task is done.
+     * Helps and/or blocks until the given task is done or timeout.
      *
-     * @param joiner the joining worker
+     * @param w caller
      * @param task the task
+     * @param deadline for timed waits, if nonzero
      * @return task status on exit
      */
-    final int awaitJoin(WorkQueue joiner, ForkJoinTask<?> task) {
+    final int awaitJoin(WorkQueue w, ForkJoinTask<?> task, long deadline) {
         int s = 0;
-        if (task != null && (s = task.status) >= 0 && joiner != null) {
-            ForkJoinTask<?> prevJoin = joiner.currentJoin;
-            joiner.currentJoin = task;
-            do {} while (joiner.tryRemoveAndExec(task) && // process local tasks
-                         (s = task.status) >= 0);
-            if (s >= 0 && (task instanceof CountedCompleter))
-                s = helpComplete(joiner, (CountedCompleter<?>)task, Integer.MAX_VALUE);
-            long cc = 0;        // for stability checks
-            while (s >= 0 && (s = task.status) >= 0) {
-                if ((s = tryHelpStealer(joiner, task)) == 0 &&
-                    (s = task.status) >= 0) {
-                    if (!tryCompensate(cc))
-                        cc = ctl;
-                    else {
-                        if (task.trySetSignal() && (s = task.status) >= 0) {
-                            synchronized (task) {
-                                if (task.status >= 0) {
-                                    try {                // see ForkJoinTask
-                                        task.wait();     //  for explanation
-                                    } catch (InterruptedException ie) {
-                                    }
-                                }
-                                else
-                                    task.notifyAll();
-                            }
-                        }
-                        long c; // reactivate
-                        do {} while (!U.compareAndSwapLong
-                                     (this, CTL, c = ctl,
-                                      ((c & ~AC_MASK) |
-                                       ((c & AC_MASK) + AC_UNIT))));
-                    }
+        if (task != null && w != null) {
+            ForkJoinTask<?> prevJoin = w.currentJoin;
+            U.putOrderedObject(w, QCURRENTJOIN, task);
+            CountedCompleter<?> cc = (task instanceof CountedCompleter) ?
+                (CountedCompleter<?>)task : null;
+            for (;;) {
+                if ((s = task.status) < 0)
+                    break;
+                if (cc != null)
+                    helpComplete(w, cc, 0);
+                else if (w.base == w.top || w.tryRemoveAndExec(task))
+                    helpStealer(w, task);
+                if ((s = task.status) < 0)
+                    break;
+                long ms, ns;
+                if (deadline == 0L)
+                    ms = 0L;
+                else if ((ns = deadline - System.nanoTime()) <= 0L)
+                    break;
+                else if ((ms = TimeUnit.NANOSECONDS.toMillis(ns)) <= 0L)
+                    ms = 1L;
+                if (tryCompensate(w)) {
+                    task.internalWait(ms);
+                    U.getAndAddLong(this, CTL, AC_UNIT);
                 }
             }
-            joiner.currentJoin = prevJoin;
+            U.putOrderedObject(w, QCURRENTJOIN, prevJoin);
         }
         return s;
     }
 
-    /**
-     * Stripped-down variant of awaitJoin used by timed joins. Tries
-     * to help join only while there is continuous progress. (Caller
-     * will then enter a timed wait.)
-     *
-     * @param joiner the joining worker
-     * @param task the task
-     */
-    final void helpJoinOnce(WorkQueue joiner, ForkJoinTask<?> task) {
-        int s;
-        if (joiner != null && task != null && (s = task.status) >= 0) {
-            ForkJoinTask<?> prevJoin = joiner.currentJoin;
-            joiner.currentJoin = task;
-            do {} while (joiner.tryRemoveAndExec(task) && // process local tasks
-                         (s = task.status) >= 0);
-            if (s >= 0) {
-                if (task instanceof CountedCompleter)
-                    helpComplete(joiner, (CountedCompleter<?>)task, Integer.MAX_VALUE);
-                do {} while (task.status >= 0 &&
-                             tryHelpStealer(joiner, task) > 0);
-            }
-            joiner.currentJoin = prevJoin;
-        }
-    }
+    // Specialized scanning
 
     /**
      * Returns a (probably) non-empty steal queue, if one is found
@@ -2068,19 +2069,24 @@
      * caller if, by the time it tries to use the queue, it is empty.
      */
     private WorkQueue findNonEmptyStealQueue() {
+        WorkQueue[] ws; int m;  // one-shot version of scan loop
         int r = ThreadLocalRandom.nextSecondarySeed();
-        for (;;) {
-            int ps = plock, m; WorkQueue[] ws; WorkQueue q;
-            if ((ws = workQueues) != null && (m = ws.length - 1) >= 0) {
-                for (int j = (m + 1) << 2; j >= 0; --j) {
-                    if ((q = ws[(((r - j) << 1) | 1) & m]) != null &&
-                        q.base - q.top < 0)
+        if ((ws = workQueues) != null && (m = ws.length - 1) >= 0) {
+            for (int origin = r & m, k = origin, oldSum = 0, checkSum = 0;;) {
+                WorkQueue q; int b;
+                if ((q = ws[k]) != null) {
+                    if ((b = q.base) - q.top < 0)
                         return q;
+                    checkSum += b;
+                }
+                if ((k = (k + 1) & m) == origin) {
+                    if (oldSum == (oldSum = checkSum))
+                        break;
+                    checkSum = 0;
                 }
             }
-            if (plock == ps)
-                return null;
         }
+        return null;
     }
 
     /**
@@ -2090,35 +2096,34 @@
      * find tasks either.
      */
     final void helpQuiescePool(WorkQueue w) {
-        ForkJoinTask<?> ps = w.currentSteal;
+        ForkJoinTask<?> ps = w.currentSteal; // save context
         for (boolean active = true;;) {
             long c; WorkQueue q; ForkJoinTask<?> t; int b;
-            while ((t = w.nextLocalTask()) != null)
-                t.doExec();
+            w.execLocalTasks();     // run locals before each scan
             if ((q = findNonEmptyStealQueue()) != null) {
                 if (!active) {      // re-establish active count
                     active = true;
-                    do {} while (!U.compareAndSwapLong
-                                 (this, CTL, c = ctl,
-                                  ((c & ~AC_MASK) |
-                                   ((c & AC_MASK) + AC_UNIT))));
+                    U.getAndAddLong(this, CTL, AC_UNIT);
                 }
-                if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null)
-                    w.runTask(t);
+                if ((b = q.base) - q.top < 0 && (t = q.pollAt(b)) != null) {
+                    U.putOrderedObject(w, QCURRENTSTEAL, t);
+                    t.doExec();
+                    if (++w.nsteals < 0)
+                        w.transferStealCount(this);
+                }
             }
             else if (active) {      // decrement active count without queuing
-                long nc = ((c = ctl) & ~AC_MASK) | ((c & AC_MASK) - AC_UNIT);
-                if ((int)(nc >> AC_SHIFT) + parallelism == 0)
+                long nc = (AC_MASK & ((c = ctl) - AC_UNIT)) | (~AC_MASK & c);
+                if ((int)(nc >> AC_SHIFT) + (config & SMASK) <= 0)
                     break;          // bypass decrement-then-increment
                 if (U.compareAndSwapLong(this, CTL, c, nc))
                     active = false;
             }
-            else if ((int)((c = ctl) >> AC_SHIFT) + parallelism <= 0 &&
-                     U.compareAndSwapLong
-                     (this, CTL, c, ((c & ~AC_MASK) |
-                                     ((c & AC_MASK) + AC_UNIT))))
+            else if ((int)((c = ctl) >> AC_SHIFT) + (config & SMASK) <= 0 &&
+                     U.compareAndSwapLong(this, CTL, c, c + AC_UNIT))
                 break;
         }
+        U.putOrderedObject(w, QCURRENTSTEAL, ps);
     }
 
     /**
@@ -2141,7 +2146,7 @@
     /**
      * Returns a cheap heuristic guide for task partitioning when
      * programmers, frameworks, tools, or languages have little or no
-     * idea about task granularity.  In essence by offering this
+     * idea about task granularity.  In essence, by offering this
      * method, we ask users only about tradeoffs in overhead vs
      * expected throughput and its variance, rather than how finely to
      * partition tasks.
@@ -2179,15 +2184,12 @@
      * many of these by further considering the number of "idle"
      * threads, that are known to have zero queued tasks, so
      * compensate by a factor of (#idle/#active) threads.
-     *
-     * Note: The approximation of #busy workers as #active workers is
-     * not very good under current signalling scheme, and should be
-     * improved.
      */
     static int getSurplusQueuedTaskCount() {
         Thread t; ForkJoinWorkerThread wt; ForkJoinPool pool; WorkQueue q;
         if (((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)) {
-            int p = (pool = (wt = (ForkJoinWorkerThread)t).pool).parallelism;
+            int p = (pool = (wt = (ForkJoinWorkerThread)t).pool).
+                config & SMASK;
             int n = (q = wt.workQueue).top - q.base;
             int a = (int)(pool.ctl >> AC_SHIFT) + p;
             return n - (a > (p >>>= 1) ? 0 :
@@ -2202,13 +2204,7 @@
     //  Termination
 
     /**
-     * Possibly initiates and/or completes termination.  The caller
-     * triggering termination runs three passes through workQueues:
-     * (0) Setting termination status, followed by wakeups of queued
-     * workers; (1) cancelling all tasks; (2) interrupting lagging
-     * threads (likely in external tasks, but possibly also blocked in
-     * joins).  Each pass repeats previous steps because of potential
-     * lagging thread creation.
+     * Possibly initiates and/or completes termination.
      *
      * @param now if true, unconditionally terminate, else only
      * if no work and no active workers
@@ -2216,166 +2212,256 @@
      * @return true if now terminating or terminated
      */
     private boolean tryTerminate(boolean now, boolean enable) {
-        int ps;
-        if (this == common)                        // cannot shut down
+        int rs;
+        if (this == common)                       // cannot shut down
             return false;
-        if ((ps = plock) >= 0) {                   // enable by setting plock
+        if ((rs = runState) >= 0) {
             if (!enable)
                 return false;
-            if ((ps & PL_LOCK) != 0 ||
-                !U.compareAndSwapInt(this, PLOCK, ps, ps += PL_LOCK))
-                ps = acquirePlock();
-            int nps = ((ps + PL_LOCK) & ~SHUTDOWN) | SHUTDOWN;
-            if (!U.compareAndSwapInt(this, PLOCK, ps, nps))
-                releasePlock(nps);
+            rs = lockRunState();                  // enter SHUTDOWN phase
+            unlockRunState(rs, (rs & ~RSLOCK) | SHUTDOWN);
         }
-        for (long c;;) {
-            if (((c = ctl) & STOP_BIT) != 0) {     // already terminating
-                if ((short)(c >>> TC_SHIFT) + parallelism <= 0) {
-                    synchronized (this) {
-                        notifyAll();               // signal when 0 workers
-                    }
-                }
-                return true;
-            }
-            if (!now) {                            // check if idle & no tasks
-                WorkQueue[] ws; WorkQueue w;
-                if ((int)(c >> AC_SHIFT) + parallelism > 0)
-                    return false;
-                if ((ws = workQueues) != null) {
-                    for (int i = 0; i < ws.length; ++i) {
-                        if ((w = ws[i]) != null &&
-                            (!w.isEmpty() ||
-                             ((i & 1) != 0 && w.eventCount >= 0))) {
-                            signalWork(ws, w);
-                            return false;
+
+        if ((rs & STOP) == 0) {
+            if (!now) {                           // check quiescence
+                for (long oldSum = 0L;;) {        // repeat until stable
+                    WorkQueue[] ws; WorkQueue w; int m, b; long c;
+                    long checkSum = ctl;
+                    if ((int)(checkSum >> AC_SHIFT) + (config & SMASK) > 0)
+                        return false;             // still active workers
+                    if ((ws = workQueues) == null || (m = ws.length - 1) <= 0)
+                        break;                    // check queues
+                    for (int i = 0; i <= m; ++i) {
+                        if ((w = ws[i]) != null) {
+                            if ((b = w.base) != w.top || w.scanState >= 0 ||
+                                w.currentSteal != null) {
+                                tryRelease(c = ctl, ws[m & (int)c], AC_UNIT);
+                                return false;     // arrange for recheck
+                            }
+                            checkSum += b;
+                            if ((i & 1) == 0)
+                                w.qlock = -1;     // try to disable external
                         }
                     }
+                    if (oldSum == (oldSum = checkSum))
+                        break;
                 }
             }
-            if (U.compareAndSwapLong(this, CTL, c, c | STOP_BIT)) {
-                for (int pass = 0; pass < 3; ++pass) {
-                    WorkQueue[] ws; WorkQueue w; Thread wt;
-                    if ((ws = workQueues) != null) {
-                        int n = ws.length;
-                        for (int i = 0; i < n; ++i) {
-                            if ((w = ws[i]) != null) {
-                                w.qlock = -1;
-                                if (pass > 0) {
-                                    w.cancelAll();
-                                    if (pass > 1 && (wt = w.owner) != null) {
-                                        if (!wt.isInterrupted()) {
-                                            try {
-                                                wt.interrupt();
-                                            } catch (Throwable ignore) {
-                                            }
-                                        }
-                                        U.unpark(wt);
-                                    }
+            if ((runState & STOP) == 0) {
+                rs = lockRunState();              // enter STOP phase
+                unlockRunState(rs, (rs & ~RSLOCK) | STOP);
+            }
+        }
+
+        int pass = 0;                             // 3 passes to help terminate
+        for (long oldSum = 0L;;) {                // or until done or stable
+            WorkQueue[] ws; WorkQueue w; ForkJoinWorkerThread wt; int m;
+            long checkSum = ctl;
+            if ((short)(checkSum >>> TC_SHIFT) + (config & SMASK) <= 0 ||
+                (ws = workQueues) == null || (m = ws.length - 1) <= 0) {
+                if ((runState & TERMINATED) == 0) {
+                    rs = lockRunState();          // done
+                    unlockRunState(rs, (rs & ~RSLOCK) | TERMINATED);
+                    synchronized (this) { notifyAll(); } // for awaitTermination
+                }
+                break;
+            }
+            for (int i = 0; i <= m; ++i) {
+                if ((w = ws[i]) != null) {
+                    checkSum += w.base;
+                    w.qlock = -1;                 // try to disable
+                    if (pass > 0) {
+                        w.cancelAll();            // clear queue
+                        if (pass > 1 && (wt = w.owner) != null) {
+                            if (!wt.isInterrupted()) {
+                                try {             // unblock join
+                                    wt.interrupt();
+                                } catch (Throwable ignore) {
                                 }
                             }
-                        }
-                        // Wake up workers parked on event queue
-                        int i, e; long cc; Thread p;
-                        while ((e = (int)(cc = ctl) & E_MASK) != 0 &&
-                               (i = e & SMASK) < n && i >= 0 &&
-                               (w = ws[i]) != null) {
-                            long nc = ((long)(w.nextWait & E_MASK) |
-                                       ((cc + AC_UNIT) & AC_MASK) |
-                                       (cc & (TC_MASK|STOP_BIT)));
-                            if (w.eventCount == (e | INT_SIGN) &&
-                                U.compareAndSwapLong(this, CTL, cc, nc)) {
-                                w.eventCount = (e + E_SEQ) & E_MASK;
-                                w.qlock = -1;
-                                if ((p = w.parker) != null)
-                                    U.unpark(p);
-                            }
+                            if (w.scanState < 0)
+                                U.unpark(wt);     // wake up
                         }
                     }
                 }
             }
+            if (checkSum != oldSum) {             // unstable
+                oldSum = checkSum;
+                pass = 0;
+            }
+            else if (pass > 3 && pass > m)        // can't further help
+                break;
+            else if (++pass > 1) {                // try to dequeue
+                long c; int j = 0, sp;            // bound attempts
+                while (j++ <= m && (sp = (int)(c = ctl)) != 0)
+                    tryRelease(c, ws[sp & m], AC_UNIT);
+            }
+        }
+        return true;
+    }
+
+    // External operations
+
+    /**
+     * Full version of externalPush, handling uncommon cases, as well
+     * as performing secondary initialization upon the first
+     * submission of the first task to the pool.  It also detects
+     * first submission by an external thread and creates a new shared
+     * queue if the one at index if empty or contended.
+     *
+     * @param task the task. Caller must ensure non-null.
+     */
+    private void externalSubmit(ForkJoinTask<?> task) {
+        int r;                                    // initialize caller's probe
+        if ((r = ThreadLocalRandom.getProbe()) == 0) {
+            ThreadLocalRandom.localInit();
+            r = ThreadLocalRandom.getProbe();
+        }
+        for (;;) {
+            WorkQueue[] ws; WorkQueue q; int rs, m, k;
+            boolean move = false;
+            if ((rs = runState) < 0) {
+                tryTerminate(false, false);     // help terminate
+                throw new RejectedExecutionException();
+            }
+            else if ((rs & STARTED) == 0 ||     // initialize
+                     ((ws = workQueues) == null || (m = ws.length - 1) < 0)) {
+                int ns = 0;
+                rs = lockRunState();
+                try {
+                    if ((rs & STARTED) == 0) {
+                        U.compareAndSwapObject(this, STEALCOUNTER, null,
+                                               new AtomicLong());
+                        // create workQueues array with size a power of two
+                        int p = config & SMASK; // ensure at least 2 slots
+                        int n = (p > 1) ? p - 1 : 1;
+                        n |= n >>> 1; n |= n >>> 2;  n |= n >>> 4;
+                        n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1;
+                        workQueues = new WorkQueue[n];
+                        ns = STARTED;
+                    }
+                } finally {
+                    unlockRunState(rs, (rs & ~RSLOCK) | ns);
+                }
+            }
+            else if ((q = ws[k = r & m & SQMASK]) != null) {
+                if (q.qlock == 0 && U.compareAndSwapInt(q, QLOCK, 0, 1)) {
+                    ForkJoinTask<?>[] a = q.array;
+                    int s = q.top;
+                    boolean submitted = false; // initial submission or resizing
+                    try {                      // locked version of push
+                        if ((a != null && a.length > s + 1 - q.base) ||
+                            (a = q.growArray()) != null) {
+                            int j = (((a.length - 1) & s) << ASHIFT) + ABASE;
+                            U.putOrderedObject(a, j, task);
+                            U.putOrderedInt(q, QTOP, s + 1);
+                            submitted = true;
+                        }
+                    } finally {
+                        U.compareAndSwapInt(q, QLOCK, 1, 0);
+                    }
+                    if (submitted) {
+                        signalWork(ws, q);
+                        return;
+                    }
+                }
+                move = true;                   // move on failure
+            }
+            else if (((rs = runState) & RSLOCK) == 0) { // create new queue
+                q = new WorkQueue(this, null);
+                q.hint = r;
+                q.config = k | SHARED_QUEUE;
+                q.scanState = INACTIVE;
+                rs = lockRunState();           // publish index
+                if (rs > 0 &&  (ws = workQueues) != null &&
+                    k < ws.length && ws[k] == null)
+                    ws[k] = q;                 // else terminated
+                unlockRunState(rs, rs & ~RSLOCK);
+            }
+            else
+                move = true;                   // move if busy
+            if (move)
+                r = ThreadLocalRandom.advanceProbe(r);
         }
     }
 
-    // external operations on common pool
+    /**
+     * Tries to add the given task to a submission queue at
+     * submitter's current queue. Only the (vastly) most common path
+     * is directly handled in this method, while screening for need
+     * for externalSubmit.
+     *
+     * @param task the task. Caller must ensure non-null.
+     */
+    final void externalPush(ForkJoinTask<?> task) {
+        WorkQueue[] ws; WorkQueue q; int m;
+        int r = ThreadLocalRandom.getProbe();
+        int rs = runState;
+        if ((ws = workQueues) != null && (m = (ws.length - 1)) >= 0 &&
+            (q = ws[m & r & SQMASK]) != null && r != 0 && rs > 0 &&
+            U.compareAndSwapInt(q, QLOCK, 0, 1)) {
+            ForkJoinTask<?>[] a; int am, n, s;
+            if ((a = q.array) != null &&
+                (am = a.length - 1) > (n = (s = q.top) - q.base)) {
+                int j = ((am & s) << ASHIFT) + ABASE;
+                U.putOrderedObject(a, j, task);
+                U.putOrderedInt(q, QTOP, s + 1);
+                U.putOrderedInt(q, QLOCK, 0);
+                if (n <= 1)
+                    signalWork(ws, q);
+                return;
+            }
+            U.compareAndSwapInt(q, QLOCK, 1, 0);
+        }
+        externalSubmit(task);
+    }
 
     /**
-     * Returns common pool queue for a thread that has submitted at
-     * least one task.
+     * Returns common pool queue for an external thread.
      */
     static WorkQueue commonSubmitterQueue() {
-        ForkJoinPool p; WorkQueue[] ws; int m, z;
-        return ((z = ThreadLocalRandom.getProbe()) != 0 &&
-                (p = common) != null &&
-                (ws = p.workQueues) != null &&
+        ForkJoinPool p = common;
+        int r = ThreadLocalRandom.getProbe();
+        WorkQueue[] ws; int m;
+        return (p != null && (ws = p.workQueues) != null &&
                 (m = ws.length - 1) >= 0) ?
-            ws[m & z & SQMASK] : null;
+            ws[m & r & SQMASK] : null;
     }
 
     /**
-     * Tries to pop the given task from submitter's queue in common pool.
+     * Performs tryUnpush for an external submitter: Finds queue,
+     * locks if apparently non-empty, validates upon locking, and
+     * adjusts top. Each check can fail but rarely does.
      */
     final boolean tryExternalUnpush(ForkJoinTask<?> task) {
-        WorkQueue joiner; ForkJoinTask<?>[] a; int m, s;
-        WorkQueue[] ws = workQueues;
-        int z = ThreadLocalRandom.getProbe();
-        boolean popped = false;
-        if (ws != null && (m = ws.length - 1) >= 0 &&
-            (joiner = ws[z & m & SQMASK]) != null &&
-            joiner.base != (s = joiner.top) &&
-            (a = joiner.array) != null) {
+        WorkQueue[] ws; WorkQueue w; ForkJoinTask<?>[] a; int m, s;
+        int r = ThreadLocalRandom.getProbe();
+        if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 &&
+            (w = ws[m & r & SQMASK]) != null &&
+            (a = w.array) != null && (s = w.top) != w.base) {
             long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
-            if (U.getObject(a, j) == task &&
-                U.compareAndSwapInt(joiner, QLOCK, 0, 1)) {
-                if (joiner.top == s && joiner.array == a &&
+            if (U.compareAndSwapInt(w, QLOCK, 0, 1)) {
+                if (w.top == s && w.array == a &&
+                    U.getObject(a, j) == task &&
                     U.compareAndSwapObject(a, j, task, null)) {
-                    joiner.top = s - 1;
-                    popped = true;
+                    U.putOrderedInt(w, QTOP, s - 1);
+                    U.putOrderedInt(w, QLOCK, 0);
+                    return true;
                 }
-                joiner.qlock = 0;
+                U.compareAndSwapInt(w, QLOCK, 1, 0);
             }
         }
-        return popped;
+        return false;
     }
 
+    /**
+     * Performs helpComplete for an external submitter.
+     */
     final int externalHelpComplete(CountedCompleter<?> task, int maxTasks) {
-        WorkQueue joiner; int m;
-        WorkQueue[] ws = workQueues;
-        int j = ThreadLocalRandom.getProbe();
-        int s = 0;
-        if (ws != null && (m = ws.length - 1) >= 0 &&
-            (joiner = ws[j & m & SQMASK]) != null && task != null) {
-            int scans = m + m + 1;
-            long c = 0L;             // for stability check
-            j |= 1;                  // poll odd queues
-            for (int k = scans; ; j += 2) {
-                WorkQueue q;
-                if ((s = task.status) < 0)
-                    break;
-                else if (joiner.externalPopAndExecCC(task)) {
-                    if (--maxTasks <= 0) {
-                        s = task.status;
-                        break;
-                    }
-                    k = scans;
-                }
-                else if ((s = task.status) < 0)
-                    break;
-                else if ((q = ws[j & m]) != null && q.pollAndExecCC(task)) {
-                    if (--maxTasks <= 0) {
-                        s = task.status;
-                        break;
-                    }
-                    k = scans;
-                }
-                else if (--k < 0) {
-                    if (c == (c = ctl))
-                        break;
-                    k = scans;
-                }
-            }
-        }
-        return s;
+        WorkQueue[] ws; int n;
+        int r = ThreadLocalRandom.getProbe();
+        return ((ws = workQueues) == null || (n = ws.length) == 0) ? 0 :
+            helpComplete(ws[(n - 1) & r & SQMASK], task, maxTasks);
     }
 
     // Exported methods
@@ -2447,7 +2533,7 @@
         this(checkParallelism(parallelism),
              checkFactory(factory),
              handler,
-             (asyncMode ? FIFO_QUEUE : LIFO_QUEUE),
+             asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
              "ForkJoinPool-" + nextPoolId() + "-worker-");
         checkPermission();
     }
@@ -2478,8 +2564,7 @@
         this.workerNamePrefix = workerNamePrefix;
         this.factory = factory;
         this.ueh = handler;
-        this.mode = (short)mode;
-        this.parallelism = (short)parallelism;
+        this.config = (parallelism & SMASK) | mode;
         long np = (long)(-parallelism); // offset ctl counts
         this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
     }
@@ -2624,7 +2709,7 @@
         // In previous versions of this class, this method constructed
         // a task to run ForkJoinTask.invokeAll, but now external
         // invocation of multiple tasks is at least as efficient.
-        ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size());
+        ArrayList<Future<T>> futures = new ArrayList<>(tasks.size());
 
         boolean done = false;
         try {
@@ -2670,7 +2755,7 @@
      */
     public int getParallelism() {
         int par;
-        return ((par = parallelism) > 0) ? par : 1;
+        return ((par = config & SMASK) > 0) ? par : 1;
     }
 
     /**
@@ -2692,7 +2777,7 @@
      * @return the number of worker threads
      */
     public int getPoolSize() {
-        return parallelism + (short)(ctl >>> TC_SHIFT);
+        return (config & SMASK) + (short)(ctl >>> TC_SHIFT);
     }
 
     /**
@@ -2702,7 +2787,7 @@
      * @return {@code true} if this pool uses async mode
      */
     public boolean getAsyncMode() {
-        return mode == FIFO_QUEUE;
+        return (config & FIFO_QUEUE) != 0;
     }
 
     /**
@@ -2733,7 +2818,7 @@
      * @return the number of active threads
      */
     public int getActiveThreadCount() {
-        int r = parallelism + (int)(ctl >> AC_SHIFT);
+        int r = (config & SMASK) + (int)(ctl >> AC_SHIFT);
         return (r <= 0) ? 0 : r; // suppress momentarily negative values
     }
 
@@ -2749,7 +2834,7 @@
      * @return {@code true} if all threads are currently idle
      */
     public boolean isQuiescent() {
-        return parallelism + (int)(ctl >> AC_SHIFT) <= 0;
+        return (config & SMASK) + (int)(ctl >> AC_SHIFT) <= 0;
     }
 
     /**
@@ -2764,7 +2849,8 @@
      * @return the number of steals
      */
     public long getStealCount() {
-        long count = stealCount;
+        AtomicLong sc = stealCounter;
+        long count = (sc == null) ? 0L : sc.get();
         WorkQueue[] ws; WorkQueue w;
         if ((ws = workQueues) != null) {
             for (int i = 1; i < ws.length; i += 2) {
@@ -2894,7 +2980,8 @@
     public String toString() {
         // Use a single pass through workQueues to collect counts
         long qt = 0L, qs = 0L; int rc = 0;
-        long st = stealCount;
+        AtomicLong sc = stealCounter;
+        long st = (sc == null) ? 0L : sc.get();
         long c = ctl;
         WorkQueue[] ws; WorkQueue w;
         if ((ws = workQueues) != null) {
@@ -2912,16 +2999,16 @@
                 }
             }
         }
-        int pc = parallelism;
+        int pc = (config & SMASK);
         int tc = pc + (short)(c >>> TC_SHIFT);
         int ac = pc + (int)(c >> AC_SHIFT);
         if (ac < 0) // ignore transient negative
             ac = 0;
-        String level;
-        if ((c & STOP_BIT) != 0)
-            level = (tc == 0) ? "Terminated" : "Terminating";
-        else
-            level = plock < 0 ? "Shutting down" : "Running";
+        int rs = runState;
+        String level = ((rs & TERMINATED) != 0 ? "Terminated" :
+                        (rs & STOP)       != 0 ? "Terminating" :
+                        (rs & SHUTDOWN)   != 0 ? "Shutting down" :
+                        "Running");
         return super.toString() +
             "[" + level +
             ", parallelism = " + pc +
@@ -2983,9 +3070,7 @@
      * @return {@code true} if all tasks have completed following shut down
      */
     public boolean isTerminated() {
-        long c = ctl;
-        return ((c & STOP_BIT) != 0L &&
-                (short)(c >>> TC_SHIFT) + parallelism <= 0);
+        return (runState & TERMINATED) != 0;
     }
 
     /**
@@ -3002,9 +3087,8 @@
      * @return {@code true} if terminating but not yet terminated
      */
     public boolean isTerminating() {
-        long c = ctl;
-        return ((c & STOP_BIT) != 0L &&
-                (short)(c >>> TC_SHIFT) + parallelism > 0);
+        int rs = runState;
+        return (rs & STOP) != 0 && (rs & TERMINATED) == 0;
     }
 
     /**
@@ -3013,7 +3097,7 @@
      * @return {@code true} if this pool has been shut down
      */
     public boolean isShutdown() {
-        return plock < 0;
+        return (runState & SHUTDOWN) != 0;
     }
 
     /**
@@ -3090,8 +3174,9 @@
             }
             found = false;
             for (int j = (m + 1) << 2; j >= 0; --j) {
-                ForkJoinTask<?> t; WorkQueue q; int b;
-                if ((q = ws[r++ & m]) != null && (b = q.base) - q.top < 0) {
+                ForkJoinTask<?> t; WorkQueue q; int b, k;
+                if ((k = r++ & m) <= m && k >= 0 && (q = ws[k]) != null &&
+                    (b = q.base) - q.top < 0) {
                     found = true;
                     if ((t = q.pollAt(b)) != null)
                         t.doExec();
@@ -3115,8 +3200,8 @@
      * in {@link ForkJoinPool}s.
      *
      * <p>A {@code ManagedBlocker} provides two methods.  Method
-     * {@code isReleasable} must return {@code true} if blocking is
-     * not necessary. Method {@code block} blocks the current thread
+     * {@link #isReleasable} must return {@code true} if blocking is
+     * not necessary. Method {@link #block} blocks the current thread
      * if necessary (perhaps internally invoking {@code isReleasable}
      * before actually blocking). These actions are performed by any
      * thread invoking {@link ForkJoinPool#managedBlock(ManagedBlocker)}.
@@ -3185,37 +3270,46 @@
     }
 
     /**
-     * Blocks in accord with the given blocker.  If the current thread
-     * is a {@link ForkJoinWorkerThread}, this method possibly
-     * arranges for a spare thread to be activated if necessary to
-     * ensure sufficient parallelism while the current thread is blocked.
+     * Runs the given possibly blocking task.  When {@linkplain
+     * ForkJoinTask#inForkJoinPool() running in a ForkJoinPool}, this
+     * method possibly arranges for a spare thread to be activated if
+     * necessary to ensure sufficient parallelism while the current
+     * thread is blocked in {@link ManagedBlocker#block blocker.block()}.
      *
-     * <p>If the caller is not a {@link ForkJoinTask}, this method is
+     * <p>This method repeatedly calls {@code blocker.isReleasable()} and
+     * {@code blocker.block()} until either method returns {@code true}.
+     * Every call to {@code blocker.block()} is preceded by a call to
+     * {@code blocker.isReleasable()} that returned {@code false}.
+     *
+     * <p>If not running in a ForkJoinPool, this method is
      * behaviorally equivalent to
      *  <pre> {@code
      * while (!blocker.isReleasable())
      *   if (blocker.block())
-     *     return;
-     * }</pre>
+     *     break;}</pre>
      *
-     * If the caller is a {@code ForkJoinTask}, then the pool may
-     * first be expanded to ensure parallelism, and later adjusted.
+     * If running in a ForkJoinPool, the pool may first be expanded to
+     * ensure sufficient parallelism available during the call to
+     * {@code blocker.block()}.
      *
-     * @param blocker the blocker
-     * @throws InterruptedException if blocker.block did so
+     * @param blocker the blocker task
+     * @throws InterruptedException if {@code blocker.block()} did so
      */
     public static void managedBlock(ManagedBlocker blocker)
         throws InterruptedException {
+        ForkJoinPool p;
+        ForkJoinWorkerThread wt;
         Thread t = Thread.currentThread();
-        if (t instanceof ForkJoinWorkerThread) {
-            ForkJoinPool p = ((ForkJoinWorkerThread)t).pool;
+        if ((t instanceof ForkJoinWorkerThread) &&
+            (p = (wt = (ForkJoinWorkerThread)t).pool) != null) {
+            WorkQueue w = wt.workQueue;
             while (!blocker.isReleasable()) {
-                if (p.tryCompensate(p.ctl)) {
+                if (p.tryCompensate(w)) {
                     try {
                         do {} while (!blocker.isReleasable() &&
                                      !blocker.block());
                     } finally {
-                        p.incrementActiveCount();
+                        U.getAndAddLong(p, CTL, AC_UNIT);
                     }
                     break;
                 }
@@ -3241,15 +3335,18 @@
 
     // Unsafe mechanics
     private static final sun.misc.Unsafe U;
+    private static final int  ABASE;
+    private static final int  ASHIFT;
     private static final long CTL;
+    private static final long RUNSTATE;
+    private static final long STEALCOUNTER;
     private static final long PARKBLOCKER;
-    private static final int ABASE;
-    private static final int ASHIFT;
-    private static final long STEALCOUNT;
-    private static final long PLOCK;
-    private static final long INDEXSEED;
-    private static final long QBASE;
+    private static final long QTOP;
     private static final long QLOCK;
+    private static final long QSCANSTATE;
+    private static final long QPARKER;
+    private static final long QCURRENTSTEAL;
+    private static final long QCURRENTJOIN;
 
     static {
         // initialize field offsets for CAS etc
@@ -3258,20 +3355,26 @@
             Class<?> k = ForkJoinPool.class;
             CTL = U.objectFieldOffset
                 (k.getDeclaredField("ctl"));
-            STEALCOUNT = U.objectFieldOffset
-                (k.getDeclaredField("stealCount"));
-            PLOCK = U.objectFieldOffset
-                (k.getDeclaredField("plock"));
-            INDEXSEED = U.objectFieldOffset
-                (k.getDeclaredField("indexSeed"));
+            RUNSTATE = U.objectFieldOffset
+                (k.getDeclaredField("runState"));
+            STEALCOUNTER = U.objectFieldOffset
+                (k.getDeclaredField("stealCounter"));
             Class<?> tk = Thread.class;
             PARKBLOCKER = U.objectFieldOffset
                 (tk.getDeclaredField("parkBlocker"));
             Class<?> wk = WorkQueue.class;
-            QBASE = U.objectFieldOffset
-                (wk.getDeclaredField("base"));
+            QTOP = U.objectFieldOffset
+                (wk.getDeclaredField("top"));
             QLOCK = U.objectFieldOffset
                 (wk.getDeclaredField("qlock"));
+            QSCANSTATE = U.objectFieldOffset
+                (wk.getDeclaredField("scanState"));
+            QPARKER = U.objectFieldOffset
+                (wk.getDeclaredField("parker"));
+            QCURRENTSTEAL = U.objectFieldOffset
+                (wk.getDeclaredField("currentSteal"));
+            QCURRENTJOIN = U.objectFieldOffset
+                (wk.getDeclaredField("currentJoin"));
             Class<?> ak = ForkJoinTask[].class;
             ABASE = U.arrayBaseOffset(ak);
             int scale = U.arrayIndexScale(ak);
@@ -3282,6 +3385,7 @@
             throw new Error(e);
         }
 
+        commonMaxSpares = DEFAULT_COMMON_MAX_SPARES;
         defaultForkJoinWorkerThreadFactory =
             new DefaultForkJoinWorkerThreadFactory();
         modifyThreadPermission = new RuntimePermission("modifyThread");
@@ -3289,7 +3393,7 @@
         common = java.security.AccessController.doPrivileged
             (new java.security.PrivilegedAction<ForkJoinPool>() {
                 public ForkJoinPool run() { return makeCommonPool(); }});
-        int par = common.parallelism; // report 1 even if threads disabled
+        int par = common.config & SMASK; // report 1 even if threads disabled
         commonParallelism = par > 0 ? par : 1;
     }
 
diff --git a/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java b/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java
index 936bfc2..4439c24 100644
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinTask.java
@@ -297,15 +297,22 @@
     }
 
     /**
-     * Tries to set SIGNAL status unless already completed. Used by
-     * ForkJoinPool. Other variants are directly incorporated into
-     * externalAwaitDone etc.
+     * If not done, sets SIGNAL status and performs Object.wait(timeout).
+     * This task may or may not be done on exit. Ignores interrupts.
      *
-     * @return true if successful
+     * @param timeout using Object.wait conventions.
      */
-    final boolean trySetSignal() {
-        int s = status;
-        return s >= 0 && U.compareAndSwapInt(this, STATUS, s, s | SIGNAL);
+    final void internalWait(long timeout) {
+        int s;
+        if ((s = status) >= 0 && // force completer to issue notify
+            U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
+            synchronized (this) {
+                if (status >= 0)
+                    try { wait(timeout); } catch (InterruptedException ie) { }
+                else
+                    notifyAll();
+            }
+        }
     }
 
     /**
@@ -313,35 +320,29 @@
      * @return status upon completion
      */
     private int externalAwaitDone() {
-        int s;
-        ForkJoinPool cp = ForkJoinPool.common;
-        if ((s = status) >= 0) {
-            if (cp != null) {
-                if (this instanceof CountedCompleter)
-                    s = cp.externalHelpComplete((CountedCompleter<?>)this, Integer.MAX_VALUE);
-                else if (cp.tryExternalUnpush(this))
-                    s = doExec();
-            }
-            if (s >= 0 && (s = status) >= 0) {
-                boolean interrupted = false;
-                do {
-                    if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
-                        synchronized (this) {
-                            if (status >= 0) {
-                                try {
-                                    wait();
-                                } catch (InterruptedException ie) {
-                                    interrupted = true;
-                                }
+        int s = ((this instanceof CountedCompleter) ? // try helping
+                 ForkJoinPool.common.externalHelpComplete(
+                     (CountedCompleter<?>)this, 0) :
+                 ForkJoinPool.common.tryExternalUnpush(this) ? doExec() : 0);
+        if (s >= 0 && (s = status) >= 0) {
+            boolean interrupted = false;
+            do {
+                if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
+                    synchronized (this) {
+                        if (status >= 0) {
+                            try {
+                                wait(0L);
+                            } catch (InterruptedException ie) {
+                                interrupted = true;
                             }
-                            else
-                                notifyAll();
                         }
+                        else
+                            notifyAll();
                     }
-                } while ((s = status) >= 0);
-                if (interrupted)
-                    Thread.currentThread().interrupt();
-            }
+                }
+            } while ((s = status) >= 0);
+            if (interrupted)
+                Thread.currentThread().interrupt();
         }
         return s;
     }
@@ -351,22 +352,22 @@
      */
     private int externalInterruptibleAwaitDone() throws InterruptedException {
         int s;
-        ForkJoinPool cp = ForkJoinPool.common;
         if (Thread.interrupted())
             throw new InterruptedException();
-        if ((s = status) >= 0 && cp != null) {
-            if (this instanceof CountedCompleter)
-                cp.externalHelpComplete((CountedCompleter<?>)this, Integer.MAX_VALUE);
-            else if (cp.tryExternalUnpush(this))
-                doExec();
-        }
-        while ((s = status) >= 0) {
-            if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
-                synchronized (this) {
-                    if (status >= 0)
-                        wait();
-                    else
-                        notifyAll();
+        if ((s = status) >= 0 &&
+            (s = ((this instanceof CountedCompleter) ?
+                  ForkJoinPool.common.externalHelpComplete(
+                      (CountedCompleter<?>)this, 0) :
+                  ForkJoinPool.common.tryExternalUnpush(this) ? doExec() :
+                  0)) >= 0) {
+            while ((s = status) >= 0) {
+                if (U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
+                    synchronized (this) {
+                        if (status >= 0)
+                            wait(0L);
+                        else
+                            notifyAll();
+                    }
                 }
             }
         }
@@ -386,7 +387,7 @@
             ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
             (w = (wt = (ForkJoinWorkerThread)t).workQueue).
             tryUnpush(this) && (s = doExec()) < 0 ? s :
-            wt.pool.awaitJoin(w, this) :
+            wt.pool.awaitJoin(w, this, 0L) :
             externalAwaitDone();
     }
 
@@ -399,7 +400,8 @@
         int s; Thread t; ForkJoinWorkerThread wt;
         return (s = doExec()) < 0 ? s :
             ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) ?
-            (wt = (ForkJoinWorkerThread)t).pool.awaitJoin(wt.workQueue, this) :
+            (wt = (ForkJoinWorkerThread)t).pool.
+            awaitJoin(wt.workQueue, this, 0L) :
             externalAwaitDone();
     }
 
@@ -577,7 +579,7 @@
         Throwable ex;
         if (e == null || (ex = e.ex) == null)
             return null;
-        if (false && e.thrower != Thread.currentThread().getId()) {
+        if (e.thrower != Thread.currentThread().getId()) {
             Class<? extends Throwable> ec = ex.getClass();
             try {
                 Constructor<?> noArgCtor = null;
@@ -587,13 +589,17 @@
                     Class<?>[] ps = c.getParameterTypes();
                     if (ps.length == 0)
                         noArgCtor = c;
-                    else if (ps.length == 1 && ps[0] == Throwable.class)
-                        return (Throwable)(c.newInstance(ex));
+                    else if (ps.length == 1 && ps[0] == Throwable.class) {
+                        Throwable wx = (Throwable)c.newInstance(ex);
+                        return (wx == null) ? ex : wx;
+                    }
                 }
                 if (noArgCtor != null) {
                     Throwable wx = (Throwable)(noArgCtor.newInstance());
-                    wx.initCause(ex);
-                    return wx;
+                    if (wx != null) {
+                        wx.initCause(ex);
+                        return wx;
+                    }
                 }
             } catch (Exception ignore) {
             }
@@ -1017,67 +1023,40 @@
      */
     public final V get(long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException {
+        int s;
+        long nanos = unit.toNanos(timeout);
         if (Thread.interrupted())
             throw new InterruptedException();
-        // Messy in part because we measure in nanosecs, but wait in millisecs
-        int s; long ms;
-        long ns = unit.toNanos(timeout);
-        ForkJoinPool cp;
-        if ((s = status) >= 0 && ns > 0L) {
-            long deadline = System.nanoTime() + ns;
-            ForkJoinPool p = null;
-            ForkJoinPool.WorkQueue w = null;
+        if ((s = status) >= 0 && nanos > 0L) {
+            long d = System.nanoTime() + nanos;
+            long deadline = (d == 0L) ? 1L : d; // avoid 0
             Thread t = Thread.currentThread();
             if (t instanceof ForkJoinWorkerThread) {
                 ForkJoinWorkerThread wt = (ForkJoinWorkerThread)t;
-                p = wt.pool;
-                w = wt.workQueue;
-                p.helpJoinOnce(w, this); // no retries on failure
+                s = wt.pool.awaitJoin(wt.workQueue, this, deadline);
             }
-            else if ((cp = ForkJoinPool.common) != null) {
-                if (this instanceof CountedCompleter)
-                    cp.externalHelpComplete((CountedCompleter<?>)this, Integer.MAX_VALUE);
-                else if (cp.tryExternalUnpush(this))
-                    doExec();
-            }
-            boolean canBlock = false;
-            boolean interrupted = false;
-            try {
-                while ((s = status) >= 0) {
-                    if (w != null && w.qlock < 0)
-                        cancelIgnoringExceptions(this);
-                    else if (!canBlock) {
-                        if (p == null || p.tryCompensate(p.ctl))
-                            canBlock = true;
-                    }
-                    else {
-                        if ((ms = TimeUnit.NANOSECONDS.toMillis(ns)) > 0L &&
-                            U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
-                            synchronized (this) {
-                                if (status >= 0) {
-                                    try {
-                                        wait(ms);
-                                    } catch (InterruptedException ie) {
-                                        if (p == null)
-                                            interrupted = true;
-                                    }
-                                }
-                                else
-                                    notifyAll();
-                            }
+            else if ((s = ((this instanceof CountedCompleter) ?
+                           ForkJoinPool.common.externalHelpComplete(
+                               (CountedCompleter<?>)this, 0) :
+                           ForkJoinPool.common.tryExternalUnpush(this) ?
+                           doExec() : 0)) >= 0) {
+                long ns, ms; // measure in nanosecs, but wait in millisecs
+                while ((s = status) >= 0 &&
+                       (ns = deadline - System.nanoTime()) > 0L) {
+                    if ((ms = TimeUnit.NANOSECONDS.toMillis(ns)) > 0L &&
+                        U.compareAndSwapInt(this, STATUS, s, s | SIGNAL)) {
+                        synchronized (this) {
+                            if (status >= 0)
+                                wait(ms); // OK to throw InterruptedException
+                            else
+                                notifyAll();
                         }
-                        if ((s = status) < 0 || interrupted ||
-                            (ns = deadline - System.nanoTime()) <= 0L)
-                            break;
                     }
                 }
-            } finally {
-                if (p != null && canBlock)
-                    p.incrementActiveCount();
             }
-            if (interrupted)
-                throw new InterruptedException();
         }
+        if (s >= 0)
+            s = status;
         if ((s &= DONE_MASK) != NORMAL) {
             Throwable ex;
             if (s == CANCELLED)
diff --git a/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java b/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java
index 404c47c..8723f0a 100644
--- a/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java
+++ b/jdk/src/share/classes/java/util/concurrent/ForkJoinWorkerThread.java
@@ -66,7 +66,7 @@
      * owning thread.
      *
      * Support for (non-public) subclass InnocuousForkJoinWorkerThread
-     * requires that we break quite a lot of encapulation (via Unsafe)
+     * requires that we break quite a lot of encapsulation (via Unsafe)
      * both here and in the subclass to access and set Thread fields.
      */
 
@@ -118,7 +118,7 @@
      * @return the index number
      */
     public int getPoolIndex() {
-        return workQueue.poolIndex >>> 1; // ignore odd/even tag bit
+        return workQueue.getPoolIndex();
     }
 
     /**
@@ -171,7 +171,7 @@
     }
 
     /**
-     * Erases ThreadLocals by nulling out Thread maps
+     * Erases ThreadLocals by nulling out Thread maps.
      */
     final void eraseThreadLocals() {
         U.putObject(this, THREADLOCALS, null);
@@ -246,8 +246,8 @@
 
         /**
          * Returns a new group with the system ThreadGroup (the
-         * topmost, parentless group) as parent.  Uses Unsafe to
-         * traverse Thread group and ThreadGroup parent fields.
+         * topmost, parent-less group) as parent.  Uses Unsafe to
+         * traverse Thread.group and ThreadGroup.parent fields.
          */
         private static ThreadGroup createThreadGroup() {
             try {
@@ -274,4 +274,3 @@
     }
 
 }
-
diff --git a/jdk/src/share/classes/java/util/logging/FileHandler.java b/jdk/src/share/classes/java/util/logging/FileHandler.java
index 9699b72..2c3bb50 100644
--- a/jdk/src/share/classes/java/util/logging/FileHandler.java
+++ b/jdk/src/share/classes/java/util/logging/FileHandler.java
@@ -402,6 +402,14 @@
         openFiles();
     }
 
+    private  boolean isParentWritable(Path path) {
+        Path parent = path.getParent();
+        if (parent == null) {
+            parent = path.toAbsolutePath().getParent();
+        }
+        return parent != null && Files.isWritable(parent);
+    }
+
     /**
      * Open the set of output files, based on the configured
      * instance variables.
@@ -458,7 +466,7 @@
                         // Note that this is a situation that may happen,
                         // but not too frequently.
                         if (Files.isRegularFile(lockFilePath, LinkOption.NOFOLLOW_LINKS)
-                            && Files.isWritable(lockFilePath.getParent())) {
+                            && isParentWritable(lockFilePath)) {
                             try {
                                 channel = FileChannel.open(lockFilePath,
                                     WRITE, APPEND);
diff --git a/jdk/src/share/classes/java/util/logging/LogRecord.java b/jdk/src/share/classes/java/util/logging/LogRecord.java
index 50444f1..d9255f4 100644
--- a/jdk/src/share/classes/java/util/logging/LogRecord.java
+++ b/jdk/src/share/classes/java/util/logging/LogRecord.java
@@ -513,7 +513,13 @@
         // If necessary, try to regenerate the resource bundle.
         if (resourceBundleName != null) {
             try {
-                resourceBundle = ResourceBundle.getBundle(resourceBundleName);
+                // use system class loader to ensure the ResourceBundle
+                // instance is a different instance than null loader uses
+                final ResourceBundle bundle =
+                        ResourceBundle.getBundle(resourceBundleName,
+                                Locale.getDefault(),
+                                ClassLoader.getSystemClassLoader());
+                resourceBundle = bundle;
             } catch (MissingResourceException ex) {
                 // This is not a good place to throw an exception,
                 // so we simply leave the resourceBundle null.
diff --git a/jdk/src/share/classes/java/util/logging/Logger.java b/jdk/src/share/classes/java/util/logging/Logger.java
index 90cbb87..4629320 100644
--- a/jdk/src/share/classes/java/util/logging/Logger.java
+++ b/jdk/src/share/classes/java/util/logging/Logger.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -1934,6 +1934,9 @@
         }
 
         setCallersClassLoaderRef(callersClass);
+        if (isSystemLogger && getCallersClassLoader() != null) {
+            checkPermission();
+        }
         if (findResourceBundle(name, true) == null) {
             // We've failed to find an expected ResourceBundle.
             // unset the caller's ClassLoader since we were unable to find the
@@ -2168,11 +2171,13 @@
                 return trb;
             }
             final String rbName = isSystemLogger
-                ? trb.resourceBundleName
+                // ancestor of a system logger is expected to be a system logger.
+                // ignore resource bundle name if it's not.
+                ? (target.isSystemLogger ? trb.resourceBundleName : null)
                 : target.getResourceBundleName();
             if (rbName != null) {
                 return LoggerBundle.get(rbName,
-                            findResourceBundle(rbName, true));
+                        findResourceBundle(rbName, true));
             }
             target = isSystemLogger ? target.parent : target.getParent();
         }
diff --git a/jdk/src/share/classes/javax/crypto/Cipher.java b/jdk/src/share/classes/javax/crypto/Cipher.java
index ffcc7cf..9593540 100644
--- a/jdk/src/share/classes/javax/crypto/Cipher.java
+++ b/jdk/src/share/classes/javax/crypto/Cipher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -167,6 +167,11 @@
     private static final Debug debug =
                         Debug.getInstance("jca", "Cipher");
 
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("cipher");
+
     /**
      * Constant used to initialize cipher to encryption mode.
      */
@@ -1110,6 +1115,21 @@
         }
     }
 
+    private static String getOpmodeString(int opmode) {
+        switch (opmode) {
+            case ENCRYPT_MODE:
+                return "encryption";
+            case DECRYPT_MODE:
+                return "decryption";
+            case WRAP_MODE:
+                return "key wrapping";
+            case UNWRAP_MODE:
+                return "key unwrapping";
+            default:
+                return "";
+        }
+    }
+
     /**
      * Initializes this cipher with a key.
      *
@@ -1235,6 +1255,12 @@
 
         initialized = true;
         this.opmode = opmode;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Cipher." + transformation + " " +
+                getOpmodeString(opmode) + " algorithm from: " +
+                this.provider.getName());
+        }
     }
 
     /**
@@ -1372,6 +1398,12 @@
 
         initialized = true;
         this.opmode = opmode;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Cipher." + transformation + " " +
+                getOpmodeString(opmode) + " algorithm from: " +
+                this.provider.getName());
+        }
     }
 
     /**
@@ -1509,6 +1541,12 @@
 
         initialized = true;
         this.opmode = opmode;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Cipher." + transformation + " " +
+                getOpmodeString(opmode) + " algorithm from: " +
+                this.provider.getName());
+        }
     }
 
     /**
@@ -1693,6 +1731,12 @@
 
         initialized = true;
         this.opmode = opmode;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Cipher." + transformation + " " +
+                getOpmodeString(opmode) + " algorithm from: " +
+                this.provider.getName());
+        }
     }
 
     /**
diff --git a/jdk/src/share/classes/javax/crypto/CipherInputStream.java b/jdk/src/share/classes/javax/crypto/CipherInputStream.java
index 0e80a60..d777ca0 100644
--- a/jdk/src/share/classes/javax/crypto/CipherInputStream.java
+++ b/jdk/src/share/classes/javax/crypto/CipherInputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -88,6 +88,8 @@
     private int ofinish = 0;
     // stream status
     private boolean closed = false;
+    // The stream has been read from.  False if the stream has never been read.
+    private boolean read = false;
 
     /**
      * private convenience function.
@@ -103,13 +105,15 @@
     private int getMoreData() throws IOException {
         if (done) return -1;
         int readin = input.read(ibuffer);
+        read = true;
         if (readin == -1) {
             done = true;
             try {
                 obuffer = cipher.doFinal();
+            } catch (IllegalBlockSizeException | BadPaddingException e) {
+                obuffer = null;
+                throw new IOException(e);
             }
-            catch (IllegalBlockSizeException e) {obuffer = null;}
-            catch (BadPaddingException e) {obuffer = null;}
             if (obuffer == null)
                 return -1;
             else {
@@ -120,7 +124,10 @@
         }
         try {
             obuffer = cipher.update(ibuffer, 0, readin);
-        } catch (IllegalStateException e) {obuffer = null;};
+        } catch (IllegalStateException e) {
+            obuffer = null;
+            throw e;
+        }
         ostart = 0;
         if (obuffer == null)
             ofinish = 0;
@@ -308,6 +315,11 @@
             }
         }
         catch (BadPaddingException | IllegalBlockSizeException ex) {
+            /* If no data has been read from the stream to be en/decrypted,
+               we supress any exceptions, and close quietly. */
+            if (read) {
+                throw new IOException(ex);
+            }
         }
         ostart = 0;
         ofinish = 0;
diff --git a/jdk/src/share/classes/javax/crypto/KeyAgreement.java b/jdk/src/share/classes/javax/crypto/KeyAgreement.java
index 70221aa..2c24470 100644
--- a/jdk/src/share/classes/javax/crypto/KeyAgreement.java
+++ b/jdk/src/share/classes/javax/crypto/KeyAgreement.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -78,6 +78,11 @@
     private static final Debug debug =
                         Debug.getInstance("jca", "KeyAgreement");
 
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("keyagreement");
+
     // The provider
     private Provider provider;
 
@@ -468,6 +473,11 @@
                 throw new InvalidKeyException(e);
             }
         }
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("KeyAgreement." + algorithm + " algorithm from: " +
+                this.provider.getName());
+        }
     }
 
     /**
@@ -524,6 +534,11 @@
         } else {
             chooseProvider(I_PARAMS, key, params, random);
         }
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("KeyAgreement." + algorithm + " algorithm from: " +
+                this.provider.getName());
+        }
     }
 
     /**
diff --git a/jdk/src/share/classes/javax/crypto/KeyGenerator.java b/jdk/src/share/classes/javax/crypto/KeyGenerator.java
index 030207e..9da64e9 100644
--- a/jdk/src/share/classes/javax/crypto/KeyGenerator.java
+++ b/jdk/src/share/classes/javax/crypto/KeyGenerator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -33,6 +33,7 @@
 
 import sun.security.jca.*;
 import sun.security.jca.GetInstance.Instance;
+import sun.security.util.Debug;
 
 /**
  * This class provides the functionality of a secret (symmetric) key generator.
@@ -108,6 +109,11 @@
 
 public class KeyGenerator {
 
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("keygenerator");
+
     // see java.security.KeyPairGenerator for failover notes
 
     private final static int I_NONE   = 1;
@@ -145,6 +151,11 @@
         this.spi = keyGenSpi;
         this.provider = provider;
         this.algorithm = algorithm;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("KeyGenerator." + algorithm + " algorithm from: " +
+                this.provider.getName());
+        }
     }
 
     private KeyGenerator(String algorithm) throws NoSuchAlgorithmException {
@@ -158,6 +169,11 @@
             throw new NoSuchAlgorithmException
                 (algorithm + " KeyGenerator not available");
         }
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("KeyGenerator." + algorithm + " algorithm from: " +
+                this.provider.getName());
+        }
     }
 
     /**
diff --git a/jdk/src/share/classes/javax/crypto/Mac.java b/jdk/src/share/classes/javax/crypto/Mac.java
index d0e241d..8a497da 100644
--- a/jdk/src/share/classes/javax/crypto/Mac.java
+++ b/jdk/src/share/classes/javax/crypto/Mac.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -77,6 +77,11 @@
     private static final Debug debug =
                         Debug.getInstance("jca", "Mac");
 
+    private static final Debug pdebug =
+                        Debug.getInstance("provider", "Provider");
+    private static final boolean skipDebug =
+        Debug.isOn("engine=") && !Debug.isOn("mac");
+
     // The provider
     private Provider provider;
 
@@ -413,6 +418,11 @@
             throw new InvalidKeyException("init() failed", e);
         }
         initialized = true;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Mac." + algorithm + " algorithm from: " +
+                this.provider.getName());
+        }
     }
 
     /**
@@ -435,6 +445,11 @@
             chooseProvider(key, params);
         }
         initialized = true;
+
+        if (!skipDebug && pdebug != null) {
+            pdebug.println("Mac." + algorithm + " algorithm from: " +
+                this.provider.getName());
+        }
     }
 
     /**
diff --git a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java
index c5a7f59..b21dab6 100644
--- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java
+++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java
@@ -2895,6 +2895,14 @@
                     return comp;
                 }
 
+                if (flavor1.isFlavorTextType()) {
+                    return 1;
+                }
+
+                if (flavor2.isFlavorTextType()) {
+                    return -1;
+                }
+
                 // Next, look for application/x-java-* types. Prefer unknown
                 // MIME types because if the user provides his own data flavor,
                 // it will likely be the most descriptive one.
diff --git a/jdk/src/share/classes/sun/awt/image/BytePackedRaster.java b/jdk/src/share/classes/sun/awt/image/BytePackedRaster.java
index bd3835d..3e60f19 100644
--- a/jdk/src/share/classes/sun/awt/image/BytePackedRaster.java
+++ b/jdk/src/share/classes/sun/awt/image/BytePackedRaster.java
@@ -1408,10 +1408,10 @@
             }
         }
 
-        int lastbit = (dataBitOffset
-                       + (height-1) * scanlineStride * 8
-                       + (width-1) * pixelBitStride
-                       + pixelBitStride - 1);
+        long lastbit = (long) dataBitOffset
+                       + (long) (height - 1) * (long) scanlineStride * 8
+                       + (long) (width - 1) * (long) pixelBitStride
+                       + (long) pixelBitStride - 1;
         if (lastbit < 0 || lastbit / 8 >= data.length) {
             throw new RasterFormatException("raster dimensions overflow " +
                                             "array bounds");
diff --git a/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java b/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java
index a95aefb..fc870fc 100644
--- a/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java
+++ b/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java
@@ -102,19 +102,24 @@
         case PUBLIC:
             return true;  // already checked above
         case PROTECTED:
+            assert !defc.isInterface(); // protected members aren't allowed in interfaces
             if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 &&
                 isSamePackage(defc, lookupClass))
                 return true;
             if ((allowedModes & PROTECTED) == 0)
                 return false;
+            // Protected members are accessible by subclasses, which does not include interfaces.
+            // Interfaces are types, not classes. They should not have access to
+            // protected members in j.l.Object, even though it is their superclass.
             if ((mods & STATIC) != 0 &&
                 !isRelatedClass(refc, lookupClass))
                 return false;
             if ((allowedModes & PROTECTED) != 0 &&
-                isSuperClass(defc, lookupClass))
+                isSubClass(lookupClass, defc))
                 return true;
             return false;
         case PACKAGE_ONLY:  // That is, zero.  Unmarked member is package-only access.
+            assert !defc.isInterface(); // package-private members aren't allowed in interfaces
             return ((allowedModes & PACKAGE_ALLOWED) != 0 &&
                     isSamePackage(defc, lookupClass));
         case PRIVATE:
@@ -129,12 +134,13 @@
 
     static boolean isRelatedClass(Class<?> refc, Class<?> lookupClass) {
         return (refc == lookupClass ||
-                refc.isAssignableFrom(lookupClass) ||
-                lookupClass.isAssignableFrom(refc));
+                isSubClass(refc, lookupClass) ||
+                isSubClass(lookupClass, refc));
     }
 
-    static boolean isSuperClass(Class<?> defc, Class<?> lookupClass) {
-        return defc.isAssignableFrom(lookupClass);
+    static boolean isSubClass(Class<?> lookupClass, Class<?> defc) {
+        return defc.isAssignableFrom(lookupClass) &&
+               !lookupClass.isInterface(); // interfaces are types, not classes.
     }
 
     static int getClassModifiers(Class<?> c) {
diff --git a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
index a34286b..53e84d4 100644
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
@@ -740,6 +740,26 @@
 
                     // set or refresh local address
                     localAddress = Net.localAddress(fd);
+
+                    // flush any packets already received.
+                    boolean blocking = false;
+                    synchronized (blockingLock()) {
+                        try {
+                            blocking = isBlocking();
+                            // remainder of each packet thrown away
+                            ByteBuffer tmpBuf = ByteBuffer.allocate(1);
+                            if (blocking) {
+                                configureBlocking(false);
+                            }
+                            do {
+                                tmpBuf.clear();
+                            } while (receive(tmpBuf) != null);
+                        } finally {
+                            if (blocking) {
+                                configureBlocking(true);
+                            }
+                        }
+                    }
                 }
             }
         }
diff --git a/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java b/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java
index 6e73de7..120fe7a 100644
--- a/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java
+++ b/jdk/src/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -29,7 +29,6 @@
 import java.lang.reflect.*;
 import java.io.Serializable;
 import java.util.*;
-import java.lang.annotation.*;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
@@ -45,6 +44,11 @@
     private final Map<String, Object> memberValues;
 
     AnnotationInvocationHandler(Class<? extends Annotation> type, Map<String, Object> memberValues) {
+        Class<?>[] superInterfaces = type.getInterfaces();
+        if (!type.isAnnotation() ||
+            superInterfaces.length != 1 ||
+            superInterfaces[0] != java.lang.annotation.Annotation.class)
+            throw new AnnotationFormatError("Attempt to create proxy for a non-annotation type.");
         this.type = type;
         this.memberValues = memberValues;
     }
@@ -57,13 +61,17 @@
         if (member.equals("equals") && paramTypes.length == 1 &&
             paramTypes[0] == Object.class)
             return equalsImpl(args[0]);
-        assert paramTypes.length == 0;
-        if (member.equals("toString"))
+        if (paramTypes.length != 0)
+            throw new AssertionError("Too many parameters for an annotation method");
+
+        switch(member) {
+        case "toString":
             return toStringImpl();
-        if (member.equals("hashCode"))
+        case "hashCode":
             return hashCodeImpl();
-        if (member.equals("annotationType"))
+        case "annotationType":
             return type;
+        }
 
         // Handle annotation member accessors
         Object result = memberValues.get(member);
@@ -129,7 +137,7 @@
      * Implementation of dynamicProxy.toString()
      */
     private String toStringImpl() {
-        StringBuffer result = new StringBuffer(128);
+        StringBuilder result = new StringBuilder(128);
         result.append('@');
         result.append(type.getName());
         result.append('(');
@@ -277,6 +285,7 @@
                 new PrivilegedAction<Method[]>() {
                     public Method[] run() {
                         final Method[] mm = type.getDeclaredMethods();
+                        validateAnnotationMethods(mm);
                         AccessibleObject.setAccessible(mm, true);
                         return mm;
                     }
@@ -287,6 +296,94 @@
     private transient volatile Method[] memberMethods = null;
 
     /**
+     * Validates that a method is structurally appropriate for an
+     * annotation type. As of Java SE 8, annotation types cannot
+     * contain static methods and the declared methods of an
+     * annotation type must take zero arguments and there are
+     * restrictions on the return type.
+     */
+    private void validateAnnotationMethods(Method[] memberMethods) {
+        /*
+         * Specification citations below are from JLS
+         * 9.6.1. Annotation Type Elements
+         */
+        boolean valid = true;
+        for(Method method : memberMethods) {
+            /*
+             * "By virtue of the AnnotationTypeElementDeclaration
+             * production, a method declaration in an annotation type
+             * declaration cannot have formal parameters, type
+             * parameters, or a throws clause.
+             *
+             * "By virtue of the AnnotationTypeElementModifier
+             * production, a method declaration in an annotation type
+             * declaration cannot be default or static."
+             */
+            if (method.getModifiers() != (Modifier.PUBLIC | Modifier.ABSTRACT) ||
+                method.isDefault() ||
+                method.getParameterCount() != 0 ||
+                method.getExceptionTypes().length != 0) {
+                valid = false;
+                break;
+            }
+
+            /*
+             * "It is a compile-time error if the return type of a
+             * method declared in an annotation type is not one of the
+             * following: a primitive type, String, Class, any
+             * parameterized invocation of Class, an enum type
+             * (section 8.9), an annotation type, or an array type
+             * (chapter 10) whose element type is one of the preceding
+             * types."
+             */
+            Class<?> returnType = method.getReturnType();
+            if (returnType.isArray()) {
+                returnType = returnType.getComponentType();
+                if (returnType.isArray()) { // Only single dimensional arrays
+                    valid = false;
+                    break;
+                }
+            }
+
+            if (!((returnType.isPrimitive() && returnType != void.class) ||
+                  returnType == java.lang.String.class ||
+                  returnType == java.lang.Class.class ||
+                  returnType.isEnum() ||
+                  returnType.isAnnotation())) {
+                valid = false;
+                break;
+            }
+
+            /*
+             * "It is a compile-time error if any method declared in an
+             * annotation type has a signature that is
+             * override-equivalent to that of any public or protected
+             * method declared in class Object or in the interface
+             * java.lang.annotation.Annotation."
+             *
+             * The methods in Object or Annotation meeting the other
+             * criteria (no arguments, contrained return type, etc.)
+             * above are:
+             *
+             * String toString()
+             * int hashCode()
+             * Class<? extends Annotation> annotationType()
+             */
+            String methodName = method.getName();
+            if ((methodName.equals("toString") && returnType == java.lang.String.class) ||
+                (methodName.equals("hashCode") && returnType == int.class) ||
+                (methodName.equals("annotationType") && returnType == java.lang.Class.class)) {
+                valid = false;
+                break;
+            }
+        }
+        if (valid)
+            return;
+        else
+            throw new AnnotationFormatError("Malformed method on an annotation type");
+    }
+
+    /**
      * Implementation of dynamicProxy.hashCode()
      */
     private int hashCodeImpl() {
@@ -330,7 +427,6 @@
         throws java.io.IOException, ClassNotFoundException {
         s.defaultReadObject();
 
-
         // Check to make sure that types have not evolved incompatibly
 
         AnnotationType annotationType = null;
@@ -343,7 +439,6 @@
 
         Map<String, Class<?>> memberTypes = annotationType.memberTypes();
 
-
         // If there are annotation members without values, that
         // situation is handled by the invoke method.
         for (Map.Entry<String, Object> memberValue : memberValues.entrySet()) {
diff --git a/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java b/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java
index 1c66bf5..2390639 100644
--- a/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java
+++ b/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java
@@ -523,13 +523,6 @@
                     valid = false;
                 }
 
-                // get the mechanism token
-                byte[] mechToken = initToken.getMechToken();
-                if (mechToken == null) {
-                    throw new GSSException(GSSException.FAILURE, -1,
-                            "mechToken is missing");
-                }
-
                 /*
                  * Select the best match between the list of mechs
                  * that the initiator requested and the list that
@@ -545,7 +538,19 @@
                 internal_mech = mech_wanted;
 
                 // get the token for mechanism
-                byte[] accept_token = GSS_acceptSecContext(mechToken);
+                byte[] accept_token;
+
+                if (mechList[0].equals(mech_wanted)) {
+                    // get the mechanism token
+                    byte[] mechToken = initToken.getMechToken();
+                    if (mechToken == null) {
+                        throw new GSSException(GSSException.FAILURE, -1,
+                                "mechToken is missing");
+                    }
+                    accept_token = GSS_acceptSecContext(mechToken);
+                } else {
+                    accept_token = null;
+                }
 
                 // verify MIC
                 if (!GSSUtil.useMSInterop() && valid) {
@@ -594,9 +599,27 @@
                 retVal = targToken.getEncoded();
 
             } else if (state == STATE_IN_PROCESS) {
+                // read data
+                byte[] token = new byte[is.available()];
+                SpNegoToken.readFully(is, token);
+                if (DEBUG) {
+                    System.out.println("SpNegoContext.acceptSecContext: " +
+                            "receiving token = " +
+                            SpNegoToken.getHexBytes(token));
+                }
+
+                // read the SPNEGO token
+                // token will be validated when parsing
+                NegTokenTarg inputToken = new NegTokenTarg(token);
+
+                if (DEBUG) {
+                    System.out.println("SpNegoContext.acceptSecContext: " +
+                            "received token of type = " +
+                            SpNegoToken.getTokenName(inputToken.getType()));
+                }
+
                 // read the token
-                byte[] client_token = new byte[is.available()];
-                SpNegoToken.readFully(is, client_token);
+                byte[] client_token = inputToken.getResponseToken();
                 byte[] accept_token = GSS_acceptSecContext(client_token);
                 if (accept_token == null) {
                     valid = false;
@@ -1055,7 +1078,7 @@
      * This is only valid on the acceptor side of the context.
      * @return GSSCredentialSpi object for the delegated credential
      * @exception GSSException
-     * @see GSSContext#getDelegCredState
+     * @see GSSContext#getCredDelegState
      */
     public final GSSCredentialSpi getDelegCred() throws GSSException {
         if (state != STATE_IN_PROCESS && state != STATE_DONE)
diff --git a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java
index 528b369..7035171 100644
--- a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java
+++ b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -968,7 +968,7 @@
          * 1. Prefer Suite B compliant cipher suites, see RFC6460 (To be
          *    changed later, see below).
          * 2. Prefer the stronger bulk cipher, in the order of AES_256(GCM),
-         *    AES_128(GCM), AES_256, AES_128, RC-4, 3DES-EDE.
+         *    AES_128(GCM), AES_256, AES_128, 3DES-EDE, RC-4.
          * 3. Prefer the stronger MAC algorithm, in the order of SHA384,
          *    SHA256, SHA, MD5.
          * 4. Prefer the better performance of key exchange and digital
@@ -1055,18 +1055,6 @@
         add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
             0x0032, --p, K_DHE_DSS,     B_AES_128, T);
 
-        // RC-4
-        add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
-            0xC007, --p, K_ECDHE_ECDSA, B_RC4_128, N);
-        add("TLS_ECDHE_RSA_WITH_RC4_128_SHA",
-            0xC011, --p, K_ECDHE_RSA,   B_RC4_128, N);
-        add("SSL_RSA_WITH_RC4_128_SHA",
-            0x0005, --p, K_RSA,         B_RC4_128, N);
-        add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
-            0xC002, --p, K_ECDH_ECDSA,  B_RC4_128, N);
-        add("TLS_ECDH_RSA_WITH_RC4_128_SHA",
-            0xC00C, --p, K_ECDH_RSA,    B_RC4_128, N);
-
         // Cipher suites in GCM mode, see RFC 5288/5289.
         //
         // We may increase the priority of cipher suites in GCM mode when
@@ -1127,6 +1115,17 @@
         add("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
             0x0013, --p, K_DHE_DSS,     B_3DES,    N);
 
+        // RC-4
+        add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+            0xC007, --p, K_ECDHE_ECDSA, B_RC4_128, N);
+        add("TLS_ECDHE_RSA_WITH_RC4_128_SHA",
+            0xC011, --p, K_ECDHE_RSA,   B_RC4_128, N);
+        add("SSL_RSA_WITH_RC4_128_SHA",
+            0x0005, --p, K_RSA,         B_RC4_128, N);
+        add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
+            0xC002, --p, K_ECDH_ECDSA,  B_RC4_128, N);
+        add("TLS_ECDH_RSA_WITH_RC4_128_SHA",
+            0xC00C, --p, K_ECDH_RSA,    B_RC4_128, N);
         add("SSL_RSA_WITH_RC4_128_MD5",
             0x0004, --p, K_RSA,         B_RC4_128, N);
 
@@ -1146,7 +1145,7 @@
          * 2. If a cipher suite has been obsoleted, we put it at the end of
          *    the list.
          * 3. Prefer the stronger bulk cipher, in the order of AES_256,
-         *    AES_128, RC-4, 3DES-EDE, DES, RC4_40, DES40, NULL.
+         *    AES_128, 3DES-EDE, RC-4, DES, DES40, RC4_40, NULL.
          * 4. Prefer the stronger MAC algorithm, in the order of SHA384,
          *    SHA256, SHA, MD5.
          * 5. Prefer the better performance of key exchange and digital
@@ -1174,15 +1173,40 @@
         add("TLS_DH_anon_WITH_AES_128_CBC_SHA",
             0x0034, --p, K_DH_ANON,     B_AES_128, N);
 
+        add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
+            0xC017, --p, K_ECDH_ANON,   B_3DES,    N);
+        add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
+            0x001b, --p, K_DH_ANON,     B_3DES,    N);
+
         add("TLS_ECDH_anon_WITH_RC4_128_SHA",
             0xC016, --p, K_ECDH_ANON,   B_RC4_128, N);
         add("SSL_DH_anon_WITH_RC4_128_MD5",
             0x0018, --p, K_DH_ANON,     B_RC4_128, N);
 
-        add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
-            0xC017, --p, K_ECDH_ANON,   B_3DES,    N);
-        add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
-            0x001b, --p, K_DH_ANON,     B_3DES,    N);
+        // weak cipher suites obsoleted in TLS 1.2
+        add("SSL_RSA_WITH_DES_CBC_SHA",
+            0x0009, --p, K_RSA,         B_DES,     N, tls12);
+        add("SSL_DHE_RSA_WITH_DES_CBC_SHA",
+            0x0015, --p, K_DHE_RSA,     B_DES,     N, tls12);
+        add("SSL_DHE_DSS_WITH_DES_CBC_SHA",
+            0x0012, --p, K_DHE_DSS,     B_DES,     N, tls12);
+        add("SSL_DH_anon_WITH_DES_CBC_SHA",
+            0x001a, --p, K_DH_ANON,     B_DES,     N, tls12);
+
+        // weak cipher suites obsoleted in TLS 1.1
+        add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+            0x0008, --p, K_RSA_EXPORT,  B_DES_40,  N, tls11);
+        add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+            0x0014, --p, K_DHE_RSA,     B_DES_40,  N, tls11);
+        add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+            0x0011, --p, K_DHE_DSS,     B_DES_40,  N, tls11);
+        add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
+            0x0019, --p, K_DH_ANON,     B_DES_40,  N, tls11);
+
+        add("SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+            0x0003, --p, K_RSA_EXPORT,  B_RC4_40,  N, tls11);
+        add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
+            0x0017, --p, K_DH_ANON,     B_RC4_40,  N, tls11);
 
         add("TLS_RSA_WITH_NULL_SHA256",
             0x003b, --p, K_RSA,         B_NULL,    N, max, tls12, P_SHA256);
@@ -1201,52 +1225,27 @@
         add("SSL_RSA_WITH_NULL_MD5",
             0x0001, --p, K_RSA,         B_NULL,    N);
 
-        // weak cipher suites obsoleted in TLS 1.2
-        add("SSL_RSA_WITH_DES_CBC_SHA",
-            0x0009, --p, K_RSA,         B_DES,     N, tls12);
-        add("SSL_DHE_RSA_WITH_DES_CBC_SHA",
-            0x0015, --p, K_DHE_RSA,     B_DES,     N, tls12);
-        add("SSL_DHE_DSS_WITH_DES_CBC_SHA",
-            0x0012, --p, K_DHE_DSS,     B_DES,     N, tls12);
-        add("SSL_DH_anon_WITH_DES_CBC_SHA",
-            0x001a, --p, K_DH_ANON,     B_DES,     N, tls12);
-
-        // weak cipher suites obsoleted in TLS 1.1
-        add("SSL_RSA_EXPORT_WITH_RC4_40_MD5",
-            0x0003, --p, K_RSA_EXPORT,  B_RC4_40,  N, tls11);
-        add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
-            0x0017, --p, K_DH_ANON,     B_RC4_40,  N, tls11);
-
-        add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
-            0x0008, --p, K_RSA_EXPORT,  B_DES_40,  N, tls11);
-        add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
-            0x0014, --p, K_DHE_RSA,     B_DES_40,  N, tls11);
-        add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
-            0x0011, --p, K_DHE_DSS,     B_DES_40,  N, tls11);
-        add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
-            0x0019, --p, K_DH_ANON,     B_DES_40,  N, tls11);
-
         // Supported Kerberos ciphersuites from RFC2712
-        add("TLS_KRB5_WITH_RC4_128_SHA",
-            0x0020, --p, K_KRB5,        B_RC4_128, N);
-        add("TLS_KRB5_WITH_RC4_128_MD5",
-            0x0024, --p, K_KRB5,        B_RC4_128, N);
         add("TLS_KRB5_WITH_3DES_EDE_CBC_SHA",
             0x001f, --p, K_KRB5,        B_3DES,    N);
         add("TLS_KRB5_WITH_3DES_EDE_CBC_MD5",
             0x0023, --p, K_KRB5,        B_3DES,    N);
+        add("TLS_KRB5_WITH_RC4_128_SHA",
+            0x0020, --p, K_KRB5,        B_RC4_128, N);
+        add("TLS_KRB5_WITH_RC4_128_MD5",
+            0x0024, --p, K_KRB5,        B_RC4_128, N);
         add("TLS_KRB5_WITH_DES_CBC_SHA",
             0x001e, --p, K_KRB5,        B_DES,     N, tls12);
         add("TLS_KRB5_WITH_DES_CBC_MD5",
             0x0022, --p, K_KRB5,        B_DES,     N, tls12);
-        add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
-            0x0028, --p, K_KRB5_EXPORT, B_RC4_40,  N, tls11);
-        add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
-            0x002b, --p, K_KRB5_EXPORT, B_RC4_40,  N, tls11);
         add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",
             0x0026, --p, K_KRB5_EXPORT, B_DES_40,  N, tls11);
         add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",
             0x0029, --p, K_KRB5_EXPORT, B_DES_40,  N, tls11);
+        add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
+            0x0028, --p, K_KRB5_EXPORT, B_RC4_40,  N, tls11);
+        add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
+            0x002b, --p, K_KRB5_EXPORT, B_RC4_40,  N, tls11);
 
         /*
          * Other values from the TLS Cipher Suite Registry, as of August 2010.
diff --git a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java
index 5c3abbc..5108528 100644
--- a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java
+++ b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -36,6 +36,8 @@
 
 import java.security.cert.X509Certificate;
 import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
+import javax.security.auth.x500.X500Principal;
 
 import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
@@ -89,12 +91,66 @@
     private final static boolean enableSNIExtension =
             Debug.getBooleanProperty("jsse.enableSNIExtension", true);
 
+    /*
+     * Allow unsafe server certificate change?
+     *
+     * Server certificate change during SSL/TLS renegotiation may be considered
+     * unsafe, as described in the Triple Handshake attacks:
+     *
+     *     https://secure-resumption.com/tlsauth.pdf
+     *
+     * Endpoint identification (See
+     * SSLParameters.getEndpointIdentificationAlgorithm()) is a pretty nice
+     * guarantee that the server certificate change in renegotiation is legal.
+     * However, endpoing identification is only enabled for HTTPS and LDAP
+     * over SSL/TLS by default.  It is not enough to protect SSL/TLS
+     * connections other than HTTPS and LDAP.
+     *
+     * The renegotiation indication extension (See RFC 5764) is a pretty
+     * strong guarantee that the endpoints on both client and server sides
+     * are identical on the same connection.  However, the Triple Handshake
+     * attacks can bypass this guarantee if there is a session-resumption
+     * handshake between the initial full handshake and the renegotiation
+     * full handshake.
+     *
+     * Server certificate change may be unsafe and should be restricted if
+     * endpoint identification is not enabled and the previous handshake is
+     * a session-resumption abbreviated initial handshake, unless the
+     * identities represented by both certificates can be regraded as the
+     * same (See isIdentityEquivalent()).
+     *
+     * Considering the compatibility impact and the actual requirements to
+     * support server certificate change in practice, the system property,
+     * jdk.tls.allowUnsafeServerCertChange, is used to define whether unsafe
+     * server certificate change in renegotiation is allowed or not.  The
+     * default value of the system property is "false".  To mitigate the
+     * compactibility impact, applications may want to set the system
+     * property to "true" at their own risk.
+     *
+     * If the value of the system property is "false", server certificate
+     * change in renegotiation after a session-resumption abbreviated initial
+     * handshake is restricted (See isIdentityEquivalent()).
+     *
+     * If the system property is set to "true" explicitly, the restriction on
+     * server certificate change in renegotiation is disabled.
+     */
+    private final static boolean allowUnsafeServerCertChange =
+        Debug.getBooleanProperty("jdk.tls.allowUnsafeServerCertChange", false);
+
     private List<SNIServerName> requestedServerNames =
             Collections.<SNIServerName>emptyList();
 
     private boolean serverNamesAccepted = false;
 
     /*
+     * the reserved server certificate chain in previous handshaking
+     *
+     * The server certificate chain is only reserved if the previous
+     * handshake is a session-resumption abbreviated initial handshake.
+     */
+    private X509Certificate[] reservedServerCerts = null;
+
+    /*
      * Constructors
      */
     ClientHandshaker(SSLSocketImpl socket, SSLContextImpl context,
@@ -555,14 +611,19 @@
                 // we wanted to resume, but the server refused
                 session = null;
                 if (!enableNewSession) {
-                    throw new SSLException
-                        ("New session creation is disabled");
+                    throw new SSLException("New session creation is disabled");
                 }
             }
         }
 
         if (resumingSession && session != null) {
             setHandshakeSessionSE(session);
+            // Reserve the handshake state if this is a session-resumption
+            // abbreviated initial handshake.
+            if (isInitialHandshake) {
+                session.setAsSessionResumption(true);
+            }
+
             return;
         }
 
@@ -1064,6 +1125,13 @@
         }
 
         /*
+         * Reset the handshake state if this is not an initial handshake.
+         */
+        if (!isInitialHandshake) {
+            session.setAsSessionResumption(false);
+        }
+
+        /*
          * OK, it verified.  If we're doing the fast handshake, add that
          * "Finished" message to the hash of handshake messages, then send
          * our own change_cipher_spec and Finished message for the server
@@ -1161,8 +1229,23 @@
                 System.out.println("%% No cached client session");
             }
         }
-        if ((session != null) && (session.isRejoinable() == false)) {
-            session = null;
+        if (session != null) {
+            // If unsafe server certificate change is not allowed, reserve
+            // current server certificates if the previous handshake is a
+            // session-resumption abbreviated initial handshake.
+            if (!allowUnsafeServerCertChange && session.isSessionResumption()) {
+                try {
+                    // If existing, peer certificate chain cannot be null.
+                    reservedServerCerts =
+                        (X509Certificate[])session.getPeerCertificates();
+                } catch (SSLPeerUnverifiedException puve) {
+                    // Maybe not certificate-based, ignore the exception.
+                }
+            }
+
+            if (!session.isRejoinable()) {
+                session = null;
+            }
         }
 
         if (session != null) {
@@ -1331,9 +1414,28 @@
         }
         X509Certificate[] peerCerts = mesg.getCertificateChain();
         if (peerCerts.length == 0) {
-            fatalSE(Alerts.alert_bad_certificate,
-                "empty certificate chain");
+            fatalSE(Alerts.alert_bad_certificate, "empty certificate chain");
         }
+
+        // Allow server certificate change in client side during renegotiation
+        // after a session-resumption abbreviated initial handshake?
+        //
+        // DO NOT need to check allowUnsafeServerCertChange here. We only
+        // reserve server certificates when allowUnsafeServerCertChange is
+        // flase.
+        if (reservedServerCerts != null) {
+            // It is not necessary to check the certificate update if endpoint
+            // identification is enabled.
+            String identityAlg = getEndpointIdentificationAlgorithmSE();
+            if ((identityAlg == null || identityAlg.length() == 0) &&
+                !isIdentityEquivalent(peerCerts[0], reservedServerCerts[0])) {
+
+                fatalSE(Alerts.alert_bad_certificate,
+                        "server certificate change is restricted " +
+                        "during renegotiation");
+            }
+        }
+
         // ask the trust manager to verify the chain
         X509TrustManager tm = sslContext.getX509TrustManager();
         try {
@@ -1370,4 +1472,81 @@
         }
         session.setPeerCertificates(peerCerts);
     }
+
+    /*
+     * Whether the certificates can represent the same identity?
+     *
+     * The certificates can be used to represent the same identity:
+     *     1. If the subject alternative names of IP address are present in
+     *        both certificates, they should be identical; otherwise,
+     *     2. if the subject alternative names of DNS name are present in
+     *        both certificates, they should be identical; otherwise,
+     *     3. if the subject fields are present in both certificates, the
+     *        certificate subjects and issuers should be identical.
+     */
+    private static boolean isIdentityEquivalent(X509Certificate thisCert,
+            X509Certificate prevCert) {
+        if (thisCert.equals(prevCert)) {
+            return true;
+        }
+
+        // check the iPAddress field in subjectAltName extension
+        Object thisIPAddress = getSubjectAltName(thisCert, 7);  // 7: iPAddress
+        Object prevIPAddress = getSubjectAltName(prevCert, 7);
+        if (thisIPAddress != null && prevIPAddress!= null) {
+            // only allow the exactly match
+            return Objects.equals(thisIPAddress, prevIPAddress);
+        }
+
+        // check the dNSName field in subjectAltName extension
+        Object thisDNSName = getSubjectAltName(thisCert, 2);    // 2: dNSName
+        Object prevDNSName = getSubjectAltName(prevCert, 2);
+        if (thisDNSName != null && prevDNSName!= null) {
+            // only allow the exactly match
+            return Objects.equals(thisDNSName, prevDNSName);
+        }
+
+        // check the certificate subject and issuer
+        X500Principal thisSubject = thisCert.getSubjectX500Principal();
+        X500Principal prevSubject = prevCert.getSubjectX500Principal();
+        X500Principal thisIssuer = thisCert.getIssuerX500Principal();
+        X500Principal prevIssuer = prevCert.getIssuerX500Principal();
+        if (!thisSubject.getName().isEmpty() &&
+                !prevSubject.getName().isEmpty() &&
+                thisSubject.equals(prevSubject) &&
+                thisIssuer.equals(prevIssuer)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /*
+     * Returns the subject alternative name of the specified type in the
+     * subjectAltNames extension of a certificate.
+     */
+    private static Object getSubjectAltName(X509Certificate cert, int type) {
+        Collection<List<?>> subjectAltNames;
+
+        try {
+            subjectAltNames = cert.getSubjectAlternativeNames();
+        } catch (CertificateParsingException cpe) {
+            if (debug != null && Debug.isOn("handshake")) {
+                System.out.println(
+                        "Attempt to obtain subjectAltNames extension failed!");
+            }
+            return null;
+        }
+
+        if (subjectAltNames != null) {
+            for (List<?> subjectAltName : subjectAltNames) {
+                int subjectAltNameType = (Integer)subjectAltName.get(0);
+                if (subjectAltNameType == type) {
+                    return subjectAltName.get(1);
+                }
+            }
+        }
+
+        return null;
+    }
 }
diff --git a/jdk/src/share/classes/sun/security/ssl/Handshaker.java b/jdk/src/share/classes/sun/security/ssl/Handshaker.java
index bea8608..80c2a51 100644
--- a/jdk/src/share/classes/sun/security/ssl/Handshaker.java
+++ b/jdk/src/share/classes/sun/security/ssl/Handshaker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -359,6 +359,17 @@
         }
     }
 
+    String getEndpointIdentificationAlgorithmSE() {
+        SSLParameters paras;
+        if (conn != null) {
+            paras = conn.getSSLParameters();
+        } else {
+            paras = engine.getSSLParameters();
+        }
+
+        return paras.getEndpointIdentificationAlgorithm();
+    }
+
     private void setVersionSE(ProtocolVersion protocolVersion) {
         if (conn != null) {
             conn.setVersion(protocolVersion);
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java
index 6cb4170..b5f304b 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -115,6 +115,14 @@
     private Principal localPrincipal;
 
     /*
+     * Is the session currently re-established with a session-resumption
+     * abbreviated initial handshake?
+     *
+     * Note that currently we only set this variable in client side.
+     */
+    private boolean isSessionResumption = false;
+
+    /*
      * We count session creations, eventually for statistical data but
      * also since counters make shorter debugging IDs than the big ones
      * we use in the protocol for uniqueness-over-time.
@@ -325,6 +333,22 @@
     }
 
     /**
+     * Return true if the session is currently re-established with a
+     * session-resumption abbreviated initial handshake.
+     */
+    boolean isSessionResumption() {
+        return isSessionResumption;
+    }
+
+    /**
+     * Resets whether the session is re-established with a session-resumption
+     * abbreviated initial handshake.
+     */
+    void setAsSessionResumption(boolean flag) {
+        isSessionResumption = flag;
+    }
+
+    /**
      * Returns the name of the cipher suite in use on this session
      */
     @Override
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources.java
index 6199927..73eac26 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/Resources.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources.java
@@ -336,7 +336,7 @@
         {"New.prompt.", "New {0}: "},
         {"Passwords.must.differ", "Passwords must differ"},
         {"Re.enter.new.prompt.", "Re-enter new {0}: "},
-        {"Re.enter.passpword.", "Re-enter password: "},
+        {"Re.enter.password.", "Re-enter password: "},
         {"Re.enter.new.password.", "Re-enter new password: "},
         {"They.don.t.match.Try.again", "They don't match. Try again"},
         {"Enter.prompt.alias.name.", "Enter {0} alias name:  "},
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java
index 2a80245..a024795 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_de.java
@@ -336,7 +336,7 @@
         {"New.prompt.", "Neues {0}: "},
         {"Passwords.must.differ", "Kennw\u00F6rter m\u00FCssen sich unterscheiden"},
         {"Re.enter.new.prompt.", "Neues {0} erneut eingeben: "},
-        {"Re.enter.passpword.", "Geben Sie das Kennwort erneut ein: "},
+        {"Re.enter.password.", "Geben Sie das Kennwort erneut ein: "},
         {"Re.enter.new.password.", "Neues Kennwort erneut eingeben: "},
         {"They.don.t.match.Try.again", "Keine \u00DCbereinstimmung. Wiederholen Sie den Vorgang"},
         {"Enter.prompt.alias.name.", "{0}-Aliasnamen eingeben:  "},
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java
index 4c0bd34..5348d1a 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_es.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -336,7 +336,7 @@
         {"New.prompt.", "Nuevo {0}: "},
         {"Passwords.must.differ", "Las contrase\u00F1as deben ser distintas"},
         {"Re.enter.new.prompt.", "Vuelva a escribir el nuevo {0}: "},
-        {"Re.enter.passpword.", "Vuelva a introducir la contrase\u00F1a: "},
+        {"Re.enter.password.", "Vuelva a introducir la contrase\u00F1a: "},
         {"Re.enter.new.password.", "Volver a escribir la contrase\u00F1a nueva: "},
         {"They.don.t.match.Try.again", "No coinciden. Int\u00E9ntelo de nuevo"},
         {"Enter.prompt.alias.name.", "Escriba el nombre de alias de {0}:  "},
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java
index 6ba2985..6b22844 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_fr.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -336,7 +336,7 @@
         {"New.prompt.", "Nouveau {0} : "},
         {"Passwords.must.differ", "Les mots de passe doivent diff\u00E9rer"},
         {"Re.enter.new.prompt.", "Indiquez encore le nouveau {0} : "},
-        {"Re.enter.passpword.", "R\u00E9p\u00E9tez le mot de passe : "},
+        {"Re.enter.password.", "R\u00E9p\u00E9tez le mot de passe : "},
         {"Re.enter.new.password.", "Ressaisissez le nouveau mot de passe : "},
         {"They.don.t.match.Try.again", "Ils sont diff\u00E9rents. R\u00E9essayez."},
         {"Enter.prompt.alias.name.", "Indiquez le nom d''alias {0} :  "},
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java
index 68b64ce..2a49fe6 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_it.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -336,7 +336,7 @@
         {"New.prompt.", "Nuova {0}: "},
         {"Passwords.must.differ", "Le password non devono coincidere"},
         {"Re.enter.new.prompt.", "Reimmettere un nuovo valore per {0}: "},
-        {"Re.enter.passpword.", "Reimmettere la password: "},
+        {"Re.enter.password.", "Reimmettere la password: "},
         {"Re.enter.new.password.", "Immettere nuovamente la nuova password: "},
         {"They.don.t.match.Try.again", "Non corrispondono. Riprovare."},
         {"Enter.prompt.alias.name.", "Immettere nome alias {0}:  "},
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java
index 5f5ee09..d910203 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_ja.java
@@ -248,7 +248,7 @@
                  "\u65E2\u5B58\u306E\u30A8\u30F3\u30C8\u30EA\u306E\u5225\u540D{0}\u304C\u5B58\u5728\u3057\u3066\u3044\u307E\u3059\u3002\u4E0A\u66F8\u304D\u3057\u307E\u3059\u304B\u3002[\u3044\u3044\u3048]:  "},
         {"Too.many.failures.try.later", "\u969C\u5BB3\u304C\u591A\u3059\u304E\u307E\u3059 - \u5F8C\u3067\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044"},
         {"Certification.request.stored.in.file.filename.",
-                "\u8A3C\u660E\u66F8\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u30D5\u30A1\u30A4\u30EB<{0}>\u306B\u4FDD\u5B58\u3055\u308C\u307E\u3057\u305F"},
+                "\u8A8D\u8A3C\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u30D5\u30A1\u30A4\u30EB<{0}>\u306B\u4FDD\u5B58\u3055\u308C\u307E\u3057\u305F"},
         {"Submit.this.to.your.CA", "\u3053\u308C\u3092CA\u306B\u63D0\u51FA\u3057\u3066\u304F\u3060\u3055\u3044"},
         {"if.alias.not.specified.destalias.and.srckeypass.must.not.be.specified",
             "\u5225\u540D\u3092\u6307\u5B9A\u3057\u306A\u3044\u5834\u5408\u3001\u51FA\u529B\u5148\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u5225\u540D\u304A\u3088\u3073\u30BD\u30FC\u30B9\u30FB\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093"},
@@ -336,7 +336,7 @@
         {"New.prompt.", "\u65B0\u898F{0}: "},
         {"Passwords.must.differ", "\u30D1\u30B9\u30EF\u30FC\u30C9\u306F\u7570\u306A\u3063\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059"},
         {"Re.enter.new.prompt.", "\u65B0\u898F{0}\u3092\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044: "},
-        {"Re.enter.passpword.", "\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044: "},
+        {"Re.enter.password.", "\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044: "},
         {"Re.enter.new.password.", "\u65B0\u898F\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044: "},
         {"They.don.t.match.Try.again", "\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002\u3082\u3046\u4E00\u5EA6\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044"},
         {"Enter.prompt.alias.name.", "{0}\u306E\u5225\u540D\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044:  "},
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java
index d0bed5c..40ede29 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_ko.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -336,7 +336,7 @@
         {"New.prompt.", "\uC0C8 {0}: "},
         {"Passwords.must.differ", "\uBE44\uBC00\uBC88\uD638\uB294 \uB2EC\uB77C\uC57C \uD569\uB2C8\uB2E4."},
         {"Re.enter.new.prompt.", "\uC0C8 {0} \uB2E4\uC2DC \uC785\uB825: "},
-        {"Re.enter.passpword.", "\uBE44\uBC00\uBC88\uD638  \uB2E4\uC2DC \uC785\uB825: "},
+        {"Re.enter.password.", "\uBE44\uBC00\uBC88\uD638  \uB2E4\uC2DC \uC785\uB825: "},
         {"Re.enter.new.password.", "\uC0C8 \uBE44\uBC00\uBC88\uD638 \uB2E4\uC2DC \uC785\uB825: "},
         {"They.don.t.match.Try.again", "\uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC2ED\uC2DC\uC624."},
         {"Enter.prompt.alias.name.", "{0} \uBCC4\uCE6D \uC774\uB984 \uC785\uB825:  "},
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java
index 2f6b6ee..0b976a3 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_pt_BR.java
@@ -336,7 +336,7 @@
         {"New.prompt.", "Nova {0}: "},
         {"Passwords.must.differ", "As senhas devem ser diferentes"},
         {"Re.enter.new.prompt.", "Informe novamente a nova {0}: "},
-        {"Re.enter.passpword.", "Redigite a senha: "},
+        {"Re.enter.password.", "Redigite a senha: "},
         {"Re.enter.new.password.", "Informe novamente a nova senha: "},
         {"They.don.t.match.Try.again", "Elas n\u00E3o correspondem. Tente novamente"},
         {"Enter.prompt.alias.name.", "Informe o nome do alias {0}:  "},
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java
index effa0d6..c6b4a84 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_sv.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -336,7 +336,7 @@
         {"New.prompt.", "Nytt {0}: "},
         {"Passwords.must.differ", "L\u00F6senorden m\u00E5ste vara olika"},
         {"Re.enter.new.prompt.", "Ange nytt {0} igen: "},
-        {"Re.enter.passpword.", "Ange l\u00F6senord igen: "},
+        {"Re.enter.password.", "Ange l\u00F6senord igen: "},
         {"Re.enter.new.password.", "Ange det nya l\u00F6senordet igen: "},
         {"They.don.t.match.Try.again", "De matchar inte. F\u00F6rs\u00F6k igen"},
         {"Enter.prompt.alias.name.", "Ange aliasnamn f\u00F6r {0}:  "},
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java
index 99f85df..6ae574e 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_CN.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -336,7 +336,7 @@
         {"New.prompt.", "\u65B0{0}: "},
         {"Passwords.must.differ", "\u53E3\u4EE4\u4E0D\u80FD\u76F8\u540C"},
         {"Re.enter.new.prompt.", "\u91CD\u65B0\u8F93\u5165\u65B0{0}: "},
-        {"Re.enter.passpword.", "\u518D\u6B21\u8F93\u5165\u53E3\u4EE4: "},
+        {"Re.enter.password.", "\u518D\u6B21\u8F93\u5165\u53E3\u4EE4: "},
         {"Re.enter.new.password.", "\u518D\u6B21\u8F93\u5165\u65B0\u53E3\u4EE4: "},
         {"They.don.t.match.Try.again", "\u5B83\u4EEC\u4E0D\u5339\u914D\u3002\u8BF7\u91CD\u8BD5"},
         {"Enter.prompt.alias.name.", "\u8F93\u5165{0}\u522B\u540D:  "},
diff --git a/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java b/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java
index 9f6ec38..1f0bb68 100644
--- a/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java
+++ b/jdk/src/share/classes/sun/security/tools/keytool/Resources_zh_TW.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -336,7 +336,7 @@
         {"New.prompt.", "\u65B0 {0}: "},
         {"Passwords.must.differ", "\u5FC5\u9808\u662F\u4E0D\u540C\u7684\u5BC6\u78BC"},
         {"Re.enter.new.prompt.", "\u91CD\u65B0\u8F38\u5165\u65B0 {0}: "},
-        {"Re.enter.passpword.", "\u91CD\u65B0\u8F38\u5165\u5BC6\u78BC:"},
+        {"Re.enter.password.", "\u91CD\u65B0\u8F38\u5165\u5BC6\u78BC:"},
         {"Re.enter.new.password.", "\u91CD\u65B0\u8F38\u5165\u65B0\u5BC6\u78BC: "},
         {"They.don.t.match.Try.again", "\u5B83\u5011\u4E0D\u76F8\u7B26\u3002\u8ACB\u91CD\u8A66"},
         {"Enter.prompt.alias.name.", "\u8F38\u5165 {0} \u5225\u540D\u540D\u7A31:  "},
diff --git a/jdk/src/share/classes/sun/security/util/Debug.java b/jdk/src/share/classes/sun/security/util/Debug.java
index f4005a4..8dd0c3b 100644
--- a/jdk/src/share/classes/sun/security/util/Debug.java
+++ b/jdk/src/share/classes/sun/security/util/Debug.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -104,7 +104,15 @@
         System.err.println("codebase=<URL>");
         System.err.println("              only dump output if specified codebase");
         System.err.println("              is being checked");
-
+        System.err.println();
+        System.err.println("The following can be used with provider:");
+        System.err.println();
+        System.err.println("engine=<engines>");
+        System.err.println("              only dump output for the specified list");
+        System.err.println("              of JCA engines. Supported values:");
+        System.err.println("              Cipher, KeyAgreement, KeyGenerator,");
+        System.err.println("              KeyPairGenerator, KeyStore, Mac,");
+        System.err.println("              MessageDigest, SecureRandom, Signature.");
         System.err.println();
         System.err.println("Note: Separate multiple options with a comma");
         System.exit(0);
diff --git a/jdk/src/share/classes/sun/text/resources/FormatData.java b/jdk/src/share/classes/sun/text/resources/FormatData.java
index 971177f..bcb328d 100644
--- a/jdk/src/share/classes/sun/text/resources/FormatData.java
+++ b/jdk/src/share/classes/sun/text/resources/FormatData.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -154,18 +154,18 @@
             },
             { "MonthNarrows",
                 new String[] {
-                    "J",
-                    "F",
-                    "M",
-                    "A",
-                    "M",
-                    "J",
-                    "J",
-                    "A",
-                    "S",
-                    "O",
-                    "N",
-                    "D",
+                    "1",
+                    "2",
+                    "3",
+                    "4",
+                    "5",
+                    "6",
+                    "7",
+                    "8",
+                    "9",
+                    "10",
+                    "11",
+                    "12",
                     "",
                 }
             },
diff --git a/jdk/src/share/classes/sun/text/resources/en/FormatData_en.java b/jdk/src/share/classes/sun/text/resources/en/FormatData_en.java
index d51c9f3..85ae55d 100644
--- a/jdk/src/share/classes/sun/text/resources/en/FormatData_en.java
+++ b/jdk/src/share/classes/sun/text/resources/en/FormatData_en.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -53,6 +53,23 @@
         // define this method as follows:
         //    return new Object[][] { };
         return new Object[][] {
+            { "MonthNarrows",
+                new String[] {
+                    "J",
+                    "F",
+                    "M",
+                    "A",
+                    "M",
+                    "J",
+                    "J",
+                    "A",
+                    "S",
+                    "O",
+                    "N",
+                    "D",
+                    "",
+                }
+            },
             { "NumberPatterns",
                 new String[] {
                     "#,##0.###;-#,##0.###", // decimal pattern
diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties
index 05f8b1b..a09ee8b 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties
+++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages_ja.properties
@@ -103,7 +103,7 @@
 HELP_ABOUT_DIALOG_JAVA_VERSION=Java VM\u30D0\u30FC\u30B8\u30E7\u30F3:<br>{0}
 HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=\u30DE\u30B9\u30C8\u30D8\u30C3\u30C9\u56F3\u5F62
 HELP_ABOUT_DIALOG_MASTHEAD_TITLE=JConsole\u306B\u3064\u3044\u3066
-HELP_ABOUT_DIALOG_TITLE=JConsole: \u8A73\u7D30
+HELP_ABOUT_DIALOG_TITLE=JConsole: \u60C5\u5831
 HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://docs.oracle.com/javase/{0}/docs/technotes/guides/management/jconsole.html
 HELP_MENU_ABOUT_TITLE=JConsole\u306B\u3064\u3044\u3066(&A)
 HELP_MENU_USER_GUIDE_TITLE=\u30AA\u30F3\u30E9\u30A4\u30F3\u30FB\u30E6\u30FC\u30B6\u30FC\u30FB\u30AC\u30A4\u30C9(&U)
diff --git a/jdk/src/share/classes/sun/util/locale/BaseLocale.java b/jdk/src/share/classes/sun/util/locale/BaseLocale.java
index 6eee582..e0e9ed0 100644
--- a/jdk/src/share/classes/sun/util/locale/BaseLocale.java
+++ b/jdk/src/share/classes/sun/util/locale/BaseLocale.java
@@ -31,6 +31,7 @@
  */
 
 package sun.util.locale;
+import java.lang.ref.SoftReference;
 
 
 public final class BaseLocale {
@@ -163,11 +164,11 @@
         return h;
     }
 
-    private static final class Key implements Comparable<Key> {
-        private final String lang;
-        private final String scrt;
-        private final String regn;
-        private final String vart;
+    private static final class Key {
+        private final SoftReference<String> lang;
+        private final SoftReference<String> scrt;
+        private final SoftReference<String> regn;
+        private final SoftReference<String> vart;
         private final boolean normalized;
         private final int hash;
 
@@ -179,10 +180,10 @@
             assert language.intern() == language
                    && region.intern() == region;
 
-            lang = language;
-            scrt = "";
-            regn = region;
-            vart = "";
+            lang = new SoftReference(language);
+            scrt = new SoftReference("");
+            regn = new SoftReference(region);
+            vart = new SoftReference("");
             this.normalized = true;
 
             int h = language.hashCode();
@@ -203,40 +204,40 @@
                     String variant, boolean normalized) {
             int h = 0;
             if (language != null) {
-                lang = language;
+                lang = new SoftReference(language);
                 int len = language.length();
                 for (int i = 0; i < len; i++) {
                     h = 31*h + LocaleUtils.toLower(language.charAt(i));
                 }
             } else {
-                lang = "";
+                lang = new SoftReference("");
             }
             if (script != null) {
-                scrt = script;
+                scrt = new SoftReference(script);
                 int len = script.length();
                 for (int i = 0; i < len; i++) {
                     h = 31*h + LocaleUtils.toLower(script.charAt(i));
                 }
             } else {
-                scrt = "";
+                scrt = new SoftReference("");
             }
             if (region != null) {
-                regn = region;
+                regn = new SoftReference(region);
                 int len = region.length();
                 for (int i = 0; i < len; i++) {
                     h = 31*h + LocaleUtils.toLower(region.charAt(i));
                 }
             } else {
-                regn = "";
+                regn = new SoftReference("");
             }
             if (variant != null) {
-                vart = variant;
+                vart = new SoftReference(variant);
                 int len = variant.length();
                 for (int i = 0; i < len; i++) {
                     h = 31*h + variant.charAt(i);
                 }
             } else {
-                vart = "";
+                vart = new SoftReference("");
             }
             hash = h;
             this.normalized = normalized;
@@ -244,28 +245,31 @@
 
         @Override
         public boolean equals(Object obj) {
-            return (this == obj) ||
-                    (obj instanceof Key)
-                    && this.hash == ((Key)obj).hash
-                    && LocaleUtils.caseIgnoreMatch(((Key)obj).lang, this.lang)
-                    && LocaleUtils.caseIgnoreMatch(((Key)obj).scrt, this.scrt)
-                    && LocaleUtils.caseIgnoreMatch(((Key)obj).regn, this.regn)
-                    && ((Key)obj).vart.equals(vart); // variant is case sensitive in JDK!
+            if (this == obj) {
+                return true;
         }
 
-        @Override
-        public int compareTo(Key other) {
-            int res = LocaleUtils.caseIgnoreCompare(this.lang, other.lang);
-            if (res == 0) {
-                res = LocaleUtils.caseIgnoreCompare(this.scrt, other.scrt);
-                if (res == 0) {
-                    res = LocaleUtils.caseIgnoreCompare(this.regn, other.regn);
-                    if (res == 0) {
-                        res = this.vart.compareTo(other.vart);
+            if (obj instanceof Key && this.hash == ((Key)obj).hash) {
+                String tl = this.lang.get();
+                String ol = ((Key)obj).lang.get();
+                if (tl != null && ol != null &&
+                    LocaleUtils.caseIgnoreMatch(ol, tl)) {
+                    String ts = this.scrt.get();
+                    String os = ((Key)obj).scrt.get();
+                    if (ts != null && os != null &&
+                        LocaleUtils.caseIgnoreMatch(os, ts)) {
+                        String tr = this.regn.get();
+                        String or = ((Key)obj).regn.get();
+                        if (tr != null && or != null &&
+                            LocaleUtils.caseIgnoreMatch(or, tr)) {
+                            String tv = this.vart.get();
+                            String ov = ((Key)obj).vart.get();
+                            return (ov != null && ov.equals(tv));
                     }
                 }
             }
-            return res;
+            }
+            return false;
         }
 
         @Override
@@ -278,10 +282,10 @@
                 return key;
             }
 
-            String lang = LocaleUtils.toLowerString(key.lang).intern();
-            String scrt = LocaleUtils.toTitleString(key.scrt).intern();
-            String regn = LocaleUtils.toUpperString(key.regn).intern();
-            String vart = key.vart.intern(); // preserve upper/lower cases
+            String lang = LocaleUtils.toLowerString(key.lang.get()).intern();
+            String scrt = LocaleUtils.toTitleString(key.scrt.get()).intern();
+            String regn = LocaleUtils.toUpperString(key.regn.get()).intern();
+            String vart = key.vart.get().intern(); // preserve upper/lower cases
 
             return new Key(lang, scrt, regn, vart, true);
         }
@@ -294,12 +298,18 @@
 
         @Override
         protected Key normalizeKey(Key key) {
+            assert key.lang.get() != null &&
+                   key.scrt.get() != null &&
+                   key.regn.get() != null &&
+                   key.vart.get() != null;
+
             return Key.normalize(key);
         }
 
         @Override
         protected BaseLocale createObject(Key key) {
-            return new BaseLocale(key.lang, key.scrt, key.regn, key.vart);
+            return new BaseLocale(key.lang.get(), key.scrt.get(),
+                                  key.regn.get(), key.vart.get());
         }
     }
 }
diff --git a/jdk/src/share/classes/sun/util/locale/LocaleObjectCache.java b/jdk/src/share/classes/sun/util/locale/LocaleObjectCache.java
index 88920aa..eae1480 100644
--- a/jdk/src/share/classes/sun/util/locale/LocaleObjectCache.java
+++ b/jdk/src/share/classes/sun/util/locale/LocaleObjectCache.java
@@ -57,8 +57,10 @@
             value = entry.get();
         }
         if (value == null) {
-            key = normalizeKey(key);
             V newVal = createObject(key);
+            // make sure key is normalized *after* the object creation
+            // so that newVal is assured to be created from a valid key.
+            key = normalizeKey(key);
             if (key == null || newVal == null) {
                 // subclass must return non-null key/value object
                 return null;
diff --git a/jdk/src/share/javavm/export/jvm.h b/jdk/src/share/javavm/export/jvm.h
index 396ca68..1aaec31 100644
--- a/jdk/src/share/javavm/export/jvm.h
+++ b/jdk/src/share/javavm/export/jvm.h
@@ -386,6 +386,19 @@
 JVM_FindClassFromBootLoader(JNIEnv *env, const char *name);
 
 /*
+ * Find a class from a given class loader.  Throws ClassNotFoundException.
+ *  name:   name of class
+ *  init:   whether initialization is done
+ *  loader: class loader to look up the class. This may not be the same as the caller's
+ *          class loader.
+ *  caller: initiating class. The initiating class may be null when a security
+ *          manager is not installed.
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindClassFromCaller(JNIEnv *env, const char *name, jboolean init,
+                        jobject loader, jclass caller);
+
+/*
  * Find a class from a given class loader. Throw ClassNotFoundException
  * or NoClassDefFoundError depending on the value of the last
  * argument.
diff --git a/jdk/src/share/native/java/lang/Class.c b/jdk/src/share/native/java/lang/Class.c
index c5e717f..b80b717 100644
--- a/jdk/src/share/native/java/lang/Class.c
+++ b/jdk/src/share/native/java/lang/Class.c
@@ -94,7 +94,7 @@
 
 JNIEXPORT jclass JNICALL
 Java_java_lang_Class_forName0(JNIEnv *env, jclass this, jstring classname,
-                              jboolean initialize, jobject loader)
+                              jboolean initialize, jobject loader, jclass caller)
 {
     char *clname;
     jclass cls = 0;
@@ -132,8 +132,7 @@
         goto done;
     }
 
-    cls = JVM_FindClassFromClassLoader(env, clname, initialize,
-                                       loader, JNI_FALSE);
+    cls = JVM_FindClassFromCaller(env, clname, initialize, loader, caller);
 
  done:
     if (clname != buf) {
diff --git a/jdk/src/share/native/java/util/zip/CRC32.c b/jdk/src/share/native/java/util/zip/CRC32.c
index e9185b5..b03b2b9 100644
--- a/jdk/src/share/native/java/util/zip/CRC32.c
+++ b/jdk/src/share/native/java/util/zip/CRC32.c
@@ -54,7 +54,8 @@
     return crc;
 }
 
-JNIEXPORT jint ZIP_CRC32(jint crc, const jbyte *buf, jint len)
+JNIEXPORT jint JNICALL
+ZIP_CRC32(jint crc, const jbyte *buf, jint len)
 {
     return crc32(crc, (Bytef*)buf, len);
 }
diff --git a/jdk/src/share/native/java/util/zip/ZipFile.c b/jdk/src/share/native/java/util/zip/ZipFile.c
index e2916c2..7b34f66 100644
--- a/jdk/src/share/native/java/util/zip/ZipFile.c
+++ b/jdk/src/share/native/java/util/zip/ZipFile.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -172,11 +172,7 @@
     }
     (*env)->GetByteArrayRegion(env, name, 0, ulen, (jbyte *)path);
     path[ulen] = '\0';
-    if (addSlash == JNI_FALSE) {
-        ze = ZIP_GetEntry(zip, path, 0);
-    } else {
-        ze = ZIP_GetEntry(zip, path, (jint)ulen);
-    }
+    ze = ZIP_GetEntry2(zip, path, (jint)ulen, addSlash);
     if (path != buf) {
         free(path);
     }
@@ -269,7 +265,7 @@
     switch (type) {
     case java_util_zip_ZipFile_JZENTRY_NAME:
         if (ze->name != 0) {
-            len = (int)strlen(ze->name);
+            len = (int)ze->nlen;
             if (len == 0 || (jba = (*env)->NewByteArray(env, len)) == NULL)
                 break;
             (*env)->SetByteArrayRegion(env, jba, 0, len, (jbyte *)ze->name);
diff --git a/jdk/src/share/native/java/util/zip/zip_util.c b/jdk/src/share/native/java/util/zip/zip_util.c
index a072e66..b172cde 100644
--- a/jdk/src/share/native/java/util/zip/zip_util.c
+++ b/jdk/src/share/native/java/util/zip/zip_util.c
@@ -1021,6 +1021,7 @@
     if ((ze->name = malloc(nlen + 1)) == NULL) goto Catch;
     memcpy(ze->name, cen + CENHDR, nlen);
     ze->name[nlen] = '\0';
+    ze->nlen = nlen;
     if (elen > 0) {
         char *extra = cen + CENHDR + nlen;
 
@@ -1118,7 +1119,34 @@
 jzentry *
 ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
 {
-    unsigned int hsh = hash(name);
+    if (ulen == 0) {
+        return ZIP_GetEntry2(zip, name, strlen(name), JNI_FALSE);
+    }
+    return ZIP_GetEntry2(zip, name, ulen, JNI_TRUE);
+}
+
+jboolean equals(char* name1, int len1, char* name2, int len2) {
+    if (len1 != len2) {
+        return JNI_FALSE;
+    }
+    while (len1-- > 0) {
+        if (*name1++ != *name2++) {
+            return JNI_FALSE;
+        }
+    }
+    return JNI_TRUE;
+}
+
+/*
+ * Returns the zip entry corresponding to the specified name, or
+ * NULL if not found.
+ * This method supports embedded null character in "name", use ulen
+ * for the length of "name".
+ */
+jzentry *
+ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash)
+{
+    unsigned int hsh = hashN(name, ulen);
     jint idx;
     jzentry *ze = 0;
 
@@ -1139,7 +1167,7 @@
 
         /* Check the cached entry first */
         ze = zip->cache;
-        if (ze && strcmp(ze->name,name) == 0) {
+        if (ze && equals(ze->name, ze->nlen, name, ulen)) {
             /* Cache hit!  Remove and return the cached entry. */
             zip->cache = 0;
             ZIP_Unlock(zip);
@@ -1165,7 +1193,7 @@
                  * we keep searching.
                  */
                 ze = newEntry(zip, zc, ACCESS_RANDOM);
-                if (ze && strcmp(ze->name, name)==0) {
+                if (ze && equals(ze->name, ze->nlen, name, ulen)) {
                     break;
                 }
                 if (ze != 0) {
@@ -1184,8 +1212,8 @@
             break;
         }
 
-        /* If no real length was passed in, we are done */
-        if (ulen == 0) {
+        /* If no need to try appending slash, we are done */
+        if (!addSlash) {
             break;
         }
 
@@ -1195,11 +1223,11 @@
         }
 
         /* Add slash and try once more */
-        name[ulen] = '/';
-        name[ulen+1] = '\0';
+        name[ulen++] = '/';
+        name[ulen] = '\0';
         hsh = hash_append(hsh, '/');
         idx = zip->table[hsh % zip->tablelen];
-        ulen = 0;
+        addSlash = JNI_FALSE;
     }
 
 Finally:
diff --git a/jdk/src/share/native/java/util/zip/zip_util.h b/jdk/src/share/native/java/util/zip/zip_util.h
index a4aaf83..a64668c 100644
--- a/jdk/src/share/native/java/util/zip/zip_util.h
+++ b/jdk/src/share/native/java/util/zip/zip_util.h
@@ -154,6 +154,7 @@
  * - If pos <= 0 then it is the position of entry LOC header.
  *   If pos > 0 then it is the position of entry data.
  *   pos should not be accessed directly, but only by ZIP_GetEntryDataOffset.
+ * - entry name may include embedded null character, use nlen for length
  */
 
 typedef struct jzentry {  /* Zip file entry */
@@ -166,6 +167,7 @@
     jbyte *extra;         /* optional extra data */
     jlong pos;            /* position of LOC header or entry data */
     jint flag;            /* general purpose flag */
+    jint nlen;            /* length of the entry name */
 } jzentry;
 
 /*
@@ -269,5 +271,5 @@
 jint ZIP_Read(jzfile *zip, jzentry *entry, jlong pos, void *buf, jint len);
 void ZIP_FreeEntry(jzfile *zip, jzentry *ze);
 jlong ZIP_GetEntryDataOffset(jzfile *zip, jzentry *entry);
-
+jzentry * ZIP_GetEntry2(jzfile *zip, char *name, jint ulen, jboolean addSlash);
 #endif /* !_ZIP_H_ */
diff --git a/jdk/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp b/jdk/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp
index 3707efd..e985b81 100644
--- a/jdk/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp
+++ b/jdk/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp
@@ -243,12 +243,22 @@
         le_uint16 srSetCount = SWAPW(subRuleSetCount);
 
         if (coverageIndex < srSetCount) {
+            LEReferenceToArrayOf<Offset> subRuleSetTableOffsetArrayRef(base, success,
+                    &subRuleSetTableOffsetArray[coverageIndex], 1);
+            if (LE_FAILURE(success)) {
+                return 0;
+            }
             Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]);
             LEReferenceTo<SubRuleSetTable>
                  subRuleSetTable(base, success, (const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset));
             le_uint16 subRuleCount = SWAPW(subRuleSetTable->subRuleCount);
             le_int32 position = glyphIterator->getCurrStreamPosition();
 
+            LEReferenceToArrayOf<Offset> subRuleTableOffsetArrayRef(base, success,
+                    subRuleSetTable->subRuleTableOffsetArray, subRuleCount);
+            if (LE_FAILURE(success)) {
+                return 0;
+            }
             for (le_uint16 subRule = 0; subRule < subRuleCount; subRule += 1) {
                 Offset subRuleTableOffset =
                     SWAPW(subRuleSetTable->subRuleTableOffsetArray[subRule]);
@@ -301,13 +311,22 @@
                                                                 glyphIterator->getCurrGlyphID(),
                                                                 success);
 
-        if (setClass < scSetCount && subClassSetTableOffsetArray[setClass] != 0) {
+        if (setClass < scSetCount) {
+            LEReferenceToArrayOf<Offset>
+                 subClassSetTableOffsetArrayRef(base, success, subClassSetTableOffsetArray, setClass);
+            if (LE_FAILURE(success)) { return 0; }
+            if (subClassSetTableOffsetArray[setClass] != 0) {
+
             Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]);
             LEReferenceTo<SubClassSetTable>
                  subClassSetTable(base, success, (const SubClassSetTable *) ((char *) this + subClassSetTableOffset));
             le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount);
             le_int32 position = glyphIterator->getCurrStreamPosition();
-
+                LEReferenceToArrayOf<Offset>
+                    subClassRuleTableOffsetArrayRef(base, success, subClassSetTable->subClassRuleTableOffsetArray, subClassRuleCount);
+                if (LE_FAILURE(success)) {
+                    return 0;
+                }
             for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) {
                 Offset subClassRuleTableOffset =
                     SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]);
@@ -331,6 +350,7 @@
                 glyphIterator->setCurrStreamPosition(position);
             }
         }
+        }
 
         // XXX If we get here, the table is mal-formed...
     }
@@ -442,13 +462,22 @@
         le_uint16 srSetCount = SWAPW(chainSubRuleSetCount);
 
         if (coverageIndex < srSetCount) {
+            LEReferenceToArrayOf<Offset>
+                chainSubRuleSetTableOffsetArrayRef(base, success, chainSubRuleSetTableOffsetArray, coverageIndex);
+            if (LE_FAILURE(success)) {
+                return 0;
+            }
             Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]);
             LEReferenceTo<ChainSubRuleSetTable>
                  chainSubRuleSetTable(base, success, (const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset));
             le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount);
             le_int32 position = glyphIterator->getCurrStreamPosition();
             GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
-
+            LEReferenceToArrayOf<Offset>
+                chainSubRuleTableOffsetArrayRef(base, success, chainSubRuleSetTable->chainSubRuleTableOffsetArray, chainSubRuleCount);
+            if (LE_FAILURE(success)) {
+                return 0;
+            }
             for (le_uint16 subRule = 0; subRule < chainSubRuleCount; subRule += 1) {
                 Offset chainSubRuleTableOffset =
                     SWAPW(chainSubRuleSetTable->chainSubRuleTableOffsetArray[subRule]);
@@ -530,6 +559,11 @@
         le_int32 setClass = inputClassDefinitionTable->getGlyphClass(inputClassDefinitionTable,
                                                                      glyphIterator->getCurrGlyphID(),
                                                                      success);
+        LEReferenceToArrayOf<Offset>
+            chainSubClassSetTableOffsetArrayRef(base, success, chainSubClassSetTableOffsetArray, setClass);
+        if (LE_FAILURE(success)) {
+            return 0;
+        }
 
         if (setClass < scSetCount && chainSubClassSetTableOffsetArray[setClass] != 0) {
             Offset chainSubClassSetTableOffset = SWAPW(chainSubClassSetTableOffsetArray[setClass]);
@@ -538,7 +572,11 @@
             le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount);
             le_int32 position = glyphIterator->getCurrStreamPosition();
             GlyphIterator tempIterator(*glyphIterator, emptyFeatureList);
-
+            LEReferenceToArrayOf<Offset>
+                chainSubClassRuleTableOffsetArrayRef(base, success, chainSubClassSetTable->chainSubClassRuleTableOffsetArray, chainSubClassRuleCount);
+            if (LE_FAILURE(success)) {
+                return 0;
+            }
             for (le_uint16 scRule = 0; scRule < chainSubClassRuleCount; scRule += 1) {
                 Offset chainSubClassRuleTableOffset =
                     SWAPW(chainSubClassSetTable->chainSubClassRuleTableOffsetArray[scRule]);
@@ -603,12 +641,14 @@
     }
 
     le_uint16 backtrkGlyphCount = SWAPW(backtrackGlyphCount);
+    LEReferenceToArrayOf<Offset> backtrackGlyphArrayRef(base, success, backtrackCoverageTableOffsetArray, backtrkGlyphCount);
+    if (LE_FAILURE(success)) {
+        return 0;
+    }
     le_uint16 inputGlyphCount = (le_uint16) SWAPW(backtrackCoverageTableOffsetArray[backtrkGlyphCount]);
     LEReferenceToArrayOf<Offset>   inputCoverageTableOffsetArray(base, success, &backtrackCoverageTableOffsetArray[backtrkGlyphCount + 1], inputGlyphCount+2); // offset
     if (LE_FAILURE(success)) { return 0; }
     const le_uint16 lookaheadGlyphCount = (le_uint16) SWAPW(inputCoverageTableOffsetArray[inputGlyphCount]);
-
-    if( LE_FAILURE(success)) { return 0; }
     LEReferenceToArrayOf<Offset>   lookaheadCoverageTableOffsetArray(base, success, inputCoverageTableOffsetArray.getAlias(inputGlyphCount + 1, success), lookaheadGlyphCount+2);
 
     if( LE_FAILURE(success) ) { return 0; }
diff --git a/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp b/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp
index f2612ad..5c07645 100644
--- a/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp
+++ b/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp
@@ -41,7 +41,9 @@
 void ThrowException(JNIEnv *env, const char *exceptionName)
 {
     jclass exceptionClazz = env->FindClass(exceptionName);
-    env->ThrowNew(exceptionClazz, NULL);
+    if (exceptionClazz != NULL) {
+        env->ThrowNew(exceptionClazz, NULL);
+    }
 }
 
 /*
@@ -80,7 +82,6 @@
     return jEncodedBytes;
 }
 
-
 /*
  * Class:     sun_security_ec_ECKeyPairGenerator
  * Method:    generateECKeyPair
@@ -103,6 +104,9 @@
     params_item.len = env->GetArrayLength(encodedParams);
     params_item.data =
         (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
+    if (params_item.data == NULL) {
+        goto cleanup;
+    }
 
     // Fill a new ECParams using the supplied OID
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
@@ -170,6 +174,7 @@
             SECITEM_FreeItem(&privKey->publicValue, B_FALSE);
             free(privKey);
         }
+
         if (pSeedBuffer) {
             delete [] pSeedBuffer;
         }
@@ -206,6 +211,7 @@
     digest_item.len = jDigestLength;
 
     ECPrivateKey privKey;
+    privKey.privateValue.data = NULL;
 
     // Initialize the ECParams struct
     ECParams *ecparams = NULL;
@@ -213,6 +219,9 @@
     params_item.len = env->GetArrayLength(encodedParams);
     params_item.data =
         (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
+    if (params_item.data == NULL) {
+        goto cleanup;
+    }
 
     // Fill a new ECParams using the supplied OID
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
@@ -226,6 +235,9 @@
     privKey.privateValue.len = env->GetArrayLength(privateKey);
     privKey.privateValue.data =
         (unsigned char *) env->GetByteArrayElements(privateKey, 0);
+    if (privKey.privateValue.data == NULL) {
+        goto cleanup;
+    }
 
     // Prepare a buffer for the signature (twice the key length)
     pSignedDigestBuffer = new jbyte[ecparams->order.len * 2];
@@ -245,6 +257,9 @@
 
     // Create new byte array
     temp = env->NewByteArray(signature_item.len);
+    if (temp == NULL) {
+        goto cleanup;
+    }
 
     // Copy data from native buffer
     env->SetByteArrayRegion(temp, 0, signature_item.len, pSignedDigestBuffer);
@@ -317,6 +332,9 @@
     params_item.len = env->GetArrayLength(encodedParams);
     params_item.data =
         (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
+    if (params_item.data == NULL) {
+        goto cleanup;
+    }
 
     // Fill a new ECParams using the supplied OID
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
@@ -369,25 +387,37 @@
   (JNIEnv *env, jclass clazz, jbyteArray privateKey, jbyteArray publicKey, jbyteArray encodedParams)
 {
     jbyteArray jSecret = NULL;
+    ECParams *ecparams = NULL;
+    SECItem privateValue_item;
+    privateValue_item.data = NULL;
+    SECItem publicValue_item;
+    publicValue_item.data = NULL;
+    SECKEYECParams params_item;
+    params_item.data = NULL;
 
     // Extract private key value
-    SECItem privateValue_item;
     privateValue_item.len = env->GetArrayLength(privateKey);
     privateValue_item.data =
             (unsigned char *) env->GetByteArrayElements(privateKey, 0);
+    if (privateValue_item.data == NULL) {
+        goto cleanup;
+    }
 
     // Extract public key value
-    SECItem publicValue_item;
     publicValue_item.len = env->GetArrayLength(publicKey);
     publicValue_item.data =
         (unsigned char *) env->GetByteArrayElements(publicKey, 0);
+    if (publicValue_item.data == NULL) {
+        goto cleanup;
+    }
 
     // Initialize the ECParams struct
-    ECParams *ecparams = NULL;
-    SECKEYECParams params_item;
     params_item.len = env->GetArrayLength(encodedParams);
     params_item.data =
         (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
+    if (params_item.data == NULL) {
+        goto cleanup;
+    }
 
     // Fill a new ECParams using the supplied OID
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
@@ -409,6 +439,9 @@
 
     // Create new byte array
     jSecret = env->NewByteArray(secret_item.len);
+    if (jSecret == NULL) {
+        goto cleanup;
+    }
 
     // Copy bytes from the SECItem buffer to a Java byte array
     env->SetByteArrayRegion(jSecret, 0, secret_item.len,
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XRootWindow.java b/jdk/src/solaris/classes/sun/awt/X11/XRootWindow.java
index 1a35581..6b8b162 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XRootWindow.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XRootWindow.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -46,7 +46,8 @@
     }
 
     private XRootWindow() {
-        super(new XCreateWindowParams(new Object[] {DELAYED, Boolean.TRUE}));
+        super(new XCreateWindowParams(new Object[] { DELAYED, Boolean.TRUE,
+                                                     EVENT_MASK, XConstants.StructureNotifyMask }));
     }
 
     public void postInit(XCreateWindowParams params){
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
index 2a628ec..800be8f 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
@@ -2354,9 +2354,7 @@
 
     private static XEventDispatcher oops_waiter;
     private static boolean oops_updated;
-    private static boolean oops_failed;
-    private XAtom oops;
-    private static final long WORKAROUND_SLEEP = 100;
+    private static boolean oops_move;
 
     /**
      * @inheritDoc
@@ -2367,52 +2365,33 @@
         if (oops_waiter == null) {
             oops_waiter = new XEventDispatcher() {
                     public void dispatchEvent(XEvent e) {
-                        if (e.get_type() == XConstants.SelectionNotify) {
-                            XSelectionEvent pe = e.get_xselection();
-                            if (pe.get_property() == oops.getAtom()) {
-                                oops_updated = true;
-                                awtLockNotifyAll();
-                            } else if (pe.get_selection() == XAtom.get("WM_S0").getAtom() &&
-                                       pe.get_target() == XAtom.get("VERSION").getAtom() &&
-                                       pe.get_property() == 0 &&
-                                       XlibWrapper.XGetSelectionOwner(getDisplay(), XAtom.get("WM_S0").getAtom()) == 0)
-                            {
-                                // WM forgot to acquire selection  or there is no WM
-                                oops_failed = true;
-                                awtLockNotifyAll();
-                            }
-
+                        if (e.get_type() == XConstants.ConfigureNotify) {
+                            // OOPS ConfigureNotify event catched
+                            oops_updated = true;
+                            awtLockNotifyAll();
                         }
                     }
                 };
         }
 
-        if (oops == null) {
-            oops = XAtom.get("OOPS");
-        }
-
         awtLock();
         try {
             addEventDispatcher(win.getWindow(), oops_waiter);
 
             oops_updated = false;
-            oops_failed = false;
-            // Wait for selection notify for oops on win
             long event_number = getEventNumber();
-            XAtom atom = XAtom.get("WM_S0");
-            if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {
-                eventLog.finer("WM_S0 selection owner {0}", XlibWrapper.XGetSelectionOwner(getDisplay(), atom.getAtom()));
-            }
-            XlibWrapper.XConvertSelection(getDisplay(), atom.getAtom(),
-                                          XAtom.get("VERSION").getAtom(), oops.getAtom(),
-                                          win.getWindow(), XConstants.CurrentTime);
+            // Generate OOPS ConfigureNotify event
+            XlibWrapper.XMoveWindow(getDisplay(), win.getWindow(), oops_move ? 0 : 1, 0);
+            // Change win position each time to avoid system optimization
+            oops_move = !oops_move;
             XSync();
 
-            eventLog.finer("Requested OOPS");
+            eventLog.finer("Generated OOPS ConfigureNotify event");
 
             long start = System.currentTimeMillis();
-            while (!oops_updated && !oops_failed) {
+            while (!oops_updated) {
                 try {
+                    // Wait for OOPS ConfigureNotify event
                     awtLockWait(timeout);
                 } catch (InterruptedException e) {
                     throw new RuntimeException(e);
@@ -2423,20 +2402,8 @@
                     throw new OperationTimedOut(Long.toString(System.currentTimeMillis() - start));
                 }
             }
-            if (oops_failed && getEventNumber() - event_number == 1) {
-                // If selection update failed we can simply wait some time
-                // hoping some events will arrive
-                awtUnlock();
-                eventLog.finest("Emergency sleep");
-                try {
-                    Thread.sleep(WORKAROUND_SLEEP);
-                } catch (InterruptedException ie) {
-                    throw new RuntimeException(ie);
-                } finally {
-                    awtLock();
-                }
-            }
-            return getEventNumber() - event_number > 2;
+            // Don't take into account OOPS ConfigureNotify event
+            return getEventNumber() - event_number > 1;
         } finally {
             removeEventDispatcher(win.getWindow(), oops_waiter);
             eventLog.finer("Exiting syncNativeQueue");
diff --git a/jdk/src/solaris/classes/sun/print/CUPSPrinter.java b/jdk/src/solaris/classes/sun/print/CUPSPrinter.java
index c8f9020..1a941d0 100644
--- a/jdk/src/solaris/classes/sun/print/CUPSPrinter.java
+++ b/jdk/src/solaris/classes/sun/print/CUPSPrinter.java
@@ -126,7 +126,7 @@
     /**
      * Returns array of MediaSizeNames derived from PPD.
      */
-    public MediaSizeName[] getMediaSizeNames() {
+    MediaSizeName[] getMediaSizeNames() {
         initMedia();
         return cupsMediaSNames;
     }
@@ -135,7 +135,7 @@
     /**
      * Returns array of Custom MediaSizeNames derived from PPD.
      */
-    public CustomMediaSizeName[] getCustomMediaSizeNames() {
+    CustomMediaSizeName[] getCustomMediaSizeNames() {
         initMedia();
         return cupsCustomMediaSNames;
     }
@@ -147,7 +147,7 @@
     /**
      * Returns array of MediaPrintableArea derived from PPD.
      */
-    public MediaPrintableArea[] getMediaPrintableArea() {
+    MediaPrintableArea[] getMediaPrintableArea() {
         initMedia();
         return cupsMediaPrintables;
     }
@@ -155,7 +155,7 @@
     /**
      * Returns array of MediaTrays derived from PPD.
      */
-    public MediaTray[] getMediaTrays() {
+    MediaTray[] getMediaTrays() {
         initMedia();
         return cupsMediaTrays;
     }
diff --git a/jdk/src/solaris/classes/sun/print/IPPPrintService.java b/jdk/src/solaris/classes/sun/print/IPPPrintService.java
index 1be02c9..a355b17 100644
--- a/jdk/src/solaris/classes/sun/print/IPPPrintService.java
+++ b/jdk/src/solaris/classes/sun/print/IPPPrintService.java
@@ -994,7 +994,9 @@
 
     public synchronized Class[] getSupportedAttributeCategories() {
         if (supportedCats != null) {
-            return supportedCats;
+            Class<?> [] copyCats = new Class<?>[supportedCats.length];
+            System.arraycopy(supportedCats, 0, copyCats, 0, copyCats.length);
+            return copyCats;
         }
 
         initAttributes();
@@ -1051,7 +1053,9 @@
         }
         supportedCats = new Class[catList.size()];
         catList.toArray(supportedCats);
-        return supportedCats;
+        Class<?>[] copyCats = new Class<?>[supportedCats.length];
+        System.arraycopy(supportedCats, 0, copyCats, 0, copyCats.length);
+        return copyCats;
     }
 
 
diff --git a/jdk/src/solaris/native/java/net/AbstractPlainDatagramSocketImpl.c b/jdk/src/solaris/native/java/net/AbstractPlainDatagramSocketImpl.c
new file mode 100644
index 0000000..075fffc
--- /dev/null
+++ b/jdk/src/solaris/native/java/net/AbstractPlainDatagramSocketImpl.c
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#ifdef __solaris__
+#include <unistd.h>
+#include <stropts.h>
+
+#ifndef BSD_COMP
+#define BSD_COMP
+#endif
+
+#endif
+
+#include <sys/ioctl.h>
+
+#include "jvm.h"
+#include "jni_util.h"
+#include "net_util.h"
+
+#include "java_net_AbstractPlainDatagramSocketImpl.h"
+
+static jfieldID IO_fd_fdID;
+
+static jfieldID apdsi_fdID;
+
+
+/*
+ * Class:     java_net_AbstractPlainDatagramSocketImpl
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_AbstractPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) {
+
+    apdsi_fdID = (*env)->GetFieldID(env, cls, "fd",
+                                   "Ljava/io/FileDescriptor;");
+    CHECK_NULL(apdsi_fdID);
+
+    IO_fd_fdID = NET_GetFileDescriptorID(env);
+}
+
+/*
+ * Class:     java_net_AbstractPlainDatagramSocketImpl
+ * Method:    dataAvailable
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable
+(JNIEnv *env, jobject this) {
+    int fd, retval;
+
+    jobject fdObj = (*env)->GetObjectField(env, this, apdsi_fdID);
+
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                        "Socket closed");
+        return -1;
+    }
+    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+
+    if (ioctl(fd, FIONREAD, &retval) < 0) {
+        return -1;
+    }
+    return retval;
+}
diff --git a/jdk/src/solaris/native/sun/awt/awt_util.h b/jdk/src/solaris/native/sun/awt/awt_util.h
index dd0be22..8708905 100644
--- a/jdk/src/solaris/native/sun/awt/awt_util.h
+++ b/jdk/src/solaris/native/sun/awt/awt_util.h
@@ -52,6 +52,8 @@
  */
 extern XErrorHandler current_native_xerror_handler;
 
+Window get_xawt_root_shell(JNIEnv *env);
+
 #endif /* !HEADLESS */
 
 #ifndef INTERSECTS
diff --git a/jdk/src/solaris/native/sun/xawt/XlibWrapper.c b/jdk/src/solaris/native/sun/xawt/XlibWrapper.c
index 60298f7..f1d6318 100644
--- a/jdk/src/solaris/native/sun/xawt/XlibWrapper.c
+++ b/jdk/src/solaris/native/sun/xawt/XlibWrapper.c
@@ -2011,10 +2011,14 @@
  * Toolkit thread to process PropertyNotify or SelectionNotify events.
  */
 static Bool
-secondary_loop_event(Display* dpy, XEvent* event, char* arg) {
-    return (event->type == SelectionNotify ||
-            event->type == SelectionClear  ||
-            event->type == PropertyNotify) ? True : False;
+secondary_loop_event(Display* dpy, XEvent* event, XPointer xawt_root_window) {
+    return (
+                event->type == SelectionNotify ||
+                event->type == SelectionClear  ||
+                event->type == PropertyNotify  ||
+                (event->type == ConfigureNotify
+                    && event->xany.window == *(Window*) xawt_root_window)
+            ) ? True : False;
 }
 
 
@@ -2025,8 +2029,11 @@
 
     AWT_CHECK_HAVE_LOCK_RETURN(JNI_FALSE);
     exitSecondaryLoop = False;
+    Window xawt_root_window = get_xawt_root_shell(env);
+
     while (!exitSecondaryLoop) {
-        if (XCheckIfEvent((Display*) jlong_to_ptr(display), (XEvent*) jlong_to_ptr(ptr), secondary_loop_event, NULL)) {
+        if (XCheckIfEvent((Display*) jlong_to_ptr(display),
+                (XEvent*) jlong_to_ptr(ptr), secondary_loop_event, (XPointer) &xawt_root_window)) {
             return JNI_TRUE;
         }
         timeout = (timeout < AWT_SECONDARY_LOOP_TIMEOUT) ? (timeout << 1) : AWT_SECONDARY_LOOP_TIMEOUT;
diff --git a/jdk/src/windows/native/java/net/AbstractPlainDatagramSocketImpl.c b/jdk/src/windows/native/java/net/AbstractPlainDatagramSocketImpl.c
new file mode 100644
index 0000000..dd2c7e8
--- /dev/null
+++ b/jdk/src/windows/native/java/net/AbstractPlainDatagramSocketImpl.c
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+#include <windows.h>
+#include <winsock2.h>
+
+#include "jvm.h"
+#include "jni_util.h"
+#include "net_util.h"
+
+#include "java_net_AbstractPlainDatagramSocketImpl.h"
+
+static jfieldID IO_fd_fdID = NULL;
+static jfieldID apdsi_fdID = NULL;
+
+static jfieldID apdsi_fd1ID = NULL;
+static jclass two_stacks_clazz = NULL;
+
+
+/*
+ * Class:     java_net_AbstractPlainDatagramSocketImpl
+ * Method:    init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_java_net_AbstractPlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) {
+
+    apdsi_fdID = (*env)->GetFieldID(env, cls, "fd",
+                                   "Ljava/io/FileDescriptor;");
+    CHECK_NULL(apdsi_fdID);
+    IO_fd_fdID = NET_GetFileDescriptorID(env);
+    CHECK_NULL(IO_fd_fdID);
+
+    two_stacks_clazz = (*env)->FindClass(env, "java/net/TwoStacksPlainDatagramSocketImpl");
+    CHECK_NULL(two_stacks_clazz);
+
+    /* Handle both TwoStacks and DualStack here */
+
+    if (JNU_Equals(env, cls, two_stacks_clazz)) {
+        /* fd1 present only in TwoStack.. */
+        apdsi_fd1ID = (*env)->GetFieldID(env, cls, "fd1",
+                                   "Ljava/io/FileDescriptor;");
+        CHECK_NULL(apdsi_fd1ID);
+    }
+
+    JNU_CHECK_EXCEPTION(env);
+}
+
+/*
+ * Class:     java_net_AbstractPlainDatagramSocketImpl
+ * Method:    dataAvailable
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_java_net_AbstractPlainDatagramSocketImpl_dataAvailable
+(JNIEnv *env, jobject this) {
+    SOCKET fd;
+    SOCKET fd1;
+    int  rv = -1, rv1 = -1;
+    jobject fdObj = (*env)->GetObjectField(env, this, apdsi_fdID);
+
+    if (!IS_NULL(fdObj)) {
+        int retval = 0;
+        fd = (SOCKET)(*env)->GetIntField(env, fdObj, IO_fd_fdID);
+        rv = ioctlsocket(fd, FIONREAD, &retval);
+        if (retval > 0) {
+            return retval;
+        }
+    }
+
+    if (!IS_NULL(apdsi_fd1ID)) {
+        /* TwoStacks */
+        jobject fd1Obj = (*env)->GetObjectField(env, this, apdsi_fd1ID);
+        if (!IS_NULL(fd1Obj)) {
+            int retval = 0;
+            fd1 = (SOCKET)(*env)->GetIntField(env, fd1Obj, IO_fd_fdID);
+            rv1 = ioctlsocket(fd1, FIONREAD, &retval);
+            if (retval > 0) {
+                return retval;
+            }
+        }
+    }
+
+    if (rv < 0 && rv1 < 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                            "Socket closed");
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/jdk/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c b/jdk/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c
index ddbc006..8e02c18 100644
--- a/jdk/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c
+++ b/jdk/src/windows/native/sun/awt/splashscreen/splashscreen_sys.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -213,6 +213,14 @@
 void
 SplashRedrawWindow(Splash * splash)
 {
+    if (!SplashIsStillLooping(splash)) {
+        KillTimer(splash->hWnd, 0);
+    }
+
+    if (splash->currentFrame < 0) {
+        return;
+    }
+
     SplashUpdateScreenData(splash);
     if (splash->isLayered) {
         BLENDFUNCTION bf;
@@ -303,9 +311,6 @@
             time = 0;
         SetTimer(splash->hWnd, 0, time, NULL);
     }
-    else {
-        KillTimer(splash->hWnd, 0);
-    }
 }
 
 void SplashReconfigureNow(Splash * splash) {
diff --git a/jdk/src/windows/native/sun/java2d/windows/GDIRenderer.cpp b/jdk/src/windows/native/sun/java2d/windows/GDIRenderer.cpp
index 643d64d..36991f4 100644
--- a/jdk/src/windows/native/sun/java2d/windows/GDIRenderer.cpp
+++ b/jdk/src/windows/native/sun/java2d/windows/GDIRenderer.cpp
@@ -670,7 +670,7 @@
         if (ypoints != NULL) {
             pPoints = TransformPoly(xpoints, ypoints, transx, transy,
                                 tmpPts, &npoints, FALSE, FALSE);
-            env->ReleasePrimitiveArrayCritical(ypointsarray, xpoints, JNI_ABORT);
+            env->ReleasePrimitiveArrayCritical(ypointsarray, ypoints, JNI_ABORT);
         }
         env->ReleasePrimitiveArrayCritical(xpointsarray, xpoints, JNI_ABORT);
     }
diff --git a/jdk/src/windows/native/sun/security/mscapi/security.cpp b/jdk/src/windows/native/sun/security/mscapi/security.cpp
index 49cbe81..8b5d8ae 100644
--- a/jdk/src/windows/native/sun/security/mscapi/security.cpp
+++ b/jdk/src/windows/native/sun/security/mscapi/security.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -74,7 +74,10 @@
     const char* pszHashAlgorithm = NULL;
     ALG_ID algId = 0;
 
-    pszHashAlgorithm = env->GetStringUTFChars(jHashAlgorithm, NULL);
+    if ((pszHashAlgorithm = env->GetStringUTFChars(jHashAlgorithm, NULL))
+        == NULL) {
+        return algId;
+    }
 
     if ((strcmp("SHA", pszHashAlgorithm) == 0) ||
         (strcmp("SHA1", pszHashAlgorithm) == 0) ||
@@ -179,7 +182,9 @@
          */
         if (length < 0) {
             length = env->GetArrayLength(seed);
-            reseedBytes = env->GetByteArrayElements(seed, 0);
+            if ((reseedBytes = env->GetByteArrayElements(seed, 0)) == NULL) {
+                __leave;
+            }
 
             if (::CryptGenRandom(
                 hCryptProv,
@@ -211,7 +216,9 @@
         } else { // length == 0
 
             length = env->GetArrayLength(seed);
-            seedBytes = env->GetByteArrayElements(seed, 0);
+            if ((seedBytes = env->GetByteArrayElements(seed, 0)) == NULL) {
+                __leave;
+            }
 
             if (::CryptGenRandom(
                 hCryptProv,
@@ -275,7 +282,10 @@
     __try
     {
         // Open a system certificate store.
-        pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL);
+        if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
+            == NULL) {
+            __leave;
+        }
         if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName))
             == NULL) {
 
@@ -710,7 +720,10 @@
 
     __try
     {
-        pszKeyContainerName = env->GetStringUTFChars(keyContainerName, NULL);
+        if ((pszKeyContainerName =
+            env->GetStringUTFChars(keyContainerName, NULL)) == NULL) {
+            __leave;
+        }
 
         // Acquire a CSP context (create a new key container).
         // Prefer a PROV_RSA_AES CSP, when available, due to its support
@@ -847,7 +860,10 @@
     __try
     {
         // Open a system certificate store.
-        pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL);
+        if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
+            == NULL) {
+            __leave;
+        }
         if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
             ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
             __leave;
@@ -1086,7 +1102,10 @@
     __try
     {
         // Open a system certificate store.
-        pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL);
+        if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
+            == NULL) {
+            __leave;
+        }
         if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
             ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
             __leave;
@@ -1123,7 +1142,10 @@
                 cchNameString);
 
             // Compare the certificate's friendly name with supplied alias name
-            pszCertAliasName = env->GetStringUTFChars(jCertAliasName, NULL);
+            if ((pszCertAliasName = env->GetStringUTFChars(jCertAliasName, NULL))
+                == NULL) {
+                __leave;
+            }
             if (strcmp(pszCertAliasName, pszNameString) == 0) {
 
                 // Only delete the certificate if the alias names matches
@@ -1181,7 +1203,10 @@
 
     __try
     {
-        pszKeyContainerName = env->GetStringUTFChars(keyContainerName, NULL);
+        if ((pszKeyContainerName =
+            env->GetStringUTFChars(keyContainerName, NULL)) == NULL) {
+            __leave;
+        }
 
         // Destroying the default key container is not permitted
         // (because it may contain more one keypair).
@@ -1234,8 +1259,14 @@
 
     __try
     {
-        pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL);
-        pszCertAliasName = env->GetStringUTFChars(jCertAliasName, NULL);
+        if ((pszCertStoreName = env->GetStringUTFChars(jCertStoreName, NULL))
+            == NULL) {
+            __leave;
+        }
+        if ((pszCertAliasName = env->GetStringUTFChars(jCertAliasName, NULL))
+            == NULL) {
+            __leave;
+        }
 
         // Open a system certificate store.
         if ((hCertStore = ::CertOpenSystemStore(NULL, pszCertStoreName)) == NULL) {
@@ -1530,7 +1561,9 @@
     __try {
 
         jsize length = env->GetArrayLength(jKeyBlob);
-        keyBlob = env->GetByteArrayElements(jKeyBlob, 0);
+        if ((keyBlob = env->GetByteArrayElements(jKeyBlob, 0)) == NULL) {
+            __leave;
+        }
 
         PUBLICKEYSTRUC* pPublicKeyStruc = (PUBLICKEYSTRUC *) keyBlob;
 
@@ -1580,7 +1613,9 @@
     __try {
 
         jsize length = env->GetArrayLength(jKeyBlob);
-        keyBlob = env->GetByteArrayElements(jKeyBlob, 0);
+        if ((keyBlob = env->GetByteArrayElements(jKeyBlob, 0)) == NULL) {
+            __leave;
+        }
 
         PUBLICKEYSTRUC* pPublicKeyStruc = (PUBLICKEYSTRUC *) keyBlob;
 
@@ -1632,6 +1667,9 @@
     }
 
     jbyte* sourceBytes = env->GetByteArrayElements(source, 0);
+    if (sourceBytes == NULL) {
+        return -1;
+    }
 
     // Copy bytes from the end of the source array to the beginning of the
     // destination array (until the destination array is full).
@@ -1740,45 +1778,61 @@
         }
         // The length argument must be the smaller of jPublicExponentLength
         // and sizeof(pRsaPubKey->pubkey)
-        convertToLittleEndian(env, jPublicExponent,
-            (jbyte *) &(pRsaPubKey->pubexp), jPublicExponentLength);
+        if ((jElementLength = convertToLittleEndian(env, jPublicExponent,
+            (jbyte *) &(pRsaPubKey->pubexp), jPublicExponentLength)) < 0) {
+            __leave;
+        }
 
         // Modulus n
         jBlobElement =
             (jbyte *) (jBlobBytes + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY));
-        jElementLength = convertToLittleEndian(env, jModulus, jBlobElement,
-            jKeyByteLength);
+        if ((jElementLength = convertToLittleEndian(env, jModulus, jBlobElement,
+            jKeyByteLength)) < 0) {
+            __leave;
+        }
 
         if (bGeneratePrivateKeyBlob) {
             // Prime p
             jBlobElement += jElementLength;
-            jElementLength = convertToLittleEndian(env, jPrimeP, jBlobElement,
-                jKeyByteLength / 2);
+            if ((jElementLength = convertToLittleEndian(env, jPrimeP,
+                jBlobElement, jKeyByteLength / 2)) < 0) {
+                __leave;
+            }
 
             // Prime q
             jBlobElement += jElementLength;
-            jElementLength = convertToLittleEndian(env, jPrimeQ, jBlobElement,
-                jKeyByteLength / 2);
+            if ((jElementLength = convertToLittleEndian(env, jPrimeQ,
+                jBlobElement, jKeyByteLength / 2)) < 0) {
+                __leave;
+            }
 
             // Prime exponent p
             jBlobElement += jElementLength;
-            jElementLength = convertToLittleEndian(env, jExponentP,
-                jBlobElement, jKeyByteLength / 2);
+            if ((jElementLength = convertToLittleEndian(env, jExponentP,
+                jBlobElement, jKeyByteLength / 2)) < 0) {
+                __leave;
+            }
 
             // Prime exponent q
             jBlobElement += jElementLength;
-            jElementLength = convertToLittleEndian(env, jExponentQ,
-                jBlobElement, jKeyByteLength / 2);
+            if ((jElementLength = convertToLittleEndian(env, jExponentQ,
+                jBlobElement, jKeyByteLength / 2)) < 0) {
+                __leave;
+            }
 
             // CRT coefficient
             jBlobElement += jElementLength;
-            jElementLength = convertToLittleEndian(env, jCrtCoefficient,
-                jBlobElement, jKeyByteLength / 2);
+            if ((jElementLength = convertToLittleEndian(env, jCrtCoefficient,
+                jBlobElement, jKeyByteLength / 2)) < 0) {
+                __leave;
+            }
 
             // Private exponent
             jBlobElement += jElementLength;
-            convertToLittleEndian(env, jPrivateExponent, jBlobElement,
-                jKeyByteLength);
+            if ((jElementLength = convertToLittleEndian(env, jPrivateExponent,
+                jBlobElement, jKeyByteLength)) < 0) {
+                __leave;
+            }
         }
 
         jBlob = env->NewByteArray(jBlobLength);
@@ -1849,9 +1903,15 @@
 
     __try
     {
-        pszKeyContainerName = env->GetStringUTFChars(keyContainerName, NULL);
+        if ((pszKeyContainerName =
+            env->GetStringUTFChars(keyContainerName, NULL)) == NULL) {
+            __leave;
+        }
         dwBlobLen = env->GetArrayLength(keyBlob);
-        pbKeyBlob = (BYTE *) env->GetByteArrayElements(keyBlob, 0);
+        if ((pbKeyBlob = (BYTE *) env->GetByteArrayElements(keyBlob, 0))
+            == NULL) {
+            __leave;
+        }
 
         // Acquire a CSP context (create a new key container).
         if (::CryptAcquireContext(
@@ -1923,7 +1983,10 @@
     __try
     {
         dwBlobLen = env->GetArrayLength(keyBlob);
-        pbKeyBlob = (BYTE *) env->GetByteArrayElements(keyBlob, 0);
+        if ((pbKeyBlob = (BYTE *) env->GetByteArrayElements(keyBlob, 0))
+            == NULL) {
+            __leave;
+        }
 
         // Acquire a CSP context (create a new key container).
         // Prefer a PROV_RSA_AES CSP, when available, due to its support
diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp
index 5bd7bf4..3baae0f 100644
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp
@@ -3955,7 +3955,6 @@
         DASSERT(stringCls);
         CHECK_NULL(stringCls);
         clauseReading = env->NewObjectArray(cClause, stringCls, NULL);
-        env->DeleteLocalRef(stringCls);
         DASSERT(clauseReading);
         CHECK_NULL(clauseReading);
         for (int i=0; i<cClause; i++)   env->SetObjectArrayElement(clauseReading, i, rgClauseReading[i]);
diff --git a/jdk/src/windows/native/sun/windows/awt_TextArea.cpp b/jdk/src/windows/native/sun/windows/awt_TextArea.cpp
index 938da4c..427a0b8 100644
--- a/jdk/src/windows/native/sun/windows/awt_TextArea.cpp
+++ b/jdk/src/windows/native/sun/windows/awt_TextArea.cpp
@@ -47,16 +47,12 @@
 
 jfieldID AwtTextArea::scrollbarVisibilityID;
 
-WNDPROC AwtTextArea::sm_pDefWindowProc = NULL;
-
 /************************************************************************
  * AwtTextArea methods
  */
 
 AwtTextArea::AwtTextArea() {
-    m_bIgnoreEnChange = FALSE;
     m_bCanUndo        = FALSE;
-    m_hEditCtrl       = NULL;
     m_lHDeltaAccum    = 0;
     m_lVDeltaAccum    = 0;
 }
@@ -67,10 +63,6 @@
 
 void AwtTextArea::Dispose()
 {
-    if (m_hEditCtrl != NULL) {
-        VERIFY(::DestroyWindow(m_hEditCtrl));
-        m_hEditCtrl = NULL;
-    }
     AwtTextComponent::Dispose();
 }
 
@@ -91,10 +83,6 @@
     }
 }
 
-void AwtTextArea::EditGetSel(CHARRANGE &cr) {
-    SendMessage(EM_EXGETSEL, 0, reinterpret_cast<LPARAM>(&cr));
-}
-
 /* Count how many '\n's are there in jStr */
 size_t AwtTextArea::CountNewLines(JNIEnv *env, jstring jStr, size_t maxlen)
 {
@@ -149,159 +137,6 @@
     return retValue;
 }
 
-/*
- * This routine is a window procedure for the subclass of the standard edit control
- * used to generate context menu. RichEdit controls don't have built-in context menu.
- * To implement this functionality we have to create an invisible edit control and
- * forward WM_CONTEXTMENU messages from a RichEdit control to this helper edit control.
- * While the edit control context menu is active we intercept the message generated in
- * response to particular item selection and forward it back to the RichEdit control.
- * (See AwtTextArea::WmContextMenu for more details).
- */
-LRESULT
-AwtTextArea::EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
-
-    static BOOL bContextMenuActive = FALSE;
-
-    LRESULT retValue = 0;
-    MsgRouting mr = mrDoDefault;
-
-    DASSERT(::IsWindow(::GetParent(hWnd)));
-
-    switch (message) {
-    case WM_UNDO:
-    case WM_CUT:
-    case WM_COPY:
-    case WM_PASTE:
-    case WM_CLEAR:
-    case EM_SETSEL:
-        if (bContextMenuActive) {
-            ::SendMessage(::GetParent(hWnd), message, wParam, lParam);
-            mr = mrConsume;
-        }
-        break;
-    case WM_CONTEXTMENU:
-        bContextMenuActive = TRUE;
-        break;
-    }
-
-    if (mr == mrDoDefault) {
-        DASSERT(sm_pDefWindowProc != NULL);
-        retValue = ::CallWindowProc(sm_pDefWindowProc,
-                                    hWnd, message, wParam, lParam);
-    }
-
-    if (message == WM_CONTEXTMENU) {
-        bContextMenuActive = FALSE;
-    }
-
-    return retValue;
-}
-
-MsgRouting
-AwtTextArea::WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos) {
-    /* Use the system provided edit control class to generate context menu. */
-    if (m_hEditCtrl == NULL) {
-        DWORD dwStyle = WS_CHILD;
-        DWORD dwExStyle = 0;
-        m_hEditCtrl = ::CreateWindowEx(dwExStyle,
-                                        L"EDIT",
-                                        L"TEXT",
-                                        dwStyle,
-                                        0, 0, 0, 0,
-                                        GetHWnd(),
-                                        reinterpret_cast<HMENU>(
-                                         static_cast<INT_PTR>(
-                                             CreateControlID())),
-                                        AwtToolkit::GetInstance().GetModuleHandle(),
-                                        NULL);
-        DASSERT(m_hEditCtrl != NULL);
-        if (sm_pDefWindowProc == NULL) {
-            sm_pDefWindowProc = (WNDPROC)::GetWindowLongPtr(m_hEditCtrl,
-                                                         GWLP_WNDPROC);
-        }
-        ::SetLastError(0);
-        INT_PTR ret = ::SetWindowLongPtr(m_hEditCtrl, GWLP_WNDPROC,
-                                   (INT_PTR)AwtTextArea::EditProc);
-        DASSERT(ret != 0 || ::GetLastError() == 0);
-    }
-
-    /*
-     * Tricks on the edit control to ensure that its context menu has
-     * the correct set of enabled items according to the RichEdit state.
-     */
-    ::SetWindowText(m_hEditCtrl, TEXT("TEXT"));
-
-    if (m_bCanUndo == TRUE && SendMessage(EM_CANUNDO)) {
-        /* Enable 'Undo' item. */
-        ::SendMessage(m_hEditCtrl, WM_CHAR, 'A', 0);
-    }
-
-    {
-        /*
-         * Initial selection for the edit control - (0,1).
-         * This enables 'Cut', 'Copy' and 'Delete' and 'Select All'.
-         */
-        INT nStart = 0;
-        INT nEnd = 1;
-        if (SendMessage(EM_SELECTIONTYPE) == SEL_EMPTY) {
-            /*
-             * RichEdit selection is empty - clear selection of the edit control.
-             * This disables 'Cut', 'Copy' and 'Delete'.
-             */
-            nStart = -1;
-            nEnd = 0;
-        } else {
-
-            CHARRANGE cr;
-            EditGetSel(cr);
-            /* Check if all the text is selected. */
-            if (cr.cpMin == 0) {
-
-                int len = ::GetWindowTextLength(GetHWnd());
-                if (cr.cpMin == 0 && cr.cpMax >= len) {
-                    /*
-                     * All the text is selected in RichEdit - select all the
-                     * text in the edit control. This disables 'Select All'.
-                     */
-                    nStart = 0;
-                    nEnd = -1;
-                }
-            }
-        }
-        ::SendMessage(m_hEditCtrl, EM_SETSEL, (WPARAM)nStart, (LPARAM)nEnd);
-    }
-
-    /* Disable 'Paste' item if the RichEdit control is read-only. */
-    ::SendMessage(m_hEditCtrl, EM_SETREADONLY,
-                  GetStyle() & ES_READONLY ? TRUE : FALSE, 0);
-
-    POINT p;
-    p.x = xPos;
-    p.y = yPos;
-
-    /*
-     * If the context menu is requested with SHIFT+F10 or VK_APPS key,
-     * we position its top left corner to the center of the RichEdit
-     * client rect.
-     */
-    if (p.x == -1 && p.y == -1) {
-        RECT r;
-        VERIFY(::GetClientRect(GetHWnd(), &r));
-        p.x = (r.left + r.right) / 2;
-        p.y = (r.top + r.bottom) / 2;
-        VERIFY(::ClientToScreen(GetHWnd(), &p));
-    }
-
-    // The context menu steals focus from the proxy.
-    // So, set the focus-restore flag up.
-    SetRestoreFocus(TRUE);
-    ::SendMessage(m_hEditCtrl, WM_CONTEXTMENU, (WPARAM)m_hEditCtrl, MAKELPARAM(p.x, p.y));
-    SetRestoreFocus(FALSE);
-
-    return mrConsume;
-}
-
 MsgRouting
 AwtTextArea::WmNcHitTest(UINT x, UINT y, LRESULT& retVal)
 {
@@ -314,27 +149,8 @@
 
 
 MsgRouting
-AwtTextArea::WmNotify(UINT notifyCode)
-{
-    if (notifyCode == EN_CHANGE) {
-        /*
-         * Ignore notifications if the text hasn't been changed.
-         * EN_CHANGE sent on character formatting changes as well.
-         */
-        if (m_bIgnoreEnChange == FALSE) {
-            m_bCanUndo = TRUE;
-            DoCallback("valueChanged", "()V");
-        } else {
-            m_bCanUndo = FALSE;
-        }
-    }
-    return mrDoDefault;
-}
-
-MsgRouting
 AwtTextArea::HandleEvent(MSG *msg, BOOL synthetic)
 {
-    MsgRouting returnVal;
     /*
      * RichEdit 1.0 control starts internal message loop if the
      * left mouse button is pressed while the cursor is not over
@@ -486,26 +302,6 @@
         }
         delete msg;
         return mrConsume;
-    } else if (msg->message == WM_RBUTTONUP ||
-               (msg->message == WM_SYSKEYDOWN && msg->wParam == VK_F10 &&
-                HIBYTE(::GetKeyState(VK_SHIFT)))) {
-        POINT p;
-        if (msg->message == WM_RBUTTONUP) {
-            VERIFY(::GetCursorPos(&p));
-        } else {
-            p.x = -1;
-            p.y = -1;
-        }
-
-        if (!::PostMessage(GetHWnd(), WM_CONTEXTMENU, (WPARAM)GetHWnd(),
-                           MAKELPARAM(p.x, p.y))) {
-            JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
-            JNU_ThrowInternalError(env, "Message not posted, native event queue may be full.");
-            env->ExceptionDescribe();
-            env->ExceptionClear();
-        }
-        delete msg;
-        return mrConsume;
     } else if (msg->message == WM_MOUSEWHEEL) {
         // 4417236: If there is an old version of RichEd32.dll which
         // does not provide the mouse wheel scrolling we have to
@@ -596,15 +392,7 @@
         // 4417236: end of fix
     }
 
-    /*
-     * Store the 'synthetic' parameter so that the WM_PASTE security check
-     * happens only for synthetic events.
-     */
-    m_synthetic = synthetic;
-    returnVal = AwtComponent::HandleEvent(msg, synthetic);
-    m_synthetic = FALSE;
-
-    return returnVal;
+    return AwtTextComponent::HandleEvent(msg, synthetic);
 }
 
 
diff --git a/jdk/src/windows/native/sun/windows/awt_TextArea.h b/jdk/src/windows/native/sun/windows/awt_TextArea.h
index 931a319..1738e64 100644
--- a/jdk/src/windows/native/sun/windows/awt_TextArea.h
+++ b/jdk/src/windows/native/sun/windows/awt_TextArea.h
@@ -57,17 +57,11 @@
     static size_t GetALength(JNIEnv* env, jstring jStr, size_t maxlen);
 
     LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
-    static LRESULT CALLBACK EditProc(HWND hWnd, UINT message,
-                                     WPARAM wParam, LPARAM lParam);
 
     MsgRouting WmEnable(BOOL fEnabled);
-    MsgRouting WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos);
-    MsgRouting WmNotify(UINT notifyCode);
     MsgRouting WmNcHitTest(UINT x, UINT y, LRESULT &retVal);
     MsgRouting HandleEvent(MSG *msg, BOOL synthetic);
 
-    INLINE void SetIgnoreEnChange(BOOL b) { m_bIgnoreEnChange = b; }
-
     virtual BOOL InheritsNativeMouseWheelBehavior();
     virtual void Reshape(int x, int y, int w, int h);
 
@@ -81,22 +75,7 @@
 protected:
 
     void EditSetSel(CHARRANGE &cr);
-    void EditGetSel(CHARRANGE &cr);
   private:
-    // RichEdit 1.0 control generates EN_CHANGE notifications not only
-    // on text changes, but also on any character formatting change.
-    // This flag is true when the latter case is detected.
-    BOOL    m_bIgnoreEnChange;
-
-    // RichEdit 1.0 control undoes a character formatting change
-    // if it is the latest. We don't create our own undo buffer,
-    // but just prohibit undo in case if the latest operation
-    // is a formatting change.
-    BOOL    m_bCanUndo;
-
-    HWND    m_hEditCtrl;
-    static WNDPROC sm_pDefWindowProc;
-
     LONG    m_lHDeltaAccum;
     LONG    m_lVDeltaAccum;
 
diff --git a/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp b/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp
index d96a194..eaa8bca 100644
--- a/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp
+++ b/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp
@@ -66,6 +66,8 @@
     m_lLastPos  = -1;
     m_isLFonly        = FALSE;
     m_EOLchecked      = FALSE;
+    m_hEditCtrl       = NULL;
+    m_bIgnoreEnChange = FALSE;
 //    javaEventsMask = 0;    // accessibility support
 }
 
@@ -213,6 +215,16 @@
     return c;
 }
 
+void AwtTextComponent::Dispose()
+{
+    if (m_hEditCtrl != NULL) {
+        VERIFY(::DestroyWindow(m_hEditCtrl));
+        m_hEditCtrl = NULL;
+    }
+    AwtComponent::Dispose();
+}
+
+
 LRESULT
 AwtTextComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
 
@@ -322,7 +334,16 @@
 AwtTextComponent::WmNotify(UINT notifyCode)
 {
     if (notifyCode == EN_CHANGE) {
-      DoCallback("valueChanged", "()V");
+        /*
+         * Ignore notifications if the text hasn't been changed.
+         * EN_CHANGE sent on character formatting changes as well.
+         */
+        if (m_bIgnoreEnChange == FALSE) {
+            m_bCanUndo = TRUE;
+            DoCallback("valueChanged", "()V");
+        } else {
+            m_bCanUndo = FALSE;
+        }
     }
     return mrDoDefault;
 }
@@ -337,6 +358,28 @@
 {
     MsgRouting returnVal;
 
+    if (msg->message == WM_RBUTTONUP ||
+               (msg->message == WM_SYSKEYDOWN && msg->wParam == VK_F10 &&
+                HIBYTE(::GetKeyState(VK_SHIFT)))) {
+        POINT p;
+        if (msg->message == WM_RBUTTONUP) {
+            VERIFY(::GetCursorPos(&p));
+        } else {
+            p.x = -1;
+            p.y = -1;
+        }
+
+        if (!::PostMessage(GetHWnd(), WM_CONTEXTMENU, (WPARAM)GetHWnd(),
+                           MAKELPARAM(p.x, p.y))) {
+            JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+            JNU_ThrowInternalError(env, "Message not posted, native event queue may be full.");
+            env->ExceptionDescribe();
+            env->ExceptionClear();
+        }
+        delete msg;
+        return mrConsume;
+    }
+
     /*
      * Store the 'synthetic' parameter so that the WM_PASTE security check
      * happens only for synthetic events.
@@ -701,6 +744,10 @@
     SendMessage(EM_SETBKGNDCOLOR, (WPARAM)FALSE, (LPARAM)GetBackgroundColor());
 }
 
+void AwtTextComponent::EditGetSel(CHARRANGE &cr) {
+    SendMessage(EM_EXGETSEL, 0, reinterpret_cast<LPARAM>(&cr));
+}
+
 
 /************************************************************************
  * WTextComponentPeer native methods
@@ -983,6 +1030,161 @@
 }
 
 
+/*
+ * This routine is a window procedure for the subclass of the standard edit control
+ * used to generate context menu. RichEdit controls don't have built-in context menu.
+ * To implement this functionality we have to create an invisible edit control and
+ * forward WM_CONTEXTMENU messages from a RichEdit control to this helper edit control.
+ * While the edit control context menu is active we intercept the message generated in
+ * response to particular item selection and forward it back to the RichEdit control.
+ * (See AwtTextArea::WmContextMenu for more details).
+ */
+
+WNDPROC AwtTextComponent::sm_pDefWindowProc = NULL;
+
+LRESULT
+AwtTextComponent::EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
+
+    static BOOL bContextMenuActive = FALSE;
+
+    LRESULT retValue = 0;
+    MsgRouting mr = mrDoDefault;
+
+    DASSERT(::IsWindow(::GetParent(hWnd)));
+
+    switch (message) {
+    case WM_UNDO:
+    case WM_CUT:
+    case WM_COPY:
+    case WM_PASTE:
+    case WM_CLEAR:
+    case EM_SETSEL:
+        if (bContextMenuActive) {
+            ::SendMessage(::GetParent(hWnd), message, wParam, lParam);
+            mr = mrConsume;
+        }
+        break;
+    case WM_CONTEXTMENU:
+        bContextMenuActive = TRUE;
+        break;
+    }
+
+    if (mr == mrDoDefault) {
+        DASSERT(sm_pDefWindowProc != NULL);
+        retValue = ::CallWindowProc(sm_pDefWindowProc,
+                                    hWnd, message, wParam, lParam);
+    }
+
+    if (message == WM_CONTEXTMENU) {
+        bContextMenuActive = FALSE;
+    }
+
+    return retValue;
+}
+
+MsgRouting
+AwtTextComponent::WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos) {
+    /* Use the system provided edit control class to generate context menu. */
+    if (m_hEditCtrl == NULL) {
+        DWORD dwStyle = WS_CHILD;
+        DWORD dwExStyle = 0;
+        m_hEditCtrl = ::CreateWindowEx(dwExStyle,
+                                        L"EDIT",
+                                        L"TEXT",
+                                        dwStyle,
+                                        0, 0, 0, 0,
+                                        GetHWnd(),
+                                        reinterpret_cast<HMENU>(
+                                         static_cast<INT_PTR>(
+                                             CreateControlID())),
+                                        AwtToolkit::GetInstance().GetModuleHandle(),
+                                        NULL);
+        DASSERT(m_hEditCtrl != NULL);
+        if (sm_pDefWindowProc == NULL) {
+            sm_pDefWindowProc = (WNDPROC)::GetWindowLongPtr(m_hEditCtrl,
+                                                         GWLP_WNDPROC);
+        }
+        ::SetLastError(0);
+        INT_PTR ret = ::SetWindowLongPtr(m_hEditCtrl, GWLP_WNDPROC,
+                                   (INT_PTR)AwtTextArea::EditProc);
+        DASSERT(ret != 0 || ::GetLastError() == 0);
+    }
+
+    /*
+     * Tricks on the edit control to ensure that its context menu has
+     * the correct set of enabled items according to the RichEdit state.
+     */
+    ::SetWindowText(m_hEditCtrl, TEXT("TEXT"));
+
+    if (m_bCanUndo == TRUE && SendMessage(EM_CANUNDO)) {
+        /* Enable 'Undo' item. */
+        ::SendMessage(m_hEditCtrl, WM_CHAR, 'A', 0);
+    }
+
+    {
+        /*
+         * Initial selection for the edit control - (0,1).
+         * This enables 'Cut', 'Copy' and 'Delete' and 'Select All'.
+         */
+        INT nStart = 0;
+        INT nEnd = 1;
+        if (SendMessage(EM_SELECTIONTYPE) == SEL_EMPTY) {
+            /*
+             * RichEdit selection is empty - clear selection of the edit control.
+             * This disables 'Cut', 'Copy' and 'Delete'.
+             */
+            nStart = -1;
+            nEnd = 0;
+        } else {
+
+            CHARRANGE cr;
+            EditGetSel(cr);
+            /* Check if all the text is selected. */
+            if (cr.cpMin == 0) {
+
+                int len = ::GetWindowTextLength(GetHWnd());
+                if (cr.cpMin == 0 && cr.cpMax >= len) {
+                    /*
+                     * All the text is selected in RichEdit - select all the
+                     * text in the edit control. This disables 'Select All'.
+                     */
+                    nStart = 0;
+                    nEnd = -1;
+                }
+            }
+        }
+        ::SendMessage(m_hEditCtrl, EM_SETSEL, (WPARAM)nStart, (LPARAM)nEnd);
+    }
+
+    /* Disable 'Paste' item if the RichEdit control is read-only. */
+    ::SendMessage(m_hEditCtrl, EM_SETREADONLY,
+                  GetStyle() & ES_READONLY ? TRUE : FALSE, 0);
+
+    POINT p;
+    p.x = xPos;
+    p.y = yPos;
+
+    /*
+     * If the context menu is requested with SHIFT+F10 or VK_APPS key,
+     * we position its top left corner to the center of the RichEdit
+     * client rect.
+     */
+    if (p.x == -1 && p.y == -1) {
+        RECT r;
+        VERIFY(::GetClientRect(GetHWnd(), &r));
+        p.x = (r.left + r.right) / 2;
+        p.y = (r.top + r.bottom) / 2;
+        VERIFY(::ClientToScreen(GetHWnd(), &p));
+    }
+
+    // The context menu steals focus from the proxy.
+    // So, set the focus-restore flag up.
+    SetRestoreFocus(TRUE);
+    ::SendMessage(m_hEditCtrl, WM_CONTEXTMENU, (WPARAM)m_hEditCtrl, MAKELPARAM(p.x, p.y));
+    SetRestoreFocus(FALSE);
+
+    return mrConsume;
+}
 
 //
 // Accessibility support
diff --git a/jdk/src/windows/native/sun/windows/awt_TextComponent.h b/jdk/src/windows/native/sun/windows/awt_TextComponent.h
index 356ed64..2a9eecc 100644
--- a/jdk/src/windows/native/sun/windows/awt_TextComponent.h
+++ b/jdk/src/windows/native/sun/windows/awt_TextComponent.h
@@ -47,6 +47,8 @@
 
     static AwtTextComponent* Create(jobject self, jobject parent, BOOL isMultiline);
 
+    virtual void Dispose();
+
     virtual LPCTSTR GetClassName();
     LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
 
@@ -83,6 +85,8 @@
     MsgRouting HandleEvent(MSG *msg, BOOL synthetic);
     MsgRouting WmPaste();
 
+    INLINE void SetIgnoreEnChange(BOOL b) { m_bIgnoreEnChange = b; }
+
     virtual BOOL IsFocusingMouseMessage(MSG *pMsg);
 
 /*  To be fully implemented in a future release
@@ -115,11 +119,24 @@
     INLINE VOID SetEndSelectionPos(LONG lPos) { m_lEndPos = lPos; }
     INLINE VOID SetLastSelectionPos(LONG lPos) { m_lLastPos = lPos; }
 
+    void EditGetSel(CHARRANGE &cr);
+
     // Used to prevent untrusted code from synthesizing a WM_PASTE message
     // by posting a <CTRL>-V KeyEvent
     BOOL    m_synthetic;
     LONG EditGetCharFromPos(POINT& pt);
 
+    // RichEdit 1.0 control generates EN_CHANGE notifications not only
+    // on text changes, but also on any character formatting change.
+    // This flag is true when the latter case is detected.
+    BOOL    m_bIgnoreEnChange;
+
+    // RichEdit 1.0 control undoes a character formatting change
+    // if it is the latest. We don't create our own undo buffer,
+    // but just prohibit undo in case if the latest operation
+    // is a formatting change.
+    BOOL    m_bCanUndo;
+
     /*****************************************************************
      * Inner class OleCallback declaration.
      */
@@ -166,6 +183,13 @@
 
     static OleCallback sm_oleCallback;
 
+    static WNDPROC sm_pDefWindowProc;
+    HWND    m_hEditCtrl;
+
+    static LRESULT CALLBACK EditProc(HWND hWnd, UINT message,
+                                     WPARAM wParam, LPARAM lParam);
+    MsgRouting WmContextMenu(HWND hCtrl, UINT xPos, UINT yPos);
+
     //
     // Accessibility support
     //
diff --git a/jdk/src/windows/native/sun/windows/awt_TextField.cpp b/jdk/src/windows/native/sun/windows/awt_TextField.cpp
index b37b5c7..1c966aa 100644
--- a/jdk/src/windows/native/sun/windows/awt_TextField.cpp
+++ b/jdk/src/windows/native/sun/windows/awt_TextField.cpp
@@ -249,13 +249,7 @@
         }
     }
 
-    /*
-     * Store the 'synthetic' parameter so that the WM_PASTE security check
-     * happens only for synthetic events.
-     */
-    m_synthetic = synthetic;
-    returnVal = AwtComponent::HandleEvent(msg, synthetic);
-    m_synthetic = FALSE;
+    returnVal = AwtTextComponent::HandleEvent(msg, synthetic);
 
     if(systemBeeperEnabled){
         SystemParametersInfo(SPI_SETBEEP, 1, NULL, 0);
diff --git a/jdk/test/com/sun/jdi/EvalInterfaceStatic.sh b/jdk/test/com/sun/jdi/EvalInterfaceStatic.sh
new file mode 100644
index 0000000..92340b3
--- /dev/null
+++ b/jdk/test/com/sun/jdi/EvalInterfaceStatic.sh
@@ -0,0 +1,126 @@
+#!/bin/sh
+
+#
+# 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 8031195
+#  @summary JDB allows evaluation of calls to static interface methods
+#  @author Jaroslav Bachorik
+#
+#  @run shell/timeout=300 EvalInterfaceStatic.sh
+
+#  The test exercises the ability to invoke static methods on interfaces.
+#  Static interface methods are a new feature added in JDK8.
+#
+#  The test makes sure that it is, at all, possible to invoke an interface
+#  static method and that the static methods are not inherited by extending
+#  interfaces.
+
+classname=EvalStaticInterfaces
+
+createJavaFile()
+{
+    cat <<EOF > $classname.java.1
+public interface $classname {
+    static String staticMethod1() {
+        return "base:staticMethod1";
+    }
+
+    static String staticMethod2() {
+        return "base:staticMethod2";
+    }
+
+    public static void main(String[] args) {
+        // prove that these work
+        System.out.println("base staticMethod1(): " + $classname.staticMethod1());
+        System.out.println("base staticMethod2(): " + $classname.staticMethod2());
+        System.out.println("overridden staticMethod2(): " + Extended$classname.staticMethod2());
+        System.out.println("base staticMethod3(): " + Extended$classname.staticMethod3());
+
+        gus();
+    }
+
+    static void gus() {
+        int x = 0;             // @1 breakpoint
+    }
+}
+
+interface Extended$classname extends $classname {
+    static String staticMethod2() {
+        return "extended:staticMethod2";
+    }
+
+    static String staticMethod3() {
+        return "extended:staticMethod3";
+    }
+}
+
+
+
+EOF
+}
+
+# drive jdb by sending cmds to it and examining its output
+dojdbCmds()
+{
+    setBkpts @1
+    runToBkpt @1
+
+    cmd eval "$classname.staticMethod1()"
+    jdbFailIfNotPresent "base:staticMethod1" 2
+
+    cmd eval "$classname.staticMethod2()"
+    jdbFailIfNotPresent "base:staticMethod2" 2
+
+    cmd eval "Extended$classname.staticMethod1()"
+    jdbFailIfPresent "base:staticMethod1" 2
+
+    cmd eval "Extended$classname.staticMethod2()"
+    jdbFailIfNotPresent "extended:staticMethod2" 2
+
+    cmd eval "Extended$classname.staticMethod3()"
+    jdbFailIfNotPresent "extended:staticMethod3" 2
+}
+
+
+mysetup()
+{
+    if [ -z "$TESTSRC" ] ; then
+        TESTSRC=.
+    fi
+
+    for ii in . $TESTSRC $TESTSRC/.. ; do
+        if [ -r "$ii/ShellScaffold.sh" ] ; then
+            . $ii/ShellScaffold.sh
+            break
+        fi
+    done
+}
+
+# You could replace this next line with the contents
+# of ShellScaffold.sh and this script will run just the same.
+mysetup
+
+runit
+pass
diff --git a/jdk/test/com/sun/jdi/InterfaceMethodsTest.java b/jdk/test/com/sun/jdi/InterfaceMethodsTest.java
new file mode 100644
index 0000000..e127fa5
--- /dev/null
+++ b/jdk/test/com/sun/jdi/InterfaceMethodsTest.java
@@ -0,0 +1,422 @@
+/*
+ * 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 8031195
+ *  @summary  JDI: Add support for static and default methods in interfaces
+ *
+ *  @run build TestScaffold VMConnection TargetListener TargetAdapter
+ *  @run build InterfaceMethodsTest
+ *  @run main InterfaceMethodsTest
+ */
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+import java.util.Collections;
+
+public class InterfaceMethodsTest extends TestScaffold {
+    private static final int RESULT_A = 1;
+    private static final int RESULT_B = 1;
+    private static final int RESULT_TARGET = 1;
+    static interface InterfaceA {
+        static int staticMethodA() {
+            System.out.println("-InterfaceA: static interface method A-");
+            return RESULT_A;
+        }
+        static int staticMethodB() {
+            System.out.println("-InterfaceA: static interface method B-");
+            return RESULT_A;
+        }
+        default int defaultMethodA() {
+            System.out.println("-InterfaceA: default interface method A-");
+            return RESULT_A;
+        }
+        default int defaultMethodB() {
+            System.out.println("-InterfaceA: default interface method B-");
+            return RESULT_A;
+        }
+        default int defaultMethodC() {
+            System.out.println("-InterfaceA: default interface method C-");
+            return RESULT_A;
+        }
+
+        int implementedMethod();
+    }
+
+    static interface InterfaceB extends InterfaceA {
+        @Override
+        default int defaultMethodC() {
+            System.out.println("-InterfaceB: overridden default interface method C-");
+            return RESULT_B;
+        }
+        default int defaultMethodD() {
+            System.out.println("-InterfaceB: default interface method D-");
+            return RESULT_B;
+        }
+
+        static int staticMethodB() {
+            System.out.println("-InterfaceB: overridden static interface method B-");
+            return RESULT_B;
+        }
+
+        static int staticMethodC() {
+            System.out.println("-InterfaceB: static interface method C-");
+            return RESULT_B;
+        }
+    }
+
+    final static class TargetClass implements InterfaceB {
+        public int classMethod() {
+            System.out.println("-TargetClass: class only method-");
+            return RESULT_TARGET;
+        }
+
+        @Override
+        public int implementedMethod() {
+            System.out.println("-TargetClass: implemented non-default interface method-");
+            return RESULT_TARGET;
+        }
+
+        @Override
+        public int defaultMethodB() {
+            System.out.println("-TargetClass: overridden default interface method D");
+
+            return RESULT_TARGET;
+        }
+
+        public static void main(String[] args) {
+            TargetClass tc = new TargetClass();
+            tc.doTests(tc);
+        }
+
+        private void doTests(TargetClass ref) {
+            // break
+        }
+    }
+
+    public InterfaceMethodsTest(String[] args) {
+        super(args);
+    }
+
+    public static void main(String[] args) throws Exception {
+        new InterfaceMethodsTest(args).startTests();
+    }
+
+    private static final String TEST_CLASS_NAME = InterfaceMethodsTest.class.getName().replace('.', '/');
+    private static final String TARGET_CLASS_NAME = TargetClass.class.getName().replace('.', '/');
+    private static final String INTERFACEA_NAME = InterfaceA.class.getName().replace('.', '/');
+    private static final String INTERFACEB_NAME = InterfaceB.class.getName().replace('.', '/');
+
+    protected void runTests() throws Exception {
+        /*
+         * Get to the top of main()
+         * to determine targetClass and mainThread
+         */
+        BreakpointEvent bpe = startToMain(TARGET_CLASS_NAME);
+
+        bpe = resumeTo(TARGET_CLASS_NAME, "doTests", "(L" + TARGET_CLASS_NAME +";)V");
+
+        mainThread = bpe.thread();
+
+        StackFrame frame = mainThread.frame(0);
+        ObjectReference thisObject = frame.thisObject();
+        ObjectReference ref = (ObjectReference)frame.getArgumentValues().get(0);
+
+        ReferenceType targetClass = bpe.location().declaringType();
+        testImplementationClass(targetClass, thisObject);
+
+        testInterfaceA(ref);
+
+        testInterfaceB(ref);
+
+        /*
+         * resume the target listening for events
+         */
+        listenUntilVMDisconnect();
+
+        /*
+         * deal with results of test
+         * if anything has called failure("foo") testFailed will be true
+         */
+        if (!testFailed) {
+            println("InterfaceMethodsTest: passed");
+        } else {
+            throw new Exception("InterfaceMethodsTest: failed");
+        }
+    }
+
+    private void testInterfaceA(ObjectReference ref) {
+        // Test non-virtual calls on InterfaceA
+
+        ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEA_NAME).get(0);
+        /* Default method calls */
+
+        // invoke the InterfaceA's "defaultMethodA"
+        testInvokePos(ifaceClass, ref, "defaultMethodA", "()I", vm().mirrorOf(RESULT_A));
+
+        // invoke the InterfaceA's "defaultMethodB"
+        testInvokePos(ifaceClass, ref, "defaultMethodB", "()I", vm().mirrorOf(RESULT_A));
+
+        // invoke the InterfaceA's "defaultMethodC"
+        testInvokePos(ifaceClass, ref, "defaultMethodC", "()I", vm().mirrorOf(RESULT_A));
+
+        // "defaultMethodD" from InterfaceB is not accessible from here
+        testInvokeNeg(ifaceClass, ref, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B),
+                "Attempted to invoke non-existing method");
+
+        // trying to invoke the asbtract method "implementedMethod"
+        testInvokeNeg(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(TARGET_CLASS_NAME),
+                "Invocation of non-default methods is not supported");
+
+
+        /* Static method calls */
+
+        // invoke interface static method A
+        testInvokePos(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A));
+
+        // try to invoke static method A on the instance
+        testInvokePos(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A));
+
+        // invoke interface static method B
+        testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_A));
+
+        // try to invoke static method B on the instance
+        testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_A));
+    }
+
+    private void testInterfaceB(ObjectReference ref) {
+        // Test non-virtual calls on InterfaceB
+        ReferenceType ifaceClass = (ReferenceType)vm().classesByName(INTERFACEB_NAME).get(0);
+
+        /* Default method calls */
+
+        // invoke the inherited "defaultMethodA"
+        testInvokePos(ifaceClass, ref, "defaultMethodA", "()I", vm().mirrorOf(RESULT_A));
+
+        // invoke the inherited "defaultMethodB"
+        testInvokePos(ifaceClass, ref, "defaultMethodB", "()I", vm().mirrorOf(RESULT_A));
+
+        // invoke the inherited and overridden "defaultMethodC"
+        testInvokePos(ifaceClass, ref, "defaultMethodC", "()I", vm().mirrorOf(RESULT_B));
+
+        // invoke InterfaceB only "defaultMethodD"
+        testInvokePos(ifaceClass, ref, "defaultMethodD", "()I", vm().mirrorOf(RESULT_B));
+
+        // "implementedMethod" is not present in InterfaceB
+        testInvokeNeg(ifaceClass, ref, "implementedMethod", "()I", vm().mirrorOf(RESULT_TARGET),
+                "Invocation of non-default methods is not supported");
+
+
+        /* Static method calls*/
+
+        // "staticMethodA" must not be inherited by InterfaceB
+        testInvokeNeg(ifaceClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
+                "Static interface methods are not inheritable");
+
+        // however it is possible to call "staticMethodA" on the actual instance
+        testInvokeNeg(ifaceClass, ref, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
+                "Static interface methods are not inheritable");
+
+        // "staticMethodB" is overridden in InterfaceB
+        testInvokePos(ifaceClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_B));
+
+        // the instance invokes the overriden form of "staticMethodB" from InterfaceB
+        testInvokePos(ifaceClass, ref, "staticMethodB", "()I", vm().mirrorOf(RESULT_B));
+
+        // "staticMethodC" is present only in InterfaceB
+        testInvokePos(ifaceClass, null, "staticMethodC", "()I", vm().mirrorOf(RESULT_B));
+
+        // "staticMethodC" should be reachable from the instance too
+        testInvokePos(ifaceClass, ref, "staticMethodC", "()I", vm().mirrorOf(RESULT_B));
+    }
+
+    private void testImplementationClass(ReferenceType targetClass, ObjectReference thisObject) {
+        // Test invocations on the implementation object
+
+        /* Default method calls */
+
+        // "defaultMethodA" is accessible and not overridden
+        testInvokePos(targetClass, thisObject, "defaultMethodA", "()I", vm().mirrorOf(RESULT_TARGET));
+
+        // "defaultMethodB" is accessible and overridden in TargetClass
+        testInvokePos(targetClass, thisObject, "defaultMethodB", "()I", vm().mirrorOf(RESULT_TARGET));
+
+        // "defaultMethodC" is accessible and overridden in InterfaceB
+        testInvokePos(targetClass, thisObject, "defaultMethodC", "()I", vm().mirrorOf(RESULT_TARGET));
+
+        // "defaultMethodD" is accessible
+        testInvokePos(targetClass, thisObject, "defaultMethodD", "()I", vm().mirrorOf(RESULT_TARGET));
+
+
+        /* Non-default instance method calls */
+
+        // "classMethod" declared in TargetClass is accessible
+        testInvokePos(targetClass, thisObject, "classMethod", "()I", vm().mirrorOf(RESULT_TARGET));
+
+        // the abstract "implementedMethod" has been implemented in TargetClass
+        testInvokePos(targetClass, thisObject, "implementedMethod", "()I", vm().mirrorOf(RESULT_TARGET));
+
+
+        /* Static method calls */
+
+        // All the static methods declared by the interfaces are not reachable from the instance of the implementor class
+        testInvokeNeg(targetClass, thisObject, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
+                "Static interface methods are not inheritable");
+
+        testInvokeNeg(targetClass, thisObject, "staticMethodB", "()I", vm().mirrorOf(RESULT_B),
+                "Static interface methods are not inheritable");
+
+        testInvokeNeg(targetClass, thisObject, "staticMethodC", "()I", vm().mirrorOf(RESULT_B),
+                "Static interface methods are not inheritable");
+
+        // All the static methods declared by the interfaces are not reachable through the implementor class
+        testInvokeNeg(targetClass, null, "staticMethodA", "()I", vm().mirrorOf(RESULT_A),
+                "Static interface methods are not inheritable");
+
+        testInvokeNeg(targetClass, null, "staticMethodB", "()I", vm().mirrorOf(RESULT_B),
+                "Static interface methods are not inheritable");
+
+        testInvokeNeg(targetClass, null, "staticMethodC", "()I", vm().mirrorOf(RESULT_B),
+                "Static interface methods are not inheritable");
+    }
+
+    private void testInvokePos(ReferenceType targetClass, ObjectReference ref, String methodName,
+                               String methodSig, Value value) {
+        logInvocation(ref, methodName, methodSig, targetClass);
+        try {
+            invoke(targetClass, ref, methodName, methodSig, value);
+            System.err.println("--- PASSED");
+        } catch (Exception e) {
+            System.err.println("--- FAILED");
+            failure("FAILED: Invocation failed with error message " + e.getLocalizedMessage());
+        }
+    }
+
+    private void testInvokeNeg(ReferenceType targetClass, ObjectReference ref, String methodName,
+                               String methodSig, Value value, String msg) {
+        logInvocation(ref, methodName, methodSig, targetClass);
+        try {
+            invoke(targetClass, ref, methodName, methodSig, value);
+            System.err.println("--- FAILED");
+            failure("FAILED: " + msg);
+        } catch (Exception e) {
+            System.err.println("--- PASSED");
+
+        }
+    }
+
+    private void invoke(ReferenceType targetClass, ObjectReference ref, String methodName,
+                        String methodSig, Value value)
+    throws Exception {
+        Method method = getMethod(targetClass, methodName, methodSig);
+        if (method == null) {
+            throw new Exception("Can't find method: " + methodName  + " for class = " + targetClass);
+        }
+
+        println("Invoking " + (method.isAbstract() ? "abstract " : " ") + "method: " + method);
+
+        Value returnValue = null;
+        if (ref != null) {
+            returnValue = invokeInstance(ref, method);
+        } else {
+            returnValue = invokeStatic(targetClass, method);
+        }
+
+        println("        return val = " + returnValue);
+        // It has to be the same value as what we passed in!
+        if (returnValue.equals(value)) {
+            println("         " + method.name() + " return value matches: "
+                    + value);
+        } else {
+            if (value != null) {
+                throw new Exception(method.name() + " returned: " + returnValue +
+                                    " expected: " + value );
+            } else {
+                println("         " + method.name() + " return value : " + returnValue);
+            }
+
+        }
+    }
+
+    private Value invokeInstance(ObjectReference ref, Method method) throws Exception {
+        return ref.invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
+    }
+
+    private Value invokeStatic(ReferenceType refType, Method method) throws Exception {
+        if (refType instanceof ClassType) {
+            return ((ClassType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
+        } else {
+            return ((InterfaceType)refType).invokeMethod(mainThread, method, Collections.emptyList(), ObjectReference.INVOKE_NONVIRTUAL);
+        }
+    }
+
+    private Method getMethod(ReferenceType rt, String name, String signature) {
+        if (rt == null) return null;
+        Method m = findMethod(rt, name, signature);
+        if (m == null) {
+            if (rt instanceof ClassType) {
+                for (Object ifc : ((ClassType)rt).interfaces()) {
+                    m = getMethod((ReferenceType)ifc, name, signature);
+                    if (m != null) {
+                        break;
+                    }
+                }
+                if (m == null) {
+                    m = getMethod(((ClassType)rt).superclass(), name, signature);
+                } else {
+                    if (m.isStatic()) {
+                        // interface static methods are not inherited
+                        m = null;
+                    }
+                }
+            } else if (rt instanceof InterfaceType) {
+                for(Object ifc : ((InterfaceType)rt).superinterfaces()) {
+                    m = getMethod((ReferenceType)ifc, name, signature);
+                    if (m != null) {
+                        if (m.isStatic()) {
+                            // interface static methods are not inherited
+                            m = null;
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+
+        return m;
+    }
+
+    private void logInvocation(ObjectReference ref, String methodName, String methodSig, ReferenceType targetClass) {
+        if (ref != null) {
+            System.err.println("Invoking: " + ref.referenceType().name() + "." +
+                    methodName + methodSig + " with target of type " +
+                    targetClass.name());
+        } else {
+            System.err.println("Invoking static : " + targetClass.name() + "." +
+                    methodName + methodSig);
+        }
+    }
+}
+
+
+
diff --git a/jdk/test/com/sun/jdi/VisibleMethods.java b/jdk/test/com/sun/jdi/VisibleMethods.java
new file mode 100644
index 0000000..70f7f5a
--- /dev/null
+++ b/jdk/test/com/sun/jdi/VisibleMethods.java
@@ -0,0 +1,141 @@
+/*
+ * 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
+ *  @summary Test ReferenceType.visibleMethods
+ *  @bug 8028430
+ *
+ *  @author Staffan Larsen
+ *
+ *  @run build TestScaffold VMConnection TargetListener TargetAdapter
+ *  @run compile -g VisibleMethods.java
+ *  @run main VisibleMethods
+ */
+import com.sun.jdi.Method;
+import com.sun.jdi.ReferenceType;
+import com.sun.jdi.StackFrame;
+import com.sun.jdi.StringReference;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.event.BreakpointEvent;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/********** target program **********/
+
+interface Super {
+    public void m(Object o); // This method should not be visible in AC
+    public void m(String s); // This method should not be visible in AC
+}
+
+interface One extends Super {
+    public void m(Object o);
+    public void m1(); // Either this method or Two.m1 should be visible in AC
+}
+
+interface Two extends Super {
+    public void m(String s);
+    public void m1(); // Either this method or One.m1 should be visible in AC
+}
+
+abstract class AC implements One, Two {
+}
+
+class CC extends AC {
+    public void m(Object o) {
+    }
+    public void m(String s) {
+    }
+    public void m1() {
+    }
+    public static void main(String[] args) {
+        System.out.println("Goodbye from VisibleMethods!");
+    }
+}
+
+/********** test program **********/
+
+public class VisibleMethods extends TestScaffold {
+    ReferenceType targetClass;
+    ThreadReference mainThread;
+
+    VisibleMethods(String args[]) {
+        super(args);
+    }
+
+    public static void main(String[] args) throws Exception {
+        new VisibleMethods(args).startTests();
+    }
+
+    /********** test core **********/
+
+    protected void runTests()
+        throws Exception
+    {
+        /*
+         * Run to String.<init>
+         */
+        startToMain("CC");
+
+        ReferenceType ac = findReferenceType("AC");
+        List<String> visible = ac.visibleMethods().
+                stream().
+                map(Method::toString).
+                collect(Collectors.toList());
+
+        System.out.println("visibleMethods(): " + visible);
+
+        verifyContains(visible, 1, "Two.m(java.lang.String)");
+        verifyContains(visible, 1, "One.m(java.lang.Object)");
+        verifyContains(visible, 0, "Super.m(java.lang.Object)");
+        verifyContains(visible, 0, "Super.m(java.lang.String)");
+        verifyContains(visible, 1, "Two.m1()", "One.m1()");
+
+        /*
+         * resume the target listening for events
+         */
+        listenUntilVMDisconnect();
+    }
+
+    private void verifyContains(List<String> methods, int matches,
+            String... sigs) throws Exception {
+        if (countMatches(methods, sigs) != matches) {
+            throw new Exception("visibleMethods() should have contained "
+                    + matches + " entry/entries from " + Arrays.toString(sigs));
+        }
+    }
+
+    private int countMatches(List<String> list1, String[] list2) {
+        int count = 0;
+        for (String s1 : list1) {
+            for (String s2 : list2) {
+                if (s1.equals(s2)) {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
+}
diff --git a/jdk/test/java/awt/Focus/SortingFPT/JDK8048887.java b/jdk/test/java/awt/Focus/SortingFPT/JDK8048887.java
index 72f0ada..0128706 100644
--- a/jdk/test/java/awt/Focus/SortingFPT/JDK8048887.java
+++ b/jdk/test/java/awt/Focus/SortingFPT/JDK8048887.java
@@ -26,7 +26,7 @@
   @bug       8048887
   @summary   Tests SortingFTP for an exception caused by the tim-sort algo.
   @author    anton.tarasov: area=awt.focus
-  @run       main JDK8040632
+  @run       main JDK8048887
 */
 
 import javax.swing.JFrame;
diff --git a/jdk/test/java/net/InetAddress/IPv4Formats.java b/jdk/test/java/net/InetAddress/IPv4Formats.java
index 7c6dc86..e626043 100644
--- a/jdk/test/java/net/InetAddress/IPv4Formats.java
+++ b/jdk/test/java/net/InetAddress/IPv4Formats.java
@@ -27,6 +27,7 @@
  * @summary InetAddress.getByName behaves differently on windows
  */
 import java.net.*;
+import java.util.UUID;
 
 public class IPv4Formats {
     public static void main(String[] args) {
@@ -36,7 +37,7 @@
             {"126.1", "126.0.0.1"},
             {"128.50.65534", "128.50.255.254"},
             {"192.168.1.2", "192.168.1.2"},
-            {"hello.foo.bar", null},
+            {"invalidhost.invalid", null},
             {"1024.1.2.3", null},
             {"128.14.66000", null }
         };
diff --git a/jdk/test/java/util/logging/FileHandlerPath.java b/jdk/test/java/util/logging/FileHandlerPath.java
new file mode 100644
index 0000000..9385909
--- /dev/null
+++ b/jdk/test/java/util/logging/FileHandlerPath.java
@@ -0,0 +1,315 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import static java.nio.file.StandardOpenOption.CREATE_NEW;
+import static java.nio.file.StandardOpenOption.WRITE;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.PropertyPermission;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.FileHandler;
+import java.util.logging.LogManager;
+import java.util.logging.LoggingPermission;
+
+/**
+ * @test
+ * @bug 8059269
+ * @summary tests that using a simple (non composite) pattern does not lead
+ *        to NPE when the lock file already exists.
+ * @run main/othervm FileHandlerPath UNSECURE
+ * @run main/othervm FileHandlerPath SECURE
+ * @author danielfuchs
+ */
+public class FileHandlerPath {
+
+    /**
+     * We will test the simple pattern in two configurations.
+     * UNSECURE: No security manager.
+     * SECURE: With the security manager present - and the required
+     *         permissions granted.
+     */
+    public static enum TestCase {
+        UNSECURE, SECURE;
+        public void run(Properties propertyFile) throws Exception {
+            System.out.println("Running test case: " + name());
+            Configure.setUp(this, propertyFile);
+            test(this.name() + " " + propertyFile.getProperty("test.name"), propertyFile);
+        }
+    }
+
+
+    // Use a random name provided by UUID to avoid collision with other tests
+    final static String logFile = FileHandlerPath.class.getSimpleName() + "_"
+                + UUID.randomUUID().toString() + ".log";
+    final static String tmpLogFile;
+    final static String userDir = System.getProperty("user.dir");
+    final static String tmpDir = System.getProperty("java.io.tmpdir");
+    private static final List<Properties> properties;
+    static {
+        tmpLogFile = new File(tmpDir, logFile).toString();
+        Properties props1 = new Properties();
+        Properties props2 = new Properties();
+        props1.setProperty("test.name", "relative file");
+        props1.setProperty("test.file.name", logFile);
+        props1.setProperty(FileHandler.class.getName() + ".pattern", logFile);
+        props1.setProperty(FileHandler.class.getName() + ".count", "1");
+        props2.setProperty("test.name", "absoluste file");
+        props2.setProperty("test.file.name", tmpLogFile);
+        props2.setProperty(FileHandler.class.getName() + ".pattern", "%t/" + logFile);
+        props2.setProperty(FileHandler.class.getName() + ".count", "1");
+        properties = Collections.unmodifiableList(Arrays.asList(
+                    props1,
+                    props2));
+    }
+
+    public static void main(String... args) throws Exception {
+
+        if (args == null || args.length == 0) {
+            args = new String[] {
+                TestCase.UNSECURE.name(),
+                TestCase.SECURE.name(),
+            };
+        }
+
+        // Sanity checks
+
+        if (!Files.isWritable(Paths.get(userDir))) {
+            throw new RuntimeException(userDir +
+                    ": user.dir is not writable - can't run test.");
+        }
+        if (!Files.isWritable(Paths.get(tmpDir))) {
+            throw new RuntimeException(tmpDir +
+                    ": java.io.tmpdir is not writable - can't run test.");
+        }
+
+        File[] files = {
+            new File(logFile),
+            new File(tmpLogFile),
+            new File(logFile+".1"),
+            new File(tmpLogFile+".1"),
+            new File(logFile+".lck"),
+            new File(tmpLogFile+".lck"),
+            new File(logFile+".1.lck"),
+            new File(tmpLogFile+".1.lck")
+        };
+
+        for (File log : files) {
+            if (log.exists()) {
+                throw new Exception(log +": file already exists - can't run test.");
+            }
+        }
+
+        // Now start the real test
+
+        try {
+            for (String testName : args) {
+                for (Properties propertyFile : properties) {
+                    TestCase test = TestCase.valueOf(testName);
+                    test.run(propertyFile);
+                }
+            }
+        } finally {
+            // Cleanup...
+            Configure.doPrivileged(() -> {
+                for(File log : files) {
+                    try {
+                        final boolean isLockFile = log.getName().endsWith(".lck");
+                        // lock file should already be deleted, except if the
+                        // test failed in exception.
+                        // log file should all be present, except if the test
+                        // failed in exception.
+                        if (log.exists()) {
+                            if (!isLockFile) {
+                                System.out.println("deleting "+log.toString());
+                            } else {
+                                System.err.println("deleting lock file "+log.toString());
+                            }
+                            log.delete();
+                        } else {
+                            if (!isLockFile) {
+                                System.err.println(log.toString() + ": not found.");
+                            }
+                        }
+                    } catch (Throwable t) {
+                        // should not happen
+                        t.printStackTrace();
+                    }
+                }
+            });
+        }
+    }
+
+    static class Configure {
+        static Policy policy = null;
+        static final AtomicBoolean allowAll = new AtomicBoolean(false);
+        static void setUp(TestCase test, Properties propertyFile) {
+            switch (test) {
+                case SECURE:
+                    if (policy == null && System.getSecurityManager() != null) {
+                        throw new IllegalStateException("SecurityManager already set");
+                    } else if (policy == null) {
+                        policy = new SimplePolicy(TestCase.SECURE, allowAll);
+                        Policy.setPolicy(policy);
+                        System.setSecurityManager(new SecurityManager());
+                    }
+                    if (System.getSecurityManager() == null) {
+                        throw new IllegalStateException("No SecurityManager.");
+                    }
+                    if (policy == null) {
+                        throw new IllegalStateException("policy not configured");
+                    }
+                    break;
+                case UNSECURE:
+                    if (System.getSecurityManager() != null) {
+                        throw new IllegalStateException("SecurityManager already set");
+                    }
+                    break;
+                default:
+                    new InternalError("No such testcase: " + test);
+            }
+            doPrivileged(() -> {
+                try {
+                    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+                    propertyFile.store(bytes, propertyFile.getProperty("test.name"));
+                    ByteArrayInputStream bais = new ByteArrayInputStream(bytes.toByteArray());
+                    LogManager.getLogManager().readConfiguration(bais);
+                } catch (IOException ex) {
+                    throw new RuntimeException(ex);
+                }
+            });
+        }
+        static void doPrivileged(Runnable run) {
+            allowAll.set(true);
+            try {
+                run.run();
+            } finally {
+                allowAll.set(false);
+            }
+        }
+    }
+
+    public static void test(String name, Properties props) throws Exception {
+        System.out.println("Testing: " + name);
+        String file = props.getProperty("test.file.name");
+        // create the lock files first - in order to take the path that
+        // used to trigger the NPE
+        Files.createFile(Paths.get(file + ".lck"));
+        Files.createFile(Paths.get(file + ".1.lck"));
+        final FileHandler f1 = new FileHandler();
+        final FileHandler f2 = new FileHandler();
+        f1.close();
+        f2.close();
+        System.out.println("Success for " + name);
+    }
+
+
+    final static class PermissionsBuilder {
+        final Permissions perms;
+        public PermissionsBuilder() {
+            this(new Permissions());
+        }
+        public PermissionsBuilder(Permissions perms) {
+            this.perms = perms;
+        }
+        public PermissionsBuilder add(Permission p) {
+            perms.add(p);
+            return this;
+        }
+        public PermissionsBuilder addAll(PermissionCollection col) {
+            if (col != null) {
+                for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) {
+                    perms.add(e.nextElement());
+                }
+            }
+            return this;
+        }
+        public Permissions toPermissions() {
+            final PermissionsBuilder builder = new PermissionsBuilder();
+            builder.addAll(perms);
+            return builder.perms;
+        }
+    }
+
+    public static class SimplePolicy extends Policy {
+
+        final Permissions permissions;
+        final Permissions allPermissions;
+        final AtomicBoolean allowAll;
+        public SimplePolicy(TestCase test, AtomicBoolean allowAll) {
+            this.allowAll = allowAll;
+            permissions = new Permissions();
+            permissions.add(new LoggingPermission("control", null)); // needed by new FileHandler()
+            permissions.add(new FilePermission("<<ALL FILES>>", "read")); // needed by new FileHandler()
+            permissions.add(new FilePermission(logFile, "write,delete")); // needed by new FileHandler()
+            permissions.add(new FilePermission(logFile+".lck", "write,delete")); // needed by FileHandler.close()
+            permissions.add(new FilePermission(logFile+".1", "write,delete")); // needed by new FileHandler()
+            permissions.add(new FilePermission(logFile+".1.lck", "write,delete")); // needed by FileHandler.close()
+            permissions.add(new FilePermission(tmpLogFile, "write,delete")); // needed by new FileHandler()
+            permissions.add(new FilePermission(tmpLogFile+".lck", "write,delete")); // needed by FileHandler.close()
+            permissions.add(new FilePermission(tmpLogFile+".1", "write,delete")); // needed by new FileHandler()
+            permissions.add(new FilePermission(tmpLogFile+".1.lck", "write,delete")); // needed by FileHandler.close()
+            permissions.add(new FilePermission(userDir, "write")); // needed by new FileHandler()
+            permissions.add(new FilePermission(tmpDir, "write")); // needed by new FileHandler()
+            permissions.add(new PropertyPermission("user.dir", "read"));
+            permissions.add(new PropertyPermission("java.io.tmpdir", "read"));
+            allPermissions = new Permissions();
+            allPermissions.add(new java.security.AllPermission());
+        }
+
+        @Override
+        public boolean implies(ProtectionDomain domain, Permission permission) {
+            if (allowAll.get()) return allPermissions.implies(permission);
+            return permissions.implies(permission);
+        }
+
+        @Override
+        public PermissionCollection getPermissions(CodeSource codesource) {
+            return new PermissionsBuilder().addAll(allowAll.get()
+                    ? allPermissions : permissions).toPermissions();
+        }
+
+        @Override
+        public PermissionCollection getPermissions(ProtectionDomain domain) {
+            return new PermissionsBuilder().addAll(allowAll.get()
+                    ? allPermissions : permissions).toPermissions();
+        }
+    }
+
+}
diff --git a/jdk/test/javax/xml/ws/xsanymixed/CopyingResponse.java b/jdk/test/javax/xml/ws/xsanymixed/CopyingResponse.java
new file mode 100644
index 0000000..88c4084
--- /dev/null
+++ b/jdk/test/javax/xml/ws/xsanymixed/CopyingResponse.java
@@ -0,0 +1,35 @@
+/*
+ * 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 org.somewhere.ws.EchoRequest;
+import org.somewhere.ws.EchoResponse;
+
+public class CopyingResponse extends EchoResponse {
+
+    public CopyingResponse() {}
+
+    public CopyingResponse(EchoRequest request) {
+        content = request.getContent();
+    }
+}
diff --git a/jdk/test/javax/xml/ws/xsanymixed/ServiceImpl.java b/jdk/test/javax/xml/ws/xsanymixed/ServiceImpl.java
new file mode 100644
index 0000000..b045893
--- /dev/null
+++ b/jdk/test/javax/xml/ws/xsanymixed/ServiceImpl.java
@@ -0,0 +1,51 @@
+/*
+ * 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 org.somewhere.ws.EchoRequest;
+import org.somewhere.ws.EchoResponse;
+import org.somewhere.ws.TestPort;
+
+import javax.jws.WebService;
+import javax.xml.namespace.QName;
+
+
+/**
+ * Simple Webservice implementation just copying xml part as is
+ * from incoming request into outgoing response
+ */
+@WebService(
+        endpointInterface = "org.somewhere.ws.TestPort",
+        targetNamespace = "http://ws.somewhere.org/",
+        serviceName = "TestService",
+        portName = "TestPort")
+public class ServiceImpl implements TestPort {
+
+    public static final QName PORT_NAME = new QName("http://ws.somewhere.org/", "TestPort");
+    public static final QName SERVICE_NAME = new QName("http://ws.somewhere.org/", "TestService");
+
+    @Override
+    public EchoResponse echo(EchoRequest request) {
+        return new CopyingResponse(request);
+    }
+
+}
diff --git a/jdk/test/javax/xml/ws/xsanymixed/Test.java b/jdk/test/javax/xml/ws/xsanymixed/Test.java
new file mode 100644
index 0000000..4287d8c
--- /dev/null
+++ b/jdk/test/javax/xml/ws/xsanymixed/Test.java
@@ -0,0 +1,197 @@
+/*
+ * 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 8036981 8038966 8051441
+ * @summary the content of xs:any content:mixed should remain as is,
+ *          no white space changes and no changes to namespace prefixes
+ * @run shell compile-wsdl.sh
+ * @run main/othervm Test
+ */
+
+import com.sun.net.httpserver.HttpServer;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.Dispatch;
+import javax.xml.ws.Endpoint;
+import javax.xml.ws.Service;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.InetSocketAddress;
+import java.net.URL;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+
+import static java.nio.file.FileVisitResult.CONTINUE;
+
+public class Test {
+
+    private static HttpServer httpServer;
+    private static Endpoint endpoint;
+    private static final String NL = System.getProperty("line.separator");
+
+    private static final String XS_ANY_MIXED_PART =
+            "<AppHdr xmlns=\"urn:head.001\">" + NL +
+            "      <Fr>" + NL + NL +
+            "<FIId xmlns=\"urn:head.009\">" + NL + NL +
+            "        any" + NL +
+            "    white" + NL +
+            "      space" + NL + NL +
+            "        <FinInstnId>... and" + NL + NL +
+            "            NO namespace prefixes!!!" + NL + NL +
+            "        </FinInstnId>" + NL + NL +
+            "  </FIId>" + NL +
+            "</Fr>" + NL +
+            "</AppHdr>";
+
+    private static final String XML_REQUEST = "<soap:Envelope " +
+            "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
+            "xmlns:ws=\"http://ws.somewhere.org/\">" +
+            "<soap:Header/><soap:Body>" +
+            "<ws:echoRequest>" + NL +
+                XS_ANY_MIXED_PART + NL +
+            "</ws:echoRequest>" +
+            "</soap:Body></soap:Envelope>";
+
+    private static String deployWebservice() throws IOException {
+        // Manually create HttpServer here using ephemeral address for port
+        // so as to not end up with attempt to bind to an in-use port
+        httpServer = HttpServer.create(new InetSocketAddress(0), 0);
+        httpServer.start();
+        endpoint = Endpoint.create(new ServiceImpl());
+        endpoint.publish(httpServer.createContext("/wservice"));
+
+        String wsdlAddress = "http://localhost:" + httpServer.getAddress().getPort() + "/wservice?wsdl";
+        log("address = " + wsdlAddress);
+        return wsdlAddress;
+    }
+
+    private static void stopWebservice() {
+        if (endpoint != null && endpoint.isPublished()) {
+            endpoint.stop();
+        }
+        if (httpServer != null) {
+            httpServer.stop(0);
+        }
+    }
+
+    public static void main(String[] args) throws IOException, TransformerException {
+
+        try {
+            String address = deployWebservice();
+            Service service = Service.create(new URL(address), ServiceImpl.SERVICE_NAME);
+
+            Dispatch<Source> d = service.createDispatch(ServiceImpl.PORT_NAME, Source.class, Service.Mode.MESSAGE);
+            Source response = d.invoke(new StreamSource(new StringReader(XML_REQUEST)));
+
+            String resultXml = toString(response);
+
+            log("= request ======== \n");
+            log(XML_REQUEST);
+            log("= result ========= \n");
+            log(resultXml);
+            log("\n==================");
+
+            boolean xsAnyMixedPartSame = resultXml.contains(XS_ANY_MIXED_PART);
+            log("resultXml.contains(XS_ANY_PART) = " + xsAnyMixedPartSame);
+            if (!xsAnyMixedPartSame) {
+                fail("The xs:any content=mixed part is supposed to be same in request and response.");
+                throw new RuntimeException();
+            }
+
+            log("TEST PASSED");
+        } finally {
+            stopWebservice();
+
+            // if you need to debug or explore wsdl generation result
+            // comment this line out:
+            deleteGeneratedFiles();
+        }
+    }
+
+    private static String toString(Source response) throws TransformerException, IOException {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        TransformerFactory transformerFactory = TransformerFactory.newInstance();
+        Transformer transformer = transformerFactory.newTransformer();
+        transformer.transform(response, new StreamResult(bos));
+        bos.close();
+        return new String(bos.toByteArray());
+    }
+
+    private static void fail(String message) {
+        log("TEST FAILED.");
+        throw new RuntimeException(message);
+    }
+
+    private static void log(String msg) {
+        System.out.println(msg);
+    }
+
+    private static void deleteGeneratedFiles() {
+        Path p = Paths.get("..", "classes", "javax", "xml", "ws", "xsanymixed", "org");
+        System.out.println("performing cleanup, deleting wsdl compilation result: " + p.toFile().getAbsolutePath());
+        if (Files.exists(p)) {
+            try {
+                Files.walkFileTree(p, new SimpleFileVisitor<Path>() {
+                    @Override
+                    public FileVisitResult visitFile(
+                            Path file,
+                            BasicFileAttributes attrs) throws IOException {
+
+                        System.out.println("deleting file [" + file.toFile().getAbsoluteFile() + "]");
+                        Files.delete(file);
+                        return CONTINUE;
+                    }
+
+                    @Override
+                    public FileVisitResult postVisitDirectory(
+                            Path dir,
+                            IOException exc) throws IOException {
+
+                        System.out.println("deleting dir [" + dir.toFile().getAbsoluteFile() + "]");
+                        if (exc == null) {
+                            Files.delete(dir);
+                            return CONTINUE;
+                        } else {
+                            throw exc;
+                        }
+                    }
+                });
+            } catch (IOException ioe) {
+                ioe.printStackTrace();
+            }
+        }
+    }
+
+}
diff --git a/jdk/test/javax/xml/ws/xsanymixed/compile-wsdl.sh b/jdk/test/javax/xml/ws/xsanymixed/compile-wsdl.sh
new file mode 100644
index 0000000..a93050a
--- /dev/null
+++ b/jdk/test/javax/xml/ws/xsanymixed/compile-wsdl.sh
@@ -0,0 +1,36 @@
+#! /bin/sh
+
+#
+# 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.
+#
+
+#
+
+if [ "x$TESTJAVA" = x ]; then
+  TESTJAVA=$1; shift
+  TESTCLASSES=.
+fi
+
+echo "compiling [test-service.wsdl] wsdl ..."
+$TESTJAVA/bin/wsimport -keep  -d ${TESTCLASSES} ${TESTSRC}/service.wsdl
+
+echo "WSDL compiled. Main test class Test.java can be compiled now."
diff --git a/jdk/test/javax/xml/ws/xsanymixed/service.wsdl b/jdk/test/javax/xml/ws/xsanymixed/service.wsdl
new file mode 100644
index 0000000..3a8f541
--- /dev/null
+++ b/jdk/test/javax/xml/ws/xsanymixed/service.wsdl
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+  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.
+-->
+<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:tns="http://ws.somewhere.org/"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
+             name="TestService"
+             targetNamespace="http://ws.somewhere.org/">
+
+    <types>
+        <xsd:schema targetNamespace="http://ws.somewhere.org/" version="1.0"
+                    xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.somewhere.org/">
+
+            <xsd:element type="tns:echoRequest" name="echoRequest"/>
+            <xsd:element type="tns:echoResponse" name="echoResponse"/>
+
+            <xsd:complexType name="echoRequest" mixed="true">
+                <xsd:sequence>
+                    <xsd:any namespace="##any" processContents="skip" minOccurs="1" maxOccurs="10"/>
+                </xsd:sequence>
+            </xsd:complexType>
+
+            <xsd:complexType name="echoResponse" mixed="true">
+                <xsd:sequence>
+                    <xsd:any namespace="##any" processContents="skip" minOccurs="1" maxOccurs="10"/>
+                </xsd:sequence>
+            </xsd:complexType>
+        </xsd:schema>
+    </types>
+
+    <message name="echoRequest">
+        <part element="tns:echoRequest" name="parameters"/>
+    </message>
+    <message name="echoResponse">
+        <part element="tns:echoResponse" name="parameters"/>
+    </message>
+
+    <portType name="TestPort">
+        <operation name="echo">
+            <input message="tns:echoRequest" wsam:Action="http://ws.somewhere.org/tester/echoRequest"/>
+            <output message="tns:echoResponse" wsam:Action="http://ws.somewhere.org/tester/echoResponse"/>
+        </operation>
+    </portType>
+
+    <binding name="TestServicePortBinding" type="tns:TestPort">
+        <soap:binding style="document"
+                      transport="http://schemas.xmlsoap.org/soap/http"/>
+
+        <operation name="echo">
+            <soap:operation soapAction=""/>
+            <input>
+                <soap:body use="literal"/>
+            </input>
+            <output>
+                <soap:body use="literal"/>
+            </output>
+        </operation>
+    </binding>
+
+    <service name="TestService">
+        <port binding="tns:TestServicePortBinding" name="TestPort">
+            <soap:address location="http://localhost/ws/tester"/>
+        </port>
+    </service>
+</definitions>
diff --git a/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java b/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java
new file mode 100644
index 0000000..cc926c8
--- /dev/null
+++ b/jdk/test/sun/awt/datatransfer/DataFlavorComparatorTest1.java
@@ -0,0 +1,115 @@
+/*
+ * 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 8058473
+   @summary "Comparison method violates its general contract" when using Clipboard
+            Ensure that DataTransferer.DataFlavorComparator conforms to Comparator contract
+   @author Anton Nashatyrev
+   @run main DataFlavorComparatorTest1
+*/
+import sun.awt.datatransfer.DataTransferer;
+
+import java.awt.datatransfer.DataFlavor;
+import java.util.Comparator;
+
+public class DataFlavorComparatorTest1 {
+
+    public static void main(String[] args) throws Exception {
+        String[] mimes = new String[] {
+                "text/plain",
+                "text/plain; charset=unicode",
+                "text/plain; charset=cp1251",
+                "text/plain; charset=unicode; class=java.io.InputStream",
+                "text/plain; charset=unicode; class=java.io.Serializable",
+                "text/plain; charset=unicode; class=java.lang.Object",
+                "text/plain; class=java.lang.String",
+                "text/plain; class=java.io.Reader",
+                "text/plain; class=java.lang.Object",
+                "text/html",
+                "text/html; charset=unicode",
+                "text/html; charset=cp1251",
+                "text/html; charset=unicode; class=java.io.InputStream",
+                "text/html; charset=unicode; class=java.io.Serializable",
+                "text/html; charset=unicode; class=java.lang.Object",
+                "text/html; class=java.lang.String",
+                "text/html; class=java.io.Reader",
+                "text/html; class=java.lang.Object",
+                "text/unknown",
+                "text/unknown; charset=unicode",
+                "text/unknown; charset=cp1251",
+                "text/unknown; charset=unicode; class=java.io.InputStream",
+                "text/unknown; charset=unicode; class=java.io.Serializable",
+                "text/unknown; charset=unicode; class=java.lang.Object",
+                "text/unknown; class=java.lang.String",
+                "text/unknown; class=java.io.Reader",
+                "text/unknown; class=java.lang.Object",
+                "application/unknown; class=java.io.InputStream",
+                "application/unknown; class=java.lang.Object",
+                "application/unknown",
+                "application/x-java-jvm-local-objectref; class=java.io.InputStream",
+                "application/x-java-jvm-local-objectref; class=java.lang.Object",
+                "application/x-java-jvm-local-objectref",
+                "unknown/flavor",
+                "unknown/flavor; class=java.io.InputStream",
+                "unknown/flavor; class=java.lang.Object",
+        };
+
+        DataFlavor[] flavors = new DataFlavor[mimes.length];
+        for (int i = 0; i < flavors.length; i++) {
+            flavors[i] = new DataFlavor(mimes[i]);
+        }
+
+        testComparator(new DataTransferer.DataFlavorComparator(true), flavors);
+        testComparator(new DataTransferer.DataFlavorComparator(false), flavors);
+
+    }
+
+    private static void testComparator(Comparator cmp, DataFlavor[] flavs)
+            throws ClassNotFoundException {
+
+        for (DataFlavor x: flavs) {
+            for (DataFlavor y: flavs) {
+                if (Math.signum(cmp.compare(x,y)) != -Math.signum(cmp.compare(y,x))) {
+                    throw new RuntimeException("Antisymmetry violated: " + x + ", " + y);
+                }
+                if (cmp.compare(x,y) == 0 && !x.equals(y)) {
+                    throw new RuntimeException("Equals rule violated: " + x + ", " + y);
+                }
+                for (DataFlavor z: flavs) {
+                    if (cmp.compare(x,y) == 0) {
+                        if (Math.signum(cmp.compare(x, z)) != Math.signum(cmp.compare(y, z))) {
+                            throw new RuntimeException("Transitivity (1) violated: " + x + ", " + y + ", " + z);
+                        }
+                    } else {
+                        if (Math.signum(cmp.compare(x, y)) == Math.signum(cmp.compare(y, z))) {
+                            if (Math.signum(cmp.compare(x, y)) != Math.signum(cmp.compare(x, z))) {
+                                throw new RuntimeException("Transitivity (2) violated: " + x + ", " + y + ", " + z);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java b/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java
index 12139f6..a867e45 100644
--- a/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java
+++ b/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 6476665 7033534 6830714
+ * @bug 6476665 7033534 6830714 8052162
  * @summary Verifies color conversion of Component Color Model based images
  * @run main ColConvCCMTest
  */
diff --git a/jdk/test/sun/security/jgss/spnego/NotPreferredMech.java b/jdk/test/sun/security/jgss/spnego/NotPreferredMech.java
new file mode 100644
index 0000000..5eb8150
--- /dev/null
+++ b/jdk/test/sun/security/jgss/spnego/NotPreferredMech.java
@@ -0,0 +1,100 @@
+/*
+ * 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 8048194
+ * @run main/othervm NotPreferredMech
+ * @summary GSSContext.acceptSecContext fails when a supported mech is not initiator preferred
+ */
+
+import org.ietf.jgss.*;
+import sun.security.jgss.*;
+import sun.security.jgss.spnego.NegTokenInit;
+import sun.security.jgss.spnego.NegTokenTarg;
+import sun.security.util.BitArray;
+import sun.security.util.DerOutputStream;
+import sun.security.util.DerValue;
+import sun.security.util.ObjectIdentifier;
+
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+public class NotPreferredMech {
+
+    public static void main(String[] argv) throws Exception {
+
+        // Generates a NegTokenInit mechTypes field, with an
+        // unsupported mech as the preferred.
+        DerOutputStream mech = new DerOutputStream();
+        mech.write(new Oid("1.2.3.4").getDER());
+        mech.write(GSSUtil.GSS_KRB5_MECH_OID.getDER());
+        DerOutputStream mechTypeList = new DerOutputStream();
+        mechTypeList.write(DerValue.tag_Sequence, mech);
+
+        // Generates a NegTokenInit mechToken field for 1.2.3.4 mech
+        GSSHeader h1 = new GSSHeader(new ObjectIdentifier("1.2.3.4"), 1);
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        h1.encode(bout);
+        bout.write(new byte[1]);
+
+        // Generates the NegTokenInit token
+        Constructor<NegTokenInit> ctor = NegTokenInit.class.getDeclaredConstructor(
+                byte[].class, BitArray.class, byte[].class, byte[].class);
+        ctor.setAccessible(true);
+        NegTokenInit initToken = ctor.newInstance(
+                mechTypeList.toByteArray(),
+                new BitArray(0),
+                bout.toByteArray(),
+                null);
+        Method m = Class.forName("sun.security.jgss.spnego.SpNegoToken")
+                .getDeclaredMethod("getEncoded");
+        m.setAccessible(true);
+        byte[] spnegoToken = (byte[])m.invoke(initToken);
+
+        // and wraps it into a GSSToken
+        GSSHeader h = new GSSHeader(
+                new ObjectIdentifier(GSSUtil.GSS_SPNEGO_MECH_OID.toString()),
+                spnegoToken.length);
+        bout = new ByteArrayOutputStream();
+        h.encode(bout);
+        bout.write(spnegoToken);
+        byte[] token = bout.toByteArray();
+
+        // and feeds it to a GSS acceptor
+        GSSManager man = GSSManager.getInstance();
+        GSSContext ctxt = man.createContext((GSSCredential) null);
+        token = ctxt.acceptSecContext(token, 0, token.length);
+        NegTokenTarg targ = new NegTokenTarg(token);
+
+        // Make sure it's a GO-ON message
+        Method m2 = NegTokenTarg.class.getDeclaredMethod("getNegotiatedResult");
+        m2.setAccessible(true);
+        int negResult = (int)m2.invoke(targ);
+
+        if (negResult != 1 /* ACCEPT_INCOMPLETE */) {
+            throw new Exception("Not a continue");
+        }
+    }
+}
diff --git a/jdk/test/sun/security/ssl/sanity/ciphersuites/CipherSuitesInOrder.java b/jdk/test/sun/security/ssl/sanity/ciphersuites/CipherSuitesInOrder.java
index 361ac86..69745aa 100644
--- a/jdk/test/sun/security/ssl/sanity/ciphersuites/CipherSuitesInOrder.java
+++ b/jdk/test/sun/security/ssl/sanity/ciphersuites/CipherSuitesInOrder.java
@@ -69,11 +69,6 @@
         "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
         "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
         "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
-        "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
-        "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
-        "SSL_RSA_WITH_RC4_128_SHA",
-        "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
-        "TLS_ECDH_RSA_WITH_RC4_128_SHA",
 
         "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
         "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
@@ -97,6 +92,12 @@
         "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
         "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
         "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
+
+        "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+        "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
+        "SSL_RSA_WITH_RC4_128_SHA",
+        "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
+        "TLS_ECDH_RSA_WITH_RC4_128_SHA",
         "SSL_RSA_WITH_RC4_128_MD5",
 
         "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
@@ -110,10 +111,20 @@
         "TLS_DH_anon_WITH_AES_128_CBC_SHA256",
         "TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
         "TLS_DH_anon_WITH_AES_128_CBC_SHA",
-        "TLS_ECDH_anon_WITH_RC4_128_SHA",
-        "SSL_DH_anon_WITH_RC4_128_MD5",
         "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
         "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
+        "TLS_ECDH_anon_WITH_RC4_128_SHA",
+        "SSL_DH_anon_WITH_RC4_128_MD5",
+        "SSL_RSA_WITH_DES_CBC_SHA",
+        "SSL_DHE_RSA_WITH_DES_CBC_SHA",
+        "SSL_DHE_DSS_WITH_DES_CBC_SHA",
+        "SSL_DH_anon_WITH_DES_CBC_SHA",
+        "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+        "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+        "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+        "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
+        "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+        "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
         "TLS_RSA_WITH_NULL_SHA256",
         "TLS_ECDHE_ECDSA_WITH_NULL_SHA",
         "TLS_ECDHE_RSA_WITH_NULL_SHA",
@@ -122,26 +133,16 @@
         "TLS_ECDH_RSA_WITH_NULL_SHA",
         "TLS_ECDH_anon_WITH_NULL_SHA",
         "SSL_RSA_WITH_NULL_MD5",
-        "SSL_RSA_WITH_DES_CBC_SHA",
-        "SSL_DHE_RSA_WITH_DES_CBC_SHA",
-        "SSL_DHE_DSS_WITH_DES_CBC_SHA",
-        "SSL_DH_anon_WITH_DES_CBC_SHA",
-        "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
-        "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
-        "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
-        "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
-        "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
-        "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
-        "TLS_KRB5_WITH_RC4_128_SHA",
-        "TLS_KRB5_WITH_RC4_128_MD5",
         "TLS_KRB5_WITH_3DES_EDE_CBC_SHA",
         "TLS_KRB5_WITH_3DES_EDE_CBC_MD5",
+        "TLS_KRB5_WITH_RC4_128_SHA",
+        "TLS_KRB5_WITH_RC4_128_MD5",
         "TLS_KRB5_WITH_DES_CBC_SHA",
         "TLS_KRB5_WITH_DES_CBC_MD5",
-        "TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
-        "TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
         "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",
-        "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5"
+        "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",
+        "TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
+        "TLS_KRB5_EXPORT_WITH_RC4_40_MD5"
     );
 
     private final static String[] protocols = {
diff --git a/jdk/test/sun/text/resources/LocaleData b/jdk/test/sun/text/resources/LocaleData
index 9dca93b..f6439c2 100644
--- a/jdk/test/sun/text/resources/LocaleData
+++ b/jdk/test/sun/text/resources/LocaleData
@@ -2502,7 +2502,7 @@
 CalendarData/pl_PL/minimalDaysInFirstWeek=4
 CalendarData/pt_PT/minimalDaysInFirstWeek=4
 
-#bug 4945388 
+#bug 4945388
 CurrencyNames/be_BY/BYR=\u0420\u0443\u0431
 CurrencyNames/bg_BG/BGN=\u043B\u0432.
 
@@ -5422,7 +5422,7 @@
 FormatData/en_SG/DatePatterns/2=MMM d, yyyy
 FormatData/en_SG/DatePatterns/3=M/d/yy
 FormatData/en_SG/DateTimePatterns/0={1} {0}
-# Use approved data 
+# Use approved data
 FormatData/ms/Eras/0=BCE
 FormatData/ms/Eras/1=CE
 FormatData/sr_BA/MonthNames/5=\u0458\u0443\u043d\u0438
@@ -5571,7 +5571,7 @@
 FormatData/fi/AmPmMarkers/0=ap.
 FormatData/fi/AmPmMarkers/1=ip.
 
-# bug 6507067 
+# bug 6507067
 TimeZoneNames/zh_TW/Asia\/Taipei/1=\u53f0\u7063\u6a19\u6e96\u6642\u9593
 TimeZoneNames/zh_TW/Asia\/Taipei/2=TST
 
@@ -7702,3 +7702,577 @@
 
 # bug 8055222
 CurrencyNames/lt_LT/EUR=\u20AC
+
+# bug 8042126 + missing MonthNarrows data
+FormatData//MonthNarrows/0=1
+FormatData//MonthNarrows/1=2
+FormatData//MonthNarrows/2=3
+FormatData//MonthNarrows/3=4
+FormatData//MonthNarrows/4=5
+FormatData//MonthNarrows/5=6
+FormatData//MonthNarrows/6=7
+FormatData//MonthNarrows/7=8
+FormatData//MonthNarrows/8=9
+FormatData//MonthNarrows/9=10
+FormatData//MonthNarrows/10=11
+FormatData//MonthNarrows/11=12
+FormatData//MonthNarrows/12=
+FormatData/bg/MonthNarrows/0=\u044f
+FormatData/bg/MonthNarrows/1=\u0444
+FormatData/bg/MonthNarrows/2=\u043c
+FormatData/bg/MonthNarrows/3=\u0430
+FormatData/bg/MonthNarrows/4=\u043c
+FormatData/bg/MonthNarrows/5=\u044e
+FormatData/bg/MonthNarrows/6=\u044e
+FormatData/bg/MonthNarrows/7=\u0430
+FormatData/bg/MonthNarrows/8=\u0441
+FormatData/bg/MonthNarrows/9=\u043e
+FormatData/bg/MonthNarrows/10=\u043d
+FormatData/bg/MonthNarrows/11=\u0434
+FormatData/bg/MonthNarrows/12=
+FormatData/zh_TW/MonthNarrows/0=1
+FormatData/zh_TW/MonthNarrows/1=2
+FormatData/zh_TW/MonthNarrows/2=3
+FormatData/zh_TW/MonthNarrows/3=4
+FormatData/zh_TW/MonthNarrows/4=5
+FormatData/zh_TW/MonthNarrows/5=6
+FormatData/zh_TW/MonthNarrows/6=7
+FormatData/zh_TW/MonthNarrows/7=8
+FormatData/zh_TW/MonthNarrows/8=9
+FormatData/zh_TW/MonthNarrows/9=10
+FormatData/zh_TW/MonthNarrows/10=11
+FormatData/zh_TW/MonthNarrows/11=12
+FormatData/zh_TW/MonthNarrows/12=
+FormatData/it/MonthNarrows/0=G
+FormatData/it/MonthNarrows/1=F
+FormatData/it/MonthNarrows/2=M
+FormatData/it/MonthNarrows/3=A
+FormatData/it/MonthNarrows/4=M
+FormatData/it/MonthNarrows/5=G
+FormatData/it/MonthNarrows/6=L
+FormatData/it/MonthNarrows/7=A
+FormatData/it/MonthNarrows/8=S
+FormatData/it/MonthNarrows/9=O
+FormatData/it/MonthNarrows/10=N
+FormatData/it/MonthNarrows/11=D
+FormatData/it/MonthNarrows/12=
+FormatData/ko/MonthNarrows/0=1\uc6d4
+FormatData/ko/MonthNarrows/1=2\uc6d4
+FormatData/ko/MonthNarrows/2=3\uc6d4
+FormatData/ko/MonthNarrows/3=4\uc6d4
+FormatData/ko/MonthNarrows/4=5\uc6d4
+FormatData/ko/MonthNarrows/5=6\uc6d4
+FormatData/ko/MonthNarrows/6=7\uc6d4
+FormatData/ko/MonthNarrows/7=8\uc6d4
+FormatData/ko/MonthNarrows/8=9\uc6d4
+FormatData/ko/MonthNarrows/9=10\uc6d4
+FormatData/ko/MonthNarrows/10=11\uc6d4
+FormatData/ko/MonthNarrows/11=12\uc6d4
+FormatData/ko/MonthNarrows/12=
+FormatData/uk/MonthNarrows/0=\u0421
+FormatData/uk/MonthNarrows/1=\u041b
+FormatData/uk/MonthNarrows/2=\u0411
+FormatData/uk/MonthNarrows/3=\u041a
+FormatData/uk/MonthNarrows/4=\u0422
+FormatData/uk/MonthNarrows/5=\u0427
+FormatData/uk/MonthNarrows/6=\u041b
+FormatData/uk/MonthNarrows/7=\u0421
+FormatData/uk/MonthNarrows/8=\u0412
+FormatData/uk/MonthNarrows/9=\u0416
+FormatData/uk/MonthNarrows/10=\u041b
+FormatData/uk/MonthNarrows/11=\u0413
+FormatData/uk/MonthNarrows/12=
+FormatData/lv/MonthNarrows/0=J
+FormatData/lv/MonthNarrows/1=F
+FormatData/lv/MonthNarrows/2=M
+FormatData/lv/MonthNarrows/3=A
+FormatData/lv/MonthNarrows/4=M
+FormatData/lv/MonthNarrows/5=J
+FormatData/lv/MonthNarrows/6=J
+FormatData/lv/MonthNarrows/7=A
+FormatData/lv/MonthNarrows/8=S
+FormatData/lv/MonthNarrows/9=O
+FormatData/lv/MonthNarrows/10=N
+FormatData/lv/MonthNarrows/11=D
+FormatData/lv/MonthNarrows/12=
+FormatData/pt/MonthNarrows/0=J
+FormatData/pt/MonthNarrows/1=F
+FormatData/pt/MonthNarrows/2=M
+FormatData/pt/MonthNarrows/3=A
+FormatData/pt/MonthNarrows/4=M
+FormatData/pt/MonthNarrows/5=J
+FormatData/pt/MonthNarrows/6=J
+FormatData/pt/MonthNarrows/7=A
+FormatData/pt/MonthNarrows/8=S
+FormatData/pt/MonthNarrows/9=O
+FormatData/pt/MonthNarrows/10=N
+FormatData/pt/MonthNarrows/11=D
+FormatData/pt/MonthNarrows/12=
+FormatData/sk/MonthNarrows/0=j
+FormatData/sk/MonthNarrows/1=f
+FormatData/sk/MonthNarrows/2=m
+FormatData/sk/MonthNarrows/3=a
+FormatData/sk/MonthNarrows/4=m
+FormatData/sk/MonthNarrows/5=j
+FormatData/sk/MonthNarrows/6=j
+FormatData/sk/MonthNarrows/7=a
+FormatData/sk/MonthNarrows/8=s
+FormatData/sk/MonthNarrows/9=o
+FormatData/sk/MonthNarrows/10=n
+FormatData/sk/MonthNarrows/11=d
+FormatData/sk/MonthNarrows/12=
+FormatData/hi_IN/MonthNarrows/0=\u091c
+FormatData/hi_IN/MonthNarrows/1=\u092b\u093c
+FormatData/hi_IN/MonthNarrows/2=\u092e\u093e
+FormatData/hi_IN/MonthNarrows/3=\u0905
+FormatData/hi_IN/MonthNarrows/4=\u092e
+FormatData/hi_IN/MonthNarrows/5=\u091c\u0942
+FormatData/hi_IN/MonthNarrows/6=\u091c\u0941
+FormatData/hi_IN/MonthNarrows/7=\u0905
+FormatData/hi_IN/MonthNarrows/8=\u0938\u093f
+FormatData/hi_IN/MonthNarrows/9=\u0905
+FormatData/hi_IN/MonthNarrows/10=\u0928
+FormatData/hi_IN/MonthNarrows/11=\u0926\u093f
+FormatData/hi_IN/MonthNarrows/12=
+FormatData/ga/MonthNarrows/0=E
+FormatData/ga/MonthNarrows/1=F
+FormatData/ga/MonthNarrows/2=M
+FormatData/ga/MonthNarrows/3=A
+FormatData/ga/MonthNarrows/4=B
+FormatData/ga/MonthNarrows/5=M
+FormatData/ga/MonthNarrows/6=I
+FormatData/ga/MonthNarrows/7=L
+FormatData/ga/MonthNarrows/8=M
+FormatData/ga/MonthNarrows/9=D
+FormatData/ga/MonthNarrows/10=S
+FormatData/ga/MonthNarrows/11=N
+FormatData/ga/MonthNarrows/12=
+FormatData/et/MonthNarrows/0=J
+FormatData/et/MonthNarrows/1=V
+FormatData/et/MonthNarrows/2=M
+FormatData/et/MonthNarrows/3=A
+FormatData/et/MonthNarrows/4=M
+FormatData/et/MonthNarrows/5=J
+FormatData/et/MonthNarrows/6=J
+FormatData/et/MonthNarrows/7=A
+FormatData/et/MonthNarrows/8=S
+FormatData/et/MonthNarrows/9=O
+FormatData/et/MonthNarrows/10=N
+FormatData/et/MonthNarrows/11=D
+FormatData/et/MonthNarrows/12=
+FormatData/sv/MonthNarrows/0=J
+FormatData/sv/MonthNarrows/1=F
+FormatData/sv/MonthNarrows/2=M
+FormatData/sv/MonthNarrows/3=A
+FormatData/sv/MonthNarrows/4=M
+FormatData/sv/MonthNarrows/5=J
+FormatData/sv/MonthNarrows/6=J
+FormatData/sv/MonthNarrows/7=A
+FormatData/sv/MonthNarrows/8=S
+FormatData/sv/MonthNarrows/9=O
+FormatData/sv/MonthNarrows/10=N
+FormatData/sv/MonthNarrows/11=D
+FormatData/sv/MonthNarrows/12=
+FormatData/cs/MonthNarrows/0=l
+FormatData/cs/MonthNarrows/1=\u00fa
+FormatData/cs/MonthNarrows/2=b
+FormatData/cs/MonthNarrows/3=d
+FormatData/cs/MonthNarrows/4=k
+FormatData/cs/MonthNarrows/5=\u010d
+FormatData/cs/MonthNarrows/6=\u010d
+FormatData/cs/MonthNarrows/7=s
+FormatData/cs/MonthNarrows/8=z
+FormatData/cs/MonthNarrows/9=\u0159
+FormatData/cs/MonthNarrows/10=l
+FormatData/cs/MonthNarrows/11=p
+FormatData/cs/MonthNarrows/12=
+FormatData/el/MonthNarrows/0=\u0399
+FormatData/el/MonthNarrows/1=\u03a6
+FormatData/el/MonthNarrows/2=\u039c
+FormatData/el/MonthNarrows/3=\u0391
+FormatData/el/MonthNarrows/4=\u039c
+FormatData/el/MonthNarrows/5=\u0399
+FormatData/el/MonthNarrows/6=\u0399
+FormatData/el/MonthNarrows/7=\u0391
+FormatData/el/MonthNarrows/8=\u03a3
+FormatData/el/MonthNarrows/9=\u039f
+FormatData/el/MonthNarrows/10=\u039d
+FormatData/el/MonthNarrows/11=\u0394
+FormatData/el/MonthNarrows/12=
+FormatData/hu/MonthNarrows/0=J
+FormatData/hu/MonthNarrows/1=F
+FormatData/hu/MonthNarrows/2=M
+FormatData/hu/MonthNarrows/3=\u00c1
+FormatData/hu/MonthNarrows/4=M
+FormatData/hu/MonthNarrows/5=J
+FormatData/hu/MonthNarrows/6=J
+FormatData/hu/MonthNarrows/7=A
+FormatData/hu/MonthNarrows/8=Sz
+FormatData/hu/MonthNarrows/9=O
+FormatData/hu/MonthNarrows/10=N
+FormatData/hu/MonthNarrows/11=D
+FormatData/hu/MonthNarrows/12=
+FormatData/es/MonthNarrows/0=E
+FormatData/es/MonthNarrows/1=F
+FormatData/es/MonthNarrows/2=M
+FormatData/es/MonthNarrows/3=A
+FormatData/es/MonthNarrows/4=M
+FormatData/es/MonthNarrows/5=J
+FormatData/es/MonthNarrows/6=J
+FormatData/es/MonthNarrows/7=A
+FormatData/es/MonthNarrows/8=S
+FormatData/es/MonthNarrows/9=O
+FormatData/es/MonthNarrows/10=N
+FormatData/es/MonthNarrows/11=D
+FormatData/es/MonthNarrows/12=
+FormatData/tr/MonthNarrows/0=O
+FormatData/tr/MonthNarrows/1=\u015e
+FormatData/tr/MonthNarrows/2=M
+FormatData/tr/MonthNarrows/3=N
+FormatData/tr/MonthNarrows/4=M
+FormatData/tr/MonthNarrows/5=H
+FormatData/tr/MonthNarrows/6=T
+FormatData/tr/MonthNarrows/7=A
+FormatData/tr/MonthNarrows/8=E
+FormatData/tr/MonthNarrows/9=E
+FormatData/tr/MonthNarrows/10=K
+FormatData/tr/MonthNarrows/11=A
+FormatData/tr/MonthNarrows/12=
+FormatData/hr/MonthNarrows/0=1.
+FormatData/hr/MonthNarrows/1=2.
+FormatData/hr/MonthNarrows/2=3.
+FormatData/hr/MonthNarrows/3=4.
+FormatData/hr/MonthNarrows/4=5.
+FormatData/hr/MonthNarrows/5=6.
+FormatData/hr/MonthNarrows/6=7.
+FormatData/hr/MonthNarrows/7=8.
+FormatData/hr/MonthNarrows/8=9.
+FormatData/hr/MonthNarrows/9=10.
+FormatData/hr/MonthNarrows/10=11.
+FormatData/hr/MonthNarrows/11=12.
+FormatData/hr/MonthNarrows/12=
+FormatData/lt/MonthNarrows/0=S
+FormatData/lt/MonthNarrows/1=V
+FormatData/lt/MonthNarrows/2=K
+FormatData/lt/MonthNarrows/3=B
+FormatData/lt/MonthNarrows/4=G
+FormatData/lt/MonthNarrows/5=B
+FormatData/lt/MonthNarrows/6=L
+FormatData/lt/MonthNarrows/7=R
+FormatData/lt/MonthNarrows/8=R
+FormatData/lt/MonthNarrows/9=S
+FormatData/lt/MonthNarrows/10=L
+FormatData/lt/MonthNarrows/11=G
+FormatData/lt/MonthNarrows/12=
+FormatData/sq/MonthNarrows/0=J
+FormatData/sq/MonthNarrows/1=S
+FormatData/sq/MonthNarrows/2=M
+FormatData/sq/MonthNarrows/3=P
+FormatData/sq/MonthNarrows/4=M
+FormatData/sq/MonthNarrows/5=Q
+FormatData/sq/MonthNarrows/6=K
+FormatData/sq/MonthNarrows/7=G
+FormatData/sq/MonthNarrows/8=S
+FormatData/sq/MonthNarrows/9=T
+FormatData/sq/MonthNarrows/10=N
+FormatData/sq/MonthNarrows/11=D
+FormatData/sq/MonthNarrows/12=
+FormatData/fr/MonthNarrows/0=J
+FormatData/fr/MonthNarrows/1=F
+FormatData/fr/MonthNarrows/2=M
+FormatData/fr/MonthNarrows/3=A
+FormatData/fr/MonthNarrows/4=M
+FormatData/fr/MonthNarrows/5=J
+FormatData/fr/MonthNarrows/6=J
+FormatData/fr/MonthNarrows/7=A
+FormatData/fr/MonthNarrows/8=S
+FormatData/fr/MonthNarrows/9=O
+FormatData/fr/MonthNarrows/10=N
+FormatData/fr/MonthNarrows/11=D
+FormatData/fr/MonthNarrows/12=
+FormatData/is/MonthNarrows/0=J
+FormatData/is/MonthNarrows/1=F
+FormatData/is/MonthNarrows/2=M
+FormatData/is/MonthNarrows/3=A
+FormatData/is/MonthNarrows/4=M
+FormatData/is/MonthNarrows/5=J
+FormatData/is/MonthNarrows/6=J
+FormatData/is/MonthNarrows/7=\u00c1
+FormatData/is/MonthNarrows/8=L
+FormatData/is/MonthNarrows/9=O
+FormatData/is/MonthNarrows/10=N
+FormatData/is/MonthNarrows/11=D
+FormatData/is/MonthNarrows/12=
+FormatData/de/MonthNarrows/0=J
+FormatData/de/MonthNarrows/1=F
+FormatData/de/MonthNarrows/2=M
+FormatData/de/MonthNarrows/3=A
+FormatData/de/MonthNarrows/4=M
+FormatData/de/MonthNarrows/5=J
+FormatData/de/MonthNarrows/6=J
+FormatData/de/MonthNarrows/7=A
+FormatData/de/MonthNarrows/8=S
+FormatData/de/MonthNarrows/9=O
+FormatData/de/MonthNarrows/10=N
+FormatData/de/MonthNarrows/11=D
+FormatData/de/MonthNarrows/12=
+FormatData/en/MonthNarrows/0=J
+FormatData/en/MonthNarrows/1=F
+FormatData/en/MonthNarrows/2=M
+FormatData/en/MonthNarrows/3=A
+FormatData/en/MonthNarrows/4=M
+FormatData/en/MonthNarrows/5=J
+FormatData/en/MonthNarrows/6=J
+FormatData/en/MonthNarrows/7=A
+FormatData/en/MonthNarrows/8=S
+FormatData/en/MonthNarrows/9=O
+FormatData/en/MonthNarrows/10=N
+FormatData/en/MonthNarrows/11=D
+FormatData/en/MonthNarrows/12=
+FormatData/ca/MonthNarrows/0=G
+FormatData/ca/MonthNarrows/1=F
+FormatData/ca/MonthNarrows/2=M
+FormatData/ca/MonthNarrows/3=A
+FormatData/ca/MonthNarrows/4=M
+FormatData/ca/MonthNarrows/5=J
+FormatData/ca/MonthNarrows/6=G
+FormatData/ca/MonthNarrows/7=A
+FormatData/ca/MonthNarrows/8=S
+FormatData/ca/MonthNarrows/9=O
+FormatData/ca/MonthNarrows/10=N
+FormatData/ca/MonthNarrows/11=D
+FormatData/ca/MonthNarrows/12=
+FormatData/sl/MonthNarrows/0=j
+FormatData/sl/MonthNarrows/1=f
+FormatData/sl/MonthNarrows/2=m
+FormatData/sl/MonthNarrows/3=a
+FormatData/sl/MonthNarrows/4=m
+FormatData/sl/MonthNarrows/5=j
+FormatData/sl/MonthNarrows/6=j
+FormatData/sl/MonthNarrows/7=a
+FormatData/sl/MonthNarrows/8=s
+FormatData/sl/MonthNarrows/9=o
+FormatData/sl/MonthNarrows/10=n
+FormatData/sl/MonthNarrows/11=d
+FormatData/sl/MonthNarrows/12=
+FormatData/fi/MonthNarrows/0=T
+FormatData/fi/MonthNarrows/1=H
+FormatData/fi/MonthNarrows/2=M
+FormatData/fi/MonthNarrows/3=H
+FormatData/fi/MonthNarrows/4=T
+FormatData/fi/MonthNarrows/5=K
+FormatData/fi/MonthNarrows/6=H
+FormatData/fi/MonthNarrows/7=E
+FormatData/fi/MonthNarrows/8=S
+FormatData/fi/MonthNarrows/9=L
+FormatData/fi/MonthNarrows/10=M
+FormatData/fi/MonthNarrows/11=J
+FormatData/fi/MonthNarrows/12=
+FormatData/mk/MonthNarrows/0=\u0458
+FormatData/mk/MonthNarrows/1=\u0444
+FormatData/mk/MonthNarrows/2=\u043c
+FormatData/mk/MonthNarrows/3=\u0430
+FormatData/mk/MonthNarrows/4=\u043c
+FormatData/mk/MonthNarrows/5=\u0458
+FormatData/mk/MonthNarrows/6=\u0458
+FormatData/mk/MonthNarrows/7=\u0430
+FormatData/mk/MonthNarrows/8=\u0441
+FormatData/mk/MonthNarrows/9=\u043e
+FormatData/mk/MonthNarrows/10=\u043d
+FormatData/mk/MonthNarrows/11=\u0434
+FormatData/mk/MonthNarrows/12=
+FormatData/sr-Latn/MonthNarrows/0=j
+FormatData/sr-Latn/MonthNarrows/1=f
+FormatData/sr-Latn/MonthNarrows/2=m
+FormatData/sr-Latn/MonthNarrows/3=a
+FormatData/sr-Latn/MonthNarrows/4=m
+FormatData/sr-Latn/MonthNarrows/5=j
+FormatData/sr-Latn/MonthNarrows/6=j
+FormatData/sr-Latn/MonthNarrows/7=a
+FormatData/sr-Latn/MonthNarrows/8=s
+FormatData/sr-Latn/MonthNarrows/9=o
+FormatData/sr-Latn/MonthNarrows/10=n
+FormatData/sr-Latn/MonthNarrows/11=d
+FormatData/sr-Latn/MonthNarrows/12=
+FormatData/th/MonthNarrows/0=\u0e21.\u0e04.
+FormatData/th/MonthNarrows/1=\u0e01.\u0e1e.
+FormatData/th/MonthNarrows/2=\u0e21\u0e35.\u0e04.
+FormatData/th/MonthNarrows/3=\u0e40\u0e21.\u0e22.
+FormatData/th/MonthNarrows/4=\u0e1e.\u0e04.
+FormatData/th/MonthNarrows/5=\u0e21\u0e34.\u0e22
+FormatData/th/MonthNarrows/6=\u0e01.\u0e04.
+FormatData/th/MonthNarrows/7=\u0e2a.\u0e04.
+FormatData/th/MonthNarrows/8=\u0e01.\u0e22.
+FormatData/th/MonthNarrows/9=\u0e15.\u0e04.
+FormatData/th/MonthNarrows/10=\u0e1e.\u0e22.
+FormatData/th/MonthNarrows/11=\u0e18.\u0e04.
+FormatData/th/MonthNarrows/12=
+FormatData/ar/MonthNarrows/0=\u064a
+FormatData/ar/MonthNarrows/1=\u0641
+FormatData/ar/MonthNarrows/2=\u0645
+FormatData/ar/MonthNarrows/3=\u0623
+FormatData/ar/MonthNarrows/4=\u0648
+FormatData/ar/MonthNarrows/5=\u0646
+FormatData/ar/MonthNarrows/6=\u0644
+FormatData/ar/MonthNarrows/7=\u063a
+FormatData/ar/MonthNarrows/8=\u0633
+FormatData/ar/MonthNarrows/9=\u0643
+FormatData/ar/MonthNarrows/10=\u0628
+FormatData/ar/MonthNarrows/11=\u062f
+FormatData/ar/MonthNarrows/12=
+FormatData/ru/MonthNarrows/0=\u042f
+FormatData/ru/MonthNarrows/1=\u0424
+FormatData/ru/MonthNarrows/2=\u041c
+FormatData/ru/MonthNarrows/3=\u0410
+FormatData/ru/MonthNarrows/4=\u041c
+FormatData/ru/MonthNarrows/5=\u0418
+FormatData/ru/MonthNarrows/6=\u0418
+FormatData/ru/MonthNarrows/7=\u0410
+FormatData/ru/MonthNarrows/8=\u0421
+FormatData/ru/MonthNarrows/9=\u041e
+FormatData/ru/MonthNarrows/10=\u041d
+FormatData/ru/MonthNarrows/11=\u0414
+FormatData/ru/MonthNarrows/12=
+FormatData/ms/MonthNarrows/0=J
+FormatData/ms/MonthNarrows/1=F
+FormatData/ms/MonthNarrows/2=M
+FormatData/ms/MonthNarrows/3=A
+FormatData/ms/MonthNarrows/4=M
+FormatData/ms/MonthNarrows/5=J
+FormatData/ms/MonthNarrows/6=J
+FormatData/ms/MonthNarrows/7=O
+FormatData/ms/MonthNarrows/8=S
+FormatData/ms/MonthNarrows/9=O
+FormatData/ms/MonthNarrows/10=N
+FormatData/ms/MonthNarrows/11=D
+FormatData/ms/MonthNarrows/12=
+FormatData/nl/MonthNarrows/0=J
+FormatData/nl/MonthNarrows/1=F
+FormatData/nl/MonthNarrows/2=M
+FormatData/nl/MonthNarrows/3=A
+FormatData/nl/MonthNarrows/4=M
+FormatData/nl/MonthNarrows/5=J
+FormatData/nl/MonthNarrows/6=J
+FormatData/nl/MonthNarrows/7=A
+FormatData/nl/MonthNarrows/8=S
+FormatData/nl/MonthNarrows/9=O
+FormatData/nl/MonthNarrows/10=N
+FormatData/nl/MonthNarrows/11=D
+FormatData/nl/MonthNarrows/12=
+FormatData/vi/MonthNarrows/0=1
+FormatData/vi/MonthNarrows/1=2
+FormatData/vi/MonthNarrows/2=3
+FormatData/vi/MonthNarrows/3=4
+FormatData/vi/MonthNarrows/4=5
+FormatData/vi/MonthNarrows/5=6
+FormatData/vi/MonthNarrows/6=7
+FormatData/vi/MonthNarrows/7=8
+FormatData/vi/MonthNarrows/8=9
+FormatData/vi/MonthNarrows/9=10
+FormatData/vi/MonthNarrows/10=11
+FormatData/vi/MonthNarrows/11=12
+FormatData/vi/MonthNarrows/12=
+FormatData/sr/MonthNarrows/0=\u0458
+FormatData/sr/MonthNarrows/1=\u0444
+FormatData/sr/MonthNarrows/2=\u043c
+FormatData/sr/MonthNarrows/3=\u0430
+FormatData/sr/MonthNarrows/4=\u043c
+FormatData/sr/MonthNarrows/5=\u0458
+FormatData/sr/MonthNarrows/6=\u0458
+FormatData/sr/MonthNarrows/7=\u0430
+FormatData/sr/MonthNarrows/8=\u0441
+FormatData/sr/MonthNarrows/9=\u043e
+FormatData/sr/MonthNarrows/10=\u043d
+FormatData/sr/MonthNarrows/11=\u0434
+FormatData/sr/MonthNarrows/12=
+FormatData/mt/MonthNarrows/0=J
+FormatData/mt/MonthNarrows/1=F
+FormatData/mt/MonthNarrows/2=M
+FormatData/mt/MonthNarrows/3=A
+FormatData/mt/MonthNarrows/4=M
+FormatData/mt/MonthNarrows/5=\u0120
+FormatData/mt/MonthNarrows/6=L
+FormatData/mt/MonthNarrows/7=A
+FormatData/mt/MonthNarrows/8=S
+FormatData/mt/MonthNarrows/9=O
+FormatData/mt/MonthNarrows/10=N
+FormatData/mt/MonthNarrows/11=D
+FormatData/mt/MonthNarrows/12=
+FormatData/da/MonthNarrows/0=J
+FormatData/da/MonthNarrows/1=F
+FormatData/da/MonthNarrows/2=M
+FormatData/da/MonthNarrows/3=A
+FormatData/da/MonthNarrows/4=M
+FormatData/da/MonthNarrows/5=J
+FormatData/da/MonthNarrows/6=J
+FormatData/da/MonthNarrows/7=A
+FormatData/da/MonthNarrows/8=S
+FormatData/da/MonthNarrows/9=O
+FormatData/da/MonthNarrows/10=N
+FormatData/da/MonthNarrows/11=D
+FormatData/da/MonthNarrows/12=
+FormatData/ro/MonthNarrows/0=I
+FormatData/ro/MonthNarrows/1=F
+FormatData/ro/MonthNarrows/2=M
+FormatData/ro/MonthNarrows/3=A
+FormatData/ro/MonthNarrows/4=M
+FormatData/ro/MonthNarrows/5=I
+FormatData/ro/MonthNarrows/6=I
+FormatData/ro/MonthNarrows/7=A
+FormatData/ro/MonthNarrows/8=S
+FormatData/ro/MonthNarrows/9=O
+FormatData/ro/MonthNarrows/10=N
+FormatData/ro/MonthNarrows/11=D
+FormatData/ro/MonthNarrows/12=
+FormatData/no/MonthNarrows/0=J
+FormatData/no/MonthNarrows/1=F
+FormatData/no/MonthNarrows/2=M
+FormatData/no/MonthNarrows/3=A
+FormatData/no/MonthNarrows/4=M
+FormatData/no/MonthNarrows/5=J
+FormatData/no/MonthNarrows/6=J
+FormatData/no/MonthNarrows/7=A
+FormatData/no/MonthNarrows/8=S
+FormatData/no/MonthNarrows/9=O
+FormatData/no/MonthNarrows/10=N
+FormatData/no/MonthNarrows/11=D
+FormatData/no/MonthNarrows/12=
+FormatData/pl/MonthNarrows/0=s
+FormatData/pl/MonthNarrows/1=l
+FormatData/pl/MonthNarrows/2=m
+FormatData/pl/MonthNarrows/3=k
+FormatData/pl/MonthNarrows/4=m
+FormatData/pl/MonthNarrows/5=c
+FormatData/pl/MonthNarrows/6=l
+FormatData/pl/MonthNarrows/7=s
+FormatData/pl/MonthNarrows/8=w
+FormatData/pl/MonthNarrows/9=p
+FormatData/pl/MonthNarrows/10=l
+FormatData/pl/MonthNarrows/11=g
+FormatData/pl/MonthNarrows/12=
+FormatData/iw/MonthNarrows/0=1
+FormatData/iw/MonthNarrows/1=2
+FormatData/iw/MonthNarrows/2=3
+FormatData/iw/MonthNarrows/3=4
+FormatData/iw/MonthNarrows/4=5
+FormatData/iw/MonthNarrows/5=6
+FormatData/iw/MonthNarrows/6=7
+FormatData/iw/MonthNarrows/7=8
+FormatData/iw/MonthNarrows/8=9
+FormatData/iw/MonthNarrows/9=10
+FormatData/iw/MonthNarrows/10=11
+FormatData/iw/MonthNarrows/11=12
+FormatData/iw/MonthNarrows/12=
+FormatData/zh/MonthNarrows/0=1
+FormatData/zh/MonthNarrows/1=2
+FormatData/zh/MonthNarrows/2=3
+FormatData/zh/MonthNarrows/3=4
+FormatData/zh/MonthNarrows/4=5
+FormatData/zh/MonthNarrows/5=6
+FormatData/zh/MonthNarrows/6=7
+FormatData/zh/MonthNarrows/7=8
+FormatData/zh/MonthNarrows/8=9
+FormatData/zh/MonthNarrows/9=10
+FormatData/zh/MonthNarrows/10=11
+FormatData/zh/MonthNarrows/11=12
+FormatData/zh/MonthNarrows/12=
diff --git a/jdk/test/sun/text/resources/LocaleDataTest.java b/jdk/test/sun/text/resources/LocaleDataTest.java
index e2cea1a..6ac5dc5 100644
--- a/jdk/test/sun/text/resources/LocaleDataTest.java
+++ b/jdk/test/sun/text/resources/LocaleDataTest.java
@@ -36,7 +36,7 @@
  *      6919624 6998391 7019267 7020960 7025837 7020583 7036905 7066203 7101495
  *      7003124 7085757 7028073 7171028 7189611 8000983 7195759 8004489 8006509
  *      7114053 7074882 7040556 8013836 8021121 6192407 6931564 8027695 7090826
- *      8017142 8037343 8055222
+ *      8017142 8037343 8055222 8042126
  * @summary Verify locale data
  *
  */
diff --git a/langtools/.hgtags b/langtools/.hgtags
index aef91d8..2d373eb 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -312,6 +312,25 @@
 9239118487dfb47ee850d2cc9b10a0a2e510da3c jdk8u20-b24
 9239118487dfb47ee850d2cc9b10a0a2e510da3c jdk8u20-b25
 5e6d409a72327a31b8a8f9aa0b32ef213c8b629c jdk8u20-b26
+f491f1581f196950c2cb858508dd06601968c417 jdk8u25-b00
+5bc865e0a2e3c59c1c8bc41e731509e1737ddea1 jdk8u25-b01
+4dec0c684a9ead80ea2bca6b042682367c1abf90 jdk8u25-b02
+1d039298d33f8062a0aa75442bd39434e16ee2df jdk8u25-b03
+5c806c4b2830056caaca3329e634ff040bfe1c7b jdk8u25-b04
+f1625806cabab809993fbc650b77c5a28d70035d jdk8u25-b05
+7a6309461a7294cc78789f547b0a652757d17156 jdk8u25-b06
+aad835b33337c22f4d632c2531c453de00a8f778 jdk8u25-b07
+224b8260b2c72e2902e48522240c97de11b3570a jdk8u25-b08
+a5fa1a2bd63cfcce67dae074c07cd0f2baa8ddc0 jdk8u25-b09
+0dfd4099658397efa118918cd43f79e194c320ea jdk8u25-b10
+eee8277448304f5d785310edff072d993a0c1868 jdk8u25-b11
+664a10268f61616b682985855015663c30d0476f jdk8u25-b12
+89b2f04998c7a1f987cadb4c42801d1ec500a870 jdk8u25-b13
+a340d68b020585cad7aa6e38d1aafb19ad0e4e07 jdk8u25-b14
+6e0c19cd42d7c4d307bea26840ee831cbd14e2fc jdk8u25-b15
+7fa6fa7cc204de988e224c6f8f75e62128fa84cd jdk8u25-b16
+53ca196be1ae098466976c017b166d4ce180c36f jdk8u25-b17
+a4f0c6dd8f97d4dd89baf09463c748abea9b3ed7 jdk8u25-b18
 d231957fe3103e790465fcf058fb8cb33bbc4c4e jdk8u40-b00
 bf89a471779d13a9407f7d1c86f7716258bc4aa6 jdk8u40-b01
 0b6cc4ea670f5d17b56c088f202869bdbb80a5ce jdk8u40-b02
@@ -321,3 +340,4 @@
 7c3d27120b92b6abbd2df910722405dfb02d4399 jdk8u40-b06
 2fa3858a281f9deae15bcc49224efd5b951b745d jdk8u40-b07
 d3515520e68e26c1012fca18eef190f8aff3a7a1 jdk8u40-b08
+8bb38a35072279618aa2cacd4fea74155a6dccf9 jdk8u40-b09
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
index 044a998..c5ea6a5 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
@@ -2032,12 +2032,11 @@
 
     void adjustAliveRanges(int oldCP, int delta) {
         for (LocalVar localVar: lvar) {
-            if (localVar == null) {
-                return;
-            }
-            for (LocalVar.Range range: localVar.aliveRanges) {
-                if (range.closed() && range.start_pc + range.length >= oldCP) {
-                    range.length += delta;
+            if (localVar != null) {
+                for (LocalVar.Range range: localVar.aliveRanges) {
+                    if (range.closed() && range.start_pc + range.length >= oldCP) {
+                        range.length += delta;
+                    }
                 }
             }
         }
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties
index abe569b..5a26687 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_ja.properties
@@ -1677,6 +1677,9 @@
 # 0: string
 compiler.err.static.intf.methods.not.supported.in.source=static\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u306F-source {0}\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\n(static\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u3092\u4F7F\u7528\u53EF\u80FD\u306B\u3059\u308B\u306B\u306F\u3001-source 8\u4EE5\u4E0A\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044)
 
+# 0: string
+compiler.err.static.intf.method.invoke.not.supported.in.source=static\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u30FB\u30E1\u30BD\u30C3\u30C9\u547C\u51FA\u3057\u306F-source {0}\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\n(static\u30A4\u30F3\u30BF\u30D5\u30A7\u30FC\u30B9\u30FB\u30E1\u30BD\u30C3\u30C9\u547C\u51FA\u3057\u3092\u4F7F\u7528\u53EF\u80FD\u306B\u3059\u308B\u306B\u306F\u3001-source 8\u4EE5\u4E0A\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044)
+
 ########################################
 # Diagnostics for verbose resolution
 # used by Resolve (debug only)
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties
index bd08ba5..45efe98 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties
@@ -1677,6 +1677,9 @@
 # 0: string
 compiler.err.static.intf.methods.not.supported.in.source=-source {0} \u4E2D\u4E0D\u652F\u6301\u9759\u6001\u63A5\u53E3\u65B9\u6CD5\n(\u8BF7\u4F7F\u7528 -source 8 \u6216\u66F4\u9AD8\u7248\u672C\u4EE5\u542F\u7528\u9759\u6001\u63A5\u53E3\u65B9\u6CD5)
 
+# 0: string
+compiler.err.static.intf.method.invoke.not.supported.in.source=-source {0} \u4E2D\u4E0D\u652F\u6301\u9759\u6001\u63A5\u53E3\u65B9\u6CD5\u8C03\u7528\n(\u8BF7\u4F7F\u7528 -source 8 \u6216\u66F4\u9AD8\u7248\u672C\u4EE5\u542F\u7528\u9759\u6001\u63A5\u53E3\u65B9\u6CD5\u8C03\u7528)
+
 ########################################
 # Diagnostics for verbose resolution
 # used by Resolve (debug only)
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/javac_ja.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/javac_ja.properties
index 506adc6..17d96af 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/javac_ja.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/javac_ja.properties
@@ -37,7 +37,7 @@
 javac.opt.Xbootclasspath.p=\u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306B\u4ED8\u52A0\u3059\u308B
 javac.opt.Xbootclasspath.a=\u30D6\u30FC\u30C8\u30B9\u30C8\u30E9\u30C3\u30D7\u30FB\u30AF\u30E9\u30B9\u30FB\u30D1\u30B9\u306B\u8FFD\u52A0\u3059\u308B
 javac.opt.endorseddirs=\u63A8\u5968\u898F\u683C\u30D1\u30B9\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B
-javac.opt.extdirs=\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u6E08\u307F\u62E1\u5F35\u6A5F\u80FD\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B
+javac.opt.extdirs=\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u6E08\u62E1\u5F35\u6A5F\u80FD\u306E\u5834\u6240\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3059\u308B
 javac.opt.processorpath=\u6CE8\u91C8\u30D7\u30ED\u30BB\u30C3\u30B5\u3092\u691C\u7D22\u3059\u308B\u4F4D\u7F6E\u3092\u6307\u5B9A\u3059\u308B
 javac.opt.processor=\u5B9F\u884C\u3059\u308B\u6CE8\u91C8\u30D7\u30ED\u30BB\u30C3\u30B5\u306E\u540D\u524D\u3002\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u691C\u51FA\u51E6\u7406\u3092\u30D0\u30A4\u30D1\u30B9
 javac.opt.parameters=\u30E1\u30BD\u30C3\u30C9\u30FB\u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u30EA\u30D5\u30EC\u30AF\u30B7\u30E7\u30F3\u7528\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u751F\u6210\u3057\u307E\u3059
diff --git a/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps_ja.properties b/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps_ja.properties
index a5f27a0..123d68d 100644
--- a/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps_ja.properties
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps_ja.properties
@@ -1,4 +1,4 @@
-main.usage.summary=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <classes...>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001-h\u3001-?\u307E\u305F\u306F--help\u3092\u4F7F\u7528\u3057\u307E\u3059
+main.usage.summary=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <classes...>\n\u4F7F\u7528\u53EF\u80FD\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u30EA\u30B9\u30C8\u306B\u3064\u3044\u3066\u306F\u3001-h\u3001-?\u307E\u305F\u306F-help\u3092\u4F7F\u7528\u3057\u307E\u3059
 
 main.usage=\u4F7F\u7528\u65B9\u6CD5: {0} <options> <classes...>\n<classes>\u306B\u306F\u3001.class\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9\u540D\u3001\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3001JAR\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u5B8C\u5168\u4FEE\u98FE\n\u30AF\u30E9\u30B9\u540D\u3092\u6307\u5B9A\u3067\u304D\u307E\u3059\u3002\u4F7F\u7528\u3067\u304D\u308B\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059:
 
@@ -9,21 +9,23 @@
 
 main.opt.version=\  -version                           \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831
 
-main.opt.v=\  -v           -verbose              \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u3059\u3079\u3066\u51FA\u529B\u3057\u307E\u3059\n  -verbose:package                   \u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n                                     (\u540C\u3058\u30A2\u30FC\u30AB\u30A4\u30D6\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)\n  -verbose:class                     \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n                                     (\u540C\u3058\u30A2\u30FC\u30AB\u30A4\u30D6\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)
+main.opt.v=\  -v           -verbose              \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u3059\u3079\u3066\u51FA\u529B\u3057\u307E\u3059\n                                     -verbose:class -filter:none\u3068\u540C\u7B49\u3067\u3059\u3002\n  -verbose:package                   \u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n                                     (\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)\n  -verbose:class                     \u30AF\u30E9\u30B9\u30FB\u30EC\u30D9\u30EB\u306E\u4F9D\u5B58\u6027\u3092\u51FA\u529B\u3057\u307E\u3059\n                                     (\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u306F\u3001\u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u9664\u304F)
+
+main.opt.f=\  -f <regex>   -filter <regex>       \u6307\u5B9A\u306E\u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\n                                     \u8907\u6570\u56DE\u6307\u5B9A\u3055\u308C\u305F\u5834\u5408\u3001\u6700\u5F8C\u306E\u3082\u306E\u304C\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002\n  -filter:package                    \u540C\u3058\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059(\u30C7\u30D5\u30A9\u30EB\u30C8)\n  -filter:archive                    \u540C\u3058\u30A2\u30FC\u30AB\u30A4\u30D6\u5185\u306E\u4F9D\u5B58\u6027\u3092\u30D5\u30A3\u30EB\u30BF\u3057\u307E\u3059\n  -filter:none                       -filter:package\u304A\u3088\u3073-filter:archive\u306E\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0\u306F\u884C\u308F\u308C\u307E\u305B\u3093\n                                     -filter\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u6307\u5B9A\u3057\u305F\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0\u304C\u5F15\u304D\u7D9A\u304D\u9069\u7528\u3055\u308C\u307E\u3059\u3002
 
 main.opt.s=\  -s           -summary              \u4F9D\u5B58\u6027\u306E\u30B5\u30DE\u30EA\u30FC\u306E\u307F\u51FA\u529B\u3057\u307E\u3059
 
-main.opt.p=\  -p <pkgname> -package <pkgname>    \u6307\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n                                     (\u8907\u6570\u56DE\u6307\u5B9A\u53EF\u80FD)
+main.opt.p=\  -p <pkgname> -package <pkgname>    \u6307\u5B9A\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u540D\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n                                     (\u8907\u6570\u56DE\u6307\u5B9A\u53EF\u80FD)
 
-main.opt.e=\  -e <regex>   -regex <regex>        \u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u30D1\u30C3\u30B1\u30FC\u30B8\u5185\u306E\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n                                     (-p\u3068-e\u306F\u6392\u4ED6\u7684)
+main.opt.e=\  -e <regex>   -regex <regex>        \u6307\u5B9A\u306E\u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u3092\u691C\u51FA\u3057\u307E\u3059\n                                     (-p\u3068-e\u306F\u6392\u4ED6\u7684)
 
-main.opt.include=\  -include <regex>                   \u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u30AF\u30E9\u30B9\u306B\u5206\u6790\u3092\u5236\u9650\u3057\u307E\u3059\n                                     \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u5206\u6790\u5BFE\u8C61\u30AF\u30E9\u30B9\u306E\n                                     \u30EA\u30B9\u30C8\u304C\u30D5\u30A3\u30EB\u30BF\u51E6\u7406\u3055\u308C\u307E\u3059\u3002\u30D1\u30BF\u30FC\u30F3\u3092\u4F9D\u5B58\u6027\u306B\n                                     \u9069\u7528\u3059\u308B-p\u304A\u3088\u3073-e\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u3059
+main.opt.include=\  -include <regex>                   \u30D1\u30BF\u30FC\u30F3\u306B\u4E00\u81F4\u3059\u308B\u30AF\u30E9\u30B9\u306B\u5206\u6790\u3092\u5236\u9650\u3057\u307E\u3059\n                                     \u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u6307\u5B9A\u3059\u308B\u3068\u3001\u5206\u6790\u5BFE\u8C61\u30AF\u30E9\u30B9\u306E\n                                     \u30EA\u30B9\u30C8\u304C\u30D5\u30A3\u30EB\u30BF\u3055\u308C\u307E\u3059\u3002\u30D1\u30BF\u30FC\u30F3\u3092\u4F9D\u5B58\u6027\u306B\n                                     \u9069\u7528\u3059\u308B-p\u304A\u3088\u3073-e\u3068\u4E00\u7DD2\u306B\u4F7F\u7528\u3067\u304D\u307E\u3059
 
 main.opt.P=\  -P           -profile              \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3001\u307E\u305F\u306F\u30D1\u30C3\u30B1\u30FC\u30B8\u3092\u542B\u3080\u30D5\u30A1\u30A4\u30EB\u3092\u8868\u793A\u3057\u307E\u3059
 
 main.opt.cp=\  -cp <path>   -classpath <path>     \u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u5834\u6240\u3092\u6307\u5B9A\u3057\u307E\u3059
 
-main.opt.R=\  -R           -recursive            \u3059\u3079\u3066\u306E\u4F9D\u5B58\u6027\u3092\u53CD\u5FA9\u7684\u306B\u8D70\u67FB\u3057\u307E\u3059
+main.opt.R=\  -R           -recursive            \u3059\u3079\u3066\u306E\u4F9D\u5B58\u6027\u3092\u518D\u5E30\u7684\u306B\u30C8\u30E9\u30D0\u30FC\u30B9\u3057\u307E\u3059\u3002\n                                     -R\u30AA\u30D7\u30B7\u30E7\u30F3\u306F-filter:none\u3092\u610F\u5473\u3057\u307E\u3059\u3002-p\u3001-e\u3001-f\n                                     \u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001\u4E00\u81F4\u3059\u308B\u4F9D\u5B58\u6027\u306E\u307F\n                                     \u5206\u6790\u3055\u308C\u307E\u3059\u3002
 
 main.opt.apionly=\  -apionly                           \u5206\u6790\u3092API\u3001\u3064\u307E\u308A\u3001\u30D1\u30D6\u30EA\u30C3\u30AF\u30FB\u30AF\u30E9\u30B9\u306E\n                                     \u30D1\u30D6\u30EA\u30C3\u30AF\u30FB\u30E1\u30F3\u30D0\u30FC\u304A\u3088\u3073\u4FDD\u8B77\u3055\u308C\u305F\u30E1\u30F3\u30D0\u30FC\u306E\n                                     \u7F72\u540D\u306B\u304A\u3051\u308B\u4F9D\u5B58\u6027(\u30D5\u30A3\u30FC\u30EB\u30C9\u30FB\u30BF\u30A4\u30D7\u3001\u30E1\u30BD\u30C3\u30C9\u30FB\n                                     \u30D1\u30E9\u30E1\u30FC\u30BF\u30FB\u30BF\u30A4\u30D7\u3001\u623B\u3055\u308C\u305F\u30BF\u30A4\u30D7\u3001\u30C1\u30A7\u30C3\u30AF\u3055\u308C\u305F\n                                     \u4F8B\u5916\u30BF\u30A4\u30D7\u306A\u3069)\u306B\u5236\u9650\u3057\u307E\u3059
 
@@ -36,13 +38,14 @@
 
 err.unknown.option=\u4E0D\u660E\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}
 err.missing.arg={0}\u306B\u5024\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093
-err.internal.error=\u5185\u90E8\u30A8\u30E9\u30FC: {0} {1} {2}
 err.invalid.arg.for.option=\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5F15\u6570\u304C\u7121\u52B9\u3067\u3059: {0}
 err.option.after.class=\u30AA\u30D7\u30B7\u30E7\u30F3\u306F\u30AF\u30E9\u30B9\u306E\u524D\u306B\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059: {0}
 err.option.unsupported={0}\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093: {1}
 err.profiles.msg=\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u60C5\u5831\u304C\u3042\u308A\u307E\u305B\u3093
-err.dot.output.path=\u7121\u52B9\u306A\u30D1\u30B9: {0}
+err.invalid.path=\u7121\u52B9\u306A\u30D1\u30B9: {0}
 warn.invalid.arg=\u7121\u52B9\u306A\u30AF\u30E9\u30B9\u540D\u307E\u305F\u306F\u30D1\u30B9\u540D\u304C\u5B58\u5728\u3057\u307E\u305B\u3093: {0}
 warn.split.package=\u30D1\u30C3\u30B1\u30FC\u30B8{0}\u306F{1} {2}\u3067\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u307E\u3059
+warn.replace.useJDKInternals=JDK\u5185\u90E8API\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u304A\u3089\u305A\u3001JDK\u5B9F\u88C5\u5C02\u7528\u3067\u3059\u304C\u3001\u4E92\u63DB\u6027\u306A\u3057\u3067\n\u524A\u9664\u307E\u305F\u306F\u5909\u66F4\u3055\u308C\u308B\u5834\u5408\u304C\u3042\u308A\u3001\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u3092\u4E2D\u65AD\u3055\u305B\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\nJDK\u5185\u90E8API\u306E\u4F9D\u5B58\u6027\u3092\u524A\u9664\u3059\u308B\u3088\u3046\u30B3\u30FC\u30C9\u3092\u5909\u66F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002\nJDK\u5185\u90E8API\u306E\u7F6E\u63DB\u306B\u95A2\u3059\u308B\u6700\u65B0\u306E\u66F4\u65B0\u306B\u3064\u3044\u3066\u306F\u3001\u6B21\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044:\n{0}
 
 artifact.not.found=\u898B\u3064\u304B\u308A\u307E\u305B\u3093
+jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
diff --git a/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps_zh_CN.properties
index 6b3942a..c51ae8a 100644
--- a/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps_zh_CN.properties
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps_zh_CN.properties
@@ -1,4 +1,4 @@
-main.usage.summary=\u7528\u6CD5: {0} <options> <classes...>\n\u4F7F\u7528 -h, -? \u6216 --help \u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879
+main.usage.summary=\u7528\u6CD5: {0} <options> <classes...>\n\u4F7F\u7528 -h, -? \u6216 -help \u5217\u51FA\u53EF\u80FD\u7684\u9009\u9879
 
 main.usage=\u7528\u6CD5: {0} <options> <classes...>\n\u5176\u4E2D <classes> \u53EF\u4EE5\u662F .class \u6587\u4EF6, \u76EE\u5F55, JAR \u6587\u4EF6\u7684\u8DEF\u5F84\u540D,\n\u4E5F\u53EF\u4EE5\u662F\u5168\u9650\u5B9A\u7C7B\u540D\u3002\u53EF\u80FD\u7684\u9009\u9879\u5305\u62EC:
 
@@ -9,13 +9,15 @@
 
 main.opt.version=\  -version                           \u7248\u672C\u4FE1\u606F
 
-main.opt.v=\  -v           -verbose              \u8F93\u51FA\u6240\u6709\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61\n  -verbose:package                   \u8F93\u51FA\u7A0B\u5E8F\u5305\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \u4E0D\u5305\u62EC\n                                     \u540C\u4E00\u6863\u6848\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n  -verbose:class                     \u8F93\u51FA\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \u4E0D\u5305\u62EC\n                                     \u540C\u4E00\u6863\u6848\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61
+main.opt.v=\  -v           -verbose              \u8F93\u51FA\u6240\u6709\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                     \u7B49\u540C\u4E8E -verbose:class -filter:none\u3002\n  -verbose:package                   \u9ED8\u8BA4\u60C5\u51B5\u4E0B\u8F93\u51FA\u7A0B\u5E8F\u5305\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \n                                     \u4E0D\u5305\u62EC\u540C\u4E00\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n  -verbose:class                     \u9ED8\u8BA4\u60C5\u51B5\u4E0B\u8F93\u51FA\u7C7B\u7EA7\u522B\u88AB\u4F9D\u8D56\u5BF9\u8C61, \n                                     \u4E0D\u5305\u62EC\u540C\u4E00\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61
+
+main.opt.f=\  -f <regex>   -filter <regex>       \u7B5B\u9009\u4E0E\u6307\u5B9A\u6A21\u5F0F\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                     \u5982\u679C\u591A\u6B21\u6307\u5B9A, \u5219\u5C06\u4F7F\u7528\u6700\u540E\u4E00\u4E2A\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n  -filter:package                    \u7B5B\u9009\u4F4D\u4E8E\u540C\u4E00\u7A0B\u5E8F\u5305\u5185\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61 (\u9ED8\u8BA4)\n  -filter:archive                    \u7B5B\u9009\u4F4D\u4E8E\u540C\u4E00\u6863\u6848\u5185\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n  -filter:none                       \u4E0D\u4F7F\u7528 -filter:package \u548C -filter:archive \u7B5B\u9009\n                                     \u901A\u8FC7 -filter \u9009\u9879\u6307\u5B9A\u7684\u7B5B\u9009\u4ECD\u65E7\u9002\u7528\u3002
 
 main.opt.s=\  -s           -summary              \u4EC5\u8F93\u51FA\u88AB\u4F9D\u8D56\u5BF9\u8C61\u6982\u8981
 
-main.opt.p=\  -p <pkgname> -package <pkgname>    \u67E5\u627E\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                     (\u53EF\u80FD\u591A\u6B21\u6307\u5B9A)
+main.opt.p=\  -p <pkgname> -package <pkgname>    \u67E5\u627E\u4E0E\u7ED9\u5B9A\u7A0B\u5E8F\u5305\u540D\u79F0\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                     (\u53EF\u591A\u6B21\u6307\u5B9A)
 
-main.opt.e=\  -e <regex>   -regex <regex>        \u67E5\u627E\u4E0E\u6A21\u5F0F\u5339\u914D\u7684\u7A0B\u5E8F\u5305\u4E2D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                     (-p \u548C -e \u4E92\u76F8\u6392\u65A5)
+main.opt.e=\  -e <regex>   -regex <regex>        \u67E5\u627E\u4E0E\u6307\u5B9A\u6A21\u5F0F\u5339\u914D\u7684\u88AB\u4F9D\u8D56\u5BF9\u8C61\n                                     (-p \u548C -e \u4E92\u76F8\u6392\u65A5)
 
 main.opt.include=\  -include <regex>                   \u5C06\u5206\u6790\u9650\u5236\u4E3A\u4E0E\u6A21\u5F0F\u5339\u914D\u7684\u7C7B\n                                     \u6B64\u9009\u9879\u7B5B\u9009\u8981\u5206\u6790\u7684\u7C7B\u7684\u5217\u8868\u3002\n                                     \u5B83\u53EF\u4EE5\u4E0E\u5411\u88AB\u4F9D\u8D56\u5BF9\u8C61\u5E94\u7528\u6A21\u5F0F\u7684\n                                     -p \u548C -e \u7ED3\u5408\u4F7F\u7528
 
@@ -23,7 +25,7 @@
 
 main.opt.cp=\  -cp <path>   -classpath <path>     \u6307\u5B9A\u67E5\u627E\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E
 
-main.opt.R=\  -R           -recursive            \u9012\u5F52\u904D\u5386\u6240\u6709\u88AB\u4F9D\u8D56\u5BF9\u8C61
+main.opt.R=\  -R           -recursive            \u9012\u5F52\u904D\u5386\u6240\u6709\u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002\n                                     -R \u9009\u9879\u8868\u793A -filter:none\u3002\u5982\u679C\u6307\u5B9A\u4E86 -p, -e, -f\n                                     \u9009\u9879, \u5219\u53EA\u5206\u6790\u5339\u914D\u7684\n                                     \u88AB\u4F9D\u8D56\u5BF9\u8C61\u3002
 
 main.opt.apionly=\  -apionly                           \u901A\u8FC7\u516C\u5171\u7C7B (\u5305\u62EC\u5B57\u6BB5\u7C7B\u578B, \u65B9\u6CD5\u53C2\u6570\n                                     \u7C7B\u578B, \u8FD4\u56DE\u7C7B\u578B, \u53D7\u63A7\u5F02\u5E38\u9519\u8BEF\u7C7B\u578B\n                                     \u7B49) \u7684\u516C\u5171\u548C\u53D7\u4FDD\u62A4\u6210\u5458\u7684\u7B7E\u540D\n                                     \u9650\u5236\u5BF9 API (\u5373\u88AB\u4F9D\u8D56\u5BF9\u8C61)\n                                     \u8FDB\u884C\u5206\u6790
 
@@ -36,13 +38,14 @@
 
 err.unknown.option=\u672A\u77E5\u9009\u9879: {0}
 err.missing.arg=\u6CA1\u6709\u4E3A{0}\u6307\u5B9A\u503C
-err.internal.error=\u5185\u90E8\u9519\u8BEF: {0} {1} {2}
 err.invalid.arg.for.option=\u9009\u9879\u7684\u53C2\u6570\u65E0\u6548: {0}
 err.option.after.class=\u5FC5\u987B\u5728\u7C7B\u4E4B\u524D\u6307\u5B9A\u9009\u9879: {0}
 err.option.unsupported=\u4E0D\u652F\u6301{0}: {1}
 err.profiles.msg=\u6CA1\u6709\u914D\u7F6E\u6587\u4EF6\u4FE1\u606F
-err.dot.output.path=\u65E0\u6548\u8DEF\u5F84: {0}
+err.invalid.path=\u65E0\u6548\u8DEF\u5F84: {0}
 warn.invalid.arg=\u7C7B\u540D\u65E0\u6548\u6216\u8DEF\u5F84\u540D\u4E0D\u5B58\u5728: {0}
 warn.split.package=\u5DF2\u5728{1} {2}\u4E2D\u5B9A\u4E49\u7A0B\u5E8F\u5305{0}
+warn.replace.useJDKInternals=\u4E0D\u652F\u6301 JDK \u5185\u90E8 API, \u5B83\u4EEC\u4E13\u7528\u4E8E\u901A\u8FC7\u4E0D\u517C\u5BB9\u65B9\u5F0F\u6765\u5220\u9664\n\u6216\u66F4\u6539\u7684 JDK \u5B9E\u73B0, \u53EF\u80FD\u4F1A\u635F\u574F\u60A8\u7684\u5E94\u7528\u7A0B\u5E8F\u3002\n\u8BF7\u4FEE\u6539\u60A8\u7684\u4EE3\u7801, \u6D88\u9664\u4E0E\u4EFB\u4F55 JDK \u5185\u90E8 API \u7684\u76F8\u5173\u6027\u3002\n\u6709\u5173 JDK \u5185\u90E8 API \u66FF\u6362\u7684\u6700\u65B0\u66F4\u65B0, \u8BF7\u67E5\u770B:\n{0}
 
 artifact.not.found=\u627E\u4E0D\u5230
+jdeps.wiki.url=https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
diff --git a/langtools/test/tools/javac/flow/LVTHarness.java b/langtools/test/tools/javac/flow/LVTHarness.java
index c176e5e..33ab044 100644
--- a/langtools/test/tools/javac/flow/LVTHarness.java
+++ b/langtools/test/tools/javac/flow/LVTHarness.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 7047734 8027660 8037937 8047719
+ * @bug 7047734 8027660 8037937 8047719 8058708
  * @summary The LVT is not generated correctly during some try/catch scenarios
  *          javac crash while creating LVT entry for a local variable defined in
  *          an inner block
diff --git a/langtools/test/tools/javac/flow/tests/TestCaseIf.java b/langtools/test/tools/javac/flow/tests/TestCaseIf.java
index 9869443..fa0a0a6 100644
--- a/langtools/test/tools/javac/flow/tests/TestCaseIf.java
+++ b/langtools/test/tools/javac/flow/tests/TestCaseIf.java
@@ -58,4 +58,18 @@
         }
         o = "";
     }
+
+    @AliveRange(varName="finalLocal", bytecodeStart=11, bytecodeLength=6)
+    @AliveRange(varName="used", bytecodeStart=13, bytecodeLength=4)
+    void m5(Object o) {
+        if (o != null) {
+            Object notUsed;
+            Object used;
+            if (o != null) {
+                final Object finalLocal = null;
+                used = null;
+                if (o == null) {}
+            }
+        }
+    }
 }
diff --git a/make/Jprt.gmk b/make/Jprt.gmk
index c1ebee5..b833f86 100644
--- a/make/Jprt.gmk
+++ b/make/Jprt.gmk
@@ -25,6 +25,9 @@
 
 # This file is contains targets utilities needed by JPRT.
 
+          ifdef ALT_BSDIFF_DIR
+	    @$(ECHO) " --with-bsdiff-dir=$(call UnixPath,$(ALT_BSDIFF_DIR)) " >> $@.tmp
+          endif
 ifndef JPRT_ARCHIVE_BUNDLE
   JPRT_ARCHIVE_BUNDLE=/tmp/jprt_bundles/j2sdk-image.zip
 endif
diff --git a/nashorn/.hgtags b/nashorn/.hgtags
index e4bf0b5..3fc29d4 100644
--- a/nashorn/.hgtags
+++ b/nashorn/.hgtags
@@ -300,6 +300,25 @@
 d3da140e179343011017669a6dbfcc52b0e56f52 jdk8u20-b24
 d3da140e179343011017669a6dbfcc52b0e56f52 jdk8u20-b25
 a23ac9db4227d78b3389e01fa94a8cb695a8fb0a jdk8u20-b26
+7001e9f95b443a75e432205a29974c05b88e0fdc jdk8u25-b00
+a9f77bd14874d5f8fdf935704dd54a0451f2bc69 jdk8u25-b01
+895e47783e2ee6823496a5ae84039a4f50311c7d jdk8u25-b02
+b84d92194c367411fcd8b5f510d4589709a8e71e jdk8u25-b03
+894ab2f06c93987f8596f5906985ff0a452f2fb2 jdk8u25-b04
+25b89ca363c41e1a1d90d7e95d5227d23e4292f3 jdk8u25-b05
+0a50d568a901700213fe40c38089748ca1d1af88 jdk8u25-b06
+25b719b33ac8f8ffb7e4353fddcda93ca6027b0d jdk8u25-b07
+0f74f65763a300cfe5f897b6b21f36d64f9d2115 jdk8u25-b08
+158837f537e45fc4664a56ad4759f8a1b30cab73 jdk8u25-b09
+7e00c05fc54b0404bf2eedda35dd38ae1ad23e50 jdk8u25-b10
+8cd6af10dd4de9e28ffe30c9107954fffd15dc99 jdk8u25-b11
+f76715cd4e902602bdbb4ba9a3774c10afeee012 jdk8u25-b12
+34c95bcacff79a5794416a8e715a8e63bfe7fc58 jdk8u25-b13
+6a93467eaa36f732b84ecd463e046c4066fef40c jdk8u25-b14
+71e8403a2f8279315419adf5f4e9d6b232b6835c jdk8u25-b15
+1500138ce513600457be6bfa10979ecce6515aa6 jdk8u25-b16
+4b9cc65dd24d398c4f921c0beccfb8caeaaaf584 jdk8u25-b17
+cdbf34dbef404b47805c8c85b11c65c2afaa6674 jdk8u25-b18
 f2925491b61b22ac42f8c30ee9c6723ffa401a4c jdk8u40-b00
 62468d841b842769d875bd97d10370585c296eb7 jdk8u40-b01
 b476c69c820ac1e05071f4de5abab8e2dff80e87 jdk8u40-b02
@@ -309,3 +328,4 @@
 1196f17cf7bc709766319f5bf7a5394a7251b47a jdk8u40-b06
 0032961e1866c22afe3d0bbbb217f8840be61846 jdk8u40-b07
 89551828b279233825204b72233edafc72d8feb3 jdk8u40-b08
+6a8ecdeae4a9a438eed637b5a5d0d18fddb9f711 jdk8u40-b09
diff --git a/nashorn/bin/fixwhitespace.sh b/nashorn/bin/fixwhitespace.sh
new file mode 100644
index 0000000..d327470
--- /dev/null
+++ b/nashorn/bin/fixwhitespace.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# Copyright (c) 2010, 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.
+#
+
+fix() {
+    #convert tabs to spaces
+    find . -name $1 -exec sed -i "" 's/	/    /g' {} \;
+    #remove trailing whitespace
+    find . -name $1 -exec sed -i "" 's/[ 	]*$//' \{} \;
+}
+
+if [ ! -z $1 ]; then 
+    fix $1;
+else
+    fix "*.java"
+    fix "*.js"
+fi
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java
index 2059567..7587431 100644
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java
@@ -292,7 +292,6 @@
             mi.push(memInfo.getArity());
             mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY, SCRIPTFUNCTION_SETARITY_DESC);
         }
-
     }
 
     static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) {
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java
index c8a929d..cc3524d 100644
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java
@@ -28,7 +28,6 @@
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.STRING_DESC;
-
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
 import jdk.nashorn.internal.objects.annotations.Where;
@@ -75,10 +74,6 @@
          * This is a specialized version of a function
          */
         SPECIALIZED_FUNCTION,
-        /**
-         * This is a specialized version of a constructor
-         */
-        SPECIALIZED_CONSTRUCTOR
     }
 
     // keep in sync with jdk.nashorn.internal.objects.annotations.Attribute
@@ -107,6 +102,12 @@
 
     private Where where;
 
+    private Type linkLogicClass;
+
+    private boolean isSpecializedConstructor;
+
+    private boolean isOptimistic;
+
     /**
      * @return the kind
      */
@@ -136,6 +137,57 @@
     }
 
     /**
+     * Tag something as specialized constructor or not
+     * @param isSpecializedConstructor boolean, true if specialized constructor
+     */
+    public void setIsSpecializedConstructor(final boolean isSpecializedConstructor) {
+        this.isSpecializedConstructor = isSpecializedConstructor;
+    }
+
+    /**
+     * Check if something is a specialized constructor
+     * @return true if specialized constructor
+     */
+    public boolean isSpecializedConstructor() {
+        return isSpecializedConstructor;
+    }
+
+    /**
+     * Check if this is an optimistic builtin function
+     * @return true if optimistic builtin
+     */
+    public boolean isOptimistic() {
+        return isOptimistic;
+    }
+
+    /**
+     * Tag something as optimitic builtin or not
+     * @param isOptimistic boolean, true if builtin constructor
+     */
+    public void setIsOptimistic(final boolean isOptimistic) {
+        this.isOptimistic = isOptimistic;
+    }
+
+    /**
+     * Get the SpecializedFunction guard for specializations, i.e. optimistic
+     * builtins
+     * @return specialization, null if none
+     */
+    public Type getLinkLogicClass() {
+        return linkLogicClass;
+    }
+
+    /**
+     * Set thre SpecializedFunction link logic class for specializations, i.e. optimistic
+     * builtins
+     * @param linkLogicClass link logic class
+     */
+
+    public void setLinkLogicClass(final Type linkLogicClass) {
+        this.linkLogicClass = linkLogicClass;
+    }
+
+    /**
      * @return the attributes
      */
     public int getAttributes() {
@@ -304,19 +356,6 @@
                 }
             }
             break;
-            case SPECIALIZED_CONSTRUCTOR: {
-                final Type returnType = Type.getReturnType(javaDesc);
-                if (!isJSObjectType(returnType)) {
-                    error("return value of a @SpecializedConstructor method should be a valid JS type, found " + returnType);
-                }
-                final Type[] argTypes = Type.getArgumentTypes(javaDesc);
-                for (int i = 0; i < argTypes.length; i++) {
-                    if (!isValidJSType(argTypes[i])) {
-                        error(i + "'th argument of a @SpecializedConstructor method is not valid JS type, found " + argTypes[i]);
-                    }
-                }
-            }
-            break;
             case FUNCTION: {
                 final Type returnType = Type.getReturnType(javaDesc);
                 if (!(isValidJSType(returnType) || Type.VOID_TYPE == returnType)) {
@@ -351,7 +390,7 @@
             break;
             case SPECIALIZED_FUNCTION: {
                 final Type returnType = Type.getReturnType(javaDesc);
-                if (!(isValidJSType(returnType) || Type.VOID_TYPE == returnType)) {
+                if (!(isValidJSType(returnType) || (isSpecializedConstructor() && Type.VOID_TYPE == returnType))) {
                     error("return value of a @SpecializedFunction method should be a valid JS type, found " + returnType);
                 }
                 final Type[] argTypes = Type.getArgumentTypes(javaDesc);
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java
index a8d6ae2..a8bd954 100644
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java
@@ -56,6 +56,7 @@
 import static jdk.internal.org.objectweb.asm.Opcodes.IALOAD;
 import static jdk.internal.org.objectweb.asm.Opcodes.IASTORE;
 import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0;
+import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_1;
 import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD;
 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEINTERFACE;
 import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
@@ -76,13 +77,16 @@
 import static jdk.internal.org.objectweb.asm.Opcodes.SASTORE;
 import static jdk.internal.org.objectweb.asm.Opcodes.SIPUSH;
 import static jdk.internal.org.objectweb.asm.Opcodes.SWAP;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.METHODHANDLE_TYPE;
-import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_METHODHANDLE;
-
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SPECIALIZATION_INIT2;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SPECIALIZATION_INIT3;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.SPECIALIZATION_TYPE;
+import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_SPECIALIZATION;
 import java.util.List;
 import jdk.internal.org.objectweb.asm.Handle;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Type;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
 
 /**
  * Base class for all method generating classes.
@@ -95,6 +99,8 @@
     private final Type returnType;
     private final Type[] argumentTypes;
 
+    static final Type EMPTY_LINK_LOGIC_TYPE = Type.getType(LinkLogic.getEmptyLinkLogicClass());
+
     MethodGenerator(final MethodVisitor mv, final int access, final String name, final String descriptor) {
         super(ASM4, mv);
         this.access        = access;
@@ -380,6 +386,11 @@
         super.visitFieldInsn(GETFIELD, owner, field, desc);
     }
 
+    private static boolean linkLogicIsEmpty(final Type type) {
+        assert EMPTY_LINK_LOGIC_TYPE != null; //type is ok for null if we are a @SpecializedFunction without any attribs
+        return EMPTY_LINK_LOGIC_TYPE.equals(type);
+    }
+
     void memberInfoArray(final String className, final List<MemberInfo> mis) {
         if (mis.isEmpty()) {
             pushNull();
@@ -388,12 +399,22 @@
 
         int pos = 0;
         push(mis.size());
-        newObjectArray(METHODHANDLE_TYPE);
+        newObjectArray(SPECIALIZATION_TYPE);
         for (final MemberInfo mi : mis) {
             dup();
             push(pos++);
+            visitTypeInsn(NEW, SPECIALIZATION_TYPE);
+            dup();
             visitLdcInsn(new Handle(H_INVOKESTATIC, className, mi.getJavaName(), mi.getJavaDesc()));
-            arrayStore(TYPE_METHODHANDLE);
+            final Type    linkLogicClass = mi.getLinkLogicClass();
+            final boolean linkLogic      = !linkLogicIsEmpty(linkLogicClass);
+            final String  ctor           = linkLogic ? SPECIALIZATION_INIT3 : SPECIALIZATION_INIT2;
+            if (linkLogic) {
+                visitLdcInsn(linkLogicClass);
+            }
+            visitInsn(mi.isOptimistic() ? ICONST_1 : ICONST_0);
+            visitMethodInsn(INVOKESPECIAL, SPECIALIZATION_TYPE, INIT, ctor, false);
+            arrayStore(TYPE_SPECIALIZATION);
         }
     }
 
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java
index 0a1579f..9e3dfc1 100644
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java
@@ -37,8 +37,8 @@
 import jdk.nashorn.internal.objects.annotations.Property;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
 import jdk.nashorn.internal.objects.annotations.Setter;
-import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
 import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
 import jdk.nashorn.internal.objects.annotations.Where;
 import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind;
 
@@ -56,8 +56,8 @@
     static final String SETTER_ANNO_DESC        = Type.getDescriptor(Setter.class);
     static final String PROPERTY_ANNO_DESC      = Type.getDescriptor(Property.class);
     static final String WHERE_ENUM_DESC         = Type.getDescriptor(Where.class);
+    static final String LINK_LOGIC_DESC         = Type.getDescriptor(LinkLogic.class);
     static final String SPECIALIZED_FUNCTION    = Type.getDescriptor(SpecializedFunction.class);
-    static final String SPECIALIZED_CONSTRUCTOR = Type.getDescriptor(SpecializedConstructor.class);
 
     static final Map<String, Kind> annotations = new HashMap<>();
 
@@ -69,7 +69,6 @@
         annotations.put(SETTER_ANNO_DESC, Kind.SETTER);
         annotations.put(PROPERTY_ANNO_DESC, Kind.PROPERTY);
         annotations.put(SPECIALIZED_FUNCTION, Kind.SPECIALIZED_FUNCTION);
-        annotations.put(SPECIALIZED_CONSTRUCTOR, Kind.SPECIALIZED_CONSTRUCTOR);
     }
 
     // name of the script class
@@ -119,11 +118,12 @@
     List<MemberInfo> getSpecializedConstructors() {
         final List<MemberInfo> res = new LinkedList<>();
         for (final MemberInfo memInfo : members) {
-            if (memInfo.getKind() == Kind.SPECIALIZED_CONSTRUCTOR) {
+            if (memInfo.isSpecializedConstructor()) {
+                assert memInfo.getKind() == Kind.SPECIALIZED_FUNCTION;
                 res.add(memInfo);
             }
         }
-        return res;
+        return Collections.unmodifiableList(res);
     }
 
     int getPrototypeMemberCount() {
@@ -175,7 +175,7 @@
                 res.add(memInfo);
             }
         }
-        return res;
+        return Collections.unmodifiableList(res);
     }
 
     MemberInfo findSetter(final MemberInfo getter) {
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java
index 5561cfb..aa47762 100644
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java
@@ -27,7 +27,6 @@
 
 import static jdk.nashorn.internal.tools.nasgen.ScriptClassInfo.SCRIPT_CLASS_ANNO_DESC;
 import static jdk.nashorn.internal.tools.nasgen.ScriptClassInfo.WHERE_ENUM_DESC;
-
 import java.io.BufferedInputStream;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -41,6 +40,7 @@
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.Type;
 import jdk.nashorn.internal.objects.annotations.Where;
 import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind;
 
@@ -194,6 +194,7 @@
 
                     final MemberInfo memInfo = new MemberInfo();
 
+                    //annokind == e.g. GETTER or SPECIALIZED_FUNCTION
                     memInfo.setKind(annoKind);
                     memInfo.setJavaName(methodName);
                     memInfo.setJavaDesc(methodDesc);
@@ -208,12 +209,18 @@
                         private Integer attributes;
                         private Integer arity;
                         private Where   where;
+                        private boolean isSpecializedConstructor;
+                        private boolean isOptimistic;
+                        private Type    linkLogicClass = MethodGenerator.EMPTY_LINK_LOGIC_TYPE;
 
                         @Override
                         public void visit(final String annotationName, final Object annotationValue) {
                             switch (annotationName) {
                             case "name":
                                 this.name = (String)annotationValue;
+                                if (name.isEmpty()) {
+                                    name = null;
+                                }
                                 break;
                             case "attributes":
                                 this.attributes = (Integer)annotationValue;
@@ -221,6 +228,17 @@
                             case "arity":
                                 this.arity = (Integer)annotationValue;
                                 break;
+                            case "isConstructor":
+                                assert annoKind == Kind.SPECIALIZED_FUNCTION;
+                                this.isSpecializedConstructor = (Boolean)annotationValue;
+                                break;
+                            case "isOptimistic":
+                                assert annoKind == Kind.SPECIALIZED_FUNCTION;
+                                this.isOptimistic = (Boolean)annotationValue;
+                                break;
+                            case "linkLogic":
+                                this.linkLogicClass = (Type)annotationValue;
+                                break;
                             default:
                                 break;
                             }
@@ -230,12 +248,19 @@
 
                         @Override
                         public void visitEnum(final String enumName, final String desc, final String enumValue) {
-                            if ("where".equals(enumName) && WHERE_ENUM_DESC.equals(desc)) {
-                                this.where = Where.valueOf(enumValue);
+                            switch (enumName) {
+                            case "where":
+                                if (WHERE_ENUM_DESC.equals(desc)) {
+                                    this.where = Where.valueOf(enumValue);
+                                }
+                                break;
+                            default:
+                                break;
                             }
                             super.visitEnum(enumName, desc, enumValue);
                         }
 
+                        @SuppressWarnings("fallthrough")
                         @Override
                         public void visitEnd() {
                             super.visitEnd();
@@ -256,7 +281,6 @@
                                     case SETTER:
                                         where = Where.INSTANCE;
                                         break;
-                                    case SPECIALIZED_CONSTRUCTOR:
                                     case CONSTRUCTOR:
                                         where = Where.CONSTRUCTOR;
                                         break;
@@ -264,12 +288,18 @@
                                         where = Where.PROTOTYPE;
                                         break;
                                     case SPECIALIZED_FUNCTION:
-                                        //TODO is this correct
+                                        if (isSpecializedConstructor) {
+                                            where = Where.CONSTRUCTOR;
+                                        }
+                                        //fallthru
                                     default:
                                         break;
                                 }
                             }
                             memInfo.setWhere(where);
+                            memInfo.setLinkLogicClass(linkLogicClass);
+                            memInfo.setIsSpecializedConstructor(isSpecializedConstructor);
+                            memInfo.setIsOptimistic(isOptimistic);
                         }
                     };
                 }
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java
index 0ec233a..0d6a9e3 100644
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java
@@ -38,7 +38,6 @@
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
 import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_TYPE;
-
 import java.io.BufferedInputStream;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java
index fb72bbe..8656a42 100644
--- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java
+++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java
@@ -37,6 +37,7 @@
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.Specialization;
 
 /**
  * String constants used for code generation/instrumentation.
@@ -44,20 +45,26 @@
 @SuppressWarnings("javadoc")
 public interface StringConstants {
     // standard jdk types, methods
-    static final Type TYPE_METHODHANDLE       = Type.getType(MethodHandle.class);
-    static final Type TYPE_METHODHANDLE_ARRAY = Type.getType(MethodHandle[].class);
-    static final Type TYPE_OBJECT             = Type.getType(Object.class);
-    static final Type TYPE_STRING             = Type.getType(String.class);
-    static final Type TYPE_COLLECTION         = Type.getType(Collection.class);
-    static final Type TYPE_COLLECTIONS        = Type.getType(Collections.class);
-    static final Type TYPE_ARRAYLIST          = Type.getType(ArrayList.class);
-    static final Type TYPE_LIST               = Type.getType(List.class);
+    static final Type TYPE_METHODHANDLE         = Type.getType(MethodHandle.class);
+    static final Type TYPE_METHODHANDLE_ARRAY   = Type.getType(MethodHandle[].class);
+    static final Type TYPE_SPECIALIZATION       = Type.getType(Specialization.class);
+    static final Type TYPE_SPECIALIZATION_ARRAY = Type.getType(Specialization[].class);
+    static final Type TYPE_OBJECT               = Type.getType(Object.class);
+    static final Type TYPE_STRING               = Type.getType(String.class);
+    static final Type TYPE_CLASS                = Type.getType(Class.class);
+    static final Type TYPE_COLLECTION           = Type.getType(Collection.class);
+    static final Type TYPE_COLLECTIONS          = Type.getType(Collections.class);
+    static final Type TYPE_ARRAYLIST            = Type.getType(ArrayList.class);
+    static final Type TYPE_LIST                 = Type.getType(List.class);
 
     static final String CLINIT = "<clinit>";
     static final String INIT = "<init>";
     static final String DEFAULT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE);
 
     static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName();
+    static final String SPECIALIZATION_TYPE = TYPE_SPECIALIZATION.getInternalName();
+    static final String SPECIALIZATION_INIT2 = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_METHODHANDLE, Type.getType(boolean.class));
+    static final String SPECIALIZATION_INIT3 = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_METHODHANDLE, TYPE_CLASS, Type.getType(boolean.class));
     static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName();
     static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor();
     static final String STRING_TYPE = TYPE_STRING.getInternalName();
@@ -122,11 +129,11 @@
     static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC =
         Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE);
     static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC =
-        Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY);
+        Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY);
     static final String SCRIPTFUNCTIONIMPL_INIT_DESC3 =
-        Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY);
+        Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY);
     static final String SCRIPTFUNCTIONIMPL_INIT_DESC4 =
-        Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_METHODHANDLE_ARRAY);
+        Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_SPECIALIZATION_ARRAY);
 
     // ScriptObject
     static final String SCRIPTOBJECT_TYPE = TYPE_SCRIPTOBJECT.getInternalName();
diff --git a/nashorn/make/BuildNashorn.gmk b/nashorn/make/BuildNashorn.gmk
index a987874..683d462 100644
--- a/nashorn/make/BuildNashorn.gmk
+++ b/nashorn/make/BuildNashorn.gmk
@@ -65,7 +65,7 @@
     SETUP := GENERATE_NEWBYTECODE_DEBUG, \
     SRC := $(NASGEN_SRC) $(ASM_SRC), \
     BIN := $(NASHORN_OUTPUTDIR)/nasgen_classes, \
-    ADD_JAVAC_FLAGS := -cp $(NASHORN_OUTPUTDIR)/nashorn_classes))
+    ADD_JAVAC_FLAGS := -bootclasspath "$(BOOT_RTJAR)$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes"))
 
 # Nasgen needs nashorn classes
 $(BUILD_NASGEN): $(BUILD_NASHORN)
diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml
index 9d21de8..9bb600d 100644
--- a/nashorn/make/build.xml
+++ b/nashorn/make/build.xml
@@ -78,7 +78,7 @@
       <istrue value="${jfr}"/>
     </condition>
   </target>
-
+  
   <target name="init" depends="init-conditions, init-cc">
     <!-- extends jvm args -->
     <property name="run.test.jvmargs" value="${run.test.jvmargs.main} ${run.test.cc.jvmargs} ${jfr.options}"/>
@@ -419,6 +419,7 @@
         <propertyref prefix="test-sys-prop-no-security."/>
         <mapper from="test-sys-prop-no-security.*" to="*" type="glob"/>
       </propertyset>
+      <sysproperty key="optimistic.override" value="${optimistic}"/>
       <classpath>
           <pathelement path="${run.test.classpath}"/>
       </classpath>
@@ -430,7 +431,7 @@
     <delete dir="${build.dir}/nashorn_code_cache"/>
     <property name="debug.test.jvmargs" value=""/>
     <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
-       verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
+	    verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
       <jvmarg line="${ext.class.path}"/>
       <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -Dbuild.dir=${build.dir}"/>
       <jvmarg line="${debug.test.jvmargs}"/>
@@ -441,6 +442,7 @@
         <propertyref prefix="test-sys-prop."/>
         <mapper from="test-sys-prop.*" to="*" type="glob"/>
       </propertyset>
+      <sysproperty key="optimistic.override" value="${optimistic}"/>
       <sysproperty key="test.js.excludes.file" value="${exclude.list}"/>
       <classpath>
           <pathelement path="${run.test.classpath}"/>
@@ -448,7 +450,27 @@
     </testng>
   </target>
 
-  <target name="test" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file, -test-security, -test-nosecurity" if="testng.available"/>
+  <target name="test" depends="test-pessimistic, test-optimistic"/>
+
+  <target name="test-optimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+    <echo message="Running test suite in OPTIMISTIC mode..."/>
+    <antcall target="-test-nosecurity" inheritRefs="true">
+      <param name="optimistic" value="true"/>
+    </antcall>    
+    <antcall target="-test-security" inheritRefs="true">
+      <param name="optimistic" value="true"/>
+    </antcall>
+  </target>
+
+  <target name="test-pessimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
+    <echo message="Running test suite in PESSIMISTIC mode..."/>
+    <antcall target="-test-nosecurity" inheritRefs="true">
+      <param name="optimistic" value="false"/>
+    </antcall>    
+    <antcall target="-test-security" inheritRefs="true">
+      <param name="optimistic" value="false"/>
+    </antcall>
+  </target>
 
   <target name="check-jemmy.jfx.testng" unless="jemmy.jfx.testng.available">
     <echo message="WARNING: Jemmy or JavaFX or TestNG not available, will not run tests. Please copy testng.jar, JemmyCore.jar, JemmyFX.jar, JemmyAWTInput.jar under test${file.separator}lib directory. And make sure you have jfxrt.jar in ${java.home}${file.separator}lib${file.separator}ext dir."/>
diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties
index 800a629..9d36fbd 100644
--- a/nashorn/make/project.properties
+++ b/nashorn/make/project.properties
@@ -286,7 +286,8 @@
 # turn on assertions for tests
 run.test.jvmargs.main=${run.test.jvmargs.common} -ea
 
-# extra jvmargs that might be useful for debugging
+# Extra jvmargs that might be useful for debugging
+# and performance improvements/monitoring
 #
 # -XX:+UnlockDiagnosticVMOptions 
 #
@@ -304,9 +305,25 @@
 #
 # print all compiled nmethods with oopmaps and lots of other info
 # -XX:+PrintNMethods
+#
+# activate the generic "UseNewCode" flag to test whatever functionality
+# lies behind it. This is the preferred way to test a, yet flagless,
+# feature in HotSpot - for example, the uncommon trap placement fix
+# was hidden behind this flag before it became the default
+#
+# -XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode 
+#
+# Crank up the type profile level to 222, which has some warmup
+# penalties, but produces much better code for JavaScript, where better
+# and more intrusive type profiling is required to get rid of
+# a large amount of unnecessary guard code, that could not otherwise
+# be eliminated
+#
+# -XX:TypeProfileLevel=222
+#
 
 # Use best known performance options for octane
-run.test.jvmargs.octane.main=${run.test.jvmargs.common} -XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode -XX:TypeProfileLevel=222
+run.test.jvmargs.octane.main=${run.test.jvmargs.common} -XX:TypeProfileLevel=222
 
 # Security manager args - make sure that we run with the nashorn.policy that the build creates
 run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${build.dir}/nashorn.policy
diff --git a/nashorn/samples/BufferArray.java b/nashorn/samples/BufferArray.java
index 00d6602..b26b5c0 100644
--- a/nashorn/samples/BufferArray.java
+++ b/nashorn/samples/BufferArray.java
@@ -29,8 +29,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import jdk.nashorn.api.scripting.AbstractJSObject;
 import java.nio.DoubleBuffer;
+import jdk.nashorn.api.scripting.AbstractJSObject;
 
 /**
  * Simple class demonstrating pluggable script object
@@ -52,41 +52,49 @@
     // underlying nio buffer
     private final DoubleBuffer buf;
 
-    public BufferArray(int size) {
+    /**
+     * Constructor
+     * @param size initial size
+     */
+    public BufferArray(final int size) {
         buf = DoubleBuffer.allocate(size);
     }
 
-    public BufferArray(DoubleBuffer buf) {
+    /**
+     * Constructur
+     * @param buf {@link DoubleBuffer} to link to
+     */
+    public BufferArray(final DoubleBuffer buf) {
         this.buf = buf;
     }
 
     // called to check if indexed property exists
     @Override
-    public boolean hasSlot(int index) {
+    public boolean hasSlot(final int index) {
         return index > 0 && index < buf.capacity();
     }
 
     // get the value from that index
     @Override
-    public Object getSlot(int index) {
+    public Object getSlot(final int index) {
        return buf.get(index);
     }
 
     // set the value at that index
     @Override
-    public void setSlot(int index, Object value) {
+    public void setSlot(final int index, final Object value) {
        buf.put(index, ((Number)value).doubleValue());
     }
 
     // do you have a property of that given name?
     @Override
-    public boolean hasMember(String name) {
+    public boolean hasMember(final String name) {
        return "length".equals(name) || "buf".equals(name);
     }
 
     // get the value of that named property
     @Override
-    public Object getMember(String name) {
+    public Object getMember(final String name) {
        switch (name) {
           case "length":
               return buf.capacity();
@@ -94,7 +102,7 @@
               // return a 'function' value for this property
               return new AbstractJSObject() {
                   @Override
-                  public Object call(Object thiz, Object... args) {
+                  public Object call(final Object thiz, final Object... args) {
                       return BufferArray.this.buf;
                   }
 
@@ -104,6 +112,8 @@
                       return true;
                   }
               };
+          default:
+              break;
        }
        return null;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ApplySpecialization.java b/nashorn/src/jdk/nashorn/internal/codegen/ApplySpecialization.java
index d166889..b05475b 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/ApplySpecialization.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ApplySpecialization.java
@@ -27,7 +27,6 @@
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR;
 import static jdk.nashorn.internal.codegen.CompilerConstants.EXPLODED_ARGUMENT_PREFIX;
-
 import java.lang.invoke.MethodType;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
@@ -35,7 +34,6 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-
 import jdk.nashorn.internal.ir.AccessNode;
 import jdk.nashorn.internal.ir.CallNode;
 import jdk.nashorn.internal.ir.Expression;
@@ -131,11 +129,12 @@
         @SuppressWarnings("serial")
         final UnsupportedOperationException uoe = new UnsupportedOperationException() {
             @Override
-            public Throwable fillInStackTrace() {
+            public synchronized Throwable fillInStackTrace() {
                 return null;
             }
         };
 
+        final Set<Expression> argumentsFound = new HashSet<>();
         final Deque<Set<Expression>> stack = new ArrayDeque<>();
         //ensure that arguments is only passed as arg to apply
         try {
@@ -145,7 +144,11 @@
                 }
 
                 private boolean isArguments(final Expression expr) {
-                    return expr instanceof IdentNode && ARGUMENTS.equals(((IdentNode)expr).getName());
+                    if (expr instanceof IdentNode && ARGUMENTS.equals(((IdentNode)expr).getName())) {
+                        argumentsFound.add(expr);
+                        return true;
+                    }
+                    return false;
                 }
 
                 private boolean isParam(final String name) {
@@ -159,7 +162,7 @@
 
                 @Override
                 public Node leaveIdentNode(final IdentNode identNode) {
-                    if (isParam(identNode.getName()) || ARGUMENTS.equals(identNode.getName()) && !isCurrentArg(identNode)) {
+                    if (isParam(identNode.getName()) || isArguments(identNode) && !isCurrentArg(identNode)) {
                         throw uoe; //avoid filling in stack trace
                     }
                     return identNode;
@@ -186,7 +189,9 @@
                 }
             });
         } catch (final UnsupportedOperationException e) {
-            log.fine("'arguments' escapes, is not used in standard call dispatch, or is reassigned in '" + functionNode.getName() + "'. Aborting");
+            if (!argumentsFound.isEmpty()) {
+                log.fine("'arguments' is used but escapes, or is reassigned in '" + functionNode.getName() + "'. Aborting");
+            }
             return true; //bad
         }
 
@@ -267,9 +272,9 @@
             return false;
         }
 
-        if (!Global.instance().isSpecialNameValid("apply")) {
+        if (!Global.isBuiltinFunctionPrototypeApply()) {
             log.fine("Apply transform disabled: apply/call overridden");
-            assert !Global.instance().isSpecialNameValid("call") : "call and apply should have the same SwitchPoint";
+            assert !Global.isBuiltinFunctionPrototypeCall() : "call and apply should have the same SwitchPoint";
             return false;
         }
 
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java
index 9f7fe79..7a89e49 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java
@@ -51,15 +51,14 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
 import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
 import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
-
 import java.io.ByteArrayOutputStream;
 import java.io.PrintWriter;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.Set;
-
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.util.TraceClassVisitor;
@@ -160,8 +159,12 @@
         this.methodNames    = new HashSet<>();
     }
 
+    /**
+     * Return the method names encountered
+     * @return method names
+     */
     public Set<String> getMethodNames() {
-        return methodNames;
+        return Collections.unmodifiableSet(methodNames);
     }
 
     /**
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
index 97b2621..ae3ee69 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
@@ -104,6 +104,7 @@
 import jdk.nashorn.internal.ir.IndexNode;
 import jdk.nashorn.internal.ir.JoinPredecessor;
 import jdk.nashorn.internal.ir.JoinPredecessorExpression;
+import jdk.nashorn.internal.ir.JumpStatement;
 import jdk.nashorn.internal.ir.LabelNode;
 import jdk.nashorn.internal.ir.LexicalContext;
 import jdk.nashorn.internal.ir.LexicalContextNode;
@@ -1204,17 +1205,21 @@
 
     @Override
     public boolean enterBreakNode(final BreakNode breakNode) {
+        return enterJumpStatement(breakNode);
+    }
+
+    private boolean enterJumpStatement(final JumpStatement jump) {
         if(!method.isReachable()) {
             return false;
         }
-        enterStatement(breakNode);
+        enterStatement(jump);
 
-        method.beforeJoinPoint(breakNode);
-        final BreakableNode breakFrom = lc.getBreakable(breakNode.getLabelName());
-        popScopesUntil(breakFrom);
-        final Label breakLabel = breakFrom.getBreakLabel();
-        breakLabel.markAsBreakTarget();
-        method.splitAwareGoto(lc, breakLabel, breakFrom);
+        method.beforeJoinPoint(jump);
+        final BreakableNode target = jump.getTarget(lc);
+        popScopesUntil(target);
+        final Label targetLabel = jump.getTargetLabel(target);
+        targetLabel.markAsBreakTarget();
+        method.splitAwareGoto(lc, targetLabel, target);
 
         return false;
     }
@@ -1517,19 +1522,7 @@
 
     @Override
     public boolean enterContinueNode(final ContinueNode continueNode) {
-        if(!method.isReachable()) {
-            return false;
-        }
-        enterStatement(continueNode);
-        method.beforeJoinPoint(continueNode);
-
-        final LoopNode continueTo = lc.getContinueTo(continueNode.getLabelName());
-        popScopesUntil(continueTo);
-        final Label continueLabel = continueTo.getContinueLabel();
-        continueLabel.markAsBreakTarget();
-        method.splitAwareGoto(lc, continueLabel, continueTo);
-
-        return false;
+        return enterJumpStatement(continueNode);
     }
 
     @Override
@@ -2807,6 +2800,7 @@
         final boolean hasReturn = method.hasReturn();
         final SplitMethodEmitter splitMethod = ((SplitMethodEmitter)method);
         final List<Label> targets = splitMethod.getExternalTargets();
+        final boolean hasControlFlow = hasReturn || !targets.isEmpty();
         final List<BreakableNode> targetNodes  = splitMethod.getExternalTargetNodes();
         final Type returnType = lc.getCurrentFunction().getReturnType();
 
@@ -2814,6 +2808,9 @@
             // Wrap up this method.
 
             if(method.isReachable()) {
+                if (hasControlFlow) {
+                    method.setSplitState(-1);
+                }
                 method.loadCompilerConstant(RETURN, returnType);
                 method._return(returnType);
             }
@@ -2831,17 +2828,16 @@
             throw e;
         }
 
+        //no external jump targets or return in switch node
+        if (!hasControlFlow) {
+            return splitNode;
+        }
+
         // Handle return from split method if there was one.
         final MethodEmitter caller = method;
         final int     targetCount = targets.size();
 
-        //no external jump targets or return in switch node
-        if (!hasReturn && targets.isEmpty()) {
-            return splitNode;
-        }
-
-        caller.loadCompilerConstant(SCOPE);
-        caller.checkcast(Scope.class);
+        caller.loadScope();
         caller.invoke(Scope.GET_SPLIT_STATE);
 
         final Label breakLabel = new Label("no_split_state");
@@ -2873,19 +2869,16 @@
                     caller.loadCompilerConstant(RETURN, returnType);
                     caller._return(returnType);
                 } else {
-                    // Clear split state.
-                    caller.loadCompilerConstant(SCOPE);
-                    caller.checkcast(Scope.class);
-                    caller.load(-1);
-                    caller.invoke(Scope.SET_SPLIT_STATE);
                     final BreakableNode targetNode = targetNodes.get(i - 1);
                     final Label label = targets.get(i - 1);
-                    final JoinPredecessor jumpOrigin = splitNode.getJumpOrigin(label);
-                    if(jumpOrigin != null) {
-                        method.beforeJoinPoint(jumpOrigin);
+                    if (!lc.isExternalTarget(splitNode, targetNode)) {
+                        final JoinPredecessor jumpOrigin = splitNode.getJumpOrigin(label);
+                        if(jumpOrigin != null) {
+                            method.beforeJoinPoint(jumpOrigin);
+                        }
+                        popScopesUntil(targetNode);
                     }
-                    popScopesUntil(targetNode);
-                    caller.splitAwareGoto(lc, targets.get(i - 1), targetNode);
+                    caller.splitAwareGoto(lc, label, targetNode);
                 }
             }
             caller.label(breakLabel);
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java
index 603157d..1ba77a7 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java
@@ -38,7 +38,6 @@
 import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SPLIT;
 import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SYMBOLS_ASSIGNED;
 import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote;
-
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.EnumSet;
@@ -48,7 +47,6 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-
 import jdk.nashorn.internal.AssertsEnabled;
 import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
 import jdk.nashorn.internal.ir.FunctionNode;
@@ -627,7 +625,7 @@
 
     /**
      * Start a compilation phase
-     * @param compiler
+     * @param compiler the compiler to use
      * @param functionNode function to compile
      * @return function node
      */
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java b/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java
index d45a58f..2d3cd2b 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java
@@ -60,6 +60,10 @@
         emittedUnitCount++;
     }
 
+    /**
+     * Get the amount of emitted compile units so far in the system
+     * @return emitted compile unit count
+     */
     public static int getEmittedUnitCount() {
         return emittedUnitCount;
     }
@@ -72,6 +76,10 @@
         return isUsed;
     }
 
+    /**
+     * Check if a compile unit has code, not counting inits and clinits
+     * @return true of if there is "real code" in the compile unit
+     */
     public boolean hasCode() {
         return (classEmitter.getMethodCount() - classEmitter.getInitCount() - classEmitter.getClinitCount()) > 0;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
index 0a1de70..3a0cc6b 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
@@ -32,7 +32,6 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
 import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
 import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote;
-
 import java.io.File;
 import java.lang.invoke.MethodType;
 import java.util.Arrays;
@@ -154,6 +153,13 @@
     private RecompilableScriptFunctionData compiledFunction;
 
     /**
+     * Most compile unit names are longer than the default StringBuilder buffer,
+     * worth startup performance when massive class generation is going on to increase
+     * this
+     */
+    private static final int COMPILE_UNIT_NAME_BUFFER_SIZE = 32;
+
+    /**
      * Compilation phases that a compilation goes through
      */
     public static class CompilationPhases implements Iterable<CompilationPhase> {
@@ -452,12 +458,16 @@
 
     @Override
     public DebugLogger initLogger(final Context ctxt) {
+        final boolean optimisticTypes = env._optimistic_types;
+        final boolean lazyCompilation = env._lazy_compilation;
+
         return ctxt.getLogger(this.getClass(), new Consumer<DebugLogger>() {
             @Override
             public void accept(final DebugLogger newLogger) {
-                if (!Compiler.this.getScriptEnvironment()._lazy_compilation) {
+                if (!lazyCompilation) {
                     newLogger.warning("WARNING: Running with lazy compilation switched off. This is not a default setting.");
                 }
+                newLogger.warning("Optimistic types are ", optimisticTypes ? "ENABLED." : "DISABLED.");
             }
         });
     }
@@ -535,9 +545,10 @@
      * @throws CompilationException if error occurs during compilation
      */
     public FunctionNode compile(final FunctionNode functionNode, final CompilationPhases phases) throws CompilationException {
-
-        log.finest("Starting compile job for ", DebugLogger.quote(functionNode.getName()), " phases=", quote(phases.getDesc()));
-        log.indent();
+        if (log.isEnabled()) {
+            log.info(">> Starting compile job for ", DebugLogger.quote(functionNode.getName()), " phases=", quote(phases.getDesc()));
+            log.indent();
+        }
 
         final String name = DebugLogger.quote(functionNode.getName());
 
@@ -554,7 +565,7 @@
         long time = 0L;
 
         for (final CompilationPhase phase : phases) {
-            log.fine(phase, " starting for ", quote(name));
+            log.fine(phase, " starting for ", name);
 
             try {
                 newFunctionNode = phase.apply(this, phases, newFunctionNode);
@@ -582,8 +593,11 @@
         log.unindent();
 
         if (info) {
-            final StringBuilder sb = new StringBuilder();
-            sb.append("Compile job for ").append(newFunctionNode.getSource()).append(':').append(quote(newFunctionNode.getName())).append(" finished");
+            final StringBuilder sb = new StringBuilder("<< Finished compile job for ");
+            sb.append(newFunctionNode.getSource()).
+                append(':').
+                append(quote(newFunctionNode.getName()));
+
             if (time > 0L && timeLogger != null) {
                 assert env.isTimingEnabled();
                 sb.append(" in ").append(time).append(" ms");
@@ -631,7 +645,8 @@
     }
 
     String nextCompileUnitName() {
-        final StringBuilder sb = new StringBuilder(firstCompileUnitName);
+        final StringBuilder sb = new StringBuilder(COMPILE_UNIT_NAME_BUFFER_SIZE);
+        sb.append(firstCompileUnitName);
         final int cuid = nextCompileUnitId.getAndIncrement();
         if (cuid > 0) {
             sb.append("$cu").append(cuid);
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Label.java b/nashorn/src/jdk/nashorn/internal/codegen/Label.java
index 8630469..7c86abf 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Label.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Label.java
@@ -590,8 +590,13 @@
         return label.getOffset() > other.label.getOffset();
     }
 
+    private String str;
+
     @Override
     public String toString() {
-        return name + '_' + id;
+        if (str == null) {
+            str = name + '_' + id;
+        }
+        return str;
     }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java b/nashorn/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java
index c9580d4..491ef2c 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java
@@ -464,21 +464,20 @@
 
     @Override
     public boolean enterBreakNode(final BreakNode breakNode) {
-        if(!reachable) {
-            return false;
-        }
-
-        final BreakableNode target = lc.getBreakable(breakNode.getLabelName());
-        return splitAwareJumpToLabel(breakNode, target, target.getBreakLabel());
+        return enterJumpStatement(breakNode);
     }
 
     @Override
     public boolean enterContinueNode(final ContinueNode continueNode) {
+        return enterJumpStatement(continueNode);
+    }
+
+    private boolean enterJumpStatement(final JumpStatement jump) {
         if(!reachable) {
             return false;
         }
-        final LoopNode target = lc.getContinueTo(continueNode.getLabelName());
-        return splitAwareJumpToLabel(continueNode, target, target.getContinueLabel());
+        final BreakableNode target = jump.getTarget(lc);
+        return splitAwareJumpToLabel(jump, target, jump.getTargetLabel(target));
     }
 
     private boolean splitAwareJumpToLabel(final JumpStatement jumpStatement, final BreakableNode target, final Label targetLabel) {
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
index 2c87f3b..dddf697 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
@@ -52,6 +52,7 @@
 import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
 import jdk.nashorn.internal.ir.IdentNode;
 import jdk.nashorn.internal.ir.IfNode;
+import jdk.nashorn.internal.ir.JumpStatement;
 import jdk.nashorn.internal.ir.LabelNode;
 import jdk.nashorn.internal.ir.LexicalContext;
 import jdk.nashorn.internal.ir.LiteralNode;
@@ -382,12 +383,16 @@
 
             @Override
             public Node leaveBreakNode(final BreakNode breakNode) {
-                return copy(breakNode, (Node)Lower.this.lc.getBreakable(breakNode.getLabelName()));
+                return leaveJumpStatement(breakNode);
             }
 
             @Override
             public Node leaveContinueNode(final ContinueNode continueNode) {
-                return copy(continueNode, Lower.this.lc.getContinueTo(continueNode.getLabelName()));
+                return leaveJumpStatement(continueNode);
+            }
+
+            private Node leaveJumpStatement(final JumpStatement jump) {
+                return copy(jump, (Node)jump.getTarget(Lower.this.lc));
             }
 
             @Override
@@ -627,7 +632,7 @@
             @Override
             public Node leaveContinueNode(final ContinueNode node) {
                 // all inner loops have been popped.
-                if (lex.contains(lex.getContinueTo(node.getLabelName()))) {
+                if (lex.contains(node.getTarget(lex))) {
                     escapes.add(node);
                 }
                 return node;
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java
index 2bd4c4c..400d521 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java
@@ -71,7 +71,6 @@
 import static jdk.nashorn.internal.codegen.ObjectClassGenerator.PRIMITIVE_FIELD_TYPE;
 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC;
 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT;
-
 import java.io.PrintStream;
 import java.lang.reflect.Array;
 import java.util.Collection;
@@ -105,7 +104,9 @@
 import jdk.nashorn.internal.runtime.Debug;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.RewriteException;
+import jdk.nashorn.internal.runtime.Scope;
 import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.logging.DebugLogger;
@@ -180,9 +181,6 @@
     /** Bootstrap for array populators */
     private static final Handle POPULATE_ARRAY_BOOTSTRAP = new Handle(H_INVOKESTATIC, RewriteException.BOOTSTRAP.className(), RewriteException.BOOTSTRAP.name(), RewriteException.BOOTSTRAP.descriptor());
 
-    /** Bootstrap for global name invalidation */
-    private static final Handle INVALIDATE_NAME_BOOTSTRAP = new Handle(H_INVOKESTATIC, Global.BOOTSTRAP.className(), Global.BOOTSTRAP.name(), Global.BOOTSTRAP.descriptor());
-
     /**
      * Constructor - internal use from ClassEmitter only
      * @see ClassEmitter#method
@@ -1050,6 +1048,14 @@
         return load(getCompilerConstantSymbol(cc), type != null ? type : getCompilerConstantType(cc));
     }
 
+    MethodEmitter loadScope() {
+        return loadCompilerConstant(SCOPE).checkcast(Scope.class);
+    }
+
+    MethodEmitter setSplitState(final int state) {
+        return loadScope().load(state).invoke(Scope.SET_SPLIT_STATE);
+    }
+
     void storeCompilerConstant(final CompilerConstants cc) {
         storeCompilerConstant(cc, null);
     }
@@ -2131,10 +2137,15 @@
     }
 
     MethodEmitter invalidateSpecialName(final String name) {
-        //this is a nop if the global hasn't registered this as a special name - we can just ignore it
-        if (Global.instance().isSpecialName(name)) {
-            debug("dynamic_invalidate_name", "name=", name);
-            method.visitInvokeDynamicInsn(name, "()V", INVALIDATE_NAME_BOOTSTRAP);
+        switch (name) {
+        case "apply":
+        case "call":
+            debug("invalidate_name", "name=", name);
+            load("Function");
+            invoke(ScriptRuntime.INVALIDATE_RESERVED_BUILTIN_NAME);
+            break;
+        default:
+            break;
         }
         return this;
     }
@@ -2575,12 +2586,55 @@
      *
      * @param args debug information to print
      */
+    @SuppressWarnings("unused")
     private void debug(final Object... args) {
         if (debug) {
             debug(30, args);
         }
     }
 
+    private void debug(final String arg) {
+        if (debug) {
+            debug(30, arg);
+        }
+    }
+
+    private void debug(final Object arg0, final Object arg1) {
+        if (debug) {
+            debug(30, new Object[] { arg0, arg1 });
+        }
+    }
+
+    private void debug(final Object arg0, final Object arg1, final Object arg2) {
+        if (debug) {
+            debug(30, new Object[] { arg0, arg1, arg2 });
+        }
+    }
+
+    private void debug(final Object arg0, final Object arg1, final Object arg2, final Object arg3) {
+        if (debug) {
+            debug(30, new Object[] { arg0, arg1, arg2, arg3 });
+        }
+    }
+
+    private void debug(final Object arg0, final Object arg1, final Object arg2, final Object arg3, final Object arg4) {
+        if (debug) {
+            debug(30, new Object[] { arg0, arg1, arg2, arg3, arg4 });
+        }
+    }
+
+    private void debug(final Object arg0, final Object arg1, final Object arg2, final Object arg3, final Object arg4, final Object arg5) {
+        if (debug) {
+            debug(30, new Object[] { arg0, arg1, arg2, arg3, arg4, arg5 });
+        }
+    }
+
+    private void debug(final Object arg0, final Object arg1, final Object arg2, final Object arg3, final Object arg4, final Object arg5, final Object arg6) {
+        if (debug) {
+            debug(30, new Object[] { arg0, arg1, arg2, arg3, arg4, arg5, arg6 });
+        }
+    }
+
     /**
      * Debug function that outputs generated bytecode and stack contents
      * for a label - indentation is currently the only thing that differs
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java b/nashorn/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java
index 3c835ac..05a7687 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java
@@ -429,7 +429,6 @@
     }
 
     private static void doCleanup() throws IOException {
-        final long start = System.nanoTime();
         final Path[] files = getAllRegularFilesInLastModifiedOrder();
         final int nFiles = files.length;
         final int filesToDelete = Math.max(0, nFiles - MAX_FILES);
@@ -444,8 +443,7 @@
                 // does not increase filesDeleted
             }
             files[i] = null; // gc eligible
-        };
-        final long duration = System.nanoTime() - start;
+        }
     }
 
     private static Path[] getAllRegularFilesInLastModifiedOrder() throws IOException {
@@ -456,7 +454,7 @@
                 @Override
                 public boolean test(final Path path) {
                     return !Files.isDirectory(path);
-                };
+                }
             })
             .map(new Function<Path, PathAndTime>() {
                 @Override
@@ -497,7 +495,7 @@
         private static long getTime(final Path path) {
             try {
                 return Files.getLastModifiedTime(path).toMillis();
-            } catch (IOException e) {
+            } catch (final IOException e) {
                 // All files for which we can't retrieve the last modified date will be considered oldest.
                 return -1L;
             }
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/SplitMethodEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/SplitMethodEmitter.java
index d5feac5..792a625 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/SplitMethodEmitter.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/SplitMethodEmitter.java
@@ -25,8 +25,6 @@
 
 package jdk.nashorn.internal.codegen;
 
-import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
-
 import java.util.ArrayList;
 import java.util.List;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
@@ -34,7 +32,6 @@
 import jdk.nashorn.internal.ir.BreakableNode;
 import jdk.nashorn.internal.ir.LexicalContext;
 import jdk.nashorn.internal.ir.SplitNode;
-import jdk.nashorn.internal.runtime.Scope;
 
 /**
  * Emitter used for splitting methods. Needs to keep track of if there are jump targets
@@ -65,15 +62,13 @@
         assert splitNode != null;
         final int index = findExternalTarget(lc, label, targetNode);
         if (index >= 0) {
-            loadCompilerConstant(SCOPE);
-            checkcast(Scope.class);
-            load(index + 1);
-            invoke(Scope.SET_SPLIT_STATE);
-            loadUndefined(Type.OBJECT);
-            _return(functionNode.getReturnType());
-            return;
+            setSplitState(index + 1); // 0 is ordinary return
+            final Type retType = functionNode.getReturnType();
+            loadUndefined(retType);
+            _return(retType);
+        } else {
+            super.splitAwareGoto(lc, label, targetNode);
         }
-        super.splitAwareGoto(lc, label, targetNode);
     }
 
     private int findExternalTarget(final LexicalContext lc, final Label label, final BreakableNode targetNode) {
@@ -94,11 +89,7 @@
     @Override
     MethodEmitter registerReturn() {
         setHasReturn();
-        loadCompilerConstant(SCOPE);
-        checkcast(Scope.class);
-        load(0);
-        invoke(Scope.SET_SPLIT_STATE);
-        return this;
+        return setSplitState(0);
     }
 
     final List<Label> getExternalTargets() {
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java b/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java
index 9ce9403..9e5e5a2 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java
@@ -47,7 +47,6 @@
 import static jdk.internal.org.objectweb.asm.Opcodes.T_INT;
 import static jdk.internal.org.objectweb.asm.Opcodes.T_LONG;
 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
-
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
@@ -55,8 +54,10 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.util.Collections;
 import java.util.Map;
 import java.util.TreeMap;
+import java.util.WeakHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import jdk.internal.org.objectweb.asm.Handle;
@@ -104,6 +105,16 @@
     /** The class for this type */
     private final Class<?> clazz;
 
+    /**
+     * Cache for internal types - this is a query that requires complex stringbuilding inside
+     * ASM and it saves startup time to cache the type mappings
+     */
+    private static final Map<Class<?>, jdk.internal.org.objectweb.asm.Type> INTERNAL_TYPE_CACHE =
+            Collections.synchronizedMap(new WeakHashMap<Class<?>, jdk.internal.org.objectweb.asm.Type>());
+
+    /** Internal ASM type for this Type - computed once at construction */
+    private final jdk.internal.org.objectweb.asm.Type internalType;
+
     /** Weights are used to decide which types are "wider" than other types */
     protected static final int MIN_WEIGHT = -1;
 
@@ -122,12 +133,13 @@
      * @param slots       how many bytecode slots the type takes up
      */
     Type(final String name, final Class<?> clazz, final int weight, final int slots) {
-        this.name       = name;
-        this.clazz      = clazz;
-        this.descriptor = jdk.internal.org.objectweb.asm.Type.getDescriptor(clazz);
-        this.weight     = weight;
+        this.name         = name;
+        this.clazz        = clazz;
+        this.descriptor   = jdk.internal.org.objectweb.asm.Type.getDescriptor(clazz);
+        this.weight       = weight;
         assert weight >= MIN_WEIGHT && weight <= MAX_WEIGHT : "illegal type weight: " + weight;
-        this.slots      = slots;
+        this.slots        = slots;
+        this.internalType = getInternalType(clazz);
     }
 
     /**
@@ -299,7 +311,7 @@
      *
      * @param typeMap the type map
      * @param output data output
-     * @throws IOException
+     * @throws IOException if write cannot be completed
      */
     public static void writeTypeMap(final Map<Integer, Type> typeMap, final DataOutput output) throws IOException {
         if (typeMap == null) {
@@ -329,7 +341,7 @@
      *
      * @param input data input
      * @return type map
-     * @throws IOException
+     * @throws IOException if read cannot be completed
      */
     public static Map<Integer, Type> readTypeMap(final DataInput input) throws IOException {
         final int size = input.readInt();
@@ -357,11 +369,22 @@
     }
 
     private jdk.internal.org.objectweb.asm.Type getInternalType() {
-        return jdk.internal.org.objectweb.asm.Type.getType(getTypeClass());
+        return internalType;
+    }
+
+    private static jdk.internal.org.objectweb.asm.Type lookupInternalType(final Class<?> type) {
+        final Map<Class<?>, jdk.internal.org.objectweb.asm.Type> cache = INTERNAL_TYPE_CACHE;
+        jdk.internal.org.objectweb.asm.Type itype = cache.get(type);
+        if (itype != null) {
+            return itype;
+        }
+        itype = jdk.internal.org.objectweb.asm.Type.getType(type);
+        cache.put(type, itype);
+        return itype;
     }
 
     private static jdk.internal.org.objectweb.asm.Type getInternalType(final Class<?> type) {
-        return jdk.internal.org.objectweb.asm.Type.getType(type);
+        return lookupInternalType(type);
     }
 
     static void invokestatic(final MethodVisitor method, final Call call) {
diff --git a/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java b/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java
index c127b1a..7a60792 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/BreakNode.java
@@ -25,6 +25,7 @@
 
 package jdk.nashorn.internal.ir;
 
+import jdk.nashorn.internal.codegen.Label;
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 
@@ -68,4 +69,14 @@
     String getStatementName() {
         return "break";
     }
+
+    @Override
+    public BreakableNode getTarget(final LexicalContext lc) {
+        return lc.getBreakable(getLabelName());
+    }
+
+    @Override
+    public Label getTargetLabel(final BreakableNode target) {
+        return target.getBreakLabel();
+    }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java b/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java
index d5177db..ce62179 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java
@@ -25,6 +25,7 @@
 
 package jdk.nashorn.internal.ir;
 
+import jdk.nashorn.internal.codegen.Label;
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 
@@ -67,5 +68,16 @@
     String getStatementName() {
         return "continue";
     }
+
+
+    @Override
+    public BreakableNode getTarget(final LexicalContext lc) {
+        return lc.getContinueTo(getLabelName());
+    }
+
+    @Override
+    public Label getTargetLabel(final BreakableNode target) {
+        return ((LoopNode)target).getContinueLabel();
+    }
 }
 
diff --git a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
index b911f22..1bbc7ab 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
@@ -238,17 +238,21 @@
      * Note that even IS_STRICT is one such flag but that requires special handling.
      */
 
-    // parser, lower debugging this function
+    /** parser, print parse tree */
     public static final int IS_PRINT_PARSE       = 1 << 18;
+    /** parser, print lower parse tree */
     public static final int IS_PRINT_LOWER_PARSE = 1 << 19;
+    /** parser, print AST */
     public static final int IS_PRINT_AST         = 1 << 20;
+    /** parser, print lower AST */
     public static final int IS_PRINT_LOWER_AST   = 1 << 21;
+    /** parser, print symbols */
     public static final int IS_PRINT_SYMBOLS     = 1 << 22;
 
+    // callsite tracing, profiling within this function
     /** profile callsites in this function? */
     public static final int IS_PROFILE         = 1 << 23;
 
-    // callsite tracing, profiling within this function
     /** trace callsite enterexit in this function? */
     public static final int IS_TRACE_ENTEREXIT = 1 << 24;
 
@@ -337,7 +341,7 @@
     private FunctionNode(
         final FunctionNode functionNode,
         final long lastToken,
-        Object endParserState,
+        final Object endParserState,
         final int flags,
         final String name,
         final Type returnType,
diff --git a/nashorn/src/jdk/nashorn/internal/ir/JumpStatement.java b/nashorn/src/jdk/nashorn/internal/ir/JumpStatement.java
index aabb9de..5888a83 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/JumpStatement.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/JumpStatement.java
@@ -25,6 +25,8 @@
 
 package jdk.nashorn.internal.ir;
 
+import jdk.nashorn.internal.codegen.Label;
+
 /**
  * Common base class for jump statements (e.g. {@code break} and {@code continue}).
  */
@@ -82,6 +84,24 @@
 
     abstract String getStatementName();
 
+    /**
+     * Finds the target for this jump statement in a lexical context.
+     * @param lc the lexical context
+     * @return the target, or null if not found
+     */
+    public abstract BreakableNode getTarget(final LexicalContext lc);
+
+    /**
+     * Returns the label corresponding to this kind of jump statement (either a break or continue label) in the target.
+     * @param target the target. Note that it need not be the target of this jump statement, as the method can retrieve
+     * a label on any passed target as long as the target has a label of the requisite kind. Of course, it is advisable
+     * to invoke the method on a jump statement that targets the breakable.
+     * @return the label of the target corresponding to the kind of jump statement.
+     * @throws ClassCastException if invoked on the kind of breakable node that this jump statement is not prepared to
+     * handle.
+     */
+    public abstract Label getTargetLabel(final BreakableNode target);
+
     @Override
     public JumpStatement setLocalVariableConversion(final LexicalContext lc, final LocalVariableConversion conversion) {
         if(this.conversion == conversion) {
diff --git a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
index c6ede94..42a9cf4 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
@@ -237,6 +237,10 @@
         return value;
     }
 
+    private static Expression[] valueToArray(final List<Expression> value) {
+        return value.toArray(new Expression[value.size()]);
+    }
+
     /**
      * Create a new null literal
      *
@@ -981,10 +985,9 @@
      * @return the new literal node
      */
     public static LiteralNode<Expression[]> newInstance(final long token, final int finish, final List<Expression> value) {
-        return new ArrayLiteralNode(token, finish, value.toArray(new Expression[value.size()]));
+        return new ArrayLiteralNode(token, finish, valueToArray(value));
     }
 
-
     /**
      * Create a new array literal based on a parent node (source, token, finish)
      *
@@ -994,7 +997,7 @@
      * @return the new literal node
      */
     public static LiteralNode<?> newInstance(final Node parent, final List<Expression> value) {
-        return new ArrayLiteralNode(parent.getToken(), parent.getFinish(), value.toArray(new Expression[value.size()]));
+        return new ArrayLiteralNode(parent.getToken(), parent.getFinish(), valueToArray(value));
     }
 
     /**
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
index c6e4a50..8d7acfb 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
@@ -448,14 +448,25 @@
         return (flags & IS_FUNCTION_SELF) != 0;
     }
 
+    /**
+     * Is this a block scoped symbol
+     * @return true if block scoped
+     */
     public boolean isBlockScoped() {
         return isLet() || isConst();
     }
 
+    /**
+     * Has this symbol been declared
+     * @return true if declared
+     */
     public boolean hasBeenDeclared() {
         return (flags & HAS_BEEN_DECLARED) != 0;
     }
 
+    /**
+     * Mark this symbol as declared
+     */
     public void setHasBeenDeclared() {
         if (!hasBeenDeclared()) {
             flags |= HAS_BEEN_DECLARED;
diff --git a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java
index 8ef13d7..0622215 100644
--- a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java
+++ b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java
@@ -116,6 +116,10 @@
 
     private static final String VOID_TAG = "[VOID]";
 
+    private static void err(final String str) {
+        Context.getContext().getErr().println(str);
+    }
+
     /**
      * Tracer that is applied before a value is returned from the traced function. It will output the return
      * value and its class
@@ -124,13 +128,16 @@
      * @return return value unmodified
      */
     static Object traceReturn(final DebugLogger logger, final Object value) {
-        if (logger.isEnabled()) {
-            final String str = "    return" +
-                    (VOID_TAG.equals(value) ?
-                        ";" :
-                        " " + stripName(value) + "; // [type=" + (value == null ? "null]" : stripName(value.getClass()) + ']'));
+        final String str = "    return" +
+                (VOID_TAG.equals(value) ?
+                    ";" :
+                    " " + stripName(value) + "; // [type=" + (value == null ? "null]" : stripName(value.getClass()) + ']'));
+        if (logger == null) {
+            err(str);
+        } else if (logger.isEnabled()) {
             logger.log(TRACE_LEVEL, str);
         }
+
         return value;
     }
 
@@ -169,8 +176,11 @@
             }
         }
 
-        assert logger != null;
-        logger.log(TRACE_LEVEL, sb);
+        if (logger == null) {
+            err(sb.toString());
+        } else {
+            logger.log(TRACE_LEVEL, sb);
+        }
         stacktrace(logger);
     }
 
@@ -181,7 +191,12 @@
         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
         final PrintStream ps = new PrintStream(baos);
         new Throwable().printStackTrace(ps);
-        logger.log(TRACE_LEVEL, baos.toString());
+        final String st = baos.toString();
+        if (logger == null) {
+            err(st);
+        } else {
+            logger.log(TRACE_LEVEL, st);
+        }
     }
 
     private static String argString(final Object arg) {
@@ -201,7 +216,7 @@
         if (arg instanceof ScriptObject) {
             return arg.toString() +
                 " (map=" + Debug.id(((ScriptObject)arg).getMap()) +
-                ")";
+                ')';
         }
 
         return arg.toString();
@@ -209,6 +224,18 @@
 
     /**
      * Add a debug printout to a method handle, tracing parameters and return values
+     * Output will be unconditional to stderr
+     *
+     * @param mh  method handle to trace
+     * @param tag start of trace message
+     * @return traced method handle
+     */
+    public static MethodHandle addDebugPrintout(final MethodHandle mh, final Object tag) {
+        return addDebugPrintout(null, Level.OFF, mh, 0, true, tag);
+    }
+
+    /**
+     * Add a debug printout to a method handle, tracing parameters and return values
      *
      * @param logger a specific logger to which to write the output
      * @param level level over which to print
@@ -222,6 +249,20 @@
 
     /**
      * Add a debug printout to a method handle, tracing parameters and return values
+     * Output will be unconditional to stderr
+     *
+     * @param mh  method handle to trace
+     * @param paramStart first param to print/trace
+     * @param printReturnValue should we print/trace return value if available?
+     * @param tag start of trace message
+     * @return  traced method handle
+     */
+    public static MethodHandle addDebugPrintout(final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Object tag) {
+        return addDebugPrintout(null, Level.OFF, mh, paramStart, printReturnValue, tag);
+    }
+
+     /**
+     * Add a debug printout to a method handle, tracing parameters and return values
      *
      * @param logger a specific logger to which to write the output
      * @param level level over which to print
@@ -240,7 +281,6 @@
             return mh;
         }
 
-        assert logger != null;
         assert TRACE != null;
 
         MethodHandle trace = MethodHandles.insertArguments(TRACE, 0, logger, tag, paramStart);
@@ -428,6 +468,12 @@
         }
 
         @Override
+        public MethodHandle identity(final Class<?> type) {
+            final MethodHandle mh = MethodHandles.identity(type);
+            return debug(mh, "identity", type);
+        }
+
+        @Override
         public MethodHandle asCollector(final MethodHandle handle, final Class<?> arrayType, final int arrayLength) {
             final MethodHandle mh = handle.asCollector(arrayType, arrayLength);
             return debug(mh, "asCollector", handle, arrayType, arrayLength);
diff --git a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java
index 756c0b7..beaa85c 100644
--- a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java
+++ b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFunctionality.java
@@ -173,6 +173,15 @@
     public MethodHandle constant(Class<?> type, Object value);
 
     /**
+     * Wrapper for {@link java.lang.invoke.MethodHandles#identity(Class)}
+     *
+     * @param type  type of value
+     *
+     * @return method handle that returns identity argument
+     */
+    public MethodHandle identity(Class<?> type);
+
+    /**
      * Wrapper for {@link java.lang.invoke.MethodHandle#asType(MethodType)}
      *
      * @param handle  method handle for type conversion
diff --git a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
index 93506c3..efcc3dd 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
@@ -31,6 +31,7 @@
 
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java
index b8ec90f..eb56de0 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java
@@ -25,23 +25,19 @@
 
 package jdk.nashorn.internal.objects;
 
-import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
 import static jdk.nashorn.internal.lookup.Lookup.MH;
 import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.lang.invoke.CallSite;
-import java.lang.invoke.ConstantCallSite;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
 import java.lang.invoke.SwitchPoint;
 import java.lang.reflect.Field;
+import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
@@ -52,8 +48,6 @@
 import jdk.internal.dynalink.linker.LinkRequest;
 import jdk.nashorn.api.scripting.ClassFilter;
 import jdk.nashorn.api.scripting.ScriptObjectMirror;
-import jdk.nashorn.internal.codegen.ApplySpecialization;
-import jdk.nashorn.internal.codegen.CompilerConstants.Call;
 import jdk.nashorn.internal.lookup.Lookup;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Property;
@@ -72,6 +66,7 @@
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.ScriptingFunctions;
+import jdk.nashorn.internal.runtime.Specialization;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.InvokeByName;
@@ -107,10 +102,6 @@
      * it's when you start adding property checks for said builtins you have
      * problems with guard speed.
      */
-    public final Map<String, SwitchPoint> optimisticFunctionMap;
-
-    /** Name invalidator for things like call/apply */
-    public static final Call BOOTSTRAP = staticCall(MethodHandles.lookup(), Global.class, "invalidateNameBootstrap", CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
 
     /** Nashorn extension: arguments array */
     @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
@@ -428,9 +419,6 @@
     private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH_S("loadWithNewGlobal",   Object.class, Object.class, Object[].class);
     private static final MethodHandle EXIT              = findOwnMH_S("exit",                Object.class, Object.class, Object.class);
 
-    /** Invalidate a reserved name, such as "apply" or "call" if assigned */
-    public MethodHandle INVALIDATE_RESERVED_NAME = MH.bindTo(findOwnMH_V("invalidateReservedName", void.class, String.class), this);
-
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
@@ -482,7 +470,6 @@
         super(checkAndGetMap(context));
         this.context = context;
         this.setIsScope();
-        this.optimisticFunctionMap = new HashMap<>();
         //we can only share one instance of Global constants between globals, or we consume way too much
         //memory - this is good enough for most programs
         while (gcsInstance.get() == null) {
@@ -574,6 +561,7 @@
      *
      * @param engine ScriptEngine to initialize
      */
+    @SuppressWarnings("hiding")
     public void initBuiltinObjects(final ScriptEngine engine) {
         if (this.builtinObject != null) {
             // already initialized, just return
@@ -918,10 +906,12 @@
         }
 
         switch (nameStr) {
-            case "context":
-                return sctxt;
-            case "engine":
-                return global.engine;
+        case "context":
+            return sctxt;
+        case "engine":
+            return global.engine;
+        default:
+            break;
         }
 
         if (self == UNDEFINED) {
@@ -1244,6 +1234,40 @@
         return instance.function == instance.getBuiltinFunction();
     }
 
+    /**
+     * Get the switchpoint used to check property changes for Function.prototype.apply
+     * @return the switchpoint guarding apply (same as guarding call, and everything else in function)
+     */
+    public static SwitchPoint getBuiltinFunctionApplySwitchPoint() {
+        return ScriptFunction.getPrototype(Global.instance().getBuiltinFunction()).getProperty("apply").getBuiltinSwitchPoint();
+    }
+
+    private static boolean isBuiltinFunctionProperty(final String name) {
+        final Global instance = Global.instance();
+        final ScriptFunction builtinFunction = instance.getBuiltinFunction();
+        if (builtinFunction == null) {
+            return false; //conservative for compile-only mode
+        }
+        final boolean isBuiltinFunction = instance.function == builtinFunction;
+        return isBuiltinFunction && ScriptFunction.getPrototype(builtinFunction).getProperty(name).isBuiltin();
+    }
+
+    /**
+     * Check if the Function.prototype.apply has not been replaced
+     * @return true if Function.prototype.apply has been replaced
+     */
+    public static boolean isBuiltinFunctionPrototypeApply() {
+        return isBuiltinFunctionProperty("apply");
+    }
+
+    /**
+     * Check if the Function.prototype.apply has not been replaced
+     * @return true if Function.prototype.call has been replaced
+     */
+    public static boolean isBuiltinFunctionPrototypeCall() {
+        return isBuiltinFunctionProperty("call");
+    }
+
     private ScriptFunction getBuiltinJSAdapter() {
         return builtinJSAdapter;
     }
@@ -1688,6 +1712,13 @@
         splitState = state;
     }
 
+    private <T extends ScriptObject> T initConstructorAndSwitchPoint(final String name, final Class<T> clazz) {
+        final T func = initConstructor(name, clazz);
+        tagBuiltinProperties(name, func);
+        return func;
+    }
+
+    @SuppressWarnings("hiding")
     private void init(final ScriptEngine engine) {
         assert Context.getGlobal() == this : "this global is not set as current";
 
@@ -1702,8 +1733,19 @@
         // initialize global function properties
         this.eval = this.builtinEval = ScriptFunctionImpl.makeFunction("eval", EVAL);
 
-        this.parseInt           = ScriptFunctionImpl.makeFunction("parseInt",   GlobalFunctions.PARSEINT,
-                new MethodHandle[] { GlobalFunctions.PARSEINT_OI, GlobalFunctions.PARSEINT_O });
+        this.parseInt = ScriptFunctionImpl.makeFunction("parseInt",   GlobalFunctions.PARSEINT,
+                    new Specialization[] {
+                    new Specialization(GlobalFunctions.PARSEINT_Z),
+                    new Specialization(GlobalFunctions.PARSEINT_I),
+                    new Specialization(GlobalFunctions.PARSEINT_J),
+                    new Specialization(GlobalFunctions.PARSEINT_OI),
+                    new Specialization(GlobalFunctions.PARSEINT_O) });
+        this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
+        this.isNaN = ScriptFunctionImpl.makeFunction("isNaN",   GlobalFunctions.IS_NAN,
+                   new Specialization[] {
+                        new Specialization(GlobalFunctions.IS_NAN_I),
+                        new Specialization(GlobalFunctions.IS_NAN_J),
+                        new Specialization(GlobalFunctions.IS_NAN_D) });
         this.parseFloat         = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
         this.isNaN              = ScriptFunctionImpl.makeFunction("isNaN",      GlobalFunctions.IS_NAN);
         this.isFinite           = ScriptFunctionImpl.makeFunction("isFinite",   GlobalFunctions.IS_FINITE);
@@ -1720,15 +1762,15 @@
         this.quit               = ScriptFunctionImpl.makeFunction("quit",       EXIT);
 
         // built-in constructors
-        this.builtinArray     = initConstructor("Array", ScriptFunction.class);
-        this.builtinBoolean   = initConstructor("Boolean", ScriptFunction.class);
-        this.builtinDate      = initConstructor("Date", ScriptFunction.class);
-        this.builtinJSON      = initConstructor("JSON", ScriptObject.class);
-        this.builtinJSAdapter = initConstructor("JSAdapter", ScriptFunction.class);
-        this.builtinMath      = initConstructor("Math", ScriptObject.class);
-        this.builtinNumber    = initConstructor("Number", ScriptFunction.class);
-        this.builtinRegExp    = initConstructor("RegExp", ScriptFunction.class);
-        this.builtinString    = initConstructor("String", ScriptFunction.class);
+        this.builtinArray     = initConstructorAndSwitchPoint("Array", ScriptFunction.class);
+        this.builtinBoolean   = initConstructorAndSwitchPoint("Boolean", ScriptFunction.class);
+        this.builtinDate      = initConstructorAndSwitchPoint("Date", ScriptFunction.class);
+        this.builtinJSON      = initConstructorAndSwitchPoint("JSON", ScriptObject.class);
+        this.builtinJSAdapter = initConstructorAndSwitchPoint("JSAdapter", ScriptFunction.class);
+        this.builtinMath      = initConstructorAndSwitchPoint("Math", ScriptObject.class);
+        this.builtinNumber    = initConstructorAndSwitchPoint("Number", ScriptFunction.class);
+        this.builtinRegExp    = initConstructorAndSwitchPoint("RegExp", ScriptFunction.class);
+        this.builtinString    = initConstructorAndSwitchPoint("String", ScriptFunction.class);
 
         // initialize String.prototype.length to 0
         // add String.prototype.length
@@ -1830,6 +1872,8 @@
         // Error.prototype.message = "";
         errorProto.set(NativeError.MESSAGE, "", 0);
 
+        tagBuiltinProperties("Error", builtinError);
+
         this.builtinEvalError = initErrorSubtype("EvalError", errorProto);
         this.builtinRangeError = initErrorSubtype("RangeError", errorProto);
         this.builtinReferenceError = initErrorSubtype("ReferenceError", errorProto);
@@ -1844,6 +1888,7 @@
         prototype.set(NativeError.NAME, name, 0);
         prototype.set(NativeError.MESSAGE, "", 0);
         prototype.setInitialProto(errorProto);
+        tagBuiltinProperties(name, cons);
         return cons;
     }
 
@@ -1910,17 +1955,18 @@
     }
 
     private void initTypedArray() {
-        this.builtinArrayBuffer       = initConstructor("ArrayBuffer", ScriptFunction.class);
-        this.builtinDataView          = initConstructor("DataView", ScriptFunction.class);
-        this.builtinInt8Array         = initConstructor("Int8Array", ScriptFunction.class);
-        this.builtinUint8Array        = initConstructor("Uint8Array", ScriptFunction.class);
-        this.builtinUint8ClampedArray = initConstructor("Uint8ClampedArray", ScriptFunction.class);
-        this.builtinInt16Array        = initConstructor("Int16Array", ScriptFunction.class);
-        this.builtinUint16Array       = initConstructor("Uint16Array", ScriptFunction.class);
-        this.builtinInt32Array        = initConstructor("Int32Array", ScriptFunction.class);
-        this.builtinUint32Array       = initConstructor("Uint32Array", ScriptFunction.class);
-        this.builtinFloat32Array      = initConstructor("Float32Array", ScriptFunction.class);
-        this.builtinFloat64Array      = initConstructor("Float64Array", ScriptFunction.class);
+        this.builtinArrayBuffer       = initConstructorAndSwitchPoint("ArrayBuffer", ScriptFunction.class);
+        this.builtinDataView          = initConstructorAndSwitchPoint("DataView", ScriptFunction.class);
+        this.builtinInt8Array         = initConstructorAndSwitchPoint("Int8Array", ScriptFunction.class);
+        this.builtinUint8Array        = initConstructorAndSwitchPoint("Uint8Array", ScriptFunction.class);
+        this.builtinUint8ClampedArray = initConstructorAndSwitchPoint("Uint8ClampedArray", ScriptFunction.class);
+        this.builtinInt16Array        = initConstructorAndSwitchPoint("Int16Array", ScriptFunction.class);
+        this.builtinUint16Array       = initConstructorAndSwitchPoint("Uint16Array", ScriptFunction.class);
+        this.builtinInt32Array        = initConstructorAndSwitchPoint("Int32Array", ScriptFunction.class);
+        this.builtinUint32Array       = initConstructorAndSwitchPoint("Uint32Array", ScriptFunction.class);
+        this.builtinFloat32Array      = initConstructorAndSwitchPoint("Float32Array", ScriptFunction.class);
+        this.builtinFloat64Array      = initConstructorAndSwitchPoint("Float64Array", ScriptFunction.class);
+
     }
 
     private void copyBuiltins() {
@@ -1993,10 +2039,6 @@
         return UNDEFINED;
     }
 
-    /**
-     * These classes are generated by nasgen tool and so we have to use
-     * reflection to load and create new instance of these classes.
-     */
     private <T extends ScriptObject> T initConstructor(final String name, final Class<T> clazz) {
         try {
             // Assuming class name pattern for built-in JS constructors.
@@ -2021,12 +2063,52 @@
             }
 
             res.setIsBuiltin();
+
             return res;
         } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
             throw new RuntimeException(e);
         }
     }
 
+    private List<jdk.nashorn.internal.runtime.Property> extractBuiltinProperties(final String name, final ScriptObject func) {
+        final List<jdk.nashorn.internal.runtime.Property> list = new ArrayList<>();
+
+        list.addAll(Arrays.asList(func.getMap().getProperties()));
+
+        if (func instanceof ScriptFunction) {
+            final ScriptObject proto = ScriptFunction.getPrototype((ScriptFunction)func);
+            if (proto != null) {
+                list.addAll(Arrays.asList(proto.getMap().getProperties()));
+            }
+        }
+
+        final jdk.nashorn.internal.runtime.Property prop = getProperty(name);
+        if (prop != null) {
+            list.add(prop);
+        }
+
+        return list;
+    }
+
+    /**
+     * Given a builtin object, traverse its properties recursively and associate them with a name that
+     * will be a key to their invalidation switchpoint.
+     * @param name name for key
+     * @param func builtin script object
+     */
+    private void tagBuiltinProperties(final String name, final ScriptObject func) {
+        SwitchPoint sp = context.getBuiltinSwitchPoint(name);
+        if (sp == null) {
+            sp = context.newBuiltinSwitchPoint(name);
+        }
+
+        //get all builtin properties in this builtin object and register switchpoints keyed on the propery name,
+        //one overwrite destroys all for now, e.g. Function.prototype.apply = 17; also destroys Function.prototype.call etc
+        for (final jdk.nashorn.internal.runtime.Property prop : extractBuiltinProperties(name, func)) {
+            prop.setBuiltinSwitchPoint(sp);
+        }
+    }
+
     // Function and Object constructors are inter-dependent. Also,
     // Function.prototype
     // functions are not properly initialized. We fix the references here.
@@ -2035,7 +2117,8 @@
     // to play with object references carefully!!
     private void initFunctionAndObject() {
         // First-n-foremost is Function
-        this.builtinFunction      = initConstructor("Function", ScriptFunction.class);
+
+        this.builtinFunction = initConstructor("Function", ScriptFunction.class);
 
         // create global anonymous function
         final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction();
@@ -2101,13 +2184,6 @@
             }
         }
 
-        //make sure apply and call have the same invalidation switchpoint
-        final SwitchPoint sp = new SwitchPoint();
-        optimisticFunctionMap.put("apply", sp);
-        optimisticFunctionMap.put("call", sp);
-        getFunctionPrototype().getProperty("apply").setChangeCallback(sp);
-        getFunctionPrototype().getProperty("call").setChangeCallback(sp);
-
         properties = getObjectPrototype().getMap().getProperties();
 
         for (final jdk.nashorn.internal.runtime.Property property : properties) {
@@ -2125,10 +2201,10 @@
                 }
             }
         }
-    }
 
-    private static MethodHandle findOwnMH_V(final String name, final Class<?> rtype, final Class<?>... types) {
-        return MH.findVirtual(MethodHandles.lookup(), Global.class, name, MH.type(rtype, types));
+        tagBuiltinProperties("Object", builtinObject);
+        tagBuiltinProperties("Function", builtinFunction);
+        tagBuiltinProperties("Function", anon);
     }
 
     private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
@@ -2147,62 +2223,4 @@
     protected boolean isGlobal() {
         return true;
     }
-
-    /**
-     * Check if there is a switchpoint for a reserved name. If there
-     * is, it must be invalidated upon properties with this name
-     * @param name property name
-     * @return switchpoint for invalidating this property, or null if not registered
-     */
-    public SwitchPoint getChangeCallback(final String name) {
-        return optimisticFunctionMap.get(name);
-    }
-
-    /**
-     * Is this a special name, that might be subject to invalidation
-     * on write, such as "apply" or "call"
-     * @param name name to check
-     * @return true if special name
-     */
-    public boolean isSpecialName(final String name) {
-        return getChangeCallback(name) != null;
-    }
-
-    /**
-     * Check if a reserved property name is invalidated
-     * @param name property name
-     * @return true if someone has written to it since Global was instantiated
-     */
-    public boolean isSpecialNameValid(final String name) {
-        final SwitchPoint sp = getChangeCallback(name);
-        return sp != null && !sp.hasBeenInvalidated();
-    }
-
-    /**
-     * Tag a reserved name as invalidated - used when someone writes
-     * to a property with this name - overly conservative, but link time
-     * is too late to apply e.g. apply-&gt;call specialization
-     * @param name property name
-     */
-    public void invalidateReservedName(final String name) {
-        final SwitchPoint sp = getChangeCallback(name);
-        if (sp != null) {
-            getContext().getLogger(ApplySpecialization.class).info("Overwrote special name '" + name +"' - invalidating switchpoint");
-            SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
-        }
-    }
-
-    /**
-     * Bootstrapper for invalidating a builtin name
-     * @param lookup lookup
-     * @param name   name to invalidate
-     * @param type   methodhandle type
-     * @return callsite for invalidator
-     */
-    public static CallSite invalidateNameBootstrap(final MethodHandles.Lookup lookup, final String name, final MethodType type) {
-        final MethodHandle target = MH.insertArguments(Global.instance().INVALIDATE_RESERVED_NAME, 0, name);
-        return new ConstantCallSite(target);
-    }
-
-
 }
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
index 163e86a..c83e888 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -33,8 +33,8 @@
 import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.arrayLikeIterator;
 import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.reverseArrayLikeIterator;
 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT;
-
 import java.lang.invoke.MethodHandle;
+import java.lang.invoke.SwitchPoint;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -52,12 +52,13 @@
 import jdk.nashorn.internal.objects.annotations.Getter;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
 import jdk.nashorn.internal.objects.annotations.Setter;
-import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
 import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
 import jdk.nashorn.internal.objects.annotations.Where;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.Debug;
 import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.OptimisticBuiltins;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptFunction;
@@ -67,17 +68,20 @@
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
 import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
+import jdk.nashorn.internal.runtime.arrays.ContinuousArrayData;
+import jdk.nashorn.internal.runtime.arrays.IntElements;
+import jdk.nashorn.internal.runtime.arrays.IntOrLongElements;
 import jdk.nashorn.internal.runtime.arrays.IteratorAction;
+import jdk.nashorn.internal.runtime.arrays.NumericElements;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.InvokeByName;
-import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 
 /**
  * Runtime representation of a JavaScript array. NativeArray only holds numeric
  * keyed values. All other values are stored in spill.
  */
 @ScriptClass("Array")
-public final class NativeArray extends ScriptObject {
+public final class NativeArray extends ScriptObject implements OptimisticBuiltins {
     private static final Object JOIN                     = new Object();
     private static final Object EVERY_CALLBACK_INVOKER   = new Object();
     private static final Object SOME_CALLBACK_INVOKER    = new Object();
@@ -88,6 +92,16 @@
     private static final Object CALL_CMP                 = new Object();
     private static final Object TO_LOCALE_STRING         = new Object();
 
+    private SwitchPoint   lengthMadeNotWritableSwitchPoint;
+    private PushLinkLogic pushLinkLogic;
+    private PopLinkLogic  popLinkLogic;
+
+    /**
+     * Index for the modification SwitchPoint that triggers when length
+     * becomes not writable
+     */
+    private static final int LENGTH_NOT_WRITABLE_SWITCHPOINT = 0;
+
     /*
      * Constructors.
      */
@@ -420,6 +434,28 @@
         return getArray().asObjectArray();
     }
 
+    @Override
+    public void setIsLengthNotWritable() {
+        super.setIsLengthNotWritable();
+        /*
+         * Switchpoints are created lazily. If we link any push or pop site,
+         * we need to create the "length made not writable" switchpoint, if it
+         * doesn't exist.
+         *
+         * If the switchpoint already exists, we will find it here, and invalidate
+         * it, invalidating all previous callsites that use it.
+         *
+         * If the switchpoint doesn't exist, no push/pop has been linked so far,
+         * because that would create it too. We invalidate it immediately and the
+         * check link logic for all future callsites will fail immediately at link
+         * time
+         */
+        if (lengthMadeNotWritableSwitchPoint == null) {
+            lengthMadeNotWritableSwitchPoint = new SwitchPoint();
+        }
+        SwitchPoint.invalidateAll(new SwitchPoint[] { lengthMadeNotWritableSwitchPoint });
+    }
+
     /**
      * ECMA 15.4.3.2 Array.isArray ( arg )
      *
@@ -638,7 +674,7 @@
      * @param self   self reference
      * @return the new NativeArray
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static NativeArray construct(final boolean newObj, final Object self) {
         return new NativeArray(0);
     }
@@ -653,7 +689,7 @@
      * @param element first element
      * @return the new NativeArray
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static Object construct(final boolean newObj, final Object self, final boolean element) {
         return new NativeArray(new Object[] { element });
     }
@@ -668,7 +704,7 @@
      * @param length array length
      * @return the new NativeArray
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static NativeArray construct(final boolean newObj, final Object self, final int length) {
         if (length >= 0) {
             return new NativeArray(length);
@@ -687,7 +723,7 @@
      * @param length array length
      * @return the new NativeArray
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static NativeArray construct(final boolean newObj, final Object self, final long length) {
         if (length >= 0L && length <= JSType.MAX_UINT) {
             return new NativeArray(length);
@@ -706,7 +742,7 @@
      * @param length array length
      * @return the new NativeArray
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static NativeArray construct(final boolean newObj, final Object self, final double length) {
         final long uint32length = JSType.toUint32(length);
 
@@ -721,7 +757,7 @@
      * ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
      *
      * @param self self reference
-     * @param args arguments to concat
+     * @param args arguments
      * @return resulting NativeArray
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
@@ -793,6 +829,68 @@
     }
 
     /**
+     * Specialization of pop for ContinuousArrayData
+     *   The link guard checks that the array is continuous AND not empty.
+     *   The runtime guard checks that the guard is continuous (CCE otherwise)
+     *
+     * Primitive specialization, {@link LinkLogic}
+     *
+     * @param self self reference
+     * @return element popped
+     * @throws ClassCastException if array is empty, facilitating Undefined return value
+     */
+    @SpecializedFunction(name="pop", linkLogic=PopLinkLogic.class)
+    public static int popInt(final Object self) {
+        //must be non empty IntArrayData
+        return getContinuousNonEmptyArrayDataCCE(self, IntElements.class).fastPopInt();
+    }
+
+    /**
+     * Specialization of pop for ContinuousArrayData
+     *
+     * Primitive specialization, {@link LinkLogic}
+     *
+     * @param self self reference
+     * @return element popped
+     * @throws ClassCastException if array is empty, facilitating Undefined return value
+     */
+    @SpecializedFunction(name="pop", linkLogic=PopLinkLogic.class)
+    public static long popLong(final Object self) {
+        //must be non empty Int or LongArrayData
+        return getContinuousNonEmptyArrayDataCCE(self, IntOrLongElements.class).fastPopLong();
+    }
+
+    /**
+     * Specialization of pop for ContinuousArrayData
+     *
+     * Primitive specialization, {@link LinkLogic}
+     *
+     * @param self self reference
+     * @return element popped
+     * @throws ClassCastException if array is empty, facilitating Undefined return value
+     */
+    @SpecializedFunction(name="pop", linkLogic=PopLinkLogic.class)
+    public static double popDouble(final Object self) {
+        //must be non empty int long or double array data
+        return getContinuousNonEmptyArrayDataCCE(self, NumericElements.class).fastPopDouble();
+    }
+
+    /**
+     * Specialization of pop for ContinuousArrayData
+     *
+     * Primitive specialization, {@link LinkLogic}
+     *
+     * @param self self reference
+     * @return element popped
+     * @throws ClassCastException if array is empty, facilitating Undefined return value
+     */
+    @SpecializedFunction(name="pop", linkLogic=PopLinkLogic.class)
+    public static Object popObject(final Object self) {
+        //can be any data, because the numeric ones will throw cce and force relink
+        return getContinuousArrayDataCCE(self, null).fastPopObject();
+    }
+
+    /**
      * ECMA 15.4.4.6 Array.prototype.pop ()
      *
      * @param self self reference
@@ -829,6 +927,62 @@
     /**
      * ECMA 15.4.4.7 Array.prototype.push (args...)
      *
+     * Primitive specialization, {@link LinkLogic}
+     *
+     * @param self self reference
+     * @param arg a primitive to push
+     * @return array length after push
+     */
+    @SpecializedFunction(linkLogic=PushLinkLogic.class)
+    public static long push(final Object self, final int arg) {
+        return getContinuousArrayDataCCE(self, Integer.class).fastPush(arg);
+    }
+
+    /**
+     * ECMA 15.4.4.7 Array.prototype.push (args...)
+     *
+     * Primitive specialization, {@link LinkLogic}
+     *
+     * @param self self reference
+     * @param arg a primitive to push
+     * @return array length after push
+     */
+    @SpecializedFunction(linkLogic=PushLinkLogic.class)
+    public static long push(final Object self, final long arg) {
+        return getContinuousArrayDataCCE(self, Long.class).fastPush(arg);
+    }
+
+    /**
+     * ECMA 15.4.4.7 Array.prototype.push (args...)
+     *
+     * Primitive specialization, {@link LinkLogic}
+     *
+     * @param self self reference
+     * @param arg a primitive to push
+     * @return array length after push
+     */
+    @SpecializedFunction(linkLogic=PushLinkLogic.class)
+    public static long push(final Object self, final double arg) {
+        return getContinuousArrayDataCCE(self, Double.class).fastPush(arg);
+    }
+
+    /**
+     * ECMA 15.4.4.7 Array.prototype.push (args...)
+     *
+     * Primitive specialization, {@link LinkLogic}
+     *
+     * @param self self reference
+     * @param arg a primitive to push
+     * @return array length after push
+     */
+    @SpecializedFunction(name="push", linkLogic=PushLinkLogic.class)
+    public static long pushObject(final Object self, final Object arg) {
+        return getContinuousArrayDataCCE(self, Object.class).fastPush(arg);
+    }
+
+    /**
+     * ECMA 15.4.4.7 Array.prototype.push (args...)
+     *
      * @param self self reference
      * @param args arguments to push
      * @return array length after pushes
@@ -857,61 +1011,6 @@
     }
 
     /**
-     * ECMA 15.4.4.7 Array.prototype.push (args...) specialized for single int argument
-     *
-     * @param self self reference
-     * @param arg argument to push
-     * @return array after pushes
-     */
-/*    @SpecializedFunction
-    public static long push(final Object self, final int arg) {
-        try {
-            final ScriptObject sobj = (ScriptObject)self;
-            final ArrayData arrayData = sobj.getArray();
-            final long length = arrayData.length();
-
-            if (bulkable(sobj) && length + 1 <= JSType.MAX_UINT) {
-                sobj.setArray(arrayData.ensure(length).set(ArrayIndex.getArrayIndex(length), arg, true));
-                return length + 1;
-            }
-
-            long len = JSType.toUint32(sobj.getLength());
-            sobj.set(len++, arg, true);
-            sobj.set("length", len, true);
-            return len;
-        } catch (final ClassCastException | NullPointerException e) {
-            throw typeError("not.an.object", ScriptRuntime.safeToString(self));
-        }
-    }
-*/
-    /**
-     * ECMA 15.4.4.7 Array.prototype.push (args...) specialized for single number argument
-     *
-     * @param self self reference
-     * @param arg argument to push
-     * @return array after pushes
-     */
- /*   @SpecializedFunction
-    public static long push(final Object self, final double arg) {
-        try {
-            final ScriptObject sobj = (ScriptObject)self;        final ArrayData arrayData = sobj.getArray();
-            final long length = arrayData.length();
-
-            if (bulkable(sobj) && length + 1 <= JSType.MAX_UINT) {
-                sobj.setArray(arrayData.ensure(length).set(ArrayIndex.getArrayIndex(length), arg, true));
-                return length + 1;
-            }
-
-            long len = JSType.toUint32(sobj.getLength());
-            sobj.set(len++, arg, true);
-            sobj.set("length", len, true);
-            return len;
-        } catch (final ClassCastException | NullPointerException e) {
-            throw typeError("not.an.object", ScriptRuntime.safeToString(self));
-        }
-    }
-*/
-    /**
      * ECMA 15.4.4.7 Array.prototype.push (args...) specialized for single object argument
      *
      * @param self self reference
@@ -925,7 +1024,7 @@
             final ArrayData arrayData = sobj.getArray();
             final long length = arrayData.length();
             if (bulkable(sobj) && length < JSType.MAX_UINT) {
-                sobj.setArray(arrayData.push(true, arg)); //ensure(length).set(ArrayIndex.getArrayIndex(length), arg, true));
+                sobj.setArray(arrayData.push(true, arg));
                 return length + 1;
             }
 
@@ -1584,6 +1683,192 @@
 
     @Override
     public String toString() {
-        return "NativeArray@" + Debug.id(this) + '@' + getArray().getClass().getSimpleName();
+        return "NativeArray@" + Debug.id(this) + " [" + getArray().getClass().getSimpleName() + ']';
+    }
+
+    @Override
+    public SpecializedFunction.LinkLogic getLinkLogic(final Class<? extends LinkLogic> clazz) {
+        if (clazz == PushLinkLogic.class) {
+            return pushLinkLogic == null ? new PushLinkLogic(this) : pushLinkLogic;
+        } else if (clazz == PopLinkLogic.class) {
+            return popLinkLogic == null ? new PopLinkLogic(this) : pushLinkLogic;
+        }
+        return null;
+    }
+
+    @Override
+    public boolean hasPerInstanceAssumptions() {
+        return true; //length switchpoint
+    }
+
+    /**
+     * This is an abstract super class that contains common functionality for all
+     * specialized optimistic builtins in NativeArray. For example, it handles the
+     * modification switchpoint which is touched when length is written.
+     */
+    private static abstract class ArrayLinkLogic extends SpecializedFunction.LinkLogic {
+        private final NativeArray array;
+
+        protected ArrayLinkLogic(final NativeArray array) {
+            this.array = array;
+        }
+
+        private SwitchPoint getSwitchPoint() {
+            return array.lengthMadeNotWritableSwitchPoint;
+        }
+
+        private SwitchPoint newSwitchPoint() {
+            assert array.lengthMadeNotWritableSwitchPoint == null;
+            final SwitchPoint sp = new SwitchPoint();
+            array.lengthMadeNotWritableSwitchPoint = sp;
+            return sp;
+        }
+
+        protected static ContinuousArrayData getContinuousArrayData(final Object self) {
+            try {
+                //cast to NativeArray, to avoid cases like x = {0:0, 1:1}, x.length = 2, where we can't use the array push/pop
+                return (ContinuousArrayData)((NativeArray)self).getArray();
+            } catch (final Exception e) {
+                return null;
+            }
+        }
+
+        /**
+         * Push and pop callsites can throw ClassCastException as a mechanism to have them
+         * relinked - this enabled fast checks of the kind of ((IntArrayData)arrayData).push(x)
+         * for an IntArrayData only push - if this fails, a CCE will be thrown and we will relink
+         */
+        @Override
+        public Class<? extends Throwable> getRelinkException() {
+            return ClassCastException.class;
+        }
+
+        @Override
+        public boolean hasModificationSwitchPoints() {
+            return getSwitchPoint() != null;
+        }
+
+        @Override
+        public boolean hasModificationSwitchPoint(final int index) {
+            assert index == LENGTH_NOT_WRITABLE_SWITCHPOINT;
+            return hasModificationSwitchPoints();
+        }
+
+        @Override
+        public SwitchPoint getOrCreateModificationSwitchPoint(final int index) {
+            assert index == LENGTH_NOT_WRITABLE_SWITCHPOINT;
+            SwitchPoint sp = getSwitchPoint();
+            if (sp == null) {
+                sp = newSwitchPoint();
+            }
+            return sp;
+        }
+
+        @Override
+        public SwitchPoint[] getOrCreateModificationSwitchPoints() {
+            return new SwitchPoint[] { getOrCreateModificationSwitchPoint(LENGTH_NOT_WRITABLE_SWITCHPOINT) };
+        }
+
+        @Override
+        public void invalidateModificationSwitchPoint(final int index) {
+            assert index == LENGTH_NOT_WRITABLE_SWITCHPOINT;
+            invalidateModificationSwitchPoints();
+        }
+
+        @Override
+        public void invalidateModificationSwitchPoints() {
+            final SwitchPoint sp = getSwitchPoint();
+            assert sp != null : "trying to invalidate non-existant modified SwitchPoint";
+            if (!sp.hasBeenInvalidated()) {
+                SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
+            }
+        }
+
+        @Override
+        public boolean hasInvalidatedModificationSwitchPoint(final int index) {
+            assert index == LENGTH_NOT_WRITABLE_SWITCHPOINT;
+            return hasInvalidatedModificationSwitchPoints();
+        }
+
+        @Override
+        public boolean hasInvalidatedModificationSwitchPoints() {
+            final SwitchPoint sp = getSwitchPoint();
+            return sp != null && !sp.hasBeenInvalidated();
+        }
+    }
+
+    /**
+     * This is linker logic for optimistic pushes
+     */
+    private static final class PushLinkLogic extends ArrayLinkLogic {
+        private PushLinkLogic(final NativeArray array) {
+            super(array);
+        }
+
+        @Override
+        public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
+            return getContinuousArrayData(self) != null;
+        }
+    }
+
+    /**
+     * This is linker logic for optimistic pops
+     */
+    private static final class PopLinkLogic extends ArrayLinkLogic {
+        private PopLinkLogic(final NativeArray array) {
+            super(array);
+        }
+
+        /**
+         * We need to check if we are dealing with a continuous non empty array data here,
+         * as pop with a primitive return value returns undefined for arrays with length 0
+         */
+        @Override
+        public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
+            final ContinuousArrayData data = getContinuousNonEmptyArrayData(self);
+            if (data != null) {
+                final Class<?> elementType = data.getElementType();
+                final Class<?> returnType  = desc.getMethodType().returnType();
+                final boolean  typeFits    = JSType.getAccessorTypeIndex(returnType) >= JSType.getAccessorTypeIndex(elementType);
+                return typeFits;
+            }
+            return false;
+        }
+
+        private static ContinuousArrayData getContinuousNonEmptyArrayData(final Object self) {
+            final ContinuousArrayData data = getContinuousArrayData(self);
+            if (data != null) {
+                return data.length() == 0 ? null : data;
+            }
+            return null;
+        }
+    }
+
+    //runtime calls for push and pops. they could be used as guards, but they also perform the runtime logic,
+    //so rather than synthesizing them into a guard method handle that would also perform the push on the
+    //retrieved receiver, we use this as runtime logic
+
+    //TODO - fold these into the Link logics, but I'll do that as a later step, as I want to do a checkin
+    //where everything works first
+
+    private static final <T> ContinuousArrayData getContinuousNonEmptyArrayDataCCE(final Object self, final Class<T> clazz) {
+        try {
+            @SuppressWarnings("unchecked")
+            final ContinuousArrayData data = (ContinuousArrayData)(T)((NativeArray)self).getArray();
+            if (data.length() != 0L) {
+                return data; //if length is 0 we cannot pop and have to relink, because then we'd have to return an undefined, which is a wider type than e.g. int
+           }
+        } catch (final NullPointerException e) {
+            //fallthru
+        }
+        throw new ClassCastException();
+    }
+
+    private static final ContinuousArrayData getContinuousArrayDataCCE(final Object self, final Class<?> elementType) {
+        try {
+           return (ContinuousArrayData)((NativeArray)self).getArray(elementType); //ensure element type can fit "elementType"
+        } catch (final NullPointerException e) {
+            throw new ClassCastException();
+        }
     }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDataView.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDataView.java
index 470803e..0adde06 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDataView.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDataView.java
@@ -27,7 +27,6 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import jdk.nashorn.internal.objects.annotations.Attribute;
@@ -35,7 +34,6 @@
 import jdk.nashorn.internal.objects.annotations.Function;
 import jdk.nashorn.internal.objects.annotations.Property;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
-import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
 import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyMap;
@@ -156,7 +154,7 @@
      * @param offset offset in bytes from the start of the ArrayBuffer
      * @return newly constructed DataView object
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static NativeDataView constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset) {
         if (!(arrBuf instanceof NativeArrayBuffer)) {
             throw typeError("not.an.arraybuffer.in.dataview");
@@ -174,7 +172,7 @@
      * @param length is the number of bytes from the offset that this DataView will reference
      * @return newly constructed DataView object
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static NativeDataView constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset, final int length) {
         if (!(arrBuf instanceof NativeArrayBuffer)) {
             throw typeError("not.an.arraybuffer.in.dataview");
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
index eac59c4..c85016a 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
@@ -30,7 +30,6 @@
 import static java.lang.Double.isNaN;
 import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
-
 import java.util.Locale;
 import java.util.TimeZone;
 import java.util.concurrent.Callable;
@@ -38,7 +37,7 @@
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
-import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
 import jdk.nashorn.internal.objects.annotations.Where;
 import jdk.nashorn.internal.parser.DateParser;
 import jdk.nashorn.internal.runtime.ConsString;
@@ -155,7 +154,7 @@
      * @param self  self references
      * @return Date representing now
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static Object construct(final boolean isNew, final Object self) {
         final NativeDate result = new NativeDate();
         return isNew ? result : toStringImpl(result, FORMAT_DATE_TIME);
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
index 20dd85e..3d8f109 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
 import java.io.PrintWriter;
 import java.util.LinkedList;
 import java.util.Objects;
@@ -262,8 +261,8 @@
 
     /**
      * Set the event queue capacity
-     * @param self
-     * @param newCapacity
+     * @param self an event queue
+     * @param newCapacity new capacity
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
     public static void setEventQueueCapacity(final Object self, final Object newCapacity) {
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
index b2639c4..049d8fa 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -85,6 +84,11 @@
         }
 
         @Override
+        public Class<?> getElementType() {
+            return double.class;
+        }
+
+        @Override
         protected MethodHandle getGetElem() {
             return GET_ELEM;
         }
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
index 9316295..79268cc 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -94,6 +93,11 @@
             return SET_ELEM;
         }
 
+        @Override
+        public Class<?> getElementType() {
+            return double.class;
+        }
+
         private double getElem(final int index) {
             try {
                 return nb.get(index);
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
index ad61cbd..72e24a2 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -95,6 +94,11 @@
             return SET_ELEM;
         }
 
+        @Override
+        public Class<?> getElementType() {
+            return int.class;
+        }
+
         private int getElem(final int index) {
             try {
                 return nb.get(index);
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
index b018f04..56b3106 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -113,6 +112,11 @@
         }
 
         @Override
+        public Class<?> getElementType() {
+            return int.class;
+        }
+
+        @Override
         public int getInt(final int index) {
             return getElem(index);
         }
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
index 6f9f6e7..68e6b0b 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -93,6 +92,11 @@
             return SET_ELEM;
         }
 
+        @Override
+        public Class<?> getElementType() {
+            return int.class;
+        }
+
         private int getElem(final int index) {
             try {
                 return nb.get(index);
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
index f2b1bef..c5ca910 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
@@ -48,7 +48,6 @@
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
-import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
 import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
 import jdk.nashorn.internal.scripts.JO;
 
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
index 01806d4..33ef284 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
@@ -33,13 +33,14 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.Callable;
+
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
 import jdk.nashorn.internal.objects.annotations.Function;
 import jdk.nashorn.internal.objects.annotations.Getter;
 import jdk.nashorn.internal.objects.annotations.Property;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
-import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
 import jdk.nashorn.internal.objects.annotations.Where;
 import jdk.nashorn.internal.runtime.BitVector;
 import jdk.nashorn.internal.runtime.JSType;
@@ -143,7 +144,7 @@
      * @param self  self reference
      * @return new NativeRegExp
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static NativeRegExp constructor(final boolean isNew, final Object self) {
         return new NativeRegExp("", "");
     }
@@ -158,7 +159,7 @@
      * @param pattern pattern
      * @return new NativeRegExp
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static NativeRegExp constructor(final boolean isNew, final Object self, final Object pattern) {
         return newRegExp(pattern, UNDEFINED);
     }
@@ -174,7 +175,7 @@
      * @param flags  flags
      * @return new NativeRegExp
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static NativeRegExp constructor(final boolean isNew, final Object self, final Object pattern, final Object flags) {
         return newRegExp(pattern, flags);
     }
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
index 69d34c2..850af62 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
@@ -29,7 +29,6 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
@@ -49,11 +48,12 @@
 import jdk.nashorn.internal.objects.annotations.Function;
 import jdk.nashorn.internal.objects.annotations.Getter;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
-import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
 import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
 import jdk.nashorn.internal.objects.annotations.Where;
 import jdk.nashorn.internal.runtime.ConsString;
 import jdk.nashorn.internal.runtime.JSType;
+import jdk.nashorn.internal.runtime.OptimisticBuiltins;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -67,7 +67,7 @@
  * ECMA 15.5 String Objects.
  */
 @ScriptClass("String")
-public final class NativeString extends ScriptObject {
+public final class NativeString extends ScriptObject implements OptimisticBuiltins {
 
     private final CharSequence value;
 
@@ -568,6 +568,14 @@
         return pos < 0 || pos >= str.length() ? "" : String.valueOf(str.charAt(pos));
     }
 
+    private static int getValidChar(final Object self, final int pos) {
+        try {
+            return ((CharSequence)self).charAt(pos);
+        } catch (final IndexOutOfBoundsException e) {
+            throw new ClassCastException();
+        }
+    }
+
     /**
      * ECMA 15.5.4.5 String.prototype.charCodeAt (pos)
      * @param self self reference
@@ -576,7 +584,9 @@
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
     public static double charCodeAt(final Object self, final Object pos) {
-        return charCodeAtImpl(checkObjectToString(self), JSType.toInteger(pos));
+        final String str = checkObjectToString(self);
+        final int    idx = JSType.toInteger(pos);
+        return idx < 0 || idx >= str.length() ? Double.NaN : str.charAt(idx);
     }
 
     /**
@@ -585,9 +595,20 @@
      * @param pos  position in string
      * @return number representing charcode at position
      */
-    @SpecializedFunction
-    public static double charCodeAt(final Object self, final double pos) {
-        return charCodeAt(self, (int) pos);
+    @SpecializedFunction(linkLogic=CharCodeAtLinkLogic.class)
+    public static int charCodeAt(final Object self, final double pos) {
+        return charCodeAt(self, (int)pos); //toInt pos is ok
+    }
+
+    /**
+     * ECMA 15.5.4.5 String.prototype.charCodeAt (pos) - specialized version for long position
+     * @param self self reference
+     * @param pos  position in string
+     * @return number representing charcode at position
+     */
+    @SpecializedFunction(linkLogic=CharCodeAtLinkLogic.class)
+    public static int charCodeAt(final Object self, final long pos) {
+        return charCodeAt(self, (int)pos);
     }
 
     /**
@@ -596,13 +617,10 @@
      * @param pos  position in string
      * @return number representing charcode at position
      */
-    @SpecializedFunction
-    public static double charCodeAt(final Object self, final int pos) {
-        return charCodeAtImpl(checkObjectToString(self), pos);
-    }
 
-    private static double charCodeAtImpl(final String str, final int pos) {
-        return pos < 0 || pos >= str.length() ? Double.NaN : str.charAt(pos);
+    @SpecializedFunction(linkLogic=CharCodeAtLinkLogic.class)
+    public static int charCodeAt(final Object self, final int pos) {
+        return getValidChar(self, pos);
     }
 
     /**
@@ -1097,7 +1115,6 @@
      */
     @Function(attributes = Attribute.NOT_ENUMERABLE)
     public static String trim(final Object self) {
-
         final String str = checkObjectToString(self);
         int start = 0;
         int end   = str.length() - 1;
@@ -1181,7 +1198,7 @@
      *
      * @return new NativeString ("")
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static Object constructor(final boolean newObj, final Object self) {
         return newObj ? newObj("") : "";
     }
@@ -1197,7 +1214,7 @@
      *
      * @return new NativeString (arg)
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static Object constructor(final boolean newObj, final Object self, final Object arg) {
         final CharSequence str = JSType.toCharSequence(arg);
         return newObj ? newObj(str) : str.toString();
@@ -1214,8 +1231,42 @@
      *
      * @return new NativeString containing the string representation of the arg
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static Object constructor(final boolean newObj, final Object self, final int arg) {
+        final String str = Integer.toString(arg);
+        return newObj ? newObj(str) : str;
+    }
+
+    /**
+     * ECMA 15.5.2.1 new String ( [ value ] ) - special version with exactly one {@code int} arg
+     *
+     * Constructor
+     *
+     * @param newObj is this constructor invoked with the new operator
+     * @param self   self reference
+     * @param arg    the arg
+     *
+     * @return new NativeString containing the string representation of the arg
+     */
+    @SpecializedFunction(isConstructor=true)
+    public static Object constructor(final boolean newObj, final Object self, final long arg) {
+        final String str = Long.toString(arg);
+        return newObj ? newObj(str) : str;
+    }
+
+    /**
+     * ECMA 15.5.2.1 new String ( [ value ] ) - special version with exactly one {@code int} arg
+     *
+     * Constructor
+     *
+     * @param newObj is this constructor invoked with the new operator
+     * @param self   self reference
+     * @param arg    the arg
+     *
+     * @return new NativeString containing the string representation of the arg
+     */
+    @SpecializedFunction(isConstructor=true)
+    public static Object constructor(final boolean newObj, final Object self, final double arg) {
         final String str = JSType.toString(arg);
         return newObj ? newObj(str) : str;
     }
@@ -1231,9 +1282,9 @@
      *
      * @return new NativeString containing the string representation of the arg
      */
-    @SpecializedConstructor
+    @SpecializedFunction(isConstructor=true)
     public static Object constructor(final boolean newObj, final Object self, final boolean arg) {
-        final String str = JSType.toString(arg);
+        final String str = Boolean.toString(arg);
         return newObj ? newObj(str) : str;
     }
 
@@ -1281,7 +1332,7 @@
         } else if (self != null && self == Global.instance().getStringPrototype()) {
             return "";
         } else {
-            throw typeError( "not.a.string", ScriptRuntime.safeToString(self));
+            throw typeError("not.a.string", ScriptRuntime.safeToString(self));
         }
     }
 
@@ -1310,4 +1361,50 @@
         return MH.findStatic(MethodHandles.lookup(), NativeString.class, name, type);
     }
 
+    @Override
+    public LinkLogic getLinkLogic(final Class<? extends LinkLogic> clazz) {
+        if (clazz == CharCodeAtLinkLogic.class) {
+            return CharCodeAtLinkLogic.INSTANCE;
+        }
+        return null;
+    }
+
+    @Override
+    public boolean hasPerInstanceAssumptions() {
+        return false;
+    }
+
+    /**
+     * This is linker logic charCodeAt - when we specialize further methods in NativeString
+     * It may be expanded. It's link check makes sure that we are dealing with a char
+     * sequence and that we are in range
+     */
+    private static final class CharCodeAtLinkLogic extends SpecializedFunction.LinkLogic {
+
+        private static final CharCodeAtLinkLogic INSTANCE = new CharCodeAtLinkLogic();
+
+        @Override
+        public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
+            try {
+                //check that it's a char sequence or throw cce
+                final CharSequence cs = (CharSequence)self;
+                //check that the index, representable as an int, is inside the array
+                final int intIndex = JSType.toInteger(request.getArguments()[1]);
+                return intIndex >= 0 && intIndex < cs.length(); //can link
+            } catch (final ClassCastException | IndexOutOfBoundsException e) {
+                //fallthru
+            }
+            return false;
+        }
+
+        /**
+         * charCodeAt callsites can throw ClassCastException as a mechanism to have them
+         * relinked - this enabled fast checks of the kind of ((IntArrayData)arrayData).push(x)
+         * for an IntArrayData only push - if this fails, a CCE will be thrown and we will relink
+         */
+        @Override
+        public Class<? extends Throwable> getRelinkException() {
+            return ClassCastException.class;
+        }
+    }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
index 68bd410..d049c93 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -119,6 +118,11 @@
         }
 
         @Override
+        public Class<?> getElementType() {
+            return int.class;
+        }
+
+        @Override
         public int getInt(final int index) {
             return getElem(index);
         }
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
index 47ee08d..2ae2be0 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -128,6 +127,11 @@
         }
 
         @Override
+        public Class<?> getElementType() {
+            return int.class;
+        }
+
+        @Override
         public int getInt(final int index) {
             return (int)getLong(index);
         }
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
index 15e0124..1067baa 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.objects;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -119,6 +118,11 @@
         }
 
         @Override
+        public Class<?> getElementType() {
+            return int.class;
+        }
+
+        @Override
         public int getInt(final int index) {
             return getElem(index);
         }
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
index db19ab3..ffd0f14 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
@@ -28,7 +28,6 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
 import static jdk.nashorn.internal.lookup.Lookup.MH;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -98,6 +97,11 @@
             return SET_ELEM;
         }
 
+        @Override
+        public Class<?> getElementType() {
+            return int.class;
+        }
+
         private int getElem(final int index) {
             try {
                 return nb.get(index) & 0xff;
diff --git a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
index a52051c..36e7716 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
@@ -30,6 +30,7 @@
 
 import java.lang.invoke.MethodHandle;
 import java.util.ArrayList;
+
 import jdk.nashorn.internal.runtime.AccessorProperty;
 import jdk.nashorn.internal.runtime.GlobalFunctions;
 import jdk.nashorn.internal.runtime.Property;
@@ -38,6 +39,7 @@
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptFunctionData;
 import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.Specialization;
 
 /**
  * Concrete implementation of ScriptFunction. This sets correct map for the
@@ -58,7 +60,7 @@
     // Marker object for lazily initialized prototype object
     private static final Object LAZY_PROTOTYPE = new Object();
 
-    private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs, final Global global) {
+    private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final Specialization[] specs, final Global global) {
         super(name, invokeHandle, map$, null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
         init(global);
     }
@@ -71,11 +73,11 @@
      * @param invokeHandle handle for invocation
      * @param specs specialized versions of this method, if available, null otherwise
      */
-    ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs) {
+    ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final Specialization[] specs) {
         this(name, invokeHandle, specs, Global.instance());
     }
 
-    private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs, final Global global) {
+    private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs, final Global global) {
         super(name, invokeHandle, map.addAll(map$), null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
         init(global);
     }
@@ -89,11 +91,11 @@
      * @param map initial property map
      * @param specs specialized versions of this method, if available, null otherwise
      */
-    ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs) {
+    ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final Specialization[] specs) {
         this(name, invokeHandle, map, specs, Global.instance());
     }
 
-    private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final int flags, final Global global) {
+    private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final Specialization[] specs, final int flags, final Global global) {
         super(name, methodHandle, getMap(isStrict(flags)), scope, specs, flags);
         init(global);
     }
@@ -107,7 +109,7 @@
      * @param specs specialized versions of this method, if available, null otherwise
      * @param flags {@link ScriptFunctionData} flags
      */
-    ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final int flags) {
+    ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final Specialization[] specs, final int flags) {
         this(name, methodHandle, scope, specs, flags, Global.instance());
     }
 
@@ -184,7 +186,7 @@
         return new AnonymousFunction();
     }
 
-    private static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs, final int flags) {
+    private static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final Specialization[] specs, final int flags) {
         final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, flags);
         func.setPrototype(UNDEFINED);
         // Non-constructor built-in functions do not have "prototype" property
@@ -201,7 +203,7 @@
      * @param specs  specialized versions of function if available, null otherwise
      * @return new ScriptFunction
      */
-    static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs) {
+    static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final Specialization[] specs) {
         return makeFunction(name, methodHandle, specs, ScriptFunctionData.IS_BUILTIN);
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedConstructor.java b/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedConstructor.java
deleted file mode 100644
index 9e6bd0a..0000000
--- a/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedConstructor.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2010, 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.  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 jdk.nashorn.internal.objects.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * The SpecializedConstructor annotation is used to flag more type specific constructors than the standard one in
- * Native objects. For example {@link jdk.nashorn.internal.objects.NativeArray#construct} takes an arbitrary number of
- * Object elements as an array. Call this constructor, including the varargs collector that allocates the array
- * upon each invocation, is much more expensive than calling a specialized constructor that takes one arguments
- * of, e.g. int type from the call site, such as
- * {@link jdk.nashorn.internal.objects.NativeArray#construct(boolean, Object, int)}.
- * {@link jdk.nashorn.internal.runtime.ScriptFunction} will try to look up the most specific function when
- * linking the callsite.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface SpecializedConstructor {
-    //empty
-}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java b/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java
index 1e75d2a..36f47b2 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -29,18 +29,315 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.SwitchPoint;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.runtime.ScriptFunction;
 
 /**
- * The SpecializedFunction annotation is used to flag more type specific functions than the standard one in
- * Native objects. For example {@link jdk.nashorn.internal.objects.NativeMath#max} takes an arbitrary number of
- * Object elements as an array. Call this function, including the varargs collector that allocates the array
- * upon each invocation, is much more expensive than calling a specialized function that takes two arguments
- * of, e.g. int type from the call site, such as {@link jdk.nashorn.internal.objects.NativeMath#max(Object, int, int)}.
- * {@link jdk.nashorn.internal.runtime.ScriptFunction} will try to look up the most specific function when
- * linking the callsite.
+ * The SpecializedFunction annotation is used to flag more type specific
+ * functions than the standard one in the native objects
  */
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
 public @interface SpecializedFunction {
-    //empty
+
+    /**
+     * Functionality for testing if we are allowed to link a specialized
+     * function the first time we encounter it. Then the guard will handle the
+     * rest of the invocations
+     *
+     * This is the same for all callsites in Nashorn, the first time callsite is
+     * linked, we have to manually check that the linkage is OK. Even if we add
+     * a guard and it fails upon the first try, this is not good enough.
+     * (Symmetrical to how it works everywhere else in the Nashorn runtime).
+     *
+     * Here we abstract out a few of the most common link guard checks.
+     */
+    public static abstract class LinkLogic {
+        /**
+         * Empty link logic instance - this is the default
+         * "no special linking or runtime guard behavior"
+         */
+        public static final LinkLogic EMPTY_INSTANCE = new Empty();
+
+        private static final SwitchPoint[] INVALIDATED_SWITCHPOINTS = new SwitchPoint[0];
+
+        private SwitchPoint[] modificationSwitchPoints; //cache
+
+        /** Empty link logic class - allow all linking, no guards */
+        private static final class Empty extends LinkLogic {
+            @Override
+            public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
+                return true;
+            }
+
+            @Override
+            public boolean isEmpty() {
+                return true;
+            }
+        }
+
+        /**
+         * Get the class representing the empty link logic
+         * @return class representing empty link logic
+         */
+        public static Class<? extends LinkLogic> getEmptyLinkLogicClass() {
+            return Empty.class;
+        }
+
+        /**
+         * Should this callsite relink when an exception is thrown
+         *
+         * @return the relink exception, or null if none
+         */
+        public Class<? extends Throwable> getRelinkException() {
+            return null;
+        }
+
+        /**
+         * Is this link logic class empty - i.e. no special linking logic
+         * supplied
+         *
+         * @param clazz class to check
+         *
+         * @return true if this link logic is empty
+         */
+        public static boolean isEmpty(final Class<? extends LinkLogic> clazz) {
+            return clazz == Empty.class;
+        }
+
+        /**
+         * Is this link logic instance empty - i.e. no special linking logic
+         * supplied
+         *
+         * @return true if this link logic instance is empty
+         */
+        public boolean isEmpty() {
+            return false;
+        }
+
+        /**
+         * Given a callsite, can we link this method based on the receiver and
+         * parameters?
+         *
+         * @param self    receiver
+         * @param desc    callsite descriptor
+         * @param request link request
+         *
+         * @return true if we can link this callsite at this time
+         */
+        public abstract boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request);
+
+        /**
+         * Given a callsite, do we require an extra guard for specialization to
+         * go through?
+         *
+         * @param self receiver
+         *
+         * @return true if a guard is to be woven into the callsite
+         */
+        public boolean needsGuard(final Object self) {
+            return true;
+        }
+
+        /**
+         * Given a callsite, and optional arguments, do we need an extra guard
+         * for specialization to go through - this guard can be a function of
+         * the arguments too
+         *
+         * @param self receiver
+         * @param args arguments
+         *
+         * @return true if a guard is to be woven into the callsite
+         */
+        public boolean needsGuard(final Object self, final Object... args) {
+            return true;
+        }
+
+        /**
+         * Given a callsite, and optional arguments, return any extra guard we
+         * might need for specialization as a method handle.
+         *
+         * @return methodhandle for guard, or null if no guard is needed
+         */
+        public MethodHandle getGuard() {
+            return null;
+        }
+
+        /**
+         * Return the modification SwitchPoint of a particular index from this OptimisticBuiltins
+         * If none exists, one is created and that one is return.
+         *
+         * The implementor must map indexes to specific SwitchPoints for specific events and keep
+         * track of what they mean, for example NativeArray.LENGTH_NOT_WRITABLE_SWITCHPOINT
+         * might be a useful index mapping
+         *
+         * @param index index for SwitchPoint to get or create
+         * @return modification SwitchPoint of particular index for the receiver
+         */
+        public SwitchPoint getOrCreateModificationSwitchPoint(final int index) {
+            return null;
+        }
+
+        /**
+         * Return the modification SwitchPoint from this OptimisticBuiltins. If none
+         * exists, one is created and that one is return.
+         *
+         * @return modification SwitchPoint for the receiver
+         */
+        public SwitchPoint[] getOrCreateModificationSwitchPoints() {
+            return null;
+        }
+
+        /**
+         * Hook to invalidate a modification SwitchPoint by index.
+         *
+         * @param index index for SwitchPoint to invalidate
+         */
+        public void invalidateModificationSwitchPoint(final int index) {
+            //empty
+        }
+
+        /**
+         * Hook to invalidate all modification SwitchPoints for a receiver
+         */
+        public void invalidateModificationSwitchPoints() {
+            //empty
+        }
+
+        /**
+         * Check whether the receiver has an invalidated modification SwitchPoint.
+         *
+         * @param  index index for the modification SwitchPoint
+         * @return true if the particular SwitchPoint at the index is invalidated
+         */
+        public boolean hasInvalidatedModificationSwitchPoint(final int index) {
+            return false;
+        }
+
+        /**
+         * Check whether at least one of the modification SwitchPoints has been
+         * invalidated
+         * @return true if one of the SwitchPoints has been invalidated
+         */
+        public boolean hasInvalidatedModificationSwitchPoints() {
+            return false;
+        }
+
+        /**
+         * Check whether this OptimisticBuiltins has a SwitchPoints of particular
+         * index.
+         *
+         * As creation overhead for a SwitchPoint is non-zero, we have to create them lazily instead of,
+         * e.g. in the constructor of every subclass.
+         *
+         * @param index index for the modification SwitchPoint
+         * @return true if a modification SwitchPoint exists, no matter if it has been invalidated or not
+         */
+        public boolean hasModificationSwitchPoint(final int index) {
+            return false;
+        }
+
+        /**
+         * Check whether this OptimisticBuiltins has SwitchPoints.
+         *
+         * As creation overhead for a SwitchPoint is non-zero, we have to create them lazily instead of,
+         * e.g. in the constructor of every subclass.
+         *
+         * @return true if a modification SwitchPoint exists, no matter if it has been invalidated or not
+         */
+        public boolean hasModificationSwitchPoints() {
+            return false;
+        }
+
+        /**
+         * Check, given a link request and a receiver, if this specialization
+         * fits This is used by the linker in {@link ScriptFunction} to figure
+         * out if an optimistic builtin can be linked when first discovered
+         *
+         * @param self receiver
+         * @param desc callsite descriptor
+         * @param request link request
+
+         * @return true if we can link, false otherwise - that means we have to
+         *         pick a non specialized target
+         */
+        public boolean checkLinkable(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
+            // no matter what the modification switchpoints are, if any of them are invalidated,
+            // we can't link. Side effect is that if it's the first time we see this callsite,
+            // we have to create the SwitchPoint(s) so future modification switchpoint invalidations
+            // relink it
+            final SwitchPoint[] sps = getOrCreateModificationSwitchPoints(self);
+            if (sps == INVALIDATED_SWITCHPOINTS) {
+                // nope, can't do the fast link as this assumption
+                // has been invalidated already, e.g. length of an
+                // array set to not writable
+                return false;
+            }
+            modificationSwitchPoints = sps; //cache
+
+            // check the link guard, if it says we can link, go ahead
+            return canLink(self, desc, request);
+        }
+
+        private SwitchPoint[] getOrCreateModificationSwitchPoints(final Object self) {
+            final SwitchPoint[] sps = getOrCreateModificationSwitchPoints(); //ask for all my switchpoints
+            if (sps != null) { //switchpoint exists, but some may be invalidated
+                for (final SwitchPoint sp : sps) {
+                    if (sp.hasBeenInvalidated()) {
+                        return INVALIDATED_SWITCHPOINTS;
+                    }
+                }
+            }
+            return sps;
+        }
+
+        /**
+         * Get the cached modification switchpoints. Only possible to do after a link
+         * check call has been performed, one that has answered "true", or you will get the
+         * wrong information.
+         *
+         * Should be used only from {@link ScriptFunction#findCallMethod}
+         *
+         * @return cached modification switchpoints for this callsite, null if none
+         */
+        public SwitchPoint[] getModificationSwitchPoints() {
+            return modificationSwitchPoints == null ? null : modificationSwitchPoints.clone();
+        }
+    }
+
+    /**
+     * name override for return value polymorphism, for example we can't have
+     * pop(V)I and pop(V)D in the same Java class, so they need to be named,
+     * e.g. popInt(V)I and popDouble(V)D for disambiguation, however, their
+     * names still need to resolve to "pop" to JavaScript so we can still
+     * specialize on return values and so that the linker can find them
+     *
+     * @return name, "" means no override, use the Java function name, e.g.
+     *         "push"
+     */
+    String name() default "";
+
+    /**
+     * Return the guard for this specialized function. The default is no guard.
+     *
+     * @return guard
+     */
+    Class<?> linkLogic() default LinkLogic.Empty.class;
+
+    /**
+     * Is this a specialized constructor?
+     */
+    boolean isConstructor() default false;
+
+    /**
+     * Can this function throw UnwarrantedOptimismExceptions? This works just
+     * like the normal functions, but we need the function to be
+     * immutable/non-state modifying, as we can't generate continuations for
+     * native code. Luckily a lot of the methods we want to specialize have this
+     * property
+     */
+    boolean isOptimistic() default false;
 }
diff --git a/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java b/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java
index 589fb9c..3eb45cf 100644
--- a/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java
+++ b/nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java
@@ -30,7 +30,6 @@
 import static jdk.nashorn.internal.parser.TokenType.EOF;
 import static jdk.nashorn.internal.parser.TokenType.EOL;
 import static jdk.nashorn.internal.parser.TokenType.IDENT;
-
 import java.util.HashMap;
 import java.util.Map;
 import jdk.nashorn.internal.ir.IdentNode;
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
index 44b3c3b..e293536 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
@@ -36,7 +36,6 @@
 import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
 import static jdk.nashorn.internal.runtime.JSType.getNumberOfAccessorTypes;
 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
-
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.lang.invoke.MethodHandle;
@@ -57,9 +56,7 @@
     private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
 
     private static final MethodHandle REPLACE_MAP   = findOwnMH_S("replaceMap", Object.class, Object.class, PropertyMap.class);
-    private static final MethodHandle INVALIDATE_SP = findOwnMH_S("invalidateSwitchPoint", Object.class, Object.class, SwitchPoint.class);
-
-    private static final SwitchPoint NO_CHANGE_CALLBACK = new SwitchPoint();
+    private static final MethodHandle INVALIDATE_SP = findOwnMH_S("invalidateSwitchPoint", Object.class, AccessorProperty.class, Object.class);
 
     private static final int NOOF_TYPES = getNumberOfAccessorTypes();
     private static final long serialVersionUID = 3371720170182154920L;
@@ -221,7 +218,7 @@
      * @param setter the property setter or null if non writable, non configurable
      */
     private AccessorProperty(final String key, final int flags, final int slot, final MethodHandle getter, final MethodHandle setter) {
-        super(key, flags | (getter.type().returnType().isPrimitive() ? IS_NASGEN_PRIMITIVE : 0), slot);
+        super(key, flags | IS_BUILTIN | (getter.type().returnType().isPrimitive() ? IS_NASGEN_PRIMITIVE : 0), slot);
         assert !isSpill();
 
         // we don't need to prep the setters these will never be invalidated as this is a nasgen
@@ -602,7 +599,6 @@
 
     private Property getWiderProperty(final Class<?> type) {
         return copy(type); //invalidate cache of new property
-
     }
 
     private PropertyMap getWiderMap(final PropertyMap oldMap, final Property newProperty) {
@@ -627,8 +623,10 @@
     }
 
     @SuppressWarnings("unused")
-    private static Object invalidateSwitchPoint(final Object obj, final SwitchPoint sp) {
-        SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
+    private static Object invalidateSwitchPoint(final AccessorProperty property, final Object obj) {
+         if (!property.builtinSwitchPoint.hasBeenInvalidated()) {
+            SwitchPoint.invalidateAll(new SwitchPoint[] { property.builtinSwitchPoint });
+        }
         return obj;
     }
 
@@ -668,12 +666,8 @@
             mh = generateSetter(!forType.isPrimitive() ? Object.class : forType, type);
         }
 
-        /**
-         * Check if this is a special global name that requires switchpoint invalidation
-         */
-        final SwitchPoint ccb = getChangeCallback();
-        if (ccb != null && ccb != NO_CHANGE_CALLBACK) {
-            mh = MH.filterArguments(mh, 0, MH.insertArguments(debugInvalidate(getKey(), ccb), 1, changeCallback));
+        if (isBuiltin()) {
+           mh = MH.filterArguments(mh, 0, debugInvalidate(MH.insertArguments(INVALIDATE_SP, 0, this), getKey()));
         }
 
         assert mh.type().returnType() == void.class : mh.type();
@@ -681,25 +675,6 @@
         return mh;
     }
 
-    /**
-     * Get the change callback for this property
-     * @return switchpoint that is invalidated when property changes
-     */
-    protected SwitchPoint getChangeCallback() {
-        if (changeCallback == null) {
-            try {
-                changeCallback = Global.instance().getChangeCallback(getKey());
-            } catch (final NullPointerException e) {
-                assert !"apply".equals(getKey()) && !"call".equals(getKey());
-                //empty
-            }
-            if (changeCallback == null) {
-                changeCallback = NO_CHANGE_CALLBACK;
-            }
-        }
-        return changeCallback;
-    }
-
     @Override
     public final boolean canChangeType() {
         if (OBJECT_FIELDS_ONLY) {
@@ -724,7 +699,6 @@
         return currentType;
     }
 
-
     private MethodHandle debug(final MethodHandle mh, final Class<?> forType, final Class<?> type, final String tag) {
         if (!Context.DEBUG || !Global.hasInstance()) {
             return mh;
@@ -780,9 +754,9 @@
         return mh;
     }
 
-    private static MethodHandle debugInvalidate(final String key, final SwitchPoint sp) {
+    private static MethodHandle debugInvalidate(final MethodHandle invalidator, final String key) {
         if (!Context.DEBUG || !Global.hasInstance()) {
-            return INVALIDATE_SP;
+            return invalidator;
         }
 
         final Context context = Context.getContextTrusted();
@@ -790,11 +764,11 @@
 
         return context.addLoggingToHandle(
                 ObjectClassGenerator.class,
-                INVALIDATE_SP,
+                invalidator,
                 new Supplier<String>() {
                     @Override
                     public String get() {
-                        return "Field change callback for " + key + " triggered: " + sp;
+                        return "Field change callback for " + key + " triggered ";
                     }
                 });
     }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java
index 7a7df46..e2b5afe 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java
@@ -81,13 +81,17 @@
 
     /**
      * Store a compiled script for later reuse
+     *
+     * @param cacheKey key to use in cache
      * @param source the script source
      * @param mainClassName the main class name
      * @param classBytes map of class names to class bytes
+     * @param initializers compilation id -> FunctionInitializer map
      * @param constants constants array
+     * @param compilationId compilation id
      */
-    public void storeScript(String cacheKey, Source source, String mainClassName, Map<String, byte[]> classBytes,
-                            Map<Integer, FunctionInitializer> initializers, Object[] constants, int compilationId);
+    public void storeScript(final String cacheKey, final Source source, final String mainClassName, final Map<String, byte[]> classBytes,
+            final Map<Integer, FunctionInitializer> initializers, final Object[] constants, final int compilationId);
 
     /**
      * Load a previously compiled script
@@ -96,4 +100,21 @@
      * @return compiled script data
      */
     public StoredScript loadScript(Source source, String functionKey);
+
+    /**
+     * Returns a new code installer that shares most of the functionality of this code installer, but uses a
+     * new, independent class loader.
+     * @return a new code installer with a new independent class loader.
+     */
+    public CodeInstaller<T> withNewLoader();
+
+    /**
+     * Returns true if this code installer is compatible with the other code installer. Compatibility is expected to be
+     * an equivalence relation, and installers are supposed to be compatible with those they create using
+     * {@link #withNewLoader()}.
+     * @param other the other code installer tested for compatibility with this code installer.
+     * @return true if this code installer is compatible with the other code installer.
+     */
+    public boolean isCompatibleWith(CodeInstaller<T> other);
+
 }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/CodeStore.java b/nashorn/src/jdk/nashorn/internal/runtime/CodeStore.java
index a736cc3..0748ccc 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/CodeStore.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/CodeStore.java
@@ -118,6 +118,8 @@
      * @param initializers  the function initializers
      * @param constants     the constants array
      * @param compilationId the compilation id
+     *
+     * @return stored script
      */
     public StoredScript store(final String functionKey,
                               final Source source,
@@ -153,11 +155,13 @@
     /**
      * Returns a new StoredScript instance.
      *
+     * @param source the source
      * @param mainClassName the main class name
      * @param classBytes a map of class bytes
      * @param initializers function initializers
      * @param constants the constants array
      * @param compilationId the compilation id
+     *
      * @return The compiled script
      */
     public StoredScript storedScriptFor(final Source source, final String mainClassName,
@@ -206,7 +210,7 @@
         /**
          * Constructor
          *
-         * @throws IOException
+         * @throws IOException if there are read/write problems with the cache and cache directory
          */
         public DirectoryCodeStore() throws IOException {
             this(Options.getStringProperty("nashorn.persistent.code.cache", "nashorn_code_cache"), false, DEFAULT_MIN_SIZE);
@@ -216,8 +220,9 @@
          * Constructor
          *
          * @param path    directory to store code in
+         * @param readOnly is this a read only code store
          * @param minSize minimum file size for caching scripts
-         * @throws IOException
+         * @throws IOException if there are read/write problems with the cache and cache directory
          */
         public DirectoryCodeStore(final String path, final boolean readOnly, final int minSize) throws IOException {
             this.dir = checkDirectory(path, readOnly);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java
index 28a81de..2655e78 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java
@@ -33,12 +33,13 @@
 import java.lang.invoke.MethodType;
 import java.lang.invoke.MutableCallSite;
 import java.lang.invoke.SwitchPoint;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.function.Supplier;
 import java.util.logging.Level;
-
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.nashorn.internal.codegen.Compiler;
 import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
@@ -46,6 +47,7 @@
 import jdk.nashorn.internal.codegen.types.ArrayType;
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
 import jdk.nashorn.internal.runtime.events.RecompilationEvent;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.logging.DebugLogger;
@@ -63,6 +65,8 @@
 
     private final DebugLogger log;
 
+    static final Collection<CompiledFunction> NO_FUNCTIONS = Collections.emptySet();
+
     /**
      * The method type may be more specific than the invoker, if. e.g.
      * the invoker is guarded, and a guard with a generic object only
@@ -75,19 +79,38 @@
     private final int flags; // from FunctionNode
     private final MethodType callSiteType;
 
+    private final Specialization specialization;
+
     CompiledFunction(final MethodHandle invoker) {
-        this(invoker, null);
+        this(invoker, null, null);
     }
 
-    static CompiledFunction createBuiltInConstructor(final MethodHandle invoker) {
-        return new CompiledFunction(MH.insertArguments(invoker, 0, false), createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)));
+    static CompiledFunction createBuiltInConstructor(final MethodHandle invoker, final Specialization specialization) {
+        return new CompiledFunction(MH.insertArguments(invoker, 0, false), createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)), specialization);
     }
 
-    CompiledFunction(final MethodHandle invoker, final MethodHandle constructor) {
-        this(invoker, constructor, 0, null, DebugLogger.DISABLED_LOGGER);
+    CompiledFunction(final MethodHandle invoker, final MethodHandle constructor, final Specialization specialization) {
+        this(invoker, constructor, 0, null, specialization, DebugLogger.DISABLED_LOGGER);
     }
 
-    CompiledFunction(final MethodHandle invoker, final MethodHandle constructor, final int flags, final MethodType callSiteType, final DebugLogger log) {
+    CompiledFunction(final MethodHandle invoker, final MethodHandle constructor, final int flags, final MethodType callSiteType, final Specialization specialization, final DebugLogger log) {
+        this.specialization = specialization;
+        if (specialization != null && specialization.isOptimistic()) {
+            /*
+             * An optimistic builtin with isOptimistic=true works like any optimistic generated function, i.e. it
+             * can throw unwarranted optimism exceptions. As native functions trivially can't have parts of them
+             * regenerated as restof methods, this only works if the methods are atomic/functional in their behavior
+             * and doesn't modify state before an UOE can be thrown. If they aren't, we can reexecute a wider version
+             * of the same builtin in a recompilation handler for FinalScriptFunctionData. There are several
+             * candidate methods in Native* that would benefit from this, but I haven't had time to implement any
+             * of them currently. In order to fit in with the relinking framework, the current thinking is
+             * that the methods still take a program point to fit in with other optimistic functions, but
+             * it is set to "first", which is the beginning of the method. The relinker can tell the difference
+             * between builtin and JavaScript functions. This might change. TODO
+             */
+            this.invoker = MH.insertArguments(invoker, invoker.type().parameterCount() - 1, UnwarrantedOptimismException.FIRST_PROGRAM_POINT);
+            throw new AssertionError("Optimistic (UnwarrantedOptimismException throwing) builtin functions are currently not in use");
+        }
         this.invoker = invoker;
         this.constructor = constructor;
         this.flags = flags;
@@ -97,7 +120,7 @@
 
     CompiledFunction(final MethodHandle invoker, final RecompilableScriptFunctionData functionData,
             final Map<Integer, Type> invalidatedProgramPoints, final MethodType callSiteType, final int flags) {
-        this(invoker, null, flags, callSiteType, functionData.getLogger());
+        this(invoker, null, flags, callSiteType, null, functionData.getLogger());
         if ((flags & FunctionNode.IS_DEOPTIMIZABLE) != 0) {
             optimismInfo = new OptimismInfo(functionData, invalidatedProgramPoints);
         } else {
@@ -105,10 +128,45 @@
         }
     }
 
+    static CompiledFunction createBuiltInConstructor(final MethodHandle invoker) {
+        return new CompiledFunction(MH.insertArguments(invoker, 0, false), createConstructorFromInvoker(MH.insertArguments(invoker, 0, true)), null);
+    }
+
+    boolean isSpecialization() {
+        return specialization != null;
+    }
+
+    boolean hasLinkLogic() {
+        return getLinkLogicClass() != null;
+    }
+
+    Class<? extends LinkLogic> getLinkLogicClass() {
+        if (isSpecialization()) {
+            final Class<? extends LinkLogic> linkLogicClass = specialization.getLinkLogicClass();
+            assert !LinkLogic.isEmpty(linkLogicClass) : "empty link logic classes should have been removed by nasgen";
+            return linkLogicClass;
+        }
+        return null;
+    }
+
     int getFlags() {
         return flags;
     }
 
+    /**
+     * An optimistic specialization is one that can throw UnwarrantedOptimismException.
+     * This is allowed for native methods, as long as they are functional, i.e. don't change
+     * any state between entering and throwing the UOE. Then we can re-execute a wider version
+     * of the method in the continuation. Rest-of method generation for optimistic builtins is
+     * of course not possible, but this approach works and fits into the same relinking
+     * framework
+     *
+     * @return true if optimistic builtin
+     */
+    boolean isOptimistic() {
+        return isSpecialization() ? specialization.isOptimistic() : false;
+    }
+
     boolean isApplyToCall() {
         return (flags & FunctionNode.HAS_APPLY_TO_CALL_SPECIALIZATION) != 0;
     }
@@ -119,7 +177,19 @@
 
     @Override
     public String toString() {
-        return "[invokerType=" + invoker.type() + " ctor=" + constructor + " weight=" + weight() + " isApplyToCall=" + isApplyToCall() + "]";
+        final StringBuilder sb = new StringBuilder();
+        final Class<? extends LinkLogic> linkLogicClass = getLinkLogicClass();
+
+        sb.append("[invokerType=").
+            append(invoker.type()).
+            append(" ctor=").
+            append(constructor).
+            append(" weight=").
+            append(weight()).
+            append(" linkLogic=").
+            append(linkLogicClass != null ? linkLogicClass.getSimpleName() : "none");
+
+        return sb.toString();
     }
 
     boolean needsCallee() {
@@ -281,10 +351,12 @@
         if (other == null) {
             return true;
         }
-        return betterThanFinal(type(), other.type(), callSiteMethodType);
+        return betterThanFinal(this, other, callSiteMethodType);
     }
 
-    static boolean betterThanFinal(final MethodType thisMethodType, final MethodType otherMethodType, final MethodType callSiteMethodType) {
+    private static boolean betterThanFinal(final CompiledFunction cf, final CompiledFunction other, final MethodType callSiteMethodType) {
+        final MethodType thisMethodType  = cf.type();
+        final MethodType otherMethodType = other.type();
         final int thisParamCount = getParamCount(thisMethodType);
         final int otherParamCount = getParamCount(otherMethodType);
         final int callSiteRawParamCount = getParamCount(callSiteMethodType);
@@ -406,7 +478,17 @@
             return false;
         }
 
-        throw new AssertionError(thisMethodType + " identically applicable to " + otherMethodType + " for " + callSiteMethodType); // Signatures are identical
+        //if they are equal, pick the specialized one first
+        if (cf.isSpecialization() != other.isSpecialization()) {
+            return cf.isSpecialization(); //always pick the specialized version if we can
+        }
+
+        if (cf.isSpecialization() && other.isSpecialization()) {
+            return cf.getLinkLogicClass() != null; //pick link logic specialization above generic specializations
+        }
+
+        // Signatures are identical
+        throw new AssertionError(thisMethodType + " identically applicable to " + otherMethodType + " for " + callSiteMethodType);
     }
 
     private static Type[] toTypeWithoutCallee(final MethodType type, final int thisIndex) {
@@ -427,8 +509,8 @@
         return ((ArrayType)paramTypes[paramTypes.length - 1]).getElementType();
     }
 
-    boolean matchesCallSite(final MethodType callSiteType, final boolean pickVarArg) {
-        if (callSiteType.equals(this.callSiteType)) {
+    boolean matchesCallSite(final MethodType other, final boolean pickVarArg) {
+        if (other.equals(this.callSiteType)) {
             return true;
         }
         final MethodType type  = type();
@@ -438,7 +520,7 @@
             return pickVarArg;
         }
 
-        final int csParamCount = getParamCount(callSiteType);
+        final int csParamCount = getParamCount(other);
         final boolean csIsVarArg = csParamCount == Integer.MAX_VALUE;
         final int thisThisIndex = needsCallee() ? 1 : 0; // Index of "this" parameter in this function's type
 
@@ -447,7 +529,7 @@
         // We must match all incoming parameters, except "this". Starting from 1 to skip "this".
         for(int i = 1; i < minParams; ++i) {
             final Type fnType = Type.typeFor(type.parameterType(i + thisThisIndex));
-            final Type csType = csIsVarArg ? Type.OBJECT : Type.typeFor(callSiteType.parameterType(i + 1));
+            final Type csType = csIsVarArg ? Type.OBJECT : Type.typeFor(other.parameterType(i + 1));
             if(!fnType.isEquivalentTo(csType)) {
                 return false;
             }
@@ -669,9 +751,9 @@
         return sb.toString();
     }
 
-    private void logRecompile(final String reason, final FunctionNode fn, final MethodType callSiteType, final Map<Integer, Type> ipp) {
+    private void logRecompile(final String reason, final FunctionNode fn, final MethodType type, final Map<Integer, Type> ipp) {
         if (log.isEnabled()) {
-            log.info(reason, DebugLogger.quote(fn.getName()), " signature: ", callSiteType, " ", toStringInvalidations(ipp));
+            log.info(reason, DebugLogger.quote(fn.getName()), " signature: ", type, " ", toStringInvalidations(ipp));
         }
     }
 
@@ -732,8 +814,6 @@
             compiler.persistClassInfo(cacheKey, normalFn);
         }
 
-        FunctionNode fn2 = effectiveOptInfo.reparse();
-        fn2 = compiler.compile(fn2, CompilationPhases.COMPILE_UPTO_BYTECODE);
         log.info("Done.");
 
         final boolean canBeDeoptimized = normalFn.canBeDeoptimized();
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
index aa3306a..e77c204 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
@@ -33,13 +33,13 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 import static jdk.nashorn.internal.runtime.Source.sourceFor;
-
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.lang.invoke.SwitchPoint;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.SoftReference;
 import java.lang.reflect.Field;
@@ -127,6 +127,16 @@
     private static MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
     private static MethodType CREATE_PROGRAM_FUNCTION_TYPE = MethodType.methodType(ScriptFunction.class, ScriptObject.class);
 
+    /**
+     * Keeps track of which builtin prototypes and properties have been relinked
+     * Currently we are conservative and associate the name of a builtin class with all
+     * its properties, so it's enough to invalidate a property to break all assumptions
+     * about a prototype. This can be changed to a more fine grained approach, but no one
+     * ever needs this, given the very rare occurance of swapping out only parts of
+     * a builtin v.s. the entire builtin object
+     */
+    private final Map<String, SwitchPoint> builtinSwitchPoints = new HashMap<>();
+
     /* Force DebuggerSupport to be loaded. */
     static {
         DebuggerSupport.FORCELOAD = true;
@@ -148,7 +158,7 @@
         }
 
         /**
-         * Return the context for this installer
+         * Return the script environment for this installer
          * @return ScriptEnvironment
          */
         @Override
@@ -212,6 +222,20 @@
             }
             return null;
         }
+
+        @Override
+        public CodeInstaller<ScriptEnvironment> withNewLoader() {
+            return new ContextCodeInstaller(context, context.createNewLoader(), codeSource);
+        }
+
+        @Override
+        public boolean isCompatibleWith(final CodeInstaller<ScriptEnvironment> other) {
+            if (other instanceof ContextCodeInstaller) {
+                final ContextCodeInstaller cci = (ContextCodeInstaller)other;
+                return cci.context == context && cci.codeSource == codeSource;
+            }
+            return false;
+        }
     }
 
     /** Is Context global debug mode enabled ? */
@@ -1113,6 +1137,9 @@
 
         StoredScript storedScript = null;
         FunctionNode functionNode = null;
+        // We only use the code store here if optimistic types are disabled. With optimistic types,
+        // code is stored per function in RecompilableScriptFunctionData.
+        // TODO: This should really be triggered by lazy compilation, not optimistic types.
         final boolean useCodeStore = env._persistent_cache && !env._parse_only && !env._optimistic_types;
         final String cacheKey = useCodeStore ? CodeStore.getCacheKey(0, null) : null;
 
@@ -1199,7 +1226,7 @@
         final String   mainClassName   = storedScript.getMainClassName();
         final byte[]   mainClassBytes  = classBytes.get(mainClassName);
         final Class<?> mainClass       = installer.install(mainClassName, mainClassBytes);
-        final Map<Integer, FunctionInitializer> initialzers = storedScript.getInitializers();
+        final Map<Integer, FunctionInitializer> initializers = storedScript.getInitializers();
 
         installedClasses.put(mainClassName, mainClass);
 
@@ -1219,8 +1246,8 @@
             if (constant instanceof RecompilableScriptFunctionData) {
                 final RecompilableScriptFunctionData data = (RecompilableScriptFunctionData) constant;
                 data.initTransients(source, installer);
-                if (initialzers != null) {
-                    final FunctionInitializer initializer = initialzers.get(data.getFunctionNodeId());
+                final FunctionInitializer initializer = initializers.get(data.getFunctionNodeId());
+                if (initializer != null) {
                     initializer.setCode(installedClasses.get(initializer.getClassName()));
                     data.initializeCode(initializer);
                 }
@@ -1371,4 +1398,34 @@
         return null;
     }
 
+    /**
+     * This is a special kind of switchpoint used to guard builtin
+     * properties and prototypes. In the future it might contain
+     * logic to e.g. multiple switchpoint classes.
+     */
+    public static final class BuiltinSwitchPoint extends SwitchPoint {
+        //empty
+    }
+
+    /**
+     * Create a new builtin switchpoint and return it
+     * @param name key name
+     * @return new builtin switchpoint
+     */
+    public SwitchPoint newBuiltinSwitchPoint(final String name) {
+        assert builtinSwitchPoints.get(name) == null;
+        final SwitchPoint sp = new BuiltinSwitchPoint();
+        builtinSwitchPoints.put(name, sp);
+        return sp;
+    }
+
+    /**
+     * Return the builtin switchpoint for a particular key name
+     * @param name key name
+     * @return builtin switchpoint or null if none
+     */
+    public SwitchPoint getBuiltinSwitchPoint(final String name) {
+        return builtinSwitchPoints.get(name);
+    }
+
 }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Debug.java b/nashorn/src/jdk/nashorn/internal/runtime/Debug.java
index c152418..a2d136f 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/Debug.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Debug.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.runtime;
 
 import static jdk.nashorn.internal.parser.TokenType.EOF;
-
 import jdk.nashorn.internal.parser.Lexer;
 import jdk.nashorn.internal.parser.Token;
 import jdk.nashorn.internal.parser.TokenStream;
@@ -42,12 +41,12 @@
 
     /**
      * Return the topmost JavaScript frame in a stack trace
-     * @param e
+     * @param t throwable that contains the stack trace
      * @return line describing the topmost JavaScript frame
      */
-    public static String firstJSFrame(final Throwable e) {
-        for (final StackTraceElement ste : e.getStackTrace()) {
-            if(ECMAErrors.isScriptFrame(ste)) {
+    public static String firstJSFrame(final Throwable t) {
+        for (final StackTraceElement ste : t.getStackTrace()) {
+            if (ECMAErrors.isScriptFrame(ste)) {
                 return ste.toString();
             }
         }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java
index f75dc82..c868aab 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java
@@ -60,13 +60,13 @@
      * @param specs specializations
      * @param flags {@link ScriptFunctionData} flags
      */
-    FinalScriptFunctionData(final String name, final MethodHandle mh, final MethodHandle[] specs, final int flags) {
+    FinalScriptFunctionData(final String name, final MethodHandle mh, final Specialization[] specs, final int flags) {
         super(name, methodHandleArity(mh), flags);
 
         addInvoker(mh);
         if (specs != null) {
-            for (final MethodHandle spec : specs) {
-                addInvoker(spec);
+            for (final Specialization spec : specs) {
+                addInvoker(spec.getMethodHandle(), spec);
             }
         }
     }
@@ -114,16 +114,25 @@
         return MethodType.genericMethodType(max + 1);
     }
 
-    private void addInvoker(final MethodHandle mh) {
+    private CompiledFunction addInvoker(final MethodHandle mh, final Specialization specialization) {
         assert !needsCallee(mh);
+
+        final CompiledFunction invoker;
         if (isConstructor(mh)) {
             // only nasgen constructors: (boolean, self, args) are subject to binding a boolean newObj. isConstructor
             // is too conservative a check. However, isConstructor(mh) always implies isConstructor param
             assert isConstructor();
-            code.add(CompiledFunction.createBuiltInConstructor(mh));
+            invoker = CompiledFunction.createBuiltInConstructor(mh);
         } else {
-            code.add(new CompiledFunction(mh));
+            invoker = new CompiledFunction(mh, null, specialization);
         }
+        code.add(invoker);
+
+        return invoker;
+    }
+
+    private CompiledFunction addInvoker(final MethodHandle mh) {
+        return addInvoker(mh, null);
     }
 
     private static int methodHandleArity(final MethodHandle mh) {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java
index 06f682b..b4e0012 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java
@@ -79,6 +79,8 @@
      *
      * @param type type of getter, e.g. int.class if we want a function with {@code get()I} signature
      * @param programPoint program point, or INVALID_PROGRAM_POINT if pessimistic
+     * @param request link request
+     *
      * @return method handle for the getter
      */
     public MethodHandle getGetter(final Class<?> type, final int programPoint, final LinkRequest request) {
@@ -102,6 +104,7 @@
      *
      * @param type type of setter, e.g. int.class if we want a function with {@code set(I)V} signature
      * @param strict are we in strict mode
+     * @param request link request
      *
      * @return method handle for the getter
      */
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalConstants.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalConstants.java
index 3a10481..6099a70b 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalConstants.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalConstants.java
@@ -358,8 +358,12 @@
      * @param c constant value
      * @return method handle (with dummy receiver) that returns this constant
      */
+    public static MethodHandle staticConstantGetter(final Object c) {
+        return MH.dropArguments(JSType.unboxConstant(c), 0, Object.class);
+    }
+
     private MethodHandle constantGetter(final Object c) {
-        final MethodHandle mh = MH.dropArguments(JSType.unboxConstant(c), 0, Object.class);
+        final MethodHandle mh = staticConstantGetter(c);
         if (log.isEnabled()) {
             return MethodHandleFactory.addDebugPrintout(log, Level.FINEST, mh, "getting as constant");
         }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java
index 2776cc6..c7094ad 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java
@@ -42,12 +42,30 @@
     /** Methodhandle (specialized) to implementation of ECMA 15.1.2.2, parseInt */
     public static final MethodHandle PARSEINT_OI = findOwnMH("parseInt", double.class, Object.class, Object.class, int.class);
 
+    /** ParseInt - NaN for booleans (thru string conversion to number conversion) */
+    public static final MethodHandle PARSEINT_Z = MH.dropArguments(MH.dropArguments(MH.constant(double.class, Double.NaN), 0, boolean.class), 0, Object.class);
+
+    /** ParseInt - identity for ints */
+    public static final MethodHandle PARSEINT_I = MH.dropArguments(MH.identity(int.class), 0, Object.class);
+
+    /** ParseInt - identity for longs */
+    public static final MethodHandle PARSEINT_J = MH.dropArguments(MH.identity(long.class), 0, Object.class);
+
     /** Methodhandle (specialized) to implementation of ECMA 15.1.2.2, parseInt */
     public static final MethodHandle PARSEINT_O = findOwnMH("parseInt", double.class, Object.class, Object.class);
 
     /** Methodhandle to implementation of ECMA 15.1.2.3, parseFloat */
     public static final MethodHandle PARSEFLOAT = findOwnMH("parseFloat", double.class, Object.class, Object.class);
 
+    /** isNan for integers - always false */
+    public static final MethodHandle IS_NAN_I = MH.dropArguments(MH.constant(boolean.class, false), 0, Object.class);
+
+    /** isNan for longs - always false */
+    public static final MethodHandle IS_NAN_J = MH.dropArguments(MH.constant(boolean.class, false), 0, Object.class);
+
+    /** IsNan for doubles - use Double.isNaN */
+    public static final MethodHandle IS_NAN_D = MH.dropArguments(MH.findStatic(MethodHandles.lookup(), Double.class, "isNaN", MH.type(boolean.class, double.class)), 0, Object.class);
+
     /** Methodhandle to implementation of ECMA 15.1.2.4, isNaN */
     public static final MethodHandle IS_NAN = findOwnMH("isNaN",      boolean.class, Object.class, Object.class);
 
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/OptimisticBuiltins.java b/nashorn/src/jdk/nashorn/internal/runtime/OptimisticBuiltins.java
new file mode 100644
index 0000000..6829dde
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/OptimisticBuiltins.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010, 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 jdk.nashorn.internal.runtime;
+
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
+
+/**
+ * This is an interface for classes that need custom linkage logic. This means Native objects
+ * that contain optimistic native methods, that need special/extra rules for linking, guards and
+ * SwitchPointing, known and internal to the Native object for its linkage
+ */
+public interface OptimisticBuiltins {
+
+    /**
+     * Return an instance of the linking logic we need for a particular LinkLogic
+     * subclass, gotten from the compile time annotation of a specialized builtin method
+     * No assumptions can be made about the lifetime of the instance. The receiver may
+     * keep it as a perpetual final instance field or create new linking logic depending
+     * on its current state for each call, depending on if the global state has changed
+     * or other factors
+     *
+     * @param clazz linking logic class
+     * @return linking logic instance for this class
+     */
+    public SpecializedFunction.LinkLogic getLinkLogic(final Class<? extends LinkLogic> clazz);
+
+    /**
+     * Does this link logic vary depending on which instance we are working with.
+     * Then we have to sort out certain primitives, as they are created as new
+     * objects in the wrapFilter by JavaScript semantics. An example of instance only
+     * assumptions are switchPoints per instance, as in NativeArray. NativeString is
+     * fine, as it's only static.
+     *
+     * TODO: finer granularity on this, on the function level so certain functions
+     * are forbidden only. Currently we don't have enough specialization to bump into this
+     *
+     * @return true if there are per instance assumptions for the optimism
+     */
+    public boolean hasPerInstanceAssumptions();
+
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Property.java b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
index 1f9f145..f57246c 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/Property.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
@@ -28,7 +28,6 @@
 import static jdk.nashorn.internal.runtime.PropertyDescriptor.CONFIGURABLE;
 import static jdk.nashorn.internal.runtime.PropertyDescriptor.ENUMERABLE;
 import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
-
 import java.io.Serializable;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.SwitchPoint;
@@ -84,6 +83,9 @@
      */
     public static final int IS_NASGEN_PRIMITIVE     = 1 << 6;
 
+    /** Is this a builtin property, e.g. Function.prototype.apply */
+    public static final int IS_BUILTIN = 1 << 7;
+
     /** Is this property bound to a receiver? This means get/set operations will be delegated to
      *  a statically defined object instead of the object passed as callsite parameter. */
     public static final int IS_BOUND                = 1 << 7;
@@ -101,7 +103,7 @@
     private final int slot;
 
     /** SwitchPoint that is invalidated when property is changed, optional */
-    protected transient SwitchPoint changeCallback;
+    protected transient SwitchPoint builtinSwitchPoint;
 
     private static final long serialVersionUID = 2099814273074501176L;
 
@@ -125,10 +127,10 @@
      * @param property source property
      */
     Property(final Property property, final int flags) {
-        this.key            = property.key;
-        this.slot           = property.slot;
-        this.changeCallback = property.changeCallback;
-        this.flags          = flags;
+        this.key                = property.key;
+        this.slot               = property.slot;
+        this.builtinSwitchPoint = property.builtinSwitchPoint;
+        this.flags              = flags;
     }
 
     /**
@@ -182,8 +184,26 @@
      * changed
      * @param sp SwitchPoint to use for change callback
      */
-    public final void setChangeCallback(final SwitchPoint sp) {
-        this.changeCallback = sp;
+    public final void setBuiltinSwitchPoint(final SwitchPoint sp) {
+        this.builtinSwitchPoint = sp;
+    }
+
+    /**
+     * Builtin properties have an invalidation switchpoint that is
+     * invalidated when they are set, this is a getter for it
+     * @return builtin switchpoint, or null if none
+     */
+    public final SwitchPoint getBuiltinSwitchPoint() {
+        return builtinSwitchPoint;
+    }
+
+    /**
+     * Checks if this is a builtin property, this means that it has
+     * a builtin switchpoint that hasn't been invalidated by a setter
+     * @return true if builtin, untouched (unset) property
+     */
+    public boolean isBuiltin() {
+        return builtinSwitchPoint != null && !builtinSwitchPoint.hasBeenInvalidated();
     }
 
     /**
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
index d8e7608..6191233 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
@@ -950,7 +950,7 @@
 
         @Override
         public void remove() {
-            throw new UnsupportedOperationException();
+            throw new UnsupportedOperationException("remove");
         }
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
index 2d5ccc0..f3ad233 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
@@ -31,6 +31,7 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -268,7 +269,7 @@
         if (this.source == null && this.installer == null) {
             this.source    = src;
             this.installer = inst;
-        } else if (this.source != src || this.installer != inst) {
+        } else if (this.source != src || !this.installer.isCompatibleWith(inst)) {
             // Existing values must be same as those passed as parameters
             throw new IllegalArgumentException();
         }
@@ -407,6 +408,17 @@
         return getCompiler(fn, actualCallSiteType, newLocals(runtimeScope), null, null);
     }
 
+    /**
+     * Returns a code installer for installing new code. If we're using either optimistic typing or loader-per-compile,
+     * then asks for a code installer with a new class loader; otherwise just uses the current installer. We use
+     * a new class loader with optimistic typing so that deoptimized code can get reclaimed by GC.
+     * @return a code installer for installing new code.
+     */
+    private CodeInstaller<ScriptEnvironment> getInstallerForNewCode() {
+        final ScriptEnvironment env = installer.getOwner();
+        return env._optimistic_types || env._loader_per_compile ? installer.withNewLoader() : installer;
+    }
+
     Compiler getCompiler(final FunctionNode functionNode, final MethodType actualCallSiteType,
             final ScriptObject runtimeScope, final Map<Integer, Type> invalidatedProgramPoints,
             final int[] continuationEntryPoints) {
@@ -417,7 +429,7 @@
         return new Compiler(
                 context,
                 context.getEnv(),
-                installer,
+                getInstallerForNewCode(),
                 functionNode.getSource(),  // source
                 context.getErrorManager(),
                 isStrict() | functionNode.isStrict(), // is strict
@@ -454,7 +466,7 @@
         // CompilationEnvironment#declareLocalSymbol()).
 
         if (log.isEnabled()) {
-            log.info("Type specialization of '", functionName, "' signature: ", actualCallSiteType);
+            log.info("Parameter type specialization of '", functionName, "' signature: ", actualCallSiteType);
         }
 
         final boolean persistentCache = usePersistentCodeCache() && persist;
@@ -463,11 +475,12 @@
             final TypeMap typeMap = typeMap(actualCallSiteType);
             final Type[] paramTypes = typeMap == null ? null : typeMap.getParameterTypes(functionNodeId);
             cacheKey = CodeStore.getCacheKey(functionNodeId, paramTypes);
-            final StoredScript script = installer.loadScript(source, cacheKey);
+            final CodeInstaller<ScriptEnvironment> newInstaller = getInstallerForNewCode();
+            final StoredScript script = newInstaller.loadScript(source, cacheKey);
 
             if (script != null) {
                 Compiler.updateCompilationId(script.getCompilationId());
-                return install(script);
+                return installStoredScript(script, newInstaller);
             }
         }
 
@@ -481,15 +494,7 @@
         return new FunctionInitializer(compiledFn, compiler.getInvalidatedProgramPoints());
     }
 
-
-    /**
-     * Install this script using the given {@code installer}.
-     *
-     * @param script the compiled script
-     * @return the function initializer
-     */
-    private FunctionInitializer install(final StoredScript script) {
-
+    private static Map<String, Class<?>> installStoredScriptClasses(final StoredScript script, final CodeInstaller<ScriptEnvironment> installer) {
         final Map<String, Class<?>> installedClasses = new HashMap<>();
         final Map<String, byte[]>   classBytes       = script.getClassBytes();
         final String   mainClassName   = script.getMainClassName();
@@ -501,14 +506,25 @@
 
         for (final Map.Entry<String, byte[]> entry : classBytes.entrySet()) {
             final String className = entry.getKey();
-            final byte[] code = entry.getValue();
+            final byte[] bytecode = entry.getValue();
 
             if (className.equals(mainClassName)) {
                 continue;
             }
 
-            installedClasses.put(className, installer.install(className, code));
+            installedClasses.put(className, installer.install(className, bytecode));
         }
+        return installedClasses;
+    }
+
+    /**
+     * Install this script using the given {@code installer}.
+     *
+     * @param script the compiled script
+     * @return the function initializer
+     */
+    private FunctionInitializer installStoredScript(final StoredScript script, final CodeInstaller<ScriptEnvironment> newInstaller) {
+        final Map<String, Class<?>> installedClasses = installStoredScriptClasses(script, newInstaller);
 
         final Map<Integer, FunctionInitializer> initializers = script.getInitializers();
         assert initializers != null;
@@ -523,7 +539,7 @@
             }
         }
 
-        installer.initialize(installedClasses.values(), source, constants);
+        newInstaller.initialize(installedClasses.values(), source, constants);
         initializer.setCode(installedClasses.get(initializer.getClassName()));
         return initializer;
     }
@@ -588,15 +604,19 @@
         return lookupCodeMethod(fn.getCompileUnit().getCode(), type);
     }
 
-    MethodHandle lookupCodeMethod(final Class<?> code, final MethodType targetType) {
-        log.info("Looking up ", DebugLogger.quote(name), " type=", targetType);
-        return MH.findStatic(LOOKUP, code, functionName, targetType);
+    MethodHandle lookupCodeMethod(final Class<?> codeClass, final MethodType targetType) {
+        if (log.isEnabled()) {
+            log.info("Looking up ", DebugLogger.quote(name), " type=", targetType);
+        }
+        return MH.findStatic(LOOKUP, codeClass, functionName, targetType);
     }
 
     /**
      * Initializes this function data with the eagerly generated version of the code. This method can only be invoked
      * by the compiler internals in Nashorn and is public for implementation reasons only. Attempting to invoke it
      * externally will result in an exception.
+     *
+     * @param initializer FunctionInitializer for this data
      */
     public void initializeCode(final FunctionInitializer initializer) {
         // Since the method is public, we double-check that we aren't invoked with an inappropriate compile unit.
@@ -658,8 +678,8 @@
 
 
     @Override
-    synchronized CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope) {
-        CompiledFunction existingBest = super.getBest(callSiteType, runtimeScope);
+    synchronized CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
+        CompiledFunction existingBest = super.getBest(callSiteType, runtimeScope, forbidden);
         if (existingBest == null) {
             existingBest = addCode(compileTypeSpecialization(callSiteType, runtimeScope, true), callSiteType);
         }
@@ -723,6 +743,10 @@
         return functionNodeId;
     }
 
+    /**
+     * Get the source for the script
+     * @return source
+     */
     public Source getSource() {
         return source;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
index e6034bf..cd528a0 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
@@ -181,9 +181,6 @@
     /** print symbols and their contents for the script */
     public final boolean _print_symbols;
 
-    /** range analysis for known types */
-    public final boolean _range_analysis;
-
     /** is this environment in scripting mode? */
     public final boolean _scripting;
 
@@ -255,7 +252,6 @@
         _print_parse          = options.getBoolean("print.parse");
         _print_lower_parse    = options.getBoolean("print.lower.parse");
         _print_symbols        = options.getBoolean("print.symbols");
-        _range_analysis       = options.getBoolean("range.analysis");
         _scripting            = options.getBoolean("scripting");
         _strict               = options.getBoolean("strict");
         _version              = options.getBoolean("version");
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java
index d9f71a2..0ba06b3 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java
@@ -30,26 +30,29 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 import java.lang.invoke.SwitchPoint;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
-
+import java.util.HashSet;
+import java.util.List;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
 import jdk.internal.dynalink.support.Guards;
 import jdk.nashorn.internal.codegen.ApplySpecialization;
+import jdk.nashorn.internal.codegen.Compiler;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
 import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.objects.NativeFunction;
-import jdk.nashorn.internal.runtime.ScriptFunctionData;
-import jdk.nashorn.internal.runtime.ScriptObject;
-import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
+import jdk.nashorn.internal.runtime.logging.DebugLogger;
 
 /**
  * Runtime representation of a JavaScript function.
@@ -114,7 +117,7 @@
             final MethodHandle methodHandle,
             final PropertyMap map,
             final ScriptObject scope,
-            final MethodHandle[] specs,
+            final Specialization[] specs,
             final int flags) {
 
         this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope);
@@ -468,13 +471,12 @@
     protected GuardedInvocation findNewMethod(final CallSiteDescriptor desc, final LinkRequest request) {
         final MethodType type = desc.getMethodType();
         assert desc.getMethodType().returnType() == Object.class && !NashornCallSiteDescriptor.isOptimistic(desc);
-        final CompiledFunction cf = data.getBestConstructor(type, scope);
+        final CompiledFunction cf = data.getBestConstructor(type, scope, CompiledFunction.NO_FUNCTIONS);
         final GuardedInvocation bestCtorInv = cf.createConstructorInvocation();
         //TODO - ClassCastException
         return new GuardedInvocation(pairArguments(bestCtorInv.getInvocation(), type), getFunctionGuard(this, cf.getFlags()), bestCtorInv.getSwitchPoints(), null);
     }
 
-    @SuppressWarnings("unused")
     private static Object wrapFilter(final Object obj) {
         if (obj instanceof ScriptObject || !ScriptFunctionData.isPrimitiveThis(obj)) {
             return obj;
@@ -490,6 +492,35 @@
     }
 
     /**
+     * Some receivers are primitive, in that case, according to the Spec we create a new
+     * native object per callsite with the wrap filter. We can only apply optimistic builtins
+     * if there is no per instance state saved for these wrapped objects (e.g. currently NativeStrings),
+     * otherwise we can't create optimistic versions
+     *
+     * @param self            receiver
+     * @param linkLogicClass  linkLogicClass, or null if no link logic exists
+     * @return link logic instance, or null if one could not be constructed for this receiver
+     */
+    private static LinkLogic getLinkLogic(final Object self, final Class<? extends LinkLogic> linkLogicClass) {
+        if (linkLogicClass == null) {
+            return LinkLogic.EMPTY_INSTANCE; //always OK to link this, specialization but without special linking logic
+        }
+
+        if (!Context.getContextTrusted().getEnv()._optimistic_types) {
+            return null; //if optimistic types are off, optimistic builtins are too
+        }
+
+        final Object wrappedSelf = wrapFilter(self);
+        if (wrappedSelf instanceof OptimisticBuiltins) {
+            if (wrappedSelf != self && ((OptimisticBuiltins)wrappedSelf).hasPerInstanceAssumptions()) {
+                return null; //pessimistic - we created a wrapped object different from the primitive, but the assumptions have instance state
+            }
+            return ((OptimisticBuiltins)wrappedSelf).getLinkLogic(linkLogicClass);
+        }
+        return null;
+    }
+
+    /**
      * dyn:call call site signature: (callee, thiz, [args...])
      * generated method signature:   (callee, thiz, [args...])
      *
@@ -547,8 +578,53 @@
             }
         } //else just fall through and link as ordinary function or unstable apply
 
-        final int programPoint = NashornCallSiteDescriptor.isOptimistic(desc) ? NashornCallSiteDescriptor.getProgramPoint(desc) : INVALID_PROGRAM_POINT;
-        final CompiledFunction cf = data.getBestInvoker(type, scope);
+        int programPoint = INVALID_PROGRAM_POINT;
+        if (NashornCallSiteDescriptor.isOptimistic(desc)) {
+            programPoint = NashornCallSiteDescriptor.getProgramPoint(desc);
+        }
+
+        CompiledFunction cf = data.getBestInvoker(type, scope, CompiledFunction.NO_FUNCTIONS);
+        final Object self = request.getArguments()[1];
+        final Collection<CompiledFunction> forbidden = new HashSet<>();
+
+        //check for special fast versions of the compiled function
+        final List<SwitchPoint> sps = new ArrayList<>();
+        Class<? extends Throwable> exceptionGuard = null;
+
+        while (cf.isSpecialization()) {
+            final Class<? extends LinkLogic> linkLogicClass = cf.getLinkLogicClass();
+            //if linklogic is null, we can always link with the standard mechanism, it's still a specialization
+            final LinkLogic linkLogic = getLinkLogic(self, linkLogicClass);
+
+            if (linkLogic != null && linkLogic.checkLinkable(self, desc, request)) {
+                final DebugLogger log = Context.getContextTrusted().getLogger(Compiler.class);
+
+                if (log.isEnabled()) {
+                    log.info("Linking optimistic builtin function: '", name, "' args=", Arrays.toString(request.getArguments()), " desc=", desc);
+                }
+
+                final SwitchPoint[] msps = linkLogic.getModificationSwitchPoints();
+                if (msps != null) {
+                    for (final SwitchPoint sp : msps) {
+                        if (sp != null) {
+                            assert !sp.hasBeenInvalidated();
+                            sps.add(sp);
+                        }
+                    }
+                }
+
+                exceptionGuard = linkLogic.getRelinkException();
+
+                break;
+            }
+
+            //could not link this specialization because link check failed
+            forbidden.add(cf);
+            final CompiledFunction oldCf = cf;
+            cf = data.getBestInvoker(type, scope, forbidden);
+            assert oldCf != cf;
+        }
+
         final GuardedInvocation bestInvoker = cf.createFunctionInvocation(type.returnType(), programPoint);
         final MethodHandle callHandle = bestInvoker.getInvocation();
 
@@ -588,7 +664,20 @@
 
         boundHandle = pairArguments(boundHandle, type);
 
-        return new GuardedInvocation(boundHandle, guard == null ? getFunctionGuard(this, cf.getFlags()) : guard, bestInvoker.getSwitchPoints(), null);
+        if (bestInvoker.getSwitchPoints() != null) {
+            sps.addAll(Arrays.asList(bestInvoker.getSwitchPoints()));
+        }
+        final SwitchPoint[] spsArray = sps.isEmpty() ? null : sps.toArray(new SwitchPoint[sps.size()]);
+
+        return new GuardedInvocation(
+                boundHandle,
+                guard == null ?
+                        getFunctionGuard(
+                                this,
+                                cf.getFlags()) :
+                        guard,
+                        spsArray,
+                exceptionGuard);
     }
 
     private GuardedInvocation createApplyOrCallCall(final boolean isApply, final CallSiteDescriptor desc, final LinkRequest request, final Object[] args) {
@@ -610,7 +699,7 @@
 
         //box call back to apply
         CallSiteDescriptor appliedDesc = desc;
-        final SwitchPoint applyToCallSwitchPoint = Global.instance().getChangeCallback("apply");
+        final SwitchPoint applyToCallSwitchPoint = Global.getBuiltinFunctionApplySwitchPoint();
         //enough to change the proto switchPoint here
 
         final boolean isApplyToCall = NashornCallSiteDescriptor.isApplyToCall(desc);
@@ -656,7 +745,7 @@
             }
         }
 
-        appliedDesc = appliedDesc.changeMethodType(appliedType);
+        appliedDesc = appliedDesc.changeMethodType(appliedType); //no extra args
 
         // Create the same arguments for the delegate linking request that would be passed in an actual apply'd invocation
         final Object[] appliedArgs = new Object[isApply ? 3 : appliedType.parameterCount()];
@@ -681,6 +770,7 @@
 
         // Ask the linker machinery for an invocation of the target function
         final LinkRequest appliedRequest = request.replaceArguments(appliedDesc, appliedArgs);
+
         GuardedInvocation appliedInvocation;
         try {
             appliedInvocation = Bootstrap.getLinkerServices().getGuardedInvocation(appliedRequest);
@@ -742,7 +832,7 @@
         // We need to account for the dropped (apply|call) function argument.
         guard = MH.dropArguments(guard, 0, descType.parameterType(0));
         // Take the "isApplyFunction" guard, and bind it to this function.
-        MethodHandle applyFnGuard = MH.insertArguments(IS_APPLY_FUNCTION, 2, this);
+        MethodHandle applyFnGuard = MH.insertArguments(IS_APPLY_FUNCTION, 2, this); //TODO replace this with switchpoint
         // Adapt the guard to receive all the arguments that the original guard does.
         applyFnGuard = MH.dropArguments(applyFnGuard, 2, guardType.parameterArray());
         // Fold the original function guard into our apply guard.
@@ -894,6 +984,7 @@
         return self instanceof ScriptFunction && ((ScriptFunction)self).data == data && arg instanceof ScriptObject;
     }
 
+    //TODO this can probably be removed given that we have builtin switchpoints in the context
     @SuppressWarnings("unused")
     private static boolean isApplyFunction(final boolean appliedFnCondition, final Object self, final Object expectedSelf) {
         // NOTE: we're using self == expectedSelf as we're only using this with built-in functions apply() and call()
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
index d92b12d..3472cda 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
@@ -28,13 +28,13 @@
 import static jdk.nashorn.internal.lookup.Lookup.MH;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.Serializable;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
@@ -136,7 +136,7 @@
         final MethodHandle boundInvoker = bindInvokeHandle(originalInv.createComposableInvoker(), fn, self, args);
 
         if (isConstructor()) {
-            return new CompiledFunction(boundInvoker, bindConstructHandle(originalInv.createComposableConstructor(), fn, args));
+            return new CompiledFunction(boundInvoker, bindConstructHandle(originalInv.createComposableConstructor(), fn, args), null);
         }
 
         return new CompiledFunction(boundInvoker);
@@ -224,18 +224,22 @@
      * @param callSiteType callsite type
      * @return compiled function object representing the best invoker.
      */
-     final CompiledFunction getBestInvoker(final MethodType callSiteType, final ScriptObject runtimeScope) {
-        final CompiledFunction cf = getBest(callSiteType, runtimeScope);
+    final CompiledFunction getBestInvoker(final MethodType callSiteType, final ScriptObject runtimeScope) {
+        return getBestInvoker(callSiteType, runtimeScope, CompiledFunction.NO_FUNCTIONS);
+    }
+
+    final CompiledFunction getBestInvoker(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
+        final CompiledFunction cf = getBest(callSiteType, runtimeScope, forbidden);
         assert cf != null;
         return cf;
     }
 
-    final CompiledFunction getBestConstructor(final MethodType callSiteType, final ScriptObject runtimeScope) {
+    final CompiledFunction getBestConstructor(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
         if (!isConstructor()) {
             throw typeError("not.a.constructor", toSource());
         }
         // Constructor call sites don't have a "this", but getBest is meant to operate on "callee, this, ..." style
-        final CompiledFunction cf = getBest(callSiteType.insertParameterTypes(1, Object.class), runtimeScope);
+        final CompiledFunction cf = getBest(callSiteType.insertParameterTypes(1, Object.class), runtimeScope, forbidden);
         return cf;
     }
 
@@ -350,7 +354,7 @@
      * scope is not known, but that might cause compilation of code that will need more deoptimization passes.
      * @return the best function for the specified call site type.
      */
-    CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope) {
+    CompiledFunction getBest(final MethodType callSiteType, final ScriptObject runtimeScope, final Collection<CompiledFunction> forbidden) {
         assert callSiteType.parameterCount() >= 2 : callSiteType; // Must have at least (callee, this)
         assert callSiteType.parameterType(0).isAssignableFrom(ScriptFunction.class) : callSiteType; // Callee must be assignable from script function
 
@@ -363,8 +367,8 @@
         }
 
         CompiledFunction best = null;
-        for(final CompiledFunction candidate: code) {
-            if(candidate.betterThanFinal(best, callSiteType)) {
+        for (final CompiledFunction candidate: code) {
+            if (!forbidden.contains(candidate) && candidate.betterThanFinal(best, callSiteType)) {
                 best = candidate;
             }
         }
@@ -376,7 +380,7 @@
     abstract boolean isRecompilable();
 
     CompiledFunction getGeneric(final ScriptObject runtimeScope) {
-        return getBest(getGenericType(), runtimeScope);
+        return getBest(getGenericType(), runtimeScope, CompiledFunction.NO_FUNCTIONS);
     }
 
     /**
@@ -420,7 +424,7 @@
 
         final List<CompiledFunction> boundList = new LinkedList<>();
         final ScriptObject runtimeScope = fn.getScope();
-        final CompiledFunction bindTarget = new CompiledFunction(getGenericInvoker(runtimeScope), getGenericConstructor(runtimeScope));
+        final CompiledFunction bindTarget = new CompiledFunction(getGenericInvoker(runtimeScope), getGenericConstructor(runtimeScope), null);
         boundList.add(bind(bindTarget, fn, self, allArgs));
 
         return new FinalScriptFunctionData(name, Math.max(0, getArity() - length), boundList, boundFlags);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
index 8d616b5..87d2897 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
@@ -47,7 +47,6 @@
 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex;
 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
 import static jdk.nashorn.internal.runtime.linker.NashornGuards.explicitInstanceOfCheck;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
@@ -820,6 +819,19 @@
         return false;
     }
 
+    private SwitchPoint findBuiltinSwitchPoint(final String key) {
+        for (ScriptObject myProto = getProto(); myProto != null; myProto = myProto.getProto()) {
+            final Property prop = myProto.getMap().findProperty(key);
+            if (prop != null) {
+                final SwitchPoint sp = prop.getBuiltinSwitchPoint();
+                if (sp != null && !sp.hasBeenInvalidated()) {
+                    return sp;
+                }
+            }
+        }
+        return null;
+    }
+
     /**
      * Add a new property to the object.
      * <p>
@@ -923,10 +935,10 @@
      * creating setters that probably aren't used. Inject directly into the spill pool
      * the defaults for "arguments" and "caller"
      *
-     * @param key
-     * @param propertyFlags
-     * @param getter
-     * @param setter
+     * @param key           property key
+     * @param propertyFlags flags
+     * @param getter        getter for {@link UserAccessorProperty}, null if not present or N/A
+     * @param setter        setter for {@link UserAccessorProperty}, null if not present or N/A
      */
     protected final void initUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) {
         final int slot = spillLength;
@@ -1514,6 +1526,23 @@
     }
 
     /**
+     * Get the {@link ArrayData}, for this ScriptObject, ensuring it is of a type
+     * that can handle elementType
+     * @param elementType elementType
+     * @return array data
+     */
+    public final ArrayData getArray(final Class<?> elementType) {
+        if (elementType == null) {
+            return arrayData;
+        }
+        final ArrayData newArrayData = arrayData.convert(elementType);
+        if (newArrayData != arrayData) {
+            arrayData = newArrayData;
+        }
+        return newArrayData;
+    }
+
+    /**
      * Get the {@link ArrayData} for this ScriptObject if it is an array
      * @return array data
      */
@@ -1720,8 +1749,8 @@
      */
     public Object put(final Object key, final Object value, final boolean strict) {
         final Object oldValue = get(key);
-        final int flags = strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0;
-        set(key, value, flags);
+        final int scriptObjectFlags = strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0;
+        set(key, value, scriptObjectFlags);
         return oldValue;
     }
 
@@ -1734,9 +1763,9 @@
      * @param strict strict mode or not
      */
     public void putAll(final Map<?, ?> otherMap, final boolean strict) {
-        final int flags = strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0;
+        final int scriptObjectFlags = strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0;
         for (final Map.Entry<?, ?> entry : otherMap.entrySet()) {
-            set(entry.getKey(), entry.getValue(), flags);
+            set(entry.getKey(), entry.getValue(), scriptObjectFlags);
         }
     }
 
@@ -1916,17 +1945,6 @@
         return MH.filterArguments(methodHandle, 0, filter.asType(filter.type().changeReturnType(methodHandle.type().parameterType(0))));
     }
 
-    //this will only return true if apply is still builtin
-    private static SwitchPoint checkReservedName(final CallSiteDescriptor desc, final LinkRequest request) {
-        final boolean isApplyToCall = NashornCallSiteDescriptor.isApplyToCall(desc);
-        final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
-        if ("apply".equals(name) && isApplyToCall && Global.instance().isSpecialNameValid(name)) {
-            assert Global.instance().getChangeCallback("apply") == Global.instance().getChangeCallback("call");
-            return Global.instance().getChangeCallback("apply");
-        }
-        return null;
-    }
-
     /**
      * Find the appropriate GET method for an invoke dynamic call.
      *
@@ -1938,14 +1956,13 @@
      */
     protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
         final boolean explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request);
-        final String name;
-        final SwitchPoint reservedNameSwitchPoint;
 
-        reservedNameSwitchPoint = checkReservedName(desc, request);
-        if (reservedNameSwitchPoint != null) {
-            name = "call"; //turn apply into call, it is the builtin apply and has been modified to explode args
-        } else {
-            name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+        String name;
+        name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
+        if (NashornCallSiteDescriptor.isApplyToCall(desc)) {
+            if (Global.isBuiltinFunctionPrototypeApply()) {
+                name = "call";
+            }
         }
 
         if (request.isCallSiteUnstable() || hasWithScope()) {
@@ -2006,7 +2023,7 @@
         assert OBJECT_FIELDS_ONLY || guard != null : "we always need a map guard here";
 
         final GuardedInvocation inv = new GuardedInvocation(mh, guard, protoSwitchPoint, exception);
-        return inv.addSwitchPoint(reservedNameSwitchPoint);
+        return inv.addSwitchPoint(findBuiltinSwitchPoint(name));
     }
 
     private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) {
@@ -2029,7 +2046,7 @@
     // Marks a property as declared and sets its value. Used as slow path for block-scoped LET and CONST
     @SuppressWarnings("unused")
     private void declareAndSet(final String key, final Object value) {
-        final PropertyMap map = getMap();
+        final PropertyMap oldMap = getMap();
         final FindProperty find = findProperty(key, false);
         assert find != null;
 
@@ -2037,7 +2054,7 @@
         assert property != null;
         assert property.needsDeclaration();
 
-        final PropertyMap newMap = map.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION));
+        final PropertyMap newMap = oldMap.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION));
         setMap(newMap);
         set(key, value, 0);
     }
@@ -2166,7 +2183,7 @@
             }
         }
 
-        final GuardedInvocation inv = new SetMethodCreator(this, find, desc, request).createGuardedInvocation();
+        final GuardedInvocation inv = new SetMethodCreator(this, find, desc, request).createGuardedInvocation(findBuiltinSwitchPoint(name));
 
         final GuardedInvocation cinv = Global.getConstants().findSetMethod(find, this, inv, desc, request);
         if (cinv != null) {
@@ -2429,7 +2446,7 @@
 
         @Override
         public void remove() {
-            throw new UnsupportedOperationException();
+            throw new UnsupportedOperationException("remove");
         }
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java
index 47b2a8d..e927d4f 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java
@@ -32,9 +32,9 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.syntaxError;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.invoke.SwitchPoint;
 import java.lang.reflect.Array;
 import java.util.Collections;
 import java.util.Iterator;
@@ -46,6 +46,7 @@
 import jdk.internal.dynalink.beans.StaticClass;
 import jdk.nashorn.api.scripting.JSObject;
 import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import jdk.nashorn.internal.codegen.ApplySpecialization;
 import jdk.nashorn.internal.codegen.CompilerConstants;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
 import jdk.nashorn.internal.ir.debug.JSONWriter;
@@ -113,6 +114,11 @@
     public static final Call THROW_REFERENCE_ERROR = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "throwReferenceError", void.class, String.class);
 
     /**
+     * Used to invalidate builtin names, e.g "Function" mapping to all properties in Function.prototype and Function.prototype itself.
+     */
+    public static final Call INVALIDATE_RESERVED_BUILTIN_NAME = staticCallNoLookup(ScriptRuntime.class, "invalidateReservedBuiltinName", void.class, String.class);
+
+    /**
      * Converts a switch tag value to a simple integer. deflt value if it can't.
      *
      * @param tag   Switch statement tag value.
@@ -290,7 +296,7 @@
 
         @Override
         public void remove() {
-            throw new UnsupportedOperationException();
+            throw new UnsupportedOperationException("remove");
         }
     }
 
@@ -328,7 +334,7 @@
 
                 @Override
                 public void remove() {
-                    throw new UnsupportedOperationException();
+                    throw new UnsupportedOperationException("remove");
                 }
             };
         }
@@ -998,4 +1004,19 @@
         return nx < ny;
     }
 
+    /**
+     * Tag a reserved name as invalidated - used when someone writes
+     * to a property with this name - overly conservative, but link time
+     * is too late to apply e.g. apply-&gt;call specialization
+     * @param name property name
+     */
+    public static void invalidateReservedBuiltinName(final String name) {
+        final Context context = Context.getContextTrusted();
+        final SwitchPoint sp = context.getBuiltinSwitchPoint(name);
+        assert sp != null;
+        if (sp != null) {
+            context.getLogger(ApplySpecialization.class).info("Overwrote special name '" + name +"' - invalidating switchpoint");
+            SwitchPoint.invalidateAll(new SwitchPoint[] { sp });
+        }
+    }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
index 99ec313..90bbf43 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
@@ -28,7 +28,6 @@
 import static jdk.nashorn.internal.lookup.Lookup.MH;
 import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
 import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.SwitchPoint;
 import jdk.internal.dynalink.CallSiteDescriptor;
@@ -81,8 +80,8 @@
      * Creates the actual guarded invocation that represents the dynamic setter method for the property.
      * @return the actual guarded invocation that represents the dynamic setter method for the property.
      */
-    GuardedInvocation createGuardedInvocation() {
-        return createSetMethod().createGuardedInvocation();
+    GuardedInvocation createGuardedInvocation(final SwitchPoint builtinSwitchPoint) {
+        return createSetMethod(builtinSwitchPoint).createGuardedInvocation();
     }
 
     /**
@@ -119,7 +118,7 @@
         }
     }
 
-    private SetMethod createSetMethod() {
+    private SetMethod createSetMethod(final SwitchPoint builtinSwitchPoint) {
         if (find != null) {
             return createExistingPropertySetter();
         }
@@ -130,7 +129,7 @@
             return createGlobalPropertySetter();
         }
 
-        return createNewPropertySetter();
+        return createNewPropertySetter(builtinSwitchPoint);
     }
 
     private void checkStrictCreateNewVariable() {
@@ -185,8 +184,8 @@
         return new SetMethod(MH.filterArguments(global.addSpill(type, getName()), 0, ScriptObject.GLOBALFILTER), null);
     }
 
-    private SetMethod createNewPropertySetter() {
-        final SetMethod sm = map.getFreeFieldSlot() > -1 ? createNewFieldSetter() : createNewSpillPropertySetter();
+    private SetMethod createNewPropertySetter(final SwitchPoint builtinSwitchPoint) {
+        final SetMethod sm = map.getFreeFieldSlot() > -1 ? createNewFieldSetter(builtinSwitchPoint) : createNewSpillPropertySetter(builtinSwitchPoint);
         final PropertyListeners listeners = map.getListeners();
         if (listeners != null) {
             listeners.propertyAdded(sm.property);
@@ -194,7 +193,9 @@
         return sm;
     }
 
-    private SetMethod createNewSetter(final Property property) {
+    private SetMethod createNewSetter(final Property property, final SwitchPoint builtinSwitchPoint) {
+        property.setBuiltinSwitchPoint(builtinSwitchPoint);
+
         final PropertyMap oldMap   = getMap();
         final PropertyMap newMap   = getNewMap(property);
         final boolean     isStrict = NashornCallSiteDescriptor.isStrict(desc);
@@ -230,12 +231,12 @@
         return new SetMethod(MH.asType(MH.guardWithTest(extCheck, casGuard, nop), fastSetter.type()), property);
     }
 
-    private SetMethod createNewFieldSetter() {
-        return createNewSetter(new AccessorProperty(getName(), 0, sobj.getClass(), getMap().getFreeFieldSlot(), type));
+    private SetMethod createNewFieldSetter(final SwitchPoint builtinSwitchPoint) {
+        return createNewSetter(new AccessorProperty(getName(), 0, sobj.getClass(), getMap().getFreeFieldSlot(), type), builtinSwitchPoint);
     }
 
-    private SetMethod createNewSpillPropertySetter() {
-        return createNewSetter(new SpillProperty(getName(), 0, getMap().getFreeSpillSlot(), type));
+    private SetMethod createNewSpillPropertySetter(final SwitchPoint builtinSwitchPoint) {
+        return createNewSetter(new SpillProperty(getName(), 0, getMap().getFreeSpillSlot(), type), builtinSwitchPoint);
     }
 
     private PropertyMap getNewMap(final Property property) {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Specialization.java b/nashorn/src/jdk/nashorn/internal/runtime/Specialization.java
new file mode 100644
index 0000000..9807cc6
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Specialization.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2010, 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 jdk.nashorn.internal.runtime;
+
+import java.lang.invoke.MethodHandle;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
+import jdk.nashorn.internal.objects.annotations.SpecializedFunction.LinkLogic;
+
+/**
+ * Specialization info for a {@link SpecializedFunction}
+ */
+public final class Specialization {
+    private final MethodHandle mh;
+    private final Class<? extends LinkLogic> linkLogicClass;
+    private final boolean isOptimistic;
+
+    /**
+     * Constructor
+     *
+     * @param mh  invoker method handler
+     */
+    public Specialization(final MethodHandle mh) {
+        this(mh, false);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param mh  invoker method handler
+     * @param isOptimistic is this an optimistic native method, i.e. can it throw {@link UnwarrantedOptimismException}
+     *   which would have to lead to a relink and return value processing
+     */
+    public Specialization(final MethodHandle mh, final boolean isOptimistic) {
+        this(mh, null, isOptimistic);
+    }
+
+    /**
+     * Constructor
+     *
+     * @param mh  invoker method handler
+     * @param linkLogicClass extra link logic needed for this function. Instances of this class also contains logic for checking
+     *  if this can be linked on its first encounter, which is needed as per our standard linker semantics
+     * @param isOptimistic is this an optimistic native method, i.e. can it throw {@link UnwarrantedOptimismException}
+     *   which would have to lead to a relink and return value processing
+     */
+    public Specialization(final MethodHandle mh, final Class<? extends LinkLogic> linkLogicClass, final boolean isOptimistic) {
+        this.mh             = mh;
+        this.isOptimistic   = isOptimistic;
+        if (linkLogicClass != null) {
+            //null out the "empty" link logic class for optimization purposes
+            //we only use the empty instance because we can't default class annotations
+            //to null
+            this.linkLogicClass = LinkLogic.isEmpty(linkLogicClass) ? null : linkLogicClass;
+        } else {
+            this.linkLogicClass = null;
+        }
+     }
+
+    /**
+     * Get the method handle for the invoker of this ScriptFunction
+     * @return the method handle
+     */
+    public MethodHandle getMethodHandle() {
+        return mh;
+    }
+
+    /**
+     * Get the link logic class for this ScriptFunction
+     * @return link logic class info, i.e. one whose instance contains stuff like
+     *  "do we need exception check for every call", and logic to check if we may link
+     */
+    public Class<? extends LinkLogic> getLinkLogicClass() {
+        return linkLogicClass;
+    }
+
+    /**
+     * An optimistic specialization is one that can throw UnwarrantedOptimismException.
+     * This is allowed for native methods, as long as they are functional, i.e. don't change
+     * any state between entering and throwing the UOE. Then we can re-execute a wider version
+     * of the method in the continuation. Rest-of method generation for optimistic builtins is
+     * of course not possible, but this approach works and fits into the same relinking
+     * framework
+     *
+     * @return true if optimistic
+     */
+    public boolean isOptimistic() {
+        return isOptimistic;
+    }
+
+}
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/StoredScript.java b/nashorn/src/jdk/nashorn/internal/runtime/StoredScript.java
index 5b6a77b..14a0ced 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/StoredScript.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/StoredScript.java
@@ -55,8 +55,10 @@
     /**
      * Constructor.
      *
+     * @param compilationId compilation id
      * @param mainClassName main class name
      * @param classBytes map of class names to class bytes
+     * @param initializers initializer map, id -> FunctionInitializer
      * @param constants constants array
      */
     public StoredScript(final int compilationId, final String mainClassName, final Map<String, byte[]> classBytes, final Map<Integer, FunctionInitializer> initializers, final Object[] constants) {
@@ -67,6 +69,10 @@
         this.initializers = initializers;
     }
 
+    /**
+     * Get the compilation id for this StoredScript
+     * @return compilation id
+     */
     public int getCompilationId() {
         return compilationId;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
index 7350ff4..5fdec00 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
@@ -25,7 +25,6 @@
 
 package jdk.nashorn.internal.runtime;
 
-import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
 import static jdk.nashorn.internal.lookup.Lookup.MH;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.JSType.CONVERT_OBJECT_OPTIMISTIC;
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java
index 897636e..9e606ee 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.runtime.arrays;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -58,7 +57,7 @@
     /**
      * Length of the array data. Not necessarily length of the wrapped array.
      */
-    private long length;
+    protected long length;
 
     /**
      * Method handle to throw an {@link UnwarrantedOptimismException} when getting an element
@@ -520,7 +519,7 @@
      * @param type new element type
      * @return new array data
      */
-    protected abstract ArrayData convert(Class<?> type);
+    public abstract ArrayData convert(Class<?> type);
 
     /**
      * Push an array of items to the end of the array
@@ -537,7 +536,7 @@
         final Class<?>  widest  = widestType(items);
 
         ArrayData newData = convert(widest);
-        long      pos     = newData.length();
+        long      pos     = newData.length;
         for (final Object item : items) {
             newData = newData.ensure(pos); //avoid sparse array
             newData.set((int)pos++, item, strict);
@@ -655,7 +654,7 @@
      * @param size current size
      * @return next size to allocate for internal array
      */
-    protected static int nextSize(final int size) {
+    public static int nextSize(final int size) {
         return alignUp(size + 1) * 2;
     }
 
@@ -681,6 +680,18 @@
         }
     }
 
+   /**
+     * Find a fast call if one exists
+     *
+     * @param clazz    array data class
+     * @param desc     callsite descriptor
+     * @param request  link request
+     * @return fast property getter if one is found
+     */
+    public GuardedInvocation findFastCallMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) {
+        return null;
+    }
+
     /**
      * Find a fast property getter if one exists
      *
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java
index be41673..8d71cc0 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java
@@ -39,7 +39,7 @@
     protected ArrayData underlying;
 
     ArrayFilter(final ArrayData underlying) {
-        super(underlying.length());
+        super(underlying.length);
         this.underlying = underlying;
     }
 
@@ -70,13 +70,13 @@
     @Override
     public void shiftLeft(final int by) {
         underlying.shiftLeft(by);
-        setLength(underlying.length());
+        setLength(underlying.length);
     }
 
     @Override
     public ArrayData shiftRight(final int by) {
         underlying = underlying.shiftRight(by);
-        setLength(underlying.length());
+        setLength(underlying.length);
 
         return this;
     }
@@ -84,7 +84,7 @@
     @Override
     public ArrayData ensure(final long safeIndex) {
         underlying = underlying.ensure(safeIndex);
-        setLength(underlying.length());
+        setLength(underlying.length);
 
         return this;
     }
@@ -92,7 +92,7 @@
     @Override
     public ArrayData shrink(final long newLength) {
         underlying = underlying.shrink(newLength);
-        setLength(underlying.length());
+        setLength(underlying.length);
 
         return this;
     }
@@ -100,7 +100,7 @@
     @Override
     public ArrayData set(final int index, final Object value, final boolean strict) {
         underlying = underlying.set(index, value, strict);
-        setLength(underlying.length());
+        setLength(underlying.length);
 
         return this;
     }
@@ -108,7 +108,7 @@
     @Override
     public ArrayData set(final int index, final int value, final boolean strict) {
         underlying = underlying.set(index, value, strict);
-        setLength(underlying.length());
+        setLength(underlying.length);
 
         return this;
     }
@@ -116,7 +116,7 @@
     @Override
     public ArrayData set(final int index, final long value, final boolean strict) {
         underlying = underlying.set(index, value, strict);
-        setLength(underlying.length());
+        setLength(underlying.length);
 
         return this;
     }
@@ -124,7 +124,7 @@
     @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         underlying = underlying.set(index, value, strict);
-        setLength(underlying.length());
+        setLength(underlying.length);
 
         return this;
     }
@@ -189,28 +189,28 @@
     @Override
     public ArrayData delete(final int index) {
         underlying = underlying.delete(index);
-        setLength(underlying.length());
+        setLength(underlying.length);
         return this;
     }
 
     @Override
     public ArrayData delete(final long from, final long to) {
         underlying = underlying.delete(from, to);
-        setLength(underlying.length());
+        setLength(underlying.length);
         return this;
     }
 
     @Override
-    protected ArrayData convert(final Class<?> type) {
+    public ArrayData convert(final Class<?> type) {
         underlying = underlying.convert(type);
-        setLength(underlying.length());
+        setLength(underlying.length);
         return this;
     }
 
     @Override
     public Object pop() {
         final Object value = underlying.pop();
-        setLength(underlying.length());
+        setLength(underlying.length);
 
         return value;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java
index f6e4d38..dfa6133 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ContinuousArrayData.java
@@ -30,7 +30,6 @@
 import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
@@ -77,11 +76,11 @@
      * array without reallocating, or if we are overwriting an already
      * allocated element
      *
-     * @param index
+     * @param index index to check
      * @return true if we don't need to do any array reallocation to fit an element at index
      */
     public final boolean hasRoomFor(final int index) {
-        return has(index) || (index == length() && ensure(index) == this);
+        return has(index) || (index == length && ensure(index) == this);
     }
 
     /**
@@ -116,6 +115,12 @@
     }
 
     /**
+     * Returns the type used to store an element in this array
+     * @return element type
+     */
+    public abstract Class<?> getElementType();
+
+    /**
      * Look up a continuous array element getter
      * @param get          getter, sometimes combined with a has check that throws CCE on failure for relink
      * @param returnType   return type
@@ -175,11 +180,6 @@
         return MH.asType(setHas, setHas.type().changeParameterType(2, elementType).changeParameterType(0, clazz));
     }
 
-    @Override
-    public GuardedInvocation findFastGetMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
-        return null;
-    }
-
     /** Fast access guard - it is impractical for JIT performance reasons to use only CCE asType as guard :-(, also we need
       the null case explicitly, which is the one that CCE doesn't handle */
     protected static final MethodHandle FAST_ACCESS_GUARD =
@@ -269,4 +269,72 @@
 
         return null;
     }
+
+    /**
+     * Specialization - fast push implementation
+     * @param arg argument
+     * @return new array length
+     */
+    public long fastPush(final int arg) {
+        throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
+    }
+
+    /**
+     * Specialization - fast push implementation
+     * @param arg argument
+     * @return new array length
+     */
+    public long fastPush(final long arg) {
+        throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
+    }
+
+    /**
+     * Specialization - fast push implementation
+     * @param arg argument
+     * @return new array length
+     */
+    public long fastPush(final double arg) {
+        throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
+    }
+
+    /**
+     * Specialization - fast push implementation
+     * @param arg argument
+     * @return new array length
+     */
+    public long fastPush(final Object arg) {
+        throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
+    }
+
+    /**
+     * Specialization - fast pop implementation
+     * @return element value
+     */
+    public int fastPopInt() {
+        throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
+    }
+
+    /**
+     * Specialization - fast pop implementation
+     * @return element value
+     */
+    public long fastPopLong() {
+        throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
+    }
+
+    /**
+     * Specialization - fast pop implementation
+     * @return element value
+     */
+    public double fastPopDouble() {
+       throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
+    }
+
+    /**
+     * Specialization - fast pop implementation
+     * @return element value
+     */
+    public Object fastPopObject() {
+        throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
+    }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java
index bf120ea..4f54b63 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.runtime.arrays;
 
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
 import java.lang.reflect.Array;
 import jdk.nashorn.internal.runtime.BitVector;
 
@@ -40,7 +39,7 @@
     DeletedArrayFilter(final ArrayData underlying) {
         super(underlying);
 
-        this.deleted = new BitVector(underlying.length());
+        this.deleted = new BitVector(underlying.length);
     }
 
     @Override
@@ -80,25 +79,25 @@
     @Override
     public void shiftLeft(final int by) {
         super.shiftLeft(by);
-        deleted.shiftLeft(by, length());
+        deleted.shiftLeft(by, length);
     }
 
     @Override
     public ArrayData shiftRight(final int by) {
         super.shiftRight(by);
-        deleted.shiftRight(by, length());
+        deleted.shiftRight(by, length);
 
         return this;
     }
 
     @Override
     public ArrayData ensure(final long safeIndex) {
-        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length()) {
+        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length) {
             return new SparseArrayData(this, safeIndex + 1);
         }
 
         super.ensure(safeIndex);
-        deleted.resize(length());
+        deleted.resize(length);
 
         return this;
     }
@@ -106,7 +105,7 @@
     @Override
     public ArrayData shrink(final long newLength) {
         super.shrink(newLength);
-        deleted.resize(length());
+        deleted.resize(length);
 
         return this;
     }
@@ -147,7 +146,7 @@
     @Override
     public ArrayData delete(final int index) {
         final long longIndex = ArrayIndex.toLongIndex(index);
-        assert longIndex >= 0 && longIndex < length();
+        assert longIndex >= 0 && longIndex < length;
         deleted.set(longIndex);
         underlying.setEmpty(index);
         return this;
@@ -155,7 +154,7 @@
 
     @Override
     public ArrayData delete(final long fromIndex, final long toIndex) {
-        assert fromIndex >= 0 && fromIndex <= toIndex && toIndex < length();
+        assert fromIndex >= 0 && fromIndex <= toIndex && toIndex < length;
         deleted.setRange(fromIndex, toIndex + 1);
         underlying.setEmpty(fromIndex, toIndex);
         return this;
@@ -163,7 +162,7 @@
 
     @Override
     public Object pop() {
-        final long index = length() - 1;
+        final long index = length - 1;
 
         if (super.has((int)index)) {
             final boolean isDeleted = deleted.isSet(index);
@@ -180,7 +179,7 @@
         final ArrayData newArray = underlying.slice(from, to);
         final DeletedArrayFilter newFilter = new DeletedArrayFilter(newArray);
         newFilter.getDeleted().copy(deleted);
-        newFilter.getDeleted().shiftLeft(from, newFilter.length());
+        newFilter.getDeleted().shiftLeft(from, newFilter.length);
 
         return newFilter;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java
index b74d078..8732add 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java
@@ -45,7 +45,7 @@
         if(hi < SparseArrayData.MAX_DENSE_LENGTH || underlying instanceof SparseArrayData) {
             return underlying;
         }
-        return new SparseArrayData(underlying, underlying.length());
+        return new SparseArrayData(underlying, underlying.length);
     }
 
     private boolean isEmpty() {
@@ -93,7 +93,7 @@
 
     @Override
     public ArrayData ensure(final long safeIndex) {
-        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length()) {
+        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length) {
             return new SparseArrayData(this, safeIndex + 1);
         }
 
@@ -110,8 +110,9 @@
     @Override
     public ArrayData shiftRight(final int by) {
         super.shiftRight(by);
-        lo = Math.min(length(), lo + by);
-        hi = Math.min(length() - 1, hi + by);
+        final long len = length;
+        lo = Math.min(len, lo + by);
+        hi = Math.min(len - 1, hi + by);
 
         return isEmpty() ? getUnderlying() : this;
     }
@@ -237,7 +238,7 @@
 
     @Override
     public Object pop() {
-        final int index = (int)(length() - 1);
+        final int index = (int)length - 1;
         if (super.has(index)) {
             final boolean isDeleted = isDeleted(index);
             final Object value      = super.pop();
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java
index 57d0cd9..48dd088 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.runtime.arrays;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.util.Arrays;
@@ -38,7 +37,7 @@
  * Implementation of {@link ArrayData} as soon as an int has been
  * written to the array. This is the default data for new arrays
  */
-final class IntArrayData extends ContinuousArrayData {
+final class IntArrayData extends ContinuousArrayData implements IntElements {
     /**
      * The wrapped array
      */
@@ -64,9 +63,19 @@
         this.array = array;
     }
 
+    @Override
+    public Class<?> getElementType() {
+        return int.class;
+    }
+
     private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), IntArrayData.class, "getElem", int.class, int.class).methodHandle();
     private static final MethodHandle SET_ELEM     = specialCall(MethodHandles.lookup(), IntArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
 
+    @Override
+    public Object[] asObjectArray() {
+        return toObjectArray();
+    }
+
     @SuppressWarnings("unused")
     private int getElem(final int index) {
         if (has(index)) {
@@ -96,23 +105,18 @@
 
     @Override
     public ArrayData copy() {
-        return new IntArrayData(array.clone(), (int) length());
-    }
-
-    @Override
-    public Object[] asObjectArray() {
-        return toObjectArray(array, (int) length());
+        return new IntArrayData(array.clone(), (int)length);
     }
 
     @Override
     public Object asArrayOfType(final Class<?> componentType) {
         if (componentType == int.class) {
-            return array.length == length() ? array.clone() : Arrays.copyOf(array, (int) length());
+            return array.length == length ? array.clone() : Arrays.copyOf(array, (int)length);
         }
         return super.asArrayOfType(componentType);
     }
 
-    private static Object[] toObjectArray(final int[] array, final int length) {
+    private Object[] toObjectArray() {
         assert length <= array.length : "length exceeds internal array size";
         final Object[] oarray = new Object[array.length];
 
@@ -123,7 +127,7 @@
         return oarray;
     }
 
-    private static double[] toDoubleArray(final int[] array, final int length) {
+    private double[] toDoubleArray() {
         assert length <= array.length : "length exceeds internal array size";
         final double[] darray = new double[array.length];
 
@@ -134,7 +138,7 @@
         return darray;
     }
 
-    private static long[] toLongArray(final int[] array, final int length) {
+    private long[] toLongArray() {
         assert length <= array.length : "length exceeds internal array size";
         final long[] larray = new long[array.length];
 
@@ -145,18 +149,30 @@
         return larray;
     }
 
+    private LongArrayData convertToLong() {
+        return new LongArrayData(toLongArray(), (int)length);
+    }
+
+    private NumberArrayData convertToDouble() {
+        return new NumberArrayData(toDoubleArray(), (int)length);
+    }
+
+    private ObjectArrayData convertToObject() {
+        return new ObjectArrayData(toObjectArray(), (int)length);
+    }
+
     @Override
     public ArrayData convert(final Class<?> type) {
         if (type == Integer.class) {
             return this;
         }
-        final int length = (int) length();
         if (type == Long.class) {
-            return new LongArrayData(IntArrayData.toLongArray(array, length), length);
+            return convertToLong();
         } else if (type == Double.class) {
-            return new NumberArrayData(IntArrayData.toDoubleArray(array, length), length);
+            return convertToDouble();
         } else {
-            return new ObjectArrayData(IntArrayData.toObjectArray(array, length), length);
+            assert type == null || (!Number.class.isAssignableFrom(type) && !type.isPrimitive());
+            return convertToObject();
         }
     }
 
@@ -167,7 +183,7 @@
 
     @Override
     public ArrayData shiftRight(final int by) {
-        final ArrayData newData = ensure(by + length() - 1);
+        final ArrayData newData = ensure(by + length - 1);
         if (newData != this) {
             newData.shiftRight(by);
             return newData;
@@ -213,7 +229,7 @@
     @Override
     public ArrayData set(final int index, final int value, final boolean strict) {
         array[index] = value;
-        setLength(Math.max(index + 1, length()));
+        setLength(Math.max(index + 1, length));
 
         return this;
     }
@@ -222,7 +238,7 @@
     public ArrayData set(final int index, final long value, final boolean strict) {
         if (JSType.isRepresentableAsInt(value)) {
             array[index] = JSType.toInt32(value);
-            setLength(Math.max(index + 1, length()));
+            setLength(Math.max(index + 1, length));
             return this;
         }
 
@@ -233,7 +249,7 @@
     public ArrayData set(final int index, final double value, final boolean strict) {
         if (JSType.isRepresentableAsInt(value)) {
             array[index] = (int)(long)value;
-            setLength(Math.max(index + 1, length()));
+            setLength(Math.max(index + 1, length));
             return this;
         }
 
@@ -282,7 +298,7 @@
 
     @Override
     public boolean has(final int index) {
-        return 0 <= index && index < length();
+        return 0 <= index && index < length;
     }
 
     @Override
@@ -297,11 +313,11 @@
 
     @Override
     public Object pop() {
-        if (length() == 0) {
+        if (length == 0) {
             return ScriptRuntime.UNDEFINED;
         }
 
-        final int newLength = (int) length() - 1;
+        final int newLength = (int)length - 1;
         final int elem = array[newLength];
         array[newLength] = 0;
         setLength(newLength);
@@ -311,7 +327,7 @@
 
     @Override
     public ArrayData slice(final long from, final long to) {
-        final long start     = from < 0 ? from + length() : from;
+        final long start     = from < 0 ? from + length : from;
         final long newLength = to - start;
 
         return new IntArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
@@ -319,18 +335,18 @@
 
     @Override
     public final ArrayData push(final boolean strict, final int item) {
-        final long      length = length();
-        final ArrayData newData = ensure(length);
+        final long      len     = length;
+        final ArrayData newData = ensure(len);
         if (newData == this) {
-            array[(int)length] = item;
+            array[(int)len] = item;
             return this;
         }
-        return newData.set((int)length, item, strict);
+        return newData.set((int)len, item, strict);
     }
 
     @Override
     public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
-        final long oldLength = length();
+        final long oldLength = length;
         final long newLength = oldLength - removed + added;
         if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
             throw new UnsupportedOperationException();
@@ -355,4 +371,41 @@
 
         return returnValue;
     }
+
+    @Override
+    public long fastPush(final int arg) {
+        final int len = (int)length;
+        if (len == array.length) {
+            array = Arrays.copyOf(array, nextSize(len));
+        }
+        array[len] = arg;
+        return ++length;
+    }
+
+    //length must not be zero
+    @Override
+    public int fastPopInt() {
+        if (length == 0) {
+            throw new ClassCastException(); //relink
+        }
+        final int newLength = (int)--length;
+        final int elem = array[newLength];
+        array[newLength] = 0;
+        return elem;
+    }
+
+    @Override
+    public long fastPopLong() {
+        return fastPopInt();
+    }
+
+    @Override
+    public double fastPopDouble() {
+        return fastPopInt();
+    }
+
+    @Override
+    public Object fastPopObject() {
+        return fastPopInt();
+    }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntElements.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntElements.java
new file mode 100644
index 0000000..5bd2684
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntElements.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010, 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 jdk.nashorn.internal.runtime.arrays;
+
+/**
+ * Marker interface for any ContinuousArray with int elements
+ * Used for type checks that throw ClassCastExceptions and force relinks
+ * for fast NativeArray specializations of builtin methods
+ */
+public interface IntElements extends IntOrLongElements {
+    //empty
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntOrLongElements.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntOrLongElements.java
new file mode 100644
index 0000000..f176d75
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IntOrLongElements.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010, 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 jdk.nashorn.internal.runtime.arrays;
+
+/**
+ * Marker interface for any ContinuousArray with int or long elements
+ * Used for type checks that throw ClassCastExceptions and force relinks
+ * for fast NativeArray specializations of builtin methods
+ */
+public interface IntOrLongElements extends NumericElements {
+    //empty
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java
index 4fc0c63..ad050d6 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java
@@ -27,7 +27,6 @@
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
 import static jdk.nashorn.internal.lookup.Lookup.MH;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.util.Arrays;
@@ -39,7 +38,7 @@
  * Implementation of {@link ArrayData} as soon as a long has been
  * written to the array
  */
-final class LongArrayData extends ContinuousArrayData {
+final class LongArrayData extends ContinuousArrayData implements IntOrLongElements {
     /**
      * The wrapped array
      */
@@ -57,13 +56,18 @@
     }
 
     @Override
+    public Class<?> getElementType() {
+        return long.class;
+    }
+
+    @Override
     public ArrayData copy() {
-        return new LongArrayData(array.clone(), (int)length());
+        return new LongArrayData(array.clone(), (int)length);
     }
 
     @Override
     public Object[] asObjectArray() {
-        return toObjectArray(array, (int)length());
+        return toObjectArray(array, (int)length);
     }
 
     private static Object[] toObjectArray(final long[] array, final int length) {
@@ -80,7 +84,7 @@
     @Override
     public Object asArrayOfType(final Class<?> componentType) {
         if (componentType == long.class) {
-            return array.length == length() ? array.clone() : Arrays.copyOf(array, (int)length());
+            return array.length == length ? array.clone() : Arrays.copyOf(array, (int)length);
         }
         return super.asArrayOfType(componentType);
     }
@@ -101,11 +105,11 @@
         if (type == Integer.class || type == Long.class) {
             return this;
         }
-        final int length = (int) length();
+        final int len = (int)length;
         if (type == Double.class) {
-            return new NumberArrayData(LongArrayData.toDoubleArray(array, length), length);
+            return new NumberArrayData(LongArrayData.toDoubleArray(array, len), len);
         }
-        return new ObjectArrayData(LongArrayData.toObjectArray(array, length), length);
+        return new ObjectArrayData(LongArrayData.toObjectArray(array, len), len);
     }
 
     @Override
@@ -115,7 +119,7 @@
 
     @Override
     public ArrayData shiftRight(final int by) {
-        final ArrayData newData = ensure(by + length() - 1);
+        final ArrayData newData = ensure(by + length - 1);
         if (newData != this) {
             newData.shiftRight(by);
             return newData;
@@ -161,14 +165,14 @@
     @Override
     public ArrayData set(final int index, final int value, final boolean strict) {
         array[index] = value;
-        setLength(Math.max(index + 1, length()));
+        setLength(Math.max(index + 1, length));
         return this;
     }
 
     @Override
     public ArrayData set(final int index, final long value, final boolean strict) {
         array[index] = value;
-        setLength(Math.max(index + 1, length()));
+        setLength(Math.max(index + 1, length));
         return this;
     }
 
@@ -176,7 +180,7 @@
     public ArrayData set(final int index, final double value, final boolean strict) {
         if (JSType.isRepresentableAsLong(value)) {
             array[index] = (long)value;
-            setLength(Math.max(index + 1, length()));
+            setLength(Math.max(index + 1, length));
             return this;
         }
         return convert(Double.class).set(index, value, strict);
@@ -252,7 +256,7 @@
 
     @Override
     public boolean has(final int index) {
-        return 0 <= index && index < length();
+        return 0 <= index && index < length;
     }
 
     @Override
@@ -267,11 +271,11 @@
 
     @Override
     public Object pop() {
-        if (length() == 0) {
+        if (length == 0) {
             return ScriptRuntime.UNDEFINED;
         }
 
-        final int newLength = (int) (length() - 1);
+        final int newLength = (int)length - 1;
         final long elem = array[newLength];
         array[newLength] = 0;
         setLength(newLength);
@@ -281,25 +285,25 @@
 
     @Override
     public ArrayData slice(final long from, final long to) {
-        final long start     = from < 0 ? from + length() : from;
+        final long start     = from < 0 ? from + length : from;
         final long newLength = to - start;
         return new LongArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
     }
 
     @Override
     public final ArrayData push(final boolean strict, final long item) {
-        final long      length = length();
-        final ArrayData newData = ensure(length);
+        final long      len     = length;
+        final ArrayData newData = ensure(len);
         if (newData == this) {
-            array[(int)length] = item;
+            array[(int)len] = item;
             return this;
         }
-        return newData.set((int)length, item, strict);
+        return newData.set((int)len, item, strict);
     }
 
     @Override
     public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
-        final long oldLength = length();
+        final long oldLength = length;
         final long newLength = oldLength - removed + added;
         if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
             throw new UnsupportedOperationException();
@@ -324,4 +328,40 @@
 
         return returnValue;
     }
+
+    @Override
+    public long fastPush(final int arg) {
+        return fastPush((long)arg);
+    }
+
+    @Override
+    public long fastPush(final long arg) {
+        final int len = (int)length;
+        if (len == array.length) {
+            array = Arrays.copyOf(array, nextSize(len));
+        }
+        array[len] = arg;
+        return ++length;
+    }
+
+    @Override
+    public long fastPopLong() {
+        if (length == 0) {
+            throw new ClassCastException();
+        }
+        final int newLength = (int)--length;
+        final long elem = array[newLength];
+        array[newLength] = 0;
+        return elem;
+    }
+
+    @Override
+    public double fastPopDouble() {
+        return fastPopLong();
+   }
+
+    @Override
+    public Object fastPopObject() {
+        return fastPopLong();
+    }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/NoTypeArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/NoTypeArrayData.java
index 4e0ce37..143cd22 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/NoTypeArrayData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/NoTypeArrayData.java
@@ -58,19 +58,19 @@
 
     @Override
     public ArrayData convert(final Class<?> type) {
-        final long length = length();
+        final long len = length;
         final ArrayData arrayData;
         if (type == Long.class) {
-            arrayData = new LongArrayData(new long[ArrayData.nextSize((int)length)], (int)length);
+            arrayData = new LongArrayData(new long[ArrayData.nextSize((int)len)], (int)len);
         } else if (type == Double.class) {
-            arrayData = new NumberArrayData(new double[ArrayData.nextSize((int)length)], (int)length);
+            arrayData = new NumberArrayData(new double[ArrayData.nextSize((int)len)], (int)len);
         } else if (type == Integer.class) {
-            arrayData = new IntArrayData(new int[ArrayData.nextSize((int)length)], (int)length);
+            arrayData = new IntArrayData(new int[ArrayData.nextSize((int)len)], (int)len);
         } else {
             assert !type.isPrimitive();
-            arrayData = new ObjectArrayData(new Object[ArrayData.nextSize((int)length)], (int)length);
+            arrayData = new ObjectArrayData(new Object[ArrayData.nextSize((int)len)], (int)len);
         }
-        return length == 0 ? arrayData : new DeletedRangeArrayFilter(arrayData, 0, length - 1);
+        return length == 0 ? arrayData : new DeletedRangeArrayFilter(arrayData, 0, len - 1);
     }
 
     @Override
@@ -90,11 +90,11 @@
         }
 
         // Don't trample the shared EMPTY_ARRAY.
-        if (length() == 0) {
-            return new NoTypeArrayData(Math.max(safeIndex + 1, length()));
+        if (length == 0) {
+            return new NoTypeArrayData(Math.max(safeIndex + 1, length));
         }
 
-        setLength(Math.max(safeIndex + 1, length()));
+        setLength(Math.max(safeIndex + 1, length));
         return this;
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java
index 0739ae8..b2d843e 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java
@@ -28,7 +28,6 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
 import static jdk.nashorn.internal.lookup.Lookup.MH;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.util.Arrays;
@@ -38,7 +37,7 @@
  * Implementation of {@link ArrayData} as soon as a double has been
  * written to the array
  */
-final class NumberArrayData extends ContinuousArrayData {
+final class NumberArrayData extends ContinuousArrayData implements NumericElements {
     /**
      * The wrapped array
      */
@@ -56,13 +55,18 @@
     }
 
     @Override
+    public Class<?> getElementType() {
+        return double.class;
+    }
+
+    @Override
     public ArrayData copy() {
-        return new NumberArrayData(array.clone(), (int) length());
+        return new NumberArrayData(array.clone(), (int)length);
     }
 
     @Override
     public Object[] asObjectArray() {
-        return toObjectArray(array, (int) length());
+        return toObjectArray(array, (int)length);
     }
 
     private static Object[] toObjectArray(final double[] array, final int length) {
@@ -78,7 +82,7 @@
     @Override
     public Object asArrayOfType(final Class<?> componentType) {
         if(componentType == double.class) {
-            return array.length == length() ? array.clone() : Arrays.copyOf(array, (int) length());
+            return array.length == length ? array.clone() : Arrays.copyOf(array, (int)length);
         }
         return super.asArrayOfType(componentType);
     }
@@ -86,8 +90,8 @@
     @Override
     public ArrayData convert(final Class<?> type) {
         if (type != Double.class && type != Integer.class && type != Long.class) {
-            final int length = (int) length();
-            return new ObjectArrayData(NumberArrayData.toObjectArray(array, length), length);
+            final int len = (int)length;
+            return new ObjectArrayData(NumberArrayData.toObjectArray(array, len), len);
         }
         return this;
     }
@@ -99,7 +103,7 @@
 
     @Override
     public ArrayData shiftRight(final int by) {
-        final ArrayData newData = ensure(by + length() - 1);
+        final ArrayData newData = ensure(by + length - 1);
         if (newData != this) {
             newData.shiftRight(by);
             return newData;
@@ -144,21 +148,21 @@
     @Override
     public ArrayData set(final int index, final int value, final boolean strict) {
         array[index] = value;
-        setLength(Math.max(index + 1, length()));
+        setLength(Math.max(index + 1, length));
         return this;
     }
 
     @Override
     public ArrayData set(final int index, final long value, final boolean strict) {
         array[index] = value;
-        setLength(Math.max(index + 1, length()));
+        setLength(Math.max(index + 1, length));
         return this;
     }
 
     @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         array[index] = value;
-        setLength(Math.max(index + 1, length()));
+        setLength(Math.max(index + 1, length));
         return this;
     }
 
@@ -227,7 +231,7 @@
 
     @Override
     public boolean has(final int index) {
-        return 0 <= index && index < length();
+        return 0 <= index && index < length;
     }
 
     @Override
@@ -242,11 +246,11 @@
 
     @Override
     public Object pop() {
-        if (length() == 0) {
+        if (length == 0) {
             return UNDEFINED;
         }
 
-        final int newLength = (int) (length() - 1);
+        final int newLength = (int)length - 1;
         final double elem = array[newLength];
         array[newLength] = 0;
         setLength(newLength);
@@ -255,25 +259,25 @@
 
     @Override
     public ArrayData slice(final long from, final long to) {
-        final long start     = from < 0 ? from + length() : from;
+        final long start     = from < 0 ? from + length : from;
         final long newLength = to - start;
         return new NumberArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
     }
 
     @Override
     public final ArrayData push(final boolean strict, final double item) {
-        final long      length = length();
-        final ArrayData newData = ensure(length);
+        final long      len     = length;
+        final ArrayData newData = ensure(len);
         if (newData == this) {
-            array[(int)length] = item;
+            array[(int)len] = item;
             return this;
         }
-        return newData.set((int)length, item, strict);
+        return newData.set((int)len, item, strict);
     }
 
     @Override
     public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
-        final long oldLength = length();
+        final long oldLength = length;
         final long newLength = oldLength - removed + added;
         if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
             throw new UnsupportedOperationException();
@@ -298,4 +302,41 @@
 
         return returnValue;
     }
+
+    @Override
+    public long fastPush(final int arg) {
+        return fastPush((double)arg);
+    }
+
+    @Override
+    public long fastPush(final long arg) {
+        return fastPush((double)arg);
+    }
+
+    @Override
+    public long fastPush(final double arg) {
+        final int len = (int)length;
+        if (len == array.length) {
+           //note that fastpush never creates spares arrays, there is nothing to gain by that - it will just use even more memory
+           array = Arrays.copyOf(array, nextSize(len));
+        }
+        array[len] = arg;
+        return ++length;
+    }
+
+    @Override
+    public double fastPopDouble() {
+        if (length == 0) {
+            throw new ClassCastException();
+        }
+        final int newLength = (int)--length;
+        final double elem = array[newLength];
+        array[newLength] = 0;
+        return elem;
+    }
+
+    @Override
+    public Object fastPopObject() {
+        return fastPopDouble();
+    }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumericElements.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumericElements.java
new file mode 100644
index 0000000..ad940e2
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/NumericElements.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 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 jdk.nashorn.internal.runtime.arrays;
+
+/**
+ * Marker interface for any ContinuousArray with numeric elements
+ * (int, long or double)
+ * Used for type checks that throw ClassCastExceptions and force relinks
+ * for fast NativeArray specializations of builtin methods
+ */
+public interface NumericElements {
+    //empty
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java
index 636c8c2..8fd1a45 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.runtime.arrays;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.util.Arrays;
@@ -57,20 +56,25 @@
     }
 
     @Override
+    public Class<?> getElementType() {
+        return Object.class;
+    }
+
+    @Override
     public ArrayData copy() {
-        return new ObjectArrayData(array.clone(), (int) length());
+        return new ObjectArrayData(array.clone(), (int)length);
     }
 
     @Override
     public Object[] asObjectArray() {
-        return array.length == length() ? array.clone() : asObjectArrayCopy();
+        return array.length == length ? array.clone() : asObjectArrayCopy();
     }
 
     private Object[] asObjectArrayCopy() {
-        final long l = length();
-        assert l <= Integer.MAX_VALUE;
-        final Object[] copy = new Object[(int)l];
-        System.arraycopy(array, 0, copy, 0, (int)l);
+        final long len = length;
+        assert len <= Integer.MAX_VALUE;
+        final Object[] copy = new Object[(int)len];
+        System.arraycopy(array, 0, copy, 0, (int)len);
         return copy;
     }
 
@@ -86,7 +90,7 @@
 
     @Override
     public ArrayData shiftRight(final int by) {
-        final ArrayData newData = ensure(by + length() - 1);
+        final ArrayData newData = ensure(by + length - 1);
         if (newData != this) {
             newData.shiftRight(by);
             return newData;
@@ -118,28 +122,28 @@
     @Override
     public ArrayData set(final int index, final Object value, final boolean strict) {
         array[index] = value;
-        setLength(Math.max(index + 1, length()));
+        setLength(Math.max(index + 1, length));
         return this;
     }
 
     @Override
     public ArrayData set(final int index, final int value, final boolean strict) {
         array[index] = value;
-        setLength(Math.max(index + 1, length()));
+        setLength(Math.max(index + 1, length));
         return this;
     }
 
     @Override
     public ArrayData set(final int index, final long value, final boolean strict) {
         array[index] = value;
-        setLength(Math.max(index + 1, length()));
+        setLength(Math.max(index + 1, length));
         return this;
     }
 
     @Override
     public ArrayData set(final int index, final double value, final boolean strict) {
         array[index] = value;
-        setLength(Math.max(index + 1, length()));
+        setLength(Math.max(index + 1, length));
         return this;
     }
 
@@ -216,7 +220,7 @@
 
     @Override
     public boolean has(final int index) {
-        return 0 <= index && index < length();
+        return 0 <= index && index < length;
     }
 
     @Override
@@ -232,12 +236,48 @@
     }
 
     @Override
+    public long fastPush(final int arg) {
+        return fastPush((Object)arg);
+    }
+
+    @Override
+    public long fastPush(final long arg) {
+        return fastPush((Object)arg);
+    }
+
+    @Override
+    public long fastPush(final double arg) {
+        return fastPush((Object)arg);
+    }
+
+    @Override
+    public long fastPush(final Object arg) {
+        final int len = (int)length;
+        if (len == array.length) {
+            array = Arrays.copyOf(array, nextSize(len));
+        }
+        array[len] = arg;
+        return ++length;
+    }
+
+    @Override
+    public Object fastPopObject() {
+        if (length == 0) {
+            return ScriptRuntime.UNDEFINED;
+        }
+        final int newLength = (int)--length;
+        final Object elem = array[newLength];
+        array[newLength] = ScriptRuntime.EMPTY;
+        return elem;
+    }
+
+    @Override
     public Object pop() {
-        if (length() == 0) {
+        if (length == 0) {
             return ScriptRuntime.UNDEFINED;
         }
 
-        final int newLength = (int) (length() - 1);
+        final int newLength = (int)length - 1;
         final Object elem = array[newLength];
         setEmpty(newLength);
         setLength(newLength);
@@ -246,25 +286,25 @@
 
     @Override
     public ArrayData slice(final long from, final long to) {
-        final long start     = from < 0 ? from + length() : from;
+        final long start     = from < 0 ? from + length : from;
         final long newLength = to - start;
         return new ObjectArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
     }
 
     @Override
     public ArrayData push(final boolean strict, final Object item) {
-        final long      length = length();
-        final ArrayData newData = ensure(length);
+        final long      len     = length;
+        final ArrayData newData = ensure(len);
         if (newData == this) {
-            array[(int)length] = item;
+            array[(int)len] = item;
             return this;
         }
-        return newData.set((int)length, item, strict);
+        return newData.set((int)len, item, strict);
     }
 
     @Override
     public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
-        final long oldLength = length();
+        final long oldLength = length;
         final long newLength = oldLength - removed + added;
         if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
             throw new UnsupportedOperationException();
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java
index 623e315..d28b731 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java
@@ -53,28 +53,28 @@
 
     SparseArrayData(final ArrayData underlying, final long length, final TreeMap<Long, Object> sparseMap) {
         super(length);
-        assert underlying.length() <= length;
+        assert underlying.length <= length;
         this.underlying = underlying;
-        this.maxDenseLength = Math.max(MAX_DENSE_LENGTH, underlying.length());
+        this.maxDenseLength = Math.max(MAX_DENSE_LENGTH, underlying.length);
         this.sparseMap = sparseMap;
     }
 
     @Override
     public ArrayData copy() {
-        return new SparseArrayData(underlying.copy(), length(), new TreeMap<>(sparseMap));
+        return new SparseArrayData(underlying.copy(), length, new TreeMap<>(sparseMap));
     }
 
     @Override
     public Object[] asObjectArray() {
-        final int length = (int) Math.min(length(), Integer.MAX_VALUE);
-        final int underlyingLength = (int) Math.min(length, underlying.length());
-        final Object[] objArray = new Object[length];
+        final int len = (int)Math.min(length, Integer.MAX_VALUE);
+        final int underlyingLength = (int)Math.min(len, underlying.length);
+        final Object[] objArray = new Object[len];
 
         for (int i = 0; i < underlyingLength; i++) {
             objArray[i] = underlying.getObject(i);
         }
 
-        Arrays.fill(objArray, underlyingLength, length, ScriptRuntime.UNDEFINED);
+        Arrays.fill(objArray, underlyingLength, len, ScriptRuntime.UNDEFINED);
 
         for (final Map.Entry<Long, Object> entry : sparseMap.entrySet()) {
             final long key = entry.getKey();
@@ -104,14 +104,14 @@
         }
 
         sparseMap = newSparseMap;
-        setLength(Math.max(length() - by, 0));
+        setLength(Math.max(length - by, 0));
     }
 
     @Override
     public ArrayData shiftRight(final int by) {
         final TreeMap<Long, Object> newSparseMap = new TreeMap<>();
-        if (underlying.length() + by > maxDenseLength) {
-            for (long i = maxDenseLength - by; i < underlying.length(); i++) {
+        if (underlying.length + by > maxDenseLength) {
+            for (long i = maxDenseLength - by; i < underlying.length; i++) {
                 if (underlying.has((int) i)) {
                     newSparseMap.put(Long.valueOf(i + by), underlying.getObject((int) i));
                 }
@@ -127,23 +127,23 @@
         }
 
         sparseMap = newSparseMap;
-        setLength(length() + by);
+        setLength(length + by);
 
         return this;
     }
 
     @Override
     public ArrayData ensure(final long safeIndex) {
-        if (safeIndex < maxDenseLength && underlying.length() <= safeIndex) {
+        if (safeIndex < maxDenseLength && underlying.length <= safeIndex) {
             underlying = underlying.ensure(safeIndex);
         }
-        setLength(Math.max(safeIndex + 1, length()));
+        setLength(Math.max(safeIndex + 1, length));
         return this;
     }
 
     @Override
     public ArrayData shrink(final long newLength) {
-        if (newLength < underlying.length()) {
+        if (newLength < underlying.length) {
             underlying = underlying.shrink(newLength);
             underlying.setLength(newLength);
             sparseMap.clear();
@@ -160,11 +160,11 @@
         if (index >= 0 && index < maxDenseLength) {
             ensure(index);
             underlying = underlying.set(index, value, strict);
-            setLength(Math.max(underlying.length(), length()));
+            setLength(Math.max(underlying.length, length));
         } else {
             final Long longIndex = indexToKey(index);
             sparseMap.put(longIndex, value);
-            setLength(Math.max(longIndex + 1, length()));
+            setLength(Math.max(longIndex + 1, length));
         }
 
         return this;
@@ -175,11 +175,11 @@
         if (index >= 0 && index < maxDenseLength) {
             ensure(index);
             underlying = underlying.set(index, value, strict);
-            setLength(Math.max(underlying.length(), length()));
+            setLength(Math.max(underlying.length, length));
         } else {
             final Long longIndex = indexToKey(index);
             sparseMap.put(longIndex, value);
-            setLength(Math.max(longIndex + 1, length()));
+            setLength(Math.max(longIndex + 1, length));
         }
         return this;
     }
@@ -189,11 +189,11 @@
         if (index >= 0 && index < maxDenseLength) {
             ensure(index);
             underlying = underlying.set(index, value, strict);
-            setLength(Math.max(underlying.length(), length()));
+            setLength(Math.max(underlying.length, length));
         } else {
             final Long longIndex = indexToKey(index);
             sparseMap.put(longIndex, value);
-            setLength(Math.max(longIndex + 1, length()));
+            setLength(Math.max(longIndex + 1, length));
         }
         return this;
     }
@@ -203,11 +203,11 @@
         if (index >= 0 && index < maxDenseLength) {
             ensure(index);
             underlying = underlying.set(index, value, strict);
-            setLength(Math.max(underlying.length(), length()));
+            setLength(Math.max(underlying.length, length));
         } else {
             final Long longIndex = indexToKey(index);
             sparseMap.put(longIndex, value);
-            setLength(Math.max(longIndex + 1, length()));
+            setLength(Math.max(longIndex + 1, length));
         }
         return this;
     }
@@ -294,7 +294,7 @@
     @Override
     public boolean has(final int index) {
         if (index >= 0 && index < maxDenseLength) {
-            return index < underlying.length() && underlying.has(index);
+            return index < underlying.length && underlying.has(index);
         }
 
         return sparseMap.containsKey(indexToKey(index));
@@ -303,7 +303,7 @@
     @Override
     public ArrayData delete(final int index) {
         if (index >= 0 && index < maxDenseLength) {
-            if (index < underlying.length()) {
+            if (index < underlying.length) {
                 underlying = underlying.delete(index);
             }
         } else {
@@ -315,8 +315,8 @@
 
     @Override
     public ArrayData delete(final long fromIndex, final long toIndex) {
-        if (fromIndex < maxDenseLength && fromIndex < underlying.length()) {
-            underlying = underlying.delete(fromIndex, Math.min(toIndex, underlying.length() - 1));
+        if (fromIndex < maxDenseLength && fromIndex < underlying.length) {
+            underlying = underlying.delete(fromIndex, Math.min(toIndex, underlying.length - 1));
         }
         if (toIndex >= maxDenseLength) {
             sparseMap.subMap(fromIndex, true, toIndex, true).clear();
@@ -329,37 +329,37 @@
     }
 
     @Override
-    protected ArrayData convert(final Class<?> type) {
+    public ArrayData convert(final Class<?> type) {
         underlying = underlying.convert(type);
         return this;
     }
 
     @Override
     public Object pop() {
-        if (length() == 0) {
+        if (length == 0) {
             return ScriptRuntime.UNDEFINED;
         }
-        if (length() == underlying.length()) {
+        if (length == underlying.length) {
             final Object result = underlying.pop();
-            setLength(underlying.length());
+            setLength(underlying.length);
             return result;
         }
-        setLength(length() - 1);
-        final Long key = Long.valueOf(length());
+        setLength(length - 1);
+        final Long key = Long.valueOf(length);
         return sparseMap.containsKey(key) ? sparseMap.remove(key) : ScriptRuntime.UNDEFINED;
     }
 
     @Override
     public ArrayData slice(final long from, final long to) {
-        assert to <= length();
-        final long start = from < 0 ? (from + length()) : from;
+        assert to <= length;
+        final long start = from < 0 ? (from + length) : from;
         final long newLength = to - start;
 
         if (start >= 0 && to <= maxDenseLength) {
-            if (newLength <= underlying.length()) {
+            if (newLength <= underlying.length) {
                 return underlying.slice(from, to);
             }
-            return underlying.slice(from, to).ensure(newLength - 1).delete(underlying.length(), newLength);
+            return underlying.slice(from, to).ensure(newLength - 1).delete(underlying.length, newLength);
         }
 
         ArrayData sliced = EMPTY_ARRAY;
@@ -369,13 +369,13 @@
                 sliced = sliced.set((int)(i - start), getObject((int)i), false);
             }
         }
-        assert sliced.length() == newLength;
+        assert sliced.length == newLength;
         return sliced;
     }
 
     @Override
     public long nextIndex(final long index) {
-        if (index < underlying.length() - 1) {
+        if (index < underlying.length - 1) {
             return underlying.nextIndex(index);
         }
 
@@ -383,6 +383,6 @@
         if (nextKey != null) {
             return nextKey;
         }
-        return length();
+        return length;
     }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/TypedArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/TypedArrayData.java
index 291e59e..428678d 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/TypedArrayData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/TypedArrayData.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.runtime.arrays;
 
 import static jdk.nashorn.internal.lookup.Lookup.MH;
-
 import java.lang.invoke.MethodHandle;
 import java.nio.Buffer;
 import jdk.internal.dynalink.CallSiteDescriptor;
@@ -55,11 +54,11 @@
     }
 
     /**
-     * Length in elements. Accessed from {@code ArrayBufferView}
+     * Length in number of elements. Accessed from {@code ArrayBufferView}
      * @return element length
      */
     public final int getElementLength() {
-        return (int)length();
+        return (int)length;
     }
 
     /**
@@ -120,7 +119,7 @@
 
     @Override
     public final boolean has(final int index) {
-        return 0 <= index && index < length();
+        return 0 <= index && index < length;
     }
 
     @Override
@@ -134,7 +133,7 @@
     }
 
     @Override
-    protected ArrayData convert(final Class<?> type) {
+    public ArrayData convert(final Class<?> type) {
         throw new UnsupportedOperationException();
     }
 
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java
index e2488d3..f744aac 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java
@@ -26,7 +26,6 @@
 package jdk.nashorn.internal.runtime.arrays;
 
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
 import java.lang.reflect.Array;
 import jdk.nashorn.internal.runtime.BitVector;
 import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
@@ -41,7 +40,7 @@
     UndefinedArrayFilter(final ArrayData underlying) {
         super(underlying);
 
-        this.undefined = new BitVector(underlying.length());
+        this.undefined = new BitVector(underlying.length);
     }
 
     @Override
@@ -81,25 +80,25 @@
     @Override
     public void shiftLeft(final int by) {
         super.shiftLeft(by);
-        undefined.shiftLeft(by, length());
+        undefined.shiftLeft(by, length);
     }
 
     @Override
     public ArrayData shiftRight(final int by) {
         super.shiftRight(by);
-        undefined.shiftRight(by, length());
+        undefined.shiftRight(by, length);
 
         return this;
     }
 
     @Override
     public ArrayData ensure(final long safeIndex) {
-        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length()) {
+        if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH && safeIndex >= length) {
             return new SparseArrayData(this, safeIndex + 1);
         }
 
         super.ensure(safeIndex);
-        undefined.resize(length());
+        undefined.resize(length);
 
         return this;
     }
@@ -107,7 +106,7 @@
     @Override
     public ArrayData shrink(final long newLength) {
         super.shrink(newLength);
-        undefined.resize(length());
+        undefined.resize(length);
 
         return this;
     }
@@ -217,7 +216,7 @@
 
     @Override
     public Object pop() {
-        final long index = length() - 1;
+        final long index = length - 1;
 
         if (super.has((int)index)) {
             final boolean isUndefined = undefined.isSet(index);
@@ -234,7 +233,7 @@
         final ArrayData newArray = underlying.slice(from, to);
         final UndefinedArrayFilter newFilter = new UndefinedArrayFilter(newArray);
         newFilter.getUndefined().copy(undefined);
-        newFilter.getUndefined().shiftLeft(from, newFilter.length());
+        newFilter.getUndefined().shiftLeft(from, newFilter.length);
 
         return newFilter;
     }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java
index f377c9d..2a536bb 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java
@@ -26,14 +26,16 @@
 package jdk.nashorn.internal.runtime.linker;
 
 import static jdk.nashorn.internal.lookup.Lookup.MH;
-
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodType;
+import java.lang.invoke.SwitchPoint;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
 import jdk.internal.dynalink.support.Guards;
+import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.FindProperty;
+import jdk.nashorn.internal.runtime.GlobalConstants;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.UserAccessorProperty;
 
@@ -86,27 +88,41 @@
                                                     final MethodHandle protoFilter) {
         final CallSiteDescriptor desc = request.getCallSiteDescriptor();
 
-        if(desc.getNameTokenCount() > 2) {
+        //checks whether the property name is hard-coded in the call-site (i.e. a getProp vs a getElem, or setProp vs setElem)
+        //if it is we can make assumptions on the property: that if it is not defined on primitive wrapper itself it never will be.
+        //so in that case we can skip creation of primitive wrapper and start our search with the prototype.
+        if (desc.getNameTokenCount() > 2) {
             final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
             final FindProperty find = wrappedReceiver.findProperty(name, true);
-            if(find == null) {
+
+            if (find == null) {
                 // Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it.
                 return null;
-            } else if (find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) {
+            }
+
+            final SwitchPoint sp = find.getProperty().getBuiltinSwitchPoint(); //can use this instead of proto filter
+            if (sp instanceof Context.BuiltinSwitchPoint && !sp.hasBeenInvalidated()) {
+                return new GuardedInvocation(GlobalConstants.staticConstantGetter(find.getObjectValue()), guard, sp, null);
+            }
+
+            if (find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) {
                 // If property is found in the prototype object bind the method handle directly to
                 // the proto filter instead of going through wrapper instantiation below.
                 final ScriptObject proto = wrappedReceiver.getProto();
                 final GuardedInvocation link = proto.lookup(desc, request);
 
                 if (link != null) {
-                    final MethodHandle invocation = link.getInvocation();
+                    final MethodHandle invocation = link.getInvocation(); //this contains the builtin switchpoint
+
                     final MethodHandle adaptedInvocation = MH.asType(invocation, invocation.type().changeParameterType(0, Object.class));
                     final MethodHandle method = MH.filterArguments(adaptedInvocation, 0, protoFilter);
                     final MethodHandle protoGuard = MH.filterArguments(link.getGuard(), 0, protoFilter);
+
                     return new GuardedInvocation(method, NashornGuards.combineGuards(guard, protoGuard));
                 }
             }
         }
+
         final GuardedInvocation link = wrappedReceiver.lookup(desc, request);
         if (link != null) {
             MethodHandle method = link.getInvocation();
@@ -116,8 +132,10 @@
                 assert receiverType.isAssignableFrom(wrapType.returnType());
                 method = MH.filterArguments(method, 0, MH.asType(wrapFilter, wrapType.changeReturnType(receiverType)));
             }
+
             return new GuardedInvocation(method, guard, link.getSwitchPoints(), null);
         }
+
         return null;
     }
 }
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java
index 08168b6..77b1b3d 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java
@@ -25,6 +25,9 @@
 
 package jdk.nashorn.internal.runtime.regexp;
 
+import java.util.Collections;
+import java.util.Set;
+import java.util.WeakHashMap;
 import jdk.nashorn.internal.runtime.ParserException;
 import jdk.nashorn.internal.runtime.options.Options;
 
@@ -39,6 +42,15 @@
     private final static String JDK  = "jdk";
     private final static String JONI = "joni";
 
+    /** Weak cache of already validated regexps - when reparsing, we don't, for example
+     *  need to recompile (reverify) all regexps that have previously been parsed by this
+     *  RegExpFactory in a previous compilation. This saves significant time in e.g. avatar
+     *  startup */
+    private static final Set<String> VALID_CACHE_SET =
+            Collections.newSetFromMap(
+                    Collections.synchronizedMap(
+                            new WeakHashMap<String, Boolean>()));
+
     static {
         final String impl = Options.getStringProperty("nashorn.regexp.impl", JONI);
         switch (impl) {
@@ -88,7 +100,9 @@
      */
     // @SuppressWarnings({"unused"})
     public static void validate(final String pattern, final String flags) throws ParserException {
-        instance.compile(pattern, flags);
+        if (VALID_CACHE_SET.add(pattern + flags)) {
+            instance.compile(pattern, flags);
+        }
     }
 
     /**
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
index a5e8cd5..57943e0 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
@@ -203,9 +203,9 @@
 
 nashorn.option.optimistic.types = {                                                                      \
     name="--optimistic-types",                                                                           \
-    is_undocumented=true,                                                                                \
-    desc="Use optimistic type assumptions with deoptimizing recompilation.", \
-    default=true                                   \
+    short_name="-ot",                                                                                    \
+    desc="Use optimistic type assumptions with deoptimizing recompilation. This makes the compiler try, for any program symbol whose type cannot be proven at compile time, to type it as narrow and primitive as possible. If the runtime encounters an error because symbol type is too narrow, a wider method will be generated until steady stage is reached. While this produces as optimal Java Bytecode as possible, erroneous type guesses will lead to longer warmup. Optimistic typing is currently disabled by default, but can be enabled for significantly better peak performance.",                     \
+    default=false                                                                                        \
 }
 
 nashorn.option.loader.per.compile = {              \
diff --git a/nashorn/test/examples/charcodeat-benchmark.js b/nashorn/test/examples/charcodeat-benchmark.js
new file mode 100644
index 0000000..308e2a0
--- /dev/null
+++ b/nashorn/test/examples/charcodeat-benchmark.js
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Simple benchmark to measure charCodeAt specialized method performance
+ */
+
+var str = "sghjkdsfkjghsdfjkfkjdfkjdfjkdfjkfdjkfdkfldjfhdfpkjdhafgksdjfgldfgjldfkjgdlfjgldkfjgkldfj";
+var RESULT1 = 9187;
+var RESULT2 = 1496;
+
+function f() {
+    var len = str.length;
+    var c = 0;
+    for (var i = 0; i < len; i++) {
+	c += str.charCodeAt(i);
+    }
+    return c;
+}
+
+function bench(res) {
+    var d = new Date;
+    var sum = 0;
+    for (var i = 0; i < 1e6; i++) {
+	sum |= f();
+    }
+    if (sum == res) {
+	print("Verified OK"); 
+    } else {
+	print("Verification failed " + sum + " should be " + res);
+    }
+    print((new Date - d) + " ms");
+}
+
+bench(RESULT1);
+
+print("Replacing charCodeAt... ");
+
+String.prototype.charCodeAt = function() { return 17; }
+
+bench(RESULT2);
+
+print("Done");
diff --git a/nashorn/test/examples/push-pop-benchmark.js b/nashorn/test/examples/push-pop-benchmark.js
new file mode 100644
index 0000000..16f4c94
--- /dev/null
+++ b/nashorn/test/examples/push-pop-benchmark.js
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * Simple benchmark to measure push/pop specialized method performance
+ */
+
+var a = [];
+
+var RESULT = 15;
+
+function bench() {
+    var sum = 0;
+    for (var i=0;i<10;i++) {
+	a.push(i);
+    }
+    for (var i=0;i<10;i++) {
+	sum |= a.pop();
+    }
+    return sum;
+}
+
+function runbench() {
+    var sum = 0;
+    for (var iters = 0; iters<1e8; iters++) {
+	sum |= bench();
+    }
+    return sum;
+}
+
+var d = new Date;
+var res = runbench();
+print((new Date - d) + " ms");
+print();
+if (res != RESULT) {
+    print("ERROR: Wrong result - should be " + RESULT);
+} else {
+    print("Verified OK - result is correct");
+}
diff --git a/nashorn/test/script/basic/apply_to_call/apply_to_call5.js b/nashorn/test/script/basic/apply_to_call/apply_to_call5.js
new file mode 100644
index 0000000..adb9401
--- /dev/null
+++ b/nashorn/test/script/basic/apply_to_call/apply_to_call5.js
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * apply_to_call5.js - do one apply to call specialization, then override, apply and make sure it reverts (i.e. stops
+ * calling call)
+ *
+ * @test
+ * @run
+ */
+
+print("start");
+
+var x = {
+    a : 0,
+    b : 0,
+    c : 0,
+    initialize : function(x,y,z) {
+	this.a = x;
+	this.b = y;
+	this.c = z;
+    }
+};
+
+function test() {
+    x.initialize.apply(x, arguments);
+}
+
+test(4711,23,17);
+print(x.a);
+print(x.b);
+print(x.c);
+
+print("Overwriting apply now");
+x.initialize.apply = function() { print("New function for apply - not a property"); }
+  
+test(4712);
+print(x.a);
+
+
+var x2 = {
+    a : 0,
+    b : 0,
+    c : 0,
+    initialize : function(x,y,z) {
+    this.a = x;
+    this.b = y;
+    this.c = z;
+    }
+};
+
+function test2() {
+    x2.initialize.apply(x2, arguments);
+}
+
+test2(4711,23,17);
+print(x2.a);
+print(x2.b);
+print(x2.c);
+
+print("Overwriting apply now");
+x2.initialize['apply'] = function() { print("New function for apply - not a property"); }
+
+test(4712);
+print(x2.a);
+
+var x3 = {
+    a : 0,
+    b : 0,
+    c : 0,
+    initialize : function(x,y,z) {
+    this.a = x;
+    this.b = y;
+    this.c = z;
+    }
+};
+
+function test3() {
+    x3.initialize.apply(x3, arguments);
+}
+
+test3(4711,23,17);
+print(x3.a);
+print(x3.b);
+print(x3.c);
+
+print("Overwriting apply now");
+eval("x3.initialize['apply'] = function() { print('New function for apply - not a property'); }");
+
+test(4712);
+print(x3.a);
diff --git a/nashorn/test/script/basic/apply_to_call/apply_to_call5.js.EXPECTED b/nashorn/test/script/basic/apply_to_call/apply_to_call5.js.EXPECTED
new file mode 100644
index 0000000..4d678e9
--- /dev/null
+++ b/nashorn/test/script/basic/apply_to_call/apply_to_call5.js.EXPECTED
@@ -0,0 +1,19 @@
+start
+4711
+23
+17
+Overwriting apply now
+New function for apply - not a property
+4711
+4711
+23
+17
+Overwriting apply now
+New function for apply - not a property
+4711
+4711
+23
+17
+Overwriting apply now
+New function for apply - not a property
+4711
diff --git a/nashorn/test/script/basic/fastpushpop.js b/nashorn/test/script/basic/fastpushpop.js
new file mode 100644
index 0000000..fffd3f2
--- /dev/null
+++ b/nashorn/test/script/basic/fastpushpop.js
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010, 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.
+ */
+
+/**
+ * fastpushpop.js: make sure guards work for fast push implementation
+ * and normal one
+ *
+ * @test
+ * @run
+ */
+
+var a = [1,2,3];
+a.push(4);
+a.push(5);
+a.push(6);
+print(a);
+
+var a2 = Object.defineProperty(a,"length", { writable: false });
+try { 
+    a2.push(7);
+} catch (e) {
+    print("first: " + (e instanceof TypeError));
+}
+
+print(a2);
+
+var b = [1,2,3,,,,4711.17,"dingo!"];
+b.push(4);
+b.push(5);
+b.push(6);
+print(b);
+
+var b2 = Object.defineProperty(b,"length", { writable: false });
+try { 
+    b2.push(7);
+} catch (e) {
+    print("second: " + (e instanceof TypeError));
+}
+
+print(b2);
+
diff --git a/nashorn/test/script/basic/fastpushpop.js.EXPECTED b/nashorn/test/script/basic/fastpushpop.js.EXPECTED
new file mode 100644
index 0000000..0120e1d
--- /dev/null
+++ b/nashorn/test/script/basic/fastpushpop.js.EXPECTED
@@ -0,0 +1,6 @@
+1,2,3,4,5,6
+first: true
+1,2,3,4,5,6,7
+1,2,3,,,,4711.17,dingo!,4,5,6
+second: true
+1,2,3,,,,4711.17,dingo!,4,5,6,7
diff --git a/nashorn/test/script/basic/octane-payload.js b/nashorn/test/script/basic/octane-payload.js
index 36c780d..f2be6b1 100644
--- a/nashorn/test/script/basic/octane-payload.js
+++ b/nashorn/test/script/basic/octane-payload.js
@@ -40,7 +40,7 @@
     {name:"gbemu",         files:["gbemu-part1.js", "gbemu-part2.js"], suite:"GameboyBenchmark"},
     {name:"mandreel",      files:["mandreel.js"],                      suite:"MandreelBenchmark"},
     {name:"navier-stokes", files:["navier-stokes.js"],                 suite:"NavierStokes"},
-    {name:"pdfjs",         files:["pdfjs.js"],                         suite:"PdfJS"},
+    {name:"pdfjs",         files:["pdfjs.js"],                         suite:"PdfJS",                cleanUpIteration: function() { canvas_logs = []; }},
     {name:"raytrace",      files:["raytrace.js"],                      suite:"RayTrace"},
     {name:"regexp",        files:["regexp.js"],                        suite:"RegExpSuite"},
     {name:"richards",      files:["richards.js"],                      suite:"Richards"},
diff --git a/nashorn/test/script/basic/run-octane.js b/nashorn/test/script/basic/run-octane.js
index 0c666f2..a0a9bdc 100644
--- a/nashorn/test/script/basic/run-octane.js
+++ b/nashorn/test/script/basic/run-octane.js
@@ -24,8 +24,8 @@
 /**
  * @subtest
  */
-var payload = __DIR__ + "octane-payload.js";
-load(payload);
+var dir = typeof(__DIR__) == 'undefined' ? "test/script/basic/" : __DIR__;
+load(dir + "octane-payload.js");
 
 var runtime = undefined;
 var verbose = false;
@@ -43,27 +43,27 @@
 function load_bench(arg) {
 
     for (var idx = 0; idx < arg.files.length; idx++) {
-    var f = arg.files[idx];
-    var file = f.split('/');
-    var file_name = path + file[file.length - 1];
+        var f = arg.files[idx];
+        var file = f.split('/');
+        var file_name = path + file[file.length - 1];
 
-    var compile_and_return = should_compile_only(file_name);
-    if (compile_and_return) {
-        if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them
-        return true;
+        var compile_and_return = should_compile_only(file_name);
+        if (compile_and_return) {
+            if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them
+                return true;
+            }
         }
-    }
 
-    print_verbose(arg, "loading '" + arg.name + "' [" + f + "]...");
-    load(file_name);
+        print_verbose(arg, "loading '" + arg.name + "' [" + f + "]... " + file_name);
+        load(file_name);
     }
 
     if (typeof arg.before !== 'undefined') {
-    arg.before();
+        arg.before();
     }
 
     if (compile_and_return) {
-    print_always(arg, "Compiled OK");
+        print_always(arg, "Compiled OK");
     }
     return !compile_and_return;
 
@@ -73,16 +73,16 @@
 function run_one_benchmark(arg, iters) {
 
     if (!load_bench(arg)) {
-    return;
+        return;
     }
 
     var success = true;
     var current_name;
 
     if (iters == undefined) {
-    iters = numberOfIterations;
+        iters = numberOfIterations;
     } else {
-    numberOfIterations = iters;
+        numberOfIterations = iters;
     }
 
     var benchmarks = eval(arg.suite + ".benchmarks");
@@ -91,64 +91,69 @@
     var mean_score = 0;
 
     try {
-    for (var x = 0; x < benchmarks.length ; x++) {
-        //do warmup run
-        //reset random number generator needed as of octane 9 before each run
-        BenchmarkSuite.ResetRNG();
-        benchmarks[x].Setup();
-    }
-    BenchmarkSuite.ResetRNG();
-    print_verbose(arg, "running '" + arg.name + "' for " + iters + " iterations of no less than " + min_time + " seconds");
-
-    var scores = [];
-
-    var min_time_ms = min_time * 1000;
-    var len = benchmarks.length;
-
-    for (var it = 0; it < iters + 1; it++) {
-        //every iteration must take a minimum of 10 secs
-        var ops = 0;
-        var elapsed = 0;
-        var start = new Date;
-        do {
-        for (var i = 0; i < len; i++) {
-            benchmarks[i].run();
-            //important - no timing here like elapsed = new Date() - start, as in the
-            //original harness. This will make timing very non-deterministic.
-            //NOTHING else must live in this loop
+        for (var x = 0; x < benchmarks.length ; x++) {
+            //do warmup run
+            //reset random number generator needed as of octane 9 before each run
+            BenchmarkSuite.ResetRNG();
+            benchmarks[x].Setup();
         }
-        ops += len;
-        elapsed = new Date - start;
-        } while (elapsed < min_time * 1000);
+        BenchmarkSuite.ResetRNG();
+        print_verbose(arg, "running '" + arg.name + "' for " + iters + " iterations of no less than " + min_time + " seconds");
 
-        var score = ops / elapsed * 1000 * 60;
-        scores.push(score);
-        var name = it == 0 ? "warmup" : "iteration " + it;
-        print_verbose(arg, name + " finished " + score.toFixed(0) + " ops/minute");
-    }
+        var scores = [];
 
-    for (var x = 0; x < benchmarks.length ; x++) {
-        benchmarks[x].TearDown();
-    }
+        var min_time_ms = min_time * 1000;
+        var len = benchmarks.length;
 
-    for (var x = 1; x < iters + 1 ; x++) {
-        mean_score += scores[x];
-        min_score = Math.min(min_score, scores[x]);
-        max_score = Math.max(max_score, scores[x]);
-    }
-    mean_score /= iters;
+        for (var it = 0; it < iters + 1; it++) {
+            //every iteration must take a minimum of 10 secs
+            var ops = 0;
+            var elapsed = 0;
+            var start = new Date;
+            do {
+                for (var i = 0; i < len; i++) {
+                    benchmarks[i].run();
+                    //important - no timing here like elapsed = new Date() - start, as in the
+                    //original harness. This will make timing very non-deterministic.
+                    //NOTHING else must live in this loop
+                }
+                ops += len;
+                elapsed = new Date - start;
+            } while (elapsed < min_time * 1000);
+
+            var score = ops / elapsed * 1000 * 60;
+            scores.push(score);
+            var name = it == 0 ? "warmup" : "iteration " + it;
+            print_verbose(arg, name + " finished " + score.toFixed(0) + " ops/minute");
+
+            // optional per-iteration cleanup hook
+            if (typeof arg.cleanUpIteration == "function") {
+                arg.cleanUpIteration();
+            }
+        }
+
+        for (var x = 0; x < benchmarks.length ; x++) {
+            benchmarks[x].TearDown();
+        }
+
+        for (var x = 1; x < iters + 1 ; x++) {
+            mean_score += scores[x];
+            min_score = Math.min(min_score, scores[x]);
+            max_score = Math.max(max_score, scores[x]);
+        }
+        mean_score /= iters;
     } catch (e) {
-    print_always(arg, "*** Aborted and setting score to zero. Reason: " + e);
-    if (e instanceof java.lang.Throwable) {
-        e.printStackTrace();
-    }
-    mean_score = min_score = max_score = 0;
-    scores = [0];
+        print_always(arg, "*** Aborted and setting score to zero. Reason: " + e);
+        if (is_this_nashorn() && e instanceof java.lang.Throwable) {
+            e.printStackTrace();
+        }
+        mean_score = min_score = max_score = 0;
+        scores = [0];
     }
 
     var res = mean_score.toFixed(0);
     if (verbose) {
-    res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0);
+        res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0);
     }
     print_always(arg, res);
 }
@@ -163,13 +168,13 @@
 
 function print_verbose(arg, x) {
     if (verbose) {
-    print_always(arg, x)
+        print_always(arg, x)
     }
 }
 
 function run_suite(tests, iters) {
     for (var idx = 0; idx < tests.length; idx++) {
-    run_one_benchmark(tests[idx], iters);
+        run_one_benchmark(tests[idx], iters);
     }
 }
 
@@ -184,13 +189,13 @@
 var new_args = [];
 for (i in args) {
     if (args[i].toString().indexOf(' ') != -1) {
-    args[i] = args[i].replace(/\/$/, '');
-    var s = args[i].split(' ');
-    for (j in s) {
-        new_args.push(s[j]);
-    }
+        args[i] = args[i].replace(/\/$/, '');
+        var s = args[i].split(' ');
+        for (j in s) {
+            new_args.push(s[j]);
+        }
     } else {
-    new_args.push(args[i]);
+        new_args.push(args[i]);
     }
 }
 
@@ -205,46 +210,46 @@
 for (var i = 0; i < args.length; i++) {
     arg = args[i];
     if (arg == "--iterations") {
-    iters = +args[++i];
-    if (isNaN(iters)) {
-        throw "'--iterations' must be followed by integer";
-    }
+        iters = +args[++i];
+        if (isNaN(iters)) {
+            throw "'--iterations' must be followed by integer";
+        }
     } else if (arg == "--runtime") {
-    runtime = args[++i];
+        runtime = args[++i];
     } else if (arg == "--verbose") {
-    verbose = true;
+        verbose = true;
     } else if (arg == "--min-time") {
-    min_time = +args[++i];
-    if (isNaN(iters)) {
-        throw "'--min-time' must be followed by integer";
-    }
+        min_time = +args[++i];
+        if (isNaN(iters)) {
+            throw "'--min-time' must be followed by integer";
+        }
     } else if (arg == "") {
-    continue; //skip
+        continue; //skip
     } else {
-    var found = false;
-    for (j in tests) {
-        if (tests[j].name === arg) {
-        tests_found.push(tests[j]);
-        found = true;
-        break;
-        }
-    }
-    if (!found) {
-        var str = "unknown test name: '" + arg + "' -- valid names are: ";
+        var found = false;
         for (j in tests) {
-        if (j != 0) {
-            str += ", ";
+            if (tests[j].name === arg) {
+                tests_found.push(tests[j]);
+                found = true;
+                break;
+            }
         }
-        str += "'" + tests[j].name + "'";
+        if (!found) {
+            var str = "unknown test name: '" + arg + "' -- valid names are: ";
+            for (j in tests) {
+                if (j != 0) {
+                    str += ", ";
+                }
+                str += "'" + tests[j].name + "'";
+            }
+            throw str;
         }
-        throw str;
-    }
     }
 }
 
 if (tests_found.length == 0) {
     for (i in tests) {
-    tests_found.push(tests[i]);
+        tests_found.push(tests[i]);
     }
 }
 
@@ -255,21 +260,21 @@
 
 if (is_this_nashorn()) {
     try {
-    read = readFully;
+        read = readFully;
     } catch (e) {
-    print("ABORTING: Cannot find 'readFully'. You must have scripting enabled to use this test harness. (-scripting)");
-    throw e;
+        print("ABORTING: Cannot find 'readFully'. You must have scripting enabled to use this test harness. (-scripting)");
+        throw e;
     }
 }
 
 // run tests in alphabetical order by name
 tests_found.sort(function(a, b) {
     if (a.name < b.name) {
-    return -1;
+        return -1;
     } else if (a.name > b.name) {
-    return 1;
+        return 1;
     } else {
-    return 0;
+        return 0;
     }
 });
 
diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/ClassFilterTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/ClassFilterTest.java
index 558833e..7471731 100644
--- a/nashorn/test/src/jdk/nashorn/internal/runtime/ClassFilterTest.java
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/ClassFilterTest.java
@@ -25,10 +25,10 @@
 
 package jdk.nashorn.internal.runtime;
 
-
 import jdk.nashorn.api.scripting.ClassFilter;
 import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
 import jdk.nashorn.api.scripting.URLReader;
+import jdk.nashorn.internal.test.framework.TestFinder;
 import org.testng.annotations.Test;
 
 import javax.script.ScriptEngine;
@@ -126,9 +126,9 @@
     private void persistentCacheTestImpl() {
         NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
         ScriptEngine engine = factory.getScriptEngine(
-                new String[]{"--persistent-code-cache"},
-                getClass().getClassLoader(),
-                getClassFilter()
+              TestFinder.addExplicitOptimisticTypes(new String[]{"--persistent-code-cache", "--optimistic-types=true"}),
+                  getClass().getClassLoader(),
+                  getClassFilter()
         );
         String testScript = "var a = Java.type('java.lang.String');" + generateCodeForPersistentStore();
         try {
@@ -137,7 +137,7 @@
             fail(exc.getMessage());
         }
         ScriptEngine engineSafe = factory.getScriptEngine(
-                new String[]{"--persistent-code-cache"},
+                TestFinder.addExplicitOptimisticTypes(new String[]{"--persistent-code-cache", "--optimistic-types=true"}),
                 getClass().getClassLoader(),
                 new ClassFilter() {
                     @Override
@@ -151,7 +151,7 @@
             fail("ClassNotFoundException should have been thrown");
         } catch (final Exception exc) {
             if (!(exc.getCause() instanceof ClassNotFoundException)) {
-                fail("ClassNotFoundException expected");
+                fail("ClassNotFoundException expected, got " + exc.getClass());
             }
         }
     }
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java
index f8aef77..ee26061 100644
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java
@@ -179,7 +179,7 @@
         for (final String str : forkJVMOptions) {
             if(!str.isEmpty()) {
                 cmd.add(str);
-            }
+        }
         }
         cmd.add(Shell.class.getName());
         // now add the rest of the "in process" runtime arguments
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java
index 4a96a4a..018f4c7 100644
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java
@@ -56,6 +56,7 @@
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
@@ -75,7 +76,7 @@
  * Utility class to find/parse script test files and to create 'test' instances.
  * Actual 'test' object type is decided by clients of this class.
  */
-final class TestFinder {
+public final class TestFinder {
     private TestFinder() {}
 
     interface TestFactory<T> {
@@ -215,6 +216,8 @@
         final List<String> scriptArguments = new ArrayList<>();
         boolean inComment = false;
 
+        boolean explicitOptimistic = false;
+
         try (Scanner scanner = new Scanner(testFile)) {
             while (scanner.hasNext()) {
                 // TODO: Scan for /ref=file qualifiers, etc, to determine run
@@ -287,7 +290,11 @@
                     scriptArguments.add(scanner.next());
                     break;
                 case "@option":
-                    engineOptions.add(scanner.next());
+                    final String next = scanner.next();
+                    engineOptions.add(next);
+                    if (next.startsWith("--optimistic-types")) {
+                        explicitOptimistic = true;
+                    }
                     break;
                 case "@fork":
                     fork = true;
@@ -336,12 +343,61 @@
                 testOptions.put(OPTIONS_FORK, "true");
             }
 
+            //if there are explicit optimistic type settings, use those - do not override
+            //the test might only work with optimistic types on or off.
+            if (!explicitOptimistic) {
+                addExplicitOptimisticTypes(engineOptions);
+            }
+
             tests.add(factory.createTest(framework, testFile.toFile(), engineOptions, testOptions, scriptArguments));
         } else if (!isNotTest) {
             orphans.add(name);
         }
     }
 
+    //the reverse of the default setting for optimistic types, if enabled, false, otherwise true
+    //thus, true for 8u40, false for 9
+    private static final boolean OPTIMISTIC_OVERRIDE = true;
+
+    /**
+     * Check if there is an optimistic override, that disables the default
+     * false optimistic types and sets them to true, for testing purposes
+     *
+     * @return true if optimistic type override has been set by test suite
+     */
+    public static boolean hasOptimisticOverride() {
+        return Boolean.valueOf(OPTIMISTIC_OVERRIDE).toString().equals(System.getProperty("optimistic.override"));
+    }
+
+    /**
+     * Add an optimistic-types=true option to an argument list if this
+     * is set to override the default false. Add an optimistic-types=true
+     * options to an argument list if this is set to override the default
+     * true
+     *
+     * @args new argument list array
+     */
+    public static String[] addExplicitOptimisticTypes(String[] args) {
+        if (hasOptimisticOverride()) {
+            final List<String> newList = new ArrayList<>(Arrays.asList(args));
+            newList.add("--optimistic-types=" + Boolean.valueOf(OPTIMISTIC_OVERRIDE));
+            return newList.toArray(new String[0]);
+        }
+        return args;
+    }
+
+    /**
+     * Add an optimistic-types=true option to an argument list if this
+     * is set to override the default false
+     *
+     * @args argument list
+     */
+    public static void addExplicitOptimisticTypes(List<String> args) {
+        if (hasOptimisticOverride()) {
+            args.add("--optimistic-types=" + Boolean.valueOf(OPTIMISTIC_OVERRIDE));
+        }
+    }
+
     private static boolean strictModeEnabled() {
         return Boolean.getBoolean(TEST_JS_ENABLE_STRICT_MODE);
     }