changeset 1355:6ccd32c284ac

Merge
author kamg
date Wed, 07 Apr 2010 12:28:22 -0400
parents 895d9ade6111 (diff) 0fd6320854d3 (current diff)
children e4c77b879561 96d554193f72
files
diffstat 18 files changed, 187 insertions(+), 216 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/zero/vm/cppInterpreter_zero.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -206,7 +206,6 @@
 
   // Update the invocation counter
   if ((UseCompiler || CountCompiledCalls) && !method->is_synchronized()) {
-    thread->set_do_not_unlock();
     InvocationCounter *counter = method->invocation_counter();
     counter->increment();
     if (counter->reached_InvocationLimit()) {
@@ -215,7 +214,6 @@
       if (HAS_PENDING_EXCEPTION)
         goto unwind_and_return;
     }
-    thread->clr_do_not_unlock();
   }
 
   // Lock if necessary
--- a/src/cpu/zero/vm/methodHandles_zero.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/cpu/zero/vm/methodHandles_zero.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
- * Copyright 2009 Red Hat, Inc.
+ * Copyright 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,4 +23,10 @@
  *
  */
 
-// This file is intentionally empty
+#include "incls/_precompiled.incl"
+#include "incls/_methodHandles_zero.cpp.incl"
+
+void MethodHandles::generate_method_handle_stub(MacroAssembler*          masm,
+                                                MethodHandles::EntryKind ek) {
+  ShouldNotCallThis();
+}
--- a/src/cpu/zero/vm/stubRoutines_zero.hpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/cpu/zero/vm/stubRoutines_zero.hpp	Wed Apr 07 12:28:22 2010 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
- * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,10 @@
     code_size2 = 0       // if these are too small.  Simply increase
   };                     // them if that happens.
 
+  enum method_handles_platform_dependent_constants {
+    method_handles_adapters_code_size = 0
+  };
+
 #ifdef IA32
   class x86 {
     friend class VMStructs;
--- a/src/share/vm/ci/ciConstant.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/ci/ciConstant.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -36,7 +36,7 @@
              basictype_to_str(basic_type()));
   switch (basic_type()) {
   case T_BOOLEAN:
-    tty->print("%s", bool_to_str(_value._int == 0));
+    tty->print("%s", bool_to_str(_value._int != 0));
     break;
   case T_CHAR:
   case T_BYTE:
--- a/src/share/vm/ci/ciEnv.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/ci/ciEnv.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -385,11 +385,6 @@
                                                      KILL_COMPILE_ON_FATAL_(fail_type));
   }
 
-  if (found_klass != NULL) {
-    // Found it.  Build a CI handle.
-    return get_object(found_klass)->as_klass();
-  }
-
   // If we fail to find an array klass, look again for its element type.
   // The element type may be available either locally or via constraints.
   // In either case, if we can find the element type in the system dictionary,
@@ -414,6 +409,11 @@
     }
   }
 
+  if (found_klass != NULL) {
+    // Found it.  Build a CI handle.
+    return get_object(found_klass)->as_klass();
+  }
+
   if (require_local)  return NULL;
   // Not yet loaded into the VM, or not governed by loader constraints.
   // Make a CI representative for it.
--- a/src/share/vm/classfile/loaderConstraints.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/classfile/loaderConstraints.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -334,33 +334,6 @@
   return NULL;
 }
 
