示例#1
0
文件: ncode.cpp 项目: AdamSpitz/self
bool NCodeBase::verify2(const char* name) {
  bool r = true;
  if ((int32)this & (oopSize - 1)) {
    error2("alignment error in %s at %#lx", name, this);
    r = false;
  }
  if (instsLen() > 256 * K) {
    error3("instr length of %s at %#lx seems too big (%ld)", name, this, instsLen());
    r = false;
  }
  return r;
}
示例#2
0
文件: ncode.cpp 项目: AdamSpitz/self
void NCodeBase::moveTo(NCodeBase* to, int32 size) {
  int32 delta = (char*) to - (char*) this;
  moveTo_inner(to, delta, size);
  copy_words_overlapping(  (int32*)this,  (int32*)to,  size / sizeof(int32));
  // must use "to"; cannot use "this" anymore since there may be overlap
  if (to->isNMethod())
    ; // cannot do this simple check because moveTo_inner fixes up branches in place for nmethods()
  else if (CheckAssertions || 1 /* turn this on for now, since PPC has been buggy */)
    check_branch_relocation( (char*)to->insts() - delta,  to->insts(),  instsLen() );

  MachineCache::flush_instruction_cache_range(to->insts(), to->instsEnd());
}
示例#3
0
bool nmethod::isTiny() {
# ifdef SIC_COMPILER
  // is this a "tiny" nmethod, i.e. is it likely to be small when inlined?
  if (isAccess()) return true;
  if (compiler() == NIC) {
    // the NIC's code is large because it has many inline caches, so look
    // at the source
    fint len = ((methodMap*)method()->map())->codes()->length();
    fint max = key.receiverMap()->is_block() ?
                  TinyBlockSourceSize : TinyFnSourceSize;
    if  (len <= max) return true;
  } else {
    fint len = instsLen() - oopSize * PrologueSize;
    if (len < TinyFnObjSize) return true;
  }

  // try this last because it's relatively expensive
  return isCheapMessage((stringOop)key.selector);
# else
  return false;
# endif
}
示例#4
0
nmethod::nmethod(AbstractCompiler* c, bool generateDebugCode) {
  CHECK_VTBL_VALUE;
  _instsLen  = roundTo(iLen, oopSize);
  _locsLen   = ilLen;
  depsLen    = dLen;
  // backpointer is just before deps
  depsAddr   = (nmln*)     ((char*)dAddr + sizeof(nmethod*));

  *dBackLinkAddr() = this;
  
  // Copy the nmethodScopes scopeDescs generated by the ScopeDescRecorder
  // to the allocation area.
  c->scopeDescRecorder()->copyTo((VtblPtr_t*)sAddr, (int32)this);
  
  this->scopes = (nmethodScopes*) sAddr;

  oldCount = 0;
  flags.clear();
  flags.isDebug = generateDebugCode;
  setCompiler(c->name());
  flags.isUncommonRecompiled = currentProcess->isUncommon();
    
  verifiedOffset      = c->verifiedOffset();
  diCheckOffset       = c->diCheckOffset();

  frameCreationOffset = c->frameCreationOffset();
  
  rememberLink.init();
  codeTableLink= NULL;
  diLink.init(c->diLink);
  if (diLink.notEmpty()) flags.isDI = true;
  flags.level = c->level();
  if (flags.level >= MaxRecompilationLevels) { // added = zzzz
    warning1("setting invalid nmethod level %ld", flags.level);  // fix this
    flags.level = 0;
  }
  flags.version = c->version();
  if (c->nmName() == nm_nic && ((FCompiler*)c)->isImpure)
    makeImpureNIC();
  key.set_from(c->L->key);
  check_store();
  
  clear_frame_chain();
  assert(c->frameSize() >= 0, "frame size cannot be negative");
  frame_size = c->frameSize();
  _incoming_arg_count = c->incoming_arg_count();
  get_platform_specific_data(c);

  Assembler* instsA = c->instructions();
  copy_bytes(        instsA->instsStart,        insts(), instsLen());
  copy_words((int32*)instsA->locsStart,  (int32*)locs(),  ilLen/4);
  copy_words((int32*)depsStart,          (int32*)deps(),  depsLen/4);
  
  addrDesc *l, *lend;
  for (l = locs(), lend = locsEnd(); l < lend; l++) {
    l->initialShift(this, (char*)insts() - (char*)instsA->instsStart, 0);
  }

  char* bound = Memory->new_gen->boundary();
  for (l = locs(), lend = locsEnd(); l < lend; l++) {
    if (l->isOop())
      OopNCode::check_store(oop(l->referent(this)), bound); // cfront garbage
    else if (l->isSendDesc()) {
      l->asSendDesc(this)->dependency()->init();
    } else if (l->isDIDesc()) {
      l->asDIDesc(this)->dependency()->init();
      flags.isDI = true; 
    }
  }
  
  for (nmln* d = deps(), *dend = depsEnd(); d < dend; d++) {
    d->relocate();
  }
  
  MachineCache::flush_instruction_cache_range(insts(), instsEnd());
  MachineCache::flush_instruction_cache_for_debugging();
  
  if (this == (nmethod*)catchThisOne) warning("caught nmethod");
}
示例#5
0
void nmethod::flush() {
  BlockProfilerTicks bpt(exclude_nmethod_flush);
  CSect cs(profilerSemaphore);          // for profiler
# if GENERATE_DEBUGGING_AIDS
    if (CheckAssertions) {
      // for debugging
      if (nmethodFlushCount  &&  --nmethodFlushCount == 0)
        warning("nmethodFlushCount");
      if (this == (nmethod*)catchThisOne) warning("caught nmethod");
    }
# endif
  
  // EventMarker em("flushing nmethod %#lx %s", this, "");
  if (PrintMethodFlushing) {
    ResourceMark m;
    char *compilerName = VMString[compiler()]->copy_null_terminated();
    lprintf("*flushing %s%s%s-nmethod 0x%lx %d\t(",
           isZombie() ? "zombie " : "", 
           isAccess() ? "access " : "",
           compilerName, (void*)(long unsigned)this, (void*)useCount[id]);
    printName(0, key.selector);
    lprintf(")");
  }

  // always check the following - tests are really cheap
  if (flags.flushed) fatal1("nmethod %#lx already flushed", this);
  if (zone::frame_chain_nesting == 0) fatal("frames must be chained when flushing");

  if (frame_chain != NoFrameChain) {
    // Can't remove an nmethod from deps chains now, because later
    // programming changes may need to invalidate it.
    // That is, don't unlink() now.
   
    // See comment for makeZombie routine. The comment above is the 
    // "original comment" referred to there.
    // -- dmu 1/12/03

    if (this == recompilee) {
      // nmethod is being recompiled; cannot really flush yet
      // em.event.args[1] = "(being recompiled)";
      if (PrintMethodFlushing) {
        lprintf(" (being recompiled)\n");
      }
    } else {
      // nmethod is currently being executed; cannot flush yet
      // em.event.args[1] = "(currently active)";
      if (PrintMethodFlushing) {
        lprintf(" (currently active)\n");
      }
    }
    makeZombie(false);
  } else {
    unlink();
  
    // nmethod is not being executed; completely throw away
    // em.event.args[1] = "(not currently active)";
    if (PrintMethodFlushing) {
      lprintf("\n");
    }
    flatProfiler->flush((char*)this, instsEnd());
    zoneLink.remove();
    rememberLink.remove();
    for (addrDesc* p = locs(), *pend = locsEnd(); p < pend; p++) {
      if (p->isSendDesc()) {
        p->asSendDesc(this)->unlink();
      } else if (p->isDIDesc()) {
        p->asDIDesc(this)->dependency()->flush();
      }
    }
    flags.flushed = 1;                        // to detect flushing errors
#   if GENERATE_DEBUGGING_AIDS
    if (CheckAssertions) {
      set_oops((oop*)insts(), instsLen()/oopSize, 0); // for quicker detection
    }
#   endif
    Memory->code->free_nmethod(this);
  }
  MachineCache::flush_instruction_cache_for_debugging();
}
示例#6
0
void nmethod::print() {
  ResourceMark rm;
  printIndent();
  lprintf("(nmethod*)%#lx", this);
  if (scopes->root()->isDataAccessScope()) {
    lprintf(" (data access)");
  } else if (scopes->root()->isDataAssignmentScope()) {
    lprintf(" (data assignment)");
  } else {
    lprintf(" for method %#lx", method());
  }
  lprintf(" { ");
  if (isYoung()) lprintf("YOUNG ");
  switch (compiler()) {
   case NIC: lprintf("NIC "); if (isImpureNIC()) lprintf("impure "); break;
   case SIC: lprintf("SIC level %ld ", level()); break;
   default:  lprintf("!?!unknown compiler!?! "); break;
  }
  if (version())           lprintf("v%d ", version());
  if (isDI())              lprintf("DI ");
  if (isZombie())          lprintf("zombie ");
  if (isInvalid())         lprintf("INVALID ");
  if (isDebug())           lprintf("DEBUG ");
  if (isToBeRecompiled())  lprintf("TBR ");
  if (isUncommon() || isUncommonRecompiled()) lprintf("UNCOMMON ");
  lprintf("}:\n");
 
  lprintf( "incoming_arg_count = %d\n", incoming_arg_count() );
  
  print_platform_specific_data();
  
  Indent ++;
  
  key.print();
  
  printIndent();
  lprintf("code table link: %#lx\n", codeTableLink);
  
  printIndent();
  lprintf("remember link: ");
  rememberLink.print();
  lprintf("\n");
  
  printIndent();
  lprintf("linked sends: ");
  linkedSends.print();
  lprintf("\n");
  
  printIndent();
  lprintf("di link: ");
  diLink.print();
  lprintf("\n");
  
  printIndent();
  lprintf("instructions (%ld bytes): %#lx,%#lx/i / x/%ldi %#lx\n",
         instsLen(), 
         insts(),
         instsEnd() - oopSize,
         instsLen() / oopSize,
         insts());
  printIndent(); lprintf("p ((nmethod*)%#lx)->printCode() \n", this);
  scopes->print();
  // printLocs();
  // printDeps();
  Indent --;
}
示例#7
0
void NCodeBase::verify2(const char* name) {
  if ((int)this & (oopSize - 1))
    error("alignment error in %s at %#lx", name, this);
  if (instsLen() > 256 * K)
    error("instr length of %s at %#lx seems too big (%ld)", name, this, instsLen());
}
示例#8
0
 char* instsEnd() const 		{ return insts() + instsLen(); }