View Javadoc
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  
25  package sun.jvm.hotspot.runtime;
26  
27  import 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  
44  public 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 }