StackFrameStream.java revision 9883:903a2e023ffb
1/* 2 * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25package sun.jvm.hotspot.runtime; 26 27import sun.jvm.hotspot.utilities.*; 28 29/** <P> StackFrameStream iterates through the frames of a thread 30 starting from top most frame. It automatically takes care of 31 updating the location of all (callee-saved) registers. Notice: If 32 a thread is stopped at a safepoint, all registers are saved, not 33 only the callee-saved ones. </P> 34 35 <P> Use: </P> 36 37 <PRE> 38 for(StackFrameStream fst = new StackFrameStream(thread); !fst.isDone(); fst.next()) { 39 ... 40 } 41 </PRE> 42*/ 43 44public class StackFrameStream { 45 private Frame fr; 46 private RegisterMap regMap; 47 private boolean isDone; 48 49 /** Equivalent to StackFrameStream(thread, true) */ 50 public StackFrameStream(JavaThread thread) { 51 this(thread, true); 52 } 53 54 public StackFrameStream(JavaThread thread, boolean update) { 55 if (!VM.getVM().isDebugging()) { 56 if (Assert.ASSERTS_ENABLED) { 57 Assert.that(thread.hasLastJavaFrame(), "sanity check"); 58 } 59 fr = thread.getLastFrame(); 60 regMap = thread.newRegisterMap(update); 61 isDone = false; 62 } else { 63 // Special case code to find the topmost Java frame 64 // FIXME: should check to see whether we're at safepoint, and if 65 // so, skip the "current frame guess" call and unnecessary 66 // stackwalking work 67 fr = thread.getCurrentFrameGuess(); 68 regMap = thread.newRegisterMap(update); 69 while ((fr != null) && (!fr.isJavaFrame())) { 70 if (fr.isFirstFrame()) { 71 fr = null; 72 } else { 73 fr = fr.sender(regMap); 74 } 75 } 76 if (fr == null) { 77 isDone = true; 78 } 79 } 80 } 81 82 /** Iteration */ 83 public boolean isDone() { 84 if (isDone) { 85 return true; 86 } else { 87 if (fr == null) { 88 isDone = true; 89 return true; 90 } 91 isDone = fr.isFirstFrame(); 92 return false; 93 } 94 } 95 96 public void next() { 97 if (!isDone) { 98 fr = fr.sender(regMap); 99 } 100 } 101 102 /** Query */ 103 public Frame getCurrent() { return fr; } 104 public RegisterMap getRegisterMap() { return regMap; } 105} 106