Example #1
0
static void shieldSync(Arena arena, Seg seg)
{
    AVERT(Arena, arena);
    AVERT(Seg, seg);

    if (SegPM(seg) != SegSM(seg)) {
        ProtSet(SegBase(seg), SegLimit(seg), SegSM(seg));
        SegSetPM(seg, SegSM(seg));
        /* inv.prot.shield */
    }
}
Example #2
0
void (ShieldLower)(Arena arena, Seg seg, AccessSet mode)
{
    /* Don't check seg or arena, see .seg.broken */
    AVER((SegSM(seg) & mode) == mode);
    /* synced(seg) is not changed by the following
     * preserving inv.unsynced.suspended
     * Also inv.prot.shield preserved
     */
    SegSetSM(seg, SegSM(seg) & ~mode);
    protLower(arena, seg, mode);
    AVERT(Arena, arena);
    AVERT(Seg, seg);
}
Example #3
0
void (ShieldRaise) (Arena arena, Seg seg, AccessSet mode)
{
    /* .seg.broken: Seg's shield invariants may not be true at */
    /* this point (this function is called to enforce them) so we */
    /* can't check seg. Nor can we check arena as that checks the */
    /* segs in the cache. */

    AVER((SegSM(seg) & mode) == AccessSetEMPTY);
    SegSetSM(seg, SegSM(seg) | mode); /* inv.prot.shield preserved */

    /* ensure inv.unsynced.suspended & inv.unsynced.depth */
    cache(arena, seg);
    AVERT(Arena, arena);
    AVERT(Seg, seg);
}
Example #4
0
/* If the segment is out of sync, either sync it, or ensure
 * depth > 0, and the arena is suspended.
 */
