1.1 --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Wed Apr 16 17:36:29 2008 -0400 1.2 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Apr 17 22:18:15 2008 -0400 1.3 @@ -1886,6 +1886,627 @@ 1.4 1.5 } 1.6 1.7 +#ifdef HAVE_DTRACE_H 1.8 +// --------------------------------------------------------------------------- 1.9 +// Generate a dtrace nmethod for a given signature. The method takes arguments 1.10 +// in the Java compiled code convention, marshals them to the native 1.11 +// abi and then leaves nops at the position you would expect to call a native 1.12 +// function. When the probe is enabled the nops are replaced with a trap 1.13 +// instruction that dtrace inserts and the trace will cause a notification 1.14 +// to dtrace. 1.15 +// 1.16 +// The probes are only able to take primitive types and java/lang/String as 1.17 +// arguments. No other java types are allowed. Strings are converted to utf8 1.18 +// strings so that from dtrace point of view java strings are converted to C 1.19 +// strings. There is an arbitrary fixed limit on the total space that a method 1.20 +// can use for converting the strings. (256 chars per string in the signature). 1.21 +// So any java string larger then this is truncated. 1.22 + 1.23 +static int fp_offset[ConcreteRegisterImpl::number_of_registers] = { 0 }; 1.24 +static bool offsets_initialized = false; 1.25 + 1.26 + 1.27 +nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm, 1.28 + methodHandle method) { 1.29 + 1.30 + 1.31 + // generate_dtrace_nmethod is guarded by a mutex so we are sure to 1.32 + // be single threaded in this method. 1.33 + assert(AdapterHandlerLibrary_lock->owned_by_self(), "must be"); 1.34 + 1.35 + if (!offsets_initialized) { 1.36 + fp_offset[c_rarg0->as_VMReg()->value()] = -1 * wordSize; 1.37 + fp_offset[c_rarg1->as_VMReg()->value()] = -2 * wordSize; 1.38 + fp_offset[c_rarg2->as_VMReg()->value()] = -3 * wordSize; 1.39 + fp_offset[c_rarg3->as_VMReg()->value()] = -4 * wordSize; 1.40 + fp_offset[c_rarg4->as_VMReg()->value()] = -5 * wordSize; 1.41 + fp_offset[c_rarg5->as_VMReg()->value()] = -6 * wordSize; 1.42 + 1.43 + fp_offset[c_farg0->as_VMReg()->value()] = -7 * wordSize; 1.44 + fp_offset[c_farg1->as_VMReg()->value()] = -8 * wordSize; 1.45 + fp_offset[c_farg2->as_VMReg()->value()] = -9 * wordSize; 1.46 + fp_offset[c_farg3->as_VMReg()->value()] = -10 * wordSize; 1.47 + fp_offset[c_farg4->as_VMReg()->value()] = -11 * wordSize; 1.48 + fp_offset[c_farg5->as_VMReg()->value()] = -12 * wordSize; 1.49 + fp_offset[c_farg6->as_VMReg()->value()] = -13 * wordSize; 1.50 + fp_offset[c_farg7->as_VMReg()->value()] = -14 * wordSize; 1.51 + 1.52 + offsets_initialized = true; 1.53 + } 1.54 + // Fill in the signature array, for the calling-convention call. 1.55 + int total_args_passed = method->size_of_parameters(); 1.56 + 1.57 + BasicType* in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed); 1.58 + VMRegPair *in_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed); 1.59 + 1.60 + // The signature we are going to use for the trap that dtrace will see 1.61 + // java/lang/String is converted. We drop "this" and any other object 1.62 + // is converted to NULL. (A one-slot java/lang/Long object reference 1.63 + // is converted to a two-slot long, which is why we double the allocation). 1.64 + BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed * 2); 1.65 + VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed * 2); 1.66 + 1.67 + int i=0; 1.68 + int total_strings = 0; 1.69 + int first_arg_to_pass = 0; 1.70 + int total_c_args = 0; 1.71 + int box_offset = java_lang_boxing_object::value_offset_in_bytes(); 1.72 + 1.73 + // Skip the receiver as dtrace doesn't want to see it 1.74 + if( !method->is_static() ) { 1.75 + in_sig_bt[i++] = T_OBJECT; 1.76 + first_arg_to_pass = 1; 1.77 + } 1.78 + 1.79 + // We need to convert the java args to where a native (non-jni) function 1.80 + // would expect them. To figure out where they go we convert the java 1.81 + // signature to a C signature. 1.82 + 1.83 + SignatureStream ss(method->signature()); 1.84 + for ( ; !ss.at_return_type(); ss.next()) { 1.85 + BasicType bt = ss.type(); 1.86 + in_sig_bt[i++] = bt; // Collect remaining bits of signature 1.87 + out_sig_bt[total_c_args++] = bt; 1.88 + if( bt == T_OBJECT) { 1.89 + symbolOop s = ss.as_symbol_or_null(); 1.90 + if (s == vmSymbols::java_lang_String()) { 1.91 + total_strings++; 1.92 + out_sig_bt[total_c_args-1] = T_ADDRESS; 1.93 + } else if (s == vmSymbols::java_lang_Boolean() || 1.94 + s == vmSymbols::java_lang_Character() || 1.95 + s == vmSymbols::java_lang_Byte() || 1.96 + s == vmSymbols::java_lang_Short() || 1.97 + s == vmSymbols::java_lang_Integer() || 1.98 + s == vmSymbols::java_lang_Float()) { 1.99 + out_sig_bt[total_c_args-1] = T_INT; 1.100 + } else if (s == vmSymbols::java_lang_Long() || 1.101 + s == vmSymbols::java_lang_Double()) { 1.102 + out_sig_bt[total_c_args-1] = T_LONG; 1.103 + out_sig_bt[total_c_args++] = T_VOID; 1.104 + } 1.105 + } else if ( bt == T_LONG || bt == T_DOUBLE ) { 1.106 + in_sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots 1.107 + // We convert double to long 1.108 + out_sig_bt[total_c_args-1] = T_LONG; 1.109 + out_sig_bt[total_c_args++] = T_VOID; 1.110 + } else if ( bt == T_FLOAT) { 1.111 + // We convert float to int 1.112 + out_sig_bt[total_c_args-1] = T_INT; 1.113 + } 1.114 + } 1.115 + 1.116 + assert(i==total_args_passed, "validly parsed signature"); 1.117 + 1.118 + // Now get the compiled-Java layout as input arguments 1.119 + int comp_args_on_stack; 1.120 + comp_args_on_stack = SharedRuntime::java_calling_convention( 1.121 + in_sig_bt, in_regs, total_args_passed, false); 1.122 + 1.123 + // Now figure out where the args must be stored and how much stack space 1.124 + // they require (neglecting out_preserve_stack_slots but space for storing 1.125 + // the 1st six register arguments). It's weird see int_stk_helper. 1.126 + 1.127 + int out_arg_slots; 1.128 + out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args); 1.129 + 1.130 + // Calculate the total number of stack slots we will need. 1.131 + 1.132 + // First count the abi requirement plus all of the outgoing args 1.133 + int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots; 1.134 + 1.135 + // Now space for the string(s) we must convert 1.136 + int* string_locs = NEW_RESOURCE_ARRAY(int, total_strings + 1); 1.137 + for (i = 0; i < total_strings ; i++) { 1.138 + string_locs[i] = stack_slots; 1.139 + stack_slots += max_dtrace_string_size / VMRegImpl::stack_slot_size; 1.140 + } 1.141 + 1.142 + // Plus the temps we might need to juggle register args 1.143 + // regs take two slots each 1.144 + stack_slots += (Argument::n_int_register_parameters_c + 1.145 + Argument::n_float_register_parameters_c) * 2; 1.146 + 1.147 + 1.148 + // + 4 for return address (which we own) and saved rbp, 1.149 + 1.150 + stack_slots += 4; 1.151 + 1.152 + // Ok The space we have allocated will look like: 1.153 + // 1.154 + // 1.155 + // FP-> | | 1.156 + // |---------------------| 1.157 + // | string[n] | 1.158 + // |---------------------| <- string_locs[n] 1.159 + // | string[n-1] | 1.160 + // |---------------------| <- string_locs[n-1] 1.161 + // | ... | 1.162 + // | ... | 1.163 + // |---------------------| <- string_locs[1] 1.164 + // | string[0] | 1.165 + // |---------------------| <- string_locs[0] 1.166 + // | outbound memory | 1.167 + // | based arguments | 1.168 + // | | 1.169 + // |---------------------| 1.170 + // | | 1.171 + // SP-> | out_preserved_slots | 1.172 + // 1.173 + // 1.174 + 1.175 + // Now compute actual number of stack words we need rounding to make 1.176 + // stack properly aligned. 1.177 + stack_slots = round_to(stack_slots, 4 * VMRegImpl::slots_per_word); 1.178 + 1.179 + int stack_size = stack_slots * VMRegImpl::stack_slot_size; 1.180 + 1.181 + intptr_t start = (intptr_t)__ pc(); 1.182 + 1.183 + // First thing make an ic check to see if we should even be here 1.184 + 1.185 + // We are free to use all registers as temps without saving them and 1.186 + // restoring them except rbp. rbp, is the only callee save register 1.187 + // as far as the interpreter and the compiler(s) are concerned. 1.188 + 1.189 + const Register ic_reg = rax; 1.190 + const Register receiver = rcx; 1.191 + Label hit; 1.192 + Label exception_pending; 1.193 + 1.194 + 1.195 + __ verify_oop(receiver); 1.196 + __ cmpl(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes())); 1.197 + __ jcc(Assembler::equal, hit); 1.198 + 1.199 + __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1.200 + 1.201 + // verified entry must be aligned for code patching. 1.202 + // and the first 5 bytes must be in the same cache line 1.203 + // if we align at 8 then we will be sure 5 bytes are in the same line 1.204 + __ align(8); 1.205 + 1.206 + __ bind(hit); 1.207 + 1.208 + int vep_offset = ((intptr_t)__ pc()) - start; 1.209 + 1.210 + 1.211 + // The instruction at the verified entry point must be 5 bytes or longer 1.212 + // because it can be patched on the fly by make_non_entrant. The stack bang 1.213 + // instruction fits that requirement. 1.214 + 1.215 + // Generate stack overflow check 1.216 + 1.217 + if (UseStackBanging) { 1.218 + if (stack_size <= StackShadowPages*os::vm_page_size()) { 1.219 + __ bang_stack_with_offset(StackShadowPages*os::vm_page_size()); 1.220 + } else { 1.221 + __ movl(rax, stack_size); 1.222 + __ bang_stack_size(rax, rbx); 1.223 + } 1.224 + } else { 1.225 + // need a 5 byte instruction to allow MT safe patching to non-entrant 1.226 + __ fat_nop(); 1.227 + } 1.228 + 1.229 + assert(((uintptr_t)__ pc() - start - vep_offset) >= 5, 1.230 + "valid size for make_non_entrant"); 1.231 + 1.232 + // Generate a new frame for the wrapper. 1.233 + __ enter(); 1.234 + 1.235 + // -4 because return address is already present and so is saved rbp, 1.236 + if (stack_size - 2*wordSize != 0) { 1.237 + __ subq(rsp, stack_size - 2*wordSize); 1.238 + } 1.239 + 1.240 + // Frame is now completed as far a size and linkage. 1.241 + 1.242 + int frame_complete = ((intptr_t)__ pc()) - start; 1.243 + 1.244 + int c_arg, j_arg; 1.245 + 1.246 + // State of input register args 1.247 + 1.248 + bool live[ConcreteRegisterImpl::number_of_registers]; 1.249 + 1.250 + live[j_rarg0->as_VMReg()->value()] = false; 1.251 + live[j_rarg1->as_VMReg()->value()] = false; 1.252 + live[j_rarg2->as_VMReg()->value()] = false; 1.253 + live[j_rarg3->as_VMReg()->value()] = false; 1.254 + live[j_rarg4->as_VMReg()->value()] = false; 1.255 + live[j_rarg5->as_VMReg()->value()] = false; 1.256 + 1.257 + live[j_farg0->as_VMReg()->value()] = false; 1.258 + live[j_farg1->as_VMReg()->value()] = false; 1.259 + live[j_farg2->as_VMReg()->value()] = false; 1.260 + live[j_farg3->as_VMReg()->value()] = false; 1.261 + live[j_farg4->as_VMReg()->value()] = false; 1.262 + live[j_farg5->as_VMReg()->value()] = false; 1.263 + live[j_farg6->as_VMReg()->value()] = false; 1.264 + live[j_farg7->as_VMReg()->value()] = false; 1.265 + 1.266 + 1.267 + bool rax_is_zero = false; 1.268 + 1.269 + // All args (except strings) destined for the stack are moved first 1.270 + for (j_arg = first_arg_to_pass, c_arg = 0 ; 1.271 + j_arg < total_args_passed ; j_arg++, c_arg++ ) { 1.272 + VMRegPair src = in_regs[j_arg]; 1.273 + VMRegPair dst = out_regs[c_arg]; 1.274 + 1.275 + // Get the real reg value or a dummy (rsp) 1.276 + 1.277 + int src_reg = src.first()->is_reg() ? 1.278 + src.first()->value() : 1.279 + rsp->as_VMReg()->value(); 1.280 + 1.281 + bool useless = in_sig_bt[j_arg] == T_ARRAY || 1.282 + (in_sig_bt[j_arg] == T_OBJECT && 1.283 + out_sig_bt[c_arg] != T_INT && 1.284 + out_sig_bt[c_arg] != T_ADDRESS && 1.285 + out_sig_bt[c_arg] != T_LONG); 1.286 + 1.287 + live[src_reg] = !useless; 1.288 + 1.289 + if (dst.first()->is_stack()) { 1.290 + 1.291 + // Even though a string arg in a register is still live after this loop 1.292 + // after the string conversion loop (next) it will be dead so we take 1.293 + // advantage of that now for simpler code to manage live. 1.294 + 1.295 + live[src_reg] = false; 1.296 + switch (in_sig_bt[j_arg]) { 1.297 + 1.298 + case T_ARRAY: 1.299 + case T_OBJECT: 1.300 + { 1.301 + Address stack_dst(rsp, reg2offset_out(dst.first())); 1.302 + 1.303 + if (out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) { 1.304 + // need to unbox a one-word value 1.305 + Register in_reg = rax; 1.306 + if ( src.first()->is_reg() ) { 1.307 + in_reg = src.first()->as_Register(); 1.308 + } else { 1.309 + __ movq(rax, Address(rbp, reg2offset_in(src.first()))); 1.310 + rax_is_zero = false; 1.311 + } 1.312 + Label skipUnbox; 1.313 + __ movptr(Address(rsp, reg2offset_out(dst.first())), 1.314 + (int32_t)NULL_WORD); 1.315 + __ testq(in_reg, in_reg); 1.316 + __ jcc(Assembler::zero, skipUnbox); 1.317 + 1.318 + Address src1(in_reg, box_offset); 1.319 + if ( out_sig_bt[c_arg] == T_LONG ) { 1.320 + __ movq(in_reg, src1); 1.321 + __ movq(stack_dst, in_reg); 1.322 + assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); 1.323 + ++c_arg; // skip over T_VOID to keep the loop indices in sync 1.324 + } else { 1.325 + __ movl(in_reg, src1); 1.326 + __ movl(stack_dst, in_reg); 1.327 + } 1.328 + 1.329 + __ bind(skipUnbox); 1.330 + } else if (out_sig_bt[c_arg] != T_ADDRESS) { 1.331 + // Convert the arg to NULL 1.332 + if (!rax_is_zero) { 1.333 + __ xorq(rax, rax); 1.334 + rax_is_zero = true; 1.335 + } 1.336 + __ movq(stack_dst, rax); 1.337 + } 1.338 + } 1.339 + break; 1.340 + 1.341 + case T_VOID: 1.342 + break; 1.343 + 1.344 + case T_FLOAT: 1.345 + // This does the right thing since we know it is destined for the 1.346 + // stack 1.347 + float_move(masm, src, dst); 1.348 + break; 1.349 + 1.350 + case T_DOUBLE: 1.351 + // This does the right thing since we know it is destined for the 1.352 + // stack 1.353 + double_move(masm, src, dst); 1.354 + break; 1.355 + 1.356 + case T_LONG : 1.357 + long_move(masm, src, dst); 1.358 + break; 1.359 + 1.360 + case T_ADDRESS: assert(false, "found T_ADDRESS in java args"); 1.361 + 1.362 + default: 1.363 + move32_64(masm, src, dst); 1.364 + } 1.365 + } 1.366 + 1.367 + } 1.368 + 1.369 + // If we have any strings we must store any register based arg to the stack 1.370 + // This includes any still live xmm registers too. 1.371 + 1.372 + int sid = 0; 1.373 + 1.374 + if (total_strings > 0 ) { 1.375 + for (j_arg = first_arg_to_pass, c_arg = 0 ; 1.376 + j_arg < total_args_passed ; j_arg++, c_arg++ ) { 1.377 + VMRegPair src = in_regs[j_arg]; 1.378 + VMRegPair dst = out_regs[c_arg]; 1.379 + 1.380 + if (src.first()->is_reg()) { 1.381 + Address src_tmp(rbp, fp_offset[src.first()->value()]); 1.382 + 1.383 + // string oops were left untouched by the previous loop even if the 1.384 + // eventual (converted) arg is destined for the stack so park them 1.385 + // away now (except for first) 1.386 + 1.387 + if (out_sig_bt[c_arg] == T_ADDRESS) { 1.388 + Address utf8_addr = Address( 1.389 + rsp, string_locs[sid++] * VMRegImpl::stack_slot_size); 1.390 + if (sid != 1) { 1.391 + // The first string arg won't be killed until after the utf8 1.392 + // conversion 1.393 + __ movq(utf8_addr, src.first()->as_Register()); 1.394 + } 1.395 + } else if (dst.first()->is_reg()) { 1.396 + if (in_sig_bt[j_arg] == T_FLOAT || in_sig_bt[j_arg] == T_DOUBLE) { 1.397 + 1.398 + // Convert the xmm register to an int and store it in the reserved 1.399 + // location for the eventual c register arg 1.400 + XMMRegister f = src.first()->as_XMMRegister(); 1.401 + if (in_sig_bt[j_arg] == T_FLOAT) { 1.402 + __ movflt(src_tmp, f); 1.403 + } else { 1.404 + __ movdbl(src_tmp, f); 1.405 + } 1.406 + } else { 1.407 + // If the arg is an oop type we don't support don't bother to store 1.408 + // it remember string was handled above. 1.409 + bool useless = in_sig_bt[j_arg] == T_ARRAY || 1.410 + (in_sig_bt[j_arg] == T_OBJECT && 1.411 + out_sig_bt[c_arg] != T_INT && 1.412 + out_sig_bt[c_arg] != T_LONG); 1.413 + 1.414 + if (!useless) { 1.415 + __ movq(src_tmp, src.first()->as_Register()); 1.416 + } 1.417 + } 1.418 + } 1.419 + } 1.420 + if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { 1.421 + assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); 1.422 + ++c_arg; // skip over T_VOID to keep the loop indices in sync 1.423 + } 1.424 + } 1.425 + 1.426 + // Now that the volatile registers are safe, convert all the strings 1.427 + sid = 0; 1.428 + 1.429 + for (j_arg = first_arg_to_pass, c_arg = 0 ; 1.430 + j_arg < total_args_passed ; j_arg++, c_arg++ ) { 1.431 + if (out_sig_bt[c_arg] == T_ADDRESS) { 1.432 + // It's a string 1.433 + Address utf8_addr = Address( 1.434 + rsp, string_locs[sid++] * VMRegImpl::stack_slot_size); 1.435 + // The first string we find might still be in the original java arg 1.436 + // register 1.437 + 1.438 + VMReg src = in_regs[j_arg].first(); 1.439 + 1.440 + // We will need to eventually save the final argument to the trap 1.441 + // in the von-volatile location dedicated to src. This is the offset 1.442 + // from fp we will use. 1.443 + int src_off = src->is_reg() ? 1.444 + fp_offset[src->value()] : reg2offset_in(src); 1.445 + 1.446 + // This is where the argument will eventually reside 1.447 + VMRegPair dst = out_regs[c_arg]; 1.448 + 1.449 + if (src->is_reg()) { 1.450 + if (sid == 1) { 1.451 + __ movq(c_rarg0, src->as_Register()); 1.452 + } else { 1.453 + __ movq(c_rarg0, utf8_addr); 1.454 + } 1.455 + } else { 1.456 + // arg is still in the original location 1.457 + __ movq(c_rarg0, Address(rbp, reg2offset_in(src))); 1.458 + } 1.459 + Label done, convert; 1.460 + 1.461 + // see if the oop is NULL 1.462 + __ testq(c_rarg0, c_rarg0); 1.463 + __ jcc(Assembler::notEqual, convert); 1.464 + 1.465 + if (dst.first()->is_reg()) { 1.466 + // Save the ptr to utf string in the origina src loc or the tmp 1.467 + // dedicated to it 1.468 + __ movq(Address(rbp, src_off), c_rarg0); 1.469 + } else { 1.470 + __ movq(Address(rsp, reg2offset_out(dst.first())), c_rarg0); 1.471 + } 1.472 + __ jmp(done); 1.473 + 1.474 + __ bind(convert); 1.475 + 1.476 + __ lea(c_rarg1, utf8_addr); 1.477 + if (dst.first()->is_reg()) { 1.478 + __ movq(Address(rbp, src_off), c_rarg1); 1.479 + } else { 1.480 + __ movq(Address(rsp, reg2offset_out(dst.first())), c_rarg1); 1.481 + } 1.482 + // And do the conversion 1.483 + __ call(RuntimeAddress( 1.484 + CAST_FROM_FN_PTR(address, SharedRuntime::get_utf))); 1.485 + 1.486 + __ bind(done); 1.487 + } 1.488 + if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { 1.489 + assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); 1.490 + ++c_arg; // skip over T_VOID to keep the loop indices in sync 1.491 + } 1.492 + } 1.493 + // The get_utf call killed all the c_arg registers 1.494 + live[c_rarg0->as_VMReg()->value()] = false; 1.495 + live[c_rarg1->as_VMReg()->value()] = false; 1.496 + live[c_rarg2->as_VMReg()->value()] = false; 1.497 + live[c_rarg3->as_VMReg()->value()] = false; 1.498 + live[c_rarg4->as_VMReg()->value()] = false; 1.499 + live[c_rarg5->as_VMReg()->value()] = false; 1.500 + 1.501 + live[c_farg0->as_VMReg()->value()] = false; 1.502 + live[c_farg1->as_VMReg()->value()] = false; 1.503 + live[c_farg2->as_VMReg()->value()] = false; 1.504 + live[c_farg3->as_VMReg()->value()] = false; 1.505 + live[c_farg4->as_VMReg()->value()] = false; 1.506 + live[c_farg5->as_VMReg()->value()] = false; 1.507 + live[c_farg6->as_VMReg()->value()] = false; 1.508 + live[c_farg7->as_VMReg()->value()] = false; 1.509 + } 1.510 + 1.511 + // Now we can finally move the register args to their desired locations 1.512 + 1.513 + rax_is_zero = false; 1.514 + 1.515 + for (j_arg = first_arg_to_pass, c_arg = 0 ; 1.516 + j_arg < total_args_passed ; j_arg++, c_arg++ ) { 1.517 + 1.518 + VMRegPair src = in_regs[j_arg]; 1.519 + VMRegPair dst = out_regs[c_arg]; 1.520 + 1.521 + // Only need to look for args destined for the interger registers (since we 1.522 + // convert float/double args to look like int/long outbound) 1.523 + if (dst.first()->is_reg()) { 1.524 + Register r = dst.first()->as_Register(); 1.525 + 1.526 + // Check if the java arg is unsupported and thereofre useless 1.527 + bool useless = in_sig_bt[j_arg] == T_ARRAY || 1.528 + (in_sig_bt[j_arg] == T_OBJECT && 1.529 + out_sig_bt[c_arg] != T_INT && 1.530 + out_sig_bt[c_arg] != T_ADDRESS && 1.531 + out_sig_bt[c_arg] != T_LONG); 1.532 + 1.533 + 1.534 + // If we're going to kill an existing arg save it first 1.535 + if (live[dst.first()->value()]) { 1.536 + // you can't kill yourself 1.537 + if (src.first() != dst.first()) { 1.538 + __ movq(Address(rbp, fp_offset[dst.first()->value()]), r); 1.539 + } 1.540 + } 1.541 + if (src.first()->is_reg()) { 1.542 + if (live[src.first()->value()] ) { 1.543 + if (in_sig_bt[j_arg] == T_FLOAT) { 1.544 + __ movdl(r, src.first()->as_XMMRegister()); 1.545 + } else if (in_sig_bt[j_arg] == T_DOUBLE) { 1.546 + __ movdq(r, src.first()->as_XMMRegister()); 1.547 + } else if (r != src.first()->as_Register()) { 1.548 + if (!useless) { 1.549 + __ movq(r, src.first()->as_Register()); 1.550 + } 1.551 + } 1.552 + } else { 1.553 + // If the arg is an oop type we don't support don't bother to store 1.554 + // it 1.555 + if (!useless) { 1.556 + if (in_sig_bt[j_arg] == T_DOUBLE || 1.557 + in_sig_bt[j_arg] == T_LONG || 1.558 + in_sig_bt[j_arg] == T_OBJECT ) { 1.559 + __ movq(r, Address(rbp, fp_offset[src.first()->value()])); 1.560 + } else { 1.561 + __ movl(r, Address(rbp, fp_offset[src.first()->value()])); 1.562 + } 1.563 + } 1.564 + } 1.565 + live[src.first()->value()] = false; 1.566 + } else if (!useless) { 1.567 + // full sized move even for int should be ok 1.568 + __ movq(r, Address(rbp, reg2offset_in(src.first()))); 1.569 + } 1.570 + 1.571 + // At this point r has the original java arg in the final location 1.572 + // (assuming it wasn't useless). If the java arg was an oop 1.573 + // we have a bit more to do 1.574 + 1.575 + if (in_sig_bt[j_arg] == T_ARRAY || in_sig_bt[j_arg] == T_OBJECT ) { 1.576 + if (out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) { 1.577 + // need to unbox a one-word value 1.578 + Label skip; 1.579 + __ testq(r, r); 1.580 + __ jcc(Assembler::equal, skip); 1.581 + Address src1(r, box_offset); 1.582 + if ( out_sig_bt[c_arg] == T_LONG ) { 1.583 + __ movq(r, src1); 1.584 + } else { 1.585 + __ movl(r, src1); 1.586 + } 1.587 + __ bind(skip); 1.588 + 1.589 + } else if (out_sig_bt[c_arg] != T_ADDRESS) { 1.590 + // Convert the arg to NULL 1.591 + __ xorq(r, r); 1.592 + } 1.593 + } 1.594 + 1.595 + // dst can longer be holding an input value 1.596 + live[dst.first()->value()] = false; 1.597 + } 1.598 + if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { 1.599 + assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); 1.600 + ++c_arg; // skip over T_VOID to keep the loop indices in sync 1.601 + } 1.602 + } 1.603 + 1.604 + 1.605 + // Ok now we are done. Need to place the nop that dtrace wants in order to 1.606 + // patch in the trap 1.607 + int patch_offset = ((intptr_t)__ pc()) - start; 1.608 + 1.609 + __ nop(); 1.610 + 1.611 + 1.612 + // Return 1.613 + 1.614 + __ leave(); 1.615 + __ ret(0); 1.616 + 1.617 + __ flush(); 1.618 + 1.619 + nmethod *nm = nmethod::new_dtrace_nmethod( 1.620 + method, masm->code(), vep_offset, patch_offset, frame_complete, 1.621 + stack_slots / VMRegImpl::slots_per_word); 1.622 + return nm; 1.623 + 1.624 +} 1.625 + 1.626 +#endif // HAVE_DTRACE_H 1.627 + 1.628 // this function returns the adjust size (in number of words) to a c2i adapter 1.629 // activation for use during deoptimization 1.630 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) {