Merge
authordcubed
Sat, 16 May 2015 13:19:11 -0700
changeset 30751 deee942af125
parent 30635 8884c2399789 (current diff)
parent 30750 0074894f4b79 (diff)
child 30752 e8641f96a82b
child 30753 75e795c4d14f
Merge
hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
hotspot/src/os/linux/vm/os_linux.cpp
--- a/hotspot/make/test/JtregNative.gmk	Thu May 14 12:05:32 2015 -0700
+++ b/hotspot/make/test/JtregNative.gmk	Sat May 16 13:19:11 2015 -0700
@@ -42,6 +42,8 @@
 # Add more directories here when needed.
 BUILD_HOTSPOT_JTREG_NATIVE_SRC := \
     $(HOTSPOT_TOPDIR)/test/native_sanity \
+    $(HOTSPOT_TOPDIR)/test/runtime/jni/8025979 \
+    $(HOTSPOT_TOPDIR)/test/runtime/jni/8033445 \
     #
 
 BUILD_HOTSPOT_JTREG_OUTPUT_DIR := $(BUILD_OUTPUT)/support/test/hotspot/jtreg/native
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Thu May 14 12:05:32 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp	Sat May 16 13:19:11 2015 -0700
@@ -1035,8 +1035,7 @@
 //      rdx, c_rarg1: BasicObjectLock to be used for locking
 //
 // Kills:
-//      rax
-//      rscratch1 (scratch regs)
+//      rax, rbx
 void InterpreterMacroAssembler::lock_object(Register lock_reg) {
   assert(lock_reg == LP64_ONLY(c_rarg1) NOT_LP64(rdx),
          "The argument is only for looks. It must be c_rarg1");
@@ -1049,6 +1048,8 @@
     Label done;
 
     const Register swap_reg = rax; // Must use rax for cmpxchg instruction
+    const Register tmp_reg = rbx; // Will be passed to biased_locking_enter to avoid a
+                                  // problematic case where tmp_reg = no_reg.
     const Register obj_reg = LP64_ONLY(c_rarg3) NOT_LP64(rcx); // Will contain the oop
 
     const int obj_offset = BasicObjectLock::obj_offset_in_bytes();
@@ -1062,7 +1063,7 @@
     movptr(obj_reg, Address(lock_reg, obj_offset));
 
     if (UseBiasedLocking) {
-      biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, done, &slow_case);
+      biased_locking_enter(lock_reg, obj_reg, swap_reg, tmp_reg, false, done, &slow_case);
     }
 
     // Load immediate 1 into swap_reg %rax
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Thu May 14 12:05:32 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Sat May 16 13:19:11 2015 -0700
@@ -1069,15 +1069,8 @@
                                          BiasedLockingCounters* counters) {
   assert(UseBiasedLocking, "why call this otherwise?");
   assert(swap_reg == rax, "swap_reg must be rax for cmpxchgq");
-  LP64_ONLY( assert(tmp_reg != noreg, "tmp_reg must be supplied"); )
-  bool need_tmp_reg = false;
-  if (tmp_reg == noreg) {
-    need_tmp_reg = true;
-    tmp_reg = lock_reg;
-    assert_different_registers(lock_reg, obj_reg, swap_reg);
-  } else {
-    assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg);
-  }
+  assert(tmp_reg != noreg, "tmp_reg must be supplied");
+  assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg);
   assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout");
   Address mark_addr      (obj_reg, oopDesc::mark_offset_in_bytes());
   Address saved_mark_addr(lock_reg, 0);
@@ -1097,15 +1090,9 @@
     null_check_offset = offset();
     movptr(swap_reg, mark_addr);
   }
-  if (need_tmp_reg) {
-    push(tmp_reg);
-  }
   movptr(tmp_reg, swap_reg);
   andptr(tmp_reg, markOopDesc::biased_lock_mask_in_place);
   cmpptr(tmp_reg, markOopDesc::biased_lock_pattern);
-  if (need_tmp_reg) {
-    pop(tmp_reg);
-  }
   jcc(Assembler::notEqual, cas_label);
   // The bias pattern is present in the object's header. Need to check
   // whether the bias owner and the epoch are both still current.
@@ -1117,9 +1104,6 @@
   // simpler.
   movptr(saved_mark_addr, swap_reg);
 #endif
-  if (need_tmp_reg) {
-    push(tmp_reg);
-  }
   if (swap_reg_contains_mark) {
     null_check_offset = offset();
   }