static void cache(Arena arena, Seg seg)
{
    /* <design/trace/#fix.noaver> */
    AVERT_CRITICAL(Arena, arena);
    AVERT_CRITICAL(Seg, seg);

    if (SegSM(seg) == SegPM(seg)) return;
    if (SegDepth(seg) > 0) {
        ShieldSuspend(arena);
        return;
    }
    if (ShieldCacheSIZE == 0 || !arena->suspended)
        shieldSync(arena, seg);
    else {
        SegSetDepth(seg, SegDepth(seg) + 1);
        ++arena->shDepth;
        AVER(arena->shDepth > 0);
        AVER(SegDepth(seg) > 0);
        AVER(arena->shCacheLimit <= ShieldCacheSIZE);
        AVER(arena->shCacheI < arena->shCacheLimit);
        flush(arena, arena->shCacheI);
        arena->shCache[arena->shCacheI] = seg;
        ++arena->shCacheI;
        if (arena->shCacheI == ShieldCacheSIZE)
            arena->shCacheI = 0;
        if (arena->shCacheI == arena->shCacheLimit)
            ++arena->shCacheLimit;
    }
}
Example #5
0
File: shield.c Project: bhanug/mps
static void shieldSync(Shield shield, Seg seg)
{
  SHIELD_AVERT_CRITICAL(Seg, seg);

  if (!SegIsSynced(seg)) {
    shieldSetPM(shield, seg, SegSM(seg));
    ProtSet(SegBase(seg), SegLimit(seg), SegPM(seg));
  }
}
Example #6
0
File: shield.c Project: bhanug/mps
static void shieldFlushEntries(Shield shield)
{
  Addr base = NULL, limit;
  AccessSet mode;
  Index i;

  if (shield->length == 0) {
    AVER(shield->queue == NULL);
    return;
  }

  QuickSort((void *)shield->queue, shield->limit,
            shieldQueueEntryCompare, UNUSED_POINTER,
            &shield->sortStruct);

  mode = AccessSetEMPTY;
  limit = NULL;
  for (i = 0; i < shield->limit; ++i) {
    Seg seg = shieldDequeue(shield, i);
    if (!SegIsSynced(seg)) {
      shieldSetPM(shield, seg, SegSM(seg));
      if (SegSM(seg) != mode || SegBase(seg) != limit) {
        if (base != NULL) {
          AVER(base < limit);
          ProtSet(base, limit, mode);
        }
        base = SegBase(seg);
        mode = SegSM(seg);
      }
      limit = SegLimit(seg);
    }
  }
  if (base != NULL) {
    AVER(base < limit);
    ProtSet(base, limit, mode);
  }

  shieldQueueReset(shield);
}
Example #7
0
File: shield.c Project: bhanug/mps
static void shieldSetSM(Shield shield, Seg seg, AccessSet mode)
{
  if (SegSM(seg) != mode) {
    if (SegIsSynced(seg)) {
      SegSetSM(seg, mode);
      ++shield->unsynced;
    } else {
      SegSetSM(seg, mode);
      if (SegIsSynced(seg)) {
        AVER(shield->unsynced > 0);
        --shield->unsynced;
      }
    }
  }
}
Example #8
0
File: shield.c Project: bhanug/mps
void (ShieldLower)(Arena arena, Seg seg, AccessSet mode)
{
  Shield shield;
  
  AVERT(Arena, arena);
  shield = ArenaShield(arena);
  SHIELD_AVERT(Seg, seg);
  AVERT(AccessSet, mode);

  /* SegIsSynced(seg) is not changed by the following preserving
     design.mps.shield.inv.unsynced.suspended and
     design.mps.shield.inv.prot.shield. */
  shieldSetSM(shield, seg, BS_DIFF(SegSM(seg), mode));
  /* TODO: Do we need to promptly call shieldProtLower here?  It
     loses the opportunity to coalesce the protection call. It would
     violate design.mps.shield.prop.inside.access. */
  /* shieldQueue(arena, seg); */
  shieldProtLower(shield, seg, mode);

  /* Check queue and segment consistency. */
  AVERT(Arena, arena);
  AVERT(Seg, seg);
}
Example #9
0
File: shield.c Project: bhanug/mps
void (ShieldRaise)(Arena arena, Seg seg, AccessSet mode)
{
  Shield shield;

  SHIELD_AVERT(Arena, arena);
  SHIELD_AVERT(Seg, seg);
  AVERT(AccessSet, mode);
  shield = ArenaShield(arena);
  AVER(!shield->queuePending);
  shield->queuePending = TRUE;

  /* design.mps.shield.inv.prot.shield preserved */
  shieldSetSM(ArenaShield(arena), seg, BS_UNION(SegSM(seg), mode));
  
  /* Ensure design.mps.shield.inv.unsynced.suspended and
     design.mps.shield.inv.unsynced.depth */
  shieldQueue(arena, seg);
  shield->queuePending = FALSE;

  /* Check queue and segment consistency. */
  AVERT(Arena, arena);
  AVERT(Seg, seg);
}
Example #10
0
/* ArenaExposeRemember -- park arena and then lift all protection
   barriers.  Parameter 'remember' specifies whether to remember the
   protection state or not (for later restoration with
   ArenaRestoreProtection).
   */
void ArenaExposeRemember(Globals globals, Bool remember)
{
  Seg seg;
  Arena arena;

  AVERT(Globals, globals);
  AVERT(Bool, remember);

  ArenaPark(globals);

  arena = GlobalsArena(globals);
  if(SegFirst(&seg, arena)) {
    Addr base;

    do {
      base = SegBase(seg);
      if (IsA(GCSeg, seg)) {
        if(remember) {
          RefSet summary;

          summary = SegSummary(seg);
          if(summary != RefSetUNIV) {
            Res res = arenaRememberSummaryOne(globals, base, summary);
            if(res != ResOK) {
              /* If we got an error then stop trying to remember any
              protections. */
              remember = 0;
            }
          }
        }
        SegSetSummary(seg, RefSetUNIV);
        AVER(SegSM(seg) == AccessSetEMPTY);
      }
    } while(SegNext(&seg, arena, seg));
  }
}
Example #11
0
File: shield.c Project: bhanug/mps
static Bool SegIsSynced(Seg seg)
{
  SHIELD_AVERT_CRITICAL(Seg, seg);
  return SegSM(seg) == SegPM(seg);
}