stack_zero.hpp revision 1472:c18cbe5936b8
1/* 2 * Copyright (c) 2003, 2007, 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 26class ZeroStack { 27 private: 28 intptr_t *_base; // the last available word 29 intptr_t *_top; // the word past the end of the stack 30 intptr_t *_sp; // the top word on the stack 31 32 private: 33 int _shadow_pages_size; // how much ABI stack must we keep free? 34 35 public: 36 ZeroStack() 37 : _base(NULL), _top(NULL), _sp(NULL) { 38 _shadow_pages_size = StackShadowPages * os::vm_page_size(); 39 } 40 41 bool needs_setup() const { 42 return _base == NULL; 43 } 44 45 int suggest_size(Thread *thread) const; 46 47 void setup(void *mem, size_t size) { 48 assert(needs_setup(), "already set up"); 49 assert(!(size & WordAlignmentMask), "unaligned"); 50 51 _base = (intptr_t *) mem; 52 _top = _base + (size >> LogBytesPerWord); 53 _sp = _top; 54 } 55 void teardown() { 56 assert(!needs_setup(), "not set up"); 57 assert(_sp == _top, "stuff on stack at teardown"); 58 59 _base = NULL; 60 _top = NULL; 61 _sp = NULL; 62 } 63 64 intptr_t *sp() const { 65 return _sp; 66 } 67 void set_sp(intptr_t *new_sp) { 68 assert(_top >= new_sp && new_sp >= _base, "bad stack pointer"); 69 _sp = new_sp; 70 } 71 72 int total_words() const { 73 return _top - _base; 74 } 75 int available_words() const { 76 return _sp - _base; 77 } 78 79 void push(intptr_t value) { 80 assert(_sp > _base, "stack overflow"); 81 *(--_sp) = value; 82 } 83 intptr_t pop() { 84 assert(_sp < _top, "stack underflow"); 85 return *(_sp++); 86 } 87 88 void *alloc(size_t size) { 89 int count = align_size_up(size, wordSize) >> LogBytesPerWord; 90 assert(count <= available_words(), "stack overflow"); 91 return _sp -= count; 92 } 93 94 int shadow_pages_size() const { 95 return _shadow_pages_size; 96 } 97 int abi_stack_available(Thread *thread) const; 98 99 public: 100 void overflow_check(int required_words, TRAPS); 101 static void handle_overflow(TRAPS); 102 103 public: 104 void zap(int c) PRODUCT_RETURN; 105 106 public: 107 static ByteSize base_offset() { 108 return byte_offset_of(ZeroStack, _base); 109 } 110 static ByteSize top_offset() { 111 return byte_offset_of(ZeroStack, _top); 112 } 113 static ByteSize sp_offset() { 114 return byte_offset_of(ZeroStack, _sp); 115 } 116}; 117 118 119class EntryFrame; 120class InterpreterFrame; 121class SharkFrame; 122class FakeStubFrame; 123 124// 125// | ... | 126// +--------------------+ ------------------ 127// | ... | low addresses 128// | frame_type | 129// | next_frame | high addresses 130// +--------------------+ ------------------ 131// | ... | 132 133class ZeroFrame { 134 friend class frame; 135 friend class ZeroStackPrinter; 136 137 protected: 138 ZeroFrame() { 139 ShouldNotCallThis(); 140 } 141 142 enum Layout { 143 next_frame_off, 144 frame_type_off, 145 jf_header_words 146 }; 147 148 enum FrameType { 149 ENTRY_FRAME = 1, 150 INTERPRETER_FRAME, 151 SHARK_FRAME, 152 FAKE_STUB_FRAME 153 }; 154 155 protected: 156 intptr_t *addr_of_word(int offset) const { 157 return (intptr_t *) this - offset; 158 } 159 intptr_t value_of_word(int offset) const { 160 return *addr_of_word(offset); 161 } 162 163 public: 164 ZeroFrame *next() const { 165 return (ZeroFrame *) value_of_word(next_frame_off); 166 } 167 168 protected: 169 FrameType type() const { 170 return (FrameType) value_of_word(frame_type_off); 171 } 172 173 public: 174 bool is_entry_frame() const { 175 return type() == ENTRY_FRAME; 176 } 177 bool is_interpreter_frame() const { 178 return type() == INTERPRETER_FRAME; 179 } 180 bool is_shark_frame() const { 181 return type() == SHARK_FRAME; 182 } 183 bool is_fake_stub_frame() const { 184 return type() == FAKE_STUB_FRAME; 185 } 186 187 public: 188 EntryFrame *as_entry_frame() const { 189 assert(is_entry_frame(), "should be"); 190 return (EntryFrame *) this; 191 } 192 InterpreterFrame *as_interpreter_frame() const { 193 assert(is_interpreter_frame(), "should be"); 194 return (InterpreterFrame *) this; 195 } 196 SharkFrame *as_shark_frame() const { 197 assert(is_shark_frame(), "should be"); 198 return (SharkFrame *) this; 199 } 200 FakeStubFrame *as_fake_stub_frame() const { 201 assert(is_fake_stub_frame(), "should be"); 202 return (FakeStubFrame *) this; 203 } 204 205 public: 206 void identify_word(int frame_index, 207 int offset, 208 char* fieldbuf, 209 char* valuebuf, 210 int buflen) const; 211 212 protected: 213 void identify_vp_word(int frame_index, 214 intptr_t* addr, 215 intptr_t* monitor_base, 216 intptr_t* stack_base, 217 char* fieldbuf, 218 int buflen) const; 219}; 220