Commit 07b50849 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: Fix object initialization when slack tracking for it's map is still enabled.

Port 2fc2cb99

Original commit message:
    The old code was not ready for properly initialize objects with non
    standard headers and non zero in-object properties number.

    MacroAssembler::Allocate() implementations now return both start and
    end addresses of the new object (done by parameter renaming).

R=ishell@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1472473003

Cr-Commit-Position: refs/heads/master@{#32182}
parent bc5e7fc3
...@@ -438,33 +438,28 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, ...@@ -438,33 +438,28 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
Label rt_call_reload_new_target; Label rt_call_reload_new_target;
__ lbz(r6, FieldMemOperand(r5, Map::kInstanceSizeOffset)); __ lbz(r6, FieldMemOperand(r5, Map::kInstanceSizeOffset));
__ Allocate(r6, r7, r8, r9, &rt_call_reload_new_target, SIZE_IN_WORDS); __ Allocate(r6, r7, r6, r9, &rt_call_reload_new_target, SIZE_IN_WORDS);
// Allocated the JSObject, now initialize the fields. Map is set to // Allocated the JSObject, now initialize the fields. Map is set to
// initial map and properties and elements are set to empty fixed array. // initial map and properties and elements are set to empty fixed array.
// r4: constructor function // r4: constructor function
// r5: initial map // r5: initial map
// r6: object size // r6: start of next object
// r7: JSObject (not tagged) // r7: JSObject (not tagged)
__ LoadRoot(r9, Heap::kEmptyFixedArrayRootIndex); __ LoadRoot(r9, Heap::kEmptyFixedArrayRootIndex);
__ mr(r8, r7); __ StoreP(r5, MemOperand(r7, JSObject::kMapOffset));
__ StoreP(r5, MemOperand(r8, JSObject::kMapOffset)); __ StoreP(r9, MemOperand(r7, JSObject::kPropertiesOffset));
__ StoreP(r9, MemOperand(r8, JSObject::kPropertiesOffset)); __ StoreP(r9, MemOperand(r7, JSObject::kElementsOffset));
__ StoreP(r9, MemOperand(r8, JSObject::kElementsOffset)); __ addi(r8, r7, Operand(JSObject::kElementsOffset + kPointerSize));
__ addi(r8, r8, Operand(JSObject::kElementsOffset + kPointerSize));
__ ShiftLeftImm(r9, r6, Operand(kPointerSizeLog2));
__ add(r9, r7, r9); // End of object.
// Fill all the in-object properties with the appropriate filler. // Fill all the in-object properties with the appropriate filler.
// r4: constructor function // r4: constructor function
// r5: initial map // r5: initial map
// r6: object size // r6: start of next object
// r7: JSObject (not tagged) // r7: JSObject (not tagged)
// r8: First in-object property of JSObject (not tagged) // r8: First in-object property of JSObject (not tagged)
// r9: End of object
DCHECK_EQ(3 * kPointerSize, JSObject::kHeaderSize); DCHECK_EQ(3 * kPointerSize, JSObject::kHeaderSize);
__ LoadRoot(r10, Heap::kUndefinedValueRootIndex); __ LoadRoot(r9, Heap::kUndefinedValueRootIndex);
if (!is_api_function) { if (!is_api_function) {
Label no_inobject_slack_tracking; Label no_inobject_slack_tracking;
...@@ -474,34 +469,23 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, ...@@ -474,34 +469,23 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
__ blt(&no_inobject_slack_tracking); __ blt(&no_inobject_slack_tracking);
// Allocate object with a slack. // Allocate object with a slack.
__ lbz(r3, __ lbz(r3, FieldMemOperand(r5, Map::kUnusedPropertyFieldsOffset));
FieldMemOperand( __ ShiftLeftImm(r3, r3, Operand(kPointerSizeLog2));
r5, __ sub(r3, r6, r3);
Map::kInObjectPropertiesOrConstructorFunctionIndexOffset)); // r3: offset of first field after pre-allocated fields
__ lbz(r5, FieldMemOperand(r5, Map::kUnusedPropertyFieldsOffset));
__ sub(r3, r3, r5);
if (FLAG_debug_code) { if (FLAG_debug_code) {
__ ShiftLeftImm(r0, r3, Operand(kPointerSizeLog2)); __ cmp(r8, r3);
__ add(r0, r8, r0);
// r0: offset of first field after pre-allocated fields
__ cmp(r0, r9);
__ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields);
} }
{ __ InitializeFieldsWithFiller(r8, r3, r9);
Label done;
__ cmpi(r3, Operand::Zero());
__ beq(&done);
__ InitializeNFieldsWithFiller(r8, r3, r10);
__ bind(&done);
}
// To allow for truncation. // To allow for truncation.
__ LoadRoot(r10, Heap::kOnePointerFillerMapRootIndex); __ LoadRoot(r9, Heap::kOnePointerFillerMapRootIndex);
// Fill the remaining fields with one pointer filler map. // Fill the remaining fields with one pointer filler map.
__ bind(&no_inobject_slack_tracking); __ bind(&no_inobject_slack_tracking);
} }
__ InitializeFieldsWithFiller(r8, r9, r10); __ InitializeFieldsWithFiller(r8, r6, r9);
// Add the object tag to make the JSObject real, so that we can continue // Add the object tag to make the JSObject real, so that we can continue
// and jump into the continuation code at any time from now on. // and jump into the continuation code at any time from now on.
......
...@@ -1526,14 +1526,14 @@ void MacroAssembler::Allocate(int object_size, Register result, ...@@ -1526,14 +1526,14 @@ void MacroAssembler::Allocate(int object_size, Register result,
void MacroAssembler::Allocate(Register object_size, Register result, void MacroAssembler::Allocate(Register object_size, Register result,
Register scratch1, Register scratch2, Register result_end, Register scratch,
Label* gc_required, AllocationFlags flags) { Label* gc_required, AllocationFlags flags) {
if (!FLAG_inline_new) { if (!FLAG_inline_new) {
if (emit_debug_code()) { if (emit_debug_code()) {
// Trash the registers to simulate an allocation failure. // Trash the registers to simulate an allocation failure.
li(result, Operand(0x7091)); li(result, Operand(0x7091));
li(scratch1, Operand(0x7191)); li(scratch, Operand(0x7191));
li(scratch2, Operand(0x7291)); li(result_end, Operand(0x7291));
} }
b(gc_required); b(gc_required);
return; return;
...@@ -1541,13 +1541,13 @@ void MacroAssembler::Allocate(Register object_size, Register result, ...@@ -1541,13 +1541,13 @@ void MacroAssembler::Allocate(Register object_size, Register result,
// Assert that the register arguments are different and that none of // Assert that the register arguments are different and that none of
// them are ip. ip is used explicitly in the code generated below. // them are ip. ip is used explicitly in the code generated below.
DCHECK(!result.is(scratch1)); DCHECK(!result.is(scratch));
DCHECK(!result.is(scratch2)); DCHECK(!result.is(result_end));
DCHECK(!scratch1.is(scratch2)); DCHECK(!scratch.is(result_end));
DCHECK(!object_size.is(ip)); DCHECK(!object_size.is(ip));
DCHECK(!result.is(ip)); DCHECK(!result.is(ip));
DCHECK(!scratch1.is(ip)); DCHECK(!scratch.is(ip));
DCHECK(!scratch2.is(ip)); DCHECK(!result_end.is(ip));
// Check relative positions of allocation top and limit addresses. // Check relative positions of allocation top and limit addresses.
ExternalReference allocation_top = ExternalReference allocation_top =
...@@ -1559,7 +1559,7 @@ void MacroAssembler::Allocate(Register object_size, Register result, ...@@ -1559,7 +1559,7 @@ void MacroAssembler::Allocate(Register object_size, Register result,
DCHECK((limit - top) == kPointerSize); DCHECK((limit - top) == kPointerSize);
// Set up allocation top address. // Set up allocation top address.
Register topaddr = scratch1; Register topaddr = scratch;
mov(topaddr, Operand(allocation_top)); mov(topaddr, Operand(allocation_top));
// This code stores a temporary value in ip. This is OK, as the code below // This code stores a temporary value in ip. This is OK, as the code below
...@@ -1588,15 +1588,15 @@ void MacroAssembler::Allocate(Register object_size, Register result, ...@@ -1588,15 +1588,15 @@ void MacroAssembler::Allocate(Register object_size, Register result,
STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
#else #else
STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment); STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
andi(scratch2, result, Operand(kDoubleAlignmentMask)); andi(result_end, result, Operand(kDoubleAlignmentMask));
Label aligned; Label aligned;
beq(&aligned, cr0); beq(&aligned, cr0);
if ((flags & PRETENURE) != 0) { if ((flags & PRETENURE) != 0) {
cmpl(result, ip); cmpl(result, ip);
bge(gc_required); bge(gc_required);
} }
mov(scratch2, Operand(isolate()->factory()->one_pointer_filler_map())); mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
stw(scratch2, MemOperand(result)); stw(result_end, MemOperand(result));
addi(result, result, Operand(kDoubleSize / 2)); addi(result, result, Operand(kDoubleSize / 2));
bind(&aligned); bind(&aligned);
#endif #endif
...@@ -1607,22 +1607,22 @@ void MacroAssembler::Allocate(Register object_size, Register result, ...@@ -1607,22 +1607,22 @@ void MacroAssembler::Allocate(Register object_size, Register result,
// required to get the number of bytes. // required to get the number of bytes.
sub(r0, ip, result); sub(r0, ip, result);
if ((flags & SIZE_IN_WORDS) != 0) { if ((flags & SIZE_IN_WORDS) != 0) {
ShiftLeftImm(scratch2, object_size, Operand(kPointerSizeLog2)); ShiftLeftImm(result_end, object_size, Operand(kPointerSizeLog2));
cmp(r0, scratch2); cmp(r0, result_end);
blt(gc_required); blt(gc_required);
add(scratch2, result, scratch2); add(result_end, result, result_end);
} else { } else {
cmp(r0, object_size); cmp(r0, object_size);
blt(gc_required); blt(gc_required);
add(scratch2, result, object_size); add(result_end, result, object_size);
} }
// Update allocation top. result temporarily holds the new top. // Update allocation top. result temporarily holds the new top.
if (emit_debug_code()) { if (emit_debug_code()) {
andi(r0, scratch2, Operand(kObjectAlignmentMask)); andi(r0, result_end, Operand(kObjectAlignmentMask));
Check(eq, kUnalignedAllocationInNewSpace, cr0); Check(eq, kUnalignedAllocationInNewSpace, cr0);
} }
StoreP(scratch2, MemOperand(topaddr)); StoreP(result_end, MemOperand(topaddr));
// Tag object if requested. // Tag object if requested.
if ((flags & TAG_OBJECT) != 0) { if ((flags & TAG_OBJECT) != 0) {
...@@ -2887,25 +2887,25 @@ void MacroAssembler::CopyBytes(Register src, Register dst, Register length, ...@@ -2887,25 +2887,25 @@ void MacroAssembler::CopyBytes(Register src, Register dst, Register length,
} }
void MacroAssembler::InitializeNFieldsWithFiller(Register start_offset, void MacroAssembler::InitializeNFieldsWithFiller(Register current_address,
Register count, Register count,
Register filler) { Register filler) {
Label loop; Label loop;
mtctr(count); mtctr(count);
bind(&loop); bind(&loop);
StoreP(filler, MemOperand(start_offset)); StoreP(filler, MemOperand(current_address));
addi(start_offset, start_offset, Operand(kPointerSize)); addi(current_address, current_address, Operand(kPointerSize));
bdnz(&loop); bdnz(&loop);
} }
void MacroAssembler::InitializeFieldsWithFiller(Register start_offset, void MacroAssembler::InitializeFieldsWithFiller(Register current_address,
Register end_offset, Register end_address,
Register filler) { Register filler) {
Label done; Label done;
sub(r0, end_offset, start_offset, LeaveOE, SetRC); sub(r0, end_address, current_address, LeaveOE, SetRC);
beq(&done, cr0); beq(&done, cr0);
ShiftRightImm(r0, r0, Operand(kPointerSizeLog2)); ShiftRightImm(r0, r0, Operand(kPointerSizeLog2));
InitializeNFieldsWithFiller(start_offset, r0, filler); InitializeNFieldsWithFiller(current_address, r0, filler);
bind(&done); bind(&done);
} }
......
...@@ -653,8 +653,8 @@ class MacroAssembler : public Assembler { ...@@ -653,8 +653,8 @@ class MacroAssembler : public Assembler {
void Allocate(int object_size, Register result, Register scratch1, void Allocate(int object_size, Register result, Register scratch1,
Register scratch2, Label* gc_required, AllocationFlags flags); Register scratch2, Label* gc_required, AllocationFlags flags);
void Allocate(Register object_size, Register result, Register scratch1, void Allocate(Register object_size, Register result, Register result_end,
Register scratch2, Label* gc_required, AllocationFlags flags); Register scratch, Label* gc_required, AllocationFlags flags);
void AllocateTwoByteString(Register result, Register length, void AllocateTwoByteString(Register result, Register length,
Register scratch1, Register scratch2, Register scratch1, Register scratch2,
...@@ -696,17 +696,17 @@ class MacroAssembler : public Assembler { ...@@ -696,17 +696,17 @@ class MacroAssembler : public Assembler {
void CopyBytes(Register src, Register dst, Register length, Register scratch); void CopyBytes(Register src, Register dst, Register length, Register scratch);
// Initialize fields with filler values. |count| fields starting at // Initialize fields with filler values. |count| fields starting at
// |start_offset| are overwritten with the value in |filler|. At the end the // |current_address| are overwritten with the value in |filler|. At the end
// loop, |start_offset| points at the next uninitialized field. |count| is // the loop, |current_address| points at the next uninitialized field.
// assumed to be non-zero. // |count| is assumed to be non-zero.
void InitializeNFieldsWithFiller(Register start_offset, Register count, void InitializeNFieldsWithFiller(Register current_address, Register count,
Register filler); Register filler);
// Initialize fields with filler values. Fields starting at |start_offset| // Initialize fields with filler values. Fields starting at |current_address|
// not including end_offset are overwritten with the value in |filler|. At // not including |end_address| are overwritten with the value in |filler|. At
// the end the loop, |start_offset| takes the value of |end_offset|. // the end the loop, |current_address| takes the value of |end_address|.
void InitializeFieldsWithFiller(Register start_offset, Register end_offset, void InitializeFieldsWithFiller(Register current_address,
Register filler); Register end_address, Register filler);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Support functions. // Support functions.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment