src/cpu/x86/vm/interp_masm_x86_64.cpp

changeset 5921
ce0cc25bc5e2
parent 5914
d13d7aba8c12
child 5987
5ccbab1c69f3
     1.1 --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp	Fri Oct 11 19:51:31 2013 -0700
     1.2 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp	Sat Oct 12 12:12:59 2013 +0200
     1.3 @@ -1120,7 +1120,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 @@ -1130,35 +1130,92 @@
    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 -        movq(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 +          movq(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 +        subq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args));
    1.41 +        subl(tmp, 1);
    1.42 +        Address arg_addr = argument_address(tmp);
    1.43 +        movptr(tmp, arg_addr);
    1.44 +
    1.45 +        Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args);
    1.46 +        profile_obj_type(tmp, mdo_arg_addr);
    1.47 +
    1.48 +        int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
    1.49 +        addptr(mdp, to_add);
    1.50 +        off_to_args += to_add;
    1.51        }
    1.52 -      movptr(tmp, Address(callee, Method::const_offset()));
    1.53 -      load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset()));
    1.54 -      subq(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::stack_slot_offset(i))-off_to_args));
    1.55 -      subl(tmp, 1);
    1.56 -      Address arg_addr = argument_address(tmp);
    1.57 -      movptr(tmp, arg_addr);
    1.58  
    1.59 -      Address mdo_arg_addr(mdp, in_bytes(TypeStackSlotEntries::type_offset(i))-off_to_args);
    1.60 -      profile_obj_type(tmp, mdo_arg_addr);
    1.61 +      if (MethodData::profile_return()) {
    1.62 +        movq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
    1.63 +        subl(tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());
    1.64 +      }
    1.65  
    1.66 -      int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
    1.67 -      addptr(mdp, to_add);
    1.68 -      off_to_args += to_add;
    1.69 +      bind(done);
    1.70 +
    1.71 +      if (MethodData::profile_return()) {
    1.72 +        // We're right after the type profile for the last
    1.73 +        // argument. tmp is the number of cell left in the
    1.74 +        // CallTypeData/VirtualCallTypeData to reach its end. Non null
    1.75 +        // if there's a return to profile.
    1.76 +        assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type");
    1.77 +        shll(tmp, exact_log2(DataLayout::cell_size));
    1.78 +        addptr(mdp, tmp);
    1.79 +      }
    1.80 +      movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp);
    1.81 +    } else {
    1.82 +      assert(MethodData::profile_return(), "either profile call args or call ret");
    1.83 +      update_mdp_by_constant(mdp, in_bytes(ReturnTypeEntry::size()));
    1.84      }
    1.85  
    1.86 -    bind(done);
    1.87 +    // mdp points right after the end of the
    1.88 +    // CallTypeData/VirtualCallTypeData, right after the cells for the
    1.89 +    // return value type if there's one
    1.90  
    1.91 -    movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp);
    1.92 +    bind(profile_continue);
    1.93 +  }
    1.94 +}
    1.95 +
    1.96 +void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) {
    1.97 +  assert_different_registers(mdp, ret, tmp, r13);
    1.98 +  if (ProfileInterpreter && MethodData::profile_return()) {
    1.99 +    Label profile_continue, done;
   1.100 +
   1.101 +    test_method_data_pointer(mdp, profile_continue);
   1.102 +
   1.103 +    if (MethodData::profile_return_jsr292_only()) {
   1.104 +      // If we don't profile all invoke bytecodes we must make sure
   1.105 +      // it's a bytecode we indeed profile. We can't go back to the
   1.106 +      // begining of the ProfileData we intend to update to check its
   1.107 +      // type because we're right after it and we don't known its
   1.108 +      // length
   1.109 +      Label do_profile;
   1.110 +      cmpb(Address(r13, 0), Bytecodes::_invokedynamic);
   1.111 +      jcc(Assembler::equal, do_profile);
   1.112 +      cmpb(Address(r13, 0), Bytecodes::_invokehandle);
   1.113 +      jcc(Assembler::equal, do_profile);
   1.114 +      get_method(tmp);
   1.115 +      cmpb(Address(tmp, Method::intrinsic_id_offset_in_bytes()), vmIntrinsics::_compiledLambdaForm);
   1.116 +      jcc(Assembler::notEqual, profile_continue);
   1.117 +
   1.118 +      bind(do_profile);
   1.119 +    }
   1.120 +
   1.121 +    Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size()));
   1.122 +    mov(tmp, ret);
   1.123 +    profile_obj_type(tmp, mdo_ret_addr);
   1.124  
   1.125      bind(profile_continue);
   1.126    }

mercurial