提交 6d3dceaf 编写于 作者: T twisti

6951083: oops and relocations should part of nmethod not CodeBlob

Summary: This moves the oops from Codeblob to nmethod.
Reviewed-by: kvn, never
上级 0f0ccf63
/*
* Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2010 Sun Microsystems, Inc. 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
......@@ -42,8 +42,6 @@ public class CodeBlob extends VMObject {
private static CIntegerField instructionsOffsetField;
private static CIntegerField frameCompleteOffsetField;
private static CIntegerField dataOffsetField;
private static CIntegerField oopsOffsetField;
private static CIntegerField oopsLengthField;
private static CIntegerField frameSizeField;
private static AddressField oopMapsField;
......@@ -72,8 +70,6 @@ public class CodeBlob extends VMObject {
frameCompleteOffsetField = type.getCIntegerField("_frame_complete_offset");
instructionsOffsetField = type.getCIntegerField("_instructions_offset");
dataOffsetField = type.getCIntegerField("_data_offset");
oopsOffsetField = type.getCIntegerField("_oops_offset");
oopsLengthField = type.getCIntegerField("_oops_length");
frameSizeField = type.getCIntegerField("_frame_size");
oopMapsField = type.getAddressField("_oop_maps");
......@@ -131,19 +127,10 @@ public class CodeBlob extends VMObject {
return headerBegin().addOffsetTo(sizeField.getValue(addr));
}
public Address oopsBegin() {
return headerBegin().addOffsetTo(oopsOffsetField.getValue(addr));
}
public Address oopsEnd() {
return oopsBegin().addOffsetTo(getOopsLength());
}
// Offsets
public int getRelocationOffset() { return (int) headerSizeField.getValue(addr); }
public int getInstructionsOffset() { return (int) instructionsOffsetField.getValue(addr); }
public int getDataOffset() { return (int) dataOffsetField.getValue(addr); }
public int getOopsOffset() { return (int) oopsOffsetField.getValue(addr); }
// Sizes
public int getSize() { return (int) sizeField.getValue(addr); }
......@@ -157,19 +144,9 @@ public class CodeBlob extends VMObject {
// FIXME: add relocationContains
public boolean instructionsContains(Address addr) { return instructionsBegin().lessThanOrEqual(addr) && instructionsEnd().greaterThan(addr); }
public boolean dataContains(Address addr) { return dataBegin().lessThanOrEqual(addr) && dataEnd().greaterThan(addr); }
public boolean oopsContains(Address addr) { return oopsBegin().lessThanOrEqual(addr) && oopsEnd().greaterThan(addr); }
public boolean contains(Address addr) { return instructionsContains(addr); }
public boolean isFrameCompleteAt(Address a) { return instructionsContains(a) && a.minus(instructionsBegin()) >= frameCompleteOffsetField.getValue(addr); }
/** Support for oops in scopes and relocs. Note: index 0 is reserved for null. */
public OopHandle getOopAt(int index) {
if (index == 0) return null;
if (Assert.ASSERTS_ENABLED) {
Assert.that(index > 0 && index <= getOopsLength(), "must be a valid non-zero index");
}
return oopsBegin().getOopHandleAt((index - 1) * VM.getVM().getOopSize());
}
// Reclamation support (really only used by the nmethods, but in order to get asserts to work
// in the CodeCache they are defined virtual here)
public boolean isZombie() { return false; }
......@@ -223,18 +200,8 @@ public class CodeBlob extends VMObject {
}
protected void printComponentsOn(PrintStream tty) {
// FIXME: add relocation information
tty.println(" instructions: [" + instructionsBegin() + ", " + instructionsEnd() + "), " +
" data: [" + dataBegin() + ", " + dataEnd() + "), " +
" oops: [" + oopsBegin() + ", " + oopsEnd() + "), " +
" frame size: " + getFrameSize());
}
//--------------------------------------------------------------------------------
// Internals only below this point
//
private int getOopsLength() {
return (int) oopsLengthField.getValue(addr);
}
}
/*
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2010 Sun Microsystems, Inc. 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
......@@ -49,6 +49,7 @@ public class NMethod extends CodeBlob {
private static CIntegerField deoptOffsetField;
private static CIntegerField origPCOffsetField;
private static CIntegerField stubOffsetField;
private static CIntegerField oopsOffsetField;
private static CIntegerField scopesDataOffsetField;
private static CIntegerField scopesPCsOffsetField;
private static CIntegerField dependenciesOffsetField;
......@@ -98,6 +99,7 @@ public class NMethod extends CodeBlob {
deoptOffsetField = type.getCIntegerField("_deoptimize_offset");
origPCOffsetField = type.getCIntegerField("_orig_pc_offset");
stubOffsetField = type.getCIntegerField("_stub_offset");
oopsOffsetField = type.getCIntegerField("_oops_offset");
scopesDataOffsetField = type.getCIntegerField("_scopes_data_offset");
scopesPCsOffsetField = type.getCIntegerField("_scopes_pcs_offset");
dependenciesOffsetField = type.getCIntegerField("_dependencies_offset");
......@@ -141,7 +143,9 @@ public class NMethod extends CodeBlob {
public Address exceptionBegin() { return headerBegin().addOffsetTo(getExceptionOffset()); }
public Address deoptBegin() { return headerBegin().addOffsetTo(getDeoptOffset()); }
public Address stubBegin() { return headerBegin().addOffsetTo(getStubOffset()); }
public Address stubEnd() { return headerBegin().addOffsetTo(getScopesDataOffset()); }
public Address stubEnd() { return headerBegin().addOffsetTo(getOopsOffset()); }
public Address oopsBegin() { return headerBegin().addOffsetTo(getOopsOffset()); }
public Address oopsEnd() { return headerBegin().addOffsetTo(getScopesDataOffset()); }
public Address scopesDataBegin() { return headerBegin().addOffsetTo(getScopesDataOffset()); }
public Address scopesDataEnd() { return headerBegin().addOffsetTo(getScopesPCsOffset()); }
public Address scopesPCsBegin() { return headerBegin().addOffsetTo(getScopesPCsOffset()); }
......@@ -156,6 +160,7 @@ public class NMethod extends CodeBlob {
public int constantsSize() { return (int) constantsEnd() .minus(constantsBegin()); }
public int codeSize() { return (int) codeEnd() .minus(codeBegin()); }
public int stubSize() { return (int) stubEnd() .minus(stubBegin()); }
public int oopsSize() { return (int) oopsEnd() .minus(oopsBegin()); }
public int scopesDataSize() { return (int) scopesDataEnd() .minus(scopesDataBegin()); }
public int scopesPCsSize() { return (int) scopesPCsEnd() .minus(scopesPCsBegin()); }
public int dependenciesSize() { return (int) dependenciesEnd().minus(dependenciesBegin()); }
......@@ -178,6 +183,7 @@ public class NMethod extends CodeBlob {
public boolean constantsContains (Address addr) { return constantsBegin() .lessThanOrEqual(addr) && constantsEnd() .greaterThan(addr); }
public boolean codeContains (Address addr) { return codeBegin() .lessThanOrEqual(addr) && codeEnd() .greaterThan(addr); }
public boolean stubContains (Address addr) { return stubBegin() .lessThanOrEqual(addr) && stubEnd() .greaterThan(addr); }
public boolean oopsContains (Address addr) { return oopsBegin() .lessThanOrEqual(addr) && oopsEnd() .greaterThan(addr); }
public boolean scopesDataContains (Address addr) { return scopesDataBegin() .lessThanOrEqual(addr) && scopesDataEnd() .greaterThan(addr); }
public boolean scopesPCsContains (Address addr) { return scopesPCsBegin() .lessThanOrEqual(addr) && scopesPCsEnd() .greaterThan(addr); }
public boolean handlerTableContains(Address addr) { return handlerTableBegin().lessThanOrEqual(addr) && handlerTableEnd().greaterThan(addr); }
......@@ -187,6 +193,15 @@ public class NMethod extends CodeBlob {
public Address getEntryPoint() { return entryPointField.getValue(addr); }
public Address getVerifiedEntryPoint() { return verifiedEntryPointField.getValue(addr); }
/** Support for oops in scopes and relocs. Note: index 0 is reserved for null. */
public OopHandle getOopAt(int index) {
if (index == 0) return null;
if (Assert.ASSERTS_ENABLED) {
Assert.that(index > 0 && index <= oopsSize(), "must be a valid non-zero index");
}
return oopsBegin().getOopHandleAt((index - 1) * VM.getVM().getOopSize());
}
// FIXME: add interpreter_entry_point()
// FIXME: add lazy_interpreter_entry_point() for C2
......@@ -338,6 +353,14 @@ public class NMethod extends CodeBlob {
printOn(System.out);
}
protected void printComponentsOn(PrintStream tty) {
// FIXME: add relocation information
tty.println(" instructions: [" + instructionsBegin() + ", " + instructionsEnd() + "), " +
" data: [" + dataBegin() + ", " + dataEnd() + "), " +
" oops: [" + oopsBegin() + ", " + oopsEnd() + "), " +
" frame size: " + getFrameSize());
}
public String toString() {
Method method = getMethod();
return "NMethod for " +
......@@ -367,6 +390,7 @@ public class NMethod extends CodeBlob {
private int getExceptionOffset() { return (int) exceptionOffsetField .getValue(addr); }
private int getDeoptOffset() { return (int) deoptOffsetField .getValue(addr); }
private int getStubOffset() { return (int) stubOffsetField .getValue(addr); }
private int getOopsOffset() { return (int) oopsOffsetField .getValue(addr); }
private int getScopesDataOffset() { return (int) scopesDataOffsetField .getValue(addr); }
private int getScopesPCsOffset() { return (int) scopesPCsOffsetField .getValue(addr); }
private int getDependenciesOffset() { return (int) dependenciesOffsetField.getValue(addr); }
......
/*
* Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2010 Sun Microsystems, Inc. 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
......@@ -98,7 +98,12 @@ public class PointerFinder {
}
loc.inBlobInstructions = loc.blob.instructionsContains(a);
loc.inBlobData = loc.blob.dataContains(a);
loc.inBlobOops = loc.blob.oopsContains(a);
if (loc.blob.isNMethod()) {
NMethod nm = (NMethod) loc.blob;
loc.inBlobOops = nm.oopsContains(a);
}
loc.inBlobUnknownLocation = (!(loc.inBlobInstructions ||
loc.inBlobData ||
loc.inBlobOops));
......
/*
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2010 Sun Microsystems, Inc. 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
......@@ -321,7 +321,8 @@ void NativeMovConstReg::set_data(intptr_t x) {
set_long_at(add_offset, set_data32_simm13( long_at(add_offset), x));
// also store the value into an oop_Relocation cell, if any
CodeBlob* nm = CodeCache::find_blob(instruction_address());
CodeBlob* cb = CodeCache::find_blob(instruction_address());
nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL;
if (nm != NULL) {
RelocIterator iter(nm, instruction_address(), next_instruction_address());
oop* oop_addr = NULL;
......@@ -430,7 +431,8 @@ void NativeMovConstRegPatching::set_data(int x) {
set_long_at(add_offset, set_data32_simm13(long_at(add_offset), x));
// also store the value into an oop_Relocation cell, if any
CodeBlob* nm = CodeCache::find_blob(instruction_address());
CodeBlob* cb = CodeCache::find_blob(instruction_address());
nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL;
if (nm != NULL) {
RelocIterator iter(nm, instruction_address(), next_instruction_address());
oop* oop_addr = NULL;
......
/*
* Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2003-2010 Sun Microsystems, Inc. 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
......@@ -232,12 +232,11 @@ int generateJvmOffsets(GEN_variant gen_variant) {
GEN_OFFS(CodeBlob, _header_size);
GEN_OFFS(CodeBlob, _instructions_offset);
GEN_OFFS(CodeBlob, _data_offset);
GEN_OFFS(CodeBlob, _oops_offset);
GEN_OFFS(CodeBlob, _oops_length);
GEN_OFFS(CodeBlob, _frame_size);
printf("\n");
GEN_OFFS(nmethod, _method);
GEN_OFFS(nmethod, _oops_offset);
GEN_OFFS(nmethod, _scopes_data_offset);
GEN_OFFS(nmethod, _scopes_pcs_offset);
GEN_OFFS(nmethod, _handler_table_offset);
......
/*
* Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2003-2010 Sun Microsystems, Inc. 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
......@@ -130,7 +130,7 @@ typedef struct Nmethod_t {
int32_t scopes_data_beg; /* _scopes_data_offset */
int32_t scopes_data_end;
int32_t oops_beg; /* _oops_offset */
int32_t oops_len; /* _oops_length */
int32_t oops_end;
int32_t scopes_pcs_beg; /* _scopes_pcs_offset */
int32_t scopes_pcs_end;
......@@ -597,9 +597,9 @@ static int nmethod_info(Nmethod_t *N)
CHECK_FAIL(err);
/* Oops */
err = ps_pread(J->P, nm + OFFSET_CodeBlob_oops_offset, &N->oops_beg, SZ32);
err = ps_pread(J->P, nm + OFFSET_nmethod_oops_offset, &N->oops_beg, SZ32);
CHECK_FAIL(err);
err = ps_pread(J->P, nm + OFFSET_CodeBlob_oops_length, &N->oops_len, SZ32);
err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_offset, &N->oops_end, SZ32);
CHECK_FAIL(err);
/* scopes_pcs */
......@@ -624,8 +624,8 @@ static int nmethod_info(Nmethod_t *N)
fprintf(stderr, "\t nmethod_info: orig_pc_offset: %#x \n",
N->orig_pc_offset);
fprintf(stderr, "\t nmethod_info: oops_beg: %#x, oops_len: %#x\n",
N->oops_beg, N->oops_len);
fprintf(stderr, "\t nmethod_info: oops_beg: %#x, oops_end: %#x\n",
N->oops_beg, N->oops_end);
fprintf(stderr, "\t nmethod_info: scopes_data_beg: %#x, scopes_data_end: %#x\n",
N->scopes_data_beg, N->scopes_data_end);
......@@ -959,8 +959,8 @@ static int scopeDesc_chain(Nmethod_t *N) {
err = scope_desc_at(N, decode_offset, vf);
CHECK_FAIL(err);
if (vf->methodIdx > N->oops_len) {
fprintf(stderr, "\t scopeDesc_chain: (methodIdx > oops_len) !\n");
if (vf->methodIdx > ((N->oops_end - N->oops_beg) / POINTER_SIZE)) {
fprintf(stderr, "\t scopeDesc_chain: (methodIdx > oops length) !\n");
return -1;
}
err = read_pointer(N->J, N->nm + N->oops_beg + (vf->methodIdx-1)*POINTER_SIZE,
......
......@@ -510,9 +510,9 @@ class CodeBuffer: public StackObj {
copy_relocations_to(blob);
copy_code_to(blob);
}
void copy_oops_to(CodeBlob* blob) {
void copy_oops_to(nmethod* nm) {
if (!oop_recorder()->is_unused()) {
oop_recorder()->copy_to(blob);
oop_recorder()->copy_to(nm);
}
}
......
......@@ -66,8 +66,6 @@ CodeBlob::CodeBlob(const char* name, int header_size, int size, int frame_comple
_relocation_size = locs_size;
_instructions_offset = align_code_offset(header_size + locs_size);
_data_offset = size;
_oops_offset = size;
_oops_length = 0;
_frame_size = 0;
set_oop_maps(NULL);
}
......@@ -94,9 +92,6 @@ CodeBlob::CodeBlob(
_relocation_size = round_to(cb->total_relocation_size(), oopSize);
_instructions_offset = align_code_offset(header_size + _relocation_size);
_data_offset = _instructions_offset + round_to(cb->total_code_size(), oopSize);
_oops_offset = _size - round_to(cb->total_oop_size(), oopSize);
_oops_length = 0; // temporary, until the copy_oops handshake
assert(_oops_offset >= _data_offset, "codeBlob is too small");
assert(_data_offset <= size, "codeBlob is too small");
cb->copy_code_and_locs_to(this);
......@@ -131,99 +126,6 @@ void CodeBlob::flush() {
}
// Promote one word from an assembly-time handle to a live embedded oop.
inline void CodeBlob::initialize_immediate_oop(oop* dest, jobject handle) {
if (handle == NULL ||
// As a special case, IC oops are initialized to 1 or -1.
handle == (jobject) Universe::non_oop_word()) {
(*dest) = (oop)handle;
} else {
(*dest) = JNIHandles::resolve_non_null(handle);
}
}
void CodeBlob::copy_oops(GrowableArray<jobject>* array) {
assert(_oops_length == 0, "do this handshake just once, please");
int length = array->length();
assert((address)(oops_begin() + length) <= data_end(), "oops big enough");
oop* dest = oops_begin();
for (int index = 0 ; index < length; index++) {
initialize_immediate_oop(&dest[index], array->at(index));
}
_oops_length = length;
// Now we can fix up all the oops in the code.
// We need to do this in the code because
// the assembler uses jobjects as placeholders.
// The code and relocations have already been
// initialized by the CodeBlob constructor,
// so it is valid even at this early point to
// iterate over relocations and patch the code.
fix_oop_relocations(NULL, NULL, /*initialize_immediates=*/ true);
}
relocInfo::relocType CodeBlob::reloc_type_for_address(address pc) {
RelocIterator iter(this, pc, pc+1);
while (iter.next()) {
return (relocInfo::relocType) iter.type();
}
// No relocation info found for pc
ShouldNotReachHere();
return relocInfo::none; // dummy return value
}
bool CodeBlob::is_at_poll_return(address pc) {
RelocIterator iter(this, pc, pc+1);
while (iter.next()) {
if (iter.type() == relocInfo::poll_return_type)
return true;
}
return false;
}
bool CodeBlob::is_at_poll_or_poll_return(address pc) {
RelocIterator iter(this, pc, pc+1);
while (iter.next()) {
relocInfo::relocType t = iter.type();
if (t == relocInfo::poll_return_type || t == relocInfo::poll_type)
return true;
}
return false;
}
void CodeBlob::fix_oop_relocations(address begin, address end,
bool initialize_immediates) {
// re-patch all oop-bearing instructions, just in case some oops moved
RelocIterator iter(this, begin, end);
while (iter.next()) {
if (iter.type() == relocInfo::oop_type) {
oop_Relocation* reloc = iter.oop_reloc();
if (initialize_immediates && reloc->oop_is_immediate()) {
oop* dest = reloc->oop_addr();
initialize_immediate_oop(dest, (jobject) *dest);
}
// Refresh the oop-related bits of this instruction.
reloc->fix_oop_relocation();
}
// There must not be any interfering patches or breakpoints.
assert(!(iter.type() == relocInfo::breakpoint_type
&& iter.breakpoint_reloc()->active()),
"no active breakpoint");
}
}
void CodeBlob::do_unloading(BoolObjectClosure* is_alive,
OopClosure* keep_alive,
bool unloading_occurred) {
ShouldNotReachHere();
}
OopMap* CodeBlob::oop_map_for_return_address(address return_address) {
address pc = return_address ;
assert (oop_maps() != NULL, "nope");
......
......@@ -54,17 +54,12 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
// that range. There is a similar range(s) on returns
// which we don't detect.
int _data_offset; // offset to where data region begins
int _oops_offset; // offset to where embedded oop table begins (inside data)
int _oops_length; // number of embedded oops
int _frame_size; // size of stack frame
OopMapSet* _oop_maps; // OopMap for this CodeBlob
CodeComments _comments;
friend class OopRecorder;
void fix_oop_relocations(address begin, address end, bool initialize_immediates);
inline void initialize_immediate_oop(oop* dest, jobject handle);
public:
// Returns the space needed for CodeBlob
static unsigned int allocation_size(CodeBuffer* cb, int header_size);
......@@ -115,14 +110,11 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
address instructions_end() const { return (address) header_begin() + _data_offset; }
address data_begin() const { return (address) header_begin() + _data_offset; }
address data_end() const { return (address) header_begin() + _size; }
oop* oops_begin() const { return (oop*) (header_begin() + _oops_offset); }
oop* oops_end() const { return oops_begin() + _oops_length; }
// Offsets
int relocation_offset() const { return _header_size; }
int instructions_offset() const { return _instructions_offset; }
int data_offset() const { return _data_offset; }
int oops_offset() const { return _oops_offset; }
// Sizes
int size() const { return _size; }
......@@ -130,40 +122,16 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
int relocation_size() const { return (address) relocation_end() - (address) relocation_begin(); }
int instructions_size() const { return instructions_end() - instructions_begin(); }
int data_size() const { return data_end() - data_begin(); }
int oops_size() const { return (address) oops_end() - (address) oops_begin(); }
// Containment
bool blob_contains(address addr) const { return header_begin() <= addr && addr < data_end(); }
bool relocation_contains(relocInfo* addr) const{ return relocation_begin() <= addr && addr < relocation_end(); }
bool instructions_contains(address addr) const { return instructions_begin() <= addr && addr < instructions_end(); }
bool data_contains(address addr) const { return data_begin() <= addr && addr < data_end(); }
bool oops_contains(oop* addr) const { return oops_begin() <= addr && addr < oops_end(); }
bool contains(address addr) const { return instructions_contains(addr); }
bool is_frame_complete_at(address addr) const { return instructions_contains(addr) &&
addr >= instructions_begin() + _frame_complete_offset; }
// Relocation support
void fix_oop_relocations(address begin, address end) {
fix_oop_relocations(begin, end, false);
}
void fix_oop_relocations() {
fix_oop_relocations(NULL, NULL, false);
}
relocInfo::relocType reloc_type_for_address(address pc);
bool is_at_poll_return(address pc);
bool is_at_poll_or_poll_return(address pc);
// Support for oops in scopes and relocs:
// Note: index 0 is reserved for null.
oop oop_at(int index) const { return index == 0? (oop)NULL: *oop_addr_at(index); }
oop* oop_addr_at(int index) const{ // for GC
// relocation indexes are biased by 1 (because 0 is reserved)
assert(index > 0 && index <= _oops_length, "must be a valid non-zero index");
return &oops_begin()[index-1];
}
void copy_oops(GrowableArray<jobject>* oops);
// CodeCache support: really only used by the nmethods, but in order to get
// asserts and certain bookkeeping to work in the CodeCache they are defined
// virtual here.
......@@ -175,12 +143,6 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
// GC support
virtual bool is_alive() const = 0;
virtual void do_unloading(BoolObjectClosure* is_alive,
OopClosure* keep_alive,
bool unloading_occurred);
virtual void oops_do(OopClosure* f) = 0;
// (All CodeBlob subtypes other than NMethod currently have
// an empty oops_do() method.
// OopMap for frame
OopMapSet* oop_maps() const { return _oop_maps; }
......@@ -245,11 +207,6 @@ class BufferBlob: public CodeBlob {
// GC/Verification support
void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }
bool is_alive() const { return true; }
void do_unloading(BoolObjectClosure* is_alive,
OopClosure* keep_alive,
bool unloading_occurred) { /* do nothing */ }
void oops_do(OopClosure* f) { /* do nothing*/ }
void verify();
void print() const PRODUCT_RETURN;
......@@ -334,10 +291,6 @@ class RuntimeStub: public CodeBlob {
// GC/Verification support
void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ }
bool is_alive() const { return true; }
void do_unloading(BoolObjectClosure* is_alive,
OopClosure* keep_alive,
bool unloading_occurred) { /* do nothing */ }
void oops_do(OopClosure* f) { /* do-nothing*/ }
void verify();
void print() const PRODUCT_RETURN;
......@@ -363,9 +316,6 @@ class SingletonBlob: public CodeBlob {
{};
bool is_alive() const { return true; }
void do_unloading(BoolObjectClosure* is_alive,
OopClosure* keep_alive,
bool unloading_occurred) { /* do-nothing*/ }
void verify(); // does nothing
void print() const PRODUCT_RETURN;
......@@ -423,9 +373,6 @@ class DeoptimizationBlob: public SingletonBlob {
// GC for args
void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* Nothing to do */ }
// Iteration
void oops_do(OopClosure* f) {}
// Printing
void print_value_on(outputStream* st) const PRODUCT_RETURN;
......@@ -477,9 +424,6 @@ class UncommonTrapBlob: public SingletonBlob {
// Typing
bool is_uncommon_trap_stub() const { return true; }
// Iteration
void oops_do(OopClosure* f) {}
};
......@@ -512,9 +456,6 @@ class ExceptionBlob: public SingletonBlob {
// Typing
bool is_exception_stub() const { return true; }
// Iteration
void oops_do(OopClosure* f) {}
};
#endif // COMPILER2
......@@ -548,7 +489,4 @@ class SafepointBlob: public SingletonBlob {
// Typing
bool is_safepoint_stub() const { return true; }
// Iteration
void oops_do(OopClosure* f) {}
};
......@@ -74,12 +74,12 @@ class CodeBlob_sizes {
total_size += cb->size();
header_size += cb->header_size();
relocation_size += cb->relocation_size();
scopes_oop_size += cb->oops_size();
if (cb->is_nmethod()) {
nmethod *nm = (nmethod*)cb;
nmethod* nm = cb->as_nmethod_or_null();
code_size += nm->code_size();
stub_size += nm->stub_size();
scopes_oop_size += nm->oops_size();
scopes_data_size += nm->scopes_data_size();
scopes_pcs_size += nm->scopes_pcs_size();
} else {
......@@ -262,14 +262,14 @@ int CodeCache::alignment_offset() {
}
// Mark code blobs for unloading if they contain otherwise
// unreachable oops.
// Mark nmethods for unloading if they contain otherwise unreachable
// oops.
void CodeCache::do_unloading(BoolObjectClosure* is_alive,
OopClosure* keep_alive,
bool unloading_occurred) {
assert_locked_or_safepoint(CodeCache_lock);
FOR_ALL_ALIVE_BLOBS(cb) {
cb->do_unloading(is_alive, keep_alive, unloading_occurred);
FOR_ALL_ALIVE_NMETHODS(nm) {
nm->do_unloading(is_alive, keep_alive, unloading_occurred);
}
}
......@@ -509,9 +509,9 @@ void CodeCache::gc_epilogue() {
if (needs_cache_clean()) {
nm->cleanup_inline_caches();
}
debug_only(nm->verify();)
DEBUG_ONLY(nm->verify());
nm->fix_oop_relocations();
}
cb->fix_oop_relocations();
}
set_needs_cache_clean(false);
prune_scavenge_root_nmethods();
......
/*
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2010 Sun Microsystems, Inc. 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
......@@ -441,11 +441,11 @@ void CompiledIC::compute_monomorphic_entry(methodHandle method,
}
inline static RelocIterator parse_ic(CodeBlob* code, address ic_call, oop* &_oop_addr, bool *is_optimized) {
inline static RelocIterator parse_ic(nmethod* nm, address ic_call, oop* &_oop_addr, bool *is_optimized) {
address first_oop = NULL;
// Mergers please note: Sun SC5.x CC insists on an lvalue for a reference parameter.
CodeBlob *code1 = code;
return virtual_call_Relocation::parse_ic(code1, ic_call, first_oop, _oop_addr, is_optimized);
nmethod* tmp_nm = nm;
return virtual_call_Relocation::parse_ic(tmp_nm, ic_call, first_oop, _oop_addr, is_optimized);
}
CompiledIC::CompiledIC(NativeCall* ic_call)
......
......@@ -99,12 +99,12 @@ struct nmethod_stats_struct {
code_size += nm->code_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();
dependencies_size += nm->dependencies_size();
handler_table_size += nm->handler_table_size();
nul_chk_table_size += nm->nul_chk_table_size();
oops_size += nm->oops_size();
}
void print_nmethod_stats() {
if (nmethod_count == 0) return;
......@@ -114,12 +114,12 @@ struct nmethod_stats_struct {
if (code_size != 0) tty->print_cr(" main code = %d", code_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);
if (dependencies_size != 0) tty->print_cr(" dependencies = %d", dependencies_size);
if (handler_table_size != 0) tty->print_cr(" handler table = %d", handler_table_size);
if (nul_chk_table_size != 0) tty->print_cr(" nul chk table = %d", nul_chk_table_size);
if (oops_size != 0) tty->print_cr(" oops = %d", oops_size);
}
int native_nmethod_count;
......@@ -600,7 +600,8 @@ nmethod::nmethod(
#endif // def HAVE_DTRACE_H
_stub_offset = data_offset();
_consts_offset = data_offset();
_scopes_data_offset = data_offset();
_oops_offset = data_offset();
_scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize);
_scopes_pcs_offset = _scopes_data_offset;
_dependencies_offset = _scopes_pcs_offset;
_handler_table_offset = _dependencies_offset;
......@@ -690,7 +691,8 @@ nmethod::nmethod(
_orig_pc_offset = 0;
_stub_offset = data_offset();
_consts_offset = data_offset();
_scopes_data_offset = data_offset();
_oops_offset = data_offset();
_scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size(), oopSize);
_scopes_pcs_offset = _scopes_data_offset;
_dependencies_offset = _scopes_pcs_offset;
_handler_table_offset = _dependencies_offset;
......@@ -805,8 +807,9 @@ nmethod::nmethod(
_unwind_handler_offset = -1;
}
_consts_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->consts()->start());
_scopes_data_offset = data_offset();
_scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize);
_oops_offset = data_offset();
_scopes_data_offset = _oops_offset + round_to(code_buffer->total_oop_size (), oopSize);
_scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize);
_dependencies_offset = _scopes_pcs_offset + adjust_pcs_size(debug_info->pcs_size());
_handler_table_offset = _dependencies_offset + round_to(dependencies->size_in_bytes (), oopSize);
_nul_chk_table_offset = _handler_table_offset + round_to(handler_table->size_in_bytes(), oopSize);
......@@ -990,6 +993,79 @@ void nmethod::set_version(int v) {
}
// Promote one word from an assembly-time handle to a live embedded oop.
inline void nmethod::initialize_immediate_oop(oop* dest, jobject handle) {
if (handle == NULL ||
// As a special case, IC oops are initialized to 1 or -1.
handle == (jobject) Universe::non_oop_word()) {
(*dest) = (oop) handle;
} else {
(*dest) = JNIHandles::resolve_non_null(handle);
}
}
void nmethod::copy_oops(GrowableArray<jobject>* array) {
//assert(oops_size() == 0, "do this handshake just once, please");
int length = array->length();
assert((address)(oops_begin() + length) <= data_end(), "oops big enough");
oop* dest = oops_begin();
for (int index = 0 ; index < length; index++) {
initialize_immediate_oop(&dest[index], array->at(index));
}
// Now we can fix up all the oops in the code. We need to do this
// in the code because the assembler uses jobjects as placeholders.
// The code and relocations have already been initialized by the
// CodeBlob constructor, so it is valid even at this early point to
// iterate over relocations and patch the code.
fix_oop_relocations(NULL, NULL, /*initialize_immediates=*/ true);
}
bool nmethod::is_at_poll_return(address pc) {
RelocIterator iter(this, pc, pc+1);
while (iter.next()) {
if (iter.type() == relocInfo::poll_return_type)
return true;
}
return false;
}
bool nmethod::is_at_poll_or_poll_return(address pc) {
RelocIterator iter(this, pc, pc+1);
while (iter.next()) {
relocInfo::relocType t = iter.type();
if (t == relocInfo::poll_return_type || t == relocInfo::poll_type)
return true;
}
return false;
}
void nmethod::fix_oop_relocations(address begin, address end, bool initialize_immediates) {
// re-patch all oop-bearing instructions, just in case some oops moved
RelocIterator iter(this, begin, end);
while (iter.next()) {
if (iter.type() == relocInfo::oop_type) {
oop_Relocation* reloc = iter.oop_reloc();
if (initialize_immediates && reloc->oop_is_immediate()) {
oop* dest = reloc->oop_addr();
initialize_immediate_oop(dest, (jobject) *dest);
}
// Refresh the oop-related bits of this instruction.
reloc->fix_oop_relocation();
}
// There must not be any interfering patches or breakpoints.
assert(!(iter.type() == relocInfo::breakpoint_type
&& iter.breakpoint_reloc()->active()),
"no active breakpoint");
}
}
ScopeDesc* nmethod::scope_desc_at(address pc) {
PcDesc* pd = pc_desc_at(pc);
guarantee(pd != NULL, "scope must be present");
......@@ -2282,6 +2358,10 @@ void nmethod::print() const {
consts_begin(),
consts_end(),
consts_size());
if (oops_size () > 0) tty->print_cr(" oops [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
oops_begin(),
oops_end(),
oops_size());
if (scopes_data_size () > 0) tty->print_cr(" scopes data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
scopes_data_begin(),
scopes_data_end(),
......
......@@ -105,6 +105,7 @@ struct nmFlags {
// [Relocation]
// - relocation information
// - constant part (doubles, longs and floats used in nmethod)
// - oop table
// [Code]
// - code body
// - exception handler
......@@ -161,6 +162,7 @@ class nmethod : public CodeBlob {
#endif // def HAVE_DTRACE_H
int _stub_offset;
int _consts_offset;
int _oops_offset; // offset to where embedded oop table begins (inside data)
int _scopes_data_offset;
int _scopes_pcs_offset;
int _dependencies_offset;
......@@ -347,7 +349,10 @@ class nmethod : public CodeBlob {
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() + _scopes_data_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) ; }
address scopes_data_begin () const { return header_begin() + _scopes_data_offset ; }
address scopes_data_end () const { return header_begin() + _scopes_pcs_offset ; }
PcDesc* scopes_pcs_begin () const { return (PcDesc*)(header_begin() + _scopes_pcs_offset ); }
......@@ -359,20 +364,24 @@ class nmethod : public CodeBlob {
address nul_chk_table_begin () const { return header_begin() + _nul_chk_table_offset ; }
address nul_chk_table_end () const { return header_begin() + _nmethod_end_offset ; }
int code_size () const { return code_end () - code_begin (); }
int stub_size () const { return stub_end () - stub_begin (); }
int consts_size () const { return consts_end () - consts_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 (); }
int dependencies_size () const { return dependencies_end () - dependencies_begin (); }
int handler_table_size() const { return handler_table_end() - handler_table_begin(); }
int nul_chk_table_size() const { return nul_chk_table_end() - nul_chk_table_begin(); }
// Sizes
int code_size () const { return code_end () - code_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 (); }
int dependencies_size () const { return dependencies_end () - dependencies_begin (); }
int handler_table_size() const { return handler_table_end() - handler_table_begin(); }
int nul_chk_table_size() const { return nul_chk_table_end() - nul_chk_table_begin(); }
int total_size () const;
// Containment
bool code_contains (address addr) const { return code_begin () <= addr && addr < code_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 (); }
bool handler_table_contains(address addr) const { return handler_table_begin() <= addr && addr < handler_table_end(); }
......@@ -431,6 +440,29 @@ class nmethod : public CodeBlob {
int version() const { return flags.version; }
void set_version(int v);
// Support for oops in scopes and relocs:
// Note: index 0 is reserved for null.
oop oop_at(int index) const { return index == 0 ? (oop) NULL: *oop_addr_at(index); }
oop* oop_addr_at(int index) const { // for GC
// relocation indexes are biased by 1 (because 0 is reserved)
assert(index > 0 && index <= oops_size(), "must be a valid non-zero index");
return &oops_begin()[index - 1];
}
void copy_oops(GrowableArray<jobject>* oops);
// Relocation support
private:
void fix_oop_relocations(address begin, address end, bool initialize_immediates);
inline void initialize_immediate_oop(oop* dest, jobject handle);
public:
void fix_oop_relocations(address begin, address end) { fix_oop_relocations(begin, end, false); }
void fix_oop_relocations() { fix_oop_relocations(NULL, NULL, false); }
bool is_at_poll_return(address pc);
bool is_at_poll_or_poll_return(address pc);
// Non-perm oop support
bool on_scavenge_root_list() const { return (_scavenge_root_state & 1) != 0; }
protected:
......@@ -511,8 +543,8 @@ class nmethod : public CodeBlob {
void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map,
OopClosure* f);
virtual void oops_do(OopClosure* f) { oops_do(f, false); }
void oops_do(OopClosure* f, bool do_strong_roots_only);
void oops_do(OopClosure* f) { oops_do(f, false); }
void oops_do(OopClosure* f, bool do_strong_roots_only);
bool detect_scavenge_root_oops();
void verify_scavenge_root_oops() PRODUCT_RETURN;
......
/*
* Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1998-2010 Sun Microsystems, Inc. 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
......@@ -50,10 +50,10 @@ int OopRecorder::oop_size() {
return _handles->length() * sizeof(oop);
}
void OopRecorder::copy_to(CodeBlob* code) {
void OopRecorder::copy_to(nmethod* nm) {
assert(_complete, "must be frozen");
maybe_initialize(); // get non-null handles, even if we have no oops
code->copy_oops(_handles);
nm->copy_oops(_handles);
}
void OopRecorder::maybe_initialize() {
......
/*
* Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1998-2010 Sun Microsystems, Inc. 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
......@@ -70,8 +70,8 @@ class OopRecorder : public ResourceObj {
return _handles->length() + first_index;
}
// copy the generated oop table to CodeBlob
void copy_to(CodeBlob* code); // => code->copy_oops(_handles)
// copy the generated oop table to nmethod
void copy_to(nmethod* nm); // => nm->copy_oops(_handles)
bool is_unused() { return _handles == NULL && !_complete; }
#ifdef ASSERT
......
/*
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2010 Sun Microsystems, Inc. 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
......@@ -115,24 +115,25 @@ void relocInfo::remove_reloc_info_for_address(RelocIterator *itr, address pc, re
// ----------------------------------------------------------------------------------------------------
// Implementation of RelocIterator
void RelocIterator::initialize(CodeBlob* cb, address begin, address limit) {
void RelocIterator::initialize(nmethod* nm, address begin, address limit) {
initialize_misc();
if (cb == NULL && begin != NULL) {
// allow CodeBlob to be deduced from beginning address
cb = CodeCache::find_blob(begin);
if (nm == NULL && begin != NULL) {
// allow nmethod to be deduced from beginning address
CodeBlob* cb = CodeCache::find_blob(begin);
nm = cb->as_nmethod_or_null();
}
assert(cb != NULL, "must be able to deduce nmethod from other arguments");
assert(nm != NULL, "must be able to deduce nmethod from other arguments");
_code = cb;
_current = cb->relocation_begin()-1;
_end = cb->relocation_end();
_addr = (address) cb->instructions_begin();
_code = nm;
_current = nm->relocation_begin() - 1;
_end = nm->relocation_end();
_addr = (address) nm->instructions_begin();
assert(!has_current(), "just checking");
address code_end = cb->instructions_end();
address code_end = nm->instructions_end();
assert(begin == NULL || begin >= cb->instructions_begin(), "in bounds");
assert(begin == NULL || begin >= nm->instructions_begin(), "in bounds");
// FIX THIS assert(limit == NULL || limit <= code_end, "in bounds");
set_limits(begin, limit);
}
......@@ -754,7 +755,7 @@ oop* oop_Relocation::oop_addr() {
// oop is stored in the code stream
return (oop*) pd_address_in_code();
} else {
// oop is stored in table at CodeBlob::oops_begin
// oop is stored in table at nmethod::oops_begin
return code()->oop_addr_at(n);
}
}
......@@ -776,26 +777,28 @@ void oop_Relocation::fix_oop_relocation() {
}
RelocIterator virtual_call_Relocation::parse_ic(CodeBlob* &code, address &ic_call, address &first_oop,
RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop,
oop* &oop_addr, bool *is_optimized) {
assert(ic_call != NULL, "ic_call address must be set");
assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input");
if (code == NULL) {
if (nm == NULL) {
CodeBlob* code;
if (ic_call != NULL) {
code = CodeCache::find_blob(ic_call);
} else if (first_oop != NULL) {
code = CodeCache::find_blob(first_oop);
}
assert(code != NULL, "address to parse must be in CodeBlob");
nm = code->as_nmethod_or_null();
assert(nm != NULL, "address to parse must be in nmethod");
}
assert(ic_call == NULL || code->contains(ic_call), "must be in CodeBlob");
assert(first_oop == NULL || code->contains(first_oop), "must be in CodeBlob");
assert(ic_call == NULL || nm->contains(ic_call), "must be in nmethod");
assert(first_oop == NULL || nm->contains(first_oop), "must be in nmethod");
address oop_limit = NULL;
if (ic_call != NULL) {
// search for the ic_call at the given address
RelocIterator iter(code, ic_call, ic_call+1);
RelocIterator iter(nm, ic_call, ic_call+1);
bool ret = iter.next();
assert(ret == true, "relocInfo must exist at this address");
assert(iter.addr() == ic_call, "must find ic_call");
......@@ -814,7 +817,7 @@ RelocIterator virtual_call_Relocation::parse_ic(CodeBlob* &code, address &ic_cal
}
// search for the first_oop, to get its oop_addr
RelocIterator all_oops(code, first_oop);
RelocIterator all_oops(nm, first_oop);
RelocIterator iter = all_oops;
iter.set_limit(first_oop+1);
bool found_oop = false;
......@@ -842,7 +845,7 @@ RelocIterator virtual_call_Relocation::parse_ic(CodeBlob* &code, address &ic_cal
}
}
guarantee(!did_reset, "cannot find ic_call");
iter = RelocIterator(code); // search the whole CodeBlob
iter = RelocIterator(nm); // search the whole nmethod
did_reset = true;
}
......@@ -1175,9 +1178,9 @@ void RelocIterator::print() {
// For the debugger:
extern "C"
void print_blob_locs(CodeBlob* cb) {
cb->print();
RelocIterator iter(cb);
void print_blob_locs(nmethod* nm) {
nm->print();
RelocIterator iter(nm);
iter.print();
}
extern "C"
......
......@@ -512,7 +512,7 @@ class RelocIterator : public StackObj {
address _limit; // stop producing relocations after this _addr
relocInfo* _current; // the current relocation information
relocInfo* _end; // end marker; we're done iterating when _current == _end
CodeBlob* _code; // compiled method containing _addr
nmethod* _code; // compiled method containing _addr
address _addr; // instruction to which the relocation applies
short _databuf; // spare buffer for compressed data
short* _data; // pointer to the relocation's data
......@@ -549,7 +549,7 @@ class RelocIterator : public StackObj {
address compute_section_start(int n) const; // out-of-line helper
void initialize(CodeBlob* nm, address begin, address limit);
void initialize(nmethod* nm, address begin, address limit);
friend class PatchingRelocIterator;
// make an uninitialized one, for PatchingRelocIterator:
......@@ -557,7 +557,7 @@ class RelocIterator : public StackObj {
public:
// constructor
RelocIterator(CodeBlob* cb, address begin = NULL, address limit = NULL);
RelocIterator(nmethod* nm, address begin = NULL, address limit = NULL);
RelocIterator(CodeSection* cb, address begin = NULL, address limit = NULL);
// get next reloc info, return !eos
......@@ -592,7 +592,7 @@ class RelocIterator : public StackObj {
relocType type() const { return current()->type(); }
int format() const { return (relocInfo::have_format) ? current()->format() : 0; }
address addr() const { return _addr; }
CodeBlob* code() const { return _code; }
nmethod* code() const { return _code; }
short* data() const { return _data; }
int datalen() const { return _datalen; }
bool has_current() const { return _datalen >= 0; }
......@@ -790,9 +790,9 @@ class Relocation VALUE_OBJ_CLASS_SPEC {
public:
// accessors which only make sense for a bound Relocation
address addr() const { return binding()->addr(); }
CodeBlob* code() const { return binding()->code(); }
bool addr_in_const() const { return binding()->addr_in_const(); }
address addr() const { return binding()->addr(); }
nmethod* code() const { return binding()->code(); }
bool addr_in_const() const { return binding()->addr_in_const(); }
protected:
short* data() const { return binding()->data(); }
int datalen() const { return binding()->datalen(); }
......@@ -982,12 +982,12 @@ class virtual_call_Relocation : public CallRelocation {
// Figure out where an ic_call is hiding, given a set-oop or call.
// Either ic_call or first_oop must be non-null; the other is deduced.
// Code if non-NULL must be the CodeBlob, else it is deduced.
// Code if non-NULL must be the nmethod, else it is deduced.
// The address of the patchable oop is also deduced.
// The returned iterator will enumerate over the oops and the ic_call,
// as well as any other relocations that happen to be in that span of code.
// Recognize relevant set_oops with: oop_reloc()->oop_addr() == oop_addr.
static RelocIterator parse_ic(CodeBlob* &code, address &ic_call, address &first_oop, oop* &oop_addr, bool *is_optimized);
static RelocIterator parse_ic(nmethod* &nm, address &ic_call, address &first_oop, oop* &oop_addr, bool *is_optimized);
};
......@@ -1304,8 +1304,8 @@ inline name##_Relocation* RelocIterator::name##_reloc() { \
APPLY_TO_RELOCATIONS(EACH_CASE);
#undef EACH_CASE
inline RelocIterator::RelocIterator(CodeBlob* cb, address begin, address limit) {
initialize(cb, begin, limit);
inline RelocIterator::RelocIterator(nmethod* nm, address begin, address limit) {
initialize(nm, begin, limit);
}
// if you are going to patch code, you should use this subclass of
......@@ -1323,8 +1323,8 @@ class PatchingRelocIterator : public RelocIterator {
void operator=(const RelocIterator&);
public:
PatchingRelocIterator(CodeBlob* cb, address begin =NULL, address limit =NULL)
: RelocIterator(cb, begin, limit) { prepass(); }
PatchingRelocIterator(nmethod* nm, address begin = NULL, address limit = NULL)
: RelocIterator(nm, begin, limit) { prepass(); }
~PatchingRelocIterator() { postpass(); }
};
/*
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2010 Sun Microsystems, Inc. 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
......@@ -58,8 +58,8 @@ MarkingCodeBlobClosure::MarkScope::~MarkScope() {
}
void MarkingCodeBlobClosure::do_code_blob(CodeBlob* cb) {
if (!cb->is_nmethod()) return;
nmethod* nm = (nmethod*) cb;
nmethod* nm = cb->as_nmethod_or_null();
if (nm == NULL) return;
if (!nm->test_set_oops_do_mark()) {
NOT_PRODUCT(if (TraceScavenge) nm->print_on(tty, "oops_do, 1st visit\n"));
do_newly_marked_nmethod(nm);
......@@ -74,11 +74,14 @@ void CodeBlobToOopClosure::do_newly_marked_nmethod(nmethod* nm) {
void CodeBlobToOopClosure::do_code_blob(CodeBlob* cb) {
if (!_do_marking) {
NOT_PRODUCT(if (TraceScavenge && Verbose && cb->is_nmethod()) ((nmethod*)cb)->print_on(tty, "oops_do, unmarked visit\n"));
nmethod* nm = cb->as_nmethod_or_null();
NOT_PRODUCT(if (TraceScavenge && Verbose && nm != NULL) nm->print_on(tty, "oops_do, unmarked visit\n"));
// This assert won't work, since there are lots of mini-passes
// (mostly in debug mode) that co-exist with marking phases.
//assert(!(cb->is_nmethod() && ((nmethod*)cb)->test_oops_do_mark()), "found marked nmethod during mark-free phase");
cb->oops_do(_cl);
if (nm != NULL) {
nm->oops_do(_cl);
}
} else {
MarkingCodeBlobClosure::do_code_blob(cb);
}
......
......@@ -1435,7 +1435,7 @@ IRT_LEAF(void, SharedRuntime::fixup_callers_callsite(methodOopDesc* method, addr
// for the rest of its life! Just another racing bug in the life of
// fixup_callers_callsite ...
//
RelocIterator iter(cb, call->instruction_address(), call->next_instruction_address());
RelocIterator iter(nm, call->instruction_address(), call->next_instruction_address());
iter.next();
assert(iter.has_current(), "must have a reloc at java call site");
relocInfo::relocType typ = iter.reloc()->type();
......
/*
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2000-2010 Sun Microsystems, Inc. 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
......@@ -607,8 +607,6 @@ static inline uint64_t cast_uint64_t(size_t x)
nonstatic_field(CodeBlob, _instructions_offset, int) \
nonstatic_field(CodeBlob, _frame_complete_offset, int) \
nonstatic_field(CodeBlob, _data_offset, int) \
nonstatic_field(CodeBlob, _oops_offset, int) \
nonstatic_field(CodeBlob, _oops_length, int) \
nonstatic_field(CodeBlob, _frame_size, int) \
nonstatic_field(CodeBlob, _oop_maps, OopMapSet*) \
\
......@@ -626,6 +624,8 @@ static inline uint64_t cast_uint64_t(size_t x)
nonstatic_field(nmethod, _deoptimize_offset, int) \
nonstatic_field(nmethod, _orig_pc_offset, int) \
nonstatic_field(nmethod, _stub_offset, int) \
nonstatic_field(nmethod, _consts_offset, int) \
nonstatic_field(nmethod, _oops_offset, int) \
nonstatic_field(nmethod, _scopes_data_offset, int) \
nonstatic_field(nmethod, _scopes_pcs_offset, int) \
nonstatic_field(nmethod, _dependencies_offset, int) \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册