1884 oop_maps); |
1884 oop_maps); |
1885 return nm; |
1885 return nm; |
1886 |
1886 |
1887 } |
1887 } |
1888 |
1888 |
|
1889 #ifdef HAVE_DTRACE_H |
|
1890 // --------------------------------------------------------------------------- |
|
1891 // Generate a dtrace nmethod for a given signature. The method takes arguments |
|
1892 // in the Java compiled code convention, marshals them to the native |
|
1893 // abi and then leaves nops at the position you would expect to call a native |
|
1894 // function. When the probe is enabled the nops are replaced with a trap |
|
1895 // instruction that dtrace inserts and the trace will cause a notification |
|
1896 // to dtrace. |
|
1897 // |
|
1898 // The probes are only able to take primitive types and java/lang/String as |
|
1899 // arguments. No other java types are allowed. Strings are converted to utf8 |
|
1900 // strings so that from dtrace point of view java strings are converted to C |
|
1901 // strings. There is an arbitrary fixed limit on the total space that a method |
|
1902 // can use for converting the strings. (256 chars per string in the signature). |
|
1903 // So any java string larger then this is truncated. |
|
1904 |
|
1905 static int fp_offset[ConcreteRegisterImpl::number_of_registers] = { 0 }; |
|
1906 static bool offsets_initialized = false; |
|
1907 |
|
1908 |
|
1909 nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm, |
|
1910 methodHandle method) { |
|
1911 |
|
1912 |
|
1913 // generate_dtrace_nmethod is guarded by a mutex so we are sure to |
|
1914 // be single threaded in this method. |
|
1915 assert(AdapterHandlerLibrary_lock->owned_by_self(), "must be"); |
|
1916 |
|
1917 if (!offsets_initialized) { |
|
1918 fp_offset[c_rarg0->as_VMReg()->value()] = -1 * wordSize; |
|
1919 fp_offset[c_rarg1->as_VMReg()->value()] = -2 * wordSize; |
|
1920 fp_offset[c_rarg2->as_VMReg()->value()] = -3 * wordSize; |
|
1921 fp_offset[c_rarg3->as_VMReg()->value()] = -4 * wordSize; |
|
1922 fp_offset[c_rarg4->as_VMReg()->value()] = -5 * wordSize; |
|
1923 fp_offset[c_rarg5->as_VMReg()->value()] = -6 * wordSize; |
|
1924 |
|
1925 fp_offset[c_farg0->as_VMReg()->value()] = -7 * wordSize; |
|
1926 fp_offset[c_farg1->as_VMReg()->value()] = -8 * wordSize; |
|
1927 fp_offset[c_farg2->as_VMReg()->value()] = -9 * wordSize; |
|
1928 fp_offset[c_farg3->as_VMReg()->value()] = -10 * wordSize; |
|
1929 fp_offset[c_farg4->as_VMReg()->value()] = -11 * wordSize; |
|
1930 fp_offset[c_farg5->as_VMReg()->value()] = -12 * wordSize; |
|
1931 fp_offset[c_farg6->as_VMReg()->value()] = -13 * wordSize; |
|
1932 fp_offset[c_farg7->as_VMReg()->value()] = -14 * wordSize; |
|
1933 |
|
1934 offsets_initialized = true; |
|
1935 } |
|
1936 // Fill in the signature array, for the calling-convention call. |
|
1937 int total_args_passed = method->size_of_parameters(); |
|
1938 |
|
1939 BasicType* in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed); |
|
1940 VMRegPair *in_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed); |
|
1941 |
|
1942 // The signature we are going to use for the trap that dtrace will see |
|
1943 // java/lang/String is converted. We drop "this" and any other object |
|
1944 // is converted to NULL. (A one-slot java/lang/Long object reference |
|
1945 // is converted to a two-slot long, which is why we double the allocation). |
|
1946 BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed * 2); |
|
1947 VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed * 2); |
|
1948 |
|
1949 int i=0; |
|
1950 int total_strings = 0; |
|
1951 int first_arg_to_pass = 0; |
|
1952 int total_c_args = 0; |
|
1953 int box_offset = java_lang_boxing_object::value_offset_in_bytes(); |
|
1954 |
|
1955 // Skip the receiver as dtrace doesn't want to see it |
|
1956 if( !method->is_static() ) { |
|
1957 in_sig_bt[i++] = T_OBJECT; |
|
1958 first_arg_to_pass = 1; |
|
1959 } |
|
1960 |
|
1961 // We need to convert the java args to where a native (non-jni) function |
|
1962 // would expect them. To figure out where they go we convert the java |
|
1963 // signature to a C signature. |
|
1964 |
|
1965 SignatureStream ss(method->signature()); |
|
1966 for ( ; !ss.at_return_type(); ss.next()) { |
|
1967 BasicType bt = ss.type(); |
|
1968 in_sig_bt[i++] = bt; // Collect remaining bits of signature |
|
1969 out_sig_bt[total_c_args++] = bt; |
|
1970 if( bt == T_OBJECT) { |
|
1971 symbolOop s = ss.as_symbol_or_null(); |
|
1972 if (s == vmSymbols::java_lang_String()) { |
|
1973 total_strings++; |
|
1974 out_sig_bt[total_c_args-1] = T_ADDRESS; |
|
1975 } else if (s == vmSymbols::java_lang_Boolean() || |
|
1976 s == vmSymbols::java_lang_Character() || |
|
1977 s == vmSymbols::java_lang_Byte() || |
|
1978 s == vmSymbols::java_lang_Short() || |
|
1979 s == vmSymbols::java_lang_Integer() || |
|
1980 s == vmSymbols::java_lang_Float()) { |
|
1981 out_sig_bt[total_c_args-1] = T_INT; |
|
1982 } else if (s == vmSymbols::java_lang_Long() || |
|
1983 s == vmSymbols::java_lang_Double()) { |
|
1984 out_sig_bt[total_c_args-1] = T_LONG; |
|
1985 out_sig_bt[total_c_args++] = T_VOID; |
|
1986 } |
|
1987 } else if ( bt == T_LONG || bt == T_DOUBLE ) { |
|
1988 in_sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots |
|
1989 // We convert double to long |
|
1990 out_sig_bt[total_c_args-1] = T_LONG; |
|
1991 out_sig_bt[total_c_args++] = T_VOID; |
|
1992 } else if ( bt == T_FLOAT) { |
|
1993 // We convert float to int |
|
1994 out_sig_bt[total_c_args-1] = T_INT; |
|
1995 } |
|
1996 } |
|
1997 |
|
1998 assert(i==total_args_passed, "validly parsed signature"); |
|
1999 |
|
2000 // Now get the compiled-Java layout as input arguments |
|
2001 int comp_args_on_stack; |
|
2002 comp_args_on_stack = SharedRuntime::java_calling_convention( |
|
2003 in_sig_bt, in_regs, total_args_passed, false); |
|
2004 |
|
2005 // Now figure out where the args must be stored and how much stack space |
|
2006 // they require (neglecting out_preserve_stack_slots but space for storing |
|
2007 // the 1st six register arguments). It's weird see int_stk_helper. |
|
2008 |
|
2009 int out_arg_slots; |
|
2010 out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args); |
|
2011 |
|
2012 // Calculate the total number of stack slots we will need. |
|
2013 |
|
2014 // First count the abi requirement plus all of the outgoing args |
|
2015 int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots; |
|
2016 |
|
2017 // Now space for the string(s) we must convert |
|
2018 int* string_locs = NEW_RESOURCE_ARRAY(int, total_strings + 1); |
|
2019 for (i = 0; i < total_strings ; i++) { |
|
2020 string_locs[i] = stack_slots; |
|
2021 stack_slots += max_dtrace_string_size / VMRegImpl::stack_slot_size; |
|
2022 } |
|
2023 |
|
2024 // Plus the temps we might need to juggle register args |
|
2025 // regs take two slots each |
|
2026 stack_slots += (Argument::n_int_register_parameters_c + |
|
2027 Argument::n_float_register_parameters_c) * 2; |
|
2028 |
|
2029 |
|
2030 // + 4 for return address (which we own) and saved rbp, |
|
2031 |
|
2032 stack_slots += 4; |
|
2033 |
|
2034 // Ok The space we have allocated will look like: |
|
2035 // |
|
2036 // |
|
2037 // FP-> | | |
|
2038 // |---------------------| |
|
2039 // | string[n] | |
|
2040 // |---------------------| <- string_locs[n] |
|
2041 // | string[n-1] | |
|
2042 // |---------------------| <- string_locs[n-1] |
|
2043 // | ... | |
|
2044 // | ... | |
|
2045 // |---------------------| <- string_locs[1] |
|
2046 // | string[0] | |
|
2047 // |---------------------| <- string_locs[0] |
|
2048 // | outbound memory | |
|
2049 // | based arguments | |
|
2050 // | | |
|
2051 // |---------------------| |
|
2052 // | | |
|
2053 // SP-> | out_preserved_slots | |
|
2054 // |
|
2055 // |
|
2056 |
|
2057 // Now compute actual number of stack words we need rounding to make |
|
2058 // stack properly aligned. |
|
2059 stack_slots = round_to(stack_slots, 4 * VMRegImpl::slots_per_word); |
|
2060 |
|
2061 int stack_size = stack_slots * VMRegImpl::stack_slot_size; |
|
2062 |
|
2063 intptr_t start = (intptr_t)__ pc(); |
|
2064 |
|
2065 // First thing make an ic check to see if we should even be here |
|
2066 |
|
2067 // We are free to use all registers as temps without saving them and |
|
2068 // restoring them except rbp. rbp, is the only callee save register |
|
2069 // as far as the interpreter and the compiler(s) are concerned. |
|
2070 |
|
2071 const Register ic_reg = rax; |
|
2072 const Register receiver = rcx; |
|
2073 Label hit; |
|
2074 Label exception_pending; |
|
2075 |
|
2076 |
|
2077 __ verify_oop(receiver); |
|
2078 __ cmpl(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes())); |
|
2079 __ jcc(Assembler::equal, hit); |
|
2080 |
|
2081 __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); |
|
2082 |
|
2083 // verified entry must be aligned for code patching. |
|
2084 // and the first 5 bytes must be in the same cache line |
|
2085 // if we align at 8 then we will be sure 5 bytes are in the same line |
|
2086 __ align(8); |
|
2087 |
|
2088 __ bind(hit); |
|
2089 |
|
2090 int vep_offset = ((intptr_t)__ pc()) - start; |
|
2091 |
|
2092 |
|
2093 // The instruction at the verified entry point must be 5 bytes or longer |
|
2094 // because it can be patched on the fly by make_non_entrant. The stack bang |
|
2095 // instruction fits that requirement. |
|
2096 |
|
2097 // Generate stack overflow check |
|
2098 |
|
2099 if (UseStackBanging) { |
|
2100 if (stack_size <= StackShadowPages*os::vm_page_size()) { |
|
2101 __ bang_stack_with_offset(StackShadowPages*os::vm_page_size()); |
|
2102 } else { |
|
2103 __ movl(rax, stack_size); |
|
2104 __ bang_stack_size(rax, rbx); |
|
2105 } |
|
2106 } else { |
|
2107 // need a 5 byte instruction to allow MT safe patching to non-entrant |
|
2108 __ fat_nop(); |
|
2109 } |
|
2110 |
|
2111 assert(((uintptr_t)__ pc() - start - vep_offset) >= 5, |
|
2112 "valid size for make_non_entrant"); |
|
2113 |
|
2114 // Generate a new frame for the wrapper. |
|
2115 __ enter(); |
|
2116 |
|
2117 // -4 because return address is already present and so is saved rbp, |
|
2118 if (stack_size - 2*wordSize != 0) { |
|
2119 __ subq(rsp, stack_size - 2*wordSize); |
|
2120 } |
|
2121 |
|
2122 // Frame is now completed as far a size and linkage. |
|
2123 |
|
2124 int frame_complete = ((intptr_t)__ pc()) - start; |
|
2125 |
|
2126 int c_arg, j_arg; |
|
2127 |
|
2128 // State of input register args |
|
2129 |
|
2130 bool live[ConcreteRegisterImpl::number_of_registers]; |
|
2131 |
|
2132 live[j_rarg0->as_VMReg()->value()] = false; |
|
2133 live[j_rarg1->as_VMReg()->value()] = false; |
|
2134 live[j_rarg2->as_VMReg()->value()] = false; |
|
2135 live[j_rarg3->as_VMReg()->value()] = false; |
|
2136 live[j_rarg4->as_VMReg()->value()] = false; |
|
2137 live[j_rarg5->as_VMReg()->value()] = false; |
|
2138 |
|
2139 live[j_farg0->as_VMReg()->value()] = false; |
|
2140 live[j_farg1->as_VMReg()->value()] = false; |
|
2141 live[j_farg2->as_VMReg()->value()] = false; |
|
2142 live[j_farg3->as_VMReg()->value()] = false; |
|
2143 live[j_farg4->as_VMReg()->value()] = false; |
|
2144 live[j_farg5->as_VMReg()->value()] = false; |
|
2145 live[j_farg6->as_VMReg()->value()] = false; |
|
2146 live[j_farg7->as_VMReg()->value()] = false; |
|
2147 |
|
2148 |
|
2149 bool rax_is_zero = false; |
|
2150 |
|
2151 // All args (except strings) destined for the stack are moved first |
|
2152 for (j_arg = first_arg_to_pass, c_arg = 0 ; |
|
2153 j_arg < total_args_passed ; j_arg++, c_arg++ ) { |
|
2154 VMRegPair src = in_regs[j_arg]; |
|
2155 VMRegPair dst = out_regs[c_arg]; |
|
2156 |
|
2157 // Get the real reg value or a dummy (rsp) |
|
2158 |
|
2159 int src_reg = src.first()->is_reg() ? |
|
2160 src.first()->value() : |
|
2161 rsp->as_VMReg()->value(); |
|
2162 |
|
2163 bool useless = in_sig_bt[j_arg] == T_ARRAY || |
|
2164 (in_sig_bt[j_arg] == T_OBJECT && |
|
2165 out_sig_bt[c_arg] != T_INT && |
|
2166 out_sig_bt[c_arg] != T_ADDRESS && |
|
2167 out_sig_bt[c_arg] != T_LONG); |
|
2168 |
|
2169 live[src_reg] = !useless; |
|
2170 |
|
2171 if (dst.first()->is_stack()) { |
|
2172 |
|
2173 // Even though a string arg in a register is still live after this loop |
|
2174 // after the string conversion loop (next) it will be dead so we take |
|
2175 // advantage of that now for simpler code to manage live. |
|
2176 |
|
2177 live[src_reg] = false; |
|
2178 switch (in_sig_bt[j_arg]) { |
|
2179 |
|
2180 case T_ARRAY: |
|
2181 case T_OBJECT: |
|
2182 { |
|
2183 Address stack_dst(rsp, reg2offset_out(dst.first())); |
|
2184 |
|
2185 if (out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) { |
|
2186 // need to unbox a one-word value |
|
2187 Register in_reg = rax; |
|
2188 if ( src.first()->is_reg() ) { |
|
2189 in_reg = src.first()->as_Register(); |
|
2190 } else { |
|
2191 __ movq(rax, Address(rbp, reg2offset_in(src.first()))); |
|
2192 rax_is_zero = false; |
|
2193 } |
|
2194 Label skipUnbox; |
|
2195 __ movptr(Address(rsp, reg2offset_out(dst.first())), |
|
2196 (int32_t)NULL_WORD); |
|
2197 __ testq(in_reg, in_reg); |
|
2198 __ jcc(Assembler::zero, skipUnbox); |
|
2199 |
|
2200 Address src1(in_reg, box_offset); |
|
2201 if ( out_sig_bt[c_arg] == T_LONG ) { |
|
2202 __ movq(in_reg, src1); |
|
2203 __ movq(stack_dst, in_reg); |
|
2204 assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); |
|
2205 ++c_arg; // skip over T_VOID to keep the loop indices in sync |
|
2206 } else { |
|
2207 __ movl(in_reg, src1); |
|
2208 __ movl(stack_dst, in_reg); |
|
2209 } |
|
2210 |
|
2211 __ bind(skipUnbox); |
|
2212 } else if (out_sig_bt[c_arg] != T_ADDRESS) { |
|
2213 // Convert the arg to NULL |
|
2214 if (!rax_is_zero) { |
|
2215 __ xorq(rax, rax); |
|
2216 rax_is_zero = true; |
|
2217 } |
|
2218 __ movq(stack_dst, rax); |
|
2219 } |
|
2220 } |
|
2221 break; |
|
2222 |
|
2223 case T_VOID: |
|
2224 break; |
|
2225 |
|
2226 case T_FLOAT: |
|
2227 // This does the right thing since we know it is destined for the |
|
2228 // stack |
|
2229 float_move(masm, src, dst); |
|
2230 break; |
|
2231 |
|
2232 case T_DOUBLE: |
|
2233 // This does the right thing since we know it is destined for the |
|
2234 // stack |
|
2235 double_move(masm, src, dst); |
|
2236 break; |
|
2237 |
|
2238 case T_LONG : |
|
2239 long_move(masm, src, dst); |
|
2240 break; |
|
2241 |
|
2242 case T_ADDRESS: assert(false, "found T_ADDRESS in java args"); |
|
2243 |
|
2244 default: |
|
2245 move32_64(masm, src, dst); |
|
2246 } |
|
2247 } |
|
2248 |
|
2249 } |
|
2250 |
|
2251 // If we have any strings we must store any register based arg to the stack |
|
2252 // This includes any still live xmm registers too. |
|
2253 |
|
2254 int sid = 0; |
|
2255 |
|
2256 if (total_strings > 0 ) { |
|
2257 for (j_arg = first_arg_to_pass, c_arg = 0 ; |
|
2258 j_arg < total_args_passed ; j_arg++, c_arg++ ) { |
|
2259 VMRegPair src = in_regs[j_arg]; |
|
2260 VMRegPair dst = out_regs[c_arg]; |
|
2261 |
|
2262 if (src.first()->is_reg()) { |
|
2263 Address src_tmp(rbp, fp_offset[src.first()->value()]); |
|
2264 |
|
2265 // string oops were left untouched by the previous loop even if the |
|
2266 // eventual (converted) arg is destined for the stack so park them |
|
2267 // away now (except for first) |
|
2268 |
|
2269 if (out_sig_bt[c_arg] == T_ADDRESS) { |
|
2270 Address utf8_addr = Address( |
|
2271 rsp, string_locs[sid++] * VMRegImpl::stack_slot_size); |
|
2272 if (sid != 1) { |
|
2273 // The first string arg won't be killed until after the utf8 |
|
2274 // conversion |
|
2275 __ movq(utf8_addr, src.first()->as_Register()); |
|
2276 } |
|
2277 } else if (dst.first()->is_reg()) { |
|
2278 if (in_sig_bt[j_arg] == T_FLOAT || in_sig_bt[j_arg] == T_DOUBLE) { |
|
2279 |
|
2280 // Convert the xmm register to an int and store it in the reserved |
|
2281 // location for the eventual c register arg |
|
2282 XMMRegister f = src.first()->as_XMMRegister(); |
|
2283 if (in_sig_bt[j_arg] == T_FLOAT) { |
|
2284 __ movflt(src_tmp, f); |
|
2285 } else { |
|
2286 __ movdbl(src_tmp, f); |
|
2287 } |
|
2288 } else { |
|
2289 // If the arg is an oop type we don't support don't bother to store |
|
2290 // it remember string was handled above. |
|
2291 bool useless = in_sig_bt[j_arg] == T_ARRAY || |
|
2292 (in_sig_bt[j_arg] == T_OBJECT && |
|
2293 out_sig_bt[c_arg] != T_INT && |
|
2294 out_sig_bt[c_arg] != T_LONG); |
|
2295 |
|
2296 if (!useless) { |
|
2297 __ movq(src_tmp, src.first()->as_Register()); |
|
2298 } |
|
2299 } |
|
2300 } |
|
2301 } |
|
2302 if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { |
|
2303 assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); |
|
2304 ++c_arg; // skip over T_VOID to keep the loop indices in sync |
|
2305 } |
|
2306 } |
|
2307 |
|
2308 // Now that the volatile registers are safe, convert all the strings |
|
2309 sid = 0; |
|
2310 |
|
2311 for (j_arg = first_arg_to_pass, c_arg = 0 ; |
|
2312 j_arg < total_args_passed ; j_arg++, c_arg++ ) { |
|
2313 if (out_sig_bt[c_arg] == T_ADDRESS) { |
|
2314 // It's a string |
|
2315 Address utf8_addr = Address( |
|
2316 rsp, string_locs[sid++] * VMRegImpl::stack_slot_size); |
|
2317 // The first string we find might still be in the original java arg |
|
2318 // register |
|
2319 |
|
2320 VMReg src = in_regs[j_arg].first(); |
|
2321 |
|
2322 // We will need to eventually save the final argument to the trap |
|
2323 // in the von-volatile location dedicated to src. This is the offset |
|
2324 // from fp we will use. |
|
2325 int src_off = src->is_reg() ? |
|
2326 fp_offset[src->value()] : reg2offset_in(src); |
|
2327 |
|
2328 // This is where the argument will eventually reside |
|
2329 VMRegPair dst = out_regs[c_arg]; |
|
2330 |
|
2331 if (src->is_reg()) { |
|
2332 if (sid == 1) { |
|
2333 __ movq(c_rarg0, src->as_Register()); |
|
2334 } else { |
|
2335 __ movq(c_rarg0, utf8_addr); |
|
2336 } |
|
2337 } else { |
|
2338 // arg is still in the original location |
|
2339 __ movq(c_rarg0, Address(rbp, reg2offset_in(src))); |
|
2340 } |
|
2341 Label done, convert; |
|
2342 |
|
2343 // see if the oop is NULL |
|
2344 __ testq(c_rarg0, c_rarg0); |
|
2345 __ jcc(Assembler::notEqual, convert); |
|
2346 |
|
2347 if (dst.first()->is_reg()) { |
|
2348 // Save the ptr to utf string in the origina src loc or the tmp |
|
2349 // dedicated to it |
|
2350 __ movq(Address(rbp, src_off), c_rarg0); |
|
2351 } else { |
|
2352 __ movq(Address(rsp, reg2offset_out(dst.first())), c_rarg0); |
|
2353 } |
|
2354 __ jmp(done); |
|
2355 |
|
2356 __ bind(convert); |
|
2357 |
|
2358 __ lea(c_rarg1, utf8_addr); |
|
2359 if (dst.first()->is_reg()) { |
|
2360 __ movq(Address(rbp, src_off), c_rarg1); |
|
2361 } else { |
|
2362 __ movq(Address(rsp, reg2offset_out(dst.first())), c_rarg1); |
|
2363 } |
|
2364 // And do the conversion |
|
2365 __ call(RuntimeAddress( |
|
2366 CAST_FROM_FN_PTR(address, SharedRuntime::get_utf))); |
|
2367 |
|
2368 __ bind(done); |
|
2369 } |
|
2370 if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { |
|
2371 assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); |
|
2372 ++c_arg; // skip over T_VOID to keep the loop indices in sync |
|
2373 } |
|
2374 } |
|
2375 // The get_utf call killed all the c_arg registers |
|
2376 live[c_rarg0->as_VMReg()->value()] = false; |
|
2377 live[c_rarg1->as_VMReg()->value()] = false; |
|
2378 live[c_rarg2->as_VMReg()->value()] = false; |
|
2379 live[c_rarg3->as_VMReg()->value()] = false; |
|
2380 live[c_rarg4->as_VMReg()->value()] = false; |
|
2381 live[c_rarg5->as_VMReg()->value()] = false; |
|
2382 |
|
2383 live[c_farg0->as_VMReg()->value()] = false; |
|
2384 live[c_farg1->as_VMReg()->value()] = false; |
|
2385 live[c_farg2->as_VMReg()->value()] = false; |
|
2386 live[c_farg3->as_VMReg()->value()] = false; |
|
2387 live[c_farg4->as_VMReg()->value()] = false; |
|
2388 live[c_farg5->as_VMReg()->value()] = false; |
|
2389 live[c_farg6->as_VMReg()->value()] = false; |
|
2390 live[c_farg7->as_VMReg()->value()] = false; |
|
2391 } |
|
2392 |
|
2393 // Now we can finally move the register args to their desired locations |
|
2394 |
|
2395 rax_is_zero = false; |
|
2396 |
|
2397 for (j_arg = first_arg_to_pass, c_arg = 0 ; |
|
2398 j_arg < total_args_passed ; j_arg++, c_arg++ ) { |
|
2399 |
|
2400 VMRegPair src = in_regs[j_arg]; |
|
2401 VMRegPair dst = out_regs[c_arg]; |
|
2402 |
|
2403 // Only need to look for args destined for the interger registers (since we |
|
2404 // convert float/double args to look like int/long outbound) |
|
2405 if (dst.first()->is_reg()) { |
|
2406 Register r = dst.first()->as_Register(); |
|
2407 |
|
2408 // Check if the java arg is unsupported and thereofre useless |
|
2409 bool useless = in_sig_bt[j_arg] == T_ARRAY || |
|
2410 (in_sig_bt[j_arg] == T_OBJECT && |
|
2411 out_sig_bt[c_arg] != T_INT && |
|
2412 out_sig_bt[c_arg] != T_ADDRESS && |
|
2413 out_sig_bt[c_arg] != T_LONG); |
|
2414 |
|
2415 |
|
2416 // If we're going to kill an existing arg save it first |
|
2417 if (live[dst.first()->value()]) { |
|
2418 // you can't kill yourself |
|
2419 if (src.first() != dst.first()) { |
|
2420 __ movq(Address(rbp, fp_offset[dst.first()->value()]), r); |
|
2421 } |
|
2422 } |
|
2423 if (src.first()->is_reg()) { |
|
2424 if (live[src.first()->value()] ) { |
|
2425 if (in_sig_bt[j_arg] == T_FLOAT) { |
|
2426 __ movdl(r, src.first()->as_XMMRegister()); |
|
2427 } else if (in_sig_bt[j_arg] == T_DOUBLE) { |
|
2428 __ movdq(r, src.first()->as_XMMRegister()); |
|
2429 } else if (r != src.first()->as_Register()) { |
|
2430 if (!useless) { |
|
2431 __ movq(r, src.first()->as_Register()); |
|
2432 } |
|
2433 } |
|
2434 } else { |
|
2435 // If the arg is an oop type we don't support don't bother to store |
|
2436 // it |
|
2437 if (!useless) { |
|
2438 if (in_sig_bt[j_arg] == T_DOUBLE || |
|
2439 in_sig_bt[j_arg] == T_LONG || |
|
2440 in_sig_bt[j_arg] == T_OBJECT ) { |
|
2441 __ movq(r, Address(rbp, fp_offset[src.first()->value()])); |
|
2442 } else { |
|
2443 __ movl(r, Address(rbp, fp_offset[src.first()->value()])); |
|
2444 } |
|
2445 } |
|
2446 } |
|
2447 live[src.first()->value()] = false; |
|
2448 } else if (!useless) { |
|
2449 // full sized move even for int should be ok |
|
2450 __ movq(r, Address(rbp, reg2offset_in(src.first()))); |
|
2451 } |
|
2452 |
|
2453 // At this point r has the original java arg in the final location |
|
2454 // (assuming it wasn't useless). If the java arg was an oop |
|
2455 // we have a bit more to do |
|
2456 |
|
2457 if (in_sig_bt[j_arg] == T_ARRAY || in_sig_bt[j_arg] == T_OBJECT ) { |
|
2458 if (out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) { |
|
2459 // need to unbox a one-word value |
|
2460 Label skip; |
|
2461 __ testq(r, r); |
|
2462 __ jcc(Assembler::equal, skip); |
|
2463 Address src1(r, box_offset); |
|
2464 if ( out_sig_bt[c_arg] == T_LONG ) { |
|
2465 __ movq(r, src1); |
|
2466 } else { |
|
2467 __ movl(r, src1); |
|
2468 } |
|
2469 __ bind(skip); |
|
2470 |
|
2471 } else if (out_sig_bt[c_arg] != T_ADDRESS) { |
|
2472 // Convert the arg to NULL |
|
2473 __ xorq(r, r); |
|
2474 } |
|
2475 } |
|
2476 |
|
2477 // dst can longer be holding an input value |
|
2478 live[dst.first()->value()] = false; |
|
2479 } |
|
2480 if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { |
|
2481 assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); |
|
2482 ++c_arg; // skip over T_VOID to keep the loop indices in sync |
|
2483 } |
|
2484 } |
|
2485 |
|
2486 |
|
2487 // Ok now we are done. Need to place the nop that dtrace wants in order to |
|
2488 // patch in the trap |
|
2489 int patch_offset = ((intptr_t)__ pc()) - start; |
|
2490 |
|
2491 __ nop(); |
|
2492 |
|
2493 |
|
2494 // Return |
|
2495 |
|
2496 __ leave(); |
|
2497 __ ret(0); |
|
2498 |
|
2499 __ flush(); |
|
2500 |
|
2501 nmethod *nm = nmethod::new_dtrace_nmethod( |
|
2502 method, masm->code(), vep_offset, patch_offset, frame_complete, |
|
2503 stack_slots / VMRegImpl::slots_per_word); |
|
2504 return nm; |
|
2505 |
|
2506 } |
|
2507 |
|
2508 #endif // HAVE_DTRACE_H |
|
2509 |
1889 // this function returns the adjust size (in number of words) to a c2i adapter |
2510 // this function returns the adjust size (in number of words) to a c2i adapter |
1890 // activation for use during deoptimization |
2511 // activation for use during deoptimization |
1891 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) { |
2512 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) { |
1892 return (callee_locals - callee_parameters) * Interpreter::stackElementWords(); |
2513 return (callee_locals - callee_parameters) * Interpreter::stackElementWords(); |
1893 } |
2514 } |