/* * 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.runtime; import org.jikesrvm.architecture.AbstractRegisters; import org.jikesrvm.compilers.common.CompiledMethod; import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Address; /** * Interface for exception delivery called by RuntimeEntrypoints.deliverException() to * pass control to a stackframe whose method has an appropriate "catch" block * or to step over a stackframe that does not have an appropriate catch block. * <p> * The exception delivery implementation is specific to the compiler * that generated the method's machine instructions. * <p> * Note that the "deliverException" and "unwindStackFrame" methods of this * class will be called in an environment that does not permit garbage * collection: see VM.disableGC(). * We must do this because some of the parameters to these methods are raw * machine addresses. They are not recognized by the garbage collector as * Object references and so would not be correctly fixed up in the event of * object motion during GC. As a * consequence, implementors of these methods must not cause object allocations * to take place (i.e. by calling "new" either directly or indirectly). */ public abstract class ExceptionDeliverer { /** * Stackframe's method has a "catch" block for exception being * thrown and control is to be passed to that catch block. * * <p> Note: * Implementers must issue the following two lines just before * transferring control to the catch block: * * <pre> * VM.enableGC(); * registers.inuse = false; * </pre> * * <p> Note: this method does not return * (execution resumes at catchBlockInstructionAddress) * * @param compiledMethod method whose catch block is to receive control * @param catchBlockInstructionAddress instruction address at which * to begin execution of catch block * @param exceptionObject exception object to be passed as argument to * catch block * @param registers registers to be loaded before passing control to * catch block */ @Unpreemptible("Deliver exception possibly from unpreemptible code") public abstract void deliverException(CompiledMethod compiledMethod, Address catchBlockInstructionAddress, Throwable exceptionObject, AbstractRegisters registers); /** * Stackframe's method has no "catch" block for exception being thrown * and stackframe is to be "unwound" as follows: * * <ul> * <li> 1. for a synchronized method, call ObjectModel.genericUnlock(), * passing it the appropriate "lock" object * <ul> * <li>for non-static methods, the lock is the method's * first argument ("this") * <li>for static methods, the lock is the method's java.lang.Class * </ul> * * <li> 2. restore the non-volatile registers (including fp) that were saved * in the method's prologue, by copying them from the method's stackframe * save area into the provided "registers" object * </ul> * * @param compiledMethod method whose stackframe is to be unwound * @param registers thread state to be updated by restoring non-volatiles * and unwinding the stackframe */ @Unpreemptible("Unwind stack possibly from unpreemptible code") public abstract void unwindStackFrame(CompiledMethod compiledMethod, AbstractRegisters registers); }