@@ -1135,9 +1119,6 @@
   Register header_reg = swap_reg;
 #endif
   andptr(header_reg, ~((int) markOopDesc::age_mask_in_place));
-  if (need_tmp_reg) {
-    pop(tmp_reg);
-  }
   if (counters != NULL) {
     cond_inc32(Assembler::zero,
                ExternalAddress((address) counters->biased_lock_entry_count_addr()));
@@ -1180,9 +1161,6 @@
   NOT_LP64( movptr(swap_reg, saved_mark_addr); )
   andptr(swap_reg,
          markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place);
-  if (need_tmp_reg) {
-    push(tmp_reg);
-  }
 #ifdef _LP64
   movptr(tmp_reg, swap_reg);
   orptr(tmp_reg, r15_thread);
@@ -1194,9 +1172,6 @@
     lock();
   }
   cmpxchgptr(tmp_reg, mark_addr); // compare tmp_reg and swap_reg
-  if (need_tmp_reg) {
-    pop(tmp_reg);
-  }
   // If the biasing toward our thread failed, this means that
   // another thread succeeded in biasing it toward itself and we
   // need to revoke that bias. The revocation will occur in the
@@ -1220,9 +1195,6 @@
   //
   // FIXME: due to a lack of registers we currently blow away the age
   // bits in this situation. Should attempt to preserve them.
-  if (need_tmp_reg) {
-    push(tmp_reg);
-  }
   load_prototype_header(tmp_reg, obj_reg);
 #ifdef _LP64
   orptr(tmp_reg, r15_thread);
@@ -1235,9 +1207,6 @@
     lock();
   }
   cmpxchgptr(tmp_reg, mark_addr); // compare tmp_reg and swap_reg
-  if (need_tmp_reg) {
-    pop(tmp_reg);
-  }
   // If the biasing toward our thread failed, then another thread
   // succeeded in biasing it toward itself and we need to revoke that
   // bias. The revocation will occur in the runtime in the slow case.
@@ -1263,17 +1232,11 @@
   // FIXME: due to a lack of registers we currently blow away the age
   // bits in this situation. Should attempt to preserve them.
   NOT_LP64( movptr(swap_reg, saved_mark_addr); )
-  if (need_tmp_reg) {
-    push(tmp_reg);
-  }
   load_prototype_header(tmp_reg, obj_reg);
   if (os::is_MP()) {
     lock();
   }
   cmpxchgptr(tmp_reg, mark_addr); // compare tmp_reg and swap_reg
-  if (need_tmp_reg) {
-    pop(tmp_reg);
-  }
   // Fall through to the normal CAS-based lock, because no matter what
   // the result of the above CAS, some thread must have succeeded in
   // removing the bias bit from the object's header.
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Thu May 14 12:05:32 2015 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Sat May 16 13:19:11 2015 -0700
@@ -5878,14 +5878,6 @@
 
 extern char** environ;
 
-#ifndef __NR_fork
-  #define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57) AARCH64_ONLY(1079)
-#endif
-
-#ifndef __NR_execve
-  #define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59) AARCH64_ONLY(221)
-#endif
-
 // Run the specified command in a separate process. Return its exit value,
 // or -1 on failure (e.g. can't fork a new process).
 // Unlike system(), this function can be called from signal handler. It
@@ -5893,13 +5885,7 @@
 int os::fork_and_exec(char* cmd) {
   const char * argv[4] = {"sh", "-c", cmd, NULL};
 
-  // fork() in LinuxThreads/NPTL is not async-safe. It needs to run
-  // pthread_atfork handlers and reset pthread library. All we need is a
-  // separate process to execve. Make a direct syscall to fork process.
-  // On IA64 there's no fork syscall, we have to use fork() and hope for
-  // the best...
-  pid_t pid = NOT_IA64(syscall(__NR_fork);)
-  IA64_ONLY(fork();)
+  pid_t pid = fork();
 
   if (pid < 0) {
     // fork failed
@@ -5908,15 +5894,7 @@
   } else if (pid == 0) {
     // child process
 
-    // execve() in LinuxThreads will call pthread_kill_other_threads_np()
-    // first to kill every thread on the thread list. Because this list is
-    // not reset by fork() (see notes above), execve() will instead kill
-    // every thread in the parent process. We know this is the only thread
-    // in the new process, so make a system call directly.
-    // IA64 should use normal execve() from glibc to match the glibc fork()
-    // above.
-    NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);)
-    IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
+    execve("/bin/sh", (char* const*)argv, environ);
 
     // execve failed
     _exit(-1);
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp	Thu May 14 12:05:32 2015 -0700
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp	Sat May 16 13:19:11 2015 -0700
@@ -1587,6 +1587,26 @@
   result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK);
 }
 
