Esempio n. 1
0
  /**
   * Notify that the concurrent phase has completed successfully. This must only be called by a
   * single thread after it has determined that the phase has been completed successfully.
   */
  public static void notifyConcurrentPhaseComplete() {
    if (Options.verbose.getValue() >= 2) {
      Log.write("< Concurrent phase ");
      Log.write(getName(concurrentPhaseId));
      Log.writeln(" complete >");
    }
    /* Concurrent phase is complete*/
    concurrentPhaseId = 0;
    /* Remove it from the stack */
    popScheduledPhase();
    /* Pop the next phase off the stack */
    int nextScheduledPhase = getNextPhase();

    if (nextScheduledPhase > 0) {
      short schedule = getSchedule(nextScheduledPhase);

      /* A concurrent phase, lets wake up and do it all again */
      if (schedule == SCHEDULE_CONCURRENT) {
        concurrentPhaseId = getPhaseId(nextScheduledPhase);
        scheduleConcurrentWorkers();
        return;
      }

      /* Push phase back on and resume atomic collection */
      pushScheduledPhase(nextScheduledPhase);
      VM.collection.triggerAsyncCollection(Collection.INTERNAL_PHASE_GC_TRIGGER);
    }
  }
Esempio n. 2
0
  /**
   * Place a phase on the phase stack and begin processing.
   *
   * @param scheduledPhase The phase to execute
   * @return True if the phase stack is exhausted.
   */
  public static boolean beginNewPhaseStack(int scheduledPhase) {
    int order = VM.collection.rendezvous(1001);

    if (order == 1) {
      pushScheduledPhase(scheduledPhase);
    }
    return processPhaseStack(false);
  }
Esempio n. 3
0
  /**
   * Pull the next scheduled phase off the stack. This may involve processing several complex phases
   * and skipping placeholders, etc.
   *
   * @return The next phase to run, or -1 if no phases are left.
   */
  private static int getNextPhase() {
    boolean allowConcurrentPhase = Plan.collectionTrigger == Collection.INTERNAL_PHASE_GC_TRIGGER;

    while (phaseStackPointer >= 0) {
      int scheduledPhase = peekScheduledPhase();
      short schedule = getSchedule(scheduledPhase);
      short phaseId = getPhaseId(scheduledPhase);

      switch (schedule) {
        case SCHEDULE_PLACEHOLDER:
          {
            /* Placeholders are ignored and we continue looking */
            popScheduledPhase();
            continue;
          }

        case SCHEDULE_GLOBAL:
        case SCHEDULE_COLLECTOR:
        case SCHEDULE_MUTATOR:
          {
            /* Simple phases are just popped off the stack and executed */
            popScheduledPhase();
            return scheduledPhase;
          }

        case SCHEDULE_CONCURRENT:
          {
            /* Concurrent phases are either popped off or we forward to
             * an associated non-concurrent phase. */
            if (!allowConcurrentPhase) {
              popScheduledPhase();
              ConcurrentPhase cp = (ConcurrentPhase) getPhase(phaseId);
              int alternateScheduledPhase = cp.getAtomicScheduledPhase();
              if (VM.VERIFY_ASSERTIONS)
                VM.assertions._assert(getSchedule(alternateScheduledPhase) != SCHEDULE_CONCURRENT);
              pushScheduledPhase(alternateScheduledPhase);
              continue;
            }
            if (VM.VERIFY_ASSERTIONS) {
              /* Concurrent phases can not have a timer */
              VM.assertions._assert(getPhase(getPhaseId(scheduledPhase)).timer == null);
            }
            return scheduledPhase;
          }

        case SCHEDULE_COMPLEX:
          {
            /* A complex phase may either be a newly pushed complex phase,
             * or a complex phase we are in the process of executing in
             * which case we move to the next subphase. */
            ComplexPhase p = (ComplexPhase) getPhase(phaseId);
            int cursor = incrementComplexPhaseCursor();
            if (cursor == 0 && p.timer != null) {
              /* Tell the primary thread to start the timer after the next sync. */
              startComplexTimer = phaseId;
            }
            if (cursor < p.count()) {
              /* There are more entries, we push the next one and continue */
              pushScheduledPhase(p.get(cursor));
              continue;
            }

            /* We have finished this complex phase */
            popScheduledPhase();
            if (p.timer != null) {
              /* Tell the primary thread to stop the timer after the next sync. */
              stopComplexTimer = phaseId;
            }
            continue;
          }

        default:
          {
            VM.assertions.fail("Invalid phase type encountered");
          }
      }
    }
    return -1;
  }