8284578: Relax InterpreterCodelet stub alignment
Reviewed-by: kvn, dlong
This commit is contained in:
parent
bf85b0095f
commit
2241a05705
@ -61,14 +61,17 @@ class ICStub: public Stub {
|
||||
|
||||
// General info
|
||||
int size() const { return _size; }
|
||||
static int code_size_to_size(int code_size) { return align_up((int)sizeof(ICStub), CodeEntryAlignment) + code_size; }
|
||||
|
||||
// ICStub_from_destination_address looks up Stub* address from code entry address,
|
||||
// which unfortunately means the stub head should be at the same alignment as the code.
|
||||
static int alignment() { return CodeEntryAlignment; }
|
||||
|
||||
public:
|
||||
// Creation
|
||||
void set_stub(CompiledIC *ic, void* cached_value, address dest_addr);
|
||||
|
||||
// Code info
|
||||
address code_begin() const { return (address)this + align_up(sizeof(ICStub), CodeEntryAlignment); }
|
||||
address code_begin() const { return align_up((address)this + sizeof(ICStub), CodeEntryAlignment); }
|
||||
address code_end() const { return (address)this + size(); }
|
||||
|
||||
// Call site info
|
||||
|
@ -113,12 +113,18 @@ Stub* StubQueue::request_committed(int code_size) {
|
||||
return s;
|
||||
}
|
||||
|
||||
int StubQueue::compute_stub_size(Stub* stub, int code_size) {
|
||||
address stub_begin = (address) stub;
|
||||
address code_begin = stub_code_begin(stub);
|
||||
address code_end = align_up(code_begin + code_size, stub_alignment());
|
||||
return (int)(code_end - stub_begin);
|
||||
}
|
||||
|
||||
Stub* StubQueue::request(int requested_code_size) {
|
||||
assert(requested_code_size > 0, "requested_code_size must be > 0");
|
||||
if (_mutex != NULL) _mutex->lock_without_safepoint_check();
|
||||
Stub* s = current_stub();
|
||||
int requested_size = align_up(stub_code_size_to_size(requested_code_size), CodeEntryAlignment);
|
||||
int requested_size = compute_stub_size(s, requested_code_size);
|
||||
if (requested_size <= available_space()) {
|
||||
if (is_contiguous()) {
|
||||
// Queue: |...|XXXXXXX|.............|
|
||||
@ -154,8 +160,8 @@ Stub* StubQueue::request(int requested_code_size) {
|
||||
|
||||
void StubQueue::commit(int committed_code_size) {
|
||||
assert(committed_code_size > 0, "committed_code_size must be > 0");
|
||||
int committed_size = align_up(stub_code_size_to_size(committed_code_size), CodeEntryAlignment);
|
||||
Stub* s = current_stub();
|
||||
int committed_size = compute_stub_size(s, committed_code_size);
|
||||
assert(committed_size <= stub_size(s), "committed size must not exceed requested size");
|
||||
stub_initialize(s, committed_size);
|
||||
_queue_end += committed_size;
|
||||
@ -211,10 +217,10 @@ void StubQueue::verify() {
|
||||
guarantee(0 <= _queue_begin && _queue_begin < _buffer_limit, "_queue_begin out of bounds");
|
||||
guarantee(0 <= _queue_end && _queue_end <= _buffer_limit, "_queue_end out of bounds");
|
||||
// verify alignment
|
||||
guarantee(_buffer_size % CodeEntryAlignment == 0, "_buffer_size not aligned");
|
||||
guarantee(_buffer_limit % CodeEntryAlignment == 0, "_buffer_limit not aligned");
|
||||
guarantee(_queue_begin % CodeEntryAlignment == 0, "_queue_begin not aligned");
|
||||
guarantee(_queue_end % CodeEntryAlignment == 0, "_queue_end not aligned");
|
||||
guarantee(_buffer_size % stub_alignment() == 0, "_buffer_size not aligned");
|
||||
guarantee(_buffer_limit % stub_alignment() == 0, "_buffer_limit not aligned");
|
||||
guarantee(_queue_begin % stub_alignment() == 0, "_queue_begin not aligned");
|
||||
guarantee(_queue_end % stub_alignment() == 0, "_queue_end not aligned");
|
||||
// verify buffer limit/size relationship
|
||||
if (is_contiguous()) {
|
||||
guarantee(_buffer_limit == _buffer_size, "_buffer_limit must equal _buffer_size");
|
||||
|
@ -42,20 +42,19 @@
|
||||
// A concrete stub layout may look like this (both data
|
||||
// and code sections could be empty as well):
|
||||
//
|
||||
// ________
|
||||
// stub -->| | <--+
|
||||
//
|
||||
// stub -->|--------| <--+ <--- aligned by alignment()
|
||||
// | | |
|
||||
// | data | |
|
||||
// |________| |
|
||||
// code_begin -->| | |
|
||||
// | | |
|
||||
// code_begin -->|--------| | <--- aligned by CodeEntryAlignment
|
||||
// | | |
|
||||
// | | |
|
||||
// | code | | size
|
||||
// | | |
|
||||
// |________| |
|
||||
// code_end -->| | |
|
||||
// | data | |
|
||||
// |________| |
|
||||
// <--+
|
||||
|
||||
// | | |
|
||||
// code_end -->|--------| <--+
|
||||
//
|
||||
|
||||
class Stub {
|
||||
public:
|
||||
@ -65,7 +64,6 @@ class Stub {
|
||||
|
||||
// General info/converters
|
||||
int size() const { ShouldNotCallThis(); return 0; } // must return the size provided by initialize
|
||||
static int code_size_to_size(int code_size) { ShouldNotCallThis(); return 0; } // computes the size given the code size
|
||||
|
||||
// Code info
|
||||
address code_begin() const { ShouldNotCallThis(); return NULL; } // points to the first byte of the code
|
||||
@ -97,8 +95,8 @@ class StubInterface: public CHeapObj<mtCode> {
|
||||
virtual void finalize(Stub* self) = 0; // called before deallocation
|
||||
|
||||
// General info/converters
|
||||
virtual int size(Stub* self) const = 0; // the total size of the stub in bytes (must be a multiple of CodeEntryAlignment)
|
||||
virtual int code_size_to_size(int code_size) const = 0; // computes the total stub size in bytes given the code size in bytes
|
||||
virtual int size(Stub* self) const = 0; // the total size of the stub in bytes (must be a multiple of HeapWordSize)
|
||||
virtual int alignment() const = 0; // computes the alignment
|
||||
|
||||
// Code info
|
||||
virtual address code_begin(Stub* self) const = 0; // points to the first code byte
|
||||
@ -126,7 +124,7 @@ class StubInterface: public CHeapObj<mtCode> {
|
||||
\
|
||||
/* General info */ \
|
||||
virtual int size(Stub* self) const { return cast(self)->size(); } \
|
||||
virtual int code_size_to_size(int code_size) const { return stub::code_size_to_size(code_size); } \
|
||||
virtual int alignment() const { return stub::alignment(); } \
|
||||
\
|
||||
/* Code info */ \
|
||||
virtual address code_begin(Stub* self) const { return cast(self)->code_begin(); } \
|
||||
@ -153,21 +151,25 @@ class StubQueue: public CHeapObj<mtCode> {
|
||||
int _number_of_stubs; // the number of buffered stubs
|
||||
Mutex* const _mutex; // the lock used for a (request, commit) transaction
|
||||
|
||||
void check_index(int i) const { assert(0 <= i && i < _buffer_limit && i % CodeEntryAlignment == 0, "illegal index"); }
|
||||
void check_index(int i) const { assert(0 <= i && i < _buffer_limit && i % stub_alignment() == 0, "illegal index"); }
|
||||
bool is_contiguous() const { return _queue_begin <= _queue_end; }
|
||||
int index_of(Stub* s) const { int i = (address)s - _stub_buffer; check_index(i); return i; }
|
||||
Stub* stub_at(int i) const { check_index(i); return (Stub*)(_stub_buffer + i); }
|
||||
Stub* current_stub() const { return stub_at(_queue_end); }
|
||||
|
||||
// Stub functionality accessed via interface
|
||||
void stub_initialize(Stub* s, int size) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size); }
|
||||
void stub_initialize(Stub* s, int size) { assert(size % stub_alignment() == 0, "size not aligned"); _stub_interface->initialize(s, size); }
|
||||
void stub_finalize(Stub* s) { _stub_interface->finalize(s); }
|
||||
int stub_size(Stub* s) const { return _stub_interface->size(s); }
|
||||
bool stub_contains(Stub* s, address pc) const { return _stub_interface->code_begin(s) <= pc && pc < _stub_interface->code_end(s); }
|
||||
int stub_code_size_to_size(int code_size) const { return _stub_interface->code_size_to_size(code_size); }
|
||||
int stub_alignment() const { return _stub_interface->alignment(); }
|
||||
address stub_code_begin(Stub* s) const { return _stub_interface->code_begin(s); }
|
||||
void stub_verify(Stub* s) { _stub_interface->verify(s); }
|
||||
void stub_print(Stub* s) { _stub_interface->print(s); }
|
||||
|
||||
// Helpers
|
||||
int compute_stub_size(Stub* stub, int code_size);
|
||||
|
||||
public:
|
||||
StubQueue(StubInterface* stub_interface, int buffer_size, Mutex* lock,
|
||||
const char* name);
|
||||
|
@ -59,10 +59,10 @@ class InterpreterCodelet: public Stub {
|
||||
|
||||
// General info/converters
|
||||
int size() const { return _size; }
|
||||
static int code_size_to_size(int code_size) { return align_up((int)sizeof(InterpreterCodelet), CodeEntryAlignment) + code_size; }
|
||||
static int alignment() { return HeapWordSize; }
|
||||
|
||||
// Code info
|
||||
address code_begin() const { return (address)this + align_up(sizeof(InterpreterCodelet), CodeEntryAlignment); }
|
||||
address code_begin() const { return align_up((address)this + sizeof(InterpreterCodelet), CodeEntryAlignment); }
|
||||
address code_end() const { return (address)this + size(); }
|
||||
|
||||
// Debugging
|
||||
|
@ -47,10 +47,10 @@ void TemplateInterpreter::initialize_stub() {
|
||||
// allocate interpreter
|
||||
int code_size = InterpreterCodeSize;
|
||||
NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space
|
||||
// 270+ interpreter codelets are generated and each of them is required to be aligned to
|
||||
// CodeEntryAlignment twice. So we need additional size due to alignment.
|
||||
// 270+ interpreter codelets are generated and each of them is aligned to HeapWordSize,
|
||||
// plus their code section is aligned to CodeEntryAlignement. So we need additional size due to alignment.
|
||||
int max_aligned_codelets = 280;
|
||||
int max_aligned_bytes = max_aligned_codelets * CodeEntryAlignment * 2;
|
||||
int max_aligned_bytes = max_aligned_codelets * (HeapWordSize + CodeEntryAlignment);
|
||||
_code = new StubQueue(new InterpreterCodeletInterface, code_size + max_aligned_bytes, NULL,
|
||||
"Interpreter");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user