< prev index next >

src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp

Print this page


 325   // ordering of C2's stack overflow check / rsp decrement and allows
 326   // the SharedRuntime stack overflow handling to be consistent
 327   // between the two compilers.
 328   generate_stack_overflow_check(bang_size_in_bytes);
 329 
 330   if (!needs_stack_repair && verified_value_entry_label != NULL) {
 331     bind(*verified_value_entry_label);
 332   }
 333   push(rbp);
 334   if (PreserveFramePointer) {
 335     mov(rbp, rsp);
 336   }
 337 #ifdef TIERED
 338   // c2 leaves fpu stack dirty. Clean it on entry
 339   if (UseSSE < 2 ) {
 340     empty_FPU_stack();
 341   }
 342 #endif // TIERED
 343   decrement(rsp, frame_size_in_bytes); // does not emit code for frame_size == 0
 344   if (needs_stack_repair) {
 345     movptr(Address(rsp, frame_size_in_bytes - wordSize), frame_size_in_bytes
 346            + wordSize     // skip over pushed rbp
 347            + wordSize);   // skip over RA pushed by caller

 348     if (verified_value_entry_label != NULL) {
 349       bind(*verified_value_entry_label);
 350     }
 351   }
 352 
 353   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
 354   bs->nmethod_entry_barrier(this);
 355 }
 356 
 357 
 358 void C1_MacroAssembler::remove_frame(int frame_size_in_bytes, bool needs_stack_repair) {
 359   if (!needs_stack_repair) {
 360     increment(rsp, frame_size_in_bytes);  // Does not emit code for frame_size == 0
 361     pop(rbp);
 362   } else {
 363     movq(r13, Address(rsp, frame_size_in_bytes + wordSize)); // return address
 364     movq(rbp, Address(rsp, frame_size_in_bytes));
 365     addq(rsp, Address(rsp, frame_size_in_bytes - wordSize)); // now we are back to caller frame, without the outgoing returned address
 366     push(r13);                  // restore the returned address, as pushed by caller
 367   }


 381   }
 382   if (C1Breakpoint)int3();
 383   // build frame
 384   verify_FPU(0, "method_entry");
 385 }
 386 
 387 int C1_MacroAssembler::scalarized_entry(const CompiledEntrySignature *ces, int frame_size_in_bytes, int bang_size_in_bytes, Label& verified_value_entry_label, bool is_value_ro_entry) {
 388   if (C1Breakpoint || VerifyFPU || !UseStackBanging) {
 389     // Verified Entry first instruction should be 5 bytes long for correct
 390     // patching by patch_verified_entry().
 391     //
 392     // C1Breakpoint and VerifyFPU have one byte first instruction.
 393     // Also first instruction will be one byte "push(rbp)" if stack banging
 394     // code is not generated (see build_frame() above).
 395     // For all these cases generate long instruction first.
 396     fat_nop();
 397   }
 398   if (C1Breakpoint)int3();
 399   verify_FPU(0, "method_entry");
 400 
 401   // FIXME -- call runtime only if we cannot in-line allocate all the incoming value args.
 402   push(rbp); // Create a temp frame so we can call into runtime // FIXME: need to be able to handle GC during the call
























 403   if (PreserveFramePointer) {
 404     mov(rbp, rsp);
 405   }
 406   subptr(rsp, frame_size_in_bytes);









 407   movptr(rbx, (intptr_t)(ces->method()));
 408   if (is_value_ro_entry) {
 409     call(RuntimeAddress(Runtime1::entry_for(Runtime1::buffer_value_args_no_receiver_id)));
 410   } else {
 411     call(RuntimeAddress(Runtime1::entry_for(Runtime1::buffer_value_args_id)));
 412   }
 413   int rt_call_offset = offset();
 414 

 415   addptr(rsp, frame_size_in_bytes);
 416   pop(rbp);
 417 
 418   assert(ValueTypePassFieldsAsArgs, "sanity");
 419 
 420   GrowableArray<SigEntry>* sig   = &ces->sig();
 421   GrowableArray<SigEntry>* sig_cc = is_value_ro_entry ? &ces->sig_cc_ro() : &ces->sig_cc();
 422   VMRegPair* regs      = ces->regs();
 423   VMRegPair* regs_cc   = is_value_ro_entry ? ces->regs_cc_ro() : ces->regs_cc();
 424   int args_on_stack    = ces->args_on_stack();
 425   int args_on_stack_cc = is_value_ro_entry ? ces->args_on_stack_cc_ro() : ces->args_on_stack_cc();
 426 
 427   assert(sig->length() <= sig_cc->length(), "Zero-sized value class not allowed!");
 428   BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sig_cc->length());
 429   int args_passed = sig->length();
 430   int args_passed_cc = SigEntry::fill_sig_bt(sig_cc, sig_bt);
 431 
 432   int extra_stack_offset = wordSize; // tos is return address.
 433   int sp_inc = shuffle_value_args(true, is_value_ro_entry, extra_stack_offset, sig_bt, sig_cc,
 434                                   args_passed_cc, args_on_stack_cc, regs_cc, // from
 435                                   args_passed, args_on_stack, regs);         // to

 436 
 437   if (sp_inc != 0) {


 438     assert(sp_inc > 0, "stack should not shrink");
 439     generate_stack_overflow_check(bang_size_in_bytes);
 440     push(rbp);
 441     if (PreserveFramePointer) {
 442       mov(rbp, rsp);
 443     }
 444 #ifdef TIERED
 445     // c2 leaves fpu stack dirty. Clean it on entry
 446     if (UseSSE < 2 ) {
 447       empty_FPU_stack();
 448     }
 449 #endif // TIERED
 450     decrement(rsp, frame_size_in_bytes);
 451     movptr(Address(rsp, frame_size_in_bytes - wordSize), frame_size_in_bytes +
 452            + wordSize  // pushed rbp
 453            + wordSize  // returned address pushed by the stack extension code
 454            + sp_inc);  // stack extension
 455   }
 456 
 457   jmp(verified_value_entry_label);
 458   return rt_call_offset;
 459 }
 460 
 461 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
 462   // rbp, + 0: link
 463   //     + 1: return address
 464   //     + 2: argument with offset 0
 465   //     + 3: argument with offset 1
 466   //     + 4: ...
 467 
 468   movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord));
 469 }
 470 
 471 #ifndef PRODUCT
 472 
 473 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
 474   if (!VerifyOops) return;




 325   // ordering of C2's stack overflow check / rsp decrement and allows
 326   // the SharedRuntime stack overflow handling to be consistent
 327   // between the two compilers.
 328   generate_stack_overflow_check(bang_size_in_bytes);
 329 
 330   if (!needs_stack_repair && verified_value_entry_label != NULL) {
 331     bind(*verified_value_entry_label);
 332   }
 333   push(rbp);
 334   if (PreserveFramePointer) {
 335     mov(rbp, rsp);
 336   }
 337 #ifdef TIERED
 338   // c2 leaves fpu stack dirty. Clean it on entry
 339   if (UseSSE < 2 ) {
 340     empty_FPU_stack();
 341   }
 342 #endif // TIERED
 343   decrement(rsp, frame_size_in_bytes); // does not emit code for frame_size == 0
 344   if (needs_stack_repair) {
 345     int real_frame_size =  frame_size_in_bytes
 346            + wordSize     // skip over pushed rbp
 347            + wordSize;   // skip over RA pushed by caller
 348     movptr(Address(rsp, frame_size_in_bytes - wordSize), real_frame_size);
 349     if (verified_value_entry_label != NULL) {
 350       bind(*verified_value_entry_label);
 351     }
 352   }
 353 
 354   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
 355   bs->nmethod_entry_barrier(this);
 356 }
 357 
 358 
 359 void C1_MacroAssembler::remove_frame(int frame_size_in_bytes, bool needs_stack_repair) {
 360   if (!needs_stack_repair) {
 361     increment(rsp, frame_size_in_bytes);  // Does not emit code for frame_size == 0
 362     pop(rbp);
 363   } else {
 364     movq(r13, Address(rsp, frame_size_in_bytes + wordSize)); // return address
 365     movq(rbp, Address(rsp, frame_size_in_bytes));
 366     addq(rsp, Address(rsp, frame_size_in_bytes - wordSize)); // now we are back to caller frame, without the outgoing returned address
 367     push(r13);                  // restore the returned address, as pushed by caller
 368   }


 382   }
 383   if (C1Breakpoint)int3();
 384   // build frame
 385   verify_FPU(0, "method_entry");
 386 }
 387 
 388 int C1_MacroAssembler::scalarized_entry(const CompiledEntrySignature *ces, int frame_size_in_bytes, int bang_size_in_bytes, Label& verified_value_entry_label, bool is_value_ro_entry) {
 389   if (C1Breakpoint || VerifyFPU || !UseStackBanging) {
 390     // Verified Entry first instruction should be 5 bytes long for correct
 391     // patching by patch_verified_entry().
 392     //
 393     // C1Breakpoint and VerifyFPU have one byte first instruction.
 394     // Also first instruction will be one byte "push(rbp)" if stack banging
 395     // code is not generated (see build_frame() above).
 396     // For all these cases generate long instruction first.
 397     fat_nop();
 398   }
 399   if (C1Breakpoint)int3();
 400   verify_FPU(0, "method_entry");
 401 
 402   assert(ValueTypePassFieldsAsArgs, "sanity");
 403   GrowableArray<SigEntry>* sig   = &ces->sig();
 404   GrowableArray<SigEntry>* sig_cc = is_value_ro_entry ? &ces->sig_cc_ro() : &ces->sig_cc();
 405   VMRegPair* regs      = ces->regs();
 406   VMRegPair* regs_cc   = is_value_ro_entry ? ces->regs_cc_ro() : ces->regs_cc();
 407   int args_on_stack    = ces->args_on_stack();
 408   int args_on_stack_cc = is_value_ro_entry ? ces->args_on_stack_cc_ro() : ces->args_on_stack_cc();
 409 
 410   assert(sig->length() <= sig_cc->length(), "Zero-sized value class not allowed!");
 411   BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sig_cc->length());
 412   int args_passed = sig->length();
 413   int args_passed_cc = SigEntry::fill_sig_bt(sig_cc, sig_bt);
 414 
 415   int extra_stack_offset = wordSize; // tos is return address.
 416 
 417   // Create a temp frame so we can call into runtime. It must be properly set up to accomodate GC.
 418   int sp_inc = (args_on_stack - args_on_stack_cc) * VMRegImpl::stack_slot_size;
 419   if (sp_inc > 0) {
 420     pop(r13);
 421     sp_inc = align_up(sp_inc, StackAlignmentInBytes);
 422     subptr(rsp, sp_inc);
 423     push(r13);
 424   } else {
 425     sp_inc = 0;
 426   }
 427   push(rbp);
 428   if (PreserveFramePointer) {
 429     mov(rbp, rsp);
 430   }
 431   subptr(rsp, frame_size_in_bytes);
 432   if (sp_inc > 0) {
 433     int real_frame_size = frame_size_in_bytes +
 434            + wordSize  // pushed rbp
 435            + wordSize  // returned address pushed by the stack extension code
 436            + sp_inc;  // stack extension
 437     movptr(Address(rsp, frame_size_in_bytes - wordSize), real_frame_size);
 438   }
 439 
 440   // FIXME -- call runtime only if we cannot in-line allocate all the incoming value args.
 441   movptr(rbx, (intptr_t)(ces->method()));
 442   if (is_value_ro_entry) {
 443     call(RuntimeAddress(Runtime1::entry_for(Runtime1::buffer_value_args_no_receiver_id)));
 444   } else {
 445     call(RuntimeAddress(Runtime1::entry_for(Runtime1::buffer_value_args_id)));
 446   }
 447   int rt_call_offset = offset();
 448 
 449   // Remove the temp frame
 450   addptr(rsp, frame_size_in_bytes);
 451   pop(rbp);
 452 
 453   int n = shuffle_value_args(true, is_value_ro_entry, extra_stack_offset, sig_bt, sig_cc,















 454                              args_passed_cc, args_on_stack_cc, regs_cc, // from
 455                              args_passed, args_on_stack, regs);         // to
 456   assert(sp_inc == n, "must be");
 457 
 458   if (sp_inc != 0) {
 459     // Do the stack banging here, and skip over the stack repair code in the
 460     // verified_value_entry (which has a different real_frame_size).
 461     assert(sp_inc > 0, "stack should not shrink");
 462     generate_stack_overflow_check(bang_size_in_bytes);
 463     push(rbp);
 464     if (PreserveFramePointer) {
 465       mov(rbp, rsp);
 466     }
 467 #ifdef TIERED
 468     // c2 leaves fpu stack dirty. Clean it on entry
 469     if (UseSSE < 2 ) {
 470       empty_FPU_stack();
 471     }
 472 #endif // TIERED
 473     decrement(rsp, frame_size_in_bytes);




 474   }
 475 
 476   jmp(verified_value_entry_label);
 477   return rt_call_offset;
 478 }
 479 
 480 void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
 481   // rbp, + 0: link
 482   //     + 1: return address
 483   //     + 2: argument with offset 0
 484   //     + 3: argument with offset 1
 485   //     + 4: ...
 486 
 487   movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord));
 488 }
 489 
 490 #ifndef PRODUCT
 491 
 492 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
 493   if (!VerifyOops) return;


< prev index next >