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