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