提交 fad19589 编写于 作者: G goetz

8066964: ppc64: argument and return type profiling, fix problem with popframe

Reviewed-by: roland, kvn
上级 9839909a
......@@ -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.
......
......@@ -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
......
......@@ -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[] = {
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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);
......
......@@ -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 */);
}
......
......@@ -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() {
......
此差异已折叠。
......@@ -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.
......
......@@ -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_<os_cpu>.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;
}
......
......@@ -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
......@@ -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
......@@ -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
......@@ -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
......@@ -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; }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册