codeBuffer.hpp revision 1483
/*
* Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
class CodeComments;
class AbstractAssembler;
class MacroAssembler;
class PhaseCFG;
class Compile;
class BufferBlob;
class CodeBuffer;
class CodeOffsets: public StackObj {
public:
Frame_Complete, // Offset in the code where the frame setup is (for forte stackwalks) is complete
Exceptions, // Offset where exception handler lives
Deopt, // Offset where deopt handler lives
DeoptMH, // Offset where MethodHandle deopt handler lives
UnwindHandler, // Offset to default unwind handler
max_Entries };
// special value to note codeBlobs where profile (forte) stack walking is
// always dangerous and suspect.
enum { frame_never_safe = -1 };
private:
int _values[max_Entries];
public:
CodeOffsets() {
_values[Verified_Entry] = 0;
}
};
// This class represents a stream of code and associated relocations.
// There are a few in each CodeBuffer.
// They are filled concurrently, and concatenated at the end.
class CodeSection VALUE_OBJ_CLASS_SPEC {
friend class CodeBuffer;
public:
typedef int csize_t; // code size type; would be size_t except for history
private:
bool _locs_own; // did I allocate the locs myself?
bool _frozen; // no more expansion of this section
char _index; // my section number (SECT_INST, etc.)
// (Note: _locs_point used to be called _last_reloc_offset.)
CodeSection() {
_locs_start = NULL;
_locs_limit = NULL;
_locs_point = NULL;
_locs_own = false;
_frozen = false;
}
}
_locs_point = start;
}
void initialize_locs(int locs_capacity);
void expand_locs(int new_capacity);
// helper for CodeBuffer::expand()
}
public:
// is a given address in this section? (2nd version is end-inclusive)
void set_locs_end(relocInfo* p) {
_locs_end = p;
}
_locs_point = pc;
}
// Share a scratch buffer for relocinfo. (Hacky; saves a resource allocation.)
// Manage labels and their addresses.
// Emit a relocation.
}
// alignment requirement for starting offset
// Requirements are that the instruction area and the
// stubs area must start on CodeEntryAlignment, and
// the ctable on sizeof(jdouble)
// Slop between sections, used only when allocating temporary BufferBlob buffers.
// Mark a section frozen. Assign its remaining space to
// the following section. It will never expand after this point.
inline void freeze(); // { _outer->freeze_section(this); }
// Ensure there's enough space left in the current section.
// Return true if there was an expansion.
#ifndef PRODUCT
void decode();
void dump();
#endif //PRODUCT
};
class CodeComment;
class CodeComments VALUE_OBJ_CLASS_SPEC {
private:
#ifndef PRODUCT
#endif
public:
CodeComments() {
#ifndef PRODUCT
#endif
}
void free() PRODUCT_RETURN;
};
// A CodeBuffer describes a memory space into which assembly
// code is generated. This memory space usually occupies the
// interior of a single BufferBlob, but in some cases it may be
// an arbitrary span of memory, even outside the code cache.
//
// A code buffer comes in two variants:
//
// (1) A CodeBuffer referring to an already allocated piece of memory:
// This is used to direct 'static' code generation (e.g. for interpreter
// or stubroutine generation, etc.). This code comes with NO relocation
// information.
//
// (2) A CodeBuffer referring to a piece of memory allocated when the
// CodeBuffer is allocated. This is used for nmethod generation.
//
// The memory can be divided up into several parts called sections.
// Each section independently accumulates code (or data) an relocations.
// Sections can grow (at the expense of a reallocation of the BufferBlob
// and recopying of all active sections). When the buffered code is finally
// written to an nmethod (or other CodeBlob), the contents (code, data,
// and relocations) of the sections are padded to an alignment and concatenated.
// Instructions and data in one section can contain relocatable references to
// addresses in a sibling section.
class CodeBuffer: public StackObj {
friend class CodeSection;
private:
// CodeBuffers must be allocated on the stack except for a single
// special case during expansion which is handled internally. This
// is done to guarantee proper cleanup of resources.
void operator delete(void* p) { ResourceObj::operator delete(p); }
public:
typedef int csize_t; // code size type; would be size_t except for history
enum {
// Here is the list of all possible sections, in order of ascending address.
SECT_INSTS, // Executable instructions.
SECT_STUBS, // Outbound trampolines for supporting call sites.
SECT_CONSTS, // Non-instruction data: Floats, jump tables, etc.
};
private:
enum {
};
const char* _name;
void initialize_misc(const char * name) {
// all pointers other than code_start/end and those inside the sections
}
// Initialize the main section:
}
// helper for CodeBuffer::expand()
#ifdef ASSERT
// ensure sections are disjoint, ordered, and contained in the blob
bool verify_section_allocation();
#endif
// copies combined relocations to the blob, returns bytes copied
// (if target is null, it is a dry run only, just for sizing)
// copies combined code to the blob (assumes relocs are already in there)
// moves code sections to new buffer (assumes relocs are already in there)
// set up a model of the final layout of my contents
// Expand the given section so at least 'amount' is remaining.
// Creates a new, larger BufferBlob, and rewrites the code & relocs.
// Helper for expand.
public:
// (1) code buffer referring to pre-allocated instruction memory
// (2) code buffer allocating codeBlob memory for code & relocation
// info but with lazy initialization. The name must be something
// informative.
CodeBuffer(const char* name) {
}
// (3) code buffer allocating codeBlob memory for code & relocation
// info. The name must be something informative and code_size must
// include both code and stubs sizes.
}
~CodeBuffer();
// Initialize a CodeBuffer constructed using constructor 2. Using
// constructor 3 is equivalent to calling constructor 2 and then
// calling this method. It's been factored out for convenience of
// construction.
// present sections in order; return NULL at end; insts is #0, etc.
CodeSection* code_section(int n) {
// This makes the slightly questionable but portable assumption that
// the various members (_insts, _stubs, etc.) are adjacent in the
// layout of CodeBuffer.
return cs;
}
return ((CodeBuffer*)this)->code_section(n);
}
static const char* code_section_name(int n);
// handy for debugging
}
// A stable mapping between 'locators' (small ints) and addresses.
// Properties
void free_blob(); // Free the blob, if we own one.
// Properties relative to the insts section:
// is there anything in the buffer other than the current section?
// size in bytes of output so far in the insts sections
// same as code_size(), except that it asserts there is no non-code here
return code_size(); }
// capacity in bytes of the insts sections
// number of bytes remaining in the insts section
// is a given address in the insts section? (2nd version is end-inclusive)
// allocated size of code in all sections, when aligned and concatenated
// (this is the eventual state of the code in its final CodeBlob)
csize_t total_code_size() const;
// combined offset (relative to start of insts) of given address,
// as eventually found in the final CodeBlob
// allocated size of all relocation data, including index, rounded up
csize_t total_relocation_size() const;
// allocated size of any and all recorded oops
csize_t total_oop_size() const {
}
// Configuration functions, called immediately after the CB is constructed.
// The section sizes are subtracted from the original insts section.
// Note: Call them in reverse section order, because each steals from insts.
// Override default oop recorder.
void initialize_oop_recorder(OopRecorder* r);
// Code generation
}
}
// Management of overflow storage for binding of Labels.
// NMethod generation
}
if (!oop_recorder()->is_unused()) {
}
}
// Transform an address from the code in this code buffer to a specified code buffer
#ifndef PRODUCT
public:
// Printing / Decoding
// decodes from decode_begin() to code_end() and sets decode_begin to end
void decode();
void decode_all(); // decodes all the code
void skip_decode(); // sets decode_begin to code_end();
void print();
#endif
// The following header contains architecture-specific implementations
#include "incls/_codeBuffer_pd.hpp.incl"
};
inline void CodeSection::freeze() {
_outer->freeze_section(this);
}
return false;
}