/* * 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 static org.jikesrvm.runtime.UnboxedSizeConstants.BYTES_IN_ADDRESS; import org.jikesrvm.VM; import org.jikesrvm.architecture.ArchConstants; 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.AddressArray; /** * 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. * <p> * 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 * responsible for reporting the location of references in the stack or * register save areas. * * @see GCMapIterator * @see CompiledMethod * @see CollectorThread */ public final class GCMapIteratorGroup { /** current location (memory address) of each gpr register */ private final AddressArray 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 = AddressArray.create(ArchConstants.getNumberOfGPRs()); if (VM.BuildForIA32) { baselineIterator = new org.jikesrvm.compilers.baseline.ia32.BaselineGCMapIterator(registerLocations); jniIterator = new org.jikesrvm.jni.ia32.JNIGCMapIterator(registerLocations); if (VM.BuildForOptCompiler) { optIterator = new org.jikesrvm.compilers.opt.runtimesupport.ia32.OptGCMapIterator(registerLocations); } else { optIterator = null; } } else { if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC); baselineIterator = new org.jikesrvm.compilers.baseline.ppc.BaselineGCMapIterator(registerLocations); jniIterator = new org.jikesrvm.jni.ppc.JNIGCMapIterator(registerLocations); if (VM.BuildForOptCompiler) { optIterator = new org.jikesrvm.compilers.opt.runtimesupport.ppc.OptGCMapIterator(registerLocations); } else { optIterator = null; } } 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 * @param registerLocation start address of the memory location where * register contents are saved */ @Uninterruptible public void newStackWalk(RVMThread thread, Address registerLocation) { for (int i = 0; i < registerLocations.length(); ++i) { registerLocations.set(i, registerLocation); 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(VM.NOT_REACHED, "GCMapIteratorGroup.selectIterator: Unknown type of compiled method"); } return null; } }