/* * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.max.vm.runtime; import static com.sun.max.lang.Classes.*; import static com.sun.max.platform.Platform.*; import com.sun.max.annotate.*; import com.sun.max.unsafe.*; import com.sun.max.vm.*; import com.sun.max.vm.compiler.target.*; /** * Accessor for the contents of the {@linkplain Stubs#trapStub trap stub's} frame. * It contains the {@linkplain Trap.Number trap number} and the values of the * processor's registers when a trap occurs. * <p> * There is a single {@linkplain MaxineVM#trapFrameAccess instance} of this class * for the current platform. This object is used to access and/or modify a given * trap frame. */ public abstract class TrapFrameAccess { @HOSTED_ONLY public static TrapFrameAccess create() { try { final String isa = platform().isa.name(); final Class<?> c = Class.forName(getPackageName(TrapFrameAccess.class) + "." + isa.toLowerCase() + "." + isa + TrapFrameAccess.class.getSimpleName()); return (TrapFrameAccess) c.newInstance(); } catch (Exception exception) { throw FatalError.unexpected("could not create trapFrameAccess", exception); } } /** * Gets the address of the memory word in a given trap state holding * the program counter denoting instruction causing the trap. * * @param trapFrame the block of memory holding the trap state */ public abstract Pointer getPCPointer(Pointer trapFrame); /** * Gets the program counter denoting instruction causing the trap. * This is also the address to which the trap handler will return * unless the handler unwinds to an exception handler in a method * other than the one that trapped. * * @param trapFrame the block of memory holding the trap state */ public final Pointer getPC(Pointer trapFrame) { return getPCPointer(trapFrame).readWord(0).asPointer(); } /** * Updates the address to which the trap handler will return. * * @param trapFrame the block of memory holding the trap state */ public final void setPC(Pointer trapFrame, Pointer value) { getPCPointer(trapFrame).writeWord(0, value); } /** * Gets the value of the stack pointer at the point of the trap. * * @param trapFrame the block of memory holding the trap state */ public abstract Pointer getSP(Pointer trapFrame); /** * Gets the value of the frame pointer at the point of the trap. * * @param trapFrame the block of memory holding the trap state */ public abstract Pointer getFP(Pointer trapFrame); /** * Gets the value of the safepoint last saved in a given trap frame. * * @param trapFrame the block of memory holding the trap state * @return the value of the safepoint latch at the time the trap denoted by {@code trapFrame} occurred */ public abstract Pointer getSafepointLatch(Pointer trapFrame); /** * Sets the value that will be restored to the safepoint latch when the trap returns. * * @param trapFrame the block of memory holding the trap state */ public abstract void setSafepointLatch(Pointer trapFrame, Pointer value); /** * Gets the value of the {@linkplain Trap.Number trap number} in a given trap frame. * * @param trapFrame the block of memory holding the trap state * @return the value of the trap number in {@code trapFrame} */ public abstract int getTrapNumber(Pointer trapFrame); /** * Gets the address of the callee save area in the trap stub's frame. * * @param trapFrame the trap stub's frame * @return the address of the callee save area within {@code trapFrame} */ public abstract Pointer getCalleeSaveArea(Pointer trapFrame); /** * Sets the value of the {@linkplain Trap.Number trap number} in a given trap frame. * * @param trapFrame the block of memory holding the trap state * @param trapNumber the value to which the trap number in {@code trapFrame} will be set */ public abstract void setTrapNumber(Pointer trapFrame, int trapNumber); /** * Prints the contents of a given trap frame to the VM {@linkplain Log#out log} stream. * This method assumes that the caller holds the {@linkplain Log#lock() lock} on the stream. * * @param trapFrame the block of memory holding the trap state */ public abstract void logTrapFrame(Pointer trapFrame); }