示例#1
0
void nmethod::remove_me_from_inline_cache() {
  static int n = 0;
  while (linkedSends.notEmpty()) {
    nmln *x= linkedSends.next;
    assert(x->next != NULL, "");
    findThing(x)->unlink_me(x);
  }
}
示例#2
0
fint nmethod::invocationCount() {
  if (useCount[id]) {
    // nmethod counts in prologue (to save space for count stubs)
    return useCount[id];
  } else {
    fint count = 0;
    for (nmln* l = linkedSends.next; l != &linkedSends; l = l->next) {
      NCodeBase* s = findThing(l);
      if (s->isCountStub()) count += ((CountStub*)s)->count();
    }
    return count;
  }
}
示例#3
0
void nmethod::forwardLinkedSends(nmethod* to) {
  // the to nmethod is about to replace the receiver; replace receiver in
  // all inline caches
  if (key.receiverMapOop() != to->key.receiverMapOop()) {
    // receiver map has changed - either through programming or because
    // a block map has changed -- don't forward (too complicated e.g. if
    // called by CountStub via a PIC)
    return;
  }
  while(linkedSends.notEmpty()) {
    nmln *x = linkedSends.next;
    findThing(x)->forwardLinkedSend(x, to);
  }
}
示例#4
0
bool sendDesc::checkLookupTypeAndEntryPoint() {
  char *insts= jump_addr();
  if (insts == lookupRoutine()) return true;
  NCodeBase *n= findThing(insts);
  if (n->isCacheStub()) {
    return true; // checked in CacheStub::verify
  }
  nmethod* nm;
  if (n->isNMethod()) {
    nm= (nmethod*)n;
  } else {
    assert(n->isCountStub(), "what is it?");
    CountStub *cs= (CountStub*)n;
    nm= cs->target();
    insts= cs->jump_addr();
  }
  return checkLookupTypeAndEntryPoint(nm, insts);
}
示例#5
0
void nmethod::makeOld() {
  flags.isYoung= 0;
  // remove all AgingStubs
  nmln* nextl;
  for (nmln* l= linkedSends.next;  l != &linkedSends;  l= nextl) {
    nextl= l->next;             // because we're mutating l
    NCodeBase* s= findThing(l);
    if (s->isAgingStub()) {
      AgingStub *a= (AgingStub*)s;
      sendDesc* sd= a->sd();
      if (sd) {
        a->deallocate();
        sd->setCounting(NonCounting);
        sd->rebind(this);
      } else {
        CacheStub *pic= a->pic();
        assert(pic, "no pic for sendDesc");
        pic->rebind(a->sdLink.next, this, NULL);
        a->deallocate();
      }
    }
  }
}
示例#6
0
void handleMapLoadTrap(InterruptedContext* c) {
    int32* pc = (int32*)c->pc();
    assert(isMapLoad(pc), "not a map load");
    assert(c->next_pc() == c->pc() + 4, "flow should be sequential");
    Location dest = Location(rd(pc));
    mapOop resultMap;
    
    // get the result map to load
    # if  TARGET_OS_VERSION == SOLARIS_VERSION_broken
        // disabled for now -- there's some bug in get_reg  --Urs 8/94
        Location src = Location(rs1(pc));
        fint rcvrTag = int(c->get_reg(src)) & Tag_Mask;
        if (rcvrTag == Int_Tag) {
          resultMap = Memory->smi_map->enclosing_mapOop();
        } else if (rcvrTag == Float_Tag) {
          resultMap = Memory->float_map->enclosing_mapOop();
        } else {
          fatal("bad receiver tag in map load trap");
        }
    # else
        // Can't read registers, and signal handler doesn't get faulting address,
        // so don't know what the correct map is.  But it's not really needed
        // (only important thing is that it's different from any mem map) since
        // the map testing code always checks the tag if an immediate is expected.
        resultMap = NULL;
    # endif

    NCodeBase* thing = findThing(pc);
    if (!thing->isNMethod()) {
      // a PIC -- no problem, will fix itself to eliminate trap
    } else {
      nmethod* nm = findNMethod(pc);
      if ((char*)pc >= nm->verifiedEntryPoint()) {
        // the trap happened in the body, not in the prologue
        if (nm->flags.trapCount > MapLoadTrapLimit) {
          // recompile the nmethod on next invocation to eliminate the traps
          nm->makeToBeRecompiled();
          if (nm->isYoung())
            // manipulate counters to provoke recompilation
            nm->makeVeryYoung();
          else
            nm->makeYoung();
        } else {
          nm->flags.trapCount++;
          if (nm->flags.trapCount <= 0) {
            // counter overflowed
            nm->flags.trapCount--;
          }
        }
      }
    }
    # if  TARGET_OS_VERSION == SOLARIS_VERSION
        // simply set the destination register and continue
        c->set_reg(dest, resultMap);
        c->set_pc(c->next_pc());
        c->set_next_pc(c->pc() + 4);
    # elif  TARGET_OS_VERSION == SUNOS_VERSION
        // can't set register in interrupt handler - argh!!
        if (mapLoadHandler[dest]) {
          char* cont = c->next_pc();
          InterruptedContext::set_continuation_address(first_inst_addr(mapLoadHandler[dest]), true, true);
          continuePC = cont;
          mapToLoad = resultMap;
        } else {
          fatal1("map load trap: bad destination register %d", dest);
        }
    # endif
}
示例#7
-4
void nmethod::moveTo_inner(NCodeBase* p, int32 delta, int32 size) {
  nmethod* to = (nmethod*)p;
  if (this == to) return;
  if (PrintCodeCompaction) {
    lprintf("*moving nmethod %#lx (", this);
    printName(0, key.selector);
    lprintf(") to %#lx\n", to);
  }

  OopNCode::moveTo_inner(to, delta, size);

  assert(iabs((char*)to - (char*)this) >= sizeof(NCodeBase),
         "nmethods overlap too much");
  assert(sizeof(NCodeBase) % oopSize == 0, "should be word-aligned");
  // init to's vtable
  copy_words((int32*)this, (int32*)to, sizeof(NCodeBase) / sizeof(int32));

  scopes->_nmethod_backPointer = to;
  *dBackLinkAddr() = to;
  flatProfiler->move(insts(), instsEnd(), to->insts());
  
  zoneLink.shift(delta);
  
  FOR_MY_CODETABLE_ENTRIES(e) {
    e->nm= to;
  }

  for (nmln *x = linkedSends.next, *y = x->next;
       x != &linkedSends;
       x = y, y = y->next) {
    NCodeBase* s = findThing(x);
    s->shift_target(x, delta);
  }
  linkedSends.shift(delta, this);
  
  if (diLink.notEmpty()) {
    assert(diLink.next->next == &diLink, "diLink should be a pair");
    diLink.next->asDIDesc()->shift_jump_addr(delta);
  }
  diLink.shift(delta);
  
  for (addrDesc* q = locs(), *pend = locsEnd(); q < pend; q++) {
    if (q->isSendDesc()) {
      sendDesc* sd = q->asSendDesc(this);
      sd->shift(delta, this);
    }
    else if (q->isDIDesc()) {
      nmln* l = q->asDIDesc(this)->dependency();
      l->shift(delta);
    }
    q->shift(this, delta);
  }
  if (frame_chain != NoFrameChain && frame_chain != SavedFrameChain)
    frame_chain->nmethod_moved_by(delta, this);
}