# HG changeset patch # User kamg # Date 1270657702 14400 # Node ID 6ccd32c284ac06acdaf2eca8edd9b8e47cf13a20 # Parent 895d9ade6111a096d14d5ea4d37cd2e6b3e11ea7# Parent 0fd6320854d32ab384319c4de1fea06803ddfd0c Merge diff -r 0fd6320854d3 -r 6ccd32c284ac src/cpu/zero/vm/cppInterpreter_zero.cpp --- 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 diff -r 0fd6320854d3 -r 6ccd32c284ac src/cpu/zero/vm/methodHandles_zero.cpp --- 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(); +} diff -r 0fd6320854d3 -r 6ccd32c284ac src/cpu/zero/vm/stubRoutines_zero.hpp --- 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; diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/ci/ciConstant.cpp --- 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: diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/ci/ciEnv.cpp --- 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. diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/classfile/loaderConstraints.cpp --- 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) { diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/classfile/loaderConstraints.hpp --- 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 diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/classfile/systemDictionary.cpp --- 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) { diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/interpreter/bytecodeInterpreter.cpp --- 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; diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/oops/typeArrayKlass.cpp --- 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); } diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/opto/cfgnode.cpp --- 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()), ""); diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/opto/doCall.cpp --- 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(); diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/opto/parse.hpp --- 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); diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/opto/parse1.cpp --- 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; diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/opto/type.cpp --- 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()); } diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/prims/forte.cpp --- 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; } diff -r 0fd6320854d3 -r 6ccd32c284ac src/share/vm/runtime/globals.hpp --- 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") \ diff -r 0fd6320854d3 -r 6ccd32c284ac test/compiler/6892265/Test.java --- /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"); + } + +}