never@1445: /* stefank@2314: * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. twisti@1814: * Copyright 2008, 2009, 2010 Red Hat, Inc. never@1445: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. never@1445: * never@1445: * This code is free software; you can redistribute it and/or modify it never@1445: * under the terms of the GNU General Public License version 2 only, as never@1445: * published by the Free Software Foundation. never@1445: * never@1445: * This code is distributed in the hope that it will be useful, but WITHOUT never@1445: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or never@1445: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License never@1445: * version 2 for more details (a copy is included in the LICENSE file that never@1445: * accompanied this code). never@1445: * never@1445: * You should have received a copy of the GNU General Public License version never@1445: * 2 along with this work; if not, write to the Free Software Foundation, never@1445: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. never@1445: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. never@1445: * never@1445: */ never@1445: stefank@2314: #ifndef CPU_ZERO_VM_STACK_ZERO_HPP stefank@2314: #define CPU_ZERO_VM_STACK_ZERO_HPP stefank@2314: stefank@2314: #include "utilities/sizes.hpp" stefank@2314: never@1445: class ZeroStack { never@1445: private: never@1445: intptr_t *_base; // the last available word never@1445: intptr_t *_top; // the word past the end of the stack never@1445: intptr_t *_sp; // the top word on the stack never@1445: twisti@1814: private: twisti@1814: int _shadow_pages_size; // how much ABI stack must we keep free? twisti@1814: never@1445: public: never@1445: ZeroStack() twisti@1814: : _base(NULL), _top(NULL), _sp(NULL) { twisti@1814: _shadow_pages_size = StackShadowPages * os::vm_page_size(); twisti@1814: } never@1445: never@1445: bool needs_setup() const { never@1445: return _base == NULL; never@1445: } never@1445: twisti@1866: int suggest_size(Thread *thread) const; twisti@1866: never@1445: void setup(void *mem, size_t size) { never@1445: assert(needs_setup(), "already set up"); never@1445: assert(!(size & WordAlignmentMask), "unaligned"); never@1445: never@1445: _base = (intptr_t *) mem; never@1445: _top = _base + (size >> LogBytesPerWord); never@1445: _sp = _top; never@1445: } never@1445: void teardown() { never@1445: assert(!needs_setup(), "not set up"); never@1445: assert(_sp == _top, "stuff on stack at teardown"); never@1445: never@1445: _base = NULL; never@1445: _top = NULL; never@1445: _sp = NULL; never@1445: } never@1445: never@1445: intptr_t *sp() const { never@1445: return _sp; never@1445: } never@1445: void set_sp(intptr_t *new_sp) { never@1445: assert(_top >= new_sp && new_sp >= _base, "bad stack pointer"); never@1445: _sp = new_sp; never@1445: } never@1445: twisti@1866: int total_words() const { twisti@1866: return _top - _base; twisti@1866: } never@1445: int available_words() const { never@1445: return _sp - _base; never@1445: } never@1445: never@1445: void push(intptr_t value) { never@1445: assert(_sp > _base, "stack overflow"); never@1445: *(--_sp) = value; never@1445: } never@1445: intptr_t pop() { never@1445: assert(_sp < _top, "stack underflow"); never@1445: return *(_sp++); never@1445: } never@1445: never@1445: void *alloc(size_t size) { never@1445: int count = align_size_up(size, wordSize) >> LogBytesPerWord; never@1445: assert(count <= available_words(), "stack overflow"); never@1445: return _sp -= count; never@1445: } never@1445: twisti@1814: int shadow_pages_size() const { twisti@1814: return _shadow_pages_size; twisti@1814: } twisti@1866: int abi_stack_available(Thread *thread) const; twisti@1814: twisti@1814: public: twisti@1814: void overflow_check(int required_words, TRAPS); twisti@1814: static void handle_overflow(TRAPS); twisti@1814: never@1445: public: twisti@1860: void zap(int c) PRODUCT_RETURN; twisti@1860: twisti@1860: public: never@1445: static ByteSize base_offset() { never@1445: return byte_offset_of(ZeroStack, _base); never@1445: } never@1445: static ByteSize top_offset() { never@1445: return byte_offset_of(ZeroStack, _top); never@1445: } never@1445: static ByteSize sp_offset() { never@1445: return byte_offset_of(ZeroStack, _sp); never@1445: } never@1445: }; never@1445: never@1445: never@1445: class EntryFrame; never@1445: class InterpreterFrame; never@1445: class SharkFrame; never@1445: class FakeStubFrame; never@1445: never@1445: // never@1445: // | ... | never@1445: // +--------------------+ ------------------ never@1445: // | ... | low addresses never@1445: // | frame_type | never@1445: // | next_frame | high addresses never@1445: // +--------------------+ ------------------ never@1445: // | ... | never@1445: never@1445: class ZeroFrame { never@1445: friend class frame; never@1445: friend class ZeroStackPrinter; never@1445: never@1445: protected: never@1445: ZeroFrame() { never@1445: ShouldNotCallThis(); never@1445: } never@1445: never@1445: enum Layout { never@1445: next_frame_off, never@1445: frame_type_off, never@1445: jf_header_words never@1445: }; never@1445: never@1445: enum FrameType { never@1445: ENTRY_FRAME = 1, never@1445: INTERPRETER_FRAME, never@1445: SHARK_FRAME, never@1445: FAKE_STUB_FRAME never@1445: }; never@1445: never@1445: protected: never@1445: intptr_t *addr_of_word(int offset) const { never@1445: return (intptr_t *) this - offset; never@1445: } never@1445: intptr_t value_of_word(int offset) const { never@1445: return *addr_of_word(offset); never@1445: } never@1445: never@1445: public: never@1445: ZeroFrame *next() const { never@1445: return (ZeroFrame *) value_of_word(next_frame_off); never@1445: } never@1445: never@1445: protected: never@1445: FrameType type() const { never@1445: return (FrameType) value_of_word(frame_type_off); never@1445: } never@1445: never@1445: public: never@1445: bool is_entry_frame() const { never@1445: return type() == ENTRY_FRAME; never@1445: } never@1445: bool is_interpreter_frame() const { never@1445: return type() == INTERPRETER_FRAME; never@1445: } never@1445: bool is_shark_frame() const { never@1445: return type() == SHARK_FRAME; never@1445: } never@1445: bool is_fake_stub_frame() const { never@1445: return type() == FAKE_STUB_FRAME; never@1445: } never@1445: never@1445: public: never@1445: EntryFrame *as_entry_frame() const { never@1445: assert(is_entry_frame(), "should be"); never@1445: return (EntryFrame *) this; never@1445: } never@1445: InterpreterFrame *as_interpreter_frame() const { never@1445: assert(is_interpreter_frame(), "should be"); never@1445: return (InterpreterFrame *) this; never@1445: } never@1445: SharkFrame *as_shark_frame() const { never@1445: assert(is_shark_frame(), "should be"); never@1445: return (SharkFrame *) this; never@1445: } never@1445: FakeStubFrame *as_fake_stub_frame() const { never@1445: assert(is_fake_stub_frame(), "should be"); never@1445: return (FakeStubFrame *) this; never@1445: } never@1445: never@1445: public: never@1445: void identify_word(int frame_index, never@1445: int offset, never@1445: char* fieldbuf, never@1445: char* valuebuf, never@1445: int buflen) const; never@1445: never@1445: protected: never@1445: void identify_vp_word(int frame_index, never@1445: intptr_t* addr, never@1445: intptr_t* monitor_base, never@1445: intptr_t* stack_base, never@1445: char* fieldbuf, never@1445: int buflen) const; never@1445: }; stefank@2314: stefank@2314: #endif // CPU_ZERO_VM_STACK_ZERO_HPP