Esempio n. 1
0
  /** Process the phase stack. This method is called by multiple threads. */
  private static boolean processPhaseStack(boolean resume) {
    int order = VM.collection.rendezvous(1001);
    final boolean primary = order == 1;

    boolean log = Options.verbose.getValue() >= 6;
    boolean logDetails = Options.verbose.getValue() >= 7;

    if (primary && resume) {
      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!Phase.isPhaseStackEmpty());
      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!Plan.gcInProgress());
      Plan.setGCStatus(Plan.GC_PROPER);
    }

    /* In order to reduce the need for synchronization, we keep an odd or even
     * counter for the number of phases processed. As each phase has a single
     * rendezvous it is only possible to be out by one so the odd or even counter
     * protects us. */
    boolean isEvenPhase = true;

    if (primary) {
      /* First phase will be even, so we say we are odd here so that the next phase set is even*/
      setNextPhase(false, getNextPhase(), false);
    }

    /* Make sure everyone sees the first phase */
    VM.collection.rendezvous(1002);

    /* Global and Collector instances used in phases */
    Plan plan = VM.activePlan.global();
    CollectorContext collector = VM.activePlan.collector();

    /* The main phase execution loop */
    int scheduledPhase;
    while ((scheduledPhase = getCurrentPhase(isEvenPhase)) > 0) {
      short schedule = getSchedule(scheduledPhase);
      short phaseId = getPhaseId(scheduledPhase);
      Phase p = getPhase(phaseId);

      /* Start the timer(s) */
      if (primary) {
        if (resume) {
          resumeComplexTimers();
        }
        if (p.timer != null) p.timer.start();
        if (startComplexTimer > 0) {
          Phase.getPhase(startComplexTimer).timer.start();
          startComplexTimer = 0;
        }
      }

      if (log) {
        Log.write("Execute ");
        p.logPhase();
      }

      /* Execute a single simple scheduled phase */
      switch (schedule) {
          /* Global phase */
        case SCHEDULE_GLOBAL:
          {
            if (logDetails) Log.writeln(" as Global...");
            if (primary) plan.collectionPhase(phaseId);
            break;
          }

          /* Collector phase */
        case SCHEDULE_COLLECTOR:
          {
            if (logDetails) Log.writeln(" as Collector...");
            collector.collectionPhase(phaseId, primary);
            break;
          }

          /* Mutator phase */
        case SCHEDULE_MUTATOR:
          {
            if (logDetails) Log.writeln(" as Mutator...");
            /* Iterate through all mutator contexts */
            MutatorContext mutator;
            while ((mutator = VM.activePlan.getNextMutator()) != null) {
              mutator.collectionPhase(phaseId, primary);
            }
            break;
          }

          /* Concurrent phase */
        case SCHEDULE_CONCURRENT:
          {
            /* We are yielding to a concurrent collection phase */
            if (logDetails) Log.writeln(" as Concurrent, yielding...");
            if (primary) {
              concurrentPhaseId = phaseId;
              scheduleConcurrentWorkers();
              /* Concurrent phase, we need to stop gc */
              Plan.setGCStatus(Plan.NOT_IN_GC);
            }
            VM.collection.rendezvous(1003);
            if (primary) {
              pauseComplexTimers();
            }
            return false;
          }

        default:
          {
            /* getNextPhase has done the wrong thing */
            VM.assertions.fail("Invalid schedule in Phase.processPhaseStack");
            break;
          }
      }

      if (primary) {
        /* Set the next phase by processing the stack */
        int next = getNextPhase();
        boolean needsResetRendezvous =
            (next > 0) && (schedule == SCHEDULE_MUTATOR && getSchedule(next) == SCHEDULE_MUTATOR);
        setNextPhase(isEvenPhase, next, needsResetRendezvous);
      }

      /* Sync point after execution of a phase */
      VM.collection.rendezvous(1004);

      /* Mutator phase reset */
      if (primary && schedule == SCHEDULE_MUTATOR) {
        VM.activePlan.resetMutatorIterator();
      }

      /* At this point, in the case of consecutive phases with mutator
       * scheduling, we have to double-synchronize to ensure all
       * collector threads see the reset mutator counter. */
      if (needsMutatorResetRendezvous(isEvenPhase)) {
        VM.collection.rendezvous(1005);
      }

      /* Stop the timer(s) */
      if (primary) {
        if (p.timer != null) p.timer.stop();
        if (stopComplexTimer > 0) {
          Phase.getPhase(stopComplexTimer).timer.stop();
          stopComplexTimer = 0;
        }
      }

      /* Flip the even / odd phase sense */
      isEvenPhase = !isEvenPhase;
      resume = false;
    }

    /* Phase stack exhausted so we return true */
    return true;
  }
Esempio n. 2
0
 /**
  * Take the passed phase and return an encoded phase to run that phase in a mutator context;
  *
  * @param phaseId The phase to run on mutators
  * @return The encoded phase value.
  */
 public static int schedulePlaceholder(short phaseId) {
   if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Phase.getPhase(phaseId) instanceof SimplePhase);
   return (SCHEDULE_PLACEHOLDER << 16) + phaseId;
 }
Esempio n. 3
0
 /**
  * Take the passed phase and return an encoded phase to run that phase in a mutator context;
  *
  * @param phaseId The phase to run on mutators
  * @return The encoded phase value.
  */
 public static int scheduleMutator(short phaseId) {
   if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Phase.getPhase(phaseId) instanceof SimplePhase);
   return (SCHEDULE_MUTATOR << 16) + phaseId;
 }
Esempio n. 4
0
 /**
  * Take the passed phase and return an encoded phase to run that phase in a global context;
  *
  * @param phaseId The phase to run globally
  * @return The encoded phase value.
  */
 public static int scheduleGlobal(short phaseId) {
   if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Phase.getPhase(phaseId) instanceof SimplePhase);
   return (SCHEDULE_GLOBAL << 16) + phaseId;
 }
Esempio n. 5
0
 /**
  * Take the passed phase and return an encoded phase to run that phase as a concurrent phase.
  *
  * @param phaseId The phase to run as concurrent
  * @return The encoded phase value.
  */
 public static int scheduleConcurrent(short phaseId) {
   if (VM.VERIFY_ASSERTIONS)
     VM.assertions._assert(Phase.getPhase(phaseId) instanceof ConcurrentPhase);
   return (SCHEDULE_CONCURRENT << 16) + phaseId;
 }
Esempio n. 6
0
 /**
  * Take the passed phase and return an encoded phase to run that phase as a complex phase.
  *
  * @param phaseId The phase to run as complex
  * @return The encoded phase value.
  */
 public static int scheduleComplex(short phaseId) {
   if (VM.VERIFY_ASSERTIONS)
     VM.assertions._assert(Phase.getPhase(phaseId) instanceof ComplexPhase);
   return (SCHEDULE_COMPLEX << 16) + phaseId;
 }