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.concurrent; 014 015import org.mmtk.plan.Phase; 016import org.mmtk.plan.Simple; 017import org.mmtk.utility.Log; 018import org.mmtk.utility.options.ConcurrentTrigger; 019import org.mmtk.utility.options.Options; 020 021import org.vmmagic.pragma.*; 022 023/** 024 * This class implements the global state of a concurrent collector. 025 */ 026@Uninterruptible 027public abstract class Concurrent extends Simple { 028 029 /**************************************************************************** 030 * Constants 031 */ 032 033 /**************************************************************************** 034 * Class variables 035 */ 036 037 /** 038 * 039 */ 040 public static final short FLUSH_MUTATOR = Phase.createSimple("flush-mutator", null); 041 public static final short SET_BARRIER_ACTIVE = Phase.createSimple("set-barrier", null); 042 public static final short FLUSH_COLLECTOR = Phase.createSimple("flush-collector", null); 043 public static final short CLEAR_BARRIER_ACTIVE = Phase.createSimple("clear-barrier", null); 044 045 // CHECKSTYLE:OFF 046 047 /** 048 * When we preempt a concurrent marking phase we must flush mutators and then continue the closure. 049 */ 050 protected static final short preemptConcurrentClosure = Phase.createComplex("preeempt-concurrent-trace", null, 051 Phase.scheduleMutator (FLUSH_MUTATOR), 052 Phase.scheduleCollector(CLOSURE)); 053 054 public static final short CONCURRENT_CLOSURE = Phase.createConcurrent("concurrent-closure", 055 Phase.scheduleComplex(preemptConcurrentClosure)); 056 057 /** 058 * Perform the initial determination of liveness from the roots. 059 */ 060 protected static final short concurrentClosure = Phase.createComplex("concurrent-mark", null, 061 Phase.scheduleGlobal (SET_BARRIER_ACTIVE), 062 Phase.scheduleMutator (SET_BARRIER_ACTIVE), 063 Phase.scheduleCollector (FLUSH_COLLECTOR), 064 Phase.scheduleConcurrent(CONCURRENT_CLOSURE), 065 Phase.scheduleGlobal (CLEAR_BARRIER_ACTIVE), 066 Phase.scheduleMutator (CLEAR_BARRIER_ACTIVE)); 067 068 /** Build, validate and then build another sanity table */ 069 protected static final short preSanityPhase = Phase.createComplex("sanity", null, 070 Phase.scheduleComplex (sanityBuildPhase), 071 Phase.scheduleGlobal (SANITY_SET_PREGC), 072 Phase.scheduleComplex (sanityCheckPhase), 073 Phase.scheduleComplex (sanityBuildPhase)); 074 075 /** Validate, build and validate the second sanity table */ 076 protected static final short postSanityPhase = Phase.createComplex("sanity", null, 077 Phase.scheduleGlobal (SANITY_SET_POSTGC), 078 Phase.scheduleComplex (sanityCheckPhase), 079 Phase.scheduleComplex (sanityBuildPhase), 080 Phase.scheduleGlobal (SANITY_SET_PREGC), 081 Phase.scheduleComplex (sanityCheckPhase)); 082 083 // CHECKSTYLE:OFF 084 085 /**************************************************************************** 086 * Instance variables 087 */ 088 089 /**************************************************************************** 090 * Constructor. 091 */ 092 public Concurrent() { 093 Options.concurrentTrigger = new ConcurrentTrigger(); 094 } 095 096 /***************************************************************************** 097 * 098 * Collection 099 */ 100 101 /** 102 * {@inheritDoc} 103 */ 104 @Override 105 @Interruptible 106 public void processOptions() { 107 super.processOptions(); 108 109 /* Set up the concurrent marking phase */ 110 replacePhase(Phase.scheduleCollector(CLOSURE), Phase.scheduleComplex(concurrentClosure)); 111 112 if (Options.sanityCheck.getValue()) { 113 Log.writeln("Collection sanity checking enabled."); 114 replacePhase(Phase.schedulePlaceholder(PRE_SANITY_PLACEHOLDER), Phase.scheduleComplex(preSanityPhase)); 115 replacePhase(Phase.schedulePlaceholder(POST_SANITY_PLACEHOLDER), Phase.scheduleComplex(postSanityPhase)); 116 } 117 } 118 119 /**************************************************************************** 120 * 121 * Collection 122 */ 123 124 /** 125 * 126 */ 127 private boolean inConcurrentCollection = false; 128 129 @Override 130 @Inline 131 public void collectionPhase(short phaseId) { 132 if (phaseId == SET_BARRIER_ACTIVE) { 133 ConcurrentMutator.newMutatorBarrierActive = true; 134 return; 135 } 136 if (phaseId == CLEAR_BARRIER_ACTIVE) { 137 ConcurrentMutator.newMutatorBarrierActive = false; 138 return; 139 } 140 if (phaseId == CLOSURE) { 141 return; 142 } 143 if (phaseId == PREPARE) { 144 inConcurrentCollection = true; 145 } 146 if (phaseId == RELEASE) { 147 inConcurrentCollection = false; 148 } 149 super.collectionPhase(phaseId); 150 } 151 152 @Override 153 protected boolean concurrentCollectionRequired() { 154 return !Phase.concurrentPhaseActive() && 155 ((getPagesReserved() * 100) / getTotalPages()) > Options.concurrentTrigger.getValue(); 156 } 157 158 @Override 159 public boolean lastCollectionFullHeap() { 160 // TODO: Why this? 161 return !inConcurrentCollection; 162 } 163 164 /***************************************************************************** 165 * 166 * Accounting 167 */ 168}