1 /*
2  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3  * Copyright 2008, 2009, 2010 Red Hat, Inc.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.
9  *
10  * This code is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * version 2 for more details (a copy is included in the LICENSE file that
14  * accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License version
17  * 2 along with this work; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21  * or visit www.oracle.com if you need additional information or have any
22  * questions.
23  *
24  */
25 
26 #ifndef CPU_ZERO_VM_STACK_ZERO_HPP
27 #define CPU_ZERO_VM_STACK_ZERO_HPP
28 
29 #include "utilities/sizes.hpp"
30 
31 class ZeroStack {
32  private:
33   intptr_t *_base; // the last available word
34   intptr_t *_top;  // the word past the end of the stack
35   intptr_t *_sp;   // the top word on the stack
36 
37  private:
38   int _shadow_pages_size; // how much ABI stack must we keep free?
39 
40  public:
ZeroStack()41   ZeroStack()
42     : _base(NULL), _top(NULL), _sp(NULL) {
43     _shadow_pages_size = StackShadowPages * os::vm_page_size();
44   }
45 
needs_setup() const46   bool needs_setup() const {
47     return _base == NULL;
48   }
49 
50   int suggest_size(Thread *thread) const;
51 
setup(void * mem,size_t size)52   void setup(void *mem, size_t size) {
53     assert(needs_setup(), "already set up");
54     assert(!(size & WordAlignmentMask), "unaligned");
55 
56     _base = (intptr_t *) mem;
57     _top  = _base + (size >> LogBytesPerWord);
58     _sp   = _top;
59   }
teardown()60   void teardown() {
61     assert(!needs_setup(), "not set up");
62     assert(_sp == _top, "stuff on stack at teardown");
63 
64     _base = NULL;
65     _top  = NULL;
66     _sp   = NULL;
67   }
68 
sp() const69   intptr_t *sp() const {
70     return _sp;
71   }
set_sp(intptr_t * new_sp)72   void set_sp(intptr_t *new_sp) {
73     assert(_top >= new_sp && new_sp >= _base, "bad stack pointer");
74     _sp = new_sp;
75   }
76 
total_words() const77   int total_words() const {
78     return _top - _base;
79   }
available_words() const80   int available_words() const {
81     return _sp - _base;
82   }
83 
push(intptr_t value)84   void push(intptr_t value) {
85     assert(_sp > _base, "stack overflow");
86     *(--_sp) = value;
87   }
pop()88   intptr_t pop() {
89     assert(_sp < _top, "stack underflow");
90     return *(_sp++);
91   }
92 
alloc(size_t size)93   void *alloc(size_t size) {
94     int count = align_size_up(size, wordSize) >> LogBytesPerWord;
95     assert(count <= available_words(), "stack overflow");
96     return _sp -= count;
97   }
98 
shadow_pages_size() const99   int shadow_pages_size() const {
100     return _shadow_pages_size;
101   }
102   int abi_stack_available(Thread *thread) const;
103 
104  public:
105   void overflow_check(int required_words, TRAPS);
106   static void handle_overflow(TRAPS);
107 
108  public:
109   void zap(int c) PRODUCT_RETURN;
110 
111  public:
base_offset()112   static ByteSize base_offset() {
113     return byte_offset_of(ZeroStack, _base);
114   }
top_offset()115   static ByteSize top_offset() {
116     return byte_offset_of(ZeroStack, _top);
117   }
sp_offset()118   static ByteSize sp_offset() {
119     return byte_offset_of(ZeroStack, _sp);
120   }
121 };
122 
123 
124 class EntryFrame;
125 class InterpreterFrame;
126 class SharkFrame;
127 class FakeStubFrame;
128 
129 //
130 // |  ...               |
131 // +--------------------+  ------------------
132 // |  ...               |       low addresses
133 // | frame_type         |
134 // | next_frame         |      high addresses
135 // +--------------------+  ------------------
136 // |  ...               |
137 
138 class ZeroFrame {
139   friend class frame;
140   friend class ZeroStackPrinter;
141 
142  protected:
ZeroFrame()143   ZeroFrame() {
144     ShouldNotCallThis();
145   }
146 
147   enum Layout {
148     next_frame_off,
149     frame_type_off,
150     jf_header_words
151   };
152 
153   enum FrameType {
154     ENTRY_FRAME = 1,
155     INTERPRETER_FRAME,
156     SHARK_FRAME,
157     FAKE_STUB_FRAME
158   };
159 
160  protected:
addr_of_word(int offset) const161   intptr_t *addr_of_word(int offset) const {
162     return (intptr_t *) this - offset;
163   }
value_of_word(int offset) const164   intptr_t value_of_word(int offset) const {
165     return *addr_of_word(offset);
166   }
167 
168  public:
next() const169   ZeroFrame *next() const {
170     return (ZeroFrame *) value_of_word(next_frame_off);
171   }
172 
173  protected:
type() const174   FrameType type() const {
175     return (FrameType) value_of_word(frame_type_off);
176   }
177 
178  public:
is_entry_frame() const179   bool is_entry_frame() const {
180     return type() == ENTRY_FRAME;
181   }
is_interpreter_frame() const182   bool is_interpreter_frame() const {
183     return type() == INTERPRETER_FRAME;
184   }
is_shark_frame() const185   bool is_shark_frame() const {
186     return type() == SHARK_FRAME;
187   }
is_fake_stub_frame() const188   bool is_fake_stub_frame() const {
189     return type() == FAKE_STUB_FRAME;
190   }
191 
192  public:
as_entry_frame() const193   EntryFrame *as_entry_frame() const {
194     assert(is_entry_frame(), "should be");
195     return (EntryFrame *) this;
196   }
as_interpreter_frame() const197   InterpreterFrame *as_interpreter_frame() const {
198     assert(is_interpreter_frame(), "should be");
199     return (InterpreterFrame *) this;
200   }
as_shark_frame() const201   SharkFrame *as_shark_frame() const {
202     assert(is_shark_frame(), "should be");
203     return (SharkFrame *) this;
204   }
as_fake_stub_frame() const205   FakeStubFrame *as_fake_stub_frame() const {
206     assert(is_fake_stub_frame(), "should be");
207     return (FakeStubFrame *) this;
208   }
209 
210  public:
211   void identify_word(int   frame_index,
212                      int   offset,
213                      char* fieldbuf,
214                      char* valuebuf,
215                      int   buflen) const;
216 
217  protected:
218   void identify_vp_word(int       frame_index,
219                         intptr_t* addr,
220                         intptr_t* monitor_base,
221                         intptr_t* stack_base,
222                         char*     fieldbuf,
223                         int       buflen) const;
224 };
225 
226 #endif // CPU_ZERO_VM_STACK_ZERO_HPP
227