OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1857 __ CallStub(&stub); | 1857 __ CallStub(&stub); |
1858 } | 1858 } |
1859 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1859 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
1860 | 1860 |
1861 bool result_saved = false; // Is the result saved to the stack? | 1861 bool result_saved = false; // Is the result saved to the stack? |
1862 ZoneList<Expression*>* subexprs = expr->values(); | 1862 ZoneList<Expression*>* subexprs = expr->values(); |
1863 int length = subexprs->length(); | 1863 int length = subexprs->length(); |
1864 | 1864 |
1865 // Emit code to evaluate all the non-constant subexpressions and to store | 1865 // Emit code to evaluate all the non-constant subexpressions and to store |
1866 // them into the newly cloned array. | 1866 // them into the newly cloned array. |
1867 for (int i = 0; i < length; i++) { | 1867 int array_index = 0; |
1868 Expression* subexpr = subexprs->at(i); | 1868 for (; array_index < length; array_index++) { |
| 1869 Expression* subexpr = subexprs->at(array_index); |
| 1870 if (subexpr->IsSpread()) break; |
| 1871 |
1869 // If the subexpression is a literal or a simple materialized literal it | 1872 // If the subexpression is a literal or a simple materialized literal it |
1870 // is already set in the cloned array. | 1873 // is already set in the cloned array. |
1871 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1874 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1872 | 1875 |
1873 if (!result_saved) { | 1876 if (!result_saved) { |
1874 __ Mov(x1, Smi::FromInt(expr->literal_index())); | 1877 __ Mov(x1, Smi::FromInt(expr->literal_index())); |
1875 __ Push(x0, x1); | 1878 __ Push(x0, x1); |
1876 result_saved = true; | 1879 result_saved = true; |
1877 } | 1880 } |
1878 VisitForAccumulatorValue(subexpr); | 1881 VisitForAccumulatorValue(subexpr); |
1879 | 1882 |
1880 if (has_fast_elements) { | 1883 if (has_fast_elements) { |
1881 int offset = FixedArray::kHeaderSize + (i * kPointerSize); | 1884 int offset = FixedArray::kHeaderSize + (array_index * kPointerSize); |
1882 __ Peek(x6, kPointerSize); // Copy of array literal. | 1885 __ Peek(x6, kPointerSize); // Copy of array literal. |
1883 __ Ldr(x1, FieldMemOperand(x6, JSObject::kElementsOffset)); | 1886 __ Ldr(x1, FieldMemOperand(x6, JSObject::kElementsOffset)); |
1884 __ Str(result_register(), FieldMemOperand(x1, offset)); | 1887 __ Str(result_register(), FieldMemOperand(x1, offset)); |
1885 // Update the write barrier for the array store. | 1888 // Update the write barrier for the array store. |
1886 __ RecordWriteField(x1, offset, result_register(), x10, | 1889 __ RecordWriteField(x1, offset, result_register(), x10, |
1887 kLRHasBeenSaved, kDontSaveFPRegs, | 1890 kLRHasBeenSaved, kDontSaveFPRegs, |
1888 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); | 1891 EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); |
1889 } else { | 1892 } else { |
1890 __ Mov(x3, Smi::FromInt(i)); | 1893 __ Mov(x3, Smi::FromInt(array_index)); |
1891 StoreArrayLiteralElementStub stub(isolate()); | 1894 StoreArrayLiteralElementStub stub(isolate()); |
1892 __ CallStub(&stub); | 1895 __ CallStub(&stub); |
1893 } | 1896 } |
1894 | 1897 |
1895 PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); | 1898 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
| 1899 } |
| 1900 |
| 1901 // In case the array literal contains spread expressions it has two parts. The |
| 1902 // first part is the "static" array which has a literal index is handled |
| 1903 // above. The second part is the part after the first spread expression |
| 1904 // (inclusive) and these elements gets appended to the array. Note that the |
| 1905 // number elements an iterable produces is unknown ahead of time. |
| 1906 if (array_index < length && result_saved) { |
| 1907 __ Drop(1); // literal index |
| 1908 __ Pop(x0); |
| 1909 result_saved = false; |
| 1910 } |
| 1911 for (; array_index < length; array_index++) { |
| 1912 Expression* subexpr = subexprs->at(array_index); |
| 1913 |
| 1914 __ Push(x0); |
| 1915 if (subexpr->IsSpread()) { |
| 1916 VisitForStackValue(subexpr->AsSpread()->expression()); |
| 1917 __ InvokeBuiltin(Builtins::CONCAT_ITERABLE_TO_ARRAY, CALL_FUNCTION); |
| 1918 } else { |
| 1919 VisitForStackValue(subexpr); |
| 1920 __ CallRuntime(Runtime::kAppendElement, 2); |
| 1921 } |
| 1922 |
| 1923 PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); |
1896 } | 1924 } |
1897 | 1925 |
1898 if (result_saved) { | 1926 if (result_saved) { |
1899 __ Drop(1); // literal index | 1927 __ Drop(1); // literal index |
1900 context()->PlugTOS(); | 1928 context()->PlugTOS(); |
1901 } else { | 1929 } else { |
1902 context()->Plug(x0); | 1930 context()->Plug(x0); |
1903 } | 1931 } |
1904 } | 1932 } |
1905 | 1933 |
(...skipping 3547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5453 } | 5481 } |
5454 } | 5482 } |
5455 | 5483 |
5456 return INTERRUPT; | 5484 return INTERRUPT; |
5457 } | 5485 } |
5458 | 5486 |
5459 | 5487 |
5460 } } // namespace v8::internal | 5488 } } // namespace v8::internal |
5461 | 5489 |
5462 #endif // V8_TARGET_ARCH_ARM64 | 5490 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |