src/cpu/x86/vm/macroAssembler_x86.cpp

Print this page
rev 4202 : 8008555: Debugging code in compiled method sometimes leaks memory
Summary: support for strings that have same life-time as code that uses them.
Reviewed-by:


4245     movl(dst, src);
4246     bind(L);
4247   }
4248 }
4249 
4250 void MacroAssembler::cmov32(Condition cc, Register dst, Register src) {
4251   if (VM_Version::supports_cmov()) {
4252     cmovl(cc, dst, src);
4253   } else {
4254     Label L;
4255     jccb(negate_condition(cc), L);
4256     movl(dst, src);
4257     bind(L);
4258   }
4259 }
4260 
4261 void MacroAssembler::verify_oop(Register reg, const char* s) {
4262   if (!VerifyOops) return;
4263 
4264   // Pass register number to verify_oop_subroutine
4265   char* b = new char[strlen(s) + 50];
4266   sprintf(b, "verify_oop: %s: %s", reg->name(), s);





4267   BLOCK_COMMENT("verify_oop {");
4268 #ifdef _LP64
4269   push(rscratch1);                    // save r10, trashed by movptr()
4270 #endif
4271   push(rax);                          // save rax,
4272   push(reg);                          // pass register argument
4273   ExternalAddress buffer((address) b);
4274   // avoid using pushptr, as it modifies scratch registers
4275   // and our contract is not to modify anything
4276   movptr(rax, buffer.addr());
4277   push(rax);
4278   // call indirectly to solve generation ordering problem
4279   movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
4280   call(rax);
4281   // Caller pops the arguments (oop, message) and restores rax, r10
4282   BLOCK_COMMENT("} verify_oop");
4283 }
4284 
4285 
4286 RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr,
4287                                                       Register tmp,
4288                                                       int offset) {
4289   intptr_t value = *delayed_value_addr;
4290   if (value != 0)
4291     return RegisterOrConstant(value + offset);
4292 
4293   // load indirectly to solve generation ordering problem
4294   movptr(tmp, ExternalAddress((address) delayed_value_addr));
4295 
4296 #ifdef ASSERT
4297   { Label L;
4298     testptr(tmp, tmp);
4299     if (WizardMode) {







4300       jcc(Assembler::notZero, L);
4301       char* buf = new char[40];
4302       sprintf(buf, "DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]);
4303       STOP(buf);
4304     } else {
4305       jccb(Assembler::notZero, L);
4306       hlt();
4307     }
4308     bind(L);
4309   }
4310 #endif
4311 
4312   if (offset != 0)
4313     addptr(tmp, offset);
4314 
4315   return RegisterOrConstant(tmp);
4316 }
4317 
4318 
4319 Address MacroAssembler::argument_address(RegisterOrConstant arg_slot,
4320                                          int extra_slot_offset) {
4321   // cf. TemplateTable::prepare_invoke(), if (load_receiver).
4322   int stackElementSize = Interpreter::stackElementSize;


4326   assert(offset1 - offset == stackElementSize, "correct arithmetic");
4327 #endif
4328   Register             scale_reg    = noreg;
4329   Address::ScaleFactor scale_factor = Address::no_scale;
4330   if (arg_slot.is_constant()) {
4331     offset += arg_slot.as_constant() * stackElementSize;
4332   } else {
4333     scale_reg    = arg_slot.as_register();
4334     scale_factor = Address::times(stackElementSize);
4335   }
4336   offset += wordSize;           // return PC is on stack
4337   return Address(rsp, scale_reg, scale_factor, offset);
4338 }
4339 
4340 
4341 void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
4342   if (!VerifyOops) return;
4343 
4344   // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord);
4345   // Pass register number to verify_oop_subroutine
4346   char* b = new char[strlen(s) + 50];
4347   sprintf(b, "verify_oop_addr: %s", s);
4348 




4349 #ifdef _LP64
4350   push(rscratch1);                    // save r10, trashed by movptr()
4351 #endif
4352   push(rax);                          // save rax,
4353   // addr may contain rsp so we will have to adjust it based on the push
4354   // we just did (and on 64 bit we do two pushes)
4355   // NOTE: 64bit seemed to have had a bug in that it did movq(addr, rax); which
4356   // stores rax into addr which is backwards of what was intended.
4357   if (addr.uses(rsp)) {
4358     lea(rax, addr);
4359     pushptr(Address(rax, LP64_ONLY(2 *) BytesPerWord));
4360   } else {
4361     pushptr(addr);
4362   }
4363 
4364   ExternalAddress buffer((address) b);
4365   // pass msg argument
4366   // avoid using pushptr, as it modifies scratch registers
4367   // and our contract is not to modify anything
4368   movptr(rax, buffer.addr());




4245     movl(dst, src);
4246     bind(L);
4247   }
4248 }
4249 
4250 void MacroAssembler::cmov32(Condition cc, Register dst, Register src) {
4251   if (VM_Version::supports_cmov()) {
4252     cmovl(cc, dst, src);
4253   } else {
4254     Label L;
4255     jccb(negate_condition(cc), L);
4256     movl(dst, src);
4257     bind(L);
4258   }
4259 }
4260 
4261 void MacroAssembler::verify_oop(Register reg, const char* s) {
4262   if (!VerifyOops) return;
4263 
4264   // Pass register number to verify_oop_subroutine
4265   const char* b = NULL;
4266   {
4267     ResourceMark rm;
4268     stringStream ss;
4269     ss.print("verify_oop: %s: %s", reg->name(), s);
4270     b = code_string(ss.as_string());
4271   }
4272   BLOCK_COMMENT("verify_oop {");
4273 #ifdef _LP64
4274   push(rscratch1);                    // save r10, trashed by movptr()
4275 #endif
4276   push(rax);                          // save rax,
4277   push(reg);                          // pass register argument
4278   ExternalAddress buffer((address) b);
4279   // avoid using pushptr, as it modifies scratch registers
4280   // and our contract is not to modify anything
4281   movptr(rax, buffer.addr());
4282   push(rax);
4283   // call indirectly to solve generation ordering problem
4284   movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
4285   call(rax);
4286   // Caller pops the arguments (oop, message) and restores rax, r10
4287   BLOCK_COMMENT("} verify_oop");
4288 }
4289 
4290 
4291 RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr,
4292                                                       Register tmp,
4293                                                       int offset) {
4294   intptr_t value = *delayed_value_addr;
4295   if (value != 0)
4296     return RegisterOrConstant(value + offset);
4297 
4298   // load indirectly to solve generation ordering problem
4299   movptr(tmp, ExternalAddress((address) delayed_value_addr));
4300 
4301 #ifdef ASSERT
4302   { Label L;
4303     testptr(tmp, tmp);
4304     if (WizardMode) {
4305       const char* buf = NULL;
4306       {
4307         ResourceMark rm;
4308         stringStream ss;
4309         ss.print("DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]);
4310         buf = code_string(ss.as_string());
4311       }
4312       jcc(Assembler::notZero, L);


4313       STOP(buf);
4314     } else {
4315       jccb(Assembler::notZero, L);
4316       hlt();
4317     }
4318     bind(L);
4319   }
4320 #endif
4321 
4322   if (offset != 0)
4323     addptr(tmp, offset);
4324 
4325   return RegisterOrConstant(tmp);
4326 }
4327 
4328 
4329 Address MacroAssembler::argument_address(RegisterOrConstant arg_slot,
4330                                          int extra_slot_offset) {
4331   // cf. TemplateTable::prepare_invoke(), if (load_receiver).
4332   int stackElementSize = Interpreter::stackElementSize;


4336   assert(offset1 - offset == stackElementSize, "correct arithmetic");
4337 #endif
4338   Register             scale_reg    = noreg;
4339   Address::ScaleFactor scale_factor = Address::no_scale;
4340   if (arg_slot.is_constant()) {
4341     offset += arg_slot.as_constant() * stackElementSize;
4342   } else {
4343     scale_reg    = arg_slot.as_register();
4344     scale_factor = Address::times(stackElementSize);
4345   }
4346   offset += wordSize;           // return PC is on stack
4347   return Address(rsp, scale_reg, scale_factor, offset);
4348 }
4349 
4350 
4351 void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
4352   if (!VerifyOops) return;
4353 
4354   // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord);
4355   // Pass register number to verify_oop_subroutine
4356   const char* b = NULL;
4357   {
4358     ResourceMark rm;
4359     stringStream ss;
4360     ss.print("verify_oop_addr: %s", s);
4361     b = code_string(ss.as_string());
4362   }
4363 #ifdef _LP64
4364   push(rscratch1);                    // save r10, trashed by movptr()
4365 #endif
4366   push(rax);                          // save rax,
4367   // addr may contain rsp so we will have to adjust it based on the push
4368   // we just did (and on 64 bit we do two pushes)
4369   // NOTE: 64bit seemed to have had a bug in that it did movq(addr, rax); which
4370   // stores rax into addr which is backwards of what was intended.
4371   if (addr.uses(rsp)) {
4372     lea(rax, addr);
4373     pushptr(Address(rax, LP64_ONLY(2 *) BytesPerWord));
4374   } else {
4375     pushptr(addr);
4376   }
4377 
4378   ExternalAddress buffer((address) b);
4379   // pass msg argument
4380   // avoid using pushptr, as it modifies scratch registers
4381   // and our contract is not to modify anything
4382   movptr(rax, buffer.addr());