/* * Copyright (c) 2007, 2012, 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.stack; import com.sun.max.annotate.*; import com.sun.max.unsafe.*; import com.sun.max.vm.compiler.target.*; /** * A {@code StackFrame} object abstracts an activation frame on a call stack. * * TODO (Michael H) consider moving this class to tele, as it is only ever used in Inspector contexts. * For the time being, it is instead annotated with {@link HOSTED_ONLY}. */ @HOSTED_ONLY public abstract class StackFrame { /** * An address indicating (but not necessarily equal to) the next instruction to be executed in this frame. */ public final Pointer ip; public final Pointer sp; public final Pointer fp; public final StackFrame callee; private StackFrame caller; protected StackFrame(StackFrame callee, Pointer ip, Pointer sp, Pointer fp) { this.callee = callee; if (callee != null) { callee.caller = this; } this.ip = ip; this.fp = fp; this.sp = sp; } /** * Gets the target method enclosing the {@linkplain #ip execution point} in this frame. * * @return null if this is a frame of a native function */ public TargetMethod targetMethod() { return null; } /** * Gets the base address of all stack slots. This provides a convenience for stack frame visitors that need to see all stack slot as * located at a positive offset from some base pointer (e.g., stack inspectors etc...) * By default this is the frame pointer. */ public Pointer slotBase() { return fp; } /** * Computes the biased offset from the slot base to the ABI's frame pointer register. * <br> * Some platforms (e.g., Solaris SPARC v9 in 64-bit mode) use a bias from the frame pointer to access stack slot. * <br> * The default is no bias, but the offset must be adjusted by frame size to be relative to the frame pointer. * * @param offset a offset relative to the address of the stack pointer * @return the biased offset, relative to the frame pointer register. */ public Offset biasedFPOffset(Offset offset) { if (targetMethod() != null) { return offset.minus(targetMethod().frameSize()); } return offset; } /** * Returns the stack bias used by the stack frame. By default, it returns {@link StackBias#NONE}. * @return a stack bias. */ public StackBias bias() { return StackBias.NONE; } /** * Gets the frame called by this frame. * * @return null if this is the {@linkplain #isTopFrame() top} frame */ public final StackFrame calleeFrame() { return callee; } /** * Gets the frame from which this frame was called. * * @return null if this is the bottom frame (i.e. the last frame traversed in a {@linkplain StackFrameWalker stack walk}). */ public final StackFrame callerFrame() { return caller; } /** * Determines if this is the top frame. The top frame is the first frame traversed in a {@linkplain StackFrameWalker stack walk}. */ public boolean isTopFrame() { return callee == null; } /** * Indicates if a given stack frame denotes the same frame as this object. */ public abstract boolean isSameFrame(StackFrame stackFrame); @Override public abstract String toString(); }