/// cache.cc -- context cache
///
/// Author: Ian.Piumarta@inria.fr
///
/// last edited: Tue Feb 23 15:16:03 1999 by piumarta (Ian Piumarta) on pingu


#include "interp.h"
#include "translate.h"
#include "cache.h"


Context *flushContextCache(void)
{
  CachedContext *acc= activeCachedContext;
  CachedContext *lcc= lowestCachedContext;
  assert(acc != 0);
  storeCachedContextRegisters(acc);
  // allocate PseudoContexts where necessary
  acc->allocatePseudoContext();
  while (acc != lcc) (acc= acc->parent())->allocatePseudoContext();
  acc= activeCachedContext;
  topStableContext= lcc->stabilise(topStableContext);
  while (lcc != acc) {
    lcc= lcc->child();
    topStableContext= lcc->stabilise(topStableContext);
  }
  activeCachedContext= 0;
  temporaryPointer= 0;
  return topStableContext;	// the active Context
}


void flushLowestCachedContext(void)
{
  PRINTF(("flushLowest\n"));
  CachedContext *lcc= lowestCachedContext;
  CachedContext *const ncc= lcc->child();
  topStableContext= lcc->stabilise(topStableContext);
  lowestCachedContext= ncc;
  // delete the lowest stack segment
  // Note: by keeping the stack rooted at the base of the cache we
  //	avoid an overflow check at every cached context allocation
  const int displacement= ncc->stack - stackCache;
  const int size= stackPointer - ncc->stack + 1;
  PRINTF(("flush stack: %d[%d]\n", displacement, size));
  wordCopy(stackCache, stackCache + displacement, size);
  // fix the saved stack and sp fields
  while (lcc != activeCachedContext) {
    lcc= lcc->child();
    lcc->stack-= displacement;
    lcc->sp-= displacement;
    assert((lcc->sp >= (lcc->stack - 1)) || (lcc == activeCachedContext));
  }
  assert(ncc->stack == stackCache);
  // fix the external active registers
  stackPointer-= displacement;
  assert(stackPointer >= (activeCachedContext->stack) - 1);
}

