Revision: 19895
Author: [email protected]
Date: Thu Mar 13 13:18:48 2014 UTC
Log: A64: Implement and use FillFields
BUG=
[email protected]
Review URL: https://codereview.chromium.org/190763012
http://code.google.com/p/v8/source/detail?r=19895
Modified:
/branches/bleeding_edge/src/a64/builtins-a64.cc
/branches/bleeding_edge/src/a64/lithium-a64.cc
/branches/bleeding_edge/src/a64/lithium-a64.h
/branches/bleeding_edge/src/a64/lithium-codegen-a64.cc
/branches/bleeding_edge/src/a64/macro-assembler-a64.cc
/branches/bleeding_edge/src/a64/macro-assembler-a64.h
=======================================
--- /branches/bleeding_edge/src/a64/builtins-a64.cc Wed Mar 12 15:18:40
2014 UTC
+++ /branches/bleeding_edge/src/a64/builtins-a64.cc Thu Mar 13 13:18:48
2014 UTC
@@ -415,15 +415,14 @@
Register empty = x5;
__ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex);
__ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset));
- __ Str(empty, MemOperand(new_obj, JSObject::kPropertiesOffset));
- __ Str(empty, MemOperand(new_obj, JSObject::kElementsOffset));
+ STATIC_ASSERT(JSObject::kElementsOffset ==
+ (JSObject::kPropertiesOffset + kPointerSize));
+ __ Stp(empty, empty, MemOperand(new_obj,
JSObject::kPropertiesOffset));
Register first_prop = x5;
__ Add(first_prop, new_obj, JSObject::kHeaderSize);
// Fill all of the in-object properties with the appropriate filler.
- Register obj_end = x6;
- __ Add(obj_end, new_obj, Operand(obj_size, LSL, kPointerSizeLog2));
Register undef = x7;
__ LoadRoot(undef, Heap::kUndefinedValueRootIndex);
@@ -439,23 +438,42 @@
__ Ubfx(inobject_props, inst_sizes,
Map::kInObjectPropertiesByte * kBitsPerByte, kBitsPerByte);
+ // Calculate number of property fields in the object.
+ Register prop_fields = x6;
+ __ Sub(prop_fields, obj_size, JSObject::kHeaderSize / kPointerSize);
+
if (count_constructions) {
+ // Fill the pre-allocated fields with undef.
+ __ FillFields(first_prop, prealloc_fields, undef);
+
// Register first_non_prealloc is the offset of the first field
after
// pre-allocated fields.
Register first_non_prealloc = x12;
__ Add(first_non_prealloc, first_prop,
Operand(prealloc_fields, LSL, kPointerSizeLog2));
+ first_prop = NoReg;
+
if (FLAG_debug_code) {
+ Register obj_end = x5;
+ __ Add(obj_end, new_obj, Operand(obj_size, LSL,
kPointerSizeLog2));
__ Cmp(first_non_prealloc, obj_end);
__ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields);
}
- __ InitializeFieldsWithFiller(first_prop, first_non_prealloc,
undef);
- // To allow for truncation.
- __ LoadRoot(x12, Heap::kOnePointerFillerMapRootIndex);
- __ InitializeFieldsWithFiller(first_prop, obj_end, x12);
+
+ // Fill the remaining fields with one pointer filler map.
+ Register one_pointer_filler = x5;
+ Register non_prealloc_fields = x6;
+ __ LoadRoot(one_pointer_filler,
Heap::kOnePointerFillerMapRootIndex);
+ __ Sub(non_prealloc_fields, prop_fields, prealloc_fields);
+ __ FillFields(first_non_prealloc, non_prealloc_fields,
+ one_pointer_filler);
+ prop_fields = NoReg;
} else {
- __ InitializeFieldsWithFiller(first_prop, obj_end, undef);
+ // Fill all of the property fields with undef.
+ __ FillFields(first_prop, prop_fields, undef);
+ first_prop = NoReg;
+ prop_fields = NoReg;
}
// Add the object tag to make the JSObject real, so that we can
continue
@@ -467,11 +485,12 @@
// Check if a non-empty properties array is needed. Continue with
// allocated object if not, or fall through to runtime call if it is.
Register element_count = x3;
- __ Ldrb(x3, FieldMemOperand(init_map,
Map::kUnusedPropertyFieldsOffset));
+ __ Ldrb(element_count,
+ FieldMemOperand(init_map, Map::kUnusedPropertyFieldsOffset));
// The field instance sizes contains both pre-allocated property
fields
// and in-object properties.
- __ Add(x3, x3, prealloc_fields);
- __ Subs(element_count, x3, inobject_props);
+ __ Add(element_count, element_count, prealloc_fields);
+ __ Subs(element_count, element_count, inobject_props);
// Done if no extra properties are to be allocated.
__ B(eq, &allocated);
@@ -494,11 +513,8 @@
// Initialize the fields to undefined.
Register elements = x10;
- Register elements_end = x11;
__ Add(elements, new_array, FixedArray::kHeaderSize);
- __ Add(elements_end, elements,
- Operand(element_count, LSL, kPointerSizeLog2));
- __ InitializeFieldsWithFiller(elements, elements_end, undef);
+ __ FillFields(elements, element_count, undef);
// Store the initialized FixedArray into the properties field of the
// JSObject.
=======================================
--- /branches/bleeding_edge/src/a64/lithium-a64.cc Thu Mar 13 07:58:58 2014
UTC
+++ /branches/bleeding_edge/src/a64/lithium-a64.cc Thu Mar 13 13:18:48 2014
UTC
@@ -878,7 +878,8 @@
LOperand* size = UseRegisterOrConstant(instr->size());
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
- LAllocate* result = new(zone()) LAllocate(context, size, temp1, temp2);
+ LOperand* temp3 = instr->MustPrefillWithFiller() ? TempRegister() : NULL;
+ LAllocate* result = new(zone()) LAllocate(context, size, temp1, temp2,
temp3);
return AssignPointerMap(DefineAsRegister(result));
}
=======================================
--- /branches/bleeding_edge/src/a64/lithium-a64.h Thu Mar 13 06:11:52 2014
UTC
+++ /branches/bleeding_edge/src/a64/lithium-a64.h Thu Mar 13 13:18:48 2014
UTC
@@ -612,22 +612,25 @@
};
-class LAllocate V8_FINAL : public LTemplateInstruction<1, 2, 2> {
+class LAllocate V8_FINAL : public LTemplateInstruction<1, 2, 3> {
public:
LAllocate(LOperand* context,
LOperand* size,
LOperand* temp1,
- LOperand* temp2) {
+ LOperand* temp2,
+ LOperand* temp3) {
inputs_[0] = context;
inputs_[1] = size;
temps_[0] = temp1;
temps_[1] = temp2;
+ temps_[2] = temp3;
}
LOperand* context() { return inputs_[0]; }
LOperand* size() { return inputs_[1]; }
LOperand* temp1() { return temps_[0]; }
LOperand* temp2() { return temps_[1]; }
+ LOperand* temp3() { return temps_[2]; }
DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate")
DECLARE_HYDROGEN_ACCESSOR(Allocate)
=======================================
--- /branches/bleeding_edge/src/a64/lithium-codegen-a64.cc Thu Mar 13
08:17:44 2014 UTC
+++ /branches/bleeding_edge/src/a64/lithium-codegen-a64.cc Thu Mar 13
13:18:48 2014 UTC
@@ -1517,23 +1517,22 @@
__ Bind(deferred->exit());
if (instr->hydrogen()->MustPrefillWithFiller()) {
+ Register filler_count = temp1;
+ Register filler = temp2;
+ Register untagged_result = ToRegister(instr->temp3());
+
if (instr->size()->IsConstantOperand()) {
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
- __ Mov(temp1, size - kPointerSize);
+ __ Mov(filler_count, size / kPointerSize);
} else {
- __ Sub(temp1.W(), ToRegister32(instr->size()), kPointerSize);
+ __ Lsr(filler_count.W(), ToRegister32(instr->size()),
kPointerSizeLog2);
}
- __ Sub(result, result, kHeapObjectTag);
- // TODO(jbramley): Optimize this loop using stp.
- Label loop;
- __ Bind(&loop);
- __ Mov(temp2, Operand(isolate()->factory()->one_pointer_filler_map()));
- __ Str(temp2, MemOperand(result, temp1));
- __ Subs(temp1, temp1, kPointerSize);
- __ B(ge, &loop);
-
- __ Add(result, result, kHeapObjectTag);
+ __ Sub(untagged_result, result, kHeapObjectTag);
+ __ Mov(filler,
Operand(isolate()->factory()->one_pointer_filler_map()));
+ __ FillFields(untagged_result, filler_count, filler);
+ } else {
+ ASSERT(instr->temp3() == NULL);
}
}
=======================================
--- /branches/bleeding_edge/src/a64/macro-assembler-a64.cc Wed Mar 12
15:18:40 2014 UTC
+++ /branches/bleeding_edge/src/a64/macro-assembler-a64.cc Thu Mar 13
13:18:48 2014 UTC
@@ -2452,17 +2452,40 @@
}
-void MacroAssembler::InitializeFieldsWithFiller(Register start_offset,
- Register end_offset,
- Register filler) {
- Label loop, entry;
+void MacroAssembler::FillFields(Register dst,
+ Register field_count,
+ Register filler) {
+ ASSERT(!dst.Is(csp));
+ UseScratchRegisterScope temps(this);
+ Register field_ptr = temps.AcquireX();
+ Register counter = temps.AcquireX();
+ Label done;
+
+ // Decrement count. If the result < zero, count was zero, and there's
nothing
+ // to do. If count was one, flags are set to fail the gt condition at
the end
+ // of the pairs loop.
+ Subs(counter, field_count, 1);
+ B(lt, &done);
+
+ // There's at least one field to fill, so do this unconditionally.
+ Str(filler, MemOperand(dst, kPointerSize, PostIndex));
+
+ // If the bottom bit of counter is set, there are an even number of
fields to
+ // fill, so pull the start pointer back by one field, allowing the pairs
loop
+ // to overwrite the field that was stored above.
+ And(field_ptr, counter, 1);
+ Sub(field_ptr, dst, Operand(field_ptr, LSL, kPointerSizeLog2));
+
+ // Store filler to memory in pairs.
+ Label entry, loop;
B(&entry);
Bind(&loop);
- // TODO(all): consider using stp here.
- Str(filler, MemOperand(start_offset, kPointerSize, PostIndex));
+ Stp(filler, filler, MemOperand(field_ptr, 2 * kPointerSize, PostIndex));
+ Subs(counter, counter, 2);
Bind(&entry);
- Cmp(start_offset, end_offset);
- B(lt, &loop);
+ B(gt, &loop);
+
+ Bind(&done);
}
=======================================
--- /branches/bleeding_edge/src/a64/macro-assembler-a64.h Thu Mar 13
09:45:02 2014 UTC
+++ /branches/bleeding_edge/src/a64/macro-assembler-a64.h Thu Mar 13
13:18:48 2014 UTC
@@ -964,6 +964,12 @@
// MacroAssembler::TmpList().
void CopyFields(Register dst, Register src, CPURegList temps, unsigned
count);
+ // Starting at address in dst, initialize field_count 64-bit fields with
+ // 64-bit value in register filler. Register dst is corrupted.
+ void FillFields(Register dst,
+ Register field_count,
+ Register filler);
+
// Copies a number of bytes from src to dst. All passed registers are
// clobbered. On exit src and dst will point to the place just after
where the
// last byte was read or written and length will be zero. Hint may be
used to
@@ -974,13 +980,6 @@
Register scratch,
CopyHint hint = kCopyUnknown);
- // Initialize fields with filler values. Fields starting at start_offset
not
- // including end_offset are overwritten with the value in filler. At the
end
- // of the loop, start_offset takes the value of end_offset.
- void InitializeFieldsWithFiller(Register start_offset,
- Register end_offset,
- Register filler);
-
// ---- String Utilities ----
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.