OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/frames.h" | 8 #include "src/frames.h" |
9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
(...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1371 // Setup elements object. | 1371 // Setup elements object. |
1372 Node* elements = InnerAllocate(array, elements_offset); | 1372 Node* elements = InnerAllocate(array, elements_offset); |
1373 StoreObjectFieldNoWriteBarrier(array, JSArray::kElementsOffset, elements); | 1373 StoreObjectFieldNoWriteBarrier(array, JSArray::kElementsOffset, elements); |
1374 Handle<Map> elements_map(is_double ? heap->fixed_double_array_map() | 1374 Handle<Map> elements_map(is_double ? heap->fixed_double_array_map() |
1375 : heap->fixed_array_map()); | 1375 : heap->fixed_array_map()); |
1376 StoreMapNoWriteBarrier(elements, HeapConstant(elements_map)); | 1376 StoreMapNoWriteBarrier(elements, HeapConstant(elements_map)); |
1377 StoreObjectFieldNoWriteBarrier( | 1377 StoreObjectFieldNoWriteBarrier( |
1378 elements, FixedArray::kLengthOffset, | 1378 elements, FixedArray::kLengthOffset, |
1379 mode == SMI_PARAMETERS ? capacity_node : SmiTag(capacity_node)); | 1379 mode == SMI_PARAMETERS ? capacity_node : SmiTag(capacity_node)); |
1380 | 1380 |
1381 FillFixedArrayWithHole(kind, elements, IntPtrConstant(0), capacity_node, | 1381 // Fill in the elements with holes. |
1382 mode); | 1382 FillFixedArrayWithValue(kind, elements, IntPtrConstant(0), capacity_node, |
| 1383 Heap::kTheHoleValueRootIndex, mode); |
1383 | 1384 |
1384 return array; | 1385 return array; |
1385 } | 1386 } |
1386 | 1387 |
1387 Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind, | 1388 Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind, |
1388 Node* capacity_node, | 1389 Node* capacity_node, |
1389 ParameterMode mode, | 1390 ParameterMode mode, |
1390 AllocationFlags flags) { | 1391 AllocationFlags flags) { |
1391 Node* total_size = GetFixedAarrayAllocationSize(capacity_node, kind, mode); | 1392 Node* total_size = GetFixedAarrayAllocationSize(capacity_node, kind, mode); |
1392 | 1393 |
1393 // Allocate both array and elements object, and initialize the JSArray. | 1394 // Allocate both array and elements object, and initialize the JSArray. |
1394 Node* array = Allocate(total_size, flags); | 1395 Node* array = Allocate(total_size, flags); |
1395 Heap* heap = isolate()->heap(); | 1396 Heap* heap = isolate()->heap(); |
1396 Handle<Map> map(IsFastDoubleElementsKind(kind) | 1397 Handle<Map> map(IsFastDoubleElementsKind(kind) |
1397 ? heap->fixed_double_array_map() | 1398 ? heap->fixed_double_array_map() |
1398 : heap->fixed_array_map()); | 1399 : heap->fixed_array_map()); |
1399 if (flags & kPretenured) { | 1400 if (flags & kPretenured) { |
1400 StoreObjectField(array, JSObject::kMapOffset, HeapConstant(map)); | 1401 StoreObjectField(array, JSObject::kMapOffset, HeapConstant(map)); |
1401 } else { | 1402 } else { |
1402 StoreMapNoWriteBarrier(array, HeapConstant(map)); | 1403 StoreMapNoWriteBarrier(array, HeapConstant(map)); |
1403 } | 1404 } |
1404 StoreObjectFieldNoWriteBarrier( | 1405 StoreObjectFieldNoWriteBarrier( |
1405 array, FixedArray::kLengthOffset, | 1406 array, FixedArray::kLengthOffset, |
1406 mode == INTEGER_PARAMETERS ? SmiTag(capacity_node) : capacity_node); | 1407 mode == INTEGER_PARAMETERS ? SmiTag(capacity_node) : capacity_node); |
1407 return array; | 1408 return array; |
1408 } | 1409 } |
1409 | 1410 |
1410 void CodeStubAssembler::FillFixedArrayWithHole(ElementsKind kind, | 1411 void CodeStubAssembler::FillFixedArrayWithValue( |
1411 compiler::Node* array, | 1412 ElementsKind kind, Node* array, Node* from_node, Node* to_node, |
1412 compiler::Node* from_node, | 1413 Heap::RootListIndex value_root_index, ParameterMode mode) { |
1413 compiler::Node* to_node, | 1414 bool is_double = IsFastDoubleElementsKind(kind); |
1414 ParameterMode mode) { | 1415 DCHECK(value_root_index == Heap::kTheHoleValueRootIndex || |
1415 int const first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag; | 1416 value_root_index == Heap::kUndefinedValueRootIndex); |
1416 Heap* heap = isolate()->heap(); | 1417 DCHECK_IMPLIES(is_double, value_root_index == Heap::kTheHoleValueRootIndex); |
1417 Node* hole = HeapConstant(Handle<HeapObject>(heap->the_hole_value())); | 1418 STATIC_ASSERT(kHoleNanLower32 == kHoleNanUpper32); |
1418 Node* double_hole = | 1419 Node* double_hole = |
1419 Is64() ? Int64Constant(kHoleNanInt64) : Int32Constant(kHoleNanLower32); | 1420 Is64() ? Int64Constant(kHoleNanInt64) : Int32Constant(kHoleNanLower32); |
1420 DCHECK_EQ(kHoleNanLower32, kHoleNanUpper32); | 1421 Node* value = LoadRoot(value_root_index); |
1421 bool is_double = IsFastDoubleElementsKind(kind); | 1422 |
| 1423 int const first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag; |
1422 int32_t to; | 1424 int32_t to; |
1423 bool constant_to = ToInt32Constant(to_node, to); | 1425 bool constant_to = ToInt32Constant(to_node, to); |
1424 int32_t from; | 1426 int32_t from; |
1425 bool constant_from = ToInt32Constant(from_node, from); | 1427 bool constant_from = ToInt32Constant(from_node, from); |
1426 if (constant_to && constant_from && | 1428 if (constant_to && constant_from && |
1427 (to - from) <= kElementLoopUnrollThreshold) { | 1429 (to - from) <= kElementLoopUnrollThreshold) { |
1428 for (int i = from; i < to; ++i) { | 1430 for (int i = from; i < to; ++i) { |
1429 if (is_double) { | 1431 if (is_double) { |
1430 Node* offset = ElementOffsetFromIndex(Int32Constant(i), kind, mode, | 1432 Node* offset = ElementOffsetFromIndex(Int32Constant(i), kind, mode, |
1431 first_element_offset); | 1433 first_element_offset); |
(...skipping 10 matching lines...) Expand all Loading... |
1442 double_hole); | 1444 double_hole); |
1443 } else { | 1445 } else { |
1444 StoreNoWriteBarrier(MachineRepresentation::kWord32, array, offset, | 1446 StoreNoWriteBarrier(MachineRepresentation::kWord32, array, offset, |
1445 double_hole); | 1447 double_hole); |
1446 offset = ElementOffsetFromIndex(Int32Constant(i), kind, mode, | 1448 offset = ElementOffsetFromIndex(Int32Constant(i), kind, mode, |
1447 first_element_offset + kPointerSize); | 1449 first_element_offset + kPointerSize); |
1448 StoreNoWriteBarrier(MachineRepresentation::kWord32, array, offset, | 1450 StoreNoWriteBarrier(MachineRepresentation::kWord32, array, offset, |
1449 double_hole); | 1451 double_hole); |
1450 } | 1452 } |
1451 } else { | 1453 } else { |
1452 StoreFixedArrayElement(array, Int32Constant(i), hole, | 1454 StoreFixedArrayElement(array, Int32Constant(i), value, |
1453 SKIP_WRITE_BARRIER); | 1455 SKIP_WRITE_BARRIER); |
1454 } | 1456 } |
1455 } | 1457 } |
1456 } else { | 1458 } else { |
1457 Variable current(this, MachineRepresentation::kTagged); | 1459 Variable current(this, MachineRepresentation::kTagged); |
1458 Label test(this); | 1460 Label test(this); |
1459 Label decrement(this, ¤t); | 1461 Label decrement(this, ¤t); |
1460 Label done(this); | 1462 Label done(this); |
1461 Node* limit = | 1463 Node* limit = |
1462 IntPtrAdd(array, ElementOffsetFromIndex(from_node, kind, mode)); | 1464 IntPtrAdd(array, ElementOffsetFromIndex(from_node, kind, mode)); |
(...skipping 14 matching lines...) Expand all Loading... |
1477 // | 1479 // |
1478 // TODO(danno): When we have a Float32/Float64 wrapper class that | 1480 // TODO(danno): When we have a Float32/Float64 wrapper class that |
1479 // preserves double bits during manipulation, remove this code/change | 1481 // preserves double bits during manipulation, remove this code/change |
1480 // this to an indexed Float64 store. | 1482 // this to an indexed Float64 store. |
1481 if (Is64()) { | 1483 if (Is64()) { |
1482 StoreNoWriteBarrier(MachineRepresentation::kWord64, current.value(), | 1484 StoreNoWriteBarrier(MachineRepresentation::kWord64, current.value(), |
1483 Int64Constant(first_element_offset), double_hole); | 1485 Int64Constant(first_element_offset), double_hole); |
1484 } else { | 1486 } else { |
1485 StoreNoWriteBarrier(MachineRepresentation::kWord32, current.value(), | 1487 StoreNoWriteBarrier(MachineRepresentation::kWord32, current.value(), |
1486 Int32Constant(first_element_offset), double_hole); | 1488 Int32Constant(first_element_offset), double_hole); |
1487 StoreNoWriteBarrier( | 1489 StoreNoWriteBarrier(MachineRepresentation::kWord32, current.value(), |
1488 MachineRepresentation::kWord32, | 1490 Int32Constant(kPointerSize + first_element_offset), |
1489 IntPtrAdd(current.value(), | 1491 double_hole); |
1490 Int32Constant(kPointerSize + first_element_offset)), | |
1491 double_hole); | |
1492 } | 1492 } |
1493 } else { | 1493 } else { |
1494 StoreNoWriteBarrier(MachineRepresentation::kTagged, current.value(), | 1494 StoreNoWriteBarrier(MachineType::PointerRepresentation(), current.value(), |
1495 IntPtrConstant(first_element_offset), hole); | 1495 IntPtrConstant(first_element_offset), value); |
1496 } | 1496 } |
1497 Node* compare = WordNotEqual(current.value(), limit); | 1497 Node* compare = WordNotEqual(current.value(), limit); |
1498 Branch(compare, &decrement, &done); | 1498 Branch(compare, &decrement, &done); |
1499 | 1499 |
1500 Bind(&done); | 1500 Bind(&done); |
1501 } | 1501 } |
1502 } | 1502 } |
1503 | 1503 |
1504 void CodeStubAssembler::CopyFixedArrayElements(ElementsKind kind, | 1504 void CodeStubAssembler::CopyFixedArrayElements(ElementsKind kind, |
1505 compiler::Node* from_array, | 1505 compiler::Node* from_array, |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1593 // that we can bump-pointer allocate from, fall back to the runtime, | 1593 // that we can bump-pointer allocate from, fall back to the runtime, |
1594 int max_size = FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind); | 1594 int max_size = FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind); |
1595 GotoIf(UintPtrGreaterThanOrEqual(new_capacity, | 1595 GotoIf(UintPtrGreaterThanOrEqual(new_capacity, |
1596 IntPtrOrSmiConstant(max_size, mode)), | 1596 IntPtrOrSmiConstant(max_size, mode)), |
1597 fail); | 1597 fail); |
1598 | 1598 |
1599 // Allocate the new backing store. | 1599 // Allocate the new backing store. |
1600 Node* new_elements = AllocateFixedArray(kind, new_capacity, mode); | 1600 Node* new_elements = AllocateFixedArray(kind, new_capacity, mode); |
1601 | 1601 |
1602 // Fill in the added capacity in the new store with holes. | 1602 // Fill in the added capacity in the new store with holes. |
1603 FillFixedArrayWithHole(kind, new_elements, capacity, new_capacity, mode); | 1603 FillFixedArrayWithValue(kind, new_elements, capacity, new_capacity, |
| 1604 Heap::kTheHoleValueRootIndex, mode); |
1604 | 1605 |
1605 // Copy the elements from the old elements store to the new. | 1606 // Copy the elements from the old elements store to the new. |
1606 CopyFixedArrayElements(kind, elements, new_elements, capacity, | 1607 CopyFixedArrayElements(kind, elements, new_elements, capacity, |
1607 SKIP_WRITE_BARRIER, mode); | 1608 SKIP_WRITE_BARRIER, mode); |
1608 | 1609 |
1609 return new_elements; | 1610 return new_elements; |
1610 } | 1611 } |
1611 | 1612 |
1612 void CodeStubAssembler::InitializeAllocationMemento( | 1613 void CodeStubAssembler::InitializeAllocationMemento( |
1613 compiler::Node* base_allocation, int base_allocation_size, | 1614 compiler::Node* base_allocation, int base_allocation_size, |
(...skipping 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2869 Node* the_hole = TheHoleConstant(); | 2870 Node* the_hole = TheHoleConstant(); |
2870 Branch(WordEqual(element, the_hole), if_not_found, if_found); | 2871 Branch(WordEqual(element, the_hole), if_not_found, if_found); |
2871 } | 2872 } |
2872 Bind(&if_isdouble); | 2873 Bind(&if_isdouble); |
2873 { | 2874 { |
2874 Node* elements = LoadElements(object); | 2875 Node* elements = LoadElements(object); |
2875 Node* length = LoadAndUntagFixedArrayBaseLength(elements); | 2876 Node* length = LoadAndUntagFixedArrayBaseLength(elements); |
2876 | 2877 |
2877 GotoUnless(UintPtrLessThan(intptr_index, length), &if_oob); | 2878 GotoUnless(UintPtrLessThan(intptr_index, length), &if_oob); |
2878 | 2879 |
2879 if (kPointerSize == kDoubleSize) { | 2880 if (Is64()) { |
2880 Node* element = LoadFixedDoubleArrayElement( | 2881 Node* element = LoadFixedDoubleArrayElement( |
2881 elements, intptr_index, MachineType::Uint64(), 0, INTPTR_PARAMETERS); | 2882 elements, intptr_index, MachineType::Uint64(), 0, INTPTR_PARAMETERS); |
2882 Node* the_hole = Int64Constant(kHoleNanInt64); | 2883 Node* the_hole = Int64Constant(kHoleNanInt64); |
2883 Branch(Word64Equal(element, the_hole), if_not_found, if_found); | 2884 Branch(Word64Equal(element, the_hole), if_not_found, if_found); |
2884 } else { | 2885 } else { |
2885 Node* element_upper = LoadFixedDoubleArrayElement( | 2886 Node* element_upper = LoadFixedDoubleArrayElement( |
2886 elements, intptr_index, MachineType::Uint32(), | 2887 elements, intptr_index, MachineType::Uint32(), |
2887 kIeeeDoubleExponentWordOffset, INTPTR_PARAMETERS); | 2888 kIeeeDoubleExponentWordOffset, INTPTR_PARAMETERS); |
2888 Branch(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)), | 2889 Branch(Word32Equal(element_upper, Int32Constant(kHoleNanUpper32)), |
2889 if_not_found, if_found); | 2890 if_not_found, if_found); |
(...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4184 Heap::kTheHoleValueRootIndex); | 4185 Heap::kTheHoleValueRootIndex); |
4185 | 4186 |
4186 // Store the WeakCell in the feedback vector. | 4187 // Store the WeakCell in the feedback vector. |
4187 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, | 4188 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, |
4188 CodeStubAssembler::SMI_PARAMETERS); | 4189 CodeStubAssembler::SMI_PARAMETERS); |
4189 return cell; | 4190 return cell; |
4190 } | 4191 } |
4191 | 4192 |
4192 } // namespace internal | 4193 } // namespace internal |
4193 } // namespace v8 | 4194 } // namespace v8 |
OLD | NEW |