duke@435: /* duke@435: * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * duke@435: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@435: * CA 95054 USA or visit www.sun.com if you need additional information or duke@435: * have any questions. duke@435: * duke@435: */ duke@435: twisti@1040: // This file contains the platform-independent parts duke@435: // of the interpreter and the interpreter generator. duke@435: duke@435: //------------------------------------------------------------------------------------------------------------------------ duke@435: // An InterpreterCodelet is a piece of interpreter code. All duke@435: // interpreter code is generated into little codelets which duke@435: // contain extra information for debugging and printing purposes. duke@435: duke@435: class InterpreterCodelet: public Stub { duke@435: friend class VMStructs; duke@435: private: duke@435: int _size; // the size in bytes duke@435: const char* _description; // a description of the codelet, for debugging & printing duke@435: Bytecodes::Code _bytecode; // associated bytecode if any duke@435: duke@435: public: duke@435: // Initialization/finalization duke@435: void initialize(int size) { _size = size; } duke@435: void finalize() { ShouldNotCallThis(); } duke@435: duke@435: // General info/converters duke@435: int size() const { return _size; } duke@435: static int code_size_to_size(int code_size) { return round_to(sizeof(InterpreterCodelet), CodeEntryAlignment) + code_size; } duke@435: duke@435: // Code info duke@435: address code_begin() const { return (address)this + round_to(sizeof(InterpreterCodelet), CodeEntryAlignment); } duke@435: address code_end() const { return (address)this + size(); } duke@435: duke@435: // Debugging duke@435: void verify(); duke@435: void print(); duke@435: duke@435: // Interpreter-specific initialization duke@435: void initialize(const char* description, Bytecodes::Code bytecode); duke@435: duke@435: // Interpreter-specific attributes duke@435: int code_size() const { return code_end() - code_begin(); } duke@435: const char* description() const { return _description; } duke@435: Bytecodes::Code bytecode() const { return _bytecode; } duke@435: }; duke@435: duke@435: // Define a prototype interface duke@435: DEF_STUB_INTERFACE(InterpreterCodelet); duke@435: duke@435: duke@435: //------------------------------------------------------------------------------------------------------------------------ duke@435: // A CodeletMark serves as an automatic creator/initializer for Codelets duke@435: // (As a subclass of ResourceMark it automatically GC's the allocated duke@435: // code buffer and assemblers). duke@435: duke@435: class CodeletMark: ResourceMark { duke@435: private: duke@435: InterpreterCodelet* _clet; duke@435: InterpreterMacroAssembler** _masm; duke@435: CodeBuffer _cb; duke@435: duke@435: int codelet_size() { duke@435: // Request the whole code buffer (minus a little for alignment). duke@435: // The commit call below trims it back for each codelet. duke@435: int codelet_size = AbstractInterpreter::code()->available_space() - 2*K; duke@435: duke@435: // Guarantee there's a little bit of code space left. duke@435: guarantee (codelet_size > 0 && (size_t)codelet_size > 2*K, duke@435: "not enough space for interpreter generation"); duke@435: duke@435: return codelet_size; duke@435: } duke@435: duke@435: public: duke@435: CodeletMark( duke@435: InterpreterMacroAssembler*& masm, duke@435: const char* description, duke@435: Bytecodes::Code bytecode = Bytecodes::_illegal): duke@435: _clet((InterpreterCodelet*)AbstractInterpreter::code()->request(codelet_size())), duke@435: _cb(_clet->code_begin(), _clet->code_size()) duke@435: duke@435: { // request all space (add some slack for Codelet data) duke@435: assert (_clet != NULL, "we checked not enough space already"); duke@435: duke@435: // initialize Codelet attributes duke@435: _clet->initialize(description, bytecode); duke@435: // create assembler for code generation duke@435: masm = new InterpreterMacroAssembler(&_cb); duke@435: _masm = &masm; duke@435: } duke@435: duke@435: ~CodeletMark() { duke@435: // align so printing shows nop's instead of random code at the end (Codelets are aligned) duke@435: (*_masm)->align(wordSize); duke@435: // make sure all code is in code buffer duke@435: (*_masm)->flush(); duke@435: duke@435: duke@435: // commit Codelet duke@435: AbstractInterpreter::code()->commit((*_masm)->code()->pure_code_size()); duke@435: // make sure nobody can use _masm outside a CodeletMark lifespan duke@435: *_masm = NULL; duke@435: } duke@435: }; duke@435: duke@435: // Wrapper classes to produce Interpreter/InterpreterGenerator from either duke@435: // the c++ interpreter or the template interpreter. duke@435: duke@435: class Interpreter: public CC_INTERP_ONLY(CppInterpreter) NOT_CC_INTERP(TemplateInterpreter) { duke@435: duke@435: public: duke@435: // Debugging/printing duke@435: static InterpreterCodelet* codelet_containing(address pc) { return (InterpreterCodelet*)_code->stub_containing(pc); } duke@435: #include "incls/_interpreter_pd.hpp.incl" duke@435: };