changeset 2765:11d17c7d2ee6

Merge
author iveresov
date Sun, 16 Oct 2011 02:59:24 -0700
parents bc257a801090 (current diff) 4bac06a82bc3 (diff)
children 23a1c8de9d51 8187c94a9a87
files
diffstat 20 files changed, 317 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/sparc/vm/sparc.ad	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/cpu/sparc/vm/sparc.ad	Sun Oct 16 02:59:24 2011 -0700
@@ -10476,7 +10476,7 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct countTrailingZerosL(iRegI dst, iRegL src, flagsReg cr) %{
+instruct countTrailingZerosL(iRegIsafe dst, iRegL src, flagsReg cr) %{
   predicate(UsePopCountInstruction);  // See Matcher::match_rule_supported
   match(Set dst (CountTrailingZerosL src));
   effect(TEMP dst, KILL cr);
--- a/src/cpu/x86/vm/frame_x86.cpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/cpu/x86/vm/frame_x86.cpp	Sun Oct 16 02:59:24 2011 -0700
@@ -232,11 +232,13 @@
 
 
 void frame::patch_pc(Thread* thread, address pc) {
+  address* pc_addr = &(((address*) sp())[-1]);
   if (TracePcPatching) {
-    tty->print_cr("patch_pc at address" INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "] ",
-                  &((address *)sp())[-1], ((address *)sp())[-1], pc);
+    tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "] ",
+                  pc_addr, *pc_addr, pc);
   }
-  ((address *)sp())[-1] = pc;
+  assert(_pc == *pc_addr, err_msg("must be: " INTPTR_FORMAT " == " INTPTR_FORMAT, _pc, *pc_addr));
+  *pc_addr = pc;
   _cb = CodeCache::find_blob(pc);
   address original_pc = nmethod::get_deopt_original_pc(this);
   if (original_pc != NULL) {
@@ -671,4 +673,3 @@
   // used to reset the saved FP
   return fp();
 }
-
--- a/src/cpu/x86/vm/methodHandles_x86.cpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Sun Oct 16 02:59:24 2011 -0700
@@ -410,8 +410,8 @@
 
 void MethodHandles::RicochetFrame::verify() const {
   verify_offsets();
-  assert(magic_number_1() == MAGIC_NUMBER_1, "");
-  assert(magic_number_2() == MAGIC_NUMBER_2, "");
+  assert(magic_number_1() == MAGIC_NUMBER_1, err_msg(PTR_FORMAT " == " PTR_FORMAT, magic_number_1(), MAGIC_NUMBER_1));
+  assert(magic_number_2() == MAGIC_NUMBER_2, err_msg(PTR_FORMAT " == " PTR_FORMAT, magic_number_2(), MAGIC_NUMBER_2));
   if (!Universe::heap()->is_gc_active()) {
     if (saved_args_layout() != NULL) {
       assert(saved_args_layout()->is_method(), "must be valid oop");
--- a/src/cpu/x86/vm/methodHandles_x86.hpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/cpu/x86/vm/methodHandles_x86.hpp	Sun Oct 16 02:59:24 2011 -0700
@@ -132,7 +132,10 @@
   intptr_t* sender_link() const         { return _sender_link; }
   address   sender_pc() const           { return _sender_pc; }
 
-  intptr_t* extended_sender_sp() const  { return saved_args_base(); }
+  intptr_t* extended_sender_sp() const {
+    // The extended sender SP is above the current RicochetFrame.
+    return (intptr_t*) (((address) this) + sizeof(RicochetFrame));
+  }
 
   intptr_t  return_value_slot_number() const {
     return adapter_conversion_vminfo(conversion());
--- a/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Sun Oct 16 02:59:24 2011 -0700
@@ -1165,11 +1165,11 @@
   Goto *x = new Goto(block_at(to_bci), to_bci <= from_bci);
   if (is_profiling()) {
     compilation()->set_would_profile(true);
-  }
-  if (profile_branches()) {
-    x->set_profiled_method(method());
     x->set_profiled_bci(bci());
-    x->set_should_profile(true);
+    if (profile_branches()) {
+      x->set_profiled_method(method());
+      x->set_should_profile(true);
+    }
   }
   append(x);
 }
@@ -1203,9 +1203,9 @@
     Goto *goto_node = i->as_Goto();
     if (goto_node != NULL) {
       compilation()->set_would_profile(true);
+      goto_node->set_profiled_bci(bci());
       if (profile_branches()) {
         goto_node->set_profiled_method(method());
-        goto_node->set_profiled_bci(bci());
         goto_node->set_should_profile(true);
         // Find out which successor is used.
         if (goto_node->default_sux() == tsux) {
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Sun Oct 16 02:59:24 2011 -0700
@@ -2493,7 +2493,7 @@
 
     // increment backedge counter if needed
     CodeEmitInfo* info = state_for(x, state);
-    increment_backedge_counter(info, info->stack()->bci());
+    increment_backedge_counter(info, x->profiled_bci());
     CodeEmitInfo* safepoint_info = state_for(x, state);
     __ safepoint(safepoint_poll_register(), safepoint_info);
   }
--- a/src/share/vm/c1/c1_LinearScan.cpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/c1/c1_LinearScan.cpp	Sun Oct 16 02:59:24 2011 -0700
@@ -2619,6 +2619,24 @@
 
     Location::Type loc_type = float_saved_as_double ? Location::float_in_dbl : Location::normal;
     VMReg rname = frame_map()->fpu_regname(opr->fpu_regnr());
+#ifndef __SOFTFP__
+#ifndef VM_LITTLE_ENDIAN
+    if (! float_saved_as_double) {
+      // On big endian system, we may have an issue if float registers use only
+      // the low half of the (same) double registers.
+      // Both the float and the double could have the same regnr but would correspond
+      // to two different addresses once saved.
+
+      // get next safely (no assertion checks)
+      VMReg next = VMRegImpl::as_VMReg(1+rname->value());
+      if (next->is_reg() &&
+          (next->as_FloatRegister() == rname->as_FloatRegister())) {
+        // the back-end does use the same numbering for the double and the float
+        rname = next; // VMReg for the low bits, e.g. the real VMReg for the float
+      }
+    }
+#endif
+#endif
     LocationValue* sv = new LocationValue(Location::new_reg_loc(loc_type, rname));
 
     scope_values->append(sv);
--- a/src/share/vm/ci/ciEnv.cpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/ci/ciEnv.cpp	Sun Oct 16 02:59:24 2011 -0700
@@ -473,6 +473,7 @@
   }
 
   if (require_local)  return NULL;
+
   // Not yet loaded into the VM, or not governed by loader constraints.
   // Make a CI representative for it.
   return get_unloaded_klass(accessing_klass, name);
@@ -498,7 +499,7 @@
                                         bool& is_accessible,
                                         ciInstanceKlass* accessor) {
   EXCEPTION_CONTEXT;
-  KlassHandle klass (THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index));
+  KlassHandle klass(THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index));
   Symbol* klass_name = NULL;
   if (klass.is_null()) {
     // The klass has not been inserted into the constant pool.
@@ -785,17 +786,17 @@
   // Either the declared holder was not loaded, or the method could
   // not be found.  Create a dummy ciMethod to represent the failed
   // lookup.
-
-  return get_unloaded_method(declared_holder,
-                             get_symbol(name_sym),
-                             get_symbol(sig_sym));
+  ciSymbol* name      = get_symbol(name_sym);
+  ciSymbol* signature = get_symbol(sig_sym);
+  return get_unloaded_method(declared_holder, name, signature, accessor);
 }
 
 
 // ------------------------------------------------------------------
 // ciEnv::get_fake_invokedynamic_method_impl
 ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
-                                                    int index, Bytecodes::Code bc) {
+                                                    int index, Bytecodes::Code bc,
+                                                    ciInstanceKlass* accessor) {
   // Compare the following logic with InterpreterRuntime::resolve_invokedynamic.
   assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic");
 
@@ -807,9 +808,10 @@
   // Call site might not be resolved yet.  We could create a real invoker method from the
   // compiler, but it is simpler to stop the code path here with an unlinked method.
   if (!is_resolved) {
-    ciInstanceKlass* mh_klass = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass();
-    ciSymbol*        sig_sym  = get_symbol(cpool->signature_ref_at(index));
-    return get_unloaded_method(mh_klass, ciSymbol::invokeExact_name(), sig_sym);
+    ciInstanceKlass* holder    = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass();
+    ciSymbol*        name      = ciSymbol::invokeExact_name();
+    ciSymbol*        signature = get_symbol(cpool->signature_ref_at(index));
+    return get_unloaded_method(holder, name, signature, accessor);
   }
 
   // Get the invoker methodOop from the constant pool.
@@ -850,9 +852,9 @@
                                      int index, Bytecodes::Code bc,
                                      ciInstanceKlass* accessor) {
   if (bc == Bytecodes::_invokedynamic) {
-    GUARDED_VM_ENTRY(return get_fake_invokedynamic_method_impl(cpool, index, bc);)
+    GUARDED_VM_ENTRY(return get_fake_invokedynamic_method_impl(cpool, index, bc, accessor);)
   } else {
-    GUARDED_VM_ENTRY(return get_method_by_index_impl(cpool, index, bc, accessor);)
+    GUARDED_VM_ENTRY(return get_method_by_index_impl(          cpool, index, bc, accessor);)
   }
 }
 
--- a/src/share/vm/ci/ciEnv.hpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/ci/ciEnv.hpp	Sun Oct 16 02:59:24 2011 -0700
@@ -153,7 +153,8 @@
                                       int method_index, Bytecodes::Code bc,
                                       ciInstanceKlass* loading_klass);
   ciMethod*  get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
-                                                int index, Bytecodes::Code bc);
+                                                int index, Bytecodes::Code bc,
+                                                ciInstanceKlass* accessor);
 
   // Helper methods
   bool       check_klass_accessibility(ciKlass* accessing_klass,
@@ -192,13 +193,14 @@
   // the result.
   ciMethod* get_unloaded_method(ciInstanceKlass* holder,
                                 ciSymbol*        name,
-                                ciSymbol*        signature) {
-    return _factory->get_unloaded_method(holder, name, signature);
+                                ciSymbol*        signature,
+                                ciInstanceKlass* accessor) {
+    return _factory->get_unloaded_method(holder, name, signature, accessor);
   }
 
   // Get a ciKlass representing an unloaded klass.
   // Ensures uniqueness of the result.
-  ciKlass* get_unloaded_klass(ciKlass* accessing_klass,
+  ciKlass* get_unloaded_klass(ciKlass*  accessing_klass,
                               ciSymbol* name) {
     return _factory->get_unloaded_klass(accessing_klass, name, true);
   }
@@ -224,7 +226,7 @@
 
   // See if we already have an unloaded klass for the given name
   // or return NULL if not.
-  ciKlass *check_get_unloaded_klass(ciKlass* accessing_klass, ciSymbol* name) {
+  ciKlass *check_get_unloaded_klass(ciKlass*  accessing_klass, ciSymbol* name) {
     return _factory->get_unloaded_klass(accessing_klass, name, false);
   }
 
--- a/src/share/vm/ci/ciMethod.cpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/ci/ciMethod.cpp	Sun Oct 16 02:59:24 2011 -0700
@@ -148,21 +148,27 @@
 //
 // Unloaded method.
 ciMethod::ciMethod(ciInstanceKlass* holder,
-                   ciSymbol* name,
-                   ciSymbol* signature) : ciObject(ciMethodKlass::make()) {
-  // These fields are always filled in.
-  _name = name;
-  _holder = holder;
-  _signature = new (CURRENT_ENV->arena()) ciSignature(_holder, constantPoolHandle(), signature);
-  _intrinsic_id = vmIntrinsics::_none;
-  _liveness = NULL;
-  _can_be_statically_bound = false;
-  _method_blocks = NULL;
-  _method_data = NULL;
+                   ciSymbol*        name,
+                   ciSymbol*        signature,
+                   ciInstanceKlass* accessor) :
+  ciObject(ciMethodKlass::make()),
+  _name(                   name),
+  _holder(                 holder),
+  _intrinsic_id(           vmIntrinsics::_none),
+  _liveness(               NULL),
+  _can_be_statically_bound(false),
+  _method_blocks(          NULL),
+  _method_data(            NULL)
 #if defined(COMPILER2) || defined(SHARK)
-  _flow = NULL;
-  _bcea = NULL;
+  ,
+  _flow(                   NULL),
+  _bcea(                   NULL)
 #endif // COMPILER2 || SHARK
+{
+  // Usually holder and accessor are the same type but in some cases
+  // the holder has the wrong class loader (e.g. invokedynamic call
+  // sites) so we pass the accessor.
+  _signature = new (CURRENT_ENV->arena()) ciSignature(accessor, constantPoolHandle(), signature);
 }
 
 
--- a/src/share/vm/ci/ciMethod.hpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/ci/ciMethod.hpp	Sun Oct 16 02:59:24 2011 -0700
@@ -88,7 +88,7 @@
 #endif
 
   ciMethod(methodHandle h_m);
-  ciMethod(ciInstanceKlass* holder, ciSymbol* name, ciSymbol* signature);
+  ciMethod(ciInstanceKlass* holder, ciSymbol* name, ciSymbol* signature, ciInstanceKlass* accessor);
 
   methodOop get_methodOop() const {
     methodOop m = (methodOop)get_oop();
--- a/src/share/vm/ci/ciObjectFactory.cpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/ci/ciObjectFactory.cpp	Sun Oct 16 02:59:24 2011 -0700
@@ -374,20 +374,32 @@
 // unloaded method.  This may need to change.
 ciMethod* ciObjectFactory::get_unloaded_method(ciInstanceKlass* holder,
                                                ciSymbol*        name,
-                                               ciSymbol*        signature) {
-  for (int i=0; i<_unloaded_methods->length(); i++) {
+                                               ciSymbol*        signature,
+                                               ciInstanceKlass* accessor) {
+  ciSignature* that = NULL;
+  for (int i = 0; i < _unloaded_methods->length(); i++) {
     ciMethod* entry = _unloaded_methods->at(i);
     if (entry->holder()->equals(holder) &&
         entry->name()->equals(name) &&
         entry->signature()->as_symbol()->equals(signature)) {
-      // We've found a match.
-      return entry;
+      // Short-circuit slow resolve.
+      if (entry->signature()->accessing_klass() == accessor) {
+        // We've found a match.
+        return entry;
+      } else {
+        // Lazily create ciSignature
+        if (that == NULL)  that = new (arena()) ciSignature(accessor, constantPoolHandle(), signature);
+        if (entry->signature()->equals(that)) {
+          // We've found a match.
+          return entry;
+        }
+      }
     }
   }
 
   // This is a new unloaded method.  Create it and stick it in
   // the cache.
-  ciMethod* new_method = new (arena()) ciMethod(holder, name, signature);
+  ciMethod* new_method = new (arena()) ciMethod(holder, name, signature, accessor);
 
   init_ident_of(new_method);
   _unloaded_methods->append(new_method);
--- a/src/share/vm/ci/ciObjectFactory.hpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/ci/ciObjectFactory.hpp	Sun Oct 16 02:59:24 2011 -0700
@@ -108,7 +108,8 @@
   // Get the ciMethod representing an unloaded/unfound method.
   ciMethod* get_unloaded_method(ciInstanceKlass* holder,
                                 ciSymbol*        name,
-                                ciSymbol*        signature);
+                                ciSymbol*        signature,
+                                ciInstanceKlass* accessor);
 
   // Get a ciKlass representing an unloaded klass.
   ciKlass* get_unloaded_klass(ciKlass* accessing_klass,
--- a/src/share/vm/ci/ciSignature.cpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/ci/ciSignature.cpp	Sun Oct 16 02:59:24 2011 -0700
@@ -80,7 +80,7 @@
 }
 
 // ------------------------------------------------------------------
-// ciSignature::return_ciType
+// ciSignature::return_type
 //
 // What is the return type of this signature?
 ciType* ciSignature::return_type() const {
@@ -88,7 +88,7 @@
 }
 
 // ------------------------------------------------------------------
-// ciSignature::ciType_at
+// ciSignature::type_at
 //
 // What is the type of the index'th element of this
 // signature?
@@ -99,6 +99,24 @@
 }
 
 // ------------------------------------------------------------------
+// ciSignature::equals
+//
+// Compare this signature to another one.  Signatures with different
+// accessing classes but with signature-types resolved to the same
+// types are defined to be equal.
+bool ciSignature::equals(ciSignature* that) {
+  // Compare signature
+  if (!this->as_symbol()->equals(that->as_symbol()))  return false;
+  // Compare all types of the arguments
+  for (int i = 0; i < _count; i++) {
+    if (this->type_at(i) != that->type_at(i))         return false;
+  }
+  // Compare the return type
+  if (this->return_type() != that->return_type())     return false;
+  return true;
+}
+
+// ------------------------------------------------------------------
 // ciSignature::print_signature
 void ciSignature::print_signature() {
   _symbol->print_symbol();
--- a/src/share/vm/ci/ciSignature.hpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/ci/ciSignature.hpp	Sun Oct 16 02:59:24 2011 -0700
@@ -43,6 +43,7 @@
   int _count;
 
   friend class ciMethod;
+  friend class ciObjectFactory;
 
   ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciSymbol* signature);
 
@@ -52,6 +53,7 @@
 
 public:
   ciSymbol* as_symbol() const                    { return _symbol; }
+  ciKlass*  accessing_klass() const              { return _accessing_klass; }
 
   ciType* return_type() const;
   ciType* type_at(int index) const;
@@ -59,6 +61,8 @@
   int       size() const                         { return _size; }
   int       count() const                        { return _count; }
 
+  bool equals(ciSignature* that);
+
   void print_signature();
   void print();
 };
--- a/src/share/vm/opto/runtime.cpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/opto/runtime.cpp	Sun Oct 16 02:59:24 2011 -0700
@@ -997,10 +997,13 @@
         force_unwind ? NULL : nm->handler_for_exception_and_pc(exception, pc);
 
       if (handler_address == NULL) {
+        Handle original_exception(thread, exception());
         handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true);
         assert (handler_address != NULL, "must have compiled handler");
-        // Update the exception cache only when the unwind was not forced.
-        if (!force_unwind) {
+        // Update the exception cache only when the unwind was not forced
+        // and there didn't happen another exception during the computation of the
+        // compiled exception handler.
+        if (!force_unwind && original_exception() == exception()) {
           nm->add_handler_for_exception_and_pc(exception,pc,handler_address);
         }
       } else {
--- a/src/share/vm/prims/methodHandleWalk.cpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/prims/methodHandleWalk.cpp	Sun Oct 16 02:59:24 2011 -0700
@@ -1387,10 +1387,8 @@
   int total = count1 + count2;
   if (count1 != -1 && count2 != -1 && total != 0) {
     // Normalize the collect counts to the invoke_count
-    tty->print("counts %d %d scaled by %d = ", count2, count1, _invoke_count);
     if (count1 != 0) _not_taken_count = (int)(_invoke_count * count1 / (double)total);
     if (count2 != 0) _taken_count = (int)(_invoke_count * count2 / (double)total);
-    tty->print_cr("%d %d", _taken_count, _not_taken_count);
     return true;
   }
   return false;
--- a/src/share/vm/runtime/sharedRuntime.cpp	Fri Oct 14 21:45:37 2011 -0700
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Sun Oct 16 02:59:24 2011 -0700
@@ -659,12 +659,14 @@
   int scope_depth = 0;
   if (!force_unwind) {
     int bci = sd->bci();
+    bool recursive_exception = false;
     do {
       bool skip_scope_increment = false;
       // exception handler lookup
       KlassHandle ek (THREAD, exception->klass());
       handler_bci = sd->method()->fast_exception_handler_bci_for(ek, bci, THREAD);
       if (HAS_PENDING_EXCEPTION) {
+        recursive_exception = true;
         // We threw an exception while trying to find the exception handler.
         // Transfer the new exception to the exception handle which will
         // be set into thread local storage, and do another lookup for an
@@ -680,6 +682,9 @@
           skip_scope_increment = true;
         }
       }
+      else {
+        recursive_exception = false;
+      }
       if (!top_frame_only && handler_bci < 0 && !skip_scope_increment) {
         sd = sd->sender();
         if (sd != NULL) {
@@ -687,7 +692,7 @@
         }
         ++scope_depth;
       }
-    } while (!top_frame_only && handler_bci < 0 && sd != NULL);
+    } while (recursive_exception || (!top_frame_only && handler_bci < 0 && sd != NULL));
   }
 
   // found handling method => lookup exception handler
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/6865265/StackOverflowBug.java	Sun Oct 16 02:59:24 2011 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2011, 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 6865265
+ * @summary JVM crashes with "missing exception handler" error
+ * @author volker.simonis@sap.com
+ *
+ * @run main/othervm -XX:CompileThreshold=100 -Xbatch -Xss128k StackOverflowBug
+ */
+
+
+public class StackOverflowBug {
+
+  public static int run() {
+    try {
+      try {
+        return run();
+      } catch (Throwable e) {
+        // Notice that the class 'Throwable' is NOT resolved by the verifier,
+        // because the verifier only checks if 'Throwable' is assignable to
+        // 'java.lang.Throwable' and this check succeeds immediately if the two
+        // types have equal names (see 'VerificationType::is_assignable_from' which
+        // is called from 'ClassVerifier::verify_exception_handler_table').
+        // This is strange, because if the two classes have different names,
+        // 'is_assignable_from()' calls 'is_reference_assignable_from()' which resolves
+        // both classes by calling 'SystemDictionary::resolve_or_fail()'. This call
+        // also takes into account the current class loader (i.e. the one which was used
+        // to load this class) and would place a corresponding
+        // "java.lang.Throwable / current-Classloader" entry into the system dictionary.
+        // This would in turn allow C2 to see 'java.lang.Throwable' as "loaded"
+        // (see 'Parse::catch_inline_exceptions()') when this method is compiled.
+        return 42;
+      }
+    }
+    finally {
+    }
+  }
+
+  public static void main(String argv[]) {
+    run();
+  }
+}
+
+/*
+  public static int run();
+    Code:
+       0: invokestatic  #2                  // Method run:()I
+       3: istore_0
+       4: iload_0
+       5: ireturn
+       6: astore_0
+       7: bipush        42
+       9: istore_1
+      10: iload_1
+      11: ireturn
+      12: astore_2
+      13: aload_2
+      14: athrow
+    Exception table:
+       from    to  target type
+           0     4     6   Class java/lang/Throwable
+           0     4    12   any
+           6    10    12   any
+          12    13    12   any
+
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/7100757/Test7100757.java	Sun Oct 16 02:59:24 2011 -0700
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2011, 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 7100757
+ * @summary The BitSet.nextSetBit() produces incorrect result in 32bit VM on Sparc
+ *
+ * @run main/timeout=300 Test7100757
+ */
+
+import java.util.*;
+
+public class Test7100757 {
+
+  public static final int NBITS = 256;
+
+  public static void main(String[] args) {
+
+    BitSet bs = new BitSet(NBITS);
+    Random rnd = new Random();
+    long[] ra = new long[(NBITS+63)/64];
+
+    for(int l=0; l < 5000000; l++) {
+
+      for(int r = 0; r < ra.length; r++) {
+        ra[r] = rnd.nextLong();
+      }
+      test(ra, bs);
+    }
+  }
+
+  static void test(long[] ra, BitSet bs) {
+      bs.clear();
+      int bits_set = 0;
+      for(int i = 0, t = 0, b = 0; i < NBITS; i++) {
+        long bit = 1L << b++;
+        if((ra[t]&bit) != 0) {
+          bs.set(i);
+          bits_set++;
+        }
+        if(b == 64) {
+          t++;
+          b = 0;
+        }
+      }
+      // Test Long.bitCount()
+      int check_bits = bs.cardinality();
+      if (check_bits != bits_set) {
+        String bs_str = bs.toString();
+        System.err.printf("cardinality bits: %d != %d  bs: %s\n", check_bits, bits_set, bs_str);
+        System.exit(97);
+      }
+      // Test Long.numberOfTrailingZeros()
+      check_bits = 0;
+      for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
+        check_bits++;
+      }
+      if (check_bits != bits_set) {
+        String bs_str = bs.toString();
+        System.err.printf("nextSetBit bits: %d != %d  bs: %s\n", check_bits, bits_set, bs_str);
+        System.exit(97);
+      }
+      // Test Long.numberOfLeadingZeros()
+      for(int i = bs.length(); i > 0; i = bs.length()) {
+        bs.clear(i-1);
+      }
+      // Test Long.bitCount()
+      check_bits = bs.cardinality();
+      if (check_bits != 0) {
+        String bs_str = bs.toString();
+        System.err.printf("after clear bits: %d != 0  bs: %s\n", check_bits, bs_str);
+        System.exit(97);
+      }
+  }
+
+};