/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.mm.mminterface; import org.jikesrvm.ArchitectureSpecific; import org.jikesrvm.ArchitectureSpecific.BaselineGCMapIterator; import org.jikesrvm.ArchitectureSpecific.JNIGCMapIterator; import org.jikesrvm.ArchitectureSpecificOpt.OptGCMapIterator; import org.jikesrvm.VM; import org.jikesrvm.SizeConstants; import org.jikesrvm.compilers.common.CompiledMethod; import org.jikesrvm.compilers.common.HardwareTrapGCMapIterator; import org.jikesrvm.scheduler.RVMThread; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.WordArray; /** * Maintains a collection of compiler specific GCMapIterators that are used * by collection threads when scanning thread stacks to locate object references * in those stacks. Each collector thread has its own GCMapIteratorGroup. * * The group contains a GCMapIterator for each type of stack frame that * may be found while scanning a stack during garbage collection, including * frames for baseline compiled methods, OPT compiled methods, and frames * for transitions from Java into JNI native code. These iterators are * repsonsible for reporting the location of references in the stack or * register save areas. * * @see GCMapIterator * @see CompiledMethod * @see CollectorThread */ public final class GCMapIteratorGroup implements SizeConstants { /** current location (memory address) of each gpr register */ private final WordArray registerLocations; /** iterator for baseline compiled frames */ private final GCMapIterator baselineIterator; /** iterator for opt compiled frames */ private final GCMapIterator optIterator; /** iterator for HardwareTrap stackframes */ private final GCMapIterator hardwareTrapIterator; /** iterator for JNI Java -> C stackframes */ private final GCMapIterator jniIterator; public GCMapIteratorGroup() { registerLocations = WordArray.create(ArchitectureSpecific.ArchConstants.NUM_GPRS); baselineIterator = new BaselineGCMapIterator(registerLocations); if (VM.BuildForOptCompiler) { optIterator = new OptGCMapIterator(registerLocations); } else { optIterator = null; } jniIterator = new JNIGCMapIterator(registerLocations); hardwareTrapIterator = new HardwareTrapGCMapIterator(registerLocations); } /** * Prepare to scan a thread's stack for object references. * Called by collector threads when beginning to scan a threads stack. * Calls newStackWalk for each of the contained GCMapIterators. * <p> * Assumption: the thread is currently suspended, ie. its saved gprs[] * contain the thread's full register state. * <p> * Side effect: registerLocations[] initialized with pointers to the * thread's saved gprs[] (in thread.contextRegisters.gprs) * <p> * @param thread Thread whose registers and stack are to be scanned */ @Uninterruptible public void newStackWalk(RVMThread thread, Address registerLocation) { for (int i = 0; i < ArchitectureSpecific.ArchConstants.NUM_GPRS; ++i) { registerLocations.set(i, registerLocation.toWord()); registerLocation = registerLocation.plus(BYTES_IN_ADDRESS); } baselineIterator.newStackWalk(thread); if (VM.BuildForOptCompiler) { optIterator.newStackWalk(thread); } hardwareTrapIterator.newStackWalk(thread); jniIterator.newStackWalk(thread); } /** * Select iterator for scanning for object references in a stackframe. * Called by collector threads while scanning a threads stack. * * @param compiledMethod CompiledMethod for the method executing * in the stack frame * * @return GCMapIterator to use */ @Uninterruptible public GCMapIterator selectIterator(CompiledMethod compiledMethod) { switch (compiledMethod.getCompilerType()) { case CompiledMethod.TRAP: return hardwareTrapIterator; case CompiledMethod.BASELINE: return baselineIterator; case CompiledMethod.OPT: return optIterator; case CompiledMethod.JNI: return jniIterator; } if (VM.VerifyAssertions) { VM._assert(false, "GCMapIteratorGroup.selectIterator: Unknown type of compiled method"); } return null; } /** * get the GCMapIterator used for scanning JNI native stack frames. * * @return jniIterator */ @Uninterruptible public GCMapIterator getJniIterator() { if (VM.VerifyAssertions) VM._assert(jniIterator != null); return jniIterator; } }