| 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 | 7 |
| 8 namespace v8 { | 8 namespace v8 { |
| 9 namespace internal { | 9 namespace internal { |
| 10 | 10 |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 | 231 |
| 232 Bind(&return_minus_x); | 232 Bind(&return_minus_x); |
| 233 var_x.Bind(Float64Neg(var_x.value())); | 233 var_x.Bind(Float64Neg(var_x.value())); |
| 234 Goto(&return_x); | 234 Goto(&return_x); |
| 235 | 235 |
| 236 Bind(&return_x); | 236 Bind(&return_x); |
| 237 return var_x.value(); | 237 return var_x.value(); |
| 238 } | 238 } |
| 239 | 239 |
| 240 Node* CodeStubAssembler::SmiFromWord32(Node* value) { | 240 Node* CodeStubAssembler::SmiFromWord32(Node* value) { |
| 241 if (Is64()) { | 241 value = ChangeInt32ToIntPtr(value); |
| 242 value = ChangeInt32ToInt64(value); | |
| 243 } | |
| 244 return WordShl(value, SmiShiftBitsConstant()); | 242 return WordShl(value, SmiShiftBitsConstant()); |
| 245 } | 243 } |
| 246 | 244 |
| 247 Node* CodeStubAssembler::SmiTag(Node* value) { | 245 Node* CodeStubAssembler::SmiTag(Node* value) { |
| 248 return WordShl(value, SmiShiftBitsConstant()); | 246 return WordShl(value, SmiShiftBitsConstant()); |
| 249 } | 247 } |
| 250 | 248 |
| 251 Node* CodeStubAssembler::SmiUntag(Node* value) { | 249 Node* CodeStubAssembler::SmiUntag(Node* value) { |
| 252 return WordSar(value, SmiShiftBitsConstant()); | 250 return WordSar(value, SmiShiftBitsConstant()); |
| 253 } | 251 } |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 StoreObjectFieldNoWriteBarrier(result, FixedArray::kLengthOffset, | 511 StoreObjectFieldNoWriteBarrier(result, FixedArray::kLengthOffset, |
| 514 SmiTag(length)); | 512 SmiTag(length)); |
| 515 | 513 |
| 516 return result; | 514 return result; |
| 517 } | 515 } |
| 518 | 516 |
| 519 Node* CodeStubAssembler::LoadFixedArrayElementInt32Index( | 517 Node* CodeStubAssembler::LoadFixedArrayElementInt32Index( |
| 520 Node* object, Node* index, int additional_offset) { | 518 Node* object, Node* index, int additional_offset) { |
| 521 Node* header_size = IntPtrConstant(additional_offset + | 519 Node* header_size = IntPtrConstant(additional_offset + |
| 522 FixedArray::kHeaderSize - kHeapObjectTag); | 520 FixedArray::kHeaderSize - kHeapObjectTag); |
| 523 if (Is64()) { | 521 index = ChangeInt32ToIntPtr(index); |
| 524 index = ChangeInt32ToInt64(index); | |
| 525 } | |
| 526 Node* scaled_index = WordShl(index, IntPtrConstant(kPointerSizeLog2)); | 522 Node* scaled_index = WordShl(index, IntPtrConstant(kPointerSizeLog2)); |
| 527 Node* offset = IntPtrAdd(scaled_index, header_size); | 523 Node* offset = IntPtrAdd(scaled_index, header_size); |
| 528 return Load(MachineType::AnyTagged(), object, offset); | 524 return Load(MachineType::AnyTagged(), object, offset); |
| 529 } | 525 } |
| 530 | 526 |
| 531 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { | 527 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { |
| 532 return Load(MachineType::Uint8(), map, | 528 return Load(MachineType::Uint8(), map, |
| 533 IntPtrConstant(Map::kInstanceSizeOffset - kHeapObjectTag)); | 529 IntPtrConstant(Map::kInstanceSizeOffset - kHeapObjectTag)); |
| 534 } | 530 } |
| 535 | 531 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 548 return Load(MachineType::AnyTagged(), object, offset); | 544 return Load(MachineType::AnyTagged(), object, offset); |
| 549 } | 545 } |
| 550 | 546 |
| 551 Node* CodeStubAssembler::LoadFixedArrayElementConstantIndex(Node* object, | 547 Node* CodeStubAssembler::LoadFixedArrayElementConstantIndex(Node* object, |
| 552 int index) { | 548 int index) { |
| 553 Node* offset = IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag + | 549 Node* offset = IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag + |
| 554 index * kPointerSize); | 550 index * kPointerSize); |
| 555 return Load(MachineType::AnyTagged(), object, offset); | 551 return Load(MachineType::AnyTagged(), object, offset); |
| 556 } | 552 } |
| 557 | 553 |
| 554 Node* CodeStubAssembler::LoadNativeContext(Node* context) { |
| 555 return LoadFixedArrayElementConstantIndex(context, |
| 556 Context::NATIVE_CONTEXT_INDEX); |
| 557 } |
| 558 |
| 558 Node* CodeStubAssembler::StoreHeapNumberValue(Node* object, Node* value) { | 559 Node* CodeStubAssembler::StoreHeapNumberValue(Node* object, Node* value) { |
| 559 return StoreNoWriteBarrier( | 560 return StoreNoWriteBarrier( |
| 560 MachineRepresentation::kFloat64, object, | 561 MachineRepresentation::kFloat64, object, |
| 561 IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag), value); | 562 IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag), value); |
| 562 } | 563 } |
| 563 | 564 |
| 564 Node* CodeStubAssembler::StoreObjectField( | 565 Node* CodeStubAssembler::StoreObjectField( |
| 565 Node* object, int offset, Node* value) { | 566 Node* object, int offset, Node* value) { |
| 566 return Store(MachineRepresentation::kTagged, object, | 567 return Store(MachineRepresentation::kTagged, object, |
| 567 IntPtrConstant(offset - kHeapObjectTag), value); | 568 IntPtrConstant(offset - kHeapObjectTag), value); |
| 568 } | 569 } |
| 569 | 570 |
| 570 Node* CodeStubAssembler::StoreObjectFieldNoWriteBarrier( | 571 Node* CodeStubAssembler::StoreObjectFieldNoWriteBarrier( |
| 571 Node* object, int offset, Node* value, MachineRepresentation rep) { | 572 Node* object, int offset, Node* value, MachineRepresentation rep) { |
| 572 return StoreNoWriteBarrier(rep, object, | 573 return StoreNoWriteBarrier(rep, object, |
| 573 IntPtrConstant(offset - kHeapObjectTag), value); | 574 IntPtrConstant(offset - kHeapObjectTag), value); |
| 574 } | 575 } |
| 575 | 576 |
| 576 Node* CodeStubAssembler::StoreMapNoWriteBarrier(Node* object, Node* map) { | 577 Node* CodeStubAssembler::StoreMapNoWriteBarrier(Node* object, Node* map) { |
| 577 return StoreNoWriteBarrier( | 578 return StoreNoWriteBarrier( |
| 578 MachineRepresentation::kTagged, object, | 579 MachineRepresentation::kTagged, object, |
| 579 IntPtrConstant(HeapNumber::kMapOffset - kHeapObjectTag), map); | 580 IntPtrConstant(HeapNumber::kMapOffset - kHeapObjectTag), map); |
| 580 } | 581 } |
| 581 | 582 |
| 582 Node* CodeStubAssembler::StoreFixedArrayElementNoWriteBarrier(Node* object, | 583 Node* CodeStubAssembler::StoreFixedArrayElementNoWriteBarrier(Node* object, |
| 583 Node* index, | 584 Node* index, |
| 584 Node* value) { | 585 Node* value) { |
| 586 index = ChangeInt32ToIntPtr(index); |
| 585 Node* offset = | 587 Node* offset = |
| 586 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)), | 588 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)), |
| 587 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); | 589 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 588 return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset, | 590 return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset, |
| 589 value); | 591 value); |
| 590 } | 592 } |
| 591 | 593 |
| 592 Node* CodeStubAssembler::StoreFixedArrayElementInt32Index(Node* object, | 594 Node* CodeStubAssembler::StoreFixedArrayElementInt32Index(Node* object, |
| 593 Node* index, | 595 Node* index, |
| 594 Node* value) { | 596 Node* value) { |
| 595 if (Is64()) { | 597 index = ChangeInt32ToIntPtr(index); |
| 596 index = ChangeInt32ToInt64(index); | |
| 597 } | |
| 598 Node* offset = | 598 Node* offset = |
| 599 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)), | 599 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)), |
| 600 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); | 600 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 601 return Store(MachineRepresentation::kTagged, object, offset, value); | 601 return Store(MachineRepresentation::kTagged, object, offset, value); |
| 602 } | 602 } |
| 603 | 603 |
| 604 Node* CodeStubAssembler::StoreFixedDoubleArrayElementInt32Index(Node* object, |
| 605 Node* index, |
| 606 Node* value) { |
| 607 index = ChangeInt32ToIntPtr(index); |
| 608 Node* offset = |
| 609 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)), |
| 610 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 611 return StoreNoWriteBarrier(MachineRepresentation::kFloat64, object, offset, |
| 612 value); |
| 613 } |
| 614 |
| 615 Node* CodeStubAssembler::StoreFixedArrayElementInt32Index(Node* object, |
| 616 int index, |
| 617 Node* value) { |
| 618 Node* offset = IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag + |
| 619 index * kPointerSize); |
| 620 return Store(MachineRepresentation::kTagged, object, offset, value); |
| 621 } |
| 622 |
| 623 Node* CodeStubAssembler::StoreFixedArrayElementNoWriteBarrier(Node* object, |
| 624 int index, |
| 625 Node* value) { |
| 626 Node* offset = IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag + |
| 627 index * kPointerSize); |
| 628 return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset, |
| 629 value); |
| 630 } |
| 631 |
| 632 Node* CodeStubAssembler::StoreFixedDoubleArrayElementInt32Index(Node* object, |
| 633 int index, |
| 634 Node* value) { |
| 635 Node* offset = IntPtrConstant(FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
| 636 index * kDoubleSize); |
| 637 return StoreNoWriteBarrier(MachineRepresentation::kFloat64, object, offset, |
| 638 value); |
| 639 } |
| 640 |
| 604 Node* CodeStubAssembler::AllocateHeapNumber() { | 641 Node* CodeStubAssembler::AllocateHeapNumber() { |
| 605 Node* result = Allocate(HeapNumber::kSize, kNone); | 642 Node* result = Allocate(HeapNumber::kSize, kNone); |
| 606 StoreMapNoWriteBarrier(result, HeapNumberMapConstant()); | 643 StoreMapNoWriteBarrier(result, HeapNumberMapConstant()); |
| 607 return result; | 644 return result; |
| 608 } | 645 } |
| 609 | 646 |
| 610 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value) { | 647 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value) { |
| 611 Node* result = AllocateHeapNumber(); | 648 Node* result = AllocateHeapNumber(); |
| 612 StoreHeapNumberValue(result, value); | 649 StoreHeapNumberValue(result, value); |
| 613 return result; | 650 return result; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 626 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length) { | 663 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length) { |
| 627 Node* result = Allocate(SeqTwoByteString::SizeFor(length)); | 664 Node* result = Allocate(SeqTwoByteString::SizeFor(length)); |
| 628 StoreMapNoWriteBarrier(result, LoadRoot(Heap::kStringMapRootIndex)); | 665 StoreMapNoWriteBarrier(result, LoadRoot(Heap::kStringMapRootIndex)); |
| 629 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset, | 666 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset, |
| 630 SmiConstant(Smi::FromInt(length))); | 667 SmiConstant(Smi::FromInt(length))); |
| 631 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot, | 668 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot, |
| 632 IntPtrConstant(String::kEmptyHashField)); | 669 IntPtrConstant(String::kEmptyHashField)); |
| 633 return result; | 670 return result; |
| 634 } | 671 } |
| 635 | 672 |
| 673 Node* CodeStubAssembler::AllocateJSArray(ElementsKind kind, |
| 674 Node* native_context, int capacity, |
| 675 int length, |
| 676 compiler::Node* allocation_site) { |
| 677 bool is_double = IsFastDoubleElementsKind(kind); |
| 678 int element_size = is_double ? kDoubleSize : kPointerSize; |
| 679 int total_size = |
| 680 JSArray::kSize + FixedArray::kHeaderSize + element_size * capacity; |
| 681 int elements_offset = JSArray::kSize; |
| 682 |
| 683 if (allocation_site != nullptr) { |
| 684 total_size += AllocationMemento::kSize; |
| 685 elements_offset += AllocationMemento::kSize; |
| 686 } |
| 687 |
| 688 // Allocate both array and elements object, and initialize the JSArray. |
| 689 Heap* heap = isolate()->heap(); |
| 690 Node* array = Allocate(total_size); |
| 691 Node* array_map = LoadFixedArrayElementConstantIndex( |
| 692 native_context, Context::ArrayMapIndex(kind)); |
| 693 StoreMapNoWriteBarrier(array, array_map); |
| 694 Node* empty_properties = |
| 695 HeapConstant(Handle<HeapObject>(heap->empty_fixed_array())); |
| 696 StoreObjectFieldNoWriteBarrier(array, JSArray::kPropertiesOffset, |
| 697 empty_properties); |
| 698 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, |
| 699 SmiConstant(Smi::FromInt(length))); |
| 700 |
| 701 if (allocation_site != nullptr) { |
| 702 InitializeAllocationMemento(array, JSArray::kSize, allocation_site); |
| 703 } |
| 704 |
| 705 // Setup elements object. |
| 706 Node* elements = InnerAllocate(array, elements_offset); |
| 707 StoreObjectFieldNoWriteBarrier(array, JSArray::kElementsOffset, elements); |
| 708 Handle<Map> elements_map(is_double ? heap->fixed_double_array_map() |
| 709 : heap->fixed_array_map()); |
| 710 StoreMapNoWriteBarrier(elements, HeapConstant(elements_map)); |
| 711 StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, |
| 712 SmiConstant(Smi::FromInt(capacity))); |
| 713 |
| 714 Node* double_hole = Float64Constant(bit_cast<double>(kHoleNanInt64)); |
| 715 Node* hole = HeapConstant(Handle<HeapObject>(heap->the_hole_value())); |
| 716 if (capacity <= kElementLoopUnrollThreshold) { |
| 717 for (int i = 0; i < capacity; ++i) { |
| 718 if (is_double) { |
| 719 StoreFixedDoubleArrayElementInt32Index(elements, i, double_hole); |
| 720 } else { |
| 721 StoreFixedArrayElementNoWriteBarrier(elements, i, hole); |
| 722 } |
| 723 } |
| 724 } else { |
| 725 // TODO(danno): Add a loop for initialization |
| 726 UNIMPLEMENTED(); |
| 727 } |
| 728 |
| 729 return array; |
| 730 } |
| 731 |
| 732 void CodeStubAssembler::InitializeAllocationMemento( |
| 733 compiler::Node* base_allocation, int base_allocation_size, |
| 734 compiler::Node* allocation_site) { |
| 735 StoreObjectFieldNoWriteBarrier( |
| 736 base_allocation, AllocationMemento::kMapOffset + base_allocation_size, |
| 737 HeapConstant(Handle<Map>(isolate()->heap()->allocation_memento_map()))); |
| 738 StoreObjectFieldNoWriteBarrier( |
| 739 base_allocation, |
| 740 AllocationMemento::kAllocationSiteOffset + base_allocation_size, |
| 741 allocation_site); |
| 742 if (FLAG_allocation_site_pretenuring) { |
| 743 Node* count = LoadObjectField(allocation_site, |
| 744 AllocationSite::kPretenureCreateCountOffset); |
| 745 Node* incremented_count = IntPtrAdd(count, SmiConstant(Smi::FromInt(1))); |
| 746 StoreObjectFieldNoWriteBarrier(allocation_site, |
| 747 AllocationSite::kPretenureCreateCountOffset, |
| 748 incremented_count); |
| 749 } |
| 750 } |
| 751 |
| 636 Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) { | 752 Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) { |
| 637 // We might need to loop once due to ToNumber conversion. | 753 // We might need to loop once due to ToNumber conversion. |
| 638 Variable var_value(this, MachineRepresentation::kTagged), | 754 Variable var_value(this, MachineRepresentation::kTagged), |
| 639 var_result(this, MachineRepresentation::kFloat64); | 755 var_result(this, MachineRepresentation::kFloat64); |
| 640 Label loop(this, &var_value), done_loop(this, &var_result); | 756 Label loop(this, &var_value), done_loop(this, &var_result); |
| 641 var_value.Bind(value); | 757 var_value.Bind(value); |
| 642 Goto(&loop); | 758 Goto(&loop); |
| 643 Bind(&loop); | 759 Bind(&loop); |
| 644 { | 760 { |
| 645 // Load the current {value}. | 761 // Load the current {value}. |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 } | 1259 } |
| 1144 | 1260 |
| 1145 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, | 1261 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, |
| 1146 uint32_t mask) { | 1262 uint32_t mask) { |
| 1147 return Word32Shr(Word32And(word32, Int32Constant(mask)), | 1263 return Word32Shr(Word32And(word32, Int32Constant(mask)), |
| 1148 Int32Constant(shift)); | 1264 Int32Constant(shift)); |
| 1149 } | 1265 } |
| 1150 | 1266 |
| 1151 } // namespace internal | 1267 } // namespace internal |
| 1152 } // namespace v8 | 1268 } // namespace v8 |
| OLD | NEW |