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