6644928: Internal Error (src/share/vm/code/relocInfo.hpp:1089)
Summary: Cardtable base can be zero, ExternalAddress can't take a NULL.
--- a/hotspot/src/cpu/x86/vm/assembler_x86_32.cpp Wed Apr 09 15:10:22 2008 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86_32.cpp Fri Apr 11 06:18:44 2008 -0700
@@ -3405,10 +3405,16 @@
assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
CardTableModRefBS* ct = (CardTableModRefBS*)bs;
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
- ExternalAddress cardtable((address)ct->byte_map_base);
- Address index(noreg, obj, Address::times_1);
-
- movb(as_Address(ArrayAddress(cardtable, index)), 0);
+
+ // The calculation for byte_map_base is as follows:
+ // byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
+ // So this essentially converts an address to a displacement and
+ // it will never need to be relocated. On 64bit however the value may be too
+ // large for a 32bit displacement
+
+ intptr_t disp = (intptr_t) ct->byte_map_base;
+ Address cardtable(noreg, obj, Address::times_1, disp);
+ movb(cardtable, 0);
}
--- a/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp Wed Apr 09 15:10:22 2008 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86_64.cpp Fri Apr 11 06:18:44 2008 -0700
@@ -4427,9 +4427,32 @@
assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind");
CardTableModRefBS* ct = (CardTableModRefBS*)bs;
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
- ExternalAddress cardtable((address)ct->byte_map_base);
- Address index(noreg, obj, Address::times_1);
- movb(as_Address(ArrayAddress(cardtable, index)), 0);
+
+ // The calculation for byte_map_base is as follows:
+ // byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
+ // So this essentially converts an address to a displacement and
+ // it will never need to be relocated. On 64bit however the value may be too
+ // large for a 32bit displacement
+
+ intptr_t disp = (intptr_t) ct->byte_map_base;
+ if (is_simm32(disp)) {
+ Address cardtable(noreg, obj, Address::times_1, disp);
+ movb(cardtable, 0);
+ } else {
+ // By doing it as an ExternalAddress disp could be converted to a rip-relative
+ // displacement and done in a single instruction given favorable mapping and
+ // a smarter version of as_Address. Worst case it is two instructions which
+ // is no worse off then loading disp into a register and doing as a simple
+ // Address() as above.
+ // We can't do as ExternalAddress as the only style since if disp == 0 we'll
+ // assert since NULL isn't acceptable in a reloci (see 6644928). In any case
+ // in some cases we'll get a single instruction version.
+
+ ExternalAddress cardtable((address)disp);
+ Address index(noreg, obj, Address::times_1);
+ movb(as_Address(ArrayAddress(cardtable, index)), 0);
+ }
+
}
void MacroAssembler::c2bool(Register x) {