예제 #1
0
  void CodeGen::fixupFrame(RegisterState* s) {
    // window size adjustment
    assert(haveStackFrame, "should have stack frame");
    fint stackTempCount = s->stackDepth + s->argDepth;
    if (stackTempCount & 1) ++stackTempCount;
    frameSize = stackTempCountToFrameSize(stackTempCount);
    assert((frameSize & (frame_word_alignment-1))  ==  0, "frame size must be even");

    a.Comment("patching stack frame creation code");
    // The mask in the inline cache marks the regs + the first ntemps stack locs.
    // If we have fewer than ntemps temps and have extra args, the bits for the
    // extra args must be set.
    // All stack locations beyond the first ntemps have to be cleared.
    
    fint ntemps = BitsPerWord - (NumInRegisters + NumLocalRegisters);
    if (stackTempCount - s->argDepth  <  ntemps   &&  s->argDepth > 0) {
      s->fixupMasks(stackTempCount);
    }
    a.saveExcursion(prologueAddr);
    if (stackTempCount <= ntemps && !s->argDepth) {
      // no need to init anything on the stack - just patch frameSize
      a.SaveI(SP, frameSize * -oopSize, SP);    // make new register window
      a.endExcursion();
    } else {
      // need to initialize extra stack locations and/or extra args
      Label* l = a.BraForward(true);
      DefinedLabel cont(a.printing);
      a.endExcursion();
      l->define();
      a.SaveI(SP, frameSize * -oopSize, SP);    // make new register window
      // clear locations beyond first ntemps 
      fint i;
      for ( i = max(ntemps, s->initStackTemps); 
            i < stackTempCount; 
            i++) {
        a.StoreI(FP, (local_slots_offset - i) * oopSize, G0);
      }
      // clear extra args marked "live" by fixupMasks
      // (necessary because the simple fixup scheme marks them as live
      // for the entire method, not only after they're used)
      for ( i = 1; 
            i <= s->argDepth; 
            i++) {
        fint bitNo = stackTempCount - i;
        if (bitNo < ntemps) {
          a.StoreI(FP, (local_slots_offset - bitNo) * oopSize, G0);
        }
      }
      a.Bra(&cont, true);
    }
  }
예제 #2
0
sparc_sp* sparc_sp::push_new_sp( char* pc,
                                 fint size_in_oops,
                                 bool zapAlways ) {
  // ( this was 1024 in one previous version and 64 in another!)
  if (size_in_oops == 0) {
    size_in_oops = stackTempCountToFrameSize(0);
    size_in_oops += size_in_oops & (frame_word_alignment-1); // make even
  }
  assert((size_in_oops & 1) == 0, "sparc frames must be even length");
  sparc_sp* sp = (sparc_sp*)( as_oops() - size_in_oops );
# if GENERATE_DEBUGGING_AIDS
    if (CheckAssertions) {
      zapAlways = true;
    }
# endif
  if (zapAlways)
    // If errorObj starts showing up where it shouldn't, I recommend
    // substituting 0xfffffffe for it below: (dmu)
    set_oops(sp->as_oops(), size_in_oops, (oop)Memory->errorObj);
  sp->set_link(as_callees_fp());
  sp->set_return_addr(pc);
  assert(sp->link() == (sparc_fp*)this, "just checkin'");
  return sp;
}