Mercurial > hg > release > icedtea7-forest-2.5 > hotspot
changeset 5775:4bd5a78ac552
Merge
author | coffeys |
---|---|
date | Thu, 07 Aug 2014 12:19:10 +0100 |
parents | c97866b6d4b0 (current diff) 342e3e35fdc1 (diff) |
children | fe122ef372f5 |
files | .hgtags |
diffstat | 21 files changed, 108 insertions(+), 125 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Tue Jul 22 10:23:29 2014 -0700 +++ b/.hgtags Thu Aug 07 12:19:10 2014 +0100 @@ -711,9 +711,15 @@ 0cb0b5abd0b5aa25fc8bd5920c8d61c5b85a10c6 jdk7u71-b03 a491e5e52998c23502ebb1340955e3e726d44ad6 jdk7u71-b04 c93efe6377ffd7484c50cba9a88a37bebf525114 jdk7u71-b05 +f95fa655cc119659686ba68c7242497fd209f9e1 jdk7u71-b06 +7f32b65fde34db41bf951ed81374240840ef88f4 jdk7u71-b07 +4e17bd4fb2304d068023d9d805e86d6b592d4230 jdk7u71-b08 1bd3adac3aac3c29c81303812b35f484ff90cb2b jdk7u72-b01 0caed46767e35c00eff69b22acf984d98eb66b3d jdk7u72-b02 3a2934191de4bb8ca9d2faca93f3381e521e8cac jdk7u72-b03 e4708cde2898df4c936595aacb57bc5b4e15869a jdk7u72-b04 137e0859cd296cb8d9f9e327112ddc793ed59318 jdk7u72-b05 +4d9d227d70f33b70461230172386217317954312 jdk7u72-b06 +ece56f93f37b41b9c8875e54fbd8010277f6b460 jdk7u72-b07 +439c695a7aa03652ab92681120434b9ce8cdd2b7 jdk7u72-b08 e6b6d91b3934c281086f8efacb0926e7451cc18b jdk7u75-b00
--- a/agent/src/os/linux/libproc.h Tue Jul 22 10:23:29 2014 -0700 +++ b/agent/src/os/linux/libproc.h Thu Aug 07 12:19:10 2014 +0100 @@ -34,19 +34,7 @@ #include "libproc_md.h" #endif -#if defined(sparc) || defined(sparcv9) -/* - If _LP64 is defined ptrace.h should be taken from /usr/include/asm-sparc64 - otherwise it should be from /usr/include/asm-sparc - These two files define pt_regs structure differently -*/ -#ifdef _LP64 -#include "asm-sparc64/ptrace.h" -#else -#include "asm-sparc/ptrace.h" -#endif - -#endif //sparc or sparcv9 +#include <linux/ptrace.h> /************************************************************************************
--- a/src/cpu/sparc/vm/assembler_sparc.hpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp Thu Aug 07 12:19:10 2014 +0100 @@ -1745,7 +1745,7 @@ inline void swap( Register s1, Register s2, Register d ); inline void swap( Register s1, int simm13a, Register d); - inline void swap( Address& a, Register d, int offset = 0 ); + inline void swap( const Address& a, Register d, int offset = 0 ); // pp 232
--- a/src/cpu/sparc/vm/assembler_sparc.inline.hpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/cpu/sparc/vm/assembler_sparc.inline.hpp Thu Aug 07 12:19:10 2014 +0100 @@ -347,7 +347,7 @@ inline void Assembler::swap( Register s1, Register s2, Register d) { v9_dep(); emit_long( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | rs2(s2) ); } inline void Assembler::swap( Register s1, int simm13a, Register d) { v9_dep(); emit_data( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } -inline void Assembler::swap( Address& a, Register d, int offset ) { +inline void Assembler::swap( const Address& a, Register d, int offset ) { relocate(a.rspec(offset)); if (a.has_index()) { assert(offset == 0, ""); swap( a.base(), a.index(), d ); } else { swap( a.base(), a.disp() + offset, d ); }
--- a/src/cpu/sparc/vm/copy_sparc.hpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/cpu/sparc/vm/copy_sparc.hpp Thu Aug 07 12:19:10 2014 +0100 @@ -184,7 +184,7 @@ assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation"); if (value == 0 && UseBlockZeroing && - (count > (BlockZeroingLowLimit >> LogHeapWordSize))) { + (count > (size_t)(BlockZeroingLowLimit >> LogHeapWordSize))) { // Call it only when block zeroing is used ((_zero_Fn)StubRoutines::zero_aligned_words())(tohw, count); } else {
--- a/src/cpu/sparc/vm/frame_sparc.hpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/cpu/sparc/vm/frame_sparc.hpp Thu Aug 07 12:19:10 2014 +0100 @@ -282,8 +282,8 @@ // next two fns read and write Lmonitors value, private: - BasicObjectLock* interpreter_frame_monitors() const { return *interpreter_frame_monitors_addr(); } - void interpreter_frame_set_monitors(BasicObjectLock* monitors) { *interpreter_frame_monitors_addr() = monitors; } + BasicObjectLock* interpreter_frame_monitors() const; + void interpreter_frame_set_monitors(BasicObjectLock* monitors); #else public: inline interpreterState get_interpreterState() const {
--- a/src/cpu/sparc/vm/frame_sparc.inline.hpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/cpu/sparc/vm/frame_sparc.inline.hpp Thu Aug 07 12:19:10 2014 +0100 @@ -217,6 +217,13 @@ return (methodOop*)sp_addr_at( Lmethod->sp_offset_in_saved_window()); } +inline BasicObjectLock* frame::interpreter_frame_monitors() const { + return *interpreter_frame_monitors_addr(); +} + +inline void frame::interpreter_frame_set_monitors(BasicObjectLock* monitors) { + *interpreter_frame_monitors_addr() = monitors; +} // Constant pool cache
--- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Aug 07 12:19:10 2014 +0100 @@ -89,7 +89,7 @@ private: #ifdef PRODUCT -#define inc_counter_np(a,b,c) (0) +#define inc_counter_np(a,b,c) #else #define inc_counter_np(counter, t1, t2) \ BLOCK_COMMENT("inc_counter " #counter); \ @@ -1126,7 +1126,7 @@ Label& L_loop, bool use_prefetch, bool use_bis); void disjoint_copy_core(Register from, Register to, Register count, int log2_elem_size, - int iter_size, CopyLoopFunc copy_loop_func) { + int iter_size, StubGenerator::CopyLoopFunc copy_loop_func) { Label L_copy; assert(log2_elem_size <= 3, "the following code should be changed"); @@ -1277,7 +1277,7 @@ __ inc(from, 8); __ sllx(O3, left_shift, O3); - disjoint_copy_core(from, to, count, log2_elem_size, 16, copy_16_bytes_shift_loop); + disjoint_copy_core(from, to, count, log2_elem_size, 16, &StubGenerator::copy_16_bytes_shift_loop); __ inccc(count, count_dec>>1 ); // + 8 bytes __ brx(Assembler::negative, true, Assembler::pn, L_copy_last_bytes); @@ -2156,7 +2156,7 @@ __ dec(count, 4); // The cmp at the beginning guaranty count >= 4 __ sllx(O3, 32, O3); - disjoint_copy_core(from, to, count, 2, 16, copy_16_bytes_loop); + disjoint_copy_core(from, to, count, 2, 16, &StubGenerator::copy_16_bytes_loop); __ br(Assembler::always, false, Assembler::pt, L_copy_4_bytes); __ delayed()->inc(count, 4); // restore 'count' @@ -2437,7 +2437,7 @@ // count >= 0 (original count - 8) __ mov(from, from64); - disjoint_copy_core(from64, to64, count, 3, 64, copy_64_bytes_loop); + disjoint_copy_core(from64, to64, count, 3, 64, &StubGenerator::copy_64_bytes_loop); // Restore O4(offset0), O5(offset8) __ sub(from64, from, offset0);
--- a/src/os_cpu/linux_sparc/vm/assembler_linux_sparc.cpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/os_cpu/linux_sparc/vm/assembler_linux_sparc.cpp Thu Aug 07 12:19:10 2014 +0100 @@ -28,7 +28,7 @@ #include "runtime/os.hpp" #include "runtime/threadLocalStorage.hpp" -#include <asm-sparc/traps.h> +#include <asm/traps.h> void MacroAssembler::read_ccr_trap(Register ccr_save) { // No implementation
--- a/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp Thu Aug 07 12:19:10 2014 +0100 @@ -79,12 +79,12 @@ __asm__ volatile( "1: \n\t" " ldx [%2], %%o2\n\t" - " add %0, %%o2, %%o3\n\t" + " add %1, %%o2, %%o3\n\t" " casx [%2], %%o2, %%o3\n\t" " cmp %%o2, %%o3\n\t" " bne %%xcc, 1b\n\t" " nop\n\t" - " add %0, %%o2, %0\n\t" + " add %1, %%o2, %0\n\t" : "=r" (rv) : "r" (add_value), "r" (dest) : "memory", "o2", "o3");
--- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Thu Aug 07 12:19:10 2014 +0100 @@ -118,7 +118,7 @@ *ret_sp = os::Linux::ucontext_get_sp(uc); } if (ret_fp) { - *ret_fp = os::Linux::ucontext_get_fp(uc); + *ret_fp = (intptr_t*)NULL; } } else { // construct empty ExtendedPC for return value checking @@ -136,18 +136,15 @@ frame os::fetch_frame_from_context(void* ucVoid) { intptr_t* sp; - intptr_t* fp; - ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); - return frame(sp, fp, epc.pc()); + ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, NULL); + return frame(sp, frame::unpatchable, epc.pc()); } frame os::get_sender_for_C_frame(frame* fr) { - return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); + return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc()); } frame os::current_frame() { - fprintf(stderr, "current_frame()"); - intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()(); frame myframe(sp, frame::unpatchable, CAST_FROM_FN_PTR(address, os::current_frame)); @@ -302,29 +299,30 @@ if (context == NULL) return; ucontext_t *uc = (ucontext_t*)context; + sigcontext* sc = (sigcontext*)context; intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc); st->print_cr("Register to memory mapping:"); st->cr(); // this is only for the "general purpose" registers - st->print("G1="); print_location(st, SIG_REGS(sc).u_regs[CON__G1]); - st->print("G2="); print_location(st, SIG_REGS(sc).u_regs[CON__G2]); - st->print("G3="); print_location(st, SIG_REGS(sc).u_regs[CON__G3]); - st->print("G4="); print_location(st, SIG_REGS(sc).u_regs[CON__G4]); - st->print("G5="); print_location(st, SIG_REGS(sc).u_regs[CON__G5]); - st->print("G6="); print_location(st, SIG_REGS(sc).u_regs[CON__G6]); - st->print("G7="); print_location(st, SIG_REGS(sc).u_regs[CON__G7]); + st->print("G1="); print_location(st, SIG_REGS(sc).u_regs[CON_G1]); + st->print("G2="); print_location(st, SIG_REGS(sc).u_regs[CON_G2]); + st->print("G3="); print_location(st, SIG_REGS(sc).u_regs[CON_G3]); + st->print("G4="); print_location(st, SIG_REGS(sc).u_regs[CON_G4]); + st->print("G5="); print_location(st, SIG_REGS(sc).u_regs[CON_G5]); + st->print("G6="); print_location(st, SIG_REGS(sc).u_regs[CON_G6]); + st->print("G7="); print_location(st, SIG_REGS(sc).u_regs[CON_G7]); st->cr(); - st->print("O0="); print_location(st, SIG_REGS(sc).u_regs[CON__O0]); - st->print("O1="); print_location(st, SIG_REGS(sc).u_regs[CON__O1]); - st->print("O2="); print_location(st, SIG_REGS(sc).u_regs[CON__O2]); - st->print("O3="); print_location(st, SIG_REGS(sc).u_regs[CON__O3]); - st->print("O4="); print_location(st, SIG_REGS(sc).u_regs[CON__O4]); - st->print("O5="); print_location(st, SIG_REGS(sc).u_regs[CON__O5]); - st->print("O6="); print_location(st, SIG_REGS(sc).u_regs[CON__O6]); - st->print("O7="); print_location(st, SIG_REGS(sc).u_regs[CON__O7]); + st->print("O0="); print_location(st, SIG_REGS(sc).u_regs[CON_O0]); + st->print("O1="); print_location(st, SIG_REGS(sc).u_regs[CON_O1]); + st->print("O2="); print_location(st, SIG_REGS(sc).u_regs[CON_O2]); + st->print("O3="); print_location(st, SIG_REGS(sc).u_regs[CON_O3]); + st->print("O4="); print_location(st, SIG_REGS(sc).u_regs[CON_O4]); + st->print("O5="); print_location(st, SIG_REGS(sc).u_regs[CON_O5]); + st->print("O6="); print_location(st, SIG_REGS(sc).u_regs[CON_O6]); + st->print("O7="); print_location(st, SIG_REGS(sc).u_regs[CON_O7]); st->cr(); st->print("L0="); print_location(st, sp[L0->sp_offset_in_saved_window()]); @@ -525,7 +523,7 @@ if (nativeInstruction_at(*pc)->is_ic_miss_trap()) { #ifdef ASSERT #ifdef TIERED - CodeBlob* cb = CodeCache::find_blob_unsafe(pc); + CodeBlob* cb = CodeCache::find_blob_unsafe(*pc); assert(cb->is_compiled_by_c2(), "Wrong compiler"); #endif // TIERED #endif // ASSERT
--- a/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp Thu Aug 07 12:19:10 2014 +0100 @@ -55,7 +55,7 @@ if (detect_niagara()) { NOT_PRODUCT(if (PrintMiscellaneous && Verbose) tty->print_cr("Detected Linux on Niagara");) - features = niagara1_m; + features = niagara1_m | T_family_m; } return features;
--- a/src/share/vm/classfile/stackMapTable.cpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/share/vm/classfile/stackMapTable.cpp Thu Aug 07 12:19:10 2014 +0100 @@ -70,24 +70,26 @@ bool StackMapTable::match_stackmap( StackMapFrame* frame, int32_t target, - bool match, bool update, ErrorContext* ctx, TRAPS) const { + bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const { int index = get_index_from_offset(target); - return match_stackmap(frame, target, index, match, update, ctx, THREAD); + return match_stackmap(frame, target, index, match, update, handler, ctx, THREAD); } // Match and/or update current_frame to the frame in stackmap table with // specified offset and frame index. Return true if the two frames match. +// handler is true if the frame in stackmap_table is for an exception handler. // -// The values of match and update are: _match__update_ +// The values of match and update are: _match__update__handler // -// checking a branch target/exception handler: true false +// checking a branch target: true false false +// checking an exception handler: true false true // linear bytecode verification following an -// unconditional branch: false true +// unconditional branch: false true false // linear bytecode verification not following an -// unconditional branch: true true +// unconditional branch: true true false bool StackMapTable::match_stackmap( StackMapFrame* frame, int32_t target, int32_t frame_index, - bool match, bool update, ErrorContext* ctx, TRAPS) const { + bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const { if (frame_index < 0 || frame_index >= _frame_count) { *ctx = ErrorContext::missing_stackmap(frame->offset()); frame->verifier()->verify_error( @@ -98,11 +100,9 @@ StackMapFrame *stackmap_frame = _frame_array[frame_index]; bool result = true; if (match) { - // when checking handler target, match == true && update == false - bool is_exception_handler = !update; // Has direct control flow from last instruction, need to match the two // frames. - result = frame->is_assignable_to(stackmap_frame, is_exception_handler, + result = frame->is_assignable_to(stackmap_frame, handler, ctx, CHECK_VERIFY_(frame->verifier(), result)); } if (update) { @@ -126,7 +126,7 @@ StackMapFrame* frame, int32_t target, TRAPS) const { ErrorContext ctx; bool match = match_stackmap( - frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier())); + frame, target, true, false, false, &ctx, CHECK_VERIFY(frame->verifier())); if (!match || (target < 0 || target >= _code_length)) { frame->verifier()->verify_error(ctx, "Inconsistent stackmap frames at branch target %d", target); @@ -134,7 +134,6 @@ } // check if uninitialized objects exist on backward branches check_new_object(frame, target, CHECK_VERIFY(frame->verifier())); - frame->verifier()->update_furthest_jump(target); } void StackMapTable::check_new_object(
--- a/src/share/vm/classfile/stackMapTable.hpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/share/vm/classfile/stackMapTable.hpp Thu Aug 07 12:19:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,12 +74,12 @@ // specified offset. Return true if the two frames match. bool match_stackmap( StackMapFrame* current_frame, int32_t offset, - bool match, bool update, ErrorContext* ctx, TRAPS) const; + bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const; // Match and/or update current_frame to the frame in stackmap table with // specified offset and frame index. Return true if the two frames match. bool match_stackmap( StackMapFrame* current_frame, int32_t offset, int32_t frame_index, - bool match, bool update, ErrorContext* ctx, TRAPS) const; + bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const; // Check jump instructions. Make sure there are no uninitialized // instances on backward branch.
--- a/src/share/vm/classfile/verifier.cpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/share/vm/classfile/verifier.cpp Thu Aug 07 12:19:10 2014 +0100 @@ -630,8 +630,6 @@ // flow from current instruction to the next // instruction in sequence - set_furthest_jump(0); - Bytecodes::Code opcode; while (!bcs.is_last_bytecode()) { // Check for recursive re-verification before each bytecode. @@ -1788,7 +1786,7 @@ // If matched, current_frame will be updated by this method. bool matches = stackmap_table->match_stackmap( current_frame, this_offset, stackmap_index, - !no_control_flow, true, &ctx, CHECK_VERIFY_(this, 0)); + !no_control_flow, true, false, &ctx, CHECK_VERIFY_(this, 0)); if (!matches) { // report type error verify_error(ctx, "Instruction type does not match stack map"); @@ -1835,7 +1833,7 @@ } ErrorContext ctx; bool matches = stackmap_table->match_stackmap( - new_frame, handler_pc, true, false, &ctx, CHECK_VERIFY(this)); + new_frame, handler_pc, true, false, true, &ctx, CHECK_VERIFY(this)); if (!matches) { verify_error(ctx, "Stack map does not match the one at " "exception handler %d", handler_pc); @@ -2243,13 +2241,6 @@ return; } - // Make sure that this call is not jumped over. - if (bci < furthest_jump()) { - verify_error(ErrorContext::bad_code(bci), - "Bad <init> method call from inside of a branch"); - return; - } - // Make sure that this call is not done from within a TRY block because // that can result in returning an incomplete object. Simply checking // (bci >= start_pc) also ensures that this call is not done after a TRY
--- a/src/share/vm/classfile/verifier.hpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/share/vm/classfile/verifier.hpp Thu Aug 07 12:19:10 2014 +0100 @@ -256,9 +256,6 @@ ErrorContext _error_context; // contains information about an error - // Used to detect illegal jumps over calls to super() and this() in ctors. - int32_t _furthest_jump; - void verify_method(methodHandle method, TRAPS); char* generate_code_data(methodHandle m, u4 code_length, TRAPS); void verify_exception_handler_table(u4 code_length, char* code_data, @@ -402,19 +399,6 @@ TypeOrigin ref_ctx(const char* str, TRAPS); - // Keep track of the furthest branch done in a method to make sure that - // there are no branches over calls to super() or this() from inside of - // a constructor. - int32_t furthest_jump() { return _furthest_jump; } - - void set_furthest_jump(int32_t target) { - _furthest_jump = target; - } - - void update_furthest_jump(int32_t target) { - if (target > _furthest_jump) _furthest_jump = target; - } - }; inline int ClassVerifier::change_sig_to_verificationType(
--- a/src/share/vm/opto/compile.cpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/share/vm/opto/compile.cpp Thu Aug 07 12:19:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -669,6 +669,7 @@ #endif set_print_inlining(PrintInlining || method()->has_option("PrintInlining") NOT_PRODUCT( || PrintOptoInlining)); set_print_intrinsics(PrintIntrinsics || method()->has_option("PrintIntrinsics")); + set_has_irreducible_loop(true); // conservative until build_loop_tree() reset it if (ProfileTraps) { // Make sure the method being compiled gets its own MDO, @@ -936,6 +937,8 @@ set_print_assembly(PrintFrameConverterAssembly); set_parsed_irreducible_loop(false); #endif + set_has_irreducible_loop(false); // no loops + CompileWrapper cw(this); Init(/*AliasLevel=*/ 0); init_tf((*generator)()); @@ -1100,7 +1103,7 @@ if( start->is_Start() ) return start->as_Start(); } - ShouldNotReachHere(); + fatal("Did not find Start node!"); return NULL; }
--- a/src/share/vm/opto/compile.hpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/share/vm/opto/compile.hpp Thu Aug 07 12:19:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -291,6 +291,7 @@ bool _trace_opto_output; bool _parsed_irreducible_loop; // True if ciTypeFlow detected irreducible loops during parsing #endif + bool _has_irreducible_loop; // Found irreducible loops // JSR 292 bool _has_method_handle_invokes; // True if this method has MethodHandle invokes. @@ -552,6 +553,8 @@ bool parsed_irreducible_loop() const { return _parsed_irreducible_loop; } void set_parsed_irreducible_loop(bool z) { _parsed_irreducible_loop = z; } #endif + bool has_irreducible_loop() const { return _has_irreducible_loop; } + void set_has_irreducible_loop(bool z) { _has_irreducible_loop = z; } // JSR 292 bool has_method_handle_invokes() const { return _has_method_handle_invokes; }
--- a/src/share/vm/opto/loopnode.cpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/share/vm/opto/loopnode.cpp Thu Aug 07 12:19:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -266,9 +266,9 @@ // Counted loop head must be a good RegionNode with only 3 not NULL // control input edges: Self, Entry, LoopBack. - if (x->in(LoopNode::Self) == NULL || x->req() != 3) + if (x->in(LoopNode::Self) == NULL || x->req() != 3 || loop->_irreducible) { return false; - + } Node *init_control = x->in(LoopNode::EntryControl); Node *back_control = x->in(LoopNode::LoopBackControl); if (init_control == NULL || back_control == NULL) // Partially dead @@ -1522,11 +1522,11 @@ // If I have one hot backedge, peel off myself loop. // I better be the outermost loop. - if( _head->req() > 3 ) { + if (_head->req() > 3 && !_irreducible) { split_outer_loop( phase ); result = true; - } else if( !_head->is_Loop() && !_irreducible ) { + } else if (!_head->is_Loop() && !_irreducible) { // Make a new LoopNode to replace the old loop head Node *l = new (phase->C) LoopNode( _head->in(1), _head->in(2) ); l = igvn.register_new_node_with_optimizer(l, _head); @@ -2938,6 +2938,7 @@ return pre_order; } } + C->set_has_irreducible_loop(_has_irreducible_loops); } // This Node might be a decision point for loops. It is only if
--- a/src/share/vm/opto/memnode.cpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/share/vm/opto/memnode.cpp Thu Aug 07 12:19:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -292,33 +292,16 @@ int alias_idx = phase->C->get_alias_index(t_adr->is_ptr()); } -#ifdef ASSERT Node* base = NULL; - if (address->is_AddP()) + if (address->is_AddP()) { base = address->in(AddPNode::Base); + } if (base != NULL && phase->type(base)->higher_equal(TypePtr::NULL_PTR) && !t_adr->isa_rawptr()) { // Note: raw address has TOP base and top->higher_equal(TypePtr::NULL_PTR) is true. - Compile* C = phase->C; - tty->cr(); - tty->print_cr("===== NULL+offs not RAW address ====="); - if (C->is_dead_node(this->_idx)) tty->print_cr("'this' is dead"); - if ((ctl != NULL) && C->is_dead_node(ctl->_idx)) tty->print_cr("'ctl' is dead"); - if (C->is_dead_node(mem->_idx)) tty->print_cr("'mem' is dead"); - if (C->is_dead_node(address->_idx)) tty->print_cr("'address' is dead"); - if (C->is_dead_node(base->_idx)) tty->print_cr("'base' is dead"); - tty->cr(); - base->dump(1); - tty->cr(); - this->dump(2); - tty->print("this->adr_type(): "); adr_type()->dump(); tty->cr(); - tty->print("phase->type(address): "); t_adr->dump(); tty->cr(); - tty->print("phase->type(base): "); phase->type(address)->dump(); tty->cr(); - tty->cr(); + // Skip this node optimization if its address has TOP base. + return NodeSentinel; // caller will return NULL } - assert(base == NULL || t_adr->isa_rawptr() || - !phase->type(base)->higher_equal(TypePtr::NULL_PTR), "NULL+offs not RAW address?"); -#endif // Avoid independent memory operations Node* old_mem = mem;
--- a/src/share/vm/opto/node.cpp Tue Jul 22 10:23:29 2014 -0700 +++ b/src/share/vm/opto/node.cpp Thu Aug 07 12:19:10 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ #include "memory/allocation.inline.hpp" #include "opto/cfgnode.hpp" #include "opto/connode.hpp" +#include "opto/loopnode.hpp" #include "opto/machnode.hpp" #include "opto/matcher.hpp" #include "opto/node.hpp" @@ -1225,6 +1226,7 @@ Node *top = igvn->C->top(); nstack.push(dead); + bool has_irreducible_loop = igvn->C->has_irreducible_loop(); while (nstack.size() > 0) { dead = nstack.pop(); @@ -1239,13 +1241,31 @@ assert (!use->is_Con(), "Control for Con node should be Root node."); use->set_req(0, top); // Cut dead edge to prevent processing nstack.push(use); // the dead node again. + } else if (!has_irreducible_loop && // Backedge could be alive in irreducible loop + use->is_Loop() && !use->is_Root() && // Don't kill Root (RootNode extends LoopNode) + use->in(LoopNode::EntryControl) == dead) { // Dead loop if its entry is dead + use->set_req(LoopNode::EntryControl, top); // Cut dead edge to prevent processing + use->set_req(0, top); // Cut self edge + nstack.push(use); } else { // Else found a not-dead user + // Dead if all inputs are top or null + bool dead_use = !use->is_Root(); // Keep empty graph alive for (uint j = 1; j < use->req(); j++) { - if (use->in(j) == dead) { // Turn all dead inputs into TOP + Node* in = use->in(j); + if (in == dead) { // Turn all dead inputs into TOP use->set_req(j, top); + } else if (in != NULL && !in->is_top()) { + dead_use = false; } } - igvn->_worklist.push(use); + if (dead_use) { + if (use->is_Region()) { + use->set_req(0, top); // Cut self edge + } + nstack.push(use); + } else { + igvn->_worklist.push(use); + } } // Refresh the iterator, since any number of kills might have happened. k = dead->last_outs(kmin);