/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.mmtk.plan; import org.mmtk.utility.Constants; import org.mmtk.utility.statistics.Timer; import org.mmtk.utility.Log; import org.mmtk.vm.VM; import org.vmmagic.pragma.*; /** * Phases of a garbage collection. * * A complex phase is a sequence of phases. * */ @Uninterruptible public final class ComplexPhase extends Phase implements Constants { /**************************************************************************** * Instance fields */ /** * The phases that comprise this phase. */ private final int[] scheduledSubPhases; /** * Construct a complex phase from an array of phase IDs. * * @param name The name of the phase. * @param scheduledSubPhases The sub phases */ protected ComplexPhase(String name, int[] scheduledSubPhases) { super(name); this.scheduledSubPhases = scheduledSubPhases; checkPhases(); } /** * Construct a complex phase from an array of phase IDs, but using * the specified timer rather than creating one. * * @param name The name of the phase. * @param timer The timer for this phase to contribute to. * @param scheduledSubPhases The sub phases */ protected ComplexPhase(String name, Timer timer, int[] scheduledSubPhases) { super(name, timer); this.scheduledSubPhases = scheduledSubPhases; checkPhases(); } /** * Validate the scheduled sub phases. */ private void checkPhases() { if (VM.VERIFY_ASSERTIONS) { VM.assertions._assert(scheduledSubPhases.length > 0); for(int scheduledPhase: scheduledSubPhases) { VM.assertions._assert(getSchedule(scheduledPhase) > 0); VM.assertions._assert(getPhaseId(scheduledPhase) > 0); } } } /** * The number of scheduled sub phases. */ protected int count() { return scheduledSubPhases.length; } /** * Return an individual scheduled sub phase. * * @param index The index * @return The scheduled phase. */ protected int get(int index) { return scheduledSubPhases[index]; } /** * Display a description of this phase, for debugging purposes. */ protected void logPhase() { Log.write("ComplexPhase("); Log.write(name); Log.write(", < "); for (int subPhase : scheduledSubPhases) { short ordering = getSchedule(subPhase); short phaseId = getPhaseId(subPhase); Log.write(getScheduleName(ordering)); Log.write("("); Log.write(getName(phaseId)); Log.write(") "); } Log.write(">)"); } /** * Replace a scheduled phase. Used for example to replace a placeholder. * * @param oldScheduledPhase The scheduled phase to replace. * @param newScheduledPhase The new scheduled phase. */ public void replacePhase(int oldScheduledPhase, int newScheduledPhase) { for (int i = 0; i < scheduledSubPhases.length; i++) { int scheduledPhase = scheduledSubPhases[i]; if (scheduledPhase == oldScheduledPhase) { /* Replace */ scheduledSubPhases[i] = newScheduledPhase; } else if (getSchedule(scheduledPhase) == SCHEDULE_COMPLEX) { /* Recurse */ ComplexPhase p = (ComplexPhase)getPhase(getPhaseId(scheduledPhase)); p.replacePhase(oldScheduledPhase, newScheduledPhase); } } } }