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.vm.VM; 016import org.vmmagic.pragma.*; 017import org.vmmagic.unboxed.*; 018 019/** 020 * This abstract class is the fundamental mechanism for performing a 021 * transitive closure over an object graph.<p> 022 * 023 * Some mechanisms only operate on nodes or edges, but due to limitations 024 * of inheritance we have combined these two here. 025 * 026 * @see org.mmtk.plan.TraceLocal 027 */ 028@Uninterruptible 029public abstract class TransitiveClosure { 030 031 /** Database of specialized scan classes. */ 032 private static final Class<?>[] specializedScans = new Class[VM.activePlan.constraints().numSpecializedScans()]; 033 034 /** 035 * A transitive closure has been created that is designed to work with a specialized scan method. We must 036 * register it here so the specializer can return the class when queried. 037 * 038 * @param id The method id to register. 039 * @param specializedScanClass The class to register. 040 */ 041 @Interruptible 042 public static synchronized void registerSpecializedScan(int id, Class<?> specializedScanClass) { 043 specializedScans[id] = specializedScanClass; 044 } 045 046 /** 047 * Get the specialized scan with the given id. 048 * 049 * @param id the id of the specialized scan 050 * @return the specialized scan class 051 */ 052 public static Class<?> getSpecializedScanClass(int id) { 053 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(specializedScans[id] != null); 054 return specializedScans[id]; 055 } 056 057 /** The specialized scan identifier */ 058 protected final int specializedScan; 059 060 protected TransitiveClosure() { 061 this(-1); 062 } 063 064 /** 065 * Constructor 066 * 067 * @param specializedScan The specialized scan for this trace. 068 */ 069 protected TransitiveClosure(int specializedScan) { 070 this.specializedScan = specializedScan; 071 if (specializedScan >= 0) { 072 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(getClass() == getSpecializedScanClass(specializedScan)); 073 } 074 } 075 076 /** 077 * Trace an edge during GC. 078 * 079 * @param source The source of the reference. 080 * @param slot The location containing the object reference. 081 */ 082 public void processEdge(ObjectReference source, Address slot) { 083 VM.assertions.fail("processEdge not implemented."); 084 } 085 086 /** 087 * Trace a node during GC. 088 * 089 * @param object The object to be processed. 090 */ 091 public void processNode(ObjectReference object) { 092 VM.assertions.fail("processNode not implemented."); 093 } 094}