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