-
-klassOop LoaderConstraintTable::find_constrained_elem_klass(symbolHandle name,
-                                                            symbolHandle elem_name,
-                                                            Handle loader,
-                                                            TRAPS) {
-  LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
-  if (p != NULL) {
-    assert(p->klass() == NULL, "Expecting null array klass");
-
-    // The array name has a constraint, but it will not have a class. Check
-    // each loader for an associated elem
-    for (int i = 0; i < p->num_loaders(); i++) {
-      Handle no_protection_domain;
-
-      klassOop k = SystemDictionary::find(elem_name, p->loader(i), no_protection_domain, THREAD);
-      if (k != NULL) {
-        // Return the first elem klass found.
-        return k;
-      }
-    }
-  }
-
-  // No constraints, or else no klass loaded yet.
-  return NULL;
-}
-
-
 void LoaderConstraintTable::ensure_loader_constraint_capacity(
                                                      LoaderConstraintEntry *p,
                                                     int nfree) {
--- a/src/share/vm/classfile/loaderConstraints.hpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/classfile/loaderConstraints.hpp	Wed Apr 07 12:28:22 2010 -0400
@@ -66,9 +66,6 @@
   //                                           bool is_method, TRAPS)
 
   klassOop find_constrained_klass(symbolHandle name, Handle loader);
-  klassOop find_constrained_elem_klass(symbolHandle name, symbolHandle elem_name,
-                                       Handle loader, TRAPS);
-
 
   // Class loader constraints
 
--- a/src/share/vm/classfile/systemDictionary.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/classfile/systemDictionary.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -2178,9 +2178,8 @@
   // a loader constraint that would require this loader to return the
   // klass that is already loaded.
   if (FieldType::is_array(class_name())) {
-    // Array classes are hard because their klassOops are not kept in the
-    // constraint table. The array klass may be constrained, but the elem class
-    // may not be.
+    // For array classes, their klassOops are not kept in the
+    // constraint table. The element klassOops are.
     jint dimension;
     symbolOop object_key;
     BasicType t = FieldType::get_array_info(class_name(), &dimension,
@@ -2190,8 +2189,9 @@
     } else {
       symbolHandle elem_name(THREAD, object_key);
       MutexLocker mu(SystemDictionary_lock, THREAD);
-      klass = constraints()->find_constrained_elem_klass(class_name, elem_name, class_loader, THREAD);
+      klass = constraints()->find_constrained_klass(elem_name, class_loader);
     }
+    // If element class already loaded, allocate array klass
     if (klass != NULL) {
       klass = Klass::cast(klass)->array_klass_or_null(dimension);
     }
@@ -2209,22 +2209,38 @@
                                              Handle class_loader1,
                                              Handle class_loader2,
                                              Thread* THREAD) {
-  unsigned int d_hash1 = dictionary()->compute_hash(class_name, class_loader1);
+  symbolHandle constraint_name;
+  if (!FieldType::is_array(class_name())) {
+    constraint_name = class_name;
+  } else {
+    // For array classes, their klassOops are not kept in the
+    // constraint table. The element classes are.
+    jint dimension;
+    symbolOop object_key;
+    BasicType t = FieldType::get_array_info(class_name(), &dimension,
+                                            &object_key, CHECK_(false));
+    // primitive types always pass
+    if (t != T_OBJECT) {
+      return true;
+    } else {
+      constraint_name = symbolHandle(THREAD, object_key);
+    }
+  }
+  unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, class_loader1);
   int d_index1 = dictionary()->hash_to_index(d_hash1);
 
-  unsigned int d_hash2 = dictionary()->compute_hash(class_name, class_loader2);
+  unsigned int d_hash2 = dictionary()->compute_hash(constraint_name, class_loader2);
   int d_index2 = dictionary()->hash_to_index(d_hash2);
-
   {
-    MutexLocker mu_s(SystemDictionary_lock, THREAD);
+  MutexLocker mu_s(SystemDictionary_lock, THREAD);
 
-    // Better never do a GC while we're holding these oops
-    No_Safepoint_Verifier nosafepoint;
+  // Better never do a GC while we're holding these oops
+  No_Safepoint_Verifier nosafepoint;
 
-    klassOop klass1 = find_class(d_index1, d_hash1, class_name, class_loader1);
-    klassOop klass2 = find_class(d_index2, d_hash2, class_name, class_loader2);
-    return constraints()->add_entry(class_name, klass1, class_loader1,
-                                    klass2, class_loader2);
+  klassOop klass1 = find_class(d_index1, d_hash1, constraint_name, class_loader1);
+  klassOop klass2 = find_class(d_index2, d_hash2, constraint_name, class_loader2);
+  return constraints()->add_entry(constraint_name, klass1, class_loader1,
+                                  klass2, class_loader2);
   }
 }
 
@@ -2301,6 +2317,7 @@
 // Returns the name of the type that failed a loader constraint check, or
 // NULL if no constraint failed. The returned C string needs cleaning up
 // with a ResourceMark in the caller.  No exception except OOME is thrown.
+// Arrays are not added to the loader constraint table, their elements are.
 char* SystemDictionary::check_signature_loaders(symbolHandle signature,
                                                Handle loader1, Handle loader2,
                                                bool is_method, TRAPS)  {
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -2328,6 +2328,17 @@
       }
 
       DEFAULT:
