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 *
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 * repsonsible 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(false, "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 }