# HG changeset patch # User coleenp # Date 1476749702 0 # Node ID e60e4f99ef9dbccdd76fbb2675a9754a454b033f # Parent b830f5141dbb80a775f046644339a91516c7bed5# Parent 14be0ae96c86ed5b281c24d63e9341ab27f72d9e Merge diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp --- a/hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp Tue Oct 18 00:15:02 2016 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -130,8 +130,8 @@ if (_num_fp_args < Argument::n_float_register_parameters_c) { __ ldrs(as_FloatRegister(_num_fp_args++), src); } else { - __ ldrh(r0, src); - __ strh(r0, Address(to(), _stack_offset)); + __ ldrw(r0, src); + __ strw(r0, Address(to(), _stack_offset)); _stack_offset += wordSize; _num_fp_args++; } @@ -349,7 +349,7 @@ _num_fp_args++; } else { *_to++ = from_obj; - _num_int_args++; + _num_fp_args++; } } @@ -364,7 +364,7 @@ _num_fp_args++; } else { *_to++ = from_obj; - _num_int_args++; + _num_fp_args++; } } diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp --- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Tue Oct 18 00:15:02 2016 +0000 @@ -989,7 +989,16 @@ // A float arg may have to do float reg int reg conversion static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { - if (src.first() != dst.first()) { + assert(src.first()->is_stack() && dst.first()->is_stack() || + src.first()->is_reg() && dst.first()->is_reg(), "Unexpected error"); + if (src.first()->is_stack()) { + if (dst.first()->is_stack()) { + __ ldrw(rscratch1, Address(rfp, reg2offset_in(src.first()))); + __ strw(rscratch1, Address(sp, reg2offset_out(dst.first()))); + } else { + ShouldNotReachHere(); + } + } else if (src.first() != dst.first()) { if (src.is_single_phys_reg() && dst.is_single_phys_reg()) __ fmovs(dst.first()->as_FloatRegister(), src.first()->as_FloatRegister()); else @@ -1023,7 +1032,16 @@ // A double move static void double_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { - if (src.first() != dst.first()) { + assert(src.first()->is_stack() && dst.first()->is_stack() || + src.first()->is_reg() && dst.first()->is_reg(), "Unexpected error"); + if (src.first()->is_stack()) { + if (dst.first()->is_stack()) { + __ ldr(rscratch1, Address(rfp, reg2offset_in(src.first()))); + __ str(rscratch1, Address(sp, reg2offset_out(dst.first()))); + } else { + ShouldNotReachHere(); + } + } else if (src.first() != dst.first()) { if (src.is_single_phys_reg() && dst.is_single_phys_reg()) __ fmovd(dst.first()->as_FloatRegister(), src.first()->as_FloatRegister()); else diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/cpu/ppc/vm/c1_MacroAssembler_ppc.cpp --- a/hotspot/src/cpu/ppc/vm/c1_MacroAssembler_ppc.cpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/cpu/ppc/vm/c1_MacroAssembler_ppc.cpp Tue Oct 18 00:15:02 2016 +0000 @@ -64,17 +64,16 @@ void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) { + // Avoid stack bang as first instruction. It may get overwritten by patch_verified_entry. + const Register return_pc = R20; + mflr(return_pc); + + // Make sure there is enough stack space for this method's activation. assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect"); - // Make sure there is enough stack space for this method's activation. generate_stack_overflow_check(bang_size_in_bytes); - // Create the frame. - const Register return_pc = R0; - - mflr(return_pc); - // Get callers sp. - std(return_pc, _abi(lr), R1_SP); // SP->lr = return_pc - push_frame(frame_size_in_bytes, R0); // SP -= frame_size_in_bytes + std(return_pc, _abi(lr), R1_SP); // SP->lr = return_pc + push_frame(frame_size_in_bytes, R0); // SP -= frame_size_in_bytes } diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp --- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Tue Oct 18 00:15:02 2016 +0000 @@ -2550,7 +2550,7 @@ __ lbzx(R17_tos, Rclass_or_obj, Roffset); __ extsb(R17_tos, R17_tos); __ push(ztos); - if (!is_static) { + if (!is_static && rc == may_rewrite) { // use btos rewriting, no truncating to t/f bit is needed for getfield. patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch); } @@ -2874,7 +2874,9 @@ if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1. __ andi(R17_tos, R17_tos, 0x1); __ stbx(R17_tos, Rclass_or_obj, Roffset); - if (!is_static) { patch_bytecode(Bytecodes::_fast_zputfield, Rbc, Rscratch, true, byte_no); } + if (!is_static && rc == may_rewrite) { + patch_bytecode(Bytecodes::_fast_zputfield, Rbc, Rscratch, true, byte_no); + } if (!support_IRIW_for_not_multiple_copy_atomic_cpu) { __ beq(CR_is_vol, Lvolatile); // Volatile? } diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp Tue Oct 18 00:15:02 2016 +0000 @@ -71,7 +71,7 @@ if (HotSpotMetaspaceConstantImpl::compressed(constant)) { #ifdef _LP64 NativeMovConstReg32* move = nativeMovConstReg32_at(pc); - narrowKlass narrowOop = record_narrow_metadata_reference(constant, CHECK); + narrowKlass narrowOop = record_narrow_metadata_reference(_instructions, pc, constant, CHECK); move->set_data((intptr_t)narrowOop); TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/0x%x", p2i(pc), narrowOop); #else @@ -79,7 +79,7 @@ #endif } else { NativeMovConstReg* move = nativeMovConstReg_at(pc); - void* reference = record_metadata_reference(constant, CHECK); + void* reference = record_metadata_reference(_instructions, pc, constant, CHECK); move->set_data((intptr_t)reference); TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(reference)); } diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp --- a/hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp Tue Oct 18 00:15:02 2016 +0000 @@ -89,14 +89,14 @@ if (HotSpotMetaspaceConstantImpl::compressed(constant)) { #ifdef _LP64 address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); - *((narrowKlass*) operand) = record_narrow_metadata_reference(constant, CHECK); + *((narrowKlass*) operand) = record_narrow_metadata_reference(_instructions, operand, constant, CHECK); TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand)); #else JVMCI_ERROR("compressed Klass* on 32bit"); #endif } else { address operand = Assembler::locate_operand(pc, Assembler::imm_operand); - *((void**) operand) = record_metadata_reference(constant, CHECK); + *((void**) operand) = record_metadata_reference(_instructions, operand, constant, CHECK); TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand)); } } diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java Tue Oct 18 00:15:02 2016 +0000 @@ -82,6 +82,7 @@ // Auto select a single available compiler for (JVMCICompilerFactory f : Services.load(JVMCICompilerFactory.class)) { if (factory == null) { + Services.exportJVMCITo(f.getClass()); factory = f; } else { // Multiple factories seen - cancel auto selection diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/share/vm/c1/c1_GraphBuilder.cpp --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Tue Oct 18 00:15:02 2016 +0000 @@ -1493,6 +1493,21 @@ // Check to see whether we are inlining. If so, Return // instructions become Gotos to the continuation point. if (continuation() != NULL) { + + int invoke_bci = state()->caller_state()->bci(); + + if (x != NULL && !ignore_return) { + ciMethod* caller = state()->scope()->caller()->method(); + Bytecodes::Code invoke_raw_bc = caller->raw_code_at_bci(invoke_bci); + if (invoke_raw_bc == Bytecodes::_invokehandle || invoke_raw_bc == Bytecodes::_invokedynamic) { + ciType* declared_ret_type = caller->get_declared_signature_at_bci(invoke_bci)->return_type(); + if (declared_ret_type->is_klass() && x->exact_type() == NULL && + x->declared_type() != declared_ret_type && declared_ret_type != compilation()->env()->Object_klass()) { + x = append(new TypeCast(declared_ret_type->as_klass(), x, copy_state_before())); + } + } + } + assert(!method()->is_synchronized() || InlineSynchronizedMethods, "can not inline synchronized methods yet"); if (compilation()->env()->dtrace_method_probes()) { @@ -1516,7 +1531,6 @@ // State at end of inlined method is the state of the caller // without the method parameters on stack, including the // return value, if any, of the inlined method on operand stack. - int invoke_bci = state()->caller_state()->bci(); set_state(state()->caller_state()->copy_for_parsing()); if (x != NULL) { if (!ignore_return) { diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/share/vm/c1/c1_Instruction.cpp --- a/hotspot/src/share/vm/c1/c1_Instruction.cpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/share/vm/c1/c1_Instruction.cpp Tue Oct 18 00:15:02 2016 +0000 @@ -360,7 +360,8 @@ } ciType* Invoke::declared_type() const { - ciType *t = _target->signature()->return_type(); + ciSignature* declared_signature = state()->scope()->method()->get_declared_signature_at_bci(state()->bci()); + ciType *t = declared_signature->return_type(); assert(t->basic_type() != T_VOID, "need return value of void method?"); return t; } diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/share/vm/ci/ciMethod.hpp --- a/hotspot/src/share/vm/ci/ciMethod.hpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/share/vm/ci/ciMethod.hpp Tue Oct 18 00:15:02 2016 +0000 @@ -256,6 +256,14 @@ return get_method_at_bci(bci, ignored_will_link, &ignored_declared_signature); } + ciSignature* get_declared_signature_at_bci(int bci) { + bool ignored_will_link; + ciSignature* declared_signature; + get_method_at_bci(bci, ignored_will_link, &declared_signature); + assert(declared_signature != NULL, "cannot be null"); + return declared_signature; + } + // Given a certain calling environment, find the monomorphic target // for the call. Return NULL if the call is not monomorphic in // its calling environment. diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp --- a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp Tue Oct 18 00:15:02 2016 +0000 @@ -172,7 +172,7 @@ return map; } -void* CodeInstaller::record_metadata_reference(Handle constant, TRAPS) { +void* CodeInstaller::record_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS) { /* * This method needs to return a raw (untyped) pointer, since the value of a pointer to the base * class is in general not equal to the pointer of the subclass. When patching metaspace pointers, @@ -184,12 +184,14 @@ Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj)); assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed klass pointer %s @ " INTPTR_FORMAT, klass->name()->as_C_string(), p2i(klass)); int index = _oop_recorder->find_index(klass); + section->relocate(dest, metadata_Relocation::spec(index)); TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string()); return klass; } else if (obj->is_a(HotSpotResolvedJavaMethodImpl::klass())) { Method* method = (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(obj); assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed method pointer %s @ " INTPTR_FORMAT, method->name()->as_C_string(), p2i(method)); int index = _oop_recorder->find_index(method); + section->relocate(dest, metadata_Relocation::spec(index)); TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), method->name()->as_C_string()); return method; } else { @@ -198,7 +200,7 @@ } #ifdef _LP64 -narrowKlass CodeInstaller::record_narrow_metadata_reference(Handle constant, TRAPS) { +narrowKlass CodeInstaller::record_narrow_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS) { oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant); assert(HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected uncompressed pointer"); @@ -208,6 +210,7 @@ Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj)); int index = _oop_recorder->find_index(klass); + section->relocate(dest, metadata_Relocation::spec(index)); TRACE_jvmci_3("narrowKlass[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string()); return Klass::encode_klass(klass); } @@ -701,12 +704,12 @@ if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { if (HotSpotMetaspaceConstantImpl::compressed(constant)) { #ifdef _LP64 - *((narrowKlass*) dest) = record_narrow_metadata_reference(constant, CHECK_OK); + *((narrowKlass*) dest) = record_narrow_metadata_reference(_constants, dest, constant, CHECK_OK); #else JVMCI_ERROR_OK("unexpected compressed Klass* in 32-bit mode"); #endif } else { - *((void**) dest) = record_metadata_reference(constant, CHECK_OK); + *((void**) dest) = record_metadata_reference(_constants, dest, constant, CHECK_OK); } } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) { Handle obj = HotSpotObjectConstantImpl::object(constant); diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp --- a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp Tue Oct 18 00:15:02 2016 +0000 @@ -189,9 +189,9 @@ ScopeValue* get_scope_value(Handle value, BasicType type, GrowableArray* objects, ScopeValue* &second, TRAPS); MonitorValue* get_monitor_value(Handle value, GrowableArray* objects, TRAPS); - void* record_metadata_reference(Handle constant, TRAPS); + void* record_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS); #ifdef _LP64 - narrowKlass record_narrow_metadata_reference(Handle constant, TRAPS); + narrowKlass record_narrow_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS); #endif // extract the fields of the HotSpotCompiledCode diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/share/vm/oops/methodData.hpp --- a/hotspot/src/share/vm/oops/methodData.hpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/share/vm/oops/methodData.hpp Tue Oct 18 00:15:02 2016 +0000 @@ -1190,12 +1190,11 @@ #if INCLUDE_JVMCI // Description of the different counters // ReceiverTypeData for instanceof/checkcast/aastore: - // C1/C2: count is incremented on type overflow and decremented for failed type checks - // JVMCI: count decremented for failed type checks and nonprofiled_count is incremented on type overflow - // TODO (chaeubl): in fact, JVMCI should also increment the count for failed type checks to mimic the C1/C2 behavior + // count is decremented for failed type checks + // JVMCI only: nonprofiled_count is incremented on type overflow // VirtualCallData for invokevirtual/invokeinterface: - // C1/C2: count is incremented on type overflow - // JVMCI: count is incremented on type overflow, nonprofiled_count is incremented on method overflow + // count is incremented on type overflow + // JVMCI only: nonprofiled_count is incremented on method overflow // JVMCI is interested in knowing the percentage of type checks involving a type not explicitly in the profile nonprofiled_count_off_set = counter_cell_count, diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/share/vm/opto/loopnode.cpp --- a/hotspot/src/share/vm/opto/loopnode.cpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/share/vm/opto/loopnode.cpp Tue Oct 18 00:15:02 2016 +0000 @@ -1687,6 +1687,12 @@ Node *init2 = phi2->in( LoopNode::EntryControl ); int stride_con2 = incr2->in(2)->get_int(); + // The ratio of the two strides cannot be represented as an int + // if stride_con2 is min_int and stride_con is -1. + if (stride_con2 == min_jint && stride_con == -1) { + continue; + } + // The general case here gets a little tricky. We want to find the // GCD of all possible parallel IV's and make a new IV using this // GCD for the loop. Then all possible IVs are simple multiples of diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/share/vm/opto/macro.cpp --- a/hotspot/src/share/vm/opto/macro.cpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/share/vm/opto/macro.cpp Tue Oct 18 00:15:02 2016 +0000 @@ -439,12 +439,6 @@ Node* adr = _igvn.transform(new AddPNode(base, base, MakeConX(offset))); const TypePtr* adr_type = _igvn.type(base)->is_ptr()->add_offset(offset); Node* m = ac->in(TypeFunc::Memory); - while (m->is_MergeMem()) { - m = m->as_MergeMem()->memory_at(C->get_alias_index(adr_type)); - if (m->is_Proj() && m->in(0)->is_MemBar()) { - m = m->in(0)->in(TypeFunc::Memory); - } - } res = LoadNode::make(_igvn, ctl, m, adr, adr_type, type, bt, MemNode::unordered, LoadNode::Pinned); } else { if (ac->modifies(offset, offset, &_igvn, true)) { @@ -978,6 +972,17 @@ return true; } +static void disconnect_projections(MultiNode* n, PhaseIterGVN& igvn) { + Node* ctl_proj = n->proj_out(TypeFunc::Control); + Node* mem_proj = n->proj_out(TypeFunc::Memory); + if (ctl_proj != NULL) { + igvn.replace_node(ctl_proj, n->in(0)); + } + if (mem_proj != NULL) { + igvn.replace_node(mem_proj, n->in(TypeFunc::Memory)); + } +} + // Process users of eliminated allocation. void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) { Node* res = alloc->result_cast(); @@ -1008,13 +1013,13 @@ // Disconnect ArrayCopy node ArrayCopyNode* ac = n->as_ArrayCopy(); assert(ac->is_clonebasic(), "unexpected array copy kind"); - Node* ctl_proj = ac->proj_out(TypeFunc::Control); - Node* mem_proj = ac->proj_out(TypeFunc::Memory); - if (ctl_proj != NULL) { - _igvn.replace_node(ctl_proj, n->in(0)); - } - if (mem_proj != NULL) { - _igvn.replace_node(mem_proj, n->in(TypeFunc::Memory)); + Node* membar_after = ac->proj_out(TypeFunc::Control)->unique_ctrl_out(); + disconnect_projections(ac, _igvn); + assert(alloc->in(0)->is_Proj() && alloc->in(0)->in(0)->Opcode() == Op_MemBarCPUOrder, "mem barrier expected before allocation"); + Node* membar_before = alloc->in(0)->in(0); + disconnect_projections(membar_before->as_MemBar(), _igvn); + if (membar_after->is_MemBar()) { + disconnect_projections(membar_after->as_MemBar(), _igvn); } } else { eliminate_card_mark(n); diff -r b830f5141dbb -r e60e4f99ef9d hotspot/src/share/vm/runtime/mutex.cpp --- a/hotspot/src/share/vm/runtime/mutex.cpp Wed Oct 12 10:41:00 2016 +0200 +++ b/hotspot/src/share/vm/runtime/mutex.cpp Tue Oct 18 00:15:02 2016 +0000 @@ -452,7 +452,7 @@ ParkEvent * const ESelf = Self->_MutexEvent; assert(_OnDeck != ESelf, "invariant"); - // As an optimization, spinners could conditionally try to set ONDECK to _LBIT + // As an optimization, spinners could conditionally try to set _OnDeck to _LBIT // Synchronizer.cpp uses a similar optimization. if (TrySpin(Self)) goto Exeunt; @@ -463,7 +463,7 @@ OrderAccess::fence(); // Optional optimization ... try barging on the inner lock - if ((NativeMonitorFlags & 32) && CASPTR (&_OnDeck, NULL, UNS(Self)) == 0) { + if ((NativeMonitorFlags & 32) && CASPTR (&_OnDeck, NULL, UNS(ESelf)) == 0) { goto OnDeck_LOOP; } @@ -471,14 +471,14 @@ // At any given time there is at most one ondeck thread. // ondeck implies not resident on cxq and not resident on EntryList - // Only the OnDeck thread can try to acquire -- contended for -- the lock. + // Only the OnDeck thread can try to acquire -- contend for -- the lock. // CONSIDER: use Self->OnDeck instead of m->OnDeck. // Deschedule Self so that others may run. - while (_OnDeck != ESelf) { + while (OrderAccess::load_ptr_acquire(&_OnDeck) != ESelf) { ParkCommon(ESelf, 0); } - // Self is now in the ONDECK position and will remain so until it + // Self is now in the OnDeck position and will remain so until it // manages to acquire the lock. OnDeck_LOOP: for (;;) { @@ -501,8 +501,8 @@ // A. Shift or defer dropping the inner lock until the subsequent IUnlock() operation. // This might avoid potential reacquisition of the inner lock in IUlock(). // B. While still holding the inner lock, attempt to opportunistically select - // and unlink the next ONDECK thread from the EntryList. - // If successful, set ONDECK to refer to that thread, otherwise clear ONDECK. + // and unlink the next OnDeck thread from the EntryList. + // If successful, set OnDeck to refer to that thread, otherwise clear OnDeck. // It's critical that the select-and-unlink operation run in constant-time as // it executes when holding the outer lock and may artificially increase the // effective length of the critical section. @@ -529,7 +529,7 @@ OrderAccess::release_store(&_LockWord.Bytes[_LSBINDEX], 0); // drop outer lock OrderAccess::storeload(); - ParkEvent * const w = _OnDeck; + ParkEvent * const w = _OnDeck; // raw load as we will just return if non-NULL assert(RelaxAssert || w != Thread::current()->_MutexEvent, "invariant"); if (w != NULL) { // Either we have a valid ondeck thread or ondeck is transiently "locked" @@ -537,7 +537,7 @@ // OnDeck allows us to discriminate two cases. If the latter, the // responsibility for progress and succession lies with that other thread. // For good performance, we also depend on the fact that redundant unpark() - // operations are cheap. That is, repeated Unpark()ing of the ONDECK thread + // operations are cheap. That is, repeated Unpark()ing of the OnDeck thread // is inexpensive. This approach provides implicit futile wakeup throttling. // Note that the referent "w" might be stale with respect to the lock. // In that case the following unpark() is harmless and the worst that'll happen @@ -586,8 +586,13 @@ _EntryList = w->ListNext; // as a diagnostic measure consider setting w->_ListNext = BAD assert(UNS(_OnDeck) == _LBIT, "invariant"); - _OnDeck = w; // pass OnDeck to w. - // w will clear OnDeck once it acquires the outer lock + + // Pass OnDeck role to w, ensuring that _EntryList has been set first. + // w will clear _OnDeck once it acquires the outer lock. + // Note that once we set _OnDeck that thread can acquire the mutex, proceed + // with its critical section and then enter this code to unlock the mutex. So + // you can have multiple threads active in IUnlock at the same time. + OrderAccess::release_store_ptr(&_OnDeck, w); // Another optional optimization ... // For heavily contended locks it's not uncommon that some other @@ -835,7 +840,7 @@ // ESelf is now on the cxq, EntryList or at the OnDeck position. // The following fragment is extracted from Monitor::ILock() for (;;) { - if (_OnDeck == ESelf && TrySpin(Self)) break; + if (OrderAccess::load_ptr_acquire(&_OnDeck) == ESelf && TrySpin(Self)) break; ParkCommon(ESelf, 0); } assert(_OnDeck == ESelf, "invariant"); @@ -1050,10 +1055,10 @@ // At any given time there is at most one ondeck thread. // ondeck implies not resident on cxq and not resident on EntryList - // Only the OnDeck thread can try to acquire -- contended for -- the lock. + // Only the OnDeck thread can try to acquire -- contend for -- the lock. // CONSIDER: use Self->OnDeck instead of m->OnDeck. for (;;) { - if (_OnDeck == ESelf && TrySpin(NULL)) break; + if (OrderAccess::load_ptr_acquire(&_OnDeck) == ESelf && TrySpin(NULL)) break; ParkCommon(ESelf, 0); } diff -r b830f5141dbb -r e60e4f99ef9d hotspot/test/compiler/arraycopy/TestEliminatedCloneBadMemEdge.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/arraycopy/TestEliminatedCloneBadMemEdge.java Tue Oct 18 00:15:02 2016 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016, Red Hat, 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8166836 + * @summary Elimination of clone's ArrayCopyNode may make compilation fail silently + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestEliminatedCloneBadMemEdge::not_inlined TestEliminatedCloneBadMemEdge + * + */ + +public class TestEliminatedCloneBadMemEdge implements Cloneable { + + int f1; + int f2; + int f3; + int f4; + int f5; + int f6; + int f7; + int f8; + int f9; + + static void not_inlined() {} + + static void test(TestEliminatedCloneBadMemEdge o1) throws CloneNotSupportedException { + TestEliminatedCloneBadMemEdge o2 = (TestEliminatedCloneBadMemEdge)o1.clone(); + not_inlined(); + o2.f1 = 0x42; + } + + static public void main(String[] args) throws CloneNotSupportedException { + TestEliminatedCloneBadMemEdge o1 = new TestEliminatedCloneBadMemEdge(); + for (int i = 0; i < 20000; i++) { + test(o1); + } + } +} diff -r b830f5141dbb -r e60e4f99ef9d hotspot/test/compiler/floatingpoint/Test15FloatJNIArgs.java --- a/hotspot/test/compiler/floatingpoint/Test15FloatJNIArgs.java Wed Oct 12 10:41:00 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2015 SAP SE. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* @test - * @bug 8139258 - * @summary Regression test for 8139258 which failed to properly pass float args - * to a jni function on ppc64le. - * - * @run main/othervm/native -Xint compiler.floatingpoint.Test15FloatJNIArgs - * @run main/othervm/native -XX:+TieredCompilation -Xcomp compiler.floatingpoint.Test15FloatJNIArgs - * @run main/othervm/native -XX:-TieredCompilation -Xcomp compiler.floatingpoint.Test15FloatJNIArgs - */ - -package compiler.floatingpoint; - -public class Test15FloatJNIArgs { - static { - try { - System.loadLibrary("Test15FloatJNIArgs"); - } catch (UnsatisfiedLinkError e) { - System.out.println("could not load native lib: " + e); - } - } - - public static native float add15floats( - float f1, float f2, float f3, float f4, - float f5, float f6, float f7, float f8, - float f9, float f10, float f11, float f12, - float f13, float f14, float f15); - - static void test() throws Exception { - float sum = Test15FloatJNIArgs.add15floats(1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); - if (sum != 15.0f) { - throw new Error("Passed 15 times 1.0f to jni function which didn't add them properly: " + sum); - } - } - - public static void main(String[] args) throws Exception { - for (int i = 0; i < 200; ++i) { - test(); - } - } -} diff -r b830f5141dbb -r e60e4f99ef9d hotspot/test/compiler/floatingpoint/TestFloatJNIArgs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/floatingpoint/TestFloatJNIArgs.java Tue Oct 18 00:15:02 2016 +0000 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2015, 2016 SAP SE. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8139258 8165673 + * @summary Regression test for passing float args to a jni function. + * + * + * @run main/othervm/native -Xint compiler.floatingpoint.TestFloatJNIArgs + * @run main/othervm/native -XX:+TieredCompilation -Xcomp compiler.floatingpoint.TestFloatJNIArgs + * @run main/othervm/native -XX:-TieredCompilation -Xcomp compiler.floatingpoint.TestFloatJNIArgs + */ + +package compiler.floatingpoint; + +public class TestFloatJNIArgs { + static { + try { + System.loadLibrary("TestFloatJNIArgs"); + } catch (UnsatisfiedLinkError e) { + System.out.println("could not load native lib: " + e); + } + } + + public static native float add15floats( + float f1, float f2, float f3, float f4, + float f5, float f6, float f7, float f8, + float f9, float f10, float f11, float f12, + float f13, float f14, float f15); + + public static native float add10floats( + float f1, float f2, float f3, float f4, + float f5, float f6, float f7, float f8, + float f9, float f10); + + public static native float addFloatsInts( + float f1, float f2, float f3, float f4, + float f5, float f6, float f7, float f8, + float f9, float f10, float f11, float f12, + float f13, float f14, float f15, int a16, int a17); + + public static native double add15doubles( + double d1, double d2, double d3, double d4, + double d5, double d6, double d7, double d8, + double d9, double d10, double d11, double d12, + double d13, double d14, double d15); + + static void test() throws Exception { + float sum = TestFloatJNIArgs.add15floats(1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + if (sum != 15.0f) { + throw new Error("Passed 15 times 1.0f to jni function which didn't add them properly: " + sum); + } + + float sum1 = TestFloatJNIArgs.add10floats(1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + if (sum1 != 10.0f) { + throw new Error("Passed 10 times 1.0f to jni function which didn't add them properly: " + sum1); + } + + float sum2 = TestFloatJNIArgs.addFloatsInts(1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1, 1); + if (sum2 != 17.0f) { + throw new Error("Passed 17 times 1 to jni function which didn't add them properly: " + sum2); + } + + double dsum = TestFloatJNIArgs.add15doubles(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0); + if (dsum != 15.0) { + throw new Error("Passed 15 times 1.0 to jni function which didn't add them properly: " + dsum); + } + } + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 200; ++i) { + test(); + } + } +} diff -r b830f5141dbb -r e60e4f99ef9d hotspot/test/compiler/floatingpoint/libTest15FloatJNIArgs.c --- a/hotspot/test/compiler/floatingpoint/libTest15FloatJNIArgs.c Wed Oct 12 10:41:00 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2015. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -JNIEXPORT jfloat JNICALL Java_compiler_floatingpoint_Test15FloatJNIArgs_add15floats - (JNIEnv *env, jclass cls, - jfloat f1, jfloat f2, jfloat f3, jfloat f4, - jfloat f5, jfloat f6, jfloat f7, jfloat f8, - jfloat f9, jfloat f10, jfloat f11, jfloat f12, - jfloat f13, jfloat f14, jfloat f15) { - return f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + f13 + f14 + f15; -} - -#ifdef __cplusplus -} -#endif diff -r b830f5141dbb -r e60e4f99ef9d hotspot/test/compiler/floatingpoint/libTestFloatJNIArgs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/floatingpoint/libTestFloatJNIArgs.c Tue Oct 18 00:15:02 2016 +0000 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015, 2016. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT jfloat JNICALL Java_compiler_floatingpoint_TestFloatJNIArgs_add15floats + (JNIEnv *env, jclass cls, + jfloat f1, jfloat f2, jfloat f3, jfloat f4, + jfloat f5, jfloat f6, jfloat f7, jfloat f8, + jfloat f9, jfloat f10, jfloat f11, jfloat f12, + jfloat f13, jfloat f14, jfloat f15) { + return f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + f13 + f14 + f15; +} + +JNIEXPORT jfloat JNICALL Java_compiler_floatingpoint_TestFloatJNIArgs_add10floats + (JNIEnv *env, jclass cls, + jfloat f1, jfloat f2, jfloat f3, jfloat f4, + jfloat f5, jfloat f6, jfloat f7, jfloat f8, + jfloat f9, jfloat f10) { + return f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10; +} + +JNIEXPORT jfloat JNICALL Java_compiler_floatingpoint_TestFloatJNIArgs_addFloatsInts + (JNIEnv *env, jclass cls, + jfloat f1, jfloat f2, jfloat f3, jfloat f4, + jfloat f5, jfloat f6, jfloat f7, jfloat f8, + jfloat f9, jfloat f10, jfloat f11, jfloat f12, + jfloat f13, jfloat f14, jfloat f15, jint a16, jint a17) { + return f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + f13 + f14 + f15 + a16 + a17; +} + +JNIEXPORT jdouble JNICALL Java_compiler_floatingpoint_TestFloatJNIArgs_add15doubles + (JNIEnv *env, jclass cls, + jdouble f1, jdouble f2, jdouble f3, jdouble f4, + jdouble f5, jdouble f6, jdouble f7, jdouble f8, + jdouble f9, jdouble f10, jdouble f11, jdouble f12, + jdouble f13, jdouble f14, jdouble f15) { + return f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + f13 + f14 + f15; +} + + +#ifdef __cplusplus +} +#endif diff -r b830f5141dbb -r e60e4f99ef9d hotspot/test/compiler/jsr292/TestArrayReturnType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jsr292/TestArrayReturnType.java Tue Oct 18 00:15:02 2016 +0000 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8134389 + * + * @run main/othervm -Xbatch compiler.jsr292.TestArrayReturnType + * @run main/othervm -Xbatch -XX:-Inline compiler.jsr292.TestArrayReturnType + * @run main/othervm -Xbatch + * -XX:CompileCommand=exclude,compiler.jsr292.TestArrayReturnType::testArrayReturnType + * compiler.jsr292.TestArrayReturnType + */ + +package compiler.jsr292; + + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class TestArrayReturnType { + + static final MethodHandle mh; + static int[] testArray = new int[1]; + static { + try { + mh = MethodHandles.lookup().findStatic(TestArrayReturnType.class, "testArrayReturnType", MethodType.methodType(int[].class)); + } catch (Exception e) { + throw new Error(e); + } + } + + static int[] testArrayReturnType() { + return testArray; + } + + public static void test() throws Throwable { + int a[] = (int[])mh.invokeExact(); + for (int i=0; i= 0; i--) { + sum += Integer.MIN_VALUE; + } + } + + public static void main(String[] args) { + testMethod(); + } +}