예제 #1
0
// Release the CompiledICHolder* associated with this call site is there is one.
void CompiledIC::cleanup_call_site(virtual_call_Relocation* call_site) {
  // This call site might have become stale so inspect it carefully.
  NativeCall* call = nativeCall_at(call_site->addr());
  if (is_icholder_entry(call->destination())) {
    NativeMovConstReg* value = nativeMovConstReg_at(call_site->cached_value());
    InlineCacheBuffer::queue_for_release((CompiledICHolder*)value->data());
  }
}
예제 #2
0
address Relocation::pd_call_destination(address orig_addr) {
  address   inst_addr = addr();

  if (NativeFarCall::is_far_call_at(inst_addr)) {
    if (!ShortenBranches) {
      if (MacroAssembler::is_call_far_pcrelative(inst_addr)) {
        address a1 = MacroAssembler::get_target_addr_pcrel(orig_addr+MacroAssembler::nop_size());
#ifdef ASSERT
        address a2 = MacroAssembler::get_target_addr_pcrel(inst_addr+MacroAssembler::nop_size());
        address a3 = nativeFarCall_at(orig_addr)->destination();
        address a4 = nativeFarCall_at(inst_addr)->destination();
        if ((a1 != a3) || (a2 != a4)) {
          unsigned int range = 128;
          Assembler::dump_code_range(tty, inst_addr, range, "pc-relative call w/o ShortenBranches?");
          Assembler::dump_code_range(tty, orig_addr, range, "pc-relative call w/o ShortenBranches?");
          assert(false, "pc-relative call w/o ShortenBranches?");
        }
#endif
        return a1;
      }
      return (address)(-1);
    }
    NativeFarCall* call;
    if (orig_addr == NULL) {
      call = nativeFarCall_at(inst_addr);
    } else {
      // must access location (in CP) where destination is stored in unmoved code, because load from CP is pc-relative
      call = nativeFarCall_at(orig_addr);
    }
    return call->destination();
  }

  if (NativeCall::is_call_at(inst_addr)) {
    NativeCall* call = nativeCall_at(inst_addr);
    if (call->is_pcrelative()) {
      intptr_t off = inst_addr - orig_addr;
      return (address) (call->destination()-off);
    }
  }

  return (address) nativeMovConstReg_at(inst_addr)->data();
}
예제 #3
0
address Relocation::pd_call_destination(address orig_addr) {
  intptr_t adj = 0;
  if (orig_addr != NULL) {
    // We just moved this call instruction from orig_addr to addr().
    // This means its target will appear to have grown by addr() - orig_addr.
    adj = -( addr() - orig_addr );
  }
  if (NativeCall::is_call_at(addr())) {
    NativeCall* call = nativeCall_at(addr());
    return call->destination() + adj;
  }
  if (NativeFarCall::is_call_at(addr())) {
    NativeFarCall* call = nativeFarCall_at(addr());
    return call->destination() + adj;
  }
  // Special case:  Patchable branch local to the code cache.
  // This will break badly if the code cache grows larger than a few Mb.
  NativeGeneralJump* br = nativeGeneralJump_at(addr());
  return br->jump_destination() + adj;
}
예제 #4
0
// Code for unit testing implementation of NativeCall class
void NativeCall::test() {
#ifdef ASSERT
  ResourceMark rm;
  CodeBuffer cb("test", 100, 100);
  MacroAssembler* a = new MacroAssembler(&cb);
  NativeCall  *nc;
  uint idx;
  int offsets[] = {
    0x0,
    0xfffffff0,
    0x7ffffff0,
    0x80000000,
    0x20,
    0x4000,
  };

  VM_Version::allow_all();

  a->call( a->pc(), relocInfo::none );
  a->delayed()->nop();
  nc = nativeCall_at( cb.insts_begin() );
  nc->print();

  nc = nativeCall_overwriting_at( nc->next_instruction_address() );
  for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
    nc->set_destination( cb.insts_begin() + offsets[idx] );
    assert(nc->destination() == (cb.insts_begin() + offsets[idx]), "check unit test");
    nc->print();
  }

  nc = nativeCall_before( cb.insts_begin() + 8 );
  nc->print();

  VM_Version::revert();
#endif
}
예제 #5
0
bool CompiledIC::is_icholder_call_site(virtual_call_Relocation* call_site) {
  // This call site might have become stale so inspect it carefully.
  NativeCall* call = nativeCall_at(call_site->addr());
  return is_icholder_entry(call->destination());
}