| Index: src/arm/codegen-arm.cc
|
| diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
|
| index 6deb31fbc26380cd68e83c3061ab4551313dec2f..5f2c34ab7cc68b2d9a094128f2e0c9e24071c798 100644
|
| --- a/src/arm/codegen-arm.cc
|
| +++ b/src/arm/codegen-arm.cc
|
| @@ -3397,12 +3397,17 @@ void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
|
| frame_->EmitPush(Operand(Smi::FromInt(node->literal_index())));
|
| frame_->EmitPush(Operand(node->constant_elements()));
|
| int length = node->values()->length();
|
| - if (node->depth() > 1) {
|
| + if (node->constant_elements()->map() == Heap::fixed_cow_array_map()) {
|
| + FastCloneShallowArrayStub stub(
|
| + FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
|
| + frame_->CallStub(&stub, 3);
|
| + } else if (node->depth() > 1) {
|
| frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
|
| - } else if (length > FastCloneShallowArrayStub::kMaximumLength) {
|
| + } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
|
| frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
|
| } else {
|
| - FastCloneShallowArrayStub stub(length);
|
| + FastCloneShallowArrayStub stub(
|
| + FastCloneShallowArrayStub::CLONE_ELEMENTS, length);
|
| frame_->CallStub(&stub, 3);
|
| }
|
| frame_->EmitPush(r0); // save the result
|
| @@ -5361,7 +5366,7 @@ void CodeGenerator::GenerateSwapElements(ZoneList<Expression*>* args) {
|
| __ tst(tmp2, Operand(KeyedLoadIC::kSlowCaseBitFieldMask));
|
| deferred->Branch(nz);
|
|
|
| - // Check the object's elements are in fast case.
|
| + // Check the object's elements are in fast case and writable.
|
| __ ldr(tmp1, FieldMemOperand(object, JSObject::kElementsOffset));
|
| __ ldr(tmp2, FieldMemOperand(tmp1, HeapObject::kMapOffset));
|
| __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
|
| @@ -6653,15 +6658,9 @@ void CodeGenerator::EmitKeyedLoad() {
|
| __ cmp(scratch1, scratch2);
|
| deferred->Branch(ne);
|
|
|
| - // Get the elements array from the receiver and check that it
|
| - // is not a dictionary.
|
| + // Get the elements array from the receiver.
|
| __ ldr(scratch1, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
| - if (FLAG_debug_code) {
|
| - __ ldr(scratch2, FieldMemOperand(scratch1, JSObject::kMapOffset));
|
| - __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
|
| - __ cmp(scratch2, ip);
|
| - __ Assert(eq, "JSObject with fast elements map has slow elements");
|
| - }
|
| + __ AssertFastElements(scratch1);
|
|
|
| // Check that key is within bounds. Use unsigned comparison to handle
|
| // negative keys.
|
| @@ -7071,6 +7070,26 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
|
| __ cmp(r3, ip);
|
| __ b(eq, &slow_case);
|
|
|
| + if (FLAG_debug_code) {
|
| + const char* message;
|
| + Heap::RootListIndex expected_map_index;
|
| + if (mode_ == CLONE_ELEMENTS) {
|
| + message = "Expected (writable) fixed array";
|
| + expected_map_index = Heap::kFixedArrayMapRootIndex;
|
| + } else {
|
| + ASSERT(mode_ == COPY_ON_WRITE_ELEMENTS);
|
| + message = "Expected copy-on-write fixed array";
|
| + expected_map_index = Heap::kFixedCOWArrayMapRootIndex;
|
| + }
|
| + __ push(r3);
|
| + __ ldr(r3, FieldMemOperand(r3, JSArray::kElementsOffset));
|
| + __ ldr(r3, FieldMemOperand(r3, HeapObject::kMapOffset));
|
| + __ LoadRoot(ip, expected_map_index);
|
| + __ cmp(r3, ip);
|
| + __ Assert(eq, message);
|
| + __ pop(r3);
|
| + }
|
| +
|
| // Allocate both the JS array and the elements array in one big
|
| // allocation. This avoids multiple limit checks.
|
| __ AllocateInNewSpace(size,
|
| @@ -7099,6 +7118,10 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
|
| __ CopyFields(r2, r3, r1.bit(), elements_size / kPointerSize);
|
| }
|
|
|
| + if (mode_ == COPY_ON_WRITE_ELEMENTS) {
|
| + __ IncrementCounter(&Counters::cow_arrays_created_stub, 1, r2, r3);
|
| + }
|
| +
|
| // Return and remove the on-stack parameters.
|
| __ add(sp, sp, Operand(3 * kPointerSize));
|
| __ Ret();
|
|
|