diff --git a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp index 8455a15ddc7adf34f01554be6052d04853c1311e..315e90019c6cd0adc79c3c8af165726cdb78fdbb 100644 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @@ -2730,9 +2730,6 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { } Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias); - __ lduw(counter_addr, tmp1); - __ add(tmp1, DataLayout::counter_increment, tmp1); - __ stw(tmp1, counter_addr); Bytecodes::Code bc = method->java_code_at_bci(bci); // Perform additional virtual call profiling for invokevirtual and // invokeinterface bytecodes @@ -2822,15 +2819,23 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { __ set(DataLayout::counter_increment, tmp1); __ st_ptr(tmp1, mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)) - mdo_offset_bias); - if (i < (VirtualCallData::row_limit() - 1)) { - __ br(Assembler::always, false, Assembler::pt, update_done); - __ delayed()->nop(); - } + __ br(Assembler::always, false, Assembler::pt, update_done); + __ delayed()->nop(); __ bind(next_test); } + // Receiver did not match any saved receiver and there is no empty row for it. + // Increment total counter to indicate polymorphic case. + __ lduw(counter_addr, tmp1); + __ add(tmp1, DataLayout::counter_increment, tmp1); + __ stw(tmp1, counter_addr); __ bind(update_done); } + } else { + // Static call + __ lduw(counter_addr, tmp1); + __ add(tmp1, DataLayout::counter_increment, tmp1); + __ stw(tmp1, counter_addr); } } diff --git a/src/cpu/sparc/vm/interp_masm_sparc.cpp b/src/cpu/sparc/vm/interp_masm_sparc.cpp index 01702ee2b2f1e3e51fff14487bd6c3a83c9efdb1..604c2b9e4e419d34f4a9f3b472775645e1e63e61 100644 --- a/src/cpu/sparc/vm/interp_masm_sparc.cpp +++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 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 @@ -1733,7 +1733,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( brx(Assembler::zero, false, Assembler::pn, found_null); delayed()->nop(); // Receiver did not match any saved receiver and there is no empty row for it. - // Increment total counter to indicate polimorphic case. + // Increment total counter to indicate polymorphic case. increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); ba(false, done); delayed()->nop(); diff --git a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp index 79c765415f66a5442cd18f0be242475d561530b9..50a5b6de13b207a7b5cf5c6fbf0488bb9bd3069a 100644 --- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp @@ -851,10 +851,10 @@ void AdapterGenerator::gen_c2i_adapter( __ set(reg2offset(r_1) + extraspace + bias, ld_off); #else int ld_off = reg2offset(r_1) + extraspace + bias; +#endif // _LP64 #ifdef ASSERT G1_forced = true; #endif // ASSERT -#endif // _LP64 r_1 = G1_scratch->as_VMReg();// as part of the load/store shuffle if (!r_2->is_valid()) __ ld (base, ld_off, G1_scratch); else __ ldx(base, ld_off, G1_scratch); @@ -865,9 +865,11 @@ void AdapterGenerator::gen_c2i_adapter( if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) { store_c2i_object(r, base, st_off); } else if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { +#ifndef _LP64 if (TieredCompilation) { assert(G1_forced || sig_bt[i] != T_LONG, "should not use register args for longs"); } +#endif // _LP64 store_c2i_long(r, base, st_off, r_2->is_stack()); } else { store_c2i_int(r, base, st_off); diff --git a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index 0e197a714d14a56a6472aa34c46944402924159f..85f370a4c6123af5972095eeef84dacd3af9a0bb 100644 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -3279,7 +3279,7 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) { __ bind(next_test); } // Receiver did not match any saved receiver and there is no empty row for it. - // Increment total counter to indicate polimorphic case. + // Increment total counter to indicate polymorphic case. __ addl(counter_addr, DataLayout::counter_increment); __ bind(update_done); diff --git a/src/cpu/x86/vm/frame_x86.inline.hpp b/src/cpu/x86/vm/frame_x86.inline.hpp index 809e26cfaa121fcc9660c5584fa69bf46b55d2f2..bf68ce9270fc6b3333a29c1a32cf60a10f0df669 100644 --- a/src/cpu/x86/vm/frame_x86.inline.hpp +++ b/src/cpu/x86/vm/frame_x86.inline.hpp @@ -233,7 +233,8 @@ inline intptr_t* frame::interpreter_frame_tos_address() const { } else { // sp() may have been extended or shrunk by an adapter. At least // check that we don't fall behind the legal region. - assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(), "bad tos"); + // For top deoptimized frame last_sp == interpreter_frame_monitor_end. + assert(last_sp <= (intptr_t*) interpreter_frame_monitor_end(), "bad tos"); return last_sp; } } diff --git a/src/cpu/x86/vm/interp_masm_x86_32.cpp b/src/cpu/x86/vm/interp_masm_x86_32.cpp index bf1e36648d7308875e03db39407e3d441526f538..205e5d80de5b1b715e60eb2e3fc69a4a91ee013d 100644 --- a/src/cpu/x86/vm/interp_masm_x86_32.cpp +++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 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 @@ -1308,7 +1308,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( if (is_virtual_call) { jccb(Assembler::zero, found_null); // Receiver did not match any saved receiver and there is no empty row for it. - // Increment total counter to indicate polimorphic case. + // Increment total counter to indicate polymorphic case. increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); jmp(done); bind(found_null); diff --git a/src/cpu/x86/vm/interp_masm_x86_64.cpp b/src/cpu/x86/vm/interp_masm_x86_64.cpp index 7e6b71fa147b846a7078a1a232e934055daf1add..62acfa226fb9ce4343a78f554e1e4abc3984b1a9 100644 --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2010 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 @@ -1341,7 +1341,7 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( if (is_virtual_call) { jccb(Assembler::zero, found_null); // Receiver did not match any saved receiver and there is no empty row for it. - // Increment total counter to indicate polimorphic case. + // Increment total counter to indicate polymorphic case. increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset())); jmp(done); bind(found_null); diff --git a/src/cpu/zero/vm/cppInterpreter_zero.cpp b/src/cpu/zero/vm/cppInterpreter_zero.cpp index 8fcb75c8b36c08f3990d8c84f7afa84007d95f7b..4f94d8851c4218946ca701b7010f1b8459d70c60 100644 --- a/src/cpu/zero/vm/cppInterpreter_zero.cpp +++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp @@ -1,6 +1,6 @@ /* * Copyright 2003-2007 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 @@ -145,7 +145,7 @@ void CppInterpreter::main_loop(int recurse, TRAPS) { } else if (istate->msg() == BytecodeInterpreter::return_from_method) { // Copy the result into the caller's frame - result_slots = type2size[method->result_type()]; + result_slots = type2size[result_type_of(method)]; assert(result_slots >= 0 && result_slots <= 2, "what?"); result = istate->stack() + result_slots; break; @@ -394,9 +394,10 @@ void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) { // Push our result if (!HAS_PENDING_EXCEPTION) { - stack->set_sp(stack->sp() - type2size[method->result_type()]); + BasicType type = result_type_of(method); + stack->set_sp(stack->sp() - type2size[type]); - switch (method->result_type()) { + switch (type) { case T_VOID: break; @@ -707,6 +708,26 @@ int AbstractInterpreter::BasicType_as_index(BasicType type) { return i; } +BasicType CppInterpreter::result_type_of(methodOop method) { + BasicType t; + switch (method->result_index()) { + case 0 : t = T_BOOLEAN; break; + case 1 : t = T_CHAR; break; + case 2 : t = T_BYTE; break; + case 3 : t = T_SHORT; break; + case 4 : t = T_INT; break; + case 5 : t = T_LONG; break; + case 6 : t = T_VOID; break; + case 7 : t = T_FLOAT; break; + case 8 : t = T_DOUBLE; break; + case 9 : t = T_OBJECT; break; + default: ShouldNotReachHere(); + } + assert(AbstractInterpreter::BasicType_as_index(t) == method->result_index(), + "out of step with AbstractInterpreter::BasicType_as_index"); + return t; +} + address InterpreterGenerator::generate_empty_entry() { if (!UseFastEmptyMethods) return NULL; diff --git a/src/cpu/zero/vm/cppInterpreter_zero.hpp b/src/cpu/zero/vm/cppInterpreter_zero.hpp index 18b9891e93777d4e4c2a869d82c85b6dff810b33..24c698c7ce580a92f011ba2fc842220552490c56 100644 --- a/src/cpu/zero/vm/cppInterpreter_zero.hpp +++ b/src/cpu/zero/vm/cppInterpreter_zero.hpp @@ -1,6 +1,6 @@ /* * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2007, 2008 Red Hat, Inc. + * Copyright 2007, 2008, 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,3 +41,7 @@ private: // Stack overflow checks static bool stack_overflow_imminent(JavaThread *thread); + + private: + // Fast result type determination + static BasicType result_type_of(methodOop method); diff --git a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp index 59ed458b23ffad1a4cec69a4ad381706767f315c..a11901ed6d48fb4131284306bbf384f16fd59306 100644 --- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2010 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 @@ -730,11 +730,12 @@ void os::print_context(outputStream *st, void *context) { st->print(", RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]); st->print(", RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]); st->cr(); - st->print(", R8=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]); + st->print( "R8=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]); st->print(", R9=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]); st->print(", R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]); st->print(", R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]); - st->print(", R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]); + st->cr(); + st->print( "R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]); st->print(", R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]); st->print(", R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]); st->print(", R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]); diff --git a/src/share/vm/c1/c1_IR.hpp b/src/share/vm/c1/c1_IR.hpp index e1af926aef12fba0c098186b5c365dbcc8ea40c6..32ed4a40d00e83dd0775ecc7e35736a02d61eb65 100644 --- a/src/share/vm/c1/c1_IR.hpp +++ b/src/share/vm/c1/c1_IR.hpp @@ -253,7 +253,8 @@ class IRScopeDebugInfo: public CompilationResourceObj { // reexecute allowed only for the topmost frame bool reexecute = topmost ? should_reexecute() : false; bool is_method_handle_invoke = false; - recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, locvals, expvals, monvals); + bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis. + recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals); } }; diff --git a/src/share/vm/ci/ciMethod.cpp b/src/share/vm/ci/ciMethod.cpp index 3d9b04a8e3dd5b8cf90bc8402ab3958dd1abac13..54a04f8af1f8ed6e0d725bfaea238bffbeb4b4fd 100644 --- a/src/share/vm/ci/ciMethod.cpp +++ b/src/share/vm/ci/ciMethod.cpp @@ -445,7 +445,8 @@ ciCallProfile ciMethod::call_profile_at_bci(int bci) { (morphism == ciCallProfile::MorphismLimit && count == 0)) { #ifdef ASSERT if (count > 0) { - tty->print_cr("bci: %d", bci); + this->print_short_name(tty); + tty->print_cr(" @ bci:%d", bci); this->print_codes(); assert(false, "this call site should not be polymorphic"); } diff --git a/src/share/vm/code/debugInfoRec.cpp b/src/share/vm/code/debugInfoRec.cpp index a1cac29439ffd904cdac799bf15b3acbd8cd4f2f..14765e4fc53716d5b0fd25d184f60bcf9bebdb04 100644 --- a/src/share/vm/code/debugInfoRec.cpp +++ b/src/share/vm/code/debugInfoRec.cpp @@ -282,6 +282,7 @@ void DebugInformationRecorder::describe_scope(int pc_offset, int bci, bool reexecute, bool is_method_handle_invoke, + bool return_oop, DebugToken* locals, DebugToken* expressions, DebugToken* monitors) { @@ -296,6 +297,7 @@ void DebugInformationRecorder::describe_scope(int pc_offset, // Record flags into pcDesc. last_pd->set_should_reexecute(reexecute); last_pd->set_is_method_handle_invoke(is_method_handle_invoke); + last_pd->set_return_oop(return_oop); // serialize sender stream offest stream()->write_int(sender_stream_offset); diff --git a/src/share/vm/code/debugInfoRec.hpp b/src/share/vm/code/debugInfoRec.hpp index c67efa09b25802729b8277d698bb86d5a5c7baf0..8282a051f08b444299e356b1b58a3a26d17afe14 100644 --- a/src/share/vm/code/debugInfoRec.hpp +++ b/src/share/vm/code/debugInfoRec.hpp @@ -89,6 +89,7 @@ class DebugInformationRecorder: public ResourceObj { int bci, bool reexecute, bool is_method_handle_invoke = false, + bool return_oop = false, DebugToken* locals = NULL, DebugToken* expressions = NULL, DebugToken* monitors = NULL); diff --git a/src/share/vm/code/nmethod.cpp b/src/share/vm/code/nmethod.cpp index 814a4069f37cc66ffeb2b8a98aa24ca3e0292e84..7ffb0f57026536aaf1d908c8333683716da77a4b 100644 --- a/src/share/vm/code/nmethod.cpp +++ b/src/share/vm/code/nmethod.cpp @@ -988,7 +988,8 @@ ScopeDesc* nmethod::scope_desc_at(address pc) { PcDesc* pd = pc_desc_at(pc); guarantee(pd != NULL, "scope must be present"); return new ScopeDesc(this, pd->scope_decode_offset(), - pd->obj_decode_offset(), pd->should_reexecute()); + pd->obj_decode_offset(), pd->should_reexecute(), + pd->return_oop()); } @@ -2010,7 +2011,10 @@ address nmethod::continuation_for_implicit_exception(address pc) { print_pcs(); } #endif - guarantee(cont_offset != 0, "unhandled implicit exception in compiled code"); + if (cont_offset == 0) { + // Let the normal error handling report the exception + return NULL; + } return instructions_begin() + cont_offset; } @@ -2156,7 +2160,8 @@ void nmethod::verify_interrupt_point(address call_site) { PcDesc* pd = pc_desc_at(ic->end_of_call()); assert(pd != NULL, "PcDesc must exist"); for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(), - pd->obj_decode_offset(), pd->should_reexecute()); + pd->obj_decode_offset(), pd->should_reexecute(), + pd->return_oop()); !sd->is_top(); sd = sd->sender()) { sd->verify(); } @@ -2421,7 +2426,8 @@ ScopeDesc* nmethod::scope_desc_in(address begin, address end) { PcDesc* p = pc_desc_near(begin+1); if (p != NULL && p->real_pc(this) <= end) { return new ScopeDesc(this, p->scope_decode_offset(), - p->obj_decode_offset(), p->should_reexecute()); + p->obj_decode_offset(), p->should_reexecute(), + p->return_oop()); } return NULL; } diff --git a/src/share/vm/code/pcDesc.cpp b/src/share/vm/code/pcDesc.cpp index 5b981645a1b4ed5b92356644e3e2ea998e5d90da..5d6456bf513893d9de866036ed71193704cee792 100644 --- a/src/share/vm/code/pcDesc.cpp +++ b/src/share/vm/code/pcDesc.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 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 @@ -52,7 +52,8 @@ void PcDesc::print(nmethod* code) { tty->print(" "); sd->method()->print_short_name(tty); tty->print(" @%d", sd->bci()); - tty->print(" reexecute=%s", sd->should_reexecute()?"true":"false"); + if (sd->should_reexecute()) + tty->print(" reexecute=true"); tty->cr(); } #endif diff --git a/src/share/vm/code/pcDesc.hpp b/src/share/vm/code/pcDesc.hpp index 74d3baaf2f7fc09ad9c1f48fbe1e22c79bee5c62..c666810613a3038913148dc97f5908864ba99a4c 100644 --- a/src/share/vm/code/pcDesc.hpp +++ b/src/share/vm/code/pcDesc.hpp @@ -39,6 +39,7 @@ class PcDesc VALUE_OBJ_CLASS_SPEC { struct { unsigned int reexecute: 1; unsigned int is_method_handle_invoke: 1; + unsigned int return_oop: 1; } bits; bool operator ==(const PcDescFlags& other) { return word == other.word; } } _flags; @@ -76,6 +77,9 @@ class PcDesc VALUE_OBJ_CLASS_SPEC { bool is_method_handle_invoke() const { return _flags.bits.is_method_handle_invoke; } void set_is_method_handle_invoke(bool z) { _flags.bits.is_method_handle_invoke = z; } + bool return_oop() const { return _flags.bits.return_oop; } + void set_return_oop(bool z) { _flags.bits.return_oop = z; } + // Returns the real pc address real_pc(const nmethod* code) const; diff --git a/src/share/vm/code/scopeDesc.cpp b/src/share/vm/code/scopeDesc.cpp index a034530e6bfb0b5e62f704be61cc3b5d678b72ca..5b411c5bef176a341e87231197008997e853841d 100644 --- a/src/share/vm/code/scopeDesc.cpp +++ b/src/share/vm/code/scopeDesc.cpp @@ -26,19 +26,21 @@ # include "incls/_scopeDesc.cpp.incl" -ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute) { +ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop) { _code = code; _decode_offset = decode_offset; _objects = decode_object_values(obj_decode_offset); _reexecute = reexecute; + _return_oop = return_oop; decode_body(); } -ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute) { +ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop) { _code = code; _decode_offset = decode_offset; _objects = decode_object_values(DebugInformationRecorder::serialized_null); _reexecute = reexecute; + _return_oop = return_oop; decode_body(); } @@ -48,6 +50,7 @@ ScopeDesc::ScopeDesc(const ScopeDesc* parent) { _decode_offset = parent->_sender_decode_offset; _objects = parent->_objects; _reexecute = false; //reexecute only applies to the first scope + _return_oop = false; decode_body(); } diff --git a/src/share/vm/code/scopeDesc.hpp b/src/share/vm/code/scopeDesc.hpp index d030eaea849b48aacf3780c0a3908ee47e592b2c..345769ae55071737330922782aefed366168eff4 100644 --- a/src/share/vm/code/scopeDesc.hpp +++ b/src/share/vm/code/scopeDesc.hpp @@ -52,17 +52,18 @@ class SimpleScopeDesc : public StackObj { class ScopeDesc : public ResourceObj { public: // Constructor - ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute); + ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop); // Calls above, giving default value of "serialized_null" to the // "obj_decode_offset" argument. (We don't use a default argument to // avoid a .hpp-.hpp dependency.) - ScopeDesc(const nmethod* code, int decode_offset, bool reexecute); + ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop); // JVM state methodHandle method() const { return _method; } int bci() const { return _bci; } bool should_reexecute() const { return _reexecute; } + bool return_oop() const { return _return_oop; } GrowableArray* locals(); GrowableArray* expressions(); @@ -88,6 +89,7 @@ class ScopeDesc : public ResourceObj { methodHandle _method; int _bci; bool _reexecute; + bool _return_oop; // Decoding offsets int _decode_offset; diff --git a/src/share/vm/includeDB_core b/src/share/vm/includeDB_core index 675a6657e0b55d6201827c9af5a43de63fada047..a3e06d2f962a64becac9af73e18c7b698cad268d 100644 --- a/src/share/vm/includeDB_core +++ b/src/share/vm/includeDB_core @@ -1484,6 +1484,7 @@ deoptimization.cpp thread.hpp deoptimization.cpp vframe.hpp deoptimization.cpp vframeArray.hpp deoptimization.cpp vframe_hp.hpp +deoptimization.cpp vmreg_.inline.hpp deoptimization.cpp xmlstream.hpp deoptimization.hpp allocation.hpp diff --git a/src/share/vm/oops/methodDataOop.hpp b/src/share/vm/oops/methodDataOop.hpp index e1c8eaf10afadc9f237bd9e2879859140cbcd5a7..ca585f8b6928ac5bcd062216588f96e539946cf7 100644 --- a/src/share/vm/oops/methodDataOop.hpp +++ b/src/share/vm/oops/methodDataOop.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2010 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 @@ -545,6 +545,10 @@ public: return cell_offset(counter_cell_count); } + void set_count(uint count) { + set_uint_at(count_off, count); + } + #ifndef PRODUCT void print_data_on(outputStream* st); #endif @@ -692,6 +696,23 @@ public: void clear_row(uint row) { assert(row < row_limit(), "oob"); + // Clear total count - indicator of polymorphic call site. + // The site may look like as monomorphic after that but + // it allow to have more accurate profiling information because + // there was execution phase change since klasses were unloaded. + // If the site is still polymorphic then MDO will be updated + // to reflect it. But it could be the case that the site becomes + // only bimorphic. Then keeping total count not 0 will be wrong. + // Even if we use monomorphic (when it is not) for compilation + // we will only have trap, deoptimization and recompile again + // with updated MDO after executing method in Interpreter. + // An additional receiver will be recorded in the cleaned row + // during next call execution. + // + // Note: our profiling logic works with empty rows in any slot. + // We do sorting a profiling info (ciCallProfile) for compilation. + // + set_count(0); set_receiver(row, NULL); set_receiver_count(row, 0); } diff --git a/src/share/vm/opto/doCall.cpp b/src/share/vm/opto/doCall.cpp index d9c1a23bd3986ba7ef9687e36b8d5143e7b927b9..2f3f734fd4537bc192a8346348fd7d175efd6b41 100644 --- a/src/share/vm/opto/doCall.cpp +++ b/src/share/vm/opto/doCall.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2010 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 @@ -70,7 +70,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, CompileLog* log = this->log(); if (log != NULL) { int rid = (receiver_count >= 0)? log->identify(profile.receiver(0)): -1; - int r2id = (profile.morphism() == 2)? log->identify(profile.receiver(1)):-1; + int r2id = (rid != -1 && profile.has_receiver(1))? log->identify(profile.receiver(1)):-1; log->begin_elem("call method='%d' count='%d' prof_factor='%g'", log->identify(call_method), site_count, prof_factor); if (call_is_virtual) log->print(" virtual='1'"); diff --git a/src/share/vm/opto/graphKit.cpp b/src/share/vm/opto/graphKit.cpp index d70fe1eef492ae35e6db5ab1a16a647a5663650e..3d550551451d430be339c7ddc4cc9305cbb1c7aa 100644 --- a/src/share/vm/opto/graphKit.cpp +++ b/src/share/vm/opto/graphKit.cpp @@ -780,12 +780,20 @@ bool GraphKit::dead_locals_are_killed() { // Helper function for enforcing certain bytecodes to reexecute if // deoptimization happens -static bool should_reexecute_implied_by_bytecode(JVMState *jvms) { +static bool should_reexecute_implied_by_bytecode(JVMState *jvms, bool is_anewarray) { ciMethod* cur_method = jvms->method(); int cur_bci = jvms->bci(); if (cur_method != NULL && cur_bci != InvocationEntryBci) { Bytecodes::Code code = cur_method->java_code_at_bci(cur_bci); - return Interpreter::bytecode_should_reexecute(code); + return Interpreter::bytecode_should_reexecute(code) || + is_anewarray && code == Bytecodes::_multianewarray; + // Reexecute _multianewarray bytecode which was replaced with + // sequence of [a]newarray. See Parse::do_multianewarray(). + // + // Note: interpreter should not have it set since this optimization + // is limited by dimensions and guarded by flag so in some cases + // multianewarray() runtime calls will be generated and + // the bytecode should not be reexecutes (stack will not be reset). } else return false; } @@ -836,7 +844,7 @@ void GraphKit::add_safepoint_edges(SafePointNode* call, bool must_throw) { // For a known set of bytecodes, the interpreter should reexecute them if // deoptimization happens. We set the reexecute state for them here if (out_jvms->is_reexecute_undefined() && //don't change if already specified - should_reexecute_implied_by_bytecode(out_jvms)) { + should_reexecute_implied_by_bytecode(out_jvms, call->is_AllocateArray())) { out_jvms->set_should_reexecute(true); //NOTE: youngest_jvms not changed } diff --git a/src/share/vm/opto/loopopts.cpp b/src/share/vm/opto/loopopts.cpp index 68e5f468c1082a415b54d51c93a9682198257e2a..05295751f1fcd68e96f71d9cfbaf14d3e4f0250f 100644 --- a/src/share/vm/opto/loopopts.cpp +++ b/src/share/vm/opto/loopopts.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2010 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 @@ -47,7 +47,7 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) { int offset = t_oop->offset(); phi = new (C,region->req()) PhiNode(region, type, NULL, iid, index, offset); } else { - phi = new (C,region->req()) PhiNode(region, type); + phi = PhiNode::make_blank(region, n); } uint old_unique = C->unique(); for( uint i = 1; i < region->req(); i++ ) { diff --git a/src/share/vm/opto/output.cpp b/src/share/vm/opto/output.cpp index 65cc41b18a218bef4971f3fa94a9aab8213a278c..deb2ac2c3c389635306cc3bcfed6f40291f19937 100644 --- a/src/share/vm/opto/output.cpp +++ b/src/share/vm/opto/output.cpp @@ -795,6 +795,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { int safepoint_pc_offset = current_offset; bool is_method_handle_invoke = false; + bool return_oop = false; // Add the safepoint in the DebugInfoRecorder if( !mach->is_MachCall() ) { @@ -807,6 +808,11 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { if (mcall->is_MachCallJava()) is_method_handle_invoke = mcall->as_MachCallJava()->_method_handle_invoke; + // Check if a call returns an object. + if (mcall->return_value_is_used() && + mcall->tf()->range()->field_at(TypeFunc::Parms)->isa_ptr()) { + return_oop = true; + } safepoint_pc_offset += mcall->ret_addr_offset(); debug_info()->add_safepoint(safepoint_pc_offset, mcall->_oop_map); } @@ -919,7 +925,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) { assert(jvms->bci() >= InvocationEntryBci && jvms->bci() <= 0x10000, "must be a valid or entry BCI"); assert(!jvms->should_reexecute() || depth == max_depth, "reexecute allowed only for the youngest"); // Now we can describe the scope. - debug_info()->describe_scope(safepoint_pc_offset, scope_method, jvms->bci(), jvms->should_reexecute(), is_method_handle_invoke, locvals, expvals, monvals); + debug_info()->describe_scope(safepoint_pc_offset, scope_method, jvms->bci(), jvms->should_reexecute(), is_method_handle_invoke, return_oop, locvals, expvals, monvals); } // End jvms loop // Mark the end of the scope set. diff --git a/src/share/vm/opto/parse3.cpp b/src/share/vm/opto/parse3.cpp index 40f9940bd71aa3b27a28a6ca42e99958f33cf59a..9f0a034bb63cb357ac31cdb2a878a2a2fbad85ea 100644 --- a/src/share/vm/opto/parse3.cpp +++ b/src/share/vm/opto/parse3.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1998-2010 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 @@ -439,8 +439,18 @@ void Parse::do_multianewarray() { // Can use multianewarray instead of [a]newarray if only one dimension, // or if all non-final dimensions are small constants. - if (expand_count == 1 || (1 <= expand_count && expand_count <= expand_limit)) { - Node* obj = expand_multianewarray(array_klass, &length[0], ndimensions, ndimensions); + if (ndimensions == 1 || (1 <= expand_count && expand_count <= expand_limit)) { + Node* obj = NULL; + // Set the original stack and the reexecute bit for the interpreter + // to reexecute the multianewarray bytecode if deoptimization happens. + // Do it unconditionally even for one dimension multianewarray. + // Note: the reexecute bit will be set in GraphKit::add_safepoint_edges() + // when AllocateArray node for newarray is created. + { PreserveReexecuteState preexecs(this); + _sp += ndimensions; + // Pass 0 as nargs since uncommon trap code does not need to restore stack. + obj = expand_multianewarray(array_klass, &length[0], ndimensions, 0); + } //original reexecute and sp are set back here push(obj); return; } diff --git a/src/share/vm/opto/runtime.cpp b/src/share/vm/opto/runtime.cpp index 055622509d4da18a6ade249f55915cda5b98901d..c2d5ca7df88f519032fa19cc8492d1afd9a9a93b 100644 --- a/src/share/vm/opto/runtime.cpp +++ b/src/share/vm/opto/runtime.cpp @@ -708,7 +708,7 @@ JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* r *(mdp + count_off) = DataLayout::counter_increment; } else { // Receiver did not match any saved receiver and there is no empty row for it. - // Increment total counter to indicate polimorphic case. + // Increment total counter to indicate polymorphic case. intptr_t* count_p = (intptr_t*)(((byte*)(data)) + in_bytes(CounterData::count_offset())); *count_p += DataLayout::counter_increment; } diff --git a/src/share/vm/opto/stringopts.cpp b/src/share/vm/opto/stringopts.cpp index 192d31f8257e53579870972125d07aec60df24b6..01476453b3d911861046312fa10e401ed11919a1 100644 --- a/src/share/vm/opto/stringopts.cpp +++ b/src/share/vm/opto/stringopts.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009-2010 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 @@ -1073,7 +1073,7 @@ void PhaseStringOpts::int_getChars(GraphKit& kit, Node* arg, Node* char_array, N kit.set_control(head); kit.set_memory(mem, char_adr_idx); - Node* q = __ DivI(kit.null(), i_phi, __ intcon(10)); + Node* q = __ DivI(NULL, i_phi, __ intcon(10)); Node* r = __ SubI(i_phi, __ AddI(__ LShiftI(q, __ intcon(3)), __ LShiftI(q, __ intcon(1)))); Node* m1 = __ SubI(charPos, __ intcon(1)); @@ -1270,14 +1270,15 @@ void PhaseStringOpts::replace_string_concat(StringConcat* sc) { // length = length + (s.count - s.offset); RegionNode *r = new (C, 3) RegionNode(3); kit.gvn().set_type(r, Type::CONTROL); - Node *phi = new (C, 3) PhiNode(r, type->join(TypeInstPtr::NOTNULL)); + Node *phi = new (C, 3) PhiNode(r, type); kit.gvn().set_type(phi, phi->bottom_type()); Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne); IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN); Node* notnull = __ IfTrue(iff); Node* isnull = __ IfFalse(iff); + kit.set_control(notnull); // set control for the cast_not_null r->init_req(1, notnull); - phi->init_req(1, arg); + phi->init_req(1, kit.cast_not_null(arg, false)); r->init_req(2, isnull); phi->init_req(2, null_string); kit.set_control(r); diff --git a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp index 93217303fcf87321dcc4a6929a534ff5613a7e2d..d09bf8152ff3b830ee1c5bc482f9d2247ab6c1e2 100644 --- a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp +++ b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp @@ -402,7 +402,7 @@ void JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nmethod *nm, address scopes_data = nm->scopes_data_begin(); for( pcd = nm->scopes_pcs_begin(); pcd < nm->scopes_pcs_end(); ++pcd ) { - ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute()); + ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->return_oop()); ScopeDesc *sd = &sc0; while( !sd->is_top() ) { sd = sd->sender(); } int bci = sd->bci(); diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp index 66d84c5c4d21cbbbb9d6b0791253caa9ea21431a..f8e9a85abac915fb39df82c22b3cf6c2122229e1 100644 --- a/src/share/vm/runtime/arguments.cpp +++ b/src/share/vm/runtime/arguments.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 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 @@ -2524,6 +2524,9 @@ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_req SOLARIS_ONLY(FLAG_SET_DEFAULT(UseISM, false)); } + // Tiered compilation is undefined with C1. + TieredCompilation = false; + #else if (!FLAG_IS_DEFAULT(OptoLoopAlignment) && FLAG_IS_DEFAULT(MaxLoopPad)) { FLAG_SET_DEFAULT(MaxLoopPad, OptoLoopAlignment-1); diff --git a/src/share/vm/runtime/deoptimization.cpp b/src/share/vm/runtime/deoptimization.cpp index 6a8f8e1224e96f184d324a950e674b49d899287b..d3d60d9152af97ac8de5026e216fff548603fe5f 100644 --- a/src/share/vm/runtime/deoptimization.cpp +++ b/src/share/vm/runtime/deoptimization.cpp @@ -145,6 +145,27 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread if (EliminateAllocations) { assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames"); GrowableArray* objects = chunk->at(0)->scope()->objects(); + + // The flag return_oop() indicates call sites which return oop + // in compiled code. Such sites include java method calls, + // runtime calls (for example, used to allocate new objects/arrays + // on slow code path) and any other calls generated in compiled code. + // It is not guaranteed that we can get such information here only + // by analyzing bytecode in deoptimized frames. This is why this flag + // is set during method compilation (see Compile::Process_OopMap_Node()). + bool save_oop_result = chunk->at(0)->scope()->return_oop(); + Handle return_value; + if (save_oop_result) { + // Reallocation may trigger GC. If deoptimization happened on return from + // call which returns oop we need to save it since it is not in oopmap. + oop result = deoptee.saved_oop_result(&map); + assert(result == NULL || result->is_oop(), "must be oop"); + return_value = Handle(thread, result); + assert(Universe::heap()->is_in_or_null(result), "must be heap pointer"); + if (TraceDeoptimization) { + tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, result, thread); + } + } bool reallocated = false; if (objects != NULL) { JRT_BLOCK @@ -158,9 +179,13 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread ttyLocker ttyl; tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread); print_objects(objects); - } + } #endif } + if (save_oop_result) { + // Restore result. + deoptee.set_saved_oop_result(&map, return_value()); + } } if (EliminateLocks) { #ifndef PRODUCT @@ -913,21 +938,6 @@ vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, Re if (TraceDeoptimization) { ttyLocker ttyl; tty->print_cr(" Created vframeArray " INTPTR_FORMAT, array); - if (Verbose) { - int count = 0; - // this used to leak deoptimizedVFrame like it was going out of style!!! - for (int index = 0; index < array->frames(); index++ ) { - vframeArrayElement* e = array->element(index); - e->print(tty); - - /* - No printing yet. - array->vframe_at(index)->print_activation(count++); - // better as... - array->print_activation_for(index, count++); - */ - } - } } #endif // PRODUCT diff --git a/src/share/vm/runtime/frame.cpp b/src/share/vm/runtime/frame.cpp index 5844107c5c0f0409b2df372681cd994860f4f59e..30782f355c649ba63a53e5f4dadb002bd3fa7eab 100644 --- a/src/share/vm/runtime/frame.cpp +++ b/src/share/vm/runtime/frame.cpp @@ -606,12 +606,12 @@ void frame::interpreter_frame_print_on(outputStream* st) const { for (BasicObjectLock* current = interpreter_frame_monitor_end(); current < interpreter_frame_monitor_begin(); current = next_monitor_in_interpreter_frame(current)) { - st->print_cr(" [ - obj "); + st->print(" - obj ["); current->obj()->print_value_on(st); - st->cr(); - st->print_cr(" - lock "); + st->print_cr("]"); + st->print(" - lock ["); current->lock()->print_on(st); - st->cr(); + st->print_cr("]"); } // monitor st->print_cr(" - monitor[" INTPTR_FORMAT "]", interpreter_frame_monitor_begin()); diff --git a/src/share/vm/runtime/sharedRuntime.cpp b/src/share/vm/runtime/sharedRuntime.cpp index 4bbdd457388ebc2d6e3ea75a3552a18cbd3dbad9..3098625858e880c54b033c5127c6db1bf8e39eda 100644 --- a/src/share/vm/runtime/sharedRuntime.cpp +++ b/src/share/vm/runtime/sharedRuntime.cpp @@ -607,7 +607,9 @@ address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread, _implicit_null_throws++; #endif target_pc = nm->continuation_for_implicit_exception(pc); - guarantee(target_pc != 0, "must have a continuation point"); + // If there's an unexpected fault, target_pc might be NULL, + // in which case we want to fall through into the normal + // error handling code. } break; // fall through @@ -621,14 +623,15 @@ address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread, _implicit_div0_throws++; #endif target_pc = nm->continuation_for_implicit_exception(pc); - guarantee(target_pc != 0, "must have a continuation point"); + // If there's an unexpected fault, target_pc might be NULL, + // in which case we want to fall through into the normal + // error handling code. break; // fall through } default: ShouldNotReachHere(); } - guarantee(target_pc != NULL, "must have computed destination PC for implicit exception"); assert(exception_kind == IMPLICIT_NULL || exception_kind == IMPLICIT_DIVIDE_BY_ZERO, "wrong implicit exception kind"); // for AbortVMOnException flag diff --git a/src/share/vm/runtime/vframeArray.cpp b/src/share/vm/runtime/vframeArray.cpp index 3f507d2174fd82434d9e97b675e7906cd7c2f017..6a9aac2efc9a193fb775372915ea8f4d2a9c16b9 100644 --- a/src/share/vm/runtime/vframeArray.cpp +++ b/src/share/vm/runtime/vframeArray.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 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 @@ -186,7 +186,7 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters, int popframe_preserved_args_size_in_bytes = 0; int popframe_preserved_args_size_in_words = 0; if (is_top_frame) { - JvmtiThreadState *state = thread->jvmti_thread_state(); + JvmtiThreadState *state = thread->jvmti_thread_state(); if (JvmtiExport::can_pop_frame() && (thread->has_pending_popframe() || thread->popframe_forcing_deopt_reexecution())) { if (thread->has_pending_popframe()) { @@ -381,7 +381,6 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters, RegisterMap map(thread); vframe* f = vframe::new_vframe(iframe(), &map, thread); f->print(); - iframe()->interpreter_frame_print_on(tty); tty->print_cr("locals size %d", locals()->size()); tty->print_cr("expression size %d", expressions()->size()); @@ -582,7 +581,7 @@ void vframeArray::print_on_2(outputStream* st) { } void vframeArrayElement::print(outputStream* st) { - st->print_cr(" - interpreter_frame -> sp: ", INTPTR_FORMAT, iframe()->sp()); + st->print_cr(" - interpreter_frame -> sp: " INTPTR_FORMAT, iframe()->sp()); } void vframeArray::print_value_on(outputStream* st) const { diff --git a/test/compiler/6910605/Test.java b/test/compiler/6910605/Test.java new file mode 100644 index 0000000000000000000000000000000000000000..42a26e1771791ee5c14ebb21bc063215700dbdc4 --- /dev/null +++ b/test/compiler/6910605/Test.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010 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 6910605 + * @summary C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+DeoptimizeALot -Xbatch Test + * + * original test: nsk/coverage/runtime/runtime007 + */ + +import java.io.*; + +public class Test { + public static int buf=0; + + public static void main( String argv[] ) { + System.exit(run(argv, System.out)+95); + } + + public static int run(String argv[],PrintStream out) { + int ret=0, retx=0, bad=0; + + for( int i=0; (i < 100000) && (bad < 10) ; i++ ) { + retx = OptoRuntime_f2i_Type(out); + ret += retx; + if( retx !=0 ) { + out.println("i="+i); + bad++; + } + } + return ret==0 ? 0 : 2 ; + } + + public static int OptoRuntime_f2i_Type(PrintStream out) { + int c1=2, c2=3, c3=4, c4=5, c5=6; + int j=0, k=0; + try { + int[][] iii=(int[][])(new int[c1][c2]); + + for( j=0; j