Beispiel #1
0
 void ComparingStub::init(nmethod* nm) {
   CountCodePattern* patt = CountStub::pattern[Comparing];
   int32* p = (int32*)insts();
   set_recompile_addr(Memory->code->trapdoors->Recompile_stub_td());
   set_count_addr(patt, (int32)&sendCounts[id()]);
   assert(isSetHi(p + patt->limit_sethi_offset), "wrong pattern");
   fint limit = recompileLimit(nm->level());
   setSetHiImm(p + patt->limit_sethi_offset, limit);
 }
Beispiel #2
0
  void ComparingStub::init(nmethod* nm) {
    CountCodePattern* patt = CountStub::pattern[Comparing];
    set_recompile_addr((pc_t)Recompile_stub);
    set_count_addr(patt, (int32)&sendCounts[id()]);

    int32* p = (int32*)(int32(insts()) + patt->limit_offset);
    assert(*p == patt->initial_limit, "???");
    fint limit = recompileLimit(nm->level());
    *p = limit;
  }
Beispiel #3
0
void nmethod::flushPartially() {
# ifdef SIC_COMPILER
  oldCount = min(recompileLimit(level()), invocationCount());
# else
  oldCount = invocationCount();
# endif
  useCount[id] = 0;
  removeFromCodeTable();
  diLink.remove();
  save_unlinked_frame_chain();  // protect from accidental flushing
  if (!UsePICRecompilation) {
    flush();                    // also flush the inline caches
  }
  assert(frame_chain != NoFrameChain, "frames should be chained now");
}
Beispiel #4
0
void CodeGen::checkRecompilation() {

  a.Comment("checkRecompilation");
  // di recompilation doesn't work right now - see recompile.c
  if (diLink) return;

  a.Comment("test for recompilation");
  int32 countID = theCompiler->countID;
  void* counter = &useCount[countID];
  a.leal(no_reg, int32(counter), VMAddressOperand, Temp2);
  a.movl(Temp2, 0, NumberOperand, Temp1);
  a.incl(Temp1);
  a.movl(Temp1, Temp2, 0, NumberOperand);

  fint limit = recompileLimit(theCompiler->level());
  // compare to limit
  a.cmpl(limit, NumberOperand, Temp1);
  Label ok;
  a.jne(&ok);


  // (no frame yet)
  
  // Pass a link to caller's sendDesc in LinkReg.
  // Pass a link to callee (i.e. this code being generated) in RecompileLinkReg
  
  // pass original return pc in normal place, push extra return pc on stack

  // call recompiler
  int32 fnaddr = diLink 
               ?   (int32)DIRecompile_stub 
               :   (int32)Recompile_stub;
  a.call(fnaddr, PVMAddressOperand);
  a.hlt();

  // we don't return here from Recompile_stub.  Recompile_stub jumps to new method if
  // we do on-stack replacement.  if we don't do on-stack replacement, it returns directly
  // to the verified entry point in the nmethod.  -mabdelmalek 12/5/2002

  ok.define();
}
Beispiel #5
0
  void CodeGen::checkRecompilation() {
    // test for recompilation
    //   sethi &counter, t3
    //   load  [t3 + lo%(&counter)], t4
    //   add t4, 1, t4
    //   cmp t4, recompileLimit
    //   bne ok
    //   store t4, [t3 + lo%(&counter)]
    //   <jumpTo recompiler>
    //   nop
    // ok:

    // di recompilation doesn't work right now - see recompile.c
    if (diLink) return;

    a.Comment("test for recompilation");
    int32 countID = theCompiler->countID;
    void* counter = &useCount[countID];
    a.SetHiA(counter, Temp3);
    a.LoadA(Temp3, counter, Temp2);
    a.AddI(Temp2, 1, Temp2);
    fint limit = recompileLimit(theCompiler->level());
    if (limit < maxImmediate) {
      a.SubCCI(Temp2, limit, G0);
    } else {
      a.SetHiI2(limit, Temp1);      // limit is multiple of 1024
      a.SubCCR(Temp2, Temp1, G0);
    }
    Label* ok = a.BneForward(false);
    // call recompiler
    void* fnaddr = diLink 
                 ? Memory->code->trapdoors->DIRecompile_stub_td() 
                 : Memory->code->trapdoors->  Recompile_stub_td();
    Location linkReg = diLink ? DIRecompileLinkReg : RecompileLinkReg;
    jumpTo(fnaddr, linkReg, linkReg);
    // The store below is always executed so that we will call the recompiler 
    // exactly once (even if it cannot recompile for some reason).
    ok->define();
    assert(Temp3 != linkReg, "counter addr reg will be trashed by jump");
    a.StoreA(Temp3, counter, Temp2);
  }
Beispiel #6
0
  void SICGenHelper::checkRecompilation(fint countID) {
    // test for recompilation
    //   sethi &counter, t3
    //   load  [t3 + lo%(&counter)], t4
    //   add t4, 1, t4
    //   cmp t4, recompileLimit
    //   bne ok
    //   store t4, [t3 + lo%(&counter)]
    //   <jumpTo recompiler>
    //   nop
    // ok:

    // di recompilation doesn't work right now - see recompile.c
    if (theSIC->diLink) return;
    Assembler* ass = theAssembler;

    ass->Comment("test for recompilation");
    void* counter = &useCount[countID];
    ass->SetHiA(counter, Temp3);
    ass->LoadA(Temp3, counter, Temp2);
    ass->AddI(Temp2, 1, Temp2);
    fint limit = recompileLimit(0);
    if (limit < maxImmediate) {
      ass->SubCCI(Temp2, limit, G0);
    } else {
      ass->SetHiI2(limit, Temp1);           // limit is multiple of 1024
      ass->SubCCR(Temp2, Temp1, G0);
    }
    Label* ok = ass->BneForward(false);
    // call recompiler
    void* fnaddr = first_inst_addr(
                     theSIC->diLink ? Memory->zone->DIRecompile_stub_td()
                                    : Memory->zone->  Recompile_stub_td() );
    Location linkReg = theSIC->diLink ? DIRecompileLinkReg : RecompileLinkReg;
    jumpTo(fnaddr, linkReg, linkReg);
    // The store below is always executed so that we will call the recompiler 
    // exactly once (even if it cannot recompile for some reason).
    ok->define();
    assert(Temp3 != linkReg, "counter addr reg will be trashed by jump");
    ass->StoreA(Temp3, counter, Temp2);
  }
Beispiel #7
0
bool nmethod::shouldNotRecompile() {
# ifdef SIC_COMPILER
  if (compiler() == NIC) return false;
  if (level() == MaxRecompilationLevels - 1)
    return true;                // no optimizable sends
  if (isYoung()) {
    if (invocationCount() > agingLimit() &&
        flags.trapCount < MapLoadTrapLimit) {
      // isn't really young anymore (but didn't trigger counter because it
      // has several callers)
      makeOld();
    } else if (nsends() > max(recompileLimit(0), 4 * agingLimit())) {
      // does a lot of sends - give it a chance anyway
    } else {
      // don't recompile yet - too young
      // but mark it for later recompilation
      makeToBeRecompiled();
      return true;
    }
  }
# endif
  return false; 
}