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 |