1.1 --- a/src/cpu/x86/vm/interp_masm_x86_32.cpp Fri Oct 11 19:51:31 2013 -0700 1.2 +++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp Sat Oct 12 12:12:59 2013 +0200 1.3 @@ -1095,7 +1095,7 @@ 1.4 return; 1.5 } 1.6 1.7 - if (MethodData::profile_arguments()) { 1.8 + if (MethodData::profile_arguments() || MethodData::profile_return()) { 1.9 Label profile_continue; 1.10 1.11 test_method_data_pointer(mdp, profile_continue); 1.12 @@ -1105,35 +1105,95 @@ 1.13 cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag); 1.14 jcc(Assembler::notEqual, profile_continue); 1.15 1.16 - Label done; 1.17 - int off_to_args = in_bytes(TypeStackSlotEntries::args_data_offset()); 1.18 - addptr(mdp, off_to_args); 1.19 + if (MethodData::profile_arguments()) { 1.20 + Label done; 1.21 + int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset()); 1.22 + addptr(mdp, off_to_args); 1.23 1.24 - for (int i = 0; i < TypeProfileArgsLimit; i++) { 1.25 - if (i > 0) { 1.26 - movl(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::cell_count_offset())-off_to_args)); 1.27 - subl(tmp, i*TypeStackSlotEntries::per_arg_count()); 1.28 - cmpl(tmp, TypeStackSlotEntries::per_arg_count()); 1.29 - jcc(Assembler::less, done); 1.30 + for (int i = 0; i < TypeProfileArgsLimit; i++) { 1.31 + if (i > 0 || MethodData::profile_return()) { 1.32 + // If return value type is profiled we may have no argument to profile 1.33 + movl(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args)); 1.34 + subl(tmp, i*TypeStackSlotEntries::per_arg_count()); 1.35 + cmpl(tmp, TypeStackSlotEntries::per_arg_count()); 1.36 + jcc(Assembler::less, done); 1.37 + } 1.38 + movptr(tmp, Address(callee, Method::const_offset())); 1.39 + load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset())); 1.40 + // stack offset o (zero based) from the start of the argument 1.41 + // list, for n arguments translates into offset n - o - 1 from 1.42 + // the end of the argument list 1.43 + subl(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args)); 1.44 + subl(tmp, 1); 1.45 + Address arg_addr = argument_address(tmp); 1.46 + movptr(tmp, arg_addr); 1.47 + 1.48 + Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args); 1.49 + profile_obj_type(tmp, mdo_arg_addr); 1.50 + 1.51 + int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); 1.52 + addptr(mdp, to_add); 1.53 + off_to_args += to_add; 1.54 } 1.55 - movptr(tmp, Address(callee, Method::const_offset())); 1.56 - load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset())); 1.57 - subl(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::stack_slot_offset(i))-off_to_args)); 1.58 - subl(tmp, 1); 1.59 - Address arg_addr = argument_address(tmp); 1.60 - movptr(tmp, arg_addr); 1.61 1.62 - Address mdo_arg_addr(mdp, in_bytes(TypeStackSlotEntries::type_offset(i))-off_to_args); 1.63 - profile_obj_type(tmp, mdo_arg_addr); 1.64 + if (MethodData::profile_return()) { 1.65 + movl(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args)); 1.66 + subl(tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count()); 1.67 + } 1.68 1.69 - int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); 1.70 - addptr(mdp, to_add); 1.71 - off_to_args += to_add; 1.72 + bind(done); 1.73 + 1.74 + if (MethodData::profile_return()) { 1.75 + // We're right after the type profile for the last 1.76 + // argument. tmp is the number of cell left in the 1.77 + // CallTypeData/VirtualCallTypeData to reach its end. Non null 1.78 + // if there's a return to profile. 1.79 + assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type"); 1.80 + shll(tmp, exact_log2(DataLayout::cell_size)); 1.81 + addptr(mdp, tmp); 1.82 + } 1.83 + movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp); 1.84 + } else { 1.85 + assert(MethodData::profile_return(), "either profile call args or call ret"); 1.86 + update_mdp_by_constant(mdp, in_bytes(ReturnTypeEntry::size())); 1.87 } 1.88 1.89 - bind(done); 1.90 + // mdp points right after the end of the 1.91 + // CallTypeData/VirtualCallTypeData, right after the cells for the 1.92 + // return value type if there's one 1.93 1.94 - movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp); 1.95 + bind(profile_continue); 1.96 + } 1.97 +} 1.98 + 1.99 +void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) { 1.100 + assert_different_registers(mdp, ret, tmp, rsi); 1.101 + if (ProfileInterpreter && MethodData::profile_return()) { 1.102 + Label profile_continue, done; 1.103 + 1.104 + test_method_data_pointer(mdp, profile_continue); 1.105 + 1.106 + if (MethodData::profile_return_jsr292_only()) { 1.107 + // If we don't profile all invoke bytecodes we must make sure 1.108 + // it's a bytecode we indeed profile. We can't go back to the 1.109 + // begining of the ProfileData we intend to update to check its 1.110 + // type because we're right after it and we don't known its 1.111 + // length 1.112 + Label do_profile; 1.113 + cmpb(Address(rsi, 0), Bytecodes::_invokedynamic); 1.114 + jcc(Assembler::equal, do_profile); 1.115 + cmpb(Address(rsi, 0), Bytecodes::_invokehandle); 1.116 + jcc(Assembler::equal, do_profile); 1.117 + get_method(tmp); 1.118 + cmpb(Address(tmp, Method::intrinsic_id_offset_in_bytes()), vmIntrinsics::_compiledLambdaForm); 1.119 + jcc(Assembler::notEqual, profile_continue); 1.120 + 1.121 + bind(do_profile); 1.122 + } 1.123 + 1.124 + Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size())); 1.125 + mov(tmp, ret); 1.126 + profile_obj_type(tmp, mdo_ret_addr); 1.127 1.128 bind(profile_continue); 1.129 }