+static void wrap_invokedynamic_exception(TRAPS) {
+  if (HAS_PENDING_EXCEPTION) {
+    if (TraceMethodHandles) {
+      tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION));
+      PENDING_EXCEPTION->print();
+    }
+    if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) {
+      // throw these guys, since they are already wrapped
+      return;
+    }
+    if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
+      // intercept only LinkageErrors which might have failed to wrap
+      return;
+    }
+    // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS.
+    Handle nested_exception(THREAD, PENDING_EXCEPTION);
+    CLEAR_PENDING_EXCEPTION;
+    THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception)
+  }
+}
 
 void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
   //resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK);
@@ -1600,7 +1620,8 @@
   ConstantPoolCacheEntry* cpce = pool->invokedynamic_cp_cache_entry_at(index);
   if (cpce->is_f1_null()) {
     int pool_index = cpce->constant_pool_index();
-    oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, CHECK);
+    oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, THREAD);
+    wrap_invokedynamic_exception(CHECK);
     assert(bsm_info != NULL, "");
     // FIXME: Cache this once per BootstrapMethods entry, not once per CONSTANT_InvokeDynamic.
     bootstrap_specifier = Handle(THREAD, bsm_info);
@@ -1609,7 +1630,8 @@
     methodHandle method(     THREAD, cpce->f1_as_method());
     Handle       appendix(   THREAD, cpce->appendix_if_resolved(pool));
     Handle       method_type(THREAD, cpce->method_type_if_resolved(pool));
-    result.set_handle(method, appendix, method_type, CHECK);
+    result.set_handle(method, appendix, method_type, THREAD);
+    wrap_invokedynamic_exception(CHECK);
     return;
   }
 
@@ -1640,25 +1662,9 @@
                                                      &resolved_appendix,
                                                      &resolved_method_type,
                                                      THREAD);
-  if (HAS_PENDING_EXCEPTION) {
-    if (TraceMethodHandles) {
-      tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION));
-      PENDING_EXCEPTION->print();
-    }
-    if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) {
-      // throw these guys, since they are already wrapped
-      return;
-    }
-    if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
-      // intercept only LinkageErrors which might have failed to wrap
-      return;
-    }
-    // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS.
-    Handle nested_exception(THREAD, PENDING_EXCEPTION);
-    CLEAR_PENDING_EXCEPTION;
-    THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception)
-  }
-  result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK);
+  wrap_invokedynamic_exception(CHECK);
+  result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD);
+  wrap_invokedynamic_exception(CHECK);
 }
 
 //------------------------------------------------------------------------------------------------------------------------
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Thu May 14 12:05:32 2015 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Sat May 16 13:19:11 2015 -0700
@@ -1062,7 +1062,9 @@
       out.print_raw   (cmd);
       out.print_raw_cr("\" ...");
 
-      os::fork_and_exec(cmd);
+      if (os::fork_and_exec(cmd) < 0) {
+        out.print_cr("os::fork_and_exec failed: %s (%d)", strerror(errno), errno);
+      }
     }
 
     // done with OnError
@@ -1147,7 +1149,9 @@
 #endif
     tty->print_cr("\"%s\"...", cmd);
 