+#ifdef ZERO
+          // Some zero configurations use the C++ interpreter as a
+          // fallback interpreter and have support for platform
+          // specific fast bytecodes which aren't supported here, so
+          // redispatch to the equivalent non-fast bytecode when they
+          // are encountered.
+          if (Bytecodes::is_defined((Bytecodes::Code)opcode)) {
+              opcode = (jubyte)Bytecodes::java_code((Bytecodes::Code)opcode);
+              goto opcode_switch;
+          }
+#endif
           fatal2("\t*** Unimplemented opcode: %d = %s\n",
                  opcode, Bytecodes::name((Bytecodes::Code)opcode));
           goto finish;
--- a/src/share/vm/oops/typeArrayKlass.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/oops/typeArrayKlass.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -123,16 +123,16 @@
      || (((unsigned int) length + (unsigned int) dst_pos) > (unsigned int) d->length()) ) {
     THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
   }
+  // Check zero copy
+  if (length == 0)
+    return;
 
   // This is an attempt to make the copy_array fast.
-  // NB: memmove takes care of overlapping memory segments.
-  // Potential problem: memmove is not guaranteed to be word atomic
-  // Revisit in Merlin
   int l2es = log2_element_size();
   int ihs = array_header_in_bytes() / wordSize;
-  char* src = (char*) ((oop*)s + ihs) + (src_pos << l2es);
-  char* dst = (char*) ((oop*)d + ihs) + (dst_pos << l2es);
-  memmove(dst, src, length << l2es);
+  char* src = (char*) ((oop*)s + ihs) + ((size_t)src_pos << l2es);
+  char* dst = (char*) ((oop*)d + ihs) + ((size_t)dst_pos << l2es);
+  Copy::conjoint_memory_atomic(src, dst, (size_t)length << l2es);
 }
 
 
