comparison src/cpu/x86/vm/sharedRuntime_x86_64.cpp @ 116:018d5b58dd4f

6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes Summary: Initial checkin of JSDT code Reviewed-by: acorn, sbohne
author kamg
date Thu, 17 Apr 2008 22:18:15 -0400
parents ba764ed4b6f2
children 437d03ea40b1
comparison
equal deleted inserted replaced
115:e7a91a357527 116:018d5b58dd4f
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 }