001/* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013package org.mmtk.plan; 014 015import org.mmtk.utility.statistics.Timer; 016import org.mmtk.utility.Log; 017import org.mmtk.vm.VM; 018 019import org.vmmagic.pragma.*; 020 021/** 022 * Phases of a garbage collection.<p> 023 * 024 * A complex phase is a sequence of phases. 025 * 026 */ 027@Uninterruptible 028public final class ComplexPhase extends Phase { 029 030 /**************************************************************************** 031 * Instance fields 032 */ 033 034 /** 035 * The phases that comprise this phase. 036 */ 037 private final int[] scheduledSubPhases; 038 039 /** 040 * Construct a complex phase from an array of phase IDs. 041 * 042 * @param name The name of the phase. 043 * @param scheduledSubPhases The sub phases 044 */ 045 protected ComplexPhase(String name, int[] scheduledSubPhases) { 046 super(name); 047 this.scheduledSubPhases = scheduledSubPhases; 048 checkPhases(); 049 } 050 051 /** 052 * Construct a complex phase from an array of phase IDs, but using 053 * the specified timer rather than creating one. 054 * 055 * @param name The name of the phase. 056 * @param timer The timer for this phase to contribute to. 057 * @param scheduledSubPhases The sub phases 058 */ 059 protected ComplexPhase(String name, Timer timer, int[] scheduledSubPhases) { 060 super(name, timer); 061 this.scheduledSubPhases = scheduledSubPhases; 062 checkPhases(); 063 } 064 065 /** 066 * Validate the scheduled sub phases. 067 */ 068 private void checkPhases() { 069 if (VM.VERIFY_ASSERTIONS) { 070 VM.assertions._assert(scheduledSubPhases.length > 0); 071 for (int scheduledPhase: scheduledSubPhases) { 072 VM.assertions._assert(getSchedule(scheduledPhase) > 0); 073 VM.assertions._assert(getPhaseId(scheduledPhase) > 0); 074 } 075 } 076 } 077 078 /** 079 * @return the number of scheduled sub phases. 080 */ 081 protected int count() { 082 return scheduledSubPhases.length; 083 } 084 085 /** 086 * Return an individual scheduled sub phase. 087 * 088 * @param index The index 089 * @return The scheduled phase. 090 */ 091 protected int get(int index) { 092 return scheduledSubPhases[index]; 093 } 094 095 @Override 096 protected void logPhase() { 097 Log.write("ComplexPhase("); 098 Log.write(name); 099 Log.write(", < "); 100 for (int subPhase : scheduledSubPhases) { 101 short ordering = getSchedule(subPhase); 102 short phaseId = getPhaseId(subPhase); 103 Log.write(getScheduleName(ordering)); 104 Log.write("("); 105 Log.write(getName(phaseId)); 106 Log.write(") "); 107 } 108 Log.write(">)"); 109 } 110 111 /** 112 * Replace a scheduled phase. Used for example to replace a placeholder. 113 * 114 * @param oldScheduledPhase The scheduled phase to replace. 115 * @param newScheduledPhase The new scheduled phase. 116 */ 117 public void replacePhase(int oldScheduledPhase, int newScheduledPhase) { 118 for (int i = 0; i < scheduledSubPhases.length; i++) { 119 int scheduledPhase = scheduledSubPhases[i]; 120 if (scheduledPhase == oldScheduledPhase) { 121 /* Replace */ 122 scheduledSubPhases[i] = newScheduledPhase; 123 } else if (getSchedule(scheduledPhase) == SCHEDULE_COMPLEX) { 124 /* Recurse */ 125 ComplexPhase p = (ComplexPhase)getPhase(getPhaseId(scheduledPhase)); 126 p.replacePhase(oldScheduledPhase, newScheduledPhase); 127 } 128 } 129 } 130}