Merge
authormullan
Tue, 25 Mar 2014 20:32:46 -0400
changeset 23579 6f6bae8b67a7
parent 23578 fa4caa7b4827 (current diff)
parent 23577 08ef6549e6a2 (diff)
child 23580 1055a611c69b
Merge
corba/make/src/classes/build/tools/stripproperties/StripPropertiesCorba.java
langtools/test/tools/javac/6464451/BigFinally.java
langtools/test/tools/javac/6464451/DeepNestedFinally.java
langtools/test/tools/javac/6464451/ManyExitsInTry.java
langtools/test/tools/javac/ArrayCloneCodeGen.java
langtools/test/tools/javac/ConditionalClass.java
langtools/test/tools/javac/NoNoClassDefFoundErrorError.java
langtools/test/tools/javac/T6557865.java
langtools/test/tools/javac/annotations/neg/MixedSource.java
langtools/test/tools/javac/boxing/NoBoxingBool.java
langtools/test/tools/javac/boxing/NoBoxingByte.java
langtools/test/tools/javac/boxing/NoBoxingChar.java
langtools/test/tools/javac/boxing/NoBoxingDouble.java
langtools/test/tools/javac/boxing/NoBoxingFloat.java
langtools/test/tools/javac/boxing/NoBoxingInt.java
langtools/test/tools/javac/boxing/NoBoxingLong.java
langtools/test/tools/javac/boxing/NoBoxingShort.java
langtools/test/tools/javac/enum/6384542/T6384542.java
langtools/test/tools/javac/enum/6384542/T6384542.out
langtools/test/tools/javac/enum/6384542/T6384542a.java
langtools/test/tools/javac/enum/6384542/T6384542a_1_4.out
langtools/test/tools/javac/enum/6384542/T6384542a_5.out
langtools/test/tools/javac/enum/EnumAsIdentifier4.out
langtools/test/tools/javac/enum/EnumAsIdentifier5.out
langtools/test/tools/javac/enum/FauxEnum2.java
langtools/test/tools/javac/foreach/T6682380.java
langtools/test/tools/javac/generics/BridgeRestype.java
langtools/test/tools/javac/generics/compat/CovariantCompat1.java
langtools/test/tools/javac/generics/compat/CovariantCompat2.java
langtools/test/tools/javac/generics/compat/OverrideBridge1.java
langtools/test/tools/javac/generics/compat/OverrideBridge2.java
langtools/test/tools/javac/generics/compat/OverrideBridge3.java
langtools/test/tools/javac/generics/compat/VisibleBridge.java
langtools/test/tools/javac/limits/FinallyNesting.java
nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java
--- a/.hgtags	Tue Mar 25 20:32:07 2014 -0400
+++ b/.hgtags	Tue Mar 25 20:32:46 2014 -0400
@@ -246,3 +246,5 @@
 f130ca87de6637acae7d99fcd7a8573eea1cbaed jdk9-b01
 b32e2219736e42baaf45daf0ad67ed34f6033799 jdk9-b02
 7f655f31f9bcee618cf832f08176ad8c1ed3fdd3 jdk9-b03
+099891b1d86f3719e116ac717ffdafc90d037fb7 jdk9-b04
+dd311791ad6895a3989020dd6c6c46db87972ab8 jdk9-b05
--- a/.hgtags-top-repo	Tue Mar 25 20:32:07 2014 -0400
+++ b/.hgtags-top-repo	Tue Mar 25 20:32:46 2014 -0400
@@ -246,3 +246,5 @@
 50669e45cec4491de0d921d3118a3fe2e767020a jdk9-b01
 135f0c7af57ebace31383d8877f47e32172759ff jdk9-b02
 fd8d51bdf9aadf7ae83e65e8655c53581017c363 jdk9-b03
+cb4c3440bc2748101923e2488506e61009ab1bf5 jdk9-b04
+8c63f0b6ada282f27e3a80125e53c3be603f9af7 jdk9-b05
--- a/common/autoconf/boot-jdk.m4	Tue Mar 25 20:32:07 2014 -0400
+++ b/common/autoconf/boot-jdk.m4	Tue Mar 25 20:32:46 2014 -0400
@@ -350,8 +350,23 @@
 
   AC_MSG_CHECKING([flags for boot jdk java command] )
 
+  # Disable special log output when a debug build is used as Boot JDK...
+  ADD_JVM_ARG_IF_OK([-XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput],boot_jdk_jvmargs,[$JAVA])
+
+  # Apply user provided options.
+  ADD_JVM_ARG_IF_OK([$with_boot_jdk_jvmargs],boot_jdk_jvmargs,[$JAVA])
+
+  AC_MSG_RESULT([$boot_jdk_jvmargs])
+
+  # For now, general JAVA_FLAGS are the same as the boot jdk jvmargs
+  JAVA_FLAGS=$boot_jdk_jvmargs
+  AC_SUBST(JAVA_FLAGS)
+
+
+  AC_MSG_CHECKING([flags for boot jdk java command for big workloads])
+
   # Starting amount of heap memory.
-  ADD_JVM_ARG_IF_OK([-Xms64M],boot_jdk_jvmargs,[$JAVA])
+  ADD_JVM_ARG_IF_OK([-Xms64M],boot_jdk_jvmargs_big,[$JAVA])
 
   # Maximum amount of heap memory.
   # Maximum stack size.
@@ -366,20 +381,24 @@
     JVM_MAX_HEAP=1600M
     STACK_SIZE=1536
   fi
-  ADD_JVM_ARG_IF_OK([-Xmx$JVM_MAX_HEAP],boot_jdk_jvmargs,[$JAVA])
-  ADD_JVM_ARG_IF_OK([-XX:ThreadStackSize=$STACK_SIZE],boot_jdk_jvmargs,[$JAVA])
+  ADD_JVM_ARG_IF_OK([-Xmx$JVM_MAX_HEAP],boot_jdk_jvmargs_big,[$JAVA])
+  ADD_JVM_ARG_IF_OK([-XX:ThreadStackSize=$STACK_SIZE],boot_jdk_jvmargs_big,[$JAVA])
+
+  AC_MSG_RESULT([$boot_jdk_jvmargs_big])
 
-  # Disable special log output when a debug build is used as Boot JDK...
-  ADD_JVM_ARG_IF_OK([-XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput],boot_jdk_jvmargs,[$JAVA])
+  JAVA_FLAGS_BIG=$boot_jdk_jvmargs_big
+  AC_SUBST(JAVA_FLAGS_BIG)
 
-  # Apply user provided options.
-  ADD_JVM_ARG_IF_OK([$with_boot_jdk_jvmargs],boot_jdk_jvmargs,[$JAVA])
+
+  AC_MSG_CHECKING([flags for boot jdk java command for small workloads])
 
-  AC_MSG_RESULT([$boot_jdk_jvmargs])
+  # Use serial gc for small short lived tools if possible
+  ADD_JVM_ARG_IF_OK([-XX:+UseSerialGC],boot_jdk_jvmargs_small,[$JAVA])
+  ADD_JVM_ARG_IF_OK([-Xms32M],boot_jdk_jvmargs_small,[$JAVA])
+  ADD_JVM_ARG_IF_OK([-Xmx512M],boot_jdk_jvmargs_small,[$JAVA])
 
-  # For now, general JAVA_FLAGS are the same as the boot jdk jvmargs
-  JAVA_FLAGS=$boot_jdk_jvmargs
+  AC_MSG_RESULT([$boot_jdk_jvmargs_small])
 
-  AC_SUBST(BOOT_JDK_JVMARGS, $boot_jdk_jvmargs)
-  AC_SUBST(JAVA_FLAGS, $JAVA_FLAGS)
+  JAVA_FLAGS_SMALL=$boot_jdk_jvmargs_small
+  AC_SUBST(JAVA_FLAGS_SMALL)
 ])
--- a/common/autoconf/flags.m4	Tue Mar 25 20:32:07 2014 -0400
+++ b/common/autoconf/flags.m4	Tue Mar 25 20:32:46 2014 -0400
@@ -148,6 +148,26 @@
       SET_SHARED_LIBRARY_NAME='-Xlinker -soname=[$]1'
       SET_SHARED_LIBRARY_MAPFILE='-Xlinker -version-script=[$]1'
     fi
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+    PICFLAG=''
+    C_FLAG_REORDER=''
+    CXX_FLAG_REORDER=''
+
+    if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+      # Linking is different on MacOSX
+      SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
+      SET_EXECUTABLE_ORIGIN='-Xlinker -rpath -Xlinker @loader_path/.'
+      SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
+      SET_SHARED_LIBRARY_NAME='-Xlinker -install_name -Xlinker @rpath/[$]1'
+      SET_SHARED_LIBRARY_MAPFILE=''
+    else
+      # Default works for linux, might work on other platforms as well.
+      SHARED_LIBRARY_FLAGS='-shared'
+      SET_EXECUTABLE_ORIGIN='-Xlinker -rpath -Xlinker \$$$$ORIGIN[$]1'
+      SET_SHARED_LIBRARY_ORIGIN="-Xlinker -z -Xlinker origin $SET_EXECUTABLE_ORIGIN"
+      SET_SHARED_LIBRARY_NAME='-Xlinker -soname=[$]1'
+      SET_SHARED_LIBRARY_MAPFILE='-Xlinker -version-script=[$]1'
+    fi
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     PICFLAG="-KPIC"
     C_FLAG_REORDER='-xF'
@@ -242,6 +262,8 @@
   # Generate make dependency files
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
     C_FLAG_DEPS="-MMD -MF"
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+    C_FLAG_DEPS="-MMD -MF"
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     C_FLAG_DEPS="-xMMD -xMF"
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
@@ -260,6 +282,9 @@
       CFLAGS_DEBUG_SYMBOLS="-g"
       CXXFLAGS_DEBUG_SYMBOLS="-g"
     fi
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+    CFLAGS_DEBUG_SYMBOLS="-g"
+    CXXFLAGS_DEBUG_SYMBOLS="-g"
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     CFLAGS_DEBUG_SYMBOLS="-g -xs"
     CXXFLAGS_DEBUG_SYMBOLS="-g0 -xs"
@@ -315,6 +340,20 @@
         C_O_FLAG_NORM="-O2"
         C_O_FLAG_NONE="-O0"
       fi
+    elif test "x$TOOLCHAIN_TYPE" = xclang; then
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        # On MacOSX we optimize for size, something
+        # we should do for all platforms?
+        C_O_FLAG_HIGHEST="-Os"
+        C_O_FLAG_HI="-Os"
+        C_O_FLAG_NORM="-Os"
+        C_O_FLAG_NONE=""
+      else
+        C_O_FLAG_HIGHEST="-O3"
+        C_O_FLAG_HI="-O3"
+        C_O_FLAG_NORM="-O2"
+        C_O_FLAG_NONE="-O0"
+      fi
     elif test "x$TOOLCHAIN_TYPE" = xxlc; then
       C_O_FLAG_HIGHEST="-O3"
       C_O_FLAG_HI="-O3 -qstrict"
--- a/common/autoconf/generated-configure.sh	Tue Mar 25 20:32:07 2014 -0400
+++ b/common/autoconf/generated-configure.sh	Tue Mar 25 20:32:46 2014 -0400
@@ -653,6 +653,9 @@
 LIBM
 LIBZIP_CAN_USE_MMAP
 USE_EXTERNAL_LIBZ
+USE_EXTERNAL_LIBPNG
+PNG_LIBS
+PNG_CFLAGS
 USE_EXTERNAL_LIBGIF
 USE_EXTERNAL_LIBJPEG
 ALSA_LIBS
@@ -793,8 +796,9 @@
 JAXP_TOPDIR
 CORBA_TOPDIR
 LANGTOOLS_TOPDIR
+JAVA_FLAGS_SMALL
+JAVA_FLAGS_BIG
 JAVA_FLAGS
-BOOT_JDK_JVMARGS
 JAVAC_FLAGS
 BOOT_JDK_SOURCETARGET
 JARSIGNER
@@ -1071,6 +1075,7 @@
 with_alsa_include
 with_alsa_lib
 with_giflib
+with_libpng
 with_zlib
 with_stdc__lib
 with_msvcr_dll
@@ -1183,6 +1188,8 @@
 FREETYPE_LIBS
 ALSA_CFLAGS
 ALSA_LIBS
+PNG_CFLAGS
+PNG_LIBS
 LIBFFI_CFLAGS
 LIBFFI_LIBS
 CCACHE'
@@ -1921,6 +1928,8 @@
   --with-alsa-lib         specify directory for the alsa library
   --with-giflib           use giflib from build system or OpenJDK source
                           (system, bundled) [bundled]
+  --with-libpng           use libpng from build system or OpenJDK source
+                          (system, bundled) [bundled]
   --with-zlib             use zlib from build system or OpenJDK source
                           (system, bundled) [bundled]
   --with-stdc++lib=<static>,<dynamic>,<default>
@@ -2045,6 +2054,8 @@
               linker flags for FREETYPE, overriding pkg-config
   ALSA_CFLAGS C compiler flags for ALSA, overriding pkg-config
   ALSA_LIBS   linker flags for ALSA, overriding pkg-config
+  PNG_CFLAGS  C compiler flags for PNG, overriding pkg-config
+  PNG_LIBS    linker flags for PNG, overriding pkg-config
   LIBFFI_CFLAGS
               C compiler flags for LIBFFI, overriding pkg-config
   LIBFFI_LIBS linker flags for LIBFFI, overriding pkg-config
@@ -4221,7 +4232,7 @@
 #CUSTOM_AUTOCONF_INCLUDE
 
 # Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1394011255
+DATE_WHEN_GENERATED=1394794899
 
 ###############################################################################
 #
@@ -25856,67 +25867,6 @@
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking flags for boot jdk java command " >&5
 $as_echo_n "checking flags for boot jdk java command ... " >&6; }
 
-  # Starting amount of heap memory.
-
-  $ECHO "Check if jvm arg is ok: -Xms64M" >&5
-  $ECHO "Command: $JAVA -Xms64M -version" >&5
-  OUTPUT=`$JAVA -Xms64M -version 2>&1`
-  FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
-  FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
-  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
-    boot_jdk_jvmargs="$boot_jdk_jvmargs -Xms64M"
-    JVM_ARG_OK=true
-  else
-    $ECHO "Arg failed:" >&5
-    $ECHO "$OUTPUT" >&5
-    JVM_ARG_OK=false
-  fi
-
-
-  # Maximum amount of heap memory.
-  # Maximum stack size.
-  if test "x$BUILD_NUM_BITS" = x32; then
-    JVM_MAX_HEAP=1100M
-    STACK_SIZE=768
-  else
-    # Running Javac on a JVM on a 64-bit machine, takes more space since 64-bit
-    # pointers are used. Apparently, we need to increase the heap and stack
-    # space for the jvm. More specifically, when running javac to build huge
-    # jdk batch
-    JVM_MAX_HEAP=1600M
-    STACK_SIZE=1536
-  fi
-
-  $ECHO "Check if jvm arg is ok: -Xmx$JVM_MAX_HEAP" >&5
-  $ECHO "Command: $JAVA -Xmx$JVM_MAX_HEAP -version" >&5
-  OUTPUT=`$JAVA -Xmx$JVM_MAX_HEAP -version 2>&1`
-  FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
-  FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
-  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
-    boot_jdk_jvmargs="$boot_jdk_jvmargs -Xmx$JVM_MAX_HEAP"
-    JVM_ARG_OK=true
-  else
-    $ECHO "Arg failed:" >&5
-    $ECHO "$OUTPUT" >&5
-    JVM_ARG_OK=false
-  fi
-
-
-  $ECHO "Check if jvm arg is ok: -XX:ThreadStackSize=$STACK_SIZE" >&5
-  $ECHO "Command: $JAVA -XX:ThreadStackSize=$STACK_SIZE -version" >&5
-  OUTPUT=`$JAVA -XX:ThreadStackSize=$STACK_SIZE -version 2>&1`
-  FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
-  FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
-  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
-    boot_jdk_jvmargs="$boot_jdk_jvmargs -XX:ThreadStackSize=$STACK_SIZE"
-    JVM_ARG_OK=true
-  else
-    $ECHO "Arg failed:" >&5
-    $ECHO "$OUTPUT" >&5
-    JVM_ARG_OK=false
-  fi
-
-
   # Disable special log output when a debug build is used as Boot JDK...
 
   $ECHO "Check if jvm arg is ok: -XX:-PrintVMOptions -XX:-UnlockDiagnosticVMOptions -XX:-LogVMOutput" >&5
@@ -25957,9 +25907,133 @@
   # For now, general JAVA_FLAGS are the same as the boot jdk jvmargs
   JAVA_FLAGS=$boot_jdk_jvmargs
 
-  BOOT_JDK_JVMARGS=$boot_jdk_jvmargs
-
-  JAVA_FLAGS=$JAVA_FLAGS
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking flags for boot jdk java command for big workloads" >&5
+$as_echo_n "checking flags for boot jdk java command for big workloads... " >&6; }
+
+  # Starting amount of heap memory.
+
+  $ECHO "Check if jvm arg is ok: -Xms64M" >&5
+  $ECHO "Command: $JAVA -Xms64M -version" >&5
+  OUTPUT=`$JAVA -Xms64M -version 2>&1`
+  FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+  FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+    boot_jdk_jvmargs_big="$boot_jdk_jvmargs_big -Xms64M"
+    JVM_ARG_OK=true
+  else
+    $ECHO "Arg failed:" >&5
+    $ECHO "$OUTPUT" >&5
+    JVM_ARG_OK=false
+  fi
+
+
+  # Maximum amount of heap memory.
+  # Maximum stack size.
+  if test "x$BUILD_NUM_BITS" = x32; then
+    JVM_MAX_HEAP=1100M
+    STACK_SIZE=768
+  else
+    # Running Javac on a JVM on a 64-bit machine, takes more space since 64-bit
+    # pointers are used. Apparently, we need to increase the heap and stack
+    # space for the jvm. More specifically, when running javac to build huge
+    # jdk batch
+    JVM_MAX_HEAP=1600M
+    STACK_SIZE=1536
+  fi
+
+  $ECHO "Check if jvm arg is ok: -Xmx$JVM_MAX_HEAP" >&5
+  $ECHO "Command: $JAVA -Xmx$JVM_MAX_HEAP -version" >&5
+  OUTPUT=`$JAVA -Xmx$JVM_MAX_HEAP -version 2>&1`
+  FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+  FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+    boot_jdk_jvmargs_big="$boot_jdk_jvmargs_big -Xmx$JVM_MAX_HEAP"
+    JVM_ARG_OK=true
+  else
+    $ECHO "Arg failed:" >&5
+    $ECHO "$OUTPUT" >&5
+    JVM_ARG_OK=false
+  fi
+
+
+  $ECHO "Check if jvm arg is ok: -XX:ThreadStackSize=$STACK_SIZE" >&5
+  $ECHO "Command: $JAVA -XX:ThreadStackSize=$STACK_SIZE -version" >&5
+  OUTPUT=`$JAVA -XX:ThreadStackSize=$STACK_SIZE -version 2>&1`
+  FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+  FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+    boot_jdk_jvmargs_big="$boot_jdk_jvmargs_big -XX:ThreadStackSize=$STACK_SIZE"
+    JVM_ARG_OK=true
+  else
+    $ECHO "Arg failed:" >&5
+    $ECHO "$OUTPUT" >&5
+    JVM_ARG_OK=false
+  fi
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $boot_jdk_jvmargs_big" >&5
+$as_echo "$boot_jdk_jvmargs_big" >&6; }
+
+  JAVA_FLAGS_BIG=$boot_jdk_jvmargs_big
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking flags for boot jdk java command for small workloads" >&5
+$as_echo_n "checking flags for boot jdk java command for small workloads... " >&6; }
+
+  # Use serial gc for small short lived tools if possible
+
+  $ECHO "Check if jvm arg is ok: -XX:+UseSerialGC" >&5
+  $ECHO "Command: $JAVA -XX:+UseSerialGC -version" >&5
+  OUTPUT=`$JAVA -XX:+UseSerialGC -version 2>&1`
+  FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+  FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+    boot_jdk_jvmargs_small="$boot_jdk_jvmargs_small -XX:+UseSerialGC"
+    JVM_ARG_OK=true
+  else
+    $ECHO "Arg failed:" >&5
+    $ECHO "$OUTPUT" >&5
+    JVM_ARG_OK=false
+  fi
+
+
+  $ECHO "Check if jvm arg is ok: -Xms32M" >&5
+  $ECHO "Command: $JAVA -Xms32M -version" >&5
+  OUTPUT=`$JAVA -Xms32M -version 2>&1`
+  FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+  FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+    boot_jdk_jvmargs_small="$boot_jdk_jvmargs_small -Xms32M"
+    JVM_ARG_OK=true
+  else
+    $ECHO "Arg failed:" >&5
+    $ECHO "$OUTPUT" >&5
+    JVM_ARG_OK=false
+  fi
+
+
+  $ECHO "Check if jvm arg is ok: -Xmx512M" >&5
+  $ECHO "Command: $JAVA -Xmx512M -version" >&5
+  OUTPUT=`$JAVA -Xmx512M -version 2>&1`
+  FOUND_WARN=`$ECHO "$OUTPUT" | grep -i warn`
+  FOUND_VERSION=`$ECHO $OUTPUT | grep " version \""`
+  if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
+    boot_jdk_jvmargs_small="$boot_jdk_jvmargs_small -Xmx512M"
+    JVM_ARG_OK=true
+  else
+    $ECHO "Arg failed:" >&5
+    $ECHO "$OUTPUT" >&5
+    JVM_ARG_OK=false
+  fi
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $boot_jdk_jvmargs_small" >&5
+$as_echo "$boot_jdk_jvmargs_small" >&6; }
+
+  JAVA_FLAGS_SMALL=$boot_jdk_jvmargs_small
 
 
 
@@ -26297,8 +26371,28 @@
   # Use indirect variable referencing
   toolchain_var_name=VALID_TOOLCHAINS_$OPENJDK_BUILD_OS
   VALID_TOOLCHAINS=${!toolchain_var_name}
-  # First toolchain type in the list is the default
-  DEFAULT_TOOLCHAIN=${VALID_TOOLCHAINS%% *}
+
+  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    # On Mac OS X, default toolchain to clang after Xcode 5
+    XCODE_VERSION_OUTPUT=`xcodebuild -version 2>&1 | $HEAD -n 1`
+    $ECHO "$XCODE_VERSION_OUTPUT" | $GREP "Xcode " > /dev/null
+    if test $? -ne 0; then
+      as_fn_error $? "Failed to determine Xcode version." "$LINENO" 5
+    fi
+    XCODE_MAJOR_VERSION=`$ECHO $XCODE_VERSION_OUTPUT | \
+        $SED -e 's/^Xcode \([1-9][0-9.]*\)/\1/' | \
+        $CUT -f 1 -d .`
+    { $as_echo "$as_me:${as_lineno-$LINENO}: Xcode major version: $XCODE_MAJOR_VERSION" >&5
+$as_echo "$as_me: Xcode major version: $XCODE_MAJOR_VERSION" >&6;}
+    if test $XCODE_MAJOR_VERSION -ge 5; then
+        DEFAULT_TOOLCHAIN="clang"
+    else
+        DEFAULT_TOOLCHAIN="gcc"
+    fi
+  else
+    # First toolchain type in the list is the default
+    DEFAULT_TOOLCHAIN=${VALID_TOOLCHAINS%% *}
+  fi
 
   if test "x$with_toolchain_type" = xlist; then
     # List all toolchains
@@ -41236,6 +41330,26 @@
       SET_SHARED_LIBRARY_NAME='-Xlinker -soname=$1'
       SET_SHARED_LIBRARY_MAPFILE='-Xlinker -version-script=$1'
     fi
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+    PICFLAG=''
+    C_FLAG_REORDER=''
+    CXX_FLAG_REORDER=''
+
+    if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+      # Linking is different on MacOSX
+      SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
+      SET_EXECUTABLE_ORIGIN='-Xlinker -rpath -Xlinker @loader_path/.'
+      SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
+      SET_SHARED_LIBRARY_NAME='-Xlinker -install_name -Xlinker @rpath/$1'
+      SET_SHARED_LIBRARY_MAPFILE=''
+    else
+      # Default works for linux, might work on other platforms as well.
+      SHARED_LIBRARY_FLAGS='-shared'
+      SET_EXECUTABLE_ORIGIN='-Xlinker -rpath -Xlinker \$$$$ORIGIN$1'
+      SET_SHARED_LIBRARY_ORIGIN="-Xlinker -z -Xlinker origin $SET_EXECUTABLE_ORIGIN"
+      SET_SHARED_LIBRARY_NAME='-Xlinker -soname=$1'
+      SET_SHARED_LIBRARY_MAPFILE='-Xlinker -version-script=$1'
+    fi
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     PICFLAG="-KPIC"
     C_FLAG_REORDER='-xF'
@@ -41297,6 +41411,8 @@
   # Generate make dependency files
   if test "x$TOOLCHAIN_TYPE" = xgcc; then
     C_FLAG_DEPS="-MMD -MF"
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+    C_FLAG_DEPS="-MMD -MF"
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     C_FLAG_DEPS="-xMMD -xMF"
   elif test "x$TOOLCHAIN_TYPE" = xxlc; then
@@ -41315,6 +41431,9 @@
       CFLAGS_DEBUG_SYMBOLS="-g"
       CXXFLAGS_DEBUG_SYMBOLS="-g"
     fi
+  elif test "x$TOOLCHAIN_TYPE" = xclang; then
+    CFLAGS_DEBUG_SYMBOLS="-g"
+    CXXFLAGS_DEBUG_SYMBOLS="-g"
   elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then
     CFLAGS_DEBUG_SYMBOLS="-g -xs"
     CXXFLAGS_DEBUG_SYMBOLS="-g0 -xs"
@@ -41370,6 +41489,20 @@
         C_O_FLAG_NORM="-O2"
         C_O_FLAG_NONE="-O0"
       fi
+    elif test "x$TOOLCHAIN_TYPE" = xclang; then
+      if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+        # On MacOSX we optimize for size, something
+        # we should do for all platforms?
+        C_O_FLAG_HIGHEST="-Os"
+        C_O_FLAG_HI="-Os"
+        C_O_FLAG_NORM="-Os"
+        C_O_FLAG_NONE=""
+      else
+        C_O_FLAG_HIGHEST="-O3"
+        C_O_FLAG_HI="-O3"
+        C_O_FLAG_NORM="-O2"
+        C_O_FLAG_NONE="-O0"
+      fi
     elif test "x$TOOLCHAIN_TYPE" = xxlc; then
       C_O_FLAG_HIGHEST="-O3"
       C_O_FLAG_HI="-O3 -qstrict"
@@ -46791,6 +46924,118 @@
 
   ###############################################################################
   #
+  # Check for the png library
+  #
+
+
+# Check whether --with-libpng was given.
+if test "${with_libpng+set}" = set; then :
+  withval=$with_libpng;
+fi
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for which libpng to use" >&5
+$as_echo_n "checking for which libpng to use... " >&6; }
+
+  # default is bundled
+  DEFAULT_LIBPNG=bundled
+
+  #
+  # if user didn't specify, use DEFAULT_LIBPNG
+  #
+  if test "x${with_libpng}" = "x"; then
+      with_libpng=${DEFAULT_LIBPNG}
+  fi
+
+  if test "x${with_libpng}" = "xbundled"; then
+      USE_EXTERNAL_LIBPNG=false
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: bundled" >&5
+$as_echo "bundled" >&6; }
+  elif test "x${with_libpng}" = "xsystem"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PNG" >&5
+$as_echo_n "checking for PNG... " >&6; }
+
+if test -n "$PNG_CFLAGS"; then
+    pkg_cv_PNG_CFLAGS="$PNG_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpng\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libpng") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_PNG_CFLAGS=`$PKG_CONFIG --cflags "libpng" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$PNG_LIBS"; then
+    pkg_cv_PNG_LIBS="$PNG_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpng\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libpng") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_PNG_LIBS=`$PKG_CONFIG --libs "libpng" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        PNG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libpng" 2>&1`
+        else
+	        PNG_PKG_ERRORS=`$PKG_CONFIG --print-errors "libpng" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$PNG_PKG_ERRORS" >&5
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+                 LIBPNG_FOUND=no
+elif test $pkg_failed = untried; then
+	 LIBPNG_FOUND=no
+else
+	PNG_CFLAGS=$pkg_cv_PNG_CFLAGS
+	PNG_LIBS=$pkg_cv_PNG_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	 LIBPNG_FOUND=yes
+fi
+      if test "x${LIBPNG_FOUND}" = "xyes"; then
+          USE_EXTERNAL_LIBPNG=true
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: system" >&5
+$as_echo "system" >&6; }
+      else
+          { $as_echo "$as_me:${as_lineno-$LINENO}: result: system not found" >&5
+$as_echo "system not found" >&6; }
+          as_fn_error $? "--with-libpng=system specified, but no libpng found!" "$LINENO" 5
+      fi
+  else
+      as_fn_error $? "Invalid value of --with-libpng: ${with_libpng}, use 'system' or 'bundled'" "$LINENO" 5
+  fi
+
+
+  ###############################################################################
+  #
   # Check for the zlib library
   #
 
--- a/common/autoconf/libraries.m4	Tue Mar 25 20:32:07 2014 -0400
+++ b/common/autoconf/libraries.m4	Tue Mar 25 20:32:46 2014 -0400
@@ -654,6 +654,46 @@
 
   ###############################################################################
   #
+  # Check for the png library
+  #
+
+  AC_ARG_WITH(libpng, [AS_HELP_STRING([--with-libpng],
+     [use libpng from build system or OpenJDK source (system, bundled) @<:@bundled@:>@])])
+
+
+  AC_MSG_CHECKING([for which libpng to use])
+
+  # default is bundled
+  DEFAULT_LIBPNG=bundled
+
+  #
+  # if user didn't specify, use DEFAULT_LIBPNG
+  #
+  if test "x${with_libpng}" = "x"; then
+      with_libpng=${DEFAULT_LIBPNG}
+  fi
+
+  if test "x${with_libpng}" = "xbundled"; then
+      USE_EXTERNAL_LIBPNG=false
+      AC_MSG_RESULT([bundled])
+  elif test "x${with_libpng}" = "xsystem"; then
+      PKG_CHECK_MODULES(PNG, libpng,
+                   [ LIBPNG_FOUND=yes ],
+                   [ LIBPNG_FOUND=no ])
+      if test "x${LIBPNG_FOUND}" = "xyes"; then
+          USE_EXTERNAL_LIBPNG=true
+          AC_MSG_RESULT([system])
+      else
+          AC_MSG_RESULT([system not found])
+          AC_MSG_ERROR([--with-libpng=system specified, but no libpng found!])
+      fi
+  else
+      AC_MSG_ERROR([Invalid value of --with-libpng: ${with_libpng}, use 'system' or 'bundled'])
+  fi
+  AC_SUBST(USE_EXTERNAL_LIBPNG)
+
+  ###############################################################################
+  #
   # Check for the zlib library
   #
 
--- a/common/autoconf/spec.gmk.in	Tue Mar 25 20:32:07 2014 -0400
+++ b/common/autoconf/spec.gmk.in	Tue Mar 25 20:32:46 2014 -0400
@@ -254,7 +254,6 @@
 
 # The boot jdk to use
 BOOT_JDK:=@BOOT_JDK@
-BOOT_JDK_JVMARGS:=@BOOT_JDK_JVMARGS@
 BOOT_RTJAR:=@BOOT_RTJAR@
 BOOT_TOOLSJAR=$(BOOT_JDK)/lib/tools.jar
 
@@ -442,8 +441,11 @@
 POST_MCS_CMD:=@POST_MCS_CMD@
 
 JAVA_FLAGS:=@JAVA_FLAGS@
+JAVA_FLAGS_BIG:=@JAVA_FLAGS_BIG@
+JAVA_FLAGS_SMALL:=@JAVA_FLAGS_SMALL@
 
-JAVA=@FIXPATH@ @JAVA@ $(JAVA_FLAGS)
+JAVA=@FIXPATH@ @JAVA@ $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
+JAVA_SMALL=@FIXPATH@ @JAVA@ $(JAVA_FLAGS_SMALL) $(JAVA_FLAGS)
 
 JAVAC:=@FIXPATH@ @JAVAC@
 # Hotspot sets this variable before reading the SPEC when compiling sa-jdi.jar. Avoid
@@ -454,7 +456,7 @@
 
 JAR:=@FIXPATH@ @JAR@
 
-NATIVE2ASCII:=@FIXPATH@ @NATIVE2ASCII@
+NATIVE2ASCII:=@FIXPATH@ @NATIVE2ASCII@ $(addprefix -J, $(JAVA_FLAGS_SMALL))
 
 JARSIGNER:=@FIXPATH@ @JARSIGNER@
 
@@ -645,6 +647,15 @@
 # Read-only single-machine data
 INSTALL_SYSCONFDIR=@sysconfdir@
 
+####################################################
+#
+# Libraries
+#
+
+USE_EXTERNAL_LIBPNG:=@USE_EXTERNAL_LIBPNG@
+PNG_LIBS:=@PNG_LIBS@
+PNG_CFLAGS:=@PNG_CFLAGS@
+
 
 ####################################################
 #
--- a/common/autoconf/toolchain.m4	Tue Mar 25 20:32:07 2014 -0400
+++ b/common/autoconf/toolchain.m4	Tue Mar 25 20:32:46 2014 -0400
@@ -96,8 +96,27 @@
   # Use indirect variable referencing
   toolchain_var_name=VALID_TOOLCHAINS_$OPENJDK_BUILD_OS
   VALID_TOOLCHAINS=${!toolchain_var_name}
-  # First toolchain type in the list is the default
-  DEFAULT_TOOLCHAIN=${VALID_TOOLCHAINS%% *}
+
+  if test "x$OPENJDK_TARGET_OS" = xmacosx; then
+    # On Mac OS X, default toolchain to clang after Xcode 5
+    XCODE_VERSION_OUTPUT=`xcodebuild -version 2>&1 | $HEAD -n 1`
+    $ECHO "$XCODE_VERSION_OUTPUT" | $GREP "Xcode " > /dev/null
+    if test $? -ne 0; then
+      AC_MSG_ERROR([Failed to determine Xcode version.])
+    fi
+    XCODE_MAJOR_VERSION=`$ECHO $XCODE_VERSION_OUTPUT | \
+        $SED -e 's/^Xcode \(@<:@1-9@:>@@<:@0-9.@:>@*\)/\1/' | \
+        $CUT -f 1 -d .`
+    AC_MSG_NOTICE([Xcode major version: $XCODE_MAJOR_VERSION])
+    if test $XCODE_MAJOR_VERSION -ge 5; then
+        DEFAULT_TOOLCHAIN="clang"
+    else
+        DEFAULT_TOOLCHAIN="gcc"
+    fi
+  else
+    # First toolchain type in the list is the default
+    DEFAULT_TOOLCHAIN=${VALID_TOOLCHAINS%% *}
+  fi
   
   if test "x$with_toolchain_type" = xlist; then
     # List all toolchains
--- a/corba/.hgtags	Tue Mar 25 20:32:07 2014 -0400
+++ b/corba/.hgtags	Tue Mar 25 20:32:46 2014 -0400
@@ -246,3 +246,5 @@
 79a8136b18c1c6848f500088f5a4b39f262f082d jdk9-b01
 8394993063135a42b63a94473280399fb2a13aa7 jdk9-b02
 d338b892a13db19b093f85cf5f949a4504e4d31f jdk9-b03
+1ed19de263e1e0772da0269118cdd9deeb9fff04 jdk9-b04
+167c39eb44731a5d66770d0f00e231164653a2ff jdk9-b05
--- a/corba/make/CompileCorba.gmk	Tue Mar 25 20:32:07 2014 -0400
+++ b/corba/make/CompileCorba.gmk	Tue Mar 25 20:32:46 2014 -0400
@@ -45,16 +45,18 @@
         org/omg/PortableInterceptor/UNKNOWN.java \
         com/sun/tools/corba/se/idl/ResourceBundleUtil.java \
         com/sun/corba/se/impl/presentation/rmi/jndi.properties, \
-    COPY := .prp LogStrings.properties, \
+    COPY := .prp, \
+    CLEAN := .properties, \
     BIN := $(CORBA_OUTPUTDIR)/classes, \
     JAR := $(CORBA_OUTPUTDIR)/dist/lib/classes.jar))
 
+# For the interim version, don't bother cleaning the properties.
 $(eval $(call SetupJavaCompilation,BUILD_INTERIM_CORBA, \
     SETUP := GENERATE_OLDBYTECODE, \
     SRC := $(BUILD_CORBA_SRC), \
     EXCLUDES := $(BUILD_CORBA_EXCLUDES), \
     EXCLUDE_FILES := $(BUILD_CORBA_EXCLUDE_FILES), \
-    COPY := $(BUILD_CORBA_COPY), \
+    COPY := $(BUILD_CORBA_COPY) $(BUILD_CORBA_CLEAN), \
     BIN := $(CORBA_OUTPUTDIR)/interim_classes, \
     JAR := $(INTERIM_CORBA_JAR)))
 
@@ -63,7 +65,6 @@
 $(eval $(call SetupZipArchive,ARCHIVE_CORBA_SRC, \
     SRC := $(CORBA_TOPDIR)/src/share/classes $(CORBA_OUTPUTDIR)/gensrc, \
     ZIP := $(CORBA_OUTPUTDIR)/dist/lib/src.zip))
-    JAR := $(CORBA_OUTPUTDIR)/dist/lib/classes.jar))
 
 ################################################################################
 # Create bin.zip containing the corba specific binaries: orb.idl, ir.idl
@@ -81,6 +82,5 @@
 
 ################################################################################
 
-
 all: $(BUILD_CORBA) $(BUILD_INTERIM_CORBA) $(ARCHIVE_CORBA_SRC) \
     $(CORBA_OUTPUTDIR)/dist/lib/bin.zip
--- a/corba/make/GensrcCorba.gmk	Tue Mar 25 20:32:07 2014 -0400
+++ b/corba/make/GensrcCorba.gmk	Tue Mar 25 20:32:46 2014 -0400
@@ -39,9 +39,6 @@
     SRC := $(CORBA_TOPDIR)/make/src/classes, \
     BIN := $(CORBA_OUTPUTDIR)/tools_classes))
 
-TOOL_STRIPPROP_CMD := $(JAVA) -cp $(CORBA_OUTPUTDIR)/tools_classes \
-    build.tools.stripproperties.StripPropertiesCorba
-
 TOOL_LOGUTIL_CMD := $(JAVA) -cp $(CORBA_OUTPUTDIR)/tools_classes \
     build.tools.logutil.MC
 
@@ -230,27 +227,14 @@
 $(BUILD_IDLS): $(BUILD_IDLJ)
 
 ################################################################################
-# Run stripproperties on all sunorb resource files.
+# zh_HK is just a copy of zh_TW
 
-STRIP_PROP_SRC_FILES := $(shell $(FIND) $(CORBA_TOPDIR)/src/share/classes -name "sunorb*.properties")
-STRIP_PROP_FILES := $(patsubst $(CORBA_TOPDIR)/src/share/classes/%, $(CORBA_OUTPUTDIR)/classes/%, \
-    $(STRIP_PROP_SRC_FILES))
-# Simple delivery of zh_HK properties files just copies zh_TW properties files
-STRIP_PROP_SRC_FILE_ZH_TW := $(shell $(FIND) $(CORBA_TOPDIR)/src/share/classes -name "sunorb_zh_TW.properties")
-STRIP_PROP_SRC_FILES += $(STRIP_PROP_SRC_FILE_ZH_TW)
-STRIP_PROP_FILES += $(patsubst $(CORBA_TOPDIR)/src/share/classes/%_zh_TW.properties, \
-    $(CORBA_OUTPUTDIR)/classes/%_zh_HK.properties, $(STRIP_PROP_SRC_FILE_ZH_TW))
-STRIP_PROP_CMDLINE := $(subst _SPACE_, $(SPACE), \
-    $(join $(addprefix -clean_SPACE_, $(STRIP_PROP_SRC_FILES)), \
-    $(addprefix _SPACE_, $(STRIP_PROP_FILES))))
-
-$(CORBA_OUTPUTDIR)/_the.stripped_properties: $(STRIP_PROP_SRC_FILES) \
-    $(BUILD_TOOLS)
-	$(MKDIR) -p $(sort $(dir $(STRIP_PROP_FILES)))
-	$(call ListPathsSafely,STRIP_PROP_CMDLINE,\n, >> $(CORBA_OUTPUTDIR)/_the.strip_prop.cmdline)
-	$(TOOL_STRIPPROP_CMD) @$(CORBA_OUTPUTDIR)/_the.strip_prop.cmdline
-	$(TOUCH) $@
+$(CORBA_OUTPUTDIR)/gensrc/com/sun/corba/se/impl/orbutil/resources/sunorb_zh_HK.properties: \
+    $(CORBA_TOPDIR)/src/share/classes/com/sun/corba/se/impl/orbutil/resources/sunorb_zh_TW.properties
+	$(install-file)
 
 ################################################################################
 
-all: $(BUILD_IDLS) $(CORBA_OUTPUTDIR)/_the.stripped_properties $(LOGWRAPPER_TARGETS)
+all: $(BUILD_IDLS) $(LOGWRAPPER_TARGETS) \
+    $(CORBA_OUTPUTDIR)/gensrc/com/sun/corba/se/impl/orbutil/resources/sunorb_zh_HK.properties
+
--- a/corba/make/src/classes/build/tools/stripproperties/StripPropertiesCorba.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,288 +0,0 @@
-/*
- * Copyright (c) 2001, 2012, 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 build.tools.stripproperties;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedWriter;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * Reads a properties file from standard input and writes an equivalent
- * properties file without comments to standard output.
- */
-public class StripPropertiesCorba {
-
-    private static void error(String msg, Exception e) {
-        System.err.println("ERROR: stripproperties: " + msg);
-        if ( e != null ) {
-            System.err.println("EXCEPTION: " + e.toString());
-            e.printStackTrace();
-        }
-    }
-
-    private static List<String> infiles = new ArrayList<String>();
-    private static List<String> outfiles = new ArrayList<String>();
-
-    private static boolean parseOptions(String args[]) {
-        boolean ok = true;
-
-        for ( int i = 0; i < args.length ; i++ ) {
-            if ( "-clean".equals(args[i]) && i+2 < args.length ) {
-                infiles.add(args[++i]);
-                outfiles.add(args[++i]);
-            } else if ( args[i].charAt(0)=='@') {
-                String filename = args[i].substring(1);
-                FileInputStream finput = null;
-                byte contents[] = null;
-                try {
-                    finput = new FileInputStream(filename);
-                    int byteCount = finput.available();
-                    if ( byteCount <= 0 ) {
-                        error("The @file is empty", null);
-                        ok = false;
-                    } else {
-                        contents = new byte[byteCount];
-                        int bytesRead = finput.read(contents);
-                        if ( byteCount != bytesRead ) {
-                            error("Cannot read all of @file", null);
-                            ok = false;
-                        }
-                    }
-                } catch ( IOException e ) {
-                    error("cannot open " + filename, e);
-                    ok = false;
-                }
-                if ( finput != null ) {
-                    try {
-                        finput.close();
-                    } catch ( IOException e ) {
-                        ok = false;
-                        error("cannot close " + filename, e);
-                    }
-                }
-                if ( ok && contents != null ) {
-                    String tokens[] = (new String(contents)).split("\\s+");
-                    if ( tokens.length > 0 ) {
-                        ok = parseOptions(tokens);
-                    }
-                }
-                if ( !ok ) {
-                    break;
-                }
-            } else {
-                infiles.add(args[i]);
-                outfiles.add(args[i]);
-            }
-        }
-        return ok;
-    }
-
-    private static boolean stripFiles(List<String> infiles, List<String> outfiles) {
-        boolean ok = true;
-        Iterator<String> inIter  = infiles.iterator();
-        Iterator<String> outIter = outfiles.iterator();
-
-        for (; inIter.hasNext(); ) {
-            String infile = inIter.next();
-            String outfile = outIter.next();
-
-            Properties prop = new Properties();
-            InputStream in = null;
-            try {
-                in = new BufferedInputStream(new FileInputStream(infile));
-                prop.load(in);
-            } catch ( FileNotFoundException e ) {
-                error("Cannot access file " + infile, e);
-                ok = false;
-            } catch ( IOException e ) {
-                error("IO exception processing file " + infile, e);
-                ok = false;
-            }
-            if ( in != null ) {
-                try {
-                    in.close();
-                } catch ( IOException e ) {
-                    error("IO exception closing file " + infile, e);
-                    ok = false;
-                }
-            }
-            if ( !ok ) {
-                break;
-            }
-
-            OutputStream out = null;
-            try {
-                out = new FileOutputStream(outfile);
-                storeProperties(prop, out);
-                out.flush();
-            } catch ( IOException e ) {
-                error("IO exception processing file " + outfile, e);
-                ok = false;
-            }
-            if ( out != null ) {
-                try {
-                    out.close();
-                } catch ( IOException e ) {
-                    error("IO exception closing file " + outfile, e);
-                    ok = false;
-                }
-            }
-            if ( !ok ) {
-                break;
-            }
-
-        }
-        return ok;
-    }
-
-    /**
-     * Strip the properties filenames supplied, replacing their contents.
-     * @param args Names of properties files to process and replace contents
-     */
-    public static void main(String args[]) {
-        boolean ok = parseOptions(args);
-        if ( !ok || !stripFiles(infiles, outfiles) ) {
-            System.exit(1);
-        }
-    }
-
-    // --- code below here is adapted from java.util.Properties ---
-
-    private static final String specialSaveChars = "=: \t\r\n\f#!";
-
-    /*
-     * Converts unicodes to encoded &#92;uxxxx
-     * and writes out any of the characters in specialSaveChars
-     * with a preceding slash
-     */
-    private static String saveConvert(String theString, boolean escapeSpace) {
-        int len = theString.length();
-        StringBuffer outBuffer = new StringBuffer(len*2);
-
-        for(int x=0; x<len; x++) {
-            char aChar = theString.charAt(x);
-            switch(aChar) {
-                case ' ':
-                    if (x == 0 || escapeSpace) {
-                        outBuffer.append('\\');
-                    }
-                    outBuffer.append(' ');
-                    break;
-                case '\\':
-                    outBuffer.append('\\');
-                    outBuffer.append('\\');
-                    break;
-                case '\t':
-                    outBuffer.append('\\');
-                    outBuffer.append('t');
-                    break;
-                case '\n':
-                    outBuffer.append('\\');
-                    outBuffer.append('n');
-                    break;
-                case '\r':
-                    outBuffer.append('\\');
-                    outBuffer.append('r');
-                    break;
-                case '\f':
-                    outBuffer.append('\\');
-                    outBuffer.append('f');
-                    break;
-                default:
-                    if ((aChar < 0x0020) || (aChar == 0x007e) || (aChar > 0x00ff)) {
-                        outBuffer.append('\\');
-                        outBuffer.append('u');
-                        outBuffer.append(toHex((aChar >> 12) & 0xF));
-                        outBuffer.append(toHex((aChar >>  8) & 0xF));
-                        outBuffer.append(toHex((aChar >>  4) & 0xF));
-                        outBuffer.append(toHex( aChar        & 0xF));
-                    } else {
-                        if (specialSaveChars.indexOf(aChar) != -1) {
-                            outBuffer.append('\\');
-                        }
-                        outBuffer.append(aChar);
-                    }
-            }
-        }
-        return outBuffer.toString();
-    }
-
-    /**
-     * Writes the content of <code>properties</code> to <code>out</code>.
-     * The format is that of Properties.store with the following modifications:
-     * <ul>
-     * <li>No header or date is written
-     * <li>Latin-1 characters are written as single bytes, not escape sequences
-     * <li>Line breaks are indicated by a single \n independent of platform
-     * <ul>
-     */
-    private static void storeProperties(Properties properties, OutputStream out)
-    throws IOException {
-        BufferedWriter awriter;
-        awriter = new BufferedWriter(new OutputStreamWriter(out, "8859_1"));
-        for (Enumeration<Object> e = properties.keys(); e.hasMoreElements();) {
-            String key = (String)e.nextElement();
-            String val = (String)properties.get(key);
-            key = saveConvert(key, true);
-
-            /* No need to escape embedded and trailing spaces for value, hence
-             * pass false to flag.
-             */
-            val = saveConvert(val, false);
-            writeln(awriter, key + "=" + val);
-        }
-        awriter.flush();
-    }
-
-    private static void writeln(BufferedWriter bw, String s) throws IOException {
-        bw.write(s);
-        bw.write("\n");
-    }
-
-    /**
-     * Convert a nibble to a hex character
-     * @param   nibble  the nibble to convert.
-     */
-    private static char toHex(int nibble) {
-        return hexDigit[(nibble & 0xF)];
-    }
-
-    /** A table of hex digits */
-    private static final char[] hexDigit = {
-        '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
-    };
-}
--- a/hotspot/.hgtags	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/.hgtags	Tue Mar 25 20:32:46 2014 -0400
@@ -406,3 +406,5 @@
 050a626a88951140df874f7b163e304d07b6c296 jdk9-b01
 b188446de75bda5fc52d102cddf242c3ef5ecbdf jdk9-b02
 b2fee789d23f3cdabb3db4e51af43038e5692d3a jdk9-b03
+3812c088b9456ee22c933e88aee1ece71f4e783a jdk9-b04
+bdc5311e1db7598589b77015119b821bf8c828bd jdk9-b05
--- a/hotspot/make/aix/Makefile	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/make/aix/Makefile	Tue Mar 25 20:32:46 2014 -0400
@@ -70,6 +70,10 @@
     FORCE_TIERED=1
   endif
 endif
+# C1 is not ported on ppc64(le), so we cannot build a tiered VM:
+ifneq (,$(filter $(ARCH),ppc64 pp64le))
+  FORCE_TIERED=0
+endif
 
 ifdef LP64
   ifeq ("$(filter $(LP64_ARCH),$(BUILDARCH))","")
--- a/hotspot/make/aix/makefiles/adjust-mflags.sh	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/make/aix/makefiles/adjust-mflags.sh	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 #! /bin/sh
 #
-# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 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
@@ -64,7 +64,7 @@
 	echo "$MFLAGS" \
 	| sed '
 		s/^-/ -/
-		s/ -\([^ 	][^ 	]*\)j/ -\1 -j/
+		s/ -\([^ 	I][^ 	I]*\)j/ -\1 -j/
 		s/ -j[0-9][0-9]*/ -j/
 		s/ -j\([^ 	]\)/ -j -\1/
 		s/ -j/ -j'${HOTSPOT_BUILD_JOBS:-${default_build_jobs}}'/
--- a/hotspot/make/bsd/makefiles/gcc.make	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/make/bsd/makefiles/gcc.make	Tue Mar 25 20:32:46 2014 -0400
@@ -260,7 +260,7 @@
   WARNINGS_ARE_ERRORS += -Wno-empty-body
 endif
 
-WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wformat=2 -Wno-error=format-nonliteral
+WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wformat=2
 
 ifeq ($(USE_CLANG),)
   # Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
--- a/hotspot/make/linux/Makefile	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/make/linux/Makefile	Tue Mar 25 20:32:46 2014 -0400
@@ -66,6 +66,10 @@
     FORCE_TIERED=1
   endif
 endif
+# C1 is not ported on ppc64(le), so we cannot build a tiered VM:
+ifneq (,$(filter $(ARCH),ppc64 pp64le))
+  FORCE_TIERED=0
+endif
 
 ifdef LP64
   ifeq ("$(filter $(LP64_ARCH),$(BUILDARCH))","")
--- a/hotspot/make/linux/makefiles/gcc.make	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/make/linux/makefiles/gcc.make	Tue Mar 25 20:32:46 2014 -0400
@@ -215,7 +215,7 @@
   WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
 endif
 
-WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value -Wformat=2 -Wno-error=format-nonliteral
+WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value -Wformat=2
 
 ifeq ($(USE_CLANG),)
   # Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
--- a/hotspot/make/linux/makefiles/zeroshark.make	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/make/linux/makefiles/zeroshark.make	Tue Mar 25 20:32:46 2014 -0400
@@ -25,6 +25,9 @@
 
 # Setup common to Zero (non-Shark) and Shark versions of VM
 
+# override this from the main file because some version of llvm do not like -Wundef
+WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wunused-function -Wunused-value
+
 # The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
 OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
 # The copied fdlibm routines in sharedRuntimeTrans.o must not be optimized
--- a/hotspot/make/solaris/makefiles/gcc.make	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/make/solaris/makefiles/gcc.make	Tue Mar 25 20:32:46 2014 -0400
@@ -118,7 +118,7 @@
 # Compiler warnings are treated as errors 
 WARNINGS_ARE_ERRORS = -Werror 
 # Enable these warnings. See 'info gcc' about details on these options
-WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef -Wformat=2 -Wno-error=format-nonliteral
+WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef -Wformat=2
 CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
 # Special cases 
 CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))  
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -124,6 +124,7 @@
   }
 };
 
+#if !defined(ABI_ELFv2)
 // A ppc64 function descriptor.
 struct FunctionDescriptor VALUE_OBJ_CLASS_SPEC {
  private:
@@ -161,6 +162,7 @@
     _env   = (address) 0xbad;
   }
 };
+#endif
 
 class Assembler : public AbstractAssembler {
  protected:
@@ -1067,6 +1069,7 @@
   // Emit an address.
   inline address emit_addr(const address addr = NULL);
 
+#if !defined(ABI_ELFv2)
   // Emit a function descriptor with the specified entry point, TOC,
   // and ENV. If the entry point is NULL, the descriptor will point
   // just past the descriptor.
@@ -1074,6 +1077,7 @@
   inline address emit_fd(address entry = NULL,
                          address toc = (address) FunctionDescriptor::friend_toc,
                          address env = (address) FunctionDescriptor::friend_env);
+#endif
 
   /////////////////////////////////////////////////////////////////////////////////////
   // PPC instructions
--- a/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/assembler_ppc.inline.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -55,6 +55,7 @@
   return start;
 }
 
+#if !defined(ABI_ELFv2)
 // Emit a function descriptor with the specified entry point, TOC, and
 // ENV. If the entry point is NULL, the descriptor will point just
 // past the descriptor.
@@ -73,6 +74,7 @@
 
   return (address)fd;
 }
+#endif
 
 // Issue an illegal instruction. 0 is guaranteed to be an illegal instruction.
 inline void Assembler::illtrap() { Assembler::emit_int32(0); }
--- a/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/cppInterpreter_ppc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1136,7 +1136,9 @@
   // (outgoing C args), R3_ARG1 to R10_ARG8, and F1_ARG1 to
   // F13_ARG13.
   __ mr(R3_ARG1, R18_locals);
+#if !defined(ABI_ELFv2)
   __ ld(signature_handler_fd, 0, signature_handler_fd);
+#endif
   __ call_stub(signature_handler_fd);
   // reload method
   __ ld(R19_method, state_(_method));
@@ -1295,8 +1297,13 @@
   // native result acrosss the call. No oop is present
 
   __ mr(R3_ARG1, R16_thread);
+#if defined(ABI_ELFv2)
+  __ call_c(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans),
+            relocInfo::none);
+#else
   __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, JavaThread::check_special_condition_for_native_trans),
             relocInfo::none);
+#endif
   __ bind(sync_check_done);
 
   //=============================================================================
@@ -1346,9 +1353,9 @@
   // notify here, we'll drop it on the floor.
 
   __ notify_method_exit(true/*native method*/,
-                        ilgl /*illegal state (not used for native methods)*/);
-
-
+                        ilgl /*illegal state (not used for native methods)*/,
+                        InterpreterMacroAssembler::NotifyJVMTI,
+                        false /*check_exceptions*/);
 
   //=============================================================================
   // Handle exceptions
@@ -1413,7 +1420,7 @@
   // First, pop to caller's frame.
   __ pop_interpreter_frame(R11_scratch1, R12_scratch2, R21_tmp1  /* set to return pc */, R22_tmp2);
 
-  __ push_frame_abi112(0, R11_scratch1);
+  __ push_frame_reg_args(0, R11_scratch1);
   // Get the address of the exception handler.
   __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
                   R16_thread,
@@ -2545,7 +2552,7 @@
   __ mr(R4_ARG2, R3_ARG1);  // ARG2 := ARG1
 
   // Find the address of the "catch_exception" stub.
-  __ push_frame_abi112(0, R11_scratch1);
+  __ push_frame_reg_args(0, R11_scratch1);
   __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
                   R16_thread,
                   R4_ARG2);
--- a/hotspot/src/cpu/ppc/vm/frame_ppc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/frame_ppc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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,10 +42,6 @@
 #include "runtime/vframeArray.hpp"
 #endif
 
-#ifndef CC_INTERP
-#error "CC_INTERP must be defined on PPC64"
-#endif
-
 #ifdef ASSERT
 void RegisterMap::check_location_valid() {
 }
@@ -89,7 +85,10 @@
 
 frame frame::sender_for_interpreter_frame(RegisterMap *map) const {
   // Pass callers initial_caller_sp as unextended_sp.
-  return frame(sender_sp(), sender_pc(), (intptr_t*)((parent_ijava_frame_abi *)callers_abi())->initial_caller_sp);
+  return frame(sender_sp(), sender_pc(),
+               CC_INTERP_ONLY((intptr_t*)((parent_ijava_frame_abi *)callers_abi())->initial_caller_sp)
+               NOT_CC_INTERP((intptr_t*)get_ijava_state()->sender_sp)
+               );
 }
 
 frame frame::sender_for_compiled_frame(RegisterMap *map) const {
@@ -183,6 +182,9 @@
     interpreterState istate = get_interpreterState();
     address lresult = (address)istate + in_bytes(BytecodeInterpreter::native_lresult_offset());
     address fresult = (address)istate + in_bytes(BytecodeInterpreter::native_fresult_offset());
+#else
+    address lresult = (address)&(get_ijava_state()->lresult);
+    address fresult = (address)&(get_ijava_state()->fresult);
 #endif
 
     switch (method->result_type()) {
@@ -259,7 +261,21 @@
     values.describe(frame_no, (intptr_t*)&(istate->_native_fresult), " native_fresult");
     values.describe(frame_no, (intptr_t*)&(istate->_native_lresult), " native_lresult");
 #else
-    Unimplemented();
+#define DESCRIBE_ADDRESS(name) \
+  values.describe(frame_no, (intptr_t*)&(get_ijava_state()->name), #name);
+
+      DESCRIBE_ADDRESS(method);
+      DESCRIBE_ADDRESS(locals);
+      DESCRIBE_ADDRESS(monitors);
+      DESCRIBE_ADDRESS(cpoolCache);
+      DESCRIBE_ADDRESS(bcp);
+      DESCRIBE_ADDRESS(esp);
+      DESCRIBE_ADDRESS(mdx);
+      DESCRIBE_ADDRESS(top_frame_sp);
+      DESCRIBE_ADDRESS(sender_sp);
+      DESCRIBE_ADDRESS(oop_tmp);
+      DESCRIBE_ADDRESS(lresult);
+      DESCRIBE_ADDRESS(fresult);
 #endif
   }
 }
--- a/hotspot/src/cpu/ppc/vm/frame_ppc.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/frame_ppc.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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,10 +29,6 @@
 #include "runtime/synchronizer.hpp"
 #include "utilities/top.hpp"
 
-#ifndef CC_INTERP
-#error "CC_INTERP must be defined on PPC64"
-#endif
-
   //  C frame layout on PPC-64.
   //
   //  In this figure the stack grows upwards, while memory grows
@@ -50,7 +46,7 @@
   //            [C_FRAME]
   //
   //  C_FRAME:
-  //    0       [ABI_112]
+  //    0       [ABI_REG_ARGS]
   //    112     CARG_9: outgoing arg 9 (arg_1 ... arg_8 via gpr_3 ... gpr_{10})
   //            ...
   //    40+M*8  CARG_M: outgoing arg M (M is the maximum of outgoing args taken over all call sites in the procedure)
@@ -77,7 +73,7 @@
   //    32      reserved
   //    40      space for TOC (=R2) register for next call
   //
-  //  ABI_112:
+  //  ABI_REG_ARGS:
   //    0       [ABI_48]
   //    48      CARG_1: spill slot for outgoing arg 1. used by next callee.
   //    ...     ...
@@ -95,23 +91,25 @@
     log_2_of_alignment_in_bits = 7
   };
 
-  // ABI_48:
-  struct abi_48 {
+  // ABI_MINFRAME:
+  struct abi_minframe {
     uint64_t callers_sp;
     uint64_t cr;                                  //_16
     uint64_t lr;
+#if !defined(ABI_ELFv2)
     uint64_t reserved1;                           //_16
     uint64_t reserved2;
+#endif
     uint64_t toc;                                 //_16
     // nothing to add here!
     // aligned to frame::alignment_in_bytes (16)
   };
 
   enum {
-    abi_48_size = sizeof(abi_48)
+    abi_minframe_size = sizeof(abi_minframe)
   };
 
-  struct abi_112 : abi_48 {
+  struct abi_reg_args : abi_minframe {
     uint64_t carg_1;
     uint64_t carg_2;                              //_16
     uint64_t carg_3;
@@ -124,13 +122,13 @@
   };
 
   enum {
-    abi_112_size = sizeof(abi_112)
+    abi_reg_args_size = sizeof(abi_reg_args)
   };
 
   #define _abi(_component) \
-          (offset_of(frame::abi_112, _component))
+          (offset_of(frame::abi_reg_args, _component))
 
-  struct abi_112_spill : abi_112 {
+  struct abi_reg_args_spill : abi_reg_args {
     // additional spill slots
     uint64_t spill_ret;
     uint64_t spill_fret;                          //_16
@@ -138,11 +136,11 @@
   };
 
   enum {
-    abi_112_spill_size = sizeof(abi_112_spill)
+    abi_reg_args_spill_size = sizeof(abi_reg_args_spill)
   };
 
-  #define _abi_112_spill(_component) \
-          (offset_of(frame::abi_112_spill, _component))
+  #define _abi_reg_args_spill(_component) \
+          (offset_of(frame::abi_reg_args_spill, _component))
 
   // non-volatile GPRs:
 
@@ -195,7 +193,85 @@
   #define _spill_nonvolatiles_neg(_component) \
      (int)(-frame::spill_nonvolatiles_size + offset_of(frame::spill_nonvolatiles, _component))
 
-  //  Frame layout for the Java interpreter on PPC64.
+
+
+#ifndef CC_INTERP
+  //  Frame layout for the Java template interpreter on PPC64.
+  //
+  //  Diffs to the CC_INTERP are marked with 'X'.
+  //
+  //  TOP_IJAVA_FRAME:
+  //
+  //    0       [TOP_IJAVA_FRAME_ABI]
+  //            alignment (optional)
+  //            [operand stack]
+  //            [monitors] (optional)
+  //           X[IJAVA_STATE]
+  //            note: own locals are located in the caller frame.
+  //
+  //  PARENT_IJAVA_FRAME:
+  //
+  //    0       [PARENT_IJAVA_FRAME_ABI]
+  //            alignment (optional)
+  //            [callee's Java result]
+  //            [callee's locals w/o arguments]
+  //            [outgoing arguments]
+  //            [used part of operand stack w/o arguments]
+  //            [monitors]      (optional)
+  //           X[IJAVA_STATE]
+  //
+
+  struct parent_ijava_frame_abi : abi_minframe {
+  };
+
+  enum {
+    parent_ijava_frame_abi_size = sizeof(parent_ijava_frame_abi)
+  };
+
+#define _parent_ijava_frame_abi(_component) \
+        (offset_of(frame::parent_ijava_frame_abi, _component))
+
+  struct top_ijava_frame_abi : abi_reg_args {
+  };
+
+  enum {
+    top_ijava_frame_abi_size = sizeof(top_ijava_frame_abi)
+  };
+
+#define _top_ijava_frame_abi(_component) \
+        (offset_of(frame::top_ijava_frame_abi, _component))
+
+  struct ijava_state {
+#ifdef ASSERT
+    uint64_t ijava_reserved;  // Used for assertion.
+    uint64_t ijava_reserved2; // Inserted for alignment.
+#endif
+    uint64_t method;
+    uint64_t locals;
+    uint64_t monitors;
+    uint64_t cpoolCache;
+    uint64_t bcp;
+    uint64_t esp;
+    uint64_t mdx;
+    uint64_t top_frame_sp; // Maybe define parent_frame_abi and move there.
+    uint64_t sender_sp;
+    // Slots only needed for native calls. Maybe better to move elsewhere.
+    uint64_t oop_tmp;
+    uint64_t lresult;
+    uint64_t fresult;
+    // Aligned to frame::alignment_in_bytes (16).
+  };
+
+  enum {
+    ijava_state_size = sizeof(ijava_state)
+  };
+
+#define _ijava_state_neg(_component) \
+        (int) (-frame::ijava_state_size + offset_of(frame::ijava_state, _component))
+
+#else // CC_INTERP:
+
+  //  Frame layout for the Java C++ interpreter on PPC64.
   //
   //  This frame layout provides a C-like frame for every Java frame.
   //
@@ -242,7 +318,7 @@
   //            [ENTRY_FRAME_LOCALS]
   //
   //  PARENT_IJAVA_FRAME_ABI:
-  //    0       [ABI_48]
+  //    0       [ABI_MINFRAME]
   //            top_frame_sp
   //            initial_caller_sp
   //
@@ -258,7 +334,7 @@
 
   // PARENT_IJAVA_FRAME_ABI
 
-  struct parent_ijava_frame_abi : abi_48 {
+  struct parent_ijava_frame_abi : abi_minframe {
     // SOE registers.
     // C2i adapters spill their top-frame stack-pointer here.
     uint64_t top_frame_sp;                        //      carg_1
@@ -285,7 +361,7 @@
     uint64_t carg_6_unused;                       //_16   carg_6
     uint64_t carg_7_unused;                       //      carg_7
     // Use arg8 for storing frame_manager_lr. The size of
-    // top_ijava_frame_abi must match abi_112.
+    // top_ijava_frame_abi must match abi_reg_args.
     uint64_t frame_manager_lr;                    //_16   carg_8
     // nothing to add here!
     // aligned to frame::alignment_in_bytes (16)
@@ -298,6 +374,8 @@
   #define _top_ijava_frame_abi(_component) \
           (offset_of(frame::top_ijava_frame_abi, _component))
 
+#endif // CC_INTERP
+
   // ENTRY_FRAME
 
   struct entry_frame_locals {
@@ -395,8 +473,8 @@
   intptr_t* fp() const { return _fp; }
 
   // Accessors for ABIs
-  inline abi_48* own_abi()     const { return (abi_48*) _sp; }
-  inline abi_48* callers_abi() const { return (abi_48*) _fp; }
+  inline abi_minframe* own_abi()     const { return (abi_minframe*) _sp; }
+  inline abi_minframe* callers_abi() const { return (abi_minframe*) _fp; }
 
  private:
 
@@ -421,6 +499,14 @@
 #ifdef CC_INTERP
   // Additional interface for interpreter frames:
   inline interpreterState get_interpreterState() const;
+#else
+  inline ijava_state* get_ijava_state() const;
+  // Some convenient register frame setters/getters for deoptimization.
+  inline intptr_t* interpreter_frame_esp() const;
+  inline void interpreter_frame_set_cpcache(ConstantPoolCache* cp);
+  inline void interpreter_frame_set_esp(intptr_t* esp);
+  inline void interpreter_frame_set_top_frame_sp(intptr_t* top_frame_sp);
+  inline void interpreter_frame_set_sender_sp(intptr_t* sender_sp);
 #endif // CC_INTERP
 
   // Size of a monitor in bytes.
--- a/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/frame_ppc.inline.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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
@@ -26,10 +26,6 @@
 #ifndef CPU_PPC_VM_FRAME_PPC_INLINE_HPP
 #define CPU_PPC_VM_FRAME_PPC_INLINE_HPP
 
-#ifndef CC_INTERP
-#error "CC_INTERP must be defined on PPC64"
-#endif
-
 // Inline functions for ppc64 frames:
 
 // Find codeblob and set deopt_state.
@@ -199,6 +195,75 @@
   interpreterState istate = get_interpreterState();
   return &istate->_constants;
 }
+
+#else // !CC_INTERP
+
+// Template Interpreter frame value accessors.
+
+inline frame::ijava_state* frame::get_ijava_state() const {
+  return (ijava_state*) ((uintptr_t)fp() - ijava_state_size);
+}
+
+inline intptr_t** frame::interpreter_frame_locals_addr() const {
+  return (intptr_t**) &(get_ijava_state()->locals);
+}
+inline intptr_t* frame::interpreter_frame_bcx_addr() const {
+  return (intptr_t*) &(get_ijava_state()->bcp);
+}
+inline intptr_t* frame::interpreter_frame_mdx_addr() const {
+  return (intptr_t*) &(get_ijava_state()->mdx);
+}
+// Pointer beyond the "oldest/deepest" BasicObjectLock on stack.
+inline BasicObjectLock* frame::interpreter_frame_monitor_end() const {
+  return (BasicObjectLock *) get_ijava_state()->monitors;
+}
+
+inline BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
+  return (BasicObjectLock *) get_ijava_state();
+}
+
+// SAPJVM ASc 2012-11-21. Return register stack slot addr at which currently interpreted method is found
+inline Method** frame::interpreter_frame_method_addr() const {
+  return (Method**) &(get_ijava_state()->method);
+}
+inline ConstantPoolCache** frame::interpreter_frame_cpoolcache_addr() const {
+  return (ConstantPoolCache**) &(get_ijava_state()->cpoolCache);
+}
+inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const {
+  return (ConstantPoolCache**) &(get_ijava_state()->cpoolCache);
+}
+
+inline oop* frame::interpreter_frame_temp_oop_addr() const {
+  return (oop *) &(get_ijava_state()->oop_tmp);
+}
+inline intptr_t* frame::interpreter_frame_esp() const {
+  return (intptr_t*) get_ijava_state()->esp;
+}
+
+// Convenient setters
+inline void frame::interpreter_frame_set_monitor_end(BasicObjectLock* end)    { get_ijava_state()->monitors = (intptr_t) end;}
+inline void frame::interpreter_frame_set_cpcache(ConstantPoolCache* cp)       { *frame::interpreter_frame_cpoolcache_addr() = cp; }
+inline void frame::interpreter_frame_set_esp(intptr_t* esp)                   { get_ijava_state()->esp = (intptr_t) esp; }
+inline void frame::interpreter_frame_set_top_frame_sp(intptr_t* top_frame_sp) { get_ijava_state()->top_frame_sp = (intptr_t) top_frame_sp; }
+inline void frame::interpreter_frame_set_sender_sp(intptr_t* sender_sp)       { get_ijava_state()->sender_sp = (intptr_t) sender_sp; }
+
+inline intptr_t* frame::interpreter_frame_expression_stack() const {
+  return (intptr_t*)interpreter_frame_monitor_end() - 1;
+}
+
+inline jint frame::interpreter_frame_expression_stack_direction() {
+  return -1;
+}
+
+// top of expression stack
+inline intptr_t* frame::interpreter_frame_tos_address() const {
+  return ((intptr_t*) get_ijava_state()->esp) + Interpreter::stackElementWords;
+}
+
+inline intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
+  return &interpreter_frame_tos_address()[offset];
+}
+
 #endif // CC_INTERP
 
 inline int frame::interpreter_frame_monitor_size() {
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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,6 +29,7 @@
 #include "asm/macroAssembler.inline.hpp"
 #include "interp_masm_ppc_64.hpp"
 #include "interpreter/interpreterRuntime.hpp"
+#include "prims/jvmtiThreadState.hpp"
 
 #ifdef PRODUCT
 #define BLOCK_COMMENT(str) // nothing
@@ -45,6 +46,691 @@
   MacroAssembler::null_check_throw(a, offset, temp_reg, exception_entry);
 }
 
+void InterpreterMacroAssembler::branch_to_entry(address entry, Register Rscratch) {
+  assert(entry, "Entry must have been generated by now");
+  if (is_within_range_of_b(entry, pc())) {
+    b(entry);
+  } else {
+    load_const_optimized(Rscratch, entry, R0);
+    mtctr(Rscratch);
+    bctr();
+  }
+}
+
+#ifndef CC_INTERP
+
+void InterpreterMacroAssembler::dispatch_next(TosState state, int bcp_incr) {
+  Register bytecode = R12_scratch2;
+  if (bcp_incr != 0) {
+    lbzu(bytecode, bcp_incr, R14_bcp);
+  } else {
+    lbz(bytecode, 0, R14_bcp);
+  }
+
+  dispatch_Lbyte_code(state, bytecode, Interpreter::dispatch_table(state));
+}
+
+void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) {
+  // Load current bytecode.
+  Register bytecode = R12_scratch2;
+  lbz(bytecode, 0, R14_bcp);
+  dispatch_Lbyte_code(state, bytecode, table);
+}
+
+// Dispatch code executed in the prolog of a bytecode which does not do it's
+// own dispatch. The dispatch address is computed and placed in R24_dispatch_addr.
+void InterpreterMacroAssembler::dispatch_prolog(TosState state, int bcp_incr) {
+  Register bytecode = R12_scratch2;
+  lbz(bytecode, bcp_incr, R14_bcp);
+
+  load_dispatch_table(R24_dispatch_addr, Interpreter::dispatch_table(state));
+
+  sldi(bytecode, bytecode, LogBytesPerWord);
+  ldx(R24_dispatch_addr, R24_dispatch_addr, bytecode);
+}
+
+// Dispatch code executed in the epilog of a bytecode which does not do it's
+// own dispatch. The dispatch address in R24_dispatch_addr is used for the
+// dispatch.
+void InterpreterMacroAssembler::dispatch_epilog(TosState state, int bcp_incr) {
+  mtctr(R24_dispatch_addr);
+  addi(R14_bcp, R14_bcp, bcp_incr);
+  bctr();
+}
+
+void InterpreterMacroAssembler::check_and_handle_popframe(Register scratch_reg) {
+  assert(scratch_reg != R0, "can't use R0 as scratch_reg here");
+  if (JvmtiExport::can_pop_frame()) {
+    Label L;
+
+    // Check the "pending popframe condition" flag in the current thread.
+    lwz(scratch_reg, in_bytes(JavaThread::popframe_condition_offset()), R16_thread);
+
+    // Initiate popframe handling only if it is not already being
+    // processed. If the flag has the popframe_processing bit set, it
+    // means that this code is called *during* popframe handling - we
+    // don't want to reenter.
+    andi_(R0, scratch_reg, JavaThread::popframe_pending_bit);
+    beq(CCR0, L);
+
+    andi_(R0, scratch_reg, JavaThread::popframe_processing_bit);
+    bne(CCR0, L);
+
+    // Call the Interpreter::remove_activation_preserving_args_entry()
+    // func to get the address of the same-named entrypoint in the
+    // generated interpreter code.
+    call_c(CAST_FROM_FN_PTR(FunctionDescriptor*,
+                            Interpreter::remove_activation_preserving_args_entry),
+           relocInfo::none);
+
+    // Jump to Interpreter::_remove_activation_preserving_args_entry.
+    mtctr(R3_RET);
+    bctr();
+
+    align(32, 12);
+    bind(L);
+  }
+}
+
+void InterpreterMacroAssembler::check_and_handle_earlyret(Register scratch_reg) {
+  const Register Rthr_state_addr = scratch_reg;
+  if (JvmtiExport::can_force_early_return()) {
+    Label Lno_early_ret;
+    ld(Rthr_state_addr, in_bytes(JavaThread::jvmti_thread_state_offset()), R16_thread);
+    cmpdi(CCR0, Rthr_state_addr, 0);
+    beq(CCR0, Lno_early_ret);
+
+    lwz(R0, in_bytes(JvmtiThreadState::earlyret_state_offset()), Rthr_state_addr);
+    cmpwi(CCR0, R0, JvmtiThreadState::earlyret_pending);
+    bne(CCR0, Lno_early_ret);
+
+    // Jump to Interpreter::_earlyret_entry.
+    lwz(R3_ARG1, in_bytes(JvmtiThreadState::earlyret_tos_offset()), Rthr_state_addr);
+    call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry));
+    mtlr(R3_RET);
+    blr();
+
+    align(32, 12);
+    bind(Lno_early_ret);
+  }
+}
+
+void InterpreterMacroAssembler::load_earlyret_value(TosState state, Register Rscratch1) {
+  const Register RjvmtiState = Rscratch1;
+  const Register Rscratch2   = R0;
+
+  ld(RjvmtiState, in_bytes(JavaThread::jvmti_thread_state_offset()), R16_thread);
+  li(Rscratch2, 0);
+
+  switch (state) {
+    case atos: ld(R17_tos, in_bytes(JvmtiThreadState::earlyret_oop_offset()), RjvmtiState);
+               std(Rscratch2, in_bytes(JvmtiThreadState::earlyret_oop_offset()), RjvmtiState);
+               break;
+    case ltos: ld(R17_tos, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState);
+               break;
+    case btos: // fall through
+    case ctos: // fall through
+    case stos: // fall through
+    case itos: lwz(R17_tos, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState);
+               break;
+    case ftos: lfs(F15_ftos, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState);
+               break;
+    case dtos: lfd(F15_ftos, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState);
+               break;
+    case vtos: break;
+    default  : ShouldNotReachHere();
+  }
+
+  // Clean up tos value in the jvmti thread state.
+  std(Rscratch2, in_bytes(JvmtiThreadState::earlyret_value_offset()), RjvmtiState);
+  // Set tos state field to illegal value.
+  li(Rscratch2, ilgl);
+  stw(Rscratch2, in_bytes(JvmtiThreadState::earlyret_tos_offset()), RjvmtiState);
+}
+
+// Common code to dispatch and dispatch_only.
+// Dispatch value in Lbyte_code and increment Lbcp.
+
+void InterpreterMacroAssembler::load_dispatch_table(Register dst, address* table) {
+  address table_base = (address)Interpreter::dispatch_table((TosState)0);
+  intptr_t table_offs = (intptr_t)table - (intptr_t)table_base;
+  if (is_simm16(table_offs)) {
+    addi(dst, R25_templateTableBase, (int)table_offs);
+  } else {
+    load_const_optimized(dst, table, R0);
+  }
+}
+
+void InterpreterMacroAssembler::dispatch_Lbyte_code(TosState state, Register bytecode, address* table, bool verify) {
+  if (verify) {
+    unimplemented("dispatch_Lbyte_code: verify"); // See Sparc Implementation to implement this
+  }
+
+#ifdef FAST_DISPATCH
+  unimplemented("dispatch_Lbyte_code FAST_DISPATCH");
+#else
+  assert_different_registers(bytecode, R11_scratch1);
+
+  // Calc dispatch table address.
+  load_dispatch_table(R11_scratch1, table);
+
+  sldi(R12_scratch2, bytecode, LogBytesPerWord);
+  ldx(R11_scratch1, R11_scratch1, R12_scratch2);
+
+  // Jump off!
+  mtctr(R11_scratch1);
+  bctr();
+#endif
+}
+
+void InterpreterMacroAssembler::load_receiver(Register Rparam_count, Register Rrecv_dst) {
+  sldi(Rrecv_dst, Rparam_count, Interpreter::logStackElementSize);
+  ldx(Rrecv_dst, Rrecv_dst, R15_esp);
+}
+
+// helpers for expression stack
+
+void InterpreterMacroAssembler::pop_i(Register r) {
+  lwzu(r, Interpreter::stackElementSize, R15_esp);
+}
+
+void InterpreterMacroAssembler::pop_ptr(Register r) {
+  ldu(r, Interpreter::stackElementSize, R15_esp);
+}
+
+void InterpreterMacroAssembler::pop_l(Register r) {
+  ld(r, Interpreter::stackElementSize, R15_esp);
+  addi(R15_esp, R15_esp, 2 * Interpreter::stackElementSize);
+}
+
+void InterpreterMacroAssembler::pop_f(FloatRegister f) {
+  lfsu(f, Interpreter::stackElementSize, R15_esp);
+}
+
+void InterpreterMacroAssembler::pop_d(FloatRegister f) {
+  lfd(f, Interpreter::stackElementSize, R15_esp);
+  addi(R15_esp, R15_esp, 2 * Interpreter::stackElementSize);
+}
+
+void InterpreterMacroAssembler::push_i(Register r) {
+  stw(r, 0, R15_esp);
+  addi(R15_esp, R15_esp, - Interpreter::stackElementSize );
+}
+
+void InterpreterMacroAssembler::push_ptr(Register r) {
+  std(r, 0, R15_esp);
+  addi(R15_esp, R15_esp, - Interpreter::stackElementSize );
+}
+
+void InterpreterMacroAssembler::push_l(Register r) {
+  std(r, - Interpreter::stackElementSize, R15_esp);
+  addi(R15_esp, R15_esp, - 2 * Interpreter::stackElementSize );
+}
+
+void InterpreterMacroAssembler::push_f(FloatRegister f) {
+  stfs(f, 0, R15_esp);
+  addi(R15_esp, R15_esp, - Interpreter::stackElementSize );
+}
+
+void InterpreterMacroAssembler::push_d(FloatRegister f)   {
+  stfd(f, - Interpreter::stackElementSize, R15_esp);
+  addi(R15_esp, R15_esp, - 2 * Interpreter::stackElementSize );
+}
+
+void InterpreterMacroAssembler::push_2ptrs(Register first, Register second) {
+  std(first, 0, R15_esp);
+  std(second, -Interpreter::stackElementSize, R15_esp);
+  addi(R15_esp, R15_esp, - 2 * Interpreter::stackElementSize );
+}
+
+void InterpreterMacroAssembler::push_l_pop_d(Register l, FloatRegister d) {
+  std(l, 0, R15_esp);
+  lfd(d, 0, R15_esp);
+}
+
+void InterpreterMacroAssembler::push_d_pop_l(FloatRegister d, Register l) {
+  stfd(d, 0, R15_esp);
+  ld(l, 0, R15_esp);
+}
+
+void InterpreterMacroAssembler::push(TosState state) {
+  switch (state) {
+    case atos: push_ptr();                break;
+    case btos:
+    case ctos:
+    case stos:
+    case itos: push_i();                  break;
+    case ltos: push_l();                  break;
+    case ftos: push_f();                  break;
+    case dtos: push_d();                  break;
+    case vtos: /* nothing to do */        break;
+    default  : ShouldNotReachHere();
+  }
+}
+
+void InterpreterMacroAssembler::pop(TosState state) {
+  switch (state) {
+    case atos: pop_ptr();            break;
+    case btos:
+    case ctos:
+    case stos:
+    case itos: pop_i();              break;
+    case ltos: pop_l();              break;
+    case ftos: pop_f();              break;
+    case dtos: pop_d();              break;
+    case vtos: /* nothing to do */   break;
+    default  : ShouldNotReachHere();
+  }
+  verify_oop(R17_tos, state);
+}
+
+void InterpreterMacroAssembler::empty_expression_stack() {
+  addi(R15_esp, R26_monitor, - Interpreter::stackElementSize);
+}
+
+void InterpreterMacroAssembler::get_2_byte_integer_at_bcp(int         bcp_offset,
+                                                          Register    Rdst,
+                                                          signedOrNot is_signed) {
+  // Read Java big endian format.
+  if (is_signed == Signed) {
+    lha(Rdst, bcp_offset, R14_bcp);
+  } else {
+    lhz(Rdst, bcp_offset, R14_bcp);
+  }
+#if 0
+  assert(Rtmp != Rdst, "need separate temp register");
+  Register Rfirst = Rtmp;
+  lbz(Rfirst, bcp_offset, R14_bcp); // first byte
+  lbz(Rdst, bcp_offset+1, R14_bcp); // second byte
+
+  // Rdst = ((Rfirst<<8) & 0xFF00) | (Rdst &~ 0xFF00)
+  rldimi(/*RA=*/Rdst, /*RS=*/Rfirst, /*sh=*/8, /*mb=*/48);
+  if (is_signed == Signed) {
+    extsh(Rdst, Rdst);
+  }
+#endif
+}
+
+void InterpreterMacroAssembler::get_4_byte_integer_at_bcp(int         bcp_offset,
+                                                          Register    Rdst,
+                                                          signedOrNot is_signed) {
+  // Read Java big endian format.
+  if (bcp_offset & 3) { // Offset unaligned?
+    load_const_optimized(Rdst, bcp_offset);
+    if (is_signed == Signed) {
+      lwax(Rdst, R14_bcp, Rdst);
+    } else {
+      lwzx(Rdst, R14_bcp, Rdst);
+    }
+  } else {
+    if (is_signed == Signed) {
+      lwa(Rdst, bcp_offset, R14_bcp);
+    } else {
+      lwz(Rdst, bcp_offset, R14_bcp);
+    }
+  }
+}
+
+// Load the constant pool cache index from the bytecode stream.
+//
+// Kills / writes:
+//   - Rdst, Rscratch
+void InterpreterMacroAssembler::get_cache_index_at_bcp(Register Rdst, int bcp_offset, size_t index_size) {
+  assert(bcp_offset > 0, "bcp is still pointing to start of bytecode");
+  if (index_size == sizeof(u2)) {
+    get_2_byte_integer_at_bcp(bcp_offset, Rdst, Unsigned);
+  } else if (index_size == sizeof(u4)) {
+    assert(EnableInvokeDynamic, "giant index used only for JSR 292");
+    get_4_byte_integer_at_bcp(bcp_offset, Rdst, Signed);
+    assert(ConstantPool::decode_invokedynamic_index(~123) == 123, "else change next line");
+    nand(Rdst, Rdst, Rdst); // convert to plain index
+  } else if (index_size == sizeof(u1)) {
+    lbz(Rdst, bcp_offset, R14_bcp);
+  } else {
+    ShouldNotReachHere();
+  }
+  // Rdst now contains cp cache index.
+}
+
+void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, int bcp_offset, size_t index_size) {
+  get_cache_index_at_bcp(cache, bcp_offset, index_size);
+  sldi(cache, cache, exact_log2(in_words(ConstantPoolCacheEntry::size()) * BytesPerWord));
+  add(cache, R27_constPoolCache, cache);
+}
+
+// Load object from cpool->resolved_references(index).
+void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result, Register index) {
+  assert_different_registers(result, index);
+  get_constant_pool(result);
+
+  // Convert from field index to resolved_references() index and from
+  // word index to byte offset. Since this is a java object, it can be compressed.
+  Register tmp = index;  // reuse
+  sldi(tmp, index, LogBytesPerHeapOop);
+  // Load pointer for resolved_references[] objArray.
+  ld(result, ConstantPool::resolved_references_offset_in_bytes(), result);
+  // JNIHandles::resolve(result)
+  ld(result, 0, result);
+#ifdef ASSERT
+  Label index_ok;
+  lwa(R0, arrayOopDesc::length_offset_in_bytes(), result);
+  sldi(R0, R0, LogBytesPerHeapOop);
+  cmpd(CCR0, tmp, R0);
+  blt(CCR0, index_ok);
+  stop("resolved reference index out of bounds", 0x09256);
+  bind(index_ok);
+#endif
+  // Add in the index.
+  add(result, tmp, result);
+  load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result);
+}
+
+// Generate a subtype check: branch to ok_is_subtype if sub_klass is
+// a subtype of super_klass. Blows registers Rsub_klass, tmp1, tmp2.
+void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass, Register Rsuper_klass, Register Rtmp1,
+                                                  Register Rtmp2, Register Rtmp3, Label &ok_is_subtype) {
+  // Profile the not-null value's klass.
+  profile_typecheck(Rsub_klass, Rtmp1, Rtmp2);
+  check_klass_subtype(Rsub_klass, Rsuper_klass, Rtmp1, Rtmp2, ok_is_subtype);
+  profile_typecheck_failed(Rtmp1, Rtmp2);
+}
+
+void InterpreterMacroAssembler::generate_stack_overflow_check_with_compare_and_throw(Register Rmem_frame_size, Register Rscratch1) {
+  Label done;
+  sub(Rmem_frame_size, R1_SP, Rmem_frame_size);
+  ld(Rscratch1, thread_(stack_overflow_limit));
+  cmpld(CCR0/*is_stack_overflow*/, Rmem_frame_size, Rscratch1);
+  bgt(CCR0/*is_stack_overflow*/, done);
+
+  // Load target address of the runtime stub.
+  assert(StubRoutines::throw_StackOverflowError_entry() != NULL, "generated in wrong order");
+  load_const_optimized(Rscratch1, (StubRoutines::throw_StackOverflowError_entry()), R0);
+  mtctr(Rscratch1);
+  // Restore caller_sp.
+#ifdef ASSERT
+  ld(Rscratch1, 0, R1_SP);
+  ld(R0, 0, R21_sender_SP);
+  cmpd(CCR0, R0, Rscratch1);
+  asm_assert_eq("backlink", 0x547);
+#endif // ASSERT
+  mr(R1_SP, R21_sender_SP);
+  bctr();
+
+  align(32, 12);
+  bind(done);
+}
+
+// Separate these two to allow for delay slot in middle.
+// These are used to do a test and full jump to exception-throwing code.
+
+// Check that index is in range for array, then shift index by index_shift,
+// and put arrayOop + shifted_index into res.
+// Note: res is still shy of address by array offset into object.
+
+void InterpreterMacroAssembler::index_check_without_pop(Register Rarray, Register Rindex, int index_shift, Register Rtmp, Register Rres) {
+  // Check that index is in range for array, then shift index by index_shift,
+  // and put arrayOop + shifted_index into res.
+  // Note: res is still shy of address by array offset into object.
+  // Kills:
+  //   - Rindex
+  // Writes:
+  //   - Rres: Address that corresponds to the array index if check was successful.
+  verify_oop(Rarray);
+  const Register Rlength   = R0;
+  const Register RsxtIndex = Rtmp;
+  Label LisNull, LnotOOR;
+
+  // Array nullcheck
+  if (!ImplicitNullChecks) {
+    cmpdi(CCR0, Rarray, 0);
+    beq(CCR0, LisNull);
+  } else {
+    null_check_throw(Rarray, arrayOopDesc::length_offset_in_bytes(), /*temp*/RsxtIndex);
+  }
+
+  // Rindex might contain garbage in upper bits (remember that we don't sign extend
+  // during integer arithmetic operations). So kill them and put value into same register
+  // where ArrayIndexOutOfBounds would expect the index in.
+  rldicl(RsxtIndex, Rindex, 0, 32); // zero extend 32 bit -> 64 bit
+
+  // Index check
+  lwz(Rlength, arrayOopDesc::length_offset_in_bytes(), Rarray);
+  cmplw(CCR0, Rindex, Rlength);
+  sldi(RsxtIndex, RsxtIndex, index_shift);
+  blt(CCR0, LnotOOR);
+  load_dispatch_table(Rtmp, (address*)Interpreter::_throw_ArrayIndexOutOfBoundsException_entry);
+  mtctr(Rtmp);
+  bctr();
+
+  if (!ImplicitNullChecks) {
+    bind(LisNull);
+    load_dispatch_table(Rtmp, (address*)Interpreter::_throw_NullPointerException_entry);
+    mtctr(Rtmp);
+    bctr();
+  }
+
+  align(32, 16);
+  bind(LnotOOR);
+
+  // Calc address
+  add(Rres, RsxtIndex, Rarray);
+}
+
+void InterpreterMacroAssembler::index_check(Register array, Register index, int index_shift, Register tmp, Register res) {
+  // pop array
+  pop_ptr(array);
+
+  // check array
+  index_check_without_pop(array, index, index_shift, tmp, res);
+}
+
+void InterpreterMacroAssembler::get_const(Register Rdst) {
+  ld(Rdst, in_bytes(Method::const_offset()), R19_method);
+}
+
+void InterpreterMacroAssembler::get_constant_pool(Register Rdst) {
+  get_const(Rdst);
+  ld(Rdst, in_bytes(ConstMethod::constants_offset()), Rdst);
+}
+
+void InterpreterMacroAssembler::get_constant_pool_cache(Register Rdst) {
+  get_constant_pool(Rdst);
+  ld(Rdst, ConstantPool::cache_offset_in_bytes(), Rdst);
+}
+
+void InterpreterMacroAssembler::get_cpool_and_tags(Register Rcpool, Register Rtags) {
+  get_constant_pool(Rcpool);
+  ld(Rtags, ConstantPool::tags_offset_in_bytes(), Rcpool);
+}
+
+// Unlock if synchronized method.
+//
+// Unlock the receiver if this is a synchronized method.
+// Unlock any Java monitors from synchronized blocks.
+//
+// If there are locked Java monitors
+//   If throw_monitor_exception
+//     throws IllegalMonitorStateException
+//   Else if install_monitor_exception
+//     installs IllegalMonitorStateException
+//   Else
+//     no error processing
+void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
+                                                              bool throw_monitor_exception,
+                                                              bool install_monitor_exception) {
+  Label Lunlocked, Lno_unlock;
+  {
+    Register Rdo_not_unlock_flag = R11_scratch1;
+    Register Raccess_flags       = R12_scratch2;
+
+    // Check if synchronized method or unlocking prevented by
+    // JavaThread::do_not_unlock_if_synchronized flag.
+    lbz(Rdo_not_unlock_flag, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread);
+    lwz(Raccess_flags, in_bytes(Method::access_flags_offset()), R19_method);
+    li(R0, 0);
+    stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread); // reset flag
+
+    push(state);
+
+    // Skip if we don't have to unlock.
+    rldicl_(R0, Raccess_flags, 64-JVM_ACC_SYNCHRONIZED_BIT, 63); // Extract bit and compare to 0.
+    beq(CCR0, Lunlocked);
+
+    cmpwi(CCR0, Rdo_not_unlock_flag, 0);
+    bne(CCR0, Lno_unlock);
+  }
+
+  // Unlock
+  {
+    Register Rmonitor_base = R11_scratch1;
+
+    Label Lunlock;
+    // If it's still locked, everything is ok, unlock it.
+    ld(Rmonitor_base, 0, R1_SP);
+    addi(Rmonitor_base, Rmonitor_base, - (frame::ijava_state_size + frame::interpreter_frame_monitor_size_in_bytes())); // Monitor base
+
+    ld(R0, BasicObjectLock::obj_offset_in_bytes(), Rmonitor_base);
+    cmpdi(CCR0, R0, 0);
+    bne(CCR0, Lunlock);
+
+    // If it's already unlocked, throw exception.
+    if (throw_monitor_exception) {
+      call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_illegal_monitor_state_exception));
+      should_not_reach_here();
+    } else {
+      if (install_monitor_exception) {
+        call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception));
+        b(Lunlocked);
+      }
+    }
+
+    bind(Lunlock);
+    unlock_object(Rmonitor_base);
+  }
+
+  // Check that all other monitors are unlocked. Throw IllegelMonitorState exception if not.
+  bind(Lunlocked);
+  {
+    Label Lexception, Lrestart;
+    Register Rcurrent_obj_addr = R11_scratch1;
+    const int delta = frame::interpreter_frame_monitor_size_in_bytes();
+    assert((delta & LongAlignmentMask) == 0, "sizeof BasicObjectLock must be even number of doublewords");
+
+    bind(Lrestart);
+    // Set up search loop: Calc num of iterations.
+    {
+      Register Riterations = R12_scratch2;
+      Register Rmonitor_base = Rcurrent_obj_addr;
+      ld(Rmonitor_base, 0, R1_SP);
+      addi(Rmonitor_base, Rmonitor_base, - frame::ijava_state_size);  // Monitor base
+
+      subf_(Riterations, R26_monitor, Rmonitor_base);
+      ble(CCR0, Lno_unlock);
+
+      addi(Rcurrent_obj_addr, Rmonitor_base, BasicObjectLock::obj_offset_in_bytes() - frame::interpreter_frame_monitor_size_in_bytes());
+      // Check if any monitor is on stack, bail out if not
+      srdi(Riterations, Riterations, exact_log2(delta));
+      mtctr(Riterations);
+    }
+
+    // The search loop: Look for locked monitors.
+    {
+      const Register Rcurrent_obj = R0;
+      Label Lloop;
+
+      ld(Rcurrent_obj, 0, Rcurrent_obj_addr);
+      addi(Rcurrent_obj_addr, Rcurrent_obj_addr, -delta);
+      bind(Lloop);
+
+      // Check if current entry is used.
+      cmpdi(CCR0, Rcurrent_obj, 0);
+      bne(CCR0, Lexception);
+      // Preload next iteration's compare value.
+      ld(Rcurrent_obj, 0, Rcurrent_obj_addr);
+      addi(Rcurrent_obj_addr, Rcurrent_obj_addr, -delta);
+      bdnz(Lloop);
+    }
+    // Fell through: Everything's unlocked => finish.
+    b(Lno_unlock);
+
+    // An object is still locked => need to throw exception.
+    bind(Lexception);
+    if (throw_monitor_exception) {
+      call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_illegal_monitor_state_exception));
+      should_not_reach_here();
+    } else {
+      // Stack unrolling. Unlock object and if requested, install illegal_monitor_exception.
+      // Unlock does not block, so don't have to worry about the frame.
+      Register Rmonitor_addr = R11_scratch1;
+      addi(Rmonitor_addr, Rcurrent_obj_addr, -BasicObjectLock::obj_offset_in_bytes() + delta);
+      unlock_object(Rmonitor_addr);
+      if (install_monitor_exception) {
+        call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::new_illegal_monitor_state_exception));
+      }
+      b(Lrestart);
+    }
+  }
+
+  align(32, 12);
+  bind(Lno_unlock);
+  pop(state);
+}
+
+// Support function for remove_activation & Co.
+void InterpreterMacroAssembler::merge_frames(Register Rsender_sp, Register return_pc, Register Rscratch1, Register Rscratch2) {
+  // Pop interpreter frame.
+  ld(Rscratch1, 0, R1_SP); // *SP
+  ld(Rsender_sp, _ijava_state_neg(sender_sp), Rscratch1); // top_frame_sp
+  ld(Rscratch2, 0, Rscratch1); // **SP
+#ifdef ASSERT
+  {
+    Label Lok;
+    ld(R0, _ijava_state_neg(ijava_reserved), Rscratch1);
+    cmpdi(CCR0, R0, 0x5afe);
+    beq(CCR0, Lok);
+    stop("frame corrupted (remove activation)", 0x5afe);
+    bind(Lok);
+  }
+#endif
+  if (return_pc!=noreg) {
+    ld(return_pc, _abi(lr), Rscratch1); // LR
+  }
+
+  // Merge top frames.
+  subf(Rscratch1, R1_SP, Rsender_sp); // top_frame_sp - SP
+  stdux(Rscratch2, R1_SP, Rscratch1); // atomically set *(SP = top_frame_sp) = **SP
+}
+
+// Remove activation.
+//
+// Unlock the receiver if this is a synchronized method.
+// Unlock any Java monitors from synchronized blocks.
+// Remove the activation from the stack.
+//
+// If there are locked Java monitors
+//    If throw_monitor_exception
+//       throws IllegalMonitorStateException
+//    Else if install_monitor_exception
+//       installs IllegalMonitorStateException
+//    Else
+//       no error processing
+void InterpreterMacroAssembler::remove_activation(TosState state,
+                                                  bool throw_monitor_exception,
+                                                  bool install_monitor_exception) {
+  unlock_if_synchronized_method(state, throw_monitor_exception, install_monitor_exception);
+
+  // Save result (push state before jvmti call and pop it afterwards) and notify jvmti.
+  notify_method_exit(false, state, NotifyJVMTI, true);
+
+  verify_oop(R17_tos, state);
+  verify_thread();
+
+  merge_frames(/*top_frame_sp*/ R21_sender_SP, /*return_pc*/ R0, R11_scratch1, R12_scratch2);
+  mtlr(R0);
+}
+
+#endif // !CC_INTERP
+
 // Lock object
 //
 // Registers alive
@@ -81,7 +767,6 @@
 
     assert_different_registers(displaced_header, object_mark_addr, current_header, tmp);
 
-
     // markOop displaced_header = obj->mark().set_unlocked();
 
     // Load markOop from object into displaced_header.
@@ -94,7 +779,6 @@
     // Set displaced_header to be (markOop of object | UNLOCK_VALUE).
     ori(displaced_header, displaced_header, markOopDesc::unlocked_value);
 
-
     // monitor->lock()->set_displaced_header(displaced_header);
 
     // Initialize the box (Must happen before we update the object mark!).
@@ -147,7 +831,6 @@
         BasicLock::displaced_header_offset_in_bytes(), monitor);
     b(done);
 
-
     // } else {
     //   // Slow path.
     //   InterpreterRuntime::monitorenter(THREAD, monitor);
@@ -158,7 +841,7 @@
     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorenter),
             monitor, /*check_for_exceptions=*/true CC_INTERP_ONLY(&& false));
     // }
-
+    align(32, 12);
     bind(done);
   }
 }
@@ -173,13 +856,13 @@
 void InterpreterMacroAssembler::unlock_object(Register monitor, bool check_for_exceptions) {
   if (UseHeavyMonitors) {
     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit),
-            monitor, /*check_for_exceptions=*/false);
+            monitor, check_for_exceptions CC_INTERP_ONLY(&& false));
   } else {
 
     // template code:
     //
     // if ((displaced_header = monitor->displaced_header()) == NULL) {
-    //   // Recursive unlock.  Mark the monitor unlocked by setting the object field to NULL.
+    //   // Recursive unlock. Mark the monitor unlocked by setting the object field to NULL.
     //   monitor->set_obj(NULL);
     // } else if (Atomic::cmpxchg_ptr(displaced_header, obj->mark_addr(), monitor) == monitor) {
     //   // We swapped the unlocked mark in displaced_header into the object's mark word.
@@ -221,7 +904,7 @@
     // If we still have a lightweight lock, unlock the object and be done.
 
     // The object address from the monitor is in object.
-    if (!UseBiasedLocking) ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor);
+    if (!UseBiasedLocking) { ld(object, BasicObjectLock::obj_offset_in_bytes(), monitor); }
     addi(object_mark_addr, object, oopDesc::mark_offset_in_bytes());
 
     // We have the displaced header in displaced_header. If the lock is still
@@ -261,6 +944,959 @@
   }
 }
 
+#ifndef CC_INTERP
+
+// Load compiled (i2c) or interpreter entry when calling from interpreted and
+// do the call. Centralized so that all interpreter calls will do the same actions.
+// If jvmti single stepping is on for a thread we must not call compiled code.
+//
+// Input:
+//   - Rtarget_method: method to call
+//   - Rret_addr:      return address
+//   - 2 scratch regs
+//
+void InterpreterMacroAssembler::call_from_interpreter(Register Rtarget_method, Register Rret_addr, Register Rscratch1, Register Rscratch2) {
+  assert_different_registers(Rscratch1, Rscratch2, Rtarget_method, Rret_addr);
+  // Assume we want to go compiled if available.
+  const Register Rtarget_addr = Rscratch1;
+  const Register Rinterp_only = Rscratch2;
+
+  ld(Rtarget_addr, in_bytes(Method::from_interpreted_offset()), Rtarget_method);
+
+  if (JvmtiExport::can_post_interpreter_events()) {
+    lwz(Rinterp_only, in_bytes(JavaThread::interp_only_mode_offset()), R16_thread);
+
+    // JVMTI events, such as single-stepping, are implemented partly by avoiding running
+    // compiled code in threads for which the event is enabled. Check here for
+    // interp_only_mode if these events CAN be enabled.
+    Label done;
+    verify_thread();
+    cmpwi(CCR0, Rinterp_only, 0);
+    beq(CCR0, done);
+    ld(Rtarget_addr, in_bytes(Method::interpreter_entry_offset()), Rtarget_method);
+    align(32, 12);
+    bind(done);
+  }
+
+#ifdef ASSERT
+  {
+    Label Lok;
+    cmpdi(CCR0, Rtarget_addr, 0);
+    bne(CCR0, Lok);
+    stop("null entry point");
+    bind(Lok);
+  }
+#endif // ASSERT
+
+  mr(R21_sender_SP, R1_SP);
+
+  // Calc a precise SP for the call. The SP value we calculated in
+  // generate_fixed_frame() is based on the max_stack() value, so we would waste stack space
+  // if esp is not max. Also, the i2c adapter extends the stack space without restoring
+  // our pre-calced value, so repeating calls via i2c would result in stack overflow.
+  // Since esp already points to an empty slot, we just have to sub 1 additional slot
+  // to meet the abi scratch requirements.
+  // The max_stack pointer will get restored by means of the GR_Lmax_stack local in
+  // the return entry of the interpreter.
+  addi(Rscratch2, R15_esp, Interpreter::stackElementSize - frame::abi_reg_args_size);
+  clrrdi(Rscratch2, Rscratch2, exact_log2(frame::alignment_in_bytes)); // round towards smaller address
+  resize_frame_absolute(Rscratch2, Rscratch2, R0);
+
+  mr_if_needed(R19_method, Rtarget_method);
+  mtctr(Rtarget_addr);
+  mtlr(Rret_addr);
+
+  save_interpreter_state(Rscratch2);
+#ifdef ASSERT
+  ld(Rscratch1, _ijava_state_neg(top_frame_sp), Rscratch2); // Rscratch2 contains fp
+  cmpd(CCR0, R21_sender_SP, Rscratch1);
+  asm_assert_eq("top_frame_sp incorrect", 0x951);
+#endif
+
+  bctr();
+}
+
+// Set the method data pointer for the current bcp.
+void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() {
+  assert(ProfileInterpreter, "must be profiling interpreter");
+  Label get_continue;
+  ld(R28_mdx, in_bytes(Method::method_data_offset()), R19_method);
+  test_method_data_pointer(get_continue);
+  call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), R19_method, R14_bcp);
+
+  addi(R28_mdx, R28_mdx, in_bytes(MethodData::data_offset()));
+  add(R28_mdx, R28_mdx, R3_RET);
+  bind(get_continue);
+}
+
+// Test ImethodDataPtr. If it is null, continue at the specified label.
+void InterpreterMacroAssembler::test_method_data_pointer(Label& zero_continue) {
+  assert(ProfileInterpreter, "must be profiling interpreter");
+  cmpdi(CCR0, R28_mdx, 0);
+  beq(CCR0, zero_continue);
+}
+
+void InterpreterMacroAssembler::verify_method_data_pointer() {
+  assert(ProfileInterpreter, "must be profiling interpreter");
+#ifdef ASSERT
+  Label verify_continue;
+  test_method_data_pointer(verify_continue);
+
+  // If the mdp is valid, it will point to a DataLayout header which is
+  // consistent with the bcp. The converse is highly probable also.
+  lhz(R11_scratch1, in_bytes(DataLayout::bci_offset()), R28_mdx);
+  ld(R12_scratch2, in_bytes(Method::const_offset()), R19_method);
+  addi(R11_scratch1, R11_scratch1, in_bytes(ConstMethod::codes_offset()));
+  add(R11_scratch1, R12_scratch2, R12_scratch2);
+  cmpd(CCR0, R11_scratch1, R14_bcp);
+  beq(CCR0, verify_continue);
+
+  call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp ), R19_method, R14_bcp, R28_mdx);
+
+  bind(verify_continue);
+#endif
+}
+
+void InterpreterMacroAssembler::test_invocation_counter_for_mdp(Register invocation_count,
+                                                                Register Rscratch,
+                                                                Label &profile_continue) {
+  assert(ProfileInterpreter, "must be profiling interpreter");
+  // Control will flow to "profile_continue" if the counter is less than the
+  // limit or if we call profile_method().
+  Label done;
+
+  // If no method data exists, and the counter is high enough, make one.
+  int ipl_offs = load_const_optimized(Rscratch, &InvocationCounter::InterpreterProfileLimit, R0, true);
+  lwz(Rscratch, ipl_offs, Rscratch);
+
+  cmpdi(CCR0, R28_mdx, 0);
+  // Test to see if we should create a method data oop.
+  cmpd(CCR1, Rscratch /* InterpreterProfileLimit */, invocation_count);
+  bne(CCR0, done);
+  bge(CCR1, profile_continue);
+
+  // Build it now.
+  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
+  set_method_data_pointer_for_bcp();
+  b(profile_continue);
+
+  align(32, 12);
+  bind(done);
+}
+
+void InterpreterMacroAssembler::test_backedge_count_for_osr(Register backedge_count, Register branch_bcp, Register Rtmp) {
+  assert_different_registers(backedge_count, Rtmp, branch_bcp);
+  assert(UseOnStackReplacement,"Must UseOnStackReplacement to test_backedge_count_for_osr");
+
+  Label did_not_overflow;
+  Label overflow_with_error;
+
+  int ibbl_offs = load_const_optimized(Rtmp, &InvocationCounter::InterpreterBackwardBranchLimit, R0, true);
+  lwz(Rtmp, ibbl_offs, Rtmp);
+  cmpw(CCR0, backedge_count, Rtmp);
+
+  blt(CCR0, did_not_overflow);
+
+  // When ProfileInterpreter is on, the backedge_count comes from the
+  // methodDataOop, which value does not get reset on the call to
+  // frequency_counter_overflow(). To avoid excessive calls to the overflow
+  // routine while the method is being compiled, add a second test to make sure
+  // the overflow function is called only once every overflow_frequency.
+  if (ProfileInterpreter) {
+    const int overflow_frequency = 1024;
+    li(Rtmp, overflow_frequency-1);
+    andr(Rtmp, Rtmp, backedge_count);
+    cmpwi(CCR0, Rtmp, 0);
+    bne(CCR0, did_not_overflow);
+  }
+
+  // Overflow in loop, pass branch bytecode.
+  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), branch_bcp, true);
+
+  // Was an OSR adapter generated?
+  // O0 = osr nmethod
+  cmpdi(CCR0, R3_RET, 0);
+  beq(CCR0, overflow_with_error);
+
+  // Has the nmethod been invalidated already?
+  lwz(Rtmp, nmethod::entry_bci_offset(), R3_RET);
+  cmpwi(CCR0, Rtmp, InvalidOSREntryBci);
+  beq(CCR0, overflow_with_error);
+
+  // Migrate the interpreter frame off of the stack.
+  // We can use all registers because we will not return to interpreter from this point.
+
+  // Save nmethod.
+  const Register osr_nmethod = R31;
+  mr(osr_nmethod, R3_RET);
+  set_top_ijava_frame_at_SP_as_last_Java_frame(R1_SP, R11_scratch1);
+  call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_begin), R16_thread);
+  reset_last_Java_frame();
+  // OSR buffer is in ARG1
+
+  // Remove the interpreter frame.
+  merge_frames(/*top_frame_sp*/ R21_sender_SP, /*return_pc*/ R0, R11_scratch1, R12_scratch2);
+
+  // Jump to the osr code.
+  ld(R11_scratch1, nmethod::osr_entry_point_offset(), osr_nmethod);
+  mtlr(R0);
+  mtctr(R11_scratch1);
+  bctr();
+
+  align(32, 12);
+  bind(overflow_with_error);
+  bind(did_not_overflow);
+}
+
+// Store a value at some constant offset from the method data pointer.
+void InterpreterMacroAssembler::set_mdp_data_at(int constant, Register value) {
+  assert(ProfileInterpreter, "must be profiling interpreter");
+
+  std(value, constant, R28_mdx);
+}
+
+// Increment the value at some constant offset from the method data pointer.
+void InterpreterMacroAssembler::increment_mdp_data_at(int constant,
+                                                      Register counter_addr,
+                                                      Register Rbumped_count,
+                                                      bool decrement) {
+  // Locate the counter at a fixed offset from the mdp:
+  addi(counter_addr, R28_mdx, constant);
+  increment_mdp_data_at(counter_addr, Rbumped_count, decrement);
+}
+
+// Increment the value at some non-fixed (reg + constant) offset from
+// the method data pointer.
+void InterpreterMacroAssembler::increment_mdp_data_at(Register reg,
+                                                      int constant,
+                                                      Register scratch,
+                                                      Register Rbumped_count,
+                                                      bool decrement) {
+  // Add the constant to reg to get the offset.
+  add(scratch, R28_mdx, reg);
+  // Then calculate the counter address.
+  addi(scratch, scratch, constant);
+  increment_mdp_data_at(scratch, Rbumped_count, decrement);
+}
+
+void InterpreterMacroAssembler::increment_mdp_data_at(Register counter_addr,
+                                                      Register Rbumped_count,
+                                                      bool decrement) {
+  assert(ProfileInterpreter, "must be profiling interpreter");
+
+  // Load the counter.
+  ld(Rbumped_count, 0, counter_addr);
+
+  if (decrement) {
+    // Decrement the register. Set condition codes.
+    addi(Rbumped_count, Rbumped_count, - DataLayout::counter_increment);
+    // Store the decremented counter, if it is still negative.
+    std(Rbumped_count, 0, counter_addr);
+    // Note: add/sub overflow check are not ported, since 64 bit
+    // calculation should never overflow.
+  } else {
+    // Increment the register. Set carry flag.
+    addi(Rbumped_count, Rbumped_count, DataLayout::counter_increment);
+    // Store the incremented counter.
+    std(Rbumped_count, 0, counter_addr);
+  }
+}
+
+// Set a flag value at the current method data pointer position.
+void InterpreterMacroAssembler::set_mdp_flag_at(int flag_constant,
+                                                Register scratch) {
+  assert(ProfileInterpreter, "must be profiling interpreter");
+  // Load the data header.
+  lbz(scratch, in_bytes(DataLayout::flags_offset()), R28_mdx);
+  // Set the flag.
+  ori(scratch, scratch, flag_constant);
+  // Store the modified header.
+  stb(scratch, in_bytes(DataLayout::flags_offset()), R28_mdx);
+}
+
+// Test the location at some offset from the method data pointer.
+// If it is not equal to value, branch to the not_equal_continue Label.
+void InterpreterMacroAssembler::test_mdp_data_at(int offset,
+                                                 Register value,
+                                                 Label& not_equal_continue,
+                                                 Register test_out) {
+  assert(ProfileInterpreter, "must be profiling interpreter");
+
+  ld(test_out, offset, R28_mdx);
+  cmpd(CCR0,  value, test_out);
+  bne(CCR0, not_equal_continue);
+}
+
+// Update the method data pointer by the displacement located at some fixed
+// offset from the method data pointer.
+void InterpreterMacroAssembler::update_mdp_by_offset(int offset_of_disp,
+                                                     Register scratch) {
+  assert(ProfileInterpreter, "must be profiling interpreter");
+
+  ld(scratch, offset_of_disp, R28_mdx);
+  add(R28_mdx, scratch, R28_mdx);
+}
+
+// Update the method data pointer by the displacement located at the
+// offset (reg + offset_of_disp).
+void InterpreterMacroAssembler::update_mdp_by_offset(Register reg,
+                                                     int offset_of_disp,
+                                                     Register scratch) {
+  assert(ProfileInterpreter, "must be profiling interpreter");
+
+  add(scratch, reg, R28_mdx);
+  ld(scratch, offset_of_disp, scratch);
+  add(R28_mdx, scratch, R28_mdx);
+}
+
+// Update the method data pointer by a simple constant displacement.
+void InterpreterMacroAssembler::update_mdp_by_constant(int constant) {
+  assert(ProfileInterpreter, "must be profiling interpreter");
+  addi(R28_mdx, R28_mdx, constant);
+}
+
+// Update the method data pointer for a _ret bytecode whose target
+// was not among our cached targets.
+void InterpreterMacroAssembler::update_mdp_for_ret(TosState state,
+                                                   Register return_bci) {
+  assert(ProfileInterpreter, "must be profiling interpreter");
+
+  push(state);
+  assert(return_bci->is_nonvolatile(), "need to protect return_bci");
+  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret), return_bci);
+  pop(state);
+}
+
+// Increments the backedge counter.
+// Returns backedge counter + invocation counter in Rdst.
+void InterpreterMacroAssembler::increment_backedge_counter(const Register Rcounters, const Register Rdst,
+                                                           const Register Rtmp1, Register Rscratch) {
+  assert(UseCompiler, "incrementing must be useful");
+  assert_different_registers(Rdst, Rtmp1);
+  const Register invocation_counter = Rtmp1;
+  const Register counter = Rdst;
+  // TODO ppc port assert(4 == InvocationCounter::sz_counter(), "unexpected field size.");
+
+  // Load backedge counter.
+  lwz(counter, in_bytes(MethodCounters::backedge_counter_offset()) +
+               in_bytes(InvocationCounter::counter_offset()), Rcounters);
+  // Load invocation counter.
+  lwz(invocation_counter, in_bytes(MethodCounters::invocation_counter_offset()) +
+                          in_bytes(InvocationCounter::counter_offset()), Rcounters);
+
+  // Add the delta to the backedge counter.
+  addi(counter, counter, InvocationCounter::count_increment);
+
+  // Mask the invocation counter.
+  li(Rscratch, InvocationCounter::count_mask_value);
+  andr(invocation_counter, invocation_counter, Rscratch);
+
+  // Store new counter value.
+  stw(counter, in_bytes(MethodCounters::backedge_counter_offset()) +
+               in_bytes(InvocationCounter::counter_offset()), Rcounters);
+  // Return invocation counter + backedge counter.
+  add(counter, counter, invocation_counter);
+}
+
+// Count a taken branch in the bytecodes.
+void InterpreterMacroAssembler::profile_taken_branch(Register scratch, Register bumped_count) {
+  if (ProfileInterpreter) {
+    Label profile_continue;
+
+    // If no method data exists, go to profile_continue.
+    test_method_data_pointer(profile_continue);
+
+    // We are taking a branch. Increment the taken count.
+    increment_mdp_data_at(in_bytes(JumpData::taken_offset()), scratch, bumped_count);
+
+    // The method data pointer needs to be updated to reflect the new target.
+    update_mdp_by_offset(in_bytes(JumpData::displacement_offset()), scratch);
+    bind (profile_continue);
+  }
+}
+
+// Count a not-taken branch in the bytecodes.
+void InterpreterMacroAssembler::profile_not_taken_branch(Register scratch1, Register scratch2) {
+  if (ProfileInterpreter) {
+    Label profile_continue;
+
+    // If no method data exists, go to profile_continue.
+    test_method_data_pointer(profile_continue);
+
+    // We are taking a branch. Increment the not taken count.
+    increment_mdp_data_at(in_bytes(BranchData::not_taken_offset()), scratch1, scratch2);
+
+    // The method data pointer needs to be updated to correspond to the
+    // next bytecode.
+    update_mdp_by_constant(in_bytes(BranchData::branch_data_size()));
+    bind (profile_continue);
+  }
+}
+
+// Count a non-virtual call in the bytecodes.
+void InterpreterMacroAssembler::profile_call(Register scratch1, Register scratch2) {
+  if (ProfileInterpreter) {
+    Label profile_continue;
+
+    // If no method data exists, go to profile_continue.
+    test_method_data_pointer(profile_continue);
+
+    // We are making a call. Increment the count.
+    increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch1, scratch2);
+
+    // The method data pointer needs to be updated to reflect the new target.
+    update_mdp_by_constant(in_bytes(CounterData::counter_data_size()));
+    bind (profile_continue);
+  }
+}
+
+// Count a final call in the bytecodes.
+void InterpreterMacroAssembler::profile_final_call(Register scratch1, Register scratch2) {
+  if (ProfileInterpreter) {
+    Label profile_continue;
+
+    // If no method data exists, go to profile_continue.
+    test_method_data_pointer(profile_continue);
+
+    // We are making a call. Increment the count.
+    increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch1, scratch2);
+
+    // The method data pointer needs to be updated to reflect the new target.
+    update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size()));
+    bind (profile_continue);
+  }
+}
+
+// Count a virtual call in the bytecodes.
+void InterpreterMacroAssembler::profile_virtual_call(Register Rreceiver,
+                                                     Register Rscratch1,
+                                                     Register Rscratch2,
+                                                     bool receiver_can_be_null) {
+  if (!ProfileInterpreter) { return; }
+  Label profile_continue;
+
+  // If no method data exists, go to profile_continue.
+  test_method_data_pointer(profile_continue);
+
+  Label skip_receiver_profile;
+  if (receiver_can_be_null) {
+    Label not_null;
+    cmpdi(CCR0, Rreceiver, 0);
+    bne(CCR0, not_null);
+    // We are making a call. Increment the count for null receiver.
+    increment_mdp_data_at(in_bytes(CounterData::count_offset()), Rscratch1, Rscratch2);
+    b(skip_receiver_profile);
+    bind(not_null);
+  }
+
+  // Record the receiver type.
+  record_klass_in_profile(Rreceiver, Rscratch1, Rscratch2, true);
+  bind(skip_receiver_profile);
+
+  // The method data pointer needs to be updated to reflect the new target.
+  update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size()));
+  bind (profile_continue);
+}
+
+void InterpreterMacroAssembler::profile_typecheck(Register Rklass, Register Rscratch1, Register Rscratch2) {
+  if (ProfileInterpreter) {
+    Label profile_continue;
+
+    // If no method data exists, go to profile_continue.
+    test_method_data_pointer(profile_continue);
+
+    int mdp_delta = in_bytes(BitData::bit_data_size());
+    if (TypeProfileCasts) {
+      mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
+
+      // Record the object type.
+      record_klass_in_profile(Rklass, Rscratch1, Rscratch2, false);
+    }
+
+    // The method data pointer needs to be updated.
+    update_mdp_by_constant(mdp_delta);
+
+    bind (profile_continue);
+  }
+}
+
+void InterpreterMacroAssembler::profile_typecheck_failed(Register Rscratch1, Register Rscratch2) {
+  if (ProfileInterpreter && TypeProfileCasts) {
+    Label profile_continue;
+
+    // If no method data exists, go to profile_continue.
+    test_method_data_pointer(profile_continue);
+
+    int count_offset = in_bytes(CounterData::count_offset());
+    // Back up the address, since we have already bumped the mdp.
+    count_offset -= in_bytes(VirtualCallData::virtual_call_data_size());
+
+    // *Decrement* the counter. We expect to see zero or small negatives.
+    increment_mdp_data_at(count_offset, Rscratch1, Rscratch2, true);
+
+    bind (profile_continue);
+  }
+}
+
+// Count a ret in the bytecodes.
+void InterpreterMacroAssembler::profile_ret(TosState state, Register return_bci, Register scratch1, Register scratch2) {
+  if (ProfileInterpreter) {
+    Label profile_continue;
+    uint row;
+
+    // If no method data exists, go to profile_continue.
+    test_method_data_pointer(profile_continue);
+
+    // Update the total ret count.
+    increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch1, scratch2 );
+
+    for (row = 0; row < RetData::row_limit(); row++) {
+      Label next_test;
+
+      // See if return_bci is equal to bci[n]:
+      test_mdp_data_at(in_bytes(RetData::bci_offset(row)), return_bci, next_test, scratch1);
+
+      // return_bci is equal to bci[n]. Increment the count.
+      increment_mdp_data_at(in_bytes(RetData::bci_count_offset(row)), scratch1, scratch2);
+
+      // The method data pointer needs to be updated to reflect the new target.
+      update_mdp_by_offset(in_bytes(RetData::bci_displacement_offset(row)), scratch1);
+      b(profile_continue);
+      bind(next_test);
+    }
+
+    update_mdp_for_ret(state, return_bci);
+
+    bind (profile_continue);
+  }
+}
+
+// Count the default case of a switch construct.
+void InterpreterMacroAssembler::profile_switch_default(Register scratch1,  Register scratch2) {
+  if (ProfileInterpreter) {
+    Label profile_continue;
+
+    // If no method data exists, go to profile_continue.
+    test_method_data_pointer(profile_continue);
+
+    // Update the default case count
+    increment_mdp_data_at(in_bytes(MultiBranchData::default_count_offset()),
+                          scratch1, scratch2);
+
+    // The method data pointer needs to be updated.
+    update_mdp_by_offset(in_bytes(MultiBranchData::default_displacement_offset()),
+                         scratch1);
+
+    bind (profile_continue);
+  }
+}
+
+// Count the index'th case of a switch construct.
+void InterpreterMacroAssembler::profile_switch_case(Register index,
+                                                    Register scratch1,
+                                                    Register scratch2,
+                                                    Register scratch3) {
+  if (ProfileInterpreter) {
+    assert_different_registers(index, scratch1, scratch2, scratch3);
+    Label profile_continue;
+
+    // If no method data exists, go to profile_continue.
+    test_method_data_pointer(profile_continue);
+
+    // Build the base (index * per_case_size_in_bytes()) + case_array_offset_in_bytes().
+    li(scratch3, in_bytes(MultiBranchData::case_array_offset()));
+
+    assert (in_bytes(MultiBranchData::per_case_size()) == 16, "so that shladd works");
+    sldi(scratch1, index, exact_log2(in_bytes(MultiBranchData::per_case_size())));
+    add(scratch1, scratch1, scratch3);
+
+    // Update the case count.
+    increment_mdp_data_at(scratch1, in_bytes(MultiBranchData::relative_count_offset()), scratch2, scratch3);
+
+    // The method data pointer needs to be updated.
+    update_mdp_by_offset(scratch1, in_bytes(MultiBranchData::relative_displacement_offset()), scratch2);
+
+    bind (profile_continue);
+  }
+}
+
+void InterpreterMacroAssembler::profile_null_seen(Register Rscratch1, Register Rscratch2) {
+  if (ProfileInterpreter) {
+    assert_different_registers(Rscratch1, Rscratch2);
+    Label profile_continue;
+
+    // If no method data exists, go to profile_continue.
+    test_method_data_pointer(profile_continue);
+
+    set_mdp_flag_at(BitData::null_seen_byte_constant(), Rscratch1);
+
+    // The method data pointer needs to be updated.
+    int mdp_delta = in_bytes(BitData::bit_data_size());
+    if (TypeProfileCasts) {
+      mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
+    }
+    update_mdp_by_constant(mdp_delta);
+
+    bind (profile_continue);
+  }
+}
+
+void InterpreterMacroAssembler::record_klass_in_profile(Register Rreceiver,
+                                                        Register Rscratch1, Register Rscratch2,
+                                                        bool is_virtual_call) {
+  assert(ProfileInterpreter, "must be profiling");
+  assert_different_registers(Rreceiver, Rscratch1, Rscratch2);
+
+  Label done;
+  record_klass_in_profile_helper(Rreceiver, Rscratch1, Rscratch2, 0, done, is_virtual_call);
+  bind (done);
+}
+
+void InterpreterMacroAssembler::record_klass_in_profile_helper(
+                                        Register receiver, Register scratch1, Register scratch2,
+                                        int start_row, Label& done, bool is_virtual_call) {
+  if (TypeProfileWidth == 0) {
+    if (is_virtual_call) {
+      increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch1, scratch2);
+    }
+    return;
+  }
+
+  int last_row = VirtualCallData::row_limit() - 1;
+  assert(start_row <= last_row, "must be work left to do");
+  // Test this row for both the receiver and for null.
+  // Take any of three different outcomes:
+  //   1. found receiver => increment count and goto done
+  //   2. found null => keep looking for case 1, maybe allocate this cell
+  //   3. found something else => keep looking for cases 1 and 2
+  // Case 3 is handled by a recursive call.
+  for (int row = start_row; row <= last_row; row++) {
+    Label next_test;
+    bool test_for_null_also = (row == start_row);
+
+    // See if the receiver is receiver[n].
+    int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row));
+    test_mdp_data_at(recvr_offset, receiver, next_test, scratch1);
+    // delayed()->tst(scratch);
+
+    // The receiver is receiver[n]. Increment count[n].
+    int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row));
+    increment_mdp_data_at(count_offset, scratch1, scratch2);
+    b(done);
+    bind(next_test);
+
+    if (test_for_null_also) {
+      Label found_null;
+      // Failed the equality check on receiver[n]... Test for null.
+      if (start_row == last_row) {
+        // The only thing left to do is handle the null case.
+        if (is_virtual_call) {
+          // Scratch1 contains test_out from test_mdp_data_at.
+          cmpdi(CCR0, scratch1, 0);
+          beq(CCR0, found_null);
+          // Receiver did not match any saved receiver and there is no empty row for it.
+          // Increment total counter to indicate polymorphic case.
+          increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch1, scratch2);
+          b(done);
+          bind(found_null);
+        } else {
+          cmpdi(CCR0, scratch1, 0);
+          bne(CCR0, done);
+        }
+        break;
+      }
+      // Since null is rare, make it be the branch-taken case.
+      cmpdi(CCR0, scratch1, 0);
+      beq(CCR0, found_null);
+
+      // Put all the "Case 3" tests here.
+      record_klass_in_profile_helper(receiver, scratch1, scratch2, start_row + 1, done, is_virtual_call);
+
+      // Found a null. Keep searching for a matching receiver,
+      // but remember that this is an empty (unused) slot.
+      bind(found_null);
+    }
+  }
+
+  // In the fall-through case, we found no matching receiver, but we
+  // observed the receiver[start_row] is NULL.
+
+  // Fill in the receiver field and increment the count.
+  int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row));
+  set_mdp_data_at(recvr_offset, receiver);
+  int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row));
+  li(scratch1, DataLayout::counter_increment);
+  set_mdp_data_at(count_offset, scratch1);
+  if (start_row > 0) {
+    b(done);
+  }
+}
+
+// Add a InterpMonitorElem to stack (see frame_sparc.hpp).
+void InterpreterMacroAssembler::add_monitor_to_stack(bool stack_is_empty, Register Rtemp1, Register Rtemp2) {
+
+  // Very-local scratch registers.
+  const Register esp  = Rtemp1;
+  const Register slot = Rtemp2;
+
+  // Extracted monitor_size.
+  int monitor_size = frame::interpreter_frame_monitor_size_in_bytes();
+  assert(Assembler::is_aligned((unsigned int)monitor_size,
+                               (unsigned int)frame::alignment_in_bytes),
+         "size of a monitor must respect alignment of SP");
+
+  resize_frame(-monitor_size, /*temp*/esp); // Allocate space for new monitor
+  std(R1_SP, _ijava_state_neg(top_frame_sp), esp); // esp contains fp
+
+  // Shuffle expression stack down. Recall that stack_base points
+  // just above the new expression stack bottom. Old_tos and new_tos
+  // are used to scan thru the old and new expression stacks.
+  if (!stack_is_empty) {
+    Label copy_slot, copy_slot_finished;
+    const Register n_slots = slot;
+
+    addi(esp, R15_esp, Interpreter::stackElementSize); // Point to first element (pre-pushed stack).
+    subf(n_slots, esp, R26_monitor);
+    srdi_(n_slots, n_slots, LogBytesPerWord);          // Compute number of slots to copy.
+    assert(LogBytesPerWord == 3, "conflicts assembler instructions");
+    beq(CCR0, copy_slot_finished);                     // Nothing to copy.
+
+    mtctr(n_slots);
+
+    // loop
+    bind(copy_slot);
+    ld(slot, 0, esp);              // Move expression stack down.
+    std(slot, -monitor_size, esp); // distance = monitor_size
+    addi(esp, esp, BytesPerWord);
+    bdnz(copy_slot);
+
+    bind(copy_slot_finished);
+  }
+
+  addi(R15_esp, R15_esp, -monitor_size);
+  addi(R26_monitor, R26_monitor, -monitor_size);
+
+  // Restart interpreter
+}
+
+// ============================================================================
+// Java locals access
+
+// Load a local variable at index in Rindex into register Rdst_value.
+// Also puts address of local into Rdst_address as a service.
+// Kills:
+//   - Rdst_value
+//   - Rdst_address
+void InterpreterMacroAssembler::load_local_int(Register Rdst_value, Register Rdst_address, Register Rindex) {
+  sldi(Rdst_address, Rindex, Interpreter::logStackElementSize);
+  subf(Rdst_address, Rdst_address, R18_locals);
+  lwz(Rdst_value, 0, Rdst_address);
+}
+
+// Load a local variable at index in Rindex into register Rdst_value.
+// Also puts address of local into Rdst_address as a service.
+// Kills:
+//   - Rdst_value
+//   - Rdst_address
+void InterpreterMacroAssembler::load_local_long(Register Rdst_value, Register Rdst_address, Register Rindex) {
+  sldi(Rdst_address, Rindex, Interpreter::logStackElementSize);
+  subf(Rdst_address, Rdst_address, R18_locals);
+  ld(Rdst_value, -8, Rdst_address);
+}
+
+// Load a local variable at index in Rindex into register Rdst_value.
+// Also puts address of local into Rdst_address as a service.
+// Input:
+//   - Rindex:      slot nr of local variable
+// Kills:
+//   - Rdst_value
+//   - Rdst_address
+void InterpreterMacroAssembler::load_local_ptr(Register Rdst_value, Register Rdst_address, Register Rindex) {
+  sldi(Rdst_address, Rindex, Interpreter::logStackElementSize);
+  subf(Rdst_address, Rdst_address, R18_locals);
+  ld(Rdst_value, 0, Rdst_address);
+}
+
+// Load a local variable at index in Rindex into register Rdst_value.
+// Also puts address of local into Rdst_address as a service.
+// Kills:
+//   - Rdst_value
+//   - Rdst_address
+void InterpreterMacroAssembler::load_local_float(FloatRegister Rdst_value, Register Rdst_address, Register Rindex) {
+  sldi(Rdst_address, Rindex, Interpreter::logStackElementSize);
+  subf(Rdst_address, Rdst_address, R18_locals);
+  lfs(Rdst_value, 0, Rdst_address);
+}
+
+// Load a local variable at index in Rindex into register Rdst_value.
+// Also puts address of local into Rdst_address as a service.
+// Kills:
+//   - Rdst_value
+//   - Rdst_address
+void InterpreterMacroAssembler::load_local_double(FloatRegister Rdst_value, Register Rdst_address, Register Rindex) {
+  sldi(Rdst_address, Rindex, Interpreter::logStackElementSize);
+  subf(Rdst_address, Rdst_address, R18_locals);
+  lfd(Rdst_value, -8, Rdst_address);
+}
+
+// Store an int value at local variable slot Rindex.
+// Kills:
+//   - Rindex
+void InterpreterMacroAssembler::store_local_int(Register Rvalue, Register Rindex) {
+  sldi(Rindex, Rindex, Interpreter::logStackElementSize);
+  subf(Rindex, Rindex, R18_locals);
+  stw(Rvalue, 0, Rindex);
+}
+
+// Store a long value at local variable slot Rindex.
+// Kills:
+//   - Rindex
+void InterpreterMacroAssembler::store_local_long(Register Rvalue, Register Rindex) {
+  sldi(Rindex, Rindex, Interpreter::logStackElementSize);
+  subf(Rindex, Rindex, R18_locals);
+  std(Rvalue, -8, Rindex);
+}
+
+// Store an oop value at local variable slot Rindex.
+// Kills:
+//   - Rindex
+void InterpreterMacroAssembler::store_local_ptr(Register Rvalue, Register Rindex) {
+  sldi(Rindex, Rindex, Interpreter::logStackElementSize);
+  subf(Rindex, Rindex, R18_locals);
+  std(Rvalue, 0, Rindex);
+}
+
+// Store an int value at local variable slot Rindex.
+// Kills:
+//   - Rindex
+void InterpreterMacroAssembler::store_local_float(FloatRegister Rvalue, Register Rindex) {
+  sldi(Rindex, Rindex, Interpreter::logStackElementSize);
+  subf(Rindex, Rindex, R18_locals);
+  stfs(Rvalue, 0, Rindex);
+}
+
+// Store an int value at local variable slot Rindex.
+// Kills:
+//   - Rindex
+void InterpreterMacroAssembler::store_local_double(FloatRegister Rvalue, Register Rindex) {
+  sldi(Rindex, Rindex, Interpreter::logStackElementSize);
+  subf(Rindex, Rindex, R18_locals);
+  stfd(Rvalue, -8, Rindex);
+}
+
+// Read pending exception from thread and jump to interpreter.
+// Throw exception entry if one if pending. Fall through otherwise.
+void InterpreterMacroAssembler::check_and_forward_exception(Register Rscratch1, Register Rscratch2) {
+  assert_different_registers(Rscratch1, Rscratch2, R3);
+  Register Rexception = Rscratch1;
+  Register Rtmp       = Rscratch2;
+  Label Ldone;
+  // Get pending exception oop.
+  ld(Rexception, thread_(pending_exception));
+  cmpdi(CCR0, Rexception, 0);
+  beq(CCR0, Ldone);
+  li(Rtmp, 0);
+  mr_if_needed(R3, Rexception);
+  std(Rtmp, thread_(pending_exception)); // Clear exception in thread
+  if (Interpreter::rethrow_exception_entry() != NULL) {
+    // Already got entry address.
+    load_dispatch_table(Rtmp, (address*)Interpreter::rethrow_exception_entry());
+  } else {
+    // Dynamically load entry address.
+    int simm16_rest = load_const_optimized(Rtmp, &Interpreter::_rethrow_exception_entry, R0, true);
+    ld(Rtmp, simm16_rest, Rtmp);
+  }
+  mtctr(Rtmp);
+  save_interpreter_state(Rtmp);
+  bctr();
+
+  align(32, 12);
+  bind(Ldone);
+}
+
+void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point, bool check_exceptions) {
+  save_interpreter_state(R11_scratch1);
+
+  MacroAssembler::call_VM(oop_result, entry_point, false);
+
+  restore_interpreter_state(R11_scratch1, /*bcp_and_mdx_only*/ true);
+
+  check_and_handle_popframe(R11_scratch1);
+  check_and_handle_earlyret(R11_scratch1);
+  // Now check exceptions manually.
+  if (check_exceptions) {
+    check_and_forward_exception(R11_scratch1, R12_scratch2);
+  }
+}
+
+void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions) {
+  // ARG1 is reserved for the thread.
+  mr_if_needed(R4_ARG2, arg_1);
+  call_VM(oop_result, entry_point, check_exceptions);
+}
+
+void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions) {
+  // ARG1 is reserved for the thread.
+  mr_if_needed(R4_ARG2, arg_1);
+  assert(arg_2 != R4_ARG2, "smashed argument");
+  mr_if_needed(R5_ARG3, arg_2);
+  call_VM(oop_result, entry_point, check_exceptions);
+}
+
+void InterpreterMacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions) {
+  // ARG1 is reserved for the thread.
+  mr_if_needed(R4_ARG2, arg_1);
+  assert(arg_2 != R4_ARG2, "smashed argument");
+  mr_if_needed(R5_ARG3, arg_2);
+  assert(arg_3 != R4_ARG2 && arg_3 != R5_ARG3, "smashed argument");
+  mr_if_needed(R6_ARG4, arg_3);
+  call_VM(oop_result, entry_point, check_exceptions);
+}
+
+void InterpreterMacroAssembler::save_interpreter_state(Register scratch) {
+  ld(scratch, 0, R1_SP);
+  std(R15_esp, _ijava_state_neg(esp), scratch);
+  std(R14_bcp, _ijava_state_neg(bcp), scratch);
+  std(R26_monitor, _ijava_state_neg(monitors), scratch);
+  if (ProfileInterpreter) { std(R28_mdx, _ijava_state_neg(mdx), scratch); }
+  // Other entries should be unchanged.
+}
+
+void InterpreterMacroAssembler::restore_interpreter_state(Register scratch, bool bcp_and_mdx_only) {
+  ld(scratch, 0, R1_SP);
+  ld(R14_bcp, _ijava_state_neg(bcp), scratch); // Changed by VM code (exception).
+  if (ProfileInterpreter) { ld(R28_mdx, _ijava_state_neg(mdx), scratch); } // Changed by VM code.
+  if (!bcp_and_mdx_only) {
+    // Following ones are Metadata.
+    ld(R19_method, _ijava_state_neg(method), scratch);
+    ld(R27_constPoolCache, _ijava_state_neg(cpoolCache), scratch);
+    // Following ones are stack addresses and don't require reload.
+    ld(R15_esp, _ijava_state_neg(esp), scratch);
+    ld(R18_locals, _ijava_state_neg(locals), scratch);
+    ld(R26_monitor, _ijava_state_neg(monitors), scratch);
+  }
+#ifdef ASSERT
+  {
+    Label Lok;
+    subf(R0, R1_SP, scratch);
+    cmpdi(CCR0, R0, frame::abi_reg_args_size + frame::ijava_state_size);
+    bge(CCR0, Lok);
+    stop("frame too small (restore istate)", 0x5432);
+    bind(Lok);
+  }
+  {
+    Label Lok;
+    ld(R0, _ijava_state_neg(ijava_reserved), scratch);
+    cmpdi(CCR0, R0, 0x5afe);
+    beq(CCR0, Lok);
+    stop("frame corrupted (restore istate)", 0x5afe);
+    bind(Lok);
+  }
+#endif
+}
+
+#endif // !CC_INTERP
+
 void InterpreterMacroAssembler::get_method_counters(Register method,
                                                     Register Rcounters,
                                                     Label& skip) {
@@ -321,6 +1957,66 @@
   if (state == atos) { MacroAssembler::verify_oop(reg); }
 }
 
+#ifndef CC_INTERP
+// Local helper function for the verify_oop_or_return_address macro.
+static bool verify_return_address(Method* m, int bci) {
+#ifndef PRODUCT
+  address pc = (address)(m->constMethod()) + in_bytes(ConstMethod::codes_offset()) + bci;
+  // Assume it is a valid return address if it is inside m and is preceded by a jsr.
+  if (!m->contains(pc))                                            return false;
+  address jsr_pc;
+  jsr_pc = pc - Bytecodes::length_for(Bytecodes::_jsr);
+  if (*jsr_pc == Bytecodes::_jsr   && jsr_pc >= m->code_base())    return true;
+  jsr_pc = pc - Bytecodes::length_for(Bytecodes::_jsr_w);
+  if (*jsr_pc == Bytecodes::_jsr_w && jsr_pc >= m->code_base())    return true;
+#endif // PRODUCT
+  return false;
+}
+
+void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) {
+  if (VerifyFPU) {
+    unimplemented("verfiyFPU");
+  }
+}
+
+void InterpreterMacroAssembler::verify_oop_or_return_address(Register reg, Register Rtmp) {
+  if (!VerifyOops) return;
+
+  // The VM documentation for the astore[_wide] bytecode allows
+  // the TOS to be not only an oop but also a return address.
+  Label test;
+  Label skip;
+  // See if it is an address (in the current method):
+
+  const int log2_bytecode_size_limit = 16;
+  srdi_(Rtmp, reg, log2_bytecode_size_limit);
+  bne(CCR0, test);
+
+  address fd = CAST_FROM_FN_PTR(address, verify_return_address);
+  unsigned int nbytes_save = 10*8; // 10 volatile gprs
+
+  save_LR_CR(Rtmp);
+  push_frame_reg_args(nbytes_save, Rtmp);
+  save_volatile_gprs(R1_SP, 112); // except R0
+
+  load_const_optimized(Rtmp, fd, R0);
+  mr_if_needed(R4_ARG2, reg);
+  mr(R3_ARG1, R19_method);
+  call_c(Rtmp); // call C
+
+  restore_volatile_gprs(R1_SP, 112); // except R0
+  pop_frame();
+  restore_LR_CR(Rtmp);
+  b(skip);
+
+  // Perform a more elaborate out-of-line call.
+  // Not an address; verify it:
+  bind(test);
+  verify_oop(reg);
+  bind(skip);
+}
+#endif // !CC_INTERP
+
 // Inline assembly for:
 //
 // if (thread is in interp_only_mode) {
@@ -343,13 +2039,12 @@
     cmpwi(CCR0, R0, 0);
     beq(CCR0, jvmti_post_done);
     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_entry),
-            /*check_exceptions=*/false);
+            /*check_exceptions=*/true CC_INTERP_ONLY(&& false));
 
     bind(jvmti_post_done);
   }
 }
 
-
 // Inline assembly for:
 //
 // if (thread is in interp_only_mode) {
@@ -365,26 +2060,33 @@
 //
 // Native methods have their result stored in d_tmp and l_tmp.
 // Java methods have their result stored in the expression stack.
-void InterpreterMacroAssembler::notify_method_exit(bool is_native_method, TosState state) {
+void InterpreterMacroAssembler::notify_method_exit(bool is_native_method, TosState state,
+                                                   NotifyMethodExitMode mode, bool check_exceptions) {
   // JVMTI
   // Whenever JVMTI puts a thread in interp_only_mode, method
   // entry/exit events are sent for that thread to track stack
   // depth. If it is possible to enter interp_only_mode we add
   // the code to check if the event should be sent.
-  if (JvmtiExport::can_post_interpreter_events()) {
+  if (mode == NotifyJVMTI && JvmtiExport::can_post_interpreter_events()) {
     Label jvmti_post_done;
 
     lwz(R0, in_bytes(JavaThread::interp_only_mode_offset()), R16_thread);
     cmpwi(CCR0, R0, 0);
     beq(CCR0, jvmti_post_done);
+    CC_INTERP_ONLY(assert(is_native_method && !check_exceptions, "must not push state"));
+    if (!is_native_method) push(state); // Expose tos to GC.
     call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit),
-            /*check_exceptions=*/false);
+            /*check_exceptions=*/check_exceptions);
+    if (!is_native_method) pop(state);
 
     align(32, 12);
     bind(jvmti_post_done);
   }
+
+  // Dtrace support not implemented.
 }
 
+#ifdef CC_INTERP
 // Convert the current TOP_IJAVA_FRAME into a PARENT_IJAVA_FRAME
 // (using parent_frame_resize) and push a new interpreter
 // TOP_IJAVA_FRAME (using frame_size).
@@ -442,7 +2144,6 @@
   std(R1_SP, _top_ijava_frame_abi(top_frame_sp), R1_SP);
 }
 
-#ifdef CC_INTERP
 // Turn state's interpreter frame into the current TOP_IJAVA_FRAME.
 void InterpreterMacroAssembler::pop_interpreter_frame_to_state(Register state, Register tmp1, Register tmp2, Register tmp3) {
   assert_different_registers(R14_state, R15_prev_state, tmp1, tmp2, tmp3);
@@ -471,7 +2172,6 @@
   // Used for non-initial callers by unextended_sp().
   std(R1_SP, _top_ijava_frame_abi(initial_caller_sp), R1_SP);
 }
-#endif // CC_INTERP
 
 // Set SP to initial caller's sp, but before fix the back chain.
 void InterpreterMacroAssembler::resize_frame_to_initial_caller(Register tmp1, Register tmp2) {
@@ -481,7 +2181,6 @@
   mr(R1_SP, tmp1); // ... and resize to initial caller.
 }
 
-#ifdef CC_INTERP
 // Pop the current interpreter state (without popping the correspoding
 // frame) and restore R14_state and R15_prev_state accordingly.
 // Use prev_state_may_be_0 to indicate whether prev_state may be 0
--- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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,7 @@
 #include "assembler_ppc.inline.hpp"
 #include "interpreter/invocationCounter.hpp"
 
-// This file specializes the assembler with interpreter-specific macros
+// This file specializes the assembler with interpreter-specific macros.
 
 
 class InterpreterMacroAssembler: public MacroAssembler {
@@ -39,15 +39,176 @@
 
   void null_check_throw(Register a, int offset, Register temp_reg);
 
-  // Handy address generation macros
+  void branch_to_entry(address entry, Register Rscratch);
+
+  // Handy address generation macros.
 #define thread_(field_name) in_bytes(JavaThread::field_name ## _offset()), R16_thread
 #define method_(field_name) in_bytes(Method::field_name ## _offset()), R19_method
 
 #ifdef CC_INTERP
 #define state_(field_name)  in_bytes(byte_offset_of(BytecodeInterpreter, field_name)), R14_state
 #define prev_state_(field_name)  in_bytes(byte_offset_of(BytecodeInterpreter, field_name)), R15_prev_state
+  void pop (TosState state) {};           // Not needed.
+  void push(TosState state) {};           // Not needed.
 #endif
 
+#ifndef CC_INTERP
+  virtual void check_and_handle_popframe(Register java_thread);
+  virtual void check_and_handle_earlyret(Register java_thread);
+
+  // Base routine for all dispatches.
+  void dispatch_base(TosState state, address* table);
+
+  void load_earlyret_value(TosState state, Register Rscratch1);
+
+  static const Address l_tmp;
+  static const Address d_tmp;
+
+  // dispatch routines
+  void dispatch_next(TosState state, int step = 0);
+  void dispatch_via (TosState state, address* table);
+  void load_dispatch_table(Register dst, address* table);
+  void dispatch_Lbyte_code(TosState state, Register bytecode, address* table, bool verify = false);
+
+  // Called by shared interpreter generator.
+  void dispatch_prolog(TosState state, int step = 0);
+  void dispatch_epilog(TosState state, int step = 0);
+
+  // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls.
+  void super_call_VM_leaf(Register thread_cache, address entry_point, Register arg_1);
+  void super_call_VM(Register thread_cache, Register oop_result, Register last_java_sp,
+                     address entry_point, Register arg_1, Register arg_2, bool check_exception = true);
+
+  // Generate a subtype check: branch to ok_is_subtype if sub_klass is
+  // a subtype of super_klass.  Blows registers tmp1, tmp2 and tmp3.
+  void gen_subtype_check(Register sub_klass, Register super_klass,
+                         Register tmp1, Register tmp2, Register tmp3, Label &ok_is_subtype);
+
+  // Load object from cpool->resolved_references(index).
+  void load_resolved_reference_at_index(Register result, Register index);
+
+  void generate_stack_overflow_check_with_compare_and_throw(Register Rmem_frame_size, Register Rscratch1);
+  void load_receiver(Register Rparam_count, Register Rrecv_dst);
+
+  // helpers for expression stack
+  void pop_i(     Register r = R17_tos);
+  void pop_ptr(   Register r = R17_tos);
+  void pop_l(     Register r = R17_tos);
+  void pop_f(FloatRegister f = F15_ftos);
+  void pop_d(FloatRegister f = F15_ftos );
+
+  void push_i(     Register r = R17_tos);
+  void push_ptr(   Register r = R17_tos);
+  void push_l(     Register r = R17_tos);
+  void push_f(FloatRegister f = F15_ftos );
+  void push_d(FloatRegister f = F15_ftos);
+
+  void push_2ptrs(Register first, Register second);
+
+  void push_l_pop_d(Register l = R17_tos, FloatRegister d = F15_ftos);
+  void push_d_pop_l(FloatRegister d = F15_ftos, Register l = R17_tos);
+
+  void pop (TosState state);           // transition vtos -> state
+  void push(TosState state);           // transition state -> vtos
+  void empty_expression_stack();       // Resets both Lesp and SP.
+
+ public:
+  // Load values from bytecode stream:
+
+  enum signedOrNot { Signed, Unsigned };
+  enum setCCOrNot  { set_CC, dont_set_CC };
+
+  void get_2_byte_integer_at_bcp(int         bcp_offset,
+                                 Register    Rdst,
+                                 signedOrNot is_signed);
+
+  void get_4_byte_integer_at_bcp(int         bcp_offset,
+                                 Register    Rdst,
+                                 signedOrNot is_signed = Unsigned);
+
+  void get_cache_index_at_bcp(Register Rdst, int bcp_offset, size_t index_size);
+
+  void get_cache_and_index_at_bcp(Register cache, int bcp_offset, size_t index_size = sizeof(u2));
+
+
+  // common code
+
+  void field_offset_at(int n, Register tmp, Register dest, Register base);
+  int  field_offset_at(Register object, address bcp, int offset);
+  void fast_iaaccess(int n, address bcp);
+  void fast_iagetfield(address bcp);
+  void fast_iaputfield(address bcp, bool do_store_check);
+
+  void index_check(Register array, Register index, int index_shift, Register tmp, Register res);
+  void index_check_without_pop(Register array, Register index, int index_shift, Register tmp, Register res);
+
+  void get_const(Register Rdst);
+  void get_constant_pool(Register Rdst);
+  void get_constant_pool_cache(Register Rdst);
+  void get_cpool_and_tags(Register Rcpool, Register Rtags);
+  void is_a(Label& L);
+
+  // Java Call Helpers
+  void call_from_interpreter(Register Rtarget_method, Register Rret_addr, Register Rscratch1, Register Rscratch2);
+
+  // --------------------------------------------------
+
+  void unlock_if_synchronized_method(TosState state, bool throw_monitor_exception = true,
+                                     bool install_monitor_exception = true);
+
+  // Removes the current activation (incl. unlocking of monitors).
+  // Additionally this code is used for earlyReturn in which case we
+  // want to skip throwing an exception and installing an exception.
+  void remove_activation(TosState state,
+                         bool throw_monitor_exception = true,
+                         bool install_monitor_exception = true);
+  void merge_frames(Register Rtop_frame_sp, Register return_pc, Register Rscratch1, Register Rscratch2); // merge top frames
+
+  void add_monitor_to_stack(bool stack_is_empty, Register Rtemp1, Register Rtemp2);
+
+  // Local variable access helpers
+  void load_local_int(Register Rdst_value, Register Rdst_address, Register Rindex);
+  void load_local_long(Register Rdst_value, Register Rdst_address, Register Rindex);
+  void load_local_ptr(Register Rdst_value, Register Rdst_address, Register Rindex);
+  void load_local_float(FloatRegister Rdst_value, Register Rdst_address, Register Rindex);
+  void load_local_double(FloatRegister Rdst_value, Register Rdst_address, Register Rindex);
+  void store_local_int(Register Rvalue, Register Rindex);
+  void store_local_long(Register Rvalue, Register Rindex);
+  void store_local_ptr(Register Rvalue, Register Rindex);
+  void store_local_float(FloatRegister Rvalue, Register Rindex);
+  void store_local_double(FloatRegister Rvalue, Register Rindex);
+
+  // Call VM for std frames
+  // Special call VM versions that check for exceptions and forward exception
+  // via short cut (not via expensive forward exception stub).
+  void check_and_forward_exception(Register Rscratch1, Register Rscratch2);
+  void call_VM(Register oop_result, address entry_point, bool check_exceptions = true);
+  void call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions = true);
+  void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true);
+  void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true);
+  // Should not be used:
+  void call_VM(Register oop_result, Register last_java_sp, address entry_point, bool check_exceptions = true) {ShouldNotReachHere();}
+  void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, bool check_exceptions = true) {ShouldNotReachHere();}
+  void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true) {ShouldNotReachHere();}
+  void call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions = true) {ShouldNotReachHere();}
+
+  Address first_local_in_stack();
+
+  enum LoadOrStore { load, store };
+  void static_iload_or_store(int which_local, LoadOrStore direction, Register Rtmp);
+  void static_aload_or_store(int which_local, LoadOrStore direction, Register Rtmp);
+  void static_dload_or_store(int which_local, LoadOrStore direction);
+
+  void save_interpreter_state(Register scratch);
+  void restore_interpreter_state(Register scratch, bool bcp_and_mdx_only = false);
+
+  void increment_backedge_counter(const Register Rcounters, Register Rtmp, Register Rtmp2, Register Rscratch);
+  void test_backedge_count_for_osr(Register backedge_count, Register branch_bcp, Register Rtmp);
+
+  void record_static_call_in_profile(Register Rentry, Register Rtmp);
+  void record_receiver_call_in_profile(Register Rklass, Register Rentry, Register Rtmp);
+#endif // !CC_INTERP
+
   void get_method_counters(Register method, Register Rcounters, Label& skip);
   void increment_invocation_counter(Register iv_be_count, Register Rtmp1, Register Rtmp2_r0);
 
@@ -55,12 +216,59 @@
   void lock_object  (Register lock_reg, Register obj_reg);
   void unlock_object(Register lock_reg, bool check_for_exceptions = true);
 
+#ifndef CC_INTERP
+
+  // Interpreter profiling operations
+  void set_method_data_pointer_for_bcp();
+  void test_method_data_pointer(Label& zero_continue);
+  void verify_method_data_pointer();
+  void test_invocation_counter_for_mdp(Register invocation_count, Register Rscratch, Label &profile_continue);
+
+  void set_mdp_data_at(int constant, Register value);
+
+  void increment_mdp_data_at(int constant, Register counter_addr, Register Rbumped_count, bool decrement = false);
+
+  void increment_mdp_data_at(Register counter_addr, Register Rbumped_count, bool decrement = false);
+  void increment_mdp_data_at(Register reg, int constant, Register scratch, Register Rbumped_count, bool decrement = false);
+
+  void set_mdp_flag_at(int flag_constant, Register scratch);
+  void test_mdp_data_at(int offset, Register value, Label& not_equal_continue, Register test_out);
+
+  void update_mdp_by_offset(int offset_of_disp, Register scratch);
+  void update_mdp_by_offset(Register reg, int offset_of_disp,
+                            Register scratch);
+  void update_mdp_by_constant(int constant);
+  void update_mdp_for_ret(TosState state, Register return_bci);
+
+  void profile_taken_branch(Register scratch, Register bumped_count);
+  void profile_not_taken_branch(Register scratch1, Register scratch2);
+  void profile_call(Register scratch1, Register scratch2);
+  void profile_final_call(Register scratch1, Register scratch2);
+  void profile_virtual_call(Register Rreceiver, Register Rscratch1, Register Rscratch2,  bool receiver_can_be_null);
+  void profile_typecheck(Register Rklass, Register Rscratch1, Register Rscratch2);
+  void profile_typecheck_failed(Register Rscratch1, Register Rscratch2);
+  void profile_ret(TosState state, Register return_bci, Register scratch1, Register scratch2);
+  void profile_switch_default(Register scratch1, Register scratch2);
+  void profile_switch_case(Register index, Register scratch1,Register scratch2, Register scratch3);
+  void profile_null_seen(Register Rscratch1, Register Rscratch2);
+  void record_klass_in_profile(Register receiver, Register scratch1, Register scratch2, bool is_virtual_call);
+  void record_klass_in_profile_helper(Register receiver, Register scratch1, Register scratch2, int start_row, Label& done, bool is_virtual_call);
+
+#endif // !CC_INTERP
+
   // Debugging
   void verify_oop(Register reg, TosState state = atos);    // only if +VerifyOops && state == atos
+#ifndef CC_INTERP
+  void verify_oop_or_return_address(Register reg, Register rtmp); // for astore
+  void verify_FPU(int stack_depth, TosState state = ftos);
+#endif // !CC_INTERP
 
-  // support for jvmdi/jvmpi
+  typedef enum { NotifyJVMTI, SkipNotifyJVMTI } NotifyMethodExitMode;
+
+  // Support for jvmdi/jvmpi.
   void notify_method_entry();
-  void notify_method_exit(bool is_native_method, TosState state);
+  void notify_method_exit(bool is_native_method, TosState state,
+                          NotifyMethodExitMode mode, bool check_exceptions);
 
 #ifdef CC_INTERP
   // Convert the current TOP_IJAVA_FRAME into a PARENT_IJAVA_FRAME
--- a/hotspot/src/cpu/ppc/vm/interpreterRT_ppc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/interpreterRT_ppc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -109,8 +109,10 @@
 }
 
 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
+#if !defined(ABI_ELFv2)
   // Emit fd for current codebuffer. Needs patching!
   __ emit_fd();
+#endif
 
   // Generate code to handle arguments.
   iterate(fingerprint);
@@ -127,11 +129,13 @@
 // Implementation of SignatureHandlerLibrary
 
 void SignatureHandlerLibrary::pd_set_handler(address handler) {
+#if !defined(ABI_ELFv2)
   // patch fd here.
   FunctionDescriptor* fd = (FunctionDescriptor*) handler;
 
   fd->set_entry(handler + (int)sizeof(FunctionDescriptor));
   assert(fd->toc() == (address)0xcafe, "need to adjust TOC here");
+#endif
 }
 
 
--- a/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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
@@ -51,10 +51,6 @@
 #include "c1/c1_Runtime1.hpp"
 #endif
 
-#ifndef CC_INTERP
-#error "CC_INTERP must be defined on PPC"
-#endif
-
 #define __ _masm->
 
 #ifdef PRODUCT
@@ -128,13 +124,13 @@
   const Register target_sp      = R28_tmp8;
   const FloatRegister floatSlot = F0;
 
-  address entry = __ emit_fd();
+  address entry = __ function_entry();
 
   __ save_LR_CR(R0);
   __ save_nonvolatile_gprs(R1_SP, _spill_nonvolatiles_neg(r14));
   // We use target_sp for storing arguments in the C frame.
   __ mr(target_sp, R1_SP);
-  __ push_frame_abi112_nonvolatiles(0, R11_scratch1);
+  __ push_frame_reg_args_nonvolatiles(0, R11_scratch1);
 
   __ mr(arg_java, R3_ARG1);
 
@@ -147,7 +143,8 @@
 #ifdef CC_INTERP
   __ ld(R19_method, state_(_method));
 #else
-  __ unimplemented("slow signature handler 1");
+  __ ld(R19_method, 0, target_sp);
+  __ ld(R19_method, _ijava_state_neg(method), R19_method);
 #endif
 
   // Get the result handler.
@@ -157,7 +154,8 @@
 #ifdef CC_INTERP
   __ ld(R19_method, state_(_method));
 #else
-  __ unimplemented("slow signature handler 2");
+  __ ld(R19_method, 0, target_sp);
+  __ ld(R19_method, _ijava_state_neg(method), R19_method);
 #endif
 
   {
@@ -453,7 +451,7 @@
   //
   // Registers alive
   //   R16_thread     - JavaThread*
-  //   R19_method     - callee's methodOop (method to be invoked)
+  //   R19_method     - callee's method (method to be invoked)
   //   R1_SP          - SP prepared such that caller's outgoing args are near top
   //   LR             - return address to caller
   //
@@ -474,7 +472,7 @@
 
   // Push a new C frame and save LR.
   __ save_LR_CR(R0);
-  __ push_frame_abi112(0, R11_scratch1);
+  __ push_frame_reg_args(0, R11_scratch1);
 
   // This is not a leaf but we have a JavaFrameAnchor now and we will
   // check (create) exceptions afterward so this is ok.
@@ -491,7 +489,12 @@
   // Return to frame manager, it will handle the pending exception.
   __ blr();
 #else
-  Unimplemented();
+  // We don't know our caller, so jump to the general forward exception stub,
+  // which will also pop our full frame off. Satisfy the interface of
+  // SharedRuntime::generate_forward_exception()
+  __ load_const_optimized(R11_scratch1, StubRoutines::forward_exception_entry(), R0);
+  __ mtctr(R11_scratch1);
+  __ bctr();
 #endif
 
   return entry;
@@ -500,8 +503,9 @@
 // Call an accessor method (assuming it is resolved, otherwise drop into
 // vanilla (slow path) entry.
 address InterpreterGenerator::generate_accessor_entry(void) {
-  if(!UseFastAccessorMethods && (!FLAG_IS_ERGO(UseFastAccessorMethods)))
+  if (!UseFastAccessorMethods && (!FLAG_IS_ERGO(UseFastAccessorMethods))) {
     return NULL;
+  }
 
   Label Lslow_path, Lacquire;
 
@@ -586,10 +590,14 @@
   // Load from branch table and dispatch (volatile case: one instruction ahead)
   __ sldi(Rflags, Rflags, LogBytesPerWord);
   __ cmpwi(CCR6, Rscratch, 1); // volatile?
-  __ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // volatile ? size of 1 instruction : 0
+  if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // volatile ? size of 1 instruction : 0
+  }
   __ ldx(Rbtable, Rbtable, Rflags);
 
-  __ subf(Rbtable, Rscratch, Rbtable); // point to volatile/non-volatile entry point
+  if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ subf(Rbtable, Rscratch, Rbtable); // point to volatile/non-volatile entry point
+  }
   __ mtctr(Rbtable);
   __ bctr();
 
@@ -605,7 +613,7 @@
   }
   assert(all_uninitialized != all_initialized, "consistency"); // either or
 
-  __ sync(); // volatile entry point (one instruction before non-volatile_entry point)
+  __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
   if (branch_table[vtos] == 0) branch_table[vtos] = __ pc(); // non-volatile_entry point
   if (branch_table[dtos] == 0) branch_table[dtos] = __ pc(); // non-volatile_entry point
   if (branch_table[ftos] == 0) branch_table[ftos] = __ pc(); // non-volatile_entry point
@@ -614,7 +622,7 @@
 
   if (branch_table[itos] == 0) { // generate only once
     __ align(32, 28, 28); // align load
-    __ sync(); // volatile entry point (one instruction before non-volatile_entry point)
+    __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
     branch_table[itos] = __ pc(); // non-volatile_entry point
     __ lwax(R3_RET, Rclass_or_obj, Roffset);
     __ beq(CCR6, Lacquire);
@@ -623,7 +631,7 @@
 
   if (branch_table[ltos] == 0) { // generate only once
     __ align(32, 28, 28); // align load
-    __ sync(); // volatile entry point (one instruction before non-volatile_entry point)
+    __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
     branch_table[ltos] = __ pc(); // non-volatile_entry point
     __ ldx(R3_RET, Rclass_or_obj, Roffset);
     __ beq(CCR6, Lacquire);
@@ -632,7 +640,7 @@
 
   if (branch_table[btos] == 0) { // generate only once
     __ align(32, 28, 28); // align load
-    __ sync(); // volatile entry point (one instruction before non-volatile_entry point)
+    __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
     branch_table[btos] = __ pc(); // non-volatile_entry point
     __ lbzx(R3_RET, Rclass_or_obj, Roffset);
     __ extsb(R3_RET, R3_RET);
@@ -642,7 +650,7 @@
 
   if (branch_table[ctos] == 0) { // generate only once
     __ align(32, 28, 28); // align load
-    __ sync(); // volatile entry point (one instruction before non-volatile_entry point)
+    __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
     branch_table[ctos] = __ pc(); // non-volatile_entry point
     __ lhzx(R3_RET, Rclass_or_obj, Roffset);
     __ beq(CCR6, Lacquire);
@@ -651,7 +659,7 @@
 
   if (branch_table[stos] == 0) { // generate only once
     __ align(32, 28, 28); // align load
-    __ sync(); // volatile entry point (one instruction before non-volatile_entry point)
+    __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
     branch_table[stos] = __ pc(); // non-volatile_entry point
     __ lhax(R3_RET, Rclass_or_obj, Roffset);
     __ beq(CCR6, Lacquire);
@@ -660,7 +668,7 @@
 
   if (branch_table[atos] == 0) { // generate only once
     __ align(32, 28, 28); // align load
-    __ sync(); // volatile entry point (one instruction before non-volatile_entry point)
+    __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
     branch_table[atos] = __ pc(); // non-volatile_entry point
     __ load_heap_oop(R3_RET, (RegisterOrConstant)Roffset, Rclass_or_obj);
     __ verify_oop(R3_RET);
@@ -683,10 +691,7 @@
 #endif
 
   __ bind(Lslow_path);
-  assert(Interpreter::entry_for_kind(Interpreter::zerolocals), "Normal entry must have been generated by now");
-  __ load_const_optimized(Rscratch, Interpreter::entry_for_kind(Interpreter::zerolocals), R0);
-  __ mtctr(Rscratch);
-  __ bctr();
+  __ branch_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), Rscratch);
   __ flush();
 
   return entry;
@@ -773,10 +778,7 @@
 
     // Generate regular method entry.
     __ bind(slow_path);
-    assert(Interpreter::entry_for_kind(Interpreter::zerolocals), "Normal entry must have been generated by now");
-    __ load_const_optimized(R11_scratch1, Interpreter::entry_for_kind(Interpreter::zerolocals), R0);
-    __ mtctr(R11_scratch1);
-    __ bctr();
+    __ branch_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), R11_scratch1);
     __ flush();
 
     return entry;
--- a/hotspot/src/cpu/ppc/vm/interpreter_ppc.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/interpreter_ppc.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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
@@ -28,15 +28,23 @@
 
  public:
 
-  // Stack index relative to tos (which points at value)
+  // Stack index relative to tos (which points at value).
   static int expr_index_at(int i) {
     return stackElementWords * i;
   }
 
-  // Already negated by c++ interpreter
+  // Already negated by c++ interpreter.
   static int local_index_at(int i) {
     assert(i <= 0, "local direction already negated");
     return stackElementWords * i;
   }
 
+#ifndef CC_INTERP
+  // The offset in bytes to access a expression stack slot
+  // relative to the esp pointer.
+  static int expr_offset_in_bytes(int slot) {
+    return stackElementSize * slot + wordSize;
+  }
+#endif
+
 #endif // CPU_PPC_VM_INTERPRETER_PPC_PP
--- a/hotspot/src/cpu/ppc/vm/javaFrameAnchor_ppc.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/javaFrameAnchor_ppc.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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
@@ -26,10 +26,6 @@
 #ifndef CPU_PPC_VM_JAVAFRAMEANCHOR_PPC_HPP
 #define CPU_PPC_VM_JAVAFRAMEANCHOR_PPC_HPP
 
-#ifndef CC_INTERP
-#error "CC_INTERP must be defined on PPC64"
-#endif
-
 public:
   // Each arch must define reset, save, restore
   // These are used by objects that only care about:
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -594,7 +594,13 @@
            "can't identify emitted call");
   } else {
     // variant 1:
-
+#if defined(ABI_ELFv2)
+    nop();
+    calculate_address_from_global_toc(R12, dest, true, true, false);
+    mtctr(R12);
+    nop();
+    nop();
+#else
     mr(R0, R11);  // spill R11 -> R0.
 
     // Load the destination address into CTR,
@@ -604,6 +610,7 @@
     mtctr(R11);
     mr(R11, R0);  // spill R11 <- R0.
     nop();
+#endif
 
     // do the call/jump
     if (link) {
@@ -912,16 +919,16 @@
   }
 }
 
-// Push a frame of size `bytes' plus abi112 on top.
-void MacroAssembler::push_frame_abi112(unsigned int bytes, Register tmp) {
-  push_frame(bytes + frame::abi_112_size, tmp);
+// Push a frame of size `bytes' plus abi_reg_args on top.
+void MacroAssembler::push_frame_reg_args(unsigned int bytes, Register tmp) {
+  push_frame(bytes + frame::abi_reg_args_size, tmp);
 }
 
 // Setup up a new C frame with a spill area for non-volatile GPRs and
 // additional space for local variables.
-void MacroAssembler::push_frame_abi112_nonvolatiles(unsigned int bytes,
-                                                    Register tmp) {
-  push_frame(bytes + frame::abi_112_size + frame::spill_nonvolatiles_size, tmp);
+void MacroAssembler::push_frame_reg_args_nonvolatiles(unsigned int bytes,
+                                                      Register tmp) {
+  push_frame(bytes + frame::abi_reg_args_size + frame::spill_nonvolatiles_size, tmp);
 }
 
 // Pop current C frame.
@@ -929,6 +936,42 @@
   ld(R1_SP, _abi(callers_sp), R1_SP);
 }
 
+#if defined(ABI_ELFv2)
+address MacroAssembler::branch_to(Register r_function_entry, bool and_link) {
+  // TODO(asmundak): make sure the caller uses R12 as function descriptor
+  // most of the times.
+  if (R12 != r_function_entry) {
+    mr(R12, r_function_entry);
+  }
+  mtctr(R12);
+  // Do a call or a branch.
+  if (and_link) {
+    bctrl();
+  } else {
+    bctr();
+  }
+  _last_calls_return_pc = pc();
+
+  return _last_calls_return_pc;
+}
+
+// Call a C function via a function descriptor and use full C
+// calling conventions. Updates and returns _last_calls_return_pc.
+address MacroAssembler::call_c(Register r_function_entry) {
+  return branch_to(r_function_entry, /*and_link=*/true);
+}
+
+// For tail calls: only branch, don't link, so callee returns to caller of this function.
+address MacroAssembler::call_c_and_return_to_caller(Register r_function_entry) {
+  return branch_to(r_function_entry, /*and_link=*/false);
+}
+
+address MacroAssembler::call_c(address function_entry, relocInfo::relocType rt) {
+  load_const(R12, function_entry, R0);
+  return branch_to(R12,  /*and_link=*/true);
+}
+
+#else
 // Generic version of a call to C function via a function descriptor
 // with variable support for C calling conventions (TOC, ENV, etc.).
 // Updates and returns _last_calls_return_pc.
@@ -1077,6 +1120,7 @@
   }
   return _last_calls_return_pc;
 }
+#endif
 
 void MacroAssembler::call_VM_base(Register oop_result,
                                   Register last_java_sp,
@@ -1091,8 +1135,11 @@
 
   // ARG1 must hold thread address.
   mr(R3_ARG1, R16_thread);
-
+#if defined(ABI_ELFv2)
+  address return_pc = call_c(entry_point, relocInfo::none);
+#else
   address return_pc = call_c((FunctionDescriptor*)entry_point, relocInfo::none);
+#endif
 
   reset_last_Java_frame();
 
@@ -1113,7 +1160,11 @@
 
 void MacroAssembler::call_VM_leaf_base(address entry_point) {
   BLOCK_COMMENT("call_VM_leaf {");
+#if defined(ABI_ELFv2)
+  call_c(entry_point, relocInfo::none);
+#else
   call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, entry_point), relocInfo::none);
+#endif
   BLOCK_COMMENT("} call_VM_leaf");
 }
 
@@ -2227,7 +2278,7 @@
   // VM call need frame to access(write) O register.
   if (needs_frame) {
     save_LR_CR(Rtmp1);
-    push_frame_abi112(0, Rtmp2);
+    push_frame_reg_args(0, Rtmp2);
   }
 
   if (Rpre_val->is_volatile() && Robj == noreg) mr(R31, Rpre_val); // Save pre_val across C call if it was preloaded.
@@ -2361,7 +2412,8 @@
 #ifdef CC_INTERP
   ld(tmp1/*pc*/, _top_ijava_frame_abi(frame_manager_lr), sp);
 #else
-  Unimplemented();
+  address entry = pc();
+  load_const_optimized(tmp1, entry);
 #endif
 
   set_last_Java_frame(/*sp=*/sp, /*pc=*/tmp1);
@@ -2421,6 +2473,16 @@
   }
 }
 
+void MacroAssembler::store_klass_gap(Register dst_oop, Register val) {
+  if (UseCompressedClassPointers) {
+    if (val == noreg) {
+      val = R0;
+      li(val, 0);
+    }
+    stw(val, oopDesc::klass_gap_offset_in_bytes(), dst_oop); // klass gap if compressed
+  }
+}
+
 int MacroAssembler::instr_size_for_decode_klass_not_null() {
   if (!UseCompressedClassPointers) return 0;
   int num_instrs = 1;  // shift or move
@@ -3006,13 +3068,13 @@
   mr(R0, tmp);
   // kill tmp
   save_LR_CR(tmp);
-  push_frame_abi112(nbytes_save, tmp);
+  push_frame_reg_args(nbytes_save, tmp);
   // restore tmp
   mr(tmp, R0);
   save_volatile_gprs(R1_SP, 112); // except R0
-  // load FunctionDescriptor**
+  // load FunctionDescriptor** / entry_address *
   load_const(tmp, fd);
-  // load FunctionDescriptor*
+  // load FunctionDescriptor* / entry_address
   ld(tmp, 0, tmp);
   mr(R4_ARG2, oop);
   load_const(R3_ARG1, (address)msg);
@@ -3092,3 +3154,15 @@
 }
 
 #endif // !PRODUCT
+
+SkipIfEqualZero::SkipIfEqualZero(MacroAssembler* masm, Register temp, const bool* flag_addr) : _masm(masm), _label() {
+  int simm16_offset = masm->load_const_optimized(temp, (address)flag_addr, R0, true);
+  assert(sizeof(bool) == 1, "PowerPC ABI");
+  masm->lbz(temp, simm16_offset, temp);
+  masm->cmpwi(CCR0, temp, 0);
+  masm->beq(CCR0, _label);
+}
+
+SkipIfEqualZero::~SkipIfEqualZero() {
+  _masm->bind(_label);
+}
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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
@@ -279,12 +279,12 @@
   // Push a frame of size `bytes'. No abi space provided.
   void push_frame(unsigned int bytes, Register tmp);
 
-  // Push a frame of size `bytes' plus abi112 on top.
-  void push_frame_abi112(unsigned int bytes, Register tmp);
+  // Push a frame of size `bytes' plus abi_reg_args on top.
+  void push_frame_reg_args(unsigned int bytes, Register tmp);
 
   // Setup up a new C frame with a spill area for non-volatile GPRs and additional
   // space for local variables
-  void push_frame_abi112_nonvolatiles(unsigned int bytes, Register tmp);
+  void push_frame_reg_args_nonvolatiles(unsigned int bytes, Register tmp);
 
   // pop current C frame
   void pop_frame();
@@ -296,17 +296,31 @@
  private:
   address _last_calls_return_pc;
 
+#if defined(ABI_ELFv2)
+  // Generic version of a call to C function.
+  // Updates and returns _last_calls_return_pc.
+  address branch_to(Register function_entry, bool and_link);
+#else
   // Generic version of a call to C function via a function descriptor
   // with variable support for C calling conventions (TOC, ENV, etc.).
   // updates and returns _last_calls_return_pc.
   address branch_to(Register function_descriptor, bool and_link, bool save_toc_before_call,
                     bool restore_toc_after_call, bool load_toc_of_callee, bool load_env_of_callee);
+#endif
 
  public:
 
   // Get the pc where the last call will return to. returns _last_calls_return_pc.
   inline address last_calls_return_pc();
 
+#if defined(ABI_ELFv2)
+  // Call a C function via a function descriptor and use full C
+  // calling conventions. Updates and returns _last_calls_return_pc.
+  address call_c(Register function_entry);
+  // For tail calls: only branch, don't link, so callee returns to caller of this function.
+  address call_c_and_return_to_caller(Register function_entry);
+  address call_c(address function_entry, relocInfo::relocType rt);
+#else
   // Call a C function via a function descriptor and use full C
   // calling conventions. Updates and returns _last_calls_return_pc.
   address call_c(Register function_descriptor);
@@ -315,6 +329,7 @@
   address call_c(const FunctionDescriptor* function_descriptor, relocInfo::relocType rt);
   address call_c_using_toc(const FunctionDescriptor* function_descriptor, relocInfo::relocType rt,
                            Register toc);
+#endif
 
  protected:
 
@@ -551,12 +566,14 @@
 
   // Load heap oop and decompress. Loaded oop may not be null.
   inline void load_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1 = noreg);
+  inline void store_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1,
+                                      /*specify if d must stay uncompressed*/ Register tmp = noreg);
 
   // Null allowed.
   inline void load_heap_oop(Register d, RegisterOrConstant offs, Register s1 = noreg);
 
   // Encode/decode heap oop. Oop may not be null, else en/decoding goes wrong.
-  inline void encode_heap_oop_not_null(Register d);
+  inline Register encode_heap_oop_not_null(Register d, Register src = noreg);
   inline void decode_heap_oop_not_null(Register d);
 
   // Null allowed.
@@ -566,6 +583,7 @@
   void load_klass(Register dst, Register src);
   void load_klass_with_trap_null_check(Register dst, Register src);
   void store_klass(Register dst_oop, Register klass, Register tmp = R0);
+  void store_klass_gap(Register dst_oop, Register val = noreg); // Will store 0 if val not specified.
   static int instr_size_for_decode_klass_not_null();
   void decode_klass_not_null(Register dst, Register src = noreg);
   void encode_klass_not_null(Register dst, Register src = noreg);
@@ -649,6 +667,11 @@
   void _verify_method_ptr(Register reg, const char * msg, const char * file, int line) {}
   void _verify_klass_ptr(Register reg, const char * msg, const char * file, int line) {}
 
+  // Convenience method returning function entry. For the ELFv1 case
+  // creates function descriptor at the current address and returs
+  // the pointer to it. For the ELFv2 case returns the current address.
+  inline address function_entry();
+
 #define verify_method_ptr(reg) _verify_method_ptr(reg, "broken method " #reg, __FILE__, __LINE__)
 #define verify_klass_ptr(reg) _verify_klass_ptr(reg, "broken klass " #reg, __FILE__, __LINE__)
 
@@ -673,4 +696,21 @@
   void zap_from_to(Register low, int before, Register high, int after, Register val, Register addr) PRODUCT_RETURN;
 };
 
+// class SkipIfEqualZero:
+//
+// Instantiating this class will result in assembly code being output that will
+// jump around any code emitted between the creation of the instance and it's
+// automatic destruction at the end of a scope block, depending on the value of
+// the flag passed to the constructor, which will be checked at run-time.
+class SkipIfEqualZero : public StackObj {
+ private:
+  MacroAssembler* _masm;
+  Label _label;
+
+ public:
+   // 'Temp' is a temp register that this object can use (and trash).
+   explicit SkipIfEqualZero(MacroAssembler*, Register temp, const bool* flag_addr);
+   ~SkipIfEqualZero();
+};
+
 #endif // CPU_PPC_VM_MACROASSEMBLER_PPC_HPP
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.inline.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.inline.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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
@@ -321,6 +321,15 @@
   }
 }
 
+inline void MacroAssembler::store_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1, Register tmp) {
+  if (UseCompressedOops) {
+    Register compressedOop = encode_heap_oop_not_null((tmp != noreg) ? tmp : d, d);
+    stw(compressedOop, offs, s1);
+  } else {
+    std(d, offs, s1);
+  }
+}
+
 inline void MacroAssembler::load_heap_oop(Register d, RegisterOrConstant offs, Register s1) {
   if (UseCompressedOops) {
     lwz(d, offs, s1);
@@ -330,13 +339,17 @@
   }
 }
 
-inline void MacroAssembler::encode_heap_oop_not_null(Register d) {
+inline Register MacroAssembler::encode_heap_oop_not_null(Register d, Register src) {
+  Register current = (src!=noreg) ? src : d; // Compressed oop is in d if no src provided.
   if (Universe::narrow_oop_base() != NULL) {
-    sub(d, d, R30);
+    sub(d, current, R30);
+    current = d;
   }
   if (Universe::narrow_oop_shift() != 0) {
-    srdi(d, d, LogMinObjAlignmentInBytes);
+    srdi(d, current, LogMinObjAlignmentInBytes);
+    current = d;
   }
+  return current; // Encoded oop is in this register.
 }
 
 inline void MacroAssembler::decode_heap_oop_not_null(Register d) {
@@ -385,4 +398,10 @@
   twi(traptoEqual | traptoGreaterThanUnsigned, a/*reg a*/, si16);
 }
 
+#if defined(ABI_ELFv2)
+inline address MacroAssembler::function_entry() { return pc(); }
+#else
+inline address MacroAssembler::function_entry() { return emit_fd(); }
+#endif
+
 #endif // CPU_PPC_VM_MACROASSEMBLER_PPC_INLINE_HPP
--- a/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -453,11 +453,11 @@
 
   if (Verbose) {
     tty->print_cr("Registers:");
-    const int abi_offset = frame::abi_112_size / 8;
+    const int abi_offset = frame::abi_reg_args_size / 8;
     for (int i = R3->encoding(); i <= R12->encoding(); i++) {
       Register r = as_Register(i);
       int count = i - R3->encoding();
-      // The registers are stored in reverse order on the stack (by save_volatile_gprs(R1_SP, abi_112_size)).
+      // The registers are stored in reverse order on the stack (by save_volatile_gprs(R1_SP, abi_reg_args_size)).
       tty->print("%3s=" PTR_FORMAT, r->name(), saved_regs[abi_offset + count]);
       if ((count + 1) % 4 == 0) {
         tty->cr();
@@ -524,9 +524,9 @@
   __ save_LR_CR(R0);
   __ mr(R0, R1_SP);                     // saved_sp
   assert(Assembler::is_simm(-nbytes_save, 16), "Overwriting R0");
-  // push_frame_abi112 only uses R0 if nbytes_save is wider than 16 bit
-  __ push_frame_abi112(nbytes_save, R0);
-  __ save_volatile_gprs(R1_SP, frame::abi_112_size); // Except R0.
+  // Push_frame_reg_args only uses R0 if nbytes_save is wider than 16 bit.
+  __ push_frame_reg_args(nbytes_save, R0);
+  __ save_volatile_gprs(R1_SP, frame::abi_reg_args_size); // Except R0.
 
   __ load_const(R3_ARG1, (address)adaptername);
   __ mr(R4_ARG2, R23_method_handle);
--- a/hotspot/src/cpu/ppc/vm/ppc.ad	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad	Tue Mar 25 20:32:46 2014 -0400
@@ -1008,7 +1008,11 @@
 }
 
 int MachCallRuntimeNode::ret_addr_offset() {
+#if defined(ABI_ELFv2)
+  return 28;
+#else
   return 40;
+#endif
 }
 
 //=============================================================================
@@ -3674,6 +3678,10 @@
     MacroAssembler _masm(&cbuf);
     const address start_pc = __ pc();
 
+#if defined(ABI_ELFv2)
+    address entry= !($meth$$method) ? NULL : (address)$meth$$method;
+    __ call_c(entry, relocInfo::runtime_call_type);
+#else
     // The function we're going to call.
     FunctionDescriptor fdtemp;
     const FunctionDescriptor* fd = !($meth$$method) ? &fdtemp : (FunctionDescriptor*)$meth$$method;
@@ -3684,6 +3692,7 @@
     // Put entry, env, toc into the constant pool, this needs up to 3 constant
     // pool entries; call_c_using_toc will optimize the call.
     __ call_c_using_toc(fd, relocInfo::runtime_call_type, Rtoc);
+#endif
 
     // Check the ret_addr_offset.
     assert(((MachCallRuntimeNode*)this)->ret_addr_offset() ==  __ last_calls_return_pc() - start_pc,
@@ -3699,20 +3708,25 @@
     __ mtctr($src$$Register);
   %}
 
-  // postalloc expand emitter for runtime leaf calls.
+  // Postalloc expand emitter for runtime leaf calls.
   enc_class postalloc_expand_java_to_runtime_call(method meth, iRegLdst toc) %{
+    loadConLNodesTuple loadConLNodes_Entry;
+#if defined(ABI_ELFv2)
+    jlong entry_address = (jlong) this->entry_point();
+    assert(entry_address, "need address here");
+    loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper(entry_address),
+                                                    OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
+#else
     // Get the struct that describes the function we are about to call.
     FunctionDescriptor* fd = (FunctionDescriptor*) this->entry_point();
     assert(fd, "need fd here");
+    jlong entry_address = (jlong) fd->entry();
     // new nodes
-    loadConLNodesTuple loadConLNodes_Entry;
     loadConLNodesTuple loadConLNodes_Env;
     loadConLNodesTuple loadConLNodes_Toc;
-    MachNode         *mtctr = NULL;
-    MachCallLeafNode *call  = NULL;
 
     // Create nodes and operands for loading the entry point.
-    loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong) fd->entry()),
+    loadConLNodes_Entry = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper(entry_address),
                                                     OptoReg::Name(R12_H_num), OptoReg::Name(R12_num));
 
 
@@ -3733,8 +3747,9 @@
     // Create nodes and operands for loading the Toc point.
     loadConLNodes_Toc = loadConLNodesTuple_create(C, ra_, n_toc, new (C) immLOper((jlong) fd->toc()),
                                                   OptoReg::Name(R2_H_num), OptoReg::Name(R2_num));
+#endif // ABI_ELFv2
     // mtctr node
-    mtctr = new (C) CallLeafDirect_mtctrNode();
+    MachNode *mtctr = new (C) CallLeafDirect_mtctrNode();
 
     assert(loadConLNodes_Entry._last != NULL, "entry must exist");
     mtctr->add_req(0, loadConLNodes_Entry._last);
@@ -3743,10 +3758,10 @@
     mtctr->_opnds[1] = new (C) iRegLdstOper();
 
     // call node
-    call = new (C) CallLeafDirectNode();
+    MachCallLeafNode *call = new (C) CallLeafDirectNode();
 
     call->_opnds[0] = _opnds[0];
-    call->_opnds[1] = new (C) methodOper((intptr_t) fd->entry()); // may get set later
+    call->_opnds[1] = new (C) methodOper((intptr_t) entry_address); // May get set later.
 
     // Make the new call node look like the old one.
     call->_name        = _name;
@@ -3773,8 +3788,10 @@
     // These must be reqired edges, as the registers are live up to
     // the call. Else the constants are handled as kills.
     call->add_req(mtctr);
+#if !defined(ABI_ELFv2)
     call->add_req(loadConLNodes_Env._last);
     call->add_req(loadConLNodes_Toc._last);
+#endif
 
     // ...as well as prec
     for (uint i = req(); i < len(); ++i) {
@@ -3787,10 +3804,12 @@
     // Insert the new nodes.
     if (loadConLNodes_Entry._large_hi) nodes->push(loadConLNodes_Entry._large_hi);
     if (loadConLNodes_Entry._last)     nodes->push(loadConLNodes_Entry._last);
+#if !defined(ABI_ELFv2)
     if (loadConLNodes_Env._large_hi)   nodes->push(loadConLNodes_Env._large_hi);
     if (loadConLNodes_Env._last)       nodes->push(loadConLNodes_Env._last);
     if (loadConLNodes_Toc._large_hi)   nodes->push(loadConLNodes_Toc._large_hi);
     if (loadConLNodes_Toc._last)       nodes->push(loadConLNodes_Toc._last);
+#endif
     nodes->push(mtctr);
     nodes->push(call);
   %}
@@ -3837,7 +3856,7 @@
   // out_preserve_stack_slots for calls to C. Supports the var-args
   // backing area for register parms.
   //
-  varargs_C_out_slots_killed(((frame::abi_112_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
+  varargs_C_out_slots_killed(((frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size));
 
   // The after-PROLOG location of the return address. Location of
   // return address specifies a type (REG or STACK) and a number
--- a/hotspot/src/cpu/ppc/vm/register_ppc.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/register_ppc.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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
@@ -579,15 +579,27 @@
 
 // Register declarations to be used in frame manager assembly code.
 // Use only non-volatile registers in order to keep values across C-calls.
+#ifdef CC_INTERP
 REGISTER_DECLARATION(Register, R14_state,      R14);      // address of new cInterpreter.
 REGISTER_DECLARATION(Register, R15_prev_state, R15);      // address of old cInterpreter
+#else // CC_INTERP
+REGISTER_DECLARATION(Register, R14_bcp,        R14);
+REGISTER_DECLARATION(Register, R15_esp,        R15);
+REGISTER_DECLARATION(FloatRegister, F15_ftos,  F15);
+#endif // CC_INTERP
 REGISTER_DECLARATION(Register, R16_thread,     R16);      // address of current thread
 REGISTER_DECLARATION(Register, R17_tos,        R17);      // address of Java tos (prepushed).
 REGISTER_DECLARATION(Register, R18_locals,     R18);      // address of first param slot (receiver).
 REGISTER_DECLARATION(Register, R19_method,     R19);      // address of current method
 #ifndef DONT_USE_REGISTER_DEFINES
+#ifdef CC_INTERP
 #define R14_state         AS_REGISTER(Register, R14)
 #define R15_prev_state    AS_REGISTER(Register, R15)
+#else // CC_INTERP
+#define R14_bcp           AS_REGISTER(Register, R14)
+#define R15_esp           AS_REGISTER(Register, R15)
+#define F15_ftos          AS_REGISTER(FloatRegister, F15)
+#endif // CC_INTERP
 #define R16_thread        AS_REGISTER(Register, R16)
 #define R17_tos           AS_REGISTER(Register, R17)
 #define R18_locals        AS_REGISTER(Register, R18)
@@ -608,6 +620,14 @@
 REGISTER_DECLARATION(Register, R27_tmp7, R27);
 REGISTER_DECLARATION(Register, R28_tmp8, R28);
 REGISTER_DECLARATION(Register, R29_tmp9, R29);
+#ifndef CC_INTERP
+REGISTER_DECLARATION(Register, R24_dispatch_addr,     R24);
+REGISTER_DECLARATION(Register, R25_templateTableBase, R25);
+REGISTER_DECLARATION(Register, R26_monitor,           R26);
+REGISTER_DECLARATION(Register, R27_constPoolCache,    R27);
+REGISTER_DECLARATION(Register, R28_mdx,               R28);
+#endif // CC_INTERP
+
 #ifndef DONT_USE_REGISTER_DEFINES
 #define R21_tmp1         AS_REGISTER(Register, R21)
 #define R22_tmp2         AS_REGISTER(Register, R22)
@@ -618,6 +638,16 @@
 #define R27_tmp7         AS_REGISTER(Register, R27)
 #define R28_tmp8         AS_REGISTER(Register, R28)
 #define R29_tmp9         AS_REGISTER(Register, R29)
+#ifndef CC_INTERP
+//    Lmonitors  : monitor pointer
+//    LcpoolCache: constant pool cache
+//    mdx: method data index
+#define R24_dispatch_addr     AS_REGISTER(Register, R24)
+#define R25_templateTableBase AS_REGISTER(Register, R25)
+#define R26_monitor           AS_REGISTER(Register, R26)
+#define R27_constPoolCache    AS_REGISTER(Register, R27)
+#define R28_mdx               AS_REGISTER(Register, R28)
+#endif
 
 #define CCR4_is_synced AS_REGISTER(ConditionRegister, CCR4)
 #endif
--- a/hotspot/src/cpu/ppc/vm/runtime_ppc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/runtime_ppc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -87,7 +87,7 @@
 
   address start = __ pc();
 
-  int frame_size_in_bytes = frame::abi_112_size;
+  int frame_size_in_bytes = frame::abi_reg_args_size;
   OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
 
   // Exception pc is 'return address' for stack walker.
@@ -99,7 +99,7 @@
 
   // Save callee-saved registers.
   // Push a C frame for the exception blob. It is needed for the C call later on.
-  __ push_frame_abi112(0, R11_scratch1);
+  __ push_frame_reg_args(0, R11_scratch1);
 
   // This call does all the hard work. It checks if an exception handler
   // exists in the method.
@@ -109,8 +109,12 @@
   __ set_last_Java_frame(/*sp=*/R1_SP, noreg);
 
   __ mr(R3_ARG1, R16_thread);
+#if defined(ABI_ELFv2)
+  __ call_c((address) OptoRuntime::handle_exception_C, relocInfo::none);
+#else
   __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, OptoRuntime::handle_exception_C),
             relocInfo::none);
+#endif
   address calls_return_pc = __ last_calls_return_pc();
 # ifdef ASSERT
   __ cmpdi(CCR0, R3_RET, 0);
@@ -162,7 +166,11 @@
   __ bind(mh_callsite);
   __ mr(R31, R3_RET); // Save branch address.
   __ mr(R3_ARG1, R16_thread);
+#if defined(ABI_ELFv2)
+  __ call_c((address) adjust_SP_for_methodhandle_callsite, relocInfo::none);
+#else
   __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, adjust_SP_for_methodhandle_callsite), relocInfo::none);
+#endif
   // Returns unextended_sp in R3_RET.
 
   __ mtctr(R31); // Move address of exception handler to SR_CTR.
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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
@@ -67,7 +67,7 @@
     return_pc_is_thread_saved_exception_pc
   };
 
-  static OopMap* push_frame_abi112_and_save_live_registers(MacroAssembler* masm,
+  static OopMap* push_frame_reg_args_and_save_live_registers(MacroAssembler* masm,
                          int* out_frame_size_in_bytes,
                          bool generate_oop_map,
                          int return_pc_adjustment,
@@ -200,12 +200,12 @@
   RegisterSaver_LiveIntReg(   R30 ), // r30 must be the last register
 };
 
-OopMap* RegisterSaver::push_frame_abi112_and_save_live_registers(MacroAssembler* masm,
+OopMap* RegisterSaver::push_frame_reg_args_and_save_live_registers(MacroAssembler* masm,
                          int* out_frame_size_in_bytes,
                          bool generate_oop_map,
                          int return_pc_adjustment,
                          ReturnPCLocation return_pc_location) {
-  // Push an abi112-frame and store all registers which may be live.
+  // Push an abi_reg_args-frame and store all registers which may be live.
   // If requested, create an OopMap: Record volatile registers as
   // callee-save values in an OopMap so their save locations will be
   // propagated to the RegisterMap of the caller frame during
@@ -221,7 +221,7 @@
                                    sizeof(RegisterSaver::LiveRegType);
   const int register_save_size   = regstosave_num * reg_size;
   const int frame_size_in_bytes  = round_to(register_save_size, frame::alignment_in_bytes)
-                                   + frame::abi_112_size;
+                                   + frame::abi_reg_args_size;
   *out_frame_size_in_bytes       = frame_size_in_bytes;
   const int frame_size_in_slots  = frame_size_in_bytes / sizeof(jint);
   const int register_save_offset = frame_size_in_bytes - register_save_size;
@@ -229,7 +229,7 @@
   // OopMap frame size is in c2 stack slots (sizeof(jint)) not bytes or words.
   OopMap* map = generate_oop_map ? new OopMap(frame_size_in_slots, 0) : NULL;
 
-  BLOCK_COMMENT("push_frame_abi112_and_save_live_registers {");
+  BLOCK_COMMENT("push_frame_reg_args_and_save_live_registers {");
 
   // Save r30 in the last slot of the not yet pushed frame so that we
   // can use it as scratch reg.
@@ -294,7 +294,7 @@
     offset += reg_size;
   }
 
-  BLOCK_COMMENT("} push_frame_abi112_and_save_live_registers");
+  BLOCK_COMMENT("} push_frame_reg_args_and_save_live_registers");
 
   // And we're done.
   return map;
@@ -699,15 +699,19 @@
 
   int i;
   VMReg reg;
-  // Leave room for C-compatible ABI_112.
-  int stk = (frame::abi_112_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size;
+  // Leave room for C-compatible ABI_REG_ARGS.
+  int stk = (frame::abi_reg_args_size - frame::jit_out_preserve_size) / VMRegImpl::stack_slot_size;
   int arg = 0;
   int freg = 0;
 
   // Avoid passing C arguments in the wrong stack slots.
+#if defined(ABI_ELFv2)
+  assert((SharedRuntime::out_preserve_stack_slots() + stk) * VMRegImpl::stack_slot_size == 96,
+         "passing C arguments in wrong stack slots");
+#else
   assert((SharedRuntime::out_preserve_stack_slots() + stk) * VMRegImpl::stack_slot_size == 112,
          "passing C arguments in wrong stack slots");
-
+#endif
   // We fill-out regs AND regs2 if an argument must be passed in a
   // register AND in a stack slot. If regs2 is NULL in such a
   // situation, we bail-out with a fatal error.
@@ -953,6 +957,9 @@
 
 #ifdef CC_INTERP
   const Register tos = R17_tos;
+#else
+  const Register tos = R15_esp;
+  __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R11_scratch1);
 #endif
 
   // load TOS
@@ -971,7 +978,7 @@
                             const BasicType *sig_bt,
                             const VMRegPair *regs) {
 
-  // Load method's entry-point from methodOop.
+  // Load method's entry-point from method.
   __ ld(R12_scratch2, in_bytes(Method::from_compiled_offset()), R19_method);
   __ mtctr(R12_scratch2);
 
@@ -992,7 +999,10 @@
 
 #ifdef CC_INTERP
   const Register ld_ptr = R17_tos;
+#else
+  const Register ld_ptr = R15_esp;
 #endif
+
   const Register value_regs[] = { R22_tmp2, R23_tmp3, R24_tmp4, R25_tmp5, R26_tmp6 };
   const int num_value_regs = sizeof(value_regs) / sizeof(Register);
   int value_regs_index = 0;
@@ -1083,8 +1093,8 @@
     }
   }
 
-  BLOCK_COMMENT("Store method oop");
-  // Store method oop into thread->callee_target.
+  BLOCK_COMMENT("Store method");
+  // Store method into thread->callee_target.
   // We might end up in handle_wrong_method if the callee is
   // deoptimized as we race thru here. If that happens we don't want
   // to take a safepoint because the caller frame will look
@@ -1504,7 +1514,11 @@
 
   __ block_comment("block_for_jni_critical");
   address entry_point = CAST_FROM_FN_PTR(address, SharedRuntime::block_for_jni_critical);
+#if defined(ABI_ELFv2)
+  __ call_c(entry_point, relocInfo::runtime_call_type);
+#else
   __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, entry_point), relocInfo::runtime_call_type);
+#endif
   address start           = __ pc() - __ offset(),
           calls_return_pc = __ last_calls_return_pc();
   oop_maps->add_gc_map(calls_return_pc - start, map);
@@ -1877,7 +1891,7 @@
   // Layout of the native wrapper frame:
   // (stack grows upwards, memory grows downwards)
   //
-  // NW     [ABI_112]                  <-- 1) R1_SP
+  // NW     [ABI_REG_ARGS]             <-- 1) R1_SP
   //        [outgoing arguments]       <-- 2) R1_SP + out_arg_slot_offset
   //        [oopHandle area]           <-- 3) R1_SP + oop_handle_offset (save area for critical natives)
   //        klass                      <-- 4) R1_SP + klass_offset
@@ -2211,8 +2225,8 @@
     // slow case of monitor enter. Inline a special case of call_VM that
     // disallows any pending_exception.
 
-    // Save argument registers and leave room for C-compatible ABI_112.
-    int frame_size = frame::abi_112_size +
+    // Save argument registers and leave room for C-compatible ABI_REG_ARGS.
+    int frame_size = frame::abi_reg_args_size +
                      round_to(total_c_args * wordSize, frame::alignment_in_bytes);
     __ mr(R11_scratch1, R1_SP);
     RegisterSaver::push_frame_and_save_argument_registers(masm, R12_scratch2, frame_size, total_c_args, out_regs, out_regs2);
@@ -2250,9 +2264,12 @@
 
   // The JNI call
   // --------------------------------------------------------------------------
-
+#if defined(ABI_ELFv2)
+  __ call_c(native_func, relocInfo::runtime_call_type);
+#else
   FunctionDescriptor* fd_native_method = (FunctionDescriptor*) native_func;
   __ call_c(fd_native_method, relocInfo::runtime_call_type);
+#endif
 
 
   // Now, we are back from the native code.
@@ -2606,8 +2623,12 @@
 #ifdef CC_INTERP
   __ std(R1_SP, _parent_ijava_frame_abi(initial_caller_sp), R1_SP);
 #else
-  Unimplemented();
+#ifdef ASSERT
+  __ load_const_optimized(pc_reg, 0x5afe);
+  __ std(pc_reg, _ijava_state_neg(ijava_reserved), R1_SP);
 #endif
+  __ std(R1_SP, _ijava_state_neg(sender_sp), R1_SP);
+#endif // CC_INTERP
   __ addi(number_of_frames_reg, number_of_frames_reg, -1);
   __ addi(frame_sizes_reg, frame_sizes_reg, wordSize);
   __ addi(pcs_reg, pcs_reg, wordSize);
@@ -2679,7 +2700,15 @@
   __ std(R12_scratch2, _abi(lr), R1_SP);
 
   // Initialize initial_caller_sp.
+#ifdef CC_INTERP
   __ std(frame_size_reg/*old_sp*/, _parent_ijava_frame_abi(initial_caller_sp), R1_SP);
+#else
+#ifdef ASSERT
+ __ load_const_optimized(pc_reg, 0x5afe);
+ __ std(pc_reg, _ijava_state_neg(ijava_reserved), R1_SP);
+#endif
+ __ std(frame_size_reg, _ijava_state_neg(sender_sp), R1_SP);
+#endif // CC_INTERP
 
 #ifdef ASSERT
   // Make sure that there is at least one entry in the array.
@@ -2724,7 +2753,7 @@
   OopMapSet *oop_maps = new OopMapSet();
 
   // size of ABI112 plus spill slots for R3_RET and F1_RET.
-  const int frame_size_in_bytes = frame::abi_112_spill_size;
+  const int frame_size_in_bytes = frame::abi_reg_args_spill_size;
   const int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
   int first_frame_size_in_bytes = 0; // frame size of "unpack frame" for call to fetch_unroll_info.
 
@@ -2757,11 +2786,11 @@
 
   // Push the "unpack frame"
   // Save everything in sight.
-  map = RegisterSaver::push_frame_abi112_and_save_live_registers(masm,
-                                                                 &first_frame_size_in_bytes,
-                                                                 /*generate_oop_map=*/ true,
-                                                                 return_pc_adjustment_no_exception,
-                                                                 RegisterSaver::return_pc_is_lr);
+  map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm,
+                                                                   &first_frame_size_in_bytes,
+                                                                   /*generate_oop_map=*/ true,
+                                                                   return_pc_adjustment_no_exception,
+                                                                   RegisterSaver::return_pc_is_lr);
   assert(map != NULL, "OopMap must have been created");
 
   __ li(exec_mode_reg, Deoptimization::Unpack_deopt);
@@ -2787,11 +2816,11 @@
   // Push the "unpack frame".
   // Save everything in sight.
   assert(R4 == R4_ARG2, "exception pc must be in r4");
-  RegisterSaver::push_frame_abi112_and_save_live_registers(masm,
-                                                           &first_frame_size_in_bytes,
-                                                           /*generate_oop_map=*/ false,
-                                                           return_pc_adjustment_exception,
-                                                           RegisterSaver::return_pc_is_r4);
+  RegisterSaver::push_frame_reg_args_and_save_live_registers(masm,
+                                                             &first_frame_size_in_bytes,
+                                                             /*generate_oop_map=*/ false,
+                                                             return_pc_adjustment_exception,
+                                                             RegisterSaver::return_pc_is_r4);
 
   // Deopt during an exception. Save exec mode for unpack_frames.
   __ li(exec_mode_reg, Deoptimization::Unpack_exception);
@@ -2876,8 +2905,8 @@
   // ...).
 
   // Spill live volatile registers since we'll do a call.
-  __ std( R3_RET,  _abi_112_spill(spill_ret),  R1_SP);
-  __ stfd(F1_RET, _abi_112_spill(spill_fret), R1_SP);
+  __ std( R3_RET, _abi_reg_args_spill(spill_ret),  R1_SP);
+  __ stfd(F1_RET, _abi_reg_args_spill(spill_fret), R1_SP);
 
   // Let the unpacker layout information in the skeletal frames just
   // allocated.
@@ -2889,8 +2918,8 @@
   __ reset_last_Java_frame();
 
   // Restore the volatiles saved above.
-  __ ld( R3_RET, _abi_112_spill(spill_ret),  R1_SP);
-  __ lfd(F1_RET, _abi_112_spill(spill_fret), R1_SP);
+  __ ld( R3_RET, _abi_reg_args_spill(spill_ret),  R1_SP);
+  __ lfd(F1_RET, _abi_reg_args_spill(spill_fret), R1_SP);
 
   // Pop the unpack frame.
   __ pop_frame();
@@ -2900,10 +2929,16 @@
   // optional c2i, caller of deoptee, ...).
 
   // Initialize R14_state.
+#ifdef CC_INTERP
   __ ld(R14_state, 0, R1_SP);
   __ addi(R14_state, R14_state, -frame::interpreter_frame_cinterpreterstate_size_in_bytes());
   // Also inititialize R15_prev_state.
   __ restore_prev_state();
+#else
+  __ restore_interpreter_state(R11_scratch1);
+  __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R11_scratch1);
+#endif // CC_INTERP
+
 
   // Return to the interpreter entry point.
   __ blr();
@@ -2930,7 +2965,7 @@
   Register unc_trap_reg     = R23_tmp3;
 
   OopMapSet* oop_maps = new OopMapSet();
-  int frame_size_in_bytes = frame::abi_112_size;
+  int frame_size_in_bytes = frame::abi_reg_args_size;
   OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
 
   // stack: (deoptee, optional i2c, caller_of_deoptee, ...).
@@ -2943,7 +2978,7 @@
   __ save_LR_CR(R11_scratch1);
 
   // Push an "uncommon_trap" frame.
-  __ push_frame_abi112(0, R11_scratch1);
+  __ push_frame_reg_args(0, R11_scratch1);
 
   // stack: (unpack frame, deoptee, optional i2c, caller_of_deoptee, ...).
 
@@ -2996,7 +3031,7 @@
   // interpreter frames just created.
 
   // Push a simple "unpack frame" here.
-  __ push_frame_abi112(0, R11_scratch1);
+  __ push_frame_reg_args(0, R11_scratch1);
 
   // stack: (unpack frame, skeletal interpreter frame, ..., optional
   // skeletal interpreter frame, optional c2i, caller of deoptee,
@@ -3022,11 +3057,17 @@
   // stack: (top interpreter frame, ..., optional interpreter frame,
   // optional c2i, caller of deoptee, ...).
 
+#ifdef CC_INTERP
   // Initialize R14_state, ...
   __ ld(R11_scratch1, 0, R1_SP);
   __ addi(R14_state, R11_scratch1, -frame::interpreter_frame_cinterpreterstate_size_in_bytes());
   // also initialize R15_prev_state.
   __ restore_prev_state();
+#else
+  __ restore_interpreter_state(R11_scratch1);
+  __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R11_scratch1);
+#endif // CC_INTERP
+
   // Return to the interpreter entry point.
   __ blr();
 
@@ -3064,11 +3105,11 @@
   }
 
   // Save registers, fpu state, and flags.
-  map = RegisterSaver::push_frame_abi112_and_save_live_registers(masm,
-                                                                 &frame_size_in_bytes,
-                                                                 /*generate_oop_map=*/ true,
-                                                                 /*return_pc_adjustment=*/0,
-                                                                 return_pc_location);
+  map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm,
+                                                                   &frame_size_in_bytes,
+                                                                   /*generate_oop_map=*/ true,
+                                                                   /*return_pc_adjustment=*/0,
+                                                                   return_pc_location);
 
   // The following is basically a call_VM. However, we need the precise
   // address of the call in order to generate an oopmap. Hence, we do all the
@@ -3104,7 +3145,6 @@
                                                       frame_size_in_bytes,
                                                       /*restore_ctr=*/true);
 
-
   BLOCK_COMMENT("  Jump to forward_exception_entry.");
   // Jump to forward_exception_entry, with the issuing PC in LR
   // so it looks like the original nmethod called forward_exception_entry.
@@ -3151,11 +3191,11 @@
 
   address start = __ pc();
 
-  map = RegisterSaver::push_frame_abi112_and_save_live_registers(masm,
-                                                                 &frame_size_in_bytes,
-                                                                 /*generate_oop_map*/ true,
-                                                                 /*return_pc_adjustment*/ 0,
-                                                                 RegisterSaver::return_pc_is_lr);
+  map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm,
+                                                                   &frame_size_in_bytes,
+                                                                   /*generate_oop_map*/ true,
+                                                                   /*return_pc_adjustment*/ 0,
+                                                                   RegisterSaver::return_pc_is_lr);
 
   // Use noreg as last_Java_pc, the return pc will be reconstructed
   // from the physical frame.
@@ -3189,7 +3229,7 @@
 
   RegisterSaver::restore_live_registers_and_pop_frame(masm, frame_size_in_bytes, /*restore_ctr*/ false);
 
-  // Get the returned methodOop.
+  // Get the returned method.
   __ get_vm_result_2(R19_method);
 
   __ bctr();
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012, 2013 SAP AG. All rights reserved.
+ * Copyright 2012, 2014 SAP AG. 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
@@ -39,15 +39,10 @@
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "utilities/top.hpp"
-#ifdef TARGET_OS_FAMILY_aix
-# include "thread_aix.inline.hpp"
-#endif
-#ifdef TARGET_OS_FAMILY_linux
-# include "thread_linux.inline.hpp"
-#endif
 #ifdef COMPILER2
 #include "opto/runtime.hpp"
 #endif
+#include "runtime/thread.inline.hpp"
 
 #define __ _masm->
 
@@ -79,11 +74,11 @@
 
     StubCodeMark mark(this, "StubRoutines", "call_stub");
 
-    address start = __ emit_fd();
+    address start = __ function_entry();
 
     // some sanity checks
-    assert((sizeof(frame::abi_48) % 16) == 0,                 "unaligned");
-    assert((sizeof(frame::abi_112) % 16) == 0,                "unaligned");
+    assert((sizeof(frame::abi_minframe) % 16) == 0,           "unaligned");
+    assert((sizeof(frame::abi_reg_args) % 16) == 0,           "unaligned");
     assert((sizeof(frame::spill_nonvolatiles) % 16) == 0,     "unaligned");
     assert((sizeof(frame::parent_ijava_frame_abi) % 16) == 0, "unaligned");
     assert((sizeof(frame::entry_frame_locals) % 16) == 0,     "unaligned");
@@ -221,7 +216,7 @@
     {
       BLOCK_COMMENT("Call frame manager or native entry.");
       // Call frame manager or native entry.
-      Register r_new_arg_entry = R14_state;
+      Register r_new_arg_entry = R14; // PPC_state;
       assert_different_registers(r_new_arg_entry, r_top_of_arguments_addr,
                                  r_arg_method, r_arg_thread);
 
@@ -234,7 +229,11 @@
       //   R16_thread  -  JavaThread*
 
       // Tos must point to last argument - element_size.
+#ifdef CC_INTERP
       const Register tos = R17_tos;
+#else
+      const Register tos = R15_esp;
+#endif
       __ addi(tos, r_top_of_arguments_addr, -Interpreter::stackElementSize);
 
       // initialize call_stub locals (step 2)
@@ -248,8 +247,11 @@
       assert(tos != r_arg_thread && R19_method != r_arg_thread, "trashed r_arg_thread");
 
       // Set R15_prev_state to 0 for simplifying checks in callee.
+#ifdef CC_INTERP
       __ li(R15_prev_state, 0);
-
+#else
+      __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R11_scratch1);
+#endif
       // Stack on entry to frame manager / native entry:
       //
       //      F0      [TOP_IJAVA_FRAME_ABI]
@@ -444,7 +446,7 @@
 
     // Save LR/CR and copy exception pc (LR) into R4_ARG2.
     __ save_LR_CR(R4_ARG2);
-    __ push_frame_abi112(0, R0);
+    __ push_frame_reg_args(0, R0);
     // Find exception handler.
     __ call_VM_leaf(CAST_FROM_FN_PTR(address,
                      SharedRuntime::exception_handler_for_return_address),
@@ -519,7 +521,7 @@
     MacroAssembler* masm = new MacroAssembler(&code);
 
     OopMapSet* oop_maps  = new OopMapSet();
-    int frame_size_in_bytes = frame::abi_112_size;
+    int frame_size_in_bytes = frame::abi_reg_args_size;
     OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
 
     StubCodeMark mark(this, "StubRoutines", "throw_exception");
@@ -529,7 +531,7 @@
     __ save_LR_CR(R11_scratch1);
 
     // Push a frame.
-    __ push_frame_abi112(0, R11_scratch1);
+    __ push_frame_reg_args(0, R11_scratch1);
 
     address frame_complete_pc = __ pc();
 
@@ -551,8 +553,11 @@
     if (arg2 != noreg) {
       __ mr(R5_ARG3, arg2);
     }
-    __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, runtime_entry),
-              relocInfo::none);
+#if defined(ABI_ELFv2)
+    __ call_c(runtime_entry, relocInfo::none);
+#else
+    __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, runtime_entry), relocInfo::none);
+#endif
 
     // Set an oopmap for the call site.
     oop_maps->add_gc_map((int)(gc_map_pc - start), map);
@@ -614,7 +619,7 @@
         // With G1, don't generate the call if we statically know that the target in uninitialized
         if (!dest_uninitialized) {
           const int spill_slots = 4 * wordSize;
-          const int frame_size  = frame::abi_112_size + spill_slots;
+          const int frame_size  = frame::abi_reg_args_size + spill_slots;
           Label filtered;
 
           // Is marking active?
@@ -628,7 +633,7 @@
           __ beq(CCR0, filtered);
 
           __ save_LR_CR(R0);
-          __ push_frame_abi112(spill_slots, R0);
+          __ push_frame_reg_args(spill_slots, R0);
           __ std(from,  frame_size - 1 * wordSize, R1_SP);
           __ std(to,    frame_size - 2 * wordSize, R1_SP);
           __ std(count, frame_size - 3 * wordSize, R1_SP);
@@ -672,7 +677,7 @@
           if (branchToEnd) {
             __ save_LR_CR(R0);
             // We need this frame only to spill LR.
-            __ push_frame_abi112(0, R0);
+            __ push_frame_reg_args(0, R0);
             __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), addr, count);
             __ pop_frame();
             __ restore_LR_CR(R0);
@@ -742,7 +747,7 @@
     StubCodeMark mark(this, "StubRoutines", "zero_words_aligned8");
 
     // Implemented as in ClearArray.
-    address start = __ emit_fd();
+    address start = __ function_entry();
 
     Register base_ptr_reg   = R3_ARG1; // tohw (needs to be 8b aligned)
     Register cnt_dwords_reg = R4_ARG2; // count (in dwords)
@@ -820,7 +825,7 @@
   //
   address generate_handler_for_unsafe_access() {
     StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
-    address start = __ emit_fd();
+    address start = __ function_entry();
     __ unimplemented("StubRoutines::handler_for_unsafe_access", 93);
     return start;
   }
@@ -861,7 +866,7 @@
   // to read from the safepoint polling page.
   address generate_load_from_poll() {
     StubCodeMark mark(this, "StubRoutines", "generate_load_from_poll");
-    address start = __ emit_fd();
+    address start = __ function_entry();
     __ unimplemented("StubRoutines::verify_oop", 95);  // TODO PPC port
     return start;
   }
@@ -885,7 +890,7 @@
   //
   address generate_fill(BasicType t, bool aligned, const char* name) {
     StubCodeMark mark(this, "StubRoutines", name);
-    address start = __ emit_fd();
+    address start = __ function_entry();
 
     const Register to    = R3_ARG1;   // source array address
     const Register value = R4_ARG2;   // fill value
@@ -1123,7 +1128,7 @@
   //
   address generate_disjoint_byte_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
-    address start = __ emit_fd();
+    address start = __ function_entry();
 
     Register tmp1 = R6_ARG4;
     Register tmp2 = R7_ARG5;
@@ -1254,15 +1259,21 @@
   //
   address generate_conjoint_byte_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
-    address start = __ emit_fd();
+    address start = __ function_entry();
 
     Register tmp1 = R6_ARG4;
     Register tmp2 = R7_ARG5;
     Register tmp3 = R8_ARG6;
 
+#if defined(ABI_ELFv2)
+     address nooverlap_target = aligned ?
+       StubRoutines::arrayof_jbyte_disjoint_arraycopy() :
+       StubRoutines::jbyte_disjoint_arraycopy();
+#else
     address nooverlap_target = aligned ?
       ((FunctionDescriptor*)StubRoutines::arrayof_jbyte_disjoint_arraycopy())->entry() :
       ((FunctionDescriptor*)StubRoutines::jbyte_disjoint_arraycopy())->entry();
+#endif
 
     array_overlap_test(nooverlap_target, 0);
     // Do reverse copy. We assume the case of actual overlap is rare enough
@@ -1345,7 +1356,7 @@
     Register tmp3 = R8_ARG6;
     Register tmp4 = R9_ARG7;
 
-    address start = __ emit_fd();
+    address start = __ function_entry();
 
       Label l_1, l_2, l_3, l_4, l_5, l_6, l_7, l_8;
     // don't try anything fancy if arrays don't have many elements
@@ -1474,15 +1485,21 @@
   //
   address generate_conjoint_short_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
-    address start = __ emit_fd();
+    address start = __ function_entry();
 
     Register tmp1 = R6_ARG4;
     Register tmp2 = R7_ARG5;
     Register tmp3 = R8_ARG6;
 
+#if defined(ABI_ELFv2)
+    address nooverlap_target = aligned ?
+        StubRoutines::arrayof_jshort_disjoint_arraycopy() :
+        StubRoutines::jshort_disjoint_arraycopy();
+#else
     address nooverlap_target = aligned ?
         ((FunctionDescriptor*)StubRoutines::arrayof_jshort_disjoint_arraycopy())->entry() :
         ((FunctionDescriptor*)StubRoutines::jshort_disjoint_arraycopy())->entry();
+#endif
 
     array_overlap_test(nooverlap_target, 1);
 
@@ -1597,7 +1614,7 @@
   //
   address generate_disjoint_int_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
-    address start = __ emit_fd();
+    address start = __ function_entry();
     generate_disjoint_int_copy_core(aligned);
     __ blr();
     return start;
@@ -1681,11 +1698,17 @@
   //
   address generate_conjoint_int_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
-    address start = __ emit_fd();
+    address start = __ function_entry();
 
+#if defined(ABI_ELFv2)
+    address nooverlap_target = aligned ?
+      StubRoutines::arrayof_jint_disjoint_arraycopy() :
+      StubRoutines::jint_disjoint_arraycopy();
+#else
     address nooverlap_target = aligned ?
       ((FunctionDescriptor*)StubRoutines::arrayof_jint_disjoint_arraycopy())->entry() :
       ((FunctionDescriptor*)StubRoutines::jint_disjoint_arraycopy())->entry();
+#endif
 
     array_overlap_test(nooverlap_target, 2);
 
@@ -1767,7 +1790,7 @@
   //
   address generate_disjoint_long_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
-    address start = __ emit_fd();
+    address start = __ function_entry();
     generate_disjoint_long_copy_core(aligned);
     __ blr();
 
@@ -1849,11 +1872,17 @@
   //
   address generate_conjoint_long_copy(bool aligned, const char * name) {
     StubCodeMark mark(this, "StubRoutines", name);
-    address start = __ emit_fd();
+    address start = __ function_entry();
 
+#if defined(ABI_ELFv2)
+    address nooverlap_target = aligned ?
+      StubRoutines::arrayof_jlong_disjoint_arraycopy() :
+      StubRoutines::jlong_disjoint_arraycopy();
+#else
     address nooverlap_target = aligned ?
       ((FunctionDescriptor*)StubRoutines::arrayof_jlong_disjoint_arraycopy())->entry() :
       ((FunctionDescriptor*)StubRoutines::jlong_disjoint_arraycopy())->entry();
+#endif
 
     array_overlap_test(nooverlap_target, 3);
     generate_conjoint_long_copy_core(aligned);
@@ -1875,11 +1904,17 @@
   address generate_conjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) {
     StubCodeMark mark(this, "StubRoutines", name);
 
-    address start = __ emit_fd();
+    address start = __ function_entry();
 
+#if defined(ABI_ELFv2)
+    address nooverlap_target = aligned ?
+      StubRoutines::arrayof_oop_disjoint_arraycopy() :
+      StubRoutines::oop_disjoint_arraycopy();
+#else
     address nooverlap_target = aligned ?
       ((FunctionDescriptor*)StubRoutines::arrayof_oop_disjoint_arraycopy())->entry() :
       ((FunctionDescriptor*)StubRoutines::oop_disjoint_arraycopy())->entry();
+#endif
 
     gen_write_ref_array_pre_barrier(R3_ARG1, R4_ARG2, R5_ARG3, dest_uninitialized, R9_ARG7);
 
@@ -1910,7 +1945,7 @@
   //
   address generate_disjoint_oop_copy(bool aligned, const char * name, bool dest_uninitialized) {
     StubCodeMark mark(this, "StubRoutines", name);
-    address start = __ emit_fd();
+    address start = __ function_entry();
 
     gen_write_ref_array_pre_barrier(R3_ARG1, R4_ARG2, R5_ARG3, dest_uninitialized, R9_ARG7);
 
@@ -1991,7 +2026,7 @@
     StubCodeMark mark(this, "StubRoutines", name);
 
     // Entry point, pc or function descriptor.
-    *entry = __ emit_fd();
+    *entry = __ function_entry();
 
     // Load *adr into R4_ARG2, may fault.
     *fault_pc = __ pc();
@@ -2056,7 +2091,7 @@
       guarantee(!UseAESIntrinsics, "not yet implemented.");
     }
 
-    // PPC uses stubs for safefetch.
+    // Safefetch stubs.
     generate_safefetch("SafeFetch32", sizeof(int),     &StubRoutines::_safefetch32_entry,
                                                        &StubRoutines::_safefetch32_fault_pc,
                                                        &StubRoutines::_safefetch32_continuation_pc);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013, 2014 SAP AG. 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.
+ *
+ */
+
+#ifndef CPU_PPC_VM_TEMPLATEINTERPRETERGENERATOR_PPC_HPP
+#define CPU_PPC_VM_TEMPLATEINTERPRETERGENERATOR_PPC_HPP
+
+ protected:
+  address generate_normal_entry(bool synchronized);
+  address generate_native_entry(bool synchronized);
+  address generate_math_entry(AbstractInterpreter::MethodKind kind);
+  address generate_empty_entry(void);
+
+  void lock_method(Register Rflags, Register Rscratch1, Register Rscratch2, bool flags_preloaded=false);
+  void unlock_method(bool check_exceptions = true);
+
+  void generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue);
+  void generate_counter_overflow(Label& continue_entry);
+
+  void generate_fixed_frame(bool native_call, Register Rsize_of_parameters, Register Rsize_of_locals);
+  void generate_stack_overflow_check(Register Rframe_size, Register Rscratch1);
+
+#endif // CPU_PPC_VM_TEMPLATEINTERPRETERGENERATOR_PPC_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,1813 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013, 2014 SAP AG. 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#ifndef CC_INTERP
+#include "asm/macroAssembler.inline.hpp"
+#include "interpreter/bytecodeHistogram.hpp"
+#include "interpreter/interpreter.hpp"
+#include "interpreter/interpreterGenerator.hpp"
+#include "interpreter/interpreterRuntime.hpp"
+#include "interpreter/templateTable.hpp"
+#include "oops/arrayOop.hpp"
+#include "oops/methodData.hpp"
+#include "oops/method.hpp"
+#include "oops/oop.inline.hpp"
+#include "prims/jvmtiExport.hpp"
+#include "prims/jvmtiThreadState.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/deoptimization.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "runtime/stubRoutines.hpp"
+#include "runtime/synchronizer.hpp"
+#include "runtime/timer.hpp"
+#include "runtime/vframeArray.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/macros.hpp"
+
+#undef __
+#define __ _masm->
+
+#ifdef PRODUCT
+#define BLOCK_COMMENT(str) /* nothing */
+#else
+#define BLOCK_COMMENT(str) __ block_comment(str)
+#endif
+
+#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
+
+//-----------------------------------------------------------------------------
+
+// Actually we should never reach here since we do stack overflow checks before pushing any frame.
+address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
+  address entry = __ pc();
+  __ unimplemented("generate_StackOverflowError_handler");
+  return entry;
+}
+
+address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(const char* name) {
+  address entry = __ pc();
+  __ empty_expression_stack();
+  __ load_const_optimized(R4_ARG2, (address) name);
+  // Index is in R17_tos.
+  __ mr(R5_ARG3, R17_tos);
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException));
+  return entry;
+}
+
+#if 0
+// Call special ClassCastException constructor taking object to cast
+// and target class as arguments.
+address TemplateInterpreterGenerator::generate_ClassCastException_verbose_handler(const char* name) {
+  address entry = __ pc();
+
+  // Target class oop is in register R6_ARG4 by convention!
+
+  // Expression stack must be empty before entering the VM if an
+  // exception happened.
+  __ empty_expression_stack();
+  // Setup parameters.
+  // Thread will be loaded to R3_ARG1.
+  __ load_const_optimized(R4_ARG2, (address) name);
+  __ mr(R5_ARG3, R17_tos);
+  // R6_ARG4 contains specified class.
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ClassCastException_verbose));
+#ifdef ASSERT
+  // Above call must not return here since exception pending.
+  __ should_not_reach_here();
+#endif
+  return entry;
+}
+#endif
+
+address TemplateInterpreterGenerator::generate_ClassCastException_handler() {
+  address entry = __ pc();
+  // Expression stack must be empty before entering the VM if an
+  // exception happened.
+  __ empty_expression_stack();
+
+  // Load exception object.
+  // Thread will be loaded to R3_ARG1.
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ClassCastException), R17_tos);
+#ifdef ASSERT
+  // Above call must not return here since exception pending.
+  __ should_not_reach_here();
+#endif
+  return entry;
+}
+
+address TemplateInterpreterGenerator::generate_exception_handler_common(const char* name, const char* message, bool pass_oop) {
+  address entry = __ pc();
+  //__ untested("generate_exception_handler_common");
+  Register Rexception = R17_tos;
+
+  // Expression stack must be empty before entering the VM if an exception happened.
+  __ empty_expression_stack();
+
+  __ load_const_optimized(R4_ARG2, (address) name, R11_scratch1);
+  if (pass_oop) {
+    __ mr(R5_ARG3, Rexception);
+    __ call_VM(Rexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_klass_exception), false);
+  } else {
+    __ load_const_optimized(R5_ARG3, (address) message, R11_scratch1);
+    __ call_VM(Rexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::create_exception), false);
+  }
+
+  // Throw exception.
+  __ mr(R3_ARG1, Rexception);
+  __ load_const_optimized(R11_scratch1, Interpreter::throw_exception_entry(), R12_scratch2);
+  __ mtctr(R11_scratch1);
+  __ bctr();
+
+  return entry;
+}
+
+address TemplateInterpreterGenerator::generate_continuation_for(TosState state) {
+  address entry = __ pc();
+  __ unimplemented("generate_continuation_for");
+  return entry;
+}
+
+// This entry is returned to when a call returns to the interpreter.
+// When we arrive here, we expect that the callee stack frame is already popped.
+address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
+  address entry = __ pc();
+
+  // Move the value out of the return register back to the TOS cache of current frame.
+  switch (state) {
+    case ltos:
+    case btos:
+    case ctos:
+    case stos:
+    case atos:
+    case itos: __ mr(R17_tos, R3_RET); break;   // RET -> TOS cache
+    case ftos:
+    case dtos: __ fmr(F15_ftos, F1_RET); break; // TOS cache -> GR_FRET
+    case vtos: break;                           // Nothing to do, this was a void return.
+    default  : ShouldNotReachHere();
+  }
+
+  __ restore_interpreter_state(R11_scratch1); // Sets R11_scratch1 = fp.
+  __ ld(R12_scratch2, _ijava_state_neg(top_frame_sp), R11_scratch1);
+  __ resize_frame_absolute(R12_scratch2, R11_scratch1, R0);
+
+  // Compiled code destroys templateTableBase, reload.
+  __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R12_scratch2);
+
+  const Register cache = R11_scratch1;
+  const Register size  = R12_scratch2;
+  __ get_cache_and_index_at_bcp(cache, 1, index_size);
+
+  // Big Endian (get least significant byte of 64 bit value):
+  __ lbz(size, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()) + 7, cache);
+  __ sldi(size, size, Interpreter::logStackElementSize);
+  __ add(R15_esp, R15_esp, size);
+  __ dispatch_next(state, step);
+  return entry;
+}
+
+address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
+  address entry = __ pc();
+  // If state != vtos, we're returning from a native method, which put it's result
+  // into the result register. So move the value out of the return register back
+  // to the TOS cache of current frame.
+
+  switch (state) {
+    case ltos:
+    case btos:
+    case ctos:
+    case stos:
+    case atos:
+    case itos: __ mr(R17_tos, R3_RET); break;   // GR_RET -> TOS cache
+    case ftos:
+    case dtos: __ fmr(F15_ftos, F1_RET); break; // TOS cache -> GR_FRET
+    case vtos: break;                           // Nothing to do, this was a void return.
+    default  : ShouldNotReachHere();
+  }
+
+  // Load LcpoolCache @@@ should be already set!
+  __ get_constant_pool_cache(R27_constPoolCache);
+
+  // Handle a pending exception, fall through if none.
+  __ check_and_forward_exception(R11_scratch1, R12_scratch2);
+
+  // Start executing bytecodes.
+  __ dispatch_next(state, step);
+
+  return entry;
+}
+
+// A result handler converts the native result into java format.
+// Use the shared code between c++ and template interpreter.
+address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type) {
+  return AbstractInterpreterGenerator::generate_result_handler_for(type);
+}
+
+address TemplateInterpreterGenerator::generate_safept_entry_for(TosState state, address runtime_entry) {
+  address entry = __ pc();
+
+  __ push(state);
+  __ call_VM(noreg, runtime_entry);
+  __ dispatch_via(vtos, Interpreter::_normal_table.table_for(vtos));
+
+  return entry;
+}
+
+// Helpers for commoning out cases in the various type of method entries.
+
+// Increment invocation count & check for overflow.
+//
+// Note: checking for negative value instead of overflow
+//       so we have a 'sticky' overflow test.
+//
+void TemplateInterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
+  // Note: In tiered we increment either counters in method or in MDO depending if we're profiling or not.
+  Register Rscratch1   = R11_scratch1;
+  Register Rscratch2   = R12_scratch2;
+  Register R3_counters = R3_ARG1;
+  Label done;
+
+  if (TieredCompilation) {
+    const int increment = InvocationCounter::count_increment;
+    const int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
+    Label no_mdo;
+    if (ProfileInterpreter) {
+      const Register Rmdo = Rscratch1;
+      // If no method data exists, go to profile_continue.
+      __ ld(Rmdo, in_bytes(Method::method_data_offset()), R19_method);
+      __ cmpdi(CCR0, Rmdo, 0);
+      __ beq(CCR0, no_mdo);
+
+      // Increment backedge counter in the MDO.
+      const int mdo_bc_offs = in_bytes(MethodData::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset());
+      __ lwz(Rscratch2, mdo_bc_offs, Rmdo);
+      __ addi(Rscratch2, Rscratch2, increment);
+      __ stw(Rscratch2, mdo_bc_offs, Rmdo);
+      __ load_const_optimized(Rscratch1, mask, R0);
+      __ and_(Rscratch1, Rscratch2, Rscratch1);
+      __ bne(CCR0, done);
+      __ b(*overflow);
+    }
+
+    // Increment counter in MethodCounters*.
+    const int mo_bc_offs = in_bytes(MethodCounters::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset());
+    __ bind(no_mdo);
+    __ get_method_counters(R19_method, R3_counters, done);
+    __ lwz(Rscratch2, mo_bc_offs, R3_counters);
+    __ addi(Rscratch2, Rscratch2, increment);
+    __ stw(Rscratch2, mo_bc_offs, R3_counters);
+    __ load_const_optimized(Rscratch1, mask, R0);
+    __ and_(Rscratch1, Rscratch2, Rscratch1);
+    __ beq(CCR0, *overflow);
+
+    __ bind(done);
+
+  } else {
+
+    // Update standard invocation counters.
+    Register Rsum_ivc_bec = R4_ARG2;
+    __ get_method_counters(R19_method, R3_counters, done);
+    __ increment_invocation_counter(R3_counters, Rsum_ivc_bec, R12_scratch2);
+    // Increment interpreter invocation counter.
+    if (ProfileInterpreter) {  // %%% Merge this into methodDataOop.
+      __ lwz(R12_scratch2, in_bytes(MethodCounters::interpreter_invocation_counter_offset()), R3_counters);
+      __ addi(R12_scratch2, R12_scratch2, 1);
+      __ stw(R12_scratch2, in_bytes(MethodCounters::interpreter_invocation_counter_offset()), R3_counters);
+    }
+    // Check if we must create a method data obj.
+    if (ProfileInterpreter && profile_method != NULL) {
+      const Register profile_limit = Rscratch1;
+      int pl_offs = __ load_const_optimized(profile_limit, &InvocationCounter::InterpreterProfileLimit, R0, true);
+      __ lwz(profile_limit, pl_offs, profile_limit);
+      // Test to see if we should create a method data oop.
+      __ cmpw(CCR0, Rsum_ivc_bec, profile_limit);
+      __ blt(CCR0, *profile_method_continue);
+      // If no method data exists, go to profile_method.
+      __ test_method_data_pointer(*profile_method);
+    }
+    // Finally check for counter overflow.
+    if (overflow) {
+      const Register invocation_limit = Rscratch1;
+      int il_offs = __ load_const_optimized(invocation_limit, &InvocationCounter::InterpreterInvocationLimit, R0, true);
+      __ lwz(invocation_limit, il_offs, invocation_limit);
+      assert(4 == sizeof(InvocationCounter::InterpreterInvocationLimit), "unexpected field size");
+      __ cmpw(CCR0, Rsum_ivc_bec, invocation_limit);
+      __ bge(CCR0, *overflow);
+    }
+
+    __ bind(done);
+  }
+}
+
+// Generate code to initiate compilation on invocation counter overflow.
+void TemplateInterpreterGenerator::generate_counter_overflow(Label& continue_entry) {
+  // Generate code to initiate compilation on the counter overflow.
+
+  // InterpreterRuntime::frequency_counter_overflow takes one arguments,
+  // which indicates if the counter overflow occurs at a backwards branch (NULL bcp)
+  // We pass zero in.
+  // The call returns the address of the verified entry point for the method or NULL
+  // if the compilation did not complete (either went background or bailed out).
+  //
+  // Unlike the C++ interpreter above: Check exceptions!
+  // Assumption: Caller must set the flag "do_not_unlock_if_sychronized" if the monitor of a sync'ed
+  // method has not yet been created. Thus, no unlocking of a non-existing monitor can occur.
+
+  __ li(R4_ARG2, 0);
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), R4_ARG2, true);
+
+  // Returns verified_entry_point or NULL.
+  // We ignore it in any case.
+  __ b(continue_entry);
+}
+
+void TemplateInterpreterGenerator::generate_stack_overflow_check(Register Rmem_frame_size, Register Rscratch1) {
+  assert_different_registers(Rmem_frame_size, Rscratch1);
+  __ generate_stack_overflow_check_with_compare_and_throw(Rmem_frame_size, Rscratch1);
+}
+
+void TemplateInterpreterGenerator::unlock_method(bool check_exceptions) {
+  __ unlock_object(R26_monitor, check_exceptions);
+}
+
+// Lock the current method, interpreter register window must be set up!
+void TemplateInterpreterGenerator::lock_method(Register Rflags, Register Rscratch1, Register Rscratch2, bool flags_preloaded) {
+  const Register Robj_to_lock = Rscratch2;
+
+  {
+    if (!flags_preloaded) {
+      __ lwz(Rflags, method_(access_flags));
+    }
+
+#ifdef ASSERT
+    // Check if methods needs synchronization.
+    {
+      Label Lok;
+      __ testbitdi(CCR0, R0, Rflags, JVM_ACC_SYNCHRONIZED_BIT);
+      __ btrue(CCR0,Lok);
+      __ stop("method doesn't need synchronization");
+      __ bind(Lok);
+    }
+#endif // ASSERT
+  }
+
+  // Get synchronization object to Rscratch2.
+  {
+    const int mirror_offset = in_bytes(Klass::java_mirror_offset());
+    Label Lstatic;
+    Label Ldone;
+
+    __ testbitdi(CCR0, R0, Rflags, JVM_ACC_STATIC_BIT);
+    __ btrue(CCR0, Lstatic);
+
+    // Non-static case: load receiver obj from stack and we're done.
+    __ ld(Robj_to_lock, R18_locals);
+    __ b(Ldone);
+
+    __ bind(Lstatic); // Static case: Lock the java mirror
+    __ ld(Robj_to_lock, in_bytes(Method::const_offset()), R19_method);
+    __ ld(Robj_to_lock, in_bytes(ConstMethod::constants_offset()), Robj_to_lock);
+    __ ld(Robj_to_lock, ConstantPool::pool_holder_offset_in_bytes(), Robj_to_lock);
+    __ ld(Robj_to_lock, mirror_offset, Robj_to_lock);
+
+    __ bind(Ldone);
+    __ verify_oop(Robj_to_lock);
+  }
+
+  // Got the oop to lock => execute!
+  __ add_monitor_to_stack(true, Rscratch1, R0);
+
+  __ std(Robj_to_lock, BasicObjectLock::obj_offset_in_bytes(), R26_monitor);
+  __ lock_object(R26_monitor, Robj_to_lock);
+}
+
+// Generate a fixed interpreter frame for pure interpreter
+// and I2N native transition frames.
+//
+// Before (stack grows downwards):
+//
+//         |  ...         |
+//         |------------- |
+//         |  java arg0   |
+//         |  ...         |
+//         |  java argn   |
+//         |              |   <-   R15_esp
+//         |              |
+//         |--------------|
+//         | abi_112      |
+//         |              |   <-   R1_SP
+//         |==============|
+//
+//
+// After:
+//
+//         |  ...         |
+//         |  java arg0   |<-   R18_locals
+//         |  ...         |
+//         |  java argn   |
+//         |--------------|
+//         |              |
+//         |  java locals |
+//         |              |
+//         |--------------|
+//         |  abi_48      |
+//         |==============|
+//         |              |
+//         |   istate     |
+//         |              |
+//         |--------------|
+//         |   monitor    |<-   R26_monitor
+//         |--------------|
+//         |              |<-   R15_esp
+//         | expression   |
+//         | stack        |
+//         |              |
+//         |--------------|
+//         |              |
+//         | abi_112      |<-   R1_SP
+//         |==============|
+//
+// The top most frame needs an abi space of 112 bytes. This space is needed,
+// since we call to c. The c function may spill their arguments to the caller
+// frame. When we call to java, we don't need these spill slots. In order to save
+// space on the stack, we resize the caller. However, java local reside in
+// the caller frame and the frame has to be increased. The frame_size for the
+// current frame was calculated based on max_stack as size for the expression
+// stack. At the call, just a part of the expression stack might be used.
+// We don't want to waste this space and cut the frame back accordingly.
+// The resulting amount for resizing is calculated as follows:
+// resize =   (number_of_locals - number_of_arguments) * slot_size
+//          + (R1_SP - R15_esp) + 48
+//
+// The size for the callee frame is calculated:
+// framesize = 112 + max_stack + monitor + state_size
+//
+// maxstack:   Max number of slots on the expression stack, loaded from the method.
+// monitor:    We statically reserve room for one monitor object.
+// state_size: We save the current state of the interpreter to this area.
+//
+void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Register Rsize_of_parameters, Register Rsize_of_locals) {
+  Register parent_frame_resize = R6_ARG4, // Frame will grow by this number of bytes.
+           top_frame_size      = R7_ARG5,
+           Rconst_method       = R8_ARG6;
+
+  assert_different_registers(Rsize_of_parameters, Rsize_of_locals, parent_frame_resize, top_frame_size);
+
+  __ ld(Rconst_method, method_(const));
+  __ lhz(Rsize_of_parameters /* number of params */,
+         in_bytes(ConstMethod::size_of_parameters_offset()), Rconst_method);
+  if (native_call) {
+    // If we're calling a native method, we reserve space for the worst-case signature
+    // handler varargs vector, which is max(Argument::n_register_parameters, parameter_count+2).
+    // We add two slots to the parameter_count, one for the jni
+    // environment and one for a possible native mirror.
+    Label skip_native_calculate_max_stack;
+    __ addi(top_frame_size, Rsize_of_parameters, 2);
+    __ cmpwi(CCR0, top_frame_size, Argument::n_register_parameters);
+    __ bge(CCR0, skip_native_calculate_max_stack);
+    __ li(top_frame_size, Argument::n_register_parameters);
+    __ bind(skip_native_calculate_max_stack);
+    __ sldi(Rsize_of_parameters, Rsize_of_parameters, Interpreter::logStackElementSize);
+    __ sldi(top_frame_size, top_frame_size, Interpreter::logStackElementSize);
+    __ sub(parent_frame_resize, R1_SP, R15_esp); // <0, off by Interpreter::stackElementSize!
+    assert(Rsize_of_locals == noreg, "Rsize_of_locals not initialized"); // Only relevant value is Rsize_of_parameters.
+  } else {
+    __ lhz(Rsize_of_locals /* number of params */, in_bytes(ConstMethod::size_of_locals_offset()), Rconst_method);
+    __ sldi(Rsize_of_parameters, Rsize_of_parameters, Interpreter::logStackElementSize);
+    __ sldi(Rsize_of_locals, Rsize_of_locals, Interpreter::logStackElementSize);
+    __ lhz(top_frame_size, in_bytes(ConstMethod::max_stack_offset()), Rconst_method);
+    __ sub(R11_scratch1, Rsize_of_locals, Rsize_of_parameters); // >=0
+    __ sub(parent_frame_resize, R1_SP, R15_esp); // <0, off by Interpreter::stackElementSize!
+    __ sldi(top_frame_size, top_frame_size, Interpreter::logStackElementSize);
+    __ add(parent_frame_resize, parent_frame_resize, R11_scratch1);
+  }
+
+  // Compute top frame size.
+  __ addi(top_frame_size, top_frame_size, frame::abi_reg_args_size + frame::ijava_state_size);
+
+  // Cut back area between esp and max_stack.
+  __ addi(parent_frame_resize, parent_frame_resize, frame::abi_minframe_size - Interpreter::stackElementSize);
+
+  __ round_to(top_frame_size, frame::alignment_in_bytes);
+  __ round_to(parent_frame_resize, frame::alignment_in_bytes);
+  // parent_frame_resize = (locals-parameters) - (ESP-SP-ABI48) Rounded to frame alignment size.
+  // Enlarge by locals-parameters (not in case of native_call), shrink by ESP-SP-ABI48.
+
+  {
+    // --------------------------------------------------------------------------
+    // Stack overflow check
+
+    Label cont;
+    __ add(R11_scratch1, parent_frame_resize, top_frame_size);
+    generate_stack_overflow_check(R11_scratch1, R12_scratch2);
+  }
+
+  // Set up interpreter state registers.
+
+  __ add(R18_locals, R15_esp, Rsize_of_parameters);
+  __ ld(R27_constPoolCache, in_bytes(ConstMethod::constants_offset()), Rconst_method);
+  __ ld(R27_constPoolCache, ConstantPool::cache_offset_in_bytes(), R27_constPoolCache);
+
+  // Set method data pointer.
+  if (ProfileInterpreter) {
+    Label zero_continue;
+    __ ld(R28_mdx, method_(method_data));
+    __ cmpdi(CCR0, R28_mdx, 0);
+    __ beq(CCR0, zero_continue);
+    __ addi(R28_mdx, R28_mdx, in_bytes(MethodData::data_offset()));
+    __ bind(zero_continue);
+  }
+
+  if (native_call) {
+    __ li(R14_bcp, 0); // Must initialize.
+  } else {
+    __ add(R14_bcp, in_bytes(ConstMethod::codes_offset()), Rconst_method);
+  }
+
+  // Resize parent frame.
+  __ mflr(R12_scratch2);
+  __ neg(parent_frame_resize, parent_frame_resize);
+  __ resize_frame(parent_frame_resize, R11_scratch1);
+  __ std(R12_scratch2, _abi(lr), R1_SP);
+
+  __ addi(R26_monitor, R1_SP, - frame::ijava_state_size);
+  __ addi(R15_esp, R26_monitor, - Interpreter::stackElementSize);
+
+  // Store values.
+  // R15_esp, R14_bcp, R26_monitor, R28_mdx are saved at java calls
+  // in InterpreterMacroAssembler::call_from_interpreter.
+  __ std(R19_method, _ijava_state_neg(method), R1_SP);
+  __ std(R21_sender_SP, _ijava_state_neg(sender_sp), R1_SP);
+  __ std(R27_constPoolCache, _ijava_state_neg(cpoolCache), R1_SP);
+  __ std(R18_locals, _ijava_state_neg(locals), R1_SP);
+
+  // Note: esp, bcp, monitor, mdx live in registers. Hence, the correct version can only
+  // be found in the frame after save_interpreter_state is done. This is always true
+  // for non-top frames. But when a signal occurs, dumping the top frame can go wrong,
+  // because e.g. frame::interpreter_frame_bcp() will not access the correct value
+  // (Enhanced Stack Trace).
+  // The signal handler does not save the interpreter state into the frame.
+  __ li(R0, 0);
+#ifdef ASSERT
+  // Fill remaining slots with constants.
+  __ load_const_optimized(R11_scratch1, 0x5afe);
+  __ load_const_optimized(R12_scratch2, 0xdead);
+#endif
+  // We have to initialize some frame slots for native calls (accessed by GC).
+  if (native_call) {
+    __ std(R26_monitor, _ijava_state_neg(monitors), R1_SP);
+    __ std(R14_bcp, _ijava_state_neg(bcp), R1_SP);
+    if (ProfileInterpreter) { __ std(R28_mdx, _ijava_state_neg(mdx), R1_SP); }
+  }
+#ifdef ASSERT
+  else {
+    __ std(R12_scratch2, _ijava_state_neg(monitors), R1_SP);
+    __ std(R12_scratch2, _ijava_state_neg(bcp), R1_SP);
+    __ std(R12_scratch2, _ijava_state_neg(mdx), R1_SP);
+  }
+  __ std(R11_scratch1, _ijava_state_neg(ijava_reserved), R1_SP);
+  __ std(R12_scratch2, _ijava_state_neg(esp), R1_SP);
+  __ std(R12_scratch2, _ijava_state_neg(lresult), R1_SP);
+  __ std(R12_scratch2, _ijava_state_neg(fresult), R1_SP);
+#endif
+  __ subf(R12_scratch2, top_frame_size, R1_SP);
+  __ std(R0, _ijava_state_neg(oop_tmp), R1_SP);
+  __ std(R12_scratch2, _ijava_state_neg(top_frame_sp), R1_SP);
+
+  // Push top frame.
+  __ push_frame(top_frame_size, R11_scratch1);
+}
+
+// End of helpers
+
+// ============================================================================
+// Various method entries
+//
+
+// Empty method, generate a very fast return. We must skip this entry if
+// someone's debugging, indicated by the flag
+// "interp_mode" in the Thread obj.
+// Note: empty methods are generated mostly methods that do assertions, which are
+// disabled in the "java opt build".
+address TemplateInterpreterGenerator::generate_empty_entry(void) {
+  if (!UseFastEmptyMethods) {
+    NOT_PRODUCT(__ should_not_reach_here();)
+    return Interpreter::entry_for_kind(Interpreter::zerolocals);
+  }
+
+  Label Lslow_path;
+  const Register Rjvmti_mode = R11_scratch1;
+  address entry = __ pc();
+
+  __ lwz(Rjvmti_mode, thread_(interp_only_mode));
+  __ cmpwi(CCR0, Rjvmti_mode, 0);
+  __ bne(CCR0, Lslow_path); // jvmti_mode!=0
+
+  // Noone's debuggin: Simply return.
+  // Pop c2i arguments (if any) off when we return.
+#ifdef ASSERT
+    __ ld(R9_ARG7, 0, R1_SP);
+    __ ld(R10_ARG8, 0, R21_sender_SP);
+    __ cmpd(CCR0, R9_ARG7, R10_ARG8);
+    __ asm_assert_eq("backlink", 0x545);
+#endif // ASSERT
+  __ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
+
+  // And we're done.
+  __ blr();
+
+  __ bind(Lslow_path);
+  __ branch_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), R11_scratch1);
+  __ flush();
+
+  return entry;
+}
+
+// Support abs and sqrt like in compiler.
+// For others we can use a normal (native) entry.
+
+inline bool math_entry_available(AbstractInterpreter::MethodKind kind) {
+  // Provide math entry with debugging on demand.
+  // Note: Debugging changes which code will get executed:
+  // Debugging or disabled InlineIntrinsics: java method will get interpreted and performs a native call.
+  // Not debugging and enabled InlineIntrinics: processor instruction will get used.
+  // Result might differ slightly due to rounding etc.
+  if (!InlineIntrinsics && (!FLAG_IS_ERGO(InlineIntrinsics))) return false; // Generate a vanilla entry.
+
+  return ((kind==Interpreter::java_lang_math_sqrt && VM_Version::has_fsqrt()) ||
+          (kind==Interpreter::java_lang_math_abs));
+}
+
+address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
+  if (!math_entry_available(kind)) {
+    NOT_PRODUCT(__ should_not_reach_here();)
+    return Interpreter::entry_for_kind(Interpreter::zerolocals);
+  }
+
+  Label Lslow_path;
+  const Register Rjvmti_mode = R11_scratch1;
+  address entry = __ pc();
+
+  // Provide math entry with debugging on demand.
+  __ lwz(Rjvmti_mode, thread_(interp_only_mode));
+  __ cmpwi(CCR0, Rjvmti_mode, 0);
+  __ bne(CCR0, Lslow_path); // jvmti_mode!=0
+
+  __ lfd(F1_RET, Interpreter::stackElementSize, R15_esp);
+
+  // Pop c2i arguments (if any) off when we return.
+#ifdef ASSERT
+  __ ld(R9_ARG7, 0, R1_SP);
+  __ ld(R10_ARG8, 0, R21_sender_SP);
+  __ cmpd(CCR0, R9_ARG7, R10_ARG8);
+  __ asm_assert_eq("backlink", 0x545);
+#endif // ASSERT
+  __ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
+
+  if (kind == Interpreter::java_lang_math_sqrt) {
+    __ fsqrt(F1_RET, F1_RET);
+  } else if (kind == Interpreter::java_lang_math_abs) {
+    __ fabs(F1_RET, F1_RET);
+  } else {
+    ShouldNotReachHere();
+  }
+
+  // And we're done.
+  __ blr();
+
+  // Provide slow path for JVMTI case.
+  __ bind(Lslow_path);
+  __ branch_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), R12_scratch2);
+  __ flush();
+
+  return entry;
+}
+
+// Interpreter stub for calling a native method. (asm interpreter)
+// This sets up a somewhat different looking stack for calling the
+// native method than the typical interpreter frame setup.
+//
+// On entry:
+//   R19_method    - method
+//   R16_thread    - JavaThread*
+//   R15_esp       - intptr_t* sender tos
+//
+//   abstract stack (grows up)
+//     [  IJava (caller of JNI callee)  ]  <-- ASP
+//        ...
+address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
+
+  address entry = __ pc();
+
+  const bool inc_counter = UseCompiler || CountCompiledCalls;
+
+  // -----------------------------------------------------------------------------
+  // Allocate a new frame that represents the native callee (i2n frame).
+  // This is not a full-blown interpreter frame, but in particular, the
+  // following registers are valid after this:
+  // - R19_method
+  // - R18_local (points to start of argumuments to native function)
+  //
+  //   abstract stack (grows up)
+  //     [  IJava (caller of JNI callee)  ]  <-- ASP
+  //        ...
+
+  const Register signature_handler_fd = R11_scratch1;
+  const Register pending_exception    = R0;
+  const Register result_handler_addr  = R31;
+  const Register native_method_fd     = R11_scratch1;
+  const Register access_flags         = R22_tmp2;
+  const Register active_handles       = R11_scratch1; // R26_monitor saved to state.
+  const Register sync_state           = R12_scratch2;
+  const Register sync_state_addr      = sync_state;   // Address is dead after use.
+  const Register suspend_flags        = R11_scratch1;
+
+  //=============================================================================
+  // Allocate new frame and initialize interpreter state.
+
+  Label exception_return;
+  Label exception_return_sync_check;
+  Label stack_overflow_return;
+
+  // Generate new interpreter state and jump to stack_overflow_return in case of
+  // a stack overflow.
+  //generate_compute_interpreter_state(stack_overflow_return);
+
+  Register size_of_parameters = R22_tmp2;
+
+  generate_fixed_frame(true, size_of_parameters, noreg /* unused */);
+
+  //=============================================================================
+  // Increment invocation counter. On overflow, entry to JNI method
+  // will be compiled.
+  Label invocation_counter_overflow, continue_after_compile;
+  if (inc_counter) {
+    if (synchronized) {
+      // Since at this point in the method invocation the exception handler
+      // would try to exit the monitor of synchronized methods which hasn't
+      // been entered yet, we set the thread local variable
+      // _do_not_unlock_if_synchronized to true. If any exception was thrown by
+      // runtime, exception handling i.e. unlock_if_synchronized_method will
+      // check this thread local flag.
+      // This flag has two effects, one is to force an unwind in the topmost
+      // interpreter frame and not perform an unlock while doing so.
+      __ li(R0, 1);
+      __ stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread);
+    }
+    generate_counter_incr(&invocation_counter_overflow, NULL, NULL);
+
+    __ BIND(continue_after_compile);
+    // Reset the _do_not_unlock_if_synchronized flag.
+    if (synchronized) {
+      __ li(R0, 0);
+      __ stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread);
+    }
+  }
+
+  // access_flags = method->access_flags();
+  // Load access flags.
+  assert(access_flags->is_nonvolatile(),
+         "access_flags must be in a non-volatile register");
+  // Type check.
+  assert(4 == sizeof(AccessFlags), "unexpected field size");
+  __ lwz(access_flags, method_(access_flags));
+
+  // We don't want to reload R19_method and access_flags after calls
+  // to some helper functions.
+  assert(R19_method->is_nonvolatile(),
+         "R19_method must be a non-volatile register");
+
+  // Check for synchronized methods. Must happen AFTER invocation counter
+  // check, so method is not locked if counter overflows.
+
+  if (synchronized) {
+    lock_method(access_flags, R11_scratch1, R12_scratch2, true);
+
+    // Update monitor in state.
+    __ ld(R11_scratch1, 0, R1_SP);
+    __ std(R26_monitor, _ijava_state_neg(monitors), R11_scratch1);
+  }
+
+  // jvmti/jvmpi support
+  __ notify_method_entry();
+
+  //=============================================================================
+  // Get and call the signature handler.
+
+  __ ld(signature_handler_fd, method_(signature_handler));
+  Label call_signature_handler;
+
+  __ cmpdi(CCR0, signature_handler_fd, 0);
+  __ bne(CCR0, call_signature_handler);
+
+  // Method has never been called. Either generate a specialized
+  // handler or point to the slow one.
+  //
+  // Pass parameter 'false' to avoid exception check in call_VM.
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), R19_method, false);
+
+  // Check for an exception while looking up the target method. If we
+  // incurred one, bail.
+  __ ld(pending_exception, thread_(pending_exception));
+  __ cmpdi(CCR0, pending_exception, 0);
+  __ bne(CCR0, exception_return_sync_check); // Has pending exception.
+
+  // Reload signature handler, it may have been created/assigned in the meanwhile.
+  __ ld(signature_handler_fd, method_(signature_handler));
+  __ twi_0(signature_handler_fd); // Order wrt. load of klass mirror and entry point (isync is below).
+
+  __ BIND(call_signature_handler);
+
+  // Before we call the signature handler we push a new frame to
+  // protect the interpreter frame volatile registers when we return
+  // from jni but before we can get back to Java.
+
+  // First set the frame anchor while the SP/FP registers are
+  // convenient and the slow signature handler can use this same frame
+  // anchor.
+
+  // We have a TOP_IJAVA_FRAME here, which belongs to us.
+  __ set_top_ijava_frame_at_SP_as_last_Java_frame(R1_SP, R12_scratch2/*tmp*/);
+
+  // Now the interpreter frame (and its call chain) have been
+  // invalidated and flushed. We are now protected against eager
+  // being enabled in native code. Even if it goes eager the
+  // registers will be reloaded as clean and we will invalidate after
+  // the call so no spurious flush should be possible.
+
+  // Call signature handler and pass locals address.
+  //
+  // Our signature handlers copy required arguments to the C stack
+  // (outgoing C args), R3_ARG1 to R10_ARG8, and FARG1 to FARG13.
+  __ mr(R3_ARG1, R18_locals);
+  __ ld(signature_handler_fd, 0, signature_handler_fd);
+
+  __ call_stub(signature_handler_fd);
+
+  // Remove the register parameter varargs slots we allocated in
+  // compute_interpreter_state. SP+16 ends up pointing to the ABI
+  // outgoing argument area.
+  //
+  // Not needed on PPC64.
+  //__ add(SP, SP, Argument::n_register_parameters*BytesPerWord);
+
+  assert(result_handler_addr->is_nonvolatile(), "result_handler_addr must be in a non-volatile register");
+  // Save across call to native method.
+  __ mr(result_handler_addr, R3_RET);
+
+  __ isync(); // Acquire signature handler before trying to fetch the native entry point and klass mirror.
+
+  // Set up fixed parameters and call the native method.
+  // If the method is static, get mirror into R4_ARG2.
+  {
+    Label method_is_not_static;
+    // Access_flags is non-volatile and still, no need to restore it.
+
+    // Restore access flags.
+    __ testbitdi(CCR0, R0, access_flags, JVM_ACC_STATIC_BIT);
+    __ bfalse(CCR0, method_is_not_static);
+
+    // constants = method->constants();
+    __ ld(R11_scratch1, in_bytes(Method::const_offset()), R19_method);
+    __ ld(R11_scratch1, in_bytes(ConstMethod::constants_offset()), R11_scratch1);
+    // pool_holder = method->constants()->pool_holder();
+    __ ld(R11_scratch1/*pool_holder*/, ConstantPool::pool_holder_offset_in_bytes(),
+          R11_scratch1/*constants*/);
+
+    const int mirror_offset = in_bytes(Klass::java_mirror_offset());
+
+    // mirror = pool_holder->klass_part()->java_mirror();
+    __ ld(R0/*mirror*/, mirror_offset, R11_scratch1/*pool_holder*/);
+    // state->_native_mirror = mirror;
+
+    __ ld(R11_scratch1, 0, R1_SP);
+    __ std(R0/*mirror*/, _ijava_state_neg(oop_tmp), R11_scratch1);
+    // R4_ARG2 = &state->_oop_temp;
+    __ addi(R4_ARG2, R11_scratch1, _ijava_state_neg(oop_tmp));
+    __ BIND(method_is_not_static);
+  }
+
+  // At this point, arguments have been copied off the stack into
+  // their JNI positions. Oops are boxed in-place on the stack, with
+  // handles copied to arguments. The result handler address is in a
+  // register.
+
+  // Pass JNIEnv address as first parameter.
+  __ addir(R3_ARG1, thread_(jni_environment));
+
+  // Load the native_method entry before we change the thread state.
+  __ ld(native_method_fd, method_(native_function));
+
+  //=============================================================================
+  // Transition from _thread_in_Java to _thread_in_native. As soon as
+  // we make this change the safepoint code needs to be certain that
+  // the last Java frame we established is good. The pc in that frame
+  // just needs to be near here not an actual return address.
+
+  // We use release_store_fence to update values like the thread state, where
+  // we don't want the current thread to continue until all our prior memory
+  // accesses (including the new thread state) are visible to other threads.
+  __ li(R0, _thread_in_native);
+  __ release();
+
+  // TODO PPC port assert(4 == JavaThread::sz_thread_state(), "unexpected field size");
+  __ stw(R0, thread_(thread_state));
+
+  if (UseMembar) {
+    __ fence();
+  }
+
+  //=============================================================================
+  // Call the native method. Argument registers must not have been
+  // overwritten since "__ call_stub(signature_handler);" (except for
+  // ARG1 and ARG2 for static methods).
+  __ call_c(native_method_fd);
+
+  __ li(R0, 0);
+  __ ld(R11_scratch1, 0, R1_SP);
+  __ std(R3_RET, _ijava_state_neg(lresult), R11_scratch1);
+  __ stfd(F1_RET, _ijava_state_neg(fresult), R11_scratch1);
+  __ std(R0/*mirror*/, _ijava_state_neg(oop_tmp), R11_scratch1); // reset
+
+  // Note: C++ interpreter needs the following here:
+  // The frame_manager_lr field, which we use for setting the last
+  // java frame, gets overwritten by the signature handler. Restore
+  // it now.
+  //__ get_PC_trash_LR(R11_scratch1);
+  //__ std(R11_scratch1, _top_ijava_frame_abi(frame_manager_lr), R1_SP);
+
+  // Because of GC R19_method may no longer be valid.
+
+  // Block, if necessary, before resuming in _thread_in_Java state.
+  // In order for GC to work, don't clear the last_Java_sp until after
+  // blocking.
+
+  //=============================================================================
+  // Switch thread to "native transition" state before reading the
+  // synchronization state. This additional state is necessary
+  // because reading and testing the synchronization state is not
+  // atomic w.r.t. GC, as this scenario demonstrates: Java thread A,
+  // in _thread_in_native state, loads _not_synchronized and is
+  // preempted. VM thread changes sync state to synchronizing and
+  // suspends threads for GC. Thread A is resumed to finish this
+  // native method, but doesn't block here since it didn't see any
+  // synchronization in progress, and escapes.
+
+  // We use release_store_fence to update values like the thread state, where
+  // we don't want the current thread to continue until all our prior memory
+  // accesses (including the new thread state) are visible to other threads.
+  __ li(R0/*thread_state*/, _thread_in_native_trans);
+  __ release();
+  __ stw(R0/*thread_state*/, thread_(thread_state));
+  if (UseMembar) {
+    __ fence();
+  }
+  // Write serialization page so that the VM thread can do a pseudo remote
+  // membar. We use the current thread pointer to calculate a thread
+  // specific offset to write to within the page. This minimizes bus
+  // traffic due to cache line collision.
+  else {
+    __ serialize_memory(R16_thread, R11_scratch1, R12_scratch2);
+  }
+
+  // Now before we return to java we must look for a current safepoint
+  // (a new safepoint can not start since we entered native_trans).
+  // We must check here because a current safepoint could be modifying
+  // the callers registers right this moment.
+
+  // Acquire isn't strictly necessary here because of the fence, but
+  // sync_state is declared to be volatile, so we do it anyway
+  // (cmp-br-isync on one path, release (same as acquire on PPC64) on the other path).
+  int sync_state_offs = __ load_const_optimized(sync_state_addr, SafepointSynchronize::address_of_state(), /*temp*/R0, true);
+
+  // TODO PPC port assert(4 == SafepointSynchronize::sz_state(), "unexpected field size");
+  __ lwz(sync_state, sync_state_offs, sync_state_addr);
+
+  // TODO PPC port assert(4 == Thread::sz_suspend_flags(), "unexpected field size");
+  __ lwz(suspend_flags, thread_(suspend_flags));
+
+  Label sync_check_done;
+  Label do_safepoint;
+  // No synchronization in progress nor yet synchronized.
+  __ cmpwi(CCR0, sync_state, SafepointSynchronize::_not_synchronized);
+  // Not suspended.
+  __ cmpwi(CCR1, suspend_flags, 0);
+
+  __ bne(CCR0, do_safepoint);
+  __ beq(CCR1, sync_check_done);
+  __ bind(do_safepoint);
+  __ isync();
+  // Block. We do the call directly and leave the current
+  // last_Java_frame setup undisturbed. We must save any possible
+  // native result across the call. No oop is present.
+
+  __ mr(R3_ARG1, R16_thread);
+  __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, JavaThread::check_special_condition_for_native_trans),
+            relocInfo::none);
+
+  __ bind(sync_check_done);
+
+  //=============================================================================
+  // <<<<<< Back in Interpreter Frame >>>>>
+
+  // We are in thread_in_native_trans here and back in the normal
+  // interpreter frame. We don't have to do anything special about
+  // safepoints and we can switch to Java mode anytime we are ready.
+
+  // Note: frame::interpreter_frame_result has a dependency on how the
+  // method result is saved across the call to post_method_exit. For
+  // native methods it assumes that the non-FPU/non-void result is
+  // saved in _native_lresult and a FPU result in _native_fresult. If
+  // this changes then the interpreter_frame_result implementation
+  // will need to be updated too.
+
+  // On PPC64, we have stored the result directly after the native call.
+
+  //=============================================================================
+  // Back in Java
+
+  // We use release_store_fence to update values like the thread state, where
+  // we don't want the current thread to continue until all our prior memory
+  // accesses (including the new thread state) are visible to other threads.
+  __ li(R0/*thread_state*/, _thread_in_Java);
+  __ release();
+  __ stw(R0/*thread_state*/, thread_(thread_state));
+  if (UseMembar) {
+    __ fence();
+  }
+
+  __ reset_last_Java_frame();
+
+  // Jvmdi/jvmpi support. Whether we've got an exception pending or
+  // not, and whether unlocking throws an exception or not, we notify
+  // on native method exit. If we do have an exception, we'll end up
+  // in the caller's context to handle it, so if we don't do the
+  // notify here, we'll drop it on the floor.
+  __ notify_method_exit(true/*native method*/,
+                        ilgl /*illegal state (not used for native methods)*/,
+                        InterpreterMacroAssembler::NotifyJVMTI,
+                        false /*check_exceptions*/);
+
+  //=============================================================================
+  // Handle exceptions
+
+  if (synchronized) {
+    // Don't check for exceptions since we're still in the i2n frame. Do that
+    // manually afterwards.
+    unlock_method(false);
+  }
+
+  // Reset active handles after returning from native.
+  // thread->active_handles()->clear();
+  __ ld(active_handles, thread_(active_handles));
+  // TODO PPC port assert(4 == JNIHandleBlock::top_size_in_bytes(), "unexpected field size");
+  __ li(R0, 0);
+  __ stw(R0, JNIHandleBlock::top_offset_in_bytes(), active_handles);
+
+  Label exception_return_sync_check_already_unlocked;
+  __ ld(R0/*pending_exception*/, thread_(pending_exception));
+  __ cmpdi(CCR0, R0/*pending_exception*/, 0);
+  __ bne(CCR0, exception_return_sync_check_already_unlocked);
+
+  //-----------------------------------------------------------------------------
+  // No exception pending.
+
+  // Move native method result back into proper registers and return.
+  // Invoke result handler (may unbox/promote).
+  __ ld(R11_scratch1, 0, R1_SP);
+  __ ld(R3_RET, _ijava_state_neg(lresult), R11_scratch1);
+  __ lfd(F1_RET, _ijava_state_neg(fresult), R11_scratch1);
+  __ call_stub(result_handler_addr);
+
+  __ merge_frames(/*top_frame_sp*/ R21_sender_SP, /*return_pc*/ R0, R11_scratch1, R12_scratch2);
+
+  // Must use the return pc which was loaded from the caller's frame
+  // as the VM uses return-pc-patching for deoptimization.
+  __ mtlr(R0);
+  __ blr();
+
+  //-----------------------------------------------------------------------------
+  // An exception is pending. We call into the runtime only if the
+  // caller was not interpreted. If it was interpreted the
+  // interpreter will do the correct thing. If it isn't interpreted
+  // (call stub/compiled code) we will change our return and continue.
+
+  __ BIND(exception_return_sync_check);
+
+  if (synchronized) {
+    // Don't check for exceptions since we're still in the i2n frame. Do that
+    // manually afterwards.
+    unlock_method(false);
+  }
+  __ BIND(exception_return_sync_check_already_unlocked);
+
+  const Register return_pc = R31;
+
+  __ ld(return_pc, 0, R1_SP);
+  __ ld(return_pc, _abi(lr), return_pc);
+
+  // Get the address of the exception handler.
+  __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
+                  R16_thread,
+                  return_pc /* return pc */);
+  __ merge_frames(/*top_frame_sp*/ R21_sender_SP, noreg, R11_scratch1, R12_scratch2);
+
+  // Load the PC of the the exception handler into LR.
+  __ mtlr(R3_RET);
+
+  // Load exception into R3_ARG1 and clear pending exception in thread.
+  __ ld(R3_ARG1/*exception*/, thread_(pending_exception));
+  __ li(R4_ARG2, 0);
+  __ std(R4_ARG2, thread_(pending_exception));
+
+  // Load the original return pc into R4_ARG2.
+  __ mr(R4_ARG2/*issuing_pc*/, return_pc);
+
+  // Return to exception handler.
+  __ blr();
+
+  //=============================================================================
+  // Counter overflow.
+
+  if (inc_counter) {
+    // Handle invocation counter overflow.
+    __ bind(invocation_counter_overflow);
+
+    generate_counter_overflow(continue_after_compile);
+  }
+
+  return entry;
+}
+
+// Generic interpreted method entry to (asm) interpreter.
+//
+address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
+  bool inc_counter = UseCompiler || CountCompiledCalls;
+  address entry = __ pc();
+  // Generate the code to allocate the interpreter stack frame.
+  Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
+           Rsize_of_locals     = R5_ARG3; // Written by generate_fixed_frame.
+
+  generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals);
+
+#ifdef FAST_DISPATCH
+  __ unimplemented("Fast dispatch in generate_normal_entry");
+#if 0
+  __ set((intptr_t)Interpreter::dispatch_table(), IdispatchTables);
+  // Set bytecode dispatch table base.
+#endif
+#endif
+
+  // --------------------------------------------------------------------------
+  // Zero out non-parameter locals.
+  // Note: *Always* zero out non-parameter locals as Sparc does. It's not
+  // worth to ask the flag, just do it.
+  Register Rslot_addr = R6_ARG4,
+           Rnum       = R7_ARG5;
+  Label Lno_locals, Lzero_loop;
+
+  // Set up the zeroing loop.
+  __ subf(Rnum, Rsize_of_parameters, Rsize_of_locals);
+  __ subf(Rslot_addr, Rsize_of_parameters, R18_locals);
+  __ srdi_(Rnum, Rnum, Interpreter::logStackElementSize);
+  __ beq(CCR0, Lno_locals);
+  __ li(R0, 0);
+  __ mtctr(Rnum);
+
+  // The zero locals loop.
+  __ bind(Lzero_loop);
+  __ std(R0, 0, Rslot_addr);
+  __ addi(Rslot_addr, Rslot_addr, -Interpreter::stackElementSize);
+  __ bdnz(Lzero_loop);
+
+  __ bind(Lno_locals);
+
+  // --------------------------------------------------------------------------
+  // Counter increment and overflow check.
+  Label invocation_counter_overflow,
+        profile_method,
+        profile_method_continue;
+  if (inc_counter || ProfileInterpreter) {
+
+    Register Rdo_not_unlock_if_synchronized_addr = R11_scratch1;
+    if (synchronized) {
+      // Since at this point in the method invocation the exception handler
+      // would try to exit the monitor of synchronized methods which hasn't
+      // been entered yet, we set the thread local variable
+      // _do_not_unlock_if_synchronized to true. If any exception was thrown by
+      // runtime, exception handling i.e. unlock_if_synchronized_method will
+      // check this thread local flag.
+      // This flag has two effects, one is to force an unwind in the topmost
+      // interpreter frame and not perform an unlock while doing so.
+      __ li(R0, 1);
+      __ stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread);
+    }
+    // Increment invocation counter and check for overflow.
+    if (inc_counter) {
+      generate_counter_incr(&invocation_counter_overflow, &profile_method, &profile_method_continue);
+    }
+
+    __ bind(profile_method_continue);
+
+    // Reset the _do_not_unlock_if_synchronized flag.
+    if (synchronized) {
+      __ li(R0, 0);
+      __ stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread);
+    }
+  }
+
+  // --------------------------------------------------------------------------
+  // Locking of synchronized methods. Must happen AFTER invocation_counter
+  // check and stack overflow check, so method is not locked if overflows.
+  if (synchronized) {
+    lock_method(R3_ARG1, R4_ARG2, R5_ARG3);
+  }
+#ifdef ASSERT
+  else {
+    Label Lok;
+    __ lwz(R0, in_bytes(Method::access_flags_offset()), R19_method);
+    __ andi_(R0, R0, JVM_ACC_SYNCHRONIZED);
+    __ asm_assert_eq("method needs synchronization", 0x8521);
+    __ bind(Lok);
+  }
+#endif // ASSERT
+
+  __ verify_thread();
+
+  // --------------------------------------------------------------------------
+  // JVMTI support
+  __ notify_method_entry();
+
+  // --------------------------------------------------------------------------
+  // Start executing instructions.
+  __ dispatch_next(vtos);
+
+  // --------------------------------------------------------------------------
+  // Out of line counter overflow and MDO creation code.
+  if (ProfileInterpreter) {
+    // We have decided to profile this method in the interpreter.
+    __ bind(profile_method);
+    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
+    __ set_method_data_pointer_for_bcp();
+    __ b(profile_method_continue);
+  }
+
+  if (inc_counter) {
+    // Handle invocation counter overflow.
+    __ bind(invocation_counter_overflow);
+    generate_counter_overflow(profile_method_continue);
+  }
+  return entry;
+}
+
+// =============================================================================
+// Entry points
+
+address AbstractInterpreterGenerator::generate_method_entry(
+                                        AbstractInterpreter::MethodKind kind) {
+  // Determine code generation flags.
+  bool synchronized = false;
+  address entry_point = NULL;
+
+  switch (kind) {
+  case Interpreter::zerolocals             :                                                                             break;
+  case Interpreter::zerolocals_synchronized: synchronized = true;                                                        break;
+  case Interpreter::native                 : entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false); break;
+  case Interpreter::native_synchronized    : entry_point = ((InterpreterGenerator*) this)->generate_native_entry(true);  break;
+  case Interpreter::empty                  : entry_point = ((InterpreterGenerator*) this)->generate_empty_entry();       break;
+  case Interpreter::accessor               : entry_point = ((InterpreterGenerator*) this)->generate_accessor_entry();    break;
+  case Interpreter::abstract               : entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry();    break;
+
+  case Interpreter::java_lang_math_sin     : // fall thru
+  case Interpreter::java_lang_math_cos     : // fall thru
+  case Interpreter::java_lang_math_tan     : // fall thru
+  case Interpreter::java_lang_math_abs     : // fall thru
+  case Interpreter::java_lang_math_log     : // fall thru
+  case Interpreter::java_lang_math_log10   : // fall thru
+  case Interpreter::java_lang_math_sqrt    : // fall thru
+  case Interpreter::java_lang_math_pow     : // fall thru
+  case Interpreter::java_lang_math_exp     : entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind);    break;
+  case Interpreter::java_lang_ref_reference_get
+                                           : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
+  default                                  : ShouldNotReachHere();                                                       break;
+  }
+
+  if (entry_point) {
+    return entry_point;
+  }
+
+  return ((InterpreterGenerator*) this)->generate_normal_entry(synchronized);
+}
+
+// These should never be compiled since the interpreter will prefer
+// the compiled version to the intrinsic version.
+bool AbstractInterpreter::can_be_compiled(methodHandle m) {
+  return !math_entry_available(method_kind(m));
+}
+
+// How much stack a method activation needs in stack slots.
+// We must calc this exactly like in generate_fixed_frame.
+// Note: This returns the conservative size assuming maximum alignment.
+int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
+  const int max_alignment_size = 2;
+  const int abi_scratch = frame::abi_reg_args_size;
+  return method->max_locals() + method->max_stack() + frame::interpreter_frame_monitor_size() + max_alignment_size + abi_scratch;
+}
+
+// Fills a sceletal interpreter frame generated during deoptimizations
+// and returns the frame size in slots.
+//
+// Parameters:
+//
+// interpreter_frame == NULL:
+//   Only calculate the size of an interpreter activation, no actual layout.
+//   Note: This calculation must exactly parallel the frame setup
+//   in TemplateInterpreter::generate_normal_entry. But it does not
+//   account for the SP alignment, that might further enhance the
+//   frame size, depending on FP.
+//
+// interpreter_frame != NULL:
+//   set up the method, locals, and monitors.
+//   The frame interpreter_frame, if not NULL, is guaranteed to be the
+//   right size, as determined by a previous call to this method.
+//   It is also guaranteed to be walkable even though it is in a skeletal state
+//
+// is_top_frame == true:
+//   We're processing the *oldest* interpreter frame!
+//
+// pop_frame_extra_args:
+//   If this is != 0 we are returning to a deoptimized frame by popping
+//   off the callee frame. We want to re-execute the call that called the
+//   callee interpreted, but since the return to the interpreter would pop
+//   the arguments off advance the esp by dummy popframe_extra_args slots.
+//   Popping off those will establish the stack layout as it was before the call.
+//
+int AbstractInterpreter::layout_activation(Method* method,
+                                           int tempcount,
+                                           int popframe_extra_args,
+                                           int moncount,
+                                           int caller_actual_parameters,
+                                           int callee_param_count,
+                                           int callee_locals,
+                                           frame* caller,
+                                           frame* interpreter_frame,
+                                           bool is_top_frame,
+                                           bool is_bottom_frame) {
+
+  const int max_alignment_space = 2;
+  const int abi_scratch = is_top_frame ? (frame::abi_reg_args_size / Interpreter::stackElementSize) :
+                                         (frame::abi_minframe_size / Interpreter::stackElementSize) ;
+  const int conservative_framesize_in_slots =
+    method->max_stack() + callee_locals - callee_param_count +
+    (moncount * frame::interpreter_frame_monitor_size()) + max_alignment_space +
+    abi_scratch + frame::ijava_state_size / Interpreter::stackElementSize;
+
+  assert(!is_top_frame || conservative_framesize_in_slots * 8 > frame::abi_reg_args_size + frame::ijava_state_size, "frame too small");
+
+  if (interpreter_frame == NULL) {
+    // Since we don't know the exact alignment, we return the conservative size.
+    return (conservative_framesize_in_slots & -2);
+  } else {
+    // Now we know our caller, calc the exact frame layout and size.
+    intptr_t* locals_base  = (caller->is_interpreted_frame()) ?
+      caller->interpreter_frame_esp() + caller_actual_parameters :
+      caller->sp() + method->max_locals() - 1 + (frame::abi_minframe_size / Interpreter::stackElementSize) ;
+
+    intptr_t* monitor_base = caller->sp() - frame::ijava_state_size / Interpreter::stackElementSize ;
+    intptr_t* monitor      = monitor_base - (moncount * frame::interpreter_frame_monitor_size());
+    intptr_t* esp_base     = monitor - 1;
+    intptr_t* esp          = esp_base - tempcount - popframe_extra_args;
+    intptr_t* sp           = (intptr_t *) (((intptr_t) (esp_base- callee_locals + callee_param_count - method->max_stack()- abi_scratch)) & -StackAlignmentInBytes);
+    intptr_t* sender_sp    = caller->sp() + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize;
+    intptr_t* top_frame_sp = is_top_frame ? sp : sp + (frame::abi_minframe_size - frame::abi_reg_args_size) / Interpreter::stackElementSize;
+
+    interpreter_frame->interpreter_frame_set_method(method);
+    interpreter_frame->interpreter_frame_set_locals(locals_base);
+    interpreter_frame->interpreter_frame_set_cpcache(method->constants()->cache());
+    interpreter_frame->interpreter_frame_set_esp(esp);
+    interpreter_frame->interpreter_frame_set_monitor_end((BasicObjectLock *)monitor);
+    interpreter_frame->interpreter_frame_set_top_frame_sp(top_frame_sp);
+    if (!is_bottom_frame) {
+      interpreter_frame->interpreter_frame_set_sender_sp(sender_sp);
+    }
+
+    int framesize_in_slots = caller->sp() - sp;
+    assert(!is_top_frame ||framesize_in_slots >= (frame::abi_reg_args_size / Interpreter::stackElementSize) + frame::ijava_state_size / Interpreter::stackElementSize, "frame too small");
+    assert(framesize_in_slots <= conservative_framesize_in_slots, "exact frame size must be smaller than the convervative size!");
+    return framesize_in_slots;
+  }
+}
+
+// =============================================================================
+// Exceptions
+
+void TemplateInterpreterGenerator::generate_throw_exception() {
+  Register Rexception    = R17_tos,
+           Rcontinuation = R3_RET;
+
+  // --------------------------------------------------------------------------
+  // Entry point if an method returns with a pending exception (rethrow).
+  Interpreter::_rethrow_exception_entry = __ pc();
+  {
+    __ restore_interpreter_state(R11_scratch1); // Sets R11_scratch1 = fp.
+    __ ld(R12_scratch2, _ijava_state_neg(top_frame_sp), R11_scratch1);
+    __ resize_frame_absolute(R12_scratch2, R11_scratch1, R0);
+
+    // Compiled code destroys templateTableBase, reload.
+    __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R11_scratch1);
+  }
+
+  // Entry point if a interpreted method throws an exception (throw).
+  Interpreter::_throw_exception_entry = __ pc();
+  {
+    __ mr(Rexception, R3_RET);
+
+    __ verify_thread();
+    __ verify_oop(Rexception);
+
+    // Expression stack must be empty before entering the VM in case of an exception.
+    __ empty_expression_stack();
+    // Find exception handler address and preserve exception oop.
+    // Call C routine to find handler and jump to it.
+    __ call_VM(Rexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::exception_handler_for_exception), Rexception);
+    __ mtctr(Rcontinuation);
+    // Push exception for exception handler bytecodes.
+    __ push_ptr(Rexception);
+
+    // Jump to exception handler (may be remove activation entry!).
+    __ bctr();
+  }
+
+  // If the exception is not handled in the current frame the frame is
+  // removed and the exception is rethrown (i.e. exception
+  // continuation is _rethrow_exception).
+  //
+  // Note: At this point the bci is still the bxi for the instruction
+  // which caused the exception and the expression stack is
+  // empty. Thus, for any VM calls at this point, GC will find a legal
+  // oop map (with empty expression stack).
+
+  // In current activation
+  // tos: exception
+  // bcp: exception bcp
+
+  // --------------------------------------------------------------------------
+  // JVMTI PopFrame support
+
+  Interpreter::_remove_activation_preserving_args_entry = __ pc();
+  {
+    // Set the popframe_processing bit in popframe_condition indicating that we are
+    // currently handling popframe, so that call_VMs that may happen later do not
+    // trigger new popframe handling cycles.
+    __ lwz(R11_scratch1, in_bytes(JavaThread::popframe_condition_offset()), R16_thread);
+    __ ori(R11_scratch1, R11_scratch1, JavaThread::popframe_processing_bit);
+    __ stw(R11_scratch1, in_bytes(JavaThread::popframe_condition_offset()), R16_thread);
+
+    // Empty the expression stack, as in normal exception handling.
+    __ empty_expression_stack();
+    __ unlock_if_synchronized_method(vtos, /* throw_monitor_exception */ false, /* install_monitor_exception */ false);
+
+    // Check to see whether we are returning to a deoptimized frame.
+    // (The PopFrame call ensures that the caller of the popped frame is
+    // either interpreted or compiled and deoptimizes it if compiled.)
+    // Note that we don't compare the return PC against the
+    // deoptimization blob's unpack entry because of the presence of
+    // adapter frames in C2.
+    Label Lcaller_not_deoptimized;
+    Register return_pc = R3_ARG1;
+    __ ld(return_pc, 0, R1_SP);
+    __ ld(return_pc, _abi(lr), return_pc);
+    __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::interpreter_contains), return_pc);
+    __ cmpdi(CCR0, R3_RET, 0);
+    __ bne(CCR0, Lcaller_not_deoptimized);
+
+    // The deoptimized case.
+    // In this case, we can't call dispatch_next() after the frame is
+    // popped, but instead must save the incoming arguments and restore
+    // them after deoptimization has occurred.
+    __ ld(R4_ARG2, in_bytes(Method::const_offset()), R19_method);
+    __ lhz(R4_ARG2 /* number of params */, in_bytes(ConstMethod::size_of_parameters_offset()), R4_ARG2);
+    __ slwi(R4_ARG2, R4_ARG2, Interpreter::logStackElementSize);
+    __ addi(R5_ARG3, R18_locals, Interpreter::stackElementSize);
+    __ subf(R5_ARG3, R4_ARG2, R5_ARG3);
+    // Save these arguments.
+    __ call_VM_leaf(CAST_FROM_FN_PTR(address, Deoptimization::popframe_preserve_args), R16_thread, R4_ARG2, R5_ARG3);
+
+    // Inform deoptimization that it is responsible for restoring these arguments.
+    __ load_const_optimized(R11_scratch1, JavaThread::popframe_force_deopt_reexecution_bit);
+    __ stw(R11_scratch1, in_bytes(JavaThread::popframe_condition_offset()), R16_thread);
+
+    // Return from the current method into the deoptimization blob. Will eventually
+    // end up in the deopt interpeter entry, deoptimization prepared everything that
+    // we will reexecute the call that called us.
+    __ merge_frames(/*top_frame_sp*/ R21_sender_SP, /*reload return_pc*/ return_pc, R11_scratch1, R12_scratch2);
+    __ mtlr(return_pc);
+    __ blr();
+
+    // The non-deoptimized case.
+    __ bind(Lcaller_not_deoptimized);
+
+    // Clear the popframe condition flag.
+    __ li(R0, 0);
+    __ stw(R0, in_bytes(JavaThread::popframe_condition_offset()), R16_thread);
+
+    // Get out of the current method and re-execute the call that called us.
+    __ merge_frames(/*top_frame_sp*/ R21_sender_SP, /*return_pc*/ return_pc, R11_scratch1, R12_scratch2);
+    __ restore_interpreter_state(R11_scratch1);
+    __ ld(R12_scratch2, _ijava_state_neg(top_frame_sp), R11_scratch1);
+    __ resize_frame_absolute(R12_scratch2, R11_scratch1, R0);
+    __ mtlr(return_pc);
+    if (ProfileInterpreter) {
+      __ set_method_data_pointer_for_bcp();
+    }
+    __ dispatch_next(vtos);
+  }
+  // end of JVMTI PopFrame support
+
+  // --------------------------------------------------------------------------
+  // Remove activation exception entry.
+  // This is jumped to if an interpreted method can't handle an exception itself
+  // (we come from the throw/rethrow exception entry above). We're going to call
+  // into the VM to find the exception handler in the caller, pop the current
+  // frame and return the handler we calculated.
+  Interpreter::_remove_activation_entry = __ pc();
+  {
+    __ pop_ptr(Rexception);
+    __ verify_thread();
+    __ verify_oop(Rexception);
+    __ std(Rexception, in_bytes(JavaThread::vm_result_offset()), R16_thread);
+
+    __ unlock_if_synchronized_method(vtos, /* throw_monitor_exception */ false, true);
+    __ notify_method_exit(false, vtos, InterpreterMacroAssembler::SkipNotifyJVMTI, false);
+
+    __ get_vm_result(Rexception);
+
+    // We are done with this activation frame; find out where to go next.
+    // The continuation point will be an exception handler, which expects
+    // the following registers set up:
+    //
+    // RET:  exception oop
+    // ARG2: Issuing PC (see generate_exception_blob()), only used if the caller is compiled.
+
+    Register return_pc = R31; // Needs to survive the runtime call.
+    __ ld(return_pc, 0, R1_SP);
+    __ ld(return_pc, _abi(lr), return_pc);
+    __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), R16_thread, return_pc);
+
+    // Remove the current activation.
+    __ merge_frames(/*top_frame_sp*/ R21_sender_SP, /*return_pc*/ noreg, R11_scratch1, R12_scratch2);
+
+    __ mr(R4_ARG2, return_pc);
+    __ mtlr(R3_RET);
+    __ mr(R3_RET, Rexception);
+    __ blr();
+  }
+}
+
+// JVMTI ForceEarlyReturn support.
+// Returns "in the middle" of a method with a "fake" return value.
+address TemplateInterpreterGenerator::generate_earlyret_entry_for(TosState state) {
+
+  Register Rscratch1 = R11_scratch1,
+           Rscratch2 = R12_scratch2;
+
+  address entry = __ pc();
+  __ empty_expression_stack();
+
+  __ load_earlyret_value(state, Rscratch1);
+
+  __ ld(Rscratch1, in_bytes(JavaThread::jvmti_thread_state_offset()), R16_thread);
+  // Clear the earlyret state.
+  __ li(R0, 0);
+  __ stw(R0, in_bytes(JvmtiThreadState::earlyret_state_offset()), Rscratch1);
+
+  __ remove_activation(state, false, false);
+  // Copied from TemplateTable::_return.
+  // Restoration of lr done by remove_activation.
+  switch (state) {
+    case ltos:
+    case btos:
+    case ctos:
+    case stos:
+    case atos:
+    case itos: __ mr(R3_RET, R17_tos); break;
+    case ftos:
+    case dtos: __ fmr(F1_RET, F15_ftos); break;
+    case vtos: // This might be a constructor. Final fields (and volatile fields on PPC64) need
+               // to get visible before the reference to the object gets stored anywhere.
+               __ membar(Assembler::StoreStore); break;
+    default  : ShouldNotReachHere();
+  }
+  __ blr();
+
+  return entry;
+} // end of ForceEarlyReturn support
+
+//-----------------------------------------------------------------------------
+// Helper for vtos entry point generation
+
+void TemplateInterpreterGenerator::set_vtos_entry_points(Template* t,
+                                                         address& bep,
+                                                         address& cep,
+                                                         address& sep,
+                                                         address& aep,
+                                                         address& iep,
+                                                         address& lep,
+                                                         address& fep,
+                                                         address& dep,
+                                                         address& vep) {
+  assert(t->is_valid() && t->tos_in() == vtos, "illegal template");
+  Label L;
+
+  aep = __ pc();  __ push_ptr();  __ b(L);
+  fep = __ pc();  __ push_f();    __ b(L);
+  dep = __ pc();  __ push_d();    __ b(L);
+  lep = __ pc();  __ push_l();    __ b(L);
+  __ align(32, 12, 24); // align L
+  bep = cep = sep =
+  iep = __ pc();  __ push_i();
+  vep = __ pc();
+  __ bind(L);
+  generate_and_dispatch(t);
+}
+
+//-----------------------------------------------------------------------------
+// Generation of individual instructions
+
+// helpers for generate_and_dispatch
+
+InterpreterGenerator::InterpreterGenerator(StubQueue* code)
+  : TemplateInterpreterGenerator(code) {
+  generate_all(); // Down here so it can be "virtual".
+}
+
+//-----------------------------------------------------------------------------
+
+// Non-product code
+#ifndef PRODUCT
+address TemplateInterpreterGenerator::generate_trace_code(TosState state) {
+  //__ flush_bundle();
+  address entry = __ pc();
+
+  char *bname = NULL;
+  uint tsize = 0;
+  switch(state) {
+  case ftos:
+    bname = "trace_code_ftos {";
+    tsize = 2;
+    break;
+  case btos:
+    bname = "trace_code_btos {";
+    tsize = 2;
+    break;
+  case ctos:
+    bname = "trace_code_ctos {";
+    tsize = 2;
+    break;
+  case stos:
+    bname = "trace_code_stos {";
+    tsize = 2;
+    break;
+  case itos:
+    bname = "trace_code_itos {";
+    tsize = 2;
+    break;
+  case ltos:
+    bname = "trace_code_ltos {";
+    tsize = 3;
+    break;
+  case atos:
+    bname = "trace_code_atos {";
+    tsize = 2;
+    break;
+  case vtos:
+    // Note: In case of vtos, the topmost of stack value could be a int or doubl
+    // In case of a double (2 slots) we won't see the 2nd stack value.
+    // Maybe we simply should print the topmost 3 stack slots to cope with the problem.
+    bname = "trace_code_vtos {";
+    tsize = 2;
+
+    break;
+  case dtos:
+    bname = "trace_code_dtos {";
+    tsize = 3;
+    break;
+  default:
+    ShouldNotReachHere();
+  }
+  BLOCK_COMMENT(bname);
+
+  // Support short-cut for TraceBytecodesAt.
+  // Don't call into the VM if we don't want to trace to speed up things.
+  Label Lskip_vm_call;
+  if (TraceBytecodesAt > 0 && TraceBytecodesAt < max_intx) {
+    int offs1 = __ load_const_optimized(R11_scratch1, (address) &TraceBytecodesAt, R0, true);
+    int offs2 = __ load_const_optimized(R12_scratch2, (address) &BytecodeCounter::_counter_value, R0, true);
+    __ ld(R11_scratch1, offs1, R11_scratch1);
+    __ lwa(R12_scratch2, offs2, R12_scratch2);
+    __ cmpd(CCR0, R12_scratch2, R11_scratch1);
+    __ blt(CCR0, Lskip_vm_call);
+  }
+
+  __ push(state);
+  // Load 2 topmost expression stack values.
+  __ ld(R6_ARG4, tsize*Interpreter::stackElementSize, R15_esp);
+  __ ld(R5_ARG3, Interpreter::stackElementSize, R15_esp);
+  __ mflr(R31);
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::trace_bytecode), /* unused */ R4_ARG2, R5_ARG3, R6_ARG4, false);
+  __ mtlr(R31);
+  __ pop(state);
+
+  if (TraceBytecodesAt > 0 && TraceBytecodesAt < max_intx) {
+    __ bind(Lskip_vm_call);
+  }
+  __ blr();
+  BLOCK_COMMENT("} trace_code");
+  return entry;
+}
+
+void TemplateInterpreterGenerator::count_bytecode() {
+  int offs = __ load_const_optimized(R11_scratch1, (address) &BytecodeCounter::_counter_value, R12_scratch2, true);
+  __ lwz(R12_scratch2, offs, R11_scratch1);
+  __ addi(R12_scratch2, R12_scratch2, 1);
+  __ stw(R12_scratch2, offs, R11_scratch1);
+}
+
+void TemplateInterpreterGenerator::histogram_bytecode(Template* t) {
+  int offs = __ load_const_optimized(R11_scratch1, (address) &BytecodeHistogram::_counters[t->bytecode()], R12_scratch2, true);
+  __ lwz(R12_scratch2, offs, R11_scratch1);
+  __ addi(R12_scratch2, R12_scratch2, 1);
+  __ stw(R12_scratch2, offs, R11_scratch1);
+}
+
+void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) {
+  const Register addr = R11_scratch1,
+                 tmp  = R12_scratch2;
+  // Get index, shift out old bytecode, bring in new bytecode, and store it.
+  // _index = (_index >> log2_number_of_codes) |
+  //          (bytecode << log2_number_of_codes);
+  int offs1 = __ load_const_optimized(addr, (address)&BytecodePairHistogram::_index, tmp, true);
+  __ lwz(tmp, offs1, addr);
+  __ srwi(tmp, tmp, BytecodePairHistogram::log2_number_of_codes);
+  __ ori(tmp, tmp, ((int) t->bytecode()) << BytecodePairHistogram::log2_number_of_codes);
+  __ stw(tmp, offs1, addr);
+
+  // Bump bucket contents.
+  // _counters[_index] ++;
+  int offs2 = __ load_const_optimized(addr, (address)&BytecodePairHistogram::_counters, R0, true);
+  __ sldi(tmp, tmp, LogBytesPerInt);
+  __ add(addr, tmp, addr);
+  __ lwz(tmp, offs2, addr);
+  __ addi(tmp, tmp, 1);
+  __ stw(tmp, offs2, addr);
+}
+
+void TemplateInterpreterGenerator::trace_bytecode(Template* t) {
+  // Call a little run-time stub to avoid blow-up for each bytecode.
+  // The run-time runtime saves the right registers, depending on
+  // the tosca in-state for the given template.
+
+  assert(Interpreter::trace_code(t->tos_in()) != NULL,
+         "entry must have been generated");
+
+  // Note: we destroy LR here.
+  __ bl(Interpreter::trace_code(t->tos_in()));
+}
+
+void TemplateInterpreterGenerator::stop_interpreter_at() {
+  Label L;
+  int offs1 = __ load_const_optimized(R11_scratch1, (address) &StopInterpreterAt, R0, true);
+  int offs2 = __ load_const_optimized(R12_scratch2, (address) &BytecodeCounter::_counter_value, R0, true);
+  __ ld(R11_scratch1, offs1, R11_scratch1);
+  __ lwa(R12_scratch2, offs2, R12_scratch2);
+  __ cmpd(CCR0, R12_scratch2, R11_scratch1);
+  __ bne(CCR0, L);
+  __ illtrap();
+  __ bind(L);
+}
+
+#endif // !PRODUCT
+#endif // !CC_INTERP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013, 2014 SAP AG. 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.
+ *
+ */
+
+#ifndef CPU_PPC_VM_TEMPLATEINTERPRETER_PPC_HPP
+#define CPU_PPC_VM_TEMPLATEINTERPRETER_PPC_HPP
+
+ protected:
+
+  // Size of interpreter code.  Increase if too small.  Interpreter will
+  // fail with a guarantee ("not enough space for interpreter generation");
+  // if too small.
+  // Run with +PrintInterpreter to get the VM to print out the size.
+  // Max size with JVMTI
+
+  const static int InterpreterCodeSize = 210*K;
+
+#endif // CPU_PPC_VM_TEMPLATEINTERPRETER_PPC_HPP
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,4082 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013, 2014 SAP AG. 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "interpreter/interpreter.hpp"
+#include "interpreter/interpreterRuntime.hpp"
+#include "interpreter/templateInterpreter.hpp"
+#include "interpreter/templateTable.hpp"
+#include "memory/universe.inline.hpp"
+#include "oops/objArrayKlass.hpp"
+#include "oops/oop.inline.hpp"
+#include "prims/methodHandles.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "runtime/stubRoutines.hpp"
+#include "runtime/synchronizer.hpp"
+#include "utilities/macros.hpp"
+
+#ifndef CC_INTERP
+
+#undef __
+#define __ _masm->
+
+// ============================================================================
+// Misc helpers
+
+// Do an oop store like *(base + index) = val OR *(base + offset) = val
+// (only one of both variants is possible at the same time).
+// Index can be noreg.
+// Kills:
+//   Rbase, Rtmp
+static void do_oop_store(InterpreterMacroAssembler* _masm,
+                         Register           Rbase,
+                         RegisterOrConstant offset,
+                         Register           Rval,         // Noreg means always null.
+                         Register           Rtmp1,
+                         Register           Rtmp2,
+                         Register           Rtmp3,
+                         BarrierSet::Name   barrier,
+                         bool               precise,
+                         bool               check_null) {
+  assert_different_registers(Rtmp1, Rtmp2, Rtmp3, Rval, Rbase);
+
+  switch (barrier) {
+#ifndef SERIALGC
+    case BarrierSet::G1SATBCT:
+    case BarrierSet::G1SATBCTLogging:
+      {
+        // Load and record the previous value.
+        __ g1_write_barrier_pre(Rbase, offset,
+                                Rtmp3, /* holder of pre_val ? */
+                                Rtmp1, Rtmp2, false /* frame */);
+
+        Label Lnull, Ldone;
+        if (Rval != noreg) {
+          if (check_null) {
+            __ cmpdi(CCR0, Rval, 0);
+            __ beq(CCR0, Lnull);
+          }
+          __ store_heap_oop_not_null(Rval, offset, Rbase, /*Rval must stay uncompressed.*/ Rtmp1);
+          // Mark the card.
+          if (!(offset.is_constant() && offset.as_constant() == 0) && precise) {
+            __ add(Rbase, offset, Rbase);
+          }
+          __ g1_write_barrier_post(Rbase, Rval, Rtmp1, Rtmp2, Rtmp3, /*filtered (fast path)*/ &Ldone);
+          if (check_null) { __ b(Ldone); }
+        }
+
+        if (Rval == noreg || check_null) { // Store null oop.
+          Register Rnull = Rval;
+          __ bind(Lnull);
+          if (Rval == noreg) {
+            Rnull = Rtmp1;
+            __ li(Rnull, 0);
+          }
+          if (UseCompressedOops) {
+            __ stw(Rnull, offset, Rbase);
+          } else {
+            __ std(Rnull, offset, Rbase);
+          }
+        }
+        __ bind(Ldone);
+      }
+      break;
+#endif // SERIALGC
+    case BarrierSet::CardTableModRef:
+    case BarrierSet::CardTableExtension:
+      {
+        Label Lnull, Ldone;
+        if (Rval != noreg) {
+          if (check_null) {
+            __ cmpdi(CCR0, Rval, 0);
+            __ beq(CCR0, Lnull);
+          }
+          __ store_heap_oop_not_null(Rval, offset, Rbase, /*Rval should better stay uncompressed.*/ Rtmp1);
+          // Mark the card.
+          if (!(offset.is_constant() && offset.as_constant() == 0) && precise) {
+            __ add(Rbase, offset, Rbase);
+          }
+          __ card_write_barrier_post(Rbase, Rval, Rtmp1);
+          if (check_null) {
+            __ b(Ldone);
+          }
+        }
+
+        if (Rval == noreg || check_null) { // Store null oop.
+          Register Rnull = Rval;
+          __ bind(Lnull);
+          if (Rval == noreg) {
+            Rnull = Rtmp1;
+            __ li(Rnull, 0);
+          }
+          if (UseCompressedOops) {
+            __ stw(Rnull, offset, Rbase);
+          } else {
+            __ std(Rnull, offset, Rbase);
+          }
+        }
+        __ bind(Ldone);
+      }
+      break;
+    case BarrierSet::ModRef:
+    case BarrierSet::Other:
+      ShouldNotReachHere();
+      break;
+    default:
+      ShouldNotReachHere();
+  }
+}
+
+// ============================================================================
+// Platform-dependent initialization
+
+void TemplateTable::pd_initialize() {
+  // No ppc64 specific initialization.
+}
+
+Address TemplateTable::at_bcp(int offset) {
+  // Not used on ppc.
+  ShouldNotReachHere();
+  return Address();
+}
+
+// Patches the current bytecode (ptr to it located in bcp)
+// in the bytecode stream with a new one.
+void TemplateTable::patch_bytecode(Bytecodes::Code new_bc, Register Rnew_bc, Register Rtemp, bool load_bc_into_bc_reg /*=true*/, int byte_no) {
+  // With sharing on, may need to test method flag.
+  if (!RewriteBytecodes) return;
+  Label L_patch_done;
+
+  switch (new_bc) {
+    case Bytecodes::_fast_aputfield:
+    case Bytecodes::_fast_bputfield:
+    case Bytecodes::_fast_cputfield:
+    case Bytecodes::_fast_dputfield:
+    case Bytecodes::_fast_fputfield:
+    case Bytecodes::_fast_iputfield:
+    case Bytecodes::_fast_lputfield:
+    case Bytecodes::_fast_sputfield:
+    {
+      // We skip bytecode quickening for putfield instructions when
+      // the put_code written to the constant pool cache is zero.
+      // This is required so that every execution of this instruction
+      // calls out to InterpreterRuntime::resolve_get_put to do
+      // additional, required work.
+      assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
+      assert(load_bc_into_bc_reg, "we use bc_reg as temp");
+      __ get_cache_and_index_at_bcp(Rtemp /* dst = cache */, 1);
+      // Big Endian: ((*(cache+indices))>>((1+byte_no)*8))&0xFF
+      __ lbz(Rnew_bc, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 7 - (1 + byte_no), Rtemp);
+      __ cmpwi(CCR0, Rnew_bc, 0);
+      __ li(Rnew_bc, (unsigned int)(unsigned char)new_bc);
+      __ beq(CCR0, L_patch_done);
+      // __ isync(); // acquire not needed
+      break;
+    }
+
+    default:
+      assert(byte_no == -1, "sanity");
+      if (load_bc_into_bc_reg) {
+        __ li(Rnew_bc, (unsigned int)(unsigned char)new_bc);
+      }
+  }
+
+  if (JvmtiExport::can_post_breakpoint()) {
+    Label L_fast_patch;
+    __ lbz(Rtemp, 0, R14_bcp);
+    __ cmpwi(CCR0, Rtemp, (unsigned int)(unsigned char)Bytecodes::_breakpoint);
+    __ bne(CCR0, L_fast_patch);
+    // Perform the quickening, slowly, in the bowels of the breakpoint table.
+    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), R19_method, R14_bcp, Rnew_bc);
+    __ b(L_patch_done);
+    __ bind(L_fast_patch);
+  }
+
+  // Patch bytecode.
+  __ stb(Rnew_bc, 0, R14_bcp);
+
+  __ bind(L_patch_done);
+}
+
+// ============================================================================
+// Individual instructions
+
+void TemplateTable::nop() {
+  transition(vtos, vtos);
+  // Nothing to do.
+}
+
+void TemplateTable::shouldnotreachhere() {
+  transition(vtos, vtos);
+  __ stop("shouldnotreachhere bytecode");
+}
+
+void TemplateTable::aconst_null() {
+  transition(vtos, atos);
+  __ li(R17_tos, 0);
+}
+
+void TemplateTable::iconst(int value) {
+  transition(vtos, itos);
+  assert(value >= -1 && value <= 5, "");
+  __ li(R17_tos, value);
+}
+
+void TemplateTable::lconst(int value) {
+  transition(vtos, ltos);
+  assert(value >= -1 && value <= 5, "");
+  __ li(R17_tos, value);
+}
+
+void TemplateTable::fconst(int value) {
+  transition(vtos, ftos);
+  static float zero = 0.0;
+  static float one  = 1.0;
+  static float two  = 2.0;
+  switch (value) {
+    default: ShouldNotReachHere();
+    case 0: {
+      int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&zero, R0);
+      __ lfs(F15_ftos, simm16_offset, R11_scratch1);
+      break;
+    }
+    case 1: {
+      int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&one, R0);
+      __ lfs(F15_ftos, simm16_offset, R11_scratch1);
+      break;
+    }
+    case 2: {
+      int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&two, R0);
+      __ lfs(F15_ftos, simm16_offset, R11_scratch1);
+      break;
+    }
+  }
+}
+
+void TemplateTable::dconst(int value) {
+  transition(vtos, dtos);
+  static double zero = 0.0;
+  static double one  = 1.0;
+  switch (value) {
+    case 0: {
+      int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&zero, R0);
+      __ lfd(F15_ftos, simm16_offset, R11_scratch1);
+      break;
+    }
+    case 1: {
+      int simm16_offset = __ load_const_optimized(R11_scratch1, (address*)&one, R0);
+      __ lfd(F15_ftos, simm16_offset, R11_scratch1);
+      break;
+    }
+    default: ShouldNotReachHere();
+  }
+}
+
+void TemplateTable::bipush() {
+  transition(vtos, itos);
+  __ lbz(R17_tos, 1, R14_bcp);
+  __ extsb(R17_tos, R17_tos);
+}
+
+void TemplateTable::sipush() {
+  transition(vtos, itos);
+  __ get_2_byte_integer_at_bcp(1, R17_tos, InterpreterMacroAssembler::Signed);
+}
+
+void TemplateTable::ldc(bool wide) {
+  Register Rscratch1 = R11_scratch1,
+           Rscratch2 = R12_scratch2,
+           Rcpool    = R3_ARG1;
+
+  transition(vtos, vtos);
+  Label notInt, notClass, exit;
+
+  __ get_cpool_and_tags(Rcpool, Rscratch2); // Set Rscratch2 = &tags.
+  if (wide) { // Read index.
+    __ get_2_byte_integer_at_bcp(1, Rscratch1, InterpreterMacroAssembler::Unsigned);
+  } else {
+    __ lbz(Rscratch1, 1, R14_bcp);
+  }
+
+  const int base_offset = ConstantPool::header_size() * wordSize;
+  const int tags_offset = Array<u1>::base_offset_in_bytes();
+
+  // Get type from tags.
+  __ addi(Rscratch2, Rscratch2, tags_offset);
+  __ lbzx(Rscratch2, Rscratch2, Rscratch1);
+
+  __ cmpwi(CCR0, Rscratch2, JVM_CONSTANT_UnresolvedClass); // Unresolved class?
+  __ cmpwi(CCR1, Rscratch2, JVM_CONSTANT_UnresolvedClassInError); // Unresolved class in error state?
+  __ cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
+
+  // Resolved class - need to call vm to get java mirror of the class.
+  __ cmpwi(CCR1, Rscratch2, JVM_CONSTANT_Class);
+  __ crnor(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); // Neither resolved class nor unresolved case from above?
+  __ beq(CCR0, notClass);
+
+  __ li(R4, wide ? 1 : 0);
+  call_VM(R17_tos, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), R4);
+  __ push(atos);
+  __ b(exit);
+
+  __ align(32, 12);
+  __ bind(notClass);
+  __ addi(Rcpool, Rcpool, base_offset);
+  __ sldi(Rscratch1, Rscratch1, LogBytesPerWord);
+  __ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Integer);
+  __ bne(CCR0, notInt);
+  __ isync(); // Order load of constant wrt. tags.
+  __ lwax(R17_tos, Rcpool, Rscratch1);
+  __ push(itos);
+  __ b(exit);
+
+  __ align(32, 12);
+  __ bind(notInt);
+#ifdef ASSERT
+  // String and Object are rewritten to fast_aldc
+  __ cmpdi(CCR0, Rscratch2, JVM_CONSTANT_Float);
+  __ asm_assert_eq("unexpected type", 0x8765);
+#endif
+  __ isync(); // Order load of constant wrt. tags.
+  __ lfsx(F15_ftos, Rcpool, Rscratch1);
+  __ push(ftos);
+
+  __ align(32, 12);
+  __ bind(exit);
+}
+
+// Fast path for caching oop constants.
+void TemplateTable::fast_aldc(bool wide) {
+  transition(vtos, atos);
+
+  int index_size = wide ? sizeof(u2) : sizeof(u1);
+  const Register Rscratch = R11_scratch1;
+  Label resolved;
+
+  // We are resolved if the resolved reference cache entry contains a
+  // non-null object (CallSite, etc.)
+  __ get_cache_index_at_bcp(Rscratch, 1, index_size);  // Load index.
+  __ load_resolved_reference_at_index(R17_tos, Rscratch);
+  __ cmpdi(CCR0, R17_tos, 0);
+  __ bne(CCR0, resolved);
+  __ load_const_optimized(R3_ARG1, (int)bytecode());
+
+  address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
+
+  // First time invocation - must resolve first.
+  __ call_VM(R17_tos, entry, R3_ARG1);
+
+  __ align(32, 12);
+  __ bind(resolved);
+  __ verify_oop(R17_tos);
+}
+
+void TemplateTable::ldc2_w() {
+  transition(vtos, vtos);
+  Label Llong, Lexit;
+
+  Register Rindex = R11_scratch1,
+           Rcpool = R12_scratch2,
+           Rtag   = R3_ARG1;
+  __ get_cpool_and_tags(Rcpool, Rtag);
+  __ get_2_byte_integer_at_bcp(1, Rindex, InterpreterMacroAssembler::Unsigned);
+
+  const int base_offset = ConstantPool::header_size() * wordSize;
+  const int tags_offset = Array<u1>::base_offset_in_bytes();
+  // Get type from tags.
+  __ addi(Rcpool, Rcpool, base_offset);
+  __ addi(Rtag, Rtag, tags_offset);
+
+  __ lbzx(Rtag, Rtag, Rindex);
+
+  __ sldi(Rindex, Rindex, LogBytesPerWord);
+  __ cmpdi(CCR0, Rtag, JVM_CONSTANT_Double);
+  __ bne(CCR0, Llong);
+  // A double can be placed at word-aligned locations in the constant pool.
+  // Check out Conversions.java for an example.
+  // Also ConstantPool::header_size() is 20, which makes it very difficult
+  // to double-align double on the constant pool. SG, 11/7/97
+  __ isync(); // Order load of constant wrt. tags.
+  __ lfdx(F15_ftos, Rcpool, Rindex);
+  __ push(dtos);
+  __ b(Lexit);
+
+  __ bind(Llong);
+  __ isync(); // Order load of constant wrt. tags.
+  __ ldx(R17_tos, Rcpool, Rindex);
+  __ push(ltos);
+
+  __ bind(Lexit);
+}
+
+// Get the locals index located in the bytecode stream at bcp + offset.
+void TemplateTable::locals_index(Register Rdst, int offset) {
+  __ lbz(Rdst, offset, R14_bcp);
+}
+
+void TemplateTable::iload() {
+  transition(vtos, itos);
+
+  // Get the local value into tos
+  const Register Rindex = R22_tmp2;
+  locals_index(Rindex);
+
+  // Rewrite iload,iload  pair into fast_iload2
+  //         iload,caload pair into fast_icaload
+  if (RewriteFrequentPairs) {
+    Label Lrewrite, Ldone;
+    Register Rnext_byte  = R3_ARG1,
+             Rrewrite_to = R6_ARG4,
+             Rscratch    = R11_scratch1;
+
+    // get next byte
+    __ lbz(Rnext_byte, Bytecodes::length_for(Bytecodes::_iload), R14_bcp);
+
+    // if _iload, wait to rewrite to iload2. We only want to rewrite the
+    // last two iloads in a pair. Comparing against fast_iload means that
+    // the next bytecode is neither an iload or a caload, and therefore
+    // an iload pair.
+    __ cmpwi(CCR0, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_iload);
+    __ beq(CCR0, Ldone);
+
+    __ cmpwi(CCR1, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_fast_iload);
+    __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_iload2);
+    __ beq(CCR1, Lrewrite);
+
+    __ cmpwi(CCR0, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_caload);
+    __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_icaload);
+    __ beq(CCR0, Lrewrite);
+
+    __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_iload);
+
+    __ bind(Lrewrite);
+    patch_bytecode(Bytecodes::_iload, Rrewrite_to, Rscratch, false);
+    __ bind(Ldone);
+  }
+
+  __ load_local_int(R17_tos, Rindex, Rindex);
+}
+
+// Load 2 integers in a row without dispatching
+void TemplateTable::fast_iload2() {
+  transition(vtos, itos);
+
+  __ lbz(R3_ARG1, 1, R14_bcp);
+  __ lbz(R17_tos, Bytecodes::length_for(Bytecodes::_iload) + 1, R14_bcp);
+
+  __ load_local_int(R3_ARG1, R11_scratch1, R3_ARG1);
+  __ load_local_int(R17_tos, R12_scratch2, R17_tos);
+  __ push_i(R3_ARG1);
+}
+
+void TemplateTable::fast_iload() {
+  transition(vtos, itos);
+  // Get the local value into tos
+
+  const Register Rindex = R11_scratch1;
+  locals_index(Rindex);
+  __ load_local_int(R17_tos, Rindex, Rindex);
+}
+
+// Load a local variable type long from locals area to TOS cache register.
+// Local index resides in bytecodestream.
+void TemplateTable::lload() {
+  transition(vtos, ltos);
+
+  const Register Rindex = R11_scratch1;
+  locals_index(Rindex);
+  __ load_local_long(R17_tos, Rindex, Rindex);
+}
+
+void TemplateTable::fload() {
+  transition(vtos, ftos);
+
+  const Register Rindex = R11_scratch1;
+  locals_index(Rindex);
+  __ load_local_float(F15_ftos, Rindex, Rindex);
+}
+
+void TemplateTable::dload() {
+  transition(vtos, dtos);
+
+  const Register Rindex = R11_scratch1;
+  locals_index(Rindex);
+  __ load_local_double(F15_ftos, Rindex, Rindex);
+}
+
+void TemplateTable::aload() {
+  transition(vtos, atos);
+
+  const Register Rindex = R11_scratch1;
+  locals_index(Rindex);
+  __ load_local_ptr(R17_tos, Rindex, Rindex);
+}
+
+void TemplateTable::locals_index_wide(Register Rdst) {
+  // Offset is 2, not 1, because Lbcp points to wide prefix code.
+  __ get_2_byte_integer_at_bcp(2, Rdst, InterpreterMacroAssembler::Unsigned);
+}
+
+void TemplateTable::wide_iload() {
+  // Get the local value into tos.
+
+  const Register Rindex = R11_scratch1;
+  locals_index_wide(Rindex);
+  __ load_local_int(R17_tos, Rindex, Rindex);
+}
+
+void TemplateTable::wide_lload() {
+  transition(vtos, ltos);
+
+  const Register Rindex = R11_scratch1;
+  locals_index_wide(Rindex);
+  __ load_local_long(R17_tos, Rindex, Rindex);
+}
+
+void TemplateTable::wide_fload() {
+  transition(vtos, ftos);
+
+  const Register Rindex = R11_scratch1;
+  locals_index_wide(Rindex);
+  __ load_local_float(F15_ftos, Rindex, Rindex);
+}
+
+void TemplateTable::wide_dload() {
+  transition(vtos, dtos);
+
+  const Register Rindex = R11_scratch1;
+  locals_index_wide(Rindex);
+  __ load_local_double(F15_ftos, Rindex, Rindex);
+}
+
+void TemplateTable::wide_aload() {
+  transition(vtos, atos);
+
+  const Register Rindex = R11_scratch1;
+  locals_index_wide(Rindex);
+  __ load_local_ptr(R17_tos, Rindex, Rindex);
+}
+
+void TemplateTable::iaload() {
+  transition(itos, itos);
+
+  const Register Rload_addr = R3_ARG1,
+                 Rarray     = R4_ARG2,
+                 Rtemp      = R5_ARG3;
+  __ index_check(Rarray, R17_tos /* index */, LogBytesPerInt, Rtemp, Rload_addr);
+  __ lwa(R17_tos, arrayOopDesc::base_offset_in_bytes(T_INT), Rload_addr);
+}
+
+void TemplateTable::laload() {
+  transition(itos, ltos);
+
+  const Register Rload_addr = R3_ARG1,
+                 Rarray     = R4_ARG2,
+                 Rtemp      = R5_ARG3;
+  __ index_check(Rarray, R17_tos /* index */, LogBytesPerLong, Rtemp, Rload_addr);
+  __ ld(R17_tos, arrayOopDesc::base_offset_in_bytes(T_LONG), Rload_addr);
+}
+
+void TemplateTable::faload() {
+  transition(itos, ftos);
+
+  const Register Rload_addr = R3_ARG1,
+                 Rarray     = R4_ARG2,
+                 Rtemp      = R5_ARG3;
+  __ index_check(Rarray, R17_tos /* index */, LogBytesPerInt, Rtemp, Rload_addr);
+  __ lfs(F15_ftos, arrayOopDesc::base_offset_in_bytes(T_FLOAT), Rload_addr);
+}
+
+void TemplateTable::daload() {
+  transition(itos, dtos);
+
+  const Register Rload_addr = R3_ARG1,
+                 Rarray     = R4_ARG2,
+                 Rtemp      = R5_ARG3;
+  __ index_check(Rarray, R17_tos /* index */, LogBytesPerLong, Rtemp, Rload_addr);
+  __ lfd(F15_ftos, arrayOopDesc::base_offset_in_bytes(T_DOUBLE), Rload_addr);
+}
+
+void TemplateTable::aaload() {
+  transition(itos, atos);
+
+  // tos: index
+  // result tos: array
+  const Register Rload_addr = R3_ARG1,
+                 Rarray     = R4_ARG2,
+                 Rtemp      = R5_ARG3;
+  __ index_check(Rarray, R17_tos /* index */, UseCompressedOops ? 2 : LogBytesPerWord, Rtemp, Rload_addr);
+  __ load_heap_oop(R17_tos, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rload_addr);
+  __ verify_oop(R17_tos);
+  //__ dcbt(R17_tos); // prefetch
+}
+
+void TemplateTable::baload() {
+  transition(itos, itos);
+
+  const Register Rload_addr = R3_ARG1,
+                 Rarray     = R4_ARG2,
+                 Rtemp      = R5_ARG3;
+  __ index_check(Rarray, R17_tos /* index */, 0, Rtemp, Rload_addr);
+  __ lbz(R17_tos, arrayOopDesc::base_offset_in_bytes(T_BYTE), Rload_addr);
+  __ extsb(R17_tos, R17_tos);
+}
+
+void TemplateTable::caload() {
+  transition(itos, itos);
+
+  const Register Rload_addr = R3_ARG1,
+                 Rarray     = R4_ARG2,
+                 Rtemp      = R5_ARG3;
+  __ index_check(Rarray, R17_tos /* index */, LogBytesPerShort, Rtemp, Rload_addr);
+  __ lhz(R17_tos, arrayOopDesc::base_offset_in_bytes(T_CHAR), Rload_addr);
+}
+
+// Iload followed by caload frequent pair.
+void TemplateTable::fast_icaload() {
+  transition(vtos, itos);
+
+  const Register Rload_addr = R3_ARG1,
+                 Rarray     = R4_ARG2,
+                 Rtemp      = R11_scratch1;
+
+  locals_index(R17_tos);
+  __ load_local_int(R17_tos, Rtemp, R17_tos);
+  __ index_check(Rarray, R17_tos /* index */, LogBytesPerShort, Rtemp, Rload_addr);
+  __ lhz(R17_tos, arrayOopDesc::base_offset_in_bytes(T_CHAR), Rload_addr);
+}
+
+void TemplateTable::saload() {
+  transition(itos, itos);
+
+  const Register Rload_addr = R11_scratch1,
+                 Rarray     = R12_scratch2,
+                 Rtemp      = R3_ARG1;
+  __ index_check(Rarray, R17_tos /* index */, LogBytesPerShort, Rtemp, Rload_addr);
+  __ lha(R17_tos, arrayOopDesc::base_offset_in_bytes(T_SHORT), Rload_addr);
+}
+
+void TemplateTable::iload(int n) {
+  transition(vtos, itos);
+
+  __ lwz(R17_tos, Interpreter::local_offset_in_bytes(n), R18_locals);
+}
+
+void TemplateTable::lload(int n) {
+  transition(vtos, ltos);
+
+  __ ld(R17_tos, Interpreter::local_offset_in_bytes(n + 1), R18_locals);
+}
+
+void TemplateTable::fload(int n) {
+  transition(vtos, ftos);
+
+  __ lfs(F15_ftos, Interpreter::local_offset_in_bytes(n), R18_locals);
+}
+
+void TemplateTable::dload(int n) {
+  transition(vtos, dtos);
+
+  __ lfd(F15_ftos, Interpreter::local_offset_in_bytes(n + 1), R18_locals);
+}
+
+void TemplateTable::aload(int n) {
+  transition(vtos, atos);
+
+  __ ld(R17_tos, Interpreter::local_offset_in_bytes(n), R18_locals);
+}
+
+void TemplateTable::aload_0() {
+  transition(vtos, atos);
+  // According to bytecode histograms, the pairs:
+  //
+  // _aload_0, _fast_igetfield
+  // _aload_0, _fast_agetfield
+  // _aload_0, _fast_fgetfield
+  //
+  // occur frequently. If RewriteFrequentPairs is set, the (slow)
+  // _aload_0 bytecode checks if the next bytecode is either
+  // _fast_igetfield, _fast_agetfield or _fast_fgetfield and then
+  // rewrites the current bytecode into a pair bytecode; otherwise it
+  // rewrites the current bytecode into _0 that doesn't do
+  // the pair check anymore.
+  //
+  // Note: If the next bytecode is _getfield, the rewrite must be
+  //       delayed, otherwise we may miss an opportunity for a pair.
+  //
+  // Also rewrite frequent pairs
+  //   aload_0, aload_1
+  //   aload_0, iload_1
+  // These bytecodes with a small amount of code are most profitable
+  // to rewrite.
+
+  if (RewriteFrequentPairs) {
+
+    Label Lrewrite, Ldont_rewrite;
+    Register Rnext_byte  = R3_ARG1,
+             Rrewrite_to = R6_ARG4,
+             Rscratch    = R11_scratch1;
+
+    // Get next byte.
+    __ lbz(Rnext_byte, Bytecodes::length_for(Bytecodes::_aload_0), R14_bcp);
+
+    // If _getfield, wait to rewrite. We only want to rewrite the last two bytecodes in a pair.
+    __ cmpwi(CCR0, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_getfield);
+    __ beq(CCR0, Ldont_rewrite);
+
+    __ cmpwi(CCR1, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_fast_igetfield);
+    __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_iaccess_0);
+    __ beq(CCR1, Lrewrite);
+
+    __ cmpwi(CCR0, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_fast_agetfield);
+    __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_aaccess_0);
+    __ beq(CCR0, Lrewrite);
+
+    __ cmpwi(CCR1, Rnext_byte, (unsigned int)(unsigned char)Bytecodes::_fast_fgetfield);
+    __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_faccess_0);
+    __ beq(CCR1, Lrewrite);
+
+    __ li(Rrewrite_to, (unsigned int)(unsigned char)Bytecodes::_fast_aload_0);
+
+    __ bind(Lrewrite);
+    patch_bytecode(Bytecodes::_aload_0, Rrewrite_to, Rscratch, false);
+    __ bind(Ldont_rewrite);
+  }
+
+  // Do actual aload_0 (must do this after patch_bytecode which might call VM and GC might change oop).
+  aload(0);
+}
+
+void TemplateTable::istore() {
+  transition(itos, vtos);
+
+  const Register Rindex = R11_scratch1;
+  locals_index(Rindex);
+  __ store_local_int(R17_tos, Rindex);
+}
+
+void TemplateTable::lstore() {
+  transition(ltos, vtos);
+  const Register Rindex = R11_scratch1;
+  locals_index(Rindex);
+  __ store_local_long(R17_tos, Rindex);
+}
+
+void TemplateTable::fstore() {
+  transition(ftos, vtos);
+
+  const Register Rindex = R11_scratch1;
+  locals_index(Rindex);
+  __ store_local_float(F15_ftos, Rindex);
+}
+
+void TemplateTable::dstore() {
+  transition(dtos, vtos);
+
+  const Register Rindex = R11_scratch1;
+  locals_index(Rindex);
+  __ store_local_double(F15_ftos, Rindex);
+}
+
+void TemplateTable::astore() {
+  transition(vtos, vtos);
+
+  const Register Rindex = R11_scratch1;
+  __ pop_ptr();
+  __ verify_oop_or_return_address(R17_tos, Rindex);
+  locals_index(Rindex);
+  __ store_local_ptr(R17_tos, Rindex);
+}
+
+void TemplateTable::wide_istore() {
+  transition(vtos, vtos);
+
+  const Register Rindex = R11_scratch1;
+  __ pop_i();
+  locals_index_wide(Rindex);
+  __ store_local_int(R17_tos, Rindex);
+}
+
+void TemplateTable::wide_lstore() {
+  transition(vtos, vtos);
+
+  const Register Rindex = R11_scratch1;
+  __ pop_l();
+  locals_index_wide(Rindex);
+  __ store_local_long(R17_tos, Rindex);
+}
+
+void TemplateTable::wide_fstore() {
+  transition(vtos, vtos);
+
+  const Register Rindex = R11_scratch1;
+  __ pop_f();
+  locals_index_wide(Rindex);
+  __ store_local_float(F15_ftos, Rindex);
+}
+
+void TemplateTable::wide_dstore() {
+  transition(vtos, vtos);
+
+  const Register Rindex = R11_scratch1;
+  __ pop_d();
+  locals_index_wide(Rindex);
+  __ store_local_double(F15_ftos, Rindex);
+}
+
+void TemplateTable::wide_astore() {
+  transition(vtos, vtos);
+
+  const Register Rindex = R11_scratch1;
+  __ pop_ptr();
+  __ verify_oop_or_return_address(R17_tos, Rindex);
+  locals_index_wide(Rindex);
+  __ store_local_ptr(R17_tos, Rindex);
+}
+
+void TemplateTable::iastore() {
+  transition(itos, vtos);
+
+  const Register Rindex      = R3_ARG1,
+                 Rstore_addr = R4_ARG2,
+                 Rarray      = R5_ARG3,
+                 Rtemp       = R6_ARG4;
+  __ pop_i(Rindex);
+  __ index_check(Rarray, Rindex, LogBytesPerInt, Rtemp, Rstore_addr);
+  __ stw(R17_tos, arrayOopDesc::base_offset_in_bytes(T_INT), Rstore_addr);
+  }
+
+void TemplateTable::lastore() {
+  transition(ltos, vtos);
+
+  const Register Rindex      = R3_ARG1,
+                 Rstore_addr = R4_ARG2,
+                 Rarray      = R5_ARG3,
+                 Rtemp       = R6_ARG4;
+  __ pop_i(Rindex);
+  __ index_check(Rarray, Rindex, LogBytesPerLong, Rtemp, Rstore_addr);
+  __ std(R17_tos, arrayOopDesc::base_offset_in_bytes(T_LONG), Rstore_addr);
+  }
+
+void TemplateTable::fastore() {
+  transition(ftos, vtos);
+
+  const Register Rindex      = R3_ARG1,
+                 Rstore_addr = R4_ARG2,
+                 Rarray      = R5_ARG3,
+                 Rtemp       = R6_ARG4;
+  __ pop_i(Rindex);
+  __ index_check(Rarray, Rindex, LogBytesPerInt, Rtemp, Rstore_addr);
+  __ stfs(F15_ftos, arrayOopDesc::base_offset_in_bytes(T_FLOAT), Rstore_addr);
+  }
+
+void TemplateTable::dastore() {
+  transition(dtos, vtos);
+
+  const Register Rindex      = R3_ARG1,
+                 Rstore_addr = R4_ARG2,
+                 Rarray      = R5_ARG3,
+                 Rtemp       = R6_ARG4;
+  __ pop_i(Rindex);
+  __ index_check(Rarray, Rindex, LogBytesPerLong, Rtemp, Rstore_addr);
+  __ stfd(F15_ftos, arrayOopDesc::base_offset_in_bytes(T_DOUBLE), Rstore_addr);
+  }
+
+// Pop 3 values from the stack and...
+void TemplateTable::aastore() {
+  transition(vtos, vtos);
+
+  Label Lstore_ok, Lis_null, Ldone;
+  const Register Rindex    = R3_ARG1,
+                 Rarray    = R4_ARG2,
+                 Rscratch  = R11_scratch1,
+                 Rscratch2 = R12_scratch2,
+                 Rarray_klass = R5_ARG3,
+                 Rarray_element_klass = Rarray_klass,
+                 Rvalue_klass = R6_ARG4,
+                 Rstore_addr = R31;    // Use register which survives VM call.
+
+  __ ld(R17_tos, Interpreter::expr_offset_in_bytes(0), R15_esp); // Get value to store.
+  __ lwz(Rindex, Interpreter::expr_offset_in_bytes(1), R15_esp); // Get index.
+  __ ld(Rarray, Interpreter::expr_offset_in_bytes(2), R15_esp);  // Get array.
+
+  __ verify_oop(R17_tos);
+  __ index_check_without_pop(Rarray, Rindex, UseCompressedOops ? 2 : LogBytesPerWord, Rscratch, Rstore_addr);
+  // Rindex is dead!
+  Register Rscratch3 = Rindex;
+
+  // Do array store check - check for NULL value first.
+  __ cmpdi(CCR0, R17_tos, 0);
+  __ beq(CCR0, Lis_null);
+
+  __ load_klass(Rarray_klass, Rarray);
+  __ load_klass(Rvalue_klass, R17_tos);
+
+  // Do fast instanceof cache test.
+  __ ld(Rarray_element_klass, in_bytes(ObjArrayKlass::element_klass_offset()), Rarray_klass);
+
+  // Generate a fast subtype check. Branch to store_ok if no failure. Throw if failure.
+  __ gen_subtype_check(Rvalue_klass /*subklass*/, Rarray_element_klass /*superklass*/, Rscratch, Rscratch2, Rscratch3, Lstore_ok);
+
+  // Fell through: subtype check failed => throw an exception.
+  __ load_dispatch_table(R11_scratch1, (address*)Interpreter::_throw_ArrayStoreException_entry);
+  __ mtctr(R11_scratch1);
+  __ bctr();
+
+  __ bind(Lis_null);
+  do_oop_store(_masm, Rstore_addr, arrayOopDesc::base_offset_in_bytes(T_OBJECT), noreg /* 0 */,
+               Rscratch, Rscratch2, Rscratch3, _bs->kind(), true /* precise */, false /* check_null */);
+  __ profile_null_seen(Rscratch, Rscratch2);
+  __ b(Ldone);
+
+  // Store is OK.
+  __ bind(Lstore_ok);
+  do_oop_store(_masm, Rstore_addr, arrayOopDesc::base_offset_in_bytes(T_OBJECT), R17_tos /* value */,
+               Rscratch, Rscratch2, Rscratch3, _bs->kind(), true /* precise */, false /* check_null */);
+
+  __ bind(Ldone);
+  // Adjust sp (pops array, index and value).
+  __ addi(R15_esp, R15_esp, 3 * Interpreter::stackElementSize);
+}
+
+void TemplateTable::bastore() {
+  transition(itos, vtos);
+
+  const Register Rindex   = R11_scratch1,
+                 Rarray   = R12_scratch2,
+                 Rscratch = R3_ARG1;
+  __ pop_i(Rindex);
+  // tos: val
+  // Rarray: array ptr (popped by index_check)
+  __ index_check(Rarray, Rindex, 0, Rscratch, Rarray);
+  __ stb(R17_tos, arrayOopDesc::base_offset_in_bytes(T_BYTE), Rarray);
+}
+
+void TemplateTable::castore() {
+  transition(itos, vtos);
+
+  const Register Rindex   = R11_scratch1,
+                 Rarray   = R12_scratch2,
+                 Rscratch = R3_ARG1;
+  __ pop_i(Rindex);
+  // tos: val
+  // Rarray: array ptr (popped by index_check)
+  __ index_check(Rarray, Rindex, LogBytesPerShort, Rscratch, Rarray);
+  __ sth(R17_tos, arrayOopDesc::base_offset_in_bytes(T_CHAR), Rarray);
+}
+
+void TemplateTable::sastore() {
+  castore();
+}
+
+void TemplateTable::istore(int n) {
+  transition(itos, vtos);
+  __ stw(R17_tos, Interpreter::local_offset_in_bytes(n), R18_locals);
+}
+
+void TemplateTable::lstore(int n) {
+  transition(ltos, vtos);
+  __ std(R17_tos, Interpreter::local_offset_in_bytes(n + 1), R18_locals);
+}
+
+void TemplateTable::fstore(int n) {
+  transition(ftos, vtos);
+  __ stfs(F15_ftos, Interpreter::local_offset_in_bytes(n), R18_locals);
+}
+
+void TemplateTable::dstore(int n) {
+  transition(dtos, vtos);
+  __ stfd(F15_ftos, Interpreter::local_offset_in_bytes(n + 1), R18_locals);
+}
+
+void TemplateTable::astore(int n) {
+  transition(vtos, vtos);
+
+  __ pop_ptr();
+  __ verify_oop_or_return_address(R17_tos, R11_scratch1);
+  __ std(R17_tos, Interpreter::local_offset_in_bytes(n), R18_locals);
+}
+
+void TemplateTable::pop() {
+  transition(vtos, vtos);
+
+  __ addi(R15_esp, R15_esp, Interpreter::stackElementSize);
+}
+
+void TemplateTable::pop2() {
+  transition(vtos, vtos);
+
+  __ addi(R15_esp, R15_esp, Interpreter::stackElementSize * 2);
+}
+
+void TemplateTable::dup() {
+  transition(vtos, vtos);
+
+  __ ld(R11_scratch1, Interpreter::stackElementSize, R15_esp);
+  __ push_ptr(R11_scratch1);
+}
+
+void TemplateTable::dup_x1() {
+  transition(vtos, vtos);
+
+  Register Ra = R11_scratch1,
+           Rb = R12_scratch2;
+  // stack: ..., a, b
+  __ ld(Rb, Interpreter::stackElementSize,     R15_esp);
+  __ ld(Ra, Interpreter::stackElementSize * 2, R15_esp);
+  __ std(Rb, Interpreter::stackElementSize * 2, R15_esp);
+  __ std(Ra, Interpreter::stackElementSize,     R15_esp);
+  __ push_ptr(Rb);
+  // stack: ..., b, a, b
+}
+
+void TemplateTable::dup_x2() {
+  transition(vtos, vtos);
+
+  Register Ra = R11_scratch1,
+           Rb = R12_scratch2,
+           Rc = R3_ARG1;
+
+  // stack: ..., a, b, c
+  __ ld(Rc, Interpreter::stackElementSize,     R15_esp);  // load c
+  __ ld(Ra, Interpreter::stackElementSize * 3, R15_esp);  // load a
+  __ std(Rc, Interpreter::stackElementSize * 3, R15_esp); // store c in a
+  __ ld(Rb, Interpreter::stackElementSize * 2, R15_esp);  // load b
+  // stack: ..., c, b, c
+  __ std(Ra, Interpreter::stackElementSize * 2, R15_esp); // store a in b
+  // stack: ..., c, a, c
+  __ std(Rb, Interpreter::stackElementSize,     R15_esp); // store b in c
+  __ push_ptr(Rc);                                        // push c
+  // stack: ..., c, a, b, c
+}
+
+void TemplateTable::dup2() {
+  transition(vtos, vtos);
+
+  Register Ra = R11_scratch1,
+           Rb = R12_scratch2;
+  // stack: ..., a, b
+  __ ld(Rb, Interpreter::stackElementSize,     R15_esp);
+  __ ld(Ra, Interpreter::stackElementSize * 2, R15_esp);
+  __ push_2ptrs(Ra, Rb);
+  // stack: ..., a, b, a, b
+}
+
+void TemplateTable::dup2_x1() {
+  transition(vtos, vtos);
+
+  Register Ra = R11_scratch1,
+           Rb = R12_scratch2,
+           Rc = R3_ARG1;
+  // stack: ..., a, b, c
+  __ ld(Rc, Interpreter::stackElementSize,     R15_esp);
+  __ ld(Rb, Interpreter::stackElementSize * 2, R15_esp);
+  __ std(Rc, Interpreter::stackElementSize * 2, R15_esp);
+  __ ld(Ra, Interpreter::stackElementSize * 3, R15_esp);
+  __ std(Ra, Interpreter::stackElementSize,     R15_esp);
+  __ std(Rb, Interpreter::stackElementSize * 3, R15_esp);
+  // stack: ..., b, c, a
+  __ push_2ptrs(Rb, Rc);
+  // stack: ..., b, c, a, b, c
+}
+
+void TemplateTable::dup2_x2() {
+  transition(vtos, vtos);
+
+  Register Ra = R11_scratch1,
+           Rb = R12_scratch2,
+           Rc = R3_ARG1,
+           Rd = R4_ARG2;
+  // stack: ..., a, b, c, d
+  __ ld(Rb, Interpreter::stackElementSize * 3, R15_esp);
+  __ ld(Rd, Interpreter::stackElementSize,     R15_esp);
+  __ std(Rb, Interpreter::stackElementSize,     R15_esp);  // store b in d
+  __ std(Rd, Interpreter::stackElementSize * 3, R15_esp);  // store d in b
+  __ ld(Ra, Interpreter::stackElementSize * 4, R15_esp);
+  __ ld(Rc, Interpreter::stackElementSize * 2, R15_esp);
+  __ std(Ra, Interpreter::stackElementSize * 2, R15_esp);  // store a in c
+  __ std(Rc, Interpreter::stackElementSize * 4, R15_esp);  // store c in a
+  // stack: ..., c, d, a, b
+  __ push_2ptrs(Rc, Rd);
+  // stack: ..., c, d, a, b, c, d
+}
+
+void TemplateTable::swap() {
+  transition(vtos, vtos);
+  // stack: ..., a, b
+
+  Register Ra = R11_scratch1,
+           Rb = R12_scratch2;
+  // stack: ..., a, b
+  __ ld(Rb, Interpreter::stackElementSize,     R15_esp);
+  __ ld(Ra, Interpreter::stackElementSize * 2, R15_esp);
+  __ std(Rb, Interpreter::stackElementSize * 2, R15_esp);
+  __ std(Ra, Interpreter::stackElementSize,     R15_esp);
+  // stack: ..., b, a
+}
+
+void TemplateTable::iop2(Operation op) {
+  transition(itos, itos);
+
+  Register Rscratch = R11_scratch1;
+
+  __ pop_i(Rscratch);
+  // tos  = number of bits to shift
+  // Rscratch = value to shift
+  switch (op) {
+    case  add:   __ add(R17_tos, Rscratch, R17_tos); break;
+    case  sub:   __ sub(R17_tos, Rscratch, R17_tos); break;
+    case  mul:   __ mullw(R17_tos, Rscratch, R17_tos); break;
+    case  _and:  __ andr(R17_tos, Rscratch, R17_tos); break;
+    case  _or:   __ orr(R17_tos, Rscratch, R17_tos); break;
+    case  _xor:  __ xorr(R17_tos, Rscratch, R17_tos); break;
+    case  shl:   __ rldicl(R17_tos, R17_tos, 0, 64-5); __ slw(R17_tos, Rscratch, R17_tos); break;
+    case  shr:   __ rldicl(R17_tos, R17_tos, 0, 64-5); __ sraw(R17_tos, Rscratch, R17_tos); break;
+    case  ushr:  __ rldicl(R17_tos, R17_tos, 0, 64-5); __ srw(R17_tos, Rscratch, R17_tos); break;
+    default:     ShouldNotReachHere();
+  }
+}
+
+void TemplateTable::lop2(Operation op) {
+  transition(ltos, ltos);
+
+  Register Rscratch = R11_scratch1;
+  __ pop_l(Rscratch);
+  switch (op) {
+    case  add:   __ add(R17_tos, Rscratch, R17_tos); break;
+    case  sub:   __ sub(R17_tos, Rscratch, R17_tos); break;
+    case  _and:  __ andr(R17_tos, Rscratch, R17_tos); break;
+    case  _or:   __ orr(R17_tos, Rscratch, R17_tos); break;
+    case  _xor:  __ xorr(R17_tos, Rscratch, R17_tos); break;
+    default:     ShouldNotReachHere();
+  }
+}
+
+void TemplateTable::idiv() {
+  transition(itos, itos);
+
+  Label Lnormal, Lexception, Ldone;
+  Register Rdividend = R11_scratch1; // Used by irem.
+
+  __ addi(R0, R17_tos, 1);
+  __ cmplwi(CCR0, R0, 2);
+  __ bgt(CCR0, Lnormal); // divisor <-1 or >1
+
+  __ cmpwi(CCR1, R17_tos, 0);
+  __ beq(CCR1, Lexception); // divisor == 0
+
+  __ pop_i(Rdividend);
+  __ mullw(R17_tos, Rdividend, R17_tos); // div by +/-1
+  __ b(Ldone);
+
+  __ bind(Lexception);
+  __ load_dispatch_table(R11_scratch1, (address*)Interpreter::_throw_ArithmeticException_entry);
+  __ mtctr(R11_scratch1);
+  __ bctr();
+
+  __ align(32, 12);
+  __ bind(Lnormal);
+  __ pop_i(Rdividend);
+  __ divw(R17_tos, Rdividend, R17_tos); // Can't divide minint/-1.
+  __ bind(Ldone);
+}
+
+void TemplateTable::irem() {
+  transition(itos, itos);
+
+  __ mr(R12_scratch2, R17_tos);
+  idiv();
+  __ mullw(R17_tos, R17_tos, R12_scratch2);
+  __ subf(R17_tos, R17_tos, R11_scratch1); // Dividend set by idiv.
+}
+
+void TemplateTable::lmul() {
+  transition(ltos, ltos);
+
+  __ pop_l(R11_scratch1);
+  __ mulld(R17_tos, R11_scratch1, R17_tos);
+}
+
+void TemplateTable::ldiv() {
+  transition(ltos, ltos);
+
+  Label Lnormal, Lexception, Ldone;
+  Register Rdividend = R11_scratch1; // Used by lrem.
+
+  __ addi(R0, R17_tos, 1);
+  __ cmpldi(CCR0, R0, 2);
+  __ bgt(CCR0, Lnormal); // divisor <-1 or >1
+
+  __ cmpdi(CCR1, R17_tos, 0);
+  __ beq(CCR1, Lexception); // divisor == 0
+
+  __ pop_l(Rdividend);
+  __ mulld(R17_tos, Rdividend, R17_tos); // div by +/-1
+  __ b(Ldone);
+
+  __ bind(Lexception);
+  __ load_dispatch_table(R11_scratch1, (address*)Interpreter::_throw_ArithmeticException_entry);
+  __ mtctr(R11_scratch1);
+  __ bctr();
+
+  __ align(32, 12);
+  __ bind(Lnormal);
+  __ pop_l(Rdividend);
+  __ divd(R17_tos, Rdividend, R17_tos); // Can't divide minint/-1.
+  __ bind(Ldone);
+}
+
+void TemplateTable::lrem() {
+  transition(ltos, ltos);
+
+  __ mr(R12_scratch2, R17_tos);
+  ldiv();
+  __ mulld(R17_tos, R17_tos, R12_scratch2);
+  __ subf(R17_tos, R17_tos, R11_scratch1); // Dividend set by ldiv.
+}
+
+void TemplateTable::lshl() {
+  transition(itos, ltos);
+
+  __ rldicl(R17_tos, R17_tos, 0, 64-6); // Extract least significant bits.
+  __ pop_l(R11_scratch1);
+  __ sld(R17_tos, R11_scratch1, R17_tos);
+}
+
+void TemplateTable::lshr() {
+  transition(itos, ltos);
+
+  __ rldicl(R17_tos, R17_tos, 0, 64-6); // Extract least significant bits.
+  __ pop_l(R11_scratch1);
+  __ srad(R17_tos, R11_scratch1, R17_tos);
+}
+
+void TemplateTable::lushr() {
+  transition(itos, ltos);
+
+  __ rldicl(R17_tos, R17_tos, 0, 64-6); // Extract least significant bits.
+  __ pop_l(R11_scratch1);
+  __ srd(R17_tos, R11_scratch1, R17_tos);
+}
+
+void TemplateTable::fop2(Operation op) {
+  transition(ftos, ftos);
+
+  switch (op) {
+    case add: __ pop_f(F0_SCRATCH); __ fadds(F15_ftos, F0_SCRATCH, F15_ftos); break;
+    case sub: __ pop_f(F0_SCRATCH); __ fsubs(F15_ftos, F0_SCRATCH, F15_ftos); break;
+    case mul: __ pop_f(F0_SCRATCH); __ fmuls(F15_ftos, F0_SCRATCH, F15_ftos); break;
+    case div: __ pop_f(F0_SCRATCH); __ fdivs(F15_ftos, F0_SCRATCH, F15_ftos); break;
+    case rem:
+      __ pop_f(F1_ARG1);
+      __ fmr(F2_ARG2, F15_ftos);
+      __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::frem));
+      __ fmr(F15_ftos, F1_RET);
+      break;
+
+    default: ShouldNotReachHere();
+  }
+}
+
+void TemplateTable::dop2(Operation op) {
+  transition(dtos, dtos);
+
+  switch (op) {
+    case add: __ pop_d(F0_SCRATCH); __ fadd(F15_ftos, F0_SCRATCH, F15_ftos); break;
+    case sub: __ pop_d(F0_SCRATCH); __ fsub(F15_ftos, F0_SCRATCH, F15_ftos); break;
+    case mul: __ pop_d(F0_SCRATCH); __ fmul(F15_ftos, F0_SCRATCH, F15_ftos); break;
+    case div: __ pop_d(F0_SCRATCH); __ fdiv(F15_ftos, F0_SCRATCH, F15_ftos); break;
+    case rem:
+      __ pop_d(F1_ARG1);
+      __ fmr(F2_ARG2, F15_ftos);
+      __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::drem));
+      __ fmr(F15_ftos, F1_RET);
+      break;
+
+    default: ShouldNotReachHere();
+  }
+}
+
+// Negate the value in the TOS cache.
+void TemplateTable::ineg() {
+  transition(itos, itos);
+
+  __ neg(R17_tos, R17_tos);
+}
+
+// Negate the value in the TOS cache.
+void TemplateTable::lneg() {
+  transition(ltos, ltos);
+
+  __ neg(R17_tos, R17_tos);
+}
+
+void TemplateTable::fneg() {
+  transition(ftos, ftos);
+
+  __ fneg(F15_ftos, F15_ftos);
+}
+
+void TemplateTable::dneg() {
+  transition(dtos, dtos);
+
+  __ fneg(F15_ftos, F15_ftos);
+}
+
+// Increments a local variable in place.
+void TemplateTable::iinc() {
+  transition(vtos, vtos);
+
+  const Register Rindex     = R11_scratch1,
+                 Rincrement = R0,
+                 Rvalue     = R12_scratch2;
+
+  locals_index(Rindex);              // Load locals index from bytecode stream.
+  __ lbz(Rincrement, 2, R14_bcp);    // Load increment from the bytecode stream.
+  __ extsb(Rincrement, Rincrement);
+
+  __ load_local_int(Rvalue, Rindex, Rindex); // Puts address of local into Rindex.
+
+  __ add(Rvalue, Rincrement, Rvalue);
+  __ stw(Rvalue, 0, Rindex);
+}
+
+void TemplateTable::wide_iinc() {
+  transition(vtos, vtos);
+
+  Register Rindex       = R11_scratch1,
+           Rlocals_addr = Rindex,
+           Rincr        = R12_scratch2;
+  locals_index_wide(Rindex);
+  __ get_2_byte_integer_at_bcp(4, Rincr, InterpreterMacroAssembler::Signed);
+  __ load_local_int(R17_tos, Rlocals_addr, Rindex);
+  __ add(R17_tos, Rincr, R17_tos);
+  __ stw(R17_tos, 0, Rlocals_addr);
+}
+
+void TemplateTable::convert() {
+  // %%%%% Factor this first part accross platforms
+#ifdef ASSERT
+  TosState tos_in  = ilgl;
+  TosState tos_out = ilgl;
+  switch (bytecode()) {
+    case Bytecodes::_i2l: // fall through
+    case Bytecodes::_i2f: // fall through
+    case Bytecodes::_i2d: // fall through
+    case Bytecodes::_i2b: // fall through
+    case Bytecodes::_i2c: // fall through
+    case Bytecodes::_i2s: tos_in = itos; break;
+    case Bytecodes::_l2i: // fall through
+    case Bytecodes::_l2f: // fall through
+    case Bytecodes::_l2d: tos_in = ltos; break;
+    case Bytecodes::_f2i: // fall through
+    case Bytecodes::_f2l: // fall through
+    case Bytecodes::_f2d: tos_in = ftos; break;
+    case Bytecodes::_d2i: // fall through
+    case Bytecodes::_d2l: // fall through
+    case Bytecodes::_d2f: tos_in = dtos; break;
+    default             : ShouldNotReachHere();
+  }
+  switch (bytecode()) {
+    case Bytecodes::_l2i: // fall through
+    case Bytecodes::_f2i: // fall through
+    case Bytecodes::_d2i: // fall through
+    case Bytecodes::_i2b: // fall through
+    case Bytecodes::_i2c: // fall through
+    case Bytecodes::_i2s: tos_out = itos; break;
+    case Bytecodes::_i2l: // fall through
+    case Bytecodes::_f2l: // fall through
+    case Bytecodes::_d2l: tos_out = ltos; break;
+    case Bytecodes::_i2f: // fall through
+    case Bytecodes::_l2f: // fall through
+    case Bytecodes::_d2f: tos_out = ftos; break;
+    case Bytecodes::_i2d: // fall through
+    case Bytecodes::_l2d: // fall through
+    case Bytecodes::_f2d: tos_out = dtos; break;
+    default             : ShouldNotReachHere();
+  }
+  transition(tos_in, tos_out);
+#endif
+
+  // Conversion
+  Label done;
+  switch (bytecode()) {
+    case Bytecodes::_i2l:
+      __ extsw(R17_tos, R17_tos);
+      break;
+
+    case Bytecodes::_l2i:
+      // Nothing to do, we'll continue to work with the lower bits.
+      break;
+
+    case Bytecodes::_i2b:
+      __ extsb(R17_tos, R17_tos);
+      break;
+
+    case Bytecodes::_i2c:
+      __ rldicl(R17_tos, R17_tos, 0, 64-2*8);
+      break;
+
+    case Bytecodes::_i2s:
+      __ extsh(R17_tos, R17_tos);
+      break;
+
+    case Bytecodes::_i2d:
+      __ extsw(R17_tos, R17_tos);
+    case Bytecodes::_l2d:
+      __ push_l_pop_d();
+      __ fcfid(F15_ftos, F15_ftos);
+      break;
+
+    case Bytecodes::_i2f:
+      __ extsw(R17_tos, R17_tos);
+      __ push_l_pop_d();
+      if (VM_Version::has_fcfids()) { // fcfids is >= Power7 only
+        // Comment: alternatively, load with sign extend could be done by lfiwax.
+        __ fcfids(F15_ftos, F15_ftos);
+      } else {
+        __ fcfid(F15_ftos, F15_ftos);
+        __ frsp(F15_ftos, F15_ftos);
+      }
+      break;
+
+    case Bytecodes::_l2f:
+      if (VM_Version::has_fcfids()) { // fcfids is >= Power7 only
+        __ push_l_pop_d();
+        __ fcfids(F15_ftos, F15_ftos);
+      } else {
+        // Avoid rounding problem when result should be 0x3f800001: need fixup code before fcfid+frsp.
+        __ mr(R3_ARG1, R17_tos);
+        __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::l2f));
+        __ fmr(F15_ftos, F1_RET);
+      }
+      break;
+
+    case Bytecodes::_f2d:
+      // empty
+      break;
+
+    case Bytecodes::_d2f:
+      __ frsp(F15_ftos, F15_ftos);
+      break;
+
+    case Bytecodes::_d2i:
+    case Bytecodes::_f2i:
+      __ fcmpu(CCR0, F15_ftos, F15_ftos);
+      __ li(R17_tos, 0); // 0 in case of NAN
+      __ bso(CCR0, done);
+      __ fctiwz(F15_ftos, F15_ftos);
+      __ push_d_pop_l();
+      break;
+
+    case Bytecodes::_d2l:
+    case Bytecodes::_f2l:
+      __ fcmpu(CCR0, F15_ftos, F15_ftos);
+      __ li(R17_tos, 0); // 0 in case of NAN
+      __ bso(CCR0, done);
+      __ fctidz(F15_ftos, F15_ftos);
+      __ push_d_pop_l();
+      break;
+
+    default: ShouldNotReachHere();
+  }
+  __ bind(done);
+}
+
+// Long compare
+void TemplateTable::lcmp() {
+  transition(ltos, itos);
+
+  const Register Rscratch = R11_scratch1;
+  __ pop_l(Rscratch); // first operand, deeper in stack
+
+  __ cmpd(CCR0, Rscratch, R17_tos); // compare
+  __ mfcr(R17_tos); // set bit 32..33 as follows: <: 0b10, =: 0b00, >: 0b01
+  __ srwi(Rscratch, R17_tos, 30);
+  __ srawi(R17_tos, R17_tos, 31);
+  __ orr(R17_tos, Rscratch, R17_tos); // set result as follows: <: -1, =: 0, >: 1
+}
+
+// fcmpl/fcmpg and dcmpl/dcmpg bytecodes
+// unordered_result == -1 => fcmpl or dcmpl
+// unordered_result ==  1 => fcmpg or dcmpg
+void TemplateTable::float_cmp(bool is_float, int unordered_result) {
+  const FloatRegister Rfirst  = F0_SCRATCH,
+                      Rsecond = F15_ftos;
+  const Register Rscratch = R11_scratch1;
+
+  if (is_float) {
+    __ pop_f(Rfirst);
+  } else {
+    __ pop_d(Rfirst);
+  }
+
+  Label Lunordered, Ldone;
+  __ fcmpu(CCR0, Rfirst, Rsecond); // compare
+  if (unordered_result) {
+    __ bso(CCR0, Lunordered);
+  }
+  __ mfcr(R17_tos); // set bit 32..33 as follows: <: 0b10, =: 0b00, >: 0b01
+  __ srwi(Rscratch, R17_tos, 30);
+  __ srawi(R17_tos, R17_tos, 31);
+  __ orr(R17_tos, Rscratch, R17_tos); // set result as follows: <: -1, =: 0, >: 1
+  if (unordered_result) {
+    __ b(Ldone);
+    __ bind(Lunordered);
+    __ load_const_optimized(R17_tos, unordered_result);
+  }
+  __ bind(Ldone);
+}
+
+// Branch_conditional which takes TemplateTable::Condition.
+void TemplateTable::branch_conditional(ConditionRegister crx, TemplateTable::Condition cc, Label& L, bool invert) {
+  bool positive = false;
+  Assembler::Condition cond = Assembler::equal;
+  switch (cc) {
+    case TemplateTable::equal:         positive = true ; cond = Assembler::equal  ; break;
+    case TemplateTable::not_equal:     positive = false; cond = Assembler::equal  ; break;
+    case TemplateTable::less:          positive = true ; cond = Assembler::less   ; break;
+    case TemplateTable::less_equal:    positive = false; cond = Assembler::greater; break;
+    case TemplateTable::greater:       positive = true ; cond = Assembler::greater; break;
+    case TemplateTable::greater_equal: positive = false; cond = Assembler::less   ; break;
+    default: ShouldNotReachHere();
+  }
+  int bo = (positive != invert) ? Assembler::bcondCRbiIs1 : Assembler::bcondCRbiIs0;
+  int bi = Assembler::bi0(crx, cond);
+  __ bc(bo, bi, L);
+}
+
+void TemplateTable::branch(bool is_jsr, bool is_wide) {
+
+  // Note: on SPARC, we use InterpreterMacroAssembler::if_cmp also.
+  __ verify_thread();
+
+  const Register Rscratch1    = R11_scratch1,
+                 Rscratch2    = R12_scratch2,
+                 Rscratch3    = R3_ARG1,
+                 R4_counters  = R4_ARG2,
+                 bumped_count = R31,
+                 Rdisp        = R22_tmp2;
+
+  __ profile_taken_branch(Rscratch1, bumped_count);
+
+  // Get (wide) offset.
+  if (is_wide) {
+    __ get_4_byte_integer_at_bcp(1, Rdisp, InterpreterMacroAssembler::Signed);
+  } else {
+    __ get_2_byte_integer_at_bcp(1, Rdisp, InterpreterMacroAssembler::Signed);
+  }
+
+  // --------------------------------------------------------------------------
+  // Handle all the JSR stuff here, then exit.
+  // It's much shorter and cleaner than intermingling with the
+  // non-JSR normal-branch stuff occurring below.
+  if (is_jsr) {
+    // Compute return address as bci in Otos_i.
+    __ ld(Rscratch1, in_bytes(Method::const_offset()), R19_method);
+    __ addi(Rscratch2, R14_bcp, -in_bytes(ConstMethod::codes_offset()) + (is_wide ? 5 : 3));
+    __ subf(R17_tos, Rscratch1, Rscratch2);
+
+    // Bump bcp to target of JSR.
+    __ add(R14_bcp, Rdisp, R14_bcp);
+    // Push returnAddress for "ret" on stack.
+    __ push_ptr(R17_tos);
+    // And away we go!
+    __ dispatch_next(vtos);
+    return;
+  }
+
+  // --------------------------------------------------------------------------
+  // Normal (non-jsr) branch handling
+
+  const bool increment_invocation_counter_for_backward_branches = UseCompiler && UseLoopCounter;
+  if (increment_invocation_counter_for_backward_branches) {
+    //__ unimplemented("branch invocation counter");
+
+    Label Lforward;
+    __ add(R14_bcp, Rdisp, R14_bcp); // Add to bc addr.
+
+    // Check branch direction.
+    __ cmpdi(CCR0, Rdisp, 0);
+    __ bgt(CCR0, Lforward);
+
+    __ get_method_counters(R19_method, R4_counters, Lforward);
+
+    if (TieredCompilation) {
+      Label Lno_mdo, Loverflow;
+      const int increment = InvocationCounter::count_increment;
+      const int mask = ((1 << Tier0BackedgeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
+      if (ProfileInterpreter) {
+        Register Rmdo = Rscratch1;
+
+        // If no method data exists, go to profile_continue.
+        __ ld(Rmdo, in_bytes(Method::method_data_offset()), R19_method);
+        __ cmpdi(CCR0, Rmdo, 0);
+        __ beq(CCR0, Lno_mdo);
+
+        // Increment backedge counter in the MDO.
+        const int mdo_bc_offs = in_bytes(MethodData::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset());
+        __ lwz(Rscratch2, mdo_bc_offs, Rmdo);
+        __ load_const_optimized(Rscratch3, mask, R0);
+        __ addi(Rscratch2, Rscratch2, increment);
+        __ stw(Rscratch2, mdo_bc_offs, Rmdo);
+        __ and_(Rscratch3, Rscratch2, Rscratch3);
+        __ bne(CCR0, Lforward);
+        __ b(Loverflow);
+      }
+
+      // If there's no MDO, increment counter in method.
+      const int mo_bc_offs = in_bytes(MethodCounters::backedge_counter_offset()) + in_bytes(InvocationCounter::counter_offset());
+      __ bind(Lno_mdo);
+      __ lwz(Rscratch2, mo_bc_offs, R4_counters);
+      __ load_const_optimized(Rscratch3, mask, R0);
+      __ addi(Rscratch2, Rscratch2, increment);
+      __ stw(Rscratch2, mo_bc_offs, R19_method);
+      __ and_(Rscratch3, Rscratch2, Rscratch3);
+      __ bne(CCR0, Lforward);
+
+      __ bind(Loverflow);
+
+      // Notify point for loop, pass branch bytecode.
+      __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), R14_bcp, true);
+
+      // Was an OSR adapter generated?
+      // O0 = osr nmethod
+      __ cmpdi(CCR0, R3_RET, 0);
+      __ beq(CCR0, Lforward);
+
+      // Has the nmethod been invalidated already?
+      __ lwz(R0, nmethod::entry_bci_offset(), R3_RET);
+      __ cmpwi(CCR0, R0, InvalidOSREntryBci);
+      __ beq(CCR0, Lforward);
+
+      // Migrate the interpreter frame off of the stack.
+      // We can use all registers because we will not return to interpreter from this point.
+
+      // Save nmethod.
+      const Register osr_nmethod = R31;
+      __ mr(osr_nmethod, R3_RET);
+      __ set_top_ijava_frame_at_SP_as_last_Java_frame(R1_SP, R11_scratch1);
+      __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_begin), R16_thread);
+      __ reset_last_Java_frame();
+      // OSR buffer is in ARG1.
+
+      // Remove the interpreter frame.
+      __ merge_frames(/*top_frame_sp*/ R21_sender_SP, /*return_pc*/ R0, R11_scratch1, R12_scratch2);
+
+      // Jump to the osr code.
+      __ ld(R11_scratch1, nmethod::osr_entry_point_offset(), osr_nmethod);
+      __ mtlr(R0);
+      __ mtctr(R11_scratch1);
+      __ bctr();
+
+    } else {
+
+      const Register invoke_ctr = Rscratch1;
+      // Update Backedge branch separately from invocations.
+      __ increment_backedge_counter(R4_counters, invoke_ctr, Rscratch2, Rscratch3);
+
+      if (ProfileInterpreter) {
+        __ test_invocation_counter_for_mdp(invoke_ctr, Rscratch2, Lforward);
+        if (UseOnStackReplacement) {
+          __ test_backedge_count_for_osr(bumped_count, R14_bcp, Rscratch2);
+        }
+      } else {
+        if (UseOnStackReplacement) {
+          __ test_backedge_count_for_osr(invoke_ctr, R14_bcp, Rscratch2);
+        }
+      }
+    }
+
+    __ bind(Lforward);
+
+  } else {
+    // Bump bytecode pointer by displacement (take the branch).
+    __ add(R14_bcp, Rdisp, R14_bcp); // Add to bc addr.
+  }
+  // Continue with bytecode @ target.
+  // %%%%% Like Intel, could speed things up by moving bytecode fetch to code above,
+  // %%%%% and changing dispatch_next to dispatch_only.
+  __ dispatch_next(vtos);
+}
+
+// Helper function for if_cmp* methods below.
+// Factored out common compare and branch code.
+void TemplateTable::if_cmp_common(Register Rfirst, Register Rsecond, Register Rscratch1, Register Rscratch2, Condition cc, bool is_jint, bool cmp0) {
+  Label Lnot_taken;
+  // Note: The condition code we get is the condition under which we
+  // *fall through*! So we have to inverse the CC here.
+
+  if (is_jint) {
+    if (cmp0) {
+      __ cmpwi(CCR0, Rfirst, 0);
+    } else {
+      __ cmpw(CCR0, Rfirst, Rsecond);
+    }
+  } else {
+    if (cmp0) {
+      __ cmpdi(CCR0, Rfirst, 0);
+    } else {
+      __ cmpd(CCR0, Rfirst, Rsecond);
+    }
+  }
+  branch_conditional(CCR0, cc, Lnot_taken, /*invert*/ true);
+
+  // Conition is false => Jump!
+  branch(false, false);
+
+  // Condition is not true => Continue.
+  __ align(32, 12);
+  __ bind(Lnot_taken);
+  __ profile_not_taken_branch(Rscratch1, Rscratch2);
+}
+
+// Compare integer values with zero and fall through if CC holds, branch away otherwise.
+void TemplateTable::if_0cmp(Condition cc) {
+  transition(itos, vtos);
+
+  if_cmp_common(R17_tos, noreg, R11_scratch1, R12_scratch2, cc, true, true);
+}
+
+// Compare integer values and fall through if CC holds, branch away otherwise.
+//
+// Interface:
+//  - Rfirst: First operand  (older stack value)
+//  - tos:    Second operand (younger stack value)
+void TemplateTable::if_icmp(Condition cc) {
+  transition(itos, vtos);
+
+  const Register Rfirst  = R0,
+                 Rsecond = R17_tos;
+
+  __ pop_i(Rfirst);
+  if_cmp_common(Rfirst, Rsecond, R11_scratch1, R12_scratch2, cc, true, false);
+}
+
+void TemplateTable::if_nullcmp(Condition cc) {
+  transition(atos, vtos);
+
+  if_cmp_common(R17_tos, noreg, R11_scratch1, R12_scratch2, cc, false, true);
+}
+
+void TemplateTable::if_acmp(Condition cc) {
+  transition(atos, vtos);
+
+  const Register Rfirst  = R0,
+                 Rsecond = R17_tos;
+
+  __ pop_ptr(Rfirst);
+  if_cmp_common(Rfirst, Rsecond, R11_scratch1, R12_scratch2, cc, false, false);
+}
+
+void TemplateTable::ret() {
+  locals_index(R11_scratch1);
+  __ load_local_ptr(R17_tos, R11_scratch1, R11_scratch1);
+
+  __ profile_ret(vtos, R17_tos, R11_scratch1, R12_scratch2);
+
+  __ ld(R11_scratch1, in_bytes(Method::const_offset()), R19_method);
+  __ add(R11_scratch1, R17_tos, R11_scratch1);
+  __ addi(R14_bcp, R11_scratch1, in_bytes(ConstMethod::codes_offset()));
+  __ dispatch_next(vtos);
+}
+
+void TemplateTable::wide_ret() {
+  transition(vtos, vtos);
+
+  const Register Rindex = R3_ARG1,
+                 Rscratch1 = R11_scratch1,
+                 Rscratch2 = R12_scratch2;
+
+  locals_index_wide(Rindex);
+  __ load_local_ptr(R17_tos, R17_tos, Rindex);
+  __ profile_ret(vtos, R17_tos, Rscratch1, R12_scratch2);
+  // Tos now contains the bci, compute the bcp from that.
+  __ ld(Rscratch1, in_bytes(Method::const_offset()), R19_method);
+  __ addi(Rscratch2, R17_tos, in_bytes(ConstMethod::codes_offset()));
+  __ add(R14_bcp, Rscratch1, Rscratch2);
+  __ dispatch_next(vtos);
+}
+
+void TemplateTable::tableswitch() {
+  transition(itos, vtos);
+
+  Label Ldispatch, Ldefault_case;
+  Register Rlow_byte         = R3_ARG1,
+           Rindex            = Rlow_byte,
+           Rhigh_byte        = R4_ARG2,
+           Rdef_offset_addr  = R5_ARG3, // is going to contain address of default offset
+           Rscratch1         = R11_scratch1,
+           Rscratch2         = R12_scratch2,
+           Roffset           = R6_ARG4;
+
+  // Align bcp.
+  __ addi(Rdef_offset_addr, R14_bcp, BytesPerInt);
+  __ clrrdi(Rdef_offset_addr, Rdef_offset_addr, log2_long((jlong)BytesPerInt));
+
+  // Load lo & hi.
+  __ lwz(Rlow_byte, BytesPerInt, Rdef_offset_addr);
+  __ lwz(Rhigh_byte, BytesPerInt * 2, Rdef_offset_addr);
+
+  // Check for default case (=index outside [low,high]).
+  __ cmpw(CCR0, R17_tos, Rlow_byte);
+  __ cmpw(CCR1, R17_tos, Rhigh_byte);
+  __ blt(CCR0, Ldefault_case);
+  __ bgt(CCR1, Ldefault_case);
+
+  // Lookup dispatch offset.
+  __ sub(Rindex, R17_tos, Rlow_byte);
+  __ extsw(Rindex, Rindex);
+  __ profile_switch_case(Rindex, Rhigh_byte /* scratch */, Rscratch1, Rscratch2);
+  __ sldi(Rindex, Rindex, LogBytesPerInt);
+  __ addi(Rindex, Rindex, 3 * BytesPerInt);
+  __ lwax(Roffset, Rdef_offset_addr, Rindex);
+  __ b(Ldispatch);
+
+  __ bind(Ldefault_case);
+  __ profile_switch_default(Rhigh_byte, Rscratch1);
+  __ lwa(Roffset, 0, Rdef_offset_addr);
+
+  __ bind(Ldispatch);
+
+  __ add(R14_bcp, Roffset, R14_bcp);
+  __ dispatch_next(vtos);
+}
+
+void TemplateTable::lookupswitch() {
+  transition(itos, itos);
+  __ stop("lookupswitch bytecode should have been rewritten");
+}
+
+// Table switch using linear search through cases.
+// Bytecode stream format:
+// Bytecode (1) | 4-byte padding | default offset (4) | count (4) | value/offset pair1 (8) | value/offset pair2 (8) | ...
+// Note: Everything is big-endian format here. So on little endian machines, we have to revers offset and count and cmp value.
+void TemplateTable::fast_linearswitch() {
+  transition(itos, vtos);
+
+  Label Lloop_entry, Lsearch_loop, Lfound, Lcontinue_execution, Ldefault_case;
+
+  Register Rcount           = R3_ARG1,
+           Rcurrent_pair    = R4_ARG2,
+           Rdef_offset_addr = R5_ARG3, // Is going to contain address of default offset.
+           Roffset          = R31,     // Might need to survive C call.
+           Rvalue           = R12_scratch2,
+           Rscratch         = R11_scratch1,
+           Rcmp_value       = R17_tos;
+
+  // Align bcp.
+  __ addi(Rdef_offset_addr, R14_bcp, BytesPerInt);
+  __ clrrdi(Rdef_offset_addr, Rdef_offset_addr, log2_long((jlong)BytesPerInt));
+
+  // Setup loop counter and limit.
+  __ lwz(Rcount, BytesPerInt, Rdef_offset_addr);    // Load count.
+  __ addi(Rcurrent_pair, Rdef_offset_addr, 2 * BytesPerInt); // Rcurrent_pair now points to first pair.
+
+  // Set up search loop.
+  __ cmpwi(CCR0, Rcount, 0);
+  __ beq(CCR0, Ldefault_case);
+
+  __ mtctr(Rcount);
+
+  // linear table search
+  __ bind(Lsearch_loop);
+
+  __ lwz(Rvalue, 0, Rcurrent_pair);
+  __ lwa(Roffset, 1 * BytesPerInt, Rcurrent_pair);
+
+  __ cmpw(CCR0, Rvalue, Rcmp_value);
+  __ beq(CCR0, Lfound);
+
+  __ addi(Rcurrent_pair, Rcurrent_pair, 2 * BytesPerInt);
+  __ bdnz(Lsearch_loop);
+
+  // default case
+  __ bind(Ldefault_case);
+
+  __ lwa(Roffset, 0, Rdef_offset_addr);
+  if (ProfileInterpreter) {
+    __ profile_switch_default(Rdef_offset_addr, Rcount/* scratch */);
+    __ b(Lcontinue_execution);
+  }
+
+  // Entry found, skip Roffset bytecodes and continue.
+  __ bind(Lfound);
+  if (ProfileInterpreter) {
+    // Calc the num of the pair we hit. Careful, Rcurrent_pair points 2 ints
+    // beyond the actual current pair due to the auto update load above!
+    __ sub(Rcurrent_pair, Rcurrent_pair, Rdef_offset_addr);
+    __ addi(Rcurrent_pair, Rcurrent_pair, - 2 * BytesPerInt);
+    __ srdi(Rcurrent_pair, Rcurrent_pair, LogBytesPerInt + 1);
+    __ profile_switch_case(Rcurrent_pair, Rcount /*scratch*/, Rdef_offset_addr/*scratch*/, Rscratch);
+    __ bind(Lcontinue_execution);
+  }
+  __ add(R14_bcp, Roffset, R14_bcp);
+  __ dispatch_next(vtos);
+}
+
+// Table switch using binary search (value/offset pairs are ordered).
+// Bytecode stream format:
+// Bytecode (1) | 4-byte padding | default offset (4) | count (4) | value/offset pair1 (8) | value/offset pair2 (8) | ...
+// Note: Everything is big-endian format here. So on little endian machines, we have to revers offset and count and cmp value.
+void TemplateTable::fast_binaryswitch() {
+
+  transition(itos, vtos);
+  // Implementation using the following core algorithm: (copied from Intel)
+  //
+  // int binary_search(int key, LookupswitchPair* array, int n) {
+  //   // Binary search according to "Methodik des Programmierens" by
+  //   // Edsger W. Dijkstra and W.H.J. Feijen, Addison Wesley Germany 1985.
+  //   int i = 0;
+  //   int j = n;
+  //   while (i+1 < j) {
+  //     // invariant P: 0 <= i < j <= n and (a[i] <= key < a[j] or Q)
+  //     // with      Q: for all i: 0 <= i < n: key < a[i]
+  //     // where a stands for the array and assuming that the (inexisting)
+  //     // element a[n] is infinitely big.
+  //     int h = (i + j) >> 1;
+  //     // i < h < j
+  //     if (key < array[h].fast_match()) {
+  //       j = h;
+  //     } else {
+  //       i = h;
+  //     }
+  //   }
+  //   // R: a[i] <= key < a[i+1] or Q
+  //   // (i.e., if key is within array, i is the correct index)
+  //   return i;
+  // }
+
+  // register allocation
+  const Register Rkey     = R17_tos;          // already set (tosca)
+  const Register Rarray   = R3_ARG1;
+  const Register Ri       = R4_ARG2;
+  const Register Rj       = R5_ARG3;
+  const Register Rh       = R6_ARG4;
+  const Register Rscratch = R11_scratch1;
+
+  const int log_entry_size = 3;
+  const int entry_size = 1 << log_entry_size;
+
+  Label found;
+
+  // Find Array start,
+  __ addi(Rarray, R14_bcp, 3 * BytesPerInt);
+  __ clrrdi(Rarray, Rarray, log2_long((jlong)BytesPerInt));
+
+  // initialize i & j
+  __ li(Ri,0);
+  __ lwz(Rj, -BytesPerInt, Rarray);
+
+  // and start.
+  Label entry;
+  __ b(entry);
+
+  // binary search loop
+  { Label loop;
+    __ bind(loop);
+    // int h = (i + j) >> 1;
+    __ srdi(Rh, Rh, 1);
+    // if (key < array[h].fast_match()) {
+    //   j = h;
+    // } else {
+    //   i = h;
+    // }
+    __ sldi(Rscratch, Rh, log_entry_size);
+    __ lwzx(Rscratch, Rscratch, Rarray);
+
+    // if (key < current value)
+    //   Rh = Rj
+    // else
+    //   Rh = Ri
+    Label Lgreater;
+    __ cmpw(CCR0, Rkey, Rscratch);
+    __ bge(CCR0, Lgreater);
+    __ mr(Rj, Rh);
+    __ b(entry);
+    __ bind(Lgreater);
+    __ mr(Ri, Rh);
+
+    // while (i+1 < j)
+    __ bind(entry);
+    __ addi(Rscratch, Ri, 1);
+    __ cmpw(CCR0, Rscratch, Rj);
+    __ add(Rh, Ri, Rj); // start h = i + j >> 1;
+
+    __ blt(CCR0, loop);
+  }
+
+  // End of binary search, result index is i (must check again!).
+  Label default_case;
+  Label continue_execution;
+  if (ProfileInterpreter) {
+    __ mr(Rh, Ri);              // Save index in i for profiling.
+  }
+  // Ri = value offset
+  __ sldi(Ri, Ri, log_entry_size);
+  __ add(Ri, Ri, Rarray);
+  __ lwz(Rscratch, 0, Ri);
+
+  Label not_found;
+  // Ri = offset offset
+  __ cmpw(CCR0, Rkey, Rscratch);
+  __ beq(CCR0, not_found);
+  // entry not found -> j = default offset
+  __ lwz(Rj, -2 * BytesPerInt, Rarray);
+  __ b(default_case);
+
+  __ bind(not_found);
+  // entry found -> j = offset
+  __ profile_switch_case(Rh, Rj, Rscratch, Rkey);
+  __ lwz(Rj, BytesPerInt, Ri);
+
+  if (ProfileInterpreter) {
+    __ b(continue_execution);
+  }
+
+  __ bind(default_case); // fall through (if not profiling)
+  __ profile_switch_default(Ri, Rscratch);
+
+  __ bind(continue_execution);
+
+  __ extsw(Rj, Rj);
+  __ add(R14_bcp, Rj, R14_bcp);
+  __ dispatch_next(vtos);
+}
+
+void TemplateTable::_return(TosState state) {
+  transition(state, state);
+  assert(_desc->calls_vm(),
+         "inconsistent calls_vm information"); // call in remove_activation
+
+  if (_desc->bytecode() == Bytecodes::_return_register_finalizer) {
+
+    Register Rscratch     = R11_scratch1,
+             Rklass       = R12_scratch2,
+             Rklass_flags = Rklass;
+    Label Lskip_register_finalizer;
+
+    // Check if the method has the FINALIZER flag set and call into the VM to finalize in this case.
+    assert(state == vtos, "only valid state");
+    __ ld(R17_tos, 0, R18_locals);
+
+    // Load klass of this obj.
+    __ load_klass(Rklass, R17_tos);
+    __ lwz(Rklass_flags, in_bytes(Klass::access_flags_offset()), Rklass);
+    __ testbitdi(CCR0, R0, Rklass_flags, exact_log2(JVM_ACC_HAS_FINALIZER));
+    __ bfalse(CCR0, Lskip_register_finalizer);
+
+    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), R17_tos /* obj */);
+
+    __ align(32, 12);
+    __ bind(Lskip_register_finalizer);
+  }
+
+  // Move the result value into the correct register and remove memory stack frame.
+  __ remove_activation(state, /* throw_monitor_exception */ true);
+  // Restoration of lr done by remove_activation.
+  switch (state) {
+    case ltos:
+    case btos:
+    case ctos:
+    case stos:
+    case atos:
+    case itos: __ mr(R3_RET, R17_tos); break;
+    case ftos:
+    case dtos: __ fmr(F1_RET, F15_ftos); break;
+    case vtos: // This might be a constructor. Final fields (and volatile fields on PPC64) need
+               // to get visible before the reference to the object gets stored anywhere.
+               __ membar(Assembler::StoreStore); break;
+    default  : ShouldNotReachHere();
+  }
+  __ blr();
+}
+
+// ============================================================================
+// Constant pool cache access
+//
+// Memory ordering:
+//
+// Like done in C++ interpreter, we load the fields
+//   - _indices
+//   - _f12_oop
+// acquired, because these are asked if the cache is already resolved. We don't
+// want to float loads above this check.
+// See also comments in ConstantPoolCacheEntry::bytecode_1(),
+// ConstantPoolCacheEntry::bytecode_2() and ConstantPoolCacheEntry::f1();
+
+// Call into the VM if call site is not yet resolved
+//
+// Input regs:
+//   - None, all passed regs are outputs.
+//
+// Returns:
+//   - Rcache:  The const pool cache entry that contains the resolved result.
+//   - Rresult: Either noreg or output for f1/f2.
+//
+// Kills:
+//   - Rscratch
+void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register Rscratch, size_t index_size) {
+
+  __ get_cache_and_index_at_bcp(Rcache, 1, index_size);
+  Label Lresolved, Ldone;
+
+  assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
+  // We are resolved if the indices offset contains the current bytecode.
+  // Big Endian:
+  __ lbz(Rscratch, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::indices_offset()) + 7 - (byte_no + 1), Rcache);
+  // Acquire by cmp-br-isync (see below).
+  __ cmpdi(CCR0, Rscratch, (int)bytecode());
+  __ beq(CCR0, Lresolved);
+
+  address entry = NULL;
+  switch (bytecode()) {
+    case Bytecodes::_getstatic      : // fall through
+    case Bytecodes::_putstatic      : // fall through
+    case Bytecodes::_getfield       : // fall through
+    case Bytecodes::_putfield       : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
+    case Bytecodes::_invokevirtual  : // fall through
+    case Bytecodes::_invokespecial  : // fall through
+    case Bytecodes::_invokestatic   : // fall through
+    case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break;
+    case Bytecodes::_invokehandle   : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle); break;
+    case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
+    default                         : ShouldNotReachHere(); break;
+  }
+  __ li(R4_ARG2, (int)bytecode());
+  __ call_VM(noreg, entry, R4_ARG2, true);
+
+  // Update registers with resolved info.
+  __ get_cache_and_index_at_bcp(Rcache, 1, index_size);
+  __ b(Ldone);
+
+  __ bind(Lresolved);
+  __ isync(); // Order load wrt. succeeding loads.
+  __ bind(Ldone);
+}
+
+// Load the constant pool cache entry at field accesses into registers.
+// The Rcache and Rindex registers must be set before call.
+// Input:
+//   - Rcache, Rindex
+// Output:
+//   - Robj, Roffset, Rflags
+void TemplateTable::load_field_cp_cache_entry(Register Robj,
+                                              Register Rcache,
+                                              Register Rindex /* unused on PPC64 */,
+                                              Register Roffset,
+                                              Register Rflags,
+                                              bool is_static = false) {
+  assert_different_registers(Rcache, Rflags, Roffset);
+  // assert(Rindex == noreg, "parameter not used on PPC64");
+
+  ByteSize cp_base_offset = ConstantPoolCache::base_offset();
+  __ ld(Rflags, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::flags_offset()), Rcache);
+  __ ld(Roffset, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::f2_offset()), Rcache);
+  if (is_static) {
+    __ ld(Robj, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::f1_offset()), Rcache);
+    __ ld(Robj, in_bytes(Klass::java_mirror_offset()), Robj);
+    // Acquire not needed here. Following access has an address dependency on this value.
+  }
+}
+
+// Load the constant pool cache entry at invokes into registers.
+// Resolve if necessary.
+
+// Input Registers:
+//   - None, bcp is used, though
+//
+// Return registers:
+//   - Rmethod       (f1 field or f2 if invokevirtual)
+//   - Ritable_index (f2 field)
+//   - Rflags        (flags field)
+//
+// Kills:
+//   - R21
+//
+void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
+                                               Register Rmethod,
+                                               Register Ritable_index,
+                                               Register Rflags,
+                                               bool is_invokevirtual,
+                                               bool is_invokevfinal,
+                                               bool is_invokedynamic) {
+
+  ByteSize cp_base_offset = ConstantPoolCache::base_offset();
+  // Determine constant pool cache field offsets.
+  assert(is_invokevirtual == (byte_no == f2_byte), "is_invokevirtual flag redundant");
+  const int method_offset = in_bytes(cp_base_offset + (is_invokevirtual ? ConstantPoolCacheEntry::f2_offset() : ConstantPoolCacheEntry::f1_offset()));
+  const int flags_offset  = in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset());
+  // Access constant pool cache fields.
+  const int index_offset  = in_bytes(cp_base_offset + ConstantPoolCacheEntry::f2_offset());
+
+  Register Rcache = R21_tmp1; // Note: same register as R21_sender_SP.
+
+  if (is_invokevfinal) {
+    assert(Ritable_index == noreg, "register not used");
+    // Already resolved.
+    __ get_cache_and_index_at_bcp(Rcache, 1);
+  } else {
+    resolve_cache_and_index(byte_no, Rcache, R0, is_invokedynamic ? sizeof(u4) : sizeof(u2));
+  }
+
+  __ ld(Rmethod, method_offset, Rcache);
+  __ ld(Rflags, flags_offset, Rcache);
+
+  if (Ritable_index != noreg) {
+    __ ld(Ritable_index, index_offset, Rcache);
+  }
+}
+
+// ============================================================================
+// Field access
+
+// Volatile variables demand their effects be made known to all CPU's
+// in order. Store buffers on most chips allow reads & writes to
+// reorder; the JMM's ReadAfterWrite.java test fails in -Xint mode
+// without some kind of memory barrier (i.e., it's not sufficient that
+// the interpreter does not reorder volatile references, the hardware
+// also must not reorder them).
+//
+// According to the new Java Memory Model (JMM):
+// (1) All volatiles are serialized wrt to each other. ALSO reads &
+//     writes act as aquire & release, so:
+// (2) A read cannot let unrelated NON-volatile memory refs that
+//     happen after the read float up to before the read. It's OK for
+//     non-volatile memory refs that happen before the volatile read to
+//     float down below it.
+// (3) Similar a volatile write cannot let unrelated NON-volatile
+//     memory refs that happen BEFORE the write float down to after the
+//     write. It's OK for non-volatile memory refs that happen after the
+//     volatile write to float up before it.
+//
+// We only put in barriers around volatile refs (they are expensive),
+// not _between_ memory refs (that would require us to track the
+// flavor of the previous memory refs). Requirements (2) and (3)
+// require some barriers before volatile stores and after volatile
+// loads. These nearly cover requirement (1) but miss the
+// volatile-store-volatile-load case.  This final case is placed after
+// volatile-stores although it could just as well go before
+// volatile-loads.
+
+// The registers cache and index expected to be set before call.
+// Correct values of the cache and index registers are preserved.
+// Kills:
+//   Rcache (if has_tos)
+//   Rscratch
+void TemplateTable::jvmti_post_field_access(Register Rcache, Register Rscratch, bool is_static, bool has_tos) {
+
+  assert_different_registers(Rcache, Rscratch);
+
+  if (JvmtiExport::can_post_field_access()) {
+    ByteSize cp_base_offset = ConstantPoolCache::base_offset();
+    Label Lno_field_access_post;
+
+    // Check if post field access in enabled.
+    int offs = __ load_const_optimized(Rscratch, JvmtiExport::get_field_access_count_addr(), R0, true);
+    __ lwz(Rscratch, offs, Rscratch);
+
+    __ cmpwi(CCR0, Rscratch, 0);
+    __ beq(CCR0, Lno_field_access_post);
+
+    // Post access enabled - do it!
+    __ addi(Rcache, Rcache, in_bytes(cp_base_offset));
+    if (is_static) {
+      __ li(R17_tos, 0);
+    } else {
+      if (has_tos) {
+        // The fast bytecode versions have obj ptr in register.
+        // Thus, save object pointer before call_VM() clobbers it
+        // put object on tos where GC wants it.
+        __ push_ptr(R17_tos);
+      } else {
+        // Load top of stack (do not pop the value off the stack).
+        __ ld(R17_tos, Interpreter::expr_offset_in_bytes(0), R15_esp);
+      }
+      __ verify_oop(R17_tos);
+    }
+    // tos:   object pointer or NULL if static
+    // cache: cache entry pointer
+    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access), R17_tos, Rcache);
+    if (!is_static && has_tos) {
+      // Restore object pointer.
+      __ pop_ptr(R17_tos);
+      __ verify_oop(R17_tos);
+    } else {
+      // Cache is still needed to get class or obj.
+      __ get_cache_and_index_at_bcp(Rcache, 1);
+    }
+
+    __ align(32, 12);
+    __ bind(Lno_field_access_post);
+  }
+}
+
+// kills R11_scratch1
+void TemplateTable::pop_and_check_object(Register Roop) {
+  Register Rtmp = R11_scratch1;
+
+  assert_different_registers(Rtmp, Roop);
+  __ pop_ptr(Roop);
+  // For field access must check obj.
+  __ null_check_throw(Roop, -1, Rtmp);
+  __ verify_oop(Roop);
+}
+
+// PPC64: implement volatile loads as fence-store-acquire.
+void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
+  transition(vtos, vtos);
+
+  Label Lacquire, Lisync;
+
+  const Register Rcache        = R3_ARG1,
+                 Rclass_or_obj = R22_tmp2,
+                 Roffset       = R23_tmp3,
+                 Rflags        = R31,
+                 Rbtable       = R5_ARG3,
+                 Rbc           = R6_ARG4,
+                 Rscratch      = R12_scratch2;
+
+  static address field_branch_table[number_of_states],
+                 static_branch_table[number_of_states];
+
+  address* branch_table = is_static ? static_branch_table : field_branch_table;
+
+  // Get field offset.
+  resolve_cache_and_index(byte_no, Rcache, Rscratch, sizeof(u2));
+
+  // JVMTI support
+  jvmti_post_field_access(Rcache, Rscratch, is_static, false);
+
+  // Load after possible GC.
+  load_field_cp_cache_entry(Rclass_or_obj, Rcache, noreg, Roffset, Rflags, is_static);
+
+  // Load pointer to branch table.
+  __ load_const_optimized(Rbtable, (address)branch_table, Rscratch);
+
+  // Get volatile flag.
+  __ rldicl(Rscratch, Rflags, 64-ConstantPoolCacheEntry::is_volatile_shift, 63); // Extract volatile bit.
+  // Note: sync is needed before volatile load on PPC64.
+
+  // Check field type.
+  __ rldicl(Rflags, Rflags, 64-ConstantPoolCacheEntry::tos_state_shift, 64-ConstantPoolCacheEntry::tos_state_bits);
+
+#ifdef ASSERT
+  Label LFlagInvalid;
+  __ cmpldi(CCR0, Rflags, number_of_states);
+  __ bge(CCR0, LFlagInvalid);
+#endif
+
+  // Load from branch table and dispatch (volatile case: one instruction ahead).
+  __ sldi(Rflags, Rflags, LogBytesPerWord);
+  __ cmpwi(CCR6, Rscratch, 1); // Volatile?
+  if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // Volatile ? size of 1 instruction : 0.
+  }
+  __ ldx(Rbtable, Rbtable, Rflags);
+
+  // Get the obj from stack.
+  if (!is_static) {
+    pop_and_check_object(Rclass_or_obj); // Kills R11_scratch1.
+  } else {
+    __ verify_oop(Rclass_or_obj);
+  }
+
+  if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ subf(Rbtable, Rscratch, Rbtable); // Point to volatile/non-volatile entry point.
+  }
+  __ mtctr(Rbtable);
+  __ bctr();
+
+#ifdef ASSERT
+  __ bind(LFlagInvalid);
+  __ stop("got invalid flag", 0x654);
+
+  // __ bind(Lvtos);
+  address pc_before_fence = __ pc();
+  __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(__ pc() - pc_before_fence == (ptrdiff_t)BytesPerInstWord, "must be single instruction");
+  assert(branch_table[vtos] == 0, "can't compute twice");
+  branch_table[vtos] = __ pc(); // non-volatile_entry point
+  __ stop("vtos unexpected", 0x655);
+#endif
+
+  __ align(32, 28, 28); // Align load.
+  // __ bind(Ldtos);
+  __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[dtos] == 0, "can't compute twice");
+  branch_table[dtos] = __ pc(); // non-volatile_entry point
+  __ lfdx(F15_ftos, Rclass_or_obj, Roffset);
+  __ push(dtos);
+  if (!is_static) patch_bytecode(Bytecodes::_fast_dgetfield, Rbc, Rscratch);
+  {
+    Label acquire_double;
+    __ beq(CCR6, acquire_double); // Volatile?
+    __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+    __ bind(acquire_double);
+    __ fcmpu(CCR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync.
+    __ beq_predict_taken(CCR0, Lisync);
+    __ b(Lisync); // In case of NAN.
+  }
+
+  __ align(32, 28, 28); // Align load.
+  // __ bind(Lftos);
+  __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[ftos] == 0, "can't compute twice");
+  branch_table[ftos] = __ pc(); // non-volatile_entry point
+  __ lfsx(F15_ftos, Rclass_or_obj, Roffset);
+  __ push(ftos);
+  if (!is_static) { patch_bytecode(Bytecodes::_fast_fgetfield, Rbc, Rscratch); }
+  {
+    Label acquire_float;
+    __ beq(CCR6, acquire_float); // Volatile?
+    __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+    __ bind(acquire_float);
+    __ fcmpu(CCR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync.
+    __ beq_predict_taken(CCR0, Lisync);
+    __ b(Lisync); // In case of NAN.
+  }
+
+  __ align(32, 28, 28); // Align load.
+  // __ bind(Litos);
+  __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[itos] == 0, "can't compute twice");
+  branch_table[itos] = __ pc(); // non-volatile_entry point
+  __ lwax(R17_tos, Rclass_or_obj, Roffset);
+  __ push(itos);
+  if (!is_static) patch_bytecode(Bytecodes::_fast_igetfield, Rbc, Rscratch);
+  __ beq(CCR6, Lacquire); // Volatile?
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align load.
+  // __ bind(Lltos);
+  __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[ltos] == 0, "can't compute twice");
+  branch_table[ltos] = __ pc(); // non-volatile_entry point
+  __ ldx(R17_tos, Rclass_or_obj, Roffset);
+  __ push(ltos);
+  if (!is_static) patch_bytecode(Bytecodes::_fast_lgetfield, Rbc, Rscratch);
+  __ beq(CCR6, Lacquire); // Volatile?
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align load.
+  // __ bind(Lbtos);
+  __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[btos] == 0, "can't compute twice");
+  branch_table[btos] = __ pc(); // non-volatile_entry point
+  __ lbzx(R17_tos, Rclass_or_obj, Roffset);
+  __ extsb(R17_tos, R17_tos);
+  __ push(btos);
+  if (!is_static) patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch);
+  __ beq(CCR6, Lacquire); // Volatile?
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align load.
+  // __ bind(Lctos);
+  __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[ctos] == 0, "can't compute twice");
+  branch_table[ctos] = __ pc(); // non-volatile_entry point
+  __ lhzx(R17_tos, Rclass_or_obj, Roffset);
+  __ push(ctos);
+  if (!is_static) patch_bytecode(Bytecodes::_fast_cgetfield, Rbc, Rscratch);
+  __ beq(CCR6, Lacquire); // Volatile?
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align load.
+  // __ bind(Lstos);
+  __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[stos] == 0, "can't compute twice");
+  branch_table[stos] = __ pc(); // non-volatile_entry point
+  __ lhax(R17_tos, Rclass_or_obj, Roffset);
+  __ push(stos);
+  if (!is_static) patch_bytecode(Bytecodes::_fast_sgetfield, Rbc, Rscratch);
+  __ beq(CCR6, Lacquire); // Volatile?
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align load.
+  // __ bind(Latos);
+  __ fence(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[atos] == 0, "can't compute twice");
+  branch_table[atos] = __ pc(); // non-volatile_entry point
+  __ load_heap_oop(R17_tos, (RegisterOrConstant)Roffset, Rclass_or_obj);
+  __ verify_oop(R17_tos);
+  __ push(atos);
+  //__ dcbt(R17_tos); // prefetch
+  if (!is_static) patch_bytecode(Bytecodes::_fast_agetfield, Rbc, Rscratch);
+  __ beq(CCR6, Lacquire); // Volatile?
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 12);
+  __ bind(Lacquire);
+  __ twi_0(R17_tos);
+  __ bind(Lisync);
+  __ isync(); // acquire
+
+#ifdef ASSERT
+  for (int i = 0; i<number_of_states; ++i) {
+    assert(branch_table[i], "get initialization");
+    //tty->print_cr("get: %s_branch_table[%d] = 0x%llx (opcode 0x%llx)",
+    //              is_static ? "static" : "field", i, branch_table[i], *((unsigned int*)branch_table[i]));
+  }
+#endif
+}
+
+void TemplateTable::getfield(int byte_no) {
+  getfield_or_static(byte_no, false);
+}
+
+void TemplateTable::getstatic(int byte_no) {
+  getfield_or_static(byte_no, true);
+}
+
+// The registers cache and index expected to be set before call.
+// The function may destroy various registers, just not the cache and index registers.
+void TemplateTable::jvmti_post_field_mod(Register Rcache, Register Rscratch, bool is_static) {
+
+  assert_different_registers(Rcache, Rscratch, R6_ARG4);
+
+  if (JvmtiExport::can_post_field_modification()) {
+    Label Lno_field_mod_post;
+
+    // Check if post field access in enabled.
+    int offs = __ load_const_optimized(Rscratch, JvmtiExport::get_field_modification_count_addr(), R0, true);
+    __ lwz(Rscratch, offs, Rscratch);
+
+    __ cmpwi(CCR0, Rscratch, 0);
+    __ beq(CCR0, Lno_field_mod_post);
+
+    // Do the post
+    ByteSize cp_base_offset = ConstantPoolCache::base_offset();
+    const Register Robj = Rscratch;
+
+    __ addi(Rcache, Rcache, in_bytes(cp_base_offset));
+    if (is_static) {
+      // Life is simple. Null out the object pointer.
+      __ li(Robj, 0);
+    } else {
+      // In case of the fast versions, value lives in registers => put it back on tos.
+      int offs = Interpreter::expr_offset_in_bytes(0);
+      Register base = R15_esp;
+      switch(bytecode()) {
+        case Bytecodes::_fast_aputfield: __ push_ptr(); offs+= Interpreter::stackElementSize; break;
+        case Bytecodes::_fast_iputfield: // Fall through
+        case Bytecodes::_fast_bputfield: // Fall through
+        case Bytecodes::_fast_cputfield: // Fall through
+        case Bytecodes::_fast_sputfield: __ push_i(); offs+=  Interpreter::stackElementSize; break;
+        case Bytecodes::_fast_lputfield: __ push_l(); offs+=2*Interpreter::stackElementSize; break;
+        case Bytecodes::_fast_fputfield: __ push_f(); offs+=  Interpreter::stackElementSize; break;
+        case Bytecodes::_fast_dputfield: __ push_d(); offs+=2*Interpreter::stackElementSize; break;
+        default: {
+          offs = 0;
+          base = Robj;
+          const Register Rflags = Robj;
+          Label is_one_slot;
+          // Life is harder. The stack holds the value on top, followed by the
+          // object. We don't know the size of the value, though; it could be
+          // one or two words depending on its type. As a result, we must find
+          // the type to determine where the object is.
+          __ ld(Rflags, in_bytes(ConstantPoolCacheEntry::flags_offset()), Rcache); // Big Endian
+          __ rldicl(Rflags, Rflags, 64-ConstantPoolCacheEntry::tos_state_shift, 64-ConstantPoolCacheEntry::tos_state_bits);
+
+          __ cmpwi(CCR0, Rflags, ltos);
+          __ cmpwi(CCR1, Rflags, dtos);
+          __ addi(base, R15_esp, Interpreter::expr_offset_in_bytes(1));
+          __ crnor(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2);
+          __ beq(CCR0, is_one_slot);
+          __ addi(base, R15_esp, Interpreter::expr_offset_in_bytes(2));
+          __ bind(is_one_slot);
+          break;
+        }
+      }
+      __ ld(Robj, offs, base);
+      __ verify_oop(Robj);
+    }
+
+    __ addi(R6_ARG4, R15_esp, Interpreter::expr_offset_in_bytes(0));
+    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), Robj, Rcache, R6_ARG4);
+    __ get_cache_and_index_at_bcp(Rcache, 1);
+
+    // In case of the fast versions, value lives in registers => put it back on tos.
+    switch(bytecode()) {
+      case Bytecodes::_fast_aputfield: __ pop_ptr(); break;
+      case Bytecodes::_fast_iputfield: // Fall through
+      case Bytecodes::_fast_bputfield: // Fall through
+      case Bytecodes::_fast_cputfield: // Fall through
+      case Bytecodes::_fast_sputfield: __ pop_i(); break;
+      case Bytecodes::_fast_lputfield: __ pop_l(); break;
+      case Bytecodes::_fast_fputfield: __ pop_f(); break;
+      case Bytecodes::_fast_dputfield: __ pop_d(); break;
+      default: break; // Nothin' to do.
+    }
+
+    __ align(32, 12);
+    __ bind(Lno_field_mod_post);
+  }
+}
+
+// PPC64: implement volatile stores as release-store (return bytecode contains an additional release).
+void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
+  Label Lvolatile;
+
+  const Register Rcache        = R5_ARG3,  // Do not use ARG1/2 (causes trouble in jvmti_post_field_mod).
+                 Rclass_or_obj = R31,      // Needs to survive C call.
+                 Roffset       = R22_tmp2, // Needs to survive C call.
+                 Rflags        = R3_ARG1,
+                 Rbtable       = R4_ARG2,
+                 Rscratch      = R11_scratch1,
+                 Rscratch2     = R12_scratch2,
+                 Rscratch3     = R6_ARG4,
+                 Rbc           = Rscratch3;
+  const ConditionRegister CR_is_vol = CCR2; // Non-volatile condition register (survives runtime call in do_oop_store).
+
+  static address field_branch_table[number_of_states],
+                 static_branch_table[number_of_states];
+
+  address* branch_table = is_static ? static_branch_table : field_branch_table;
+
+  // Stack (grows up):
+  //  value
+  //  obj
+
+  // Load the field offset.
+  resolve_cache_and_index(byte_no, Rcache, Rscratch, sizeof(u2));
+  jvmti_post_field_mod(Rcache, Rscratch, is_static);
+  load_field_cp_cache_entry(Rclass_or_obj, Rcache, noreg, Roffset, Rflags, is_static);
+
+  // Load pointer to branch table.
+  __ load_const_optimized(Rbtable, (address)branch_table, Rscratch);
+
+  // Get volatile flag.
+  __ rldicl(Rscratch, Rflags, 64-ConstantPoolCacheEntry::is_volatile_shift, 63); // Extract volatile bit.
+
+  // Check the field type.
+  __ rldicl(Rflags, Rflags, 64-ConstantPoolCacheEntry::tos_state_shift, 64-ConstantPoolCacheEntry::tos_state_bits);
+
+#ifdef ASSERT
+  Label LFlagInvalid;
+  __ cmpldi(CCR0, Rflags, number_of_states);
+  __ bge(CCR0, LFlagInvalid);
+#endif
+
+  // Load from branch table and dispatch (volatile case: one instruction ahead).
+  __ sldi(Rflags, Rflags, LogBytesPerWord);
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ cmpwi(CR_is_vol, Rscratch, 1); } // Volatile?
+  __ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // Volatile? size of instruction 1 : 0.
+  __ ldx(Rbtable, Rbtable, Rflags);
+
+  __ subf(Rbtable, Rscratch, Rbtable); // Point to volatile/non-volatile entry point.
+  __ mtctr(Rbtable);
+  __ bctr();
+
+#ifdef ASSERT
+  __ bind(LFlagInvalid);
+  __ stop("got invalid flag", 0x656);
+
+  // __ bind(Lvtos);
+  address pc_before_release = __ pc();
+  __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(__ pc() - pc_before_release == (ptrdiff_t)BytesPerInstWord, "must be single instruction");
+  assert(branch_table[vtos] == 0, "can't compute twice");
+  branch_table[vtos] = __ pc(); // non-volatile_entry point
+  __ stop("vtos unexpected", 0x657);
+#endif
+
+  __ align(32, 28, 28); // Align pop.
+  // __ bind(Ldtos);
+  __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[dtos] == 0, "can't compute twice");
+  branch_table[dtos] = __ pc(); // non-volatile_entry point
+  __ pop(dtos);
+  if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
+  __ stfdx(F15_ftos, Rclass_or_obj, Roffset);
+  if (!is_static) { patch_bytecode(Bytecodes::_fast_dputfield, Rbc, Rscratch, true, byte_no); }
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ beq(CR_is_vol, Lvolatile); // Volatile?
+  }
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align pop.
+  // __ bind(Lftos);
+  __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[ftos] == 0, "can't compute twice");
+  branch_table[ftos] = __ pc(); // non-volatile_entry point
+  __ pop(ftos);
+  if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
+  __ stfsx(F15_ftos, Rclass_or_obj, Roffset);
+  if (!is_static) { patch_bytecode(Bytecodes::_fast_fputfield, Rbc, Rscratch, true, byte_no); }
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ beq(CR_is_vol, Lvolatile); // Volatile?
+  }
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align pop.
+  // __ bind(Litos);
+  __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[itos] == 0, "can't compute twice");
+  branch_table[itos] = __ pc(); // non-volatile_entry point
+  __ pop(itos);
+  if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
+  __ stwx(R17_tos, Rclass_or_obj, Roffset);
+  if (!is_static) { patch_bytecode(Bytecodes::_fast_iputfield, Rbc, Rscratch, true, byte_no); }
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ beq(CR_is_vol, Lvolatile); // Volatile?
+  }
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align pop.
+  // __ bind(Lltos);
+  __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[ltos] == 0, "can't compute twice");
+  branch_table[ltos] = __ pc(); // non-volatile_entry point
+  __ pop(ltos);
+  if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
+  __ stdx(R17_tos, Rclass_or_obj, Roffset);
+  if (!is_static) { patch_bytecode(Bytecodes::_fast_lputfield, Rbc, Rscratch, true, byte_no); }
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ beq(CR_is_vol, Lvolatile); // Volatile?
+  }
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align pop.
+  // __ bind(Lbtos);
+  __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[btos] == 0, "can't compute twice");
+  branch_table[btos] = __ pc(); // non-volatile_entry point
+  __ pop(btos);
+  if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
+  __ stbx(R17_tos, Rclass_or_obj, Roffset);
+  if (!is_static) { patch_bytecode(Bytecodes::_fast_bputfield, Rbc, Rscratch, true, byte_no); }
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ beq(CR_is_vol, Lvolatile); // Volatile?
+  }
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align pop.
+  // __ bind(Lctos);
+  __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[ctos] == 0, "can't compute twice");
+  branch_table[ctos] = __ pc(); // non-volatile_entry point
+  __ pop(ctos);
+  if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1..
+  __ sthx(R17_tos, Rclass_or_obj, Roffset);
+  if (!is_static) { patch_bytecode(Bytecodes::_fast_cputfield, Rbc, Rscratch, true, byte_no); }
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ beq(CR_is_vol, Lvolatile); // Volatile?
+  }
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align pop.
+  // __ bind(Lstos);
+  __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[stos] == 0, "can't compute twice");
+  branch_table[stos] = __ pc(); // non-volatile_entry point
+  __ pop(stos);
+  if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
+  __ sthx(R17_tos, Rclass_or_obj, Roffset);
+  if (!is_static) { patch_bytecode(Bytecodes::_fast_sputfield, Rbc, Rscratch, true, byte_no); }
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ beq(CR_is_vol, Lvolatile); // Volatile?
+  }
+  __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+  __ align(32, 28, 28); // Align pop.
+  // __ bind(Latos);
+  __ release(); // Volatile entry point (one instruction before non-volatile_entry point).
+  assert(branch_table[atos] == 0, "can't compute twice");
+  branch_table[atos] = __ pc(); // non-volatile_entry point
+  __ pop(atos);
+  if (!is_static) { pop_and_check_object(Rclass_or_obj); } // kills R11_scratch1
+  do_oop_store(_masm, Rclass_or_obj, Roffset, R17_tos, Rscratch, Rscratch2, Rscratch3, _bs->kind(), false /* precise */, true /* check null */);
+  if (!is_static) { patch_bytecode(Bytecodes::_fast_aputfield, Rbc, Rscratch, true, byte_no); }
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ beq(CR_is_vol, Lvolatile); // Volatile?
+    __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+    __ align(32, 12);
+    __ bind(Lvolatile);
+    __ fence();
+  }
+  // fallthru: __ b(Lexit);
+
+#ifdef ASSERT
+  for (int i = 0; i<number_of_states; ++i) {
+    assert(branch_table[i], "put initialization");
+    //tty->print_cr("put: %s_branch_table[%d] = 0x%llx (opcode 0x%llx)",
+    //              is_static ? "static" : "field", i, branch_table[i], *((unsigned int*)branch_table[i]));
+  }
+#endif
+}
+
+void TemplateTable::putfield(int byte_no) {
+  putfield_or_static(byte_no, false);
+}
+
+void TemplateTable::putstatic(int byte_no) {
+  putfield_or_static(byte_no, true);
+}
+
+// See SPARC. On PPC64, we have a different jvmti_post_field_mod which does the job.
+void TemplateTable::jvmti_post_fast_field_mod() {
+  __ should_not_reach_here();
+}
+
+void TemplateTable::fast_storefield(TosState state) {
+  transition(state, vtos);
+
+  const Register Rcache        = R5_ARG3,  // Do not use ARG1/2 (causes trouble in jvmti_post_field_mod).
+                 Rclass_or_obj = R31,      // Needs to survive C call.
+                 Roffset       = R22_tmp2, // Needs to survive C call.
+                 Rflags        = R3_ARG1,
+                 Rscratch      = R11_scratch1,
+                 Rscratch2     = R12_scratch2,
+                 Rscratch3     = R4_ARG2;
+  const ConditionRegister CR_is_vol = CCR2; // Non-volatile condition register (survives runtime call in do_oop_store).
+
+  // Constant pool already resolved => Load flags and offset of field.
+  __ get_cache_and_index_at_bcp(Rcache, 1);
+  jvmti_post_field_mod(Rcache, Rscratch, false /* not static */);
+  load_field_cp_cache_entry(noreg, Rcache, noreg, Roffset, Rflags, false);
+
+  // Get the obj and the final store addr.
+  pop_and_check_object(Rclass_or_obj); // Kills R11_scratch1.
+
+  // Get volatile flag.
+  __ rldicl_(Rscratch, Rflags, 64-ConstantPoolCacheEntry::is_volatile_shift, 63); // Extract volatile bit.
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ cmpdi(CR_is_vol, Rscratch, 1); }
+  {
+    Label LnotVolatile;
+    __ beq(CCR0, LnotVolatile);
+    __ release();
+    __ align(32, 12);
+    __ bind(LnotVolatile);
+  }
+
+  // Do the store and fencing.
+  switch(bytecode()) {
+    case Bytecodes::_fast_aputfield:
+      // Store into the field.
+      do_oop_store(_masm, Rclass_or_obj, Roffset, R17_tos, Rscratch, Rscratch2, Rscratch3, _bs->kind(), false /* precise */, true /* check null */);
+      break;
+
+    case Bytecodes::_fast_iputfield:
+      __ stwx(R17_tos, Rclass_or_obj, Roffset);
+      break;
+
+    case Bytecodes::_fast_lputfield:
+      __ stdx(R17_tos, Rclass_or_obj, Roffset);
+      break;
+
+    case Bytecodes::_fast_bputfield:
+      __ stbx(R17_tos, Rclass_or_obj, Roffset);
+      break;
+
+    case Bytecodes::_fast_cputfield:
+    case Bytecodes::_fast_sputfield:
+      __ sthx(R17_tos, Rclass_or_obj, Roffset);
+      break;
+
+    case Bytecodes::_fast_fputfield:
+      __ stfsx(F15_ftos, Rclass_or_obj, Roffset);
+      break;
+
+    case Bytecodes::_fast_dputfield:
+      __ stfdx(F15_ftos, Rclass_or_obj, Roffset);
+      break;
+
+    default: ShouldNotReachHere();
+  }
+
+  if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    Label LVolatile;
+    __ beq(CR_is_vol, LVolatile);
+    __ dispatch_epilog(vtos, Bytecodes::length_for(bytecode()));
+
+    __ align(32, 12);
+    __ bind(LVolatile);
+    __ fence();
+  }
+}
+
+void TemplateTable::fast_accessfield(TosState state) {
+  transition(atos, state);
+
+  Label LisVolatile;
+  ByteSize cp_base_offset = ConstantPoolCache::base_offset();
+
+  const Register Rcache        = R3_ARG1,
+                 Rclass_or_obj = R17_tos,
+                 Roffset       = R22_tmp2,
+                 Rflags        = R23_tmp3,
+                 Rscratch      = R12_scratch2;
+
+  // Constant pool already resolved. Get the field offset.
+  __ get_cache_and_index_at_bcp(Rcache, 1);
+  load_field_cp_cache_entry(noreg, Rcache, noreg, Roffset, Rflags, false);
+
+  // JVMTI support
+  jvmti_post_field_access(Rcache, Rscratch, false, true);
+
+  // Get the load address.
+  __ null_check_throw(Rclass_or_obj, -1, Rscratch);
+
+  // Get volatile flag.
+  __ rldicl_(Rscratch, Rflags, 64-ConstantPoolCacheEntry::is_volatile_shift, 63); // Extract volatile bit.
+  __ bne(CCR0, LisVolatile);
+
+  switch(bytecode()) {
+    case Bytecodes::_fast_agetfield:
+    {
+      __ load_heap_oop(R17_tos, (RegisterOrConstant)Roffset, Rclass_or_obj);
+      __ verify_oop(R17_tos);
+      __ dispatch_epilog(state, Bytecodes::length_for(bytecode()));
+
+      __ bind(LisVolatile);
+      if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); }
+      __ load_heap_oop(R17_tos, (RegisterOrConstant)Roffset, Rclass_or_obj);
+      __ verify_oop(R17_tos);
+      __ twi_0(R17_tos);
+      __ isync();
+      break;
+    }
+    case Bytecodes::_fast_igetfield:
+    {
+      __ lwax(R17_tos, Rclass_or_obj, Roffset);
+      __ dispatch_epilog(state, Bytecodes::length_for(bytecode()));
+
+      __ bind(LisVolatile);
+      if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); }
+      __ lwax(R17_tos, Rclass_or_obj, Roffset);
+      __ twi_0(R17_tos);
+      __ isync();
+      break;
+    }
+    case Bytecodes::_fast_lgetfield:
+    {
+      __ ldx(R17_tos, Rclass_or_obj, Roffset);
+      __ dispatch_epilog(state, Bytecodes::length_for(bytecode()));
+
+      __ bind(LisVolatile);
+      if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); }
+      __ ldx(R17_tos, Rclass_or_obj, Roffset);
+      __ twi_0(R17_tos);
+      __ isync();
+      break;
+    }
+    case Bytecodes::_fast_bgetfield:
+    {
+      __ lbzx(R17_tos, Rclass_or_obj, Roffset);
+      __ extsb(R17_tos, R17_tos);
+      __ dispatch_epilog(state, Bytecodes::length_for(bytecode()));
+
+      __ bind(LisVolatile);
+      if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); }
+      __ lbzx(R17_tos, Rclass_or_obj, Roffset);
+      __ twi_0(R17_tos);
+      __ extsb(R17_tos, R17_tos);
+      __ isync();
+      break;
+    }
+    case Bytecodes::_fast_cgetfield:
+    {
+      __ lhzx(R17_tos, Rclass_or_obj, Roffset);
+      __ dispatch_epilog(state, Bytecodes::length_for(bytecode()));
+
+      __ bind(LisVolatile);
+      if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); }
+      __ lhzx(R17_tos, Rclass_or_obj, Roffset);
+      __ twi_0(R17_tos);
+      __ isync();
+      break;
+    }
+    case Bytecodes::_fast_sgetfield:
+    {
+      __ lhax(R17_tos, Rclass_or_obj, Roffset);
+      __ dispatch_epilog(state, Bytecodes::length_for(bytecode()));
+
+      __ bind(LisVolatile);
+      if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); }
+      __ lhax(R17_tos, Rclass_or_obj, Roffset);
+      __ twi_0(R17_tos);
+      __ isync();
+      break;
+    }
+    case Bytecodes::_fast_fgetfield:
+    {
+      __ lfsx(F15_ftos, Rclass_or_obj, Roffset);
+      __ dispatch_epilog(state, Bytecodes::length_for(bytecode()));
+
+      __ bind(LisVolatile);
+      Label Ldummy;
+      if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); }
+      __ lfsx(F15_ftos, Rclass_or_obj, Roffset);
+      __ fcmpu(CCR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync.
+      __ bne_predict_not_taken(CCR0, Ldummy);
+      __ bind(Ldummy);
+      __ isync();
+      break;
+    }
+    case Bytecodes::_fast_dgetfield:
+    {
+      __ lfdx(F15_ftos, Rclass_or_obj, Roffset);
+      __ dispatch_epilog(state, Bytecodes::length_for(bytecode()));
+
+      __ bind(LisVolatile);
+      Label Ldummy;
+      if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); }
+      __ lfdx(F15_ftos, Rclass_or_obj, Roffset);
+      __ fcmpu(CCR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync.
+      __ bne_predict_not_taken(CCR0, Ldummy);
+      __ bind(Ldummy);
+      __ isync();
+      break;
+    }
+    default: ShouldNotReachHere();
+  }
+}
+
+void TemplateTable::fast_xaccess(TosState state) {
+  transition(vtos, state);
+
+  Label LisVolatile;
+  ByteSize cp_base_offset = ConstantPoolCache::base_offset();
+  const Register Rcache        = R3_ARG1,
+                 Rclass_or_obj = R17_tos,
+                 Roffset       = R22_tmp2,
+                 Rflags        = R23_tmp3,
+                 Rscratch      = R12_scratch2;
+
+  __ ld(Rclass_or_obj, 0, R18_locals);
+
+  // Constant pool already resolved. Get the field offset.
+  __ get_cache_and_index_at_bcp(Rcache, 2);
+  load_field_cp_cache_entry(noreg, Rcache, noreg, Roffset, Rflags, false);
+
+  // JVMTI support not needed, since we switch back to single bytecode as soon as debugger attaches.
+
+  // Needed to report exception at the correct bcp.
+  __ addi(R14_bcp, R14_bcp, 1);
+
+  // Get the load address.
+  __ null_check_throw(Rclass_or_obj, -1, Rscratch);
+
+  // Get volatile flag.
+  __ rldicl_(Rscratch, Rflags, 64-ConstantPoolCacheEntry::is_volatile_shift, 63); // Extract volatile bit.
+  __ bne(CCR0, LisVolatile);
+
+  switch(state) {
+  case atos:
+    {
+      __ load_heap_oop(R17_tos, (RegisterOrConstant)Roffset, Rclass_or_obj);
+      __ verify_oop(R17_tos);
+      __ dispatch_epilog(state, Bytecodes::length_for(bytecode()) - 1); // Undo bcp increment.
+
+      __ bind(LisVolatile);
+      if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); }
+      __ load_heap_oop(R17_tos, (RegisterOrConstant)Roffset, Rclass_or_obj);
+      __ verify_oop(R17_tos);
+      __ twi_0(R17_tos);
+      __ isync();
+      break;
+    }
+  case itos:
+    {
+      __ lwax(R17_tos, Rclass_or_obj, Roffset);
+      __ dispatch_epilog(state, Bytecodes::length_for(bytecode()) - 1); // Undo bcp increment.
+
+      __ bind(LisVolatile);
+      if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); }
+      __ lwax(R17_tos, Rclass_or_obj, Roffset);
+      __ twi_0(R17_tos);
+      __ isync();
+      break;
+    }
+  case ftos:
+    {
+      __ lfsx(F15_ftos, Rclass_or_obj, Roffset);
+      __ dispatch_epilog(state, Bytecodes::length_for(bytecode()) - 1); // Undo bcp increment.
+
+      __ bind(LisVolatile);
+      Label Ldummy;
+      if (support_IRIW_for_not_multiple_copy_atomic_cpu) { __ fence(); }
+      __ lfsx(F15_ftos, Rclass_or_obj, Roffset);
+      __ fcmpu(CCR0, F15_ftos, F15_ftos); // Acquire by cmp-br-isync.
+      __ bne_predict_not_taken(CCR0, Ldummy);
+      __ bind(Ldummy);
+      __ isync();
+      break;
+    }
+  default: ShouldNotReachHere();
+  }
+  __ addi(R14_bcp, R14_bcp, -1);
+}
+
+// ============================================================================
+// Calls
+
+// Common code for invoke
+//
+// Input:
+//   - byte_no
+//
+// Output:
+//   - Rmethod:        The method to invoke next.
+//   - Rret_addr:      The return address to return to.
+//   - Rindex:         MethodType (invokehandle) or CallSite obj (invokedynamic)
+//   - Rrecv:          Cache for "this" pointer, might be noreg if static call.
+//   - Rflags:         Method flags from const pool cache.
+//
+//  Kills:
+//   - Rscratch1
+//
+void TemplateTable::prepare_invoke(int byte_no,
+                                   Register Rmethod,  // linked method (or i-klass)
+                                   Register Rret_addr,// return address
+                                   Register Rindex,   // itable index, MethodType, etc.
+                                   Register Rrecv,    // If caller wants to see it.
+                                   Register Rflags,   // If caller wants to test it.
+                                   Register Rscratch
+                                   ) {
+  // Determine flags.
+  const Bytecodes::Code code = bytecode();
+  const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;
+  const bool is_invokedynamic    = code == Bytecodes::_invokedynamic;
+  const bool is_invokehandle     = code == Bytecodes::_invokehandle;
+  const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
+  const bool is_invokespecial    = code == Bytecodes::_invokespecial;
+  const bool load_receiver       = (Rrecv != noreg);
+  assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic), "");
+
+  assert_different_registers(Rmethod, Rindex, Rflags, Rscratch);
+  assert_different_registers(Rmethod, Rrecv, Rflags, Rscratch);
+  assert_different_registers(Rret_addr, Rscratch);
+
+  load_invoke_cp_cache_entry(byte_no, Rmethod, Rindex, Rflags, is_invokevirtual, false, is_invokedynamic);
+
+  // Saving of SP done in call_from_interpreter.
+
+  // Maybe push "appendix" to arguments.
+  if (is_invokedynamic || is_invokehandle) {
+    Label Ldone;
+    __ rldicl_(R0, Rflags, 64-ConstantPoolCacheEntry::has_appendix_shift, 63);
+    __ beq(CCR0, Ldone);
+    // Push "appendix" (MethodType, CallSite, etc.).
+    // This must be done before we get the receiver,
+    // since the parameter_size includes it.
+    __ load_resolved_reference_at_index(Rscratch, Rindex);
+    __ verify_oop(Rscratch);
+    __ push_ptr(Rscratch);
+    __ bind(Ldone);
+  }
+
+  // Load receiver if needed (after appendix is pushed so parameter size is correct).
+  if (load_receiver) {
+    const Register Rparam_count = Rscratch;
+    __ andi(Rparam_count, Rflags, ConstantPoolCacheEntry::parameter_size_mask);
+    __ load_receiver(Rparam_count, Rrecv);
+    __ verify_oop(Rrecv);
+  }
+
+  // Get return address.
+  {
+    Register Rtable_addr = Rscratch;
+    Register Rret_type = Rret_addr;
+    address table_addr = (address) Interpreter::invoke_return_entry_table_for(code);
+
+    // Get return type. It's coded into the upper 4 bits of the lower half of the 64 bit value.
+    __ rldicl(Rret_type, Rflags, 64-ConstantPoolCacheEntry::tos_state_shift, 64-ConstantPoolCacheEntry::tos_state_bits);
+    __ load_dispatch_table(Rtable_addr, (address*)table_addr);
+    __ sldi(Rret_type, Rret_type, LogBytesPerWord);
+    // Get return address.
+    __ ldx(Rret_addr, Rtable_addr, Rret_type);
+  }
+}
+
+// Helper for virtual calls. Load target out of vtable and jump off!
+// Kills all passed registers.
+void TemplateTable::generate_vtable_call(Register Rrecv_klass, Register Rindex, Register Rret, Register Rtemp) {
+
+  assert_different_registers(Rrecv_klass, Rtemp, Rret);
+  const Register Rtarget_method = Rindex;
+
+  // Get target method & entry point.
+  const int base = InstanceKlass::vtable_start_offset() * wordSize;
+  // Calc vtable addr scale the vtable index by 8.
+  __ sldi(Rindex, Rindex, exact_log2(vtableEntry::size() * wordSize));
+  // Load target.
+  __ addi(Rrecv_klass, Rrecv_klass, base + vtableEntry::method_offset_in_bytes());
+  __ ldx(Rtarget_method, Rindex, Rrecv_klass);
+  __ call_from_interpreter(Rtarget_method, Rret, Rrecv_klass /* scratch1 */, Rtemp /* scratch2 */);
+}
+
+// Virtual or final call. Final calls are rewritten on the fly to run through "fast_finalcall" next time.
+void TemplateTable::invokevirtual(int byte_no) {
+  transition(vtos, vtos);
+
+  Register Rtable_addr = R11_scratch1,
+           Rret_type = R12_scratch2,
+           Rret_addr = R5_ARG3,
+           Rflags = R22_tmp2, // Should survive C call.
+           Rrecv = R3_ARG1,
+           Rrecv_klass = Rrecv,
+           Rvtableindex_or_method = R31, // Should survive C call.
+           Rnum_params = R4_ARG2,
+           Rnew_bc = R6_ARG4;
+
+  Label LnotFinal;
+
+  load_invoke_cp_cache_entry(byte_no, Rvtableindex_or_method, noreg, Rflags, /*virtual*/ true, false, false);
+
+  __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_vfinal_shift);
+  __ bfalse(CCR0, LnotFinal);
+
+  patch_bytecode(Bytecodes::_fast_invokevfinal, Rnew_bc, R12_scratch2);
+  invokevfinal_helper(Rvtableindex_or_method, Rflags, R11_scratch1, R12_scratch2);
+
+  __ align(32, 12);
+  __ bind(LnotFinal);
+  // Load "this" pointer (receiver).
+  __ rldicl(Rnum_params, Rflags, 64, 48);
+  __ load_receiver(Rnum_params, Rrecv);
+  __ verify_oop(Rrecv);
+
+  // Get return type. It's coded into the upper 4 bits of the lower half of the 64 bit value.
+  __ rldicl(Rret_type, Rflags, 64-ConstantPoolCacheEntry::tos_state_shift, 64-ConstantPoolCacheEntry::tos_state_bits);
+  __ load_dispatch_table(Rtable_addr, Interpreter::invoke_return_entry_table());
+  __ sldi(Rret_type, Rret_type, LogBytesPerWord);
+  __ ldx(Rret_addr, Rret_type, Rtable_addr);
+  __ null_check_throw(Rrecv, oopDesc::klass_offset_in_bytes(), R11_scratch1);
+  __ load_klass(Rrecv_klass, Rrecv);
+  __ verify_klass_ptr(Rrecv_klass);
+  __ profile_virtual_call(Rrecv_klass, R11_scratch1, R12_scratch2, false);
+
+  generate_vtable_call(Rrecv_klass, Rvtableindex_or_method, Rret_addr, R11_scratch1);
+}
+
+void TemplateTable::fast_invokevfinal(int byte_no) {
+  transition(vtos, vtos);
+
+  assert(byte_no == f2_byte, "use this argument");
+  Register Rflags  = R22_tmp2,
+           Rmethod = R31;
+  load_invoke_cp_cache_entry(byte_no, Rmethod, noreg, Rflags, /*virtual*/ true, /*is_invokevfinal*/ true, false);
+  invokevfinal_helper(Rmethod, Rflags, R11_scratch1, R12_scratch2);
+}
+
+void TemplateTable::invokevfinal_helper(Register Rmethod, Register Rflags, Register Rscratch1, Register Rscratch2) {
+
+  assert_different_registers(Rmethod, Rflags, Rscratch1, Rscratch2);
+
+  // Load receiver from stack slot.
+  Register Rrecv = Rscratch2;
+  Register Rnum_params = Rrecv;
+
+  __ ld(Rnum_params, in_bytes(Method::const_offset()), Rmethod);
+  __ lhz(Rnum_params /* number of params */, in_bytes(ConstMethod::size_of_parameters_offset()), Rnum_params);
+
+  // Get return address.
+  Register Rtable_addr = Rscratch1,
+           Rret_addr   = Rflags,
+           Rret_type   = Rret_addr;
+  // Get return type. It's coded into the upper 4 bits of the lower half of the 64 bit value.
+  __ rldicl(Rret_type, Rflags, 64-ConstantPoolCacheEntry::tos_state_shift, 64-ConstantPoolCacheEntry::tos_state_bits);
+  __ load_dispatch_table(Rtable_addr, Interpreter::invoke_return_entry_table());
+  __ sldi(Rret_type, Rret_type, LogBytesPerWord);
+  __ ldx(Rret_addr, Rret_type, Rtable_addr);
+
+  // Load receiver and receiver NULL check.
+  __ load_receiver(Rnum_params, Rrecv);
+  __ null_check_throw(Rrecv, -1, Rscratch1);
+
+  __ profile_final_call(Rrecv, Rscratch1);
+
+  // Do the call.
+  __ call_from_interpreter(Rmethod, Rret_addr, Rscratch1, Rscratch2);
+}
+
+void TemplateTable::invokespecial(int byte_no) {
+  assert(byte_no == f1_byte, "use this argument");
+  transition(vtos, vtos);
+
+  Register Rtable_addr = R3_ARG1,
+           Rret_addr   = R4_ARG2,
+           Rflags      = R5_ARG3,
+           Rreceiver   = R6_ARG4,
+           Rmethod     = R31;
+
+  prepare_invoke(byte_no, Rmethod, Rret_addr, noreg, Rreceiver, Rflags, R11_scratch1);
+
+  // Receiver NULL check.
+  __ null_check_throw(Rreceiver, -1, R11_scratch1);
+
+  __ profile_call(R11_scratch1, R12_scratch2);
+  __ call_from_interpreter(Rmethod, Rret_addr, R11_scratch1, R12_scratch2);
+}
+
+void TemplateTable::invokestatic(int byte_no) {
+  assert(byte_no == f1_byte, "use this argument");
+  transition(vtos, vtos);
+
+  Register Rtable_addr = R3_ARG1,
+           Rret_addr   = R4_ARG2,
+           Rflags      = R5_ARG3;
+
+  prepare_invoke(byte_no, R19_method, Rret_addr, noreg, noreg, Rflags, R11_scratch1);
+
+  __ profile_call(R11_scratch1, R12_scratch2);
+  __ call_from_interpreter(R19_method, Rret_addr, R11_scratch1, R12_scratch2);
+}
+
+void TemplateTable::invokeinterface_object_method(Register Rrecv_klass,
+                                                  Register Rret,
+                                                  Register Rflags,
+                                                  Register Rindex,
+                                                  Register Rtemp1,
+                                                  Register Rtemp2) {
+
+  assert_different_registers(Rindex, Rret, Rrecv_klass, Rflags, Rtemp1, Rtemp2);
+  Label LnotFinal;
+
+  // Check for vfinal.
+  __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_vfinal_shift);
+  __ bfalse(CCR0, LnotFinal);
+
+  Register Rscratch = Rflags; // Rflags is dead now.
+
+  // Final call case.
+  __ profile_final_call(Rtemp1, Rscratch);
+  // Do the final call - the index (f2) contains the method.
+  __ call_from_interpreter(Rindex, Rret, Rscratch, Rrecv_klass /* scratch */);
+
+  // Non-final callc case.
+  __ bind(LnotFinal);
+  __ profile_virtual_call(Rrecv_klass, Rtemp1, Rscratch, false);
+  generate_vtable_call(Rrecv_klass, Rindex, Rret, Rscratch);
+}
+
+void TemplateTable::invokeinterface(int byte_no) {
+  assert(byte_no == f1_byte, "use this argument");
+  transition(vtos, vtos);
+
+  const Register Rscratch1        = R11_scratch1,
+                 Rscratch2        = R12_scratch2,
+                 Rscratch3        = R9_ARG7,
+                 Rscratch4        = R10_ARG8,
+                 Rtable_addr      = Rscratch2,
+                 Rinterface_klass = R5_ARG3,
+                 Rret_type        = R8_ARG6,
+                 Rret_addr        = Rret_type,
+                 Rindex           = R6_ARG4,
+                 Rreceiver        = R4_ARG2,
+                 Rrecv_klass      = Rreceiver,
+                 Rflags           = R7_ARG5;
+
+  prepare_invoke(byte_no, Rinterface_klass, Rret_addr, Rindex, Rreceiver, Rflags, Rscratch1);
+
+  // Get receiver klass.
+  __ null_check_throw(Rreceiver, oopDesc::klass_offset_in_bytes(), Rscratch3);
+  __ load_klass(Rrecv_klass, Rreceiver);
+
+  // Check corner case object method.
+  Label LobjectMethod;
+
+  __ testbitdi(CCR0, R0, Rflags, ConstantPoolCacheEntry::is_forced_virtual_shift);
+  __ btrue(CCR0, LobjectMethod);
+
+  // Fallthrough: The normal invokeinterface case.
+  __ profile_virtual_call(Rrecv_klass, Rscratch1, Rscratch2, false);
+
+  // Find entry point to call.
+  Label Lthrow_icc, Lthrow_ame;
+  // Result will be returned in Rindex.
+  __ mr(Rscratch4, Rrecv_klass);
+  __ mr(Rscratch3, Rindex);
+  __ lookup_interface_method(Rrecv_klass, Rinterface_klass, Rindex, Rindex, Rscratch1, Rscratch2, Lthrow_icc);
+
+  __ cmpdi(CCR0, Rindex, 0);
+  __ beq(CCR0, Lthrow_ame);
+  // Found entry. Jump off!
+  __ call_from_interpreter(Rindex, Rret_addr, Rscratch1, Rscratch2);
+
+  // Vtable entry was NULL => Throw abstract method error.
+  __ bind(Lthrow_ame);
+  __ mr(Rrecv_klass, Rscratch4);
+  __ mr(Rindex, Rscratch3);
+  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
+
+  // Interface was not found => Throw incompatible class change error.
+  __ bind(Lthrow_icc);
+  __ mr(Rrecv_klass, Rscratch4);
+  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError));
+
+  __ should_not_reach_here();
+
+  // Special case of invokeinterface called for virtual method of
+  // java.lang.Object. See ConstantPoolCacheEntry::set_method() for details:
+  // The invokeinterface was rewritten to a invokevirtual, hence we have
+  // to handle this corner case. This code isn't produced by javac, but could
+  // be produced by another compliant java compiler.
+  __ bind(LobjectMethod);
+  invokeinterface_object_method(Rrecv_klass, Rret_addr, Rflags, Rindex, Rscratch1, Rscratch2);
+}
+
+void TemplateTable::invokedynamic(int byte_no) {
+  transition(vtos, vtos);
+
+  const Register Rret_addr = R3_ARG1,
+                 Rflags    = R4_ARG2,
+                 Rmethod   = R22_tmp2,
+                 Rscratch1 = R11_scratch1,
+                 Rscratch2 = R12_scratch2;
+
+  if (!EnableInvokeDynamic) {
+    // We should not encounter this bytecode if !EnableInvokeDynamic.
+    // The verifier will stop it. However, if we get past the verifier,
+    // this will stop the thread in a reasonable way, without crashing the JVM.
+    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError));
+    // The call_VM checks for exception, so we should never return here.
+    __ should_not_reach_here();
+    return;
+  }
+
+  prepare_invoke(byte_no, Rmethod, Rret_addr, Rscratch1, noreg, Rflags, Rscratch2);
+
+  // Profile this call.
+  __ profile_call(Rscratch1, Rscratch2);
+
+  // Off we go. With the new method handles, we don't jump to a method handle
+  // entry any more. Instead, we pushed an "appendix" in prepare invoke, which happens
+  // to be the callsite object the bootstrap method returned. This is passed to a
+  // "link" method which does the dispatch (Most likely just grabs the MH stored
+  // inside the callsite and does an invokehandle).
+  __ call_from_interpreter(Rmethod, Rret_addr, Rscratch1 /* scratch1 */, Rscratch2 /* scratch2 */);
+}
+
+void TemplateTable::invokehandle(int byte_no) {
+  transition(vtos, vtos);
+
+  const Register Rret_addr = R3_ARG1,
+                 Rflags    = R4_ARG2,
+                 Rrecv     = R5_ARG3,
+                 Rmethod   = R22_tmp2,
+                 Rscratch1 = R11_scratch1,
+                 Rscratch2 = R12_scratch2;
+
+  if (!EnableInvokeDynamic) {
+    // Rewriter does not generate this bytecode.
+    __ should_not_reach_here();
+    return;
+  }
+
+  prepare_invoke(byte_no, Rmethod, Rret_addr, Rscratch1, Rrecv, Rflags, Rscratch2);
+  __ verify_method_ptr(Rmethod);
+  __ null_check_throw(Rrecv, -1, Rscratch2);
+
+  __ profile_final_call(Rrecv, Rscratch1);
+
+  // Still no call from handle => We call the method handle interpreter here.
+  __ call_from_interpreter(Rmethod, Rret_addr, Rscratch1 /* scratch1 */, Rscratch2 /* scratch2 */);
+}
+
+// =============================================================================
+// Allocation
+
+// Puts allocated obj ref onto the expression stack.
+void TemplateTable::_new() {
+  transition(vtos, atos);
+
+  Label Lslow_case,
+        Ldone,
+        Linitialize_header,
+        Lallocate_shared,
+        Linitialize_object;  // Including clearing the fields.
+
+  const Register RallocatedObject = R17_tos,
+                 RinstanceKlass   = R9_ARG7,
+                 Rscratch         = R11_scratch1,
+                 Roffset          = R8_ARG6,
+                 Rinstance_size   = Roffset,
+                 Rcpool           = R4_ARG2,
+                 Rtags            = R3_ARG1,
+                 Rindex           = R5_ARG3;
+
+  const bool allow_shared_alloc = Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode;
+
+  // --------------------------------------------------------------------------
+  // Check if fast case is possible.
+
+  // Load pointers to const pool and const pool's tags array.
+  __ get_cpool_and_tags(Rcpool, Rtags);
+  // Load index of constant pool entry.
+  __ get_2_byte_integer_at_bcp(1, Rindex, InterpreterMacroAssembler::Unsigned);
+
+  if (UseTLAB) {
+    // Make sure the class we're about to instantiate has been resolved
+    // This is done before loading instanceKlass to be consistent with the order
+    // how Constant Pool is updated (see ConstantPoolCache::klass_at_put).
+    __ addi(Rtags, Rtags, Array<u1>::base_offset_in_bytes());
+    __ lbzx(Rtags, Rindex, Rtags);
+
+    __ cmpdi(CCR0, Rtags, JVM_CONSTANT_Class);
+    __ bne(CCR0, Lslow_case);
+
+    // Get instanceKlass (load from Rcpool + sizeof(ConstantPool) + Rindex*BytesPerWord).
+    __ sldi(Roffset, Rindex, LogBytesPerWord);
+    __ addi(Rscratch, Rcpool, sizeof(ConstantPool));
+    __ isync(); // Order load of instance Klass wrt. tags.
+    __ ldx(RinstanceKlass, Roffset, Rscratch);
+
+    // Make sure klass is fully initialized and get instance_size.
+    __ lbz(Rscratch, in_bytes(InstanceKlass::init_state_offset()), RinstanceKlass);
+    __ lwz(Rinstance_size, in_bytes(Klass::layout_helper_offset()), RinstanceKlass);
+
+    __ cmpdi(CCR1, Rscratch, InstanceKlass::fully_initialized);
+    // Make sure klass does not have has_finalizer, or is abstract, or interface or java/lang/Class.
+    __ andi_(R0, Rinstance_size, Klass::_lh_instance_slow_path_bit); // slow path bit equals 0?
+
+    __ crnand(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); // slow path bit set or not fully initialized?
+    __ beq(CCR0, Lslow_case);
+
+    // --------------------------------------------------------------------------
+    // Fast case:
+    // Allocate the instance.
+    // 1) Try to allocate in the TLAB.
+    // 2) If fail, and the TLAB is not full enough to discard, allocate in the shared Eden.
+    // 3) If the above fails (or is not applicable), go to a slow case (creates a new TLAB, etc.).
+
+    Register RoldTopValue = RallocatedObject; // Object will be allocated here if it fits.
+    Register RnewTopValue = R6_ARG4;
+    Register RendValue    = R7_ARG5;
+
+    // Check if we can allocate in the TLAB.
+    __ ld(RoldTopValue, in_bytes(JavaThread::tlab_top_offset()), R16_thread);
+    __ ld(RendValue,    in_bytes(JavaThread::tlab_end_offset()), R16_thread);
+
+    __ add(RnewTopValue, Rinstance_size, RoldTopValue);
+
+    // If there is enough space, we do not CAS and do not clear.
+    __ cmpld(CCR0, RnewTopValue, RendValue);
+    __ bgt(CCR0, allow_shared_alloc ? Lallocate_shared : Lslow_case);
+
+    __ std(RnewTopValue, in_bytes(JavaThread::tlab_top_offset()), R16_thread);
+
+    if (ZeroTLAB) {
+      // The fields have already been cleared.
+      __ b(Linitialize_header);
+    } else {
+      // Initialize both the header and fields.
+      __ b(Linitialize_object);
+    }
+
+    // Fall through: TLAB was too small.
+    if (allow_shared_alloc) {
+      Register RtlabWasteLimitValue = R10_ARG8;
+      Register RfreeValue = RnewTopValue;
+
+      __ bind(Lallocate_shared);
+      // Check if tlab should be discarded (refill_waste_limit >= free).
+      __ ld(RtlabWasteLimitValue, in_bytes(JavaThread::tlab_refill_waste_limit_offset()), R16_thread);
+      __ subf(RfreeValue, RoldTopValue, RendValue);
+      __ srdi(RfreeValue, RfreeValue, LogHeapWordSize); // in dwords
+      __ cmpld(CCR0, RtlabWasteLimitValue, RfreeValue);
+      __ bge(CCR0, Lslow_case);
+
+      // Increment waste limit to prevent getting stuck on this slow path.
+      __ addi(RtlabWasteLimitValue, RtlabWasteLimitValue, (int)ThreadLocalAllocBuffer::refill_waste_limit_increment());
+      __ std(RtlabWasteLimitValue, in_bytes(JavaThread::tlab_refill_waste_limit_offset()), R16_thread);
+    }
+    // else: No allocation in the shared eden. // fallthru: __ b(Lslow_case);
+  }
+  // else: Always go the slow path.
+
+  // --------------------------------------------------------------------------
+  // slow case
+  __ bind(Lslow_case);
+  call_VM(R17_tos, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), Rcpool, Rindex);
+
+  if (UseTLAB) {
+    __ b(Ldone);
+    // --------------------------------------------------------------------------
+    // Init1: Zero out newly allocated memory.
+
+    if (!ZeroTLAB || allow_shared_alloc) {
+      // Clear object fields.
+      __ bind(Linitialize_object);
+
+      // Initialize remaining object fields.
+      Register Rbase = Rtags;
+      __ addi(Rinstance_size, Rinstance_size, 7 - (int)sizeof(oopDesc));
+      __ addi(Rbase, RallocatedObject, sizeof(oopDesc));
+      __ srdi(Rinstance_size, Rinstance_size, 3);
+
+      // Clear out object skipping header. Takes also care of the zero length case.
+      __ clear_memory_doubleword(Rbase, Rinstance_size);
+      // fallthru: __ b(Linitialize_header);
+    }
+
+    // --------------------------------------------------------------------------
+    // Init2: Initialize the header: mark, klass
+    __ bind(Linitialize_header);
+
+    // Init mark.
+    if (UseBiasedLocking) {
+      __ ld(Rscratch, in_bytes(Klass::prototype_header_offset()), RinstanceKlass);
+    } else {
+      __ load_const_optimized(Rscratch, markOopDesc::prototype(), R0);
+    }
+    __ std(Rscratch, oopDesc::mark_offset_in_bytes(), RallocatedObject);
+
+    // Init klass.
+    __ store_klass_gap(RallocatedObject);
+    __ store_klass(RallocatedObject, RinstanceKlass, Rscratch); // klass (last for cms)
+
+    // Check and trigger dtrace event.
+    {
+      SkipIfEqualZero skip_if(_masm, Rscratch, &DTraceAllocProbes);
+      __ push(atos);
+      __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc));
+      __ pop(atos);
+    }
+  }
+
+  // continue
+  __ bind(Ldone);
+
+  // Must prevent reordering of stores for object initialization with stores that publish the new object.
+  __ membar(Assembler::StoreStore);
+}
+
+void TemplateTable::newarray() {
+  transition(itos, atos);
+
+  __ lbz(R4, 1, R14_bcp);
+  __ extsw(R5, R17_tos);
+  call_VM(R17_tos, CAST_FROM_FN_PTR(address, InterpreterRuntime::newarray), R4, R5 /* size */);
+
+  // Must prevent reordering of stores for object initialization with stores that publish the new object.
+  __ membar(Assembler::StoreStore);
+}
+
+void TemplateTable::anewarray() {
+  transition(itos, atos);
+
+  __ get_constant_pool(R4);
+  __ get_2_byte_integer_at_bcp(1, R5, InterpreterMacroAssembler::Unsigned);
+  __ extsw(R6, R17_tos); // size
+  call_VM(R17_tos, CAST_FROM_FN_PTR(address, InterpreterRuntime::anewarray), R4 /* pool */, R5 /* index */, R6 /* size */);
+
+  // Must prevent reordering of stores for object initialization with stores that publish the new object.
+  __ membar(Assembler::StoreStore);
+}
+
+// Allocate a multi dimensional array
+void TemplateTable::multianewarray() {
+  transition(vtos, atos);
+
+  Register Rptr = R31; // Needs to survive C call.
+
+  // Put ndims * wordSize into frame temp slot
+  __ lbz(Rptr, 3, R14_bcp);
+  __ sldi(Rptr, Rptr, Interpreter::logStackElementSize);
+  // Esp points past last_dim, so set to R4 to first_dim address.
+  __ add(R4, Rptr, R15_esp);
+  call_VM(R17_tos, CAST_FROM_FN_PTR(address, InterpreterRuntime::multianewarray), R4 /* first_size_address */);
+  // Pop all dimensions off the stack.
+  __ add(R15_esp, Rptr, R15_esp);
+
+  // Must prevent reordering of stores for object initialization with stores that publish the new object.
+  __ membar(Assembler::StoreStore);
+}
+
+void TemplateTable::arraylength() {
+  transition(atos, itos);
+
+  Label LnoException;
+  __ verify_oop(R17_tos);
+  __ null_check_throw(R17_tos, arrayOopDesc::length_offset_in_bytes(), R11_scratch1);
+  __ lwa(R17_tos, arrayOopDesc::length_offset_in_bytes(), R17_tos);
+}
+
+// ============================================================================
+// Typechecks
+
+void TemplateTable::checkcast() {
+  transition(atos, atos);
+
+  Label Ldone, Lis_null, Lquicked, Lresolved;
+  Register Roffset         = R5_ARG3,
+           RobjKlass       = R4_ARG2,
+           RspecifiedKlass = R6_ARG4, // Generate_ClassCastException_verbose_handler will expect this register.
+           Rcpool          = R11_scratch1,
+           Rtags           = R12_scratch2;
+
+  // Null does not pass.
+  __ cmpdi(CCR0, R17_tos, 0);
+  __ beq(CCR0, Lis_null);
+
+  // Get constant pool tag to find out if the bytecode has already been "quickened".
+  __ get_cpool_and_tags(Rcpool, Rtags);
+
+  __ get_2_byte_integer_at_bcp(1, Roffset, InterpreterMacroAssembler::Unsigned);
+
+  __ addi(Rtags, Rtags, Array<u1>::base_offset_in_bytes());
+  __ lbzx(Rtags, Rtags, Roffset);
+
+  __ cmpdi(CCR0, Rtags, JVM_CONSTANT_Class);
+  __ beq(CCR0, Lquicked);
+
+  // Call into the VM to "quicken" instanceof.
+  __ push_ptr();  // for GC
+  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc));
+  __ get_vm_result_2(RspecifiedKlass);
+  __ pop_ptr();   // Restore receiver.
+  __ b(Lresolved);
+
+  // Extract target class from constant pool.
+  __ bind(Lquicked);
+  __ sldi(Roffset, Roffset, LogBytesPerWord);
+  __ addi(Rcpool, Rcpool, sizeof(ConstantPool));
+  __ isync(); // Order load of specified Klass wrt. tags.
+  __ ldx(RspecifiedKlass, Rcpool, Roffset);
+
+  // Do the checkcast.
+  __ bind(Lresolved);
+  // Get value klass in RobjKlass.
+  __ load_klass(RobjKlass, R17_tos);
+  // Generate a fast subtype check. Branch to cast_ok if no failure. Return 0 if failure.
+  __ gen_subtype_check(RobjKlass, RspecifiedKlass, /*3 temp regs*/ Roffset, Rcpool, Rtags, /*target if subtype*/ Ldone);
+
+  // Not a subtype; so must throw exception
+  // Target class oop is in register R6_ARG4 == RspecifiedKlass by convention.
+  __ load_dispatch_table(R11_scratch1, (address*)Interpreter::_throw_ClassCastException_entry);
+  __ mtctr(R11_scratch1);
+  __ bctr();
+
+  // Profile the null case.
+  __ align(32, 12);
+  __ bind(Lis_null);
+  __ profile_null_seen(R11_scratch1, Rtags); // Rtags used as scratch.
+
+  __ align(32, 12);
+  __ bind(Ldone);
+}
+
+// Output:
+//   - tos == 0: Obj was null or not an instance of class.
+//   - tos == 1: Obj was an instance of class.
+void TemplateTable::instanceof() {
+  transition(atos, itos);
+
+  Label Ldone, Lis_null, Lquicked, Lresolved;
+  Register Roffset         = R5_ARG3,
+           RobjKlass       = R4_ARG2,
+           RspecifiedKlass = R6_ARG4, // Generate_ClassCastException_verbose_handler will expect the value in this register.
+           Rcpool          = R11_scratch1,
+           Rtags           = R12_scratch2;
+
+  // Null does not pass.
+  __ cmpdi(CCR0, R17_tos, 0);
+  __ beq(CCR0, Lis_null);
+
+  // Get constant pool tag to find out if the bytecode has already been "quickened".
+  __ get_cpool_and_tags(Rcpool, Rtags);
+
+  __ get_2_byte_integer_at_bcp(1, Roffset, InterpreterMacroAssembler::Unsigned);
+
+  __ addi(Rtags, Rtags, Array<u1>::base_offset_in_bytes());
+  __ lbzx(Rtags, Rtags, Roffset);
+
+  __ cmpdi(CCR0, Rtags, JVM_CONSTANT_Class);
+  __ beq(CCR0, Lquicked);
+
+  // Call into the VM to "quicken" instanceof.
+  __ push_ptr();  // for GC
+  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc));
+  __ get_vm_result_2(RspecifiedKlass);
+  __ pop_ptr();   // Restore receiver.
+  __ b(Lresolved);
+
+  // Extract target class from constant pool.
+  __ bind(Lquicked);
+  __ sldi(Roffset, Roffset, LogBytesPerWord);
+  __ addi(Rcpool, Rcpool, sizeof(ConstantPool));
+  __ isync(); // Order load of specified Klass wrt. tags.
+  __ ldx(RspecifiedKlass, Rcpool, Roffset);
+
+  // Do the checkcast.
+  __ bind(Lresolved);
+  // Get value klass in RobjKlass.
+  __ load_klass(RobjKlass, R17_tos);
+  // Generate a fast subtype check. Branch to cast_ok if no failure. Return 0 if failure.
+  __ li(R17_tos, 1);
+  __ gen_subtype_check(RobjKlass, RspecifiedKlass, /*3 temp regs*/ Roffset, Rcpool, Rtags, /*target if subtype*/ Ldone);
+  __ li(R17_tos, 0);
+
+  if (ProfileInterpreter) {
+    __ b(Ldone);
+  }
+
+  // Profile the null case.
+  __ align(32, 12);
+  __ bind(Lis_null);
+  __ profile_null_seen(Rcpool, Rtags); // Rcpool and Rtags used as scratch.
+
+  __ align(32, 12);
+  __ bind(Ldone);
+}
+
+// =============================================================================
+// Breakpoints
+
+void TemplateTable::_breakpoint() {
+  transition(vtos, vtos);
+
+  // Get the unpatched byte code.
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::get_original_bytecode_at), R19_method, R14_bcp);
+  __ mr(R31, R3_RET);
+
+  // Post the breakpoint event.
+  __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::_breakpoint), R19_method, R14_bcp);
+
+  // Complete the execution of original bytecode.
+  __ dispatch_Lbyte_code(vtos, R31, Interpreter::normal_table(vtos));
+}
+
+// =============================================================================
+// Exceptions
+
+void TemplateTable::athrow() {
+  transition(atos, vtos);
+
+  // Exception oop is in tos
+  __ verify_oop(R17_tos);
+
+  __ null_check_throw(R17_tos, -1, R11_scratch1);
+
+  // Throw exception interpreter entry expects exception oop to be in R3.
+  __ mr(R3_RET, R17_tos);
+  __ load_dispatch_table(R11_scratch1, (address*)Interpreter::throw_exception_entry());
+  __ mtctr(R11_scratch1);
+  __ bctr();
+}
+
+// =============================================================================
+// Synchronization
+// Searches the basic object lock list on the stack for a free slot
+// and uses it to lock the obect in tos.
+//
+// Recursive locking is enabled by exiting the search if the same
+// object is already found in the list. Thus, a new basic lock obj lock
+// is allocated "higher up" in the stack and thus is found first
+// at next monitor exit.
+void TemplateTable::monitorenter() {
+  transition(atos, vtos);
+
+  __ verify_oop(R17_tos);
+
+  Register Rcurrent_monitor  = R11_scratch1,
+           Rcurrent_obj      = R12_scratch2,
+           Robj_to_lock      = R17_tos,
+           Rscratch1         = R3_ARG1,
+           Rscratch2         = R4_ARG2,
+           Rscratch3         = R5_ARG3,
+           Rcurrent_obj_addr = R6_ARG4;
+
+  // ------------------------------------------------------------------------------
+  // Null pointer exception.
+  __ null_check_throw(Robj_to_lock, -1, R11_scratch1);
+
+  // Try to acquire a lock on the object.
+  // Repeat until succeeded (i.e., until monitorenter returns true).
+
+  // ------------------------------------------------------------------------------
+  // Find a free slot in the monitor block.
+  Label Lfound, Lexit, Lallocate_new;
+  ConditionRegister found_free_slot = CCR0,
+                    found_same_obj  = CCR1,
+                    reached_limit   = CCR6;
+  {
+    Label Lloop, Lentry;
+    Register Rlimit = Rcurrent_monitor;
+
+    // Set up search loop - start with topmost monitor.
+    __ add(Rcurrent_obj_addr, BasicObjectLock::obj_offset_in_bytes(), R26_monitor);
+
+    __ ld(Rlimit, 0, R1_SP);
+    __ addi(Rlimit, Rlimit, - (frame::ijava_state_size + frame::interpreter_frame_monitor_size_in_bytes() - BasicObjectLock::obj_offset_in_bytes())); // Monitor base
+
+    // Check if any slot is present => short cut to allocation if not.
+    __ cmpld(reached_limit, Rcurrent_obj_addr, Rlimit);
+    __ bgt(reached_limit, Lallocate_new);
+
+    // Pre-load topmost slot.
+    __ ld(Rcurrent_obj, 0, Rcurrent_obj_addr);
+    __ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, frame::interpreter_frame_monitor_size() * wordSize);
+    // The search loop.
+    __ bind(Lloop);
+    // Found free slot?
+    __ cmpdi(found_free_slot, Rcurrent_obj, 0);
+    // Is this entry for same obj? If so, stop the search and take the found
+    // free slot or allocate a new one to enable recursive locking.
+    __ cmpd(found_same_obj, Rcurrent_obj, Robj_to_lock);
+    __ cmpld(reached_limit, Rcurrent_obj_addr, Rlimit);
+    __ beq(found_free_slot, Lexit);
+    __ beq(found_same_obj, Lallocate_new);
+    __ bgt(reached_limit, Lallocate_new);
+    // Check if last allocated BasicLockObj reached.
+    __ ld(Rcurrent_obj, 0, Rcurrent_obj_addr);
+    __ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, frame::interpreter_frame_monitor_size() * wordSize);
+    // Next iteration if unchecked BasicObjectLocks exist on the stack.
+    __ b(Lloop);
+  }
+
+  // ------------------------------------------------------------------------------
+  // Check if we found a free slot.
+  __ bind(Lexit);
+
+  __ addi(Rcurrent_monitor, Rcurrent_obj_addr, -(frame::interpreter_frame_monitor_size() * wordSize) - BasicObjectLock::obj_offset_in_bytes());
+  __ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, - frame::interpreter_frame_monitor_size() * wordSize);
+  __ b(Lfound);
+
+  // We didn't find a free BasicObjLock => allocate one.
+  __ align(32, 12);
+  __ bind(Lallocate_new);
+  __ add_monitor_to_stack(false, Rscratch1, Rscratch2);
+  __ mr(Rcurrent_monitor, R26_monitor);
+  __ addi(Rcurrent_obj_addr, R26_monitor, BasicObjectLock::obj_offset_in_bytes());
+
+  // ------------------------------------------------------------------------------
+  // We now have a slot to lock.
+  __ bind(Lfound);
+
+  // Increment bcp to point to the next bytecode, so exception handling for async. exceptions work correctly.
+  // The object has already been poped from the stack, so the expression stack looks correct.
+  __ addi(R14_bcp, R14_bcp, 1);
+
+  __ std(Robj_to_lock, 0, Rcurrent_obj_addr);
+  __ lock_object(Rcurrent_monitor, Robj_to_lock);
+
+  // Check if there's enough space on the stack for the monitors after locking.
+  Label Lskip_stack_check;
+  // Optimization: If the monitors stack section is less then a std page size (4K) don't run
+  // the stack check. There should be enough shadow pages to fit that in.
+  __ ld(Rscratch3, 0, R1_SP);
+  __ sub(Rscratch3, Rscratch3, R26_monitor);
+  __ cmpdi(CCR0, Rscratch3, 4*K);
+  __ blt(CCR0, Lskip_stack_check);
+
+  DEBUG_ONLY(__ untested("stack overflow check during monitor enter");)
+  __ li(Rscratch1, 0);
+  __ generate_stack_overflow_check_with_compare_and_throw(Rscratch1, Rscratch2);
+
+  __ align(32, 12);
+  __ bind(Lskip_stack_check);
+
+  // The bcp has already been incremented. Just need to dispatch to next instruction.
+  __ dispatch_next(vtos);
+}
+
+void TemplateTable::monitorexit() {
+  transition(atos, vtos);
+  __ verify_oop(R17_tos);
+
+  Register Rcurrent_monitor  = R11_scratch1,
+           Rcurrent_obj      = R12_scratch2,
+           Robj_to_lock      = R17_tos,
+           Rcurrent_obj_addr = R3_ARG1,
+           Rlimit            = R4_ARG2;
+  Label Lfound, Lillegal_monitor_state;
+
+  // Check corner case: unbalanced monitorEnter / Exit.
+  __ ld(Rlimit, 0, R1_SP);
+  __ addi(Rlimit, Rlimit, - (frame::ijava_state_size + frame::interpreter_frame_monitor_size_in_bytes())); // Monitor base
+
+  // Null pointer check.
+  __ null_check_throw(Robj_to_lock, -1, R11_scratch1);
+
+  __ cmpld(CCR0, R26_monitor, Rlimit);
+  __ bgt(CCR0, Lillegal_monitor_state);
+
+  // Find the corresponding slot in the monitors stack section.
+  {
+    Label Lloop;
+
+    // Start with topmost monitor.
+    __ addi(Rcurrent_obj_addr, R26_monitor, BasicObjectLock::obj_offset_in_bytes());
+    __ addi(Rlimit, Rlimit, BasicObjectLock::obj_offset_in_bytes());
+    __ ld(Rcurrent_obj, 0, Rcurrent_obj_addr);
+    __ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, frame::interpreter_frame_monitor_size() * wordSize);
+
+    __ bind(Lloop);
+    // Is this entry for same obj?
+    __ cmpd(CCR0, Rcurrent_obj, Robj_to_lock);
+    __ beq(CCR0, Lfound);
+
+    // Check if last allocated BasicLockObj reached.
+
+    __ ld(Rcurrent_obj, 0, Rcurrent_obj_addr);
+    __ cmpld(CCR0, Rcurrent_obj_addr, Rlimit);
+    __ addi(Rcurrent_obj_addr, Rcurrent_obj_addr, frame::interpreter_frame_monitor_size() * wordSize);
+
+    // Next iteration if unchecked BasicObjectLocks exist on the stack.
+    __ ble(CCR0, Lloop);
+  }
+
+  // Fell through without finding the basic obj lock => throw up!
+  __ bind(Lillegal_monitor_state);
+  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_illegal_monitor_state_exception));
+  __ should_not_reach_here();
+
+  __ align(32, 12);
+  __ bind(Lfound);
+  __ addi(Rcurrent_monitor, Rcurrent_obj_addr,
+          -(frame::interpreter_frame_monitor_size() * wordSize) - BasicObjectLock::obj_offset_in_bytes());
+  __ unlock_object(Rcurrent_monitor);
+}
+
+// ============================================================================
+// Wide bytecodes
+
+// Wide instructions. Simply redirects to the wide entry point for that instruction.
+void TemplateTable::wide() {
+  transition(vtos, vtos);
+
+  const Register Rtable = R11_scratch1,
+                 Rindex = R12_scratch2,
+                 Rtmp   = R0;
+
+  __ lbz(Rindex, 1, R14_bcp);
+
+  __ load_dispatch_table(Rtable, Interpreter::_wentry_point);
+
+  __ slwi(Rindex, Rindex, LogBytesPerWord);
+  __ ldx(Rtmp, Rtable, Rindex);
+  __ mtctr(Rtmp);
+  __ bctr();
+  // Note: the bcp increment step is part of the individual wide bytecode implementations.
+}
+#endif // !CC_INTERP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2013, 2014 SAP AG. 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.
+ *
+ */
+
+#ifndef CPU_PPC_VM_TEMPLATETABLE_PPC_64_HPP
+#define CPU_PPC_VM_TEMPLATETABLE_PPC_64_HPP
+
+  static void prepare_invoke(int byte_no, Register Rmethod, Register Rret_addr, Register Rindex, Register Rrecv, Register Rflags, Register Rscratch);
+  static void invokevfinal_helper(Register Rmethod, Register Rflags, Register Rscratch1, Register Rscratch2);
+  static void generate_vtable_call(Register Rrecv_klass, Register Rindex, Register Rret, Register Rtemp);
+  static void invokeinterface_object_method(Register Rrecv_klass, Register Rret, Register Rflags, Register Rindex, Register Rtemp, Register Rtemp2);
+
+  // Branch_conditional which takes TemplateTable::Condition.
+  static void branch_conditional(ConditionRegister crx, TemplateTable::Condition cc, Label& L, bool invert = false);
+  static void if_cmp_common(Register Rfirst, Register Rsecond, Register Rscratch1, Register Rscratch2, Condition cc, bool is_jint, bool cmp0);
+
+#endif // CPU_PPC_VM_TEMPLATETABLE_PPC_64_HPP
--- a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -24,7 +24,8 @@
  */
 
 #include "precompiled.hpp"
-#include "assembler_ppc.inline.hpp"
+#include "asm/assembler.inline.hpp"
+#include "asm/macroAssembler.inline.hpp"
 #include "compiler/disassembler.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/java.hpp"
@@ -168,7 +169,7 @@
 
   uint32_t *code = (uint32_t *)a->pc();
   // Emit code.
-  void (*test1)() = (void(*)())(void *)a->emit_fd();
+  void (*test1)() = (void(*)())(void *)a->function_entry();
 
   Label l1;
 
@@ -242,7 +243,7 @@
   a->blr();
 
   // Emit code.
-  void (*test2)() = (void(*)())(void *)a->emit_fd();
+  void (*test2)() = (void(*)())(void *)a->function_entry();
   // uint32_t *code = (uint32_t *)a->pc();
 
   Label l2;
@@ -383,8 +384,12 @@
 #endif // COMPILER2
 
 void VM_Version::determine_features() {
+#if defined(ABI_ELFv2)
+  const int code_size = (num_features+1+2*7)*BytesPerInstWord; // TODO(asmundak): calculation is incorrect.
+#else
   // 7 InstWords for each call (function descriptor + blr instruction).
   const int code_size = (num_features+1+2*7)*BytesPerInstWord;
+#endif
   int features = 0;
 
   // create test area
@@ -398,7 +403,7 @@
   MacroAssembler* a = new MacroAssembler(&cb);
 
   // Emit code.
-  void (*test)(address addr, uint64_t offset)=(void(*)(address addr, uint64_t offset))(void *)a->emit_fd();
+  void (*test)(address addr, uint64_t offset)=(void(*)(address addr, uint64_t offset))(void *)a->function_entry();
   uint32_t *code = (uint32_t *)a->pc();
   // Don't use R0 in ldarx.
   // Keep R3_ARG1 unmodified, it contains &field (see below).
@@ -415,7 +420,7 @@
   a->blr();
 
   // Emit function to set one cache line to zero. Emit function descriptor and get pointer to it.
-  void (*zero_cacheline_func_ptr)(char*) = (void(*)(char*))(void *)a->emit_fd();
+  void (*zero_cacheline_func_ptr)(char*) = (void(*)(char*))(void *)a->function_entry();
   a->dcbz(R3_ARG1); // R3_ARG1 = addr
   a->blr();
 
--- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -413,16 +413,15 @@
   // Update standard invocation counters
   __ increment_invocation_counter(Rcounters, O0, G4_scratch);
   if (ProfileInterpreter) {
-    Address interpreter_invocation_counter(Rcounters, 0,
+    Address interpreter_invocation_counter(Rcounters,
             in_bytes(MethodCounters::interpreter_invocation_counter_offset()));
     __ ld(interpreter_invocation_counter, G4_scratch);
     __ inc(G4_scratch);
     __ st(G4_scratch, interpreter_invocation_counter);
   }
 
-  Address invocation_limit(G3_scratch, (address)&InvocationCounter::InterpreterInvocationLimit);
-  __ sethi(invocation_limit);
-  __ ld(invocation_limit, G3_scratch);
+  AddressLiteral invocation_limit((address)&InvocationCounter::InterpreterInvocationLimit);
+  __ load_contents(invocation_limit, G3_scratch);
   __ cmp(O0, G3_scratch);
   __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow);
   __ delayed()->nop();
@@ -439,7 +438,7 @@
   // do nothing for empty methods (do not even increment invocation counter)
   if ( UseFastEmptyMethods) {
     // If we need a safepoint check, generate full interpreter entry.
-    Address sync_state(G3_scratch, SafepointSynchronize::address_of_state());
+    AddressLiteral sync_state(SafepointSynchronize::address_of_state());
     __ load_contents(sync_state, G3_scratch);
     __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
     __ br(Assembler::notEqual, false, Assembler::pn, frame_manager_entry);
@@ -471,7 +470,7 @@
   if ( UseFastAccessorMethods) {
     // Check if we need to reach a safepoint and generate full interpreter
     // frame if so.
-    Address sync_state(G3_scratch, SafepointSynchronize::address_of_state());
+    AddressLiteral sync_state(SafepointSynchronize::address_of_state());
     __ load_contents(sync_state, G3_scratch);
     __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
     __ br(Assembler::notEqual, false, Assembler::pn, slow_path);
@@ -486,8 +485,8 @@
 
     // read first instruction word and extract bytecode @ 1 and index @ 2
     // get first 4 bytes of the bytecodes (big endian!)
-    __ ld_ptr(Address(G5_method, 0, in_bytes(Method::const_offset())), G1_scratch);
-    __ ld(Address(G1_scratch, 0, in_bytes(ConstMethod::codes_offset())), G1_scratch);
+    __ ld_ptr(Address(G5_method, in_bytes(Method::const_offset())), G1_scratch);
+    __ ld(Address(G1_scratch, in_bytes(ConstMethod::codes_offset())), G1_scratch);
 
     // move index @ 2 far left then to the right most two bytes.
     __ sll(G1_scratch, 2*BitsPerByte, G1_scratch);
@@ -590,15 +589,15 @@
   const Register Gtmp1 = G3_scratch ;
   const Register Gtmp2 = G1_scratch;
   const Register RconstMethod = Gtmp1;
-  const Address constMethod(G5_method, 0, in_bytes(Method::const_offset()));
-  const Address size_of_parameters(RconstMethod, 0, in_bytes(ConstMethod::size_of_parameters_offset()));
+  const Address constMethod(G5_method, in_bytes(Method::const_offset()));
+  const Address size_of_parameters(RconstMethod, in_bytes(ConstMethod::size_of_parameters_offset()));
 
   bool inc_counter  = UseCompiler || CountCompiledCalls;
 
   // make sure registers are different!
   assert_different_registers(G2_thread, G5_method, Gargs, Gtmp1, Gtmp2);
 
-  const Address access_flags      (G5_method, 0, in_bytes(Method::access_flags_offset()));
+  const Address access_flags      (G5_method, in_bytes(Method::access_flags_offset()));
 
   Label Lentry;
   __ bind(Lentry);
@@ -643,7 +642,7 @@
   // At this point Lstate points to new interpreter state
   //
 
-  const Address do_not_unlock_if_synchronized(G2_thread, 0,
+  const Address do_not_unlock_if_synchronized(G2_thread,
       in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));
   // Since at this point in the method invocation the exception handler
   // would try to exit the monitor of synchronized methods which hasn't
@@ -717,17 +716,17 @@
 
   { Label L;
     __ ld_ptr(STATE(_method), G5_method);
-    __ ld_ptr(Address(G5_method, 0, in_bytes(Method::signature_handler_offset())), G3_scratch);
+    __ ld_ptr(Address(G5_method, in_bytes(Method::signature_handler_offset())), G3_scratch);
     __ tst(G3_scratch);
     __ brx(Assembler::notZero, false, Assembler::pt, L);
     __ delayed()->nop();
     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::prepare_native_call), G5_method, false);
     __ ld_ptr(STATE(_method), G5_method);
 
-    Address exception_addr(G2_thread, 0, in_bytes(Thread::pending_exception_offset()));
+    Address exception_addr(G2_thread, in_bytes(Thread::pending_exception_offset()));
     __ ld_ptr(exception_addr, G3_scratch);
     __ br_notnull_short(G3_scratch, Assembler::pn, pending_exception_present);
-    __ ld_ptr(Address(G5_method, 0, in_bytes(Method::signature_handler_offset())), G3_scratch);
+    __ ld_ptr(Address(G5_method, in_bytes(Method::signature_handler_offset())), G3_scratch);
     __ bind(L);
   }
 
@@ -771,13 +770,13 @@
     __ br( Assembler::zero, false, Assembler::pt, not_static);
     __ delayed()->
       // get native function entry point(O0 is a good temp until the very end)
-       ld_ptr(Address(G5_method, 0, in_bytes(Method::native_function_offset())), O0);
+       ld_ptr(Address(G5_method, in_bytes(Method::native_function_offset())), O0);
     // for static methods insert the mirror argument
     const int mirror_offset = in_bytes(Klass::java_mirror_offset());
 
-    __ ld_ptr(Address(G5_method, 0, in_bytes(Method:: const_offset())), O1);
-    __ ld_ptr(Address(O1, 0, in_bytes(ConstMethod::constants_offset())), O1);
-    __ ld_ptr(Address(O1, 0, ConstantPool::pool_holder_offset_in_bytes()), O1);
+    __ ld_ptr(Address(G5_method, in_bytes(Method:: const_offset())), O1);
+    __ ld_ptr(Address(O1, in_bytes(ConstMethod::constants_offset())), O1);
+    __ ld_ptr(Address(O1, ConstantPool::pool_holder_offset_in_bytes()), O1);
     __ ld_ptr(O1, mirror_offset, O1);
     // where the mirror handle body is allocated:
 #ifdef ASSERT
@@ -831,18 +830,17 @@
   // flush the windows now. We don't care about the current (protection) frame
   // only the outer frames
 
-  __ flush_windows();
+  __ flushw();
 
   // mark windows as flushed
   Address flags(G2_thread,
-                0,
                 in_bytes(JavaThread::frame_anchor_offset()) + in_bytes(JavaFrameAnchor::flags_offset()));
   __ set(JavaFrameAnchor::flushed, G3_scratch);
   __ st(G3_scratch, flags);
 
   // Transition from _thread_in_Java to _thread_in_native. We are already safepoint ready.
 
-  Address thread_state(G2_thread, 0, in_bytes(JavaThread::thread_state_offset()));
+  Address thread_state(G2_thread, in_bytes(JavaThread::thread_state_offset()));
 #ifdef ASSERT
   { Label L;
     __ ld(thread_state, G3_scratch);
@@ -867,7 +865,7 @@
   // Block, if necessary, before resuming in _thread_in_Java state.
   // In order for GC to work, don't clear the last_Java_sp until after blocking.
   { Label no_block;
-    Address sync_state(G3_scratch, SafepointSynchronize::address_of_state());
+    AddressLiteral sync_state(SafepointSynchronize::address_of_state());
 
     // Switch thread to "native transition" state before reading the synchronization state.
     // This additional state is necessary because reading and testing the synchronization
@@ -890,7 +888,7 @@
 
 
     Label L;
-    Address suspend_state(G2_thread, 0, in_bytes(JavaThread::suspend_flags_offset()));
+    Address suspend_state(G2_thread, in_bytes(JavaThread::suspend_flags_offset()));
     __ br(Assembler::notEqual, false, Assembler::pn, L);
     __ delayed()->
       ld(suspend_state, G3_scratch);
@@ -965,7 +963,7 @@
 
   // handle exceptions (exception handling will handle unlocking!)
   { Label L;
-    Address exception_addr (G2_thread, 0, in_bytes(Thread::pending_exception_offset()));
+    Address exception_addr (G2_thread, in_bytes(Thread::pending_exception_offset()));
 
     __ ld_ptr(exception_addr, Gtemp);
     __ tst(Gtemp);
@@ -1055,8 +1053,8 @@
   assert_different_registers(state, prev_state);
   assert_different_registers(prev_state, G3_scratch);
   const Register Gtmp = G3_scratch;
-  const Address constMethod       (G5_method, 0, in_bytes(Method::const_offset()));
-  const Address access_flags      (G5_method, 0, in_bytes(Method::access_flags_offset()));
+  const Address constMethod       (G5_method, in_bytes(Method::const_offset()));
+  const Address access_flags      (G5_method, in_bytes(Method::access_flags_offset()));
 
   // slop factor is two extra slots on the expression stack so that
   // we always have room to store a result when returning from a call without parameters
@@ -1075,7 +1073,7 @@
 
   if (native) {
     const Register RconstMethod = Gtmp;
-    const Address size_of_parameters(RconstMethod, 0, in_bytes(ConstMethod::size_of_parameters_offset()));
+    const Address size_of_parameters(RconstMethod, in_bytes(ConstMethod::size_of_parameters_offset()));
     __ ld_ptr(constMethod, RconstMethod);
     __ lduh( size_of_parameters, Gtmp );
     __ calc_mem_param_words(Gtmp, Gtmp);     // space for native call parameters passed on the stack in words
@@ -1246,8 +1244,8 @@
     if (init_value != noreg) {
       Label clear_loop;
       const Register RconstMethod = O1;
-      const Address size_of_parameters(RconstMethod, 0, in_bytes(ConstMethod::size_of_parameters_offset()));
-      const Address size_of_locals    (RconstMethod, 0, in_bytes(ConstMethod::size_of_locals_offset()));
+      const Address size_of_parameters(RconstMethod, in_bytes(ConstMethod::size_of_parameters_offset()));
+      const Address size_of_locals    (RconstMethod, in_bytes(ConstMethod::size_of_locals_offset()));
 
       // NOTE: If you change the frame layout, this code will need to
       // be updated!
@@ -1496,11 +1494,11 @@
 //
 //  assert_different_registers(state, prev_state);
   const Register Gtmp = G3_scratch;
-  const RconstMethod = G3_scratch;
+  const Register RconstMethod = G3_scratch;
   const Register tmp = O2;
-  const Address constMethod(G5_method, 0, in_bytes(Method::const_offset()));
-  const Address size_of_parameters(RconstMethod, 0, in_bytes(ConstMethod::size_of_parameters_offset()));
-  const Address size_of_locals    (RconstMethod, 0, in_bytes(ConstMethod::size_of_locals_offset()));
+  const Address constMethod(G5_method, in_bytes(Method::const_offset()));
+  const Address size_of_parameters(RconstMethod, in_bytes(ConstMethod::size_of_parameters_offset()));
+  const Address size_of_locals    (RconstMethod, in_bytes(ConstMethod::size_of_locals_offset()));
 
   __ ld_ptr(constMethod, RconstMethod);
   __ lduh(size_of_parameters, tmp);
@@ -1555,8 +1553,8 @@
   const Register Gtmp1 = G3_scratch;
   // const Register Lmirror = L1;     // native mirror (native calls only)
 
-  const Address constMethod       (G5_method, 0, in_bytes(Method::const_offset()));
-  const Address access_flags      (G5_method, 0, in_bytes(Method::access_flags_offset()));
+  const Address constMethod       (G5_method, in_bytes(Method::const_offset()));
+  const Address access_flags      (G5_method, in_bytes(Method::access_flags_offset()));
 
   address entry_point = __ pc();
   __ mov(G0, prevState);                                                 // no current activation
@@ -1709,7 +1707,7 @@
 
   // We want exception in the thread no matter what we ultimately decide about frame type.
 
-  Address exception_addr (G2_thread, 0, in_bytes(Thread::pending_exception_offset()));
+  Address exception_addr (G2_thread, in_bytes(Thread::pending_exception_offset()));
   __ verify_thread();
   __ st_ptr(O0, exception_addr);
 
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -827,6 +827,7 @@
   }
 
   if (is_interpreted_frame()) {
+#ifndef CC_INTERP
     DESCRIBE_FP_OFFSET(interpreter_frame_d_scratch_fp);
     DESCRIBE_FP_OFFSET(interpreter_frame_l_scratch_fp);
     DESCRIBE_FP_OFFSET(interpreter_frame_padding);
@@ -837,6 +838,7 @@
     if ((esp >= sp()) && (esp < fp())) {
       values.describe(-1, esp, "*Lesp");
     }
+#endif
   }
 
   if (!is_compiled_frame()) {
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -2497,6 +2497,24 @@
 void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) {
   if (state == ftos || state == dtos) MacroAssembler::verify_FPU(stack_depth);
 }
+
+
+// Jump if ((*counter_addr += increment) & mask) satisfies the condition.
+void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
+                                                        int increment, int mask,
+                                                        Register scratch1, Register scratch2,
+                                                        Condition cond, Label *where) {
+  ld(counter_addr, scratch1);
+  add(scratch1, increment, scratch1);
+  if (is_simm13(mask)) {
+    andcc(scratch1, mask, G0);
+  } else {
+    set(mask, scratch2);
+    andcc(scratch1, scratch2,  G0);
+  }
+  br(cond, false, Assembler::pn, *where);
+  delayed()->st(scratch1, counter_addr);
+}
 #endif /* CC_INTERP */
 
 // Inline assembly for:
@@ -2646,20 +2664,3 @@
   }
 #endif // CC_INTERP
 }
-
-// Jump if ((*counter_addr += increment) & mask) satisfies the condition.
-void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
-                                                        int increment, int mask,
-                                                        Register scratch1, Register scratch2,
-                                                        Condition cond, Label *where) {
-  ld(counter_addr, scratch1);
-  add(scratch1, increment, scratch1);
-  if (is_simm13(mask)) {
-    andcc(scratch1, mask, G0);
-  } else {
-    set(mask, scratch2);
-    andcc(scratch1, scratch2,  G0);
-  }
-  br(cond, false, Assembler::pn, *where);
-  delayed()->st(scratch1, counter_addr);
-}
--- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -23,7 +23,8 @@
  */
 
 #include "precompiled.hpp"
-#include "asm/macroAssembler.hpp"
+#include "asm/macroAssembler.inline.hpp"
+#include "code/codeCache.hpp"
 #include "memory/resourceArea.hpp"
 #include "nativeInst_sparc.hpp"
 #include "oops/oop.inline.hpp"
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1089,6 +1089,21 @@
   emit_arith(0x23, 0xC0, dst, src);
 }
 
+void Assembler::andnl(Register dst, Register src1, Register src2) {
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  int encode = vex_prefix_0F38_and_encode(dst, src1, src2);
+  emit_int8((unsigned char)0xF2);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::andnl(Register dst, Register src1, Address src2) {
+  InstructionMark im(this);
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  vex_prefix_0F38(dst, src1, src2);
+  emit_int8((unsigned char)0xF2);
+  emit_operand(dst, src2);
+}
+
 void Assembler::bsfl(Register dst, Register src) {
   int encode = prefix_and_encode(dst->encoding(), src->encoding());
   emit_int8(0x0F);
@@ -1110,6 +1125,51 @@
   emit_int8((unsigned char)(0xC8 | encode));
 }
 
+void Assembler::blsil(Register dst, Register src) {
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  int encode = vex_prefix_0F38_and_encode(rbx, dst, src);
+  emit_int8((unsigned char)0xF3);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::blsil(Register dst, Address src) {
+  InstructionMark im(this);
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  vex_prefix_0F38(rbx, dst, src);
+  emit_int8((unsigned char)0xF3);
+  emit_operand(rbx, src);
+}
+
+void Assembler::blsmskl(Register dst, Register src) {
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  int encode = vex_prefix_0F38_and_encode(rdx, dst, src);
+  emit_int8((unsigned char)0xF3);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::blsmskl(Register dst, Address src) {
+  InstructionMark im(this);
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  vex_prefix_0F38(rdx, dst, src);
+  emit_int8((unsigned char)0xF3);
+  emit_operand(rdx, src);
+}
+
+void Assembler::blsrl(Register dst, Register src) {
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  int encode = vex_prefix_0F38_and_encode(rcx, dst, src);
+  emit_int8((unsigned char)0xF3);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::blsrl(Register dst, Address src) {
+  InstructionMark im(this);
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  vex_prefix_0F38(rcx, dst, src);
+  emit_int8((unsigned char)0xF3);
+  emit_operand(rcx, src);
+}
+
 void Assembler::call(Label& L, relocInfo::relocType rtype) {
   // suspect disp32 is always good
   int operand = LP64_ONLY(disp32_operand) NOT_LP64(imm_operand);
@@ -2878,6 +2938,24 @@
   emit_operand(dst, src);
 }
 
+void Assembler::tzcntl(Register dst, Register src) {
+  assert(VM_Version::supports_bmi1(), "tzcnt instruction not supported");
+  emit_int8((unsigned char)0xF3);
+  int encode = prefix_and_encode(dst->encoding(), src->encoding());
+  emit_int8(0x0F);
+  emit_int8((unsigned char)0xBC);
+  emit_int8((unsigned char)0xC0 | encode);
+}
+
+void Assembler::tzcntq(Register dst, Register src) {
+  assert(VM_Version::supports_bmi1(), "tzcnt instruction not supported");
+  emit_int8((unsigned char)0xF3);
+  int encode = prefixq_and_encode(dst->encoding(), src->encoding());
+  emit_int8(0x0F);
+  emit_int8((unsigned char)0xBC);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
 void Assembler::ucomisd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   emit_simd_arith_nonds(0x2E, dst, src, VEX_SIMD_66);
@@ -4837,6 +4915,21 @@
   emit_arith(0x23, 0xC0, dst, src);
 }
 
+void Assembler::andnq(Register dst, Register src1, Register src2) {
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  int encode = vex_prefix_0F38_and_encode_q(dst, src1, src2);
+  emit_int8((unsigned char)0xF2);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::andnq(Register dst, Register src1, Address src2) {
+  InstructionMark im(this);
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  vex_prefix_0F38_q(dst, src1, src2);
+  emit_int8((unsigned char)0xF2);
+  emit_operand(dst, src2);
+}
+
 void Assembler::bsfq(Register dst, Register src) {
   int encode = prefixq_and_encode(dst->encoding(), src->encoding());
   emit_int8(0x0F);
@@ -4858,6 +4951,51 @@
   emit_int8((unsigned char)(0xC8 | encode));
 }
 
+void Assembler::blsiq(Register dst, Register src) {
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  int encode = vex_prefix_0F38_and_encode_q(rbx, dst, src);
+  emit_int8((unsigned char)0xF3);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::blsiq(Register dst, Address src) {
+  InstructionMark im(this);
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  vex_prefix_0F38_q(rbx, dst, src);
+  emit_int8((unsigned char)0xF3);
+  emit_operand(rbx, src);
+}
+
+void Assembler::blsmskq(Register dst, Register src) {
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  int encode = vex_prefix_0F38_and_encode_q(rdx, dst, src);
+  emit_int8((unsigned char)0xF3);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::blsmskq(Register dst, Address src) {
+  InstructionMark im(this);
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  vex_prefix_0F38_q(rdx, dst, src);
+  emit_int8((unsigned char)0xF3);
+  emit_operand(rdx, src);
+}
+
+void Assembler::blsrq(Register dst, Register src) {
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  int encode = vex_prefix_0F38_and_encode_q(rcx, dst, src);
+  emit_int8((unsigned char)0xF3);
+  emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::blsrq(Register dst, Address src) {
+  InstructionMark im(this);
+  assert(VM_Version::supports_bmi1(), "bit manipulation instructions not supported");
+  vex_prefix_0F38_q(rcx, dst, src);
+  emit_int8((unsigned char)0xF3);
+  emit_operand(rcx, src);
+}
+
 void Assembler::cdqq() {
   prefix(REX_W);
   emit_int8((unsigned char)0x99);
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -590,10 +590,35 @@
     vex_prefix(src, nds_enc, dst_enc, pre, VEX_OPCODE_0F, false, vector256);
   }
 
+  void vex_prefix_0F38(Register dst, Register nds, Address src) {
+    bool vex_w = false;
+    bool vector256 = false;
+    vex_prefix(src, nds->encoding(), dst->encoding(),
+               VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector256);
+  }
+
+  void vex_prefix_0F38_q(Register dst, Register nds, Address src) {
+    bool vex_w = true;
+    bool vector256 = false;
+    vex_prefix(src, nds->encoding(), dst->encoding(),
+               VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector256);
+  }
   int  vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc,
                              VexSimdPrefix pre, VexOpcode opc,
                              bool vex_w, bool vector256);
 
+  int  vex_prefix_0F38_and_encode(Register dst, Register nds, Register src) {
+    bool vex_w = false;
+    bool vector256 = false;
+    return vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(),
+                                 VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector256);
+  }
+  int  vex_prefix_0F38_and_encode_q(Register dst, Register nds, Register src) {
+    bool vex_w = true;
+    bool vector256 = false;
+    return vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(),
+                                 VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector256);
+  }
   int  vex_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src,
                              VexSimdPrefix pre, bool vector256 = false,
                              VexOpcode opc = VEX_OPCODE_0F) {
@@ -897,6 +922,27 @@
   void andq(Register dst, Address src);
   void andq(Register dst, Register src);
 
+  // BMI instructions
+  void andnl(Register dst, Register src1, Register src2);
+  void andnl(Register dst, Register src1, Address src2);
+  void andnq(Register dst, Register src1, Register src2);
+  void andnq(Register dst, Register src1, Address src2);
+
+  void blsil(Register dst, Register src);
+  void blsil(Register dst, Address src);
+  void blsiq(Register dst, Register src);
+  void blsiq(Register dst, Address src);
+
+  void blsmskl(Register dst, Register src);
+  void blsmskl(Register dst, Address src);
+  void blsmskq(Register dst, Register src);
+  void blsmskq(Register dst, Address src);
+
+  void blsrl(Register dst, Register src);
+  void blsrl(Register dst, Address src);
+  void blsrq(Register dst, Register src);
+  void blsrq(Register dst, Address src);
+
   void bsfl(Register dst, Register src);
   void bsrl(Register dst, Register src);
 
@@ -1574,6 +1620,9 @@
   void testq(Register dst, int32_t imm32);
   void testq(Register dst, Register src);
 
+  // BMI - count trailing zeros
+  void tzcntl(Register dst, Register src);
+  void tzcntq(Register dst, Register src);
 
   // Unordered Compare Scalar Double-Precision Floating-Point Values and set EFLAGS
   void ucomisd(XMMRegister dst, Address src);
--- a/hotspot/src/cpu/x86/vm/bytecodeInterpreter_x86.inline.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/bytecodeInterpreter_x86.inline.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -250,7 +250,7 @@
   return op1 - op2;
 }
 
-inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) {
+inline juint BytecodeInterpreter::VMintUshr(jint op1, jint op2) {
   return ((juint) op1) >> (op2 & 0x1f);
 }
 
--- a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -574,7 +574,7 @@
                 MethodCounters::invocation_counter_offset() +
                 InvocationCounter::counter_offset());
   const Address backedge_counter  (rax,
-                MethodCounter::backedge_counter_offset() +
+                MethodCounters::backedge_counter_offset() +
                 InvocationCounter::counter_offset());
 
   __ get_method_counters(rbx, rax, done);
@@ -982,16 +982,18 @@
   //      to save/restore.
   address entry_point = __ pc();
 
-  const Address constMethod       (rbx, Method::const_offset());
   const Address access_flags      (rbx, Method::access_flags_offset());
-  const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset());
 
   // rsi/r13 == state/locals rdi == prevstate
   const Register locals = rdi;
 
   // get parameter size (always needed)
-  __ movptr(rcx, constMethod);
-  __ load_unsigned_short(rcx, size_of_parameters);
+  {
+    const Address constMethod       (rbx, Method::const_offset());
+    const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset());
+    __ movptr(rcx, constMethod);
+    __ load_unsigned_short(rcx, size_of_parameters);
+  }
 
   // rbx: Method*
   // rcx: size of parameters
@@ -1111,14 +1113,16 @@
   const Register method = rbx;
   const Register thread = LP64_ONLY(r15_thread) NOT_LP64(rdi);
   const Register t      = InterpreterRuntime::SignatureHandlerGenerator::temp();    // rcx|rscratch1
-  const Address constMethod       (method, Method::const_offset());
-  const Address size_of_parameters(t, ConstMethod::size_of_parameters_offset());
-
-  // allocate space for parameters
+
+ // allocate space for parameters
   __ movptr(method, STATE(_method));
   __ verify_method_ptr(method);
-  __ movptr(t, constMethod);
-  __ load_unsigned_short(t, size_of_parameters);
+  {
+    const Address constMethod       (method, Method::const_offset());
+    const Address size_of_parameters(t, ConstMethod::size_of_parameters_offset());
+    __ movptr(t, constMethod);
+    __ load_unsigned_short(t, size_of_parameters);
+  }
   __ shll(t, 2);
 #ifdef _LP64
   __ subptr(rsp, t);
@@ -2221,7 +2225,6 @@
     case Interpreter::empty                  : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry();        break;
     case Interpreter::accessor               : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry();     break;
     case Interpreter::abstract               : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry();     break;
-    case Interpreter::method_handle          : entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); break;
 
     case Interpreter::java_lang_math_sin     : // fall thru
     case Interpreter::java_lang_math_cos     : // fall thru
@@ -2229,7 +2232,10 @@
     case Interpreter::java_lang_math_abs     : // fall thru
     case Interpreter::java_lang_math_log     : // fall thru
     case Interpreter::java_lang_math_log10   : // fall thru
-    case Interpreter::java_lang_math_sqrt    : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind);     break;
+    case Interpreter::java_lang_math_sqrt    : // fall thru
+    case Interpreter::java_lang_math_pow     : // fall thru
+    case Interpreter::java_lang_math_exp     : // fall thru
+      entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind);     break;
     case Interpreter::java_lang_ref_reference_get
                                              : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
     default                                  : ShouldNotReachHere();                                                       break;
@@ -2451,4 +2457,22 @@
   return frame_size/BytesPerWord;
 }
 
+bool AbstractInterpreter::can_be_compiled(methodHandle m) {
+  switch (method_kind(m)) {
+    case Interpreter::java_lang_math_sin     : // fall thru
+    case Interpreter::java_lang_math_cos     : // fall thru
+    case Interpreter::java_lang_math_tan     : // fall thru
+    case Interpreter::java_lang_math_abs     : // fall thru
+    case Interpreter::java_lang_math_log     : // fall thru
+    case Interpreter::java_lang_math_log10   : // fall thru
+    case Interpreter::java_lang_math_sqrt    : // fall thru
+    case Interpreter::java_lang_math_pow     : // fall thru
+    case Interpreter::java_lang_math_exp     :
+      return false;
+    default:
+      return true;
+  }
+}
+
+
 #endif // CC_INTERP (all)
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -687,6 +687,7 @@
 
 void frame::describe_pd(FrameValues& values, int frame_no) {
   if (is_interpreted_frame()) {
+#ifndef CC_INTERP
     DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp);
     DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
     DESCRIBE_FP_OFFSET(interpreter_frame_method);
@@ -695,6 +696,7 @@
     DESCRIBE_FP_OFFSET(interpreter_frame_locals);
     DESCRIBE_FP_OFFSET(interpreter_frame_bcx);
     DESCRIBE_FP_OFFSET(interpreter_frame_initial_sp);
+#endif
   }
 }
 #endif
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -135,5 +135,11 @@
                                                                             \
   product(bool, UseCountLeadingZerosInstruction, false,                     \
           "Use count leading zeros instruction")                            \
+                                                                            \
+  product(bool, UseCountTrailingZerosInstruction, false,                    \
+          "Use count trailing zeros instruction")                           \
+                                                                            \
+  product(bool, UseBMI1Instructions, false,                                 \
+          "Use BMI instructions")
 
 #endif // CPU_X86_VM_GLOBALS_X86_HPP
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -266,20 +266,6 @@
   addptr(cache, tmp);            // construct pointer to cache entry
 }
 
-void InterpreterMacroAssembler::get_method_counters(Register method,
-                                                    Register mcs, Label& skip) {
-  Label has_counters;
-  movptr(mcs, Address(method, Method::method_counters_offset()));
-  testptr(mcs, mcs);
-  jcc(Assembler::notZero, has_counters);
-  call_VM(noreg, CAST_FROM_FN_PTR(address,
-          InterpreterRuntime::build_method_counters), method);
-  movptr(mcs, Address(method,Method::method_counters_offset()));
-  testptr(mcs, mcs);
-  jcc(Assembler::zero, skip); // No MethodCounters allocated, OutOfMemory
-  bind(has_counters);
-}
-
 // Load object from cpool->resolved_references(index)
 void InterpreterMacroAssembler::load_resolved_reference_at_index(
                                            Register result, Register index) {
@@ -678,6 +664,20 @@
 
 #endif /* !CC_INTERP */
 
+void InterpreterMacroAssembler::get_method_counters(Register method,
+                                                    Register mcs, Label& skip) {
+  Label has_counters;
+  movptr(mcs, Address(method, Method::method_counters_offset()));
+  testptr(mcs, mcs);
+  jcc(Assembler::notZero, has_counters);
+  call_VM(noreg, CAST_FROM_FN_PTR(address,
+          InterpreterRuntime::build_method_counters), method);
+  movptr(mcs, Address(method,Method::method_counters_offset()));
+  testptr(mcs, mcs);
+  jcc(Assembler::zero, skip); // No MethodCounters allocated, OutOfMemory
+  bind(has_counters);
+}
+
 
 // Lock object
 //
@@ -1359,6 +1359,19 @@
   if (state == ftos || state == dtos) MacroAssembler::verify_FPU(stack_depth);
 }
 
+// Jump if ((*counter_addr += increment) & mask) satisfies the condition.
+void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
+                                                        int increment, int mask,
+                                                        Register scratch, bool preloaded,
+                                                        Condition cond, Label* where) {
+  if (!preloaded) {
+    movl(scratch, counter_addr);
+  }
+  incrementl(scratch, increment);
+  movl(counter_addr, scratch);
+  andl(scratch, mask);
+  jcc(cond, *where);
+}
 #endif /* CC_INTERP */
 
 
@@ -1430,17 +1443,3 @@
     NOT_CC_INTERP(pop(state));
   }
 }
-
-// Jump if ((*counter_addr += increment) & mask) satisfies the condition.
-void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
-                                                        int increment, int mask,
-                                                        Register scratch, bool preloaded,
-                                                        Condition cond, Label* where) {
-  if (!preloaded) {
-    movl(scratch, counter_addr);
-  }
-  incrementl(scratch, increment);
-  movl(counter_addr, scratch);
-  andl(scratch, mask);
-  jcc(cond, *where);
-}
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -77,7 +77,6 @@
   void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
   void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
   void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));
-  void get_method_counters(Register method, Register mcs, Label& skip);
 
   // load cpool->resolved_references(index);
   void load_resolved_reference_at_index(Register result, Register index);
@@ -156,6 +155,7 @@
                          bool install_monitor_exception = true,
                          bool notify_jvmdi = true);
 #endif /* !CC_INTERP */
+  void get_method_counters(Register method, Register mcs, Label& skip);
 
   // Debugging
   void verify_oop(Register reg, TosState state = atos);    // only if +VerifyOops && state == atos
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -271,20 +271,6 @@
   addptr(cache, tmp);  // construct pointer to cache entry
 }
 
-void InterpreterMacroAssembler::get_method_counters(Register method,
-                                                    Register mcs, Label& skip) {
-  Label has_counters;
-  movptr(mcs, Address(method, Method::method_counters_offset()));
-  testptr(mcs, mcs);
-  jcc(Assembler::notZero, has_counters);
-  call_VM(noreg, CAST_FROM_FN_PTR(address,
-          InterpreterRuntime::build_method_counters), method);
-  movptr(mcs, Address(method,Method::method_counters_offset()));
-  testptr(mcs, mcs);
-  jcc(Assembler::zero, skip); // No MethodCounters allocated, OutOfMemory
-  bind(has_counters);
-}
-
 // Load object from cpool->resolved_references(index)
 void InterpreterMacroAssembler::load_resolved_reference_at_index(
                                            Register result, Register index) {
@@ -676,6 +662,21 @@
 
 #endif // C_INTERP
 
+void InterpreterMacroAssembler::get_method_counters(Register method,
+                                                    Register mcs, Label& skip) {
+  Label has_counters;
+  movptr(mcs, Address(method, Method::method_counters_offset()));
+  testptr(mcs, mcs);
+  jcc(Assembler::notZero, has_counters);
+  call_VM(noreg, CAST_FROM_FN_PTR(address,
+          InterpreterRuntime::build_method_counters), method);
+  movptr(mcs, Address(method,Method::method_counters_offset()));
+  testptr(mcs, mcs);
+  jcc(Assembler::zero, skip); // No MethodCounters allocated, OutOfMemory
+  bind(has_counters);
+}
+
+
 // Lock object
 //
 // Args:
@@ -1423,6 +1424,20 @@
 
 void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) {
 }
+
+// Jump if ((*counter_addr += increment) & mask) satisfies the condition.
+void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
+                                                        int increment, int mask,
+                                                        Register scratch, bool preloaded,
+                                                        Condition cond, Label* where) {
+  if (!preloaded) {
+    movl(scratch, counter_addr);
+  }
+  incrementl(scratch, increment);
+  movl(counter_addr, scratch);
+  andl(scratch, mask);
+  jcc(cond, *where);
+}
 #endif // !CC_INTERP
 
 
@@ -1491,16 +1506,3 @@
   }
 }
 
-// Jump if ((*counter_addr += increment) & mask) satisfies the condition.
-void InterpreterMacroAssembler::increment_mask_and_jump(Address counter_addr,
-                                                        int increment, int mask,
-                                                        Register scratch, bool preloaded,
-                                                        Condition cond, Label* where) {
-  if (!preloaded) {
-    movl(scratch, counter_addr);
-  }
-  incrementl(scratch, increment);
-  movl(counter_addr, scratch);
-  andl(scratch, mask);
-  jcc(cond, *where);
-}
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -99,7 +99,6 @@
   void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2));
   void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2));
   void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2));
-  void get_method_counters(Register method, Register mcs, Label& skip);
 
   // load cpool->resolved_references(index);
   void load_resolved_reference_at_index(Register result, Register index);
@@ -172,6 +171,7 @@
                          bool install_monitor_exception = true,
                          bool notify_jvmdi = true);
 #endif // CC_INTERP
+  void get_method_counters(Register method, Register mcs, Label& skip);
 
   // Object locking
   void lock_object  (Register lock_reg);
--- a/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -229,10 +229,12 @@
 
   // abstract method entry
 
+#ifndef CC_INTERP
   //  pop return address, reset last_sp to NULL
   __ empty_expression_stack();
   __ restore_bcp();      // rsi must be correct for exception handler   (was destroyed)
   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
+#endif
 
   // throw exception
   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
--- a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -310,10 +310,12 @@
 
   // abstract method entry
 
+#ifndef CC_INTERP
   //  pop return address, reset last_sp to NULL
   __ empty_expression_stack();
   __ restore_bcp();      // rsi must be correct for exception handler   (was destroyed)
   __ restore_locals();   // make sure locals pointer is correct as well (was destroyed)
+#endif
 
   // throw exception
   __ call_VM(noreg, CAST_FROM_FN_PTR(address,
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -429,7 +429,7 @@
   }
 
   char buf[256];
-  jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+  jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
                cores_per_cpu(), threads_per_core(),
                cpu_family(), _model, _stepping,
                (supports_cmov() ? ", cmov" : ""),
@@ -455,7 +455,9 @@
                (supports_ht() ? ", ht": ""),
                (supports_tsc() ? ", tsc": ""),
                (supports_tscinv_bit() ? ", tscinvbit": ""),
-               (supports_tscinv() ? ", tscinv": ""));
+               (supports_tscinv() ? ", tscinv": ""),
+               (supports_bmi1() ? ", bmi1" : ""),
+               (supports_bmi2() ? ", bmi2" : ""));
   _features_str = strdup(buf);
 
   // UseSSE is set to the smaller of what hardware supports and what
@@ -600,13 +602,6 @@
       }
     }
 
-    // Use count leading zeros count instruction if available.
-    if (supports_lzcnt()) {
-      if (FLAG_IS_DEFAULT(UseCountLeadingZerosInstruction)) {
-        UseCountLeadingZerosInstruction = true;
-      }
-    }
-
     // some defaults for AMD family 15h
     if ( cpu_family() == 0x15 ) {
       // On family 15h processors default is no sw prefetch
@@ -692,6 +687,35 @@
     }
 #endif // COMPILER2
 
+  // Use count leading zeros count instruction if available.
+  if (supports_lzcnt()) {
+    if (FLAG_IS_DEFAULT(UseCountLeadingZerosInstruction)) {
+      UseCountLeadingZerosInstruction = true;
+    }
+   } else if (UseCountLeadingZerosInstruction) {
+    warning("lzcnt instruction is not available on this CPU");
+    FLAG_SET_DEFAULT(UseCountLeadingZerosInstruction, false);
+  }
+
+  if (supports_bmi1()) {
+    if (FLAG_IS_DEFAULT(UseBMI1Instructions)) {
+      UseBMI1Instructions = true;
+    }
+  } else if (UseBMI1Instructions) {
+    warning("BMI1 instructions are not available on this CPU");
+    FLAG_SET_DEFAULT(UseBMI1Instructions, false);
+  }
+
+  // Use count trailing zeros instruction if available
+  if (supports_bmi1()) {
+    if (FLAG_IS_DEFAULT(UseCountTrailingZerosInstruction)) {
+      UseCountTrailingZerosInstruction = UseBMI1Instructions;
+    }
+  } else if (UseCountTrailingZerosInstruction) {
+    warning("tzcnt instruction is not available on this CPU");
+    FLAG_SET_DEFAULT(UseCountTrailingZerosInstruction, false);
+  }
+
   // Use population count instruction if available.
   if (supports_popcnt()) {
     if (FLAG_IS_DEFAULT(UsePopCountInstruction)) {
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -141,7 +141,8 @@
     struct {
       uint32_t LahfSahf     : 1,
                CmpLegacy    : 1,
-                            : 4,
+                            : 3,
+               lzcnt_intel  : 1,
                lzcnt        : 1,
                sse4a        : 1,
                misalignsse  : 1,
@@ -251,7 +252,9 @@
     CPU_AVX2   = (1 << 18),
     CPU_AES    = (1 << 19),
     CPU_ERMS   = (1 << 20), // enhanced 'rep movsb/stosb' instructions
-    CPU_CLMUL  = (1 << 21) // carryless multiply for CRC
+    CPU_CLMUL  = (1 << 21), // carryless multiply for CRC
+    CPU_BMI1   = (1 << 22),
+    CPU_BMI2   = (1 << 23)
   } cpuFeatureFlags;
 
   enum {
@@ -423,6 +426,8 @@
       if (_cpuid_info.sef_cpuid7_ebx.bits.avx2 != 0)
         result |= CPU_AVX2;
     }
+    if(_cpuid_info.sef_cpuid7_ebx.bits.bmi1 != 0)
+      result |= CPU_BMI1;
     if (_cpuid_info.std_cpuid1_edx.bits.tsc != 0)
       result |= CPU_TSC;
     if (_cpuid_info.ext_cpuid7_edx.bits.tsc_invariance != 0)
@@ -444,6 +449,13 @@
       if (_cpuid_info.ext_cpuid1_ecx.bits.sse4a != 0)
         result |= CPU_SSE4A;
     }
+    // Intel features.
+    if(is_intel()) {
+      if(_cpuid_info.sef_cpuid7_ebx.bits.bmi2 != 0)
+        result |= CPU_BMI2;
+      if(_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0)
+        result |= CPU_LZCNT;
+    }
 
     return result;
   }
@@ -560,7 +572,8 @@
   static bool supports_aes()      { return (_cpuFeatures & CPU_AES) != 0; }
   static bool supports_erms()     { return (_cpuFeatures & CPU_ERMS) != 0; }
   static bool supports_clmul()    { return (_cpuFeatures & CPU_CLMUL) != 0; }
-
+  static bool supports_bmi1()     { return (_cpuFeatures & CPU_BMI1) != 0; }
+  static bool supports_bmi2()     { return (_cpuFeatures & CPU_BMI2) != 0; }
   // Intel features
   static bool is_intel_family_core() { return is_intel() &&
                                        extended_cpu_family() == CPU_FAMILY_INTEL_CORE; }
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Tue Mar 25 20:32:46 2014 -0400
@@ -5163,6 +5163,19 @@
 %}
 
 instruct countTrailingZerosI(rRegI dst, rRegI src, eFlagsReg cr) %{
+  predicate(UseCountTrailingZerosInstruction);
+  match(Set dst (CountTrailingZerosI src));
+  effect(KILL cr);
+
+  format %{ "TZCNT    $dst, $src\t# count trailing zeros (int)" %}
+  ins_encode %{
+    __ tzcntl($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, eFlagsReg cr) %{
+  predicate(!UseCountTrailingZerosInstruction);
   match(Set dst (CountTrailingZerosI src));
   effect(KILL cr);
 
@@ -5182,6 +5195,30 @@
 %}
 
 instruct countTrailingZerosL(rRegI dst, eRegL src, eFlagsReg cr) %{
+  predicate(UseCountTrailingZerosInstruction);
+  match(Set dst (CountTrailingZerosL src));
+  effect(TEMP dst, KILL cr);
+
+  format %{ "TZCNT  $dst, $src.lo\t# count trailing zeros (long) \n\t"
+            "JNC    done\n\t"
+            "TZCNT  $dst, $src.hi\n\t"
+            "ADD    $dst, 32\n"
+            "done:" %}
+  ins_encode %{
+    Register Rdst = $dst$$Register;
+    Register Rsrc = $src$$Register;
+    Label done;
+    __ tzcntl(Rdst, Rsrc);
+    __ jccb(Assembler::carryClear, done);
+    __ tzcntl(Rdst, HIGH_FROM_LOW(Rsrc));
+    __ addl(Rdst, BitsPerInt);
+    __ bind(done);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct countTrailingZerosL_bsf(rRegI dst, eRegL src, eFlagsReg cr) %{
+  predicate(!UseCountTrailingZerosInstruction);
   match(Set dst (CountTrailingZerosL src));
   effect(TEMP dst, KILL cr);
 
@@ -8027,6 +8064,123 @@
   ins_pipe( ialu_mem_imm );
 %}
 
+// BMI1 instructions
+instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, eFlagsReg cr) %{
+  match(Set dst (AndI (XorI src1 minus_1) src2));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  format %{ "ANDNL  $dst, $src1, $src2" %}
+
+  ins_encode %{
+    __ andnl($dst$$Register, $src1$$Register, $src2$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, eFlagsReg cr) %{
+  match(Set dst (AndI (XorI src1 minus_1) (LoadI src2) ));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  ins_cost(125);
+  format %{ "ANDNL  $dst, $src1, $src2" %}
+
+  ins_encode %{
+    __ andnl($dst$$Register, $src1$$Register, $src2$$Address);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, eFlagsReg cr) %{
+  match(Set dst (AndI (SubI imm_zero src) src));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  format %{ "BLSIL  $dst, $src" %}
+
+  ins_encode %{
+    __ blsil($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, eFlagsReg cr) %{
+  match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) ));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  ins_cost(125);
+  format %{ "BLSIL  $dst, $src" %}
+
+  ins_encode %{
+    __ blsil($dst$$Register, $src$$Address);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, eFlagsReg cr)
+%{
+  match(Set dst (XorI (AddI src minus_1) src));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  format %{ "BLSMSKL $dst, $src" %}
+
+  ins_encode %{
+    __ blsmskl($dst$$Register, $src$$Register);
+  %}
+
+  ins_pipe(ialu_reg);
+%}
+
+instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, eFlagsReg cr)
+%{
+  match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  ins_cost(125);
+  format %{ "BLSMSKL $dst, $src" %}
+
+  ins_encode %{
+    __ blsmskl($dst$$Register, $src$$Address);
+  %}
+
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, eFlagsReg cr)
+%{
+  match(Set dst (AndI (AddI src minus_1) src) );
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  format %{ "BLSRL  $dst, $src" %}
+
+  ins_encode %{
+    __ blsrl($dst$$Register, $src$$Register);
+  %}
+
+  ins_pipe(ialu_reg);
+%}
+
+instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, eFlagsReg cr)
+%{
+  match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  ins_cost(125);
+  format %{ "BLSRL  $dst, $src" %}
+
+  ins_encode %{
+    __ blsrl($dst$$Register, $src$$Address);
+  %}
+
+  ins_pipe(ialu_reg_mem);
+%}
+
 // Or Instructions
 // Or Register with Register
 instruct orI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
@@ -8649,6 +8803,210 @@
   ins_pipe( ialu_reg_long_mem );
 %}
 
+// BMI1 instructions
+instruct andnL_eReg_eReg_eReg(eRegL dst, eRegL src1, eRegL src2, immL_M1 minus_1, eFlagsReg cr) %{
+  match(Set dst (AndL (XorL src1 minus_1) src2));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr, TEMP dst);
+
+  format %{ "ANDNL  $dst.lo, $src1.lo, $src2.lo\n\t"
+            "ANDNL  $dst.hi, $src1.hi, $src2.hi"
+         %}
+
+  ins_encode %{
+    Register Rdst = $dst$$Register;
+    Register Rsrc1 = $src1$$Register;
+    Register Rsrc2 = $src2$$Register;
+    __ andnl(Rdst, Rsrc1, Rsrc2);
+    __ andnl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc1), HIGH_FROM_LOW(Rsrc2));
+  %}
+  ins_pipe(ialu_reg_reg_long);
+%}
+
+instruct andnL_eReg_eReg_mem(eRegL dst, eRegL src1, memory src2, immL_M1 minus_1, eFlagsReg cr) %{
+  match(Set dst (AndL (XorL src1 minus_1) (LoadL src2) ));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr, TEMP dst);
+
+  ins_cost(125);
+  format %{ "ANDNL  $dst.lo, $src1.lo, $src2\n\t"
+            "ANDNL  $dst.hi, $src1.hi, $src2+4"
+         %}
+
+  ins_encode %{
+    Register Rdst = $dst$$Register;
+    Register Rsrc1 = $src1$$Register;
+    Address src2_hi = Address::make_raw($src2$$base, $src2$$index, $src2$$scale, $src2$$disp + 4, relocInfo::none);
+
+    __ andnl(Rdst, Rsrc1, $src2$$Address);
+    __ andnl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc1), src2_hi);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsiL_eReg_eReg(eRegL dst, eRegL src, immL0 imm_zero, eFlagsReg cr) %{
+  match(Set dst (AndL (SubL imm_zero src) src));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr, TEMP dst);
+
+  format %{ "MOVL   $dst.hi, 0\n\t"
+            "BLSIL  $dst.lo, $src.lo\n\t"
+            "JNZ    done\n\t"
+            "BLSIL  $dst.hi, $src.hi\n"
+            "done:"
+         %}
+
+  ins_encode %{
+    Label done;
+    Register Rdst = $dst$$Register;
+    Register Rsrc = $src$$Register;
+    __ movl(HIGH_FROM_LOW(Rdst), 0);
+    __ blsil(Rdst, Rsrc);
+    __ jccb(Assembler::notZero, done);
+    __ blsil(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc));
+    __ bind(done);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct blsiL_eReg_mem(eRegL dst, memory src, immL0 imm_zero, eFlagsReg cr) %{
+  match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) ));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr, TEMP dst);
+
+  ins_cost(125);
+  format %{ "MOVL   $dst.hi, 0\n\t"
+            "BLSIL  $dst.lo, $src\n\t"
+            "JNZ    done\n\t"
+            "BLSIL  $dst.hi, $src+4\n"
+            "done:"
+         %}
+
+  ins_encode %{
+    Label done;
+    Register Rdst = $dst$$Register;
+    Address src_hi = Address::make_raw($src$$base, $src$$index, $src$$scale, $src$$disp + 4, relocInfo::none);
+
+    __ movl(HIGH_FROM_LOW(Rdst), 0);
+    __ blsil(Rdst, $src$$Address);
+    __ jccb(Assembler::notZero, done);
+    __ blsil(HIGH_FROM_LOW(Rdst), src_hi);
+    __ bind(done);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsmskL_eReg_eReg(eRegL dst, eRegL src, immL_M1 minus_1, eFlagsReg cr)
+%{
+  match(Set dst (XorL (AddL src minus_1) src));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr, TEMP dst);
+
+  format %{ "MOVL    $dst.hi, 0\n\t"
+            "BLSMSKL $dst.lo, $src.lo\n\t"
+            "JNC     done\n\t"
+            "BLSMSKL $dst.hi, $src.hi\n"
+            "done:"
+         %}
+
+  ins_encode %{
+    Label done;
+    Register Rdst = $dst$$Register;
+    Register Rsrc = $src$$Register;
+    __ movl(HIGH_FROM_LOW(Rdst), 0);
+    __ blsmskl(Rdst, Rsrc);
+    __ jccb(Assembler::carryClear, done);
+    __ blsmskl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc));
+    __ bind(done);
+  %}
+
+  ins_pipe(ialu_reg);
+%}
+
+instruct blsmskL_eReg_mem(eRegL dst, memory src, immL_M1 minus_1, eFlagsReg cr)
+%{
+  match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr, TEMP dst);
+
+  ins_cost(125);
+  format %{ "MOVL    $dst.hi, 0\n\t"
+            "BLSMSKL $dst.lo, $src\n\t"
+            "JNC     done\n\t"
+            "BLSMSKL $dst.hi, $src+4\n"
+            "done:"
+         %}
+
+  ins_encode %{
+    Label done;
+    Register Rdst = $dst$$Register;
+    Address src_hi = Address::make_raw($src$$base, $src$$index, $src$$scale, $src$$disp + 4, relocInfo::none);
+
+    __ movl(HIGH_FROM_LOW(Rdst), 0);
+    __ blsmskl(Rdst, $src$$Address);
+    __ jccb(Assembler::carryClear, done);
+    __ blsmskl(HIGH_FROM_LOW(Rdst), src_hi);
+    __ bind(done);
+  %}
+
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsrL_eReg_eReg(eRegL dst, eRegL src, immL_M1 minus_1, eFlagsReg cr)
+%{
+  match(Set dst (AndL (AddL src minus_1) src) );
+  predicate(UseBMI1Instructions);
+  effect(KILL cr, TEMP dst);
+
+  format %{ "MOVL   $dst.hi, $src.hi\n\t"
+            "BLSRL  $dst.lo, $src.lo\n\t"
+            "JNC    done\n\t"
+            "BLSRL  $dst.hi, $src.hi\n"
+            "done:"
+  %}
+
+  ins_encode %{
+    Label done;
+    Register Rdst = $dst$$Register;
+    Register Rsrc = $src$$Register;
+    __ movl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc));
+    __ blsrl(Rdst, Rsrc);
+    __ jccb(Assembler::carryClear, done);
+    __ blsrl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rsrc));
+    __ bind(done);
+  %}
+
+  ins_pipe(ialu_reg);
+%}
+
+instruct blsrL_eReg_mem(eRegL dst, memory src, immL_M1 minus_1, eFlagsReg cr)
+%{
+  match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src) ));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr, TEMP dst);
+
+  ins_cost(125);
+  format %{ "MOVL   $dst.hi, $src+4\n\t"
+            "BLSRL  $dst.lo, $src\n\t"
+            "JNC    done\n\t"
+            "BLSRL  $dst.hi, $src+4\n"
+            "done:"
+  %}
+
+  ins_encode %{
+    Label done;
+    Register Rdst = $dst$$Register;
+    Address src_hi = Address::make_raw($src$$base, $src$$index, $src$$scale, $src$$disp + 4, relocInfo::none);
+    __ movl(HIGH_FROM_LOW(Rdst), src_hi);
+    __ blsrl(Rdst, $src$$Address);
+    __ jccb(Assembler::carryClear, done);
+    __ blsrl(HIGH_FROM_LOW(Rdst), src_hi);
+    __ bind(done);
+  %}
+
+  ins_pipe(ialu_reg_mem);
+%}
+
 // Or Long Register with Register
 instruct orl_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{
   match(Set dst (OrL dst src));
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Tue Mar 25 20:32:46 2014 -0400
@@ -6022,6 +6022,19 @@
 %}
 
 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
+  predicate(UseCountTrailingZerosInstruction);
+  match(Set dst (CountTrailingZerosI src));
+  effect(KILL cr);
+
+  format %{ "tzcntl    $dst, $src\t# count trailing zeros (int)" %}
+  ins_encode %{
+    __ tzcntl($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{
+  predicate(!UseCountTrailingZerosInstruction);
   match(Set dst (CountTrailingZerosI src));
   effect(KILL cr);
 
@@ -6041,6 +6054,19 @@
 %}
 
 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
+  predicate(UseCountTrailingZerosInstruction);
+  match(Set dst (CountTrailingZerosL src));
+  effect(KILL cr);
+
+  format %{ "tzcntq    $dst, $src\t# count trailing zeros (long)" %}
+  ins_encode %{
+    __ tzcntq($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{
+  predicate(!UseCountTrailingZerosInstruction);
   match(Set dst (CountTrailingZerosL src));
   effect(KILL cr);
 
@@ -8622,6 +8648,122 @@
   ins_pipe(ialu_mem_imm);
 %}
 
+// BMI1 instructions
+instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{
+  match(Set dst (AndI (XorI src1 minus_1) (LoadI src2)));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  ins_cost(125);
+  format %{ "andnl  $dst, $src1, $src2" %}
+
+  ins_encode %{
+    __ andnl($dst$$Register, $src1$$Register, $src2$$Address);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{
+  match(Set dst (AndI (XorI src1 minus_1) src2));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  format %{ "andnl  $dst, $src1, $src2" %}
+
+  ins_encode %{
+    __ andnl($dst$$Register, $src1$$Register, $src2$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{
+  match(Set dst (AndI (SubI imm_zero src) src));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  format %{ "blsil  $dst, $src" %}
+
+  ins_encode %{
+    __ blsil($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{
+  match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) ));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  ins_cost(125);
+  format %{ "blsil  $dst, $src" %}
+
+  ins_encode %{
+    __ blsil($dst$$Register, $src$$Address);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr)
+%{
+  match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) );
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  ins_cost(125);
+  format %{ "blsmskl $dst, $src" %}
+
+  ins_encode %{
+    __ blsmskl($dst$$Register, $src$$Address);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr)
+%{
+  match(Set dst (XorI (AddI src minus_1) src));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  format %{ "blsmskl $dst, $src" %}
+
+  ins_encode %{
+    __ blsmskl($dst$$Register, $src$$Register);
+  %}
+
+  ins_pipe(ialu_reg);
+%}
+
+instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr)
+%{
+  match(Set dst (AndI (AddI src minus_1) src) );
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  format %{ "blsrl  $dst, $src" %}
+
+  ins_encode %{
+    __ blsrl($dst$$Register, $src$$Register);
+  %}
+
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr)
+%{
+  match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) );
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  ins_cost(125);
+  format %{ "blsrl  $dst, $src" %}
+
+  ins_encode %{
+    __ blsrl($dst$$Register, $src$$Address);
+  %}
+
+  ins_pipe(ialu_reg);
+%}
+
 // Or Instructions
 // Or Register with Register
 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
@@ -8853,6 +8995,122 @@
   ins_pipe(ialu_mem_imm);
 %}
 
+// BMI1 instructions
+instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{
+  match(Set dst (AndL (XorL src1 minus_1) (LoadL src2)));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  ins_cost(125);
+  format %{ "andnq  $dst, $src1, $src2" %}
+
+  ins_encode %{
+    __ andnq($dst$$Register, $src1$$Register, $src2$$Address);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{
+  match(Set dst (AndL (XorL src1 minus_1) src2));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  format %{ "andnq  $dst, $src1, $src2" %}
+
+  ins_encode %{
+  __ andnq($dst$$Register, $src1$$Register, $src2$$Register);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{
+  match(Set dst (AndL (SubL imm_zero src) src));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  format %{ "blsiq  $dst, $src" %}
+
+  ins_encode %{
+    __ blsiq($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{
+  match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) ));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  ins_cost(125);
+  format %{ "blsiq  $dst, $src" %}
+
+  ins_encode %{
+    __ blsiq($dst$$Register, $src$$Address);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr)
+%{
+  match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) );
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  ins_cost(125);
+  format %{ "blsmskq $dst, $src" %}
+
+  ins_encode %{
+    __ blsmskq($dst$$Register, $src$$Address);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr)
+%{
+  match(Set dst (XorL (AddL src minus_1) src));
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  format %{ "blsmskq $dst, $src" %}
+
+  ins_encode %{
+    __ blsmskq($dst$$Register, $src$$Register);
+  %}
+
+  ins_pipe(ialu_reg);
+%}
+
+instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr)
+%{
+  match(Set dst (AndL (AddL src minus_1) src) );
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  format %{ "blsrq  $dst, $src" %}
+
+  ins_encode %{
+    __ blsrq($dst$$Register, $src$$Register);
+  %}
+
+  ins_pipe(ialu_reg);
+%}
+
+instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr)
+%{
+  match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) );
+  predicate(UseBMI1Instructions);
+  effect(KILL cr);
+
+  ins_cost(125);
+  format %{ "blsrq  $dst, $src" %}
+
+  ins_encode %{
+    __ blsrq($dst$$Register, $src$$Address);
+  %}
+
+  ins_pipe(ialu_reg);
+%}
+
 // Or Instructions
 // Or Register with Register
 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
--- a/hotspot/src/os/aix/vm/os_aix.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/os/aix/vm/os_aix.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1135,15 +1135,10 @@
 }
 
 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
-  {
-    // gettimeofday - based on time in seconds since the Epoch thus does not wrap
-    info_ptr->max_value = ALL_64_BITS;
-
-    // gettimeofday is a real time clock so it skips
-    info_ptr->may_skip_backward = true;
-    info_ptr->may_skip_forward = true;
-  }
-
+  info_ptr->max_value = ALL_64_BITS;
+  // mread_real_time() is monotonic (see 'os::javaTimeNanos()')
+  info_ptr->may_skip_backward = false;
+  info_ptr->may_skip_forward = false;
   info_ptr->kind = JVMTI_TIMER_ELAPSED;    // elapsed not CPU time
 }
 
@@ -2799,105 +2794,6 @@
   return ::read(fd, buf, nBytes);
 }
 
-#define NANOSECS_PER_MILLISEC 1000000
-
-int os::sleep(Thread* thread, jlong millis, bool interruptible) {
-  assert(thread == Thread::current(), "thread consistency check");
-
-  // Prevent nasty overflow in deadline calculation
-  // by handling long sleeps similar to solaris or windows.
-  const jlong limit = INT_MAX;
-  int result;
-  while (millis > limit) {
-    if ((result = os::sleep(thread, limit, interruptible)) != OS_OK) {
-      return result;
-    }
-    millis -= limit;
-  }
-
-  ParkEvent * const slp = thread->_SleepEvent;
-  slp->reset();
-  OrderAccess::fence();
-
-  if (interruptible) {
-    jlong prevtime = javaTimeNanos();
-
-    // Prevent precision loss and too long sleeps
-    jlong deadline = prevtime + millis * NANOSECS_PER_MILLISEC;
-
-    for (;;) {
-      if (os::is_interrupted(thread, true)) {
-        return OS_INTRPT;
-      }
-
-      jlong newtime = javaTimeNanos();
-
-      assert(newtime >= prevtime, "time moving backwards");
-      // Doing prevtime and newtime in microseconds doesn't help precision,
-      // and trying to round up to avoid lost milliseconds can result in a
-      // too-short delay.
-      millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
-
-      if (millis <= 0) {
-        return OS_OK;
-      }
-
-      // Stop sleeping if we passed the deadline
-      if (newtime >= deadline) {
-        return OS_OK;
-      }
-
-      prevtime = newtime;
-
-      {
-        assert(thread->is_Java_thread(), "sanity check");
-        JavaThread *jt = (JavaThread *) thread;
-        ThreadBlockInVM tbivm(jt);
-        OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
-
-        jt->set_suspend_equivalent();
-
-        slp->park(millis);
-
-        // were we externally suspended while we were waiting?
-        jt->check_and_wait_while_suspended();
-      }
-    }
-  } else {
-    OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
-    jlong prevtime = javaTimeNanos();
-
-    // Prevent precision loss and too long sleeps
-    jlong deadline = prevtime + millis * NANOSECS_PER_MILLISEC;
-
-    for (;;) {
-      // It'd be nice to avoid the back-to-back javaTimeNanos() calls on
-      // the 1st iteration ...
-      jlong newtime = javaTimeNanos();
-
-      if (newtime - prevtime < 0) {
-        // time moving backwards, should only happen if no monotonic clock
-        // not a guarantee() because JVM should not abort on kernel/glibc bugs
-        // - HS14 Commented out as not implemented.
-        // - TODO Maybe we should implement it?
-        //assert(!Aix::supports_monotonic_clock(), "time moving backwards");
-      } else {
-        millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
-      }
-
-      if (millis <= 0) break;
-
-      if (newtime >= deadline) {
-        break;
-      }
-
-      prevtime = newtime;
-      slp->park(millis);
-    }
-    return OS_OK;
-  }
-}
-
 void os::naked_short_sleep(jlong ms) {
   struct timespec req;
 
@@ -3246,50 +3142,6 @@
   guarantee(osthread->sr.is_running(), "Must be running!");
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// interrupt support
-
-void os::interrupt(Thread* thread) {
-  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
-    "possibility of dangling Thread pointer");
-
-  OSThread* osthread = thread->osthread();
-
-  if (!osthread->interrupted()) {
-    osthread->set_interrupted(true);
-    // More than one thread can get here with the same value of osthread,
-    // resulting in multiple notifications.  We do, however, want the store
-    // to interrupted() to be visible to other threads before we execute unpark().
-    OrderAccess::fence();
-    ParkEvent * const slp = thread->_SleepEvent;
-    if (slp != NULL) slp->unpark();
-  }
-
-  // For JSR166. Unpark even if interrupt status already was set
-  if (thread->is_Java_thread())
-    ((JavaThread*)thread)->parker()->unpark();
-
-  ParkEvent * ev = thread->_ParkEvent;
-  if (ev != NULL) ev->unpark();
-
-}
-
-bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
-  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
-    "possibility of dangling Thread pointer");
-
-  OSThread* osthread = thread->osthread();
-
-  bool interrupted = osthread->interrupted();
-
-  if (interrupted && clear_interrupted) {
-    osthread->set_interrupted(false);
-    // consider thread->_SleepEvent->reset() ... optional optimization
-  }
-
-  return interrupted;
-}
-
 ///////////////////////////////////////////////////////////////////////////////////
 // signal handling (except suspend/resume)
 
--- a/hotspot/src/os/aix/vm/os_aix.inline.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/os/aix/vm/os_aix.inline.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -283,4 +283,10 @@
                             const char* optval, socklen_t optlen) {
   return ::setsockopt(fd, level, optname, optval, optlen);
 }
+
+inline bool os::supports_monotonic_clock() {
+  // mread_real_time() is monotonic on AIX (see os::javaTimeNanos() comments)
+  return true;
+}
+
 #endif // OS_AIX_VM_OS_AIX_INLINE_HPP
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -5284,7 +5284,6 @@
 
 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
   static bool proc_task_unchecked = true;
-  static const char *proc_stat_path = "/proc/%d/stat";
   pid_t  tid = thread->osthread()->thread_id();
   char *s;
   char stat[2048];
@@ -5297,6 +5296,8 @@
   long ldummy;
   FILE *fp;
 
+  snprintf(proc_name, 64, "/proc/%d/stat", tid);
+
   // The /proc/<tid>/stat aggregates per-process usage on
   // new Linux kernels 2.6+ where NPTL is supported.
   // The /proc/self/task/<tid>/stat still has the per-thread usage.
@@ -5308,12 +5309,11 @@
     proc_task_unchecked = false;
     fp = fopen("/proc/self/task", "r");
     if (fp != NULL) {
-      proc_stat_path = "/proc/self/task/%d/stat";
+      snprintf(proc_name, 64, "/proc/self/task/%d/stat", tid);
       fclose(fp);
     }
   }
 
-  sprintf(proc_name, proc_stat_path, tid);
   fp = fopen(proc_name, "r");
   if ( fp == NULL ) return -1;
   statlen = fread(stat, 1, 2047, fp);
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -3619,13 +3619,14 @@
          "possibility of dangling Thread pointer");
 
   OSThread* osthread = thread->osthread();
-  bool interrupted = osthread->interrupted();
   // There is no synchronization between the setting of the interrupt
   // and it being cleared here. It is critical - see 6535709 - that
   // we only clear the interrupt state, and reset the interrupt event,
   // if we are going to report that we were indeed interrupted - else
   // an interrupt can be "lost", leading to spurious wakeups or lost wakeups
-  // depending on the timing
+  // depending on the timing. By checking thread interrupt event to see
+  // if the thread gets real interrupt thus prevent spurious wakeup.
+  bool interrupted = osthread->interrupted() && (WaitForSingleObject(osthread->interrupt_event(), 0) == WAIT_OBJECT_0);
   if (interrupted && clear_interrupted) {
     osthread->set_interrupted(false);
     ResetEvent(osthread->interrupt_event());
--- a/hotspot/src/share/vm/adlc/formssel.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/adlc/formssel.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -660,6 +660,7 @@
   int USE_of_memory  = 0;
   int DEF_of_memory  = 0;
   const char*    last_memory_DEF = NULL; // to test DEF/USE pairing in asserts
+  const char*    last_memory_USE = NULL;
   Component     *unique          = NULL;
   Component     *comp            = NULL;
   ComponentList &components      = (ComponentList &)_components;
@@ -681,7 +682,16 @@
           assert(0 == strcmp(last_memory_DEF, comp->_name), "every memory DEF is followed by a USE of the same name");
           last_memory_DEF = NULL;
         }
-        USE_of_memory++;
+        // Handles same memory being used multiple times in the case of BMI1 instructions.
+        if (last_memory_USE != NULL) {
+          if (strcmp(comp->_name, last_memory_USE) != 0) {
+            USE_of_memory++;
+          }
+        } else {
+          USE_of_memory++;
+        }
+        last_memory_USE = comp->_name;
+
         if (DEF_of_memory == 0)  // defs take precedence
           unique = comp;
       } else {
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1436,7 +1436,7 @@
 
   bool need_mem_bar = false;
   if (method()->name() == ciSymbol::object_initializer_name() &&
-      scope()->wrote_final()) {
+      (scope()->wrote_final() || (AlwaysSafeConstructors && scope()->wrote_fields()))) {
     need_mem_bar = true;
   }
 
@@ -1550,6 +1550,10 @@
     scope()->set_wrote_final();
   }
 
+  if (code == Bytecodes::_putfield) {
+    scope()->set_wrote_fields();
+  }
+
   const int offset = !needs_patching ? field->offset() : -1;
   switch (code) {
     case Bytecodes::_getstatic: {
@@ -3767,11 +3771,14 @@
   }
 
   // now perform tests that are based on flag settings
-  if (callee->force_inline()) {
-    if (inline_level() > MaxForceInlineLevel) INLINE_BAILOUT("MaxForceInlineLevel");
-    print_inlining(callee, "force inline by annotation");
-  } else if (callee->should_inline()) {
-    print_inlining(callee, "force inline by CompileOracle");
+  if (callee->force_inline() || callee->should_inline()) {
+    if (inline_level() > MaxForceInlineLevel                    ) INLINE_BAILOUT("MaxForceInlineLevel");
+    if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("recursive inlining too deep");
+
+    const char* msg = "";
+    if (callee->force_inline())  msg = "force inline by annotation";
+    if (callee->should_inline()) msg = "force inline by CompileOracle";
+    print_inlining(callee, msg);
   } else {
     // use heuristic controls on inlining
     if (inline_level() > MaxInlineLevel                         ) INLINE_BAILOUT("inlining too deep");
--- a/hotspot/src/share/vm/c1/c1_IR.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/c1/c1_IR.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -142,6 +142,7 @@
   _number_of_locks    = 0;
   _monitor_pairing_ok = method->has_balanced_monitors();
   _wrote_final        = false;
+  _wrote_fields       = false;
   _start              = NULL;
 
   if (osr_bci == -1) {
--- a/hotspot/src/share/vm/c1/c1_IR.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/c1/c1_IR.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -150,6 +150,7 @@
   int           _number_of_locks;                // the number of monitor lock slots needed
   bool          _monitor_pairing_ok;             // the monitor pairing info
   bool          _wrote_final;                    // has written final field
+  bool          _wrote_fields;                   // has written fields
   BlockBegin*   _start;                          // the start block, successsors are method entries
 
   BitMap        _requires_phi_function;          // bit is set if phi functions at loop headers are necessary for a local variable
@@ -184,6 +185,9 @@
   BlockBegin*   start() const                    { return _start; }
   void          set_wrote_final()                { _wrote_final = true; }
   bool          wrote_final    () const          { return _wrote_final; }
+  void          set_wrote_fields()               { _wrote_fields = true; }
+  bool          wrote_fields    () const         { return _wrote_fields; }
+
 };
 
 
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1734,7 +1734,8 @@
                 (info ? new CodeEmitInfo(info) : NULL));
   }
 
-  if (is_volatile && !needs_patching) {
+  bool needs_atomic_access = is_volatile || AlwaysAtomicAccesses;
+  if (needs_atomic_access && !needs_patching) {
     volatile_field_store(value.result(), address, info);
   } else {
     LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
@@ -1807,7 +1808,8 @@
     address = generate_address(object.result(), x->offset(), field_type);
   }
 
-  if (is_volatile && !needs_patching) {
+  bool needs_atomic_access = is_volatile || AlwaysAtomicAccesses;
+  if (needs_atomic_access && !needs_patching) {
     volatile_field_load(address, reg, info);
   } else {
     LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -809,11 +809,10 @@
   int bci = vfst.bci();
   Bytecodes::Code code = caller_method()->java_code_at(bci);
 
-#ifndef PRODUCT
   // this is used by assertions in the access_field_patching_id
   BasicType patch_field_type = T_ILLEGAL;
-#endif // PRODUCT
   bool deoptimize_for_volatile = false;
+  bool deoptimize_for_atomic = false;
   int patch_field_offset = -1;
   KlassHandle init_klass(THREAD, NULL); // klass needed by load_klass_patching code
   KlassHandle load_klass(THREAD, NULL); // klass needed by load_klass_patching code
@@ -839,11 +838,24 @@
     // is the path for patching field offsets.  load_klass is only
     // used for patching references to oops which don't need special
     // handling in the volatile case.
+
     deoptimize_for_volatile = result.access_flags().is_volatile();
 
-#ifndef PRODUCT
+    // If we are patching a field which should be atomic, then
+    // the generated code is not correct either, force deoptimizing.
+    // We need to only cover T_LONG and T_DOUBLE fields, as we can
+    // break access atomicity only for them.
+
+    // Strictly speaking, the deoptimizaation on 64-bit platforms
+    // is unnecessary, and T_LONG stores on 32-bit platforms need
+    // to be handled by special patching code when AlwaysAtomicAccesses
+    // becomes product feature. At this point, we are still going
+    // for the deoptimization for consistency against volatile
+    // accesses.
+
     patch_field_type = result.field_type();
-#endif
+    deoptimize_for_atomic = (AlwaysAtomicAccesses && (patch_field_type == T_DOUBLE || patch_field_type == T_LONG));
+
   } else if (load_klass_or_mirror_patch_id) {
     Klass* k = NULL;
     switch (code) {
@@ -918,13 +930,19 @@
     ShouldNotReachHere();
   }
 
-  if (deoptimize_for_volatile) {
-    // At compile time we assumed the field wasn't volatile but after
-    // loading it turns out it was volatile so we have to throw the
+  if (deoptimize_for_volatile || deoptimize_for_atomic) {
+    // At compile time we assumed the field wasn't volatile/atomic but after
+    // loading it turns out it was volatile/atomic so we have to throw the
     // compiled code out and let it be regenerated.
     if (TracePatching) {
-      tty->print_cr("Deoptimizing for patching volatile field reference");
+      if (deoptimize_for_volatile) {
+        tty->print_cr("Deoptimizing for patching volatile field reference");
+      }
+      if (deoptimize_for_atomic) {
+        tty->print_cr("Deoptimizing for patching atomic field reference");
+      }
     }
+
     // It's possible the nmethod was invalidated in the last
     // safepoint, but if it's still alive then make it not_entrant.
     nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -724,6 +724,11 @@
 
   VM_ENTRY_MARK;
 
+  // Disable CHA for default methods for now
+  if (root_m->get_Method()->is_default_method()) {
+    return NULL;
+  }
+
   methodHandle target;
   {
     MutexLocker locker(Compile_lock);
--- a/hotspot/src/share/vm/ci/ciMethodData.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/ci/ciMethodData.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -87,8 +87,9 @@
   DataLayout* dp_dst  = extra_data_base();
   for (;; dp_src = MethodData::next_extra(dp_src), dp_dst = MethodData::next_extra(dp_dst)) {
     assert(dp_src < end_src, "moved past end of extra data");
-    assert(dp_src->tag() == dp_dst->tag(), err_msg("should be same tags %d != %d", dp_src->tag(), dp_dst->tag()));
-    switch(dp_src->tag()) {
+    // New traps in the MDO can be added as we translate the copy so
+    // look at the entries in the copy.
+    switch(dp_dst->tag()) {
     case DataLayout::speculative_trap_data_tag: {
       ciSpeculativeTrapData* data_dst = new ciSpeculativeTrapData(dp_dst);
       SpeculativeTrapData* data_src = new SpeculativeTrapData(dp_src);
@@ -102,7 +103,7 @@
       // An empty slot or ArgInfoData entry marks the end of the trap data
       return;
     default:
-      fatal(err_msg("bad tag = %d", dp_src->tag()));
+      fatal(err_msg("bad tag = %d", dp_dst->tag()));
     }
   }
 }
--- a/hotspot/src/share/vm/code/codeCache.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -198,14 +198,12 @@
   }
   maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() -
                           (address)_heap->low_boundary()) - unallocated_capacity());
-  verify_if_often();
   print_trace("allocation", cb, size);
   return cb;
 }
 
 void CodeCache::free(CodeBlob* cb) {
   assert_locked_or_safepoint(CodeCache_lock);
-  verify_if_often();
 
   print_trace("free", cb);
   if (cb->is_nmethod()) {
@@ -221,7 +219,6 @@
 
   _heap->deallocate(cb);
 
-  verify_if_often();
   assert(_number_of_blobs >= 0, "sanity check");
 }
 
@@ -244,12 +241,6 @@
 }
 
 
-void CodeCache::flush() {
-  assert_locked_or_safepoint(CodeCache_lock);
-  Unimplemented();
-}
-
-
 // Iteration over CodeBlobs
 
 #define FOR_ALL_BLOBS(var)       for (CodeBlob *var =       first() ; var != NULL; var =       next(var) )
@@ -269,7 +260,7 @@
 CodeBlob* CodeCache::find_blob(void* start) {
   CodeBlob* result = find_blob_unsafe(start);
   if (result == NULL) return NULL;
-  // We could potientially look up non_entrant methods
+  // We could potentially look up non_entrant methods
   guarantee(!result->is_zombie() || result->is_locked_by_vm() || is_error_reported(), "unsafe access to zombie method");
   return result;
 }
@@ -741,17 +732,26 @@
   }
 }
 
+void CodeCache::print_memory_overhead() {
+  size_t wasted_bytes = 0;
+  CodeBlob *cb;
+  for (cb = first(); cb != NULL; cb = next(cb)) {
+    HeapBlock* heap_block = ((HeapBlock*)cb) - 1;
+    wasted_bytes += heap_block->length() * CodeCacheSegmentSize - cb->size();
+  }
+  // Print bytes that are allocated in the freelist
+  ttyLocker ttl;
+  tty->print_cr("Number of elements in freelist: %d",    freelist_length());
+  tty->print_cr("Allocated in freelist:          %dkB",  bytes_allocated_in_freelist()/K);
+  tty->print_cr("Unused bytes in CodeBlobs:      %dkB",  (int)(wasted_bytes/K));
+  tty->print_cr("Segment map size:               %dkB",  allocated_segments()/K); // 1 byte per segment
+}
+
 //------------------------------------------------------------------------------------------------
 // Non-product version
 
 #ifndef PRODUCT
 
-void CodeCache::verify_if_often() {
-  if (VerifyCodeCacheOften) {
-    _heap->verify();
-  }
-}
-
 void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) {
   if (PrintCodeCache2) {  // Need to add a new flag
     ResourceMark rm;
@@ -774,7 +774,7 @@
   int nmethodUnloaded = 0;
   int nmethodJava = 0;
   int nmethodNative = 0;
-  int maxCodeSize = 0;
+  int max_nm_size = 0;
   ResourceMark rm;
 
   CodeBlob *cb;
@@ -798,13 +798,11 @@
       if(nm->is_not_entrant()) { nmethodNotEntrant++; }
       if(nm->is_zombie()) { nmethodZombie++; }
       if(nm->is_unloaded()) { nmethodUnloaded++; }
-      if(nm->is_native_method()) { nmethodNative++; }
+      if(nm->method() != NULL && nm->is_native_method()) { nmethodNative++; }
 
       if(nm->method() != NULL && nm->is_java_method()) {
         nmethodJava++;
-        if (nm->insts_size() > maxCodeSize) {
-          maxCodeSize = nm->insts_size();
-        }
+        max_nm_size = MAX2(max_nm_size, nm->size());
       }
     } else if (cb->is_runtime_stub()) {
       runtimeStubCount++;
@@ -820,18 +818,19 @@
   }
 
   int bucketSize = 512;
-  int bucketLimit = maxCodeSize / bucketSize + 1;
+  int bucketLimit = max_nm_size / bucketSize + 1;
   int *buckets = NEW_C_HEAP_ARRAY(int, bucketLimit, mtCode);
-  memset(buckets,0,sizeof(int) * bucketLimit);
+  memset(buckets, 0, sizeof(int) * bucketLimit);
 
   for (cb = first(); cb != NULL; cb = next(cb)) {
     if (cb->is_nmethod()) {
       nmethod* nm = (nmethod*)cb;
       if(nm->is_java_method()) {
-        buckets[nm->insts_size() / bucketSize]++;
-      }
+        buckets[nm->size() / bucketSize]++;
+       }
     }
   }
+
   tty->print_cr("Code Cache Entries (total of %d)",total);
   tty->print_cr("-------------------------------------------------");
   tty->print_cr("nmethods: %d",nmethodCount);
@@ -858,6 +857,7 @@
   }
 
   FREE_C_HEAP_ARRAY(int, buckets, mtCode);
+  print_memory_overhead();
 }
 
 #endif // !PRODUCT
--- a/hotspot/src/share/vm/code/codeCache.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/code/codeCache.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -58,12 +58,13 @@
   static bool _needs_cache_clean;
   static nmethod* _scavenge_root_nmethods;  // linked via nm->scavenge_root_link()
 
-  static void verify_if_often() PRODUCT_RETURN;
-
   static void mark_scavenge_root_nmethods() PRODUCT_RETURN;
   static void verify_perm_nmethods(CodeBlobClosure* f_or_null) PRODUCT_RETURN;
 
   static int _codemem_full_count;
+  static size_t bytes_allocated_in_freelist() { return _heap->allocated_in_freelist(); }
+  static int    allocated_segments()          { return _heap->allocated_segments(); }
+  static size_t freelist_length()             { return _heap->freelist_length(); }
 
  public:
 
@@ -78,7 +79,6 @@
   static int alignment_unit();                      // guaranteed alignment of all CodeBlobs
   static int alignment_offset();                    // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header)
   static void free(CodeBlob* cb);                   // frees a CodeBlob
-  static void flush();                              // flushes all CodeBlobs
   static bool contains(void *p);                    // returns whether p is included
   static void blobs_do(void f(CodeBlob* cb));       // iterates over all CodeBlobs
   static void blobs_do(CodeBlobClosure* f);         // iterates over all CodeBlobs
@@ -150,6 +150,7 @@
   // Printing/debugging
   static void print();                           // prints summary
   static void print_internals();
+  static void print_memory_overhead();
   static void verify();                          // verifies the code cache
   static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;
   static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage
--- a/hotspot/src/share/vm/code/debugInfo.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/code/debugInfo.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -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
@@ -273,8 +273,8 @@
   }
   Method* read_method() {
     Method* o = (Method*)(code()->metadata_at(read_int()));
-    assert(o == NULL ||
-           o->is_metaspace_object(), "meta data only");
+    // is_metadata() is a faster check than is_metaspace_object()
+    assert(o == NULL || o->is_metadata(), "meta data only");
     return o;
   }
   ScopeValue* read_object_value();
--- a/hotspot/src/share/vm/code/dependencies.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/code/dependencies.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -725,13 +725,13 @@
 }
 
 // ----------------- DependencySignature --------------------------------------
-bool DependencySignature::equals(DependencySignature* sig) const {
-  if ((type() != sig->type()) || (args_count() != sig->args_count())) {
+bool DependencySignature::equals(DependencySignature const& s1, DependencySignature const& s2) {
+  if ((s1.type() != s2.type()) || (s1.args_count() != s2.args_count())) {
     return false;
   }
 
-  for (int i = 0; i < sig->args_count(); i++) {
-    if (arg(i) != sig->arg(i)) {
+  for (int i = 0; i < s1.args_count(); i++) {
+    if (s1.arg(i) != s2.arg(i)) {
       return false;
     }
   }
--- a/hotspot/src/share/vm/code/dependencies.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/code/dependencies.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -527,7 +527,7 @@
 };
 
 
-class DependencySignature : public GenericHashtableEntry<DependencySignature, ResourceObj> {
+class DependencySignature : public ResourceObj {
  private:
   int                   _args_count;
   uintptr_t             _argument_hash[Dependencies::max_arg_count];
@@ -542,12 +542,13 @@
     }
   }
 
-  bool equals(DependencySignature* sig) const;
-  uintptr_t key() const { return _argument_hash[0] >> 2; }
+  static bool     equals(DependencySignature const& s1, DependencySignature const& s2);
+  static unsigned hash  (DependencySignature const& s1) { return s1.arg(0) >> 2; }
 
   int args_count()             const { return _args_count; }
   uintptr_t arg(int idx)       const { return _argument_hash[idx]; }
   Dependencies::DepType type() const { return _type; }
+
 };
 
 
--- a/hotspot/src/share/vm/code/nmethod.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -39,6 +39,7 @@
 #include "prims/jvmtiImpl.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/sweeper.hpp"
+#include "utilities/resourceHash.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/events.hpp"
 #include "utilities/xmlstream.hpp"
@@ -2135,7 +2136,11 @@
   // Turn off dependency tracing while actually testing dependencies.
   NOT_PRODUCT( FlagSetting fs(TraceDependencies, false) );
 
- GenericHashtable<DependencySignature, ResourceObj>* table = new GenericHashtable<DependencySignature, ResourceObj>(11027);
+ typedef ResourceHashtable<DependencySignature, int, &DependencySignature::hash,
+                           &DependencySignature::equals, 11027> DepTable;
+
+ DepTable* table = new DepTable();
+
   // Iterate over live nmethods and check dependencies of all nmethods that are not
   // marked for deoptimization. A particular dependency is only checked once.
   for(nmethod* nm = CodeCache::alive_nmethod(CodeCache::first()); nm != NULL; nm = CodeCache::alive_nmethod(CodeCache::next(nm))) {
@@ -2143,9 +2148,10 @@
       for (Dependencies::DepStream deps(nm); deps.next(); ) {
         // Construct abstraction of a dependency.
         DependencySignature* current_sig = new DependencySignature(deps);
-        // Determine if 'deps' is already checked. table->add() returns
-        // 'true' if the dependency was added (i.e., was not in the hashtable).
-        if (table->add(current_sig)) {
+
+        // Determine if dependency is already checked. table->put(...) returns
+        // 'true' if the dependency is added (i.e., was not in the hashtable).
+        if (table->put(*current_sig, 1)) {
           if (deps.check_dependency() != NULL) {
             // Dependency checking failed. Print out information about the failed
             // dependency and finally fail with an assert. We can fail here, since
--- a/hotspot/src/share/vm/compiler/compilerOracle.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -374,25 +374,8 @@
         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
 
 #define RANGE0 "[*" RANGEBASE "]"
-#define RANGEDOT "[*" RANGEBASE ".]"
 #define RANGESLASH "[*" RANGEBASE "/]"
 
-
-// Accept several syntaxes for these patterns
-//  original syntax
-//   cmd  java.lang.String foo
-//  PrintCompilation syntax
-//   cmd  java.lang.String::foo
-//  VM syntax
-//   cmd  java/lang/String[. ]foo
-//
-
-static const char* patterns[] = {
-  "%*[ \t]%255" RANGEDOT    " "     "%255"  RANGE0 "%n",
-  "%*[ \t]%255" RANGEDOT   "::"     "%255"  RANGE0 "%n",
-  "%*[ \t]%255" RANGESLASH "%*[ .]" "%255"  RANGE0 "%n",
-};
-
 static MethodMatcher::Mode check_mode(char name[], const char*& error_msg) {
   int match = MethodMatcher::Exact;
   while (name[0] == '*') {
@@ -421,12 +404,10 @@
                       int* bytes_read, const char*& error_msg) {
   *bytes_read = 0;
   error_msg = NULL;
-  for (uint i = 0; i < ARRAY_SIZE(patterns); i++) {
-    if (2 == sscanf(line, patterns[i], class_name, method_name, bytes_read)) {
-      *c_mode = check_mode(class_name, error_msg);
-      *m_mode = check_mode(method_name, error_msg);
-      return *c_mode != MethodMatcher::Unknown && *m_mode != MethodMatcher::Unknown;
-    }
+  if (2 == sscanf(line, "%*[ \t]%255" RANGESLASH "%*[ ]" "%255"  RANGE0 "%n", class_name, method_name, bytes_read)) {
+    *c_mode = check_mode(class_name, error_msg);
+    *m_mode = check_mode(method_name, error_msg);
+    return *c_mode != MethodMatcher::Unknown && *m_mode != MethodMatcher::Unknown;
   }
   return false;
 }
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -280,6 +280,16 @@
       if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
           ((gc_cause != GCCause::_java_lang_system_gc) ||
             UseAdaptiveSizePolicyWithSystemGC)) {
+        // Swap the survivor spaces if from_space is empty. The
+        // resize_young_gen() called below is normally used after
+        // a successful young GC and swapping of survivor spaces;
+        // otherwise, it will fail to resize the young gen with
+        // the current implementation.
+        if (young_gen->from_space()->is_empty()) {
+          young_gen->from_space()->clear(SpaceDecorator::Mangle);
+          young_gen->swap_spaces();
+        }
+
         // Calculate optimal free space amounts
         assert(young_gen->max_size() >
           young_gen->from_space()->capacity_in_bytes() +
@@ -318,12 +328,8 @@
 
         heap->resize_old_gen(size_policy->calculated_old_free_size_in_bytes());
 
-        // Don't resize the young generation at an major collection.  A
-        // desired young generation size may have been calculated but
-        // resizing the young generation complicates the code because the
-        // resizing of the old generation may have moved the boundary
-        // between the young generation and the old generation.  Let the
-        // young generation resizing happen at the minor collections.
+        heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(),
+                               size_policy->calculated_survivor_size_in_bytes());
       }
       if (PrintAdaptiveSizePolicy) {
         gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -43,6 +43,7 @@
 #include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/gcTraceTime.hpp"
 #include "gc_implementation/shared/isGCActiveMark.hpp"
+#include "gc_implementation/shared/spaceDecorator.hpp"
 #include "gc_interface/gcCause.hpp"
 #include "memory/gcLocker.inline.hpp"
 #include "memory/referencePolicy.hpp"
@@ -2115,6 +2116,16 @@
       if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
           ((gc_cause != GCCause::_java_lang_system_gc) ||
             UseAdaptiveSizePolicyWithSystemGC)) {
+        // Swap the survivor spaces if from_space is empty. The
+        // resize_young_gen() called below is normally used after
+        // a successful young GC and swapping of survivor spaces;
+        // otherwise, it will fail to resize the young gen with
+        // the current implementation.
+        if (young_gen->from_space()->is_empty()) {
+          young_gen->from_space()->clear(SpaceDecorator::Mangle);
+          young_gen->swap_spaces();
+        }
+
         // Calculate optimal free space amounts
         assert(young_gen->max_size() >
           young_gen->from_space()->capacity_in_bytes() +
@@ -2154,12 +2165,8 @@
         heap->resize_old_gen(
           size_policy->calculated_old_free_size_in_bytes());
 
-        // Don't resize the young generation at an major collection.  A
-        // desired young generation size may have been calculated but
-        // resizing the young generation complicates the code because the
-        // resizing of the old generation may have moved the boundary
-        // between the young generation and the old generation.  Let the
-        // young generation resizing happen at the minor collections.
+        heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(),
+                               size_policy->calculated_survivor_size_in_bytes());
       }
       if (PrintAdaptiveSizePolicy) {
         gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -3475,7 +3475,7 @@
   tty->print_cr("&native_fresult: " INTPTR_FORMAT, (uintptr_t) &this->_native_fresult);
   tty->print_cr("native_lresult: " INTPTR_FORMAT, (uintptr_t) this->_native_lresult);
 #endif
-#if !defined(ZERO)
+#if !defined(ZERO) && defined(PPC)
   tty->print_cr("last_Java_fp: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_fp);
 #endif // !ZERO
   tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link);
--- a/hotspot/src/share/vm/interpreter/templateTable.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/interpreter/templateTable.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -376,6 +376,9 @@
 #ifdef TARGET_ARCH_MODEL_ppc_32
 # include "templateTable_ppc_32.hpp"
 #endif
+#ifdef TARGET_ARCH_MODEL_ppc_64
+# include "templateTable_ppc_64.hpp"
+#endif
 
 };
 #endif /* !CC_INTERP */
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -304,10 +304,13 @@
   }
 
   // Now take the actual NewSize into account. We will silently increase NewSize
-  // if the user specified a smaller value.
+  // if the user specified a smaller or unaligned value.
   smallest_new_size = MAX2(smallest_new_size, (uintx)align_size_down(NewSize, _gen_alignment));
   if (smallest_new_size != NewSize) {
-    FLAG_SET_ERGO(uintx, NewSize, smallest_new_size);
+    // Do not use FLAG_SET_ERGO to update NewSize here, since this will override
+    // if NewSize was set on the command line or not. This information is needed
+    // later when setting the initial and minimum young generation size.
+    NewSize = smallest_new_size;
   }
   _initial_gen0_size = NewSize;
 
--- a/hotspot/src/share/vm/memory/filemap.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/memory/filemap.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -78,6 +78,10 @@
   va_start(ap, msg);
   if (RequireSharedSpaces) {
     fail(msg, ap);
+  } else {
+    if (PrintSharedSpaces) {
+      tty->print_cr("UseSharedSpaces: %s", msg);
+    }
   }
   va_end(ap);
   UseSharedSpaces = false;
--- a/hotspot/src/share/vm/memory/heap.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/memory/heap.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -43,6 +43,7 @@
   _next_segment                 = 0;
   _freelist                     = NULL;
   _freelist_segments            = 0;
+  _freelist_length              = 0;
 }
 
 
@@ -53,7 +54,7 @@
   address p = (address)_segmap.low() + beg;
   address q = (address)_segmap.low() + end;
   // initialize interval
-  while (p < q) *p++ = 0xFF;
+  while (p < q) *p++ = free_sentinel;
 }
 
 
@@ -67,7 +68,7 @@
   int i = 0;
   while (p < q) {
     *p++ = i++;
-    if (i == 0xFF) i = 1;
+    if (i == free_sentinel) i = 1;
   }
 }
 
@@ -139,11 +140,6 @@
 }
 
 
-void CodeHeap::release() {
-  Unimplemented();
-}
-
-
 bool CodeHeap::expand_by(size_t size) {
   // expand _memory space
   size_t dm = align_to_page_size(_memory.committed_size() + size) - _memory.committed_size();
@@ -157,8 +153,8 @@
     assert(_number_of_reserved_segments >= _number_of_committed_segments, "just checking");
     // expand _segmap space
     size_t ds = align_to_page_size(_number_of_committed_segments) - _segmap.committed_size();
-    if (ds > 0) {
-      if (!_segmap.expand_by(ds)) return false;
+    if ((ds > 0) && !_segmap.expand_by(ds)) {
+      return false;
     }
     assert(_segmap.committed_size() >= (size_t) _number_of_committed_segments, "just checking");
     // initialize additional segmap entries
@@ -167,12 +163,6 @@
   return true;
 }
 
-
-void CodeHeap::shrink_by(size_t size) {
-  Unimplemented();
-}
-
-
 void CodeHeap::clear() {
   _next_segment = 0;
   mark_segmap_as_free(0, _number_of_committed_segments);
@@ -180,26 +170,23 @@
 
 
 void* CodeHeap::allocate(size_t instance_size, bool is_critical) {
-  size_t number_of_segments = size_to_segments(instance_size + sizeof(HeapBlock));
+  size_t number_of_segments = size_to_segments(instance_size + header_size());
   assert(segments_to_size(number_of_segments) >= sizeof(FreeBlock), "not enough room for FreeList");
 
   // First check if we can satisfy request from freelist
-  debug_only(verify());
+  NOT_PRODUCT(verify());
   HeapBlock* block = search_freelist(number_of_segments, is_critical);
-  debug_only(if (VerifyCodeCacheOften) verify());
+  NOT_PRODUCT(verify());
+
   if (block != NULL) {
     assert(block->length() >= number_of_segments && block->length() < number_of_segments + CodeCacheMinBlockLength, "sanity check");
     assert(!block->free(), "must be marked free");
-#ifdef ASSERT
-    memset((void *)block->allocated_space(), badCodeHeapNewVal, instance_size);
-#endif
+    DEBUG_ONLY(memset((void*)block->allocated_space(), badCodeHeapNewVal, instance_size));
     return block->allocated_space();
   }
 
   // Ensure minimum size for allocation to the heap.
-  if (number_of_segments < CodeCacheMinBlockLength) {
-    number_of_segments = CodeCacheMinBlockLength;
-  }
+  number_of_segments = MAX2((int)CodeCacheMinBlockLength, (int)number_of_segments);
 
   if (!is_critical) {
     // Make sure the allocation fits in the unallocated heap without using
@@ -215,9 +202,7 @@
     HeapBlock* b =  block_at(_next_segment);
     b->initialize(number_of_segments);
     _next_segment += number_of_segments;
-#ifdef ASSERT
-    memset((void *)b->allocated_space(), badCodeHeapNewVal, instance_size);
-#endif
+    DEBUG_ONLY(memset((void *)b->allocated_space(), badCodeHeapNewVal, instance_size));
     return b->allocated_space();
   } else {
     return NULL;
@@ -230,28 +215,56 @@
   // Find start of HeapBlock
   HeapBlock* b = (((HeapBlock *)p) - 1);
   assert(b->allocated_space() == p, "sanity check");
-#ifdef ASSERT
-  memset((void *)b->allocated_space(),
-         badCodeHeapFreeVal,
-         segments_to_size(b->length()) - sizeof(HeapBlock));
-#endif
+  DEBUG_ONLY(memset((void *)b->allocated_space(), badCodeHeapFreeVal,
+             segments_to_size(b->length()) - sizeof(HeapBlock)));
   add_to_freelist(b);
-
-  debug_only(if (VerifyCodeCacheOften) verify());
+  NOT_PRODUCT(verify());
 }
 
-
+/**
+ * Uses segment map to find the the start (header) of a nmethod. This works as follows:
+ * The memory of the code cache is divided into 'segments'. The size of a segment is
+ * determined by -XX:CodeCacheSegmentSize=XX. Allocation in the code cache can only
+ * happen at segment boundaries. A pointer in the code cache can be mapped to a segment
+ * by calling segment_for(addr). Each time memory is requested from the code cache,
+ * the segmap is updated accordingly. See the following example, which illustrates the
+ * state of code cache and the segment map: (seg -> segment, nm ->nmethod)
+ *
+ *          code cache          segmap
+ *         -----------        ---------
+ * seg 1   | nm 1    |   ->   | 0     |
+ * seg 2   | nm 1    |   ->   | 1     |
+ * ...     | nm 1    |   ->   | ..    |
+ * seg m   | nm 2    |   ->   | 0     |
+ * seg m+1 | nm 2    |   ->   | 1     |
+ * ...     | nm 2    |   ->   | 2     |
+ * ...     | nm 2    |   ->   | ..    |
+ * ...     | nm 2    |   ->   | 0xFE  |
+ * seg m+n | nm 2    |   ->   | 1     |
+ * ...     | nm 2    |   ->   |       |
+ *
+ * A value of '0' in the segmap indicates that this segment contains the beginning of
+ * an nmethod. Let's walk through a simple example: If we want to find the start of
+ * an nmethod that falls into seg 2, we read the value of the segmap[2]. The value
+ * is an offset that points to the segment that contains the start of the nmethod.
+ * Another example: If we want to get the start of nm 2, and we happen to get a pointer
+ * that points to seg m+n, we first read seg[n+m], which returns '1'. So we have to
+ * do one more read of the segmap[m+n-1] to finally get the segment header.
+ */
 void* CodeHeap::find_start(void* p) const {
   if (!contains(p)) {
     return NULL;
   }
-  size_t i = segment_for(p);
-  address b = (address)_segmap.low();
-  if (b[i] == 0xFF) {
+  size_t seg_idx = segment_for(p);
+  address seg_map = (address)_segmap.low();
+  if (is_segment_unused(seg_map[seg_idx])) {
     return NULL;
   }
-  while (b[i] > 0) i -= (int)b[i];
-  HeapBlock* h = block_at(i);
+  while (seg_map[seg_idx] > 0) {
+    seg_idx -= (int)seg_map[seg_idx];
+  }
+
+  HeapBlock* h = block_at(seg_idx);
   if (h->free()) {
     return NULL;
   }
@@ -272,7 +285,7 @@
 }
 
 // Finds the next free heapblock. If the current one is free, that it returned
-void* CodeHeap::next_free(HeapBlock *b) const {
+void* CodeHeap::next_free(HeapBlock* b) const {
   // Since free blocks are merged, there is max. on free block
   // between two used ones
   if (b != NULL && b->free()) b = next_block(b);
@@ -287,7 +300,7 @@
   return NULL;
 }
 
-HeapBlock *CodeHeap::block_start(void *q) const {
+HeapBlock* CodeHeap::block_start(void* q) const {
   HeapBlock* b = (HeapBlock*)find_start(q);
   if (b == NULL) return NULL;
   return b - 1;
@@ -312,6 +325,10 @@
   return _memory.reserved_size();
 }
 
+int CodeHeap::allocated_segments() const {
+  return (int)_next_segment;
+}
+
 size_t CodeHeap::allocated_capacity() const {
   // size of used heap - size on freelist
   return segments_to_size(_next_segment - _freelist_segments);
@@ -325,7 +342,7 @@
 
 // Free list management
 
-FreeBlock *CodeHeap::following_block(FreeBlock *b) {
+FreeBlock* CodeHeap::following_block(FreeBlock *b) {
   return (FreeBlock*)(((address)b) + _segment_size * b->length());
 }
 
@@ -343,7 +360,7 @@
 }
 
 // Try to merge this block with the following block
-void CodeHeap::merge_right(FreeBlock *a) {
+bool CodeHeap::merge_right(FreeBlock* a) {
   assert(a->free(), "must be a free block");
   if (following_block(a) == a->link()) {
     assert(a->link() != NULL && a->link()->free(), "must be free too");
@@ -353,13 +370,20 @@
     // Update find_start map
     size_t beg = segment_for(a);
     mark_segmap_as_used(beg, beg + a->length());
+    _freelist_length--;
+    return true;
   }
+  return false;
 }
 
-void CodeHeap::add_to_freelist(HeapBlock *a) {
+
+void CodeHeap::add_to_freelist(HeapBlock* a) {
   FreeBlock* b = (FreeBlock*)a;
+  _freelist_length++;
+
   assert(b != _freelist, "cannot be removed twice");
 
+
   // Mark as free and update free space count
   _freelist_segments += b->length();
   b->set_free();
@@ -371,95 +395,96 @@
     return;
   }
 
-  // Scan for right place to put into list. List
-  // is sorted by increasing addresses
-  FreeBlock* prev = NULL;
-  FreeBlock* cur  = _freelist;
-  while(cur != NULL && cur < b) {
-    assert(prev == NULL || prev < cur, "must be ordered");
-    prev = cur;
-    cur  = cur->link();
-  }
-
-  assert( (prev == NULL && b < _freelist) ||
-          (prev < b && (cur == NULL || b < cur)), "list must be ordered");
-
-  if (prev == NULL) {
+  // Since the freelist is ordered (smaller addresses -> larger addresses) and the
+  // element we want to insert into the freelist has a smaller address than the first
+  // element, we can simply add 'b' as the first element and we are done.
+  if (b < _freelist) {
     // Insert first in list
     b->set_link(_freelist);
     _freelist = b;
     merge_right(_freelist);
-  } else {
-    insert_after(prev, b);
+    return;
   }
+
+  // Scan for right place to put into list. List
+  // is sorted by increasing addresses
+  FreeBlock* prev = _freelist;
+  FreeBlock* cur  = _freelist->link();
+  while(cur != NULL && cur < b) {
+    assert(prev < cur, "Freelist must be ordered");
+    prev = cur;
+    cur  = cur->link();
+  }
+  assert((prev < b) && (cur == NULL || b < cur), "free-list must be ordered");
+  insert_after(prev, b);
 }
 
-// Search freelist for an entry on the list with the best fit
-// Return NULL if no one was found
+/**
+ * Search freelist for an entry on the list with the best fit.
+ * @return NULL, if no one was found
+ */
 FreeBlock* CodeHeap::search_freelist(size_t length, bool is_critical) {
-  FreeBlock *best_block = NULL;
-  FreeBlock *best_prev  = NULL;
-  size_t best_length = 0;
+  FreeBlock* found_block = NULL;
+  FreeBlock* found_prev  = NULL;
+  size_t     found_length = 0;
 
-  // Search for smallest block which is bigger than length
-  FreeBlock *prev = NULL;
-  FreeBlock *cur = _freelist;
+  FreeBlock* prev = NULL;
+  FreeBlock* cur = _freelist;
+  const size_t critical_boundary = (size_t)high_boundary() - CodeCacheMinimumFreeSpace;
+
+  // Search for first block that fits
   while(cur != NULL) {
-    size_t l = cur->length();
-    if (l >= length && (best_block == NULL || best_length > l)) {
-
+    if (cur->length() >= length) {
       // Non critical allocations are not allowed to use the last part of the code heap.
-      if (!is_critical) {
-        // Make sure the end of the allocation doesn't cross into the last part of the code heap
-        if (((size_t)cur + length) > ((size_t)high_boundary() - CodeCacheMinimumFreeSpace)) {
-          // the freelist is sorted by address - if one fails, all consecutive will also fail.
-          break;
-        }
+      // Make sure the end of the allocation doesn't cross into the last part of the code heap.
+      if (!is_critical && (((size_t)cur + length) > critical_boundary)) {
+        // The freelist is sorted by address - if one fails, all consecutive will also fail.
+        break;
       }
+      // Remember block, its previous element, and its length
+      found_block = cur;
+      found_prev  = prev;
+      found_length = found_block->length();
 
-      // Remember best block, its previous element, and its length
-      best_block = cur;
-      best_prev  = prev;
-      best_length = best_block->length();
+      break;
     }
-
     // Next element in list
     prev = cur;
     cur  = cur->link();
   }
 
-  if (best_block == NULL) {
+  if (found_block == NULL) {
     // None found
     return NULL;
   }
 
-  assert((best_prev == NULL && _freelist == best_block ) ||
-         (best_prev != NULL && best_prev->link() == best_block), "sanity check");
-
   // Exact (or at least good enough) fit. Remove from list.
   // Don't leave anything on the freelist smaller than CodeCacheMinBlockLength.
-  if (best_length < length + CodeCacheMinBlockLength) {
-    length = best_length;
-    if (best_prev == NULL) {
-      assert(_freelist == best_block, "sanity check");
+  if (found_length - length < CodeCacheMinBlockLength) {
+    _freelist_length--;
+    length = found_length;
+    if (found_prev == NULL) {
+      assert(_freelist == found_block, "sanity check");
       _freelist = _freelist->link();
     } else {
+      assert((found_prev->link() == found_block), "sanity check");
       // Unmap element
-      best_prev->set_link(best_block->link());
+      found_prev->set_link(found_block->link());
     }
   } else {
     // Truncate block and return a pointer to the following block
-    best_block->set_length(best_length - length);
-    best_block = following_block(best_block);
     // Set used bit and length on new block
-    size_t beg = segment_for(best_block);
+    found_block->set_length(found_length - length);
+    found_block = following_block(found_block);
+
+    size_t beg = segment_for(found_block);
     mark_segmap_as_used(beg, beg + length);
-    best_block->set_length(length);
+    found_block->set_length(length);
   }
 
-  best_block->set_used();
+  found_block->set_used();
   _freelist_segments -= length;
-  return best_block;
+  return found_block;
 }
 
 //----------------------------------------------------------------------------
@@ -471,33 +496,34 @@
   tty->print_cr("The Heap");
 }
 
-#endif
-
 void CodeHeap::verify() {
-  // Count the number of blocks on the freelist, and the amount of space
-  // represented.
-  int count = 0;
-  size_t len = 0;
-  for(FreeBlock* b = _freelist; b != NULL; b = b->link()) {
-    len += b->length();
-    count++;
-  }
-
-  // Verify that freelist contains the right amount of free space
-  //  guarantee(len == _freelist_segments, "wrong freelist");
+  if (VerifyCodeCache) {
+    size_t len = 0;
+    int count = 0;
+    for(FreeBlock* b = _freelist; b != NULL; b = b->link()) {
+      len += b->length();
+      count++;
+      // Check if we have merged all free blocks
+      assert(merge_right(b) == false, "Missed merging opportunity");
+    }
+    // Verify that freelist contains the right amount of free space
+    assert(len == _freelist_segments, "wrong freelist");
 
-  // Verify that the number of free blocks is not out of hand.
-  static int free_block_threshold = 10000;
-  if (count > free_block_threshold) {
-    warning("CodeHeap: # of free blocks > %d", free_block_threshold);
-    // Double the warning limit
-    free_block_threshold *= 2;
-  }
+    for(HeapBlock* h = first_block(); h != NULL; h = next_block(h)) {
+      if (h->free()) count--;
+    }
+    // Verify that the freelist contains the same number of blocks
+    // than free blocks found on the full list.
+    assert(count == 0, "missing free blocks");
 
-  // Verify that the freelist contains the same number of free blocks that is
-  // found on the full list.
-  for(HeapBlock *h = first_block(); h != NULL; h = next_block(h)) {
-    if (h->free()) count--;
+    // Verify that the number of free blocks is not out of hand.
+    static int free_block_threshold = 10000;
+    if (count > free_block_threshold) {
+      warning("CodeHeap: # of free blocks > %d", free_block_threshold);
+      // Double the warning limit
+      free_block_threshold *= 2;
+    }
   }
-  //  guarantee(count == 0, "missing free blocks");
 }
+
+#endif
--- a/hotspot/src/share/vm/memory/heap.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/memory/heap.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -92,24 +92,28 @@
 
   FreeBlock*   _freelist;
   size_t       _freelist_segments;               // No. of segments in freelist
+  int          _freelist_length;
+
+  enum { free_sentinel = 0xFF };
 
   // Helper functions
   size_t   size_to_segments(size_t size) const { return (size + _segment_size - 1) >> _log2_segment_size; }
   size_t   segments_to_size(size_t number_of_segments) const { return number_of_segments << _log2_segment_size; }
 
   size_t   segment_for(void* p) const            { return ((char*)p - _memory.low()) >> _log2_segment_size; }
+  bool     is_segment_unused(int val) const      { return val == free_sentinel; }
   HeapBlock* block_at(size_t i) const            { return (HeapBlock*)(_memory.low() + (i << _log2_segment_size)); }
 
   void  mark_segmap_as_free(size_t beg, size_t end);
   void  mark_segmap_as_used(size_t beg, size_t end);
 
   // Freelist management helpers
-  FreeBlock* following_block(FreeBlock *b);
+  FreeBlock* following_block(FreeBlock* b);
   void insert_after(FreeBlock* a, FreeBlock* b);
-  void merge_right (FreeBlock* a);
+  bool merge_right (FreeBlock* a);
 
   // Toplevel freelist management
-  void add_to_freelist(HeapBlock *b);
+  void add_to_freelist(HeapBlock* b);
   FreeBlock* search_freelist(size_t length, bool is_critical);
 
   // Iteration helpers
@@ -120,20 +124,18 @@
 
   // to perform additional actions on creation of executable code
   void on_code_mapping(char* base, size_t size);
+  void clear();                                 // clears all heap contents
 
  public:
   CodeHeap();
 
   // Heap extents
   bool  reserve(size_t reserved_size, size_t committed_size, size_t segment_size);
-  void  release();                               // releases all allocated memory
   bool  expand_by(size_t size);                  // expands committed memory by size
-  void  shrink_by(size_t size);                  // shrinks committed memory by size
-  void  clear();                                 // clears all heap contents
 
   // Memory allocation
   void* allocate  (size_t size, bool is_critical);  // allocates a block of size or returns NULL
-  void  deallocate(void* p);                     // deallocates a block
+  void  deallocate(void* p);                        // deallocates a block
 
   // Attributes
   char* low_boundary() const                     { return _memory.low_boundary (); }
@@ -141,12 +143,13 @@
   char* high_boundary() const                    { return _memory.high_boundary(); }
 
   bool  contains(const void* p) const            { return low_boundary() <= p && p < high(); }
-  void* find_start(void* p) const;              // returns the block containing p or NULL
-  size_t alignment_unit() const;                // alignment of any block
-  size_t alignment_offset() const;              // offset of first byte of any block, within the enclosing alignment unit
-  static size_t header_size();                  // returns the header size for each heap block
+  void* find_start(void* p)     const;           // returns the block containing p or NULL
+  size_t alignment_unit()       const;           // alignment of any block
+  size_t alignment_offset()     const;           // offset of first byte of any block, within the enclosing alignment unit
+  static size_t header_size();                   // returns the header size for each heap block
 
-  // Iteration
+  size_t allocated_in_freelist() const           { return _freelist_segments * CodeCacheSegmentSize; }
+  int    freelist_length()       const           { return _freelist_length; } // number of elements in the freelist
 
   // returns the first block or NULL
   void* first() const       { return next_free(first_block()); }
@@ -156,6 +159,7 @@
   // Statistics
   size_t capacity() const;
   size_t max_capacity() const;
+  int    allocated_segments() const;
   size_t allocated_capacity() const;
   size_t unallocated_capacity() const            { return max_capacity() - allocated_capacity(); }
 
@@ -164,7 +168,7 @@
 
 public:
   // Debugging
-  void verify();
+  void verify() PRODUCT_RETURN;
   void print()  PRODUCT_RETURN;
 };
 
--- a/hotspot/src/share/vm/oops/constantPool.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/oops/constantPool.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1295,6 +1295,7 @@
   } break;
 
   case JVM_CONSTANT_UnresolvedClass:
+  case JVM_CONSTANT_UnresolvedClassInError:
   {
     // Can be resolved after checking tag, so check the slot first.
     CPSlot entry = from_cp->slot_at(from_i);
--- a/hotspot/src/share/vm/oops/metadata.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/oops/metadata.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -42,6 +42,7 @@
   // Rehashing support for tables containing pointers to this
   unsigned int new_hash(juint seed)   { ShouldNotReachHere();  return 0; }
 
+  virtual bool is_metadata()           const volatile { return true; }
   virtual bool is_klass()              const volatile { return false; }
   virtual bool is_method()             const volatile { return false; }
   virtual bool is_methodData()         const volatile { return false; }
--- a/hotspot/src/share/vm/oops/method.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/oops/method.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -108,12 +108,16 @@
 #endif
   u2                _method_size;                // size of this object
   u1                _intrinsic_id;               // vmSymbols::intrinsic_id (0 == _none)
-  u1                _jfr_towrite      : 1,       // Flags
-                    _caller_sensitive : 1,
-                    _force_inline     : 1,
-                    _hidden           : 1,
-                    _dont_inline      : 1,
-                                      : 3;
+
+  // Flags
+  enum Flags {
+    _jfr_towrite      = 1 << 0,
+    _caller_sensitive = 1 << 1,
+    _force_inline     = 1 << 2,
+    _dont_inline      = 1 << 3,
+    _hidden           = 1 << 4
+  };
+  u1 _flags;
 
 #ifndef PRODUCT
   int               _compiled_invocation_count;  // Number of nmethod invocations so far (for perf. debugging)
@@ -759,16 +763,41 @@
   void init_intrinsic_id();     // updates from _none if a match
   static vmSymbols::SID klass_id_for_intrinsics(Klass* holder);
 
-  bool     jfr_towrite()            { return _jfr_towrite;          }
-  void set_jfr_towrite(bool x)      {        _jfr_towrite = x;      }
-  bool     caller_sensitive()       { return _caller_sensitive;     }
-  void set_caller_sensitive(bool x) {        _caller_sensitive = x; }
-  bool     force_inline()           { return _force_inline;         }
-  void set_force_inline(bool x)     {        _force_inline = x;     }
-  bool     dont_inline()            { return _dont_inline;          }
-  void set_dont_inline(bool x)      {        _dont_inline = x;      }
-  bool  is_hidden()                 { return _hidden;               }
-  void set_hidden(bool x)           {        _hidden = x;           }
+  bool jfr_towrite() {
+    return (_flags & _jfr_towrite) != 0;
+  }
+  void set_jfr_towrite(bool x) {
+    _flags = x ? (_flags | _jfr_towrite) : (_flags & ~_jfr_towrite);
+  }
+
+  bool caller_sensitive() {
+    return (_flags & _caller_sensitive) != 0;
+  }
+  void set_caller_sensitive(bool x) {
+    _flags = x ? (_flags | _caller_sensitive) : (_flags & ~_caller_sensitive);
+  }
+
+  bool force_inline() {
+    return (_flags & _force_inline) != 0;
+  }
+  void set_force_inline(bool x) {
+    _flags = x ? (_flags | _force_inline) : (_flags & ~_force_inline);
+  }
+
+  bool dont_inline() {
+    return (_flags & _dont_inline) != 0;
+  }
+  void set_dont_inline(bool x) {
+    _flags = x ? (_flags | _dont_inline) : (_flags & ~_dont_inline);
+  }
+
+  bool is_hidden() {
+    return (_flags & _hidden) != 0;
+  }
+  void set_hidden(bool x) {
+    _flags = x ? (_flags | _hidden) : (_flags & ~_hidden);
+  }
+
   ConstMethod::MethodType method_type() const {
       return _constMethod->method_type();
   }
--- a/hotspot/src/share/vm/oops/methodData.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/oops/methodData.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1071,7 +1071,8 @@
 }
 
 // Initialize the MethodData* corresponding to a given method.
-MethodData::MethodData(methodHandle method, int size, TRAPS) {
+MethodData::MethodData(methodHandle method, int size, TRAPS)
+  : _extra_data_lock(Monitor::leaf, "MDO extra data lock") {
   No_Safepoint_Verifier no_safepoint;  // init function atomic wrt GC
   ResourceMark rm;
   // Set the method back-pointer.
@@ -1235,7 +1236,7 @@
   return (DataLayout*)((address)dp + DataLayout::compute_size_in_bytes(nb_cells));
 }
 
-ProfileData* MethodData::bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp) {
+ProfileData* MethodData::bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp, bool concurrent) {
   DataLayout* end = extra_data_limit();
 
   for (;; dp = next_extra(dp)) {
@@ -1257,10 +1258,11 @@
       if (m != NULL) {
         SpeculativeTrapData* data = new SpeculativeTrapData(dp);
         // data->method() may be null in case of a concurrent
-        // allocation. Assume it's for the same method and use that
+        // allocation. Maybe it's for the same method. Try to use that
         // entry in that case.
         if (dp->bci() == bci) {
           if (data->method() == NULL) {
+            assert(concurrent, "impossible because no concurrent allocation");
             return NULL;
           } else if (data->method() == m) {
             return data;
@@ -1289,40 +1291,40 @@
   // Allocation in the extra data space has to be atomic because not
   // all entries have the same size and non atomic concurrent
   // allocation would result in a corrupted extra data space.
-  while (true) {
-    ProfileData* result = bci_to_extra_data_helper(bci, m, dp);
-    if (result != NULL) {
+  ProfileData* result = bci_to_extra_data_helper(bci, m, dp, true);
+  if (result != NULL) {
+    return result;
+  }
+
+  if (create_if_missing && dp < end) {
+    MutexLocker ml(&_extra_data_lock);
+    // Check again now that we have the lock. Another thread may
+    // have added extra data entries.
+    ProfileData* result = bci_to_extra_data_helper(bci, m, dp, false);
+    if (result != NULL || dp >= end) {
       return result;
     }
 
-    if (create_if_missing && dp < end) {
-      assert(dp->tag() == DataLayout::no_tag || (dp->tag() == DataLayout::speculative_trap_data_tag && m != NULL), "should be free");
-      assert(next_extra(dp)->tag() == DataLayout::no_tag || next_extra(dp)->tag() == DataLayout::arg_info_data_tag, "should be free or arg info");
-      u1 tag = m == NULL ? DataLayout::bit_data_tag : DataLayout::speculative_trap_data_tag;
-      // SpeculativeTrapData is 2 slots. Make sure we have room.
-      if (m != NULL && next_extra(dp)->tag() != DataLayout::no_tag) {
-        return NULL;
-      }
-      DataLayout temp;
-      temp.initialize(tag, bci, 0);
-      // May have been set concurrently
-      if (dp->header() != temp.header() && !dp->atomic_set_header(temp.header())) {
-        // Allocation failure because of concurrent allocation. Try
-        // again.
-        continue;
-      }
-      assert(dp->tag() == tag, "sane");
-      assert(dp->bci() == bci, "no concurrent allocation");
-      if (tag == DataLayout::bit_data_tag) {
-        return new BitData(dp);
-      } else {
-        // If being allocated concurrently, one trap may be lost
-        SpeculativeTrapData* data = new SpeculativeTrapData(dp);
-        data->set_method(m);
-        return data;
-      }
+    assert(dp->tag() == DataLayout::no_tag || (dp->tag() == DataLayout::speculative_trap_data_tag && m != NULL), "should be free");
+    assert(next_extra(dp)->tag() == DataLayout::no_tag || next_extra(dp)->tag() == DataLayout::arg_info_data_tag, "should be free or arg info");
+    u1 tag = m == NULL ? DataLayout::bit_data_tag : DataLayout::speculative_trap_data_tag;
+    // SpeculativeTrapData is 2 slots. Make sure we have room.
+    if (m != NULL && next_extra(dp)->tag() != DataLayout::no_tag) {
+      return NULL;
     }
-    return NULL;
+    DataLayout temp;
+    temp.initialize(tag, bci, 0);
+
+    dp->set_header(temp.header());
+    assert(dp->tag() == tag, "sane");
+    assert(dp->bci() == bci, "no concurrent allocation");
+    if (tag == DataLayout::bit_data_tag) {
+      return new BitData(dp);
+    } else {
+      SpeculativeTrapData* data = new SpeculativeTrapData(dp);
+      data->set_method(m);
+      return data;
+    }
   }
   return NULL;
 }
--- a/hotspot/src/share/vm/oops/methodData.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/oops/methodData.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -190,12 +190,6 @@
   void set_header(intptr_t value) {
     _header._bits = value;
   }
-  bool atomic_set_header(intptr_t value) {
-    if (Atomic::cmpxchg_ptr(value, (volatile intptr_t*)&_header._bits, 0) == 0) {
-      return true;
-    }
-    return false;
-  }
   intptr_t header() {
     return _header._bits;
   }
@@ -2047,10 +2041,12 @@
   // Cached hint for bci_to_dp and bci_to_data
   int _hint_di;
 
+  Mutex _extra_data_lock;
+
   MethodData(methodHandle method, int size, TRAPS);
 public:
   static MethodData* allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS);
-  MethodData() {}; // For ciMethodData
+  MethodData() : _extra_data_lock(Monitor::leaf, "MDO extra data lock") {}; // For ciMethodData
 
   bool is_methodData() const volatile { return true; }
 
@@ -2155,7 +2151,7 @@
   // What is the index of the first data entry?
   int first_di() const { return 0; }
 
-  ProfileData* bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp);
+  ProfileData* bci_to_extra_data_helper(int bci, Method* m, DataLayout*& dp, bool concurrent);
   // Find or create an extra ProfileData:
   ProfileData* bci_to_extra_data(int bci, Method* m, bool create_if_missing);
 
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -452,7 +452,7 @@
   product(bool, EliminateAutoBox, true,                                     \
           "Control optimizations for autobox elimination")                  \
                                                                             \
-  experimental(bool, UseImplicitStableValues, false,                        \
+  diagnostic(bool, UseImplicitStableValues, true,                           \
           "Mark well-known stable fields as such (e.g. String.value)")      \
                                                                             \
   product(intx, AutoBoxCacheMax, 128,                                       \
@@ -650,7 +650,7 @@
   experimental(bool, ReplaceInParentMaps, false,                            \
           "Propagate type improvements in callers of inlinee if possible")  \
                                                                             \
-  experimental(bool, UseTypeSpeculation, false,                             \
+  product(bool, UseTypeSpeculation, true,                                   \
           "Speculatively propagate types from profiles")                    \
                                                                             \
   diagnostic(bool, UseInlineDepthForSpeculativeTypes, true,                 \
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -3007,22 +3007,28 @@
   }
 
   Node* cast_obj = NULL;
-  const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr();
-  // We may not have profiling here or it may not help us. If we have
-  // a speculative type use it to perform an exact cast.
-  ciKlass* spec_obj_type = obj_type->speculative_type();
-  if (spec_obj_type != NULL ||
-      (data != NULL &&
-       // Counter has never been decremented (due to cast failure).
-       // ...This is a reasonable thing to expect.  It is true of
-       // all casts inserted by javac to implement generic types.
-       data->as_CounterData()->count() >= 0)) {
-    cast_obj = maybe_cast_profiled_receiver(not_null_obj, tk->klass(), spec_obj_type, safe_for_replace);
-    if (cast_obj != NULL) {
-      if (failure_control != NULL) // failure is now impossible
-        (*failure_control) = top();
-      // adjust the type of the phi to the exact klass:
-      phi->raise_bottom_type(_gvn.type(cast_obj)->meet_speculative(TypePtr::NULL_PTR));
+  if (tk->klass_is_exact()) {
+    // The following optimization tries to statically cast the speculative type of the object
+    // (for example obtained during profiling) to the type of the superklass and then do a
+    // dynamic check that the type of the object is what we expect. To work correctly
+    // for checkcast and aastore the type of superklass should be exact.
+    const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr();
+    // We may not have profiling here or it may not help us. If we have
+    // a speculative type use it to perform an exact cast.
+    ciKlass* spec_obj_type = obj_type->speculative_type();
+    if (spec_obj_type != NULL ||
+        (data != NULL &&
+         // Counter has never been decremented (due to cast failure).
+         // ...This is a reasonable thing to expect.  It is true of
+         // all casts inserted by javac to implement generic types.
+         data->as_CounterData()->count() >= 0)) {
+      cast_obj = maybe_cast_profiled_receiver(not_null_obj, tk->klass(), spec_obj_type, safe_for_replace);
+      if (cast_obj != NULL) {
+        if (failure_control != NULL) // failure is now impossible
+          (*failure_control) = top();
+        // adjust the type of the phi to the exact klass:
+        phi->raise_bottom_type(_gvn.type(cast_obj)->meet_speculative(TypePtr::NULL_PTR));
+      }
     }
   }
 
--- a/hotspot/src/share/vm/opto/library_call.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -3180,7 +3180,8 @@
 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted);
 bool LibraryCallKit::inline_native_isInterrupted() {
   // Add a fast path to t.isInterrupted(clear_int):
-  //   (t == Thread.current() && (!TLS._osthread._interrupted || !clear_int))
+  //   (t == Thread.current() &&
+  //    (!TLS._osthread._interrupted || WINDOWS_ONLY(false) NOT_WINDOWS(!clear_int)))
   //   ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int)
   // So, in the common case that the interrupt bit is false,
   // we avoid making a call into the VM.  Even if the interrupt bit
@@ -3237,6 +3238,7 @@
   // drop through to next case
   set_control( _gvn.transform(new (C) IfTrueNode(iff_bit)));
 
+#ifndef TARGET_OS_FAMILY_windows
   // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path.
   Node* clr_arg = argument(1);
   Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0)));
@@ -3250,6 +3252,10 @@
 
   // drop through to next case
   set_control( _gvn.transform(new (C) IfTrueNode(iff_arg)));
+#else
+  // To return true on Windows you must read the _interrupted field
+  // and check the the event state i.e. take the slow path.
+#endif // TARGET_OS_FAMILY_windows
 
   // (d) Otherwise, go to the slow path.
   slow_region->add_req(control());
--- a/hotspot/src/share/vm/opto/matcher.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/opto/matcher.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1922,6 +1922,105 @@
   return OptoReg::as_OptoReg(regs.first());
 }
 
+// This function identifies sub-graphs in which a 'load' node is
+// input to two different nodes, and such that it can be matched
+// with BMI instructions like blsi, blsr, etc.
+// Example : for b = -a[i] & a[i] can be matched to blsi r32, m32.
+// The graph is (AndL (SubL Con0 LoadL*) LoadL*), where LoadL*
+// refers to the same node.
+#ifdef X86
+// Match the generic fused operations pattern (op1 (op2 Con{ConType} mop) mop)
+// This is a temporary solution until we make DAGs expressible in ADL.
+template<typename ConType>
+class FusedPatternMatcher {
+  Node* _op1_node;
+  Node* _mop_node;
+  int _con_op;
+
+  static int match_next(Node* n, int next_op, int next_op_idx) {
+    if (n->in(1) == NULL || n->in(2) == NULL) {
+      return -1;
+    }
+
+    if (next_op_idx == -1) { // n is commutative, try rotations
+      if (n->in(1)->Opcode() == next_op) {
+        return 1;
+      } else if (n->in(2)->Opcode() == next_op) {
+        return 2;
+      }
+    } else {
+      assert(next_op_idx > 0 && next_op_idx <= 2, "Bad argument index");
+      if (n->in(next_op_idx)->Opcode() == next_op) {
+        return next_op_idx;
+      }
+    }
+    return -1;
+  }
+public:
+  FusedPatternMatcher(Node* op1_node, Node *mop_node, int con_op) :
+    _op1_node(op1_node), _mop_node(mop_node), _con_op(con_op) { }
+
+  bool match(int op1, int op1_op2_idx,  // op1 and the index of the op1->op2 edge, -1 if op1 is commutative
+             int op2, int op2_con_idx,  // op2 and the index of the op2->con edge, -1 if op2 is commutative
+             typename ConType::NativeType con_value) {
+    if (_op1_node->Opcode() != op1) {
+      return false;
+    }
+    if (_mop_node->outcnt() > 2) {
+      return false;
+    }
+    op1_op2_idx = match_next(_op1_node, op2, op1_op2_idx);
+    if (op1_op2_idx == -1) {
+      return false;
+    }
+    // Memory operation must be the other edge
+    int op1_mop_idx = (op1_op2_idx & 1) + 1;
+
+    // Check that the mop node is really what we want
+    if (_op1_node->in(op1_mop_idx) == _mop_node) {
+      Node *op2_node = _op1_node->in(op1_op2_idx);
+      if (op2_node->outcnt() > 1) {
+        return false;
+      }
+      assert(op2_node->Opcode() == op2, "Should be");
+      op2_con_idx = match_next(op2_node, _con_op, op2_con_idx);
+      if (op2_con_idx == -1) {
+        return false;
+      }
+      // Memory operation must be the other edge
+      int op2_mop_idx = (op2_con_idx & 1) + 1;
+      // Check that the memory operation is the same node
+      if (op2_node->in(op2_mop_idx) == _mop_node) {
+        // Now check the constant
+        const Type* con_type = op2_node->in(op2_con_idx)->bottom_type();
+        if (con_type != Type::TOP && ConType::as_self(con_type)->get_con() == con_value) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+};
+
+
+bool Matcher::is_bmi_pattern(Node *n, Node *m) {
+  if (n != NULL && m != NULL) {
+    if (m->Opcode() == Op_LoadI) {
+      FusedPatternMatcher<TypeInt> bmii(n, m, Op_ConI);
+      return bmii.match(Op_AndI, -1, Op_SubI,  1,  0)  ||
+             bmii.match(Op_AndI, -1, Op_AddI, -1, -1)  ||
+             bmii.match(Op_XorI, -1, Op_AddI, -1, -1);
+    } else if (m->Opcode() == Op_LoadL) {
+      FusedPatternMatcher<TypeLong> bmil(n, m, Op_ConL);
+      return bmil.match(Op_AndL, -1, Op_SubL,  1,  0) ||
+             bmil.match(Op_AndL, -1, Op_AddL, -1, -1) ||
+             bmil.match(Op_XorL, -1, Op_AddL, -1, -1);
+    }
+  }
+  return false;
+}
+#endif // X86
+
 // A method-klass-holder may be passed in the inline_cache_reg
 // and then expanded into the inline_cache_reg and a method_oop register
 //   defined in ad_<arch>.cpp
@@ -2077,6 +2176,14 @@
           set_shared(m->in(AddPNode::Base)->in(1));
         }
 
+        // if 'n' and 'm' are part of a graph for BMI instruction, clone this node.
+#ifdef X86
+        if (UseBMI1Instructions && is_bmi_pattern(n, m)) {
+          mstack.push(m, Visit);
+          continue;
+        }
+#endif
+
         // Clone addressing expressions as they are "free" in memory access instructions
         if( mem_op && i == MemNode::Address && mop == Op_AddP ) {
           // Some inputs for address expression are not put on stack
--- a/hotspot/src/share/vm/opto/matcher.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/opto/matcher.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -79,6 +79,9 @@
 
   // Find shared Nodes, or Nodes that otherwise are Matcher roots
   void find_shared( Node *n );
+#ifdef X86
+  bool is_bmi_pattern(Node *n, Node *m);
+#endif
 
   // Debug and profile information for nodes in old space:
   GrowableArray<Node_Notes*>* _old_node_note_array;
--- a/hotspot/src/share/vm/opto/memnode.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1593,35 +1593,33 @@
 
 // Try to constant-fold a stable array element.
 static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, BasicType loadbt) {
+  assert(ary->const_oop(), "array should be constant");
   assert(ary->is_stable(), "array should be stable");
 
-  if (ary->const_oop() != NULL) {
-    // Decode the results of GraphKit::array_element_address.
-    ciArray* aobj = ary->const_oop()->as_array();
-    ciConstant con = aobj->element_value_by_offset(off);
-
-    if (con.basic_type() != T_ILLEGAL && !con.is_null_or_zero()) {
-      const Type* con_type = Type::make_from_constant(con);
-      if (con_type != NULL) {
-        if (con_type->isa_aryptr()) {
-          // Join with the array element type, in case it is also stable.
-          int dim = ary->stable_dimension();
-          con_type = con_type->is_aryptr()->cast_to_stable(true, dim-1);
-        }
-        if (loadbt == T_NARROWOOP && con_type->isa_oopptr()) {
-          con_type = con_type->make_narrowoop();
-        }
+  // Decode the results of GraphKit::array_element_address.
+  ciArray* aobj = ary->const_oop()->as_array();
+  ciConstant con = aobj->element_value_by_offset(off);
+
+  if (con.basic_type() != T_ILLEGAL && !con.is_null_or_zero()) {
+    const Type* con_type = Type::make_from_constant(con);
+    if (con_type != NULL) {
+      if (con_type->isa_aryptr()) {
+        // Join with the array element type, in case it is also stable.
+        int dim = ary->stable_dimension();
+        con_type = con_type->is_aryptr()->cast_to_stable(true, dim-1);
+      }
+      if (loadbt == T_NARROWOOP && con_type->isa_oopptr()) {
+        con_type = con_type->make_narrowoop();
+      }
 #ifndef PRODUCT
-        if (TraceIterativeGVN) {
-          tty->print("FoldStableValues: array element [off=%d]: con_type=", off);
-          con_type->dump(); tty->cr();
-        }
+      if (TraceIterativeGVN) {
+        tty->print("FoldStableValues: array element [off=%d]: con_type=", off);
+        con_type->dump(); tty->cr();
+      }
 #endif //PRODUCT
-        return con_type;
-      }
+      return con_type;
     }
   }
-
   return NULL;
 }
 
@@ -1641,7 +1639,7 @@
   // Try to guess loaded type from pointer type
   if (tp->isa_aryptr()) {
     const TypeAryPtr* ary = tp->is_aryptr();
-    const Type *t = ary->elem();
+    const Type* t = ary->elem();
 
     // Determine whether the reference is beyond the header or not, by comparing
     // the offset against the offset of the start of the array's data.
@@ -1653,10 +1651,9 @@
     const bool off_beyond_header = ((uint)off >= (uint)min_base_off);
 
     // Try to constant-fold a stable array element.
-    if (FoldStableValues && ary->is_stable()) {
-      // Make sure the reference is not into the header
-      if (off_beyond_header && off != Type::OffsetBot) {
-        assert(adr->is_AddP() && adr->in(AddPNode::Offset)->is_Con(), "offset is a constant");
+    if (FoldStableValues && ary->is_stable() && ary->const_oop() != NULL) {
+      // Make sure the reference is not into the header and the offset is constant
+      if (off_beyond_header && adr->is_AddP() && off != Type::OffsetBot) {
         const Type* con_type = fold_stable_ary_elem(ary, off, memory_type());
         if (con_type != NULL) {
           return con_type;
--- a/hotspot/src/share/vm/opto/multnode.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/opto/multnode.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -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
@@ -194,7 +194,9 @@
     }
   }
 
-  ProjNode* other_proj = iff->proj_out(1-_con)->as_Proj();
+  ProjNode* other_proj = iff->proj_out(1-_con);
+  if (other_proj == NULL) // Should never happen, but make Parfait happy.
+      return false;
   if (other_proj->is_uncommon_trap_proj(reason)) {
     assert(reason == Deoptimization::Reason_none ||
            Compile::current()->is_predicate_opaq(iff->in(1)->in(1)), "should be on the list");
--- a/hotspot/src/share/vm/opto/parse.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/opto/parse.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -338,6 +338,8 @@
   GraphKit      _exits;         // Record all normal returns and throws here.
   bool          _wrote_final;   // Did we write a final field?
   bool          _wrote_volatile;     // Did we write a volatile field?
+  bool          _wrote_stable;       // Did we write a @Stable field?
+  bool          _wrote_fields;       // Did we write any field?
   bool          _count_invocations;  // update and test invocation counter
   bool          _method_data_update; // update method data oop
   Node*         _alloc_with_final;   // An allocation node with final field
@@ -383,6 +385,10 @@
   void      set_wrote_final(bool z)   { _wrote_final = z; }
   bool          wrote_volatile() const { return _wrote_volatile; }
   void      set_wrote_volatile(bool z) { _wrote_volatile = z; }
+  bool          wrote_stable() const  { return _wrote_stable; }
+  void      set_wrote_stable(bool z)  { _wrote_stable = z; }
+  bool         wrote_fields() const   { return _wrote_fields; }
+  void     set_wrote_fields(bool z)   { _wrote_fields = z; }
   bool          count_invocations() const  { return _count_invocations; }
   bool          method_data_update() const { return _method_data_update; }
   Node*    alloc_with_final() const   { return _alloc_with_final; }
--- a/hotspot/src/share/vm/opto/parse1.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/opto/parse1.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -391,6 +391,8 @@
   _depth = 1 + (caller->has_method() ? caller->depth() : 0);
   _wrote_final = false;
   _wrote_volatile = false;
+  _wrote_stable = false;
+  _wrote_fields = false;
   _alloc_with_final = NULL;
   _entry_bci = InvocationEntryBci;
   _tf = NULL;
@@ -908,26 +910,35 @@
   Node* iophi = _exits.i_o();
   _exits.set_i_o(gvn().transform(iophi));
 
-  // On PPC64, also add MemBarRelease for constructors which write
-  // volatile fields. As support_IRIW_for_not_multiple_copy_atomic_cpu
-  // is set on PPC64, no sync instruction is issued after volatile
-  // stores. We want to quarantee the same behaviour as on platforms
-  // with total store order, although this is not required by the Java
-  // memory model. So as with finals, we add a barrier here.
-  if (wrote_final() PPC64_ONLY(|| (wrote_volatile() && method()->is_initializer()))) {
-    // This method (which must be a constructor by the rules of Java)
-    // wrote a final.  The effects of all initializations must be
-    // committed to memory before any code after the constructor
-    // publishes the reference to the newly constructor object.
-    // Rather than wait for the publication, we simply block the
-    // writes here.  Rather than put a barrier on only those writes
-    // which are required to complete, we force all writes to complete.
-    //
-    // "All bets are off" unless the first publication occurs after a
-    // normal return from the constructor.  We do not attempt to detect
-    // such unusual early publications.  But no barrier is needed on
-    // exceptional returns, since they cannot publish normally.
-    //
+  // Figure out if we need to emit the trailing barrier. The barrier is only
+  // needed in the constructors, and only in three cases:
+  //
+  // 1. The constructor wrote a final. The effects of all initializations
+  //    must be committed to memory before any code after the constructor
+  //    publishes the reference to the newly constructed object. Rather
+  //    than wait for the publication, we simply block the writes here.
+  //    Rather than put a barrier on only those writes which are required
+  //    to complete, we force all writes to complete.
+  //
+  // 2. On PPC64, also add MemBarRelease for constructors which write
+  //    volatile fields. As support_IRIW_for_not_multiple_copy_atomic_cpu
+  //    is set on PPC64, no sync instruction is issued after volatile
+  //    stores. We want to guarantee the same behavior as on platforms
+  //    with total store order, although this is not required by the Java
+  //    memory model. So as with finals, we add a barrier here.
+  //
+  // 3. Experimental VM option is used to force the barrier if any field
+  //    was written out in the constructor.
+  //
+  // "All bets are off" unless the first publication occurs after a
+  // normal return from the constructor.  We do not attempt to detect
+  // such unusual early publications.  But no barrier is needed on
+  // exceptional returns, since they cannot publish normally.
+  //
+  if (method()->is_initializer() &&
+        (wrote_final() ||
+           PPC64_ONLY(wrote_volatile() ||)
+           (AlwaysSafeConstructors && wrote_fields()))) {
     _exits.insert_mem_bar(Op_MemBarRelease, alloc_with_final());
 #ifndef PRODUCT
     if (PrintOpto && (Verbose || WizardMode)) {
@@ -937,6 +948,19 @@
 #endif
   }
 
+  // Any method can write a @Stable field; insert memory barriers after
+  // those also. If there is a predecessor allocation node, bind the
+  // barrier there.
+  if (wrote_stable()) {
+    _exits.insert_mem_bar(Op_MemBarRelease, alloc_with_final());
+#ifndef PRODUCT
+    if (PrintOpto && (Verbose || WizardMode)) {
+      method()->print_name();
+      tty->print_cr(" writes @Stable and needs a memory barrier");
+    }
+#endif
+  }
+
   for (MergeMemStream mms(_exits.merged_memory()); mms.next_non_empty(); ) {
     // transform each slice of the original memphi:
     mms.set_memory(_gvn.transform(mms.memory()));
--- a/hotspot/src/share/vm/opto/parse3.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/opto/parse3.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -233,7 +233,8 @@
   // Build the load.
   //
   MemNode::MemOrd mo = is_vol ? MemNode::acquire : MemNode::unordered;
-  Node* ld = make_load(NULL, adr, type, bt, adr_type, mo, is_vol);
+  bool needs_atomic_access = is_vol || AlwaysAtomicAccesses;
+  Node* ld = make_load(NULL, adr, type, bt, adr_type, mo, needs_atomic_access);
 
   // Adjust Java stack
   if (type2size[bt] == 1)
@@ -314,7 +315,8 @@
     }
     store = store_oop_to_object(control(), obj, adr, adr_type, val, field_type, bt, mo);
   } else {
-    store = store_to_memory(control(), adr, val, bt, adr_type, mo, is_vol);
+    bool needs_atomic_access = is_vol || AlwaysAtomicAccesses;
+    store = store_to_memory(control(), adr, val, bt, adr_type, mo, needs_atomic_access);
   }
 
   // If reference is volatile, prevent following volatiles ops from
@@ -332,13 +334,23 @@
     }
   }
 
+  if (is_field) {
+    set_wrote_fields(true);
+  }
+
   // If the field is final, the rules of Java say we are in <init> or <clinit>.
   // Note the presence of writes to final non-static fields, so that we
   // can insert a memory barrier later on to keep the writes from floating
   // out of the constructor.
   // Any method can write a @Stable field; insert memory barriers after those also.
   if (is_field && (field->is_final() || field->is_stable())) {
-    set_wrote_final(true);
+    if (field->is_final()) {
+        set_wrote_final(true);
+    }
+    if (field->is_stable()) {
+        set_wrote_stable(true);
+    }
+
     // Preserve allocation ptr to create precedent edge to it in membar
     // generated on exit from constructor.
     if (C->eliminate_boxing() &&
--- a/hotspot/src/share/vm/prims/jvm.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -4360,7 +4360,7 @@
 
 JVM_ENTRY(void, JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size))
 {
-  memset(info, 0, sizeof(info_size));
+  memset(info, 0, info_size);
 
   info->jvm_version = Abstract_VM_Version::jvm_version();
   info->update_version = 0;          /* 0 in HotSpot Express VM */
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1464,7 +1464,19 @@
     // It's fine to update the thread state here because no JVMTI events
     // shall be posted for this PopFrame.
 
-    state->update_for_pop_top_frame();
+    // It is only safe to perform the direct operation on the current
+    // thread. All other usage needs to use a vm-safepoint-op for safety.
+    if (java_thread == JavaThread::current()) {
+      state->update_for_pop_top_frame();
+    } else {
+      VM_UpdateForPopTopFrame op(state);
+      VMThread::execute(&op);
+      jvmtiError err = op.result();
+      if (err != JVMTI_ERROR_NONE) {
+        return err;
+      }
+    }
+
     java_thread->set_popframe_condition(JavaThread::popframe_pending_bit);
     // Set pending step flag for this popframe and it is cleared when next
     // step event is posted.
@@ -1505,6 +1517,7 @@
 // depth - pre-checked as non-negative
 jvmtiError
 JvmtiEnv::NotifyFramePop(JavaThread* java_thread, jint depth) {
+  jvmtiError err = JVMTI_ERROR_NONE;
   ResourceMark rm;
   uint32_t debug_bits = 0;
 
@@ -1532,10 +1545,17 @@
 
   assert(vf->frame_pointer() != NULL, "frame pointer mustn't be NULL");
 
-  int frame_number = state->count_frames() - depth;
-  state->env_thread_state(this)->set_frame_pop(frame_number);
-
-  return JVMTI_ERROR_NONE;
+  // It is only safe to perform the direct operation on the current
+  // thread. All other usage needs to use a vm-safepoint-op for safety.
+  if (java_thread == JavaThread::current()) {
+    int frame_number = state->count_frames() - depth;
+    state->env_thread_state(this)->set_frame_pop(frame_number);
+  } else {
+    VM_SetFramePop op(this, state, depth);
+    VMThread::execute(&op);
+    err = op.result();
+  }
+  return err;
 } /* end NotifyFramePop */
 
 
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -29,6 +29,7 @@
 #include "prims/jvmtiEnvThreadState.hpp"
 #include "prims/jvmtiEventController.hpp"
 #include "prims/jvmtiThreadState.hpp"
+#include "prims/jvmtiThreadState.inline.hpp"
 #include "runtime/fieldDescriptor.hpp"
 #include "runtime/frame.hpp"
 #include "runtime/handles.inline.hpp"
@@ -334,6 +335,60 @@
   JvmtiEnv* next(JvmtiEnvBase* env) { return env->next_environment(); }
 };
 
+// VM operation to update for pop top frame.
+class VM_UpdateForPopTopFrame : public VM_Operation {
+private:
+  JvmtiThreadState* _state;
+  jvmtiError _result;
+
+public:
+  VM_UpdateForPopTopFrame(JvmtiThreadState* state) {
+    _state = state;
+    _result = JVMTI_ERROR_NONE;
+  }
+  VMOp_Type type() const { return VMOp_UpdateForPopTopFrame; }
+  jvmtiError result() { return _result; }
+  void doit() {
+    JavaThread* jt = _state->get_thread();
+    if (Threads::includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
+      _state->update_for_pop_top_frame();
+    } else {
+      _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+    }
+  }
+};
+
+// VM operation to set frame pop.
+class VM_SetFramePop : public VM_Operation {
+private:
+  JvmtiEnv *_env;
+  JvmtiThreadState* _state;
+  jint _depth;
+  jvmtiError _result;
+
+public:
+  VM_SetFramePop(JvmtiEnv *env, JvmtiThreadState* state, jint depth) {
+    _env = env;
+    _state = state;
+    _depth = depth;
+    _result = JVMTI_ERROR_NONE;
+  }
+  // Nested operation must be allowed for the VM_EnterInterpOnlyMode that is
+  // called from the JvmtiEventControllerPrivate::recompute_thread_enabled.
+  bool allow_nested_vm_operations() const { return true; }
+  VMOp_Type type() const { return VMOp_SetFramePop; }
+  jvmtiError result() { return _result; }
+  void doit() {
+    JavaThread* jt = _state->get_thread();
+    if (Threads::includes(jt) && !jt->is_exiting() && jt->threadObj() != NULL) {
+      int frame_number = _state->count_frames() - _depth;
+      _state->env_thread_state((JvmtiEnvBase*)_env)->set_frame_pop(frame_number);
+    } else {
+      _result = JVMTI_ERROR_THREAD_NOT_ALIVE;
+    }
+  }
+};
+
 
 // VM operation to get monitor information with stack depth.
 class VM_GetOwnedMonitorInfo : public VM_Operation {
--- a/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -190,12 +190,8 @@
 
 
 JvmtiFramePops* JvmtiEnvThreadState::get_frame_pops() {
-#ifdef ASSERT
-  uint32_t debug_bits = 0;
-#endif
-  assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
-         "frame pop data only accessible from same thread or while suspended");
-
+  assert(get_thread() == Thread::current() || SafepointSynchronize::is_at_safepoint(),
+         "frame pop data only accessible from same thread or at safepoint");
   if (_frame_pops == NULL) {
     _frame_pops = new JvmtiFramePops();
     assert(_frame_pops != NULL, "_frame_pops != NULL");
@@ -209,44 +205,32 @@
 }
 
 void JvmtiEnvThreadState::set_frame_pop(int frame_number) {
-#ifdef ASSERT
-  uint32_t debug_bits = 0;
-#endif
-  assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
-         "frame pop data only accessible from same thread or while suspended");
+  assert(get_thread() == Thread::current() || SafepointSynchronize::is_at_safepoint(),
+         "frame pop data only accessible from same thread or at safepoint");
   JvmtiFramePop fpop(frame_number);
   JvmtiEventController::set_frame_pop(this, fpop);
 }
 
 
 void JvmtiEnvThreadState::clear_frame_pop(int frame_number) {
-#ifdef ASSERT
-  uint32_t debug_bits = 0;
-#endif
-  assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
-         "frame pop data only accessible from same thread or while suspended");
+  assert(get_thread() == Thread::current() || SafepointSynchronize::is_at_safepoint(),
+         "frame pop data only accessible from same thread or at safepoint");
   JvmtiFramePop fpop(frame_number);
   JvmtiEventController::clear_frame_pop(this, fpop);
 }
 
 
 void JvmtiEnvThreadState::clear_to_frame_pop(int frame_number)  {
-#ifdef ASSERT
-  uint32_t debug_bits = 0;
-#endif
-  assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
-         "frame pop data only accessible from same thread or while suspended");
+  assert(get_thread() == Thread::current() || SafepointSynchronize::is_at_safepoint(),
+         "frame pop data only accessible from same thread or at safepoint");
   JvmtiFramePop fpop(frame_number);
   JvmtiEventController::clear_to_frame_pop(this, fpop);
 }
 
 
 bool JvmtiEnvThreadState::is_frame_pop(int cur_frame_number) {
-#ifdef ASSERT
-  uint32_t debug_bits = 0;
-#endif
-  assert(get_thread() == Thread::current() || JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
-         "frame pop data only accessible from same thread or while suspended");
+  assert(get_thread() == Thread::current() || SafepointSynchronize::is_at_safepoint(),
+         "frame pop data only accessible from same thread or at safepoint");
   if (!get_thread()->is_interp_only_mode() || _frame_pops == NULL) {
     return false;
   }
--- a/hotspot/src/share/vm/prims/jvmtiEventController.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiEventController.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -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
@@ -989,21 +989,21 @@
 
 void
 JvmtiEventController::set_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
-  MutexLocker mu(JvmtiThreadState_lock);
+  MutexLockerEx mu(SafepointSynchronize::is_at_safepoint() ? NULL : JvmtiThreadState_lock);
   JvmtiEventControllerPrivate::set_frame_pop(ets, fpop);
 }
 
 
 void
 JvmtiEventController::clear_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
-  MutexLocker mu(JvmtiThreadState_lock);
+  MutexLockerEx mu(SafepointSynchronize::is_at_safepoint() ? NULL : JvmtiThreadState_lock);
   JvmtiEventControllerPrivate::clear_frame_pop(ets, fpop);
 }
 
 
 void
 JvmtiEventController::clear_to_frame_pop(JvmtiEnvThreadState *ets, JvmtiFramePop fpop) {
-  MutexLocker mu(JvmtiThreadState_lock);
+  MutexLockerEx mu(SafepointSynchronize::is_at_safepoint() ? NULL : JvmtiThreadState_lock);
   JvmtiEventControllerPrivate::clear_to_frame_pop(ets, fpop);
 }
 
--- a/hotspot/src/share/vm/prims/jvmtiThreadState.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/prims/jvmtiThreadState.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -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
@@ -63,6 +63,7 @@
   _vm_object_alloc_event_collector = NULL;
   _the_class_for_redefinition_verification = NULL;
   _scratch_class_for_redefinition_verification = NULL;
+  _cur_stack_depth = UNKNOWN_STACK_DEPTH;
 
   // JVMTI ForceEarlyReturn support
   _pending_step_for_earlyret = false;
@@ -213,12 +214,9 @@
 
 // Helper routine used in several places
 int JvmtiThreadState::count_frames() {
-#ifdef ASSERT
-  uint32_t debug_bits = 0;
-#endif
-  assert(SafepointSynchronize::is_at_safepoint() ||
-         JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
-         "at safepoint or must be suspended");
+  guarantee(SafepointSynchronize::is_at_safepoint() ||
+    (JavaThread *)Thread::current() == get_thread(),
+    "must be current thread or at safepoint");
 
   if (!get_thread()->has_last_Java_frame()) return 0;  // no Java frames
 
@@ -243,15 +241,9 @@
 
 
 void JvmtiThreadState::invalidate_cur_stack_depth() {
-  Thread *cur = Thread::current();
-  uint32_t debug_bits = 0;
-
-  // The caller can be the VMThread at a safepoint, the current thread
-  // or the target thread must be suspended.
-  guarantee((cur->is_VM_thread() && SafepointSynchronize::is_at_safepoint()) ||
-    (JavaThread *)cur == get_thread() ||
-    JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
-    "sanity check");
+  guarantee(SafepointSynchronize::is_at_safepoint() ||
+    (JavaThread *)Thread::current() == get_thread(),
+    "must be current thread or at safepoint");
 
   _cur_stack_depth = UNKNOWN_STACK_DEPTH;
 }
@@ -280,10 +272,9 @@
 }
 
 int JvmtiThreadState::cur_stack_depth() {
-  uint32_t debug_bits = 0;
-  guarantee(JavaThread::current() == get_thread() ||
-    JvmtiEnv::is_thread_fully_suspended(get_thread(), false, &debug_bits),
-    "must be current thread or suspended");
+  guarantee(SafepointSynchronize::is_at_safepoint() ||
+    (JavaThread *)Thread::current() == get_thread(),
+    "must be current thread or at safepoint");
 
   if (!is_interp_only_mode() || _cur_stack_depth == UNKNOWN_STACK_DEPTH) {
     _cur_stack_depth = count_frames();
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -1699,7 +1699,8 @@
       // HeapBaseMinAddress can be greater than default but not less than.
       if (!FLAG_IS_DEFAULT(HeapBaseMinAddress)) {
         if (HeapBaseMinAddress < DefaultHeapBaseMinAddress) {
-          if (PrintMiscellaneous && Verbose) {  // matches compressed oops printing flags
+          // matches compressed oops printing flags
+          if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
             jio_fprintf(defaultStream::error_stream(),
                         "HeapBaseMinAddress must be at least " UINTX_FORMAT
                         " (" UINTX_FORMAT "G) which is greater than value given "
@@ -2407,9 +2408,11 @@
 
   status &= verify_interval(NmethodSweepFraction, 1, ReservedCodeCacheSize/K, "NmethodSweepFraction");
   status &= verify_interval(NmethodSweepActivity, 0, 2000, "NmethodSweepActivity");
+  status &= verify_interval(CodeCacheMinBlockLength, 1, 100, "CodeCacheMinBlockLength");
+  status &= verify_interval(CodeCacheSegmentSize, 1, 1024, "CodeCacheSegmentSize");
 
   // TieredCompilation needs at least 2 compiler threads.
-  const int num_min_compiler_threads = (TieredCompilation) ? 2 : 1;
+  const int num_min_compiler_threads = (TieredCompilation && (TieredStopAtLevel >= CompLevel_full_optimization)) ? 2 : 1;
   status &=verify_min_value(CICompilerCount, num_min_compiler_threads, "CICompilerCount");
 
   return status;
--- a/hotspot/src/share/vm/runtime/globals.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -535,6 +535,9 @@
   develop(bool, CleanChunkPoolAsync, falseInEmbedded,                       \
           "Clean the chunk pool asynchronously")                            \
                                                                             \
+  experimental(bool, AlwaysSafeConstructors, false,                         \
+          "Force safe construction, as if all fields are final.")           \
+                                                                            \
   /* Temporary: See 6948537 */                                              \
   experimental(bool, UseMemSetInBOT, true,                                  \
           "(Unstable) uses memset in BOT updates in GC code")               \
@@ -811,8 +814,8 @@
   product(bool, PrintOopAddress, false,                                     \
           "Always print the location of the oop")                           \
                                                                             \
-  notproduct(bool, VerifyCodeCacheOften, false,                             \
-          "Verify compiled-code cache often")                               \
+  notproduct(bool, VerifyCodeCache, false,                                  \
+          "Verify code cache on memory allocation/deallocation")            \
                                                                             \
   develop(bool, ZapDeadCompiledLocals, false,                               \
           "Zap dead locals in compiler frames")                             \
@@ -2984,7 +2987,8 @@
           "maximum number of nested recursive calls that are inlined")      \
                                                                             \
   develop(intx, MaxForceInlineLevel, 100,                                   \
-          "maximum number of nested @ForceInline calls that are inlined")   \
+          "maximum number of nested calls that are forced for inlining "    \
+          "(using CompilerOracle or marked w/ @ForceInline)")               \
                                                                             \
   product_pd(intx, InlineSmallCode,                                         \
           "Only inline already compiled methods if their code size is "     \
@@ -3292,8 +3296,8 @@
           "disable this feature")                                           \
                                                                             \
   /* code cache parameters */                                               \
-  /* ppc64 has large code-entry alignment. */                               \
-  develop(uintx, CodeCacheSegmentSize, 64 PPC64_ONLY(+64),                  \
+  /* ppc64/tiered compilation has large code-entry alignment. */            \
+  develop(uintx, CodeCacheSegmentSize, 64 PPC64_ONLY(+64) NOT_PPC64(TIERED_ONLY(+64)),\
           "Code cache segment size (in bytes) - smallest unit of "          \
           "allocation")                                                     \
                                                                             \
@@ -3795,8 +3799,8 @@
   experimental(bool, TrustFinalNonStaticFields, false,                      \
           "trust final non-static declarations for constant folding")       \
                                                                             \
-  experimental(bool, FoldStableValues, false,                               \
-          "Private flag to control optimizations for stable variables")     \
+  diagnostic(bool, FoldStableValues, true,                                  \
+          "Optimize loads from stable fields (marked w/ @Stable)")          \
                                                                             \
   develop(bool, TraceInvokeDynamic, false,                                  \
           "trace internal invoke dynamic operations")                       \
@@ -3864,6 +3868,9 @@
           "Allocation less than this value will be allocated "              \
           "using malloc. Larger allocations will use mmap.")                \
                                                                             \
+  experimental(bool, AlwaysAtomicAccesses, false,                           \
+          "Accesses to all variables should always be atomic")              \
+                                                                            \
   product(bool, EnableTracing, false,                                       \
           "Enable event-based tracing")                                     \
                                                                             \
--- a/hotspot/src/share/vm/runtime/thread.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -910,7 +910,7 @@
               cur != VMOperationRequest_lock &&
               cur != VMOperationQueue_lock) ||
               cur->rank() == Mutex::special) {
-          warning("Thread holding lock at safepoint that vm can block on: %s", cur->name());
+          fatal(err_msg("Thread holding lock at safepoint that vm can block on: %s", cur->name()));
         }
       }
     }
--- a/hotspot/src/share/vm/runtime/timer.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/runtime/timer.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -194,7 +194,7 @@
         system_secs = system_time - _starting_system_time;
         real_secs = real_time - _starting_real_time;
 
-        _logfile->print(" [Times: user=%3.2f sys=%3.2f, real=%3.2f secs] ",
+        _logfile->print(" [Times: user=%3.2f sys=%3.2f real=%3.2f secs] ",
           user_secs, system_secs, real_secs);
 
       } else {
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -2336,6 +2336,12 @@
   /* ConstMethod anon-enum */                                             \
   /********************************/                                      \
                                                                           \
+  declare_constant(Method::_jfr_towrite)                                  \
+  declare_constant(Method::_caller_sensitive)                             \
+  declare_constant(Method::_force_inline)                                 \
+  declare_constant(Method::_dont_inline)                                  \
+  declare_constant(Method::_hidden)                                       \
+                                                                          \
   declare_constant(ConstMethod::_has_linenumber_table)                    \
   declare_constant(ConstMethod::_has_checked_exceptions)                  \
   declare_constant(ConstMethod::_has_localvariable_table)                 \
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -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
@@ -74,6 +74,8 @@
   template(PopulateDumpSharedSpace)               \
   template(JNIFunctionTableCopier)                \
   template(RedefineClasses)                       \
+  template(UpdateForPopTopFrame)                  \
+  template(SetFramePop)                           \
   template(GetOwnedMonitorInfo)                   \
   template(GetObjectMonitorUsage)                 \
   template(GetCurrentContendedMonitor)            \
--- a/hotspot/src/share/vm/shark/llvmHeaders.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/shark/llvmHeaders.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -36,21 +36,43 @@
 #endif
 
 #include <llvm/Analysis/Verifier.h>
+#include <llvm/ExecutionEngine/ExecutionEngine.h>
+
+// includes specific to each version
+#if SHARK_LLVM_VERSION <= 31
+#include <llvm/Support/IRBuilder.h>
+#include <llvm/Type.h>
 #include <llvm/Argument.h>
 #include <llvm/Constants.h>
 #include <llvm/DerivedTypes.h>
-#include <llvm/ExecutionEngine/ExecutionEngine.h>
 #include <llvm/Instructions.h>
 #include <llvm/LLVMContext.h>
 #include <llvm/Module.h>
-#if SHARK_LLVM_VERSION <= 31
-#include <llvm/Support/IRBuilder.h>
-#else
+#elif SHARK_LLVM_VERSION <= 32
 #include <llvm/IRBuilder.h>
+#include <llvm/Type.h>
+#include <llvm/Argument.h>
+#include <llvm/Constants.h>
+#include <llvm/DerivedTypes.h>
+#include <llvm/Instructions.h>
+#include <llvm/LLVMContext.h>
+#include <llvm/Module.h>
+#else // SHARK_LLVM_VERSION <= 34
+#include <llvm/IR/IRBuilder.h>
+#include <llvm/IR/Argument.h>
+#include <llvm/IR/Constants.h>
+#include <llvm/IR/DerivedTypes.h>
+#include <llvm/ExecutionEngine/ExecutionEngine.h>
+#include <llvm/IR/Instructions.h>
+#include <llvm/IR/LLVMContext.h>
+#include <llvm/IR/Module.h>
+#include <llvm/ADT/StringRef.h>
+#include <llvm/IR/Type.h>
 #endif
+
+// common includes
 #include <llvm/Support/Threading.h>
 #include <llvm/Support/TargetSelect.h>
-#include <llvm/Type.h>
 #include <llvm/ExecutionEngine/JITMemoryManager.h>
 #include <llvm/Support/CommandLine.h>
 #include <llvm/ExecutionEngine/MCJIT.h>
--- a/hotspot/src/share/vm/shark/sharkCompiler.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/shark/sharkCompiler.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -364,3 +364,7 @@
   *(dst++) = '\0';
   return buf;
 }
+
+void SharkCompiler::print_timers() {
+  // do nothing
+}
--- a/hotspot/src/share/vm/shark/sharkCompiler.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/shark/sharkCompiler.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -56,6 +56,9 @@
   // Compile a normal (bytecode) method and install it in the VM
   void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
 
+  // Print compilation timers and statistics
+  void print_timers();
+
   // Generate a wrapper for a native (JNI) method
   nmethod* generate_native_wrapper(MacroAssembler* masm,
                                    methodHandle    target,
--- a/hotspot/src/share/vm/shark/sharkInliner.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/shark/sharkInliner.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -744,6 +744,10 @@
 }
 
 bool SharkInliner::attempt_inline(ciMethod *target, SharkState *state) {
+  if (!Inline) {
+    return false;
+  }
+
   if (SharkIntrinsics::is_intrinsic(target)) {
     SharkIntrinsics::inline_intrinsic(target, state);
     return true;
--- a/hotspot/src/share/vm/shark/sharkMemoryManager.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/shark/sharkMemoryManager.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -59,18 +59,6 @@
     entry->set_code_limit(FunctionEnd);
 }
 
-unsigned char* SharkMemoryManager::startExceptionTable(const Function* F,
-                                                       uintptr_t& ActualSize) {
-  return mm()->startExceptionTable(F, ActualSize);
-}
-
-void SharkMemoryManager::endExceptionTable(const Function* F,
-                                           unsigned char* TableStart,
-                                           unsigned char* TableEnd,
-                                           unsigned char* FrameRegister) {
-  mm()->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
-}
-
 void SharkMemoryManager::setMemoryWritable() {
   mm()->setMemoryWritable();
 }
@@ -79,10 +67,6 @@
   mm()->setMemoryExecutable();
 }
 
-void SharkMemoryManager::deallocateExceptionTable(void *ptr) {
-  mm()->deallocateExceptionTable(ptr);
-}
-
 void SharkMemoryManager::deallocateFunctionBody(void *ptr) {
   mm()->deallocateFunctionBody(ptr);
 }
@@ -96,6 +80,17 @@
   return mm()->getPointerToNamedFunction(Name, AbortOnFailure);
 }
 
+void SharkMemoryManager::setPoisonMemory(bool poison) {
+  mm()->setPoisonMemory(poison);
+}
+
+unsigned char *SharkMemoryManager::allocateSpace(intptr_t Size,
+                                                 unsigned int Alignment) {
+  return mm()->allocateSpace(Size, Alignment);
+}
+
+#if SHARK_LLVM_VERSION <= 32
+
 uint8_t* SharkMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) {
   return mm()->allocateCodeSection(Size, Alignment, SectionID);
 }
@@ -104,11 +99,34 @@
   return mm()->allocateDataSection(Size, Alignment, SectionID);
 }
 
-void SharkMemoryManager::setPoisonMemory(bool poison) {
-  mm()->setPoisonMemory(poison);
+void SharkMemoryManager::deallocateExceptionTable(void *ptr) {
+  mm()->deallocateExceptionTable(ptr);
+}
+
+unsigned char* SharkMemoryManager::startExceptionTable(const Function* F,
+                                                       uintptr_t& ActualSize) {
+  return mm()->startExceptionTable(F, ActualSize);
+}
+
+void SharkMemoryManager::endExceptionTable(const Function* F,
+                                           unsigned char* TableStart,
+                                           unsigned char* TableEnd,
+                                           unsigned char* FrameRegister) {
+  mm()->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
 }
 
-unsigned char *SharkMemoryManager::allocateSpace(intptr_t Size,
-                                                 unsigned int Alignment) {
-  return mm()->allocateSpace(Size, Alignment);
+#else
+
+uint8_t *SharkMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName) {
+    return mm()->allocateCodeSection(Size, Alignment, SectionID, SectionName);
 }
+
+uint8_t* SharkMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName, bool IsReadOnly) {
+  return mm()->allocateDataSection(Size, Alignment, SectionID, SectionName, IsReadOnly);
+}
+
+bool SharkMemoryManager::finalizeMemory(std::string *ErrMsg) {
+    return mm()->finalizeMemory(ErrMsg);
+}
+
+#endif
--- a/hotspot/src/share/vm/shark/sharkMemoryManager.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/shark/sharkMemoryManager.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -69,23 +69,32 @@
   void endFunctionBody(const llvm::Function* F,
                        unsigned char* FunctionStart,
                        unsigned char* FunctionEnd);
-  unsigned char* startExceptionTable(const llvm::Function* F,
-                                     uintptr_t& ActualSize);
-  void endExceptionTable(const llvm::Function* F,
-                         unsigned char* TableStart,
-                         unsigned char* TableEnd,
-                         unsigned char* FrameRegister);
+
   void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true);
-  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID);
-  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID);
   void setPoisonMemory(bool);
   uint8_t* allocateGlobal(uintptr_t, unsigned int);
   void setMemoryWritable();
   void setMemoryExecutable();
-  void deallocateExceptionTable(void *ptr);
   void deallocateFunctionBody(void *ptr);
   unsigned char *allocateSpace(intptr_t Size,
                                unsigned int Alignment);
+
+#if SHARK_LLVM_VERSION <= 32
+uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID);
+uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID);
+unsigned char* startExceptionTable(const llvm::Function* F,
+                                   uintptr_t& ActualSize);
+void deallocateExceptionTable(void *ptr);
+void endExceptionTable(const llvm::Function* F,
+                       unsigned char* TableStart,
+                       unsigned char* TableEnd,
+                       unsigned char* FrameRegister);
+#else
+uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, llvm::StringRef SectionName);
+uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, llvm::StringRef SectionName, bool IsReadOnly);
+bool finalizeMemory(std::string *ErrMsg = 0);
+#endif
+
 };
 
 #endif // SHARE_VM_SHARK_SHARKMEMORYMANAGER_HPP
--- a/hotspot/src/share/vm/utilities/elfFile.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/utilities/elfFile.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -140,7 +140,7 @@
       }
     }
 
-#if defined(PPC64)
+#if defined(PPC64) && !defined(ABI_ELFv2)
     // Now read the .opd section wich contains the PPC64 function descriptor table.
     // The .opd section is only available on PPC64 (see for example:
     // http://refspecs.linuxfoundation.org/LSB_3.1.1/LSB-Core-PPC64/LSB-Core-PPC64/specialsections.html)
--- a/hotspot/src/share/vm/utilities/hashtable.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/utilities/hashtable.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -25,7 +25,6 @@
 #include "precompiled.hpp"
 #include "classfile/altHashing.hpp"
 #include "classfile/javaClasses.hpp"
-#include "code/dependencies.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
 #include "memory/resourceArea.hpp"
@@ -353,116 +352,6 @@
 #endif
 
 
-template<class T, class M> GenericHashtable<T, M>::GenericHashtable(int size, bool C_heap, MEMFLAGS memflag) {
-  assert(size > 0, " Invalid hashtable size");
-  _size    = size;
-  _C_heap  = C_heap;
-  _memflag = memflag;
-  // Perform subtype-specific resource allocation
-  _items = (C_heap) ?  NEW_C_HEAP_ARRAY(T*, size, memflag) : NEW_RESOURCE_ARRAY(T*, size);
-  memset(_items, 0, sizeof(T*) * size);
-
-  DEBUG_ONLY(_num_items = 0;)
-}
-
-template<class T, class M> GenericHashtable<T, M>::~GenericHashtable() {
-  if (on_C_heap()) {
-    // Check backing array
-    for (int i = 0; i < size(); i++) {
-      T* item = head(i);
-      // Delete all items in linked list
-      while (item != NULL) {
-        T* next_item = item->next();
-        delete item;
-        DEBUG_ONLY(_num_items--);
-        item = next_item;
-      }
-    }
-    FREE_C_HEAP_ARRAY(T*, _items, _memflag);
-    _items = NULL;
-    assert (_num_items == 0, "Not all memory released");
-  }
-}
-
-/**
- * Return a pointer to the item 'I' that is stored in the hashtable for
- * which match_item->equals(I) == true. If no such item is found, NULL
- * is returned.
- */
-template<class T, class F> T* GenericHashtable<T, F>::contains(T* match_item) {
-  if (match_item != NULL) {
-    int idx = index(match_item);
-    return contains_impl(match_item, idx);
-  }
-  return NULL;
-}
-
-/**
- * Add item to the hashtable. Return 'true' if the item was added
- * and false otherwise.
- */
-template<class T, class F> bool GenericHashtable<T, F>::add(T* item) {
-  if (item != NULL) {
-    int idx = index(item);
-    T* found_item = contains_impl(item, idx);
-    if (found_item == NULL) {
-      T* list_head = head(idx);
-      item->set_next(list_head);
-      item->set_prev(NULL);
-
-      if (list_head != NULL) {
-        list_head->set_prev(item);
-      }
-      set_head(item, idx);
-      DEBUG_ONLY(_num_items++);
-      return true;
-    }
-  }
-  return false;
-}
-
-/**
- * Removes an item 'I' from the hashtable, if present. 'I' is removed, if
- * match_item->equals(I) == true. Removing an item from the hashtable does
- * not free memory.
- */
-template<class T, class F> T* GenericHashtable<T, F>::remove(T* match_item) {
-  if (match_item != NULL) {
-    int idx = index(match_item);
-    T* found_item = contains_impl(match_item, idx);
-    if (found_item != NULL) {
-      // Remove item from linked list
-      T* prev = found_item->prev();
-      T* next = found_item->next();
-      if (prev != NULL) {
-        prev->set_next(next);
-      } else {
-        set_head(next, idx);
-      }
-      if (next != NULL) {
-        next->set_prev(prev);
-      }
-
-      DEBUG_ONLY(_num_items--);
-      return found_item;
-    }
-  }
-  return NULL;
-}
-
-
-template<class T, class F> T* GenericHashtable<T, F>::contains_impl(T* item, int idx) {
-  T* current_item = head(idx);
-  while (current_item != NULL) {
-    if (current_item->equals(item)) {
-      return current_item;
-    }
-    current_item = current_item->next();
-  }
-  return NULL;
-}
-
-
 // Explicitly instantiate these types
 template class Hashtable<ConstantPool*, mtClass>;
 template class Hashtable<Symbol*, mtSymbol>;
@@ -482,5 +371,3 @@
 template class BasicHashtable<mtSymbol>;
 template class BasicHashtable<mtCode>;
 template class BasicHashtable<mtInternal>;
-
-template class GenericHashtable<DependencySignature, ResourceObj>;
--- a/hotspot/src/share/vm/utilities/hashtable.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/utilities/hashtable.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -327,86 +327,4 @@
   }
 };
 
-
-/*
- * Usage of GenericHashtable:
- *
- * class X : public GenericHashtableEntry<X, ResourceObj> {
- *
- *   // Implement virtual functions in class X
- *   bool      equals(X* sig) const;
- *   uintptr_t hash()         const;
- * };
- *
- * void foo() {
- *   GenericHashtable<X, ResourceObj>* table = new GenericHashtable<X, ResourceObj>(11027, false);
- *
- *   X* elem = new X();
- *   table->add(elem);
- *   table->contains(elem);
- * }
- *
- * You can choose other allocation types as well. For example, to store the hashtable to a
- * particular region (CHeapObj<type>) simply replace ResourceObj with the desired type:
- *
- * class X : public GenericHashtableEntry<X, CHeapObj<mtCode> > { ... };
- *
- * To make the destructor (and remove) of the hashtable work:
- * 1) override the delete operator of X
- * 2) provide a destructor of the X
- *
- * You may also find it convenient to override the new operator.
- *
- * If you use this templates do not forget to add an explicit initialization
- * (at the end of hashtable.cpp).
- *
- *  template class GenericHashtable<X, ResourceObj>;
- */
-template <class T, class M> class GenericHashtableEntry : public M {
- private:
-  T* _next;
-  T* _prev;
- public:
-  // Must be implemented by subclass.
-  virtual uintptr_t key()            const = 0;
-  virtual bool      equals(T* other) const = 0;
-
-  T* next() const        { return _next; }
-  T* prev() const        { return _prev; }
-  void set_next(T* item) { _next = item; }
-  void set_prev(T* item) { _prev = item; }
-
-  // Constructor and destructor
-  GenericHashtableEntry() : _next(NULL), _prev(NULL) { };
-  virtual ~GenericHashtableEntry() {};
-};
-
-template <class T, class M> class GenericHashtable : public M {
- private:
-  T**      _items;
-  int      _size;
-  bool     _C_heap;
-  MEMFLAGS _memflag;
-
-  // Accessor methods
-  T*   head    (int idx) const    { return _items[idx]; }
-  void set_head(T* item, int idx) { _items[idx] = item; }
-  int  index   (T* item)          { assert(item != NULL, "missing null check"); return item->key() % size(); }
-
-  // Helper function
-  T* contains_impl(T* item, int idx);
-
-  DEBUG_ONLY(int _num_items;)
- public:
-  GenericHashtable(int size, bool C_heap = false, MEMFLAGS memflag = mtNone);
-  ~GenericHashtable();
-  T*   contains(T* match_item);
-  T*   remove  (T* match_item);
-  bool add     (T* item);
-
-
-  bool on_C_heap() const { return _C_heap; }
-  int  size()      const { return _size; }
-};
-
 #endif // SHARE_VM_UTILITIES_HASHTABLE_HPP
--- a/hotspot/src/share/vm/utilities/resourceHash.hpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/utilities/resourceHash.hpp	Tue Mar 25 20:32:46 2014 -0400
@@ -105,14 +105,20 @@
     }
   }
 
-  // Inserts or replaces a value in the table
-  void put(K const& key, V const& value) {
+ /**
+  * Inserts or replaces a value in the table.
+  * @return: true:  if a new item is added
+  *          false: if the item already existed and the value is updated
+  */
+  bool put(K const& key, V const& value) {
     unsigned hv = HASH(key);
     Node** ptr = lookup_node(hv, key);
     if (*ptr != NULL) {
       (*ptr)->_value = value;
+      return false;
     } else {
       *ptr = new Node(hv, key, value);
+      return true;
     }
   }
 
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Tue Mar 25 20:32:46 2014 -0400
@@ -592,13 +592,24 @@
              st->cr();
              // Compiled code may use EBP register on x86 so it looks like
              // non-walkable C frame. Use frame.sender() for java frames.
-             if (_thread && _thread->is_Java_thread() && fr.is_java_frame()) {
-               RegisterMap map((JavaThread*)_thread, false); // No update
-               fr = fr.sender(&map);
-               continue;
+             if (_thread && _thread->is_Java_thread()) {
+               // Catch very first native frame by using stack address.
+               // For JavaThread stack_base and stack_size should be set.
+               if (!_thread->on_local_stack((address)(fr.sender_sp() + 1))) {
+                 break;
+               }
+               if (fr.is_java_frame()) {
+                 RegisterMap map((JavaThread*)_thread, false); // No update
+                 fr = fr.sender(&map);
+               } else {
+                 fr = os::get_sender_for_C_frame(&fr);
+               }
+             } else {
+               // is_first_C_frame() does only simple checks for frame pointer,
+               // it will pass if java compiled code has a pointer in EBP.
+               if (os::is_first_C_frame(&fr)) break;
+               fr = os::get_sender_for_C_frame(&fr);
              }
-             if (os::is_first_C_frame(&fr)) break;
-             fr = os::get_sender_for_C_frame(&fr);
           }
 
           if (count > StackPrintLimit) {
--- a/hotspot/test/TEST.groups	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/TEST.groups	Tue Mar 25 20:32:46 2014 -0400
@@ -130,7 +130,9 @@
   gc/arguments/TestG1HeapRegionSize.java \
   gc/metaspace/TestMetaspaceMemoryPool.java \
   runtime/InternalApi/ThreadCpuTimesDeadlock.java \
-  serviceability/threads/TestFalseDeadLock.java
+  serviceability/threads/TestFalseDeadLock.java \
+  compiler/tiered/NonTieredLevelsTest.java \
+  compiler/tiered/TieredLevelsTest.java
 
 # Compact 2 adds full VM tests
 compact2 = \
--- a/hotspot/test/compiler/ciReplay/TestVM.sh	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/ciReplay/TestVM.sh	Tue Mar 25 20:32:46 2014 -0400
@@ -78,8 +78,8 @@
         positive_test `expr $stop_level + 50` "TIERED LEVEL $stop_level :: REPLAY" \
                 "-XX:TieredStopAtLevel=$stop_level"
         stop_level=`expr $stop_level + 1`
+        cleanup
     done
-    cleanup
 fi
 
 echo TEST PASSED
--- a/hotspot/test/compiler/ciReplay/common.sh	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/ciReplay/common.sh	Tue Mar 25 20:32:46 2014 -0400
@@ -99,14 +99,13 @@
 # $2 - non-tiered comp_level 
 nontiered_tests() {
     level=`grep "^compile " $replay_data | awk '{print $6}'`
-    # is level available in non-tiere
+    # is level available in non-tiered
     if [ "$level" -eq $2 ]
     then
         positive_test $1 "NON-TIERED :: AVAILABLE COMP_LEVEL" \
                 -XX:-TieredCompilation
     else
         negative_test `expr $1 + 1` "NON-TIERED :: UNAVAILABLE COMP_LEVEL" \
-        negative_test `expr $1 + 1` "NON-TIERED :: UNAVAILABLE COMP_LEVEL" \
                 -XX:-TieredCompilation
     fi
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/codegen/BMI1.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,301 @@
+/*
+ * 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 8031321
+ * @summary Support BMI1 instructions on x86/x64
+ * @run main/othervm -Xbatch -XX:-TieredCompilation -XX:CompileCommand=compileonly,BMITests.* BMI1
+ *
+ */
+
+class MemI {
+  public int x;
+  public MemI(int x) { this.x = x; }
+}
+
+class MemL {
+  public long x;
+  public MemL(long x) { this.x = x; }
+}
+
+class BMITests {
+  static int andnl(int src1, int src2) {
+    return ~src1 & src2;
+  }
+  static long andnq(long src1, long src2) {
+    return ~src1 & src2;
+  }
+  static int andnl(int src1, MemI src2) {
+    return ~src1 & src2.x;
+  }
+  static long andnq(long src1, MemL src2) {
+    return ~src1 & src2.x;
+  }
+  static int blsil(int src1) {
+    return src1 & -src1;
+  }
+  static long blsiq(long src1) {
+    return src1 & -src1;
+  }
+  static int blsil(MemI src1) {
+    return src1.x & -src1.x;
+  }
+  static long blsiq(MemL src1) {
+    return src1.x & -src1.x;
+  }
+  static int blsmskl(int src1) {
+    return (src1 - 1) ^ src1;
+  }
+  static long blsmskq(long src1) {
+    return (src1 - 1) ^ src1;
+  }
+  static int blsmskl(MemI src1) {
+    return (src1.x - 1) ^ src1.x;
+  }
+  static long blsmskq(MemL src1) {
+    return (src1.x - 1) ^ src1.x;
+  }
+  static int blsrl(int src1) {
+    return (src1 - 1) & src1;
+  }
+  static long blsrq(long src1) {
+    return (src1 - 1) & src1;
+  }
+  static int blsrl(MemI src1) {
+    return (src1.x - 1) & src1.x;
+  }
+  static long blsrq(MemL src1) {
+    return (src1.x - 1) & src1.x;
+  }
+  static int lzcntl(int src1) {
+    return Integer.numberOfLeadingZeros(src1);
+  }
+  static int lzcntq(long src1) {
+    return Long.numberOfLeadingZeros(src1);
+  }
+  static int tzcntl(int src1) {
+    return Integer.numberOfTrailingZeros(src1);
+  }
+  static int tzcntq(long src1) {
+    return Long.numberOfTrailingZeros(src1);
+  }
+}
+
+public class BMI1 {
+  private final static int ITERATIONS = 1000000;
+
+  public static void main(String[] args) {
+    int ix = 0x01234567;
+    int iy = 0x89abcdef;
+    MemI imy = new MemI(iy);
+    long lx = 0x0123456701234567L;
+    long ly = 0x89abcdef89abcdefL;
+    MemL lmy = new MemL(ly);
+
+    { // match(Set dst (AndI (XorI src1 minus_1) src2))
+      int z = BMITests.andnl(ix, iy);
+      for (int i = 0; i < ITERATIONS; i++) {
+        int ii = BMITests.andnl(ix, iy);
+        if (ii != z) {
+          throw new Error("andnl with register failed");
+        }
+      }
+    }
+    { // match(Set dst (AndL (XorL src1 minus_1) src2))
+      long z = BMITests.andnq(lx, ly);
+      for (int i = 0; i < ITERATIONS; i++) {
+        long ll = BMITests.andnq(lx, ly);
+        if (ll != z) {
+          throw new Error("andnq with register failed");
+        }
+      }
+    }
+    { // match(Set dst (AndI (XorI src1 minus_1) (LoadI src2)))
+      int z = BMITests.andnl(ix, imy);
+      for (int i = 0; i < ITERATIONS; i++) {
+        int ii = BMITests.andnl(ix, imy);
+        if (ii != z) {
+          throw new Error("andnl with memory failed");
+        }
+      }
+    }
+    { // match(Set dst (AndL (XorL src1 minus_1) (LoadL src2)))
+      long z = BMITests.andnq(lx, lmy);
+      for (int i = 0; i < ITERATIONS; i++) {
+        long ll = BMITests.andnq(lx, lmy);
+        if (ll != z) {
+          throw new Error("andnq with memory failed");
+        }
+      }
+    }
+    { // match(Set dst (AndI (SubI imm_zero src) src))
+      int z = BMITests.blsil(ix);
+      for (int i = 0; i < ITERATIONS; i++) {
+        int ii = BMITests.blsil(ix);
+        if (ii != z) {
+          throw new Error("blsil with register failed");
+        }
+      }
+    }
+    { // match(Set dst (AndL (SubL imm_zero src) src))
+      long z = BMITests.blsiq(lx);
+      for (int i = 0; i < ITERATIONS; i++) {
+        long ll = BMITests.blsiq(lx);
+        if (ll != z) {
+          throw new Error("blsiq with register failed");
+        }
+      }
+    }
+    { // match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) ))
+      int z = BMITests.blsil(imy);
+      for (int i = 0; i < ITERATIONS; i++) {
+        int ii = BMITests.blsil(imy);
+        if (ii != z) {
+          throw new Error("blsil with memory failed");
+        }
+      }
+    }
+    { // match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) ))
+      long z = BMITests.blsiq(lmy);
+      for (int i = 0; i < ITERATIONS; i++) {
+        long ll = BMITests.blsiq(lmy);
+        if (ll != z) {
+          throw new Error("blsiq with memory failed");
+        }
+      }
+    }
+
+    { // match(Set dst (XorI (AddI src minus_1) src))
+      int z = BMITests.blsmskl(ix);
+      for (int i = 0; i < ITERATIONS; i++) {
+        int ii = BMITests.blsmskl(ix);
+        if (ii != z) {
+          throw new Error("blsmskl with register failed");
+        }
+      }
+    }
+    { // match(Set dst (XorL (AddL src minus_1) src))
+      long z = BMITests.blsmskq(lx);
+      for (int i = 0; i < ITERATIONS; i++) {
+        long ll = BMITests.blsmskq(lx);
+        if (ll != z) {
+          throw new Error("blsmskq with register failed");
+        }
+      }
+    }
+    { // match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) )
+      int z = BMITests.blsmskl(imy);
+      for (int i = 0; i < ITERATIONS; i++) {
+        int ii = BMITests.blsmskl(imy);
+        if (ii != z) {
+          throw new Error("blsmskl with memory failed");
+        }
+      }
+    }
+    {  // match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) )
+      long z = BMITests.blsmskq(lmy);
+      for (int i = 0; i < ITERATIONS; i++) {
+        long ll = BMITests.blsmskq(lmy);
+        if (ll != z) {
+          throw new Error("blsmskq with memory failed");
+        }
+      }
+    }
+
+    { //  match(Set dst (AndI (AddI src minus_1) src) )
+      int z = BMITests.blsrl(ix);
+      for (int i = 0; i < ITERATIONS; i++) {
+        int ii = BMITests.blsrl(ix);
+        if (ii != z) {
+          throw new Error("blsrl with register failed");
+        }
+      }
+    }
+    { // match(Set dst (AndL (AddL src minus_1) src) )
+      long z = BMITests.blsrq(lx);
+      for (int i = 0; i < ITERATIONS; i++) {
+        long ll = BMITests.blsrq(lx);
+        if (ll != z) {
+          throw new Error("blsrq with register failed");
+        }
+      }
+    }
+    { // match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) )
+      int z = BMITests.blsrl(imy);
+      for (int i = 0; i < ITERATIONS; i++) {
+        int ii = BMITests.blsrl(imy);
+        if (ii != z) {
+          throw new Error("blsrl with memory failed");
+        }
+      }
+    }
+    { // match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) )
+      long z = BMITests.blsrq(lmy);
+      for (int i = 0; i < ITERATIONS; i++) {
+        long ll = BMITests.blsrq(lmy);
+        if (ll != z) {
+          throw new Error("blsrq with memory failed");
+        }
+      }
+    }
+
+    {
+      int z = BMITests.lzcntl(ix);
+      for (int i = 0; i < ITERATIONS; i++) {
+        int ii = BMITests.lzcntl(ix);
+        if (ii != z) {
+          throw new Error("lzcntl failed");
+        }
+      }
+    }
+    {
+      int z = BMITests.lzcntq(lx);
+      for (int i = 0; i < ITERATIONS; i++) {
+        int ii = BMITests.lzcntq(lx);
+        if (ii != z) {
+          throw new Error("lzcntq failed");
+        }
+      }
+    }
+
+    {
+      int z = BMITests.tzcntl(ix);
+      for (int i = 0; i < ITERATIONS; i++) {
+        int ii = BMITests.tzcntl(ix);
+        if (ii != z) {
+          throw new Error("tzcntl failed");
+        }
+      }
+    }
+    {
+      int z = BMITests.tzcntq(lx);
+      for (int i = 0; i < ITERATIONS; i++) {
+        int ii = BMITests.tzcntq(lx);
+        if (ii != z) {
+          throw new Error("tzcntq failed");
+        }
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/inlining/InlineDefaultMethod1.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8036100
+ * @summary Default method returns true for a while, and then returns false
+ * @run main/othervm -Xcomp -XX:CompileOnly=InlineDefaultMethod1::test
+ *                   -XX:CompileOnly=I1::m -XX:CompileOnly=I2::m
+ *                   InlineDefaultMethod1
+ */
+interface I1 {
+    default public int m() { return 0; }
+}
+
+interface I2 extends I1 {
+    default public int m() { return 1; }
+}
+
+abstract class A implements I1 {
+}
+
+class B extends A implements I2 {
+}
+
+public class InlineDefaultMethod1 {
+    public static void test(A obj) {
+        int id = obj.m();
+        if (id != 1) {
+            throw new AssertionError("Called wrong method: 1 != "+id);
+        }
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+        test(new B());
+        System.out.println("TEST PASSED");
+    }
+}
--- a/hotspot/test/compiler/membars/DekkerTest.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/membars/DekkerTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -25,9 +25,9 @@
  * @test
  * @bug 8007898
  * @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier().
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
  * @author Martin Doerr martin DOT doerr AT sap DOT com
  *
  * Run 3 times since the failure is intermittent.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/stable/TestStableBoolean.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,627 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestStableBoolean
+ * @summary tests on stable fields and arrays
+ * @library /testlibrary
+ * @compile -XDignore.symbol.file TestStableBoolean.java
+ * @run main ClassFileInstaller
+ *           java/lang/invoke/TestStableBoolean
+ *           java/lang/invoke/TestStableBoolean$BooleanStable
+ *           java/lang/invoke/TestStableBoolean$StaticBooleanStable
+ *           java/lang/invoke/TestStableBoolean$VolatileBooleanStable
+ *           java/lang/invoke/TestStableBoolean$BooleanArrayDim1
+ *           java/lang/invoke/TestStableBoolean$BooleanArrayDim2
+ *           java/lang/invoke/TestStableBoolean$BooleanArrayDim3
+ *           java/lang/invoke/TestStableBoolean$BooleanArrayDim4
+ *           java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim0
+ *           java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim1
+ *           java/lang/invoke/TestStableBoolean$NestedStableField
+ *           java/lang/invoke/TestStableBoolean$NestedStableField$A
+ *           java/lang/invoke/TestStableBoolean$NestedStableField1
+ *           java/lang/invoke/TestStableBoolean$NestedStableField1$A
+ *           java/lang/invoke/TestStableBoolean$NestedStableField2
+ *           java/lang/invoke/TestStableBoolean$NestedStableField2$A
+ *           java/lang/invoke/TestStableBoolean$NestedStableField3
+ *           java/lang/invoke/TestStableBoolean$NestedStableField3$A
+ *           java/lang/invoke/TestStableBoolean$DefaultValue
+ *           java/lang/invoke/TestStableBoolean$ObjectArrayLowerDim2
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableBoolean
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableBoolean
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableBoolean
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableBoolean
+ */
+package java.lang.invoke;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import sun.management.ManagementFactoryHelper;
+import java.lang.reflect.InvocationTargetException;
+
+public class TestStableBoolean {
+    public static void main(String[] args) throws Exception {
+        System.out.println("@Stable enabled: "+isStableEnabled);
+        System.out.println();
+
+        run(DefaultValue.class);
+        run(BooleanStable.class);
+        run(StaticBooleanStable.class);
+        run(VolatileBooleanStable.class);
+
+        // @Stable arrays: Dim 1-4
+        run(BooleanArrayDim1.class);
+        run(BooleanArrayDim2.class);
+        run(BooleanArrayDim3.class);
+        run(BooleanArrayDim4.class);
+
+        // @Stable Object field: dynamic arrays
+        run(ObjectArrayLowerDim0.class);
+        run(ObjectArrayLowerDim1.class);
+        run(ObjectArrayLowerDim2.class);
+
+        // Nested @Stable fields
+        run(NestedStableField.class);
+        run(NestedStableField1.class);
+        run(NestedStableField2.class);
+        run(NestedStableField3.class);
+
+        if (failed) {
+            throw new Error("TEST FAILED");
+        }
+    }
+
+    /* ==================================================== */
+
+    static class DefaultValue {
+        public @Stable boolean v;
+
+        public static final DefaultValue c = new DefaultValue();
+        public static boolean get() { return c.v; }
+        public static void test() throws Exception {
+                        boolean val1 = get();
+            c.v = true; boolean val2 = get();
+            assertEquals(val1, false);
+            assertEquals(val2, true);
+        }
+    }
+
+    /* ==================================================== */
+
+    static class BooleanStable {
+        public @Stable boolean v;
+
+        public static final BooleanStable c = new BooleanStable();
+        public static boolean get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = true; boolean val1 = get();
+            c.v = false; boolean val2 = get();
+            assertEquals(val1, true);
+            assertEquals(val2, (isStableEnabled ? true : false));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class StaticBooleanStable {
+        public static @Stable boolean v;
+
+        public static final StaticBooleanStable c = new StaticBooleanStable();
+        public static boolean get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = true; boolean val1 = get();
+            c.v = false; boolean val2 = get();
+            assertEquals(val1, true);
+            assertEquals(val2, (isStableEnabled ? true : false));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class VolatileBooleanStable {
+        public @Stable volatile boolean v;
+
+        public static final VolatileBooleanStable c = new VolatileBooleanStable();
+        public static boolean get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = true; boolean val1 = get();
+            c.v = false; boolean val2 = get();
+            assertEquals(val1, true);
+            assertEquals(val2, (isStableEnabled ? true : false));
+        }
+    }
+
+    /* ==================================================== */
+    // @Stable array == field && all components are stable
+
+    static class BooleanArrayDim1 {
+        public @Stable boolean[] v;
+
+        public static final BooleanArrayDim1 c = new BooleanArrayDim1();
+        public static boolean get() { return c.v[0]; }
+        public static boolean get1() { return c.v[10]; }
+        public static boolean[] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new boolean[1]; c.v[0] = true;  boolean val1 = get();
+                                      c.v[0] = false; boolean val2 = get();
+                assertEquals(val1, true);
+                assertEquals(val2, (isStableEnabled ? true : false));
+            }
+
+            {
+                c.v = new boolean[20]; c.v[10] = true;  boolean val1 = get1();
+                                       c.v[10] = false; boolean val2 = get1();
+                assertEquals(val1, true);
+                assertEquals(val2, (isStableEnabled ? true : false));
+            }
+
+            {
+                c.v = new boolean[1]; boolean[] val1 = get2();
+                c.v = new boolean[1]; boolean[] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class BooleanArrayDim2 {
+        public @Stable boolean[][] v;
+
+        public static final BooleanArrayDim2 c = new BooleanArrayDim2();
+        public static boolean get() { return c.v[0][0]; }
+        public static boolean[] get1() { return c.v[0]; }
+        public static boolean[][] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new boolean[1][1]; c.v[0][0] = true;  boolean val1 = get();
+                                         c.v[0][0] = false; boolean val2 = get();
+                assertEquals(val1, true);
+                assertEquals(val2, (isStableEnabled ? true : false));
+
+                c.v = new boolean[1][1]; c.v[0][0] = false; boolean val3 = get();
+                assertEquals(val3, (isStableEnabled ? true : false));
+
+                c.v[0] = new boolean[1]; c.v[0][0] = false; boolean val4 = get();
+                assertEquals(val4, (isStableEnabled ? true : false));
+            }
+
+            {
+                c.v = new boolean[1][1]; boolean[] val1 = get1();
+                c.v[0] = new boolean[1]; boolean[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new boolean[1][1]; boolean[][] val1 = get2();
+                c.v = new boolean[1][1]; boolean[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class BooleanArrayDim3 {
+        public @Stable boolean[][][] v;
+
+        public static final BooleanArrayDim3 c = new BooleanArrayDim3();
+        public static boolean get() { return c.v[0][0][0]; }
+        public static boolean[] get1() { return c.v[0][0]; }
+        public static boolean[][] get2() { return c.v[0]; }
+        public static boolean[][][] get3() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new boolean[1][1][1]; c.v[0][0][0] = true;  boolean val1 = get();
+                                            c.v[0][0][0] = false; boolean val2 = get();
+                assertEquals(val1, true);
+                assertEquals(val2, (isStableEnabled ? true : false));
+
+                c.v = new boolean[1][1][1]; c.v[0][0][0] = false; boolean val3 = get();
+                assertEquals(val3, (isStableEnabled ? true : false));
+
+                c.v[0] = new boolean[1][1]; c.v[0][0][0] = false; boolean val4 = get();
+                assertEquals(val4, (isStableEnabled ? true : false));
+
+                c.v[0][0] = new boolean[1]; c.v[0][0][0] = false; boolean val5 = get();
+                assertEquals(val5, (isStableEnabled ? true : false));
+            }
+
+            {
+                c.v = new boolean[1][1][1]; boolean[] val1 = get1();
+                c.v[0][0] = new boolean[1]; boolean[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new boolean[1][1][1]; boolean[][] val1 = get2();
+                c.v[0] = new boolean[1][1]; boolean[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new boolean[1][1][1]; boolean[][][] val1 = get3();
+                c.v = new boolean[1][1][1]; boolean[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class BooleanArrayDim4 {
+        public @Stable boolean[][][][] v;
+
+        public static final BooleanArrayDim4 c = new BooleanArrayDim4();
+        public static boolean get() { return c.v[0][0][0][0]; }
+        public static boolean[] get1() { return c.v[0][0][0]; }
+        public static boolean[][] get2() { return c.v[0][0]; }
+        public static boolean[][][] get3() { return c.v[0]; }
+        public static boolean[][][][] get4() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new boolean[1][1][1][1]; c.v[0][0][0][0] = true;  boolean val1 = get();
+                                               c.v[0][0][0][0] = false; boolean val2 = get();
+                assertEquals(val1, true);
+                assertEquals(val2, (isStableEnabled ? true : false));
+
+                c.v = new boolean[1][1][1][1]; c.v[0][0][0][0] = false; boolean val3 = get();
+                assertEquals(val3, (isStableEnabled ? true : false));
+
+                c.v[0] = new boolean[1][1][1]; c.v[0][0][0][0] = false; boolean val4 = get();
+                assertEquals(val4, (isStableEnabled ? true : false));
+
+                c.v[0][0] = new boolean[1][1]; c.v[0][0][0][0] = false; boolean val5 = get();
+                assertEquals(val5, (isStableEnabled ? true : false));
+
+                c.v[0][0][0] = new boolean[1]; c.v[0][0][0][0] = false; boolean val6 = get();
+                assertEquals(val6, (isStableEnabled ? true : false));
+            }
+
+            {
+                c.v = new boolean[1][1][1][1]; boolean[] val1 = get1();
+                c.v[0][0][0] = new boolean[1]; boolean[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new boolean[1][1][1][1]; boolean[][] val1 = get2();
+                c.v[0][0] = new boolean[1][1]; boolean[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new boolean[1][1][1][1]; boolean[][][] val1 = get3();
+                c.v[0] = new boolean[1][1][1]; boolean[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new boolean[1][1][1][1]; boolean[][][][] val1 = get4();
+                c.v = new boolean[1][1][1][1]; boolean[][][][] val2 = get4();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+        }
+    }
+
+    /* ==================================================== */
+    // Dynamic Dim is higher than static
+
+    static class ObjectArrayLowerDim0 {
+        public @Stable Object v;
+
+        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
+        public static boolean get() { return ((boolean[])c.v)[0]; }
+        public static boolean[] get1() { return (boolean[])c.v; }
+        public static boolean[] get2() { return (boolean[])c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new boolean[1]; ((boolean[])c.v)[0] = true;  boolean val1 = get();
+                                      ((boolean[])c.v)[0] = false; boolean val2 = get();
+
+                assertEquals(val1, true);
+                assertEquals(val2, false);
+            }
+
+            {
+                c.v = new boolean[1]; boolean[] val1 = get1();
+                c.v = new boolean[1]; boolean[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim1 {
+        public @Stable Object[] v;
+
+        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
+        public static boolean get() { return ((boolean[][])c.v)[0][0]; }
+        public static boolean[] get1() { return (boolean[])(c.v[0]); }
+        public static Object[] get2() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new boolean[1][1]; ((boolean[][])c.v)[0][0] = true;  boolean val1 = get();
+                                         ((boolean[][])c.v)[0][0] = false; boolean val2 = get();
+
+                assertEquals(val1, true);
+                assertEquals(val2, false);
+            }
+
+            {
+                c.v = new boolean[1][1]; c.v[0] = new boolean[0]; boolean[] val1 = get1();
+                                         c.v[0] = new boolean[0]; boolean[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new boolean[0][0]; Object[] val1 = get2();
+                c.v = new boolean[0][0]; Object[] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim2 {
+        public @Stable Object[][] v;
+
+        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
+        public static boolean get() { return ((boolean[][][])c.v)[0][0][0]; }
+        public static boolean[] get1() { return (boolean[])(c.v[0][0]); }
+        public static boolean[][] get2() { return (boolean[][])(c.v[0]); }
+        public static Object[][] get3() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new boolean[1][1][1]; ((boolean[][][])c.v)[0][0][0] = true;  boolean val1 = get();
+                                            ((boolean[][][])c.v)[0][0][0] = false; boolean val2 = get();
+
+                assertEquals(val1, true);
+                assertEquals(val2, false);
+            }
+
+            {
+                c.v = new boolean[1][1][1]; c.v[0][0] = new boolean[0]; boolean[] val1 = get1();
+                                            c.v[0][0] = new boolean[0]; boolean[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new boolean[1][1][1]; c.v[0] = new boolean[0][0]; boolean[][] val1 = get2();
+                                            c.v[0] = new boolean[0][0]; boolean[][] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new boolean[0][0][0]; Object[][] val1 = get3();
+                c.v = new boolean[0][0][0]; Object[][] val2 = get3();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField {
+        static class A {
+            public @Stable boolean a;
+
+        }
+        public @Stable A v;
+
+        public static final NestedStableField c = new NestedStableField();
+        public static A get() { return c.v; }
+        public static boolean get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.a = true;  A val1 = get();
+                               c.v.a = false; A val2 = get();
+
+                assertEquals(val1.a, false);
+                assertEquals(val2.a, false);
+            }
+
+            {
+                c.v = new A(); c.v.a = true;  boolean val1 = get1();
+                               c.v.a = false; boolean val2 = get1();
+                c.v = new A(); c.v.a = false; boolean val3 = get1();
+
+                assertEquals(val1, true);
+                assertEquals(val2, (isStableEnabled ? true : false));
+                assertEquals(val3, (isStableEnabled ? true : false));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField1 {
+        static class A {
+            public @Stable boolean a;
+            public @Stable A next;
+        }
+        public @Stable A v;
+
+        public static final NestedStableField1 c = new NestedStableField1();
+        public static A get() { return c.v.next.next.next.next.next.next.next; }
+        public static boolean get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.next = new A(); c.v.next.next  = c.v;
+                               c.v.a = true;  c.v.next.a = true;  A val1 = get();
+                               c.v.a = false; c.v.next.a = false; A val2 = get();
+
+                assertEquals(val1.a, false);
+                assertEquals(val2.a, false);
+            }
+
+            {
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = true;  boolean val1 = get1();
+                               c.v.a = false; boolean val2 = get1();
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = false; boolean val3 = get1();
+
+                assertEquals(val1, true);
+                assertEquals(val2, (isStableEnabled ? true : false));
+                assertEquals(val3, (isStableEnabled ? true : false));
+            }
+        }
+    }
+   /* ==================================================== */
+
+    static class NestedStableField2 {
+        static class A {
+            public @Stable boolean a;
+            public @Stable A left;
+            public         A right;
+        }
+
+        public @Stable A v;
+
+        public static final NestedStableField2 c = new NestedStableField2();
+        public static boolean get() { return c.v.left.left.left.a; }
+        public static boolean get1() { return c.v.left.left.right.left.a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.left = c.v.right = c.v;
+                               c.v.a = true;  boolean val1 = get(); boolean val2 = get1();
+                               c.v.a = false; boolean val3 = get(); boolean val4 = get1();
+
+                assertEquals(val1, true);
+                assertEquals(val3, (isStableEnabled ? true : false));
+
+                assertEquals(val2, true);
+                assertEquals(val4, false);
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField3 {
+        static class A {
+            public @Stable boolean a;
+            public @Stable A[] left;
+            public         A[] right;
+        }
+
+        public @Stable A[] v;
+
+        public static final NestedStableField3 c = new NestedStableField3();
+        public static boolean get() { return c.v[0].left[1].left[0].left[1].a; }
+        public static boolean get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
+
+        public static void test() throws Exception {
+            {
+                A elem = new A();
+                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
+                               elem.a = true;  boolean val1 = get(); boolean val2 = get1();
+                               elem.a = false; boolean val3 = get(); boolean val4 = get1();
+
+                assertEquals(val1, true);
+                assertEquals(val3, (isStableEnabled ? true : false));
+
+                assertEquals(val2, true);
+                assertEquals(val4, false);
+            }
+        }
+    }
+
+    /* ==================================================== */
+    // Auxiliary methods
+    static void assertEquals(boolean i, boolean j) { if (i != j)  throw new AssertionError(i + " != " + j); }
+    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
+
+    static boolean failed = false;
+
+    public static void run(Class<?> test) {
+        Throwable ex = null;
+        System.out.print(test.getName()+": ");
+        try {
+            test.getMethod("test").invoke(null);
+        } catch (InvocationTargetException e) {
+            ex = e.getCause();
+        } catch (Throwable e) {
+            ex = e;
+        } finally {
+            if (ex == null) {
+                System.out.println("PASSED");
+            } else {
+                failed = true;
+                System.out.println("FAILED");
+                ex.printStackTrace(System.out);
+            }
+        }
+    }
+
+    static final boolean isStableEnabled;
+    static {
+        HotSpotDiagnosticMXBean diagnostic
+                = ManagementFactoryHelper.getDiagnosticMXBean();
+        VMOption tmp;
+        try {
+            tmp = diagnostic.getVMOption("FoldStableValues");
+        } catch (IllegalArgumentException e) {
+            tmp = null;
+        }
+        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/stable/TestStableByte.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,632 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestStableByte
+ * @summary tests on stable fields and arrays
+ * @library /testlibrary
+ * @compile -XDignore.symbol.file TestStableByte.java
+ * @run main ClassFileInstaller
+ *           java/lang/invoke/TestStableByte
+ *           java/lang/invoke/TestStableByte$ByteStable
+ *           java/lang/invoke/TestStableByte$StaticByteStable
+ *           java/lang/invoke/TestStableByte$VolatileByteStable
+ *           java/lang/invoke/TestStableByte$ByteArrayDim1
+ *           java/lang/invoke/TestStableByte$ByteArrayDim2
+ *           java/lang/invoke/TestStableByte$ByteArrayDim3
+ *           java/lang/invoke/TestStableByte$ByteArrayDim4
+ *           java/lang/invoke/TestStableByte$ObjectArrayLowerDim0
+ *           java/lang/invoke/TestStableByte$ObjectArrayLowerDim1
+ *           java/lang/invoke/TestStableByte$NestedStableField
+ *           java/lang/invoke/TestStableByte$NestedStableField$A
+ *           java/lang/invoke/TestStableByte$NestedStableField1
+ *           java/lang/invoke/TestStableByte$NestedStableField1$A
+ *           java/lang/invoke/TestStableByte$NestedStableField2
+ *           java/lang/invoke/TestStableByte$NestedStableField2$A
+ *           java/lang/invoke/TestStableByte$NestedStableField3
+ *           java/lang/invoke/TestStableByte$NestedStableField3$A
+ *           java/lang/invoke/TestStableByte$DefaultValue
+ *           java/lang/invoke/TestStableByte$ObjectArrayLowerDim2
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableByte
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableByte
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableByte
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableByte
+ */
+package java.lang.invoke;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import sun.management.ManagementFactoryHelper;
+import java.lang.reflect.InvocationTargetException;
+
+public class TestStableByte {
+    public static void main(String[] args) throws Exception {
+        System.out.println("@Stable enabled: "+isStableEnabled);
+        System.out.println();
+
+        run(DefaultValue.class);
+        run(ByteStable.class);
+        run(StaticByteStable.class);
+        run(VolatileByteStable.class);
+
+        // @Stable arrays: Dim 1-4
+        run(ByteArrayDim1.class);
+        run(ByteArrayDim2.class);
+        run(ByteArrayDim3.class);
+        run(ByteArrayDim4.class);
+
+        // @Stable Object field: dynamic arrays
+        run(ObjectArrayLowerDim0.class);
+        run(ObjectArrayLowerDim1.class);
+        run(ObjectArrayLowerDim2.class);
+
+        // Nested @Stable fields
+        run(NestedStableField.class);
+        run(NestedStableField1.class);
+        run(NestedStableField2.class);
+        run(NestedStableField3.class);
+
+        if (failed) {
+            throw new Error("TEST FAILED");
+        }
+    }
+
+    /* ==================================================== */
+
+    static class DefaultValue {
+        public @Stable byte v;
+
+        public static final DefaultValue c = new DefaultValue();
+        public static byte get() { return c.v; }
+        public static void test() throws Exception {
+                     byte val1 = get();
+            c.v = 1; byte val2 = get();
+            assertEquals(val1, 0);
+            assertEquals(val2, 1);
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ByteStable {
+        public @Stable byte v;
+
+        public static final ByteStable c = new ByteStable();
+        public static byte get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 5;   byte val1 = get();
+            c.v = 127; byte val2 = get();
+            assertEquals(val1, 5);
+            assertEquals(val2, (isStableEnabled ? 5 : 127));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class StaticByteStable {
+        public static @Stable byte v;
+
+        public static final StaticByteStable c = new StaticByteStable();
+        public static byte get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 5;   byte val1 = get();
+            c.v = 127; byte val2 = get();
+            assertEquals(val1, 5);
+            assertEquals(val2, (isStableEnabled ? 5 : 127));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class VolatileByteStable {
+        public @Stable volatile byte v;
+
+        public static final VolatileByteStable c = new VolatileByteStable();
+        public static byte get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 5;   byte val1 = get();
+            c.v = 127; byte val2 = get();
+            assertEquals(val1, 5);
+            assertEquals(val2, (isStableEnabled ? 5 : 127));
+        }
+    }
+
+    /* ==================================================== */
+    // @Stable array == field && all components are stable
+
+    static class ByteArrayDim1 {
+        public @Stable byte[] v;
+
+        public static final ByteArrayDim1 c = new ByteArrayDim1();
+        public static byte get() { return c.v[0]; }
+        public static byte get1() { return c.v[10]; }
+        public static byte[] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new byte[1]; c.v[0] = 1; byte val1 = get();
+                                   c.v[0] = 2; byte val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new byte[1]; c.v[0] = 3; byte val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+
+            {
+                c.v = new byte[20]; c.v[10] = 1; byte val1 = get1();
+                                    c.v[10] = 2; byte val2 = get1();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new byte[20]; c.v[10] = 3; byte val3 = get1();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+
+            {
+                c.v = new byte[1]; byte[] val1 = get2();
+                c.v = new byte[1]; byte[] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ByteArrayDim2 {
+        public @Stable byte[][] v;
+
+        public static final ByteArrayDim2 c = new ByteArrayDim2();
+        public static byte get() { return c.v[0][0]; }
+        public static byte[] get1() { return c.v[0]; }
+        public static byte[][] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new byte[1][1]; c.v[0][0] = 1; byte val1 = get();
+                                      c.v[0][0] = 2; byte val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new byte[1][1]; c.v[0][0] = 3; byte val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+
+                c.v[0] = new byte[1]; c.v[0][0] = 4; byte val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1 : 4));
+            }
+
+            {
+                c.v = new byte[1][1]; byte[] val1 = get1();
+                c.v[0] = new byte[1]; byte[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new byte[1][1]; byte[][] val1 = get2();
+                c.v = new byte[1][1]; byte[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ByteArrayDim3 {
+        public @Stable byte[][][] v;
+
+        public static final ByteArrayDim3 c = new ByteArrayDim3();
+        public static byte get() { return c.v[0][0][0]; }
+        public static byte[] get1() { return c.v[0][0]; }
+        public static byte[][] get2() { return c.v[0]; }
+        public static byte[][][] get3() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new byte[1][1][1]; c.v[0][0][0] = 1; byte val1 = get();
+                                         c.v[0][0][0] = 2; byte val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new byte[1][1][1]; c.v[0][0][0] = 3; byte val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+
+                c.v[0] = new byte[1][1]; c.v[0][0][0] = 4; byte val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1 : 4));
+
+                c.v[0][0] = new byte[1]; c.v[0][0][0] = 5; byte val5 = get();
+                assertEquals(val5, (isStableEnabled ? 1 : 5));
+            }
+
+            {
+                c.v = new byte[1][1][1]; byte[] val1 = get1();
+                c.v[0][0] = new byte[1]; byte[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new byte[1][1][1]; byte[][] val1 = get2();
+                c.v[0] = new byte[1][1]; byte[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new byte[1][1][1]; byte[][][] val1 = get3();
+                c.v = new byte[1][1][1]; byte[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ByteArrayDim4 {
+        public @Stable byte[][][][] v;
+
+        public static final ByteArrayDim4 c = new ByteArrayDim4();
+        public static byte get() { return c.v[0][0][0][0]; }
+        public static byte[] get1() { return c.v[0][0][0]; }
+        public static byte[][] get2() { return c.v[0][0]; }
+        public static byte[][][] get3() { return c.v[0]; }
+        public static byte[][][][] get4() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new byte[1][1][1][1]; c.v[0][0][0][0] = 1; byte val1 = get();
+                                            c.v[0][0][0][0] = 2; byte val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new byte[1][1][1][1]; c.v[0][0][0][0] = 3; byte val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+
+                c.v[0] = new byte[1][1][1]; c.v[0][0][0][0] = 4; byte val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1 : 4));
+
+                c.v[0][0] = new byte[1][1]; c.v[0][0][0][0] = 5; byte val5 = get();
+                assertEquals(val5, (isStableEnabled ? 1 : 5));
+
+                c.v[0][0][0] = new byte[1]; c.v[0][0][0][0] = 6; byte val6 = get();
+                assertEquals(val6, (isStableEnabled ? 1 : 6));
+            }
+
+            {
+                c.v = new byte[1][1][1][1]; byte[] val1 = get1();
+                c.v[0][0][0] = new byte[1]; byte[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new byte[1][1][1][1]; byte[][] val1 = get2();
+                c.v[0][0] = new byte[1][1]; byte[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new byte[1][1][1][1]; byte[][][] val1 = get3();
+                c.v[0] = new byte[1][1][1]; byte[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new byte[1][1][1][1]; byte[][][][] val1 = get4();
+                c.v = new byte[1][1][1][1]; byte[][][][] val2 = get4();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+        }
+    }
+
+    /* ==================================================== */
+    // Dynamic Dim is higher than static
+
+    static class ObjectArrayLowerDim0 {
+        public @Stable Object v;
+
+        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
+        public static byte get() { return ((byte[])c.v)[0]; }
+        public static byte[] get1() { return (byte[])c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new byte[1]; ((byte[])c.v)[0] = 1; byte val1 = get();
+                                   ((byte[])c.v)[0] = 2; byte val2 = get();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, 2);
+            }
+
+            {
+                c.v = new byte[1]; byte[] val1 = get1();
+                c.v = new byte[1]; byte[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim1 {
+        public @Stable Object[] v;
+
+        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
+        public static byte get() { return ((byte[][])c.v)[0][0]; }
+        public static byte[] get1() { return (byte[])(c.v[0]); }
+        public static Object[] get2() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new byte[1][1]; ((byte[][])c.v)[0][0] = 1; byte val1 = get();
+                                      ((byte[][])c.v)[0][0] = 2; byte val2 = get();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, 2);
+            }
+
+            {
+                c.v = new byte[1][1]; c.v[0] = new byte[0]; byte[] val1 = get1();
+                                     c.v[0] = new byte[0]; byte[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new byte[0][0]; Object[] val1 = get2();
+                c.v = new byte[0][0]; Object[] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim2 {
+        public @Stable Object[][] v;
+
+        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
+        public static byte get() { return ((byte[][][])c.v)[0][0][0]; }
+        public static byte[] get1() { return (byte[])(c.v[0][0]); }
+        public static byte[][] get2() { return (byte[][])(c.v[0]); }
+        public static Object[][] get3() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new byte[1][1][1]; ((byte[][][])c.v)[0][0][0] = 1;  byte val1 = get();
+                                         ((byte[][][])c.v)[0][0][0] = 2; byte val2 = get();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, 2);
+            }
+
+            {
+                c.v = new byte[1][1][1]; c.v[0][0] = new byte[0]; byte[] val1 = get1();
+                                         c.v[0][0] = new byte[0]; byte[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new byte[1][1][1]; c.v[0] = new byte[0][0]; byte[][] val1 = get2();
+                                         c.v[0] = new byte[0][0]; byte[][] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new byte[0][0][0]; Object[][] val1 = get3();
+                c.v = new byte[0][0][0]; Object[][] val2 = get3();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField {
+        static class A {
+            public @Stable byte a;
+
+        }
+        public @Stable A v;
+
+        public static final NestedStableField c = new NestedStableField();
+        public static A get() { return c.v; }
+        public static byte get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.a = 1; A val1 = get();
+                               c.v.a = 2; A val2 = get();
+
+                assertEquals(val1.a, 2);
+                assertEquals(val2.a, 2);
+            }
+
+            {
+                c.v = new A(); c.v.a = 1; byte val1 = get1();
+                               c.v.a = 2; byte val2 = get1();
+                c.v = new A(); c.v.a = 3; byte val3 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField1 {
+        static class A {
+            public @Stable byte a;
+            public @Stable A next;
+        }
+        public @Stable A v;
+
+        public static final NestedStableField1 c = new NestedStableField1();
+        public static A get() { return c.v.next.next.next.next.next.next.next; }
+        public static byte get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
+                               c.v.a = 1; c.v.next.a = 1; A val1 = get();
+                               c.v.a = 2; c.v.next.a = 2; A val2 = get();
+
+                assertEquals(val1.a, 2);
+                assertEquals(val2.a, 2);
+            }
+
+            {
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 1; byte val1 = get1();
+                               c.v.a = 2; byte val2 = get1();
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 3; byte val3 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+        }
+    }
+   /* ==================================================== */
+
+    static class NestedStableField2 {
+        static class A {
+            public @Stable byte a;
+            public @Stable A left;
+            public         A right;
+        }
+
+        public @Stable A v;
+
+        public static final NestedStableField2 c = new NestedStableField2();
+        public static byte get() { return c.v.left.left.left.a; }
+        public static byte get1() { return c.v.left.left.right.left.a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.left = c.v.right = c.v;
+                               c.v.a = 1; byte val1 = get(); byte val2 = get1();
+                               c.v.a = 2; byte val3 = get(); byte val4 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val3, (isStableEnabled ? 1 : 2));
+
+                assertEquals(val2, 1);
+                assertEquals(val4, 2);
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField3 {
+        static class A {
+            public @Stable byte a;
+            public @Stable A[] left;
+            public         A[] right;
+        }
+
+        public @Stable A[] v;
+
+        public static final NestedStableField3 c = new NestedStableField3();
+        public static byte get() { return c.v[0].left[1].left[0].left[1].a; }
+        public static byte get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
+
+        public static void test() throws Exception {
+            {
+                A elem = new A();
+                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
+                               elem.a = 1; byte val1 = get(); byte val2 = get1();
+                               elem.a = 2; byte val3 = get(); byte val4 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val3, (isStableEnabled ? 1 : 2));
+
+                assertEquals(val2, 1);
+                assertEquals(val4, 2);
+            }
+        }
+    }
+
+    /* ==================================================== */
+    // Auxiliary methods
+    static void assertEquals(int i, int j) { if (i != j)  throw new AssertionError(i + " != " + j); }
+    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
+
+    static boolean failed = false;
+
+    public static void run(Class<?> test) {
+        Throwable ex = null;
+        System.out.print(test.getName()+": ");
+        try {
+            test.getMethod("test").invoke(null);
+        } catch (InvocationTargetException e) {
+            ex = e.getCause();
+        } catch (Throwable e) {
+            ex = e;
+        } finally {
+            if (ex == null) {
+                System.out.println("PASSED");
+            } else {
+                failed = true;
+                System.out.println("FAILED");
+                ex.printStackTrace(System.out);
+            }
+        }
+    }
+
+    static final boolean isStableEnabled;
+    static {
+        HotSpotDiagnosticMXBean diagnostic
+                = ManagementFactoryHelper.getDiagnosticMXBean();
+        VMOption tmp;
+        try {
+            tmp = diagnostic.getVMOption("FoldStableValues");
+        } catch (IllegalArgumentException e) {
+            tmp = null;
+        }
+        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/stable/TestStableChar.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,631 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestStableChar
+ * @summary tests on stable fields and arrays
+ * @library /testlibrary
+ * @compile -XDignore.symbol.file TestStableChar.java
+ * @run main ClassFileInstaller
+ *           java/lang/invoke/TestStableChar
+ *           java/lang/invoke/TestStableChar$CharStable
+ *           java/lang/invoke/TestStableChar$StaticCharStable
+ *           java/lang/invoke/TestStableChar$VolatileCharStable
+ *           java/lang/invoke/TestStableChar$CharArrayDim1
+ *           java/lang/invoke/TestStableChar$CharArrayDim2
+ *           java/lang/invoke/TestStableChar$CharArrayDim3
+ *           java/lang/invoke/TestStableChar$CharArrayDim4
+ *           java/lang/invoke/TestStableChar$ObjectArrayLowerDim0
+ *           java/lang/invoke/TestStableChar$ObjectArrayLowerDim1
+ *           java/lang/invoke/TestStableChar$NestedStableField
+ *           java/lang/invoke/TestStableChar$NestedStableField$A
+ *           java/lang/invoke/TestStableChar$NestedStableField1
+ *           java/lang/invoke/TestStableChar$NestedStableField1$A
+ *           java/lang/invoke/TestStableChar$NestedStableField2
+ *           java/lang/invoke/TestStableChar$NestedStableField2$A
+ *           java/lang/invoke/TestStableChar$NestedStableField3
+ *           java/lang/invoke/TestStableChar$NestedStableField3$A
+ *           java/lang/invoke/TestStableChar$DefaultValue
+ *           java/lang/invoke/TestStableChar$ObjectArrayLowerDim2
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableChar
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableChar
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableChar
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableChar
+ */
+package java.lang.invoke;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import sun.management.ManagementFactoryHelper;
+import java.lang.reflect.InvocationTargetException;
+
+public class TestStableChar {
+    public static void main(String[] args) throws Exception {
+        System.out.println("@Stable enabled: "+isStableEnabled);
+        System.out.println();
+
+        run(DefaultValue.class);
+        run(CharStable.class);
+        run(StaticCharStable.class);
+        run(VolatileCharStable.class);
+
+        // @Stable arrays: Dim 1-4
+        run(CharArrayDim1.class);
+        run(CharArrayDim2.class);
+        run(CharArrayDim3.class);
+        run(CharArrayDim4.class);
+
+        // @Stable Object field: dynamic arrays
+        run(ObjectArrayLowerDim0.class);
+        run(ObjectArrayLowerDim1.class);
+        run(ObjectArrayLowerDim2.class);
+
+        // Nested @Stable fields
+        run(NestedStableField.class);
+        run(NestedStableField1.class);
+        run(NestedStableField2.class);
+        run(NestedStableField3.class);
+
+        if (failed) {
+            throw new Error("TEST FAILED");
+        }
+    }
+
+    /* ==================================================== */
+
+    static class DefaultValue {
+        public @Stable char v;
+
+        public static final DefaultValue c = new DefaultValue();
+        public static char get() { return c.v; }
+        public static void test() throws Exception {
+                       char val1 = get();
+            c.v = 'a'; char val2 = get();
+            assertEquals(val1, 0);
+            assertEquals(val2, 'a');
+        }
+    }
+
+    /* ==================================================== */
+
+    static class CharStable {
+        public @Stable char v;
+
+        public static final CharStable c = new CharStable();
+        public static char get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 'a'; char val1 = get();
+            c.v = 'b'; char val2 = get();
+            assertEquals(val1, 'a');
+            assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class StaticCharStable {
+        public @Stable char v;
+
+        public static final StaticCharStable c = new StaticCharStable();
+        public static char get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 'a'; char val1 = get();
+            c.v = 'b'; char val2 = get();
+            assertEquals(val1, 'a');
+            assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class VolatileCharStable {
+        public @Stable volatile char v;
+
+        public static final VolatileCharStable c = new VolatileCharStable();
+        public static char get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 'a'; char val1 = get();
+            c.v = 'b'; char val2 = get();
+            assertEquals(val1, 'a');
+            assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
+        }
+    }
+
+    /* ==================================================== */
+    // @Stable array == field && all components are stable
+
+    static class CharArrayDim1 {
+        public @Stable char[] v;
+
+        public static final CharArrayDim1 c = new CharArrayDim1();
+        public static char get() { return c.v[0]; }
+        public static char get1() { return c.v[10]; }
+        public static char[] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new char[1]; c.v[0] = 'a'; char val1 = get();
+                                   c.v[0] = 'b'; char val2 = get();
+                assertEquals(val1, 'a');
+                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
+
+                c.v = new char[1]; c.v[0] = 'c'; char val3 = get();
+                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
+            }
+
+            {
+                c.v = new char[20]; c.v[10] = 'a'; char val1 = get1();
+                                    c.v[10] = 'b'; char val2 = get1();
+                assertEquals(val1, 'a');
+                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
+
+                c.v = new char[20]; c.v[10] = 'c'; char val3 = get1();
+                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
+            }
+
+            {
+                c.v = new char[1]; char[] val1 = get2();
+                c.v = new char[1]; char[] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class CharArrayDim2 {
+        public @Stable char[][] v;
+
+        public static final CharArrayDim2 c = new CharArrayDim2();
+        public static char get() { return c.v[0][0]; }
+        public static char[] get1() { return c.v[0]; }
+        public static char[][] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new char[1][1]; c.v[0][0] = 'a'; char val1 = get();
+                                      c.v[0][0] = 'b'; char val2 = get();
+                assertEquals(val1, 'a');
+                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
+
+                c.v = new char[1][1]; c.v[0][0] = 'c'; char val3 = get();
+                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
+
+                c.v[0] = new char[1]; c.v[0][0] = 'd'; char val4 = get();
+                assertEquals(val4, (isStableEnabled ? 'a' : 'd'));
+            }
+
+            {
+                c.v = new char[1][1]; char[] val1 = get1();
+                c.v[0] = new char[1]; char[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new char[1][1]; char[][] val1 = get2();
+                c.v = new char[1][1]; char[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class CharArrayDim3 {
+        public @Stable char[][][] v;
+
+        public static final CharArrayDim3 c = new CharArrayDim3();
+        public static char get() { return c.v[0][0][0]; }
+        public static char[] get1() { return c.v[0][0]; }
+        public static char[][] get2() { return c.v[0]; }
+        public static char[][][] get3() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new char[1][1][1]; c.v[0][0][0] = 'a'; char val1 = get();
+                                         c.v[0][0][0] = 'b'; char val2 = get();
+                assertEquals(val1, 'a');
+                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
+
+                c.v = new char[1][1][1]; c.v[0][0][0] = 'c'; char val3 = get();
+                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
+
+                c.v[0] = new char[1][1]; c.v[0][0][0] = 'd'; char val4 = get();
+                assertEquals(val4, (isStableEnabled ? 'a' : 'd'));
+
+                c.v[0][0] = new char[1]; c.v[0][0][0] = 'e'; char val5 = get();
+                assertEquals(val5, (isStableEnabled ? 'a' : 'e'));
+            }
+
+            {
+                c.v = new char[1][1][1]; char[] val1 = get1();
+                c.v[0][0] = new char[1]; char[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new char[1][1][1]; char[][] val1 = get2();
+                c.v[0] = new char[1][1]; char[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new char[1][1][1]; char[][][] val1 = get3();
+                c.v = new char[1][1][1]; char[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class CharArrayDim4 {
+        public @Stable char[][][][] v;
+
+        public static final CharArrayDim4 c = new CharArrayDim4();
+        public static char get() { return c.v[0][0][0][0]; }
+        public static char[] get1() { return c.v[0][0][0]; }
+        public static char[][] get2() { return c.v[0][0]; }
+        public static char[][][] get3() { return c.v[0]; }
+        public static char[][][][] get4() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new char[1][1][1][1]; c.v[0][0][0][0] = 'a'; char val1 = get();
+                                            c.v[0][0][0][0] = 'b'; char val2 = get();
+                assertEquals(val1, 'a');
+                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
+
+                c.v = new char[1][1][1][1]; c.v[0][0][0][0] = 'c'; char val3 = get();
+                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
+
+                c.v[0] = new char[1][1][1]; c.v[0][0][0][0] = 'd'; char val4 = get();
+                assertEquals(val4, (isStableEnabled ? 'a' : 'd'));
+
+                c.v[0][0] = new char[1][1]; c.v[0][0][0][0] = 'e'; char val5 = get();
+                assertEquals(val5, (isStableEnabled ? 'a' : 'e'));
+
+                c.v[0][0][0] = new char[1]; c.v[0][0][0][0] = 'f'; char val6 = get();
+                assertEquals(val6, (isStableEnabled ? 'a' : 'f'));
+            }
+
+            {
+                c.v = new char[1][1][1][1]; char[] val1 = get1();
+                c.v[0][0][0] = new char[1]; char[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new char[1][1][1][1]; char[][] val1 = get2();
+                c.v[0][0] = new char[1][1]; char[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new char[1][1][1][1]; char[][][] val1 = get3();
+                c.v[0] = new char[1][1][1]; char[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new char[1][1][1][1]; char[][][][] val1 = get4();
+                c.v = new char[1][1][1][1]; char[][][][] val2 = get4();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+        }
+    }
+
+    /* ==================================================== */
+    // Dynamic Dim is higher than static
+    static class ObjectArrayLowerDim0 {
+        public @Stable Object v;
+
+        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
+        public static char get() { return ((char[])c.v)[0]; }
+        public static char[] get1() { return (char[])c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new char[1]; ((char[])c.v)[0] = 'a'; char val1 = get();
+                                   ((char[])c.v)[0] = 'b'; char val2 = get();
+
+                assertEquals(val1, 'a');
+                assertEquals(val2, 'b');
+            }
+
+            {
+                c.v = new char[1]; char[] val1 = get1();
+                c.v = new char[1]; char[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim1 {
+        public @Stable Object[] v;
+
+        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
+        public static char get() { return ((char[][])c.v)[0][0]; }
+        public static char[] get1() { return (char[])(c.v[0]); }
+        public static Object[] get2() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new char[1][1]; ((char[][])c.v)[0][0] = 'a'; char val1 = get();
+                                      ((char[][])c.v)[0][0] = 'b'; char val2 = get();
+
+                assertEquals(val1, 'a');
+                assertEquals(val2, 'b');
+            }
+
+            {
+                c.v = new char[1][1]; c.v[0] = new char[0]; char[] val1 = get1();
+                                      c.v[0] = new char[0]; char[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new char[0][0]; Object[] val1 = get2();
+                c.v = new char[0][0]; Object[] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim2 {
+        public @Stable Object[][] v;
+
+        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
+        public static char get() { return ((char[][][])c.v)[0][0][0]; }
+        public static char[] get1() { return (char[])(c.v[0][0]); }
+        public static char[][] get2() { return (char[][])(c.v[0]); }
+        public static Object[][] get3() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new char[1][1][1]; ((char[][][])c.v)[0][0][0] = 'a';  char val1 = get();
+                                         ((char[][][])c.v)[0][0][0] = 'b'; char val2 = get();
+
+                assertEquals(val1, 'a');
+                assertEquals(val2, 'b');
+            }
+
+            {
+                c.v = new char[1][1][1]; c.v[0][0] = new char[0]; char[] val1 = get1();
+                                         c.v[0][0] = new char[0]; char[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new char[1][1][1]; c.v[0] = new char[0][0]; char[][] val1 = get2();
+                                         c.v[0] = new char[0][0]; char[][] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new char[0][0][0]; Object[][] val1 = get3();
+                c.v = new char[0][0][0]; Object[][] val2 = get3();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField {
+        static class A {
+            public @Stable char a;
+
+        }
+        public @Stable A v;
+
+        public static final NestedStableField c = new NestedStableField();
+        public static A get() { return c.v; }
+        public static char get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.a = 'a'; A val1 = get();
+                               c.v.a = 'b'; A val2 = get();
+
+                assertEquals(val1.a, 'b');
+                assertEquals(val2.a, 'b');
+            }
+
+            {
+                c.v = new A(); c.v.a = 'a'; char val1 = get1();
+                               c.v.a = 'b'; char val2 = get1();
+                c.v = new A(); c.v.a = 'c'; char val3 = get1();
+
+                assertEquals(val1, 'a');
+                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
+                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField1 {
+        static class A {
+            public @Stable char a;
+            public @Stable A next;
+        }
+        public @Stable A v;
+
+        public static final NestedStableField1 c = new NestedStableField1();
+        public static A get() { return c.v.next.next.next.next.next.next.next; }
+        public static char get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.next = new A(); c.v.next.next  = c.v;
+                               c.v.a = 'a'; c.v.next.a = 'a'; A val1 = get();
+                               c.v.a = 'b'; c.v.next.a = 'b'; A val2 = get();
+
+                assertEquals(val1.a, 'b');
+                assertEquals(val2.a, 'b');
+            }
+
+            {
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 'a'; char val1 = get1();
+                               c.v.a = 'b'; char val2 = get1();
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 'c'; char val3 = get1();
+
+                assertEquals(val1, 'a');
+                assertEquals(val2, (isStableEnabled ? 'a' : 'b'));
+                assertEquals(val3, (isStableEnabled ? 'a' : 'c'));
+            }
+        }
+    }
+   /* ==================================================== */
+
+    static class NestedStableField2 {
+        static class A {
+            public @Stable char a;
+            public @Stable A left;
+            public         A right;
+        }
+
+        public @Stable A v;
+
+        public static final NestedStableField2 c = new NestedStableField2();
+        public static char get() { return c.v.left.left.left.a; }
+        public static char get1() { return c.v.left.left.right.left.a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.left = c.v.right = c.v;
+                               c.v.a = 'a'; char val1 = get(); char val2 = get1();
+                               c.v.a = 'b'; char val3 = get(); char val4 = get1();
+
+                assertEquals(val1, 'a');
+                assertEquals(val3, (isStableEnabled ? 'a' : 'b'));
+
+                assertEquals(val2, 'a');
+                assertEquals(val4, 'b');
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField3 {
+        static class A {
+            public @Stable char a;
+            public @Stable A[] left;
+            public         A[] right;
+        }
+
+        public @Stable A[] v;
+
+        public static final NestedStableField3 c = new NestedStableField3();
+        public static char get() { return c.v[0].left[1].left[0].left[1].a; }
+        public static char get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
+
+        public static void test() throws Exception {
+            {
+                A elem = new A();
+                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
+                               elem.a = 'a'; char val1 = get(); char val2 = get1();
+                               elem.a = 'b'; char val3 = get(); char val4 = get1();
+
+                assertEquals(val1, 'a');
+                assertEquals(val3, (isStableEnabled ? 'a' : 'b'));
+
+                assertEquals(val2, 'a');
+                assertEquals(val4, 'b');
+            }
+        }
+    }
+
+    /* ==================================================== */
+    // Auxiliary methods
+    static void assertEquals(int i, int j) { if (i != j)  throw new AssertionError(i + " != " + j); }
+    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
+
+    static boolean failed = false;
+
+    public static void run(Class<?> test) {
+        Throwable ex = null;
+        System.out.print(test.getName()+": ");
+        try {
+            test.getMethod("test").invoke(null);
+        } catch (InvocationTargetException e) {
+            ex = e.getCause();
+        } catch (Throwable e) {
+            ex = e;
+        } finally {
+            if (ex == null) {
+                System.out.println("PASSED");
+            } else {
+                failed = true;
+                System.out.println("FAILED");
+                ex.printStackTrace(System.out);
+            }
+        }
+    }
+
+    static final boolean isStableEnabled;
+    static {
+        HotSpotDiagnosticMXBean diagnostic
+                = ManagementFactoryHelper.getDiagnosticMXBean();
+        VMOption tmp;
+        try {
+            tmp = diagnostic.getVMOption("FoldStableValues");
+        } catch (IllegalArgumentException e) {
+            tmp = null;
+        }
+        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/stable/TestStableDouble.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,632 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestStableDouble
+ * @summary tests on stable fields and arrays
+ * @library /testlibrary
+ * @compile -XDignore.symbol.file TestStableDouble.java
+ * @run main ClassFileInstaller
+ *           java/lang/invoke/TestStableDouble
+ *           java/lang/invoke/TestStableDouble$DoubleStable
+ *           java/lang/invoke/TestStableDouble$StaticDoubleStable
+ *           java/lang/invoke/TestStableDouble$VolatileDoubleStable
+ *           java/lang/invoke/TestStableDouble$DoubleArrayDim1
+ *           java/lang/invoke/TestStableDouble$DoubleArrayDim2
+ *           java/lang/invoke/TestStableDouble$DoubleArrayDim3
+ *           java/lang/invoke/TestStableDouble$DoubleArrayDim4
+ *           java/lang/invoke/TestStableDouble$ObjectArrayLowerDim0
+ *           java/lang/invoke/TestStableDouble$ObjectArrayLowerDim1
+ *           java/lang/invoke/TestStableDouble$NestedStableField
+ *           java/lang/invoke/TestStableDouble$NestedStableField$A
+ *           java/lang/invoke/TestStableDouble$NestedStableField1
+ *           java/lang/invoke/TestStableDouble$NestedStableField1$A
+ *           java/lang/invoke/TestStableDouble$NestedStableField2
+ *           java/lang/invoke/TestStableDouble$NestedStableField2$A
+ *           java/lang/invoke/TestStableDouble$NestedStableField3
+ *           java/lang/invoke/TestStableDouble$NestedStableField3$A
+ *           java/lang/invoke/TestStableDouble$DefaultValue
+ *           java/lang/invoke/TestStableDouble$ObjectArrayLowerDim2
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableDouble
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableDouble
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableDouble
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableDouble
+ */
+package java.lang.invoke;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import sun.management.ManagementFactoryHelper;
+import java.lang.reflect.InvocationTargetException;
+
+public class TestStableDouble {
+    public static void main(String[] args) throws Exception {
+        System.out.println("@Stable enabled: "+isStableEnabled);
+        System.out.println();
+
+        run(DefaultValue.class);
+        run(DoubleStable.class);
+        run(StaticDoubleStable.class);
+        run(VolatileDoubleStable.class);
+
+        // @Stable arrays: Dim 1-4
+        run(DoubleArrayDim1.class);
+        run(DoubleArrayDim2.class);
+        run(DoubleArrayDim3.class);
+        run(DoubleArrayDim4.class);
+
+        // @Stable Object field: dynamic arrays
+        run(ObjectArrayLowerDim0.class);
+        run(ObjectArrayLowerDim1.class);
+        run(ObjectArrayLowerDim2.class);
+
+        // Nested @Stable fields
+        run(NestedStableField.class);
+        run(NestedStableField1.class);
+        run(NestedStableField2.class);
+        run(NestedStableField3.class);
+
+        if (failed) {
+            throw new Error("TEST FAILED");
+        }
+    }
+
+    /* ==================================================== */
+
+    static class DefaultValue {
+        public @Stable double v;
+
+        public static final DefaultValue c = new DefaultValue();
+        public static double get() { return c.v; }
+        public static void test() throws Exception {
+                       double val1 = get();
+            c.v = 1.0; double val2 = get();
+            assertEquals(val1, 0);
+            assertEquals(val2, 1.0);
+        }
+    }
+
+    /* ==================================================== */
+
+    static class DoubleStable {
+        public @Stable double v;
+
+        public static final DoubleStable c = new DoubleStable();
+        public static double get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 1.0; double val1 = get();
+            c.v = Double.MAX_VALUE; double val2 = get();
+            assertEquals(val1, 1.0);
+            assertEquals(val2, (isStableEnabled ? 1.0 : Double.MAX_VALUE));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class StaticDoubleStable {
+        public static @Stable double v;
+
+        public static final StaticDoubleStable c = new StaticDoubleStable();
+        public static double get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 1.0; double val1 = get();
+            c.v = Double.MAX_VALUE; double val2 = get();
+            assertEquals(val1, 1.0);
+            assertEquals(val2, (isStableEnabled ? 1.0 : Double.MAX_VALUE));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class VolatileDoubleStable {
+        public @Stable double v;
+
+        public static final VolatileDoubleStable c = new VolatileDoubleStable();
+        public static double get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 1.0; double val1 = get();
+            c.v = Double.MAX_VALUE; double val2 = get();
+            assertEquals(val1, 1.0);
+            assertEquals(val2, (isStableEnabled ? 1.0 : Double.MAX_VALUE));
+        }
+    }
+
+    /* ==================================================== */
+    // @Stable array == field && all components are stable
+
+    static class DoubleArrayDim1 {
+        public @Stable double[] v;
+
+        public static final DoubleArrayDim1 c = new DoubleArrayDim1();
+        public static double get() { return c.v[0]; }
+        public static double get1() { return c.v[10]; }
+        public static double[] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new double[1]; c.v[0] = 1.0; double val1 = get();
+                                     c.v[0] = 2.0; double val2 = get();
+                assertEquals(val1, 1.0);
+                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
+
+                c.v = new double[1]; c.v[0] = 3.0; double val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
+            }
+
+            {
+                c.v = new double[20]; c.v[10] = 1.0; double val1 = get1();
+                                      c.v[10] = 2.0; double val2 = get1();
+                assertEquals(val1, 1.0);
+                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
+
+                c.v = new double[20]; c.v[10] = 3.0; double val3 = get1();
+                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
+            }
+
+            {
+                c.v = new double[1]; double[] val1 = get2();
+                c.v = new double[1]; double[] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class DoubleArrayDim2 {
+        public @Stable double[][] v;
+
+        public static final DoubleArrayDim2 c = new DoubleArrayDim2();
+        public static double get() { return c.v[0][0]; }
+        public static double[] get1() { return c.v[0]; }
+        public static double[][] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new double[1][1]; c.v[0][0] = 1.0; double val1 = get();
+                                        c.v[0][0] = 2.0; double val2 = get();
+                assertEquals(val1, 1.0);
+                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
+
+                c.v = new double[1][1]; c.v[0][0] = 3.0; double val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
+
+                c.v[0] = new double[1]; c.v[0][0] = 4.0; double val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1.0 : 4.0));
+            }
+
+            {
+                c.v = new double[1][1]; double[] val1 = get1();
+                c.v[0] = new double[1]; double[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new double[1][1]; double[][] val1 = get2();
+                c.v = new double[1][1]; double[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class DoubleArrayDim3 {
+        public @Stable double[][][] v;
+
+        public static final DoubleArrayDim3 c = new DoubleArrayDim3();
+        public static double get() { return c.v[0][0][0]; }
+        public static double[] get1() { return c.v[0][0]; }
+        public static double[][] get2() { return c.v[0]; }
+        public static double[][][] get3() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new double[1][1][1]; c.v[0][0][0] = 1.0; double val1 = get();
+                                           c.v[0][0][0] = 2.0; double val2 = get();
+                assertEquals(val1, 1.0);
+                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
+
+                c.v = new double[1][1][1]; c.v[0][0][0] = 3.0; double val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
+
+                c.v[0] = new double[1][1]; c.v[0][0][0] = 4.0; double val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1.0 : 4.0));
+
+                c.v[0][0] = new double[1]; c.v[0][0][0] = 5.0; double val5 = get();
+                assertEquals(val5, (isStableEnabled ? 1.0 : 5.0));
+            }
+
+            {
+                c.v = new double[1][1][1]; double[] val1 = get1();
+                c.v[0][0] = new double[1]; double[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new double[1][1][1]; double[][] val1 = get2();
+                c.v[0] = new double[1][1]; double[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new double[1][1][1]; double[][][] val1 = get3();
+                c.v = new double[1][1][1]; double[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class DoubleArrayDim4 {
+        public @Stable double[][][][] v;
+
+        public static final DoubleArrayDim4 c = new DoubleArrayDim4();
+        public static double get() { return c.v[0][0][0][0]; }
+        public static double[] get1() { return c.v[0][0][0]; }
+        public static double[][] get2() { return c.v[0][0]; }
+        public static double[][][] get3() { return c.v[0]; }
+        public static double[][][][] get4() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new double[1][1][1][1]; c.v[0][0][0][0] = 1.0; double val1 = get();
+                                              c.v[0][0][0][0] = 2.0; double val2 = get();
+                assertEquals(val1, 1.0);
+                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
+
+                c.v = new double[1][1][1][1]; c.v[0][0][0][0] = 3.0; double val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
+
+                c.v[0] = new double[1][1][1]; c.v[0][0][0][0] = 4.0; double val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1.0 : 4.0));
+
+                c.v[0][0] = new double[1][1]; c.v[0][0][0][0] = 5.0; double val5 = get();
+                assertEquals(val5, (isStableEnabled ? 1.0 : 5.0));
+
+                c.v[0][0][0] = new double[1]; c.v[0][0][0][0] = 6.0; double val6 = get();
+                assertEquals(val6, (isStableEnabled ? 1.0 : 6.0));
+            }
+
+            {
+                c.v = new double[1][1][1][1]; double[] val1 = get1();
+                c.v[0][0][0] = new double[1]; double[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new double[1][1][1][1]; double[][] val1 = get2();
+                c.v[0][0] = new double[1][1]; double[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new double[1][1][1][1]; double[][][] val1 = get3();
+                c.v[0] = new double[1][1][1]; double[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new double[1][1][1][1]; double[][][][] val1 = get4();
+                c.v = new double[1][1][1][1]; double[][][][] val2 = get4();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+        }
+    }
+
+    /* ==================================================== */
+    // Dynamic Dim is higher than static
+
+    static class ObjectArrayLowerDim0 {
+        public @Stable Object v;
+
+        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
+        public static double get() { return ((double[])c.v)[0]; }
+        public static double[] get1() { return (double[])c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new double[1]; ((double[])c.v)[0] = 1.0; double val1 = get();
+                                     ((double[])c.v)[0] = 2.0; double val2 = get();
+
+                assertEquals(val1, 1.0);
+                assertEquals(val2, 2.0);
+            }
+
+            {
+                c.v = new double[1]; double[] val1 = get1();
+                c.v = new double[1]; double[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim1 {
+        public @Stable Object[] v;
+
+        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
+        public static double get() { return ((double[][])c.v)[0][0]; }
+        public static double[] get1() { return (double[])(c.v[0]); }
+        public static Object[] get2() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new double[1][1]; ((double[][])c.v)[0][0] = 1.0; double val1 = get();
+                                        ((double[][])c.v)[0][0] = 2.0; double val2 = get();
+
+                assertEquals(val1, 1.0);
+                assertEquals(val2, 2.0);
+            }
+
+            {
+                c.v = new double[1][1]; c.v[0] = new double[0]; double[] val1 = get1();
+                                        c.v[0] = new double[0]; double[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new double[0][0]; Object[] val1 = get2();
+                c.v = new double[0][0]; Object[] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim2 {
+        public @Stable Object[][] v;
+
+        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
+        public static double get() { return ((double[][][])c.v)[0][0][0]; }
+        public static double[] get1() { return (double[])(c.v[0][0]); }
+        public static double[][] get2() { return (double[][])(c.v[0]); }
+        public static Object[][] get3() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new double[1][1][1]; ((double[][][])c.v)[0][0][0] = 1.0; double val1 = get();
+                                           ((double[][][])c.v)[0][0][0] = 2.0; double val2 = get();
+
+                assertEquals(val1, 1.0);
+                assertEquals(val2, 2.0);
+            }
+
+            {
+                c.v = new double[1][1][1]; c.v[0][0] = new double[0]; double[] val1 = get1();
+                                           c.v[0][0] = new double[0]; double[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new double[1][1][1]; c.v[0] = new double[0][0]; double[][] val1 = get2();
+                                           c.v[0] = new double[0][0]; double[][] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new double[0][0][0]; Object[][] val1 = get3();
+                c.v = new double[0][0][0]; Object[][] val2 = get3();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField {
+        static class A {
+            public @Stable double a;
+
+        }
+        public @Stable A v;
+
+        public static final NestedStableField c = new NestedStableField();
+        public static A get() { return c.v; }
+        public static double get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.a = 1.0; A val1 = get();
+                               c.v.a = 2.0; A val2 = get();
+
+                assertEquals(val1.a, 2.0);
+                assertEquals(val2.a, 2.0);
+            }
+
+            {
+                c.v = new A(); c.v.a = 1.0; double val1 = get1();
+                               c.v.a = 2.0; double val2 = get1();
+                c.v = new A(); c.v.a = 3.0; double val3 = get1();
+
+                assertEquals(val1, 1.0);
+                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
+                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField1 {
+        static class A {
+            public @Stable double a;
+            public @Stable A next;
+        }
+        public @Stable A v;
+
+        public static final NestedStableField1 c = new NestedStableField1();
+        public static A get() { return c.v.next.next.next.next.next.next.next; }
+        public static double get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
+                               c.v.a = 1.0; c.v.next.a = 1.0; A val1 = get();
+                               c.v.a = 2.0; c.v.next.a = 2.0; A val2 = get();
+
+                assertEquals(val1.a, 2.0);
+                assertEquals(val2.a, 2.0);
+            }
+
+            {
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 1.0; double val1 = get1();
+                               c.v.a = 2.0; double val2 = get1();
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 3.0; double val3 = get1();
+
+                assertEquals(val1, 1.0);
+                assertEquals(val2, (isStableEnabled ? 1.0 : 2.0));
+                assertEquals(val3, (isStableEnabled ? 1.0 : 3.0));
+            }
+        }
+    }
+   /* ==================================================== */
+
+    static class NestedStableField2 {
+        static class A {
+            public @Stable double a;
+            public @Stable A left;
+            public         A right;
+        }
+
+        public @Stable A v;
+
+        public static final NestedStableField2 c = new NestedStableField2();
+        public static double get() { return c.v.left.left.left.a; }
+        public static double get1() { return c.v.left.left.right.left.a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.left = c.v.right = c.v;
+                               c.v.a = 1.0; double val1 = get(); double val2 = get1();
+                               c.v.a = 2.0; double val3 = get(); double val4 = get1();
+
+                assertEquals(val1, 1.0);
+                assertEquals(val3, (isStableEnabled ? 1.0 : 2.0));
+
+                assertEquals(val2, 1.0);
+                assertEquals(val4, 2.0);
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField3 {
+        static class A {
+            public @Stable double a;
+            public @Stable A[] left;
+            public         A[] right;
+        }
+
+        public @Stable A[] v;
+
+        public static final NestedStableField3 c = new NestedStableField3();
+        public static double get() { return c.v[0].left[1].left[0].left[1].a; }
+        public static double get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
+
+        public static void test() throws Exception {
+            {
+                A elem = new A();
+                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
+                               elem.a = 1.0; double val1 = get(); double val2 = get1();
+                               elem.a = 2.0; double val3 = get(); double val4 = get1();
+
+                assertEquals(val1, 1.0);
+                assertEquals(val3, (isStableEnabled ? 1.0 : 2.0));
+
+                assertEquals(val2, 1.0);
+                assertEquals(val4, 2.0);
+            }
+        }
+    }
+
+    /* ==================================================== */
+    // Auxiliary methods
+    static void assertEquals(double i, double j) { if (i != j)  throw new AssertionError(i + " != " + j); }
+    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
+
+    static boolean failed = false;
+
+    public static void run(Class<?> test) {
+        Throwable ex = null;
+        System.out.print(test.getName()+": ");
+        try {
+            test.getMethod("test").invoke(null);
+        } catch (InvocationTargetException e) {
+            ex = e.getCause();
+        } catch (Throwable e) {
+            ex = e;
+        } finally {
+            if (ex == null) {
+                System.out.println("PASSED");
+            } else {
+                failed = true;
+                System.out.println("FAILED");
+                ex.printStackTrace(System.out);
+            }
+        }
+    }
+
+    static final boolean isStableEnabled;
+    static {
+        HotSpotDiagnosticMXBean diagnostic
+                = ManagementFactoryHelper.getDiagnosticMXBean();
+        VMOption tmp;
+        try {
+            tmp = diagnostic.getVMOption("FoldStableValues");
+        } catch (IllegalArgumentException e) {
+            tmp = null;
+        }
+        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/stable/TestStableFloat.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,632 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestStableFloat
+ * @summary tests on stable fields and arrays
+ * @library /testlibrary
+ * @compile -XDignore.symbol.file TestStableFloat.java
+ * @run main ClassFileInstaller
+ *           java/lang/invoke/TestStableFloat
+ *           java/lang/invoke/TestStableFloat$FloatStable
+ *           java/lang/invoke/TestStableFloat$StaticFloatStable
+ *           java/lang/invoke/TestStableFloat$VolatileFloatStable
+ *           java/lang/invoke/TestStableFloat$FloatArrayDim1
+ *           java/lang/invoke/TestStableFloat$FloatArrayDim2
+ *           java/lang/invoke/TestStableFloat$FloatArrayDim3
+ *           java/lang/invoke/TestStableFloat$FloatArrayDim4
+ *           java/lang/invoke/TestStableFloat$ObjectArrayLowerDim0
+ *           java/lang/invoke/TestStableFloat$ObjectArrayLowerDim1
+ *           java/lang/invoke/TestStableFloat$NestedStableField
+ *           java/lang/invoke/TestStableFloat$NestedStableField$A
+ *           java/lang/invoke/TestStableFloat$NestedStableField1
+ *           java/lang/invoke/TestStableFloat$NestedStableField1$A
+ *           java/lang/invoke/TestStableFloat$NestedStableField2
+ *           java/lang/invoke/TestStableFloat$NestedStableField2$A
+ *           java/lang/invoke/TestStableFloat$NestedStableField3
+ *           java/lang/invoke/TestStableFloat$NestedStableField3$A
+ *           java/lang/invoke/TestStableFloat$DefaultValue
+ *           java/lang/invoke/TestStableFloat$ObjectArrayLowerDim2
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableFloat
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableFloat
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableFloat
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableFloat
+ */
+package java.lang.invoke;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import sun.management.ManagementFactoryHelper;
+import java.lang.reflect.InvocationTargetException;
+
+public class TestStableFloat {
+    public static void main(String[] args) throws Exception {
+        System.out.println("@Stable enabled: "+isStableEnabled);
+        System.out.println();
+
+        run(DefaultValue.class);
+        run(FloatStable.class);
+        run(StaticFloatStable.class);
+        run(VolatileFloatStable.class);
+
+        // @Stable arrays: Dim 1-4
+        run(FloatArrayDim1.class);
+        run(FloatArrayDim2.class);
+        run(FloatArrayDim3.class);
+        run(FloatArrayDim4.class);
+
+        // @Stable Object field: dynamic arrays
+        run(ObjectArrayLowerDim0.class);
+        run(ObjectArrayLowerDim1.class);
+        run(ObjectArrayLowerDim2.class);
+
+        // Nested @Stable fields
+        run(NestedStableField.class);
+        run(NestedStableField1.class);
+        run(NestedStableField2.class);
+        run(NestedStableField3.class);
+
+        if (failed) {
+            throw new Error("TEST FAILED");
+        }
+    }
+
+    /* ==================================================== */
+
+    static class DefaultValue {
+        public @Stable float v;
+
+        public static final DefaultValue c = new DefaultValue();
+        public static float get() { return c.v; }
+        public static void test() throws Exception {
+                        float val1 = get();
+            c.v = 1.0F; float val2 = get();
+            assertEquals(val1, 0F);
+            assertEquals(val2, 1.0F);
+        }
+    }
+
+    /* ==================================================== */
+
+    static class FloatStable {
+        public @Stable float v;
+
+        public static final FloatStable c = new FloatStable();
+        public static float get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 1.0F; float val1 = get();
+            c.v = 2.0F; float val2 = get();
+            assertEquals(val1, 1.0F);
+            assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class StaticFloatStable {
+        public static @Stable float v;
+
+        public static final StaticFloatStable c = new StaticFloatStable();
+        public static float get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 1.0F; float val1 = get();
+            c.v = 2.0F; float val2 = get();
+            assertEquals(val1, 1.0F);
+            assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class VolatileFloatStable {
+        public @Stable volatile float v;
+
+        public static final VolatileFloatStable c = new VolatileFloatStable();
+        public static float get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 1.0F; float val1 = get();
+            c.v = 2.0F; float val2 = get();
+            assertEquals(val1, 1.0F);
+            assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
+        }
+    }
+
+    /* ==================================================== */
+    // @Stable array == field && all components are stable
+
+    static class FloatArrayDim1 {
+        public @Stable float[] v;
+
+        public static final FloatArrayDim1 c = new FloatArrayDim1();
+        public static float get() { return c.v[0]; }
+        public static float get1() { return c.v[10]; }
+        public static float[] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new float[1]; c.v[0] = 1.0F; float val1 = get();
+                                    c.v[0] = 2.0F; float val2 = get();
+                assertEquals(val1, 1.0F);
+                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
+
+                c.v = new float[1]; c.v[0] = 3.0F; float val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
+            }
+
+            {
+                c.v = new float[20]; c.v[10] = 1.0F; float val1 = get1();
+                                     c.v[10] = 2.0F; float val2 = get1();
+                assertEquals(val1, 1.0F);
+                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
+
+                c.v = new float[20]; c.v[10] = 3.0F; float val3 = get1();
+                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
+            }
+
+            {
+                c.v = new float[1]; float[] val1 = get2();
+                c.v = new float[1]; float[] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class FloatArrayDim2 {
+        public @Stable float[][] v;
+
+        public static final FloatArrayDim2 c = new FloatArrayDim2();
+        public static float get() { return c.v[0][0]; }
+        public static float[] get1() { return c.v[0]; }
+        public static float[][] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new float[1][1]; c.v[0][0] = 1.0F; float val1 = get();
+                                       c.v[0][0] = 2.0F; float val2 = get();
+                assertEquals(val1, 1.0F);
+                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
+
+                c.v = new float[1][1]; c.v[0][0] = 3.0F; float val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
+
+                c.v[0] = new float[1]; c.v[0][0] = 4.0F; float val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1.0F : 4.0F));
+            }
+
+            {
+                c.v = new float[1][1]; float[] val1 = get1();
+                c.v[0] = new float[1]; float[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new float[1][1]; float[][] val1 = get2();
+                c.v = new float[1][1]; float[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class FloatArrayDim3 {
+        public @Stable float[][][] v;
+
+        public static final FloatArrayDim3 c = new FloatArrayDim3();
+        public static float get() { return c.v[0][0][0]; }
+        public static float[] get1() { return c.v[0][0]; }
+        public static float[][] get2() { return c.v[0]; }
+        public static float[][][] get3() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new float[1][1][1]; c.v[0][0][0] = 1.0F; float val1 = get();
+                                          c.v[0][0][0] = 2.0F; float val2 = get();
+                assertEquals(val1, 1.0F);
+                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
+
+                c.v = new float[1][1][1]; c.v[0][0][0] = 3.0F; float val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
+
+                c.v[0] = new float[1][1]; c.v[0][0][0] = 4.0F; float val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1.0F : 4.0F));
+
+                c.v[0][0] = new float[1]; c.v[0][0][0] = 5.0F; float val5 = get();
+                assertEquals(val5, (isStableEnabled ? 1.0F : 5.0F));
+            }
+
+            {
+                c.v = new float[1][1][1]; float[] val1 = get1();
+                c.v[0][0] = new float[1]; float[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new float[1][1][1]; float[][] val1 = get2();
+                c.v[0] = new float[1][1]; float[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new float[1][1][1]; float[][][] val1 = get3();
+                c.v = new float[1][1][1]; float[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class FloatArrayDim4 {
+        public @Stable float[][][][] v;
+
+        public static final FloatArrayDim4 c = new FloatArrayDim4();
+        public static float get() { return c.v[0][0][0][0]; }
+        public static float[] get1() { return c.v[0][0][0]; }
+        public static float[][] get2() { return c.v[0][0]; }
+        public static float[][][] get3() { return c.v[0]; }
+        public static float[][][][] get4() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new float[1][1][1][1]; c.v[0][0][0][0] = 1.0F; float val1 = get();
+                                             c.v[0][0][0][0] = 2.0F; float val2 = get();
+                assertEquals(val1, 1.0F);
+                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
+
+                c.v = new float[1][1][1][1]; c.v[0][0][0][0] = 3.0F; float val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
+
+                c.v[0] = new float[1][1][1]; c.v[0][0][0][0] = 4.0F; float val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1.0F : 4.0F));
+
+                c.v[0][0] = new float[1][1]; c.v[0][0][0][0] = 5.0F; float val5 = get();
+                assertEquals(val5, (isStableEnabled ? 1.0F : 5.0F));
+
+                c.v[0][0][0] = new float[1]; c.v[0][0][0][0] = 6.0F; float val6 = get();
+                assertEquals(val6, (isStableEnabled ? 1.0F : 6.0F));
+            }
+
+            {
+                c.v = new float[1][1][1][1]; float[] val1 = get1();
+                c.v[0][0][0] = new float[1]; float[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new float[1][1][1][1]; float[][] val1 = get2();
+                c.v[0][0] = new float[1][1]; float[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new float[1][1][1][1]; float[][][] val1 = get3();
+                c.v[0] = new float[1][1][1]; float[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new float[1][1][1][1]; float[][][][] val1 = get4();
+                c.v = new float[1][1][1][1]; float[][][][] val2 = get4();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+        }
+    }
+
+    /* ==================================================== */
+    // Dynamic Dim is higher than static
+
+    static class ObjectArrayLowerDim0 {
+        public @Stable Object v;
+
+        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
+        public static float get() { return ((float[])c.v)[0]; }
+        public static float[] get1() { return (float[])c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new float[1]; ((float[])c.v)[0] = 1.0F; float val1 = get();
+                                    ((float[])c.v)[0] = 2.0F; float val2 = get();
+
+                assertEquals(val1, 1.0F);
+                assertEquals(val2, 2.0F);
+            }
+
+            {
+                c.v = new float[1]; float[] val1 = get1();
+                c.v = new float[1]; float[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim1 {
+        public @Stable Object[] v;
+
+        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
+        public static float get() { return ((float[][])c.v)[0][0]; }
+        public static float[] get1() { return (float[])(c.v[0]); }
+        public static Object[] get2() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new float[1][1]; ((float[][])c.v)[0][0] = 1.0F; float val1 = get();
+                                       ((float[][])c.v)[0][0] = 2.0F; float val2 = get();
+
+                assertEquals(val1, 1.0F);
+                assertEquals(val2, 2.0F);
+            }
+
+            {
+                c.v = new float[1][1]; c.v[0] = new float[0]; float[] val1 = get1();
+                                       c.v[0] = new float[0]; float[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new float[0][0]; Object[] val1 = get2();
+                c.v = new float[0][0]; Object[] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim2 {
+        public @Stable Object[][] v;
+
+        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
+        public static float get() { return ((float[][][])c.v)[0][0][0]; }
+        public static float[] get1() { return (float[])(c.v[0][0]); }
+        public static float[][] get2() { return (float[][])(c.v[0]); }
+        public static Object[][] get3() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new float[1][1][1]; ((float[][][])c.v)[0][0][0] = 1.0F; float val1 = get();
+                                          ((float[][][])c.v)[0][0][0] = 2.0F; float val2 = get();
+
+                assertEquals(val1, 1.0F);
+                assertEquals(val2, 2.0F);
+            }
+
+            {
+                c.v = new float[1][1][1]; c.v[0][0] = new float[0]; float[] val1 = get1();
+                                          c.v[0][0] = new float[0]; float[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new float[1][1][1]; c.v[0] = new float[0][0]; float[][] val1 = get2();
+                                          c.v[0] = new float[0][0]; float[][] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new float[0][0][0]; Object[][] val1 = get3();
+                c.v = new float[0][0][0]; Object[][] val2 = get3();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField {
+        static class A {
+            public @Stable float a;
+
+        }
+        public @Stable A v;
+
+        public static final NestedStableField c = new NestedStableField();
+        public static A get() { return c.v; }
+        public static float get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.a = 1.0F; A val1 = get();
+                               c.v.a = 2.0F; A val2 = get();
+
+                assertEquals(val1.a, 2.0F);
+                assertEquals(val2.a, 2.0F);
+            }
+
+            {
+                c.v = new A(); c.v.a = 1.0F; float val1 = get1();
+                               c.v.a = 2.0F; float val2 = get1();
+                c.v = new A(); c.v.a = 3.0F; float val3 = get1();
+
+                assertEquals(val1, 1.0F);
+                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
+                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField1 {
+        static class A {
+            public @Stable float a;
+            public @Stable A next;
+        }
+        public @Stable A v;
+
+        public static final NestedStableField1 c = new NestedStableField1();
+        public static A get() { return c.v.next.next.next.next.next.next.next; }
+        public static float get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
+                               c.v.a = 1.0F; c.v.next.a = 1.0F; A val1 = get();
+                               c.v.a = 2.0F; c.v.next.a = 2.0F; A val2 = get();
+
+                assertEquals(val1.a, 2.0F);
+                assertEquals(val2.a, 2.0F);
+            }
+
+            {
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 1.0F; float val1 = get1();
+                               c.v.a = 2.0F; float val2 = get1();
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 3.0F; float val3 = get1();
+
+                assertEquals(val1, 1.0F);
+                assertEquals(val2, (isStableEnabled ? 1.0F : 2.0F));
+                assertEquals(val3, (isStableEnabled ? 1.0F : 3.0F));
+            }
+        }
+    }
+   /* ==================================================== */
+
+    static class NestedStableField2 {
+        static class A {
+            public @Stable float a;
+            public @Stable A left;
+            public         A right;
+        }
+
+        public @Stable A v;
+
+        public static final NestedStableField2 c = new NestedStableField2();
+        public static float get() { return c.v.left.left.left.a; }
+        public static float get1() { return c.v.left.left.right.left.a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.left = c.v.right = c.v;
+                               c.v.a = 1.0F; float val1 = get(); float val2 = get1();
+                               c.v.a = 2.0F; float val3 = get(); float val4 = get1();
+
+                assertEquals(val1, 1.0F);
+                assertEquals(val3, (isStableEnabled ? 1.0F : 2.0F));
+
+                assertEquals(val2, 1.0F);
+                assertEquals(val4, 2.0F);
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField3 {
+        static class A {
+            public @Stable float a;
+            public @Stable A[] left;
+            public         A[] right;
+        }
+
+        public @Stable A[] v;
+
+        public static final NestedStableField3 c = new NestedStableField3();
+        public static float get() { return c.v[0].left[1].left[0].left[1].a; }
+        public static float get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
+
+        public static void test() throws Exception {
+            {
+                A elem = new A();
+                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
+                               elem.a = 1.0F; float val1 = get(); float val2 = get1();
+                               elem.a = 2.0F; float val3 = get(); float val4 = get1();
+
+                assertEquals(val1, 1.0F);
+                assertEquals(val3, (isStableEnabled ? 1.0F : 2.0F));
+
+                assertEquals(val2, 1.0F);
+                assertEquals(val4, 2.0F);
+            }
+        }
+    }
+
+    /* ==================================================== */
+    // Auxiliary methods
+    static void assertEquals(float i, float j) { if (i != j)  throw new AssertionError(i + " != " + j); }
+    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
+
+    static boolean failed = false;
+
+    public static void run(Class<?> test) {
+        Throwable ex = null;
+        System.out.print(test.getName()+": ");
+        try {
+            test.getMethod("test").invoke(null);
+        } catch (InvocationTargetException e) {
+            ex = e.getCause();
+        } catch (Throwable e) {
+            ex = e;
+        } finally {
+            if (ex == null) {
+                System.out.println("PASSED");
+            } else {
+                failed = true;
+                System.out.println("FAILED");
+                ex.printStackTrace(System.out);
+            }
+        }
+    }
+
+    static final boolean isStableEnabled;
+    static {
+        HotSpotDiagnosticMXBean diagnostic
+                = ManagementFactoryHelper.getDiagnosticMXBean();
+        VMOption tmp;
+        try {
+            tmp = diagnostic.getVMOption("FoldStableValues");
+        } catch (IllegalArgumentException e) {
+            tmp = null;
+        }
+        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/stable/TestStableInt.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,632 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestStableInt
+ * @summary tests on stable fields and arrays
+ * @library /testlibrary
+ * @compile -XDignore.symbol.file TestStableInt.java
+ * @run main ClassFileInstaller
+ *           java/lang/invoke/TestStableInt
+ *           java/lang/invoke/TestStableInt$IntStable
+ *           java/lang/invoke/TestStableInt$StaticIntStable
+ *           java/lang/invoke/TestStableInt$VolatileIntStable
+ *           java/lang/invoke/TestStableInt$IntArrayDim1
+ *           java/lang/invoke/TestStableInt$IntArrayDim2
+ *           java/lang/invoke/TestStableInt$IntArrayDim3
+ *           java/lang/invoke/TestStableInt$IntArrayDim4
+ *           java/lang/invoke/TestStableInt$ObjectArrayLowerDim0
+ *           java/lang/invoke/TestStableInt$ObjectArrayLowerDim1
+ *           java/lang/invoke/TestStableInt$NestedStableField
+ *           java/lang/invoke/TestStableInt$NestedStableField$A
+ *           java/lang/invoke/TestStableInt$NestedStableField1
+ *           java/lang/invoke/TestStableInt$NestedStableField1$A
+ *           java/lang/invoke/TestStableInt$NestedStableField2
+ *           java/lang/invoke/TestStableInt$NestedStableField2$A
+ *           java/lang/invoke/TestStableInt$NestedStableField3
+ *           java/lang/invoke/TestStableInt$NestedStableField3$A
+ *           java/lang/invoke/TestStableInt$DefaultValue
+ *           java/lang/invoke/TestStableInt$ObjectArrayLowerDim2
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableInt
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableInt
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableInt
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableInt
+ */
+package java.lang.invoke;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import sun.management.ManagementFactoryHelper;
+import java.lang.reflect.InvocationTargetException;
+
+public class TestStableInt {
+    public static void main(String[] args) throws Exception {
+        System.out.println("@Stable enabled: "+isStableEnabled);
+        System.out.println();
+
+        run(DefaultValue.class);
+        run(IntStable.class);
+        run(StaticIntStable.class);
+        run(VolatileIntStable.class);
+
+        // @Stable arrays: Dim 1-4
+        run(IntArrayDim1.class);
+        run(IntArrayDim2.class);
+        run(IntArrayDim3.class);
+        run(IntArrayDim4.class);
+
+        // @Stable Object field: dynamic arrays
+        run(ObjectArrayLowerDim0.class);
+        run(ObjectArrayLowerDim1.class);
+        run(ObjectArrayLowerDim2.class);
+
+        // Nested @Stable fields
+        run(NestedStableField.class);
+        run(NestedStableField1.class);
+        run(NestedStableField2.class);
+        run(NestedStableField3.class);
+
+        if (failed) {
+            throw new Error("TEST FAILED");
+        }
+    }
+
+    /* ==================================================== */
+
+    static class DefaultValue {
+        public @Stable int v;
+
+        public static final DefaultValue c = new DefaultValue();
+        public static int get() { return c.v; }
+        public static void test() throws Exception {
+                        int val1 = get();
+            c.v = 1; int val2 = get();
+            assertEquals(val1, 0);
+            assertEquals(val2, 1);
+        }
+    }
+
+    /* ==================================================== */
+
+    static class IntStable {
+        public @Stable int v;
+
+        public static final IntStable c = new IntStable();
+        public static int get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 1; int val1 = get();
+            c.v = 2; int val2 = get();
+            assertEquals(val1, 1);
+            assertEquals(val2, (isStableEnabled ? 1 : 2));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class StaticIntStable {
+        public static @Stable int v;
+
+        public static final StaticIntStable c = new StaticIntStable();
+        public static int get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 1; int val1 = get();
+            c.v = 2; int val2 = get();
+            assertEquals(val1, 1);
+            assertEquals(val2, (isStableEnabled ? 1 : 2));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class VolatileIntStable {
+        public @Stable volatile int v;
+
+        public static final VolatileIntStable c = new VolatileIntStable();
+        public static int get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 1; int val1 = get();
+            c.v = 2; int val2 = get();
+            assertEquals(val1, 1);
+            assertEquals(val2, (isStableEnabled ? 1 : 2));
+        }
+    }
+
+    /* ==================================================== */
+    // @Stable array == field && all components are stable
+
+    static class IntArrayDim1 {
+        public @Stable int[] v;
+
+        public static final IntArrayDim1 c = new IntArrayDim1();
+        public static int get() { return c.v[0]; }
+        public static int get1() { return c.v[10]; }
+        public static int[] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new int[1]; c.v[0] = 1; int val1 = get();
+                                  c.v[0] = 2; int val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new int[1]; c.v[0] = 3; int val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+
+            {
+                c.v = new int[20]; c.v[10] = 1; int val1 = get1();
+                                   c.v[10] = 2; int val2 = get1();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new int[20]; c.v[10] = 3; int val3 = get1();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+
+            {
+                c.v = new int[1]; int[] val1 = get2();
+                c.v = new int[1]; int[] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class IntArrayDim2 {
+        public @Stable int[][] v;
+
+        public static final IntArrayDim2 c = new IntArrayDim2();
+        public static int get() { return c.v[0][0]; }
+        public static int[] get1() { return c.v[0]; }
+        public static int[][] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new int[1][1]; c.v[0][0] = 1; int val1 = get();
+                                     c.v[0][0] = 2; int val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new int[1][1]; c.v[0][0] = 3; int val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+
+                c.v[0] = new int[1]; c.v[0][0] = 4; int val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1 : 4));
+            }
+
+            {
+                c.v = new int[1][1]; int[] val1 = get1();
+                c.v[0] = new int[1]; int[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new int[1][1]; int[][] val1 = get2();
+                c.v = new int[1][1]; int[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class IntArrayDim3 {
+        public @Stable int[][][] v;
+
+        public static final IntArrayDim3 c = new IntArrayDim3();
+        public static int get() { return c.v[0][0][0]; }
+        public static int[] get1() { return c.v[0][0]; }
+        public static int[][] get2() { return c.v[0]; }
+        public static int[][][] get3() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new int[1][1][1]; c.v[0][0][0] = 1; int val1 = get();
+                                        c.v[0][0][0] = 2; int val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new int[1][1][1]; c.v[0][0][0] = 3; int val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+
+                c.v[0] = new int[1][1]; c.v[0][0][0] = 4; int val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1 : 4));
+
+                c.v[0][0] = new int[1]; c.v[0][0][0] = 5; int val5 = get();
+                assertEquals(val5, (isStableEnabled ? 1 : 5));
+            }
+
+            {
+                c.v = new int[1][1][1]; int[] val1 = get1();
+                c.v[0][0] = new int[1]; int[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new int[1][1][1]; int[][] val1 = get2();
+                c.v[0] = new int[1][1]; int[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new int[1][1][1]; int[][][] val1 = get3();
+                c.v = new int[1][1][1]; int[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class IntArrayDim4 {
+        public @Stable int[][][][] v;
+
+        public static final IntArrayDim4 c = new IntArrayDim4();
+        public static int get() { return c.v[0][0][0][0]; }
+        public static int[] get1() { return c.v[0][0][0]; }
+        public static int[][] get2() { return c.v[0][0]; }
+        public static int[][][] get3() { return c.v[0]; }
+        public static int[][][][] get4() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new int[1][1][1][1]; c.v[0][0][0][0] = 1; int val1 = get();
+                                           c.v[0][0][0][0] = 2; int val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new int[1][1][1][1]; c.v[0][0][0][0] = 3; int val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+
+                c.v[0] = new int[1][1][1]; c.v[0][0][0][0] = 4; int val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1 : 4));
+
+                c.v[0][0] = new int[1][1]; c.v[0][0][0][0] = 5; int val5 = get();
+                assertEquals(val5, (isStableEnabled ? 1 : 5));
+
+                c.v[0][0][0] = new int[1]; c.v[0][0][0][0] = 6; int val6 = get();
+                assertEquals(val6, (isStableEnabled ? 1 : 6));
+            }
+
+            {
+                c.v = new int[1][1][1][1]; int[] val1 = get1();
+                c.v[0][0][0] = new int[1]; int[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new int[1][1][1][1]; int[][] val1 = get2();
+                c.v[0][0] = new int[1][1]; int[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new int[1][1][1][1]; int[][][] val1 = get3();
+                c.v[0] = new int[1][1][1]; int[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new int[1][1][1][1]; int[][][][] val1 = get4();
+                c.v = new int[1][1][1][1]; int[][][][] val2 = get4();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+        }
+    }
+
+    /* ==================================================== */
+    // Dynamic Dim is higher than static
+
+    static class ObjectArrayLowerDim0 {
+        public @Stable Object v;
+
+        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
+        public static int get() { return ((int[])c.v)[0]; }
+        public static int[] get1() { return (int[])c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new int[1]; ((int[])c.v)[0] = 1; int val1 = get();
+                                  ((int[])c.v)[0] = 2; int val2 = get();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, 2);
+            }
+
+            {
+                c.v = new int[1]; int[] val1 = get1();
+                c.v = new int[1]; int[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim1 {
+        public @Stable Object[] v;
+
+        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
+        public static int get() { return ((int[][])c.v)[0][0]; }
+        public static int[] get1() { return (int[])(c.v[0]); }
+        public static Object[] get2() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new int[1][1]; ((int[][])c.v)[0][0] = 1; int val1 = get();
+                                     ((int[][])c.v)[0][0] = 2; int val2 = get();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, 2);
+            }
+
+            {
+                c.v = new int[1][1]; c.v[0] = new int[0]; int[] val1 = get1();
+                                     c.v[0] = new int[0]; int[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new int[0][0]; Object[] val1 = get2();
+                c.v = new int[0][0]; Object[] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim2 {
+        public @Stable Object[][] v;
+
+        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
+        public static int get() { return ((int[][][])c.v)[0][0][0]; }
+        public static int[] get1() { return (int[])(c.v[0][0]); }
+        public static int[][] get2() { return (int[][])(c.v[0]); }
+        public static Object[][] get3() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new int[1][1][1]; ((int[][][])c.v)[0][0][0] = 1; int val1 = get();
+                                        ((int[][][])c.v)[0][0][0] = 2; int val2 = get();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, 2);
+            }
+
+            {
+                c.v = new int[1][1][1]; c.v[0][0] = new int[0]; int[] val1 = get1();
+                                        c.v[0][0] = new int[0]; int[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new int[1][1][1]; c.v[0] = new int[0][0]; int[][] val1 = get2();
+                                        c.v[0] = new int[0][0]; int[][] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new int[0][0][0]; Object[][] val1 = get3();
+                c.v = new int[0][0][0]; Object[][] val2 = get3();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField {
+        static class A {
+            public @Stable int a;
+
+        }
+        public @Stable A v;
+
+        public static final NestedStableField c = new NestedStableField();
+        public static A get() { return c.v; }
+        public static int get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.a = 1; A val1 = get();
+                               c.v.a = 2; A val2 = get();
+
+                assertEquals(val1.a, 2);
+                assertEquals(val2.a, 2);
+            }
+
+            {
+                c.v = new A(); c.v.a = 1; int val1 = get1();
+                               c.v.a = 2; int val2 = get1();
+                c.v = new A(); c.v.a = 3; int val3 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField1 {
+        static class A {
+            public @Stable int a;
+            public @Stable A next;
+        }
+        public @Stable A v;
+
+        public static final NestedStableField1 c = new NestedStableField1();
+        public static A get() { return c.v.next.next.next.next.next.next.next; }
+        public static int get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
+                               c.v.a = 1; c.v.next.a = 1; A val1 = get();
+                               c.v.a = 2; c.v.next.a = 2; A val2 = get();
+
+                assertEquals(val1.a, 2);
+                assertEquals(val2.a, 2);
+            }
+
+            {
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 1; int val1 = get1();
+                               c.v.a = 2; int val2 = get1();
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 3; int val3 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+        }
+    }
+   /* ==================================================== */
+
+    static class NestedStableField2 {
+        static class A {
+            public @Stable int a;
+            public @Stable A left;
+            public         A right;
+        }
+
+        public @Stable A v;
+
+        public static final NestedStableField2 c = new NestedStableField2();
+        public static int get() { return c.v.left.left.left.a; }
+        public static int get1() { return c.v.left.left.right.left.a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.left = c.v.right = c.v;
+                               c.v.a = 1; int val1 = get(); int val2 = get1();
+                               c.v.a = 2; int val3 = get(); int val4 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val3, (isStableEnabled ? 1 : 2));
+
+                assertEquals(val2, 1);
+                assertEquals(val4, 2);
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField3 {
+        static class A {
+            public @Stable int a;
+            public @Stable A[] left;
+            public         A[] right;
+        }
+
+        public @Stable A[] v;
+
+        public static final NestedStableField3 c = new NestedStableField3();
+        public static int get() { return c.v[0].left[1].left[0].left[1].a; }
+        public static int get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
+
+        public static void test() throws Exception {
+            {
+                A elem = new A();
+                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
+                               elem.a = 1; int val1 = get(); int val2 = get1();
+                               elem.a = 2; int val3 = get(); int val4 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val3, (isStableEnabled ? 1 : 2));
+
+                assertEquals(val2, 1);
+                assertEquals(val4, 2);
+            }
+        }
+    }
+
+    /* ==================================================== */
+    // Auxiliary methods
+    static void assertEquals(int i, int j) { if (i != j)  throw new AssertionError(i + " != " + j); }
+    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
+
+    static boolean failed = false;
+
+    public static void run(Class<?> test) {
+        Throwable ex = null;
+        System.out.print(test.getName()+": ");
+        try {
+            test.getMethod("test").invoke(null);
+        } catch (InvocationTargetException e) {
+            ex = e.getCause();
+        } catch (Throwable e) {
+            ex = e;
+        } finally {
+            if (ex == null) {
+                System.out.println("PASSED");
+            } else {
+                failed = true;
+                System.out.println("FAILED");
+                ex.printStackTrace(System.out);
+            }
+        }
+    }
+
+    static final boolean isStableEnabled;
+    static {
+        HotSpotDiagnosticMXBean diagnostic
+                = ManagementFactoryHelper.getDiagnosticMXBean();
+        VMOption tmp;
+        try {
+            tmp = diagnostic.getVMOption("FoldStableValues");
+        } catch (IllegalArgumentException e) {
+            tmp = null;
+        }
+        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/stable/TestStableLong.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,632 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestStableLong
+ * @summary tests on stable fields and arrays
+ * @library /testlibrary
+ * @compile -XDignore.symbol.file TestStableLong.java
+ * @run main ClassFileInstaller
+ *           java/lang/invoke/TestStableLong
+ *           java/lang/invoke/TestStableLong$LongStable
+ *           java/lang/invoke/TestStableLong$StaticLongStable
+ *           java/lang/invoke/TestStableLong$VolatileLongStable
+ *           java/lang/invoke/TestStableLong$LongArrayDim1
+ *           java/lang/invoke/TestStableLong$LongArrayDim2
+ *           java/lang/invoke/TestStableLong$LongArrayDim3
+ *           java/lang/invoke/TestStableLong$LongArrayDim4
+ *           java/lang/invoke/TestStableLong$ObjectArrayLowerDim0
+ *           java/lang/invoke/TestStableLong$ObjectArrayLowerDim1
+ *           java/lang/invoke/TestStableLong$NestedStableField
+ *           java/lang/invoke/TestStableLong$NestedStableField$A
+ *           java/lang/invoke/TestStableLong$NestedStableField1
+ *           java/lang/invoke/TestStableLong$NestedStableField1$A
+ *           java/lang/invoke/TestStableLong$NestedStableField2
+ *           java/lang/invoke/TestStableLong$NestedStableField2$A
+ *           java/lang/invoke/TestStableLong$NestedStableField3
+ *           java/lang/invoke/TestStableLong$NestedStableField3$A
+ *           java/lang/invoke/TestStableLong$DefaultValue
+ *           java/lang/invoke/TestStableLong$ObjectArrayLowerDim2
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableLong
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableLong
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableLong
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableLong
+ */
+package java.lang.invoke;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import sun.management.ManagementFactoryHelper;
+import java.lang.reflect.InvocationTargetException;
+
+public class TestStableLong {
+    public static void main(String[] args) throws Exception {
+        System.out.println("@Stable enabled: "+isStableEnabled);
+        System.out.println();
+
+        run(DefaultValue.class);
+        run(LongStable.class);
+        run(StaticLongStable.class);
+        run(VolatileLongStable.class);
+
+        // @Stable arrays: Dim 1-4
+        run(LongArrayDim1.class);
+        run(LongArrayDim2.class);
+        run(LongArrayDim3.class);
+        run(LongArrayDim4.class);
+
+        // @Stable Object field: dynamic arrays
+        run(ObjectArrayLowerDim0.class);
+        run(ObjectArrayLowerDim1.class);
+        run(ObjectArrayLowerDim2.class);
+
+        // Nested @Stable fields
+        run(NestedStableField.class);
+        run(NestedStableField1.class);
+        run(NestedStableField2.class);
+        run(NestedStableField3.class);
+
+        if (failed) {
+            throw new Error("TEST FAILED");
+        }
+    }
+
+    /* ==================================================== */
+
+    static class DefaultValue {
+        public @Stable long v;
+
+        public static final DefaultValue c = new DefaultValue();
+        public static long get() { return c.v; }
+        public static void test() throws Exception {
+                      long val1 = get();
+            c.v = 1L; long val2 = get();
+            assertEquals(val1, 0);
+            assertEquals(val2, 1L);
+        }
+    }
+
+    /* ==================================================== */
+
+    static class LongStable {
+        public @Stable long v;
+
+        public static final LongStable c = new LongStable();
+        public static long get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 5;              long val1 = get();
+            c.v = Long.MAX_VALUE; long val2 = get();
+            assertEquals(val1, 5);
+            assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class StaticLongStable {
+        public static @Stable long v;
+
+        public static final StaticLongStable c = new StaticLongStable();
+        public static long get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 5;              long val1 = get();
+            c.v = Long.MAX_VALUE; long val2 = get();
+            assertEquals(val1, 5);
+            assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class VolatileLongStable {
+        public @Stable volatile long v;
+
+        public static final VolatileLongStable c = new VolatileLongStable();
+        public static long get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 5;              long val1 = get();
+            c.v = Long.MAX_VALUE; long val2 = get();
+            assertEquals(val1, 5);
+            assertEquals(val2, (isStableEnabled ? 5 : Long.MAX_VALUE));
+        }
+    }
+
+    /* ==================================================== */
+    // @Stable array == field && all components are stable
+
+    static class LongArrayDim1 {
+        public @Stable long[] v;
+
+        public static final LongArrayDim1 c = new LongArrayDim1();
+        public static long get() { return c.v[0]; }
+        public static long get1() { return c.v[10]; }
+        public static long[] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new long[1]; c.v[0] = 1; long val1 = get();
+                                   c.v[0] = 2; long val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new long[1]; c.v[0] = 3; long val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+
+            {
+                c.v = new long[20]; c.v[10] = 1; long val1 = get1();
+                                    c.v[10] = 2; long val2 = get1();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new long[20]; c.v[10] = 3; long val3 = get1();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+
+            {
+                c.v = new long[1]; long[] val1 = get2();
+                c.v = new long[1]; long[] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class LongArrayDim2 {
+        public @Stable long[][] v;
+
+        public static final LongArrayDim2 c = new LongArrayDim2();
+        public static long get() { return c.v[0][0]; }
+        public static long[] get1() { return c.v[0]; }
+        public static long[][] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new long[1][1]; c.v[0][0] = 1; long val1 = get();
+                                      c.v[0][0] = 2; long val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new long[1][1]; c.v[0][0] = 3; long val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+
+                c.v[0] = new long[1]; c.v[0][0] = 4; long val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1 : 4));
+            }
+
+            {
+                c.v = new long[1][1]; long[] val1 = get1();
+                c.v[0] = new long[1]; long[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new long[1][1]; long[][] val1 = get2();
+                c.v = new long[1][1]; long[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class LongArrayDim3 {
+        public @Stable long[][][] v;
+
+        public static final LongArrayDim3 c = new LongArrayDim3();
+        public static long get() { return c.v[0][0][0]; }
+        public static long[] get1() { return c.v[0][0]; }
+        public static long[][] get2() { return c.v[0]; }
+        public static long[][][] get3() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new long[1][1][1]; c.v[0][0][0] = 1; long val1 = get();
+                                         c.v[0][0][0] = 2; long val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new long[1][1][1]; c.v[0][0][0] = 3; long val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+
+                c.v[0] = new long[1][1]; c.v[0][0][0] = 4; long val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1 : 4));
+
+                c.v[0][0] = new long[1]; c.v[0][0][0] = 5; long val5 = get();
+                assertEquals(val5, (isStableEnabled ? 1 : 5));
+            }
+
+            {
+                c.v = new long[1][1][1]; long[] val1 = get1();
+                c.v[0][0] = new long[1]; long[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new long[1][1][1]; long[][] val1 = get2();
+                c.v[0] = new long[1][1]; long[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new long[1][1][1]; long[][][] val1 = get3();
+                c.v = new long[1][1][1]; long[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class LongArrayDim4 {
+        public @Stable long[][][][] v;
+
+        public static final LongArrayDim4 c = new LongArrayDim4();
+        public static long get() { return c.v[0][0][0][0]; }
+        public static long[] get1() { return c.v[0][0][0]; }
+        public static long[][] get2() { return c.v[0][0]; }
+        public static long[][][] get3() { return c.v[0]; }
+        public static long[][][][] get4() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new long[1][1][1][1]; c.v[0][0][0][0] = 1; long val1 = get();
+                                            c.v[0][0][0][0] = 2; long val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new long[1][1][1][1]; c.v[0][0][0][0] = 3; long val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+
+                c.v[0] = new long[1][1][1]; c.v[0][0][0][0] = 4; long val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1 : 4));
+
+                c.v[0][0] = new long[1][1]; c.v[0][0][0][0] = 5; long val5 = get();
+                assertEquals(val5, (isStableEnabled ? 1 : 5));
+
+                c.v[0][0][0] = new long[1]; c.v[0][0][0][0] = 6; long val6 = get();
+                assertEquals(val6, (isStableEnabled ? 1 : 6));
+            }
+
+            {
+                c.v = new long[1][1][1][1]; long[] val1 = get1();
+                c.v[0][0][0] = new long[1]; long[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new long[1][1][1][1]; long[][] val1 = get2();
+                c.v[0][0] = new long[1][1]; long[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new long[1][1][1][1]; long[][][] val1 = get3();
+                c.v[0] = new long[1][1][1]; long[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new long[1][1][1][1]; long[][][][] val1 = get4();
+                c.v = new long[1][1][1][1]; long[][][][] val2 = get4();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+        }
+    }
+
+    /* ==================================================== */
+    // Dynamic Dim is higher than static
+
+    static class ObjectArrayLowerDim0 {
+        public @Stable Object v;
+
+        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
+        public static long get() { return ((long[])c.v)[0]; }
+        public static long[] get1() { return (long[])c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new long[1]; ((long[])c.v)[0] = 1; long val1 = get();
+                                   ((long[])c.v)[0] = 2; long val2 = get();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, 2);
+            }
+
+            {
+                c.v = new long[1]; long[] val1 = get1();
+                c.v = new long[1]; long[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim1 {
+        public @Stable Object[] v;
+
+        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
+        public static long get() { return ((long[][])c.v)[0][0]; }
+        public static long[] get1() { return (long[])(c.v[0]); }
+        public static Object[] get2() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new long[1][1]; ((long[][])c.v)[0][0] = 1; long val1 = get();
+                                      ((long[][])c.v)[0][0] = 2; long val2 = get();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, 2);
+            }
+
+            {
+                c.v = new long[1][1]; c.v[0] = new long[0]; long[] val1 = get1();
+                                     c.v[0] = new long[0]; long[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new long[0][0]; Object[] val1 = get2();
+                c.v = new long[0][0]; Object[] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim2 {
+        public @Stable Object[][] v;
+
+        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
+        public static long get() { return ((long[][][])c.v)[0][0][0]; }
+        public static long[] get1() { return (long[])(c.v[0][0]); }
+        public static long[][] get2() { return (long[][])(c.v[0]); }
+        public static Object[][] get3() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new long[1][1][1]; ((long[][][])c.v)[0][0][0] = 1L; long val1 = get();
+                                         ((long[][][])c.v)[0][0][0] = 2L; long val2 = get();
+
+                assertEquals(val1, 1L);
+                assertEquals(val2, 2L);
+            }
+
+            {
+                c.v = new long[1][1][1]; c.v[0][0] = new long[0]; long[] val1 = get1();
+                                         c.v[0][0] = new long[0]; long[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new long[1][1][1]; c.v[0] = new long[0][0]; long[][] val1 = get2();
+                                         c.v[0] = new long[0][0]; long[][] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new long[0][0][0]; Object[][] val1 = get3();
+                c.v = new long[0][0][0]; Object[][] val2 = get3();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField {
+        static class A {
+            public @Stable long a;
+
+        }
+        public @Stable A v;
+
+        public static final NestedStableField c = new NestedStableField();
+        public static A get() { return c.v; }
+        public static long get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.a = 1; A val1 = get();
+                               c.v.a = 2; A val2 = get();
+
+                assertEquals(val1.a, 2);
+                assertEquals(val2.a, 2);
+            }
+
+            {
+                c.v = new A(); c.v.a = 1; long val1 = get1();
+                               c.v.a = 2; long val2 = get1();
+                c.v = new A(); c.v.a = 3; long val3 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField1 {
+        static class A {
+            public @Stable long a;
+            public @Stable A next;
+        }
+        public @Stable A v;
+
+        public static final NestedStableField1 c = new NestedStableField1();
+        public static A get() { return c.v.next.next.next.next.next.next.next; }
+        public static long get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
+                               c.v.a = 1; c.v.next.a = 1; A val1 = get();
+                               c.v.a = 2; c.v.next.a = 2; A val2 = get();
+
+                assertEquals(val1.a, 2);
+                assertEquals(val2.a, 2);
+            }
+
+            {
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 1; long val1 = get1();
+                               c.v.a = 2; long val2 = get1();
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 3; long val3 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+        }
+    }
+   /* ==================================================== */
+
+    static class NestedStableField2 {
+        static class A {
+            public @Stable long a;
+            public @Stable A left;
+            public         A right;
+        }
+
+        public @Stable A v;
+
+        public static final NestedStableField2 c = new NestedStableField2();
+        public static long get() { return c.v.left.left.left.a; }
+        public static long get1() { return c.v.left.left.right.left.a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.left = c.v.right = c.v;
+                               c.v.a = 1; long val1 = get(); long val2 = get1();
+                               c.v.a = 2; long val3 = get(); long val4 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val3, (isStableEnabled ? 1 : 2));
+
+                assertEquals(val2, 1);
+                assertEquals(val4, 2);
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField3 {
+        static class A {
+            public @Stable long a;
+            public @Stable A[] left;
+            public         A[] right;
+        }
+
+        public @Stable A[] v;
+
+        public static final NestedStableField3 c = new NestedStableField3();
+        public static long get() { return c.v[0].left[1].left[0].left[1].a; }
+        public static long get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
+
+        public static void test() throws Exception {
+            {
+                A elem = new A();
+                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
+                               elem.a = 1; long val1 = get(); long val2 = get1();
+                               elem.a = 2; long val3 = get(); long val4 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val3, (isStableEnabled ? 1 : 2));
+
+                assertEquals(val2, 1);
+                assertEquals(val4, 2);
+            }
+        }
+    }
+
+    /* ==================================================== */
+    // Auxiliary methods
+    static void assertEquals(long i, long j) { if (i != j)  throw new AssertionError(i + " != " + j); }
+    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
+
+    static boolean failed = false;
+
+    public static void run(Class<?> test) {
+        Throwable ex = null;
+        System.out.print(test.getName()+": ");
+        try {
+            test.getMethod("test").invoke(null);
+        } catch (InvocationTargetException e) {
+            ex = e.getCause();
+        } catch (Throwable e) {
+            ex = e;
+        } finally {
+            if (ex == null) {
+                System.out.println("PASSED");
+            } else {
+                failed = true;
+                System.out.println("FAILED");
+                ex.printStackTrace(System.out);
+            }
+        }
+    }
+
+    static final boolean isStableEnabled;
+    static {
+        HotSpotDiagnosticMXBean diagnostic
+                = ManagementFactoryHelper.getDiagnosticMXBean();
+        VMOption tmp;
+        try {
+            tmp = diagnostic.getVMOption("FoldStableValues");
+        } catch (IllegalArgumentException e) {
+            tmp = null;
+        }
+        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/stable/TestStableObject.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,635 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestStableObject
+ * @summary tests on stable fields and arrays
+ * @library /testlibrary
+ * @compile -XDignore.symbol.file TestStableObject.java
+ * @run main ClassFileInstaller
+ *           java/lang/invoke/TestStableObject
+ *           java/lang/invoke/TestStableObject$ObjectStable
+ *           java/lang/invoke/TestStableObject$StaticObjectStable
+ *           java/lang/invoke/TestStableObject$VolatileObjectStable
+ *           java/lang/invoke/TestStableObject$ObjectArrayDim1
+ *           java/lang/invoke/TestStableObject$ObjectArrayDim2
+ *           java/lang/invoke/TestStableObject$ObjectArrayDim3
+ *           java/lang/invoke/TestStableObject$ObjectArrayDim4
+ *           java/lang/invoke/TestStableObject$ObjectArrayLowerDim0
+ *           java/lang/invoke/TestStableObject$ObjectArrayLowerDim1
+ *           java/lang/invoke/TestStableObject$NestedStableField
+ *           java/lang/invoke/TestStableObject$NestedStableField$A
+ *           java/lang/invoke/TestStableObject$NestedStableField1
+ *           java/lang/invoke/TestStableObject$NestedStableField1$A
+ *           java/lang/invoke/TestStableObject$NestedStableField2
+ *           java/lang/invoke/TestStableObject$NestedStableField2$A
+ *           java/lang/invoke/TestStableObject$NestedStableField3
+ *           java/lang/invoke/TestStableObject$NestedStableField3$A
+ *           java/lang/invoke/TestStableObject$Values
+ *           java/lang/invoke/TestStableObject$DefaultValue
+ *           java/lang/invoke/TestStableObject$ObjectArrayLowerDim2
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableObject
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableObject
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableObject
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableObject
+ */
+package java.lang.invoke;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import sun.management.ManagementFactoryHelper;
+import java.lang.reflect.InvocationTargetException;
+
+public class TestStableObject {
+    public static void main(String[] args) throws Exception {
+        System.out.println("@Stable enabled: "+isStableEnabled);
+        System.out.println();
+
+        run(DefaultValue.class);
+        run(ObjectStable.class);
+        run(StaticObjectStable.class);
+        run(VolatileObjectStable.class);
+
+        // @Stable arrays: Dim 1-4
+        run(ObjectArrayDim1.class);
+        run(ObjectArrayDim2.class);
+        run(ObjectArrayDim3.class);
+        run(ObjectArrayDim4.class);
+
+        // @Stable Object field: dynamic arrays
+        run(ObjectArrayLowerDim0.class);
+        run(ObjectArrayLowerDim1.class);
+        run(ObjectArrayLowerDim2.class);
+
+        // Nested @Stable fields
+        run(NestedStableField.class);
+        run(NestedStableField1.class);
+        run(NestedStableField2.class);
+        run(NestedStableField3.class);
+
+        if (failed) {
+            throw new Error("TEST FAILED");
+        }
+    }
+
+    /* ==================================================== */
+
+    enum Values {A, B, C, D, E, F}
+
+    static class DefaultValue {
+        public @Stable Object v;
+
+        public static final DefaultValue c = new DefaultValue();
+        public static Object get() { return c.v; }
+        public static void test() throws Exception {
+                            Object val1 = get();
+            c.v = Values.A; Object val2 = get();
+            assertEquals(val1, null);
+            assertEquals(val2, Values.A);
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectStable {
+        public @Stable Values v;
+
+        public static final ObjectStable c = new ObjectStable ();
+        public static Values get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = Values.A; Values val1 = get();
+            c.v = Values.B; Values val2 = get();
+            assertEquals(val1, Values.A);
+            assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class StaticObjectStable {
+        public static @Stable Values v;
+
+        public static final ObjectStable c = new ObjectStable ();
+        public static Values get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = Values.A; Values val1 = get();
+            c.v = Values.B; Values val2 = get();
+            assertEquals(val1, Values.A);
+            assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class VolatileObjectStable {
+        public @Stable volatile Values v;
+
+        public static final VolatileObjectStable c = new VolatileObjectStable ();
+        public static Values get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = Values.A; Values val1 = get();
+            c.v = Values.B; Values val2 = get();
+            assertEquals(val1, Values.A);
+            assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
+        }
+    }
+
+    /* ==================================================== */
+    // @Stable array == field && all components are stable
+
+    static class ObjectArrayDim1 {
+        public @Stable Object[] v;
+
+        public static final ObjectArrayDim1 c = new ObjectArrayDim1();
+        public static Object get() { return c.v[0]; }
+        public static Object get1() { return c.v[10]; }
+        public static Object[] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new Object[1]; c.v[0] = Values.A; Object val1 = get();
+                                     c.v[0] = Values.B; Object val2 = get();
+                assertEquals(val1, Values.A);
+                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
+
+                c.v = new Object[1]; c.v[0] = Values.C; Object val3 = get();
+                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
+            }
+
+            {
+                c.v = new Object[20]; c.v[10] = Values.A; Object val1 = get1();
+                                      c.v[10] = Values.B; Object val2 = get1();
+                assertEquals(val1, Values.A);
+                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
+
+                c.v = new Object[20]; c.v[10] = Values.C; Object val3 = get1();
+                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
+            }
+
+            {
+                c.v = new Object[1]; Object[] val1 = get2();
+                c.v = new Object[1]; Object[] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayDim2 {
+        public @Stable Object[][] v;
+
+        public static final ObjectArrayDim2 c = new ObjectArrayDim2();
+        public static Object get() { return c.v[0][0]; }
+        public static Object[] get1() { return c.v[0]; }
+        public static Object[][] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new Object[1][1]; c.v[0][0] = Values.A; Object val1 = get();
+                                        c.v[0][0] = Values.B; Object val2 = get();
+                assertEquals(val1, Values.A);
+                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
+
+                c.v = new Object[1][1]; c.v[0][0] = Values.C; Object val3 = get();
+                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
+
+                c.v[0] = new Object[1]; c.v[0][0] = Values.D; Object val4 = get();
+                assertEquals(val4, (isStableEnabled ? Values.A : Values.D));
+            }
+
+            {
+                c.v = new Object[1][1]; Object[] val1 = get1();
+                c.v[0] = new Object[1]; Object[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new Object[1][1]; Object[][] val1 = get2();
+                c.v = new Object[1][1]; Object[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayDim3 {
+        public @Stable Object[][][] v;
+
+        public static final ObjectArrayDim3 c = new ObjectArrayDim3();
+        public static Object get() { return c.v[0][0][0]; }
+        public static Object[] get1() { return c.v[0][0]; }
+        public static Object[][] get2() { return c.v[0]; }
+        public static Object[][][] get3() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new Object[1][1][1]; c.v[0][0][0] = Values.A; Object val1 = get();
+                                           c.v[0][0][0] = Values.B; Object val2 = get();
+                assertEquals(val1, Values.A);
+                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
+
+                c.v = new Object[1][1][1]; c.v[0][0][0] = Values.C; Object val3 = get();
+                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
+
+                c.v[0] = new Object[1][1]; c.v[0][0][0] = Values.D; Object val4 = get();
+                assertEquals(val4, (isStableEnabled ? Values.A : Values.D));
+
+                c.v[0][0] = new Object[1]; c.v[0][0][0] = Values.E; Object val5 = get();
+                assertEquals(val5, (isStableEnabled ? Values.A : Values.E));
+            }
+
+            {
+                c.v = new Object[1][1][1]; Object[] val1 = get1();
+                c.v[0][0] = new Object[1]; Object[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new Object[1][1][1]; Object[][] val1 = get2();
+                c.v[0] = new Object[1][1]; Object[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new Object[1][1][1]; Object[][][] val1 = get3();
+                c.v = new Object[1][1][1]; Object[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayDim4 {
+        public @Stable Object[][][][] v;
+
+        public static final ObjectArrayDim4 c = new ObjectArrayDim4();
+        public static Object get() { return c.v[0][0][0][0]; }
+        public static Object[] get1() { return c.v[0][0][0]; }
+        public static Object[][] get2() { return c.v[0][0]; }
+        public static Object[][][] get3() { return c.v[0]; }
+        public static Object[][][][] get4() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new Object[1][1][1][1]; c.v[0][0][0][0] = Values.A; Object val1 = get();
+                                              c.v[0][0][0][0] = Values.B; Object val2 = get();
+                assertEquals(val1, Values.A);
+                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
+
+                c.v = new Object[1][1][1][1]; c.v[0][0][0][0] = Values.C; Object val3 = get();
+                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
+
+                c.v[0] = new Object[1][1][1]; c.v[0][0][0][0] = Values.D; Object val4 = get();
+                assertEquals(val4, (isStableEnabled ? Values.A : Values.D));
+
+                c.v[0][0] = new Object[1][1]; c.v[0][0][0][0] = Values.E; Object val5 = get();
+                assertEquals(val5, (isStableEnabled ? Values.A : Values.E));
+
+                c.v[0][0][0] = new Object[1]; c.v[0][0][0][0] = Values.F; Object val6 = get();
+                assertEquals(val6, (isStableEnabled ? Values.A : Values.F));
+            }
+
+            {
+                c.v = new Object[1][1][1][1]; Object[] val1 = get1();
+                c.v[0][0][0] = new Object[1]; Object[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new Object[1][1][1][1]; Object[][] val1 = get2();
+                c.v[0][0] = new Object[1][1]; Object[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new Object[1][1][1][1]; Object[][][] val1 = get3();
+                c.v[0] = new Object[1][1][1]; Object[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new Object[1][1][1][1]; Object[][][][] val1 = get4();
+                c.v = new Object[1][1][1][1]; Object[][][][] val2 = get4();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+        }
+    }
+
+    /* ==================================================== */
+    // Dynamic Dim is higher than static
+
+    static class ObjectArrayLowerDim0 {
+        public @Stable Object v;
+
+        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
+        public static Object get() { return ((Object[])c.v)[0]; }
+        public static Object[] get1() { return (Object[])c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new Object[1]; ((Object[])c.v)[0] = Values.A; Object val1 = get();
+                                     ((Object[])c.v)[0] = Values.B; Object val2 = get();
+
+                assertEquals(val1, Values.A);
+                assertEquals(val2, Values.B);
+            }
+
+            {
+                c.v = new Object[1]; Object[] val1 = get1();
+                c.v = new Object[1]; Object[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim1 {
+        public @Stable Object[] v;
+
+        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
+        public static Object get() { return ((Object[][])c.v)[0][0]; }
+        public static Object[] get1() { return (Object[])(c.v[0]); }
+        public static Object[] get2() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new Object[1][1]; ((Object[][])c.v)[0][0] = Values.A; Object val1 = get();
+                                        ((Object[][])c.v)[0][0] = Values.B; Object val2 = get();
+
+                assertEquals(val1, Values.A);
+                assertEquals(val2, Values.B);
+            }
+
+            {
+                c.v = new Object[1][1]; c.v[0] = new Object[0]; Object[] val1 = get1();
+                                     c.v[0] = new Object[0]; Object[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new Object[0][0]; Object[] val1 = get2();
+                c.v = new Object[0][0]; Object[] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim2 {
+        public @Stable Object[][] v;
+
+        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
+        public static Object get() { return ((Object[][][])c.v)[0][0][0]; }
+        public static Object[] get1() { return (Object[])(c.v[0][0]); }
+        public static Object[][] get2() { return (Object[][])(c.v[0]); }
+        public static Object[][] get3() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new Object[1][1][1]; ((Object[][][])c.v)[0][0][0] = Values.A; Object val1 = get();
+                                           ((Object[][][])c.v)[0][0][0] = Values.B; Object val2 = get();
+
+                assertEquals(val1, Values.A);
+                assertEquals(val2, Values.B);
+            }
+
+            {
+                c.v = new Object[1][1][1]; c.v[0][0] = new Object[0]; Object[] val1 = get1();
+                                           c.v[0][0] = new Object[0]; Object[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new Object[1][1][1]; c.v[0] = new Object[0][0]; Object[][] val1 = get2();
+                                           c.v[0] = new Object[0][0]; Object[][] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new Object[0][0][0]; Object[][] val1 = get3();
+                c.v = new Object[0][0][0]; Object[][] val2 = get3();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField {
+        static class A {
+            public @Stable Object a;
+
+        }
+        public @Stable A v;
+
+        public static final NestedStableField c = new NestedStableField();
+        public static A get() { return c.v; }
+        public static Object get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.a = Values.A; A val1 = get();
+                               c.v.a = Values.B; A val2 = get();
+
+                assertEquals(val1.a, Values.B);
+                assertEquals(val2.a, Values.B);
+            }
+
+            {
+                c.v = new A(); c.v.a = Values.A; Object val1 = get1();
+                               c.v.a = Values.B; Object val2 = get1();
+                c.v = new A(); c.v.a = Values.C; Object val3 = get1();
+
+                assertEquals(val1, Values.A);
+                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
+                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField1 {
+        static class A {
+            public @Stable Object a;
+            public @Stable A next;
+        }
+        public @Stable A v;
+
+        public static final NestedStableField1 c = new NestedStableField1();
+        public static A get() { return c.v.next.next.next.next.next.next.next; }
+        public static Object get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
+                               c.v.a = Values.A; c.v.next.a = Values.A; A val1 = get();
+                               c.v.a = Values.B; c.v.next.a = Values.B; A val2 = get();
+
+                assertEquals(val1.a, Values.B);
+                assertEquals(val2.a, Values.B);
+            }
+
+            {
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = Values.A; Object val1 = get1();
+                               c.v.a = Values.B; Object val2 = get1();
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = Values.C; Object val3 = get1();
+
+                assertEquals(val1, Values.A);
+                assertEquals(val2, (isStableEnabled ? Values.A : Values.B));
+                assertEquals(val3, (isStableEnabled ? Values.A : Values.C));
+            }
+        }
+    }
+   /* ==================================================== */
+
+    static class NestedStableField2 {
+        static class A {
+            public @Stable Object a;
+            public @Stable A left;
+            public         A right;
+        }
+
+        public @Stable A v;
+
+        public static final NestedStableField2 c = new NestedStableField2();
+        public static Object get() { return c.v.left.left.left.a; }
+        public static Object get1() { return c.v.left.left.right.left.a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.left = c.v.right = c.v;
+                               c.v.a = Values.A; Object val1 = get(); Object val2 = get1();
+                               c.v.a = Values.B; Object val3 = get(); Object val4 = get1();
+
+                assertEquals(val1, Values.A);
+                assertEquals(val3, (isStableEnabled ? Values.A : Values.B));
+
+                assertEquals(val2, Values.A);
+                assertEquals(val4, Values.B);
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField3 {
+        static class A {
+            public @Stable Object a;
+            public @Stable A[] left;
+            public         A[] right;
+        }
+
+        public @Stable A[] v;
+
+        public static final NestedStableField3 c = new NestedStableField3();
+        public static Object get() { return c.v[0].left[1].left[0].left[1].a; }
+        public static Object get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
+
+        public static void test() throws Exception {
+            {
+                A elem = new A();
+                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
+                               elem.a = Values.A; Object val1 = get(); Object val2 = get1();
+                               elem.a = Values.B; Object val3 = get(); Object val4 = get1();
+
+                assertEquals(val1, Values.A);
+                assertEquals(val3, (isStableEnabled ? Values.A : Values.B));
+
+                assertEquals(val2, Values.A);
+                assertEquals(val4, Values.B);
+            }
+        }
+    }
+
+    /* ==================================================== */
+    // Auxiliary methods
+    static void assertEquals(Object i, Object j) { if (i != j)  throw new AssertionError(i + " != " + j); }
+    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
+
+    static boolean failed = false;
+
+    public static void run(Class<?> test) {
+        Throwable ex = null;
+        System.out.print(test.getName()+": ");
+        try {
+            test.getMethod("test").invoke(null);
+        } catch (InvocationTargetException e) {
+            ex = e.getCause();
+        } catch (Throwable e) {
+            ex = e;
+        } finally {
+            if (ex == null) {
+                System.out.println("PASSED");
+            } else {
+                failed = true;
+                System.out.println("FAILED");
+                ex.printStackTrace(System.out);
+            }
+        }
+    }
+
+    static final boolean isStableEnabled;
+    static {
+        HotSpotDiagnosticMXBean diagnostic
+                = ManagementFactoryHelper.getDiagnosticMXBean();
+        VMOption tmp;
+        try {
+            tmp = diagnostic.getVMOption("FoldStableValues");
+        } catch (IllegalArgumentException e) {
+            tmp = null;
+        }
+        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/stable/TestStableShort.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,632 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestStableShort
+ * @summary tests on stable fields and arrays
+ * @library /testlibrary
+ * @compile -XDignore.symbol.file TestStableShort.java
+ * @run main ClassFileInstaller
+ *           java/lang/invoke/TestStableShort
+ *           java/lang/invoke/TestStableShort$ShortStable
+ *           java/lang/invoke/TestStableShort$StaticShortStable
+ *           java/lang/invoke/TestStableShort$VolatileShortStable
+ *           java/lang/invoke/TestStableShort$ShortArrayDim1
+ *           java/lang/invoke/TestStableShort$ShortArrayDim2
+ *           java/lang/invoke/TestStableShort$ShortArrayDim3
+ *           java/lang/invoke/TestStableShort$ShortArrayDim4
+ *           java/lang/invoke/TestStableShort$ObjectArrayLowerDim0
+ *           java/lang/invoke/TestStableShort$ObjectArrayLowerDim1
+ *           java/lang/invoke/TestStableShort$NestedStableField
+ *           java/lang/invoke/TestStableShort$NestedStableField$A
+ *           java/lang/invoke/TestStableShort$NestedStableField1
+ *           java/lang/invoke/TestStableShort$NestedStableField1$A
+ *           java/lang/invoke/TestStableShort$NestedStableField2
+ *           java/lang/invoke/TestStableShort$NestedStableField2$A
+ *           java/lang/invoke/TestStableShort$NestedStableField3
+ *           java/lang/invoke/TestStableShort$NestedStableField3$A
+ *           java/lang/invoke/TestStableShort$DefaultValue
+ *           java/lang/invoke/TestStableShort$ObjectArrayLowerDim2
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableShort
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableShort
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:+UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableShort
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:-FoldStableValues -XX:-UseCompressedOop
+ *                   -server -XX:-TieredCompilation -Xcomp
+ *                   -XX:CompileOnly=::get,::get1,::get2,::get3,::get4
+ *                   java.lang.invoke.TestStableShort
+ */
+package java.lang.invoke;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import sun.management.ManagementFactoryHelper;
+import java.lang.reflect.InvocationTargetException;
+
+public class TestStableShort {
+    public static void main(String[] args) throws Exception {
+        System.out.println("@Stable enabled: "+isStableEnabled);
+        System.out.println();
+
+        run(DefaultValue.class);
+        run(ShortStable.class);
+        run(StaticShortStable.class);
+        run(VolatileShortStable.class);
+
+        // @Stable arrays: Dim 1-4
+        run(ShortArrayDim1.class);
+        run(ShortArrayDim2.class);
+        run(ShortArrayDim3.class);
+        run(ShortArrayDim4.class);
+
+        // @Stable Object field: dynamic arrays
+        run(ObjectArrayLowerDim0.class);
+        run(ObjectArrayLowerDim1.class);
+        run(ObjectArrayLowerDim2.class);
+
+        // Nested @Stable fields
+        run(NestedStableField.class);
+        run(NestedStableField1.class);
+        run(NestedStableField2.class);
+        run(NestedStableField3.class);
+
+        if (failed) {
+            throw new Error("TEST FAILED");
+        }
+    }
+
+    /* ==================================================== */
+
+    static class DefaultValue {
+        public @Stable short v;
+
+        public static final DefaultValue c = new DefaultValue();
+        public static short get() { return c.v; }
+        public static void test() throws Exception {
+                     short val1 = get();
+            c.v = 1; short val2 = get();
+            assertEquals(val1, 0);
+            assertEquals(val2, 1);
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ShortStable {
+        public @Stable short v;
+
+        public static final ShortStable c = new ShortStable();
+        public static short get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 1;     short val1 = get();
+            c.v = 32767; short val2 = get();
+            assertEquals(val1, 1);
+            assertEquals(val2, (isStableEnabled ? 1 : 32767));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class StaticShortStable {
+        public static @Stable short v;
+
+        public static final StaticShortStable c = new StaticShortStable();
+        public static short get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 1;     short val1 = get();
+            c.v = 32767; short val2 = get();
+            assertEquals(val1, 1);
+            assertEquals(val2, (isStableEnabled ? 1 : 32767));
+        }
+    }
+
+    /* ==================================================== */
+
+    static class VolatileShortStable {
+        public @Stable volatile short v;
+
+        public static final VolatileShortStable c = new VolatileShortStable();
+        public static short get() { return c.v; }
+        public static void test() throws Exception {
+            c.v = 1;     short val1 = get();
+            c.v = 32767; short val2 = get();
+            assertEquals(val1, 1);
+            assertEquals(val2, (isStableEnabled ? 1 : 32767));
+        }
+    }
+
+    /* ==================================================== */
+    // @Stable array == field && all components are stable
+
+    static class ShortArrayDim1 {
+        public @Stable short[] v;
+
+        public static final ShortArrayDim1 c = new ShortArrayDim1();
+        public static short get() { return c.v[0]; }
+        public static short get1() { return c.v[10]; }
+        public static short[] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new short[1]; c.v[0] = 1; short val1 = get();
+                                    c.v[0] = 2; short val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new short[1]; c.v[0] = 3; short val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+
+            {
+                c.v = new short[20]; c.v[10] = 1; short val1 = get1();
+                                     c.v[10] = 2; short val2 = get1();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new short[20]; c.v[10] = 3; short val3 = get1();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+
+            {
+                c.v = new short[1]; short[] val1 = get2();
+                c.v = new short[1]; short[] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ShortArrayDim2 {
+        public @Stable short[][] v;
+
+        public static final ShortArrayDim2 c = new ShortArrayDim2();
+        public static short get() { return c.v[0][0]; }
+        public static short[] get1() { return c.v[0]; }
+        public static short[][] get2() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new short[1][1]; c.v[0][0] = 1; short val1 = get();
+                                       c.v[0][0] = 2; short val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new short[1][1]; c.v[0][0] = 3; short val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+
+                c.v[0] = new short[1]; c.v[0][0] = 4; short val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1 : 4));
+            }
+
+            {
+                c.v = new short[1][1]; short[] val1 = get1();
+                c.v[0] = new short[1]; short[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new short[1][1]; short[][] val1 = get2();
+                c.v = new short[1][1]; short[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ShortArrayDim3 {
+        public @Stable short[][][] v;
+
+        public static final ShortArrayDim3 c = new ShortArrayDim3();
+        public static short get() { return c.v[0][0][0]; }
+        public static short[] get1() { return c.v[0][0]; }
+        public static short[][] get2() { return c.v[0]; }
+        public static short[][][] get3() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new short[1][1][1]; c.v[0][0][0] = 1; short val1 = get();
+                                          c.v[0][0][0] = 2; short val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new short[1][1][1]; c.v[0][0][0] = 3; short val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+
+                c.v[0] = new short[1][1]; c.v[0][0][0] = 4; short val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1 : 4));
+
+                c.v[0][0] = new short[1]; c.v[0][0][0] = 5; short val5 = get();
+                assertEquals(val5, (isStableEnabled ? 1 : 5));
+            }
+
+            {
+                c.v = new short[1][1][1]; short[] val1 = get1();
+                c.v[0][0] = new short[1]; short[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new short[1][1][1]; short[][] val1 = get2();
+                c.v[0] = new short[1][1]; short[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new short[1][1][1]; short[][][] val1 = get3();
+                c.v = new short[1][1][1]; short[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ShortArrayDim4 {
+        public @Stable short[][][][] v;
+
+        public static final ShortArrayDim4 c = new ShortArrayDim4();
+        public static short get() { return c.v[0][0][0][0]; }
+        public static short[] get1() { return c.v[0][0][0]; }
+        public static short[][] get2() { return c.v[0][0]; }
+        public static short[][][] get3() { return c.v[0]; }
+        public static short[][][][] get4() { return c.v; }
+        public static void test() throws Exception {
+            {
+                c.v = new short[1][1][1][1]; c.v[0][0][0][0] = 1; short val1 = get();
+                                             c.v[0][0][0][0] = 2; short val2 = get();
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+
+                c.v = new short[1][1][1][1]; c.v[0][0][0][0] = 3; short val3 = get();
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+
+                c.v[0] = new short[1][1][1]; c.v[0][0][0][0] = 4; short val4 = get();
+                assertEquals(val4, (isStableEnabled ? 1 : 4));
+
+                c.v[0][0] = new short[1][1]; c.v[0][0][0][0] = 5; short val5 = get();
+                assertEquals(val5, (isStableEnabled ? 1 : 5));
+
+                c.v[0][0][0] = new short[1]; c.v[0][0][0][0] = 6; short val6 = get();
+                assertEquals(val6, (isStableEnabled ? 1 : 6));
+            }
+
+            {
+                c.v = new short[1][1][1][1]; short[] val1 = get1();
+                c.v[0][0][0] = new short[1]; short[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new short[1][1][1][1]; short[][] val1 = get2();
+                c.v[0][0] = new short[1][1]; short[][] val2 = get2();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new short[1][1][1][1]; short[][][] val1 = get3();
+                c.v[0] = new short[1][1][1]; short[][][] val2 = get3();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new short[1][1][1][1]; short[][][][] val1 = get4();
+                c.v = new short[1][1][1][1]; short[][][][] val2 = get4();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+        }
+    }
+
+    /* ==================================================== */
+    // Dynamic Dim is higher than static
+
+    static class ObjectArrayLowerDim0 {
+        public @Stable Object v;
+
+        public static final ObjectArrayLowerDim0 c = new ObjectArrayLowerDim0();
+        public static short get() { return ((short[])c.v)[0]; }
+        public static short[] get1() { return (short[])c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new short[1]; ((short[])c.v)[0] = 1; short val1 = get();
+                                    ((short[])c.v)[0] = 2; short val2 = get();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, 2);
+            }
+
+            {
+                c.v = new short[1]; short[] val1 = get1();
+                c.v = new short[1]; short[] val2 = get1();
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim1 {
+        public @Stable Object[] v;
+
+        public static final ObjectArrayLowerDim1 c = new ObjectArrayLowerDim1();
+        public static short get() { return ((short[][])c.v)[0][0]; }
+        public static short[] get1() { return (short[])(c.v[0]); }
+        public static Object[] get2() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new short[1][1]; ((short[][])c.v)[0][0] = 1; short val1 = get();
+                                       ((short[][])c.v)[0][0] = 2; short val2 = get();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, 2);
+            }
+
+            {
+                c.v = new short[1][1]; c.v[0] = new short[0]; short[] val1 = get1();
+                                       c.v[0] = new short[0]; short[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new short[0][0]; Object[] val1 = get2();
+                c.v = new short[0][0]; Object[] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class ObjectArrayLowerDim2 {
+        public @Stable Object[][] v;
+
+        public static final ObjectArrayLowerDim2 c = new ObjectArrayLowerDim2();
+        public static short get() { return ((short[][][])c.v)[0][0][0]; }
+        public static short[] get1() { return (short[])(c.v[0][0]); }
+        public static short[][] get2() { return (short[][])(c.v[0]); }
+        public static Object[][] get3() { return c.v; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new short[1][1][1]; ((short[][][])c.v)[0][0][0] = 1; short val1 = get();
+                                          ((short[][][])c.v)[0][0][0] = 2; short val2 = get();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, 2);
+            }
+
+            {
+                c.v = new short[1][1][1]; c.v[0][0] = new short[0]; short[] val1 = get1();
+                                          c.v[0][0] = new short[0]; short[] val2 = get1();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new short[1][1][1]; c.v[0] = new short[0][0]; short[][] val1 = get2();
+                                          c.v[0] = new short[0][0]; short[][] val2 = get2();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+
+            {
+                c.v = new short[0][0][0]; Object[][] val1 = get3();
+                c.v = new short[0][0][0]; Object[][] val2 = get3();
+
+                assertTrue((isStableEnabled ? (val1 == val2) : (val1 != val2)));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField {
+        static class A {
+            public @Stable short a;
+
+        }
+        public @Stable A v;
+
+        public static final NestedStableField c = new NestedStableField();
+        public static A get() { return c.v; }
+        public static short get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.a = 1; A val1 = get();
+                               c.v.a = 2; A val2 = get();
+
+                assertEquals(val1.a, 2);
+                assertEquals(val2.a, 2);
+            }
+
+            {
+                c.v = new A(); c.v.a = 1; short val1 = get1();
+                               c.v.a = 2; short val2 = get1();
+                c.v = new A(); c.v.a = 3; short val3 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField1 {
+        static class A {
+            public @Stable short a;
+            public @Stable A next;
+        }
+        public @Stable A v;
+
+        public static final NestedStableField1 c = new NestedStableField1();
+        public static A get() { return c.v.next.next.next.next.next.next.next; }
+        public static short get1() { return get().a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.next = new A();   c.v.next.next  = c.v;
+                               c.v.a = 1; c.v.next.a = 1; A val1 = get();
+                               c.v.a = 2; c.v.next.a = 2; A val2 = get();
+
+                assertEquals(val1.a, 2);
+                assertEquals(val2.a, 2);
+            }
+
+            {
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 1; short val1 = get1();
+                               c.v.a = 2; short val2 = get1();
+                c.v = new A(); c.v.next = c.v;
+                               c.v.a = 3; short val3 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val2, (isStableEnabled ? 1 : 2));
+                assertEquals(val3, (isStableEnabled ? 1 : 3));
+            }
+        }
+    }
+   /* ==================================================== */
+
+    static class NestedStableField2 {
+        static class A {
+            public @Stable short a;
+            public @Stable A left;
+            public         A right;
+        }
+
+        public @Stable A v;
+
+        public static final NestedStableField2 c = new NestedStableField2();
+        public static short get() { return c.v.left.left.left.a; }
+        public static short get1() { return c.v.left.left.right.left.a; }
+
+        public static void test() throws Exception {
+            {
+                c.v = new A(); c.v.left = c.v.right = c.v;
+                               c.v.a = 1; short val1 = get(); short val2 = get1();
+                               c.v.a = 2; short val3 = get(); short val4 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val3, (isStableEnabled ? 1 : 2));
+
+                assertEquals(val2, 1);
+                assertEquals(val4, 2);
+            }
+        }
+    }
+
+    /* ==================================================== */
+
+    static class NestedStableField3 {
+        static class A {
+            public @Stable short a;
+            public @Stable A[] left;
+            public         A[] right;
+        }
+
+        public @Stable A[] v;
+
+        public static final NestedStableField3 c = new NestedStableField3();
+        public static short get() { return c.v[0].left[1].left[0].left[1].a; }
+        public static short get1() { return c.v[1].left[0].left[1].right[0].left[1].a; }
+
+        public static void test() throws Exception {
+            {
+                A elem = new A();
+                c.v = new A[] { elem, elem }; c.v[0].left = c.v[0].right = c.v;
+                               elem.a = 1; short val1 = get(); short val2 = get1();
+                               elem.a = 2; short val3 = get(); short val4 = get1();
+
+                assertEquals(val1, 1);
+                assertEquals(val3, (isStableEnabled ? 1 : 2));
+
+                assertEquals(val2, 1);
+                assertEquals(val4, 2);
+            }
+        }
+    }
+
+    /* ==================================================== */
+    // Auxiliary methods
+    static void assertEquals(int i, int j) { if (i != j)  throw new AssertionError(i + " != " + j); }
+    static void assertTrue(boolean b) { if (!b)  throw new AssertionError(); }
+
+    static boolean failed = false;
+
+    public static void run(Class<?> test) {
+        Throwable ex = null;
+        System.out.print(test.getName()+": ");
+        try {
+            test.getMethod("test").invoke(null);
+        } catch (InvocationTargetException e) {
+            ex = e.getCause();
+        } catch (Throwable e) {
+            ex = e;
+        } finally {
+            if (ex == null) {
+                System.out.println("PASSED");
+            } else {
+                failed = true;
+                System.out.println("FAILED");
+                ex.printStackTrace(System.out);
+            }
+        }
+    }
+
+    static final boolean isStableEnabled;
+    static {
+        HotSpotDiagnosticMXBean diagnostic
+                = ManagementFactoryHelper.getDiagnosticMXBean();
+        VMOption tmp;
+        try {
+            tmp = diagnostic.getVMOption("FoldStableValues");
+        } catch (IllegalArgumentException e) {
+            tmp = null;
+        }
+        isStableEnabled = (tmp == null ? false : Boolean.parseBoolean(tmp.getValue()));
+    }
+}
--- a/hotspot/test/compiler/tiered/NonTieredLevelsTest.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/tiered/NonTieredLevelsTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -70,6 +70,9 @@
 
     @Override
     protected void test() throws Exception {
+        if (skipXcompOSR()) {
+          return;
+        }
         checkNotCompiled();
         compile();
         checkCompiled();
--- a/hotspot/test/compiler/tiered/TieredLevelsTest.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/tiered/TieredLevelsTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -51,6 +51,9 @@
 
     @Override
     protected void test() throws Exception {
+        if (skipXcompOSR()) {
+          return;
+        }
         checkNotCompiled();
         compile();
         checkCompiled();
--- a/hotspot/test/compiler/types/TestMeetTopArrayExactConstantArray.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/types/TestMeetTopArrayExactConstantArray.java	Tue Mar 25 20:32:46 2014 -0400
@@ -25,7 +25,7 @@
  * @test
  * @bug 8027571
  * @summary meet of TopPTR exact array with constant array is not symmetric
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseOnStackReplacement -XX:TypeProfileLevel=222 -XX:+UnlockExperimentalVMOptions -XX:+UseTypeSpeculation -XX:-BackgroundCompilation TestMeetTopArrayExactConstantArray
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseOnStackReplacement -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation -XX:-BackgroundCompilation TestMeetTopArrayExactConstantArray
  *
  */
 
--- a/hotspot/test/compiler/types/TestSpeculationFailedHigherEqual.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/types/TestSpeculationFailedHigherEqual.java	Tue Mar 25 20:32:46 2014 -0400
@@ -25,7 +25,7 @@
  * @test
  * @bug 8027422
  * @summary type methods shouldn't always operate on speculative part
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:TypeProfileLevel=222 -XX:+UnlockExperimentalVMOptions -XX:+UseTypeSpeculation -XX:-BackgroundCompilation TestSpeculationFailedHigherEqual
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation -XX:-BackgroundCompilation TestSpeculationFailedHigherEqual
  *
  */
 
--- a/hotspot/test/compiler/types/TypeSpeculation.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/types/TypeSpeculation.java	Tue Mar 25 20:32:46 2014 -0400
@@ -25,7 +25,7 @@
  * @test
  * @bug 8024070
  * @summary Test that type speculation doesn't cause incorrect execution
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:TypeProfileLevel=222 -XX:+UnlockExperimentalVMOptions -XX:+UseTypeSpeculation TypeSpeculation
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:TypeProfileLevel=222 -XX:+UseTypeSpeculation TypeSpeculation
  *
  */
 
--- a/hotspot/test/compiler/uncommontrap/TestSpecTrapClassUnloading.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/uncommontrap/TestSpecTrapClassUnloading.java	Tue Mar 25 20:32:46 2014 -0400
@@ -25,7 +25,7 @@
  * @test
  * @bug 8031752
  * @summary speculative traps need to be cleaned up at GC
- * @run main/othervm -XX:-TieredCompilation -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:+UnlockExperimentalVMOptions -XX:+UseTypeSpeculation -XX:TypeProfileLevel=222 -XX:CompileCommand=exclude,java.lang.reflect.Method::invoke -XX:CompileCommand=exclude,sun.reflect.DelegatingMethodAccessorImpl::invoke -Xmx1M TestSpecTrapClassUnloading
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:+UseTypeSpeculation -XX:TypeProfileLevel=222 -XX:CompileCommand=exclude,java.lang.reflect.Method::invoke -XX:CompileCommand=exclude,sun.reflect.DelegatingMethodAccessorImpl::invoke -Xmx1M TestSpecTrapClassUnloading
  *
  */
 
--- a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -196,6 +196,29 @@
     }
 
     /**
+     * Checks, that {@linkplain #method} is not compiled at the given compilation
+     * level or above.
+     *
+     * @param compLevel
+     *
+     * @throws RuntimeException if {@linkplain #method} is in compiler queue or
+     *                          is compiled, or if {@linkplain #method} has zero
+     *                          compilation level.
+     */
+
+    protected final void checkNotCompiled(int compLevel) {
+        if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
+            throw new RuntimeException(method + " must not be in queue");
+        }
+        if (WHITE_BOX.getMethodCompilationLevel(method, false) >= compLevel) {
+            throw new RuntimeException(method + " comp_level must be >= maxCompLevel");
+        }
+        if (WHITE_BOX.getMethodCompilationLevel(method, true) >= compLevel) {
+            throw new RuntimeException(method + " osr_comp_level must be >= maxCompLevel");
+        }
+    }
+
+    /**
      * Checks, that {@linkplain #method} is not compiled.
      *
      * @throws RuntimeException if {@linkplain #method} is in compiler queue or
@@ -380,6 +403,20 @@
         /** flag for OSR test case */
         boolean isOsr();
     }
+
+    /**
+     * @return {@code true} if the current test case is OSR and the mode is
+     *          Xcomp, otherwise {@code false}
+     */
+    protected boolean skipXcompOSR() {
+        boolean result =  testCase.isOsr()
+                && CompilerWhiteBoxTest.MODE.startsWith("compiled ");
+        if (result && IS_VERBOSE) {
+            System.err.printf("Warning: %s is not applicable in %s%n",
+                    testCase.name(), CompilerWhiteBoxTest.MODE);
+        }
+        return result;
+    }
 }
 
 enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
--- a/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -51,11 +51,8 @@
      */
     @Override
     protected void test() throws Exception {
-        if (testCase.isOsr() && CompilerWhiteBoxTest.MODE.startsWith(
-                "compiled ")) {
-          System.err.printf("Warning: %s is not applicable in %s%n",
-                testCase.name(), CompilerWhiteBoxTest.MODE);
-          return;
+        if (skipXcompOSR()) {
+            return;
         }
         compile();
         checkCompiled();
--- a/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -51,11 +51,8 @@
      */
     @Override
     protected void test() throws Exception {
-        if (testCase.isOsr() && CompilerWhiteBoxTest.MODE.startsWith(
-                "compiled ")) {
-          System.err.printf("Warning: %s is not applicable in %s%n",
-                testCase.name(), CompilerWhiteBoxTest.MODE);
-          return;
+        if (skipXcompOSR()) {
+            return;
         }
         compile();
         checkCompiled();
--- a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -24,13 +24,17 @@
 /*
  * @test IsMethodCompilableTest
  * @bug 8007270 8006683 8007288 8022832
- * @library /testlibrary /testlibrary/whitebox
+ * @library /testlibrary /testlibrary/whitebox /testlibrary/com/oracle/java/testlibrary
  * @build IsMethodCompilableTest
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm/timeout=2400 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* IsMethodCompilableTest
+ * @run main ClassFileInstaller com.oracle.java.testlibrary.Platform
+ * @run main/othervm/timeout=2400 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:PerMethodRecompilationCutoff=3 -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* IsMethodCompilableTest
  * @summary testing of WB::isMethodCompilable()
  * @author igor.ignatyev@oracle.com
  */
+
+import com.oracle.java.testlibrary.Platform;
+
 public class IsMethodCompilableTest extends CompilerWhiteBoxTest {
     /**
      * Value of {@code -XX:PerMethodRecompilationCutoff}
@@ -43,7 +47,7 @@
         if (tmp == -1) {
             PER_METHOD_RECOMPILATION_CUTOFF = -1 /* Inf */;
         } else {
-            PER_METHOD_RECOMPILATION_CUTOFF = 1 + (0xFFFFFFFFL & tmp);
+            PER_METHOD_RECOMPILATION_CUTOFF = (0xFFFFFFFFL & tmp);
         }
     }
 
@@ -60,19 +64,23 @@
     /**
      * Tests {@code WB::isMethodCompilable()} by recompilation of tested method
      * 'PerMethodRecompilationCutoff' times and checks compilation status. Also
-     * checks that WB::clearMethodState() clears no-compilable flags.
+     * checks that WB::clearMethodState() clears no-compilable flags. Only
+     * applicable to c2 compiled methods.
      *
      * @throws Exception if one of the checks fails.
      */
     @Override
     protected void test() throws Exception {
-        if (testCase.isOsr() && CompilerWhiteBoxTest.MODE.startsWith(
-                "compiled ")) {
-          System.err.printf("Warning: %s is not applicable in %s%n",
-                testCase.name(), CompilerWhiteBoxTest.MODE);
-          return;
+
+        // Only c2 compilations can be disabled through PerMethodRecompilationCutoff
+        if (!Platform.isServer()) {
+            return;
         }
-        if (!isCompilable()) {
+
+        if (skipXcompOSR()) {
+            return;
+        }
+        if (!isCompilable(COMP_LEVEL_FULL_OPTIMIZATION)) {
             throw new RuntimeException(method + " must be compilable");
         }
         System.out.println("PerMethodRecompilationCutoff = "
@@ -83,39 +91,37 @@
             return;
         }
 
-        // deoptimize 'PerMethodRecompilationCutoff' times and clear state
-        for (long i = 0L, n = PER_METHOD_RECOMPILATION_CUTOFF - 1; i < n; ++i) {
-            compileAndDeoptimize();
+        // deoptimize 'PerMethodRecompilationCutoff' times
+        for (long attempts = 0, successes = 0;
+               (successes < PER_METHOD_RECOMPILATION_CUTOFF)  &&
+               (attempts < PER_METHOD_RECOMPILATION_CUTOFF*2) &&
+               isCompilable(COMP_LEVEL_FULL_OPTIMIZATION); attempts++) {
+            if (compileAndDeoptimize() == COMP_LEVEL_FULL_OPTIMIZATION) {
+                successes++;
+            }
         }
-        if (!testCase.isOsr() && !isCompilable()) {
+
+        if (!testCase.isOsr() && !isCompilable(COMP_LEVEL_FULL_OPTIMIZATION)) {
             // in osr test case count of deopt maybe more than iterations
             throw new RuntimeException(method + " is not compilable after "
-                    + (PER_METHOD_RECOMPILATION_CUTOFF - 1) + " iterations");
+                    + PER_METHOD_RECOMPILATION_CUTOFF + " iterations");
         }
-        WHITE_BOX.clearMethodState(method);
 
-        // deoptimize 'PerMethodRecompilationCutoff' + 1 times
-        long i;
-        for (i = 0L; i < PER_METHOD_RECOMPILATION_CUTOFF
-                && isCompilable(); ++i) {
-            compileAndDeoptimize();
-        }
-        if (!testCase.isOsr() && i != PER_METHOD_RECOMPILATION_CUTOFF) {
-            // in osr test case count of deopt maybe more than iterations
-            throw new RuntimeException(method + " is not compilable after "
-                    + i + " iterations, but must only after "
-                    + PER_METHOD_RECOMPILATION_CUTOFF);
-        }
-        if (isCompilable()) {
+        // Now compile once more
+        compileAndDeoptimize();
+
+        if (isCompilable(COMP_LEVEL_FULL_OPTIMIZATION)) {
             throw new RuntimeException(method + " is still compilable after "
                     + PER_METHOD_RECOMPILATION_CUTOFF + " iterations");
         }
+        checkNotCompiled();
         compile();
-        checkNotCompiled();
+        waitBackgroundCompilation();
+        checkNotCompiled(COMP_LEVEL_FULL_OPTIMIZATION);
 
         // WB.clearMethodState() must reset no-compilable flags
         WHITE_BOX.clearMethodState(method);
-        if (!isCompilable()) {
+        if (!isCompilable(COMP_LEVEL_FULL_OPTIMIZATION)) {
             throw new RuntimeException(method
                     + " is not compilable after clearMethodState()");
         }
@@ -123,9 +129,11 @@
         checkCompiled();
     }
 
-    private void compileAndDeoptimize() throws Exception {
+    private int compileAndDeoptimize() throws Exception {
         compile();
         waitBackgroundCompilation();
+        int compLevel = getCompLevel();
         deoptimize();
+        return compLevel;
     }
 }
--- a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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,11 +53,8 @@
      */
     @Override
     protected void test() throws Exception {
-        if (testCase.isOsr() && CompilerWhiteBoxTest.MODE.startsWith(
-                "compiled ")) {
-          System.err.printf("Warning: %s is not applicable in %s%n",
-                testCase.name(), CompilerWhiteBoxTest.MODE);
-          return;
+        if (skipXcompOSR()) {
+            return;
         }
         checkNotCompiled();
         if (!isCompilable()) {
--- a/hotspot/test/runtime/6294277/SourceDebugExtension.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/runtime/6294277/SourceDebugExtension.java	Tue Mar 25 20:32:46 2014 -0400
@@ -25,7 +25,7 @@
  * @test
  * @bug 6294277
  * @summary java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
- * @run main/othervm -Xdebug -Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n SourceDebugExtension
+ * @run main/othervm -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n SourceDebugExtension
  */
 import java.io.*;
 
--- a/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java	Tue Mar 25 20:32:46 2014 -0400
@@ -83,8 +83,8 @@
     public static void heapBaseMinAddressTest() throws Exception {
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-XX:HeapBaseMinAddress=1m",
-            "-XX:+PrintMiscellaneous",
-            "-XX:+Verbose",
+            "-XX:+UnlockDiagnosticVMOptions",
+            "-XX:+PrintCompressedOopsMode",
             "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("HeapBaseMinAddress must be at least");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jvmti/TestRedefineWithUnresolvedClass.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,82 @@
+/*
+ * 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
+ * @summary Redefine a class with an UnresolvedClass reference in the constant pool.
+ * @bug 8035150
+ * @library /testlibrary
+ * @build UnresolvedClassAgent com.oracle.java.testlibrary.ProcessTools com.oracle.java.testlibrary.OutputAnalyzer
+ * @run main TestRedefineWithUnresolvedClass
+ */
+
+import java.io.File;
+import java.util.Arrays;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+public class TestRedefineWithUnresolvedClass {
+
+    final static String slash = File.separator;
+    final static String testClasses = System.getProperty("test.classes") + slash;
+
+    public static void main(String... args) throws Throwable {
+        // delete this class to cause a NoClassDefFoundError
+        File unresolved = new File(testClasses, "MyUnresolvedClass.class");
+        if (unresolved.exists() && !unresolved.delete()) {
+            throw new Exception("Could not delete: " + unresolved);
+        }
+
+        // build the javaagent
+        buildJar("UnresolvedClassAgent");
+
+        // launch a VM with the javaagent
+        launchTest();
+    }
+
+    private static void buildJar(String jarName) throws Throwable {
+        String testSrc = System.getProperty("test.src", "?") + slash;
+
+        String jarPath = String.format("%s%s.jar", testClasses, jarName);
+        String manifestPath = String.format("%s%s.mf", testSrc, jarName);
+        String className = String.format("%s.class", jarName);
+
+        String[] args = new String[] {"-cfm", jarPath, manifestPath, "-C", testClasses, className};
+
+        System.out.println("Running jar " + Arrays.toString(args));
+        sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar");
+        if (!jarTool.run(args)) {
+            throw new Exception("jar failed: args=" + Arrays.toString(args));
+        }
+    }
+
+    private static void launchTest() throws Throwable {
+        String[] args = {
+            "-javaagent:" + testClasses + "UnresolvedClassAgent.jar",
+            "-Dtest.classes=" + testClasses,
+            "UnresolvedClassAgent" };
+        OutputAnalyzer output = ProcessTools.executeTestJvm(args);
+        output.shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jvmti/UnresolvedClassAgent.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,69 @@
+/*
+ * 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.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.lang.instrument.ClassDefinition;
+import java.lang.instrument.Instrumentation;
+
+/*
+ * This class is present during compilation, but will be deleted before execution.
+ */
+class MyUnresolvedClass {
+    static void bar() {
+    }
+}
+
+class MyRedefinedClass {
+    static void foo() {
+        MyUnresolvedClass.bar();
+    }
+}
+
+public class UnresolvedClassAgent {
+    public static void main(String... args) {
+    }
+
+    public static void premain(String args, Instrumentation inst) throws Exception {
+        try {
+            MyRedefinedClass.foo();
+        } catch(NoClassDefFoundError err) {
+            System.out.println("NoClassDefFoundError (expected)");
+        }
+
+        File f = new File(System.getProperty("test.classes"), "MyRedefinedClass.class");
+        byte[] buf = new byte[(int)f.length()];
+        try (DataInputStream dis = new DataInputStream(new FileInputStream(f))) {
+            dis.readFully(buf);
+        }
+        ClassDefinition cd = new ClassDefinition(MyRedefinedClass.class, buf);
+        inst.redefineClasses(new ClassDefinition[] {cd});
+
+        try {
+            MyRedefinedClass.foo();
+        } catch(NoClassDefFoundError err) {
+            System.out.println("NoClassDefFoundError (expected again)");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jvmti/UnresolvedClassAgent.mf	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Premain-Class: UnresolvedClassAgent
+Can-Redefine-Classes: true
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java	Tue Mar 25 20:32:46 2014 -0400
@@ -28,6 +28,15 @@
     private static final String dataModel   = System.getProperty("sun.arch.data.model");
     private static final String vmVersion   = System.getProperty("java.vm.version");
     private static final String osArch      = System.getProperty("os.arch");
+    private static final String vmName      = System.getProperty("java.vm.name");
+
+     public static boolean isClient() {
+         return vmName.endsWith(" Client VM");
+     }
+
+     public static boolean isServer() {
+         return vmName.endsWith(" Server VM");
+     }
 
     public static boolean is32bit() {
         return dataModel.equals("32");
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java	Tue Mar 25 20:32:46 2014 -0400
@@ -163,10 +163,87 @@
 
     // Reporting
     StringBuilder cmdLine = new StringBuilder();
-    for (String cmd : args)
-        cmdLine.append(cmd).append(' ');
+    for (String cmd : args) {
+      cmdLine.append(cmd).append(' ');
+    }
     System.out.println("Command line: [" + cmdLine.toString() + "]");
 
     return new ProcessBuilder(args.toArray(new String[args.size()]));
   }
+
+  /**
+   * Executes a test jvm process, waits for it to finish and returns the process output.
+   * The default jvm options from jtreg, test.vm.opts and test.java.opts, are added.
+   * The java from the test.jdk is used to execute the command.
+   *
+   * The command line will be like:
+   * {test.jdk}/bin/java {test.vm.opts} {test.java.opts} cmds
+   *
+   * @param cmds User specifed arguments.
+   * @return The output from the process.
+   */
+  public static OutputAnalyzer executeTestJvm(String... cmds) throws Throwable {
+    ProcessBuilder pb = createJavaProcessBuilder(Utils.addTestJavaOpts(cmds));
+    return executeProcess(pb);
+  }
+
+  /**
+   * Executes a process, waits for it to finish and returns the process output.
+   * @param pb The ProcessBuilder to execute.
+   * @return The output from the process.
+   */
+  public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Throwable {
+    OutputAnalyzer output = null;
+    try {
+      output = new OutputAnalyzer(pb.start());
+      return output;
+    } catch (Throwable t) {
+      System.out.println("executeProcess() failed: " + t);
+      throw t;
+    } finally {
+      System.out.println(getProcessLog(pb, output));
+    }
+  }
+
+  /**
+   * Executes a process, waits for it to finish and returns the process output.
+   * @param cmds The command line to execute.
+   * @return The output from the process.
+   */
+  public static OutputAnalyzer executeProcess(String... cmds) throws Throwable {
+    return executeProcess(new ProcessBuilder(cmds));
+  }
+
+  /**
+   * Used to log command line, stdout, stderr and exit code from an executed process.
+   * @param pb The executed process.
+   * @param output The output from the process.
+   */
+  public static String getProcessLog(ProcessBuilder pb, OutputAnalyzer output) {
+    String stderr = output == null ? "null" : output.getStderr();
+    String stdout = output == null ? "null" : output.getStdout();
+    String exitValue = output == null ? "null": Integer.toString(output.getExitValue());
+    StringBuilder logMsg = new StringBuilder();
+    final String nl = System.getProperty("line.separator");
+    logMsg.append("--- ProcessLog ---" + nl);
+    logMsg.append("cmd: " + getCommandLine(pb) + nl);
+    logMsg.append("exitvalue: " + exitValue + nl);
+    logMsg.append("stderr: " + stderr + nl);
+    logMsg.append("stdout: " + stdout + nl);
+    return logMsg.toString();
+  }
+
+  /**
+   * @return The full command line for the ProcessBuilder.
+   */
+  public static String getCommandLine(ProcessBuilder pb) {
+    if (pb == null) {
+      return "null";
+    }
+    StringBuilder cmd = new StringBuilder();
+    for (String s : pb.command()) {
+      cmd.append(s).append(" ");
+    }
+    return cmd.toString().trim();
+  }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,263 @@
+/*
+ * 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.
+ */
+
+package com.oracle.java.testlibrary;
+
+import static com.oracle.java.testlibrary.Asserts.assertTrue;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * Common library for various test helper functions.
+ */
+public final class Utils {
+
+    /**
+     * Returns the sequence used by operating system to separate lines.
+     */
+    public static final String NEW_LINE = System.getProperty("line.separator");
+
+    /**
+     * Returns the value of 'test.vm.opts'system property.
+     */
+    public static final String VM_OPTIONS = System.getProperty("test.vm.opts", "").trim();
+
+    /**
+     * Returns the value of 'test.java.opts'system property.
+     */
+    public static final String JAVA_OPTIONS = System.getProperty("test.java.opts", "").trim();
+
+    /**
+    * Returns the value of 'test.timeout.factor' system property
+    * converted to {@code double}.
+    */
+    public static final double TIMEOUT_FACTOR;
+    static {
+        String toFactor = System.getProperty("test.timeout.factor", "1.0");
+        TIMEOUT_FACTOR = Double.parseDouble(toFactor);
+    }
+
+    private Utils() {
+        // Private constructor to prevent class instantiation
+    }
+
+    /**
+     * Returns the list of VM options.
+     *
+     * @return List of VM options
+     */
+    public static List<String> getVmOptions() {
+        return Arrays.asList(safeSplitString(VM_OPTIONS));
+    }
+
+    /**
+     * Returns the list of VM options with -J prefix.
+     *
+     * @return The list of VM options with -J prefix
+     */
+    public static List<String> getForwardVmOptions() {
+        String[] opts = safeSplitString(VM_OPTIONS);
+        for (int i = 0; i < opts.length; i++) {
+            opts[i] = "-J" + opts[i];
+        }
+        return Arrays.asList(opts);
+    }
+
+    /**
+     * Returns the default JTReg arguments for a jvm running a test.
+     * This is the combination of JTReg arguments test.vm.opts and test.java.opts.
+     * @return An array of options, or an empty array if no opptions.
+     */
+    public static String[] getTestJavaOpts() {
+        List<String> opts = new ArrayList<String>();
+        Collections.addAll(opts, safeSplitString(VM_OPTIONS));
+        Collections.addAll(opts, safeSplitString(JAVA_OPTIONS));
+        return opts.toArray(new String[0]);
+    }
+
+    /**
+     * Combines given arguments with default JTReg arguments for a jvm running a test.
+     * This is the combination of JTReg arguments test.vm.opts and test.java.opts
+     * @return The combination of JTReg test java options and user args.
+     */
+    public static String[] addTestJavaOpts(String... userArgs) {
+        List<String> opts = new ArrayList<String>();
+        Collections.addAll(opts, getTestJavaOpts());
+        Collections.addAll(opts, userArgs);
+        return opts.toArray(new String[0]);
+    }
+
+    /**
+     * Splits a string by white space.
+     * Works like String.split(), but returns an empty array
+     * if the string is null or empty.
+     */
+    private static String[] safeSplitString(String s) {
+        if (s == null || s.trim().isEmpty()) {
+            return new String[] {};
+        }
+        return s.trim().split("\\s+");
+    }
+
+    /**
+     * @return The full command line for the ProcessBuilder.
+     */
+    public static String getCommandLine(ProcessBuilder pb) {
+        StringBuilder cmd = new StringBuilder();
+        for (String s : pb.command()) {
+            cmd.append(s).append(" ");
+        }
+        return cmd.toString();
+    }
+
+    /**
+     * Returns the free port on the local host.
+     * The function will spin until a valid port number is found.
+     *
+     * @return The port number
+     * @throws InterruptedException if any thread has interrupted the current thread
+     * @throws IOException if an I/O error occurs when opening the socket
+     */
+    public static int getFreePort() throws InterruptedException, IOException {
+        int port = -1;
+
+        while (port <= 0) {
+            Thread.sleep(100);
+
+            ServerSocket serverSocket = null;
+            try {
+                serverSocket = new ServerSocket(0);
+                port = serverSocket.getLocalPort();
+            } finally {
+                serverSocket.close();
+            }
+        }
+
+        return port;
+    }
+
+    /**
+     * Returns the name of the local host.
+     *
+     * @return The host name
+     * @throws UnknownHostException if IP address of a host could not be determined
+     */
+    public static String getHostname() throws UnknownHostException {
+        InetAddress inetAddress = InetAddress.getLocalHost();
+        String hostName = inetAddress.getHostName();
+
+        assertTrue((hostName != null && !hostName.isEmpty()),
+                "Cannot get hostname");
+
+        return hostName;
+    }
+
+    /**
+     * Uses "jcmd -l" to search for a jvm pid. This function will wait
+     * forever (until jtreg timeout) for the pid to be found.
+     * @param key Regular expression to search for
+     * @return The found pid.
+     */
+    public static int waitForJvmPid(String key) throws Throwable {
+        final long iterationSleepMillis = 250;
+        System.out.println("waitForJvmPid: Waiting for key '" + key + "'");
+        System.out.flush();
+        while (true) {
+            int pid = tryFindJvmPid(key);
+            if (pid >= 0) {
+                return pid;
+            }
+            Thread.sleep(iterationSleepMillis);
+        }
+    }
+
+    /**
+     * Searches for a jvm pid in the output from "jcmd -l".
+     *
+     * Example output from jcmd is:
+     * 12498 sun.tools.jcmd.JCmd -l
+     * 12254 /tmp/jdk8/tl/jdk/JTwork/classes/com/sun/tools/attach/Application.jar
+     *
+     * @param key A regular expression to search for.
+     * @return The found pid, or -1 if Enot found.
+     * @throws Exception If multiple matching jvms are found.
+     */
+    public static int tryFindJvmPid(String key) throws Throwable {
+        OutputAnalyzer output = null;
+        try {
+            JDKToolLauncher jcmdLauncher = JDKToolLauncher.create("jcmd");
+            jcmdLauncher.addToolArg("-l");
+            output = ProcessTools.executeProcess(jcmdLauncher.getCommand());
+            output.shouldHaveExitValue(0);
+
+            // Search for a line starting with numbers (pid), follwed by the key.
+            Pattern pattern = Pattern.compile("([0-9]+)\\s.*(" + key + ").*\\r?\\n");
+            Matcher matcher = pattern.matcher(output.getStdout());
+
+            int pid = -1;
+            if (matcher.find()) {
+                pid = Integer.parseInt(matcher.group(1));
+                System.out.println("findJvmPid.pid: " + pid);
+                if (matcher.find()) {
+                    throw new Exception("Found multiple JVM pids for key: " + key);
+                }
+            }
+            return pid;
+        } catch (Throwable t) {
+            System.out.println(String.format("Utils.findJvmPid(%s) failed: %s", key, t));
+            throw t;
+        }
+    }
+
+    /**
+     * Returns file content as a list of strings
+     *
+     * @param file File to operate on
+     * @return List of strings
+     * @throws IOException
+     */
+    public static List<String> fileAsList(File file) throws IOException {
+        assertTrue(file.exists() && file.isFile(),
+                file.getAbsolutePath() + " does not exist or not a file");
+        List<String> output = new ArrayList<>();
+        try (BufferedReader reader = new BufferedReader(new FileReader(file.getAbsolutePath()))) {
+            while (reader.ready()) {
+                output.add(reader.readLine().replace(NEW_LINE, ""));
+            }
+        }
+        return output;
+    }
+
+}
--- a/jaxp/.hgtags	Tue Mar 25 20:32:07 2014 -0400
+++ b/jaxp/.hgtags	Tue Mar 25 20:32:46 2014 -0400
@@ -246,3 +246,5 @@
 e5256f530a9b5f2d677ca245de44a617ffb58f52 jdk9-b01
 02f60a253e15240087c043bad77a106792e4d56a jdk9-b02
 fb92ed0399424193f444489ad49a16748816dc12 jdk9-b03
+2846d8fc31490897817a122a668af4f44fc913d0 jdk9-b04
+b92a20e303d24c74078888cd7084b14d7626d48f jdk9-b05
--- a/jaxp/make/BuildJaxp.gmk	Tue Mar 25 20:32:07 2014 -0400
+++ b/jaxp/make/BuildJaxp.gmk	Tue Mar 25 20:32:46 2014 -0400
@@ -45,27 +45,11 @@
 $(eval $(call SetupJavaCompilation,BUILD_JAXP, \
     SETUP := GENERATE_NEWBYTECODE_DEBUG, \
     SRC := $(JAXP_TOPDIR)/src, \
+    CLEAN := .properties, \
     BIN := $(JAXP_OUTPUTDIR)/classes, \
-    SRCZIP := $(JAXP_OUTPUTDIR)/dist/lib/src.zip))
-
-# Imitate the property cleaning mechanism in the old build. This will likely be replaced
-# by the unified functionality in JavaCompilation.gmk, but keep it the same as old build
-# for now, even though it actually breaks properties containing # in the value.
-# Using nawk to avoid solaris sed.
-$(JAXP_OUTPUTDIR)/classes/%.properties: $(JAXP_TOPDIR)/src/%.properties
-	$(MKDIR) -p $(@D)
-	$(RM) $@ $@.tmp
-	$(CAT) $< | LANG=C $(NAWK) '{ sub(/#.*$$/,"#"); print }' > $@.tmp
-	$(MV) $@.tmp $@
-
-SRC_PROP_FILES := $(shell $(FIND) $(JAXP_TOPDIR)/src -name "*.properties")
-TARGET_PROP_FILES := $(patsubst $(JAXP_TOPDIR)/src/%, $(JAXP_OUTPUTDIR)/classes/%, $(SRC_PROP_FILES))
-
-$(eval $(call SetupArchive,ARCHIVE_JAXP, $(BUILD_JAXP) $(TARGET_PROP_FILES), \
-    SRCS := $(JAXP_OUTPUTDIR)/classes, \
-    SUFFIXES := .class .properties, \
+    SRCZIP := $(JAXP_OUTPUTDIR)/dist/lib/src.zip, \
     JAR := $(JAXP_OUTPUTDIR)/dist/lib/classes.jar))
 
-all: $(JAXP_OUTPUTDIR)/dist/lib/classes.jar $(JAXP_OUTPUTDIR)/dist/lib/src.zip
+all: $(BUILD_JAXP)
 
 .PHONY: default all
--- a/jaxws/.hgtags	Tue Mar 25 20:32:07 2014 -0400
+++ b/jaxws/.hgtags	Tue Mar 25 20:32:46 2014 -0400
@@ -249,3 +249,5 @@
 9c9fabbcd3d526d7ca29165169155f49a107533a jdk9-b01
 efe2bc258c78af49de9517a4a5699d3a2e630c44 jdk9-b02
 1cd9786257ed4f82a3371fd606b162e5bb6fcd81 jdk9-b03
+da44a8bdf1f3fdd518e7d785d60cc1b15983b176 jdk9-b04
+eae966c8133fec0a8bf9e16d1274a4ede3c0fb52 jdk9-b05
--- a/jaxws/make/BuildJaxws.gmk	Tue Mar 25 20:32:07 2014 -0400
+++ b/jaxws/make/BuildJaxws.gmk	Tue Mar 25 20:32:46 2014 -0400
@@ -42,11 +42,10 @@
     SERVER_DIR := $(SJAVAC_SERVER_DIR), \
     SERVER_JVM := $(SJAVAC_SERVER_JAVA)))
 
-# Dummy here is needed to trigger copying of META-INF
 $(eval $(call SetupJavaCompilation,BUILD_JAF, \
     SETUP := GENERATE_NEWBYTECODE_DEBUG, \
     SRC := $(JAXWS_TOPDIR)/src/share/jaf_classes, \
-    COPY := "dummy", \
+    CLEAN := .properties, \
     BIN := $(JAXWS_OUTPUTDIR)/jaf_classes))
 
 $(eval $(call SetupJavaCompilation,BUILD_JAXWS, \
@@ -57,6 +56,7 @@
     COPY_FILES := $(JAXWS_TOPDIR)/src/share/jaxws_classes/com/sun/tools/internal/xjc/runtime/JAXBContextFactory.java \
         $(JAXWS_TOPDIR)/src/share/jaxws_classes/com/sun/tools/internal/xjc/runtime/ZeroOneBooleanAdapter.java \
         $(JAXWS_TOPDIR)/src/share/jaxws_classes/com/sun/xml/internal/ws/assembler/jaxws-tubes-default.xml, \
+    CLEAN := .properties, \
     ADD_JAVAC_FLAGS = -Xbootclasspath/p:$(OUTPUT_ROOT)/jaxp/dist/lib/classes.jar))
 
 $(JAXWS_OUTPUTDIR)/jaxws_classes/META-INF/services/com.sun.tools.internal.ws.wscompile.Plugin: \
@@ -73,30 +73,6 @@
 BUILD_JAXWS += $(JAXWS_OUTPUTDIR)/jaxws_classes/META-INF/services/com.sun.tools.internal.ws.wscompile.Plugin \
                $(JAXWS_OUTPUTDIR)/jaxws_classes/META-INF/services/com.sun.tools.internal.xjc.Plugin
 
-# Imitate the property cleaning mechanism in the old build. This will likely be replaced
-# by the unified functionality in JavaCompilation.gmk, but keep it the same as old build
-# for now, even though it actually breaks properties containing # in the value.
-# Using nawk to avoid solaris sed.
-$(JAXWS_OUTPUTDIR)/jaxws_classes/%.properties: $(JAXWS_TOPDIR)/src/share/jaxws_classes/%.properties
-	$(MKDIR) -p $(@D)
-	$(RM) $@ $@.tmp
-	$(CAT) $< | LANG=C $(NAWK) '{ sub(/#.*$$/,"#"); print }' > $@.tmp
-	$(MV) $@.tmp $@
-
-JAXWS_SRC_PROP_FILES := $(shell $(FIND) $(JAXWS_TOPDIR)/src/share/jaxws_classes -name "*.properties")
-TARGET_PROP_FILES := $(patsubst $(JAXWS_TOPDIR)/src/share/jaxws_classes/%, \
-    $(JAXWS_OUTPUTDIR)/jaxws_classes/%, $(JAXWS_SRC_PROP_FILES))
-
-$(JAXWS_OUTPUTDIR)/jaf_classes/%.properties: $(JAXWS_TOPDIR)/src/share/jaf_classes/%.properties
-	$(MKDIR) -p $(@D)
-	$(RM) $@ $@.tmp
-	$(CAT) $< | LANG=C $(NAWK) '{ sub(/#.*$$/,"#"); print }' > $@.tmp
-	$(MV) $@.tmp $@
-
-JAF_SRC_PROP_FILES := $(shell $(FIND) $(JAXWS_TOPDIR)/src/share/jaf_classes -name "*.properties")
-TARGET_PROP_FILES += $(patsubst $(JAXWS_TOPDIR)/src/share/jaf_classes/%, \
-    $(JAXWS_OUTPUTDIR)/jaf_classes/%, $(JAF_SRC_PROP_FILES))
-
 $(eval $(call SetupArchive,ARCHIVE_JAXWS, $(BUILD_JAXWS) $(BUILD_JAF) $(TARGET_PROP_FILES), \
     SRCS := $(JAXWS_OUTPUTDIR)/jaxws_classes $(JAXWS_OUTPUTDIR)/jaf_classes, \
     SUFFIXES := .class .properties .xsd .xml .java \
--- a/jdk/.hgtags	Tue Mar 25 20:32:07 2014 -0400
+++ b/jdk/.hgtags	Tue Mar 25 20:32:46 2014 -0400
@@ -246,3 +246,5 @@
 3b4ac8d1b76fc6bec9815f0ab714f15b552e4c7b jdk9-b01
 8c8275426a3207d91393354f7a7f9bc362ec25cf jdk9-b02
 4111af6151ed8ca8e3f5603c69729a68427e1d5b jdk9-b03
+627deed79b595a4789fc9151455b663a47381257 jdk9-b04
+263198a1d8f1f4cb97d35f40c61704b08ebd3686 jdk9-b05
--- a/langtools/.hgtags	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/.hgtags	Tue Mar 25 20:32:46 2014 -0400
@@ -246,3 +246,5 @@
 077c12d527fb5531c59666c1f84000fc1245a260 jdk9-b01
 f2c58a337c8aaa1ce84dfa8a8e8c5d4c8c1e12fa jdk9-b02
 151222468d1d04ce6613d33efa3d45bfaf53e3e5 jdk9-b03
+fa2ec6b6b1697ae4a78b03b609664dc6b47dee86 jdk9-b04
+1d5e6fc88a4cca287090c16b0530a0d5849a5603 jdk9-b05
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -467,11 +467,24 @@
 
     private boolean hiddenIn(ClassSymbol clazz, Types types) {
         Symbol sym = hiddenInInternal(clazz, types);
-        return sym != null && sym != this;
+        Assert.check(sym != null, "the result of hiddenInInternal() can't be null");
+        /* If we find the current symbol then there is no symbol hiding it
+         */
+        return sym != this;
     }
 
-    private Symbol hiddenInInternal(ClassSymbol c, Types types) {
-        Scope.Entry e = c.members().lookup(name);
+    /** This method looks in the supertypes graph that has the current class as the
+     * initial node, till it finds the current symbol or another symbol that hides it.
+     * If the current class has more than one supertype (extends one class and
+     * implements one or more interfaces) then null can be returned, meaning that
+     * a wrong path in the supertypes graph was selected. Null can only be returned
+     * as a temporary value, as a result of the recursive call.
+     */
+    private Symbol hiddenInInternal(ClassSymbol currentClass, Types types) {
+        if (currentClass == owner) {
+            return this;
+        }
+        Scope.Entry e = currentClass.members().lookup(name);
         while (e.scope != null) {
             if (e.sym.kind == kind &&
                     (kind != MTH ||
@@ -481,18 +494,19 @@
             }
             e = e.next();
         }
-        List<Symbol> hiddenSyms = List.nil();
-        for (Type st : types.interfaces(c.type).prepend(types.supertype(c.type))) {
+        Symbol hiddenSym = null;
+        for (Type st : types.interfaces(currentClass.type)
+                .prepend(types.supertype(currentClass.type))) {
             if (st != null && (st.hasTag(CLASS))) {
                 Symbol sym = hiddenInInternal((ClassSymbol)st.tsym, types);
-                if (sym != null) {
-                    hiddenSyms = hiddenSyms.prepend(hiddenInInternal((ClassSymbol)st.tsym, types));
+                if (sym == this) {
+                    return this;
+                } else if (sym != null) {
+                    hiddenSym = sym;
                 }
             }
         }
-        return hiddenSyms.contains(this) ?
-                this :
-                (hiddenSyms.isEmpty() ? null : hiddenSyms.head);
+        return hiddenSym;
     }
 
     /** Is this symbol inherited into a given class?
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -1481,8 +1481,21 @@
         }
 
         public String toString() {
-            if (inst != null) return inst.toString();
-            else return qtype + "?";
+            return (inst == null) ? qtype + "?" : inst.toString();
+        }
+
+        public String debugString() {
+            String result = "inference var = " + qtype + "\n";
+            if (inst != null) {
+                result += "inst = " + inst + '\n';
+            }
+            for (InferenceBound bound: InferenceBound.values()) {
+                List<Type> aboundList = bounds.get(bound);
+                if (aboundList.size() > 0) {
+                    result += bound + " = " + aboundList + '\n';
+                }
+            }
+            return result;
         }
 
         @Override
@@ -1492,8 +1505,7 @@
 
         @Override
         public Type baseType() {
-            if (inst != null) return inst.baseType();
-            else return this;
+            return (inst == null) ? this : inst.baseType();
         }
 
         /** get all bounds of a given kind */
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Tue Mar 25 20:32:46 2014 -0400
@@ -3208,6 +3208,7 @@
             return tvar.rank_field;
         }
         case ERROR:
+        case NONE:
             return 0;
         default:
             throw new AssertionError();
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Tue Mar 25 20:32:46 2014 -0400
@@ -808,9 +808,7 @@
                 Attribute.TypeCompound tc =
                     enterTypeAnnotation(a, syms.annotationType, env);
 
-                if (tc == null) {
-                    continue;
-                }
+                Assert.checkNonNull(tc, "Failed to create type annotation");
 
                 if (annotated.containsKey(a.type.tsym)) {
                     if (!allowRepeatedAnnos) {
@@ -827,10 +825,9 @@
                 }
             }
 
-            if (s != null) {
-                s.appendTypeAttributesWithCompletion(
-                    new AnnotateRepeatedContext<>(env, annotated, pos, log, true));
-            }
+            Assert.checkNonNull(s, "Symbol argument to actualEnterTypeAnnotations is null");
+            s.appendTypeAttributesWithCompletion(
+                new AnnotateRepeatedContext<>(env, annotated, pos, log, true));
         } finally {
             if (prevLintPos != null)
                 deferredLintHandler.setPos(prevLintPos);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue Mar 25 20:32:46 2014 -0400
@@ -2173,6 +2173,12 @@
             //back-door to infer
             return Infer.this;
         }
+
+        @Override
+        public String toString() {
+            return "Inference vars: " + inferencevars + '\n' +
+                   "Undet vars: " + undetvars;
+        }
     }
 
     final InferenceContext emptyContext = new InferenceContext(List.<Type>nil());
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1037,7 +1037,7 @@
             }
             databuf.appendChar(pool.get(inner));
             databuf.appendChar(
-                inner.owner.kind == TYP ? pool.get(inner.owner) : 0);
+                inner.owner.kind == TYP && !inner.name.isEmpty() ? pool.get(inner.owner) : 0);
             databuf.appendChar(
                 !inner.name.isEmpty() ? pool.get(inner.name) : 0);
             databuf.appendChar(flags);
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1910,6 +1910,7 @@
         if (!c.isFalse()) {
             code.resolve(c.trueJumps);
             int startpc = genCrt ? code.curCP() : 0;
+            code.statBegin(tree.truepart.pos);
             genExpr(tree.truepart, pt).load();
             code.state.forceStackTop(tree.type);
             if (genCrt) code.crt.put(tree.truepart, CRT_FLOW_TARGET,
@@ -1919,6 +1920,7 @@
         if (elseChain != null) {
             code.resolve(elseChain);
             int startpc = genCrt ? code.curCP() : 0;
+            code.statBegin(tree.falsepart.pos);
             genExpr(tree.falsepart, pt).load();
             code.state.forceStackTop(tree.type);
             if (genCrt) code.crt.put(tree.falsepart, CRT_FLOW_TARGET,
--- a/langtools/src/share/classes/javax/lang/model/type/MirroredTypeException.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/src/share/classes/javax/lang/model/type/MirroredTypeException.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, 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
@@ -70,6 +70,10 @@
 
     /**
      * Explicitly set all transient fields.
+     * @param s the serial stream
+     * @throws ClassNotFoundException for a missing class during
+     * deserialization
+     * @throws IOException for an IO problem during deserialization
      */
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
--- a/langtools/src/share/classes/javax/lang/model/type/MirroredTypesException.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/src/share/classes/javax/lang/model/type/MirroredTypesException.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, 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
@@ -85,6 +85,10 @@
 
     /**
      * Explicitly set all transient fields.
+     * @param s the serial stream
+     * @throws ClassNotFoundException for a missing class during
+     * deserialization
+     * @throws IOException for an IO problem during deserialization
      */
     private void readObject(ObjectInputStream s)
         throws IOException, ClassNotFoundException {
--- a/langtools/test/tools/javac/6464451/BigFinally.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +0,0 @@
-/*
- * Copyright (c) 2007, 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     6464451
- * @summary javac in 5.0ux can not compile try-finally block which has a lot of "return"
- * @author  Wei Tao
- * @compile -source 5 -target 5 BigFinally.java
- * @clean BigFinally
- * @compile/fail BigFinally.java
- */
-
-public class BigFinally {
-    static public int func(int i) {
-        try {
-            if(i == 1) return 1;
-        } finally {
-            try {
-                if(i == 2) return 2;
-                if(i == 3 ) return 3;
-                if(i == 4 ) return 4;
-                if(i == 5 ) return 5;
-                if(i == 6 ) return 6;
-                if(i == 7 ) return 7;
-                if(i == 8 ) return 8;
-                if(i == 9 ) return 9;
-                if(i == 10 ) return 10;
-                if(i == 11 ) return 11;
-                if(i == 12 ) return 12;
-                if(i == 13 ) return 13;
-                if(i == 14 ) return 14;
-                if(i == 15 ) return 15;
-                if(i == 16 ) return 16;
-                if(i == 17 ) return 17;
-                if(i == 18 ) return 18;
-                if(i == 19 ) return 19;
-                if(i == 20 ) return 20;
-                if(i == 21 ) return 21;
-                if(i == 22 ) return 22;
-                if(i == 23 ) return 23;
-                if(i == 24 ) return 24;
-                if(i == 25 ) return 25;
-                if(i == 26 ) return 26;
-                if(i == 27 ) return 27;
-                if(i == 28 ) return 28;
-                if(i == 29 ) return 29;
-                if(i == 30 ) return 30;
-                if(i == 31 ) return 31;
-                if(i == 32 ) return 32;
-                if(i == 33 ) return 33;
-                if(i == 34 ) return 34;
-                if(i == 35 ) return 35;
-                if(i == 36 ) return 36;
-                if(i == 37 ) return 37;
-                if(i == 38 ) return 38;
-                if(i == 39 ) return 39;
-                if(i == 40 ) return 40;
-                if(i == 41 ) return 41;
-                if(i == 42 ) return 42;
-                if(i == 43 ) return 43;
-                if(i == 44 ) return 44;
-                if(i == 45 ) return 45;
-                if(i == 46 ) return 46;
-                if(i == 47 ) return 47;
-                if(i == 48 ) return 48;
-                if(i == 49 ) return 49;
-                if(i == 50 ) return 50;
-                if(i == 51 ) return 51;
-                if(i == 52 ) return 52;
-                if(i == 53 ) return 53;
-                if(i == 54 ) return 54;
-                if(i == 55 ) return 55;
-                if(i == 56 ) return 56;
-                if(i == 57 ) return 57;
-                if(i == 58 ) return 58;
-                if(i == 59 ) return 59;
-                if(i == 60 ) return 60;
-                if(i == 61 ) return 61;
-                if(i == 62 ) return 62;
-                if(i == 63 ) return 63;
-                if(i == 64 ) return 64;
-                if(i == 65 ) return 65;
-                if(i == 66 ) return 66;
-                if(i == 67 ) return 67;
-                if(i == 68 ) return 68;
-                if(i == 69 ) return 69;
-                if(i == 70 ) return 70;
-                if(i == 71 ) return 71;
-                if(i == 72 ) return 72;
-                if(i == 73 ) return 73;
-                if(i == 74 ) return 74;
-                if(i == 75 ) return 75;
-                if(i == 76 ) return 76;
-                if(i == 77 ) return 77;
-                if(i == 78 ) return 78;
-                if(i == 79 ) return 79;
-                if(i == 80 ) return 80;
-                if(i == 81 ) return 81;
-                if(i == 82 ) return 82;
-                if(i == 83 ) return 83;
-                if(i == 84 ) return 84;
-                if(i == 85 ) return 85;
-                if(i == 86 ) return 86;
-                if(i == 87 ) return 87;
-                if(i == 88 ) return 88;
-                if(i == 89 ) return 89;
-                if(i == 90 ) return 90;
-                if(i == 91 ) return 91;
-                if(i == 92 ) return 92;
-                if(i == 93 ) return 93;
-                if(i == 94 ) return 94;
-                if(i == 95 ) return 95;
-                if(i == 96 ) return 96;
-                if(i == 97 ) return 97;
-                if(i == 98 ) return 98;
-                if(i == 99 ) return 99;
-                if(i == 100 ) return 100;
-            } finally {
-                int x = 0;
-                x += 1;
-                x += 2;
-                x += 3;
-                x += 4;
-                x += 5;
-                x += 6;
-                x += 7;
-                x += 8;
-                x += 9;
-                x += 10;
-                x += 11;
-                x += 12;
-                x += 13;
-                x += 14;
-                x += 15;
-                x += 16;
-                x += 17;
-                x += 18;
-                x += 19;
-                x += 20;
-                x += 21;
-                x += 22;
-                x += 23;
-                x += 24;
-                x += 25;
-                x += 26;
-                x += 27;
-                x += 28;
-                x += 29;
-                x += 30;
-                x += 31;
-                x += 32;
-                x += 33;
-                x += 34;
-                x += 35;
-                x += 36;
-                x += 37;
-                x += 38;
-                x += 39;
-                x += 40;
-                x += 41;
-                x += 42;
-                x += 43;
-                x += 44;
-                x += 45;
-                x += 46;
-                x += 47;
-                x += 48;
-                x += 49;
-                x += 50;
-                x += 51;
-                x += 52;
-                x += 53;
-                x += 54;
-                x += 55;
-                x += 56;
-                x += 57;
-                x += 58;
-                x += 59;
-                x += 60;
-                x += 61;
-                x += 62;
-                x += 63;
-                x += 64;
-                x += 65;
-                x += 66;
-                x += 67;
-                x += 68;
-                x += 69;
-                x += 70;
-                x += 71;
-                x += 72;
-                x += 73;
-                x += 74;
-                x += 75;
-                x += 76;
-                x += 77;
-                x += 78;
-                x += 79;
-                x += 80;
-                x += 81;
-                x += 82;
-                x += 83;
-                x += 84;
-                x += 85;
-                x += 86;
-                x += 87;
-                x += 88;
-                x += 89;
-                x += 90;
-                x += 91;
-                x += 92;
-                x += 93;
-                x += 94;
-                x += 95;
-                x += 96;
-                x += 97;
-                x += 98;
-                x += 99;
-                x += 100;
-            }
-        }
-        return 0;
-    }
-}
--- a/langtools/test/tools/javac/6464451/DeepNestedFinally.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2007, 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     6464451
- * @summary javac in 5.0ux can not compile try-finally block which has a lot of "return"
- * @author  Wei Tao
- * @compile -source 5 -target 5 DeepNestedFinally.java
- * @clean DeepNestedFinally
- * @compile/fail DeepNestedFinally.java
- */
-
-public class DeepNestedFinally {
-   static public int func(int i) {
-    try {
-        if(i == 1) return 1;
-    } finally {
-        try {
-            if(i == 2) return 2;
-        } finally {
-            try {
-                if(i == 3) return 3;
-            } finally {
-                try {
-                    if(i == 4) return 4;
-                } finally {
-                    try {
-                        if(i == 5) return 5;
-                    } finally {
-                        try {
-                            if(i == 6) return 6;
-                        } finally {
-                            try {
-                                if (i == 7) return 7;
-                            } finally {
-                                int x = 0;
-                                x += 1;
-                                x += 2;
-                                x += 3;
-                                x += 4;
-                                x += 5;
-                                x += 6;
-                                x += 7;
-                                x += 8;
-                                x += 9;
-                            }
-                        }
-                    }
-                }
-             }
-         }
-      }
-      return 0;
-   }
-}
--- a/langtools/test/tools/javac/6464451/ManyExitsInTry.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2051 +0,0 @@
-/*
- * Copyright (c) 2007, 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     6464451
- * @summary javac in 5.0ux can not compile try-finally block which has a lot of "return"
- * @author  Wei Tao
- * @compile -source 5 -target 5 ManyExitsInTry.java
- * @clean ManyExitsInTry
- * @compile/fail ManyExitsInTry.java
- */
-
-public class ManyExitsInTry {
-   static public int func(int i) {
-      try {
-         if(i == 0 ) return 0;
-         if(i == 1 ) return 1;
-         if(i == 2 ) return 2;
-         if(i == 3 ) return 3;
-         if(i == 4 ) return 4;
-         if(i == 5 ) return 5;
-         if(i == 6 ) return 6;
-         if(i == 7 ) return 7;
-         if(i == 8 ) return 8;
-         if(i == 9 ) return 9;
-         if(i == 10 ) return 10;
-         if(i == 11 ) return 11;
-         if(i == 12 ) return 12;
-         if(i == 13 ) return 13;
-         if(i == 14 ) return 14;
-         if(i == 15 ) return 15;
-         if(i == 16 ) return 16;
-         if(i == 17 ) return 17;
-         if(i == 18 ) return 18;
-         if(i == 19 ) return 19;
-         if(i == 20 ) return 20;
-         if(i == 21 ) return 21;
-         if(i == 22 ) return 22;
-         if(i == 23 ) return 23;
-         if(i == 24 ) return 24;
-         if(i == 25 ) return 25;
-         if(i == 26 ) return 26;
-         if(i == 27 ) return 27;
-         if(i == 28 ) return 28;
-         if(i == 29 ) return 29;
-         if(i == 30 ) return 30;
-         if(i == 31 ) return 31;
-         if(i == 32 ) return 32;
-         if(i == 33 ) return 33;
-         if(i == 34 ) return 34;
-         if(i == 35 ) return 35;
-         if(i == 36 ) return 36;
-         if(i == 37 ) return 37;
-         if(i == 38 ) return 38;
-         if(i == 39 ) return 39;
-         if(i == 40 ) return 40;
-         if(i == 41 ) return 41;
-         if(i == 42 ) return 42;
-         if(i == 43 ) return 43;
-         if(i == 44 ) return 44;
-         if(i == 45 ) return 45;
-         if(i == 46 ) return 46;
-         if(i == 47 ) return 47;
-         if(i == 48 ) return 48;
-         if(i == 49 ) return 49;
-         if(i == 50 ) return 50;
-         if(i == 51 ) return 51;
-         if(i == 52 ) return 52;
-         if(i == 53 ) return 53;
-         if(i == 54 ) return 54;
-         if(i == 55 ) return 55;
-         if(i == 56 ) return 56;
-         if(i == 57 ) return 57;
-         if(i == 58 ) return 58;
-         if(i == 59 ) return 59;
-         if(i == 60 ) return 60;
-         if(i == 61 ) return 61;
-         if(i == 62 ) return 62;
-         if(i == 63 ) return 63;
-         if(i == 64 ) return 64;
-         if(i == 65 ) return 65;
-         if(i == 66 ) return 66;
-         if(i == 67 ) return 67;
-         if(i == 68 ) return 68;
-         if(i == 69 ) return 69;
-         if(i == 70 ) return 70;
-         if(i == 71 ) return 71;
-         if(i == 72 ) return 72;
-         if(i == 73 ) return 73;
-         if(i == 74 ) return 74;
-         if(i == 75 ) return 75;
-         if(i == 76 ) return 76;
-         if(i == 77 ) return 77;
-         if(i == 78 ) return 78;
-         if(i == 79 ) return 79;
-         if(i == 80 ) return 80;
-         if(i == 81 ) return 81;
-         if(i == 82 ) return 82;
-         if(i == 83 ) return 83;
-         if(i == 84 ) return 84;
-         if(i == 85 ) return 85;
-         if(i == 86 ) return 86;
-         if(i == 87 ) return 87;
-         if(i == 88 ) return 88;
-         if(i == 89 ) return 89;
-         if(i == 90 ) return 90;
-         if(i == 91 ) return 91;
-         if(i == 92 ) return 92;
-         if(i == 93 ) return 93;
-         if(i == 94 ) return 94;
-         if(i == 95 ) return 95;
-         if(i == 96 ) return 96;
-         if(i == 97 ) return 97;
-         if(i == 98 ) return 98;
-         if(i == 99 ) return 99;
-         if(i == 100 ) return 100;
-         if(i == 101 ) return 101;
-         if(i == 102 ) return 102;
-         if(i == 103 ) return 103;
-         if(i == 104 ) return 104;
-         if(i == 105 ) return 105;
-         if(i == 106 ) return 106;
-         if(i == 107 ) return 107;
-         if(i == 108 ) return 108;
-         if(i == 109 ) return 109;
-         if(i == 110 ) return 110;
-         if(i == 111 ) return 111;
-         if(i == 112 ) return 112;
-         if(i == 113 ) return 113;
-         if(i == 114 ) return 114;
-         if(i == 115 ) return 115;
-         if(i == 116 ) return 116;
-         if(i == 117 ) return 117;
-         if(i == 118 ) return 118;
-         if(i == 119 ) return 119;
-         if(i == 120 ) return 120;
-         if(i == 121 ) return 121;
-         if(i == 122 ) return 122;
-         if(i == 123 ) return 123;
-         if(i == 124 ) return 124;
-         if(i == 125 ) return 125;
-         if(i == 126 ) return 126;
-         if(i == 127 ) return 127;
-         if(i == 128 ) return 128;
-         if(i == 129 ) return 129;
-         if(i == 130 ) return 130;
-         if(i == 131 ) return 131;
-         if(i == 132 ) return 132;
-         if(i == 133 ) return 133;
-         if(i == 134 ) return 134;
-         if(i == 135 ) return 135;
-         if(i == 136 ) return 136;
-         if(i == 137 ) return 137;
-         if(i == 138 ) return 138;
-         if(i == 139 ) return 139;
-         if(i == 140 ) return 140;
-         if(i == 141 ) return 141;
-         if(i == 142 ) return 142;
-         if(i == 143 ) return 143;
-         if(i == 144 ) return 144;
-         if(i == 145 ) return 145;
-         if(i == 146 ) return 146;
-         if(i == 147 ) return 147;
-         if(i == 148 ) return 148;
-         if(i == 149 ) return 149;
-         if(i == 150 ) return 150;
-         if(i == 151 ) return 151;
-         if(i == 152 ) return 152;
-         if(i == 153 ) return 153;
-         if(i == 154 ) return 154;
-         if(i == 155 ) return 155;
-         if(i == 156 ) return 156;
-         if(i == 157 ) return 157;
-         if(i == 158 ) return 158;
-         if(i == 159 ) return 159;
-         if(i == 160 ) return 160;
-         if(i == 161 ) return 161;
-         if(i == 162 ) return 162;
-         if(i == 163 ) return 163;
-         if(i == 164 ) return 164;
-         if(i == 165 ) return 165;
-         if(i == 166 ) return 166;
-         if(i == 167 ) return 167;
-         if(i == 168 ) return 168;
-         if(i == 169 ) return 169;
-         if(i == 170 ) return 170;
-         if(i == 171 ) return 171;
-         if(i == 172 ) return 172;
-         if(i == 173 ) return 173;
-         if(i == 174 ) return 174;
-         if(i == 175 ) return 175;
-         if(i == 176 ) return 176;
-         if(i == 177 ) return 177;
-         if(i == 178 ) return 178;
-         if(i == 179 ) return 179;
-         if(i == 180 ) return 180;
-         if(i == 181 ) return 181;
-         if(i == 182 ) return 182;
-         if(i == 183 ) return 183;
-         if(i == 184 ) return 184;
-         if(i == 185 ) return 185;
-         if(i == 186 ) return 186;
-         if(i == 187 ) return 187;
-         if(i == 188 ) return 188;
-         if(i == 189 ) return 189;
-         if(i == 190 ) return 190;
-         if(i == 191 ) return 191;
-         if(i == 192 ) return 192;
-         if(i == 193 ) return 193;
-         if(i == 194 ) return 194;
-         if(i == 195 ) return 195;
-         if(i == 196 ) return 196;
-         if(i == 197 ) return 197;
-         if(i == 198 ) return 198;
-         if(i == 199 ) return 199;
-         if(i == 200 ) return 200;
-         if(i == 201 ) return 201;
-         if(i == 202 ) return 202;
-         if(i == 203 ) return 203;
-         if(i == 204 ) return 204;
-         if(i == 205 ) return 205;
-         if(i == 206 ) return 206;
-         if(i == 207 ) return 207;
-         if(i == 208 ) return 208;
-         if(i == 209 ) return 209;
-         if(i == 210 ) return 210;
-         if(i == 211 ) return 211;
-         if(i == 212 ) return 212;
-         if(i == 213 ) return 213;
-         if(i == 214 ) return 214;
-         if(i == 215 ) return 215;
-         if(i == 216 ) return 216;
-         if(i == 217 ) return 217;
-         if(i == 218 ) return 218;
-         if(i == 219 ) return 219;
-         if(i == 220 ) return 220;
-         if(i == 221 ) return 221;
-         if(i == 222 ) return 222;
-         if(i == 223 ) return 223;
-         if(i == 224 ) return 224;
-         if(i == 225 ) return 225;
-         if(i == 226 ) return 226;
-         if(i == 227 ) return 227;
-         if(i == 228 ) return 228;
-         if(i == 229 ) return 229;
-         if(i == 230 ) return 230;
-         if(i == 231 ) return 231;
-         if(i == 232 ) return 232;
-         if(i == 233 ) return 233;
-         if(i == 234 ) return 234;
-         if(i == 235 ) return 235;
-         if(i == 236 ) return 236;
-         if(i == 237 ) return 237;
-         if(i == 238 ) return 238;
-         if(i == 239 ) return 239;
-         if(i == 240 ) return 240;
-         if(i == 241 ) return 241;
-         if(i == 242 ) return 242;
-         if(i == 243 ) return 243;
-         if(i == 244 ) return 244;
-         if(i == 245 ) return 245;
-         if(i == 246 ) return 246;
-         if(i == 247 ) return 247;
-         if(i == 248 ) return 248;
-         if(i == 249 ) return 249;
-         if(i == 250 ) return 250;
-         if(i == 251 ) return 251;
-         if(i == 252 ) return 252;
-         if(i == 253 ) return 253;
-         if(i == 254 ) return 254;
-         if(i == 255 ) return 255;
-         if(i == 256 ) return 256;
-         if(i == 257 ) return 257;
-         if(i == 258 ) return 258;
-         if(i == 259 ) return 259;
-         if(i == 260 ) return 260;
-         if(i == 261 ) return 261;
-         if(i == 262 ) return 262;
-         if(i == 263 ) return 263;
-         if(i == 264 ) return 264;
-         if(i == 265 ) return 265;
-         if(i == 266 ) return 266;
-         if(i == 267 ) return 267;
-         if(i == 268 ) return 268;
-         if(i == 269 ) return 269;
-         if(i == 270 ) return 270;
-         if(i == 271 ) return 271;
-         if(i == 272 ) return 272;
-         if(i == 273 ) return 273;
-         if(i == 274 ) return 274;
-         if(i == 275 ) return 275;
-         if(i == 276 ) return 276;
-         if(i == 277 ) return 277;
-         if(i == 278 ) return 278;
-         if(i == 279 ) return 279;
-         if(i == 280 ) return 280;
-         if(i == 281 ) return 281;
-         if(i == 282 ) return 282;
-         if(i == 283 ) return 283;
-         if(i == 284 ) return 284;
-         if(i == 285 ) return 285;
-         if(i == 286 ) return 286;
-         if(i == 287 ) return 287;
-         if(i == 288 ) return 288;
-         if(i == 289 ) return 289;
-         if(i == 290 ) return 290;
-         if(i == 291 ) return 291;
-         if(i == 292 ) return 292;
-         if(i == 293 ) return 293;
-         if(i == 294 ) return 294;
-         if(i == 295 ) return 295;
-         if(i == 296 ) return 296;
-         if(i == 297 ) return 297;
-         if(i == 298 ) return 298;
-         if(i == 299 ) return 299;
-         if(i == 300 ) return 300;
-         if(i == 301 ) return 301;
-         if(i == 302 ) return 302;
-         if(i == 303 ) return 303;
-         if(i == 304 ) return 304;
-         if(i == 305 ) return 305;
-         if(i == 306 ) return 306;
-         if(i == 307 ) return 307;
-         if(i == 308 ) return 308;
-         if(i == 309 ) return 309;
-         if(i == 310 ) return 310;
-         if(i == 311 ) return 311;
-         if(i == 312 ) return 312;
-         if(i == 313 ) return 313;
-         if(i == 314 ) return 314;
-         if(i == 315 ) return 315;
-         if(i == 316 ) return 316;
-         if(i == 317 ) return 317;
-         if(i == 318 ) return 318;
-         if(i == 319 ) return 319;
-         if(i == 320 ) return 320;
-         if(i == 321 ) return 321;
-         if(i == 322 ) return 322;
-         if(i == 323 ) return 323;
-         if(i == 324 ) return 324;
-         if(i == 325 ) return 325;
-         if(i == 326 ) return 326;
-         if(i == 327 ) return 327;
-         if(i == 328 ) return 328;
-         if(i == 329 ) return 329;
-         if(i == 330 ) return 330;
-         if(i == 331 ) return 331;
-         if(i == 332 ) return 332;
-         if(i == 333 ) return 333;
-         if(i == 334 ) return 334;
-         if(i == 335 ) return 335;
-         if(i == 336 ) return 336;
-         if(i == 337 ) return 337;
-         if(i == 338 ) return 338;
-         if(i == 339 ) return 339;
-         if(i == 340 ) return 340;
-         if(i == 341 ) return 341;
-         if(i == 342 ) return 342;
-         if(i == 343 ) return 343;
-         if(i == 344 ) return 344;
-         if(i == 345 ) return 345;
-         if(i == 346 ) return 346;
-         if(i == 347 ) return 347;
-         if(i == 348 ) return 348;
-         if(i == 349 ) return 349;
-         if(i == 350 ) return 350;
-         if(i == 351 ) return 351;
-         if(i == 352 ) return 352;
-         if(i == 353 ) return 353;
-         if(i == 354 ) return 354;
-         if(i == 355 ) return 355;
-         if(i == 356 ) return 356;
-         if(i == 357 ) return 357;
-         if(i == 358 ) return 358;
-         if(i == 359 ) return 359;
-         if(i == 360 ) return 360;
-         if(i == 361 ) return 361;
-         if(i == 362 ) return 362;
-         if(i == 363 ) return 363;
-         if(i == 364 ) return 364;
-         if(i == 365 ) return 365;
-         if(i == 366 ) return 366;
-         if(i == 367 ) return 367;
-         if(i == 368 ) return 368;
-         if(i == 369 ) return 369;
-         if(i == 370 ) return 370;
-         if(i == 371 ) return 371;
-         if(i == 372 ) return 372;
-         if(i == 373 ) return 373;
-         if(i == 374 ) return 374;
-         if(i == 375 ) return 375;
-         if(i == 376 ) return 376;
-         if(i == 377 ) return 377;
-         if(i == 378 ) return 378;
-         if(i == 379 ) return 379;
-         if(i == 380 ) return 380;
-         if(i == 381 ) return 381;
-         if(i == 382 ) return 382;
-         if(i == 383 ) return 383;
-         if(i == 384 ) return 384;
-         if(i == 385 ) return 385;
-         if(i == 386 ) return 386;
-         if(i == 387 ) return 387;
-         if(i == 388 ) return 388;
-         if(i == 389 ) return 389;
-         if(i == 390 ) return 390;
-         if(i == 391 ) return 391;
-         if(i == 392 ) return 392;
-         if(i == 393 ) return 393;
-         if(i == 394 ) return 394;
-         if(i == 395 ) return 395;
-         if(i == 396 ) return 396;
-         if(i == 397 ) return 397;
-         if(i == 398 ) return 398;
-         if(i == 399 ) return 399;
-         if(i == 400 ) return 400;
-         if(i == 401 ) return 401;
-         if(i == 402 ) return 402;
-         if(i == 403 ) return 403;
-         if(i == 404 ) return 404;
-         if(i == 405 ) return 405;
-         if(i == 406 ) return 406;
-         if(i == 407 ) return 407;
-         if(i == 408 ) return 408;
-         if(i == 409 ) return 409;
-         if(i == 410 ) return 410;
-         if(i == 411 ) return 411;
-         if(i == 412 ) return 412;
-         if(i == 413 ) return 413;
-         if(i == 414 ) return 414;
-         if(i == 415 ) return 415;
-         if(i == 416 ) return 416;
-         if(i == 417 ) return 417;
-         if(i == 418 ) return 418;
-         if(i == 419 ) return 419;
-         if(i == 420 ) return 420;
-         if(i == 421 ) return 421;
-         if(i == 422 ) return 422;
-         if(i == 423 ) return 423;
-         if(i == 424 ) return 424;
-         if(i == 425 ) return 425;
-         if(i == 426 ) return 426;
-         if(i == 427 ) return 427;
-         if(i == 428 ) return 428;
-         if(i == 429 ) return 429;
-         if(i == 430 ) return 430;
-         if(i == 431 ) return 431;
-         if(i == 432 ) return 432;
-         if(i == 433 ) return 433;
-         if(i == 434 ) return 434;
-         if(i == 435 ) return 435;
-         if(i == 436 ) return 436;
-         if(i == 437 ) return 437;
-         if(i == 438 ) return 438;
-         if(i == 439 ) return 439;
-         if(i == 440 ) return 440;
-         if(i == 441 ) return 441;
-         if(i == 442 ) return 442;
-         if(i == 443 ) return 443;
-         if(i == 444 ) return 444;
-         if(i == 445 ) return 445;
-         if(i == 446 ) return 446;
-         if(i == 447 ) return 447;
-         if(i == 448 ) return 448;
-         if(i == 449 ) return 449;
-         if(i == 450 ) return 450;
-         if(i == 451 ) return 451;
-         if(i == 452 ) return 452;
-         if(i == 453 ) return 453;
-         if(i == 454 ) return 454;
-         if(i == 455 ) return 455;
-         if(i == 456 ) return 456;
-         if(i == 457 ) return 457;
-         if(i == 458 ) return 458;
-         if(i == 459 ) return 459;
-         if(i == 460 ) return 460;
-         if(i == 461 ) return 461;
-         if(i == 462 ) return 462;
-         if(i == 463 ) return 463;
-         if(i == 464 ) return 464;
-         if(i == 465 ) return 465;
-         if(i == 466 ) return 466;
-         if(i == 467 ) return 467;
-         if(i == 468 ) return 468;
-         if(i == 469 ) return 469;
-         if(i == 470 ) return 470;
-         if(i == 471 ) return 471;
-         if(i == 472 ) return 472;
-         if(i == 473 ) return 473;
-         if(i == 474 ) return 474;
-         if(i == 475 ) return 475;
-         if(i == 476 ) return 476;
-         if(i == 477 ) return 477;
-         if(i == 478 ) return 478;
-         if(i == 479 ) return 479;
-         if(i == 480 ) return 480;
-         if(i == 481 ) return 481;
-         if(i == 482 ) return 482;
-         if(i == 483 ) return 483;
-         if(i == 484 ) return 484;
-         if(i == 485 ) return 485;
-         if(i == 486 ) return 486;
-         if(i == 487 ) return 487;
-         if(i == 488 ) return 488;
-         if(i == 489 ) return 489;
-         if(i == 490 ) return 490;
-         if(i == 491 ) return 491;
-         if(i == 492 ) return 492;
-         if(i == 493 ) return 493;
-         if(i == 494 ) return 494;
-         if(i == 495 ) return 495;
-         if(i == 496 ) return 496;
-         if(i == 497 ) return 497;
-         if(i == 498 ) return 498;
-         if(i == 499 ) return 499;
-         if(i == 500 ) return 500;
-         if(i == 501 ) return 501;
-         if(i == 502 ) return 502;
-         if(i == 503 ) return 503;
-         if(i == 504 ) return 504;
-         if(i == 505 ) return 505;
-         if(i == 506 ) return 506;
-         if(i == 507 ) return 507;
-         if(i == 508 ) return 508;
-         if(i == 509 ) return 509;
-         if(i == 510 ) return 510;
-         if(i == 511 ) return 511;
-         if(i == 512 ) return 512;
-         if(i == 513 ) return 513;
-         if(i == 514 ) return 514;
-         if(i == 515 ) return 515;
-         if(i == 516 ) return 516;
-         if(i == 517 ) return 517;
-         if(i == 518 ) return 518;
-         if(i == 519 ) return 519;
-         if(i == 520 ) return 520;
-         if(i == 521 ) return 521;
-         if(i == 522 ) return 522;
-         if(i == 523 ) return 523;
-         if(i == 524 ) return 524;
-         if(i == 525 ) return 525;
-         if(i == 526 ) return 526;
-         if(i == 527 ) return 527;
-         if(i == 528 ) return 528;
-         if(i == 529 ) return 529;
-         if(i == 530 ) return 530;
-         if(i == 531 ) return 531;
-         if(i == 532 ) return 532;
-         if(i == 533 ) return 533;
-         if(i == 534 ) return 534;
-         if(i == 535 ) return 535;
-         if(i == 536 ) return 536;
-         if(i == 537 ) return 537;
-         if(i == 538 ) return 538;
-         if(i == 539 ) return 539;
-         if(i == 540 ) return 540;
-         if(i == 541 ) return 541;
-         if(i == 542 ) return 542;
-         if(i == 543 ) return 543;
-         if(i == 544 ) return 544;
-         if(i == 545 ) return 545;
-         if(i == 546 ) return 546;
-         if(i == 547 ) return 547;
-         if(i == 548 ) return 548;
-         if(i == 549 ) return 549;
-         if(i == 550 ) return 550;
-         if(i == 551 ) return 551;
-         if(i == 552 ) return 552;
-         if(i == 553 ) return 553;
-         if(i == 554 ) return 554;
-         if(i == 555 ) return 555;
-         if(i == 556 ) return 556;
-         if(i == 557 ) return 557;
-         if(i == 558 ) return 558;
-         if(i == 559 ) return 559;
-         if(i == 560 ) return 560;
-         if(i == 561 ) return 561;
-         if(i == 562 ) return 562;
-         if(i == 563 ) return 563;
-         if(i == 564 ) return 564;
-         if(i == 565 ) return 565;
-         if(i == 566 ) return 566;
-         if(i == 567 ) return 567;
-         if(i == 568 ) return 568;
-         if(i == 569 ) return 569;
-         if(i == 570 ) return 570;
-         if(i == 571 ) return 571;
-         if(i == 572 ) return 572;
-         if(i == 573 ) return 573;
-         if(i == 574 ) return 574;
-         if(i == 575 ) return 575;
-         if(i == 576 ) return 576;
-         if(i == 577 ) return 577;
-         if(i == 578 ) return 578;
-         if(i == 579 ) return 579;
-         if(i == 580 ) return 580;
-         if(i == 581 ) return 581;
-         if(i == 582 ) return 582;
-         if(i == 583 ) return 583;
-         if(i == 584 ) return 584;
-         if(i == 585 ) return 585;
-         if(i == 586 ) return 586;
-         if(i == 587 ) return 587;
-         if(i == 588 ) return 588;
-         if(i == 589 ) return 589;
-         if(i == 590 ) return 590;
-         if(i == 591 ) return 591;
-         if(i == 592 ) return 592;
-         if(i == 593 ) return 593;
-         if(i == 594 ) return 594;
-         if(i == 595 ) return 595;
-         if(i == 596 ) return 596;
-         if(i == 597 ) return 597;
-         if(i == 598 ) return 598;
-         if(i == 599 ) return 599;
-         if(i == 600 ) return 600;
-         if(i == 601 ) return 601;
-         if(i == 602 ) return 602;
-         if(i == 603 ) return 603;
-         if(i == 604 ) return 604;
-         if(i == 605 ) return 605;
-         if(i == 606 ) return 606;
-         if(i == 607 ) return 607;
-         if(i == 608 ) return 608;
-         if(i == 609 ) return 609;
-         if(i == 610 ) return 610;
-         if(i == 611 ) return 611;
-         if(i == 612 ) return 612;
-         if(i == 613 ) return 613;
-         if(i == 614 ) return 614;
-         if(i == 615 ) return 615;
-         if(i == 616 ) return 616;
-         if(i == 617 ) return 617;
-         if(i == 618 ) return 618;
-         if(i == 619 ) return 619;
-         if(i == 620 ) return 620;
-         if(i == 621 ) return 621;
-         if(i == 622 ) return 622;
-         if(i == 623 ) return 623;
-         if(i == 624 ) return 624;
-         if(i == 625 ) return 625;
-         if(i == 626 ) return 626;
-         if(i == 627 ) return 627;
-         if(i == 628 ) return 628;
-         if(i == 629 ) return 629;
-         if(i == 630 ) return 630;
-         if(i == 631 ) return 631;
-         if(i == 632 ) return 632;
-         if(i == 633 ) return 633;
-         if(i == 634 ) return 634;
-         if(i == 635 ) return 635;
-         if(i == 636 ) return 636;
-         if(i == 637 ) return 637;
-         if(i == 638 ) return 638;
-         if(i == 639 ) return 639;
-         if(i == 640 ) return 640;
-         if(i == 641 ) return 641;
-         if(i == 642 ) return 642;
-         if(i == 643 ) return 643;
-         if(i == 644 ) return 644;
-         if(i == 645 ) return 645;
-         if(i == 646 ) return 646;
-         if(i == 647 ) return 647;
-         if(i == 648 ) return 648;
-         if(i == 649 ) return 649;
-         if(i == 650 ) return 650;
-         if(i == 651 ) return 651;
-         if(i == 652 ) return 652;
-         if(i == 653 ) return 653;
-         if(i == 654 ) return 654;
-         if(i == 655 ) return 655;
-         if(i == 656 ) return 656;
-         if(i == 657 ) return 657;
-         if(i == 658 ) return 658;
-         if(i == 659 ) return 659;
-         if(i == 660 ) return 660;
-         if(i == 661 ) return 661;
-         if(i == 662 ) return 662;
-         if(i == 663 ) return 663;
-         if(i == 664 ) return 664;
-         if(i == 665 ) return 665;
-         if(i == 666 ) return 666;
-         if(i == 667 ) return 667;
-         if(i == 668 ) return 668;
-         if(i == 669 ) return 669;
-         if(i == 670 ) return 670;
-         if(i == 671 ) return 671;
-         if(i == 672 ) return 672;
-         if(i == 673 ) return 673;
-         if(i == 674 ) return 674;
-         if(i == 675 ) return 675;
-         if(i == 676 ) return 676;
-         if(i == 677 ) return 677;
-         if(i == 678 ) return 678;
-         if(i == 679 ) return 679;
-         if(i == 680 ) return 680;
-         if(i == 681 ) return 681;
-         if(i == 682 ) return 682;
-         if(i == 683 ) return 683;
-         if(i == 684 ) return 684;
-         if(i == 685 ) return 685;
-         if(i == 686 ) return 686;
-         if(i == 687 ) return 687;
-         if(i == 688 ) return 688;
-         if(i == 689 ) return 689;
-         if(i == 690 ) return 690;
-         if(i == 691 ) return 691;
-         if(i == 692 ) return 692;
-         if(i == 693 ) return 693;
-         if(i == 694 ) return 694;
-         if(i == 695 ) return 695;
-         if(i == 696 ) return 696;
-         if(i == 697 ) return 697;
-         if(i == 698 ) return 698;
-         if(i == 699 ) return 699;
-         if(i == 700 ) return 700;
-         if(i == 701 ) return 701;
-         if(i == 702 ) return 702;
-         if(i == 703 ) return 703;
-         if(i == 704 ) return 704;
-         if(i == 705 ) return 705;
-         if(i == 706 ) return 706;
-         if(i == 707 ) return 707;
-         if(i == 708 ) return 708;
-         if(i == 709 ) return 709;
-         if(i == 710 ) return 710;
-         if(i == 711 ) return 711;
-         if(i == 712 ) return 712;
-         if(i == 713 ) return 713;
-         if(i == 714 ) return 714;
-         if(i == 715 ) return 715;
-         if(i == 716 ) return 716;
-         if(i == 717 ) return 717;
-         if(i == 718 ) return 718;
-         if(i == 719 ) return 719;
-         if(i == 720 ) return 720;
-         if(i == 721 ) return 721;
-         if(i == 722 ) return 722;
-         if(i == 723 ) return 723;
-         if(i == 724 ) return 724;
-         if(i == 725 ) return 725;
-         if(i == 726 ) return 726;
-         if(i == 727 ) return 727;
-         if(i == 728 ) return 728;
-         if(i == 729 ) return 729;
-         if(i == 730 ) return 730;
-         if(i == 731 ) return 731;
-         if(i == 732 ) return 732;
-         if(i == 733 ) return 733;
-         if(i == 734 ) return 734;
-         if(i == 735 ) return 735;
-         if(i == 736 ) return 736;
-         if(i == 737 ) return 737;
-         if(i == 738 ) return 738;
-         if(i == 739 ) return 739;
-         if(i == 740 ) return 740;
-         if(i == 741 ) return 741;
-         if(i == 742 ) return 742;
-         if(i == 743 ) return 743;
-         if(i == 744 ) return 744;
-         if(i == 745 ) return 745;
-         if(i == 746 ) return 746;
-         if(i == 747 ) return 747;
-         if(i == 748 ) return 748;
-         if(i == 749 ) return 749;
-         if(i == 750 ) return 750;
-         if(i == 751 ) return 751;
-         if(i == 752 ) return 752;
-         if(i == 753 ) return 753;
-         if(i == 754 ) return 754;
-         if(i == 755 ) return 755;
-         if(i == 756 ) return 756;
-         if(i == 757 ) return 757;
-         if(i == 758 ) return 758;
-         if(i == 759 ) return 759;
-         if(i == 760 ) return 760;
-         if(i == 761 ) return 761;
-         if(i == 762 ) return 762;
-         if(i == 763 ) return 763;
-         if(i == 764 ) return 764;
-         if(i == 765 ) return 765;
-         if(i == 766 ) return 766;
-         if(i == 767 ) return 767;
-         if(i == 768 ) return 768;
-         if(i == 769 ) return 769;
-         if(i == 770 ) return 770;
-         if(i == 771 ) return 771;
-         if(i == 772 ) return 772;
-         if(i == 773 ) return 773;
-         if(i == 774 ) return 774;
-         if(i == 775 ) return 775;
-         if(i == 776 ) return 776;
-         if(i == 777 ) return 777;
-         if(i == 778 ) return 778;
-         if(i == 779 ) return 779;
-         if(i == 780 ) return 780;
-         if(i == 781 ) return 781;
-         if(i == 782 ) return 782;
-         if(i == 783 ) return 783;
-         if(i == 784 ) return 784;
-         if(i == 785 ) return 785;
-         if(i == 786 ) return 786;
-         if(i == 787 ) return 787;
-         if(i == 788 ) return 788;
-         if(i == 789 ) return 789;
-         if(i == 790 ) return 790;
-         if(i == 791 ) return 791;
-         if(i == 792 ) return 792;
-         if(i == 793 ) return 793;
-         if(i == 794 ) return 794;
-         if(i == 795 ) return 795;
-         if(i == 796 ) return 796;
-         if(i == 797 ) return 797;
-         if(i == 798 ) return 798;
-         if(i == 799 ) return 799;
-         if(i == 800 ) return 800;
-         if(i == 801 ) return 801;
-         if(i == 802 ) return 802;
-         if(i == 803 ) return 803;
-         if(i == 804 ) return 804;
-         if(i == 805 ) return 805;
-         if(i == 806 ) return 806;
-         if(i == 807 ) return 807;
-         if(i == 808 ) return 808;
-         if(i == 809 ) return 809;
-         if(i == 810 ) return 810;
-         if(i == 811 ) return 811;
-         if(i == 812 ) return 812;
-         if(i == 813 ) return 813;
-         if(i == 814 ) return 814;
-         if(i == 815 ) return 815;
-         if(i == 816 ) return 816;
-         if(i == 817 ) return 817;
-         if(i == 818 ) return 818;
-         if(i == 819 ) return 819;
-         if(i == 820 ) return 820;
-         if(i == 821 ) return 821;
-         if(i == 822 ) return 822;
-         if(i == 823 ) return 823;
-         if(i == 824 ) return 824;
-         if(i == 825 ) return 825;
-         if(i == 826 ) return 826;
-         if(i == 827 ) return 827;
-         if(i == 828 ) return 828;
-         if(i == 829 ) return 829;
-         if(i == 830 ) return 830;
-         if(i == 831 ) return 831;
-         if(i == 832 ) return 832;
-         if(i == 833 ) return 833;
-         if(i == 834 ) return 834;
-         if(i == 835 ) return 835;
-         if(i == 836 ) return 836;
-         if(i == 837 ) return 837;
-         if(i == 838 ) return 838;
-         if(i == 839 ) return 839;
-         if(i == 840 ) return 840;
-         if(i == 841 ) return 841;
-         if(i == 842 ) return 842;
-         if(i == 843 ) return 843;
-         if(i == 844 ) return 844;
-         if(i == 845 ) return 845;
-         if(i == 846 ) return 846;
-         if(i == 847 ) return 847;
-         if(i == 848 ) return 848;
-         if(i == 849 ) return 849;
-         if(i == 850 ) return 850;
-         if(i == 851 ) return 851;
-         if(i == 852 ) return 852;
-         if(i == 853 ) return 853;
-         if(i == 854 ) return 854;
-         if(i == 855 ) return 855;
-         if(i == 856 ) return 856;
-         if(i == 857 ) return 857;
-         if(i == 858 ) return 858;
-         if(i == 859 ) return 859;
-         if(i == 860 ) return 860;
-         if(i == 861 ) return 861;
-         if(i == 862 ) return 862;
-         if(i == 863 ) return 863;
-         if(i == 864 ) return 864;
-         if(i == 865 ) return 865;
-         if(i == 866 ) return 866;
-         if(i == 867 ) return 867;
-         if(i == 868 ) return 868;
-         if(i == 869 ) return 869;
-         if(i == 870 ) return 870;
-         if(i == 871 ) return 871;
-         if(i == 872 ) return 872;
-         if(i == 873 ) return 873;
-         if(i == 874 ) return 874;
-         if(i == 875 ) return 875;
-         if(i == 876 ) return 876;
-         if(i == 877 ) return 877;
-         if(i == 878 ) return 878;
-         if(i == 879 ) return 879;
-         if(i == 880 ) return 880;
-         if(i == 881 ) return 881;
-         if(i == 882 ) return 882;
-         if(i == 883 ) return 883;
-         if(i == 884 ) return 884;
-         if(i == 885 ) return 885;
-         if(i == 886 ) return 886;
-         if(i == 887 ) return 887;
-         if(i == 888 ) return 888;
-         if(i == 889 ) return 889;
-         if(i == 890 ) return 890;
-         if(i == 891 ) return 891;
-         if(i == 892 ) return 892;
-         if(i == 893 ) return 893;
-         if(i == 894 ) return 894;
-         if(i == 895 ) return 895;
-         if(i == 896 ) return 896;
-         if(i == 897 ) return 897;
-         if(i == 898 ) return 898;
-         if(i == 899 ) return 899;
-         if(i == 900 ) return 900;
-         if(i == 901 ) return 901;
-         if(i == 902 ) return 902;
-         if(i == 903 ) return 903;
-         if(i == 904 ) return 904;
-         if(i == 905 ) return 905;
-         if(i == 906 ) return 906;
-         if(i == 907 ) return 907;
-         if(i == 908 ) return 908;
-         if(i == 909 ) return 909;
-         if(i == 910 ) return 910;
-         if(i == 911 ) return 911;
-         if(i == 912 ) return 912;
-         if(i == 913 ) return 913;
-         if(i == 914 ) return 914;
-         if(i == 915 ) return 915;
-         if(i == 916 ) return 916;
-         if(i == 917 ) return 917;
-         if(i == 918 ) return 918;
-         if(i == 919 ) return 919;
-         if(i == 920 ) return 920;
-         if(i == 921 ) return 921;
-         if(i == 922 ) return 922;
-         if(i == 923 ) return 923;
-         if(i == 924 ) return 924;
-         if(i == 925 ) return 925;
-         if(i == 926 ) return 926;
-         if(i == 927 ) return 927;
-         if(i == 928 ) return 928;
-         if(i == 929 ) return 929;
-         if(i == 930 ) return 930;
-         if(i == 931 ) return 931;
-         if(i == 932 ) return 932;
-         if(i == 933 ) return 933;
-         if(i == 934 ) return 934;
-         if(i == 935 ) return 935;
-         if(i == 936 ) return 936;
-         if(i == 937 ) return 937;
-         if(i == 938 ) return 938;
-         if(i == 939 ) return 939;
-         if(i == 940 ) return 940;
-         if(i == 941 ) return 941;
-         if(i == 942 ) return 942;
-         if(i == 943 ) return 943;
-         if(i == 944 ) return 944;
-         if(i == 945 ) return 945;
-         if(i == 946 ) return 946;
-         if(i == 947 ) return 947;
-         if(i == 948 ) return 948;
-         if(i == 949 ) return 949;
-         if(i == 950 ) return 950;
-         if(i == 951 ) return 951;
-         if(i == 952 ) return 952;
-         if(i == 953 ) return 953;
-         if(i == 954 ) return 954;
-         if(i == 955 ) return 955;
-         if(i == 956 ) return 956;
-         if(i == 957 ) return 957;
-         if(i == 958 ) return 958;
-         if(i == 959 ) return 959;
-         if(i == 960 ) return 960;
-         if(i == 961 ) return 961;
-         if(i == 962 ) return 962;
-         if(i == 963 ) return 963;
-         if(i == 964 ) return 964;
-         if(i == 965 ) return 965;
-         if(i == 966 ) return 966;
-         if(i == 967 ) return 967;
-         if(i == 968 ) return 968;
-         if(i == 969 ) return 969;
-         if(i == 970 ) return 970;
-         if(i == 971 ) return 971;
-         if(i == 972 ) return 972;
-         if(i == 973 ) return 973;
-         if(i == 974 ) return 974;
-         if(i == 975 ) return 975;
-         if(i == 976 ) return 976;
-         if(i == 977 ) return 977;
-         if(i == 978 ) return 978;
-         if(i == 979 ) return 979;
-         if(i == 980 ) return 980;
-         if(i == 981 ) return 981;
-         if(i == 982 ) return 982;
-         if(i == 983 ) return 983;
-         if(i == 984 ) return 984;
-         if(i == 985 ) return 985;
-         if(i == 986 ) return 986;
-         if(i == 987 ) return 987;
-         if(i == 988 ) return 988;
-         if(i == 989 ) return 989;
-         if(i == 990 ) return 990;
-         if(i == 991 ) return 991;
-         if(i == 992 ) return 992;
-         if(i == 993 ) return 993;
-         if(i == 994 ) return 994;
-         if(i == 995 ) return 995;
-         if(i == 996 ) return 996;
-         if(i == 997 ) return 997;
-         if(i == 998 ) return 998;
-         if(i == 999 ) return 999;
-         if(i == 1000 ) return 1000;
-         if(i == 1001 ) return 1001;
-         if(i == 1002 ) return 1002;
-         if(i == 1003 ) return 1003;
-         if(i == 1004 ) return 1004;
-         if(i == 1005 ) return 1005;
-         if(i == 1006 ) return 1006;
-         if(i == 1007 ) return 1007;
-         if(i == 1008 ) return 1008;
-         if(i == 1009 ) return 1009;
-         if(i == 1010 ) return 1010;
-         if(i == 1011 ) return 1011;
-         if(i == 1012 ) return 1012;
-         if(i == 1013 ) return 1013;
-         if(i == 1014 ) return 1014;
-         if(i == 1015 ) return 1015;
-         if(i == 1016 ) return 1016;
-         if(i == 1017 ) return 1017;
-         if(i == 1018 ) return 1018;
-         if(i == 1019 ) return 1019;
-         if(i == 1020 ) return 1020;
-         if(i == 1021 ) return 1021;
-         if(i == 1022 ) return 1022;
-         if(i == 1023 ) return 1023;
-         if(i == 1024 ) return 1024;
-         if(i == 1025 ) return 1025;
-         if(i == 1026 ) return 1026;
-         if(i == 1027 ) return 1027;
-         if(i == 1028 ) return 1028;
-         if(i == 1029 ) return 1029;
-         if(i == 1030 ) return 1030;
-         if(i == 1031 ) return 1031;
-         if(i == 1032 ) return 1032;
-         if(i == 1033 ) return 1033;
-         if(i == 1034 ) return 1034;
-         if(i == 1035 ) return 1035;
-         if(i == 1036 ) return 1036;
-         if(i == 1037 ) return 1037;
-         if(i == 1038 ) return 1038;
-         if(i == 1039 ) return 1039;
-         if(i == 1040 ) return 1040;
-         if(i == 1041 ) return 1041;
-         if(i == 1042 ) return 1042;
-         if(i == 1043 ) return 1043;
-         if(i == 1044 ) return 1044;
-         if(i == 1045 ) return 1045;
-         if(i == 1046 ) return 1046;
-         if(i == 1047 ) return 1047;
-         if(i == 1048 ) return 1048;
-         if(i == 1049 ) return 1049;
-         if(i == 1050 ) return 1050;
-         if(i == 1051 ) return 1051;
-         if(i == 1052 ) return 1052;
-         if(i == 1053 ) return 1053;
-         if(i == 1054 ) return 1054;
-         if(i == 1055 ) return 1055;
-         if(i == 1056 ) return 1056;
-         if(i == 1057 ) return 1057;
-         if(i == 1058 ) return 1058;
-         if(i == 1059 ) return 1059;
-         if(i == 1060 ) return 1060;
-         if(i == 1061 ) return 1061;
-         if(i == 1062 ) return 1062;
-         if(i == 1063 ) return 1063;
-         if(i == 1064 ) return 1064;
-         if(i == 1065 ) return 1065;
-         if(i == 1066 ) return 1066;
-         if(i == 1067 ) return 1067;
-         if(i == 1068 ) return 1068;
-         if(i == 1069 ) return 1069;
-         if(i == 1070 ) return 1070;
-         if(i == 1071 ) return 1071;
-         if(i == 1072 ) return 1072;
-         if(i == 1073 ) return 1073;
-         if(i == 1074 ) return 1074;
-         if(i == 1075 ) return 1075;
-         if(i == 1076 ) return 1076;
-         if(i == 1077 ) return 1077;
-         if(i == 1078 ) return 1078;
-         if(i == 1079 ) return 1079;
-         if(i == 1080 ) return 1080;
-         if(i == 1081 ) return 1081;
-         if(i == 1082 ) return 1082;
-         if(i == 1083 ) return 1083;
-         if(i == 1084 ) return 1084;
-         if(i == 1085 ) return 1085;
-         if(i == 1086 ) return 1086;
-         if(i == 1087 ) return 1087;
-         if(i == 1088 ) return 1088;
-         if(i == 1089 ) return 1089;
-         if(i == 1090 ) return 1090;
-         if(i == 1091 ) return 1091;
-         if(i == 1092 ) return 1092;
-         if(i == 1093 ) return 1093;
-         if(i == 1094 ) return 1094;
-         if(i == 1095 ) return 1095;
-         if(i == 1096 ) return 1096;
-         if(i == 1097 ) return 1097;
-         if(i == 1098 ) return 1098;
-         if(i == 1099 ) return 1099;
-         if(i == 1100 ) return 1100;
-         if(i == 1101 ) return 1101;
-         if(i == 1102 ) return 1102;
-         if(i == 1103 ) return 1103;
-         if(i == 1104 ) return 1104;
-         if(i == 1105 ) return 1105;
-         if(i == 1106 ) return 1106;
-         if(i == 1107 ) return 1107;
-         if(i == 1108 ) return 1108;
-         if(i == 1109 ) return 1109;
-         if(i == 1110 ) return 1110;
-         if(i == 1111 ) return 1111;
-         if(i == 1112 ) return 1112;
-         if(i == 1113 ) return 1113;
-         if(i == 1114 ) return 1114;
-         if(i == 1115 ) return 1115;
-         if(i == 1116 ) return 1116;
-         if(i == 1117 ) return 1117;
-         if(i == 1118 ) return 1118;
-         if(i == 1119 ) return 1119;
-         if(i == 1120 ) return 1120;
-         if(i == 1121 ) return 1121;
-         if(i == 1122 ) return 1122;
-         if(i == 1123 ) return 1123;
-         if(i == 1124 ) return 1124;
-         if(i == 1125 ) return 1125;
-         if(i == 1126 ) return 1126;
-         if(i == 1127 ) return 1127;
-         if(i == 1128 ) return 1128;
-         if(i == 1129 ) return 1129;
-         if(i == 1130 ) return 1130;
-         if(i == 1131 ) return 1131;
-         if(i == 1132 ) return 1132;
-         if(i == 1133 ) return 1133;
-         if(i == 1134 ) return 1134;
-         if(i == 1135 ) return 1135;
-         if(i == 1136 ) return 1136;
-         if(i == 1137 ) return 1137;
-         if(i == 1138 ) return 1138;
-         if(i == 1139 ) return 1139;
-         if(i == 1140 ) return 1140;
-         if(i == 1141 ) return 1141;
-         if(i == 1142 ) return 1142;
-         if(i == 1143 ) return 1143;
-         if(i == 1144 ) return 1144;
-         if(i == 1145 ) return 1145;
-         if(i == 1146 ) return 1146;
-         if(i == 1147 ) return 1147;
-         if(i == 1148 ) return 1148;
-         if(i == 1149 ) return 1149;
-         if(i == 1150 ) return 1150;
-         if(i == 1151 ) return 1151;
-         if(i == 1152 ) return 1152;
-         if(i == 1153 ) return 1153;
-         if(i == 1154 ) return 1154;
-         if(i == 1155 ) return 1155;
-         if(i == 1156 ) return 1156;
-         if(i == 1157 ) return 1157;
-         if(i == 1158 ) return 1158;
-         if(i == 1159 ) return 1159;
-         if(i == 1160 ) return 1160;
-         if(i == 1161 ) return 1161;
-         if(i == 1162 ) return 1162;
-         if(i == 1163 ) return 1163;
-         if(i == 1164 ) return 1164;
-         if(i == 1165 ) return 1165;
-         if(i == 1166 ) return 1166;
-         if(i == 1167 ) return 1167;
-         if(i == 1168 ) return 1168;
-         if(i == 1169 ) return 1169;
-         if(i == 1170 ) return 1170;
-         if(i == 1171 ) return 1171;
-         if(i == 1172 ) return 1172;
-         if(i == 1173 ) return 1173;
-         if(i == 1174 ) return 1174;
-         if(i == 1175 ) return 1175;
-         if(i == 1176 ) return 1176;
-         if(i == 1177 ) return 1177;
-         if(i == 1178 ) return 1178;
-         if(i == 1179 ) return 1179;
-         if(i == 1180 ) return 1180;
-         if(i == 1181 ) return 1181;
-         if(i == 1182 ) return 1182;
-         if(i == 1183 ) return 1183;
-         if(i == 1184 ) return 1184;
-         if(i == 1185 ) return 1185;
-         if(i == 1186 ) return 1186;
-         if(i == 1187 ) return 1187;
-         if(i == 1188 ) return 1188;
-         if(i == 1189 ) return 1189;
-         if(i == 1190 ) return 1190;
-         if(i == 1191 ) return 1191;
-         if(i == 1192 ) return 1192;
-         if(i == 1193 ) return 1193;
-         if(i == 1194 ) return 1194;
-         if(i == 1195 ) return 1195;
-         if(i == 1196 ) return 1196;
-         if(i == 1197 ) return 1197;
-         if(i == 1198 ) return 1198;
-         if(i == 1199 ) return 1199;
-         if(i == 1200 ) return 1200;
-         if(i == 1201 ) return 1201;
-         if(i == 1202 ) return 1202;
-         if(i == 1203 ) return 1203;
-         if(i == 1204 ) return 1204;
-         if(i == 1205 ) return 1205;
-         if(i == 1206 ) return 1206;
-         if(i == 1207 ) return 1207;
-         if(i == 1208 ) return 1208;
-         if(i == 1209 ) return 1209;
-         if(i == 1210 ) return 1210;
-         if(i == 1211 ) return 1211;
-         if(i == 1212 ) return 1212;
-         if(i == 1213 ) return 1213;
-         if(i == 1214 ) return 1214;
-         if(i == 1215 ) return 1215;
-         if(i == 1216 ) return 1216;
-         if(i == 1217 ) return 1217;
-         if(i == 1218 ) return 1218;
-         if(i == 1219 ) return 1219;
-         if(i == 1220 ) return 1220;
-         if(i == 1221 ) return 1221;
-         if(i == 1222 ) return 1222;
-         if(i == 1223 ) return 1223;
-         if(i == 1224 ) return 1224;
-         if(i == 1225 ) return 1225;
-         if(i == 1226 ) return 1226;
-         if(i == 1227 ) return 1227;
-         if(i == 1228 ) return 1228;
-         if(i == 1229 ) return 1229;
-         if(i == 1230 ) return 1230;
-         if(i == 1231 ) return 1231;
-         if(i == 1232 ) return 1232;
-         if(i == 1233 ) return 1233;
-         if(i == 1234 ) return 1234;
-         if(i == 1235 ) return 1235;
-         if(i == 1236 ) return 1236;
-         if(i == 1237 ) return 1237;
-         if(i == 1238 ) return 1238;
-         if(i == 1239 ) return 1239;
-         if(i == 1240 ) return 1240;
-         if(i == 1241 ) return 1241;
-         if(i == 1242 ) return 1242;
-         if(i == 1243 ) return 1243;
-         if(i == 1244 ) return 1244;
-         if(i == 1245 ) return 1245;
-         if(i == 1246 ) return 1246;
-         if(i == 1247 ) return 1247;
-         if(i == 1248 ) return 1248;
-         if(i == 1249 ) return 1249;
-         if(i == 1250 ) return 1250;
-         if(i == 1251 ) return 1251;
-         if(i == 1252 ) return 1252;
-         if(i == 1253 ) return 1253;
-         if(i == 1254 ) return 1254;
-         if(i == 1255 ) return 1255;
-         if(i == 1256 ) return 1256;
-         if(i == 1257 ) return 1257;
-         if(i == 1258 ) return 1258;
-         if(i == 1259 ) return 1259;
-         if(i == 1260 ) return 1260;
-         if(i == 1261 ) return 1261;
-         if(i == 1262 ) return 1262;
-         if(i == 1263 ) return 1263;
-         if(i == 1264 ) return 1264;
-         if(i == 1265 ) return 1265;
-         if(i == 1266 ) return 1266;
-         if(i == 1267 ) return 1267;
-         if(i == 1268 ) return 1268;
-         if(i == 1269 ) return 1269;
-         if(i == 1270 ) return 1270;
-         if(i == 1271 ) return 1271;
-         if(i == 1272 ) return 1272;
-         if(i == 1273 ) return 1273;
-         if(i == 1274 ) return 1274;
-         if(i == 1275 ) return 1275;
-         if(i == 1276 ) return 1276;
-         if(i == 1277 ) return 1277;
-         if(i == 1278 ) return 1278;
-         if(i == 1279 ) return 1279;
-         if(i == 1280 ) return 1280;
-         if(i == 1281 ) return 1281;
-         if(i == 1282 ) return 1282;
-         if(i == 1283 ) return 1283;
-         if(i == 1284 ) return 1284;
-         if(i == 1285 ) return 1285;
-         if(i == 1286 ) return 1286;
-         if(i == 1287 ) return 1287;
-         if(i == 1288 ) return 1288;
-         if(i == 1289 ) return 1289;
-         if(i == 1290 ) return 1290;
-         if(i == 1291 ) return 1291;
-         if(i == 1292 ) return 1292;
-         if(i == 1293 ) return 1293;
-         if(i == 1294 ) return 1294;
-         if(i == 1295 ) return 1295;
-         if(i == 1296 ) return 1296;
-         if(i == 1297 ) return 1297;
-         if(i == 1298 ) return 1298;
-         if(i == 1299 ) return 1299;
-         if(i == 1300 ) return 1300;
-         if(i == 1301 ) return 1301;
-         if(i == 1302 ) return 1302;
-         if(i == 1303 ) return 1303;
-         if(i == 1304 ) return 1304;
-         if(i == 1305 ) return 1305;
-         if(i == 1306 ) return 1306;
-         if(i == 1307 ) return 1307;
-         if(i == 1308 ) return 1308;
-         if(i == 1309 ) return 1309;
-         if(i == 1310 ) return 1310;
-         if(i == 1311 ) return 1311;
-         if(i == 1312 ) return 1312;
-         if(i == 1313 ) return 1313;
-         if(i == 1314 ) return 1314;
-         if(i == 1315 ) return 1315;
-         if(i == 1316 ) return 1316;
-         if(i == 1317 ) return 1317;
-         if(i == 1318 ) return 1318;
-         if(i == 1319 ) return 1319;
-         if(i == 1320 ) return 1320;
-         if(i == 1321 ) return 1321;
-         if(i == 1322 ) return 1322;
-         if(i == 1323 ) return 1323;
-         if(i == 1324 ) return 1324;
-         if(i == 1325 ) return 1325;
-         if(i == 1326 ) return 1326;
-         if(i == 1327 ) return 1327;
-         if(i == 1328 ) return 1328;
-         if(i == 1329 ) return 1329;
-         if(i == 1330 ) return 1330;
-         if(i == 1331 ) return 1331;
-         if(i == 1332 ) return 1332;
-         if(i == 1333 ) return 1333;
-         if(i == 1334 ) return 1334;
-         if(i == 1335 ) return 1335;
-         if(i == 1336 ) return 1336;
-         if(i == 1337 ) return 1337;
-         if(i == 1338 ) return 1338;
-         if(i == 1339 ) return 1339;
-         if(i == 1340 ) return 1340;
-         if(i == 1341 ) return 1341;
-         if(i == 1342 ) return 1342;
-         if(i == 1343 ) return 1343;
-         if(i == 1344 ) return 1344;
-         if(i == 1345 ) return 1345;
-         if(i == 1346 ) return 1346;
-         if(i == 1347 ) return 1347;
-         if(i == 1348 ) return 1348;
-         if(i == 1349 ) return 1349;
-         if(i == 1350 ) return 1350;
-         if(i == 1351 ) return 1351;
-         if(i == 1352 ) return 1352;
-         if(i == 1353 ) return 1353;
-         if(i == 1354 ) return 1354;
-         if(i == 1355 ) return 1355;
-         if(i == 1356 ) return 1356;
-         if(i == 1357 ) return 1357;
-         if(i == 1358 ) return 1358;
-         if(i == 1359 ) return 1359;
-         if(i == 1360 ) return 1360;
-         if(i == 1361 ) return 1361;
-         if(i == 1362 ) return 1362;
-         if(i == 1363 ) return 1363;
-         if(i == 1364 ) return 1364;
-         if(i == 1365 ) return 1365;
-         if(i == 1366 ) return 1366;
-         if(i == 1367 ) return 1367;
-         if(i == 1368 ) return 1368;
-         if(i == 1369 ) return 1369;
-         if(i == 1370 ) return 1370;
-         if(i == 1371 ) return 1371;
-         if(i == 1372 ) return 1372;
-         if(i == 1373 ) return 1373;
-         if(i == 1374 ) return 1374;
-         if(i == 1375 ) return 1375;
-         if(i == 1376 ) return 1376;
-         if(i == 1377 ) return 1377;
-         if(i == 1378 ) return 1378;
-         if(i == 1379 ) return 1379;
-         if(i == 1380 ) return 1380;
-         if(i == 1381 ) return 1381;
-         if(i == 1382 ) return 1382;
-         if(i == 1383 ) return 1383;
-         if(i == 1384 ) return 1384;
-         if(i == 1385 ) return 1385;
-         if(i == 1386 ) return 1386;
-         if(i == 1387 ) return 1387;
-         if(i == 1388 ) return 1388;
-         if(i == 1389 ) return 1389;
-         if(i == 1390 ) return 1390;
-         if(i == 1391 ) return 1391;
-         if(i == 1392 ) return 1392;
-         if(i == 1393 ) return 1393;
-         if(i == 1394 ) return 1394;
-         if(i == 1395 ) return 1395;
-         if(i == 1396 ) return 1396;
-         if(i == 1397 ) return 1397;
-         if(i == 1398 ) return 1398;
-         if(i == 1399 ) return 1399;
-         if(i == 1400 ) return 1400;
-         if(i == 1401 ) return 1401;
-         if(i == 1402 ) return 1402;
-         if(i == 1403 ) return 1403;
-         if(i == 1404 ) return 1404;
-         if(i == 1405 ) return 1405;
-         if(i == 1406 ) return 1406;
-         if(i == 1407 ) return 1407;
-         if(i == 1408 ) return 1408;
-         if(i == 1409 ) return 1409;
-         if(i == 1410 ) return 1410;
-         if(i == 1411 ) return 1411;
-         if(i == 1412 ) return 1412;
-         if(i == 1413 ) return 1413;
-         if(i == 1414 ) return 1414;
-         if(i == 1415 ) return 1415;
-         if(i == 1416 ) return 1416;
-         if(i == 1417 ) return 1417;
-         if(i == 1418 ) return 1418;
-         if(i == 1419 ) return 1419;
-         if(i == 1420 ) return 1420;
-         if(i == 1421 ) return 1421;
-         if(i == 1422 ) return 1422;
-         if(i == 1423 ) return 1423;
-         if(i == 1424 ) return 1424;
-         if(i == 1425 ) return 1425;
-         if(i == 1426 ) return 1426;
-         if(i == 1427 ) return 1427;
-         if(i == 1428 ) return 1428;
-         if(i == 1429 ) return 1429;
-         if(i == 1430 ) return 1430;
-         if(i == 1431 ) return 1431;
-         if(i == 1432 ) return 1432;
-         if(i == 1433 ) return 1433;
-         if(i == 1434 ) return 1434;
-         if(i == 1435 ) return 1435;
-         if(i == 1436 ) return 1436;
-         if(i == 1437 ) return 1437;
-         if(i == 1438 ) return 1438;
-         if(i == 1439 ) return 1439;
-         if(i == 1440 ) return 1440;
-         if(i == 1441 ) return 1441;
-         if(i == 1442 ) return 1442;
-         if(i == 1443 ) return 1443;
-         if(i == 1444 ) return 1444;
-         if(i == 1445 ) return 1445;
-         if(i == 1446 ) return 1446;
-         if(i == 1447 ) return 1447;
-         if(i == 1448 ) return 1448;
-         if(i == 1449 ) return 1449;
-         if(i == 1450 ) return 1450;
-         if(i == 1451 ) return 1451;
-         if(i == 1452 ) return 1452;
-         if(i == 1453 ) return 1453;
-         if(i == 1454 ) return 1454;
-         if(i == 1455 ) return 1455;
-         if(i == 1456 ) return 1456;
-         if(i == 1457 ) return 1457;
-         if(i == 1458 ) return 1458;
-         if(i == 1459 ) return 1459;
-         if(i == 1460 ) return 1460;
-         if(i == 1461 ) return 1461;
-         if(i == 1462 ) return 1462;
-         if(i == 1463 ) return 1463;
-         if(i == 1464 ) return 1464;
-         if(i == 1465 ) return 1465;
-         if(i == 1466 ) return 1466;
-         if(i == 1467 ) return 1467;
-         if(i == 1468 ) return 1468;
-         if(i == 1469 ) return 1469;
-         if(i == 1470 ) return 1470;
-         if(i == 1471 ) return 1471;
-         if(i == 1472 ) return 1472;
-         if(i == 1473 ) return 1473;
-         if(i == 1474 ) return 1474;
-         if(i == 1475 ) return 1475;
-         if(i == 1476 ) return 1476;
-         if(i == 1477 ) return 1477;
-         if(i == 1478 ) return 1478;
-         if(i == 1479 ) return 1479;
-         if(i == 1480 ) return 1480;
-         if(i == 1481 ) return 1481;
-         if(i == 1482 ) return 1482;
-         if(i == 1483 ) return 1483;
-         if(i == 1484 ) return 1484;
-         if(i == 1485 ) return 1485;
-         if(i == 1486 ) return 1486;
-         if(i == 1487 ) return 1487;
-         if(i == 1488 ) return 1488;
-         if(i == 1489 ) return 1489;
-         if(i == 1490 ) return 1490;
-         if(i == 1491 ) return 1491;
-         if(i == 1492 ) return 1492;
-         if(i == 1493 ) return 1493;
-         if(i == 1494 ) return 1494;
-         if(i == 1495 ) return 1495;
-         if(i == 1496 ) return 1496;
-         if(i == 1497 ) return 1497;
-         if(i == 1498 ) return 1498;
-         if(i == 1499 ) return 1499;
-         if(i == 1500 ) return 1500;
-         if(i == 1501 ) return 1501;
-         if(i == 1502 ) return 1502;
-         if(i == 1503 ) return 1503;
-         if(i == 1504 ) return 1504;
-         if(i == 1505 ) return 1505;
-         if(i == 1506 ) return 1506;
-         if(i == 1507 ) return 1507;
-         if(i == 1508 ) return 1508;
-         if(i == 1509 ) return 1509;
-         if(i == 1510 ) return 1510;
-         if(i == 1511 ) return 1511;
-         if(i == 1512 ) return 1512;
-         if(i == 1513 ) return 1513;
-         if(i == 1514 ) return 1514;
-         if(i == 1515 ) return 1515;
-         if(i == 1516 ) return 1516;
-         if(i == 1517 ) return 1517;
-         if(i == 1518 ) return 1518;
-         if(i == 1519 ) return 1519;
-         if(i == 1520 ) return 1520;
-         if(i == 1521 ) return 1521;
-         if(i == 1522 ) return 1522;
-         if(i == 1523 ) return 1523;
-         if(i == 1524 ) return 1524;
-         if(i == 1525 ) return 1525;
-         if(i == 1526 ) return 1526;
-         if(i == 1527 ) return 1527;
-         if(i == 1528 ) return 1528;
-         if(i == 1529 ) return 1529;
-         if(i == 1530 ) return 1530;
-         if(i == 1531 ) return 1531;
-         if(i == 1532 ) return 1532;
-         if(i == 1533 ) return 1533;
-         if(i == 1534 ) return 1534;
-         if(i == 1535 ) return 1535;
-         if(i == 1536 ) return 1536;
-         if(i == 1537 ) return 1537;
-         if(i == 1538 ) return 1538;
-         if(i == 1539 ) return 1539;
-         if(i == 1540 ) return 1540;
-         if(i == 1541 ) return 1541;
-         if(i == 1542 ) return 1542;
-         if(i == 1543 ) return 1543;
-         if(i == 1544 ) return 1544;
-         if(i == 1545 ) return 1545;
-         if(i == 1546 ) return 1546;
-         if(i == 1547 ) return 1547;
-         if(i == 1548 ) return 1548;
-         if(i == 1549 ) return 1549;
-         if(i == 1550 ) return 1550;
-         if(i == 1551 ) return 1551;
-         if(i == 1552 ) return 1552;
-         if(i == 1553 ) return 1553;
-         if(i == 1554 ) return 1554;
-         if(i == 1555 ) return 1555;
-         if(i == 1556 ) return 1556;
-         if(i == 1557 ) return 1557;
-         if(i == 1558 ) return 1558;
-         if(i == 1559 ) return 1559;
-         if(i == 1560 ) return 1560;
-         if(i == 1561 ) return 1561;
-         if(i == 1562 ) return 1562;
-         if(i == 1563 ) return 1563;
-         if(i == 1564 ) return 1564;
-         if(i == 1565 ) return 1565;
-         if(i == 1566 ) return 1566;
-         if(i == 1567 ) return 1567;
-         if(i == 1568 ) return 1568;
-         if(i == 1569 ) return 1569;
-         if(i == 1570 ) return 1570;
-         if(i == 1571 ) return 1571;
-         if(i == 1572 ) return 1572;
-         if(i == 1573 ) return 1573;
-         if(i == 1574 ) return 1574;
-         if(i == 1575 ) return 1575;
-         if(i == 1576 ) return 1576;
-         if(i == 1577 ) return 1577;
-         if(i == 1578 ) return 1578;
-         if(i == 1579 ) return 1579;
-         if(i == 1580 ) return 1580;
-         if(i == 1581 ) return 1581;
-         if(i == 1582 ) return 1582;
-         if(i == 1583 ) return 1583;
-         if(i == 1584 ) return 1584;
-         if(i == 1585 ) return 1585;
-         if(i == 1586 ) return 1586;
-         if(i == 1587 ) return 1587;
-         if(i == 1588 ) return 1588;
-         if(i == 1589 ) return 1589;
-         if(i == 1590 ) return 1590;
-         if(i == 1591 ) return 1591;
-         if(i == 1592 ) return 1592;
-         if(i == 1593 ) return 1593;
-         if(i == 1594 ) return 1594;
-         if(i == 1595 ) return 1595;
-         if(i == 1596 ) return 1596;
-         if(i == 1597 ) return 1597;
-         if(i == 1598 ) return 1598;
-         if(i == 1599 ) return 1599;
-         if(i == 1600 ) return 1600;
-         if(i == 1601 ) return 1601;
-         if(i == 1602 ) return 1602;
-         if(i == 1603 ) return 1603;
-         if(i == 1604 ) return 1604;
-         if(i == 1605 ) return 1605;
-         if(i == 1606 ) return 1606;
-         if(i == 1607 ) return 1607;
-         if(i == 1608 ) return 1608;
-         if(i == 1609 ) return 1609;
-         if(i == 1610 ) return 1610;
-         if(i == 1611 ) return 1611;
-         if(i == 1612 ) return 1612;
-         if(i == 1613 ) return 1613;
-         if(i == 1614 ) return 1614;
-         if(i == 1615 ) return 1615;
-         if(i == 1616 ) return 1616;
-         if(i == 1617 ) return 1617;
-         if(i == 1618 ) return 1618;
-         if(i == 1619 ) return 1619;
-         if(i == 1620 ) return 1620;
-         if(i == 1621 ) return 1621;
-         if(i == 1622 ) return 1622;
-         if(i == 1623 ) return 1623;
-         if(i == 1624 ) return 1624;
-         if(i == 1625 ) return 1625;
-         if(i == 1626 ) return 1626;
-         if(i == 1627 ) return 1627;
-         if(i == 1628 ) return 1628;
-         if(i == 1629 ) return 1629;
-         if(i == 1630 ) return 1630;
-         if(i == 1631 ) return 1631;
-         if(i == 1632 ) return 1632;
-         if(i == 1633 ) return 1633;
-         if(i == 1634 ) return 1634;
-         if(i == 1635 ) return 1635;
-         if(i == 1636 ) return 1636;
-         if(i == 1637 ) return 1637;
-         if(i == 1638 ) return 1638;
-         if(i == 1639 ) return 1639;
-         if(i == 1640 ) return 1640;
-         if(i == 1641 ) return 1641;
-         if(i == 1642 ) return 1642;
-         if(i == 1643 ) return 1643;
-         if(i == 1644 ) return 1644;
-         if(i == 1645 ) return 1645;
-         if(i == 1646 ) return 1646;
-         if(i == 1647 ) return 1647;
-         if(i == 1648 ) return 1648;
-         if(i == 1649 ) return 1649;
-         if(i == 1650 ) return 1650;
-         if(i == 1651 ) return 1651;
-         if(i == 1652 ) return 1652;
-         if(i == 1653 ) return 1653;
-         if(i == 1654 ) return 1654;
-         if(i == 1655 ) return 1655;
-         if(i == 1656 ) return 1656;
-         if(i == 1657 ) return 1657;
-         if(i == 1658 ) return 1658;
-         if(i == 1659 ) return 1659;
-         if(i == 1660 ) return 1660;
-         if(i == 1661 ) return 1661;
-         if(i == 1662 ) return 1662;
-         if(i == 1663 ) return 1663;
-         if(i == 1664 ) return 1664;
-         if(i == 1665 ) return 1665;
-         if(i == 1666 ) return 1666;
-         if(i == 1667 ) return 1667;
-         if(i == 1668 ) return 1668;
-         if(i == 1669 ) return 1669;
-         if(i == 1670 ) return 1670;
-         if(i == 1671 ) return 1671;
-         if(i == 1672 ) return 1672;
-         if(i == 1673 ) return 1673;
-         if(i == 1674 ) return 1674;
-         if(i == 1675 ) return 1675;
-         if(i == 1676 ) return 1676;
-         if(i == 1677 ) return 1677;
-         if(i == 1678 ) return 1678;
-         if(i == 1679 ) return 1679;
-         if(i == 1680 ) return 1680;
-         if(i == 1681 ) return 1681;
-         if(i == 1682 ) return 1682;
-         if(i == 1683 ) return 1683;
-         if(i == 1684 ) return 1684;
-         if(i == 1685 ) return 1685;
-         if(i == 1686 ) return 1686;
-         if(i == 1687 ) return 1687;
-         if(i == 1688 ) return 1688;
-         if(i == 1689 ) return 1689;
-         if(i == 1690 ) return 1690;
-         if(i == 1691 ) return 1691;
-         if(i == 1692 ) return 1692;
-         if(i == 1693 ) return 1693;
-         if(i == 1694 ) return 1694;
-         if(i == 1695 ) return 1695;
-         if(i == 1696 ) return 1696;
-         if(i == 1697 ) return 1697;
-         if(i == 1698 ) return 1698;
-         if(i == 1699 ) return 1699;
-         if(i == 1700 ) return 1700;
-         if(i == 1701 ) return 1701;
-         if(i == 1702 ) return 1702;
-         if(i == 1703 ) return 1703;
-         if(i == 1704 ) return 1704;
-         if(i == 1705 ) return 1705;
-         if(i == 1706 ) return 1706;
-         if(i == 1707 ) return 1707;
-         if(i == 1708 ) return 1708;
-         if(i == 1709 ) return 1709;
-         if(i == 1710 ) return 1710;
-         if(i == 1711 ) return 1711;
-         if(i == 1712 ) return 1712;
-         if(i == 1713 ) return 1713;
-         if(i == 1714 ) return 1714;
-         if(i == 1715 ) return 1715;
-         if(i == 1716 ) return 1716;
-         if(i == 1717 ) return 1717;
-         if(i == 1718 ) return 1718;
-         if(i == 1719 ) return 1719;
-         if(i == 1720 ) return 1720;
-         if(i == 1721 ) return 1721;
-         if(i == 1722 ) return 1722;
-         if(i == 1723 ) return 1723;
-         if(i == 1724 ) return 1724;
-         if(i == 1725 ) return 1725;
-         if(i == 1726 ) return 1726;
-         if(i == 1727 ) return 1727;
-         if(i == 1728 ) return 1728;
-         if(i == 1729 ) return 1729;
-         if(i == 1730 ) return 1730;
-         if(i == 1731 ) return 1731;
-         if(i == 1732 ) return 1732;
-         if(i == 1733 ) return 1733;
-         if(i == 1734 ) return 1734;
-         if(i == 1735 ) return 1735;
-         if(i == 1736 ) return 1736;
-         if(i == 1737 ) return 1737;
-         if(i == 1738 ) return 1738;
-         if(i == 1739 ) return 1739;
-         if(i == 1740 ) return 1740;
-         if(i == 1741 ) return 1741;
-         if(i == 1742 ) return 1742;
-         if(i == 1743 ) return 1743;
-         if(i == 1744 ) return 1744;
-         if(i == 1745 ) return 1745;
-         if(i == 1746 ) return 1746;
-         if(i == 1747 ) return 1747;
-         if(i == 1748 ) return 1748;
-         if(i == 1749 ) return 1749;
-         if(i == 1750 ) return 1750;
-         if(i == 1751 ) return 1751;
-         if(i == 1752 ) return 1752;
-         if(i == 1753 ) return 1753;
-         if(i == 1754 ) return 1754;
-         if(i == 1755 ) return 1755;
-         if(i == 1756 ) return 1756;
-         if(i == 1757 ) return 1757;
-         if(i == 1758 ) return 1758;
-         if(i == 1759 ) return 1759;
-         if(i == 1760 ) return 1760;
-         if(i == 1761 ) return 1761;
-         if(i == 1762 ) return 1762;
-         if(i == 1763 ) return 1763;
-         if(i == 1764 ) return 1764;
-         if(i == 1765 ) return 1765;
-         if(i == 1766 ) return 1766;
-         if(i == 1767 ) return 1767;
-         if(i == 1768 ) return 1768;
-         if(i == 1769 ) return 1769;
-         if(i == 1770 ) return 1770;
-         if(i == 1771 ) return 1771;
-         if(i == 1772 ) return 1772;
-         if(i == 1773 ) return 1773;
-         if(i == 1774 ) return 1774;
-         if(i == 1775 ) return 1775;
-         if(i == 1776 ) return 1776;
-         if(i == 1777 ) return 1777;
-         if(i == 1778 ) return 1778;
-         if(i == 1779 ) return 1779;
-         if(i == 1780 ) return 1780;
-         if(i == 1781 ) return 1781;
-         if(i == 1782 ) return 1782;
-         if(i == 1783 ) return 1783;
-         if(i == 1784 ) return 1784;
-         if(i == 1785 ) return 1785;
-         if(i == 1786 ) return 1786;
-         if(i == 1787 ) return 1787;
-         if(i == 1788 ) return 1788;
-         if(i == 1789 ) return 1789;
-         if(i == 1790 ) return 1790;
-         if(i == 1791 ) return 1791;
-         if(i == 1792 ) return 1792;
-         if(i == 1793 ) return 1793;
-         if(i == 1794 ) return 1794;
-         if(i == 1795 ) return 1795;
-         if(i == 1796 ) return 1796;
-         if(i == 1797 ) return 1797;
-         if(i == 1798 ) return 1798;
-         if(i == 1799 ) return 1799;
-         if(i == 1800 ) return 1800;
-         if(i == 1801 ) return 1801;
-         if(i == 1802 ) return 1802;
-         if(i == 1803 ) return 1803;
-         if(i == 1804 ) return 1804;
-         if(i == 1805 ) return 1805;
-         if(i == 1806 ) return 1806;
-         if(i == 1807 ) return 1807;
-         if(i == 1808 ) return 1808;
-         if(i == 1809 ) return 1809;
-         if(i == 1810 ) return 1810;
-         if(i == 1811 ) return 1811;
-         if(i == 1812 ) return 1812;
-         if(i == 1813 ) return 1813;
-         if(i == 1814 ) return 1814;
-         if(i == 1815 ) return 1815;
-         if(i == 1816 ) return 1816;
-         if(i == 1817 ) return 1817;
-         if(i == 1818 ) return 1818;
-         if(i == 1819 ) return 1819;
-         if(i == 1820 ) return 1820;
-         if(i == 1821 ) return 1821;
-         if(i == 1822 ) return 1822;
-         if(i == 1823 ) return 1823;
-         if(i == 1824 ) return 1824;
-         if(i == 1825 ) return 1825;
-         if(i == 1826 ) return 1826;
-         if(i == 1827 ) return 1827;
-         if(i == 1828 ) return 1828;
-         if(i == 1829 ) return 1829;
-         if(i == 1830 ) return 1830;
-         if(i == 1831 ) return 1831;
-         if(i == 1832 ) return 1832;
-         if(i == 1833 ) return 1833;
-         if(i == 1834 ) return 1834;
-         if(i == 1835 ) return 1835;
-         if(i == 1836 ) return 1836;
-         if(i == 1837 ) return 1837;
-         if(i == 1838 ) return 1838;
-         if(i == 1839 ) return 1839;
-         if(i == 1840 ) return 1840;
-         if(i == 1841 ) return 1841;
-         if(i == 1842 ) return 1842;
-         if(i == 1843 ) return 1843;
-         if(i == 1844 ) return 1844;
-         if(i == 1845 ) return 1845;
-         if(i == 1846 ) return 1846;
-         if(i == 1847 ) return 1847;
-         if(i == 1848 ) return 1848;
-         if(i == 1849 ) return 1849;
-         if(i == 1850 ) return 1850;
-         if(i == 1851 ) return 1851;
-         if(i == 1852 ) return 1852;
-         if(i == 1853 ) return 1853;
-         if(i == 1854 ) return 1854;
-         if(i == 1855 ) return 1855;
-         if(i == 1856 ) return 1856;
-         if(i == 1857 ) return 1857;
-         if(i == 1858 ) return 1858;
-         if(i == 1859 ) return 1859;
-         if(i == 1860 ) return 1860;
-         if(i == 1861 ) return 1861;
-         if(i == 1862 ) return 1862;
-         if(i == 1863 ) return 1863;
-         if(i == 1864 ) return 1864;
-         if(i == 1865 ) return 1865;
-         if(i == 1866 ) return 1866;
-         if(i == 1867 ) return 1867;
-         if(i == 1868 ) return 1868;
-         if(i == 1869 ) return 1869;
-         if(i == 1870 ) return 1870;
-         if(i == 1871 ) return 1871;
-         if(i == 1872 ) return 1872;
-         if(i == 1873 ) return 1873;
-         if(i == 1874 ) return 1874;
-         if(i == 1875 ) return 1875;
-         if(i == 1876 ) return 1876;
-         if(i == 1877 ) return 1877;
-         if(i == 1878 ) return 1878;
-         if(i == 1879 ) return 1879;
-         if(i == 1880 ) return 1880;
-         if(i == 1881 ) return 1881;
-         if(i == 1882 ) return 1882;
-         if(i == 1883 ) return 1883;
-         if(i == 1884 ) return 1884;
-         if(i == 1885 ) return 1885;
-         if(i == 1886 ) return 1886;
-         if(i == 1887 ) return 1887;
-         if(i == 1888 ) return 1888;
-         if(i == 1889 ) return 1889;
-         if(i == 1890 ) return 1890;
-         if(i == 1891 ) return 1891;
-         if(i == 1892 ) return 1892;
-         if(i == 1893 ) return 1893;
-         if(i == 1894 ) return 1894;
-         if(i == 1895 ) return 1895;
-         if(i == 1896 ) return 1896;
-         if(i == 1897 ) return 1897;
-         if(i == 1898 ) return 1898;
-         if(i == 1899 ) return 1899;
-         if(i == 1900 ) return 1900;
-         if(i == 1901 ) return 1901;
-         if(i == 1902 ) return 1902;
-         if(i == 1903 ) return 1903;
-         if(i == 1904 ) return 1904;
-         if(i == 1905 ) return 1905;
-         if(i == 1906 ) return 1906;
-         if(i == 1907 ) return 1907;
-         if(i == 1908 ) return 1908;
-         if(i == 1909 ) return 1909;
-         if(i == 1910 ) return 1910;
-         if(i == 1911 ) return 1911;
-         if(i == 1912 ) return 1912;
-         if(i == 1913 ) return 1913;
-         if(i == 1914 ) return 1914;
-         if(i == 1915 ) return 1915;
-         if(i == 1916 ) return 1916;
-         if(i == 1917 ) return 1917;
-         if(i == 1918 ) return 1918;
-         if(i == 1919 ) return 1919;
-         if(i == 1920 ) return 1920;
-         if(i == 1921 ) return 1921;
-         if(i == 1922 ) return 1922;
-         if(i == 1923 ) return 1923;
-         if(i == 1924 ) return 1924;
-         if(i == 1925 ) return 1925;
-         if(i == 1926 ) return 1926;
-         if(i == 1927 ) return 1927;
-         if(i == 1928 ) return 1928;
-         if(i == 1929 ) return 1929;
-         if(i == 1930 ) return 1930;
-         if(i == 1931 ) return 1931;
-         if(i == 1932 ) return 1932;
-         if(i == 1933 ) return 1933;
-         if(i == 1934 ) return 1934;
-         if(i == 1935 ) return 1935;
-         if(i == 1936 ) return 1936;
-         if(i == 1937 ) return 1937;
-         if(i == 1938 ) return 1938;
-         if(i == 1939 ) return 1939;
-         if(i == 1940 ) return 1940;
-         if(i == 1941 ) return 1941;
-         if(i == 1942 ) return 1942;
-         if(i == 1943 ) return 1943;
-         if(i == 1944 ) return 1944;
-         if(i == 1945 ) return 1945;
-         if(i == 1946 ) return 1946;
-         if(i == 1947 ) return 1947;
-         if(i == 1948 ) return 1948;
-         if(i == 1949 ) return 1949;
-         if(i == 1950 ) return 1950;
-         if(i == 1951 ) return 1951;
-         if(i == 1952 ) return 1952;
-         if(i == 1953 ) return 1953;
-         if(i == 1954 ) return 1954;
-         if(i == 1955 ) return 1955;
-         if(i == 1956 ) return 1956;
-         if(i == 1957 ) return 1957;
-         if(i == 1958 ) return 1958;
-         if(i == 1959 ) return 1959;
-         if(i == 1960 ) return 1960;
-         if(i == 1961 ) return 1961;
-         if(i == 1962 ) return 1962;
-         if(i == 1963 ) return 1963;
-         if(i == 1964 ) return 1964;
-         if(i == 1965 ) return 1965;
-         if(i == 1966 ) return 1966;
-         if(i == 1967 ) return 1967;
-         if(i == 1968 ) return 1968;
-         if(i == 1969 ) return 1969;
-         if(i == 1970 ) return 1970;
-         if(i == 1971 ) return 1971;
-         if(i == 1972 ) return 1972;
-         if(i == 1973 ) return 1973;
-         if(i == 1974 ) return 1974;
-         if(i == 1975 ) return 1975;
-         if(i == 1976 ) return 1976;
-         if(i == 1977 ) return 1977;
-         if(i == 1978 ) return 1978;
-         if(i == 1979 ) return 1979;
-         if(i == 1980 ) return 1980;
-         if(i == 1981 ) return 1981;
-         if(i == 1982 ) return 1982;
-         if(i == 1983 ) return 1983;
-         if(i == 1984 ) return 1984;
-         if(i == 1985 ) return 1985;
-         if(i == 1986 ) return 1986;
-         if(i == 1987 ) return 1987;
-         if(i == 1988 ) return 1988;
-         if(i == 1989 ) return 1989;
-         if(i == 1990 ) return 1990;
-         if(i == 1991 ) return 1991;
-         if(i == 1992 ) return 1992;
-         if(i == 1993 ) return 1993;
-         if(i == 1994 ) return 1994;
-         if(i == 1995 ) return 1995;
-         if(i == 1996 ) return 1996;
-         if(i == 1997 ) return 1997;
-         if(i == 1998 ) return 1998;
-         if(i == 1999 ) return 1999;
-      } finally {
-         int x = 0;
-         x += 1;
-         x += 2;
-         x += 3;
-         x += 4;
-         x += 5;
-         x += 6;
-         x += 7;
-         x += 8;
-         x += 9;
-      }
-      return 0;
-   }
-}
--- a/langtools/test/tools/javac/ArrayCloneCodeGen.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 1999, 2001, 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 4267335
- * @summary Verify that code generated for Array.clone() with -target 1.2 passes verifier.
- * @author maddox
- *
- * @run compile -source 1.3 -target 1.2 ArrayCloneCodeGen.java
- * @run main/othervm -Xverify:all ArrayCloneCodeGen
- */
-
-public class ArrayCloneCodeGen {
-
-    public static void main(String[] args) {}
-
-    private String[] args = null;
-
-    public String[] getArgs() {
-        return (String []) (args.clone());
-    }
-}
--- a/langtools/test/tools/javac/ClassLit.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/ClassLit.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 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
@@ -26,9 +26,6 @@
  * @bug 4884387
  * @summary Use ldc instruction for class literals
  * @author gafter
- *
- * @compile -source 1.5 -target 1.5 ClassLit.java
- * @run main ClassLit
  */
 
 public class ClassLit {
--- a/langtools/test/tools/javac/ConditionalArgTypes_2.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/ConditionalArgTypes_2.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2003, 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
@@ -27,7 +27,6 @@
  * @summary Verify that both branches of a conditional expression must agree in type.
  * @author maddox
  *
- * @compile/fail -source 1.4 ConditionalArgTypes_2.java
  * @compile                  ConditionalArgTypes_2.java
  */
 
--- a/langtools/test/tools/javac/ConditionalClass.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * 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.
- *
- * 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 4949627
- * @summary javac crashes on code for new rule for semantics of ? without -source 1.5
- * @author gafter
- *
- * @compile -source 1.4 ConditionalClass.java
- */
-
-package conditional.clazz;
-
-class A{}
-class B{}
-
-public class ConditionalClass {
-    void foo(){
-        boolean b = false;
-        Class a =  b ? A.class : B.class;
-        System.out.println("a is " + a.getName());
-    }
-
-    public static void main(String[] args)
-    {
-        new ConditionalClass().foo();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/IncorrectInheritance/IncorrectInheritanceTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,68 @@
+/*
+ * 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 8034924
+ * @summary Incorrect inheritance of inaccessible static method
+ * @library /tools/javac/lib
+ * @build ToolBox
+ * @run main IncorrectInheritanceTest
+ */
+
+public class IncorrectInheritanceTest {
+    private static final String ASrc =
+            "package pkg;\n" +
+            "\n" +
+            "public class A {\n" +
+            "    static void foo(Object o) {}\n" +
+            "    private static void bar(Object o) {}\n" +
+            "}";
+
+    private static final String BSrc =
+            "import pkg.A;\n" +
+            "class B extends A {\n" +
+            "    public void foo(Object o) {}\n" +
+            "    public void bar(Object o) {}\n" +
+            "}";
+
+    private static final String CSrc =
+            "class C extends B {\n" +
+            "    public void m(Object o) {\n" +
+            "        foo(o);\n" +
+            "        bar(o);\n" +
+            "    }\n" +
+            "}";
+
+    public static void main(String[] args) throws Exception {
+        new IncorrectInheritanceTest().test();
+    }
+
+    public void test() throws Exception {
+        ToolBox.JavaToolArgs javacParams =
+                new ToolBox.JavaToolArgs()
+                .setSources(ASrc, BSrc, CSrc);
+        ToolBox.javac(javacParams);
+    }
+
+}
--- a/langtools/test/tools/javac/JsrRet.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/JsrRet.java	Tue Mar 25 20:32:46 2014 -0400
@@ -27,7 +27,7 @@
  * @summary StackOverflowError from javac
  * @author gafter
  *
- * @compile -source 1.5 -target 1.5 JsrRet.java
+ * @compile JsrRet.java
  */
 
 package jsr.ret;
--- a/langtools/test/tools/javac/NoNoClassDefFoundErrorError.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2001, 2004, 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 4313429
- * @summary Compiling <Classname>.class on CLDC crashed the compiler.
- *
- * @compile/fail -source 1.4 -target 1.4 -XDfailcomplete=java.lang.NoClassDefFoundError NoNoClassDefFoundErrorError.java
- */
-
-class NoNoClassDefFoundErrorError {
-    public static void main() {
-        Class self = NoNoClassDefFoundErrorError.class;
-    }
-}
--- a/langtools/test/tools/javac/T6266772.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/T6266772.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, 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
@@ -26,9 +26,6 @@
  * @bug     6266772
  * @summary javac crashes, assertion failure in Lower.java
  * @author  Peter von der Ah\u00e9
- * @compile/fail -source 1.4 T6266772.java
- * @compile T6266772.java
- * @run main T6266772
  */
 
 public class T6266772 {
--- a/langtools/test/tools/javac/T6557865.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2007, 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 6557865
- * @summary -source 5 -target 5 should not put ACC_SYNTHETIC on package-info
- * @author Wei Tao
- * @compile T6557865.java
- * @compile -source 5 -target 5 T6232928/package-info.java
- * @run main T6557865
- */
-
-import java.io.*;
-import java.lang.reflect.Modifier;
-
-public class T6557865 {
-  public static void main(String... args) throws Exception {
-    Class pkginfo_cls = Class.forName("T6232928.package-info");
-    int mod = pkginfo_cls.getModifiers();
-    if ((mod & 0x1000) != 0) {
-      throw new AssertionError("Test failed: interface package-info shouldn't be synthetic in -target 5.");
-    }
-  }
-}
--- a/langtools/test/tools/javac/UplevelFromAnonInSuperCall.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/UplevelFromAnonInSuperCall.java	Tue Mar 25 20:32:46 2014 -0400
@@ -29,7 +29,6 @@
  * @author maddox (cribbed from bracha/lillibridge) gafter
  *
  * @compile UplevelFromAnonInSuperCall.java
- * @compile/fail -source 1.4 UplevelFromAnonInSuperCall.java
  */
 
 class UplevelFromAnonInSuperCall {
--- a/langtools/test/tools/javac/annotations/neg/Dep.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/annotations/neg/Dep.java	Tue Mar 25 20:32:46 2014 -0400
@@ -27,7 +27,6 @@
  * @summary Please add annotation <at>Deprecated to supplant the javadoc tag
  * @author gafter
  *
- * @compile      -source 1.4 -Xlint:-options -Xlint:dep-ann -Werror Dep.java
  * @compile/fail                             -Xlint:dep-ann -Werror Dep.java
  * @compile                                  -Xlint:dep-ann         Dep.java
  */
--- a/langtools/test/tools/javac/annotations/neg/MixedSource.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2004, 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 5036565
- * @summary Annotations definitions are allowed using -source 1.4 but not annotations
- * @author gafter
- *
- * @compile/fail -source 1.4 MixedSource.java
- */
-
-package mixed.source;
-
-@interface foo {}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -49,7 +49,7 @@
 
     File compile(File f) {
         int rc = com.sun.tools.javac.Main.compile(new String[] {
-                "-source", "1.8", "-g", f.getPath() });
+                "-g", f.getPath() });
         if (rc != 0)
             throw new Error("compilation failed. rc=" + rc);
         String path = f.getPath();
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -146,7 +146,7 @@
     }
 
     File compileTestFile(File f) {
-        int rc = com.sun.tools.javac.Main.compile(new String[] { "-XDTA:writer", "-source", "1.8", "-g", f.getPath() });
+        int rc = com.sun.tools.javac.Main.compile(new String[] { "-XDTA:writer", "-g", f.getPath() });
         if (rc != 0)
             throw new Error("compilation failed. rc=" + rc);
         String path = f.getPath();
--- a/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java	Tue Mar 25 20:32:46 2014 -0400
@@ -180,7 +180,6 @@
 
     protected File compileTestFile(File f, String testClass, String... extraParams) {
         List<String> options = new ArrayList<>();
-        options.addAll(Arrays.asList("-source", "1.8"));
         options.addAll(Arrays.asList(extraParams));
         options.add(f.getPath());
         int rc = com.sun.tools.javac.Main.compile(options.toArray(new String[options.size()]));
--- a/langtools/test/tools/javac/api/T6265137.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/api/T6265137.java	Tue Mar 25 20:32:46 2014 -0400
@@ -49,6 +49,6 @@
         String srcdir = System.getProperty("test.src");
         Iterable<? extends JavaFileObject> files =
             fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(srcdir, "T6265137a.java")));
-        javac.getTask(null, fm, dl, Arrays.asList("-target","1.5"), null, files).call();
+        javac.getTask(null, fm, dl, Arrays.asList("-target","9"), null, files).call();
     }
 }
--- a/langtools/test/tools/javac/boxing/NoBoxingBool.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2004, 2006, 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 6177400
- * @summary Boxing allowed with -source 1.4
- * @author Peter von der Ah\u00e9
- * @compile/fail -source 1.4 NoBoxingBool.java
- */
-
-public class NoBoxingBool {
-    Boolean b = false;
-}
--- a/langtools/test/tools/javac/boxing/NoBoxingByte.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2004, 2006, 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 6177400
- * @summary Boxing allowed with -source 1.4
- * @author Peter von der Ah\u00e9
- * @compile/fail -source 1.4 NoBoxingByte.java
- */
-
-public class NoBoxingByte {
-    Byte b = 0;
-}
--- a/langtools/test/tools/javac/boxing/NoBoxingChar.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2004, 2006, 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 6177400
- * @summary Boxing allowed with -source 1.4
- * @author Peter von der Ah\u00e9
- * @compile/fail -source 1.4 NoBoxingChar.java
- */
-
-public class NoBoxingChar {
-    Character c = '\u0000';
-}
--- a/langtools/test/tools/javac/boxing/NoBoxingDouble.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2004, 2006, 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 6177400
- * @summary Boxing allowed with -source 1.4
- * @author Peter von der Ah\u00e9
- * @compile/fail -source 1.4 NoBoxingDouble.java
- */
-
-public class NoBoxingDouble {
-    Double d = 0D;
-}
--- a/langtools/test/tools/javac/boxing/NoBoxingFloat.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2004, 2006, 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 6177400
- * @summary Boxing allowed with -source 1.4
- * @author Peter von der Ah\u00e9
- * @compile/fail -source 1.4 NoBoxingFloat.java
- */
-
-public class NoBoxingFloat {
-    Float f = 0F;
-}
--- a/langtools/test/tools/javac/boxing/NoBoxingInt.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2004, 2006, 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 6177400
- * @summary Boxing allowed with -source 1.4
- * @author Peter von der Ah\u00e9
- * @compile/fail -source 1.4 NoBoxingInt.java
- */
-
-public class NoBoxingInt {
-    Integer i = 0;
-}
--- a/langtools/test/tools/javac/boxing/NoBoxingLong.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2004, 2006, 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 6177400
- * @summary Boxing allowed with -source 1.4
- * @author Peter von der Ah\u00e9
- * @compile/fail -source 1.4 NoBoxingLong.java
- */
-
-public class NoBoxingLong {
-    Long l = 0L;
-}
--- a/langtools/test/tools/javac/boxing/NoBoxingShort.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2004, 2006, 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 6177400
- * @summary Boxing allowed with -source 1.4
- * @author Peter von der Ah\u00e9
- * @compile/fail -source 1.4 NoBoxingShort.java
- */
-
-public class NoBoxingShort {
-    Short s = 0;
-}
--- a/langtools/test/tools/javac/classfiles/ClassVersionChecker.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/classfiles/ClassVersionChecker.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -37,7 +37,7 @@
 public class ClassVersionChecker {
 
     int errors;
-    String[] jdk = {"","1.2","1.3","1.4","1.5","1.6","1.7","1.8"};
+    String[] jdk = {"","1.6","1.7","1.8"};
     File javaFile = null;
 
     public static void main(String[] args) throws Throwable {
@@ -47,7 +47,7 @@
     void run() throws Exception {
         writeTestFile();
         /* Rules applicable for -source and -target combinations
-         * 1. If both empty, version num is for 1.7
+         * 1. If both empty, version num is for the current release
          * 2. If source is not empty and target is empty, version is based on source
          * 3. If both non-empty, version is based on target
          */
@@ -57,14 +57,10 @@
          * -1 => invalid combinations
          */
         int[][] ver =
-                {{52, -1, -1, -1, -1, -1, -1, -1},
-                 {48, 46, 47, 48, 49, 50, 51, 52},
-                 {48, 46, 47, 48, 49, 50, 51, 52},
-                 {48, -1, -1, 48, 49, 50, 51, 52},
-                 {52, -1, -1, -1, 49, 50, 51, 52},
-                 {52, -1, -1, -1, -1, 50, 51, 52},
-                 {52, -1, -1, -1, -1, -1, 51, 52},
-                 {52, -1, -1, -1, -1, -1, -1, 52}};
+                {{52, -1, -1, -1},
+                 {52, 50, 51, 52},
+                 {52, -1, 51, 52},
+                 {52, -1, -1, 52}};
 
         // Loop to run all possible combinations of source/target values
         for (int i = 0; i< ver.length; i++) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/InnerClasses/SyntheticClasses.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,97 @@
+/*
+ * 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 8034854
+ *  @summary Verify that the InnerClasses attribute has outer_class_info_index zero if it has
+ *           inner_name_index zero (for synthetic classes)
+ *  @compile SyntheticClasses.java
+ *  @run main SyntheticClasses
+ */
+
+import java.io.*;
+import java.util.*;
+import com.sun.tools.classfile.*;
+
+public class SyntheticClasses {
+
+    public static void main(String[] args) throws IOException, ConstantPoolException {
+        new SyntheticClasses().run();
+    }
+
+    private void run() throws IOException, ConstantPoolException {
+        File testClasses = new File(System.getProperty("test.classes"));
+        for (File classFile : testClasses.listFiles()) {
+            ClassFile cf = ClassFile.read(classFile);
+            if (cf.getName().matches(".*\\$[0-9]+")) {
+                EnclosingMethod_attribute encl =
+                        (EnclosingMethod_attribute) cf.getAttribute(Attribute.EnclosingMethod);
+                if (encl != null) {
+                    if (encl.method_index != 0)
+                        throw new IllegalStateException("Invalid EnclosingMethod.method_index: " +
+                                                        encl.method_index + ".");
+                }
+            }
+            InnerClasses_attribute attr =
+                    (InnerClasses_attribute) cf.getAttribute(Attribute.InnerClasses);
+            if (attr != null) {
+                for (InnerClasses_attribute.Info info : attr.classes) {
+                    if (cf.major_version < 51)
+                        throw new IllegalStateException();
+                    if (info.inner_name_index == 0 && info.outer_class_info_index != 0)
+                        throw new IllegalStateException("Invalid outer_class_info_index=" +
+                                                        info.outer_class_info_index +
+                                                        "; inner_name_index=" +
+                                                        info.inner_name_index + ".");
+                }
+            }
+        }
+    }
+}
+
+class SyntheticConstructorAccessTag {
+
+    private static class A {
+        private A(){}
+    }
+
+    public void test() {
+        new A();
+    }
+}
+
+class SyntheticEnumMapping {
+    private int convert(E e) {
+        switch (e) {
+            case A: return 0;
+            default: return -1;
+        }
+    }
+    enum E { A }
+}
+
+interface SyntheticAssertionsDisabled {
+    public default void test() {
+        assert false;
+    }
+}
--- a/langtools/test/tools/javac/enum/6384542/T6384542.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-/**
- * @test  /nodynamiccopyright/
- * @bug     6384542
- * @summary crash: test/tools/javac/versions/check.sh
- * @author  Peter von der Ah\u00e9
- * @compile/fail -source 1.4 -Xlint:-options T6384542.java
- * @compile/fail/ref=T6384542.out -source 1.4 -Xlint:-options -XDrawDiagnostics T6384542.java
- */
-
-import static java.lang.Math.sin;
-
-public enum A { }
-class B {
-    int i = 0xCafe.BabeP1;
-    List<X> l;
-    public static void main(String... args) {
-        for (String arg : args) {
-            System.out.println(arg);
-        }
-    }
-    @Override
-    public String toString() { return null; }
-}
-public klass C { }
--- a/langtools/test/tools/javac/enum/6384542/T6384542.out	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-T6384542.java:10:8: compiler.err.static.import.not.supported.in.source: 1.4
-T6384542.java:12:8: compiler.err.enums.not.supported.in.source: 1.4
-T6384542.java:14:13: compiler.err.unsupported.fp.lit: 1.4
-T6384542.java:15:9: compiler.err.generics.not.supported.in.source: 1.4
-T6384542.java:16:35: compiler.err.varargs.not.supported.in.source: 1.4
-T6384542.java:17:25: compiler.err.foreach.not.supported.in.source: 1.4
-T6384542.java:21:6: compiler.err.annotations.not.supported.in.source: 1.4
-T6384542.java:24:8: compiler.err.expected3: class, interface, enum
-8 errors
--- a/langtools/test/tools/javac/enum/6384542/T6384542a.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-/**
- * @test  /nodynamiccopyright/
- * @bug     6384542
- * @summary crash: test/tools/javac/versions/check.sh
- * @author  Peter von der Ah\u00e9
- * @compile/fail -source 5   T6384542a.java
- * @compile      -source 1.4 T6384542a.java
- * @compile/fail/ref=T6384542a_5.out -source 5   -Xlint:-options -XDrawDiagnostics T6384542a.java
- * @compile/ref=T6384542a_1_4.out    -source 1.4 -Xlint:-options -XDrawDiagnostics T6384542a.java
- */
-
-public class T6384542a {
-    T6384542a enum = null;
-}
--- a/langtools/test/tools/javac/enum/6384542/T6384542a_1_4.out	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-T6384542a.java:13:15: compiler.warn.enum.as.identifier
-1 warning
--- a/langtools/test/tools/javac/enum/6384542/T6384542a_5.out	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-T6384542a.java:13:15: compiler.err.enum.as.identifier
-1 error
--- a/langtools/test/tools/javac/enum/EnumAsIdentifier.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/enum/EnumAsIdentifier.java	Tue Mar 25 20:32:46 2014 -0400
@@ -3,8 +3,6 @@
  * @bug     8025537
  * @author  sogoel
  * @summary enum keyword used as an identifier
- * @compile/ref=EnumAsIdentifier4.out -XDrawDiagnostics -source 1.4 EnumAsIdentifier.java
- * @compile/fail/ref=EnumAsIdentifier5.out -XDrawDiagnostics -source 1.5 EnumAsIdentifier.java
  * @compile/fail/ref=EnumAsIdentifier.out -XDrawDiagnostics EnumAsIdentifier.java
  */
 
--- a/langtools/test/tools/javac/enum/EnumAsIdentifier.out	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/enum/EnumAsIdentifier.out	Tue Mar 25 20:32:46 2014 -0400
@@ -1,2 +1,2 @@
-EnumAsIdentifier.java:13:9: compiler.err.enum.as.identifier
+EnumAsIdentifier.java:11:9: compiler.err.enum.as.identifier
 1 error
--- a/langtools/test/tools/javac/enum/EnumAsIdentifier4.out	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-- compiler.warn.source.no.bootclasspath: 1.4
-- compiler.warn.option.obsolete.source: 1.4
-- compiler.warn.option.obsolete.target: 1.4
-- compiler.warn.option.obsolete.suppression
-EnumAsIdentifier.java:13:9: compiler.warn.enum.as.identifier
-5 warnings
--- a/langtools/test/tools/javac/enum/EnumAsIdentifier5.out	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-- compiler.warn.source.no.bootclasspath: 1.5
-- compiler.warn.option.obsolete.source: 1.5
-- compiler.warn.option.obsolete.suppression
-EnumAsIdentifier.java:13:9: compiler.err.enum.as.identifier
-1 error
-3 warnings
--- a/langtools/test/tools/javac/enum/FauxEnum2.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2004, 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 5009574
- * @summary verify java.lang.Enum can't be directly subclassed
- * @author Joseph D. Darcy
- *
- * @compile/fail -source 1.4 FauxEnum2.java
- */
-
-public class FauxEnum2 extends java.lang.Enum {
-    FauxEnum2() {
-        super("", 0);
-    }
-}
--- a/langtools/test/tools/javac/foreach/T6682380.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2008, 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 6682380 6679509
- * @summary Foreach loop with generics inside finally block crashes javac with -target 1.5
- * @author Jan Lahoda, Maurizio Cimadamore
- * @compile -source 1.5 -target 1.5 T6682380.java
- */
-
-import java.util.List;
-
-public class T6682380<X> {
-
-    public static void main(String[] args) {
-        try {
-        } finally {
-            List<T6682380<?>> l = null;
-            T6682380<?>[] a = null;
-            for (T6682380<?> e1 : l);
-            for (T6682380<?> e2 : a);
-        }
-    }
-}
--- a/langtools/test/tools/javac/generics/BridgeRestype.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2003, 2004, 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 4902704
- * @summary javac generates inappropriate bridge methods in -source 1.4
- * @author gafter
- *
- * @compile -source 1.4 -target 1.4 BridgeRestype.java
- * @run main BridgeRestype
- */
-
-import java.util.*;
-
-public class BridgeRestype extends Vector {
-    public static void main(String[] args) {
-        BridgeRestype t = new BridgeRestype();
-        for (int i=0; i<args.length; i++) t.add(args[i]);
-        Iterator i = t.iterator();
-    }
-}
--- a/langtools/test/tools/javac/generics/RefEqual.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/generics/RefEqual.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 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
@@ -27,7 +27,6 @@
  * @summary casting conversion checks changed for covariant returns
  * @author gafter
  *
- * @compile -source 1.4 RefEqual.java
  * @compile/fail  RefEqual.java
  */
 
--- a/langtools/test/tools/javac/generics/T5094318.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/generics/T5094318.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -26,8 +26,6 @@
  * @bug 5094318
  * @summary REGRESSION: Array cloning is not backwards compatible
  *
- * @compile -source 1.4 T5094318.java
- * @run main T5094318
  * @compile  T5094318.java
  * @run main/fail T5094318
  */
--- a/langtools/test/tools/javac/generics/compat/CovariantCompat1.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * 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.
- *
- * 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 4836051
- * @summary generics: non-generic code should be able to call covariant method
- * @author gafter
- *
- * @compile  CovariantCompat1.java
- * @compile -source 1.4 CovariantCompat2.java
- */
-
-class CovariantCompat1 {
-    static class A {
-        public A foo() { return this; }
-    }
-    static class B extends A {
-        public B foo() { return this; }
-    }
-}
--- a/langtools/test/tools/javac/generics/compat/CovariantCompat2.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * 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.
- *
- * 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.
- */
-
-class CovariantCompat2 {
-    static {
-        CovariantCompat1.B x = new CovariantCompat1.B();
-        CovariantCompat1.B o = x.foo();
-    }
-}
--- a/langtools/test/tools/javac/generics/compat/OverrideBridge1.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2003, 2004, 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 4836048 4868021 5030040 5052968 5056864
- * @summary generics: compiler allows 1.4 code to override a bridge method
- * @author gafter
- *
- * @compile  OverrideBridge1.java
- * @compile/fail -Werror -source 1.4 OverrideBridge2.java
- * @compile -source 1.4 OverrideBridge2.java
- * @compile  OverrideBridge3.java
- */
-
-// ALLOW users to override bridge methods.
-
-// Note the long list of bug numbers on this regression test.  They
-// indicate the number of times we've flip-flopped on this issue.
-// 5030040 shows why we must give a diagnostic.  5052968 shows why it
-// must be a warning.
-
-class OverrideBridge1 {
-    static class A<T> {
-        public void foo(T t) { }
-    }
-    static class B extends A<String> {
-        public void foo(String t) { }
-    }
-}
--- a/langtools/test/tools/javac/generics/compat/OverrideBridge2.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * 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.
- *
- * 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.
- */
-
-class OverrideBridge2 {
-    static class B extends OverrideBridge1.B {
-        public void foo(Object o) { }
-    }
-}
--- a/langtools/test/tools/javac/generics/compat/OverrideBridge3.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2004, 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.
- */
-
-class OverrideBridge3 {
-    static class C extends OverrideBridge2.B {
-    }
-}
--- a/langtools/test/tools/javac/generics/compat/VisibleBridge.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * 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.
- *
- * 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 4830291
- * @summary javac makes String non-backward compatible
- * @author gafter
- *
- * @compile -source 1.4 VisibleBridge.java
- */
-
-// Ensure that bridge methods are visible for maximum
-// backward compatibility.
-
-class VisibleBridge {
-    static {
-        Object o = "b";
-        if ("a".compareTo(o) > 0) {}
-    }
-}
--- a/langtools/test/tools/javac/limits/FinallyNesting.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2002, 2004, 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 4739388
- * @summary regression: javac generates too much bytecode for deply nested try-finally
- * @author gafter
- *
- * @compile -source 1.4 -target 1.4 FinallyNesting.java
- */
-// Source and target 1.4 are needed for the test to pass with default memory sizes.
-class FinallyNesting {
-    public static void main(String[] args) {
-        int x;
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-        try { x = 1; } finally {
-            x = 2;
-        }
-        }
-        }
-        }
-        }
-        }
-        }
-        }
-        }
-        }
-        }
-        }
-        }
-        }
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/linenumbers/ConditionalLineNumberTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8034091
+ * @summary Add LineNumberTable attributes for conditional operator (?:) split across several lines.
+ */
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.LineNumberTable_attribute;
+import com.sun.tools.classfile.LineNumberTable_attribute.Entry;
+
+import java.io.File;
+import java.io.IOException;
+
+public class ConditionalLineNumberTest {
+    public static void main(String[] args) throws Exception {
+        // check that we have 5 consecutive entries for method()
+        Entry[] lines = findEntries();
+        if (lines == null || lines.length != 5)
+            throw new Exception("conditional line number table incorrect");
+
+        int current = lines[0].line_number;
+        for (Entry e : lines) {
+            if (e.line_number != current)
+                throw new Exception("conditional line number table incorrect");
+            current++;
+        }
+   }
+
+    static Entry[] findEntries() throws IOException, ConstantPoolException {
+        ClassFile self = ClassFile.read(ConditionalLineNumberTest.class.getResourceAsStream("ConditionalLineNumberTest.class"));
+        for (Method m : self.methods) {
+            if ("method".equals(m.getName(self.constant_pool))) {
+                Code_attribute code_attribute = (Code_attribute)m.attributes.get(Attribute.Code);
+                for (Attribute at : code_attribute.attributes) {
+                    if (Attribute.LineNumberTable.equals(at.getName(self.constant_pool))) {
+                        return ((LineNumberTable_attribute)at).line_number_table;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    // This method should get one LineNumberTable entry per line
+    // in the method body.
+    public static String method(int field) {
+        String s = field % 2 == 0 ?
+            (field == 0 ? "false"
+             : "true" + field) : //Breakpoint
+            "false" + field; //Breakpoint
+        return s;
+    }
+}
--- a/langtools/test/tools/javac/meth/InvokeMH.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/meth/InvokeMH.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -27,7 +27,7 @@
  * @summary Generate call sites for method handle
  * @author jrose
  *
- * @compile -source 7 -target 7 -XDallowTransitionalJSR292=no InvokeMH.java
+ * @compile InvokeMH.java
  */
 
 /*
--- a/langtools/test/tools/javac/miranda/T4711325.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/miranda/T4711325.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2004, 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
@@ -28,7 +28,6 @@
  * @author gafter
  *
  * @compile                  T4711325.java
- * @compile/fail -source 1.4 T4711325.java
  */
 
 interface A {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/missingSuperRecovery/MissingInterfaceTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,15 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8036007
+ * @summary javac crashes when encountering an unresolvable interface
+ * @build MissingInterfaceTestDep
+ * @clean Closeable
+ * @compile/fail/ref=MissingInterfaceTest.out -XDrawDiagnostics MissingInterfaceTest.java
+ */
+
+public class MissingInterfaceTest {
+    void test(MissingInterfaceTestDep s) {
+        s.call();
+        s.another();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/missingSuperRecovery/MissingInterfaceTest.out	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,3 @@
+MissingInterfaceTest.java:12:10: compiler.err.cant.access: Closeable, (compiler.misc.class.file.not.found: Closeable)
+MissingInterfaceTest.java:13:10: compiler.err.cant.resolve.location.args: kindname.method, another, , , (compiler.misc.location.1: kindname.variable, s, MissingInterfaceTestDep)
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/missingSuperRecovery/MissingInterfaceTestDep.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+public class MissingInterfaceTestDep implements Intermediate {}
+interface Intermediate extends Closeable { }
+interface Closeable {}
--- a/langtools/test/tools/javac/parser/T4910483.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/parser/T4910483.java	Tue Mar 25 20:32:46 2014 -0400
@@ -21,10 +21,10 @@
  * questions.
  */
 
-/**
+/*
  * @test
  * @bug     4910483
- * @summary javac shouldn't throw NPE while compiling invalid RuntimeInvisibleParameterAnnotations
+ * @summary Javadoc renders the string ".*\\.pdf" as ".\*\.pdf"
  * @run main T4910483
  */
 
--- a/langtools/test/tools/javac/proprietary/WarnClass.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/proprietary/WarnClass.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -28,7 +28,6 @@
  * @author  Peter von der Ah\u00e9
  * @compile WarnClass.java
  * @compile/fail -Werror WarnClass.java
- * @compile/fail -Werror -source 1.4 -nowarn WarnClass.java
  * @compile/fail -Werror -nowarn WarnClass.java
  * @compile/fail -Werror -Xlint:none WarnClass.java
  */
--- a/langtools/test/tools/javac/proprietary/WarnImport.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/proprietary/WarnImport.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -28,7 +28,6 @@
  * @author  Peter von der Ah\u00e9
  * @compile WarnImport.java
  * @compile/fail -Werror WarnImport.java
- * @compile/fail -Werror -source 1.4 -nowarn WarnImport.java
  * @compile/fail -Werror -nowarn WarnImport.java
  * @compile/fail -Werror -Xlint:none WarnImport.java
  */
--- a/langtools/test/tools/javac/proprietary/WarnMethod.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/proprietary/WarnMethod.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -28,7 +28,6 @@
  * @author  Peter von der Ah\u00e9
  * @compile WarnMethod.java
  * @compile/fail -Werror WarnMethod.java
- * @compile/fail -Werror -source 1.4 -nowarn WarnMethod.java
  * @compile/fail -Werror -nowarn WarnMethod.java
  * @compile/fail -Werror -Xlint:none WarnMethod.java
  */
--- a/langtools/test/tools/javac/proprietary/WarnStaticImport.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/proprietary/WarnStaticImport.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -28,7 +28,6 @@
  * @author  Peter von der Ah\u00e9
  * @compile WarnStaticImport.java
  * @compile/fail -Werror WarnStaticImport.java
- * @compile/fail -Werror -source 1.4 -nowarn WarnStaticImport.java
  * @compile/fail -Werror -nowarn WarnStaticImport.java
  * @compile/fail -Werror -Xlint:none WarnStaticImport.java
  */
--- a/langtools/test/tools/javac/proprietary/WarnVariable.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/proprietary/WarnVariable.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -28,7 +28,6 @@
  * @author  Peter von der Ah\u00e9
  * @compile WarnVariable.java
  * @compile/fail -Werror WarnVariable.java
- * @compile/fail -Werror -source 1.4 -nowarn WarnVariable.java
  * @compile/fail -Werror -nowarn WarnVariable.java
  * @compile/fail -Werror -Xlint:none WarnVariable.java
  */
--- a/langtools/test/tools/javac/proprietary/WarnWildcard.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/proprietary/WarnWildcard.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 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
@@ -28,7 +28,6 @@
  * @author  Peter von der Ah\u00e9
  * @compile WarnWildcard.java
  * @compile/fail -Werror WarnWildcard.java
- * @compile/fail -Werror -source 1.4 -nowarn WarnWildcard.java
  * @compile/fail -Werror -nowarn WarnWildcard.java
  * @compile/fail -Werror -Xlint:none WarnWildcard.java
  */
--- a/langtools/test/tools/javac/types/CastObjectToPrimitiveTest.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/types/CastObjectToPrimitiveTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -25,7 +25,6 @@
  * @test
  * @bug 7038363
  * @summary cast from object to primitive should be for source >= 1.7
- * @compile/fail/ref=CastObjectToPrimitiveTest.out -XDrawDiagnostics -Xlint:-options -source 5 CastObjectToPrimitiveTest.java
  * @compile/fail/ref=CastObjectToPrimitiveTest.out -XDrawDiagnostics -Xlint:-options -source 6 CastObjectToPrimitiveTest.java
  * @compile CastObjectToPrimitiveTest.java
  */
--- a/langtools/test/tools/javac/types/CastObjectToPrimitiveTest.out	Tue Mar 25 20:32:07 2014 -0400
+++ b/langtools/test/tools/javac/types/CastObjectToPrimitiveTest.out	Tue Mar 25 20:32:46 2014 -0400
@@ -1,2 +1,2 @@
-CastObjectToPrimitiveTest.java:36:23: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Object, int)
+CastObjectToPrimitiveTest.java:35:23: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Object, int)
 1 error
--- a/make/common/JavaCompilation.gmk	Tue Mar 25 20:32:07 2014 -0400
+++ b/make/common/JavaCompilation.gmk	Tue Mar 25 20:32:46 2014 -0400
@@ -143,6 +143,9 @@
   ifneq (,$2)
     $1_DEPS:=$2
   else
+    # Add all source roots to the find cache since we are likely going to run find 
+    # on these more than once. The cache will only be updated if necessary.
+    $$(eval $$(call FillCacheFind, $$($1_FIND_LIST)))
     $1_DEPS:=$$(filter $$(addprefix %,$$($1_SUFFIXES)), \
         $$(call CacheFind,$$($1_SRCS)))
     ifneq (,$$($1_GREP_INCLUDE_PATTERNS))
@@ -158,6 +161,10 @@
       $1_DEPS+=$$(call CacheFind,$$(wildcard $$(addsuffix /META-INF,$$($1_SRCS))))
     endif
   endif
+  # The dependency list should never be empty
+  ifeq ($$(strip $$($1_DEPS)), )
+    $$(warning No dependencies found for $1)
+  endif
 
   # Utility macros, to make the shell script receipt somewhat easier to decipher.
 
@@ -336,7 +343,20 @@
 # Previously this was inconsistently done in different repositories.
 # This is the new clean standard. Though it is to be superseded by
 # a standard annotation processor from with sjavac.
-define add_file_to_copy_and_clean
+#
+# The sed expression does this:
+# 1. Add a backslash before any :, = or ! that do not have a backslash already.
+# 2. Apply the file unicode2x.sed which does a whole bunch of \u00XX to \xXX 
+#    conversions.
+# 3. Delete all lines starting with #.
+# 4. Delete empty lines.
+# 5. Append lines ending with \ with the next line.
+# 6. Remove leading and trailing white space.
+# 7. Replace the first \= with just =.
+# 8. Finally it's all sorted to create a stable output.
+# 
+# It is assumed that = is the character used for separating names and values.
+define add_file_to_clean
   # param 1 = BUILD_MYPACKAGE
   # parma 2 = The source file to copy and clean.
   $2_TARGET:=$2
@@ -345,12 +365,13 @@
   # Now we can setup the depency that will trigger the copying.
   $$($1_BIN)$$($2_TARGET) : $2
 	$(MKDIR) -p $$(@D)
-	$(CAT) $$< | $(SED) -e 's/\([^\\]\):/\1\\:/g' -e 's/\([^\\]\)=/\1\\=/g' -e 's/#.*/#/g' \
+	$(CAT) $$< | $(SED) -e 's/\([^\\]\):/\1\\:/g' -e 's/\([^\\]\)=/\1\\=/g' \
+	        -e 's/\([^\\]\)!/\1\\!/g' -e 's/#.*/#/g' \
 	    | $(SED) -f "$(SRC_ROOT)/make/common/support/unicode2x.sed" \
 	    | $(SED) -e '/^#/d' -e '/^$$$$/d' \
 	        -e :a -e '/\\$$$$/N; s/\\\n//; ta' \
 	        -e 's/^[ \t]*//;s/[ \t]*$$$$//' \
-	        -e 's/\\=/=/' | LANG=C $(SORT) > $$@
+	        -e 's/\\=/=/' | LC_ALL=C $(SORT) > $$@
 	$(CHMOD) -f ug+w $$@
 
   # And do not forget this target
@@ -376,8 +397,9 @@
   #   INCLUDES:=myapp.foo means will only compile java files in myapp.foo or any of its sub-packages.
   #   EXCLUDES:=myapp.foo means will do not compile java files in myapp.foo or any of its sub-packages.
   #   COPY:=.prp means copy all prp files to the corresponding package in BIN.
+  #   COPY_FILES:=myapp/foo/setting.txt means copy this file over to the package myapp/foo
   #   CLEAN:=.properties means copy and clean all properties file to the corresponding package in BIN.
-  #   COPY_FILES:=myapp/foo/setting.txt means copy this file over to the package myapp/foo
+  #   CLEAN_FILES:=myapp/foo/setting.txt means clean this file over to the package myapp/foo
   #   SRCZIP:=Create a src.zip based on the found sources and copied files.
   #   INCLUDE_FILES:="com/sun/SolarisFoobar.java" means only compile this file!
   #   EXCLUDE_FILES:="com/sun/SolarisFoobar.java" means do not compile this particular file!
@@ -405,6 +427,9 @@
   # Make sure the dirs exist.
   $$(foreach d,$$($1_SRC), $$(if $$(wildcard $$d),,$$(error SRC specified to SetupJavaCompilation $1 contains missing directory $$d)))
   $$(eval $$(call MakeDir,$$($1_BIN)))
+  # Add all source roots to the find cache since we are likely going to run find 
+  # on these more than once. The cache will only be updated if necessary.
+  $$(eval $$(call FillCacheFind,$$($1_SRC)))
   # Find all files in the source trees.
   $1_ALL_SRCS += $$(filter-out $(OVR_SRCS),$$(call CacheFind,$$($1_SRC)))
   # Extract the java files.
@@ -437,7 +462,7 @@
   endif
 
   # Find all files to be copied from source to bin.
-  ifneq (,$$($1_COPY))
+  ifneq (,$$($1_COPY)$$($1_COPY_FILES))
     # Search for all files to be copied.
     $1_ALL_COPIES := $$(filter $$(addprefix %,$$($1_COPY)),$$($1_ALL_SRCS))
     # Copy these explicitly
@@ -452,20 +477,22 @@
     ifneq (,$$($1_EXCLUDE_FILES))
       $1_ALL_COPIES := $$(filter-out $$($1_EXCLUDE_FILES_PATTERN),$$($1_ALL_COPIES))
     endif
-    # All files below META-INF are always copied.
-    $1_ALL_COPIES += $$(filter $$(addsuffix /META-INF%,$$($1_SRC)),$$($1_ALL_SRCS))
-    ifneq (,$$($1_ALL_COPIES))
-      # Yep, there are files to be copied!
-      $1_ALL_COPY_TARGETS:=
-          $$(foreach i,$$($1_ALL_COPIES),$$(eval $$(call add_file_to_copy,$1,$$i)))
-      # Now we can depend on $$($1_ALL_COPY_TARGETS) to copy all files!
-    endif
+  endif
+  # All files below META-INF are always copied.
+  $1_ALL_COPIES += $$(filter $$(addsuffix /META-INF%,$$($1_SRC)),$$($1_ALL_SRCS))
+  ifneq (,$$($1_ALL_COPIES))
+    # Yep, there are files to be copied!
+    $1_ALL_COPY_TARGETS:=
+        $$(foreach i,$$($1_ALL_COPIES),$$(eval $$(call add_file_to_copy,$1,$$i)))
+    # Now we can depend on $$($1_ALL_COPY_TARGETS) to copy all files!
   endif
 
   # Find all property files to be copied and cleaned from source to bin.
-  ifneq (,$$($1_CLEAN))
+  ifneq (,$$($1_CLEAN)$$($1_CLEAN_FILES))
     # Search for all files to be copied.
     $1_ALL_CLEANS := $$(filter $$(addprefix %,$$($1_CLEAN)),$$($1_ALL_SRCS))
+    # Clean these explicitly
+    $1_ALL_CLEANS += $$($1_CLEAN_FILES)
     # Copy and clean must also respect filters.
     ifneq (,$$($1_INCLUDES))
       $1_ALL_CLEANS := $$(filter $$($1_SRC_INCLUDES),$$($1_ALL_CLEANS))
@@ -479,7 +506,7 @@
     ifneq (,$$($1_ALL_CLEANS))
       # Yep, there are files to be copied and cleaned!
       $1_ALL_COPY_CLEAN_TARGETS:=
-          $$(foreach i,$$($1_ALL_CLEANS),$$(eval $$(call add_file_to_copy_and_clean,$1,$$i)))
+          $$(foreach i,$$($1_ALL_CLEANS),$$(eval $$(call add_file_to_clean,$1,$$i)))
       # Now we can depend on $$($1_ALL_COPY_CLEAN_TARGETS) to copy all files!
     endif
   endif
--- a/make/common/MakeBase.gmk	Tue Mar 25 20:32:07 2014 -0400
+++ b/make/common/MakeBase.gmk	Tue Mar 25 20:32:46 2014 -0400
@@ -380,11 +380,23 @@
   # On Solaris, if the target is a symlink and exists, cp won't overwrite.
   # Cp has to operate in recursive mode to allow for -P flag, to preserve soft links. If the
   # name of the target file differs from the source file, rename after copy.
+  # If the source and target parent directories are the same, recursive copy doesn't work
+  # so we fall back on regular copy, which isn't preserving symlinks.
   define install-file
 	$(MKDIR) -p $(@D)
 	$(RM) '$@'
-	$(CP) -f -r -P '$<' '$(@D)'
-	if [ "$(@F)" != "$(<F)" ]; then $(MV) '$(@D)/$(<F)' '$@'; fi
+	if [ "$(@D)" != "$(<D)" ]; then \
+	  $(CP) -f -r -P '$<' '$(@D)'; \
+	  if [ "$(@F)" != "$(<F)" ]; then \
+	    $(MV) '$(@D)/$(<F)' '$@'; \
+	  fi; \
+	else \
+	  if [ -L '$<' ]; then \
+	    $(ECHO) "Source file is a symlink and target is in the same directory: $< $@" ; \
+	    exit 1; \
+	  fi; \
+	  $(CP) -f '$<' '$@'; \
+	fi
   endef
 else ifeq ($(OPENJDK_TARGET_OS),macosx)
   # On mac, extended attributes sometimes creep into the source files, which may later
@@ -408,6 +420,7 @@
 containing = $(foreach v,$2,$(if $(findstring $1,$v),$v))
 not-containing = $(foreach v,$2,$(if $(findstring $1,$v),,$v))
 
+ifneq ($(DISABLE_CACHE_FIND), true)
 ################################################################################
 # In Cygwin, finds are very costly, both because of expensive forks and because
 # of bad file system caching. Find is used extensively in $(shell) commands to
@@ -421,16 +434,23 @@
 #
 # Needs to be called with $(eval )
 #
+  # Even if the performance benifit is negligible on other platforms, keep the
+  # functionality active unless explicitly disabled to exercise it more.
+  #
+  # Initialize FIND_CACHE_DIRS with := to make it a non recursively-expanded variable
+  FIND_CACHE_DIRS :=
 # Param 1 - Dir to find in
-ifeq ($(OPENJDK_BUILD_OS),windows)
   define FillCacheFind
-    FIND_CACHE_DIR += $1
-    FIND_CACHE := $$(sort $$(FIND_CACHE) $$(shell $(FIND) $1 -type f -o -type l))
+    # Filter out already cached dirs. The - is needed when FIND_CACHE_DIR is empty
+    # since filter out will then return empty.
+    FIND_CACHE_NEW_DIRS := $$(filter-out $$(addsuffix /%,\
+        - $(FIND_CACHE_DIRS)) $(FIND_CACHE_DIRS), $1)
+    ifneq ($$(FIND_CACHE_NEW_DIRS), )
+      # Remove any trailing slash from dirs in the cache dir list
+      FIND_CACHE_DIRS += $$(patsubst %/,%, $$(FIND_CACHE_NEW_DIRS))
+      FIND_CACHE := $$(sort $$(FIND_CACHE) $$(shell $(FIND) $$(FIND_CACHE_NEW_DIRS) -type f -o -type l))
+    endif
   endef
-else
-  define FillCacheFind
-  endef
-endif
 
 # Mimics find by looking in the cache if all of the directories have been cached.
 # Otherwise reverts to shell find. This is safe to call on all platforms, even if
@@ -439,10 +459,16 @@
 # The extra - is needed when FIND_CACHE_DIR is empty but should be harmless.
 # Param 1 - Dirs to find in
 define CacheFind
-  $(if $(filter-out $(addsuffix %,- $(FIND_CACHE_DIR)),$1), \
+    $(if $(filter-out $(addsuffix /%,- $(FIND_CACHE_DIRS)) $(FIND_CACHE_DIRS),$1), \
     $(shell $(FIND) $1 -type f -o -type l), \
     $(filter $(addsuffix %,$1),$(FIND_CACHE)))
 endef
+else
+  # If CacheFind is disabled, just run the find command.
+  define CacheFind
+    $(shell $(FIND) $1 -type f -o -type l)
+  endef
+endif
 
 ################################################################################
 
--- a/nashorn/.hgtags	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/.hgtags	Tue Mar 25 20:32:46 2014 -0400
@@ -237,3 +237,5 @@
 65347535840f045f2cd4341d7466c51009b1b06f jdk9-b01
 b3517e51f40477f10db8bc30a557aa0ea712c274 jdk9-b02
 832f89ff25d903c45cfc994553f1ade8821a4398 jdk9-b03
+3f6ef92cd7823372c45e79125adba4cbf1c9f7b2 jdk9-b04
+2a1cac93c33317d828d4a5b81239204a9927cc4a jdk9-b05
--- a/nashorn/make/BuildNashorn.gmk	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/make/BuildNashorn.gmk	Tue Mar 25 20:32:46 2014 -0400
@@ -77,7 +77,7 @@
 	$(RM) -rf $(@D)/jdk $(@D)/netscape
 	$(CP) -R -p $(NASHORN_OUTPUTDIR)/nashorn_classes/* $(@D)/
 	$(FIXPATH) $(JAVA) \
-	    -cp "$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \
+	    -Xbootclasspath/p:"$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \
 	    jdk.nashorn.internal.tools.nasgen.Main $(@D) jdk.nashorn.internal.objects $(@D)
 	$(TOUCH) $@
 
--- a/nashorn/make/build.xml	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/make/build.xml	Tue Mar 25 20:32:46 2014 -0400
@@ -125,6 +125,7 @@
       <compilerarg value="-Xlint:unchecked"/>
       <compilerarg value="-Xlint:deprecation"/>
       <compilerarg value="-XDignore.symbol.file"/>
+      <compilerarg value="-Xdiags:verbose"/>
     </javac>
     <copy todir="${build.classes.dir}/META-INF/services">
        <fileset dir="${meta.inf.dir}/services/"/>
@@ -243,6 +244,7 @@
         <compilerarg value="-J-Djava.ext.dirs="/>
         <compilerarg value="-Xlint:unchecked"/>
         <compilerarg value="-Xlint:deprecation"/>
+        <compilerarg value="-Xdiags:verbose"/>
     </javac>
 
     <copy todir="${build.test.classes.dir}/META-INF/services">
@@ -253,6 +255,10 @@
        <fileset dir="${test.src.dir}/jdk/nashorn/internal/runtime/resources"/>
     </copy>
 
+    <copy todir="${build.test.classes.dir}/jdk/nashorn/api/scripting/resources">
+       <fileset dir="${test.src.dir}/jdk/nashorn/api/scripting/resources"/>
+    </copy>
+
     <!-- tests that check nashorn internals and internal API -->
     <jar jarfile="${nashorn.internal.tests.jar}">
       <fileset dir="${build.test.classes.dir}" excludes="**/api/**"/>
--- a/nashorn/make/project.properties	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/make/project.properties	Tue Mar 25 20:32:46 2014 -0400
@@ -206,7 +206,7 @@
 
 # test262 test frameworks
 test262-test-sys-prop.test.js.framework=\
-    --class-cache-size=0 \
+    --class-cache-size=10 \
     --no-java \
     --no-typed-arrays \
     -timezone=PST \
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Tue Mar 25 20:32:46 2014 -0400
@@ -57,9 +57,9 @@
 import javax.script.ScriptEngineFactory;
 import javax.script.ScriptException;
 import javax.script.SimpleBindings;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ErrorManager;
-import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -99,7 +99,7 @@
     private final boolean             _global_per_engine;
     // This is the initial default Nashorn global object.
     // This is used as "shared" global if above option is true.
-    private final ScriptObject        global;
+    private final Global              global;
     // initialized bit late to be made 'final'.
     // Property object for "context" property of global object.
     private volatile Property         contextProperty;
@@ -264,7 +264,7 @@
     public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) {
         if (ctxt != null) {
             final int scope = ctxt.getAttributesScope(name);
-            final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
+            final Global ctxtGlobal = getNashornGlobalFrom(ctxt);
             if (scope != -1) {
                 return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
             }
@@ -317,7 +317,7 @@
         }
 
         ScriptObject realSelf = null;
-        ScriptObject realGlobal = null;
+        Global realGlobal = null;
         if(thiz == null) {
             // making interface out of global functions
             realSelf = realGlobal = getNashornGlobalFrom(context);
@@ -346,7 +346,7 @@
         }
 
         try {
-            final ScriptObject oldGlobal = Context.getGlobal();
+            final Global oldGlobal = Context.getGlobal();
             final boolean globalChanged = (oldGlobal != realGlobal);
             try {
                 if (globalChanged) {
@@ -371,7 +371,7 @@
     }
 
     // Retrieve nashorn Global object for a given ScriptContext object
-    private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) {
+    private Global getNashornGlobalFrom(final ScriptContext ctxt) {
         if (_global_per_engine) {
             // shared single global object for all ENGINE_SCOPE Bindings
             return global;
@@ -380,18 +380,18 @@
         final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
         // is this Nashorn's own Bindings implementation?
         if (bindings instanceof ScriptObjectMirror) {
-            final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)bindings);
-            if (sobj != null) {
-                return sobj;
+            final Global glob = globalFromMirror((ScriptObjectMirror)bindings);
+            if (glob != null) {
+                return glob;
             }
         }
 
         // Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
         Object scope = bindings.get(NASHORN_GLOBAL);
         if (scope instanceof ScriptObjectMirror) {
-            final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)scope);
-            if (sobj != null) {
-                return sobj;
+            final Global glob = globalFromMirror((ScriptObjectMirror)scope);
+            if (glob != null) {
+                return glob;
             }
         }
 
@@ -399,14 +399,14 @@
         // Create new global instance mirror and associate with the Bindings.
         final ScriptObjectMirror mirror = createGlobalMirror(ctxt);
         bindings.put(NASHORN_GLOBAL, mirror);
-        return mirror.getScriptObject();
+        return mirror.getHomeGlobal();
     }
 
     // Retrieve nashorn Global object from a given ScriptObjectMirror
-    private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) {
+    private Global globalFromMirror(final ScriptObjectMirror mirror) {
         ScriptObject sobj = mirror.getScriptObject();
-        if (sobj instanceof GlobalObject && isOfContext(sobj, nashornContext)) {
-            return sobj;
+        if (sobj instanceof Global && isOfContext((Global)sobj, nashornContext)) {
+            return (Global)sobj;
         }
 
         return null;
@@ -414,15 +414,15 @@
 
     // Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object
     private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) {
-        final ScriptObject newGlobal = createNashornGlobal(ctxt);
+        final Global newGlobal = createNashornGlobal(ctxt);
         return new ScriptObjectMirror(newGlobal, newGlobal);
     }
 
     // Create a new Nashorn Global object
-    private ScriptObject createNashornGlobal(final ScriptContext ctxt) {
-        final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() {
+    private Global createNashornGlobal(final ScriptContext ctxt) {
+        final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction<Global>() {
             @Override
-            public ScriptObject run() {
+            public Global run() {
                 try {
                     return nashornContext.newGlobal();
                 } catch (final RuntimeException e) {
@@ -460,7 +460,7 @@
     }
 
     // scripts should see "context" and "engine" as variables in the given global object
-    private void setContextVariables(final ScriptObject ctxtGlobal, final ScriptContext ctxt) {
+    private void setContextVariables(final Global ctxtGlobal, final ScriptContext ctxt) {
         // set "context" global variable via contextProperty - because this
         // property is non-writable
         contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false);
@@ -470,7 +470,7 @@
         }
         // if no arguments passed, expose it
         if (! (args instanceof ScriptObject)) {
-            args = ((GlobalObject)ctxtGlobal).wrapAsObject(args);
+            args = ctxtGlobal.wrapAsObject(args);
             ctxtGlobal.set("arguments", args, false);
         }
     }
@@ -478,7 +478,7 @@
     private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
         name.getClass(); // null check
 
-        ScriptObject invokeGlobal = null;
+        Global invokeGlobal = null;
         ScriptObjectMirror selfMirror = null;
         if (selfObject instanceof ScriptObjectMirror) {
             selfMirror = (ScriptObjectMirror)selfObject;
@@ -489,7 +489,7 @@
         } else if (selfObject instanceof ScriptObject) {
             // invokeMethod called from script code - in which case we may get 'naked' ScriptObject
             // Wrap it with oldGlobal to make a ScriptObjectMirror for the same.
-            final ScriptObject oldGlobal = Context.getGlobal();
+            final Global oldGlobal = Context.getGlobal();
             invokeGlobal = oldGlobal;
             if (oldGlobal == null) {
                 throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
@@ -502,7 +502,7 @@
             selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
         } else if (selfObject == null) {
             // selfObject is null => global function call
-            final ScriptObject ctxtGlobal = getNashornGlobalFrom(context);
+            final Global ctxtGlobal = getNashornGlobalFrom(context);
             invokeGlobal = ctxtGlobal;
             selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal);
         }
@@ -532,11 +532,11 @@
         return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
     }
 
-    private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final ScriptObject ctxtGlobal) throws ScriptException {
+    private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
         if (script == null) {
             return null;
         }
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != ctxtGlobal);
         try {
             if (globalChanged) {
@@ -558,7 +558,7 @@
         }
     }
 
-    private static void throwAsScriptException(final Exception e, final ScriptObject global) throws ScriptException {
+    private static void throwAsScriptException(final Exception e, final Global global) throws ScriptException {
         if (e instanceof ScriptException) {
             throw (ScriptException)e;
         } else if (e instanceof NashornException) {
@@ -582,7 +582,7 @@
         return new CompiledScript() {
             @Override
             public Object eval(final ScriptContext ctxt) throws ScriptException {
-                final ScriptObject globalObject = getNashornGlobalFrom(ctxt);
+                final Global globalObject = getNashornGlobalFrom(ctxt);
                 // Are we running the script in the correct global?
                 if (func.getScope() == globalObject) {
                     return evalImpl(func, ctxt, globalObject);
@@ -602,8 +602,8 @@
         return compileImpl(source, getNashornGlobalFrom(ctxt));
     }
 
-    private ScriptFunction compileImpl(final Source source, final ScriptObject newGlobal) throws ScriptException {
-        final ScriptObject oldGlobal = Context.getGlobal();
+    private ScriptFunction compileImpl(final Source source, final Global newGlobal) throws ScriptException {
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != newGlobal);
         try {
             if (globalChanged) {
@@ -641,8 +641,7 @@
         return true;
     }
 
-    private static boolean isOfContext(final ScriptObject global, final Context context) {
-        assert global instanceof GlobalObject: "Not a Global object";
-        return ((GlobalObject)global).isOfContext(context);
+    private static boolean isOfContext(final Global global, final Context context) {
+        return global.isOfContext(context);
     }
 }
--- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java	Tue Mar 25 20:32:46 2014 -0400
@@ -42,10 +42,10 @@
 import java.util.Set;
 import java.util.concurrent.Callable;
 import javax.script.Bindings;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.ConsString;
 import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -64,7 +64,7 @@
     private static final AccessControlContext GET_CONTEXT_ACC_CTXT = getContextAccCtxt();
 
     private final ScriptObject sobj;
-    private final ScriptObject global;
+    private final Global  global;
     private final boolean strict;
 
     @Override
@@ -95,7 +95,7 @@
 
     @Override
     public Object call(final Object thiz, final Object... args) {
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
 
         try {
@@ -125,7 +125,7 @@
 
     @Override
     public Object newObject(final Object... args) {
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
 
         try {
@@ -171,7 +171,7 @@
 
     public Object callMember(final String functionName, final Object... args) {
         functionName.getClass(); // null check
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
 
         try {
@@ -642,7 +642,7 @@
      */
     public static Object wrap(final Object obj, final Object homeGlobal) {
         if(obj instanceof ScriptObject) {
-            return homeGlobal instanceof ScriptObject ? new ScriptObjectMirror((ScriptObject)obj, (ScriptObject)homeGlobal) : obj;
+            return homeGlobal instanceof Global ? new ScriptObjectMirror((ScriptObject)obj, (Global)homeGlobal) : obj;
         }
         if(obj instanceof ConsString) {
             return obj.toString();
@@ -710,13 +710,13 @@
 
     // package-privates below this.
 
-    ScriptObjectMirror(final ScriptObject sobj, final ScriptObject global) {
+    ScriptObjectMirror(final ScriptObject sobj, final Global global) {
         assert sobj != null : "ScriptObjectMirror on null!";
-        assert global instanceof GlobalObject : "global is not a GlobalObject";
+        assert global != null : "home Global is null";
 
         this.sobj = sobj;
         this.global = global;
-        this.strict = ((GlobalObject)global).isStrictContext();
+        this.strict = global.isStrictContext();
     }
 
     // accessors for script engine
@@ -724,7 +724,7 @@
         return sobj;
     }
 
-    ScriptObject getHomeGlobal() {
+    Global getHomeGlobal() {
         return global;
     }
 
@@ -734,7 +734,7 @@
 
     // internals only below this.
     private <V> V inGlobal(final Callable<V> callable) {
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
         if (globalChanged) {
             Context.setGlobal(global);
--- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java	Tue Mar 25 20:32:46 2014 -0400
@@ -375,10 +375,11 @@
      * @return Symbol for given name or null for redefinition.
      */
     private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
-        int    flags  = symbolFlags;
-        Symbol symbol = findSymbol(block, name); // Locate symbol.
+        int     flags    = symbolFlags;
+        Symbol  symbol   = findSymbol(block, name); // Locate symbol.
+        boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
 
-        if ((flags & KINDMASK) == IS_GLOBAL) {
+        if (isGlobal) {
             flags |= IS_SCOPE;
         }
 
@@ -414,6 +415,8 @@
             // Determine where to create it.
             if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
                 symbolBlock = block; //internal vars are always defined in the block closest to them
+            } else if (isGlobal) {
+                symbolBlock = lc.getOutermostFunction().getBody();
             } else {
                 symbolBlock = lc.getFunctionBody(function);
             }
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Tue Mar 25 20:32:46 2014 -0400
@@ -685,7 +685,7 @@
             private void scopeCall(final IdentNode node, final int flags) {
                 load(node, Type.OBJECT); // Type.OBJECT as foo() makes no sense if foo == 3
                 // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
-                method.loadNull(); //the 'this'
+                method.loadUndefined(Type.OBJECT); //the 'this' object
                 method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
             }
 
@@ -818,7 +818,7 @@
             protected boolean enterDefault(final Node node) {
                 // Load up function.
                 load(function, Type.OBJECT); //TODO, e.g. booleans can be used as functions
-                method.loadNull(); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
+                method.loadUndefined(Type.OBJECT); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
                 method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
 
                 return false;
--- a/nashorn/src/jdk/nashorn/internal/codegen/SharedScopeCall.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/codegen/SharedScopeCall.java	Tue Mar 25 20:32:46 2014 -0400
@@ -156,7 +156,7 @@
         if (isCall) {
             method.convert(Type.OBJECT);
             // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
-            method.loadNull();
+            method.loadUndefined(Type.OBJECT);
             int slot = 2;
             for (final Type type : paramTypes) {
                 method.load(type, slot++);
--- a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java	Tue Mar 25 20:32:46 2014 -0400
@@ -164,11 +164,11 @@
     public static final int HAS_EVAL                    = 1 << 5;
 
     /** Does a nested function contain eval? If it does, then all variables in this function might be get/set by it. */
-    public static final int HAS_NESTED_EVAL = 1 << 6;
+    public static final int HAS_NESTED_EVAL             = 1 << 6;
 
     /** Does this function have any blocks that create a scope? This is used to determine if the function needs to
      * have a local variable slot for the scope symbol. */
-    public static final int HAS_SCOPE_BLOCK = 1 << 7;
+    public static final int HAS_SCOPE_BLOCK             = 1 << 7;
 
     /**
      * Flag this function as one that defines the identifier "arguments" as a function parameter or nested function
@@ -197,6 +197,9 @@
     /** Can this function be specialized? */
     public static final int CAN_SPECIALIZE              = 1 << 14;
 
+    /** Does this function use the "this" keyword? */
+    public static final int USES_THIS                   = 1 << 15;
+
     /** Does this function or any nested functions contain an eval? */
     private static final int HAS_DEEP_EVAL = HAS_EVAL | HAS_NESTED_EVAL;
 
@@ -591,6 +594,15 @@
     }
 
     /**
+     * Return {@code true} if this function makes use of the {@code this} object.
+     *
+     * @return true if function uses {@code this} object
+     */
+    public boolean usesThis() {
+        return getFlag(USES_THIS);
+    }
+
+    /**
      * Get the identifier for this function, this is its symbol.
      * @return the identifier as an IdentityNode
      */
--- a/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java	Tue Mar 25 20:32:46 2014 -0400
@@ -67,12 +67,8 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     AccessorPropertyDescriptor(final boolean configurable, final boolean enumerable, final Object get, final Object set, final Global global) {
-        super(global.getObjectPrototype(), getInitialMap());
+        super(global.getObjectPrototype(), $nasgenmap$);
         this.configurable = configurable;
         this.enumerable   = enumerable;
         this.get          = get;
--- a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java	Tue Mar 25 20:32:46 2014 -0400
@@ -42,12 +42,8 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength, final Global global) {
-        super(getInitialMap());
+        super($nasgenmap$);
         checkConstructorArgs(buffer, byteOffset, elementLength);
         this.setProto(getPrototype(global));
         this.setArray(factory().createArrayData(buffer, byteOffset, elementLength));
--- a/nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java	Tue Mar 25 20:32:46 2014 -0400
@@ -64,12 +64,8 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     DataPropertyDescriptor(final boolean configurable, final boolean enumerable, final boolean writable, final Object value, final Global global) {
-        super(global.getObjectPrototype(), getInitialMap());
+        super(global.getObjectPrototype(), $nasgenmap$);
         this.configurable = configurable;
         this.enumerable   = enumerable;
         this.writable     = writable;
--- a/nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java	Tue Mar 25 20:32:46 2014 -0400
@@ -55,12 +55,8 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     GenericPropertyDescriptor(final boolean configurable, final boolean enumerable, final Global global) {
-        super(global.getObjectPrototype(), getInitialMap());
+        super(global.getObjectPrototype(), $nasgenmap$);
         this.configurable = configurable;
         this.enumerable   = enumerable;
     }
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java	Tue Mar 25 20:32:46 2014 -0400
@@ -33,11 +33,8 @@
 import java.io.PrintWriter;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
 import java.lang.reflect.Field;
 import java.util.Arrays;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
@@ -51,7 +48,6 @@
 import jdk.nashorn.internal.runtime.ConsString;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.GlobalFunctions;
-import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.NativeJavaPackage;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
@@ -59,10 +55,10 @@
 import jdk.nashorn.internal.runtime.Scope;
 import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptFunctionData;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.ScriptingFunctions;
-import jdk.nashorn.internal.runtime.Source;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.InvokeByName;
@@ -73,7 +69,7 @@
  * Representation of global scope.
  */
 @ScriptClass("Global")
-public final class Global extends ScriptObject implements GlobalObject, Scope {
+public final class Global extends ScriptObject implements Scope {
     private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
     private final InvokeByName VALUE_OF  = new InvokeByName("valueOf",  ScriptObject.class);
 
@@ -229,6 +225,10 @@
     @Property(name = "ArrayBuffer", attributes = Attribute.NOT_ENUMERABLE)
     public volatile Object arrayBuffer;
 
+    /** DataView object */
+    @Property(name = "DataView", attributes = Attribute.NOT_ENUMERABLE)
+    public volatile Object dataView;
+
     /** TypedArray (int8) */
     @Property(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE)
     public volatile Object int8Array;
@@ -355,6 +355,7 @@
     private ScriptObject   builtinJavaImporter;
     private ScriptObject   builtinJavaApi;
     private ScriptObject   builtinArrayBuffer;
+    private ScriptObject   builtinDataView;
     private ScriptObject   builtinInt8Array;
     private ScriptObject   builtinUint8Array;
     private ScriptObject   builtinUint8ClampedArray;
@@ -373,9 +374,6 @@
     // Flag to indicate that a split method issued a return statement
     private int splitState = -1;
 
-    // class cache
-    private ClassCache classCache;
-
     // Used to store the last RegExp result to support deprecated RegExp constructor properties
     private RegExpResult lastRegExpResult;
 
@@ -426,11 +424,6 @@
         super(checkAndGetMap(context));
         this.context = context;
         this.setIsScope();
-
-        final int cacheSize = context.getEnv()._class_cache_size;
-        if (cacheSize > 0) {
-            classCache = new ClassCache(cacheSize);
-        }
     }
 
     /**
@@ -439,11 +432,9 @@
      * @return the global singleton
      */
     public static Global instance() {
-        ScriptObject global = Context.getGlobal();
-        if (! (global instanceof Global)) {
-            throw new IllegalStateException("no current global instance");
-        }
-        return (Global)global;
+        Global global = Context.getGlobal();
+        global.getClass(); // null check
+        return global;
     }
 
     /**
@@ -464,19 +455,30 @@
         return instance().getContext();
     }
 
-    // GlobalObject interface implementation
+    // Runtime interface to Global
 
-    @Override
+    /**
+     * Is this global of the given Context?
+     * @param ctxt the context
+     * @return true if this global belongs to the given Context
+     */
     public boolean isOfContext(final Context ctxt) {
         return this.context == ctxt;
     }
 
-    @Override
+    /**
+     * Does this global belong to a strict Context?
+     * @return true if this global belongs to a strict Context
+     */
     public boolean isStrictContext() {
         return context.getEnv()._strict;
     }
 
-    @Override
+    /**
+     * Initialize standard builtin objects like "Object", "Array", "Function" etc.
+     * as well as our extension builtin objects like "Java", "JSAdapter" as properties
+     * of the global scope object.
+     */
     public void initBuiltinObjects() {
         if (this.builtinObject != null) {
             // already initialized, just return
@@ -486,12 +488,26 @@
         init();
     }
 
-    @Override
+    /**
+     * Create a new ScriptFunction object
+     *
+     * @param name   function name
+     * @param handle invocation handle for function
+     * @param scope  the scope
+     * @param strict are we in strict mode
+     *
+     * @return new script function
+     */
     public ScriptFunction newScriptFunction(final String name, final MethodHandle handle, final ScriptObject scope, final boolean strict) {
-        return new ScriptFunctionImpl(name, handle, scope, null, strict, false, true);
+        return new ScriptFunctionImpl(name, handle, scope, null, strict ? ScriptFunctionData.IS_STRICT_CONSTRUCTOR : ScriptFunctionData.IS_CONSTRUCTOR);
     }
 
-    @Override
+    /**
+     * Wrap a Java object as corresponding script object
+     *
+     * @param obj object to wrap
+     * @return    wrapped object
+     */
     public Object wrapAsObject(final Object obj) {
         if (obj instanceof Boolean) {
             return new NativeBoolean((Boolean)obj, this);
@@ -513,7 +529,14 @@
         }
     }
 
-    @Override
+    /**
+     * Lookup helper for JS primitive types
+     *
+     * @param request the link request for the dynamic call site.
+     * @param self     self reference
+     *
+     * @return guarded invocation
+     */
     public GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
         if (self instanceof String || self instanceof ConsString) {
             return NativeString.lookupPrimitive(request, self);
@@ -525,12 +548,23 @@
         throw new IllegalArgumentException("Unsupported primitive: " + self);
     }
 
-    @Override
+    /**
+     * Create a new empty script object
+     *
+     * @return the new ScriptObject
+     */
     public ScriptObject newObject() {
         return new JO(getObjectPrototype(), JO.getInitialMap());
     }
 
-    @Override
+    /**
+     * Default value of given type
+     *
+     * @param sobj     script object
+     * @param typeHint type hint
+     *
+     * @return default value
+     */
     public Object getDefaultValue(final ScriptObject sobj, final Class<?> typeHint) {
         // When the [[DefaultValue]] internal method of O is called with no hint,
         // then it behaves as if the hint were Number, unless O is a Date object
@@ -590,7 +624,12 @@
         return UNDEFINED;
     }
 
-    @Override
+    /**
+     * Is the given ScriptObject an ECMAScript Error object?
+     *
+     * @param sobj the object being checked
+     * @return true if sobj is an Error object
+     */
     public boolean isError(final ScriptObject sobj) {
         final ScriptObject errorProto = getErrorPrototype();
         ScriptObject proto = sobj.getProto();
@@ -603,52 +642,108 @@
         return false;
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript Error object.
+     *
+     * @param msg error message
+     * @return newly created Error object
+     */
     public ScriptObject newError(final String msg) {
         return new NativeError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript EvalError object.
+     *
+     * @param msg error message
+     * @return newly created EvalError object
+     */
     public ScriptObject newEvalError(final String msg) {
         return new NativeEvalError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript RangeError object.
+     *
+     * @param msg error message
+     * @return newly created RangeError object
+     */
     public ScriptObject newRangeError(final String msg) {
         return new NativeRangeError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript ReferenceError object.
+     *
+     * @param msg error message
+     * @return newly created ReferenceError object
+     */
     public ScriptObject newReferenceError(final String msg) {
         return new NativeReferenceError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript SyntaxError object.
+     *
+     * @param msg error message
+     * @return newly created SyntaxError object
+     */
     public ScriptObject newSyntaxError(final String msg) {
         return new NativeSyntaxError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript TypeError object.
+     *
+     * @param msg error message
+     * @return newly created TypeError object
+     */
     public ScriptObject newTypeError(final String msg) {
         return new NativeTypeError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript URIError object.
+     *
+     * @param msg error message
+     * @return newly created URIError object
+     */
     public ScriptObject newURIError(final String msg) {
         return new NativeURIError(msg, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript GenericDescriptor object.
+     *
+     * @param configurable is the property configurable?
+     * @param enumerable is the property enumerable?
+     * @return newly created GenericDescriptor object
+     */
     public PropertyDescriptor newGenericDescriptor(final boolean configurable, final boolean enumerable) {
         return new GenericPropertyDescriptor(configurable, enumerable, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript DatePropertyDescriptor object.
+     *
+     * @param value of the data property
+     * @param configurable is the property configurable?
+     * @param enumerable is the property enumerable?
+     * @return newly created DataPropertyDescriptor object
+     */
     public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
         return new DataPropertyDescriptor(configurable, enumerable, writable, value, this);
     }
 
-    @Override
+    /**
+     * Create a new ECMAScript AccessorPropertyDescriptor object.
+     *
+     * @param get getter function of the user accessor property
+     * @param set setter function of the user accessor property
+     * @param configurable is the property configurable?
+     * @param enumerable is the property enumerable?
+     * @return newly created AccessorPropertyDescriptor object
+     */
     public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
         final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set, this);
 
@@ -664,62 +759,6 @@
     }
 
 
-    /**
-     * Cache for compiled script classes.
-     */
-    @SuppressWarnings("serial")
-    private static class ClassCache extends LinkedHashMap<Source, ClassReference> {
-        private final int size;
-        private final ReferenceQueue<Class<?>> queue;
-
-        ClassCache(int size) {
-            super(size, 0.75f, true);
-            this.size = size;
-            this.queue = new ReferenceQueue<>();
-        }
-
-        void cache(final Source source, final Class<?> clazz) {
-            put(source, new ClassReference(clazz, queue, source));
-        }
-
-        @Override
-        protected boolean removeEldestEntry(final Map.Entry<Source, ClassReference> eldest) {
-            return size() > size;
-        }
-
-        @Override
-        public ClassReference get(Object key) {
-            for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) {
-                remove(ref.source);
-            }
-            return super.get(key);
-        }
-
-    }
-
-    private static class ClassReference extends SoftReference<Class<?>> {
-        private final Source source;
-
-        ClassReference(final Class<?> clazz, final ReferenceQueue<Class<?>> queue, final Source source) {
-            super(clazz, queue);
-            this.source = source;
-        }
-    }
-
-    // Class cache management
-    @Override
-    public Class<?> findCachedClass(final Source source) {
-        assert classCache != null : "Class cache used without being initialized";
-        ClassReference ref = classCache.get(source);
-        return ref != null ? ref.get() : null;
-    }
-
-    @Override
-    public void cacheClass(final Source source, final Class<?> clazz) {
-        assert classCache != null : "Class cache used without being initialized";
-        classCache.cache(source, clazz);
-    }
-
     private static <T> T getLazilyCreatedValue(final Object key, final Callable<T> creator, final Map<Object, T> map) {
         final T obj = map.get(key);
         if (obj != null) {
@@ -737,14 +776,25 @@
 
     private final Map<Object, InvokeByName> namedInvokers = new ConcurrentHashMap<>();
 
-    @Override
+
+    /**
+     * Get cached InvokeByName object for the given key
+     * @param key key to be associated with InvokeByName object
+     * @param creator if InvokeByName is absent 'creator' is called to make one (lazy init)
+     * @return InvokeByName object associated with the key.
+     */
     public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator) {
         return getLazilyCreatedValue(key, creator, namedInvokers);
     }
 
     private final Map<Object, MethodHandle> dynamicInvokers = new ConcurrentHashMap<>();
 
-    @Override
+    /**
+     * Get cached dynamic method handle for the given key
+     * @param key key to be associated with dynamic method handle
+     * @param creator if method handle is absent 'creator' is called to make one (lazy init)
+     * @return dynamic method handle associated with the key.
+     */
     public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator) {
         return getLazilyCreatedValue(key, creator, dynamicInvokers);
     }
@@ -933,6 +983,10 @@
         return ScriptFunction.getPrototype(builtinArrayBuffer);
     }
 
+    ScriptObject getDataViewPrototype() {
+        return ScriptFunction.getPrototype(builtinDataView);
+    }
+
     ScriptObject getInt8ArrayPrototype() {
         return ScriptFunction.getPrototype(builtinInt8Array);
     }
@@ -1701,6 +1755,7 @@
 
     private void initTypedArray() {
         this.builtinArrayBuffer       = initConstructor("ArrayBuffer");
+        this.builtinDataView          = initConstructor("DataView");
         this.builtinInt8Array         = initConstructor("Int8Array");
         this.builtinUint8Array        = initConstructor("Uint8Array");
         this.builtinUint8ClampedArray = initConstructor("Uint8ClampedArray");
@@ -1741,6 +1796,7 @@
         this.typeError         = this.builtinTypeError;
         this.uriError          = this.builtinURIError;
         this.arrayBuffer       = this.builtinArrayBuffer;
+        this.dataView          = this.builtinDataView;
         this.int8Array         = this.builtinInt8Array;
         this.uint8Array        = this.builtinUint8Array;
         this.uint8ClampedArray = this.builtinUint8ClampedArray;
@@ -1838,7 +1894,7 @@
         anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
 
         // use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
-        this.typeErrorThrower = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, false, false, false);
+        this.typeErrorThrower = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, 0);
         typeErrorThrower.setPrototype(UNDEFINED);
         // Non-constructor built-in functions do not have "prototype" property
         typeErrorThrower.deleteOwnProperty(typeErrorThrower.getMap().findProperty("prototype"));
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java	Tue Mar 25 20:32:46 2014 -0400
@@ -156,10 +156,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     /*
      * Constructors.
      */
@@ -208,7 +204,7 @@
     }
 
     NativeArray(final ArrayData arrayData, final Global global) {
-        super(global.getArrayPrototype(), getInitialMap());
+        super(global.getArrayPrototype(), $nasgenmap$);
         this.setArray(arrayData);
         this.setIsArray();
     }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java	Tue Mar 25 20:32:46 2014 -0400
@@ -25,6 +25,7 @@
 
 package jdk.nashorn.internal.objects;
 
+import java.nio.ByteBuffer;
 import java.util.Arrays;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Constructor;
@@ -43,10 +44,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     @Constructor(arity = 1)
     public static Object constructor(final boolean newObj, final Object self, final Object... args) {
         if (args.length == 0) {
@@ -57,7 +54,7 @@
     }
 
     protected NativeArrayBuffer(final byte[] byteArray, final Global global) {
-        super(global.getArrayBufferPrototype(), getInitialMap());
+        super(global.getArrayBufferPrototype(), $nasgenmap$);
         this.buffer = byteArray;
     }
 
@@ -128,4 +125,16 @@
     public int getByteLength() {
         return buffer.length;
     }
+
+    ByteBuffer getBuffer() {
+       return ByteBuffer.wrap(buffer);
+    }
+
+    ByteBuffer getBuffer(final int offset) {
+        return ByteBuffer.wrap(buffer, offset, buffer.length - offset);
+    }
+
+    ByteBuffer getBuffer(final int offset, final int length) {
+        return ByteBuffer.wrap(buffer, offset, length);
+    }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java	Tue Mar 25 20:32:46 2014 -0400
@@ -30,6 +30,7 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
 import jdk.nashorn.internal.objects.annotations.Attribute;
@@ -50,22 +51,21 @@
 public final class NativeBoolean extends ScriptObject {
     private final boolean value;
 
-    final static MethodHandle WRAPFILTER = findWrapFilter();
+    // Method handle to create an object wrapper for a primitive boolean
+    private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeBoolean.class, Object.class));
+    // Method handle to retrieve the Boolean prototype object
+    private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
 
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private NativeBoolean(final boolean value, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         this.value = value;
     }
 
     NativeBoolean(final boolean flag, final Global global) {
-        this(flag, global.getBooleanPrototype(), getInitialMap());
+        this(flag, global.getBooleanPrototype(), $nasgenmap$);
     }
 
     NativeBoolean(final boolean flag) {
@@ -164,7 +164,7 @@
      * @return Link to be invoked at call site.
      */
     public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
-        return PrimitiveLookup.lookupPrimitive(request, Boolean.class, new NativeBoolean((Boolean)receiver), WRAPFILTER);
+        return PrimitiveLookup.lookupPrimitive(request, Boolean.class, new NativeBoolean((Boolean)receiver), WRAPFILTER, PROTOFILTER);
     }
 
     /**
@@ -178,7 +178,12 @@
         return new NativeBoolean((Boolean)receiver);
     }
 
-    private static MethodHandle findWrapFilter() {
-        return MH.findStatic(MethodHandles.lookup(), NativeBoolean.class, "wrapFilter", MH.type(NativeBoolean.class, Object.class));
+    @SuppressWarnings("unused")
+    private static Object protoFilter(final Object object) {
+        return Global.instance().getBooleanPrototype();
+    }
+
+    private static MethodHandle findOwnMH(final String name, final MethodType type) {
+        return MH.findStatic(MethodHandles.lookup(), NativeBoolean.class, name, type);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDataView.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,1015 @@
+/*
+ * 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 jdk.nashorn.internal.objects;
+
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
+import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+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.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;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
+
+/**
+ * <p>
+ * DataView builtin constructor. Based on the specification here:
+ * http://www.khronos.org/registry/typedarray/specs/latest/#8
+ * </p>
+ * <p>
+ * An ArrayBuffer is a useful object for representing an arbitrary chunk of data.
+ * In many cases, such data will be read from disk or from the network, and will
+ * not follow the alignment restrictions that are imposed on the typed array views
+ * described earlier. In addition, the data will often be heterogeneous in nature
+ * and have a defined byte order. The DataView view provides a low-level interface
+ * for reading such data from and writing it to an ArrayBuffer.
+ * </p>
+ * <p>
+ * Regardless of the host computer's endianness, DataView reads or writes values
+ * to or from main memory with a specified endianness: big or little.
+ * </p>
+ */
+@ScriptClass("DataView")
+public class NativeDataView extends ScriptObject {
+    // initialized by nasgen
+    private static PropertyMap $nasgenmap$;
+
+    // inherited ArrayBufferView properties
+
+    /**
+     * Underlying ArrayBuffer storage object
+     */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public final Object buffer;
+
+    /**
+     * The offset in bytes from the start of the ArrayBuffer
+     */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public final int byteOffset;
+
+    /**
+     * The number of bytes from the offset that this DataView will reference
+     */
+    @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
+    public final int byteLength;
+
+    // underlying ByteBuffer
+    private final ByteBuffer buf;
+
+    private NativeDataView(NativeArrayBuffer arrBuf) {
+        this(arrBuf, arrBuf.getBuffer(), 0);
+    }
+
+    private NativeDataView(NativeArrayBuffer arrBuf, int offset) {
+        this(arrBuf, bufferFrom(arrBuf, offset), offset);
+    }
+
+    private NativeDataView(NativeArrayBuffer arrBuf, int offset, int length) {
+        this(arrBuf, bufferFrom(arrBuf, offset, length), offset, length);
+    }
+
+    private NativeDataView(final NativeArrayBuffer arrBuf, final ByteBuffer buf, final int offset) {
+       this(arrBuf, buf, offset, buf.capacity() - offset);
+    }
+
+    private NativeDataView(final NativeArrayBuffer arrBuf, final ByteBuffer buf, final int offset, final int length) {
+        super(Global.instance().getDataViewPrototype(), $nasgenmap$);
+        this.buffer = arrBuf;
+        this.byteOffset = offset;
+        this.byteLength = length;
+        this.buf = buf;
+    }
+
+    /**
+     * Create a new DataView object using the passed ArrayBuffer for its
+     * storage. Optional byteOffset and byteLength can be used to limit the
+     * section of the buffer referenced. The byteOffset indicates the offset in
+     * bytes from the start of the ArrayBuffer, and the byteLength is the number
+     * of bytes from the offset that this DataView will reference. If both
+     * byteOffset and byteLength are omitted, the DataView spans the entire
+     * ArrayBuffer range. If the byteLength is omitted, the DataView extends from
+     * the given byteOffset until the end of the ArrayBuffer.
+     *
+     * If the given byteOffset and byteLength references an area beyond the end
+     * of the ArrayBuffer an exception is raised.
+
+     * @param newObj if this constructor was invoked with 'new' or not
+     * @param self   constructor function object
+     * @param args   arguments to the constructor
+     * @return newly constructed DataView object
+     */
+    @Constructor(arity = 1)
+    public static Object constructor(final boolean newObj, final Object self, final Object... args) {
+        if (args.length == 0 || !(args[0] instanceof NativeArrayBuffer)) {
+            throw typeError("not.an.arraybuffer.in.dataview");
+        }
+
+        final NativeArrayBuffer arrBuf = (NativeArrayBuffer) args[0];
+        switch (args.length) {
+            case 1:
+                return new NativeDataView(arrBuf);
+            case 2:
+                return new NativeDataView(arrBuf, JSType.toInt32(args[1]));
+            default:
+                return new NativeDataView(arrBuf, JSType.toInt32(args[1]), JSType.toInt32(args[2]));
+        }
+    }
+
+    /**
+     * Specialized version of DataView constructor
+     *
+     * @param newObj if this constructor was invoked with 'new' or not
+     * @param self   constructor function object
+     * @param arrBuf underlying ArrayBuffer storage object
+     * @param offset offset in bytes from the start of the ArrayBuffer
+     * @return newly constructed DataView object
+     */
+    @SpecializedConstructor
+    public static Object constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset) {
+        if (!(arrBuf instanceof NativeArrayBuffer)) {
+            throw typeError("not.an.arraybuffer.in.dataview");
+        }
+        return new NativeDataView((NativeArrayBuffer) arrBuf, offset);
+    }
+
+    /**
+     * Specialized version of DataView constructor
+     *
+     * @param newObj if this constructor was invoked with 'new' or not
+     * @param self   constructor function object
+     * @param arrBuf underlying ArrayBuffer storage object
+     * @param offset in bytes from the start of the ArrayBuffer
+     * @param length is the number of bytes from the offset that this DataView will reference
+     * @return newly constructed DataView object
+     */
+    @SpecializedConstructor
+    public static Object 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");
+        }
+        return new NativeDataView((NativeArrayBuffer) arrBuf, offset, length);
+    }
+
+    // Gets the value of the given type at the specified byte offset
+    // from the start of the view. There is no alignment constraint;
+    // multi-byte values may be fetched from any offset.
+    //
+    // For multi-byte values, the optional littleEndian argument
+    // indicates whether a big-endian or little-endian value should be
+    // read. If false or undefined, a big-endian value is read.
+    //
+    // These methods raise an exception if they would read
+    // beyond the end of the view.
+
+    /**
+     * Get 8-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 8-bit signed int value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static int getInt8(final Object self, final Object byteOffset) {
+        try {
+            return getBuffer(self).get(JSType.toInt32(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 8-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 8-bit signed int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getInt8(final Object self, final int byteOffset) {
+        try {
+            return getBuffer(self).get(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 8-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 8-bit unsigned int value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE)
+    public static int getUint8(final Object self, final Object byteOffset) {
+        try {
+            return (0xFF & getBuffer(self).get(JSType.toInt32(byteOffset)));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 8-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 8-bit unsigned int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getUint8(final Object self, final int byteOffset) {
+        try {
+            return (0xFF & getBuffer(self).get(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 16-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 16-bit signed int value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static int getInt16(final Object self, final Object byteOffset, final Object littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getShort(JSType.toInt32(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 16-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 16-bit signed int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getInt16(final Object self, final int byteOffset) {
+        try {
+            return getBuffer(self, false).getShort(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 16-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 16-bit signed int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getInt16(final Object self, final int byteOffset, final boolean littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getShort(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 16-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 16-bit unsigned int value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static int getUint16(final Object self, final Object byteOffset, final Object littleEndian) {
+        try {
+            return (int) (0xFFFF & getBuffer(self, littleEndian).getShort(JSType.toInt32(byteOffset)));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 16-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 16-bit unsigned int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getUint16(final Object self, final int byteOffset) {
+        try {
+            return (int) (0xFFFF & getBuffer(self, false).getShort(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 16-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 16-bit unsigned int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getUint16(final Object self, final int byteOffset, final boolean littleEndian) {
+        try {
+            return (int) (0xFFFF & getBuffer(self, littleEndian).getShort(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 32-bit signed int value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static int getInt32(final Object self, final Object byteOffset, final Object littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 32-bit signed int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getInt32(final Object self, final int byteOffset) {
+        try {
+            return getBuffer(self, false).getInt(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit signed int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 32-bit signed int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static int getInt32(final Object self, final int byteOffset, final boolean littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getInt(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 32-bit unsigned int value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static long getUint32(final Object self, final Object byteOffset, final Object littleEndian) {
+        try {
+            return (long) (0xFFFFFFFFL & getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset)));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 32-bit unsigned int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static long getUint32(final Object self, final int byteOffset) {
+        try {
+            return (long) (0xFFFFFFFFL & getBuffer(self, false).getInt(JSType.toInt32(byteOffset)));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit unsigned int from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 32-bit unsigned int value at the byteOffset
+     */
+    @SpecializedFunction
+    public static long getUint32(final Object self, final int byteOffset, final boolean littleEndian) {
+        try {
+            return (long) (0xFFFFFFFFL & getBuffer(self, littleEndian).getInt(JSType.toInt32(byteOffset)));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit float value from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 32-bit float value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static double getFloat32(final Object self, final Object byteOffset, final Object littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getFloat(JSType.toInt32(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit float value from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 32-bit float value at the byteOffset
+     */
+    @SpecializedFunction
+    public static double getFloat32(final Object self, final int byteOffset) {
+        try {
+            return getBuffer(self, false).getFloat(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 32-bit float value from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 32-bit float value at the byteOffset
+     */
+    @SpecializedFunction
+    public static double getFloat32(final Object self, final int byteOffset, final boolean littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getFloat(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 64-bit float value from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 64-bit float value at the byteOffset
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
+    public static double getFloat64(final Object self, final Object byteOffset, final Object littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getDouble(JSType.toInt32(byteOffset));
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 64-bit float value from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @return 64-bit float value at the byteOffset
+     */
+    @SpecializedFunction
+    public static double getFloat64(final Object self, final int byteOffset) {
+        try {
+            return getBuffer(self, false).getDouble(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Get 64-bit float value from given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param littleEndian (optional) flag indicating whether to read in little endian order
+     * @return 64-bit float value at the byteOffset
+     */
+    @SpecializedFunction
+    public static double getFloat64(final Object self, final int byteOffset, final boolean littleEndian) {
+        try {
+            return getBuffer(self, littleEndian).getDouble(byteOffset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    // Stores a value of the given type at the specified byte offset
+    // from the start of the view. There is no alignment constraint;
+    // multi-byte values may be stored at any offset.
+    //
+    // For multi-byte values, the optional littleEndian argument
+    // indicates whether the value should be stored in big-endian or
+    // little-endian byte order. If false or undefined, the value is
+    // stored in big-endian byte order.
+    //
+    // These methods raise an exception if they would write
+    // beyond the end of the view.
+
+    /**
+     * Set 8-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param value byte value to set
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setInt8(final Object self, final Object byteOffset, final Object value) {
+        try {
+            getBuffer(self).put(JSType.toInt32(byteOffset), (byte)JSType.toInt32(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 8-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to read from
+     * @param value byte value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setInt8(final Object self, final int byteOffset, final int value) {
+        try {
+            getBuffer(self).put(byteOffset, (byte)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 8-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value byte value to set
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setUint8(final Object self, final Object byteOffset, final Object value) {
+        try {
+            getBuffer(self).put(JSType.toInt32(byteOffset), (byte)JSType.toInt32(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 8-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value byte value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setUint8(final Object self, final int byteOffset, final int value) {
+        try {
+            getBuffer(self).put(byteOffset, (byte)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 16-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value short value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setInt16(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putShort(JSType.toInt32(byteOffset), (short)JSType.toInt32(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 16-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value short value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setInt16(final Object self, final int byteOffset, final int value) {
+        try {
+            getBuffer(self, false).putShort(byteOffset, (short)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 16-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value short value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setInt16(final Object self, final int byteOffset, final int value, final boolean littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putShort(byteOffset, (short)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 16-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value short value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setUint16(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putShort(JSType.toInt32(byteOffset), (short)JSType.toInt32(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 16-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value short value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setUint16(final Object self, final int byteOffset, final int value) {
+        try {
+            getBuffer(self, false).putShort(byteOffset, (short)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 16-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value short value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setUint16(final Object self, final int byteOffset, final int value, final boolean littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putShort(byteOffset, (short)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value int value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setInt32(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putInt(JSType.toInt32(byteOffset), (int)JSType.toInt32(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value int value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setInt32(final Object self, final int byteOffset, final int value) {
+        try {
+            getBuffer(self, false).putInt(byteOffset, value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit signed int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value int value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setInt32(final Object self, final int byteOffset, final int value, final boolean littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putInt(byteOffset, value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value int value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setUint32(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putInt(JSType.toInt32(byteOffset), (int)JSType.toUint32(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value int value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setUint32(final Object self, final int byteOffset, final long value) {
+        try {
+            getBuffer(self, false).putInt(byteOffset, (int)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit unsigned int at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value int value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setUint32(final Object self, final int byteOffset, final long value, final boolean littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putInt(byteOffset, (int)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit float at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value float value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setFloat32(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putFloat((int)JSType.toUint32(byteOffset), (float)JSType.toNumber(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit float at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value float value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setFloat32(final Object self, final int byteOffset, final double value) {
+        try {
+            getBuffer(self, false).putFloat(byteOffset, (float)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 32-bit float at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value float value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setFloat32(final Object self, final int byteOffset, final double value, final boolean littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putFloat(byteOffset, (float)value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 64-bit float at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value double value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
+    public static Object setFloat64(final Object self, final Object byteOffset, final Object value, final Object littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putDouble((int)JSType.toUint32(byteOffset), JSType.toNumber(value));
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 64-bit float at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value double value to set
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setFloat64(final Object self, final int byteOffset, final double value) {
+        try {
+            getBuffer(self, false).putDouble(byteOffset, value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    /**
+     * Set 64-bit float at the given byteOffset
+     *
+     * @param self DataView object
+     * @param byteOffset byte offset to write at
+     * @param value double value to set
+     * @param littleEndian (optional) flag indicating whether to write in little endian order
+     * @return undefined
+     */
+    @SpecializedFunction
+    public static Object setFloat64(final Object self, final int byteOffset, final double value, final boolean littleEndian) {
+        try {
+            getBuffer(self, littleEndian).putDouble(byteOffset, value);
+            return UNDEFINED;
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.offset");
+        }
+    }
+
+    // internals only below this point
+    private static ByteBuffer bufferFrom(final NativeArrayBuffer nab, final int offset) {
+        try {
+            return nab.getBuffer(offset);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.constructor.offset");
+        }
+    }
+
+    private static ByteBuffer bufferFrom(final NativeArrayBuffer nab, final int offset, final int length) {
+        try {
+            return nab.getBuffer(offset, length);
+        } catch (final IndexOutOfBoundsException ioe) {
+            throw rangeError(ioe, "dataview.constructor.offset");
+        }
+    }
+
+    private static NativeDataView checkSelf(final Object self) {
+        if (!(self instanceof NativeDataView)) {
+            throw typeError("not.an.arraybuffer", ScriptRuntime.safeToString(self));
+        }
+        return (NativeDataView)self;
+    }
+
+    private static ByteBuffer getBuffer(final Object self) {
+        return checkSelf(self).buf;
+    }
+
+    private static ByteBuffer getBuffer(final Object self, final Object littleEndian) {
+        return getBuffer(self, JSType.toBoolean(littleEndian));
+    }
+
+    private static ByteBuffer getBuffer(final Object self, final boolean littleEndian) {
+        return getBuffer(self).order(littleEndian? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
+    }
+}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java	Tue Mar 25 20:32:46 2014 -0400
@@ -114,10 +114,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private NativeDate(final double time, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         final ScriptEnvironment env = Global.getEnv();
@@ -127,7 +123,7 @@
     }
 
     NativeDate(final double time, final Global global) {
-        this(time, global.getDatePrototype(), getInitialMap());
+        this(time, global.getDatePrototype(), $nasgenmap$);
     }
 
     private NativeDate (final double time) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java	Tue Mar 25 20:32:46 2014 -0400
@@ -92,10 +92,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     @SuppressWarnings("LeakingThisInConstructor")
     private NativeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
@@ -108,7 +104,7 @@
     }
 
     NativeError(final Object msg, final Global global) {
-        this(msg, global.getErrorPrototype(), getInitialMap());
+        this(msg, global.getErrorPrototype(), $nasgenmap$);
     }
 
     private NativeError(final Object msg) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java	Tue Mar 25 20:32:46 2014 -0400
@@ -62,10 +62,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     @SuppressWarnings("LeakingThisInConstructor")
     private NativeEvalError(final Object msg, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
@@ -78,7 +74,7 @@
     }
 
     NativeEvalError(final Object msg, final Global global) {
-        this(msg, global.getEvalErrorPrototype(), getInitialMap());
+        this(msg, global.getEvalErrorPrototype(), $nasgenmap$);
     }
 
     private NativeEvalError(final Object msg) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Tue Mar 25 20:32:46 2014 -0400
@@ -146,10 +146,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     NativeJSAdapter(final Object overrides, final ScriptObject adaptee, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         this.adaptee = wrapAdaptee(adaptee);
@@ -577,7 +573,7 @@
             proto = global.getJSAdapterPrototype();
         }
 
-        return new NativeJSAdapter(overrides, (ScriptObject)adaptee, (ScriptObject)proto, getInitialMap());
+        return new NativeJSAdapter(overrides, (ScriptObject)adaptee, (ScriptObject)proto, $nasgenmap$);
     }
 
     @Override
@@ -622,7 +618,7 @@
         case "getMethod":
             final FindProperty find = adaptee.findProperty(__call__, true);
             if (find != null) {
-                final Object value = getObjectValue(find);
+                final Object value = find.getObjectValue();
                 if (value instanceof ScriptFunction) {
                     final ScriptFunctionImpl func = (ScriptFunctionImpl)value;
                     // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound
@@ -691,7 +687,7 @@
         final MethodType type = desc.getMethodType();
         if (findData != null) {
             final String name = desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null;
-            final Object value = getObjectValue(findData);
+            final Object value = findData.getObjectValue();
             if (value instanceof ScriptFunction) {
                 final ScriptFunction func = (ScriptFunction)value;
 
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Tue Mar 25 20:32:46 2014 -0400
@@ -60,17 +60,13 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private NativeJavaImporter(final Object[] args, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         this.args = args;
     }
 
     private NativeJavaImporter(final Object[] args, final Global global) {
-        this(args, global.getJavaImporterPrototype(), getInitialMap());
+        this(args, global.getJavaImporterPrototype(), $nasgenmap$);
     }
 
     private NativeJavaImporter(final Object[] args) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java	Tue Mar 25 20:32:46 2014 -0400
@@ -34,6 +34,7 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
 import java.text.NumberFormat;
 import java.util.Locale;
 import jdk.internal.dynalink.linker.GuardedInvocation;
@@ -57,7 +58,10 @@
 @ScriptClass("Number")
 public final class NativeNumber extends ScriptObject {
 
-    static final MethodHandle WRAPFILTER = findWrapFilter();
+    // Method handle to create an object wrapper for a primitive number
+    private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeNumber.class, Object.class));
+    // Method handle to retrieve the Number prototype object
+    private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
 
     /** ECMA 15.7.3.2 largest positive finite value */
     @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
@@ -86,10 +90,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private NativeNumber(final double value, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
         this.value = value;
@@ -98,7 +98,7 @@
     }
 
     NativeNumber(final double value, final Global global) {
-        this(value, global.getNumberPrototype(), getInitialMap());
+        this(value, global.getNumberPrototype(), $nasgenmap$);
     }
 
     private NativeNumber(final double value) {
@@ -322,7 +322,7 @@
      * @return Link to be invoked at call site.
      */
     public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
-        return PrimitiveLookup.lookupPrimitive(request, Number.class, new NativeNumber(((Number)receiver).doubleValue()), WRAPFILTER);
+        return PrimitiveLookup.lookupPrimitive(request, Number.class, new NativeNumber(((Number)receiver).doubleValue()), WRAPFILTER, PROTOFILTER);
     }
 
     @SuppressWarnings("unused")
@@ -330,6 +330,11 @@
         return new NativeNumber(((Number)receiver).doubleValue());
     }
 
+    @SuppressWarnings("unused")
+    private static Object protoFilter(final Object object) {
+        return Global.instance().getNumberPrototype();
+    }
+
     private static double getNumberValue(final Object self) {
         if (self instanceof Number) {
             return ((Number)self).doubleValue();
@@ -378,7 +383,7 @@
         return str;
     }
 
-    private static MethodHandle findWrapFilter() {
-        return MH.findStatic(MethodHandles.lookup(), NativeNumber.class, "wrapFilter", MH.type(NativeNumber.class, Object.class));
+    private static MethodHandle findOwnMH(final String name, final MethodType type) {
+        return MH.findStatic(MethodHandles.lookup(), NativeNumber.class, name, type);
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java	Tue Mar 25 20:32:46 2014 -0400
@@ -62,10 +62,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     @SuppressWarnings("LeakingThisInConstructor")
     private NativeRangeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
@@ -78,7 +74,7 @@
     }
 
     NativeRangeError(final Object msg, final Global global) {
-        this(msg, global.getRangeErrorPrototype(), getInitialMap());
+        this(msg, global.getRangeErrorPrototype(), $nasgenmap$);
     }
 
     private NativeRangeError(final Object msg) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java	Tue Mar 25 20:32:46 2014 -0400
@@ -62,10 +62,6 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     @SuppressWarnings("LeakingThisInConstructor")
     private NativeReferenceError(final Object msg, final ScriptObject proto, final PropertyMap map) {
         super(proto, map);
@@ -78,7 +74,7 @@
     }
 
     NativeReferenceError(final Object msg, final Global global) {
-        this(msg, global.getReferenceErrorPrototype(), getInitialMap());
+        this(msg, global.getReferenceErrorPrototype(), $nasgenmap$);
     }
 
     private NativeReferenceError(final Object msg) {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java	Tue Mar 25 20:32:46 2014 -0400
@@ -70,12 +70,8 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private NativeRegExp(final Global global) {
-        super(global.getRegExpPrototype(), getInitialMap());
+        super(global.getRegExpPrototype(), $nasgenmap$);
         this.globalObject = global;
     }
 
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java	Tue Mar 25 20:32:46 2014 -0400
@@ -53,12 +53,8 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     NativeRegExpExecResult(final RegExpResult result, final Global global) {
-        super(global.getArrayPrototype(), getInitialMap());
+        super(global.getArrayPrototype(), $nasgenmap$);
         setIsArray();
         this.setArray(ArrayData.allocate(result.getGroups().clone()));
         this.index = result.getIndex();
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java	Tue Mar 25 20:32:46 2014 -0400
@@ -32,6 +32,7 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
 import java.text.Collator;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -69,21 +70,20 @@
 
     private final CharSequence value;
 
-    static final MethodHandle WRAPFILTER = findWrapFilter();
+    // Method handle to create an object wrapper for a primitive string
+    private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeString.class, Object.class));
+    // Method handle to retrieve the String prototype object
+    private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
 
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     private NativeString(final CharSequence value) {
         this(value, Global.instance());
     }
 
     NativeString(final CharSequence value, final Global global) {
-        this(value, global.getStringPrototype(), getInitialMap());
+        this(value, global.getStringPrototype(), $nasgenmap$);
     }
 
     private NativeString(final CharSequence value, final ScriptObject proto, final PropertyMap map) {
@@ -1199,7 +1199,7 @@
      */
     public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
         final MethodHandle guard = NashornGuards.getInstanceOf2Guard(String.class, ConsString.class);
-        return PrimitiveLookup.lookupPrimitive(request, guard, new NativeString((CharSequence)receiver), WRAPFILTER);
+        return PrimitiveLookup.lookupPrimitive(request, guard, new NativeString((CharSequence)receiver), WRAPFILTER, PROTOFILTER);
     }
 
     @SuppressWarnings("unused")
@@ -1207,6 +1207,11 @@
         return new NativeString((CharSequence)receiver);
     }
 
+    @SuppressWarnings("unused")
+    private static Object protoFilter(final Object object) {
+        return Global.instance().getStringPrototype();
+    }
+
     private static CharSequence getCharSequence(final Object self) {
         if (self instanceof String || self instanceof ConsString) {
             return (CharSequence)self;
@@ -1254,7 +1259,7 @@
         return key >= 0 && key < value.length();
     }
 
-    private static MethodHandle findWrapFilter() {
-        return MH.findStatic(MethodHandles.lookup(), NativeString.class, "wrapFilter", MH.type(NativeString.class, Object.class));
+    private static MethodHandle findOwnMH(final String name, final MethodType type) {
+        return MH.findStatic(MethodHandles.lookup(), NativeString.class, name, type);
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java	Tue Mar 25 20:32:46 2014 -0400
@@ -62,13 +62,9 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     @SuppressWarnings("LeakingThisInConstructor")
     NativeSyntaxError(final Object msg, final Global global) {
-        super(global.getSyntaxErrorPrototype(), getInitialMap());
+        super(global.getSyntaxErrorPrototype(), $nasgenmap$);
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java	Tue Mar 25 20:32:46 2014 -0400
@@ -62,13 +62,9 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     @SuppressWarnings("LeakingThisInConstructor")
     NativeTypeError(final Object msg, final Global global) {
-        super(global.getTypeErrorPrototype(), getInitialMap());
+        super(global.getTypeErrorPrototype(), $nasgenmap$);
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java	Tue Mar 25 20:32:46 2014 -0400
@@ -61,13 +61,9 @@
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
 
-    static PropertyMap getInitialMap() {
-        return $nasgenmap$;
-    }
-
     @SuppressWarnings("LeakingThisInConstructor")
     NativeURIError(final Object msg, final Global global) {
-        super(global.getURIErrorPrototype(), getInitialMap());
+        super(global.getURIErrorPrototype(), $nasgenmap$);
         if (msg != UNDEFINED) {
             this.instMessage = JSType.toString(msg);
         } else {
--- a/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java	Tue Mar 25 20:32:46 2014 -0400
@@ -57,10 +57,6 @@
         map$ = PropertyMap.newMap(properties);
     }
 
-    static PropertyMap getInitialMap() {
-        return map$;
-    }
-
     private PrototypeObject(final Global global, final PropertyMap map) {
         super(global.getObjectPrototype(), map != map$? map.addAll(map$) : map$);
     }
--- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java	Tue Mar 25 20:32:46 2014 -0400
@@ -55,27 +55,11 @@
     // property map for non-strict, non-bound functions.
     private static final PropertyMap map$;
 
-    static PropertyMap getInitialMap() {
-        return map$;
-    }
-
-    static PropertyMap getInitialAnonymousMap() {
-        return AnonymousFunction.getInitialMap();
-    }
-
-    static PropertyMap getInitialStrictMap() {
-        return strictmodemap$;
-    }
-
-    static PropertyMap getInitialBoundMap() {
-        return boundfunctionmap$;
-    }
-
     // 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) {
-        super(name, invokeHandle, getInitialMap(), null, specs, false, true, true);
+        super(name, invokeHandle, map$, null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
         init(global);
     }
 
@@ -92,7 +76,7 @@
     }
 
     private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs, final Global global) {
-        super(name, invokeHandle, map.addAll(getInitialMap()), null, specs, false, true, true);
+        super(name, invokeHandle, map.addAll(map$), null, specs, ScriptFunctionData.IS_BUILTIN_CONSTRUCTOR);
         init(global);
     }
 
@@ -109,8 +93,8 @@
         this(name, invokeHandle, map, specs, Global.instance());
     }
 
-    private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor, final Global global) {
-        super(name, methodHandle, getMap(global, isStrict), scope, specs, isStrict, isBuiltin, isConstructor);
+    private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final int flags, final Global global) {
+        super(name, methodHandle, getMap(isStrict(flags)), scope, specs, flags);
         init(global);
     }
 
@@ -121,16 +105,14 @@
      * @param methodHandle handle for invocation
      * @param scope scope object
      * @param specs specialized versions of this method, if available, null otherwise
-     * @param isStrict are we in strict mode
-     * @param isBuiltin is this a built-in function
-     * @param isConstructor can the function be used as a constructor (most can; some built-ins are restricted).
+     * @param flags {@link ScriptFunctionData} flags
      */
-    ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
-        this(name, methodHandle, scope, specs, isStrict, isBuiltin, isConstructor, Global.instance());
+    ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final int flags) {
+        this(name, methodHandle, scope, specs, flags, Global.instance());
     }
 
     private ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope, final Global global) {
-        super(data, getMap(global, data.isStrict()), scope);
+        super(data, getMap(data.isStrict()), scope);
         init(global);
     }
 
@@ -150,7 +132,7 @@
      * @param global the global object
      */
     ScriptFunctionImpl(final ScriptFunctionData data, final Global global) {
-        super(data, getInitialBoundMap(), null);
+        super(data, boundfunctionmap$, null);
         init(global);
     }
 
@@ -173,9 +155,13 @@
         return newMap;
     }
 
+    private static boolean isStrict(final int flags) {
+        return (flags & ScriptFunctionData.IS_STRICT) != 0;
+    }
+
     // Choose the map based on strict mode!
-    private static PropertyMap getMap(final Global global, final boolean strict) {
-        return strict ? getInitialStrictMap() : getInitialMap();
+    private static PropertyMap getMap(final boolean strict) {
+        return strict ? strictmodemap$ : map$;
     }
 
     private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
@@ -189,12 +175,8 @@
     private static class AnonymousFunction extends ScriptFunctionImpl {
         private static final PropertyMap anonmap$ = PropertyMap.newMap();
 
-        static PropertyMap getInitialMap() {
-            return anonmap$;
-        }
-
         AnonymousFunction(final Global global) {
-            super("", GlobalFunctions.ANONYMOUS, getInitialAnonymousMap(), null);
+            super("", GlobalFunctions.ANONYMOUS, anonmap$, null);
         }
     }
 
@@ -211,7 +193,7 @@
      * @return new ScriptFunction
      */
     static ScriptFunction makeFunction(final String name, final MethodHandle methodHandle, final MethodHandle[] specs) {
-        final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, false, true, false);
+        final ScriptFunctionImpl func = new ScriptFunctionImpl(name, methodHandle, null, specs, ScriptFunctionData.IS_BUILTIN);
         func.setPrototype(UNDEFINED);
         // Non-constructor built-in functions do not have "prototype" property
         func.deleteOwnProperty(func.getMap().findProperty("prototype"));
--- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java	Tue Mar 25 20:32:46 2014 -0400
@@ -1799,6 +1799,7 @@
         case THIS:
             final String name = type.getName();
             next();
+            lc.setFlag(lc.getCurrentFunction(), FunctionNode.USES_THIS);
             return new IdentNode(primaryToken, finish, name);
         case IDENT:
             final IdentNode ident = getIdent();
--- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Tue Mar 25 20:32:46 2014 -0400
@@ -141,10 +141,12 @@
     private Class<?> currentType;
 
     /**
-     * Delegate constructor. This is used when adding properties to the Global scope, which
-     * is necessary for outermost levels in a script (the ScriptObject is represented by
-     * a JO-prefixed ScriptObject class, but the properties need to be in the Global scope
-     * and are thus rebound with that as receiver
+     * Delegate constructor for bound properties. This is used for properties created by
+     * {@link ScriptRuntime#mergeScope} and the Nashorn {@code Object.bindProperties} method.
+     * The former is used to add a script's defined globals to the current global scope while
+     * still storing them in a JO-prefixed ScriptObject class.
+     *
+     * <p>All properties created by this constructor have the {@link #IS_BOUND} flag set.</p>
      *
      * @param property  accessor property to rebind
      * @param delegate  delegate object to rebind receiver to
@@ -157,6 +159,8 @@
         this.objectGetter    = bindTo(property.ensureObjectGetter(), delegate);
         this.objectSetter    = bindTo(property.ensureObjectSetter(), delegate);
 
+        // Properties created this way are bound to a delegate
+        this.flags |= IS_BOUND;
         setCurrentType(property.getCurrentType());
     }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java	Tue Mar 25 20:32:46 2014 -0400
@@ -36,6 +36,8 @@
 import java.io.PrintWriter;
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
 import java.lang.reflect.Modifier;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -46,6 +48,7 @@
 import java.security.Permissions;
 import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
 import jdk.internal.org.objectweb.asm.ClassReader;
@@ -153,16 +156,19 @@
     /** Is Context global debug mode enabled ? */
     public static final boolean DEBUG = Options.getBooleanProperty("nashorn.debug");
 
-    private static final ThreadLocal<ScriptObject> currentGlobal = new ThreadLocal<>();
+    private static final ThreadLocal<Global> currentGlobal = new ThreadLocal<>();
+
+    // class cache
+    private ClassCache classCache;
 
     /**
      * Get the current global scope
      * @return the current global scope
      */
-    public static ScriptObject getGlobal() {
+    public static Global getGlobal() {
         // This class in a package.access protected package.
         // Trusted code only can call this method.
-        return getGlobalTrusted();
+        return currentGlobal.get();
     }
 
     /**
@@ -171,10 +177,19 @@
      */
     public static void setGlobal(final ScriptObject global) {
         if (global != null && !(global instanceof Global)) {
-            throw new IllegalArgumentException("global is not an instance of Global!");
+            throw new IllegalArgumentException("not a global!");
         }
+        setGlobal((Global)global);
+    }
 
-        setGlobalTrusted(global);
+    /**
+     * Set the current global scope
+     * @param global the global scope
+     */
+    public static void setGlobal(final Global global) {
+        // This class in a package.access protected package.
+        // Trusted code only can call this method.
+        currentGlobal.set(global);
     }
 
     /**
@@ -195,7 +210,7 @@
      * @return error writer of the current context
      */
     public static PrintWriter getCurrentErr() {
-        final ScriptObject global = getGlobalTrusted();
+        final ScriptObject global = getGlobal();
         return (global != null)? global.getContext().getErr() : new PrintWriter(System.err);
     }
 
@@ -348,6 +363,11 @@
             this.classPathLoader = null;
         }
 
+        final int cacheSize = env._class_cache_size;
+        if (cacheSize > 0) {
+            classCache = new ClassCache(cacheSize);
+        }
+
         // print version info if asked.
         if (env._version) {
             getErr().println("nashorn " + Version.version());
@@ -395,7 +415,7 @@
      * @return the property map of the current global scope
      */
     public static PropertyMap getGlobalMap() {
-        return Context.getGlobalTrusted().getMap();
+        return Context.getGlobal().getMap();
     }
 
     /**
@@ -425,7 +445,7 @@
         final String  file       = (location == UNDEFINED || location == null) ? "<eval>" : location.toString();
         final Source  source     = new Source(file, string);
         final boolean directEval = location != UNDEFINED; // is this direct 'eval' call or indirectly invoked eval?
-        final ScriptObject global = Context.getGlobalTrusted();
+        final Global  global = Context.getGlobal();
 
         ScriptObject scope = initialScope;
 
@@ -457,7 +477,7 @@
         // in the caller's environment. A new environment is created!
         if (strictFlag) {
             // Create a new scope object
-            final ScriptObject strictEvalScope = ((GlobalObject)global).newObject();
+            final ScriptObject strictEvalScope = global.newObject();
 
             // bless it as a "scope"
             strictEvalScope.setIsScope();
@@ -582,10 +602,10 @@
      * @throws IOException if source cannot be found or loaded
      */
     public Object loadWithNewGlobal(final Object from, final Object...args) throws IOException {
-        final ScriptObject oldGlobal = getGlobalTrusted();
-        final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() {
+        final Global oldGlobal = getGlobal();
+        final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction<Global>() {
            @Override
-           public ScriptObject run() {
+           public Global run() {
                try {
                    return newGlobal();
                } catch (final RuntimeException e) {
@@ -598,17 +618,17 @@
         }, CREATE_GLOBAL_ACC_CTXT);
         // initialize newly created Global instance
         initGlobal(newGlobal);
-        setGlobalTrusted(newGlobal);
+        setGlobal(newGlobal);
 
         final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY :  ScriptObjectMirror.wrapArray(args, oldGlobal);
-        newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped), env._strict);
+        newGlobal.put("arguments", newGlobal.wrapAsObject(wrapped), env._strict);
 
         try {
             // wrap objects from newGlobal's world as mirrors - but if result
             // is from oldGlobal's world, unwrap it!
             return ScriptObjectMirror.unwrap(ScriptObjectMirror.wrap(load(newGlobal, from), newGlobal), oldGlobal);
         } finally {
-            setGlobalTrusted(oldGlobal);
+            setGlobal(oldGlobal);
         }
     }
 
@@ -637,7 +657,7 @@
      * Checks that the given Class can be accessed from no permissions context.
      *
      * @param clazz Class object
-     * @throw SecurityException if not accessible
+     * @throws SecurityException if not accessible
      */
     public static void checkPackageAccess(final Class<?> clazz) {
         final SecurityManager sm = System.getSecurityManager();
@@ -654,12 +674,12 @@
      * Checks that the given package name can be accessed from no permissions context.
      *
      * @param pkgName package name
-     * @throw SecurityException if not accessible
+     * @throws SecurityException if not accessible
      */
     public static void checkPackageAccess(final String pkgName) {
         final SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
-            checkPackageAccess(sm, pkgName.endsWith(".")? pkgName : pkgName + ".");
+            checkPackageAccess(sm, pkgName.endsWith(".") ? pkgName : pkgName + ".");
         }
     }
 
@@ -783,7 +803,7 @@
      *
      * @return the initialized global scope object.
      */
-    public ScriptObject createGlobal() {
+    public Global createGlobal() {
         return initGlobal(newGlobal());
     }
 
@@ -791,7 +811,7 @@
      * Create a new uninitialized global scope object
      * @return the global script object
      */
-    public ScriptObject newGlobal() {
+    public Global newGlobal() {
         return new Global(this);
     }
 
@@ -801,20 +821,16 @@
      * @param global the global
      * @return the initialized global scope object.
      */
-    public ScriptObject initGlobal(final ScriptObject global) {
-        if (! (global instanceof GlobalObject)) {
-            throw new IllegalArgumentException("not a global object!");
-        }
-
+    public Global initGlobal(final Global global) {
         // Need only minimal global object, if we are just compiling.
         if (!env._compile_only) {
-            final ScriptObject oldGlobal = Context.getGlobalTrusted();
+            final Global oldGlobal = Context.getGlobal();
             try {
-                Context.setGlobalTrusted(global);
+                Context.setGlobal(global);
                 // initialize global scope with builtin global objects
-                ((GlobalObject)global).initBuiltinObjects();
+                global.initBuiltinObjects();
             } finally {
-                Context.setGlobalTrusted(oldGlobal);
+                Context.setGlobal(oldGlobal);
             }
         }
 
@@ -822,30 +838,15 @@
     }
 
     /**
-     * Trusted variants - package-private
-     */
-
-    /**
-     * Return the current global scope
-     * @return current global scope
+     * Trusted variant - package-private
      */
-    static ScriptObject getGlobalTrusted() {
-        return currentGlobal.get();
-    }
-
-    /**
-     * Set the current global scope
-     */
-    static void setGlobalTrusted(ScriptObject global) {
-         currentGlobal.set(global);
-    }
 
     /**
      * Return the current global's context
      * @return current global's context
      */
     static Context getContextTrusted() {
-        return Context.getGlobalTrusted().getContext();
+        return ((ScriptObject)Context.getGlobal()).getContext();
     }
 
     /**
@@ -914,7 +915,7 @@
         }
 
         // Package as a JavaScript function and pass function back to shell.
-        return ((GlobalObject)Context.getGlobalTrusted()).newScriptFunction(RUN_SCRIPT.symbolName(), runMethodHandle, scope, strict);
+        return Context.getGlobal().newScriptFunction(RUN_SCRIPT.symbolName(), runMethodHandle, scope, strict);
     }
 
     private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) {
@@ -925,16 +926,10 @@
         // start with no errors, no warnings.
         errMan.reset();
 
-        GlobalObject global = null;
-        Class<?> script;
-
-        if (env._class_cache_size > 0) {
-            global = (GlobalObject)Context.getGlobalTrusted();
-            script = global.findCachedClass(source);
-            if (script != null) {
-                Compiler.LOG.fine("Code cache hit for ", source, " avoiding recompile.");
-                return script;
-            }
+        Class<?> script = findCachedClass(source);
+        if (script != null) {
+            Compiler.LOG.fine("Code cache hit for ", source, " avoiding recompile.");
+            return script;
         }
 
         final FunctionNode functionNode = new Parser(env, source, errMan, strict).parse();
@@ -963,10 +958,7 @@
 
         final FunctionNode newFunctionNode = compiler.compile(functionNode);
         script = compiler.install(newFunctionNode);
-
-        if (global != null) {
-            global.cacheClass(source, script);
-        }
+        cacheClass(source, script);
 
         return script;
     }
@@ -988,4 +980,60 @@
     private long getUniqueScriptId() {
         return uniqueScriptId.getAndIncrement();
     }
+
+    /**
+     * Cache for compiled script classes.
+     */
+    @SuppressWarnings("serial")
+    private static class ClassCache extends LinkedHashMap<Source, ClassReference> {
+        private final int size;
+        private final ReferenceQueue<Class<?>> queue;
+
+        ClassCache(int size) {
+            super(size, 0.75f, true);
+            this.size = size;
+            this.queue = new ReferenceQueue<>();
+        }
+
+        void cache(final Source source, final Class<?> clazz) {
+            put(source, new ClassReference(clazz, queue, source));
+        }
+
+        @Override
+        protected boolean removeEldestEntry(final Map.Entry<Source, ClassReference> eldest) {
+            return size() > size;
+        }
+
+        @Override
+        public ClassReference get(Object key) {
+            for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) {
+                remove(ref.source);
+            }
+            return super.get(key);
+        }
+
+    }
+
+    private static class ClassReference extends SoftReference<Class<?>> {
+        private final Source source;
+
+        ClassReference(final Class<?> clazz, final ReferenceQueue<Class<?>> queue, final Source source) {
+            super(clazz, queue);
+            this.source = source;
+        }
+    }
+
+    // Class cache management
+    private Class<?> findCachedClass(final Source source) {
+        ClassReference ref = classCache == null ? null : classCache.get(source);
+        return ref != null ? ref.get() : null;
+    }
+
+    private void cacheClass(final Source source, final Class<?> clazz) {
+        if (classCache != null) {
+            classCache.cache(source, clazz);
+        }
+    }
+
+
 }
--- a/nashorn/src/jdk/nashorn/internal/runtime/DebuggerSupport.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/DebuggerSupport.java	Tue Mar 25 20:32:46 2014 -0400
@@ -75,7 +75,7 @@
      * @return context global.
      */
     static Object getGlobal() {
-        return Context.getGlobalTrusted();
+        return Context.getGlobal();
     }
 
     /**
@@ -87,7 +87,7 @@
      * @return Result of eval as string, or, an exception or null depending on returnException.
      */
     static Object eval(final ScriptObject scope, final Object self, final String string, final boolean returnException) {
-        final ScriptObject global = Context.getGlobalTrusted();
+        final ScriptObject global = Context.getGlobal();
         final ScriptObject initialScope = scope != null ? scope : global;
         final Object callThis = self != null ? self : global;
         final Context context = global.getContext();
--- a/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java	Tue Mar 25 20:32:46 2014 -0400
@@ -31,6 +31,7 @@
 import jdk.nashorn.api.scripting.NashornException;
 import jdk.nashorn.internal.scripts.JS;
 import jdk.nashorn.internal.codegen.CompilerConstants;
+import jdk.nashorn.internal.objects.Global;
 
 /**
  * Helper class to throw various standard "ECMA error" exceptions such as Error, ReferenceError, TypeError etc.
@@ -66,7 +67,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException asEcmaException(final ParserException e) {
-        return asEcmaException(Context.getGlobalTrusted(), e);
+        return asEcmaException(Context.getGlobal(), e);
     }
 
     /**
@@ -78,11 +79,11 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException asEcmaException(final ScriptObject global, final ParserException e) {
+    public static ECMAException asEcmaException(final Global global, final ParserException e) {
         final JSErrorType errorType = e.getErrorType();
         assert errorType != null : "error type for " + e + " was null";
 
-        final GlobalObject globalObj = (GlobalObject)global;
+        final Global globalObj    = global;
         final String       msg    = e.getMessage();
 
         // translate to ECMAScript Error object using error type
@@ -116,7 +117,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException syntaxError(final String msgId, final String... args) {
-        return syntaxError(Context.getGlobalTrusted(), msgId, args);
+        return syntaxError(Context.getGlobal(), msgId, args);
     }
 
     /**
@@ -128,7 +129,7 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException syntaxError(final ScriptObject global, final String msgId, final String... args) {
+    public static ECMAException syntaxError(final Global global, final String msgId, final String... args) {
         return syntaxError(global, null, msgId, args);
     }
 
@@ -142,7 +143,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException syntaxError(final Throwable cause, final String msgId, final String... args) {
-        return syntaxError(Context.getGlobalTrusted(), cause, msgId, args);
+        return syntaxError(Context.getGlobal(), cause, msgId, args);
     }
 
     /**
@@ -155,9 +156,9 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException syntaxError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException syntaxError(final Global global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("syntax.error." + msgId, args);
-        return error(((GlobalObject)global).newSyntaxError(msg), cause);
+        return error(global.newSyntaxError(msg), cause);
     }
 
     /**
@@ -169,7 +170,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException typeError(final String msgId, final String... args) {
-        return typeError(Context.getGlobalTrusted(), msgId, args);
+        return typeError(Context.getGlobal(), msgId, args);
     }
 
     /**
@@ -181,7 +182,7 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException typeError(final ScriptObject global, final String msgId, final String... args) {
+    public static ECMAException typeError(final Global global, final String msgId, final String... args) {
         return typeError(global, null, msgId, args);
     }
 
@@ -195,7 +196,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException typeError(final Throwable cause, final String msgId, final String... args) {
-        return typeError(Context.getGlobalTrusted(), cause, msgId, args);
+        return typeError(Context.getGlobal(), cause, msgId, args);
     }
 
     /**
@@ -208,9 +209,9 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException typeError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException typeError(final Global global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("type.error." + msgId, args);
-        return error(((GlobalObject)global).newTypeError(msg), cause);
+        return error(global.newTypeError(msg), cause);
     }
 
     /**
@@ -222,7 +223,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException rangeError(final String msgId, final String... args) {
-        return rangeError(Context.getGlobalTrusted(), msgId, args);
+        return rangeError(Context.getGlobal(), msgId, args);
     }
 
     /**
@@ -234,7 +235,7 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException rangeError(final ScriptObject global, final String msgId, final String... args) {
+    public static ECMAException rangeError(final Global global, final String msgId, final String... args) {
         return rangeError(global, null, msgId, args);
     }
 
@@ -248,7 +249,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException rangeError(final Throwable cause, final String msgId, final String... args) {
-        return rangeError(Context.getGlobalTrusted(), cause, msgId, args);
+        return rangeError(Context.getGlobal(), cause, msgId, args);
     }
 
     /**
@@ -261,9 +262,9 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException rangeError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException rangeError(final Global global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("range.error." + msgId, args);
-        return error(((GlobalObject)global).newRangeError(msg), cause);
+        return error(global.newRangeError(msg), cause);
     }
 
     /**
@@ -275,7 +276,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException referenceError(final String msgId, final String... args) {
-        return referenceError(Context.getGlobalTrusted(), msgId, args);
+        return referenceError(Context.getGlobal(), msgId, args);
     }
 
     /**
@@ -287,7 +288,7 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException referenceError(final ScriptObject global, final String msgId, final String... args) {
+    public static ECMAException referenceError(final Global global, final String msgId, final String... args) {
         return referenceError(global, null, msgId, args);
     }
 
@@ -301,7 +302,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException referenceError(final Throwable cause, final String msgId, final String... args) {
-        return referenceError(Context.getGlobalTrusted(), cause, msgId, args);
+        return referenceError(Context.getGlobal(), cause, msgId, args);
     }
 
     /**
@@ -314,9 +315,9 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException referenceError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException referenceError(final Global global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("reference.error." + msgId, args);
-        return error(((GlobalObject)global).newReferenceError(msg), cause);
+        return error(global.newReferenceError(msg), cause);
     }
 
     /**
@@ -328,7 +329,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException uriError(final String msgId, final String... args) {
-        return uriError(Context.getGlobalTrusted(), msgId, args);
+        return uriError(Context.getGlobal(), msgId, args);
     }
 
     /**
@@ -340,7 +341,7 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException uriError(final ScriptObject global, final String msgId, final String... args) {
+    public static ECMAException uriError(final Global global, final String msgId, final String... args) {
         return uriError(global, null, msgId, args);
     }
 
@@ -354,7 +355,7 @@
      * @return the resulting {@link ECMAException}
      */
     public static ECMAException uriError(final Throwable cause, final String msgId, final String... args) {
-        return uriError(Context.getGlobalTrusted(), cause, msgId, args);
+        return uriError(Context.getGlobal(), cause, msgId, args);
     }
 
     /**
@@ -367,9 +368,9 @@
      *
      * @return the resulting {@link ECMAException}
      */
-    public static ECMAException uriError(final ScriptObject global, final Throwable cause, final String msgId, final String... args) {
+    public static ECMAException uriError(final Global global, final Throwable cause, final String msgId, final String... args) {
         final String msg = getMessage("uri.error." + msgId, args);
-        return error(((GlobalObject)global).newURIError(msg), cause);
+        return error(global.newURIError(msg), cause);
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java	Tue Mar 25 20:32:46 2014 -0400
@@ -38,31 +38,27 @@
     /**
      * Constructor - used for bind
      *
-     * @param name          name
-     * @param arity         arity
-     * @param functions     precompiled code
-     * @param isStrict      strict
-     * @param isBuiltin     builtin
-     * @param isConstructor constructor
+     * @param name      name
+     * @param arity     arity
+     * @param functions precompiled code
+     * @param flags     {@link ScriptFunctionData} flags
      */
-    FinalScriptFunctionData(final String name, int arity, CompiledFunctions functions, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
-        super(name, arity, isStrict, isBuiltin, isConstructor);
+    FinalScriptFunctionData(final String name, final int arity, final CompiledFunctions functions, final int flags) {
+        super(name, arity, flags);
         code.addAll(functions);
     }
 
     /**
-     * Constructor - used from ScriptFunction. This assumes that we have code alraedy for the
+     * Constructor - used from ScriptFunction. This assumes that we have code already for the
      * method (typically a native method) and possibly specializations.
      *
-     * @param name           name
-     * @param mh             method handle for generic version of method
-     * @param specs          specializations
-     * @param isStrict       strict
-     * @param isBuiltin      builtin
-     * @param isConstructor  constructor
+     * @param name  name
+     * @param mh    method handle for generic version of method
+     * @param specs specializations
+     * @param flags {@link ScriptFunctionData} flags
      */
-    FinalScriptFunctionData(final String name, final MethodHandle mh, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
-        super(name, arity(mh), isStrict, isBuiltin, isConstructor);
+    FinalScriptFunctionData(final String name, final MethodHandle mh, final MethodHandle[] specs, final int flags) {
+        super(name, arity(mh), flags);
 
         addInvoker(mh);
         if (specs != null) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java	Tue Mar 25 20:32:07 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,244 +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.runtime;
-
-import java.lang.invoke.MethodHandle;
-import java.util.concurrent.Callable;
-import jdk.internal.dynalink.linker.GuardedInvocation;
-import jdk.internal.dynalink.linker.LinkRequest;
-import jdk.nashorn.internal.runtime.linker.InvokeByName;
-
-/**
- * Runtime interface to the global scope objects.
- */
-
-public interface GlobalObject {
-    /**
-     * Is this global of the given Context?
-     * @param ctxt the context
-     * @return true if this global belongs to the given Context
-     */
-    public boolean isOfContext(final Context ctxt);
-
-    /**
-     * Does this global belong to a strict Context?
-     * @return true if this global belongs to a strict Context
-     */
-    public boolean isStrictContext();
-
-    /**
-     * Initialize standard builtin objects like "Object", "Array", "Function" etc.
-     * as well as our extension builtin objects like "Java", "JSAdapter" as properties
-     * of the global scope object.
-     */
-    public void initBuiltinObjects();
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newScriptFunction(String, MethodHandle, ScriptObject, boolean)}
-     *
-     * @param name   function name
-     * @param handle invocation handle for function
-     * @param scope  the scope
-     * @param strict are we in strict mode
-     *
-     * @return new script function
-     */
-   public ScriptFunction newScriptFunction(String name, MethodHandle handle, ScriptObject scope, boolean strict);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#wrapAsObject(Object)}
-     *
-     * @param obj object to wrap
-     * @return    wrapped object
-     */
-   public Object wrapAsObject(Object obj);
-
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#primitiveLookup(LinkRequest, Object)}
-     *
-     * @param request the link request for the dynamic call site.
-     * @param self     self reference
-     *
-     * @return guarded invocation
-     */
-   public GuardedInvocation primitiveLookup(LinkRequest request, Object self);
-
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newObject()}
-     *
-     * @return the new ScriptObject
-     */
-   public ScriptObject newObject();
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#isError(ScriptObject)}
-     *
-     * @param sobj to check if it is an error object
-     * @return true if error object
-     */
-   public boolean isError(ScriptObject sobj);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the error
-     */
-   public ScriptObject newError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newEvalError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the eval error
-     */
-   public ScriptObject newEvalError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newRangeError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the range error
-     */
-   public ScriptObject newRangeError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newReferenceError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the reference error
-     */
-   public ScriptObject newReferenceError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newSyntaxError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the syntax error
-     */
-   public ScriptObject newSyntaxError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newTypeError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the type error
-     */
-   public ScriptObject newTypeError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newURIError(String)}
-     *
-     * @param msg the error message
-     *
-     * @return the new ScriptObject representing the URI error
-     */
-    public ScriptObject newURIError(String msg);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newGenericDescriptor(boolean, boolean)}
-     *
-     * @param configurable is the described property configurable
-     * @param enumerable   is the described property enumerable
-     *
-     * @return property descriptor
-     */
-    public PropertyDescriptor newGenericDescriptor(boolean configurable, boolean enumerable);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newDataDescriptor(Object, boolean, boolean, boolean)}
-     *
-     * @param value        data value
-     * @param configurable is the described property configurable
-     * @param enumerable   is the described property enumerable
-     * @param writable     is the described property writable
-     *
-     * @return property descriptor
-     */
-    public PropertyDescriptor newDataDescriptor(Object value, boolean configurable, boolean enumerable, boolean writable);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#newAccessorDescriptor(Object, Object, boolean, boolean)}
-     *
-     * @param get          property getter, or null if none
-     * @param set          property setter, or null if none
-     * @param configurable is the described property configurable
-     * @param enumerable   is the described property enumerable
-     *
-     * @return property descriptor
-     */
-    public PropertyDescriptor newAccessorDescriptor(Object get, Object set, boolean configurable, boolean enumerable);
-
-    /**
-     * Wrapper for {@link jdk.nashorn.internal.objects.Global#getDefaultValue(ScriptObject, Class)}
-     *
-     * @param sobj     script object
-     * @param typeHint type hint
-     *
-     * @return default value
-     */
-    public Object getDefaultValue(ScriptObject sobj, Class<?> typeHint);
-
-    /**
-     * Find the compiled Class for the given script source, if available
-     *
-     * @param source Source object of the script
-     * @return compiled Class object or null
-     */
-    public Class<?> findCachedClass(Source source);
-
-    /**
-     * Put the Source associated Class object in the Source-to-Class cache
-     *
-     * @param source Source of the script
-     * @param clazz compiled Class object for the source
-     */
-    public void cacheClass(Source source, Class<?> clazz);
-
-    /**
-     * Get cached InvokeByName object for the given key
-     * @param key key to be associated with InvokeByName object
-     * @param creator if InvokeByName is absent 'creator' is called to make one (lazy init)
-     * @return InvokeByName object associated with the key.
-     */
-    public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator);
-
-    /**
-     * Get cached dynamic method handle for the given key
-     * @param key key to be associated with dynamic method handle
-     * @param creator if method handle is absent 'creator' is called to make one (lazy init)
-     * @return dynamic method handle associated with the key.
-     */
-    public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator);
-}
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Tue Mar 25 20:32:46 2014 -0400
@@ -33,6 +33,7 @@
 import jdk.nashorn.internal.ir.ObjectNode;
 import jdk.nashorn.internal.ir.PropertyNode;
 import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.parser.JSONParser;
 import jdk.nashorn.internal.parser.TokenType;
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
@@ -47,7 +48,7 @@
     private static final Object REVIVER_INVOKER = new Object();
 
     private static MethodHandle getREVIVER_INVOKER() {
-        return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(REVIVER_INVOKER,
+        return Context.getGlobal().getDynamicInvoker(REVIVER_INVOKER,
                 new Callable<MethodHandle>() {
                     @Override
                     public MethodHandle call() {
@@ -88,7 +89,7 @@
             throw ECMAErrors.syntaxError(e, "invalid.json", e.getMessage());
         }
 
-        final ScriptObject global = Context.getGlobalTrusted();
+        final Global global = Context.getGlobal();
         Object unfiltered = convertNode(global, node);
         return applyReviver(global, unfiltered, reviver);
     }
@@ -98,10 +99,10 @@
     // parse helpers
 
     // apply 'reviver' function if available
-    private static Object applyReviver(final ScriptObject global, final Object unfiltered, final Object reviver) {
+    private static Object applyReviver(final Global global, final Object unfiltered, final Object reviver) {
         if (reviver instanceof ScriptFunction) {
-            assert global instanceof GlobalObject;
-            final ScriptObject root = ((GlobalObject)global).newObject();
+            assert global instanceof Global;
+            final ScriptObject root = global.newObject();
             root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
             return walk(root, "", (ScriptFunction)reviver);
         }
@@ -138,8 +139,8 @@
     }
 
     // Converts IR node to runtime value
-    private static Object convertNode(final ScriptObject global, final Node node) {
-        assert global instanceof GlobalObject;
+    private static Object convertNode(final Global global, final Node node) {
+        assert global instanceof Global;
 
         if (node instanceof LiteralNode) {
             // check for array literal
@@ -157,7 +158,7 @@
                     for (final Node elem : elements) {
                         values[index++] = JSType.toNumber(convertNode(global, elem));
                     }
-                    return ((GlobalObject)global).wrapAsObject(values);
+                    return global.wrapAsObject(values);
                 }
 
                 final Object[] values = new Object[elements.length];
@@ -167,14 +168,14 @@
                     values[index++] = convertNode(global, elem);
                 }
 
-                return ((GlobalObject)global).wrapAsObject(values);
+                return global.wrapAsObject(values);
             }
 
             return ((LiteralNode<?>)node).getValue();
 
         } else if (node instanceof ObjectNode) {
             final ObjectNode   objNode  = (ObjectNode) node;
-            final ScriptObject object   = ((GlobalObject)global).newObject();
+            final ScriptObject object   = global.newObject();
 
             for (final PropertyNode pNode: objNode.getElements()) {
                 final Node         valueNode = pNode.getValue();
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java	Tue Mar 25 20:32:46 2014 -0400
@@ -36,6 +36,7 @@
 import jdk.internal.dynalink.beans.StaticClass;
 import jdk.nashorn.api.scripting.JSObject;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.parser.Lexer;
 import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
@@ -852,7 +853,7 @@
      * @return the wrapped object
      */
     public static Object toScriptObject(final Object obj) {
-        return toScriptObject(Context.getGlobalTrusted(), obj);
+        return toScriptObject(Context.getGlobal(), obj);
     }
 
     /**
@@ -865,7 +866,7 @@
      *
      * @return the wrapped object
      */
-    public static Object toScriptObject(final ScriptObject global, final Object obj) {
+    public static Object toScriptObject(final Global global, final Object obj) {
         if (nullOrUndefined(obj)) {
             throw typeError(global, "not.an.object", ScriptRuntime.safeToString(obj));
         }
@@ -874,7 +875,7 @@
             return obj;
         }
 
-        return ((GlobalObject)global).wrapAsObject(obj);
+        return global.wrapAsObject(obj);
     }
 
     /**
@@ -984,7 +985,7 @@
         if (obj instanceof ScriptObject) {
             if (safe) {
                 final ScriptObject sobj = (ScriptObject)obj;
-                final GlobalObject gobj = (GlobalObject)Context.getGlobalTrusted();
+                final Global gobj = Context.getGlobal();
                 return gobj.isError(sobj) ?
                     ECMAException.safeToString(sobj) :
                     sobj.safeToString();
--- a/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java	Tue Mar 25 20:32:46 2014 -0400
@@ -34,6 +34,7 @@
 import java.util.concurrent.Callable;
 import jdk.nashorn.api.scripting.JSObject;
 import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.InvokeByName;
 
@@ -54,7 +55,7 @@
     // These add to the back and front of the list
     private static final Object PUSH    = new Object();
     private static InvokeByName getPUSH() {
-        return ((GlobalObject)Context.getGlobal()).getInvokeByName(PUSH,
+        return Context.getGlobal().getInvokeByName(PUSH,
                 new Callable<InvokeByName>() {
                     @Override
                     public InvokeByName call() {
@@ -65,7 +66,7 @@
 
     private static final Object UNSHIFT = new Object();
     private static InvokeByName getUNSHIFT() {
-        return ((GlobalObject)Context.getGlobal()).getInvokeByName(UNSHIFT,
+        return Context.getGlobal().getInvokeByName(UNSHIFT,
                 new Callable<InvokeByName>() {
                     @Override
                     public InvokeByName call() {
@@ -77,7 +78,7 @@
     // These remove from the back and front of the list
     private static final Object POP = new Object();
     private static InvokeByName getPOP() {
-        return ((GlobalObject)Context.getGlobal()).getInvokeByName(POP,
+        return Context.getGlobal().getInvokeByName(POP,
                 new Callable<InvokeByName>() {
                     @Override
                     public InvokeByName call() {
@@ -88,7 +89,7 @@
 
     private static final Object SHIFT = new Object();
     private static InvokeByName getSHIFT() {
-        return ((GlobalObject)Context.getGlobal()).getInvokeByName(SHIFT,
+        return Context.getGlobal().getInvokeByName(SHIFT,
                 new Callable<InvokeByName>() {
                     @Override
                     public InvokeByName call() {
@@ -100,7 +101,7 @@
     // These insert and remove in the middle of the list
     private static final Object SPLICE_ADD = new Object();
     private static InvokeByName getSPLICE_ADD() {
-        return ((GlobalObject)Context.getGlobal()).getInvokeByName(SPLICE_ADD,
+        return Context.getGlobal().getInvokeByName(SPLICE_ADD,
                 new Callable<InvokeByName>() {
                     @Override
                     public InvokeByName call() {
@@ -111,7 +112,7 @@
 
     private static final Object SPLICE_REMOVE = new Object();
     private static InvokeByName getSPLICE_REMOVE() {
-        return ((GlobalObject)Context.getGlobal()).getInvokeByName(SPLICE_REMOVE,
+        return  Context.getGlobal().getInvokeByName(SPLICE_REMOVE,
                 new Callable<InvokeByName>() {
                     @Override
                     public InvokeByName call() {
--- a/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java	Tue Mar 25 20:32:46 2014 -0400
@@ -35,7 +35,6 @@
 import jdk.internal.dynalink.support.Guards;
 import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
-import jdk.nashorn.internal.objects.NativeJava;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Function;
 
@@ -52,7 +51,7 @@
  * var ArrayList = java.util.ArrayList
  * var list = new ArrayList
  * </pre>
- * You can also use {@link NativeJava#type(Object, Object)} to access Java classes. These two statements are mostly
+ * You can also use {@link jdk.nashorn.internal.objects.NativeJava#type(Object, Object)} to access Java classes. These two statements are mostly
  * equivalent:
  * <pre>
  * var listType1 = java.util.ArrayList
--- a/nashorn/src/jdk/nashorn/internal/runtime/ParserException.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ParserException.java	Tue Mar 25 20:32:46 2014 -0400
@@ -26,6 +26,7 @@
 package jdk.nashorn.internal.runtime;
 
 import jdk.nashorn.api.scripting.NashornException;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.parser.Token;
 
 /**
@@ -110,7 +111,7 @@
      * Throw this {@code ParserException} as one of the 7 native JavaScript errors
      * @param global global scope object
      */
-    public void throwAsEcmaException(final ScriptObject global) {
+    public void throwAsEcmaException(final Global global) {
         throw ECMAErrors.asEcmaException(global, this);
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/runtime/Property.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Property.java	Tue Mar 25 20:32:46 2014 -0400
@@ -84,9 +84,13 @@
     /** Can this property be undefined? */
     public static final int CAN_BE_UNDEFINED = 1 << 8;
 
-    /* Is this a function declaration property ? */
+    /** Is this a function declaration property ? */
     public static final int IS_FUNCTION_DECLARATION = 1 << 9;
 
+    /** 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 << 10;
+
     /** Property key. */
     private final String key;
 
@@ -252,6 +256,16 @@
     }
 
     /**
+     * Is this property bound to a receiver? If this method returns {@code true} get and set operations
+     * will be delegated to a statically bound object instead of the object passed as parameter.
+     *
+     * @return true if this is a bound property
+     */
+    public boolean isBound() {
+        return (flags & IS_BOUND) == IS_BOUND;
+    }
+
+    /**
      * Does this property use any slots in the spill array described in
      * {@link Property#isSpill}? In that case how many. Currently a property
      * only uses max one spill slot, but this may change in future representations
--- a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Tue Mar 25 20:32:46 2014 -0400
@@ -103,9 +103,7 @@
     public RecompilableScriptFunctionData(final FunctionNode functionNode, final CodeInstaller<ScriptEnvironment> installer, final String allocatorClassName, final PropertyMap allocatorMap) {
         super(functionName(functionNode),
               functionNode.getParameters().size(),
-              functionNode.isStrict(),
-              false,
-              true);
+              getFlags(functionNode));
 
         this.functionNode       = functionNode;
         this.source             = functionNode.getSource();
@@ -129,10 +127,11 @@
         final StringBuilder sb = new StringBuilder();
 
         if (source != null) {
-            sb.append(source.getName())
-                .append(':')
-                .append(functionNode.getLineNumber())
-                .append(' ');
+            sb.append(source.getName());
+            if (functionNode != null) {
+                sb.append(':').append(functionNode.getLineNumber());
+            }
+            sb.append(' ');
         }
 
         return sb.toString() + super.toString();
@@ -159,6 +158,20 @@
         return Token.toDesc(TokenType.FUNCTION, position, length);
     }
 
+    private static int getFlags(final FunctionNode functionNode) {
+        int flags = IS_CONSTRUCTOR;
+        if (functionNode.isStrict()) {
+            flags |= IS_STRICT;
+        }
+        if (functionNode.needsCallee()) {
+            flags |= NEEDS_CALLEE;
+        }
+        if (functionNode.usesThis() || functionNode.hasEval()) {
+            flags |= USES_THIS;
+        }
+        return flags;
+    }
+
     @Override
     ScriptObject allocate(final PropertyMap map) {
         try {
@@ -182,41 +195,42 @@
         return allocatorMap;
     }
 
+
+    @Override
+    protected void ensureCompiled() {
+        if (functionNode != null && functionNode.isLazy()) {
+            Compiler.LOG.info("Trampoline hit: need to do lazy compilation of '", functionNode.getName(), "'");
+            final Compiler compiler = new Compiler(installer);
+            functionNode = compiler.compile(functionNode);
+            assert !functionNode.isLazy();
+            compiler.install(functionNode);
+            flags = getFlags(functionNode);
+        }
+    }
+
     @Override
     protected synchronized void ensureCodeGenerated() {
-         if (!code.isEmpty()) {
-             return; // nothing to do, we have code, at least some.
-         }
+        if (!code.isEmpty()) {
+            return; // nothing to do, we have code, at least some.
+        }
 
-         if (functionNode.isLazy()) {
-             Compiler.LOG.info("Trampoline hit: need to do lazy compilation of '", functionNode.getName(), "'");
-             final Compiler compiler = new Compiler(installer);
-             functionNode = compiler.compile(functionNode);
-             assert !functionNode.isLazy();
-             compiler.install(functionNode);
+        ensureCompiled();
+
+        /*
+         * We can't get to this program point unless we have bytecode, either from
+         * eager compilation or from running a lazy compile on the lines above
+         */
 
-             /*
-              * We don't need to update any flags - varArgs and needsCallee are instrincic
-              * in the function world we need to get a destination node from the compile instead
-              * and replace it with our function node. TODO
-              */
-         }
+        assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " " + functionNode.getState() + " " + Debug.id(functionNode);
+
+        // code exists - look it up and add it into the automatically sorted invoker list
+        addCode(functionNode);
 
-         /*
-          * We can't get to this program point unless we have bytecode, either from
-          * eager compilation or from running a lazy compile on the lines above
-          */
-
-         assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " " + functionNode.getState() + " " + Debug.id(functionNode);
-
-         // code exists - look it up and add it into the automatically sorted invoker list
-         addCode(functionNode);
-
-         if (! functionNode.canSpecialize()) {
-             // allow GC to claim IR stuff that is not needed anymore
-             functionNode = null;
-             installer = null;
-         }
+        if (! functionNode.canSpecialize()) {
+            // allow GC to claim IR stuff that is not needed anymore
+            functionNode = null;
+            installer = null;
+        }
     }
 
     private MethodHandle addCode(final FunctionNode fn) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Tue Mar 25 20:32:46 2014 -0400
@@ -38,6 +38,7 @@
 import jdk.internal.dynalink.linker.LinkRequest;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
 import jdk.nashorn.internal.lookup.MethodHandleFactory;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 import jdk.nashorn.internal.runtime.linker.NashornGuards;
 
@@ -66,6 +67,8 @@
 
     private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", Object.class, Object.class);
 
+    private static final MethodHandle GLOBALFILTER = findOwnMH("globalFilter", Object.class, Object.class);
+
     /** method handle to scope getter for this ScriptFunction */
     public static final Call GET_SCOPE = virtualCallNoLookup(ScriptFunction.class, "getScope", ScriptObject.class);
 
@@ -91,9 +94,7 @@
      * @param map           property map
      * @param scope         scope
      * @param specs         specialized version of this function - other method handles
-     * @param strict        is this a strict mode function?
-     * @param builtin       is this a built in function?
-     * @param isConstructor is this a constructor?
+     * @param flags         {@link ScriptFunctionData} flags
      */
     protected ScriptFunction(
             final String name,
@@ -101,11 +102,9 @@
             final PropertyMap map,
             final ScriptObject scope,
             final MethodHandle[] specs,
-            final boolean strict,
-            final boolean builtin,
-            final boolean isConstructor) {
+            final int flags) {
 
-        this(new FinalScriptFunctionData(name, methodHandle, specs, strict, builtin, isConstructor), map, scope);
+        this(new FinalScriptFunctionData(name, methodHandle, specs, flags), map, scope);
     }
 
     /**
@@ -477,7 +476,14 @@
         if (obj instanceof ScriptObject || !ScriptFunctionData.isPrimitiveThis(obj)) {
             return obj;
         }
-        return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(obj);
+        return Context.getGlobal().wrapAsObject(obj);
+    }
+
+
+    @SuppressWarnings("unused")
+    private static Object globalFilter(final Object object) {
+        // replace whatever we get with the current global object
+        return Context.getGlobal();
     }
 
     /**
@@ -495,11 +501,11 @@
     @Override
     protected GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final LinkRequest request) {
         final MethodType type = desc.getMethodType();
+        final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
 
         if (request.isCallSiteUnstable()) {
-            // (this, callee, args...) => (this, callee, args[])
-            final MethodHandle collector = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class,
-                    type.parameterCount() - 2);
+            // (callee, this, args...) => (callee, this, args[])
+            final MethodHandle collector = MH.asCollector(ScriptRuntime.APPLY.methodHandle(), Object[].class, type.parameterCount() - 2);
 
             // If call site is statically typed to take a ScriptFunction, we don't need a guard, otherwise we need a
             // generic "is this a ScriptFunction?" guard.
@@ -510,17 +516,12 @@
         MethodHandle boundHandle;
         MethodHandle guard = null;
 
-        final boolean scopeCall = NashornCallSiteDescriptor.isScope(desc);
-
         if (data.needsCallee()) {
             final MethodHandle callHandle = getBestInvoker(type, request.getArguments());
-            if (scopeCall) {
+            if (scopeCall && needsWrappedThis()) {
                 // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
-                // (callee, this, args...) => (callee, args...)
-                boundHandle = MH.insertArguments(callHandle, 1, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
-                // (callee, args...) => (callee, [this], args...)
-                boundHandle = MH.dropArguments(boundHandle, 1, Object.class);
-
+                // (callee, this, args...) => (callee, [this], args...)
+                boundHandle = MH.filterArguments(callHandle, 1, GLOBALFILTER);
             } else {
                 // It's already (callee, this, args...), just what we need
                 boundHandle = callHandle;
@@ -531,12 +532,12 @@
                 // NOTE: the only built-in named "extend" is NativeJava.extend. As a special-case we're binding the
                 // current lookup as its "this" so it can do security-sensitive creation of adapter classes.
                 boundHandle = MH.dropArguments(MH.bindTo(callHandle, desc.getLookup()), 0, Object.class, Object.class);
-            } else if (scopeCall) {
+            } else if (scopeCall && needsWrappedThis()) {
                 // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
-                // (this, args...) => (args...)
-                boundHandle = MH.bindTo(callHandle, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
-                // (args...) => ([callee], [this], args...)
-                boundHandle = MH.dropArguments(boundHandle, 0, Object.class, Object.class);
+                // (this, args...) => ([this], args...)
+                boundHandle = MH.filterArguments(callHandle, 0, GLOBALFILTER);
+                // ([this], args...) => ([callee], [this], args...)
+                boundHandle = MH.dropArguments(boundHandle, 0, Object.class);
             } else {
                 // (this, args...) => ([callee], this, args...)
                 boundHandle = MH.dropArguments(callHandle, 0, Object.class);
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Tue Mar 25 20:32:46 2014 -0400
@@ -32,6 +32,7 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
 
 /**
@@ -47,33 +48,44 @@
     /** All versions of this function that have been generated to code */
     protected final CompiledFunctions code;
 
-    private int arity;
-
-    private final boolean isStrict;
+    /** Function flags */
+    protected int flags;
 
-    private final boolean isBuiltin;
-
-    private final boolean isConstructor;
+    private int arity;
 
     private static final MethodHandle NEWFILTER     = findOwnMH("newFilter", Object.class, Object.class, Object.class);
     private static final MethodHandle BIND_VAR_ARGS = findOwnMH("bindVarArgs", Object[].class, Object[].class, Object[].class);
 
+    /** Is this a strict mode function? */
+    public static final int IS_STRICT      = 1 << 0;
+    /** Is this a built-in function? */
+    public static final int IS_BUILTIN     = 1 << 1;
+    /** Is this a constructor function? */
+    public static final int IS_CONSTRUCTOR = 1 << 2;
+    /** Does this function expect a callee argument? */
+    public static final int NEEDS_CALLEE   = 1 << 3;
+    /** Does this function make use of the this-object argument? */
+    public static final int USES_THIS      = 1 << 4;
+
+    /** Flag for strict or built-in functions */
+    public static final int IS_STRICT_OR_BUILTIN = IS_STRICT | IS_BUILTIN;
+    /** Flag for built-in constructors */
+    public static final int IS_BUILTIN_CONSTRUCTOR = IS_BUILTIN | IS_CONSTRUCTOR;
+    /** Flag for strict constructors */
+    public static final int IS_STRICT_CONSTRUCTOR = IS_STRICT | IS_CONSTRUCTOR;
+
     /**
      * Constructor
      *
      * @param name          script function name
      * @param arity         arity
-     * @param isStrict      is the function strict
-     * @param isBuiltin     is the function built in
-     * @param isConstructor is the function a constructor
+     * @param flags         the function flags
      */
-    ScriptFunctionData(final String name, final int arity, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
-        this.name          = name;
-        this.arity         = arity;
-        this.code          = new CompiledFunctions();
-        this.isStrict      = isStrict;
-        this.isBuiltin     = isBuiltin;
-        this.isConstructor = isConstructor;
+    ScriptFunctionData(final String name, final int arity, final int flags) {
+        this.name  = name;
+        this.arity = arity;
+        this.code  = new CompiledFunctions();
+        this.flags = flags;
     }
 
     final int getArity() {
@@ -105,21 +117,21 @@
      * @return true if strict, false otherwise
      */
     public boolean isStrict() {
-        return isStrict;
+        return (flags & IS_STRICT) != 0;
     }
 
     boolean isBuiltin() {
-        return isBuiltin;
+        return (flags & IS_BUILTIN) != 0;
     }
 
     boolean isConstructor() {
-        return isConstructor;
+        return (flags & IS_CONSTRUCTOR) != 0;
     }
 
     boolean needsCallee() {
-        // we don't know if we need a callee or not unless we are generated
-        ensureCodeGenerated();
-        return code.needsCallee();
+        // we don't know if we need a callee or not unless code has been compiled
+        ensureCompiled();
+        return (flags & NEEDS_CALLEE) != 0;
     }
 
     /**
@@ -128,7 +140,7 @@
      * @return true if this argument must be an object
      */
     boolean needsWrappedThis() {
-        return !isStrict && !isBuiltin;
+        return (flags & USES_THIS) != 0 && (flags & IS_STRICT_OR_BUILTIN) == 0;
     }
 
     String toSource() {
@@ -202,6 +214,15 @@
     }
 
     /**
+     * If we can have lazy code generation, this is a hook to ensure that the code has been compiled.
+     * This does not guarantee the code been installed in this {@code ScriptFunctionData} instance;
+     * use {@link #ensureCodeGenerated()} to install the actual method handles.
+     */
+    protected void ensureCompiled() {
+        //empty
+    }
+
+    /**
      * Return a generic Object/Object invoker for this method. It will ensure code
      * is generated, get the most generic of all versions of this function and adapt it
      * to Objects.
@@ -259,6 +280,8 @@
 
         final Object[] allArgs = args == null ? ScriptRuntime.EMPTY_ARRAY : args;
         final int length = args == null ? 0 : args.length;
+        // Clear the callee and this flags
+        final int boundFlags = flags & ~NEEDS_CALLEE & ~USES_THIS;
 
         CompiledFunctions boundList = new CompiledFunctions();
         if (code.size() == 1) {
@@ -273,8 +296,7 @@
             boundList.add(bind(inv, fn, self, allArgs));
         }
 
-        ScriptFunctionData boundData = new FinalScriptFunctionData(name, arity == -1 ? -1 : Math.max(0, arity - length), boundList, isStrict(), isBuiltin(), isConstructor());
-        return boundData;
+        return new FinalScriptFunctionData(name, arity == -1 ? -1 : Math.max(0, arity - length), boundList, boundFlags);
     }
 
     /**
@@ -351,11 +373,11 @@
     private Object convertThisObject(final Object thiz) {
         if (!(thiz instanceof ScriptObject) && needsWrappedThis()) {
             if (JSType.nullOrUndefined(thiz)) {
-                return Context.getGlobalTrusted();
+                return Context.getGlobal();
             }
 
             if (isPrimitiveThis(thiz)) {
-                return ((GlobalObject)Context.getGlobalTrusted()).wrapAsObject(thiz);
+                return Context.getGlobal().wrapAsObject(thiz);
             }
         }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java	Tue Mar 25 20:32:46 2014 -0400
@@ -66,6 +66,7 @@
 import jdk.nashorn.internal.lookup.MethodHandleFactory;
 import jdk.nashorn.internal.objects.AccessorPropertyDescriptor;
 import jdk.nashorn.internal.objects.DataPropertyDescriptor;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.arrays.ArrayData;
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
@@ -131,7 +132,8 @@
 
     static final MethodHandle GETPROTO           = findOwnMH("getProto", ScriptObject.class);
     static final MethodHandle SETPROTOCHECK      = findOwnMH("setProtoCheck", void.class, Object.class);
-    static final MethodHandle MEGAMORPHIC_GET    = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class);
+    static final MethodHandle MEGAMORPHIC_GET    = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class, boolean.class);
+    static final MethodHandle GLOBALFILTER       = findOwnMH("globalFilter", Object.class, Object.class);
 
     static final MethodHandle SETFIELD           = findOwnMH("setField",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
     static final MethodHandle SETSPILL           = findOwnMH("setSpill",         void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class);
@@ -225,6 +227,7 @@
             final Property oldProp = newMap.findProperty(key);
             if (oldProp == null) {
                 if (property instanceof UserAccessorProperty) {
+                    // Note: we copy accessor functions to this object which is semantically different from binding.
                     final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
                     newMap = newMap.addPropertyNoHistory(prop);
                 } else {
@@ -322,18 +325,18 @@
       * @return property descriptor
       */
     public final PropertyDescriptor toPropertyDescriptor() {
-        final GlobalObject global = (GlobalObject) Context.getGlobalTrusted();
+        final Global global = Context.getGlobal();
 
         final PropertyDescriptor desc;
         if (isDataDescriptor()) {
             if (has(SET) || has(GET)) {
-                throw typeError((ScriptObject)global, "inconsistent.property.descriptor");
+                throw typeError(global, "inconsistent.property.descriptor");
             }
 
             desc = global.newDataDescriptor(UNDEFINED, false, false, false);
         } else if (isAccessorDescriptor()) {
             if (has(VALUE) || has(WRITABLE)) {
-                throw typeError((ScriptObject)global, "inconsistent.property.descriptor");
+                throw typeError(global, "inconsistent.property.descriptor");
             }
 
             desc = global.newAccessorDescriptor(UNDEFINED, UNDEFINED, false, false);
@@ -352,7 +355,7 @@
      *
      * @return property descriptor
      */
-    public static PropertyDescriptor toPropertyDescriptor(final ScriptObject global, final Object obj) {
+    public static PropertyDescriptor toPropertyDescriptor(final Global global, final Object obj) {
         if (obj instanceof ScriptObject) {
             return ((ScriptObject)obj).toPropertyDescriptor();
         }
@@ -371,7 +374,7 @@
     public Object getOwnPropertyDescriptor(final String key) {
         final Property property = getMap().findProperty(key);
 
-        final GlobalObject global = (GlobalObject)Context.getGlobalTrusted();
+        final Global global = Context.getGlobal();
 
         if (property != null) {
             final ScriptFunction get   = property.getGetterFunction(this);
@@ -436,7 +439,7 @@
      * @return true if property was successfully defined
      */
     public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
-        final ScriptObject       global  = Context.getGlobalTrusted();
+        final Global             global  = Context.getGlobal();
         final PropertyDescriptor desc    = toPropertyDescriptor(global, propertyDesc);
         final Object             current = getOwnPropertyDescriptor(key);
         final String             name    = JSType.toString(key);
@@ -634,7 +637,7 @@
         final int propFlags = Property.toFlags(pdesc);
 
         if (pdesc.type() == PropertyDescriptor.GENERIC) {
-            final GlobalObject global = (GlobalObject) Context.getGlobalTrusted();
+            final Global global = Context.getGlobal();
             final PropertyDescriptor dDesc = global.newDataDescriptor(UNDEFINED, false, false, false);
 
             dDesc.fillFrom((ScriptObject)pdesc);
@@ -975,17 +978,6 @@
     }
 
     /**
-      * Get the object value of a property
-      *
-      * @param find {@link FindProperty} lookup result
-      *
-      * @return the value of the property
-      */
-    protected static Object getObjectValue(final FindProperty find) {
-        return find.getObjectValue();
-    }
-
-    /**
      * Return methodHandle of value function for call.
      *
      * @param find      data from find property.
@@ -995,7 +987,7 @@
      * @return value of property as a MethodHandle or null.
      */
     protected MethodHandle getCallMethodHandle(final FindProperty find, final MethodType type, final String bindName) {
-        return getCallMethodHandle(getObjectValue(find), type, bindName);
+        return getCallMethodHandle(find.getObjectValue(), type, bindName);
     }
 
     /**
@@ -1019,7 +1011,7 @@
      * @return Value of property.
      */
     public final Object getWithProperty(final Property property) {
-        return getObjectValue(new FindProperty(this, this, property));
+        return new FindProperty(this, this, property).getObjectValue();
     }
 
     /**
@@ -1158,7 +1150,7 @@
             }
             setProto((ScriptObject)newProto);
         } else {
-            final ScriptObject global = Context.getGlobalTrusted();
+            final Global global = Context.getGlobal();
             final Object  newProtoObject = JSType.toScriptObject(global, newProto);
 
             if (newProtoObject instanceof ScriptObject) {
@@ -1248,11 +1240,11 @@
      * @return the default value
      */
     public Object getDefaultValue(final Class<?> typeHint) {
-        // We delegate to GlobalObject, as the implementation uses dynamic call sites to invoke object's "toString" and
+        // We delegate to Global, as the implementation uses dynamic call sites to invoke object's "toString" and
         // "valueOf" methods, and in order to avoid those call sites from becoming megamorphic when multiple contexts
         // are being executed in a long-running program, we move the code and their associated dynamic call sites
         // (Global.TO_STRING and Global.VALUE_OF) into per-context code.
-        return ((GlobalObject)Context.getGlobalTrusted()).getDefaultValue(this, typeHint);
+        return Context.getGlobal().getDefaultValue(this, typeHint);
     }
 
     /**
@@ -1740,7 +1732,7 @@
     protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
         final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
         if (request.isCallSiteUnstable() || hasWithScope()) {
-            return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator));
+            return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator), isScope() && NashornCallSiteDescriptor.isScope(desc));
         }
 
         final FindProperty find = findProperty(name, true);
@@ -1765,9 +1757,8 @@
         final Property property = find.getProperty();
         methodHandle = find.getGetter(returnType);
 
-        final boolean noGuard = ObjectClassGenerator.OBJECT_FIELDS_ONLY && NashornCallSiteDescriptor.isFastScope(desc) && !property.canChangeType();
-        // getMap() is fine as we have the prototype switchpoint depending on where the property was found
-        final MethodHandle guard = noGuard ? null : NashornGuards.getMapGuard(getMap());
+        // Get the appropriate guard for this callsite and property.
+        final MethodHandle guard = NashornGuards.getGuard(this, property, desc);
         final ScriptObject owner = find.getOwner();
 
         if (methodHandle != null) {
@@ -1777,31 +1768,32 @@
             }
 
             if (!property.hasGetterFunction(owner)) {
-                // If not a scope bind to actual prototype as changing prototype will change the property map.
-                // For scopes we install a filter that replaces the self object with the prototype owning the property.
-                methodHandle = isScope() ?
-                        addProtoFilter(methodHandle, find.getProtoChainLength()) :
-                        bindTo(methodHandle, owner);
+                // Add a filter that replaces the self object with the prototype owning the property.
+                methodHandle = addProtoFilter(methodHandle, find.getProtoChainLength());
             }
-            return new GuardedInvocation(methodHandle, noGuard ? null : getProtoSwitchPoint(name, owner), guard);
+            return new GuardedInvocation(methodHandle, guard == null ? null : getProtoSwitchPoint(name, owner), guard);
         }
 
         assert !NashornCallSiteDescriptor.isFastScope(desc);
         return new GuardedInvocation(Lookup.emptyGetter(returnType), getProtoSwitchPoint(name, owner), guard);
     }
 
-    private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) {
-        final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod);
+    private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name,
+                                                              final boolean isMethod, final boolean isScope) {
+        final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod, isScope);
         final MethodHandle guard = getScriptObjectGuard(desc.getMethodType());
         return new GuardedInvocation(invoker, guard);
     }
 
     @SuppressWarnings("unused")
-    private Object megamorphicGet(final String key, final boolean isMethod) {
+    private Object megamorphicGet(final String key, final boolean isMethod, final boolean isScope) {
         final FindProperty find = findProperty(key, true);
 
         if (find != null) {
-            return getObjectValue(find);
+            return find.getObjectValue();
+        }
+        if (isScope) {
+            throw referenceError("not.defined", key);
         }
 
         return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key);
@@ -1996,6 +1988,15 @@
         }
     }
 
+    @SuppressWarnings("unused")
+    private static Object globalFilter(final Object object) {
+        ScriptObject sobj = (ScriptObject) object;
+        while (sobj != null && !(sobj instanceof Global)) {
+            sobj = sobj.getProto();
+        }
+        return sobj;
+    }
+
     private static GuardedInvocation findMegaMorphicSetMethod(final CallSiteDescriptor desc, final String name) {
         final MethodType type = desc.getMethodType().insertParameterTypes(1, Object.class);
         final GuardedInvocation inv = findSetIndexMethod(type, NashornCallSiteDescriptor.isStrict(desc));
@@ -2041,7 +2042,7 @@
             return noSuchProperty(desc, request);
         }
 
-        final Object value = getObjectValue(find);
+        final Object value = find.getObjectValue();
         if (! (value instanceof ScriptFunction)) {
             return createEmptyGetter(desc, name);
         }
@@ -2067,7 +2068,7 @@
         final boolean scopeAccess = isScope() && NashornCallSiteDescriptor.isScope(desc);
 
         if (find != null) {
-            final Object   value        = getObjectValue(find);
+            final Object   value        = find.getObjectValue();
             ScriptFunction func         = null;
             MethodHandle   methodHandle = null;
 
@@ -2102,7 +2103,7 @@
         final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);
 
         if (find != null) {
-            final Object func = getObjectValue(find);
+            final Object func = find.getObjectValue();
 
             if (func instanceof ScriptFunction) {
                 return ScriptRuntime.apply((ScriptFunction)func, this, name);
@@ -2124,7 +2125,7 @@
             return invokeNoSuchProperty(name);
         }
 
-        final Object value = getObjectValue(find);
+        final Object value = find.getObjectValue();
         if (! (value instanceof ScriptFunction)) {
             return UNDEFINED;
         }
@@ -2664,7 +2665,7 @@
                     final FindProperty find = object.findProperty(key, false, false, this);
 
                     if (find != null) {
-                        return getObjectValue(find);
+                        return find.getObjectValue();
                     }
                 }
 
@@ -2682,7 +2683,7 @@
             final FindProperty find = findProperty(key, true);
 
             if (find != null) {
-                return getObjectValue(find);
+                return find.getObjectValue();
             }
         }
 
@@ -2823,7 +2824,15 @@
                 throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
             }
         } else {
-            spill(key, value);
+            ScriptObject sobj = this;
+            // undefined scope properties are set in the global object.
+            if (isScope()) {
+                while (sobj != null && !(sobj instanceof Global)) {
+                    sobj = sobj.getProto();
+                }
+                assert sobj != null : "no parent global object in scope";
+            }
+            sobj.spill(key, value);
         }
     }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Tue Mar 25 20:32:46 2014 -0400
@@ -474,7 +474,7 @@
      * @return {@link WithObject} that is the new scope
      */
     public static ScriptObject openWith(final ScriptObject scope, final Object expression) {
-        final ScriptObject global = Context.getGlobalTrusted();
+        final Global global = Context.getGlobal();
         if (expression == UNDEFINED) {
             throw typeError(global, "cant.apply.with.to.undefined");
         } else if (expression == null) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Tue Mar 25 20:32:46 2014 -0400
@@ -31,7 +31,6 @@
 import java.lang.invoke.MethodHandle;
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.GuardedInvocation;
-import jdk.nashorn.internal.codegen.ObjectClassGenerator;
 import jdk.nashorn.internal.lookup.Lookup;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 import jdk.nashorn.internal.runtime.linker.NashornGuards;
@@ -104,21 +103,9 @@
          * @return the composed guarded invocation that represents the dynamic setter method for the property.
          */
         GuardedInvocation createGuardedInvocation() {
-            return new GuardedInvocation(methodHandle, getGuard());
-        }
-
-        private MethodHandle getGuard() {
-            return needsNoGuard() ? null : NashornGuards.getMapGuard(getMap());
+            return new GuardedInvocation(methodHandle, NashornGuards.getGuard(sobj, property, desc));
         }
 
-        private boolean needsNoGuard() {
-            return NashornCallSiteDescriptor.isFastScope(desc) &&
-                    (ObjectClassGenerator.OBJECT_FIELDS_ONLY || isPropertyTypeStable());
-        }
-
-        private boolean isPropertyTypeStable() {
-            return property == null || !property.canChangeType();
-        }
     }
 
     private SetMethod createSetMethod() {
@@ -153,10 +140,7 @@
 
         final MethodHandle boundHandle;
         if (!property.hasSetterFunction(find.getOwner()) && find.isInherited()) {
-            // Bind or add prototype filter depending on whether this is a scope object.
-            boundHandle = sobj.isScope() ?
-                    ScriptObject.addProtoFilter(methodHandle, find.getProtoChainLength()):
-                    ScriptObject.bindTo(methodHandle, find.getOwner());
+            boundHandle = ScriptObject.addProtoFilter(methodHandle, find.getProtoChainLength());
         } else {
             boundHandle = methodHandle;
         }
@@ -164,8 +148,8 @@
     }
 
     private SetMethod createGlobalPropertySetter() {
-        final ScriptObject global = Context.getGlobalTrusted();
-        return new SetMethod(ScriptObject.bindTo(global.addSpill(getName()), global), null);
+        final ScriptObject global = Context.getGlobal();
+        return new SetMethod(MH.filterArguments(global.addSpill(getName()), 0, ScriptObject.GLOBALFILTER), null);
     }
 
     private SetMethod createNewPropertySetter() {
--- a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Tue Mar 25 20:32:46 2014 -0400
@@ -34,6 +34,7 @@
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 
 import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
+import jdk.nashorn.internal.objects.Global;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 
@@ -73,7 +74,7 @@
 
     private static MethodHandle getINVOKE_UA_GETTER() {
 
-        return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(INVOKE_UA_GETTER,
+        return Context.getGlobal().getDynamicInvoker(INVOKE_UA_GETTER,
                 new Callable<MethodHandle>() {
                     @Override
                     public MethodHandle call() {
@@ -86,7 +87,7 @@
     /** Dynamic invoker for setter */
     private static Object INVOKE_UA_SETTER = new Object();
     private static MethodHandle getINVOKE_UA_SETTER() {
-        return ((GlobalObject)Context.getGlobal()).getDynamicInvoker(INVOKE_UA_SETTER,
+        return Context.getGlobal().getDynamicInvoker(INVOKE_UA_SETTER,
                 new Callable<MethodHandle>() {
                     @Override
                     public MethodHandle call() {
--- a/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java	Tue Mar 25 20:32:46 2014 -0400
@@ -88,6 +88,11 @@
 
     @Override
     public GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request) {
+        if (request.isCallSiteUnstable()) {
+            // Fall back to megamorphic invocation which performs a complete lookup each time without further relinking.
+            return super.lookup(desc, request);
+        }
+
         // With scopes can never be observed outside of Nashorn code, so all call sites that can address it will of
         // necessity have a Nashorn descriptor - it is safe to cast.
         final NashornCallSiteDescriptor ndesc = (NashornCallSiteDescriptor)desc;
@@ -265,7 +270,7 @@
     }
 
     private static MethodHandle filter(final MethodHandle mh, final MethodHandle filter) {
-        return MH.filterArguments(mh, 0, filter);
+        return MH.filterArguments(mh, 0, filter.asType(filter.type().changeReturnType(mh.type().parameterType(0))));
     }
 
     /**
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Tue Mar 25 20:32:46 2014 -0400
@@ -27,7 +27,7 @@
 
 import java.lang.invoke.MethodHandle;
 import java.nio.ByteBuffer;
-import jdk.nashorn.internal.runtime.GlobalObject;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
 
@@ -399,7 +399,7 @@
      *
      * @return property descriptor for element
      */
-    public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
+    public PropertyDescriptor getDescriptor(final Global global, final int index) {
         return global.newDataDescriptor(getObject(index), true, true, true);
     }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ByteBufferArrayData.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ByteBufferArrayData.java	Tue Mar 25 20:32:46 2014 -0400
@@ -27,7 +27,7 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 
 import java.nio.ByteBuffer;
-import jdk.nashorn.internal.runtime.GlobalObject;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 
@@ -60,7 +60,8 @@
      *
      * @return property descriptor for element
      */
-    public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
+    @Override
+    public PropertyDescriptor getDescriptor(final Global global, final int index) {
         // make the index properties not configurable
         return global.newDataDescriptor(getObject(index), false, true, true);
     }
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java	Tue Mar 25 20:32:46 2014 -0400
@@ -25,9 +25,9 @@
 
 package jdk.nashorn.internal.runtime.arrays;
 
+import jdk.nashorn.internal.objects.Global;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 
-import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
 
 /**
@@ -44,7 +44,7 @@
     }
 
     @Override
-    public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
+    public PropertyDescriptor getDescriptor(final Global global, final int index) {
         return global.newDataDescriptor(getObject(index), false, true, false);
     }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java	Tue Mar 25 20:32:46 2014 -0400
@@ -25,9 +25,9 @@
 
 package jdk.nashorn.internal.runtime.arrays;
 
+import jdk.nashorn.internal.objects.Global;
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 
-import jdk.nashorn.internal.runtime.GlobalObject;
 import jdk.nashorn.internal.runtime.PropertyDescriptor;
 
 /**
@@ -62,7 +62,7 @@
     }
 
     @Override
-    public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
+    public PropertyDescriptor getDescriptor(final Global global, final int index) {
         return global.newDataDescriptor(getObject(index), false, true, true);
     }
 }
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Tue Mar 25 20:32:46 2014 -0400
@@ -64,6 +64,7 @@
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
 import jdk.internal.org.objectweb.asm.commons.InstructionAdapter;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -134,6 +135,7 @@
     static final Type CONTEXT_TYPE       = Type.getType(Context.class);
     static final Type OBJECT_TYPE        = Type.getType(Object.class);
     static final Type SCRIPT_OBJECT_TYPE = Type.getType(ScriptObject.class);
+    static final Type GLOBAL_TYPE        = Type.getType(Global.class);
 
     static final String CONTEXT_TYPE_NAME = CONTEXT_TYPE.getInternalName();
     static final String OBJECT_TYPE_NAME  = OBJECT_TYPE.getInternalName();
@@ -143,8 +145,10 @@
     static final String GLOBAL_FIELD_NAME = "global";
 
     static final String SCRIPT_OBJECT_TYPE_DESCRIPTOR = SCRIPT_OBJECT_TYPE.getDescriptor();
+    static final String GLOBAL_TYPE_DESCRIPTOR = GLOBAL_TYPE.getDescriptor();
 
-    static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, SCRIPT_OBJECT_TYPE);
+
+    static final String SET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE, GLOBAL_TYPE);
     static final String VOID_NOARG_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.VOID_TYPE);
 
     private static final Type SCRIPT_FUNCTION_TYPE = Type.getType(ScriptFunction.class);
@@ -167,7 +171,7 @@
     private static final String UNSUPPORTED_OPERATION_TYPE_NAME = UNSUPPORTED_OPERATION_TYPE.getInternalName();
 
     private static final String METHOD_HANDLE_TYPE_DESCRIPTOR = METHOD_HANDLE_TYPE.getDescriptor();
-    private static final String GET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(SCRIPT_OBJECT_TYPE);
+    private static final String GET_GLOBAL_METHOD_DESCRIPTOR = Type.getMethodDescriptor(GLOBAL_TYPE);
     private static final String GET_CLASS_METHOD_DESCRIPTOR = Type.getMethodDescriptor(Type.getType(Class.class));
 
     // Package used when the adapter can't be defined in the adaptee's package (either because it's sealed, or because
@@ -259,7 +263,7 @@
     }
 
     private void generateGlobalFields() {
-        cw.visitField(ACC_PRIVATE | ACC_FINAL | (classOverride ? ACC_STATIC : 0), GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, null).visitEnd();
+        cw.visitField(ACC_PRIVATE | ACC_FINAL | (classOverride ? ACC_STATIC : 0), GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR, null, null).visitEnd();
         usedFieldNames.add(GLOBAL_FIELD_NAME);
     }
 
@@ -363,7 +367,7 @@
         }
         // Assign "global = Context.getGlobal()"
         invokeGetGlobalWithNullCheck(mv);
-        mv.putstatic(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
+        mv.putstatic(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
 
         endInitMethod(mv);
     }
@@ -508,7 +512,7 @@
         // Assign "this.global = Context.getGlobal()"
         mv.visitVarInsn(ALOAD, 0);
         invokeGetGlobalWithNullCheck(mv);
-        mv.putfield(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
+        mv.putfield(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
 
         endInitMethod(mv);
     }
@@ -652,10 +656,10 @@
         // Load the creatingGlobal object
         if(classOverride) {
             // If class handle is defined, load the static defining global
-            mv.getstatic(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
+            mv.getstatic(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
         } else {
             mv.visitVarInsn(ALOAD, 0);
-            mv.getfield(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
+            mv.getfield(generatedClassName, GLOBAL_FIELD_NAME, GLOBAL_TYPE_DESCRIPTOR);
         }
         // stack: [creatingGlobal, handle]
         final Label setupGlobal = new Label();
@@ -674,7 +678,7 @@
         // stack: [creatingGlobal, creatingGlobal, handle]
 
         // Emit code for switching to the creating global
-        // ScriptObject currentGlobal = Context.getGlobal();
+        // Global currentGlobal = Context.getGlobal();
         invokeGetGlobal(mv);
         mv.dup();
 
@@ -744,7 +748,7 @@
         final Label methodEnd = new Label();
         mv.visitLabel(methodEnd);
 
-        mv.visitLocalVariable("currentGlobal", SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, setupGlobal, methodEnd, currentGlobalVar);
+        mv.visitLocalVariable("currentGlobal", GLOBAL_TYPE_DESCRIPTOR, null, setupGlobal, methodEnd, currentGlobalVar);
         mv.visitLocalVariable("globalsDiffer", Type.INT_TYPE.getDescriptor(), null, setupGlobal, methodEnd, globalsDifferVar);
 
         if(throwableDeclared) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Tue Mar 25 20:32:46 2014 -0400
@@ -48,7 +48,6 @@
 import java.util.concurrent.ConcurrentHashMap;
 import jdk.internal.dynalink.beans.StaticClass;
 import jdk.internal.dynalink.support.LinkRequestImpl;
-import jdk.nashorn.internal.objects.NativeJava;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ECMAException;
 import jdk.nashorn.internal.runtime.ScriptFunction;
@@ -68,8 +67,8 @@
  * generate the adapter class itself; see its documentation for details about the generated class.
  * </p><p>
  * You normally don't use this class directly, but rather either create adapters from script using
- * {@link NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
- * {@link NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
+ * {@link jdk.nashorn.internal.objects.NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
+ * {@link jdk.nashorn.internal.objects.NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
  * types.
  * </p>
  */
@@ -337,6 +336,7 @@
     private static ProtectionDomain createMinimalPermissionDomain() {
         // Generated classes need to have at least the permission to access Nashorn runtime and runtime.linker packages.
         final Permissions permissions = new Permissions();
+        permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.objects"));
         permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime"));
         permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime.linker"));
         return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java	Tue Mar 25 20:32:46 2014 -0400
@@ -29,6 +29,11 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.ref.WeakReference;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+import jdk.nashorn.internal.objects.Global;
+import jdk.nashorn.internal.runtime.Property;
 import jdk.nashorn.internal.runtime.PropertyMap;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -40,6 +45,7 @@
     private static final MethodHandle IS_SCRIPTOBJECT   = findOwnMH("isScriptObject", boolean.class, Object.class);
     private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class);
     private static final MethodHandle IS_MAP            = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class);
+    private static final MethodHandle SAME_OBJECT       = findOwnMH("sameObject", boolean.class, Object.class, WeakReference.class);
     private static final MethodHandle IS_INSTANCEOF_2   = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class);
 
     // don't create me!
@@ -75,6 +81,55 @@
     }
 
     /**
+     * Determine whether the given callsite needs a guard.
+     * @param property the property, or null
+     * @param desc the callsite descriptor
+     * @return true if a guard should be used for this callsite
+     */
+    static boolean needsGuard(final Property property, final CallSiteDescriptor desc) {
+        return property == null || property.isConfigurable()
+                || property.isBound() || !ObjectClassGenerator.OBJECT_FIELDS_ONLY
+                || !NashornCallSiteDescriptor.isFastScope(desc) || property.canChangeType();
+    }
+
+    /**
+     * Get the guard for a property access. This returns an identity guard for non-configurable global properties
+     * and a map guard for everything else.
+     *
+     * @param sobj the first object in the prototype chain
+     * @param property the property
+     * @param desc the callsite descriptor
+     * @return method handle for guard
+     */
+    public static MethodHandle getGuard(final ScriptObject sobj, final Property property, final CallSiteDescriptor desc) {
+        if (!needsGuard(property, desc)) {
+            return null;
+        }
+        if (NashornCallSiteDescriptor.isScope(desc)) {
+            if (property != null && property.isBound()) {
+                // This is a declared top level variables in main script or eval, use identity guard.
+                return getIdentityGuard(sobj);
+            }
+            if (!(sobj instanceof Global) && (property == null || property.isConfigurable())) {
+                // Undeclared variables in nested evals need stronger guards
+                return combineGuards(getIdentityGuard(sobj), getMapGuard(sobj.getMap()));
+            }
+        }
+        return getMapGuard(sobj.getMap());
+    }
+
+
+    /**
+     * Get a guard that checks referential identity of the current object.
+     *
+     * @param sobj the self object
+     * @return true if same self object instance
+     */
+    public static MethodHandle getIdentityGuard(final ScriptObject sobj) {
+        return MH.insertArguments(SAME_OBJECT, 1, new WeakReference<>(sobj));
+    }
+
+    /**
      * Get a guard that checks if in item is an instance of either of two classes.
      *
      * @param class1 the first class
@@ -112,6 +167,11 @@
     }
 
     @SuppressWarnings("unused")
+    private static boolean sameObject(final Object self, final WeakReference<ScriptObject> ref) {
+        return self == ref.get();
+    }
+
+    @SuppressWarnings("unused")
     private static boolean isInstanceOf2(final Object self, final Class<?> class1, final Class<?> class2) {
         return class1.isInstance(self) || class2.isInstance(self);
     }
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java	Tue Mar 25 20:32:46 2014 -0400
@@ -37,9 +37,9 @@
 import jdk.internal.dynalink.linker.LinkerServices;
 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
 import jdk.internal.dynalink.support.TypeUtilities;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.ConsString;
 import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.GlobalObject;
 
 /**
  * Internal linker for String, Boolean, and Number objects, only ever used by Nashorn engine and not exposed to other
@@ -62,7 +62,7 @@
         final LinkRequest request = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context
 
         final Object self = request.getReceiver();
-        final GlobalObject global = (GlobalObject) Context.getGlobal();
+        final Global global = Context.getGlobal();
         final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor) request.getCallSiteDescriptor();
 
         return Bootstrap.asType(global.primitiveLookup(request, self), linkerServices, desc);
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java	Tue Mar 25 20:32:46 2014 -0400
@@ -35,6 +35,7 @@
 import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
 import jdk.internal.dynalink.support.Guards;
 import jdk.nashorn.internal.lookup.Lookup;
+import jdk.nashorn.internal.runtime.FindProperty;
 import jdk.nashorn.internal.runtime.ScriptObject;
 
 /**
@@ -61,8 +62,9 @@
      * type {@code receiverClass}.
      */
     public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Class<?> receiverClass,
-                                                    final ScriptObject wrappedReceiver, final MethodHandle wrapFilter) {
-        return lookupPrimitive(request, Guards.getInstanceOfGuard(receiverClass), wrappedReceiver, wrapFilter);
+                                                    final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
+                                                    final MethodHandle protoFilter) {
+        return lookupPrimitive(request, Guards.getInstanceOfGuard(receiverClass), wrappedReceiver, wrapFilter, protoFilter);
     }
 
     /**
@@ -79,7 +81,8 @@
      * type (that is implied by both {@code guard} and {@code wrappedReceiver}).
      */
     public static GuardedInvocation lookupPrimitive(final LinkRequest request, final MethodHandle guard,
-                                                    final ScriptObject wrappedReceiver, final MethodHandle wrapFilter) {
+                                                    final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
+                                                    final MethodHandle protoFilter) {
         final CallSiteDescriptor desc = request.getCallSiteDescriptor();
         final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
         if ("setProp".equals(operator) || "setElem".equals(operator)) {
@@ -93,9 +96,23 @@
 
         if(desc.getNameTokenCount() > 2) {
             final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
-            if(wrappedReceiver.findProperty(name, true) == null) {
+            final FindProperty find = wrappedReceiver.findProperty(name, true);
+            if(find == null) {
                 // Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it.
                 return null;
+            } else if (find.isInherited() && !find.getProperty().hasGetterFunction(find.getOwner())) {
+                // 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 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);
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Tue Mar 25 20:32:46 2014 -0400
@@ -79,6 +79,7 @@
 type.error.not.a.constructor={0} is not a constructor function
 type.error.not.a.file={0} is not a File
 type.error.not.a.bytebuffer={0} is not a java.nio.ByteBuffer
+type.error.not.an.arraybuffer.in.dataview=First arg to DataView constructor must be an ArrayBuffer
 
 # operations not permitted on undefined
 type.error.cant.call.undefined=Cannot call undefined
@@ -137,6 +138,9 @@
 type.error.method.not.constructor=Java method {0} can't be used as a constructor.
 type.error.env.not.object=$ENV must be an Object.
 type.error.unsupported.java.to.type=Unsupported Java.to target type {0}.
+
+range.error.dataview.constructor.offset=Wrong offset or length in DataView constructor
+range.error.dataview.offset=Offset is outside the bounds of the DataView
 range.error.inappropriate.array.length=inappropriate array length: {0}
 range.error.inappropriate.array.buffer.length=inappropriate array buffer length: {0}
 range.error.invalid.fraction.digits=fractionDigits argument to {0} must be in [0, 20]
--- a/nashorn/src/jdk/nashorn/tools/Shell.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/src/jdk/nashorn/tools/Shell.java	Tue Mar 25 20:32:46 2014 -0400
@@ -42,6 +42,7 @@
 import jdk.nashorn.internal.ir.FunctionNode;
 import jdk.nashorn.internal.ir.debug.ASTWriter;
 import jdk.nashorn.internal.ir.debug.PrintVisitor;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.parser.Parser;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ErrorManager;
@@ -148,7 +149,7 @@
             return COMMANDLINE_ERROR;
         }
 
-        final ScriptObject global = context.createGlobal();
+        final Global global = context.createGlobal();
         final ScriptEnvironment env = context.getEnv();
         final List<String> files = env.getFiles();
         if (files.isEmpty()) {
@@ -231,8 +232,8 @@
      * @return error code
      * @throws IOException when any script file read results in I/O error
      */
-    private static int compileScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
-        final ScriptObject oldGlobal = Context.getGlobal();
+    private static int compileScripts(final Context context, final Global global, final List<String> files) throws IOException {
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
         final ScriptEnvironment env = context.getEnv();
         try {
@@ -281,8 +282,8 @@
      * @return error code
      * @throws IOException when any script file read results in I/O error
      */
-    private int runScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
-        final ScriptObject oldGlobal = Context.getGlobal();
+    private int runScripts(final Context context, final Global global, final List<String> files) throws IOException {
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
         try {
             if (globalChanged) {
@@ -339,8 +340,8 @@
      * @return error code
      * @throws IOException when any script file read results in I/O error
      */
-    private static int runFXScripts(final Context context, final ScriptObject global, final List<String> files) throws IOException {
-        final ScriptObject oldGlobal = Context.getGlobal();
+    private static int runFXScripts(final Context context, final Global global, final List<String> files) throws IOException {
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
         try {
             if (globalChanged) {
@@ -389,11 +390,11 @@
      * @return return code
      */
     @SuppressWarnings("resource")
-    private static int readEvalPrint(final Context context, final ScriptObject global) {
+    private static int readEvalPrint(final Context context, final Global global) {
         final String prompt = bundle.getString("shell.prompt");
         final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
         final PrintWriter err = context.getErr();
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
         final ScriptEnvironment env = context.getEnv();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8034055.js	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDK-8034055: delete on global object not properly guarded
+ *
+ * @test
+ * @run
+ */
+
+
+var global = this;
+var x;
+
+function test(defineGlobals) {
+    if (defineGlobals) {
+        global.x = 1;
+        global.y = 2;
+    }
+    try {
+        print(x);
+        print(y);
+    } catch (e) {
+        print(e);
+    } finally {
+        print(delete global.x);
+        print(delete global.y);
+    }
+}
+
+// Repeatedly set and delete global variables
+test(true);
+test(false);
+test(true);
+test(false);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8034055.js.EXPECTED	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,16 @@
+1
+2
+false
+true
+1
+ReferenceError: "y" is not defined
+false
+true
+1
+2
+false
+true
+1
+ReferenceError: "y" is not defined
+false
+true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/dataview_endian.js	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDK-8015958: DataView constructor is not defined
+ *
+ * @test
+ * @run
+ */
+
+// set/get endianess checks
+
+var buffer = new ArrayBuffer(4);
+var dv = new DataView(buffer);
+
+// write (default) big endian, read big/little endian
+dv.setUint16(0, 0xABCD);
+Assert.assertEquals(dv.getUint16(0), 0xABCD);
+Assert.assertEquals(dv.getUint16(0, false), 0xABCD);
+Assert.assertEquals(dv.getUint16(0, true), 0xCDAB);
+
+// write little endian, read big/little endian
+dv.setUint16(0, 0xABCD, true);
+Assert.assertEquals(dv.getUint16(0), 0xCDAB);
+Assert.assertEquals(dv.getUint16(0, false), 0xCDAB);
+Assert.assertEquals(dv.getUint16(0, true), 0xABCD);
+
+// write explicit big endian, read big/little endian
+dv.setUint16(0, 0xABCD, false);
+Assert.assertEquals(dv.getUint16(0), 0xABCD);
+Assert.assertEquals(dv.getUint16(0, false), 0xABCD);
+Assert.assertEquals(dv.getUint16(0, true), 0xCDAB);
+
+// write (default) big endian, read big/little endian
+dv.setUint32(0, 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0), 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0, false), 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0, true), 0x89EFCDAB);
+
+// write little endian, read big/little endian
+dv.setUint32(0, 0xABCDEF89, true);
+Assert.assertEquals(dv.getUint32(0), 0x89EFCDAB);
+Assert.assertEquals(dv.getUint32(0, false), 0x89EFCDAB);
+Assert.assertEquals(dv.getUint32(0, true), 0xABCDEF89);
+
+// write explicit big endian, read big/little endian
+dv.setUint32(0, 0xABCDEF89, false);
+Assert.assertEquals(dv.getUint32(0), 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0, false), 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0, true), 0x89EFCDAB);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/dataview_getset.js	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDK-8015958: DataView constructor is not defined
+ *
+ * @test
+ * @run
+ */
+
+// checking get/set of values of various types
+// Also basic endianess check.
+
+var Float = Java.type("java.lang.Float");
+var Double = Java.type("java.lang.Double");
+
+var DOUBLE_MIN = Double.MIN_VALUE;
+var DOUBLE_MIN_NORMAL = Double.MIN_NORMAL;
+var FLOAT_MIN = Float.MIN_VALUE;
+var FLOAT_MIN_NORMAL = Float.MIN_NORMAL;
+
+var buffer = new ArrayBuffer(12);
+var dv = new DataView(buffer);
+
+dv.setInt8(1, 123);
+Assert.assertEquals(dv.getInt8(1), 123);
+dv.setInt8(1, 123, true);
+Assert.assertEquals(dv.getInt8(1, true), 123);
+
+dv.setUint8(1, 255);
+Assert.assertEquals(dv.getUint8(1), 255);
+dv.setUint8(1, 255, true);
+Assert.assertEquals(dv.getUint8(1, true), 255);
+
+dv.setInt16(1, 1234);
+Assert.assertEquals(dv.getInt16(1), 1234);
+dv.setInt16(1, 1234, true);
+Assert.assertEquals(dv.getInt16(1, true), 1234);
+
+dv.setUint16(1, 65535);
+Assert.assertEquals(dv.getUint16(1), 65535);
+dv.setUint16(1, 65535, true);
+Assert.assertEquals(dv.getUint16(1, true), 65535);
+
+dv.setInt32(1, 1234);
+Assert.assertEquals(dv.getInt32(1), 1234);
+dv.setInt32(1, 1234, true);
+Assert.assertEquals(dv.getInt32(1, true), 1234);
+
+dv.setUint32(1, 4294967295);
+Assert.assertEquals(dv.getUint32(1), 4294967295);
+dv.setUint32(1, 4294967295, true);
+Assert.assertEquals(dv.getUint32(1, true), 4294967295);
+
+dv.setFloat64(1, Math.PI);
+Assert.assertEquals(dv.getFloat64(1), Math.PI, DOUBLE_MIN);
+dv.setFloat64(1, Math.PI, true);
+Assert.assertEquals(dv.getFloat64(1, true), Math.PI, DOUBLE_MIN);
+
+dv.setFloat64(1, DOUBLE_MIN_NORMAL);
+Assert.assertEquals(dv.getFloat64(1), DOUBLE_MIN_NORMAL, DOUBLE_MIN);
+dv.setFloat64(1, DOUBLE_MIN_NORMAL, true);
+Assert.assertEquals(dv.getFloat64(1, true), DOUBLE_MIN_NORMAL, DOUBLE_MIN);
+
+dv.setFloat32(1, 1.414);
+Assert["assertEquals(float, float, float)"](dv.getFloat32(1), 1.414, FLOAT_MIN);
+dv.setFloat32(1, 1.414, true);
+Assert["assertEquals(float, float, float)"](dv.getFloat32(1, true), 1.414, FLOAT_MIN);
+
+dv.setFloat32(1, FLOAT_MIN_NORMAL);
+Assert["assertEquals(float, float, float)"](dv.getFloat32(1), FLOAT_MIN_NORMAL, FLOAT_MIN);
+dv.setFloat32(1, FLOAT_MIN_NORMAL, true);
+Assert["assertEquals(float, float, float)"](dv.getFloat32(1, true), FLOAT_MIN_NORMAL, FLOAT_MIN);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/dataview_new.js	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+/**
+ * JDK-8015958: DataView constructor is not defined
+ *
+ * @test
+ * @run
+ */
+
+// basic DataView constructor checks.
+
+// check ArrayBufferView property values of DataView instance
+function check(dv, buf, offset, length) {
+    if (dv.buffer !== buf) {
+        fail("DataView.buffer is wrong");
+    }
+
+    if (dv.byteOffset != offset) {
+        fail("DataView.byteOffset = " + dv.byteOffset + ", expected " + offset);
+    }
+
+    if (dv.byteLength != length) {
+        fail("DataView.byteLength = " + dv.byteLength + ", expected " + length);
+    }
+}
+
+var buffer = new ArrayBuffer(12);
+check(new DataView(buffer), buffer, 0, 12);
+check(new DataView(buffer, 2), buffer, 2, 10);
+check(new DataView(buffer, 4, 8), buffer, 4, 8);
+
+// make sure expected error is thrown
+function checkError(callback, ErrorType) {
+    try {
+        callback();
+        fail("Should have thrown " + ErrorType.name);
+    } catch (e) {
+        if (! (e instanceof ErrorType)) {
+            fail("Expected " + ErrorType.name + " got " + e);
+        }
+    }
+}
+
+// non ArrayBuffer as first arg
+checkError(function() { new DataView(344) }, TypeError);
+
+// illegal offset/length values
+checkError(function() { new DataView(buffer, -1) }, RangeError);
+checkError(function() { new DataView(buffer, 15) }, RangeError);
+checkError(function() { new DataView(buffer, 1, 32) }, RangeError);
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -245,4 +245,320 @@
         sb.put("x", "newX");
         assertTrue(e.eval("x", ctx).equals("newX"));
     }
+
+    /**
+     * Test multi-threaded access to defined global variables for shared script classes with multiple globals.
+     */
+    @Test
+    public static void multiThreadedVarTest() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+        final String sharedScript = "foo";
+
+        assertEquals(e.eval("var foo = 'original context';", origContext), null);
+        assertEquals(e.eval("var foo = 'new context';", newCtxt), null);
+
+        final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+
+        assertEquals(e.eval("var foo = 'newer context';", newCtxt), null);
+        final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+        final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+
+        t3.start();
+        t4.start();
+        t3.join();
+        t4.join();
+
+        assertEquals(e.eval(sharedScript), "original context");
+        assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+    }
+
+    /**
+     * Test multi-threaded access to undefined global variables for shared script classes with multiple globals.
+     */
+    @Test
+    public static void multiThreadedGlobalTest() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+        assertEquals(e.eval("foo = 'original context';", origContext), "original context");
+        assertEquals(e.eval("foo = 'new context';", newCtxt), "new context");
+        final String sharedScript = "foo";
+
+        final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+
+        Object obj3 = e.eval("delete foo; foo = 'newer context';", newCtxt);
+        assertEquals(obj3, "newer context");
+        final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+        final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+
+        t3.start();
+        t4.start();
+        t3.join();
+        t4.join();
+
+        Assert.assertEquals(e.eval(sharedScript), "original context");
+        Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+    }
+
+    /**
+     * Test multi-threaded access using the postfix ++ operator for shared script classes with multiple globals.
+     */
+    @Test
+    public static void multiThreadedIncTest() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+        assertEquals(e.eval("var x = 0;", origContext), null);
+        assertEquals(e.eval("var x = 2;", newCtxt), null);
+        final String sharedScript = "x++;";
+
+        final Thread t1 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    for (int i = 0; i < 1000; i++) {
+                        assertEquals(e.eval(sharedScript, origContext), (double)i);
+                    }
+                } catch (ScriptException se) {
+                    fail(se.toString());
+                }
+            }
+        });
+        final Thread t2 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    for (int i = 2; i < 1000; i++) {
+                        assertEquals(e.eval(sharedScript, newCtxt), (double)i);
+                    }
+                } catch (ScriptException se) {
+                    fail(se.toString());
+                }
+            }
+        });
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+    }
+
+    /**
+     * Test multi-threaded access to primitive prototype properties for shared script classes with multiple globals.
+     */
+    @Test
+    public static void multiThreadedPrimitiveTest() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+        Object obj1 = e.eval("String.prototype.foo = 'original context';", origContext);
+        Object obj2 = e.eval("String.prototype.foo = 'new context';", newCtxt);
+        assertEquals(obj1, "original context");
+        assertEquals(obj2, "new context");
+        final String sharedScript = "''.foo";
+
+        final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+
+        Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt);
+        assertEquals(obj3, "newer context");
+        final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+        final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+
+        t3.start();
+        t4.start();
+        t3.join();
+        t4.join();
+
+        Assert.assertEquals(e.eval(sharedScript), "original context");
+        Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+    }
+
+    /**
+     * Test multi-threaded scope function invocation for shared script classes with multiple globals.
+     */
+    @Test
+    public static void multiThreadedFunctionTest() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+        e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), origContext);
+        assertEquals(origContext.getAttribute("scopeVar"), 1);
+        assertEquals(e.eval("scopeTest()"), 1);
+
+        e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), newCtxt);
+        assertEquals(newCtxt.getAttribute("scopeVar"), 1);
+        assertEquals(e.eval("scopeTest();", newCtxt), 1);
+
+        assertEquals(e.eval("scopeVar = 3;", newCtxt), 3);
+        assertEquals(newCtxt.getAttribute("scopeVar"), 3);
+
+
+        final Thread t1 = new Thread(new ScriptRunner(e, origContext, "scopeTest()", 1, 1000));
+        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, "scopeTest()", 3, 1000));
+
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+
+    }
+
+    /**
+     * Test multi-threaded access to global getters and setters for shared script classes with multiple globals.
+     */
+    @Test
+    public static void getterSetterTest() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+        final String sharedScript = "accessor1";
+
+        e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext);
+        assertEquals(e.eval("accessor1 = 1;"), 1);
+        assertEquals(e.eval(sharedScript), 1);
+
+        e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt);
+        assertEquals(e.eval("accessor1 = 2;", newCtxt), 2);
+        assertEquals(e.eval(sharedScript, newCtxt), 2);
+
+
+        final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000));
+        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000));
+
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+
+        assertEquals(e.eval(sharedScript), 1);
+        assertEquals(e.eval(sharedScript, newCtxt), 2);
+        assertEquals(e.eval("v"), 1);
+        assertEquals(e.eval("v", newCtxt), 2);
+    }
+
+    /**
+     * Test multi-threaded access to global getters and setters for shared script classes with multiple globals.
+     */
+    @Test
+    public static void getterSetter2Test() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+        final Bindings b = e.createBindings();
+        final ScriptContext origContext = e.getContext();
+        final ScriptContext newCtxt = new SimpleScriptContext();
+        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+        final String sharedScript = "accessor2";
+
+        e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext);
+        assertEquals(e.eval("accessor2 = 1;"), 1);
+        assertEquals(e.eval(sharedScript), 1);
+
+        e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt);
+        assertEquals(e.eval("accessor2 = 2;", newCtxt), 2);
+        assertEquals(e.eval(sharedScript, newCtxt), 2);
+
+
+        final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000));
+        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000));
+
+        t1.start();
+        t2.start();
+        t1.join();
+        t2.join();
+
+        assertEquals(e.eval(sharedScript), 1);
+        assertEquals(e.eval(sharedScript, newCtxt), 2);
+        assertEquals(e.eval("x"), 1);
+        assertEquals(e.eval("x", newCtxt), 2);
+    }
+
+    /**
+     * Test "slow" scopes involving {@code with} and {@code eval} statements for shared script classes with multiple globals.
+     */
+    @Test
+    public static void testSlowScope() throws ScriptException, InterruptedException {
+        final ScriptEngineManager m = new ScriptEngineManager();
+        final ScriptEngine e = m.getEngineByName("nashorn");
+
+        for (int i = 0; i < 100; i++) {
+            final Bindings b = e.createBindings();
+            final ScriptContext ctxt = new SimpleScriptContext();
+            ctxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+            e.eval(new URLReader(ScopeTest.class.getResource("resources/witheval.js")), ctxt);
+            assertEquals(e.eval("a", ctxt), 1);
+            assertEquals(b.get("a"), 1);
+            assertEquals(e.eval("b", ctxt), 3);
+            assertEquals(b.get("b"), 3);
+            assertEquals(e.eval("c", ctxt), 10);
+            assertEquals(b.get("c"), 10);
+        }
+    }
+
+    private static class ScriptRunner implements Runnable {
+
+        final ScriptEngine engine;
+        final ScriptContext context;
+        final String source;
+        final Object expected;
+        final int iterations;
+
+        ScriptRunner(final ScriptEngine engine, final ScriptContext context, final String source, final Object expected, final int iterations) {
+            this.engine = engine;
+            this.context = context;
+            this.source = source;
+            this.expected = expected;
+            this.iterations = iterations;
+        }
+
+        @Override
+        public void run() {
+            try {
+                for (int i = 0; i < iterations; i++) {
+                    assertEquals(engine.eval(source, context), expected);
+                }
+            } catch (ScriptException se) {
+                throw new RuntimeException(se);
+            }
+        }
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/resources/func.js	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
+
+var scopeVar = 1;
+var global = this;
+undefGlobal = this;
+
+function scopeTest() {
+    if (this !== global) {
+        throw new Error("this !== global");
+    }
+    if (this !== undefGlobal) {
+        throw new Error("this !== undefinedGlobal")
+    }
+    return scopeVar;
+}
+
+scopeTest();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/resources/gettersetter.js	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
+
+var v;
+
+Object.defineProperty(this, "accessor1", {
+    get: function() { return v; },
+    set: function(n) { v = n; }
+});
+
+Object.defineProperty(this, "accessor2", {
+    get: function() { return x; },
+    set: function(n) { x = n; }
+});
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/resources/witheval.js	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
+
+var a;
+
+function outer(p, e) {
+    eval(e);
+    with(p) {
+        function inner() {
+            a = 1;
+            c = 10;
+            if (a !== 1) {
+                throw new Error("a !== 1");
+            }
+            if (b !== 3) {
+                throw new Error("b !== 3");
+            }
+            if (c !== 10) {
+                throw new Error("c !== 10");
+            }
+        }
+        inner();
+    }
+}
+
+outer({}, "b = 3;");
+
+if (a !== 1) {
+    throw new Error("a !== 1");
+}
+if (b !== 3) {
+    throw new Error("b !== 3");
+}
+if (c !== 10) {
+    throw new Error("c !== 10");
+}
--- a/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -28,6 +28,7 @@
 import java.io.File;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ErrorManager;
 import jdk.nashorn.internal.runtime.ScriptFunction;
@@ -58,7 +59,7 @@
     }
 
     private Context context;
-    private ScriptObject global;
+    private Global  global;
 
     @BeforeClass
     public void setupTest() {
@@ -146,7 +147,7 @@
             log("Begin compiling " + file.getAbsolutePath());
         }
 
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         final boolean globalChanged = (oldGlobal != global);
 
         try {
--- a/nashorn/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java	Tue Mar 25 20:32:46 2014 -0400
@@ -31,9 +31,9 @@
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ScriptFunction;
-import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 
 /**
@@ -89,7 +89,7 @@
     @Override
     protected Object apply(final ScriptFunction target, final Object self) {
         if (_runsPerIteration == 0 && _numberOfIterations == 0) {
-            final ScriptObject global = jdk.nashorn.internal.runtime.Context.getGlobal();
+            final Global global = jdk.nashorn.internal.runtime.Context.getGlobal();
             final ScriptFunction _target = target;
             final Object _self = self;
 
--- a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -29,6 +29,7 @@
 import static org.testng.Assert.assertTrue;
 
 import java.util.Map;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.options.Options;
 import org.testng.annotations.Test;
 
@@ -45,7 +46,7 @@
         final Options options = new Options("");
         final ErrorManager errors = new ErrorManager();
         final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         Context.setGlobal(cx.createGlobal());
         try {
             String code = "22 + 10";
@@ -65,7 +66,7 @@
         final ErrorManager errors = new ErrorManager();
         final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
         final boolean strict = cx.getEnv()._strict;
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         Context.setGlobal(cx.createGlobal());
 
         try {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/NoPersistenceCachingTest.java	Tue Mar 25 20:32:46 2014 -0400
@@ -0,0 +1,133 @@
+/*
+ * 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 jdk.nashorn.internal.runtime;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import static org.testng.Assert.fail;
+import org.testng.annotations.Test;
+
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+import javax.script.SimpleScriptContext;
+import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+
+/**
+ * @test
+ * @bug 8037378
+ * @summary Sanity tests for no persistence caching
+ * @run testng/othervm jdk.nashorn.internal.runtime.NoPersistenceCachingTest
+ */
+public class NoPersistenceCachingTest {
+
+   private ScriptEngine engine;
+   private ScriptContext context1, context2, context3;
+   private ByteArrayOutputStream stderr;
+   private PrintStream prevStderr;
+   private final String script = "print('Hello')";
+
+   public void setupTest() {
+      stderr = new ByteArrayOutputStream();
+      prevStderr = System.err;
+      System.setErr(new PrintStream(stderr));
+      NashornScriptEngineFactory nashornFactory = null;
+      ScriptEngineManager sm = new ScriptEngineManager();
+      for (ScriptEngineFactory fac : sm.getEngineFactories()) {
+         if (fac instanceof NashornScriptEngineFactory) {
+            nashornFactory = (NashornScriptEngineFactory) fac;
+            break;
+         }
+      }
+      if (nashornFactory == null) {
+         fail("Cannot find nashorn factory!");
+      }
+      String[] options = new String[]{"--log=compiler:finest"};
+      engine = nashornFactory.getScriptEngine(options);
+   }
+
+   public void setErrTest() {
+      System.setErr(prevStderr);
+   }
+
+   public void runTest(int numberOfContext, String expectedOutputPattern,
+                       int expectedPatternOccurrence) {
+      setupTest();
+      try {
+         switch (numberOfContext) {
+         case 2:
+            context1 = engine.getContext();
+            context2 = new SimpleScriptContext();
+            context2.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
+            engine.eval(script, context1);
+            engine.eval(script, context2);
+            break;
+         case 3:
+            context1 = engine.getContext();
+            context2 = new SimpleScriptContext();
+            context2.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
+            context3 = new SimpleScriptContext();
+            context3.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
+            engine.eval(script, context1);
+            engine.eval(script, context2);
+            engine.eval(script, context3);
+            break;
+         }
+      } catch (final Exception se) {
+         se.printStackTrace();
+         fail(se.getMessage());
+      }
+      Pattern deoptimizing = Pattern.compile(expectedOutputPattern);
+      Matcher matcher = deoptimizing.matcher(stderr.toString());
+      int matches = 0;
+      while (matcher.find()) {
+         matches++;
+      }
+      if (matches != expectedPatternOccurrence) {
+         fail("Number of cache hit is not correct, expected: "
+                    + expectedPatternOccurrence + " and found: " + matches + "\n"
+              + stderr);
+      }
+      setErrTest();
+   }
+
+   private static String getCodeCachePattern() {
+      return ("\\[compiler\\]\\sCode\\scache\\shit\\sfor\\s<eval>\\savoiding\\srecompile.");
+   }
+
+    @Test
+    public void twoContextTest() {
+       runTest(2, getCodeCachePattern(), 1);
+
+    }
+
+    @Test
+    public void threeContextTest() {
+       runTest(3, getCodeCachePattern(), 2);
+    }
+}
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java	Tue Mar 25 20:32:07 2014 -0400
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java	Tue Mar 25 20:32:46 2014 -0400
@@ -34,10 +34,10 @@
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import jdk.nashorn.api.scripting.NashornException;
+import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.ErrorManager;
 import jdk.nashorn.internal.runtime.ScriptFunction;
-import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.Source;
 import jdk.nashorn.internal.runtime.options.Options;
@@ -110,12 +110,12 @@
 
     @Override
     public int run(final OutputStream out, final OutputStream err, final String[] args) throws IOException {
-        final ScriptObject oldGlobal = Context.getGlobal();
+        final Global oldGlobal = Context.getGlobal();
         try {
             ctxOut.setDelegatee(out);
             ctxErr.setDelegatee(err);
             final ErrorManager errors = context.getErrorManager();
-            final ScriptObject global = context.createGlobal();
+            final Global global = context.createGlobal();
             Context.setGlobal(global);
 
             // For each file on the command line.