--- a/src/share/vm/opto/cfgnode.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/opto/cfgnode.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -956,6 +956,7 @@
     }
     if( jtkp && ttkp ) {
       if( jtkp->is_loaded() &&  jtkp->klass()->is_interface() &&
+          !jtkp->klass_is_exact() && // Keep exact interface klass (6894807)
           ttkp->is_loaded() && !ttkp->klass()->is_interface() ) {
         assert(ft == ttkp->cast_to_ptr_type(jtkp->ptr()) ||
                ft->isa_narrowoop() && ft->make_ptr() == ttkp->cast_to_ptr_type(jtkp->ptr()), "");
--- a/src/share/vm/opto/doCall.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/opto/doCall.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -714,8 +714,6 @@
 
   // iterate through all entries sequentially
   for (;!handlers.is_done(); handlers.next()) {
-    // Do nothing if turned off
-    if( !DeutschShiffmanExceptions ) break;
     ciExceptionHandler* handler = handlers.handler();
 
     if (handler->is_rethrow()) {
@@ -741,46 +739,26 @@
       return;                   // No more handling to be done here!
     }
 
-    // %%% The following logic replicates make_from_klass_unique.
-    // TO DO:  Replace by a subroutine call.  Then generalize
-    // the type check, as noted in the next "%%%" comment.
-
+    // Get the handler's klass
     ciInstanceKlass* klass = handler->catch_klass();
-    if (UseUniqueSubclasses) {
-      // (We use make_from_klass because it respects UseUniqueSubclasses.)
-      const TypeOopPtr* tp = TypeOopPtr::make_from_klass(klass);
-      klass = tp->klass()->as_instance_klass();
+
+    if (!klass->is_loaded()) {  // klass is not loaded?
+      // fall through into catch_call_exceptions which will emit a
+      // handler with an uncommon trap.
+      break;
     }
 
-    // Get the handler's klass
-    if (!klass->is_loaded())    // klass is not loaded?
-      break;                    // Must call Rethrow!
     if (klass->is_interface())  // should not happen, but...
       break;                    // bail out
-    // See if the loaded exception klass has no subtypes
-    if (klass->has_subklass())
-      break;                    // Cannot easily do precise test ==> Rethrow
 
-    // %%% Now that subclass checking is very fast, we need to rewrite
-    // this section and remove the option "DeutschShiffmanExceptions".
-    // The exception processing chain should be a normal typecase pattern,
-    // with a bailout to the interpreter only in the case of unloaded
-    // classes.  (The bailout should mark the method non-entrant.)
-    // This rewrite should be placed in GraphKit::, not Parse::.
-
-    // Add a dependence; if any subclass added we need to recompile
-    // %%% should use stronger assert_unique_concrete_subtype instead
-    if (!klass->is_final()) {
-      C->dependencies()->assert_leaf_type(klass);
-    }
-
-    // Implement precise test
+    // Check the type of the exception against the catch type
     const TypeKlassPtr *tk = TypeKlassPtr::make(klass);
     Node* con = _gvn.makecon(tk);
-    Node* cmp = _gvn.transform( new (C, 3) CmpPNode(ex_klass_node, con) );
-    Node* bol = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ne) );
-    { BuildCutout unless(this, bol, PROB_LIKELY(0.7f));
-      const TypeInstPtr* tinst = TypeInstPtr::make_exact(TypePtr::NotNull, klass);
+    Node* not_subtype_ctrl = gen_subtype_check(ex_klass_node, con);
+    if (!stopped()) {
+      PreserveJVMState pjvms(this);
+      const TypeInstPtr* tinst = TypeOopPtr::make_from_klass_unique(klass)->cast_to_ptr_type(TypePtr::NotNull)->is_instptr();
+      assert(klass->has_subklass() || tinst->klass_is_exact(), "lost exactness");
       Node* ex_oop = _gvn.transform(new (C, 2) CheckCastPPNode(control(), ex_node, tinst));
       push_ex_oop(ex_oop);      // Push exception oop for handler
 #ifndef PRODUCT
@@ -792,6 +770,7 @@
 #endif
       merge_exception(handler_bci);
     }
+    set_control(not_subtype_ctrl);
 
     // Come here if exception does not match handler.
     // Carry on with more handler checks.
@@ -800,21 +779,6 @@
 
   assert(!stopped(), "you should return if you finish the chain");
 
-  if (remaining == 1) {
-    // Further checks do not matter.
-  }
-
-  if (can_rerun_bytecode()) {
-    // Do not push_ex_oop here!
-    // Re-executing the bytecode will reproduce the throwing condition.
-    bool must_throw = true;
-    uncommon_trap(Deoptimization::Reason_unhandled,
-                  Deoptimization::Action_none,
-                  (ciKlass*)NULL, (const char*)NULL, // default args
-                  must_throw);
-    return;
-  }
-
   // Oops, need to call into the VM to resolve the klasses at runtime.
   // Note:  This call must not deoptimize, since it is not a real at this bci!
   kill_dead_locals();
--- a/src/share/vm/opto/parse.hpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/opto/parse.hpp	Wed Apr 07 12:28:22 2010 -0400
@@ -551,9 +551,6 @@
   // Also handles exceptions for individual bytecodes.
   void catch_inline_exceptions(SafePointNode* ex_map);
 
-  // Bytecode classifier, helps decide to use uncommon_trap vs. rethrow_C.
-  bool can_rerun_bytecode();
-
   // Merge the given map into correct exceptional exit state.
   // Assumes that there is no applicable local handler.
   void throw_to_exit(SafePointNode* ex_map);
--- a/src/share/vm/opto/parse1.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/opto/parse1.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -798,67 +798,6 @@
   initial_gvn()->transform_no_reclaim(exit);
 }
 
-bool Parse::can_rerun_bytecode() {
-  switch (bc()) {
-  case Bytecodes::_ldc:
-  case Bytecodes::_ldc_w:
-  case Bytecodes::_ldc2_w:
-  case Bytecodes::_getfield:
-  case Bytecodes::_putfield:
-  case Bytecodes::_getstatic:
-  case Bytecodes::_putstatic:
-  case Bytecodes::_arraylength:
-  case Bytecodes::_baload:
-  case Bytecodes::_caload:
-  case Bytecodes::_iaload:
-  case Bytecodes::_saload:
-  case Bytecodes::_faload:
-  case Bytecodes::_aaload:
-  case Bytecodes::_laload:
-  case Bytecodes::_daload:
-  case Bytecodes::_bastore:
-  case Bytecodes::_castore:
-  case Bytecodes::_iastore:
-  case Bytecodes::_sastore:
-  case Bytecodes::_fastore:
-  case Bytecodes::_aastore:
-  case Bytecodes::_lastore:
-  case Bytecodes::_dastore:
-  case Bytecodes::_irem:
-  case Bytecodes::_idiv:
-  case Bytecodes::_lrem:
-  case Bytecodes::_ldiv:
-  case Bytecodes::_frem:
-  case Bytecodes::_fdiv:
-  case Bytecodes::_drem:
-  case Bytecodes::_ddiv:
-  case Bytecodes::_checkcast:
-  case Bytecodes::_instanceof:
-  case Bytecodes::_anewarray:
-  case Bytecodes::_newarray:
-  case Bytecodes::_multianewarray:
-  case Bytecodes::_new:
-  case Bytecodes::_monitorenter:  // can re-run initial null check, only
-  case Bytecodes::_return:
-    return true;
-    break;
-
-  // Don't rerun athrow since it's part of the exception path.
-  case Bytecodes::_athrow:
-  case Bytecodes::_invokestatic:
-  case Bytecodes::_invokedynamic:
-  case Bytecodes::_invokespecial:
-  case Bytecodes::_invokevirtual:
-  case Bytecodes::_invokeinterface:
-    return false;
-    break;
-
-  default:
-    assert(false, "unexpected bytecode produced an exception");
-    return true;
-  }
-}
-
 //---------------------------do_exceptions-------------------------------------
 // Process exceptions arising from the current bytecode.
 // Send caught exceptions to the proper handler within this method.
@@ -872,9 +811,6 @@
     return;
   }
 
-  // Make sure we can classify this bytecode if we need to.
-  debug_only(can_rerun_bytecode());
-
   PreserveJVMState pjvms(this, false);
 
   SafePointNode* ex_map;
--- a/src/share/vm/opto/type.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/opto/type.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -2545,12 +2545,15 @@
       ftip->is_loaded() &&  ftip->klass()->is_interface() &&
       ktip->is_loaded() && !ktip->klass()->is_interface()) {
     // Happens in a CTW of rt.jar, 320-341, no extra flags
+    assert(!ftip->klass_is_exact(), "interface could not be exact");
     return ktip->cast_to_ptr_type(ftip->ptr());
   }
