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.jikesrvm.mm.mminterface; 014 015import static org.jikesrvm.runtime.UnboxedSizeConstants.BYTES_IN_ADDRESS; 016 017import org.jikesrvm.VM; 018import org.jikesrvm.architecture.ArchConstants; 019import org.jikesrvm.compilers.common.CompiledMethod; 020import org.jikesrvm.compilers.common.HardwareTrapGCMapIterator; 021import org.jikesrvm.scheduler.RVMThread; 022import org.vmmagic.pragma.Uninterruptible; 023import org.vmmagic.unboxed.Address; 024import org.vmmagic.unboxed.AddressArray; 025 026/** 027 * Maintains a collection of compiler specific GCMapIterators that are used 028 * by collection threads when scanning thread stacks to locate object references 029 * in those stacks. Each collector thread has its own GCMapIteratorGroup. 030 * <p> 031 * The group contains a GCMapIterator for each type of stack frame that 032 * may be found while scanning a stack during garbage collection, including 033 * frames for baseline compiled methods, OPT compiled methods, and frames 034 * for transitions from Java into JNI native code. These iterators are 035 * responsible for reporting the location of references in the stack or 036 * register save areas. 037 * 038 * @see GCMapIterator 039 * @see CompiledMethod 040 * @see CollectorThread 041 */ 042public final class GCMapIteratorGroup { 043 044 /** current location (memory address) of each gpr register */ 045 private final AddressArray registerLocations; 046 047 /** iterator for baseline compiled frames */ 048 private final GCMapIterator baselineIterator; 049 050 /** iterator for opt compiled frames */ 051 private final GCMapIterator optIterator; 052 053 /** iterator for HardwareTrap stackframes */ 054 private final GCMapIterator hardwareTrapIterator; 055 056 /** iterator for JNI Java -> C stackframes */ 057 private final GCMapIterator jniIterator; 058 059 public GCMapIteratorGroup() { 060 registerLocations = AddressArray.create(ArchConstants.getNumberOfGPRs()); 061 062 if (VM.BuildForIA32) { 063 baselineIterator = new org.jikesrvm.compilers.baseline.ia32.BaselineGCMapIterator(registerLocations); 064 jniIterator = new org.jikesrvm.jni.ia32.JNIGCMapIterator(registerLocations); 065 if (VM.BuildForOptCompiler) { 066 optIterator = new org.jikesrvm.compilers.opt.runtimesupport.ia32.OptGCMapIterator(registerLocations); 067 } else { 068 optIterator = null; 069 } 070 } else { 071 if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC); 072 baselineIterator = new org.jikesrvm.compilers.baseline.ppc.BaselineGCMapIterator(registerLocations); 073 jniIterator = new org.jikesrvm.jni.ppc.JNIGCMapIterator(registerLocations); 074 if (VM.BuildForOptCompiler) { 075 optIterator = new org.jikesrvm.compilers.opt.runtimesupport.ppc.OptGCMapIterator(registerLocations); 076 } else { 077 optIterator = null; 078 } 079 } 080 hardwareTrapIterator = new HardwareTrapGCMapIterator(registerLocations); 081 } 082 083 /** 084 * Prepare to scan a thread's stack for object references. 085 * Called by collector threads when beginning to scan a threads stack. 086 * Calls newStackWalk for each of the contained GCMapIterators. 087 * <p> 088 * Assumption: the thread is currently suspended, ie. its saved gprs[] 089 * contain the thread's full register state. 090 * <p> 091 * Side effect: registerLocations[] initialized with pointers to the 092 * thread's saved gprs[] (in thread.contextRegisters.gprs) 093 * <p> 094 * @param thread Thread whose registers and stack are to be scanned 095 * @param registerLocation start address of the memory location where 096 * register contents are saved 097 */ 098 @Uninterruptible 099 public void newStackWalk(RVMThread thread, Address registerLocation) { 100 for (int i = 0; i < registerLocations.length(); ++i) { 101 registerLocations.set(i, registerLocation); 102 registerLocation = registerLocation.plus(BYTES_IN_ADDRESS); 103 } 104 baselineIterator.newStackWalk(thread); 105 if (VM.BuildForOptCompiler) { 106 optIterator.newStackWalk(thread); 107 } 108 hardwareTrapIterator.newStackWalk(thread); 109 jniIterator.newStackWalk(thread); 110 } 111 112 /** 113 * Select iterator for scanning for object references in a stackframe. 114 * Called by collector threads while scanning a threads stack. 115 * 116 * @param compiledMethod CompiledMethod for the method executing 117 * in the stack frame 118 * 119 * @return GCMapIterator to use 120 */ 121 @Uninterruptible 122 public GCMapIterator selectIterator(CompiledMethod compiledMethod) { 123 switch (compiledMethod.getCompilerType()) { 124 case CompiledMethod.TRAP: 125 return hardwareTrapIterator; 126 case CompiledMethod.BASELINE: 127 return baselineIterator; 128 case CompiledMethod.OPT: 129 return optIterator; 130 case CompiledMethod.JNI: 131 return jniIterator; 132 } 133 if (VM.VerifyAssertions) { 134 VM._assert(VM.NOT_REACHED, "GCMapIteratorGroup.selectIterator: Unknown type of compiled method"); 135 } 136 return null; 137 } 138 139 /** 140 * get the GCMapIterator used for scanning JNI native stack frames. 141 * 142 * @return jniIterator 143 */ 144 @Uninterruptible 145 public GCMapIterator getJniIterator() { 146 if (VM.VerifyAssertions) VM._assert(jniIterator != null); 147 return jniIterator; 148 } 149}