From fad19589454c0fd88c760cf86c59cacb48ec3a8a Mon Sep 17 00:00:00 2001 From: goetz Date: Fri, 12 Dec 2014 08:48:56 +0100 Subject: [PATCH] 8066964: ppc64: argument and return type profiling, fix problem with popframe Reviewed-by: roland, kvn --- src/cpu/ppc/vm/interp_masm_ppc_64.cpp | 234 +++++++++++++++++- src/cpu/ppc/vm/interp_masm_ppc_64.hpp | 6 + src/cpu/ppc/vm/macroAssembler_ppc.cpp | 46 ++-- src/cpu/ppc/vm/macroAssembler_ppc.hpp | 1 + src/cpu/ppc/vm/nativeInst_ppc.cpp | 12 +- src/cpu/ppc/vm/ppc.ad | 10 +- src/cpu/ppc/vm/templateInterpreter_ppc.cpp | 22 +- src/cpu/ppc/vm/templateTable_ppc_64.cpp | 16 ++ src/cpu/ppc/vm/vm_version_ppc.cpp | 35 ++- src/os/aix/vm/os_aix.cpp | 215 ++++++++-------- src/os/aix/vm/os_aix.hpp | 2 +- src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp | 9 +- src/os_cpu/aix_ppc/vm/os_aix_ppc.hpp | 6 +- .../aix_ppc/vm/prefetch_aix_ppc.inline.hpp | 6 +- src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp | 6 +- src/os_cpu/aix_ppc/vm/thread_aix_ppc.hpp | 6 +- src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp | 2 +- 17 files changed, 458 insertions(+), 176 deletions(-) diff --git a/src/cpu/ppc/vm/interp_masm_ppc_64.cpp b/src/cpu/ppc/vm/interp_masm_ppc_64.cpp index 234e64e6c..0d39104ac 100644 --- a/src/cpu/ppc/vm/interp_masm_ppc_64.cpp +++ b/src/cpu/ppc/vm/interp_masm_ppc_64.cpp @@ -545,6 +545,9 @@ void InterpreterMacroAssembler::index_check_without_pop(Register Rarray, Registe cmplw(CCR0, Rindex, Rlength); sldi(RsxtIndex, RsxtIndex, index_shift); blt(CCR0, LnotOOR); + // Index should be in R17_tos, array should be in R4_ARG2. + mr(R17_tos, Rindex); + mr(R4_ARG2, Rarray); load_dispatch_table(Rtmp, (address*)Interpreter::_throw_ArrayIndexOutOfBoundsException_entry); mtctr(Rtmp); bctr(); @@ -1679,6 +1682,228 @@ void InterpreterMacroAssembler::record_klass_in_profile_helper( } } +// Argument and return type profilig. +// kills: tmp, tmp2, R0, CR0, CR1 +void InterpreterMacroAssembler::profile_obj_type(Register obj, Register mdo_addr_base, + RegisterOrConstant mdo_addr_offs, Register tmp, Register tmp2) { + Label do_nothing, do_update; + + // tmp2 = obj is allowed + assert_different_registers(obj, mdo_addr_base, tmp, R0); + assert_different_registers(tmp2, mdo_addr_base, tmp, R0); + const Register klass = tmp2; + + verify_oop(obj); + + ld(tmp, mdo_addr_offs, mdo_addr_base); + + // Set null_seen if obj is 0. + cmpdi(CCR0, obj, 0); + ori(R0, tmp, TypeEntries::null_seen); + beq(CCR0, do_update); + + load_klass(klass, obj); + + clrrdi(R0, tmp, exact_log2(-TypeEntries::type_klass_mask)); + // Basically same as andi(R0, tmp, TypeEntries::type_klass_mask); + cmpd(CCR1, R0, klass); + // Klass seen before, nothing to do (regardless of unknown bit). + //beq(CCR1, do_nothing); + + andi_(R0, klass, TypeEntries::type_unknown); + // Already unknown. Nothing to do anymore. + //bne(CCR0, do_nothing); + crorc(/*CCR0 eq*/2, /*CCR1 eq*/4+2, /*CCR0 eq*/2); // cr0 eq = cr1 eq or cr0 ne + beq(CCR0, do_nothing); + + clrrdi_(R0, tmp, exact_log2(-TypeEntries::type_mask)); + orr(R0, klass, tmp); // Combine klass and null_seen bit (only used if (tmp & type_mask)==0). + beq(CCR0, do_update); // First time here. Set profile type. + + // Different than before. Cannot keep accurate profile. + ori(R0, tmp, TypeEntries::type_unknown); + + bind(do_update); + // update profile + std(R0, mdo_addr_offs, mdo_addr_base); + + align(32, 12); + bind(do_nothing); +} + +void InterpreterMacroAssembler::profile_arguments_type(Register callee, Register tmp1, Register tmp2, bool is_virtual) { + if (!ProfileInterpreter) { + return; + } + + assert_different_registers(callee, tmp1, tmp2, R28_mdx); + + if (MethodData::profile_arguments() || MethodData::profile_return()) { + Label profile_continue; + + test_method_data_pointer(profile_continue); + + int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size()); + + lbz(tmp1, in_bytes(DataLayout::tag_offset()) - off_to_start, R28_mdx); + cmpwi(CCR0, tmp1, is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag); + bne(CCR0, profile_continue); + + if (MethodData::profile_arguments()) { + Label done; + int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset()); + add(R28_mdx, off_to_args, R28_mdx); + + for (int i = 0; i < TypeProfileArgsLimit; i++) { + if (i > 0 || MethodData::profile_return()) { + // If return value type is profiled we may have no argument to profile. + ld(tmp1, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args, R28_mdx); + cmpdi(CCR0, tmp1, (i+1)*TypeStackSlotEntries::per_arg_count()); + addi(tmp1, tmp1, -i*TypeStackSlotEntries::per_arg_count()); + blt(CCR0, done); + } + ld(tmp1, in_bytes(Method::const_offset()), callee); + lhz(tmp1, in_bytes(ConstMethod::size_of_parameters_offset()), tmp1); + // Stack offset o (zero based) from the start of the argument + // list, for n arguments translates into offset n - o - 1 from + // the end of the argument list. But there's an extra slot at + // the top of the stack. So the offset is n - o from Lesp. + ld(tmp2, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args, R28_mdx); + subf(tmp1, tmp2, tmp1); + + sldi(tmp1, tmp1, Interpreter::logStackElementSize); + ldx(tmp1, tmp1, R15_esp); + + profile_obj_type(tmp1, R28_mdx, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args, tmp2, tmp1); + + int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); + addi(R28_mdx, R28_mdx, to_add); + off_to_args += to_add; + } + + if (MethodData::profile_return()) { + ld(tmp1, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args, R28_mdx); + addi(tmp1, tmp1, -TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count()); + } + + bind(done); + + if (MethodData::profile_return()) { + // We're right after the type profile for the last + // argument. tmp1 is the number of cells left in the + // CallTypeData/VirtualCallTypeData to reach its end. Non null + // if there's a return to profile. + assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type"); + sldi(tmp1, tmp1, exact_log2(DataLayout::cell_size)); + add(R28_mdx, tmp1, R28_mdx); + } + } else { + assert(MethodData::profile_return(), "either profile call args or call ret"); + update_mdp_by_constant(in_bytes(TypeEntriesAtCall::return_only_size())); + } + + // Mdp points right after the end of the + // CallTypeData/VirtualCallTypeData, right after the cells for the + // return value type if there's one. + align(32, 12); + bind(profile_continue); + } +} + +void InterpreterMacroAssembler::profile_return_type(Register ret, Register tmp1, Register tmp2) { + assert_different_registers(ret, tmp1, tmp2); + if (ProfileInterpreter && MethodData::profile_return()) { + Label profile_continue; + + test_method_data_pointer(profile_continue); + + if (MethodData::profile_return_jsr292_only()) { + // If we don't profile all invoke bytecodes we must make sure + // it's a bytecode we indeed profile. We can't go back to the + // begining of the ProfileData we intend to update to check its + // type because we're right after it and we don't known its + // length. + lbz(tmp1, 0, R14_bcp); + lbz(tmp2, Method::intrinsic_id_offset_in_bytes(), R19_method); + cmpwi(CCR0, tmp1, Bytecodes::_invokedynamic); + cmpwi(CCR1, tmp1, Bytecodes::_invokehandle); + cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); + cmpwi(CCR1, tmp2, vmIntrinsics::_compiledLambdaForm); + cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); + bne(CCR0, profile_continue); + } + + profile_obj_type(ret, R28_mdx, -in_bytes(ReturnTypeEntry::size()), tmp1, tmp2); + + align(32, 12); + bind(profile_continue); + } +} + +void InterpreterMacroAssembler::profile_parameters_type(Register tmp1, Register tmp2, Register tmp3, Register tmp4) { + if (ProfileInterpreter && MethodData::profile_parameters()) { + Label profile_continue, done; + + test_method_data_pointer(profile_continue); + + // Load the offset of the area within the MDO used for + // parameters. If it's negative we're not profiling any parameters. + lwz(tmp1, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset()), R28_mdx); + cmpwi(CCR0, tmp1, 0); + blt(CCR0, profile_continue); + + // Compute a pointer to the area for parameters from the offset + // and move the pointer to the slot for the last + // parameters. Collect profiling from last parameter down. + // mdo start + parameters offset + array length - 1 + + // Pointer to the parameter area in the MDO. + const Register mdp = tmp1; + add(mdp, tmp1, R28_mdx); + + // Pffset of the current profile entry to update. + const Register entry_offset = tmp2; + // entry_offset = array len in number of cells + ld(entry_offset, in_bytes(ArrayData::array_len_offset()), mdp); + + int off_base = in_bytes(ParametersTypeData::stack_slot_offset(0)); + assert(off_base % DataLayout::cell_size == 0, "should be a number of cells"); + + // entry_offset (number of cells) = array len - size of 1 entry + offset of the stack slot field + addi(entry_offset, entry_offset, -TypeStackSlotEntries::per_arg_count() + (off_base / DataLayout::cell_size)); + // entry_offset in bytes + sldi(entry_offset, entry_offset, exact_log2(DataLayout::cell_size)); + + Label loop; + align(32, 12); + bind(loop); + + // Load offset on the stack from the slot for this parameter. + ld(tmp3, entry_offset, mdp); + sldi(tmp3, tmp3, Interpreter::logStackElementSize); + neg(tmp3, tmp3); + // Read the parameter from the local area. + ldx(tmp3, tmp3, R18_locals); + + // Make entry_offset now point to the type field for this parameter. + int type_base = in_bytes(ParametersTypeData::type_offset(0)); + assert(type_base > off_base, "unexpected"); + addi(entry_offset, entry_offset, type_base - off_base); + + // Profile the parameter. + profile_obj_type(tmp3, mdp, entry_offset, tmp4, tmp3); + + // Go to next parameter. + int delta = TypeStackSlotEntries::per_arg_count() * DataLayout::cell_size + (type_base - off_base); + cmpdi(CCR0, entry_offset, off_base + delta); + addi(entry_offset, entry_offset, -delta); + bge(CCR0, loop); + + align(32, 12); + bind(profile_continue); + } +} + // Add a InterpMonitorElem to stack (see frame_sparc.hpp). void InterpreterMacroAssembler::add_monitor_to_stack(bool stack_is_empty, Register Rtemp1, Register Rtemp2) { @@ -2040,20 +2265,19 @@ void InterpreterMacroAssembler::verify_oop_or_return_address(Register reg, Regis bne(CCR0, test); address fd = CAST_FROM_FN_PTR(address, verify_return_address); - unsigned int nbytes_save = 10*8; // 10 volatile gprs - - save_LR_CR(Rtmp); + const int nbytes_save = 11*8; // volatile gprs except R0 + save_volatile_gprs(R1_SP, -nbytes_save); // except R0 + save_LR_CR(Rtmp); // Save in old frame. push_frame_reg_args(nbytes_save, Rtmp); - save_volatile_gprs(R1_SP, 112); // except R0 load_const_optimized(Rtmp, fd, R0); mr_if_needed(R4_ARG2, reg); mr(R3_ARG1, R19_method); call_c(Rtmp); // call C - restore_volatile_gprs(R1_SP, 112); // except R0 pop_frame(); restore_LR_CR(Rtmp); + restore_volatile_gprs(R1_SP, -nbytes_save); // except R0 b(skip); // Perform a more elaborate out-of-line call. diff --git a/src/cpu/ppc/vm/interp_masm_ppc_64.hpp b/src/cpu/ppc/vm/interp_masm_ppc_64.hpp index 37c743228..555cc5ee9 100644 --- a/src/cpu/ppc/vm/interp_masm_ppc_64.hpp +++ b/src/cpu/ppc/vm/interp_masm_ppc_64.hpp @@ -255,6 +255,12 @@ class InterpreterMacroAssembler: public MacroAssembler { void record_klass_in_profile(Register receiver, Register scratch1, Register scratch2, bool is_virtual_call); void record_klass_in_profile_helper(Register receiver, Register scratch1, Register scratch2, int start_row, Label& done, bool is_virtual_call); + // Argument and return type profiling. + void profile_obj_type(Register obj, Register mdo_addr_base, RegisterOrConstant mdo_addr_offs, Register tmp, Register tmp2); + void profile_arguments_type(Register callee, Register tmp1, Register tmp2, bool is_virtual); + void profile_return_type(Register ret, Register tmp1, Register tmp2); + void profile_parameters_type(Register tmp1, Register tmp2, Register tmp3, Register tmp4); + #endif // !CC_INTERP // Debugging diff --git a/src/cpu/ppc/vm/macroAssembler_ppc.cpp b/src/cpu/ppc/vm/macroAssembler_ppc.cpp index ecb4deb26..95a70506c 100644 --- a/src/cpu/ppc/vm/macroAssembler_ppc.cpp +++ b/src/cpu/ppc/vm/macroAssembler_ppc.cpp @@ -806,6 +806,7 @@ void MacroAssembler::restore_nonvolatile_gprs(Register src, int offset) { // For verify_oops. void MacroAssembler::save_volatile_gprs(Register dst, int offset) { + std(R2, offset, dst); offset += 8; std(R3, offset, dst); offset += 8; std(R4, offset, dst); offset += 8; std(R5, offset, dst); offset += 8; @@ -820,6 +821,7 @@ void MacroAssembler::save_volatile_gprs(Register dst, int offset) { // For verify_oops. void MacroAssembler::restore_volatile_gprs(Register src, int offset) { + ld(R2, offset, src); offset += 8; ld(R3, offset, src); offset += 8; ld(R4, offset, src); offset += 8; ld(R5, offset, src); offset += 8; @@ -1186,6 +1188,16 @@ void MacroAssembler::call_VM(Register oop_result, address entry_point, Register call_VM(oop_result, entry_point, check_exceptions); } +void MacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3, + bool check_exceptions) { + // R3_ARG1 is reserved for the thread + mr_if_needed(R4_ARG2, arg_1); + assert(arg_2 != R4_ARG2, "smashed argument"); + mr_if_needed(R5_ARG3, arg_2); + mr_if_needed(R6_ARG4, arg_3); + call_VM(oop_result, entry_point, check_exceptions); +} + void MacroAssembler::call_VM_leaf(address entry_point) { call_VM_leaf_base(entry_point); } @@ -3058,35 +3070,27 @@ void MacroAssembler::verify_oop(Register oop, const char* msg) { if (!VerifyOops) { return; } - // Will be preserved. - Register tmp = R11; - assert(oop != tmp, "precondition"); - unsigned int nbytes_save = 10*8; // 10 volatile gprs + address/* FunctionDescriptor** */fd = StubRoutines::verify_oop_subroutine_entry_address(); - // save tmp - mr(R0, tmp); - // kill tmp - save_LR_CR(tmp); + const Register tmp = R11; // Will be preserved. + const int nbytes_save = 11*8; // Volatile gprs except R0. + save_volatile_gprs(R1_SP, -nbytes_save); // except R0 + + if (oop == tmp) mr(R4_ARG2, oop); + save_LR_CR(tmp); // save in old frame push_frame_reg_args(nbytes_save, tmp); - // restore tmp - mr(tmp, R0); - save_volatile_gprs(R1_SP, 112); // except R0 // load FunctionDescriptor** / entry_address * - load_const(tmp, fd); + load_const_optimized(tmp, fd, R0); // load FunctionDescriptor* / entry_address ld(tmp, 0, tmp); - mr(R4_ARG2, oop); - load_const(R3_ARG1, (address)msg); - // call destination for its side effect + if (oop != tmp) mr_if_needed(R4_ARG2, oop); + load_const_optimized(R3_ARG1, (address)msg, R0); + // Call destination for its side effect. call_c(tmp); - restore_volatile_gprs(R1_SP, 112); // except R0 + pop_frame(); - // save tmp - mr(R0, tmp); - // kill tmp restore_LR_CR(tmp); - // restore tmp - mr(tmp, R0); + restore_volatile_gprs(R1_SP, -nbytes_save); // except R0 } const char* stop_types[] = { diff --git a/src/cpu/ppc/vm/macroAssembler_ppc.hpp b/src/cpu/ppc/vm/macroAssembler_ppc.hpp index 5bbea5ada..c7e8de457 100644 --- a/src/cpu/ppc/vm/macroAssembler_ppc.hpp +++ b/src/cpu/ppc/vm/macroAssembler_ppc.hpp @@ -368,6 +368,7 @@ class MacroAssembler: public Assembler { void call_VM(Register oop_result, address entry_point, bool check_exceptions = true); void call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions = true); void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true); + void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg3, bool check_exceptions = true); void call_VM_leaf(address entry_point); void call_VM_leaf(address entry_point, Register arg_1); void call_VM_leaf(address entry_point, Register arg_1, Register arg_2); diff --git a/src/cpu/ppc/vm/nativeInst_ppc.cpp b/src/cpu/ppc/vm/nativeInst_ppc.cpp index 6f40af06f..6a8b9a479 100644 --- a/src/cpu/ppc/vm/nativeInst_ppc.cpp +++ b/src/cpu/ppc/vm/nativeInst_ppc.cpp @@ -100,10 +100,7 @@ void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) { MacroAssembler* a = new MacroAssembler(&cb); // Patch the call. - if (ReoptimizeCallSequences && - a->is_within_range_of_b(dest, addr_call)) { - a->bl(dest); - } else { + if (!ReoptimizeCallSequences || !a->is_within_range_of_b(dest, addr_call)) { address trampoline_stub_addr = get_trampoline(); // We did not find a trampoline stub because the current codeblob @@ -115,9 +112,12 @@ void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) { // Patch the constant in the call's trampoline stub. NativeCallTrampolineStub_at(trampoline_stub_addr)->set_destination(dest); - - a->bl(trampoline_stub_addr); + dest = trampoline_stub_addr; } + + OrderAccess::release(); + a->bl(dest); + ICache::ppc64_flush_icache_bytes(addr_call, code_size); } diff --git a/src/cpu/ppc/vm/ppc.ad b/src/cpu/ppc/vm/ppc.ad index 40bb013a8..ce0406de1 100644 --- a/src/cpu/ppc/vm/ppc.ad +++ b/src/cpu/ppc/vm/ppc.ad @@ -1938,8 +1938,9 @@ ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_ // -------------------------------------------------------------------- // Check for hi bits still needing moving. Only happens for misaligned // arguments to native calls. - if (src_hi == dst_hi) + if (src_hi == dst_hi) { return ppc64Opcode_none; // Self copy; no move. + } ShouldNotReachHere(); return ppc64Opcode_undefined; @@ -1961,14 +1962,15 @@ void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *) const { } uint MachNopNode::size(PhaseRegAlloc *ra_) const { - return _count * 4; + return _count * 4; } #ifndef PRODUCT void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); - int reg = ra_->get_reg_first(this); - st->print("ADDI %s, SP, %d \t// box node", Matcher::regName[reg], offset); + char reg_str[128]; + ra_->dump_register(this, reg_str); + st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); } #endif diff --git a/src/cpu/ppc/vm/templateInterpreter_ppc.cpp b/src/cpu/ppc/vm/templateInterpreter_ppc.cpp index 22bbbf58b..a8d19d286 100644 --- a/src/cpu/ppc/vm/templateInterpreter_ppc.cpp +++ b/src/cpu/ppc/vm/templateInterpreter_ppc.cpp @@ -90,7 +90,7 @@ address TemplateInterpreterGenerator::generate_ClassCastException_verbose_handle // Thread will be loaded to R3_ARG1. // Target class oop is in register R5_ARG3 by convention! - __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ClassCastException_verbose, R17_tos, R5_ARG3)); + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ClassCastException_verbose), R17_tos, R5_ARG3); // Above call must not return here since exception pending. DEBUG_ONLY(__ should_not_reach_here();) return entry; @@ -171,6 +171,10 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, // Compiled code destroys templateTableBase, reload. __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R12_scratch2); + if (state == atos) { + __ profile_return_type(R3_RET, R11_scratch1, R12_scratch2); + } + const Register cache = R11_scratch1; const Register size = R12_scratch2; __ get_cache_and_index_at_bcp(cache, 1, index_size); @@ -1230,6 +1234,10 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { __ li(R0, 1); __ stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread); } + + // Argument and return type profiling. + __ profile_parameters_type(R3_ARG1, R4_ARG2, R5_ARG3, R6_ARG4); + // Increment invocation counter and check for overflow. if (inc_counter) { generate_counter_incr(&invocation_counter_overflow, &profile_method, &profile_method_continue); @@ -1549,6 +1557,8 @@ void TemplateInterpreterGenerator::generate_throw_exception() { __ resize_frame_absolute(R12_scratch2, R11_scratch1, R0); if (ProfileInterpreter) { __ set_method_data_pointer_for_bcp(); + __ ld(R11_scratch1, 0, R1_SP); + __ std(R28_mdx, _ijava_state_neg(mdx), R11_scratch1); } #if INCLUDE_JVMTI Label L_done; @@ -1560,13 +1570,11 @@ void TemplateInterpreterGenerator::generate_throw_exception() { // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL. __ ld(R4_ARG2, 0, R18_locals); - __ call_VM(R11_scratch1, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), - R4_ARG2, R19_method, R14_bcp); - - __ cmpdi(CCR0, R11_scratch1, 0); + __ MacroAssembler::call_VM(R4_ARG2, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), R4_ARG2, R19_method, R14_bcp, false); + __ restore_interpreter_state(R11_scratch1, /*bcp_and_mdx_only*/ true); + __ cmpdi(CCR0, R4_ARG2, 0); __ beq(CCR0, L_done); - - __ std(R11_scratch1, wordSize, R15_esp); + __ std(R4_ARG2, wordSize, R15_esp); __ bind(L_done); #endif // INCLUDE_JVMTI __ dispatch_next(vtos); diff --git a/src/cpu/ppc/vm/templateTable_ppc_64.cpp b/src/cpu/ppc/vm/templateTable_ppc_64.cpp index 95a60ec15..c4cc257f2 100644 --- a/src/cpu/ppc/vm/templateTable_ppc_64.cpp +++ b/src/cpu/ppc/vm/templateTable_ppc_64.cpp @@ -3234,6 +3234,8 @@ void TemplateTable::generate_vtable_call(Register Rrecv_klass, Register Rindex, // Load target. __ addi(Rrecv_klass, Rrecv_klass, base + vtableEntry::method_offset_in_bytes()); __ ldx(Rtarget_method, Rindex, Rrecv_klass); + // Argument and return type profiling. + __ profile_arguments_type(Rtarget_method, Rrecv_klass /* scratch1 */, Rtemp /* scratch2 */, true); __ call_from_interpreter(Rtarget_method, Rret, Rrecv_klass /* scratch1 */, Rtemp /* scratch2 */); } @@ -3317,6 +3319,8 @@ void TemplateTable::invokevfinal_helper(Register Rmethod, Register Rflags, Regis __ null_check_throw(Rrecv, -1, Rscratch1); __ profile_final_call(Rrecv, Rscratch1); + // Argument and return type profiling. + __ profile_arguments_type(Rmethod, Rscratch1, Rscratch2, true); // Do the call. __ call_from_interpreter(Rmethod, Rret_addr, Rscratch1, Rscratch2); @@ -3338,6 +3342,8 @@ void TemplateTable::invokespecial(int byte_no) { __ null_check_throw(Rreceiver, -1, R11_scratch1); __ profile_call(R11_scratch1, R12_scratch2); + // Argument and return type profiling. + __ profile_arguments_type(Rmethod, R11_scratch1, R12_scratch2, false); __ call_from_interpreter(Rmethod, Rret_addr, R11_scratch1, R12_scratch2); } @@ -3352,6 +3358,8 @@ void TemplateTable::invokestatic(int byte_no) { prepare_invoke(byte_no, R19_method, Rret_addr, noreg, noreg, Rflags, R11_scratch1); __ profile_call(R11_scratch1, R12_scratch2); + // Argument and return type profiling. + __ profile_arguments_type(R19_method, R11_scratch1, R12_scratch2, false); __ call_from_interpreter(R19_method, Rret_addr, R11_scratch1, R12_scratch2); } @@ -3373,6 +3381,8 @@ void TemplateTable::invokeinterface_object_method(Register Rrecv_klass, // Final call case. __ profile_final_call(Rtemp1, Rscratch); + // Argument and return type profiling. + __ profile_arguments_type(Rindex, Rscratch, Rrecv_klass /* scratch */, true); // Do the final call - the index (f2) contains the method. __ call_from_interpreter(Rindex, Rret, Rscratch, Rrecv_klass /* scratch */); @@ -3424,6 +3434,8 @@ void TemplateTable::invokeinterface(int byte_no) { __ cmpdi(CCR0, Rindex, 0); __ beq(CCR0, Lthrow_ame); // Found entry. Jump off! + // Argument and return type profiling. + __ profile_arguments_type(Rindex, Rscratch1, Rscratch2, true); __ call_from_interpreter(Rindex, Rret_addr, Rscratch1, Rscratch2); // Vtable entry was NULL => Throw abstract method error. @@ -3477,6 +3489,8 @@ void TemplateTable::invokedynamic(int byte_no) { // to be the callsite object the bootstrap method returned. This is passed to a // "link" method which does the dispatch (Most likely just grabs the MH stored // inside the callsite and does an invokehandle). + // Argument and return type profiling. + __ profile_arguments_type(Rmethod, Rscratch1, Rscratch2, false); __ call_from_interpreter(Rmethod, Rret_addr, Rscratch1 /* scratch1 */, Rscratch2 /* scratch2 */); } @@ -3503,6 +3517,8 @@ void TemplateTable::invokehandle(int byte_no) { __ profile_final_call(Rrecv, Rscratch1); // Still no call from handle => We call the method handle interpreter here. + // Argument and return type profiling. + __ profile_arguments_type(Rmethod, Rscratch1, Rscratch2, true); __ call_from_interpreter(Rmethod, Rret_addr, Rscratch1 /* scratch1 */, Rscratch2 /* scratch2 */); } diff --git a/src/cpu/ppc/vm/vm_version_ppc.cpp b/src/cpu/ppc/vm/vm_version_ppc.cpp index 28f992f41..1f8375fa6 100644 --- a/src/cpu/ppc/vm/vm_version_ppc.cpp +++ b/src/cpu/ppc/vm/vm_version_ppc.cpp @@ -139,13 +139,44 @@ void VM_Version::initialize() { } assert(AllocatePrefetchLines > 0, "invalid value"); - if (AllocatePrefetchLines < 1) // Set valid value in product VM. + if (AllocatePrefetchLines < 1) { // Set valid value in product VM. AllocatePrefetchLines = 1; // Conservative value. + } - if (AllocatePrefetchStyle == 3 && AllocatePrefetchDistance < cache_line_size) + if (AllocatePrefetchStyle == 3 && AllocatePrefetchDistance < cache_line_size) { AllocatePrefetchStyle = 1; // Fall back if inappropriate. + } assert(AllocatePrefetchStyle >= 0, "AllocatePrefetchStyle should be positive"); + + if (UseCRC32Intrinsics) { + if (!FLAG_IS_DEFAULT(UseCRC32Intrinsics)) + warning("CRC32 intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); + } + + // The AES intrinsic stubs require AES instruction support. + if (UseAES) { + warning("AES instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseAES, false); + } + if (UseAESIntrinsics) { + if (!FLAG_IS_DEFAULT(UseAESIntrinsics)) + warning("AES intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } + + if (UseSHA) { + warning("SHA instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseSHA, false); + } + if (UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics) { + warning("SHA intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseSHA1Intrinsics, false); + FLAG_SET_DEFAULT(UseSHA256Intrinsics, false); + FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); + } + } void VM_Version::print_features() { diff --git a/src/os/aix/vm/os_aix.cpp b/src/os/aix/vm/os_aix.cpp index 314b80623..9a65f741a 100644 --- a/src/os/aix/vm/os_aix.cpp +++ b/src/os/aix/vm/os_aix.cpp @@ -114,12 +114,6 @@ extern "C" { } #endif -// Excerpts from systemcfg.h definitions newer than AIX 5.3 -#ifndef PV_7 -# define PV_7 0x200000 // Power PC 7 -# define PV_7_Compat 0x208000 // Power PC 7 -#endif - #define MAX_PATH (2 * K) // for timer info max values which include all bits @@ -130,17 +124,40 @@ extern "C" { #define ERROR_MP_VMGETINFO_FAILED 102 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103 -// the semantics in this file are thus that codeptr_t is a *real code ptr* +// The semantics in this file are thus that codeptr_t is a *real code ptr*. // This means that any function taking codeptr_t as arguments will assume // a real codeptr and won't handle function descriptors (eg getFuncName), // whereas functions taking address as args will deal with function -// descriptors (eg os::dll_address_to_library_name) +// descriptors (eg os::dll_address_to_library_name). typedef unsigned int* codeptr_t; -// typedefs for stackslots, stack pointers, pointers to op codes +// Typedefs for stackslots, stack pointers, pointers to op codes. typedef unsigned long stackslot_t; typedef stackslot_t* stackptr_t; +// Excerpts from systemcfg.h definitions newer than AIX 5.3. +#ifndef PV_7 +#define PV_7 0x200000 /* Power PC 7 */ +#define PV_7_Compat 0x208000 /* Power PC 7 */ +#endif +#ifndef PV_8 +#define PV_8 0x300000 /* Power PC 8 */ +#define PV_8_Compat 0x308000 /* Power PC 8 */ +#endif + +#define trcVerbose(fmt, ...) { /* PPC port */ \ + if (Verbose) { \ + fprintf(stderr, fmt, ##__VA_ARGS__); \ + fputc('\n', stderr); fflush(stderr); \ + } \ +} +#define trc(fmt, ...) /* PPC port */ + +#define ERRBYE(s) { \ + trcVerbose(s); \ + return -1; \ +} + // query dimensions of the stack of the calling thread static void query_stack_dimensions(address* p_stack_base, size_t* p_stack_size); @@ -172,12 +189,12 @@ inline bool is_valid_codepointer(codeptr_t p) { return true; } -// macro to check a given stack pointer against given stack limits and to die if test fails +// Macro to check a given stack pointer against given stack limits and to die if test fails. #define CHECK_STACK_PTR(sp, stack_base, stack_size) { \ guarantee(is_valid_stackpointer((stackptr_t)(sp), (stackptr_t)(stack_base), stack_size), "Stack Pointer Invalid"); \ } -// macro to check the current stack pointer against given stacklimits +// Macro to check the current stack pointer against given stacklimits. #define CHECK_CURRENT_STACK_PTR(stack_base, stack_size) { \ address sp; \ sp = os::current_stack_pointer(); \ @@ -211,7 +228,7 @@ static bool check_signals = true; static pid_t _initial_pid = 0; static int SR_signum = SIGUSR2; // Signal used to suspend/resume a thread (must be > SIGSEGV, see 4355769) static sigset_t SR_sigset; -static pthread_mutex_t dl_mutex; // Used to protect dlsym() calls */ +static pthread_mutex_t dl_mutex; // Used to protect dlsym() calls. julong os::available_memory() { return Aix::available_memory(); @@ -243,7 +260,6 @@ bool os::getenv(const char* name, char* buf, int len) { return false; } - // Return true if user is running as root. bool os::have_special_privileges() { @@ -274,8 +290,7 @@ static bool my_disclaim64(char* addr, size_t size) { for (int i = 0; i < numFullDisclaimsNeeded; i ++) { if (::disclaim(p, maxDisclaimSize, DISCLAIM_ZEROMEM) != 0) { - //if (Verbose) - fprintf(stderr, "Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno); + trc("Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno); return false; } p += maxDisclaimSize; @@ -283,8 +298,7 @@ static bool my_disclaim64(char* addr, size_t size) { if (lastDisclaimSize > 0) { if (::disclaim(p, lastDisclaimSize, DISCLAIM_ZEROMEM) != 0) { - //if (Verbose) - fprintf(stderr, "Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno); + trc("Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno); return false; } } @@ -324,11 +338,11 @@ pid_t os::Aix::gettid() { void os::Aix::initialize_system_info() { - // get the number of online(logical) cpus instead of configured + // Get the number of online(logical) cpus instead of configured. os::_processor_count = sysconf(_SC_NPROCESSORS_ONLN); assert(_processor_count > 0, "_processor_count must be > 0"); - // retrieve total physical storage + // Retrieve total physical storage. os::Aix::meminfo_t mi; if (!os::Aix::get_meminfo(&mi)) { fprintf(stderr, "os::Aix::get_meminfo failed.\n"); fflush(stderr); @@ -503,7 +517,6 @@ query_multipage_support_end: } // end os::Aix::query_multipage_support() -// The code for this method was initially derived from the version in os_linux.cpp. void os::init_system_properties_values() { #define DEFAULT_LIBPATH "/usr/lib:/lib" @@ -600,10 +613,11 @@ bool os::Aix::is_sig_ignored(int sig) { sigaction(sig, (struct sigaction*)NULL, &oact); void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction) : CAST_FROM_FN_PTR(void*, oact.sa_handler); - if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) + if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) { return true; - else + } else { return false; + } } void os::Aix::signal_sets_init() { @@ -777,6 +791,9 @@ bool os::Aix::get_cpuinfo(cpuinfo_t* pci) { // get the processor version from _system_configuration switch (_system_configuration.version) { + case PV_8: + strcpy(pci->version, "Power PC 8"); + break; case PV_7: strcpy(pci->version, "Power PC 7"); break; @@ -804,6 +821,9 @@ bool os::Aix::get_cpuinfo(cpuinfo_t* pci) { case PV_7_Compat: strcpy(pci->version, "PV_7_Compat"); break; + case PV_8_Compat: + strcpy(pci->version, "PV_8_Compat"); + break; default: strcpy(pci->version, "unknown"); } @@ -939,7 +959,9 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { pthread_attr_destroy(&attr); - if (ret != 0) { + if (ret == 0) { + // PPC port traceOsMisc(("Created New Thread : pthread-id %u", tid)); + } else { if (PrintMiscellaneous && (Verbose || WizardMode)) { perror("pthread_create()"); } @@ -1096,8 +1118,7 @@ jlong os::javaTimeNanos() { if (os::Aix::on_pase()) { Unimplemented(); return 0; - } - else { + } else { // On AIX use the precision of processors real time clock // or time base registers. timebasestruct_t time; @@ -1150,7 +1171,6 @@ bool os::getTimesSecs(double* process_real_time, } } - char * os::local_time_string(char *buf, size_t buflen) { struct tm t; time_t long_time; @@ -1188,7 +1208,6 @@ void os::shutdown() { if (abort_hook != NULL) { abort_hook(); } - } // Note: os::abort() might be called very early during initialization, or @@ -1220,8 +1239,7 @@ void os::die() { // from src/solaris/hpi/src/system_md.c size_t os::lasterror(char *buf, size_t len) { - - if (errno == 0) return 0; + if (errno == 0) return 0; const char *s = ::strerror(errno); size_t n = ::strlen(s); @@ -1234,6 +1252,7 @@ size_t os::lasterror(char *buf, size_t len) { } intx os::current_thread_id() { return (intx)pthread_self(); } + int os::current_process_id() { // This implementation returns a unique pid, the pid of the @@ -1370,9 +1389,9 @@ bool os::dll_address_to_function_name(address addr, char *buf, if (offset) { *offset = -1; } - if (buf) { - buf[0] = '\0'; - } + // Buf is not optional, but offset is optional. + assert(buf != NULL, "sanity check"); + buf[0] = '\0'; // Resolve function ptr literals first. addr = resolve_function_descriptor_to_code_pointer(addr); @@ -1405,12 +1424,9 @@ static int getModuleName(codeptr_t pc, // [in] program counte return 0; } - if (Verbose) { - fprintf(stderr, "pc outside any module"); - } + trcVerbose("pc outside any module"); return -1; - } bool os::dll_address_to_library_name(address addr, char* buf, @@ -1418,9 +1434,9 @@ bool os::dll_address_to_library_name(address addr, char* buf, if (offset) { *offset = -1; } - if (buf) { - buf[0] = '\0'; - } + // Buf is not optional, but offset is optional. + assert(buf != NULL, "sanity check"); + buf[0] = '\0'; // Resolve function ptr literals first. addr = resolve_function_descriptor_to_code_pointer(addr); @@ -1435,7 +1451,7 @@ bool os::dll_address_to_library_name(address addr, char* buf, } // Loads .dll/.so and in case of error it checks if .dll/.so was built -// for the same architecture as Hotspot is running on +// for the same architecture as Hotspot is running on. void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { if (ebuf && ebuflen > 0) { @@ -1598,7 +1614,6 @@ void os::print_siginfo(outputStream* st, void* siginfo) { st->cr(); } - static void print_signal_handler(outputStream* st, int sig, char* buf, size_t buflen); @@ -1622,7 +1637,7 @@ void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { static char saved_jvm_path[MAXPATHLEN] = {0}; -// Find the full path to the current module, libjvm.so or libjvm_g.so +// Find the full path to the current module, libjvm.so. void os::jvm_path(char *buf, jint buflen) { // Error checking. if (buflen < MAXPATHLEN) { @@ -1692,7 +1707,7 @@ void* os::signal(int signal_number, void* handler) { // Do not block out synchronous signals in the signal handler. // Blocking synchronous signals only makes sense if you can really // be sure that those signals won't happen during signal handling, - // when the blocking applies. Normal signal handlers are lean and + // when the blocking applies. Normal signal handlers are lean and // do not cause signals. But our signal handlers tend to be "risky" // - secondary SIGSEGV, SIGILL, SIGBUS' may and do happen. // On AIX, PASE there was a case where a SIGSEGV happened, followed @@ -2967,13 +2982,9 @@ OSReturn os::set_native_priority(Thread* thread, int newpri) { param.sched_priority = newpri; int ret = pthread_setschedparam(thr, policy, ¶m); - if (Verbose) { - if (ret == 0) { - fprintf(stderr, "changed priority of thread %d to %d\n", (int)thr, newpri); - } else { - fprintf(stderr, "Could not changed priority for thread %d to %d (error %d, %s)\n", - (int)thr, newpri, ret, strerror(ret)); - } + if (ret != 0) { + trcVerbose("Could not change priority for thread %d to %d (error %d, %s)", + (int)thr, newpri, ret, strerror(ret)); } return (ret == 0) ? OS_OK : OS_ERR; } @@ -3094,7 +3105,6 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { errno = old_errno; } - static int SR_initialize() { struct sigaction act; char *s; @@ -3337,7 +3347,6 @@ void javaSignalHandler(int sig, siginfo_t* info, void* uc) { JVM_handle_aix_signal(sig, info, uc, true); } - // This boolean allows users to forward their own non-matching signals // to JVM_handle_aix_signal, harmlessly. bool os::Aix::signal_handlers_are_installed = false; @@ -3531,7 +3540,7 @@ void os::Aix::install_signal_handlers() { set_signal_handler(SIGDANGER, true); if (libjsig_is_loaded) { - // Tell libjsig jvm finishes setting signal handlers + // Tell libjsig jvm finishes setting signal handlers. (*end_signal_setting)(); } @@ -3547,7 +3556,7 @@ void os::Aix::install_signal_handlers() { tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled"); check_signals = false; } - // need to initialize check_signal_done + // Need to initialize check_signal_done. ::sigemptyset(&check_signal_done); } } @@ -3621,7 +3630,6 @@ static void print_signal_handler(outputStream* st, int sig, st->cr(); } - #define DO_SIGNAL_CHECK(sig) \ if (!sigismember(&check_signal_done, sig)) \ os::Aix::check_signal_handler(sig) @@ -3682,7 +3690,6 @@ void os::Aix::check_signal_handler(int sig) { ? CAST_FROM_FN_PTR(address, act.sa_sigaction) : CAST_FROM_FN_PTR(address, act.sa_handler); - switch(sig) { case SIGSEGV: case SIGBUS: @@ -3830,15 +3837,13 @@ void os::init(void) { pthread_mutex_init(&dl_mutex, NULL); } -// this is called _after_ the global arguments have been parsed +// This is called _after_ the global arguments have been parsed. jint os::init_2(void) { - if (Verbose) { - fprintf(stderr, "processor count: %d\n", os::_processor_count); - fprintf(stderr, "physical memory: %lu\n", Aix::_physical_memory); - } + trcVerbose("processor count: %d", os::_processor_count); + trcVerbose("physical memory: %lu", Aix::_physical_memory); - // initially build up the loaded dll map + // Initially build up the loaded dll map. LoadedLibraries::reload(); const int page_size = Aix::page_size(); @@ -3888,7 +3893,7 @@ jint os::init_2(void) { } if (map_address != (address) MAP_FAILED) { - // map succeeded, but polling_page is not at wished address, unmap and continue. + // Map succeeded, but polling_page is not at wished address, unmap and continue. ::munmap(map_address, map_size); map_address = (address) MAP_FAILED; } @@ -3942,7 +3947,7 @@ jint os::init_2(void) { // Make the stack size a multiple of the page size so that // the yellow/red zones can be guarded. - // note that this can be 0, if no default stacksize was set + // Note that this can be 0, if no default stacksize was set. JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, vm_page_size())); Aix::libpthread_init(); @@ -4255,7 +4260,6 @@ int os::open(const char *path, int oflag, int mode) { return fd; } - // create binary file, rewriting existing file if required int os::create_binary_file(const char* path, bool rewrite_existing) { int oflags = O_WRONLY | O_CREAT; @@ -4324,7 +4328,6 @@ char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, return NULL; } - // Remap a block of memory. char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only, @@ -4372,14 +4375,14 @@ static bool thread_cpu_time_unchecked(Thread* thread, jlong* p_sys_time, jlong* jlong sys_time = 0; jlong user_time = 0; - // reimplemented using getthrds64(). + // Reimplemented using getthrds64(). // - // goes like this: + // Works like this: // For the thread in question, get the kernel thread id. Then get the // kernel thread statistics using that id. // // This only works of course when no pthread scheduling is used, - // ie there is a 1:1 relationship to kernel threads. + // i.e. there is a 1:1 relationship to kernel threads. // On AIX, see AIXTHREAD_SCOPE variable. pthread_t pthtid = thread->osthread()->pthread_id(); @@ -4526,14 +4529,12 @@ void os::Aix::initialize_os_info() { memset(&uts, 0, sizeof(uts)); strcpy(uts.sysname, "?"); if (::uname(&uts) == -1) { - fprintf(stderr, "uname failed (%d)\n", errno); + trc("uname failed (%d)", errno); guarantee(0, "Could not determine whether we run on AIX or PASE"); } else { - if (Verbose) { - fprintf(stderr,"uname says: sysname \"%s\" version \"%s\" release \"%s\" " - "node \"%s\" machine \"%s\"\n", - uts.sysname, uts.version, uts.release, uts.nodename, uts.machine); - } + trcVerbose("uname says: sysname \"%s\" version \"%s\" release \"%s\" " + "node \"%s\" machine \"%s\"\n", + uts.sysname, uts.version, uts.release, uts.nodename, uts.machine); const int major = atoi(uts.version); assert(major > 0, "invalid OS version"); const int minor = atoi(uts.release); @@ -4545,12 +4546,10 @@ void os::Aix::initialize_os_info() { // We run on AIX. We do not support versions older than AIX 5.3. _on_pase = 0; if (_os_version < 0x0503) { - fprintf(stderr, "AIX release older than AIX 5.3 not supported.\n"); + trc("AIX release older than AIX 5.3 not supported."); assert(false, "AIX release too old."); } else { - if (Verbose) { - fprintf(stderr, "We run on AIX %d.%d\n", major, minor); - } + trcVerbose("We run on AIX %d.%d\n", major, minor); } } else { assert(false, "unknown OS"); @@ -4558,7 +4557,6 @@ void os::Aix::initialize_os_info() { } guarantee(_on_pase != -1 && _os_version, "Could not determine AIX/OS400 release"); - } // end: os::Aix::initialize_os_info() // Scan environment for important settings which might effect the VM. @@ -4596,12 +4594,10 @@ void os::Aix::scan_environment() { // Note: Setting XPG_SUS_ENV in the process is too late. Must be set earlier (before // exec() ? before loading the libjvm ? ....) p = ::getenv("XPG_SUS_ENV"); - if (Verbose) { - fprintf(stderr, "XPG_SUS_ENV=%s.\n", p ? p : ""); - } + trcVerbose("XPG_SUS_ENV=%s.", p ? p : ""); if (p && strcmp(p, "ON") == 0) { _xpg_sus_mode = 1; - fprintf(stderr, "Unsupported setting: XPG_SUS_ENV=ON\n"); + trc("Unsupported setting: XPG_SUS_ENV=ON"); // This is not supported. Worst of all, it changes behaviour of mmap MAP_FIXED to // clobber address ranges. If we ever want to support that, we have to do some // testing first. @@ -4613,10 +4609,7 @@ void os::Aix::scan_environment() { // Switch off AIX internal (pthread) guard pages. This has // immediate effect for any pthread_create calls which follow. p = ::getenv("AIXTHREAD_GUARDPAGES"); - if (Verbose) { - fprintf(stderr, "AIXTHREAD_GUARDPAGES=%s.\n", p ? p : ""); - fprintf(stderr, "setting AIXTHREAD_GUARDPAGES=0.\n"); - } + trcVerbose("AIXTHREAD_GUARDPAGES=%s.", p ? p : ""); rc = ::putenv("AIXTHREAD_GUARDPAGES=0"); guarantee(rc == 0, ""); @@ -4634,7 +4627,7 @@ void os::Aix::initialize_libperfstat() { assert(os::Aix::on_aix(), "AIX only"); if (!libperfstat::init()) { - fprintf(stderr, "libperfstat initialization failed.\n"); + trc("libperfstat initialization failed."); assert(false, "libperfstat initialization failed"); } else { if (Verbose) { @@ -4806,7 +4799,6 @@ static struct timespec* compute_abstime(timespec* abstime, jlong millis) { return abstime; } - // Test-and-clear _Event, always leaves _Event set to 0, returns immediately. // Conceptually TryPark() should be equivalent to park(0). @@ -4889,7 +4881,7 @@ int os::PlatformEvent::park(jlong millis) { while (_Event < 0) { status = pthread_cond_timedwait(_cond, _mutex, &abst); assert_status(status == 0 || status == ETIMEDOUT, - status, "cond_timedwait"); + status, "cond_timedwait"); if (!FilterSpuriousWakeups) break; // previous semantics if (status == ETIMEDOUT) break; // We consume and ignore EINTR and spurious wakeups. @@ -5023,9 +5015,9 @@ void Parker::park(bool isAbsolute, jlong time) { // Optional fast-path check: // Return immediately if a permit is available. if (_counter > 0) { - _counter = 0; - OrderAccess::fence(); - return; + _counter = 0; + OrderAccess::fence(); + return; } Thread* thread = Thread::current(); @@ -5047,7 +5039,6 @@ void Parker::park(bool isAbsolute, jlong time) { unpackTime(&absTime, isAbsolute, time); } - // Enter safepoint region // Beware of deadlocks such as 6317397. // The per-thread Parker:: mutex is a classic leaf-lock. @@ -5135,7 +5126,6 @@ void Parker::unpark() { } } - extern char** environ; // Run the specified command in a separate process. Return its exit value, @@ -5154,44 +5144,43 @@ int os::fork_and_exec(char* cmd) { } else if (pid == 0) { // child process - // try to be consistent with system(), which uses "/usr/bin/sh" on AIX + // Try to be consistent with system(), which uses "/usr/bin/sh" on AIX. execve("/usr/bin/sh", argv, environ); // execve failed _exit(-1); - } else { + } else { // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't // care about the actual exit code, for now. int status; - // Wait for the child process to exit. This returns immediately if + // Wait for the child process to exit. This returns immediately if // the child has already exited. */ while (waitpid(pid, &status, 0) < 0) { - switch (errno) { + switch (errno) { case ECHILD: return 0; case EINTR: break; default: return -1; - } + } } if (WIFEXITED(status)) { - // The child exited normally; get its exit code. - return WEXITSTATUS(status); + // The child exited normally; get its exit code. + return WEXITSTATUS(status); } else if (WIFSIGNALED(status)) { - // The child exited because of a signal - // The best value to return is 0x80 + signal number, - // because that is what all Unix shells do, and because - // it allows callers to distinguish between process exit and - // process death by signal. - return 0x80 + WTERMSIG(status); + // The child exited because of a signal. + // The best value to return is 0x80 + signal number, + // because that is what all Unix shells do, and because + // it allows callers to distinguish between process exit and + // process death by signal. + return 0x80 + WTERMSIG(status); } else { - // Unknown exit code; pass it through - return status; + // Unknown exit code; pass it through. + return status; } } - // Remove warning. return -1; } @@ -5206,7 +5195,7 @@ bool os::is_headless_jre() { struct stat statbuf; char buf[MAXPATHLEN]; char libmawtpath[MAXPATHLEN]; - const char *xawtstr = "/xawt/libmawt.so"; + const char *xawtstr = "/xawt/libmawt.so"; const char *new_xawtstr = "/libawt_xawt.so"; char *p; diff --git a/src/os/aix/vm/os_aix.hpp b/src/os/aix/vm/os_aix.hpp index a7d2717c8..01831fb7c 100644 --- a/src/os/aix/vm/os_aix.hpp +++ b/src/os/aix/vm/os_aix.hpp @@ -209,7 +209,7 @@ class Aix { return _can_use_16M_pages == 1 ? true : false; } - static address ucontext_get_pc(ucontext_t* uc); + static address ucontext_get_pc(const ucontext_t* uc); static intptr_t* ucontext_get_sp(ucontext_t* uc); static intptr_t* ucontext_get_fp(ucontext_t* uc); // Set PC into context. Needed for continuation after signal. diff --git a/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp b/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp index 8573cf33e..3dfb72d1e 100644 --- a/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp +++ b/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp @@ -91,8 +91,9 @@ void os::initialize_thread(Thread *thread) { } // Frame information (pc, sp, fp) retrieved via ucontext // always looks like a C-frame according to the frame -// conventions in frame_ppc64.hpp. -address os::Aix::ucontext_get_pc(ucontext_t * uc) { +// conventions in frame_ppc.hpp. + +address os::Aix::ucontext_get_pc(const ucontext_t * uc) { return (address)uc->uc_mcontext.jmp_context.iar; } @@ -486,7 +487,7 @@ void os::Aix::init_thread_fpu_state(void) { //////////////////////////////////////////////////////////////////////////////// // thread stack -size_t os::Aix::min_stack_allowed = 768*K; +size_t os::Aix::min_stack_allowed = 128*K; // Aix is always in floating stack mode. The stack size for a new // thread can be set via pthread_attr_setstacksize(). @@ -499,7 +500,7 @@ size_t os::Aix::default_stack_size(os::ThreadType thr_type) { // because of the strange 'fallback logic' in os::create_thread(). // Better set CompilerThreadStackSize in globals_.hpp if you want to // specify a different stack size for compiler threads! - size_t s = (thr_type == os::compiler_thread ? 4 * M : 1024 * K); + size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); return s; } diff --git a/src/os_cpu/aix_ppc/vm/os_aix_ppc.hpp b/src/os_cpu/aix_ppc/vm/os_aix_ppc.hpp index 4f3072793..44fa7db38 100644 --- a/src/os_cpu/aix_ppc/vm/os_aix_ppc.hpp +++ b/src/os_cpu/aix_ppc/vm/os_aix_ppc.hpp @@ -23,8 +23,8 @@ * */ -#ifndef OS_CPU_AIX_OJDKPPC_VM_OS_AIX_PPC_HPP -#define OS_CPU_AIX_OJDKPPC_VM_OS_AIX_PPC_HPP +#ifndef OS_CPU_AIX_PPC_VM_OS_AIX_PPC_HPP +#define OS_CPU_AIX_PPC_VM_OS_AIX_PPC_HPP static void setup_fpu() {} @@ -32,4 +32,4 @@ // Note: Currently only used in 64 bit Windows implementations static bool register_code_area(char *low, char *high) { return true; } -#endif // OS_CPU_AIX_OJDKPPC_VM_OS_AIX_PPC_HPP +#endif // OS_CPU_AIX_PPC_VM_OS_AIX_PPC_HPP diff --git a/src/os_cpu/aix_ppc/vm/prefetch_aix_ppc.inline.hpp b/src/os_cpu/aix_ppc/vm/prefetch_aix_ppc.inline.hpp index 3d855f7d0..85c62b664 100644 --- a/src/os_cpu/aix_ppc/vm/prefetch_aix_ppc.inline.hpp +++ b/src/os_cpu/aix_ppc/vm/prefetch_aix_ppc.inline.hpp @@ -23,8 +23,8 @@ * */ -#ifndef OS_CPU_AIX_PPC_64_VM_PREFETCH_AIX_PPC_64_INLINE_HPP -#define OS_CPU_AIX_PPC_64_VM_PREFETCH_AIX_PPC_64_INLINE_HPP +#ifndef OS_CPU_AIX_PPC_VM_PREFETCH_AIX_PPC_INLINE_HPP +#define OS_CPU_AIX_PPC_VM_PREFETCH_AIX_PPC_INLINE_HPP #include "runtime/prefetch.hpp" @@ -55,4 +55,4 @@ inline void Prefetch::write(void *loc, intx interval) { #endif } -#endif // OS_CPU_AIX_PPC_64_VM_PREFETCH_AIX_PPC_64_INLINE_HPP +#endif // OS_CPU_AIX_PPC_VM_PREFETCH_AIX_PPC_INLINE_HPP diff --git a/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp b/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp index 1aacc8f45..825b0b843 100644 --- a/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp +++ b/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp @@ -23,8 +23,8 @@ * */ -#ifndef OS_CPU_AIX_OJDKPPC_VM_THREADLS_AIX_PPC_HPP -#define OS_CPU_AIX_OJDKPPC_VM_THREADLS_AIX_PPC_HPP +#ifndef OS_CPU_AIX_PPC_VM_THREADLS_AIX_PPC_HPP +#define OS_CPU_AIX_PPC_VM_THREADLS_AIX_PPC_HPP // Processor dependent parts of ThreadLocalStorage @@ -33,4 +33,4 @@ public: return (Thread *) os::thread_local_storage_at(thread_index()); } -#endif // OS_CPU_AIX_OJDKPPC_VM_THREADLS_AIX_PPC_HPP +#endif // OS_CPU_AIX_PPC_VM_THREADLS_AIX_PPC_HPP diff --git a/src/os_cpu/aix_ppc/vm/thread_aix_ppc.hpp b/src/os_cpu/aix_ppc/vm/thread_aix_ppc.hpp index c74b43e16..2ca7c861c 100644 --- a/src/os_cpu/aix_ppc/vm/thread_aix_ppc.hpp +++ b/src/os_cpu/aix_ppc/vm/thread_aix_ppc.hpp @@ -23,8 +23,8 @@ * */ -#ifndef OS_CPU_AIX_OJDKPPC_VM_THREAD_AIX_PPC_HPP -#define OS_CPU_AIX_OJDKPPC_VM_THREAD_AIX_PPC_HPP +#ifndef OS_CPU_AIX_PPC_VM_THREAD_AIX_PPC_HPP +#define OS_CPU_AIX_PPC_VM_THREAD_AIX_PPC_HPP private: void pd_initialize() { @@ -76,4 +76,4 @@ intptr_t* last_interpreter_fp() { return _last_interpreter_fp; } -#endif // OS_CPU_AIX_OJDKPPC_VM_THREAD_AIX_PPC_HPP +#endif // OS_CPU_AIX_PPC_VM_THREAD_AIX_PPC_HPP diff --git a/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp b/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp index d7fd74d21..f2195c49b 100644 --- a/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp +++ b/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp @@ -453,7 +453,7 @@ void os::Linux::set_fpu_control_word(int fpu_control) { //////////////////////////////////////////////////////////////////////////////// // thread stack -size_t os::Linux::min_stack_allowed = 768*K; +size_t os::Linux::min_stack_allowed = 128*K; bool os::Linux::supports_variable_stack_size() { return true; } -- GitLab