< prev index next >

src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp

Print this page




 340 
 341 // Generates a register specific stub for calling
 342 // ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
 343 // ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
 344 //
 345 // The raddr register serves as both input and output for this stub. When the stub is
 346 // called the raddr register contains the object field address (oop*) where the bad oop
 347 // was loaded from, which caused the slow path to be taken. On return from the stub the
 348 // raddr register contains the good/healed oop returned from
 349 // ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
 350 // ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
 351 static address generate_load_barrier_stub(StubCodeGenerator* cgen, Register raddr, DecoratorSet decorators) {
 352   // Don't generate stub for invalid registers
 353   if (raddr == rsp || raddr == r12 || raddr == r15) {
 354     return NULL;
 355   }
 356 
 357   // Create stub name
 358   char name[64];
 359   const bool weak = (decorators & ON_WEAK_OOP_REF) != 0;
 360   os::snprintf(name, sizeof(name), "load_barrier%s_stub_%s", weak ? "_weak" : "", raddr->name());
 361 
 362   __ align(CodeEntryAlignment);
 363   StubCodeMark mark(cgen, "StubRoutines", os::strdup(name, mtCode));
 364   address start = __ pc();
 365 
 366   // Save live registers
 367   if (raddr != rax) {
 368     __ push(rax);
 369   }
 370   if (raddr != rcx) {
 371     __ push(rcx);
 372   }
 373   if (raddr != rdx) {
 374     __ push(rdx);
 375   }
 376   if (raddr != rsi) {
 377     __ push(rsi);
 378   }
 379   if (raddr != rdi) {
 380     __ push(rdi);
 381   }
 382   if (raddr != r8) {
 383     __ push(r8);
 384   }
 385   if (raddr != r9) {
 386     __ push(r9);
 387   }
 388   if (raddr != r10) {
 389     __ push(r10);
 390   }
 391   if (raddr != r11) {
 392     __ push(r11);
 393   }
 394 
 395   // Setup arguments
 396   if (c_rarg1 != raddr) {
 397     __ movq(c_rarg1, raddr);
 398   }
 399   __ movq(c_rarg0, Address(raddr, 0));
 400 
 401   // Call barrier function
 402   __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), c_rarg0, c_rarg1);
 403 
 404   // Move result returned in rax to raddr, if needed
 405   if (raddr != rax) {
 406     __ movq(raddr, rax);
 407   }
 408 
 409   // Restore saved registers
 410   if (raddr != r11) {
 411     __ pop(r11);
 412   }
 413   if (raddr != r10) {
 414     __ pop(r10);
 415   }
 416   if (raddr != r9) {


 425   if (raddr != rsi) {
 426     __ pop(rsi);
 427   }
 428   if (raddr != rdx) {
 429     __ pop(rdx);
 430   }
 431   if (raddr != rcx) {
 432     __ pop(rcx);
 433   }
 434   if (raddr != rax) {
 435     __ pop(rax);
 436   }
 437 
 438   __ ret(0);
 439 
 440   return start;
 441 }
 442 
 443 #undef __
 444 
 445 void ZBarrierSetAssembler::barrier_stubs_init() {
 446   // Load barrier stubs
 447   int stub_code_size = 256 * 16; // Rough estimate of code size
 448 
 449   ResourceMark rm;
 450   BufferBlob* bb = BufferBlob::create("zgc_load_barrier_stubs", stub_code_size);
 451   CodeBuffer buf(bb);
 452   StubCodeGenerator cgen(&buf);
 453 
 454   Register rr = as_Register(0);
 455   for (int i = 0; i < RegisterImpl::number_of_registers; i++) {
 456     _load_barrier_slow_stub[i] = generate_load_barrier_stub(&cgen, rr, ON_STRONG_OOP_REF);
 457     _load_barrier_weak_slow_stub[i] = generate_load_barrier_stub(&cgen, rr, ON_WEAK_OOP_REF);
 458     rr = rr->successor();
 459   }





 460 }


 340 
 341 // Generates a register specific stub for calling
 342 // ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
 343 // ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
 344 //
 345 // The raddr register serves as both input and output for this stub. When the stub is
 346 // called the raddr register contains the object field address (oop*) where the bad oop
 347 // was loaded from, which caused the slow path to be taken. On return from the stub the
 348 // raddr register contains the good/healed oop returned from
 349 // ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
 350 // ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
 351 static address generate_load_barrier_stub(StubCodeGenerator* cgen, Register raddr, DecoratorSet decorators) {
 352   // Don't generate stub for invalid registers
 353   if (raddr == rsp || raddr == r12 || raddr == r15) {
 354     return NULL;
 355   }
 356 
 357   // Create stub name
 358   char name[64];
 359   const bool weak = (decorators & ON_WEAK_OOP_REF) != 0;
 360   os::snprintf(name, sizeof(name), "zgc_load_barrier%s_stub_%s", weak ? "_weak" : "", raddr->name());
 361 
 362   __ align(CodeEntryAlignment);
 363   StubCodeMark mark(cgen, "StubRoutines", os::strdup(name, mtCode));
 364   address start = __ pc();
 365 
 366   // Save live registers
 367   if (raddr != rax) {
 368     __ push(rax);
 369   }
 370   if (raddr != rcx) {
 371     __ push(rcx);
 372   }
 373   if (raddr != rdx) {
 374     __ push(rdx);
 375   }
 376   if (raddr != rsi) {
 377     __ push(rsi);
 378   }
 379   if (raddr != rdi) {
 380     __ push(rdi);
 381   }
 382   if (raddr != r8) {
 383     __ push(r8);
 384   }
 385   if (raddr != r9) {
 386     __ push(r9);
 387   }
 388   if (raddr != r10) {
 389     __ push(r10);
 390   }
 391   if (raddr != r11) {
 392     __ push(r11);
 393   }
 394 
 395   // Setup arguments
 396   if (raddr != c_rarg1) {
 397     __ movq(c_rarg1, raddr);
 398   }
 399   __ movq(c_rarg0, Address(raddr, 0));
 400 
 401   // Call barrier function
 402   __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), c_rarg0, c_rarg1);
 403 
 404   // Move result returned in rax to raddr, if needed
 405   if (raddr != rax) {
 406     __ movq(raddr, rax);
 407   }
 408 
 409   // Restore saved registers
 410   if (raddr != r11) {
 411     __ pop(r11);
 412   }
 413   if (raddr != r10) {
 414     __ pop(r10);
 415   }
 416   if (raddr != r9) {


 425   if (raddr != rsi) {
 426     __ pop(rsi);
 427   }
 428   if (raddr != rdx) {
 429     __ pop(rdx);
 430   }
 431   if (raddr != rcx) {
 432     __ pop(rcx);
 433   }
 434   if (raddr != rax) {
 435     __ pop(rax);
 436   }
 437 
 438   __ ret(0);
 439 
 440   return start;
 441 }
 442 
 443 #undef __
 444 
 445 static void barrier_stubs_init_inner(const char* label, const DecoratorSet decorators, address* stub) {
 446   const int nregs = RegisterImpl::number_of_registers;
 447   const int code_size = nregs * 128; // Rough estimate of code size
 448 
 449   ResourceMark rm;
 450 
 451   CodeBuffer buf(BufferBlob::create(label, code_size));
 452   StubCodeGenerator cgen(&buf);
 453 
 454   for (int i = 0; i < nregs; i++) {
 455     const Register reg = as_Register(i);
 456     stub[i] = generate_load_barrier_stub(&cgen, reg, decorators);


 457   }
 458 }
 459 
 460 void ZBarrierSetAssembler::barrier_stubs_init() {
 461   barrier_stubs_init_inner("zgc_load_barrier_stubs", ON_STRONG_OOP_REF, _load_barrier_slow_stub);
 462   barrier_stubs_init_inner("zgc_load_barrier_weak_stubs", ON_WEAK_OOP_REF, _load_barrier_weak_slow_stub);
 463 }
< prev index next >