Mercurial > hg > graal-compiler
comparison src/cpu/sparc/vm/interp_masm_sparc.cpp @ 17628:add2caa66e7e
8026253: New type profiling points: sparc support
Summary: c1 and interpreter support for new type profiling on sparc
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Tue, 14 Jan 2014 14:51:47 +0100 |
parents | 46c544b8fbfc |
children | d8041d695d19 d3f14809b051 ce9fd31ffd14 |
comparison
equal
deleted
inserted
replaced
17627:d7773b29c65a | 17628:add2caa66e7e |
---|---|
1890 | 1890 |
1891 bind (profile_continue); | 1891 bind (profile_continue); |
1892 } | 1892 } |
1893 } | 1893 } |
1894 | 1894 |
1895 void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr, Register tmp) { | |
1896 Label not_null, do_nothing, do_update; | |
1897 | |
1898 assert_different_registers(obj, mdo_addr.base(), tmp); | |
1899 | |
1900 verify_oop(obj); | |
1901 | |
1902 ld_ptr(mdo_addr, tmp); | |
1903 | |
1904 br_notnull_short(obj, pt, not_null); | |
1905 or3(tmp, TypeEntries::null_seen, tmp); | |
1906 ba_short(do_update); | |
1907 | |
1908 bind(not_null); | |
1909 load_klass(obj, obj); | |
1910 | |
1911 xor3(obj, tmp, obj); | |
1912 btst(TypeEntries::type_klass_mask, obj); | |
1913 // klass seen before, nothing to do. The unknown bit may have been | |
1914 // set already but no need to check. | |
1915 brx(zero, false, pt, do_nothing); | |
1916 delayed()-> | |
1917 | |
1918 btst(TypeEntries::type_unknown, obj); | |
1919 // already unknown. Nothing to do anymore. | |
1920 brx(notZero, false, pt, do_nothing); | |
1921 delayed()-> | |
1922 | |
1923 btst(TypeEntries::type_mask, tmp); | |
1924 brx(zero, true, pt, do_update); | |
1925 // first time here. Set profile type. | |
1926 delayed()->or3(tmp, obj, tmp); | |
1927 | |
1928 // different than before. Cannot keep accurate profile. | |
1929 or3(tmp, TypeEntries::type_unknown, tmp); | |
1930 | |
1931 bind(do_update); | |
1932 // update profile | |
1933 st_ptr(tmp, mdo_addr); | |
1934 | |
1935 bind(do_nothing); | |
1936 } | |
1937 | |
1938 void InterpreterMacroAssembler::profile_arguments_type(Register callee, Register tmp1, Register tmp2, bool is_virtual) { | |
1939 if (!ProfileInterpreter) { | |
1940 return; | |
1941 } | |
1942 | |
1943 assert_different_registers(callee, tmp1, tmp2, ImethodDataPtr); | |
1944 | |
1945 if (MethodData::profile_arguments() || MethodData::profile_return()) { | |
1946 Label profile_continue; | |
1947 | |
1948 test_method_data_pointer(profile_continue); | |
1949 | |
1950 int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size()); | |
1951 | |
1952 ldub(ImethodDataPtr, in_bytes(DataLayout::tag_offset()) - off_to_start, tmp1); | |
1953 cmp_and_br_short(tmp1, is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag, notEqual, pn, profile_continue); | |
1954 | |
1955 if (MethodData::profile_arguments()) { | |
1956 Label done; | |
1957 int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset()); | |
1958 add(ImethodDataPtr, off_to_args, ImethodDataPtr); | |
1959 | |
1960 for (int i = 0; i < TypeProfileArgsLimit; i++) { | |
1961 if (i > 0 || MethodData::profile_return()) { | |
1962 // If return value type is profiled we may have no argument to profile | |
1963 ld_ptr(ImethodDataPtr, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args, tmp1); | |
1964 sub(tmp1, i*TypeStackSlotEntries::per_arg_count(), tmp1); | |
1965 cmp_and_br_short(tmp1, TypeStackSlotEntries::per_arg_count(), less, pn, done); | |
1966 } | |
1967 ld_ptr(Address(callee, Method::const_offset()), tmp1); | |
1968 lduh(Address(tmp1, ConstMethod::size_of_parameters_offset()), tmp1); | |
1969 // stack offset o (zero based) from the start of the argument | |
1970 // list, for n arguments translates into offset n - o - 1 from | |
1971 // the end of the argument list. But there's an extra slot at | |
1972 // the stop of the stack. So the offset is n - o from Lesp. | |
1973 ld_ptr(ImethodDataPtr, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args, tmp2); | |
1974 sub(tmp1, tmp2, tmp1); | |
1975 | |
1976 // Can't use MacroAssembler::argument_address() which needs Gargs to be set up | |
1977 sll(tmp1, Interpreter::logStackElementSize, tmp1); | |
1978 ld_ptr(Lesp, tmp1, tmp1); | |
1979 | |
1980 Address mdo_arg_addr(ImethodDataPtr, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args); | |
1981 profile_obj_type(tmp1, mdo_arg_addr, tmp2); | |
1982 | |
1983 int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); | |
1984 add(ImethodDataPtr, to_add, ImethodDataPtr); | |
1985 off_to_args += to_add; | |
1986 } | |
1987 | |
1988 if (MethodData::profile_return()) { | |
1989 ld_ptr(ImethodDataPtr, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args, tmp1); | |
1990 sub(tmp1, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count(), tmp1); | |
1991 } | |
1992 | |
1993 bind(done); | |
1994 | |
1995 if (MethodData::profile_return()) { | |
1996 // We're right after the type profile for the last | |
1997 // argument. tmp1 is the number of cells left in the | |
1998 // CallTypeData/VirtualCallTypeData to reach its end. Non null | |
1999 // if there's a return to profile. | |
2000 assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type"); | |
2001 sll(tmp1, exact_log2(DataLayout::cell_size), tmp1); | |
2002 add(ImethodDataPtr, tmp1, ImethodDataPtr); | |
2003 } | |
2004 } else { | |
2005 assert(MethodData::profile_return(), "either profile call args or call ret"); | |
2006 update_mdp_by_constant(in_bytes(ReturnTypeEntry::size())); | |
2007 } | |
2008 | |
2009 // mdp points right after the end of the | |
2010 // CallTypeData/VirtualCallTypeData, right after the cells for the | |
2011 // return value type if there's one. | |
2012 | |
2013 bind(profile_continue); | |
2014 } | |
2015 } | |
2016 | |
2017 void InterpreterMacroAssembler::profile_return_type(Register ret, Register tmp1, Register tmp2) { | |
2018 assert_different_registers(ret, tmp1, tmp2); | |
2019 if (ProfileInterpreter && MethodData::profile_return()) { | |
2020 Label profile_continue, done; | |
2021 | |
2022 test_method_data_pointer(profile_continue); | |
2023 | |
2024 if (MethodData::profile_return_jsr292_only()) { | |
2025 // If we don't profile all invoke bytecodes we must make sure | |
2026 // it's a bytecode we indeed profile. We can't go back to the | |
2027 // begining of the ProfileData we intend to update to check its | |
2028 // type because we're right after it and we don't known its | |
2029 // length. | |
2030 Label do_profile; | |
2031 ldub(Lbcp, 0, tmp1); | |
2032 cmp_and_br_short(tmp1, Bytecodes::_invokedynamic, equal, pn, do_profile); | |
2033 cmp(tmp1, Bytecodes::_invokehandle); | |
2034 br(equal, false, pn, do_profile); | |
2035 delayed()->ldub(Lmethod, Method::intrinsic_id_offset_in_bytes(), tmp1); | |
2036 cmp_and_br_short(tmp1, vmIntrinsics::_compiledLambdaForm, notEqual, pt, profile_continue); | |
2037 | |
2038 bind(do_profile); | |
2039 } | |
2040 | |
2041 Address mdo_ret_addr(ImethodDataPtr, -in_bytes(ReturnTypeEntry::size())); | |
2042 mov(ret, tmp1); | |
2043 profile_obj_type(tmp1, mdo_ret_addr, tmp2); | |
2044 | |
2045 bind(profile_continue); | |
2046 } | |
2047 } | |
2048 | |
2049 void InterpreterMacroAssembler::profile_parameters_type(Register tmp1, Register tmp2, Register tmp3, Register tmp4) { | |
2050 if (ProfileInterpreter && MethodData::profile_parameters()) { | |
2051 Label profile_continue, done; | |
2052 | |
2053 test_method_data_pointer(profile_continue); | |
2054 | |
2055 // Load the offset of the area within the MDO used for | |
2056 // parameters. If it's negative we're not profiling any parameters. | |
2057 lduw(ImethodDataPtr, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset()), tmp1); | |
2058 cmp_and_br_short(tmp1, 0, less, pn, profile_continue); | |
2059 | |
2060 // Compute a pointer to the area for parameters from the offset | |
2061 // and move the pointer to the slot for the last | |
2062 // parameters. Collect profiling from last parameter down. | |
2063 // mdo start + parameters offset + array length - 1 | |
2064 | |
2065 // Pointer to the parameter area in the MDO | |
2066 Register mdp = tmp1; | |
2067 add(ImethodDataPtr, tmp1, mdp); | |
2068 | |
2069 // offset of the current profile entry to update | |
2070 Register entry_offset = tmp2; | |
2071 // entry_offset = array len in number of cells | |
2072 ld_ptr(mdp, ArrayData::array_len_offset(), entry_offset); | |
2073 | |
2074 int off_base = in_bytes(ParametersTypeData::stack_slot_offset(0)); | |
2075 assert(off_base % DataLayout::cell_size == 0, "should be a number of cells"); | |
2076 | |
2077 // entry_offset (number of cells) = array len - size of 1 entry + offset of the stack slot field | |
2078 sub(entry_offset, TypeStackSlotEntries::per_arg_count() - (off_base / DataLayout::cell_size), entry_offset); | |
2079 // entry_offset in bytes | |
2080 sll(entry_offset, exact_log2(DataLayout::cell_size), entry_offset); | |
2081 | |
2082 Label loop; | |
2083 bind(loop); | |
2084 | |
2085 // load offset on the stack from the slot for this parameter | |
2086 ld_ptr(mdp, entry_offset, tmp3); | |
2087 sll(tmp3,Interpreter::logStackElementSize, tmp3); | |
2088 neg(tmp3); | |
2089 // read the parameter from the local area | |
2090 ld_ptr(Llocals, tmp3, tmp3); | |
2091 | |
2092 // make entry_offset now point to the type field for this parameter | |
2093 int type_base = in_bytes(ParametersTypeData::type_offset(0)); | |
2094 assert(type_base > off_base, "unexpected"); | |
2095 add(entry_offset, type_base - off_base, entry_offset); | |
2096 | |
2097 // profile the parameter | |
2098 Address arg_type(mdp, entry_offset); | |
2099 profile_obj_type(tmp3, arg_type, tmp4); | |
2100 | |
2101 // go to next parameter | |
2102 sub(entry_offset, TypeStackSlotEntries::per_arg_count() * DataLayout::cell_size + (type_base - off_base), entry_offset); | |
2103 cmp_and_br_short(entry_offset, off_base, greaterEqual, pt, loop); | |
2104 | |
2105 bind(profile_continue); | |
2106 } | |
2107 } | |
2108 | |
1895 // add a InterpMonitorElem to stack (see frame_sparc.hpp) | 2109 // add a InterpMonitorElem to stack (see frame_sparc.hpp) |
1896 | 2110 |
1897 void InterpreterMacroAssembler::add_monitor_to_stack( bool stack_is_empty, | 2111 void InterpreterMacroAssembler::add_monitor_to_stack( bool stack_is_empty, |
1898 Register Rtemp, | 2112 Register Rtemp, |
1899 Register Rtemp2 ) { | 2113 Register Rtemp2 ) { |