-    os::fork_and_exec(cmd);
+    if (os::fork_and_exec(cmd) < 0) {
+      tty->print_cr("os::fork_and_exec failed: %s (%d)", strerror(errno), errno);
+    }
   }
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/ErrorHandling/TestOnError.java	Sat May 16 13:19:11 2015 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, 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 TestOnError
+ * @summary Test using -XX:OnError=<cmd>
+ * @library /testlibrary
+ * @build TestOnError
+ * @run main TestOnError
+ * @bug 8078470
+ */
+
+import jdk.test.lib.*;
+
+public class TestOnError {
+
+    public static void main(String[] args) throws Exception {
+        if (!Platform.isDebugBuild()) {
+            System.out.println("Test requires a non-product build - skipping");
+            return;
+        }
+
+        String msg = "Test Succeeded";
+
+        // Execute the VM so that a
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+           "-XX:-TransmitErrorReport",
+           "-XX:ErrorHandlerTest=12", // trigger potential SEGV
+           "-XX:OnError=echo " + msg,
+           TestOnError.class.getName());
+
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+        /* Actual output will include:
+           #
+           # -XX:OnError="echo Test Succeeded"
+           #   Executing /bin/sh -c "echo Test Succeeded"...
+           Test Succeeded
+
+           So we don't want to match on the "# Executing ..." line, and they
+           both get written to stdout.
+        */
+        output.stdoutShouldMatch("^" + msg); // match start of line only
+        System.out.println("PASSED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/ErrorHandling/TestOnOutOfMemoryError.java	Sat May 16 13:19:11 2015 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015, 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 TestOnOutOfMemoryError
+ * @summary Test using -XX:OnOutOfMemoryError=<cmd>
+ * @library /testlibrary
+ * @build TestOnOutOfMemoryError
+ * @run main TestOnOutOfMemoryError
+ * @bug 8078470
+ */
+
+import jdk.test.lib.*;
+
+public class TestOnOutOfMemoryError {
+
+    public static void main(String[] args) throws Exception {
+        if (args.length == 1) {
+            // This should guarantee to throw:
+            //  java.lang.OutOfMemoryError: Requested array size exceeds VM limit
+            Object[] oa = new Object[Integer.MAX_VALUE];
+            return;
+        }
+
+        // else this is the main test
+        String msg = "Test Succeeded";
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+           "-XX:OnOutOfMemoryError=echo " + msg,
+           TestOnOutOfMemoryError.class.getName(),
+           "throwOOME");
+
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+        /* Actual output should look like this:
+           #
+           # java.lang.OutOfMemoryError: Requested array size exceeds VM limit
+           # -XX:OnOutOfMemoryError="echo Test Succeeded"
+           #   Executing /bin/sh -c "echo Test Succeeded"...
+           Test Succeeded
+           Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
+           at OOME.main(OOME.java:3)
+
+           So we don't want to match on the "# Executing ..." line, and they
+           both get written to stdout.
+        */
+        output.shouldContain("Requested array size exceeds VM limit");
+        output.stdoutShouldMatch("^" + msg); // match start of line only
+        System.out.println("PASSED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/invokedynamic/BootstrapMethodErrorTest.java	Sat May 16 13:19:11 2015 -0700
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2015, 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 8051045
+ * @summary Test that exceptions from invokedynamic are wrapped in BootstrapMethodError
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @run main BootstrapMethodErrorTest
+ */
+
+import java.lang.reflect.Method;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Handle;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+public class BootstrapMethodErrorTest extends ClassLoader implements Opcodes {
+
+  @Override
+  public Class findClass(String name) throws ClassNotFoundException {
+    byte[] b;
+    try {
+      b = loadClassData(name);
+    } catch (Throwable th) {
+      throw new ClassNotFoundException("Loading error", th);
+    }
+    return defineClass(name, b, 0, b.length);
+  }
+
+  private byte[] loadClassData(String name) throws Exception {
+    ClassWriter cw = new ClassWriter(0);
+    MethodVisitor mv;
+
+    if (name.equals("C")) {
+      cw.visit(52, ACC_SUPER | ACC_PUBLIC, "C", null, "java/lang/Object", null);
+      {
+        mv = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, "m", "()V", null, null);
+        mv.visitCode();
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(0, 1);
+        mv.visitEnd();
+      }
+      cw.visitEnd();
+      return cw.toByteArray();
+    } else if (name.equals("Exec")) {
+      cw.visit(52, ACC_SUPER | ACC_PUBLIC, "Exec", null, "java/lang/Object", null);
+      {
+        mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "invokeRef", "()V", null, null);
+        mv.visitCode();
+        Handle h = new Handle(H_INVOKESTATIC, "C", "m", "()V");
+        mv.visitInvokeDynamicInsn("C", "()V", h);
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+      }
+      cw.visitEnd();
+      return cw.toByteArray();
+    }
+    return null;
+  }
+
+  public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, NoSuchMethodException {
+    new BootstrapMethodErrorTest().test();
+  }
+
+  public void test() throws ClassNotFoundException, IllegalAccessException, NoSuchMethodException {
+    Class.forName("C", true, this);
+    Class<?> exec = Class.forName("Exec", true, this);
+
+    try {
+      exec.getMethod("invokeRef").invoke(null);
+    } catch (Throwable e) {
+      Throwable c = e.getCause();
+      if (c == null) {
+        throw new RuntimeException(
+            "Expected BootstrapMethodError wrapped in an InvocationTargetException but it wasn't wrapped", e);
+      } else if (c instanceof BootstrapMethodError) {
+        // Only way to pass test, all else should throw
+        return;
+      } else {
+        throw new RuntimeException(
+            "Expected BootstrapMethodError but got another Error: "
+            + c.getClass().getName(),
+            c);
+      }
+    }
+    throw new RuntimeException("Expected BootstrapMethodError but no Error at all was thrown");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jni/8025979/UninitializedStrings.java	Sat May 16 13:19:11 2015 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2015, 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 8025979
+ * @summary
+ * regression tests for 8025922, verify uninitialized strings reference.
+ * Affects:
+ * GetStringLength
+ * GetStringChars
+ * GetStringUTFLength
+ * GetStringUTFChars
+ * @run main/native UninitializedStrings all
+ */
+
+public class UninitializedStrings {
+
+    static {
+        System.loadLibrary("UninitializedStrings");
+    }
+
+    native static void lengthTest();
+
+    native static void charsTest();
+
+    native static void utfLengthTest();
+
+    native static void utfCharsTest();
+
+    /**
+     * @param args the command line arguments
+     * @throws java.lang.Exception
+     */
+    public static void main(String[] args) throws Exception {
+        if (args.length != 1) {
+            throw new RuntimeException("invalid number of input arguments");
+        }
+
+        switch (args[0]) {
+            case "length":
+                lengthTest();
+                break;
+            case "chars":
+                charsTest();
+                break;
+            case "utf_length":
+                utfLengthTest();
+                break;
+            case "utf_chars":
+                utfCharsTest();
+                break;
+            default:
+                lengthTest();
+                charsTest();
+                utfLengthTest();
+                utfCharsTest();
+                break;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jni/8025979/libUninitializedStrings.c	Sat May 16 13:19:11 2015 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#include "jni.h"
+
+//Method to verify expression and throw java/lang/Exception if it is FALSE
+void Assert(JNIEnv *jni_env, jint expr, const char* message) {
+    if(expr == 0){ //if expr is false
+        (*jni_env)->FatalError(jni_env, message);
+    }
+}
+
+//Method to allocate a java/lang/String object and return jstring as a result
+jstring AllocateString(JNIEnv *jni_env) {
+    jclass classString = NULL;
+    jstring allocatedString = NULL;
+    classString = (*jni_env)->FindClass(jni_env, "java/lang/String");
+    //NULL check
+    Assert(jni_env, (classString != NULL), "class String not found");
+    //allocate object of type java/lang/String
+    allocatedString = (jstring) (*jni_env)->AllocObject(jni_env, classString);
+    //NULL check
+    Assert(jni_env, (allocatedString != NULL), "allocated string is NULL");
+    return allocatedString;
+}
+
+//GetStringLength test
+JNIEXPORT void JNICALL Java_UninitializedStrings_lengthTest
+(JNIEnv *jni_env, jclass cl) {
+    jint stringLength = 0;
+    jstring allocatedString = NULL;
+    //allocate object of type java/lang/String
+    allocatedString = AllocateString(jni_env);
+
+    stringLength = (*jni_env)->GetStringLength(jni_env, allocatedString);
+    Assert(jni_env, (stringLength == 0), "string length must be 0");
+}
+
+//GetStringChars test
+JNIEXPORT void JNICALL Java_UninitializedStrings_charsTest
+(JNIEnv *jni_env, jclass cl) {
+    jint compareRes = 0;
+    const jchar* stringChars = NULL;
+    jstring allocatedString = NULL;
+    //allocate object of type java/lang/String
+    allocatedString = AllocateString(jni_env);
+
+    stringChars = (*jni_env)->GetStringChars(jni_env, allocatedString, NULL);
+    compareRes = (stringChars == NULL);
+    //release stringChars pointer
+    (*jni_env)->ReleaseStringChars(jni_env, allocatedString, stringChars);
+    Assert(jni_env, compareRes, "string chars must be NULL");
+}
+
+//GetStringUTFLength test
+JNIEXPORT void JNICALL Java_UninitializedStrings_utfLengthTest
+(JNIEnv *jni_env, jclass cl) {
+    jint stringLength = 0;
+    jstring allocatedString = NULL;
+    //allocate object of type java/lang/String
+    allocatedString = AllocateString(jni_env);
+
+    stringLength = (*jni_env)->GetStringUTFLength(jni_env, allocatedString);
+    Assert(jni_env, (stringLength == 0), "string utf length must be 0");
+}
+
+//GetStringUTFChars test
+JNIEXPORT void JNICALL Java_UninitializedStrings_utfCharsTest
+(JNIEnv *jni_env, jclass cl) {
+    jint compareRes = 0;
+    const char* stringUtfChars = NULL;
+    jstring allocatedString = NULL;
+    //allocate object of type java/lang/String
+    allocatedString = AllocateString(jni_env);
+
+    stringUtfChars = (*jni_env)->GetStringUTFChars(jni_env, allocatedString, NULL);
+    compareRes = (stringUtfChars == NULL);
+    //release stringUtfChars pointer
+    (*jni_env)->ReleaseStringUTFChars(jni_env, allocatedString, stringUtfChars);
+    Assert(jni_env, compareRes, "string utf chars must be NULL");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jni/8033445/DefaultMethods.java	Sat May 16 13:19:11 2015 -0700
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015, 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 8033445
+ * @summary regression tests for 8033445, verify default methods call from JNI
+ * @run main/native DefaultMethods
+ */
+
+interface A {
+
+    default int getOne() {
+        return 1;
+    }
+}
+
+interface B extends A {
+
+}
+
+interface C extends B {
+
+    @Override
+    default int getOne() {
+        return 2;
+    }
+}
+
+abstract class Abstract implements C {
+}
+
+class Impl extends Abstract {
+
+    @Override
+    public int getOne() {
+        return 3;
+    }
+}
+
+class Impl2 extends Impl {
+
+    public static final int expectedValue = 4;
+
+    @Override
+    public int getOne() {
+        return expectedValue;
+    }
+}
+
+public class DefaultMethods {
+
+    static {
+        System.loadLibrary("DefaultMethods");
+    }
+
+    static native int callAndVerify(Impl impl, String className, int expectedResult, int implExpectedResult);
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        Impl2 impl2 = new Impl2();
+        if (args.length == 0) {
+            callAndVerify(impl2, "A", 1, Impl2.expectedValue);
+            callAndVerify(impl2, "B", 1, Impl2.expectedValue);
+            callAndVerify(impl2, "C", 2, Impl2.expectedValue);
+            callAndVerify(impl2, "Abstract", 2, Impl2.expectedValue);
+            callAndVerify(impl2, "Impl", 3, Impl2.expectedValue);
+            callAndVerify(impl2, "Impl2", 4, Impl2.expectedValue);
+        } else {
+            verifyAndRun(args, impl2, Impl2.expectedValue);
+        }
+    }
+
+    //Method to verify input arguments and run a specific test with an expected result provided in the args array
+    static void verifyAndRun(String[] args, Impl2 impl, int expectedValue) {
+        if (args.length != 2) {
+            throw new RuntimeException("invalid number of input arguments");
+        }
+
+        String className = args[0];
+        int expectedResult = Integer.parseInt(args[1]);
+
+        callAndVerify(impl, className, expectedResult, expectedValue);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/jni/8033445/libDefaultMethods.c	Sat May 16 13:19:11 2015 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2015, 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.
+ */
+
+#include <jni.h>
+
+//Default methods call test
+JNIEXPORT void JNICALL
+Java_DefaultMethods_callAndVerify(JNIEnv *env, jclass unused, jobject impl, jstring klass_name, jint expected_result, jint impl_expected_result) {
+
+    jmethodID getOne_id = NULL;
+    jint res = 0;
+    jclass clazz = NULL;
+    const char* class_name = NULL;
+
+    class_name = (*env)->GetStringUTFChars(env, klass_name, NULL);
+
+    clazz = (*env)->FindClass(env, class_name);
+    (*env)->ReleaseStringUTFChars(env, klass_name, class_name);
+    if (clazz == NULL) {
+        (*env)->FatalError(env, "could not find class");
+    }
+
+    getOne_id = (*env)->GetMethodID(env, clazz, "getOne", "()I");
+    if (getOne_id == NULL) {
+        (*env)->FatalError(env, "could not find method");
+    }
+
+    res = (*env)->CallNonvirtualIntMethod(env, impl, clazz, getOne_id);
+
+    if (res != expected_result) {
+        (*env)->FatalError(env, "wrong return value");
+    }
+
+    res = (*env)->CallIntMethod(env, impl, getOne_id);
+
+    if (res != impl_expected_result) {
+        (*env)->FatalError(env, "wrong return value");
+    }
+}