Index: src/x64/codegen-x64.cc |
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc |
index e545ffa3dc1cc132b3f9de96cf94ce4ff499a6f4..2afd67b3f54a4c4791083e36c8678cd038f481a0 100644 |
--- a/src/x64/codegen-x64.cc |
+++ b/src/x64/codegen-x64.cc |
@@ -4989,12 +4989,17 @@ void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { |
frame_->Push(node->constant_elements()); |
int length = node->values()->length(); |
Result clone; |
- if (node->depth() > 1) { |
+ if (node->constant_elements()->map() == Heap::fixed_cow_array_map()) { |
+ FastCloneShallowArrayStub stub( |
+ FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length); |
+ clone = frame_->CallStub(&stub, 3); |
+ } else if (node->depth() > 1) { |
clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3); |
- } else if (length > FastCloneShallowArrayStub::kMaximumLength) { |
+ } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { |
clone = frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); |
} else { |
- FastCloneShallowArrayStub stub(length); |
+ FastCloneShallowArrayStub stub( |
+ FastCloneShallowArrayStub::CLONE_ELEMENTS, length); |
clone = frame_->CallStub(&stub, 3); |
} |
frame_->Push(&clone); |
@@ -5004,12 +5009,9 @@ void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { |
for (int i = 0; i < length; i++) { |
Expression* value = node->values()->at(i); |
- // If value is a literal the property value is already set in the |
- // boilerplate object. |
- if (value->AsLiteral() != NULL) continue; |
- // If value is a materialized literal the property value is already set |
- // in the boilerplate object if it is simple. |
- if (CompileTimeValue::IsCompileTimeValue(value)) continue; |
+ if (!CompileTimeValue::ArrayLiteralElementNeedsInitialization(value)) { |
+ continue; |
+ } |
// The property must be set by generated code. |
Load(value); |
@@ -6875,7 +6877,7 @@ void CodeGenerator::GenerateSwapElements(ZoneList<Expression*>* args) { |
Immediate(KeyedLoadIC::kSlowCaseBitFieldMask)); |
deferred->Branch(not_zero); |
- // Check the object's elements are in fast case. |
+ // Check the object's elements are in fast case and writable. |
__ movq(tmp1.reg(), FieldOperand(object.reg(), JSObject::kElementsOffset)); |
__ CompareRoot(FieldOperand(tmp1.reg(), HeapObject::kMapOffset), |
Heap::kFixedArrayMapRootIndex); |
@@ -8419,15 +8421,10 @@ Result CodeGenerator::EmitKeyedLoad() { |
// Check that the key is a non-negative smi. |
__ JumpIfNotPositiveSmi(key.reg(), deferred->entry_label()); |
- // Get the elements array from the receiver and check that it |
- // is not a dictionary. |
+ // Get the elements array from the receiver. |
__ movq(elements.reg(), |
FieldOperand(receiver.reg(), JSObject::kElementsOffset)); |
- if (FLAG_debug_code) { |
- __ Cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), |
- Factory::fixed_array_map()); |
- __ Assert(equal, "JSObject with fast elements map has slow elements"); |
- } |
+ __ AssertFastElements(elements.reg()); |
// Check that key is within bounds. |
__ SmiCompare(key.reg(), |
@@ -8841,6 +8838,25 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { |
__ CompareRoot(rcx, Heap::kUndefinedValueRootIndex); |
__ j(equal, &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(rcx); |
+ __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset)); |
+ __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), |
+ expected_map_index); |
+ __ Assert(equal, message); |
+ __ pop(rcx); |
+ } |
+ |
// Allocate both the JS array and the elements array in one big |
// allocation. This avoids multiple limit checks. |
__ AllocateInNewSpace(size, rax, rbx, rdx, &slow_case, TAG_OBJECT); |
@@ -8867,6 +8883,10 @@ void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { |
} |
} |
+ if (mode_ == COPY_ON_WRITE_ELEMENTS) { |
+ __ IncrementCounter(&Counters::cow_arrays_created_stub, 1); |
+ } |
+ |
// Return and remove the on-stack parameters. |
__ ret(3 * kPointerSize); |