changeset 118:fb75a7673531

Merge
author rasbold
date Wed, 16 Apr 2008 14:55:36 -0700
parents 34935c25a52d deadee49286e
children d1a5218d7eaf
files src/cpu/x86/vm/assembler_x86_64.cpp
diffstat 2 files changed, 36 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/x86/vm/assembler_x86_32.cpp	Tue Apr 15 18:11:33 2008 -0400
+++ b/src/cpu/x86/vm/assembler_x86_32.cpp	Wed Apr 16 14:55:36 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/src/cpu/x86/vm/assembler_x86_64.cpp	Tue Apr 15 18:11:33 2008 -0400
+++ b/src/cpu/x86/vm/assembler_x86_64.cpp	Wed Apr 16 14:55:36 2008 -0700
@@ -4436,9 +4436,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) {