Push version 2.2.8 to trunk.
Performance improvements in the x64 and ARM backends.
git-svn-id: http://v8.googlecode.com/svn/trunk@4588 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index c20c77e..d97f04b 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -232,30 +232,23 @@
}
-// Will clobber 4 registers: object, offset, scratch, ip. The
-// register 'object' contains a heap object pointer. The heap object
-// tag is shifted away.
-void MacroAssembler::RecordWrite(Register object, Register offset,
- Register scratch) {
- // The compiled code assumes that record write doesn't change the
- // context register, so we check that none of the clobbered
- // registers are cp.
- ASSERT(!object.is(cp) && !offset.is(cp) && !scratch.is(cp));
+void MacroAssembler::RecordWriteHelper(Register object,
+ Register offset,
+ Register scratch) {
+ if (FLAG_debug_code) {
+ // Check that the object is not in new space.
+ Label not_in_new_space;
+ InNewSpace(object, scratch, ne, ¬_in_new_space);
+ Abort("new-space object passed to RecordWriteHelper");
+ bind(¬_in_new_space);
+ }
// This is how much we shift the remembered set bit offset to get the
// offset of the word in the remembered set. We divide by kBitsPerInt (32,
// shift right 5) and then multiply by kIntSize (4, shift left 2).
const int kRSetWordShift = 3;
- Label fast, done;
-
- // First, test that the object is not in the new space. We cannot set
- // remembered set bits in the new space.
- // object: heap object pointer (with tag)
- // offset: offset to store location from the object
- and_(scratch, object, Operand(ExternalReference::new_space_mask()));
- cmp(scratch, Operand(ExternalReference::new_space_start()));
- b(eq, &done);
+ Label fast;
// Compute the bit offset in the remembered set.
// object: heap object pointer (with tag)
@@ -307,6 +300,38 @@
mov(ip, Operand(1));
orr(scratch, scratch, Operand(ip, LSL, offset));
str(scratch, MemOperand(object));
+}
+
+
+void MacroAssembler::InNewSpace(Register object,
+ Register scratch,
+ Condition cc,
+ Label* branch) {
+ ASSERT(cc == eq || cc == ne);
+ and_(scratch, object, Operand(ExternalReference::new_space_mask()));
+ cmp(scratch, Operand(ExternalReference::new_space_start()));
+ b(cc, branch);
+}
+
+
+// Will clobber 4 registers: object, offset, scratch, ip. The
+// register 'object' contains a heap object pointer. The heap object
+// tag is shifted away.
+void MacroAssembler::RecordWrite(Register object, Register offset,
+ Register scratch) {
+ // The compiled code assumes that record write doesn't change the
+ // context register, so we check that none of the clobbered
+ // registers are cp.
+ ASSERT(!object.is(cp) && !offset.is(cp) && !scratch.is(cp));
+
+ Label done;
+
+ // First, test that the object is not in the new space. We cannot set
+ // remembered set bits in the new space.
+ InNewSpace(object, scratch, eq, &done);
+
+ // Record the actual write.
+ RecordWriteHelper(object, offset, scratch);
bind(&done);
@@ -399,6 +424,20 @@
}
+void MacroAssembler::InitializeNewString(Register string,
+ Register length,
+ Heap::RootListIndex map_index,
+ Register scratch1,
+ Register scratch2) {
+ mov(scratch1, Operand(length, LSL, kSmiTagSize));
+ LoadRoot(scratch2, map_index);
+ str(scratch1, FieldMemOperand(string, String::kLengthOffset));
+ mov(scratch1, Operand(String::kEmptyHashField));
+ str(scratch2, FieldMemOperand(string, HeapObject::kMapOffset));
+ str(scratch1, FieldMemOperand(string, String::kHashFieldOffset));
+}
+
+
int MacroAssembler::ActivationFrameAlignment() {
#if defined(V8_HOST_ARCH_ARM)
// Running on the real platform. Use the alignment as mandated by the local
@@ -1029,11 +1068,11 @@
TAG_OBJECT);
// Set the map, length and hash field.
- LoadRoot(scratch1, Heap::kStringMapRootIndex);
- str(length, FieldMemOperand(result, String::kLengthOffset));
- str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset));
- mov(scratch2, Operand(String::kEmptyHashField));
- str(scratch2, FieldMemOperand(result, String::kHashFieldOffset));
+ InitializeNewString(result,
+ length,
+ Heap::kStringMapRootIndex,
+ scratch1,
+ scratch2);
}
@@ -1063,12 +1102,11 @@
TAG_OBJECT);
// Set the map, length and hash field.
- LoadRoot(scratch1, Heap::kAsciiStringMapRootIndex);
- mov(scratch1, Operand(Factory::ascii_string_map()));
- str(length, FieldMemOperand(result, String::kLengthOffset));
- str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset));
- mov(scratch2, Operand(String::kEmptyHashField));
- str(scratch2, FieldMemOperand(result, String::kHashFieldOffset));
+ InitializeNewString(result,
+ length,
+ Heap::kAsciiStringMapRootIndex,
+ scratch1,
+ scratch2);
}
@@ -1083,11 +1121,12 @@
scratch2,
gc_required,
TAG_OBJECT);
- LoadRoot(scratch1, Heap::kConsStringMapRootIndex);
- mov(scratch2, Operand(String::kEmptyHashField));
- str(length, FieldMemOperand(result, String::kLengthOffset));
- str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset));
- str(scratch2, FieldMemOperand(result, String::kHashFieldOffset));
+
+ InitializeNewString(result,
+ length,
+ Heap::kConsStringMapRootIndex,
+ scratch1,
+ scratch2);
}
@@ -1102,11 +1141,12 @@
scratch2,
gc_required,
TAG_OBJECT);
- LoadRoot(scratch1, Heap::kConsAsciiStringMapRootIndex);
- mov(scratch2, Operand(String::kEmptyHashField));
- str(length, FieldMemOperand(result, String::kLengthOffset));
- str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset));
- str(scratch2, FieldMemOperand(result, String::kHashFieldOffset));
+
+ InitializeNewString(result,
+ length,
+ Heap::kConsAsciiStringMapRootIndex,
+ scratch1,
+ scratch2);
}