提交 4fd3d50f 编写于 作者: T twisti

6961697: move nmethod constants section before instruction section

Summary: This is a preparation for 6961690.
Reviewed-by: kvn, never
上级 0f9d7325
......@@ -143,13 +143,6 @@ void CodeBuffer::initialize_oop_recorder(OopRecorder* r) {
void CodeBuffer::initialize_section_size(CodeSection* cs, csize_t size) {
assert(cs != &_insts, "insts is the memory provider, not the consumer");
#ifdef ASSERT
for (int n = (int)SECT_INSTS+1; n < (int)SECT_LIMIT; n++) {
CodeSection* prevCS = code_section(n);
if (prevCS == cs) break;
assert(!prevCS->is_allocated(), "section allocation must be in reverse order");
}
#endif
csize_t slop = CodeSection::end_slop(); // margin between sections
int align = cs->alignment();
assert(is_power_of_2(align), "sanity");
......@@ -199,13 +192,13 @@ void CodeBuffer::set_blob(BufferBlob* blob) {
_total_start = start;
_total_size = end - start;
} else {
#ifdef ASSERT
#ifdef ASSERT
// Clean out dangling pointers.
_total_start = badAddress;
_consts._start = _consts._end = badAddress;
_insts._start = _insts._end = badAddress;
_stubs._start = _stubs._end = badAddress;
_consts._start = _consts._end = badAddress;
#endif //ASSERT
#endif //ASSERT
}
}
......@@ -221,9 +214,9 @@ const char* CodeBuffer::code_section_name(int n) {
return NULL;
#else //PRODUCT
switch (n) {
case SECT_CONSTS: return "consts";
case SECT_INSTS: return "insts";
case SECT_STUBS: return "stubs";
case SECT_CONSTS: return "consts";
default: return NULL;
}
#endif //PRODUCT
......@@ -445,12 +438,11 @@ void CodeBuffer::compute_final_layout(CodeBuffer* dest) const {
const CodeSection* prev_cs = NULL;
CodeSection* prev_dest_cs = NULL;
for (int n = 0; n < (int)SECT_LIMIT; n++) {
for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
// figure compact layout of each section
const CodeSection* cs = code_section(n);
address cstart = cs->start();
address cend = cs->end();
csize_t csize = cend - cstart;
csize_t csize = cs->size();
CodeSection* dest_cs = dest->code_section(n);
if (!cs->is_empty()) {
......@@ -463,7 +455,7 @@ void CodeBuffer::compute_final_layout(CodeBuffer* dest) const {
prev_dest_cs->_limit += padding;
}
#ifdef ASSERT
if (prev_cs != NULL && prev_cs->is_frozen() && n < SECT_CONSTS) {
if (prev_cs != NULL && prev_cs->is_frozen() && n < (SECT_LIMIT - 1)) {
// Make sure the ends still match up.
// This is important because a branch in a frozen section
// might target code in a following section, via a Label,
......@@ -492,22 +484,18 @@ void CodeBuffer::compute_final_layout(CodeBuffer* dest) const {
assert(dest->verify_section_allocation(), "final configuration works");
}
csize_t CodeBuffer::total_offset_of(address addr) const {
csize_t code_size_so_far = 0;
for (int n = 0; n < (int)SECT_LIMIT; n++) {
const CodeSection* cs = code_section(n);
if (!cs->is_empty()) {
code_size_so_far = cs->align_at_start(code_size_so_far);
csize_t CodeBuffer::total_offset_of(CodeSection* cs) const {
csize_t size_so_far = 0;
for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
const CodeSection* cur_cs = code_section(n);
if (!cur_cs->is_empty()) {
size_so_far = cur_cs->align_at_start(size_so_far);
}
if (cs->contains2(addr)) {
return code_size_so_far + (addr - cs->start());
if (cur_cs->index() == cs->index()) {
return size_so_far;
}
code_size_so_far += cs->size();
size_so_far += cur_cs->size();
}
#ifndef PRODUCT
tty->print_cr("Dangling address " PTR_FORMAT " in:", addr);
((CodeBuffer*)this)->print();
#endif
ShouldNotReachHere();
return -1;
}
......@@ -533,7 +521,7 @@ csize_t CodeBuffer::copy_relocations_to(CodeBlob* dest) const {
csize_t code_end_so_far = 0;
csize_t code_point_so_far = 0;
for (int n = 0; n < (int)SECT_LIMIT; n++) {
for (int n = (int) SECT_FIRST; n < (int)SECT_LIMIT; n++) {
// pull relocs out of each section
const CodeSection* cs = code_section(n);
assert(!(cs->is_empty() && cs->locs_count() > 0), "sanity");
......@@ -635,11 +623,14 @@ void CodeBuffer::copy_code_to(CodeBlob* dest_blob) {
ICache::invalidate_range(dest_blob->code_begin(), dest_blob->code_size());
}
// Move all my code into another code buffer.
// Consult applicable relocs to repair embedded addresses.
// Move all my code into another code buffer. Consult applicable
// relocs to repair embedded addresses. The layout in the destination
// CodeBuffer is different to the source CodeBuffer: the destination
// CodeBuffer gets the final layout (consts, insts, stubs in order of
// ascending address).
void CodeBuffer::relocate_code_to(CodeBuffer* dest) const {
DEBUG_ONLY(address dest_end = dest->_total_start + dest->_total_size);
for (int n = 0; n < (int)SECT_LIMIT; n++) {
for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
// pull code out of each section
const CodeSection* cs = code_section(n);
if (cs->is_empty()) continue; // skip trivial section
......@@ -681,20 +672,19 @@ csize_t CodeBuffer::figure_expanded_capacities(CodeSection* which_cs,
csize_t* new_capacity) {
csize_t new_total_cap = 0;
int prev_n = -1;
for (int n = 0; n < (int)SECT_LIMIT; n++) {
for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
const CodeSection* sect = code_section(n);
if (!sect->is_empty()) {
// Compute initial padding; assign it to the previous non-empty guy.
// Cf. compute_final_layout.
// Compute initial padding; assign it to the previous section,
// even if it's empty (e.g. consts section can be empty).
// Cf. compute_final_layout
csize_t padding = sect->align_at_start(new_total_cap) - new_total_cap;
if (padding != 0) {
new_total_cap += padding;
assert(prev_n >= 0, "sanity");
new_capacity[prev_n] += padding;
assert(n - 1 >= SECT_FIRST, "sanity");
new_capacity[n - 1] += padding;
}
prev_n = n;
}
csize_t exp = sect->size(); // 100% increase
......@@ -774,11 +764,11 @@ void CodeBuffer::expand(CodeSection* which_cs, csize_t amount) {
this->_before_expand = bxp;
// Give each section its required (expanded) capacity.
for (int n = (int)SECT_LIMIT-1; n >= SECT_INSTS; n--) {
for (int n = (int)SECT_LIMIT-1; n >= SECT_FIRST; n--) {
CodeSection* cb_sect = cb.code_section(n);
CodeSection* this_sect = code_section(n);
if (new_capacity[n] == 0) continue; // already nulled out
if (n > SECT_INSTS) {
if (n != SECT_INSTS) {
cb.initialize_section_size(cb_sect, new_capacity[n]);
}
assert(cb_sect->capacity() >= new_capacity[n], "big enough");
......@@ -844,16 +834,21 @@ bool CodeBuffer::verify_section_allocation() {
assert(tstart >= _blob->content_begin(), "sanity");
assert(tend <= _blob->content_end(), "sanity");
}
address tcheck = tstart; // advancing pointer to verify disjointness
for (int n = 0; n < (int)SECT_LIMIT; n++) {
// Verify disjointness.
for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
CodeSection* sect = code_section(n);
if (!sect->is_allocated()) continue;
assert(sect->start() >= tcheck, "sanity");
tcheck = sect->start();
assert((intptr_t)tcheck % sect->alignment() == 0
if (!sect->is_allocated() || sect->is_empty()) continue;
assert((intptr_t)sect->start() % sect->alignment() == 0
|| sect->is_empty() || _blob == NULL,
"start is aligned");
assert(sect->end() >= tcheck, "sanity");
for (int m = (int) SECT_FIRST; m < (int) SECT_LIMIT; m++) {
CodeSection* other = code_section(m);
if (!other->is_allocated() || other == sect) continue;
assert(!other->contains(sect->start() ), "sanity");
// limit is an exclusive address and can be the start of another
// section.
assert(!other->contains(sect->limit() - 1), "sanity");
}
assert(sect->end() <= tend, "sanity");
}
return true;
......
......@@ -289,10 +289,12 @@ class CodeBuffer: public StackObj {
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.
// Here is the list of all possible sections. The order reflects
// the final layout.
SECT_FIRST = 0,
SECT_CONSTS = SECT_FIRST, // Non-instruction data: Floats, jump tables, etc.
SECT_INSTS, // Executable instructions.
SECT_STUBS, // Outbound trampolines for supporting call sites.
SECT_CONSTS, // Non-instruction data: Floats, jump tables, etc.
SECT_LIMIT, SECT_NONE = -1
};
......@@ -304,9 +306,9 @@ class CodeBuffer: public StackObj {
const char* _name;
CodeSection _consts; // constants, jump tables
CodeSection _insts; // instructions (the main section)
CodeSection _stubs; // stubs (call site support), deopt, exception handling
CodeSection _consts; // constants, jump tables
CodeBuffer* _before_expand; // dead buffer, from before the last expansion
......@@ -334,9 +336,9 @@ class CodeBuffer: public StackObj {
}
void initialize(address code_start, csize_t code_size) {
_consts.initialize_outer(this, SECT_CONSTS);
_insts.initialize_outer(this, SECT_INSTS);
_stubs.initialize_outer(this, SECT_STUBS);
_consts.initialize_outer(this, SECT_CONSTS);
_total_start = code_start;
_total_size = code_size;
// Initialize the main section:
......@@ -414,16 +416,16 @@ class CodeBuffer: public StackObj {
// construction.
void initialize(csize_t code_size, csize_t locs_size);
CodeSection* consts() { return &_consts; }
CodeSection* insts() { return &_insts; }
CodeSection* stubs() { return &_stubs; }
CodeSection* consts() { return &_consts; }
// present sections in order; return NULL at end; insts is #0, etc.
// present sections in order; return NULL at end; consts 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.
CodeSection* cs = &_insts + n;
// This makes the slightly questionable but portable assumption
// that the various members (_consts, _insts, _stubs, etc.) are
// adjacent in the layout of CodeBuffer.
CodeSection* cs = &_consts + n;
assert(cs->index() == n || !cs->is_allocated(), "sanity");
return cs;
}
......@@ -484,9 +486,9 @@ class CodeBuffer: public StackObj {
// CodeBlob).
csize_t total_content_size() const;
// combined offset (relative to start of insts) of given address,
// as eventually found in the final CodeBlob
csize_t total_offset_of(address addr) const;
// Combined offset (relative to start of first section) of given
// section, as eventually found in the final CodeBlob.
csize_t total_offset_of(CodeSection* cs) const;
// allocated size of all relocation data, including index, rounded up
csize_t total_relocation_size() const;
......
......@@ -92,7 +92,7 @@ CodeBlob::CodeBlob(
_header_size = header_size;
_relocation_size = round_to(cb->total_relocation_size(), oopSize);
_content_offset = align_code_offset(header_size + _relocation_size);
_code_offset = _content_offset + cb->total_offset_of(cb->insts()->start());
_code_offset = _content_offset + cb->total_offset_of(cb->insts());
_data_offset = _content_offset + round_to(cb->total_content_size(), oopSize);
assert(_data_offset <= size, "codeBlob is too small");
......
......@@ -87,9 +87,9 @@ struct nmethod_stats_struct {
int nmethod_count;
int total_size;
int relocation_size;
int consts_size;
int insts_size;
int stub_size;
int consts_size;
int scopes_data_size;
int scopes_pcs_size;
int dependencies_size;
......@@ -101,9 +101,9 @@ struct nmethod_stats_struct {
nmethod_count += 1;
total_size += nm->size();
relocation_size += nm->relocation_size();
consts_size += nm->consts_size();
insts_size += nm->insts_size();
stub_size += nm->stub_size();
consts_size += nm->consts_size();
oops_size += nm->oops_size();
scopes_data_size += nm->scopes_data_size();
scopes_pcs_size += nm->scopes_pcs_size();
......@@ -116,9 +116,9 @@ struct nmethod_stats_struct {
tty->print_cr("Statistics for %d bytecoded nmethods:", nmethod_count);
if (total_size != 0) tty->print_cr(" total in heap = %d", total_size);
if (relocation_size != 0) tty->print_cr(" relocation = %d", relocation_size);
if (consts_size != 0) tty->print_cr(" constants = %d", consts_size);
if (insts_size != 0) tty->print_cr(" main code = %d", insts_size);
if (stub_size != 0) tty->print_cr(" stub code = %d", stub_size);
if (consts_size != 0) tty->print_cr(" constants = %d", consts_size);
if (oops_size != 0) tty->print_cr(" oops = %d", oops_size);
if (scopes_data_size != 0) tty->print_cr(" scopes data = %d", scopes_data_size);
if (scopes_pcs_size != 0) tty->print_cr(" scopes pcs = %d", scopes_pcs_size);
......@@ -404,9 +404,9 @@ void nmethod::add_handler_for_exception_and_pc(Handle exception, address pc, add
int nmethod::total_size() const {
return
consts_size() +
insts_size() +
stub_size() +
consts_size() +
scopes_data_size() +
scopes_pcs_size() +
handler_table_size() +
......@@ -789,13 +789,17 @@ nmethod::nmethod(
_orig_pc_offset = orig_pc_offset;
// Section offsets
_consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts()->start());
_stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs()->start());
_consts_offset = content_offset() + code_buffer->total_offset_of(code_buffer->consts());
_stub_offset = content_offset() + code_buffer->total_offset_of(code_buffer->stubs());
// Exception handler and deopt handler are in the stub section
_exception_offset = _stub_offset + offsets->value(CodeOffsets::Exceptions);
_deoptimize_offset = _stub_offset + offsets->value(CodeOffsets::Deopt);
if (has_method_handle_invokes()) {
_deoptimize_mh_offset = _stub_offset + offsets->value(CodeOffsets::DeoptMH);
} else {
_deoptimize_mh_offset = -1;
}
if (offsets->value(CodeOffsets::UnwindHandler) != -1) {
_unwind_handler_offset = code_offset() + offsets->value(CodeOffsets::UnwindHandler);
} else {
......@@ -885,9 +889,9 @@ void nmethod::log_new_nmethod() const {
xtty->print(" address='" INTPTR_FORMAT "'", (intptr_t) this);
LOG_OFFSET(xtty, relocation);
LOG_OFFSET(xtty, consts);
LOG_OFFSET(xtty, insts);
LOG_OFFSET(xtty, stub);
LOG_OFFSET(xtty, consts);
LOG_OFFSET(xtty, scopes_data);
LOG_OFFSET(xtty, scopes_pcs);
LOG_OFFSET(xtty, dependencies);
......@@ -2336,6 +2340,10 @@ void nmethod::print() const {
relocation_begin(),
relocation_end(),
relocation_size());
if (consts_size () > 0) tty->print_cr(" constants [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
consts_begin(),
consts_end(),
consts_size());
if (insts_size () > 0) tty->print_cr(" main code [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
insts_begin(),
insts_end(),
......@@ -2344,10 +2352,6 @@ void nmethod::print() const {
stub_begin(),
stub_end(),
stub_size());
if (consts_size () > 0) tty->print_cr(" constants [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
consts_begin(),
consts_end(),
consts_size());
if (oops_size () > 0) tty->print_cr(" oops [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
oops_begin(),
oops_end(),
......@@ -2372,10 +2376,6 @@ void nmethod::print() const {
nul_chk_table_begin(),
nul_chk_table_end(),
nul_chk_table_size());
if (oops_size () > 0) tty->print_cr(" oops [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
oops_begin(),
oops_end(),
oops_size());
}
void nmethod::print_code() {
......
......@@ -143,8 +143,8 @@ class nmethod : public CodeBlob {
#ifdef HAVE_DTRACE_H
int _trap_offset;
#endif // def HAVE_DTRACE_H
int _stub_offset;
int _consts_offset;
int _stub_offset;
int _oops_offset; // offset to where embedded oop table begins (inside data)
int _scopes_data_offset;
int _scopes_pcs_offset;
......@@ -336,16 +336,16 @@ class nmethod : public CodeBlob {
bool is_compiled_by_shark() const;
// boundaries for different parts
address insts_begin () const { return code_begin(); }
address consts_begin () const { return header_begin() + _consts_offset ; }
address consts_end () const { return header_begin() + code_offset() ; }
address insts_begin () const { return header_begin() + code_offset() ; }
address insts_end () const { return header_begin() + _stub_offset ; }
address stub_begin () const { return header_begin() + _stub_offset ; }
address stub_end () const { return header_begin() + _oops_offset ; }
address exception_begin () const { return header_begin() + _exception_offset ; }
address deopt_handler_begin () const { return header_begin() + _deoptimize_offset ; }
address deopt_mh_handler_begin() const { return header_begin() + _deoptimize_mh_offset ; }
address unwind_handler_begin () const { return _unwind_handler_offset != -1 ? (header_begin() + _unwind_handler_offset) : NULL; }
address stub_begin () const { return header_begin() + _stub_offset ; }
address stub_end () const { return header_begin() + _consts_offset ; }
address consts_begin () const { return header_begin() + _consts_offset ; }
address consts_end () const { return header_begin() + _oops_offset ; }
oop* oops_begin () const { return (oop*) (header_begin() + _oops_offset) ; }
oop* oops_end () const { return (oop*) (header_begin() + _scopes_data_offset) ; }
......@@ -361,9 +361,9 @@ class nmethod : public CodeBlob {
address nul_chk_table_end () const { return header_begin() + _nmethod_end_offset ; }
// Sizes
int consts_size () const { return consts_end () - consts_begin (); }
int insts_size () const { return insts_end () - insts_begin (); }
int stub_size () const { return stub_end () - stub_begin (); }
int consts_size () const { return consts_end () - consts_begin (); }
int oops_size () const { return (address) oops_end () - (address) oops_begin (); }
int scopes_data_size () const { return scopes_data_end () - scopes_data_begin (); }
int scopes_pcs_size () const { return (intptr_t) scopes_pcs_end () - (intptr_t) scopes_pcs_begin (); }
......@@ -374,9 +374,9 @@ class nmethod : public CodeBlob {
int total_size () const;
// Containment
bool consts_contains (address addr) const { return consts_begin () <= addr && addr < consts_end (); }
bool insts_contains (address addr) const { return insts_begin () <= addr && addr < insts_end (); }
bool stub_contains (address addr) const { return stub_begin () <= addr && addr < stub_end (); }
bool consts_contains (address addr) const { return consts_begin () <= addr && addr < consts_end (); }
bool oops_contains (oop* addr) const { return oops_begin () <= addr && addr < oops_end (); }
bool scopes_data_contains (address addr) const { return scopes_data_begin () <= addr && addr < scopes_data_end (); }
bool scopes_pcs_contains (PcDesc* addr) const { return scopes_pcs_begin () <= addr && addr < scopes_pcs_end (); }
......
......@@ -128,7 +128,16 @@ void RelocIterator::initialize(nmethod* nm, address begin, address limit) {
_code = nm;
_current = nm->relocation_begin() - 1;
_end = nm->relocation_end();
_addr = (address) nm->code_begin();
_addr = nm->content_begin();
// Initialize code sections.
_section_start[CodeBuffer::SECT_CONSTS] = nm->consts_begin();
_section_start[CodeBuffer::SECT_INSTS ] = nm->insts_begin() ;
_section_start[CodeBuffer::SECT_STUBS ] = nm->stub_begin() ;
_section_end [CodeBuffer::SECT_CONSTS] = nm->consts_end() ;
_section_end [CodeBuffer::SECT_INSTS ] = nm->insts_end() ;
_section_end [CodeBuffer::SECT_STUBS ] = nm->stub_end() ;
assert(!has_current(), "just checking");
assert(begin == NULL || begin >= nm->code_begin(), "in bounds");
......@@ -146,9 +155,11 @@ RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) {
_code = NULL; // Not cb->blob();
CodeBuffer* cb = cs->outer();
assert((int)SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
for (int n = 0; n < (int)SECT_LIMIT; n++) {
_section_start[n] = cb->code_section(n)->start();
assert((int) SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
CodeSection* cs = cb->code_section(n);
_section_start[n] = cs->start();
_section_end [n] = cs->end();
}
assert(!has_current(), "just checking");
......@@ -166,6 +177,12 @@ struct RelocIndexEntry {
};
bool RelocIterator::addr_in_const() const {
const int n = CodeBuffer::SECT_CONSTS;
return section_start(n) <= addr() && addr() < section_end(n);
}
static inline int num_cards(int code_size) {
return (code_size-1) / indexCardSize;
}
......@@ -360,31 +377,12 @@ void RelocIterator::advance_over_prefix() {
}
address RelocIterator::compute_section_start(int n) const {
// This routine not only computes a section start, but also
// memoizes it for later.
#define CACHE ((RelocIterator*)this)->_section_start[n]
CodeBlob* cb = code();
guarantee(cb != NULL, "must have a code blob");
if (n == CodeBuffer::SECT_INSTS)
return CACHE = cb->code_begin();
assert(cb->is_nmethod(), "only nmethods have these sections");
nmethod* nm = (nmethod*) cb;
address res = NULL;
switch (n) {
case CodeBuffer::SECT_STUBS:
res = nm->stub_begin();
break;
case CodeBuffer::SECT_CONSTS:
res = nm->consts_begin();
break;
default:
ShouldNotReachHere();
void RelocIterator::initialize_misc() {
set_has_current(false);
for (int i = (int) CodeBuffer::SECT_FIRST; i < (int) CodeBuffer::SECT_LIMIT; i++) {
_section_start[i] = NULL; // these will be lazily computed, if needed
_section_end [i] = NULL;
}
assert(nm->contains(res) || res == nm->code_end(), "tame pointer");
CACHE = res;
return res;
#undef CACHE
}
......
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -502,8 +502,7 @@ class RelocationHolder VALUE_OBJ_CLASS_SPEC {
// }
class RelocIterator : public StackObj {
enum { SECT_CONSTS = 2,
SECT_LIMIT = 3 }; // must be equal to CodeBuffer::SECT_LIMIT
enum { SECT_LIMIT = 3 }; // must be equal to CodeBuffer::SECT_LIMIT, checked in ctor
friend class Relocation;
friend class relocInfo; // for change_reloc_info_for_address only
typedef relocInfo::relocType relocType;
......@@ -521,6 +520,7 @@ class RelocIterator : public StackObj {
// Base addresses needed to compute targets of section_word_type relocs.
address _section_start[SECT_LIMIT];
address _section_end [SECT_LIMIT];
void set_has_current(bool b) {
_datalen = !b ? -1 : 0;
......@@ -540,14 +540,7 @@ class RelocIterator : public StackObj {
void advance_over_prefix(); // helper method
void initialize_misc() {
set_has_current(false);
for (int i = 0; i < SECT_LIMIT; i++) {
_section_start[i] = NULL; // these will be lazily computed, if needed
}
}
address compute_section_start(int n) const; // out-of-line helper
void initialize_misc();
void initialize(nmethod* nm, address begin, address limit);
......@@ -598,11 +591,15 @@ class RelocIterator : public StackObj {
bool has_current() const { return _datalen >= 0; }
void set_addr(address addr) { _addr = addr; }
bool addr_in_const() const { return addr() >= section_start(SECT_CONSTS); }
bool addr_in_const() const;
address section_start(int n) const {
address res = _section_start[n];
return (res != NULL) ? res : compute_section_start(n);
assert(_section_start[n], "must be initialized");
return _section_start[n];
}
address section_end(int n) const {
assert(_section_end[n], "must be initialized");
return _section_end[n];
}
// The address points to the affected displacement part of the instruction.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册