MIPS: Port array literal changes on ARM.
Port r10085 (1ef7d5eb2). This patch also contains a fix for StoreArrayLiteralElementStub::Generate which is only used from this code. Original commit message: Includes general array boilerplate copier and re-introduction FAST_ELEMENT optimizations in full-codegen. BUG= TEST= Review URL: http://codereview.chromium.org/8743010 Patch from Daniel Kalmard <kalmard@homejinni.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10129 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
830f763b07
commit
540ac179dc
@ -255,21 +255,61 @@ void FastNewBlockContextStub::Generate(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
|
||||
void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
|
||||
// Stack layout on entry:
|
||||
// [sp]: constant elements.
|
||||
// [sp + kPointerSize]: literal index.
|
||||
// [sp + (2 * kPointerSize)]: literals array.
|
||||
static void GenerateFastCloneShallowArrayCommon(
|
||||
MacroAssembler* masm,
|
||||
int length,
|
||||
FastCloneShallowArrayStub::Mode mode,
|
||||
Label* fail) {
|
||||
// Registers on entry:
|
||||
// a3: boilerplate literal array.
|
||||
ASSERT(mode != FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS);
|
||||
|
||||
// All sizes here are multiples of kPointerSize.
|
||||
int elements_size = 0;
|
||||
if (length_ > 0) {
|
||||
elements_size = mode_ == CLONE_DOUBLE_ELEMENTS
|
||||
? FixedDoubleArray::SizeFor(length_)
|
||||
: FixedArray::SizeFor(length_);
|
||||
if (length > 0) {
|
||||
elements_size = mode == FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
|
||||
? FixedDoubleArray::SizeFor(length)
|
||||
: FixedArray::SizeFor(length);
|
||||
}
|
||||
int size = JSArray::kSize + elements_size;
|
||||
|
||||
// Allocate both the JS array and the elements array in one big
|
||||
// allocation. This avoids multiple limit checks.
|
||||
__ AllocateInNewSpace(size,
|
||||
v0,
|
||||
a1,
|
||||
a2,
|
||||
fail,
|
||||
TAG_OBJECT);
|
||||
|
||||
// Copy the JS array part.
|
||||
for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
|
||||
if ((i != JSArray::kElementsOffset) || (length == 0)) {
|
||||
__ lw(a1, FieldMemOperand(a3, i));
|
||||
__ sw(a1, FieldMemOperand(v0, i));
|
||||
}
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
// Get hold of the elements array of the boilerplate and setup the
|
||||
// elements pointer in the resulting object.
|
||||
__ lw(a3, FieldMemOperand(a3, JSArray::kElementsOffset));
|
||||
__ Addu(a2, v0, Operand(JSArray::kSize));
|
||||
__ sw(a2, FieldMemOperand(v0, JSArray::kElementsOffset));
|
||||
|
||||
// Copy the elements array.
|
||||
ASSERT((elements_size % kPointerSize) == 0);
|
||||
__ CopyFields(a2, a3, a1.bit(), elements_size / kPointerSize);
|
||||
}
|
||||
}
|
||||
|
||||
void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
|
||||
// Stack layout on entry:
|
||||
//
|
||||
// [sp]: constant elements.
|
||||
// [sp + kPointerSize]: literal index.
|
||||
// [sp + (2 * kPointerSize)]: literals array.
|
||||
|
||||
// Load boilerplate object into r3 and check if we need to create a
|
||||
// boilerplate.
|
||||
Label slow_case;
|
||||
@ -282,17 +322,42 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
|
||||
__ LoadRoot(t1, Heap::kUndefinedValueRootIndex);
|
||||
__ Branch(&slow_case, eq, a3, Operand(t1));
|
||||
|
||||
FastCloneShallowArrayStub::Mode mode = mode_;
|
||||
if (mode == CLONE_ANY_ELEMENTS) {
|
||||
Label double_elements, check_fast_elements;
|
||||
__ lw(v0, FieldMemOperand(a3, JSArray::kElementsOffset));
|
||||
__ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset));
|
||||
__ LoadRoot(t1, Heap::kFixedCOWArrayMapRootIndex);
|
||||
__ Branch(&check_fast_elements, ne, v0, Operand(t1));
|
||||
GenerateFastCloneShallowArrayCommon(masm, 0,
|
||||
COPY_ON_WRITE_ELEMENTS, &slow_case);
|
||||
// Return and remove the on-stack parameters.
|
||||
__ DropAndRet(3);
|
||||
|
||||
__ bind(&check_fast_elements);
|
||||
__ LoadRoot(t1, Heap::kFixedArrayMapRootIndex);
|
||||
__ Branch(&double_elements, ne, v0, Operand(t1));
|
||||
GenerateFastCloneShallowArrayCommon(masm, length_,
|
||||
CLONE_ELEMENTS, &slow_case);
|
||||
// Return and remove the on-stack parameters.
|
||||
__ DropAndRet(3);
|
||||
|
||||
__ bind(&double_elements);
|
||||
mode = CLONE_DOUBLE_ELEMENTS;
|
||||
// Fall through to generate the code to handle double elements.
|
||||
}
|
||||
|
||||
if (FLAG_debug_code) {
|
||||
const char* message;
|
||||
Heap::RootListIndex expected_map_index;
|
||||
if (mode_ == CLONE_ELEMENTS) {
|
||||
if (mode == CLONE_ELEMENTS) {
|
||||
message = "Expected (writable) fixed array";
|
||||
expected_map_index = Heap::kFixedArrayMapRootIndex;
|
||||
} else if (mode_ == CLONE_DOUBLE_ELEMENTS) {
|
||||
} else if (mode == CLONE_DOUBLE_ELEMENTS) {
|
||||
message = "Expected (writable) fixed double array";
|
||||
expected_map_index = Heap::kFixedDoubleArrayMapRootIndex;
|
||||
} else {
|
||||
ASSERT(mode_ == COPY_ON_WRITE_ELEMENTS);
|
||||
ASSERT(mode == COPY_ON_WRITE_ELEMENTS);
|
||||
message = "Expected copy-on-write fixed array";
|
||||
expected_map_index = Heap::kFixedCOWArrayMapRootIndex;
|
||||
}
|
||||
@ -304,35 +369,7 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
|
||||
__ pop(a3);
|
||||
}
|
||||
|
||||
// Allocate both the JS array and the elements array in one big
|
||||
// allocation. This avoids multiple limit checks.
|
||||
// Return new object in v0.
|
||||
__ AllocateInNewSpace(size,
|
||||
v0,
|
||||
a1,
|
||||
a2,
|
||||
&slow_case,
|
||||
TAG_OBJECT);
|
||||
|
||||
// Copy the JS array part.
|
||||
for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
|
||||
if ((i != JSArray::kElementsOffset) || (length_ == 0)) {
|
||||
__ lw(a1, FieldMemOperand(a3, i));
|
||||
__ sw(a1, FieldMemOperand(v0, i));
|
||||
}
|
||||
}
|
||||
|
||||
if (length_ > 0) {
|
||||
// Get hold of the elements array of the boilerplate and setup the
|
||||
// elements pointer in the resulting object.
|
||||
__ lw(a3, FieldMemOperand(a3, JSArray::kElementsOffset));
|
||||
__ Addu(a2, v0, Operand(JSArray::kSize));
|
||||
__ sw(a2, FieldMemOperand(v0, JSArray::kElementsOffset));
|
||||
|
||||
// Copy the elements array.
|
||||
ASSERT((elements_size % kPointerSize) == 0);
|
||||
__ CopyFields(a2, a3, a1.bit(), elements_size / kPointerSize);
|
||||
}
|
||||
GenerateFastCloneShallowArrayCommon(masm, length_, mode, &slow_case);
|
||||
|
||||
// Return and remove the on-stack parameters.
|
||||
__ Addu(sp, sp, Operand(3 * kPointerSize));
|
||||
@ -7474,7 +7511,8 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
|
||||
// Update the write barrier for the array store.
|
||||
__ RecordWrite(t1, t2, a0, kRAHasNotBeenSaved, kDontSaveFPRegs,
|
||||
EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
|
||||
__ Ret();
|
||||
__ Ret(USE_DELAY_SLOT);
|
||||
__ mov(v0, a0);
|
||||
|
||||
// Array literal has ElementsKind of FAST_SMI_ONLY_ELEMENTS or
|
||||
// FAST_ELEMENTS, and value is Smi.
|
||||
@ -7483,14 +7521,16 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
|
||||
__ sll(t2, a3, kPointerSizeLog2 - kSmiTagSize);
|
||||
__ Addu(t2, t1, t2);
|
||||
__ sw(a0, FieldMemOperand(t2, FixedArray::kHeaderSize));
|
||||
__ Ret();
|
||||
__ Ret(USE_DELAY_SLOT);
|
||||
__ mov(v0, a0);
|
||||
|
||||
// Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS.
|
||||
__ bind(&double_elements);
|
||||
__ lw(t1, FieldMemOperand(a1, JSObject::kElementsOffset));
|
||||
__ StoreNumberToDoubleElements(a0, a3, a1, t1, t2, t3, t5, t6,
|
||||
&slow_elements);
|
||||
__ Ret();
|
||||
__ Ret(USE_DELAY_SLOT);
|
||||
__ mov(v0, a0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1546,6 +1546,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
ASSERT_EQ(2, constant_elements->length());
|
||||
ElementsKind constant_elements_kind =
|
||||
static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value());
|
||||
bool has_fast_elements = constant_elements_kind == FAST_ELEMENTS;
|
||||
Handle<FixedArrayBase> constant_elements_values(
|
||||
FixedArrayBase::cast(constant_elements->get(1)));
|
||||
|
||||
@ -1555,7 +1556,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
__ li(a2, Operand(Smi::FromInt(expr->literal_index())));
|
||||
__ li(a1, Operand(constant_elements));
|
||||
__ Push(a3, a2, a1);
|
||||
if (constant_elements_values->map() ==
|
||||
if (has_fast_elements && constant_elements_values->map() ==
|
||||
isolate()->heap()->fixed_cow_array_map()) {
|
||||
FastCloneShallowArrayStub stub(
|
||||
FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
|
||||
@ -1570,10 +1571,9 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
ASSERT(constant_elements_kind == FAST_ELEMENTS ||
|
||||
constant_elements_kind == FAST_SMI_ONLY_ELEMENTS ||
|
||||
FLAG_smi_only_arrays);
|
||||
FastCloneShallowArrayStub::Mode mode =
|
||||
constant_elements_kind == FAST_DOUBLE_ELEMENTS
|
||||
? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
|
||||
: FastCloneShallowArrayStub::CLONE_ELEMENTS;
|
||||
FastCloneShallowArrayStub::Mode mode = has_fast_elements
|
||||
? FastCloneShallowArrayStub::CLONE_ELEMENTS
|
||||
: FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS;
|
||||
FastCloneShallowArrayStub stub(mode, length);
|
||||
__ CallStub(&stub);
|
||||
}
|
||||
@ -1595,65 +1595,30 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
__ push(v0);
|
||||
result_saved = true;
|
||||
}
|
||||
|
||||
VisitForAccumulatorValue(subexpr);
|
||||
|
||||
__ lw(t6, MemOperand(sp)); // Copy of array literal.
|
||||
__ lw(a1, FieldMemOperand(t6, JSObject::kElementsOffset));
|
||||
__ lw(a2, FieldMemOperand(t6, JSObject::kMapOffset));
|
||||
int offset = FixedArray::kHeaderSize + (i * kPointerSize);
|
||||
|
||||
Label element_done;
|
||||
Label double_elements;
|
||||
Label smi_element;
|
||||
Label slow_elements;
|
||||
Label fast_elements;
|
||||
__ CheckFastElements(a2, a3, &double_elements);
|
||||
|
||||
// FAST_SMI_ONLY_ELEMENTS or FAST_ELEMENTS
|
||||
__ JumpIfSmi(result_register(), &smi_element);
|
||||
__ CheckFastSmiOnlyElements(a2, a3, &fast_elements);
|
||||
|
||||
// Store into the array literal requires a elements transition. Call into
|
||||
// the runtime.
|
||||
__ bind(&slow_elements);
|
||||
__ push(t6); // Copy of array literal.
|
||||
__ li(a1, Operand(Smi::FromInt(i)));
|
||||
__ li(a2, Operand(Smi::FromInt(NONE))); // PropertyAttributes
|
||||
StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE)
|
||||
? kNonStrictMode : kStrictMode;
|
||||
__ li(a3, Operand(Smi::FromInt(strict_mode_flag))); // Strict mode.
|
||||
__ Push(a1, result_register(), a2, a3);
|
||||
__ CallRuntime(Runtime::kSetProperty, 5);
|
||||
__ Branch(&element_done);
|
||||
|
||||
// Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS.
|
||||
__ bind(&double_elements);
|
||||
__ li(a3, Operand(Smi::FromInt(i)));
|
||||
__ StoreNumberToDoubleElements(result_register(), a3, t6, a1, t0, t1, t5,
|
||||
t3, &slow_elements);
|
||||
__ Branch(&element_done);
|
||||
|
||||
// Array literal has ElementsKind of FAST_ELEMENTS and value is an object.
|
||||
__ bind(&fast_elements);
|
||||
__ sw(result_register(), FieldMemOperand(a1, offset));
|
||||
// Update the write barrier for the array store.
|
||||
|
||||
__ RecordWriteField(
|
||||
a1, offset, result_register(), a2, kRAHasBeenSaved, kDontSaveFPRegs,
|
||||
EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
|
||||
__ Branch(&element_done);
|
||||
|
||||
// Array literal has ElementsKind of FAST_SMI_ONLY_ELEMENTS or
|
||||
// FAST_ELEMENTS, and value is Smi.
|
||||
__ bind(&smi_element);
|
||||
__ sw(result_register(), FieldMemOperand(a1, offset));
|
||||
// Fall through
|
||||
|
||||
__ bind(&element_done);
|
||||
if (constant_elements_kind == FAST_ELEMENTS) {
|
||||
int offset = FixedArray::kHeaderSize + (i * kPointerSize);
|
||||
__ lw(t2, MemOperand(sp)); // Copy of array literal.
|
||||
__ lw(a1, FieldMemOperand(t2, JSObject::kElementsOffset));
|
||||
__ sw(result_register(), FieldMemOperand(a1, offset));
|
||||
// Update the write barrier for the array store.
|
||||
__ RecordWriteField(a1, offset, result_register(), a2,
|
||||
kRAHasBeenSaved, kDontSaveFPRegs,
|
||||
EMIT_REMEMBERED_SET, INLINE_SMI_CHECK);
|
||||
} else {
|
||||
__ lw(a1, MemOperand(sp)); // Copy of array literal.
|
||||
__ lw(a2, FieldMemOperand(a1, JSObject::kMapOffset));
|
||||
__ li(a3, Operand(Smi::FromInt(i)));
|
||||
__ li(t0, Operand(Smi::FromInt(expr->literal_index())));
|
||||
__ mov(a0, result_register());
|
||||
StoreArrayLiteralElementStub stub;
|
||||
__ CallStub(&stub);
|
||||
}
|
||||
|
||||
PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
|
||||
}
|
||||
|
||||
if (result_saved) {
|
||||
context()->PlugTOS();
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user