+  // Interface klass type could be exact in opposite to interface type,
+  // return it here instead of incorrect Constant ptr J/L/Object (6894807).
   if (ftkp != NULL && ktkp != NULL &&
       ftkp->is_loaded() &&  ftkp->klass()->is_interface() &&
+      !ftkp->klass_is_exact() && // Keep exact interface klass
       ktkp->is_loaded() && !ktkp->klass()->is_interface()) {
-    // Happens in a CTW of rt.jar, 320-341, no extra flags
     return ktkp->cast_to_ptr_type(ftkp->ptr());
   }
 
--- a/src/share/vm/prims/forte.cpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/prims/forte.cpp	Wed Apr 07 12:28:22 2010 -0400
@@ -55,12 +55,11 @@
 };
 
 
-static void is_decipherable_compiled_frame(frame* fr, RegisterMap* map,
-  bool* is_compiled_p, bool* is_walkable_p);
+static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, nmethod* nm);
 static bool is_decipherable_interpreted_frame(JavaThread* thread,
-                                                frame* fr,
-                                                methodOop* method_p,
-                                                int* bci_p);
+                                              frame* fr,
+                                              methodOop* method_p,
+                                              int* bci_p);
 
 
 
@@ -122,41 +121,43 @@
 // Determine if 'fr' is a decipherable compiled frame. We are already
 // assured that fr is for a java nmethod.
 
-static bool is_decipherable_compiled_frame(frame* fr) {
-
-  assert(fr->cb() != NULL && fr->cb()->is_nmethod(), "invariant");
-  nmethod* nm = (nmethod*) fr->cb();
+static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, nmethod* nm) {
   assert(nm->is_java_method(), "invariant");
 
-  // First try and find an exact PcDesc
-
-  PcDesc* pc_desc = nm->pc_desc_at(fr->pc());
-
-  // Did we find a useful PcDesc?
-  if (pc_desc != NULL &&
-      pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
-
-    address probe_pc = fr->pc() + 1;
-    pc_desc = nm->pc_desc_near(probe_pc);
+  if (thread->has_last_Java_frame() && thread->last_Java_pc() == fr->pc()) {
+    // We're stopped at a call into the JVM so look for a PcDesc with
+    // the actual pc reported by the frame.
+    PcDesc* pc_desc = nm->pc_desc_at(fr->pc());
 
-    // Now do we have a useful PcDesc?
-
+    // Did we find a useful PcDesc?
     if (pc_desc != NULL &&
-        pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
-      // No debug information available for this pc
-      // vframeStream would explode if we try and walk the frames.
-      return false;
+        pc_desc->scope_decode_offset() != DebugInformationRecorder::serialized_null) {
+      return true;
     }
-
-    // This PcDesc is useful however we must adjust the frame's pc
-    // so that the vframeStream lookups will use this same pc
-
-    fr->set_pc(pc_desc->real_pc(nm));
   }
 
+  // We're at some random pc in the nmethod so search for the PcDesc
+  // whose pc is greater than the current PC.  It's done this way
+  // because the extra PcDescs that are recorded for improved debug
+  // info record the end of the region covered by the ScopeDesc
+  // instead of the beginning.
+  PcDesc* pc_desc = nm->pc_desc_near(fr->pc() + 1);
+
+  // Now do we have a useful PcDesc?
+  if (pc_desc == NULL ||
+      pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
+    // No debug information available for this pc
+    // vframeStream would explode if we try and walk the frames.
+    return false;
+  }
+
+  // This PcDesc is useful however we must adjust the frame's pc
+  // so that the vframeStream lookups will use this same pc
+  fr->set_pc(pc_desc->real_pc(nm));
   return true;
 }
 
+
 // Determine if 'fr' is a walkable interpreted frame. Returns false
 // if it is not. *method_p, and *bci_p are not set when false is
 // returned. *method_p is non-NULL if frame was executing a Java
@@ -166,9 +167,9 @@
 // even if a valid BCI cannot be found.
 
 static bool is_decipherable_interpreted_frame(JavaThread* thread,
-                                                frame* fr,
-                                                methodOop* method_p,
-                                                int* bci_p) {
+                                              frame* fr,
+                                              methodOop* method_p,
+                                              int* bci_p) {
   assert(fr->is_interpreted_frame(), "just checking");
 
   // top frame is an interpreted frame
@@ -323,13 +324,15 @@
       // have a PCDesc that can get us a bci however we did find
       // a method
 
-      if (!is_decipherable_compiled_frame(&candidate)) {
+      if (!is_decipherable_compiled_frame(thread, &candidate, nm)) {
         return false;
       }
 
       // is_decipherable_compiled_frame may modify candidate's pc
       *initial_frame_p = candidate;
 
+      assert(nm->pc_desc_at(candidate.pc()) != NULL, "if it's decipherable then pc must be valid");
+
       return true;
     }
 
--- a/src/share/vm/runtime/globals.hpp	Fri Apr 02 17:04:09 2010 -0700
+++ b/src/share/vm/runtime/globals.hpp	Wed Apr 07 12:28:22 2010 -0400
@@ -2502,10 +2502,6 @@
   notproduct(bool, TraceSpilling, false,                                    \
           "Trace spilling")                                                 \
                                                                             \
-  develop(bool, DeutschShiffmanExceptions, true,                            \
-          "Fast check to find exception handler for precisely typed "       \
-          "exceptions")                                                     \
-                                                                            \
   product(bool, SplitIfBlocks, true,                                        \
           "Clone compares and control flow through merge points to fold "   \
           "some branches")                                                  \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/6892265/Test.java	Wed Apr 07 12:28:22 2010 -0400
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6892265
+ * @summary System.arraycopy unable to reference elements beyond Integer.MAX_VALUE bytes
+ *
+ * @run main/othervm Test
+ */
+
+public class Test {
+  static  final int NCOPY = 1;
+  static  final int OVERFLOW = 1;
+  static  int[] src2 = new int[NCOPY];
+  static  int[] dst2;
+
+  static void test() {
+    int N;
+    int SIZE;
+
+    N = Integer.MAX_VALUE/4 + OVERFLOW;
+    System.arraycopy(src2, 0, dst2, N, NCOPY);
+    System.arraycopy(dst2, N, src2, 0, NCOPY);
+  }
+
+  public static void main(String[] args) {
+    try {
+      dst2 = new int[NCOPY + Integer.MAX_VALUE/4 + OVERFLOW];
+    } catch (OutOfMemoryError e) {
+       System.exit(95); // Not enough memory
+    }
+    System.out.println("warmup");
+    for (int i=0; i <11000; i++) {
+      test();
+    }
+    System.out.println("start");
+    for (int i=0; i <1000; i++) {
+      test();
+    }
+    System.out.println("finish");
+  }
+
+}