| 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 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 value = ChangeInt32ToIntPtr(value); | 241 value = ChangeInt32ToIntPtr(value); |
| 242 return WordShl(value, SmiShiftBitsConstant()); | 242 return WordShl(value, SmiShiftBitsConstant()); |
| 243 } | 243 } |
| 244 | 244 |
| 245 Node* CodeStubAssembler::SmiTag(Node* value) { | 245 Node* CodeStubAssembler::SmiTag(Node* value) { |
| 246 int32_t constant_value; |
| 247 if (ToInt32Constant(value, constant_value) && Smi::IsValid(constant_value)) { |
| 248 return SmiConstant(Smi::FromInt(constant_value)); |
| 249 } |
| 246 return WordShl(value, SmiShiftBitsConstant()); | 250 return WordShl(value, SmiShiftBitsConstant()); |
| 247 } | 251 } |
| 248 | 252 |
| 249 Node* CodeStubAssembler::SmiUntag(Node* value) { | 253 Node* CodeStubAssembler::SmiUntag(Node* value) { |
| 250 return WordSar(value, SmiShiftBitsConstant()); | 254 return WordSar(value, SmiShiftBitsConstant()); |
| 251 } | 255 } |
| 252 | 256 |
| 253 Node* CodeStubAssembler::SmiToWord32(Node* value) { | 257 Node* CodeStubAssembler::SmiToWord32(Node* value) { |
| 254 Node* result = WordSar(value, SmiShiftBitsConstant()); | 258 Node* result = WordSar(value, SmiShiftBitsConstant()); |
| 255 if (Is64()) { | 259 if (Is64()) { |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 Node* total_size = IntPtrAdd(data_size, header_size); | 520 Node* total_size = IntPtrAdd(data_size, header_size); |
| 517 | 521 |
| 518 Node* result = Allocate(total_size, kNone); | 522 Node* result = Allocate(total_size, kNone); |
| 519 StoreMapNoWriteBarrier(result, LoadRoot(Heap::kFixedArrayMapRootIndex)); | 523 StoreMapNoWriteBarrier(result, LoadRoot(Heap::kFixedArrayMapRootIndex)); |
| 520 StoreObjectFieldNoWriteBarrier(result, FixedArray::kLengthOffset, | 524 StoreObjectFieldNoWriteBarrier(result, FixedArray::kLengthOffset, |
| 521 SmiTag(length)); | 525 SmiTag(length)); |
| 522 | 526 |
| 523 return result; | 527 return result; |
| 524 } | 528 } |
| 525 | 529 |
| 526 Node* CodeStubAssembler::LoadFixedArrayElementInt32Index( | 530 Node* CodeStubAssembler::LoadFixedArrayElement(Node* object, Node* index_node, |
| 527 Node* object, Node* index, int additional_offset) { | 531 int additional_offset, |
| 528 Node* header_size = IntPtrConstant(additional_offset + | 532 ParameterMode parameter_mode) { |
| 529 FixedArray::kHeaderSize - kHeapObjectTag); | 533 int32_t header_size = |
| 530 index = ChangeInt32ToIntPtr(index); | 534 FixedArray::kHeaderSize + additional_offset - kHeapObjectTag; |
| 531 Node* scaled_index = WordShl(index, IntPtrConstant(kPointerSizeLog2)); | 535 Node* offset = ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS, |
| 532 Node* offset = IntPtrAdd(scaled_index, header_size); | 536 parameter_mode, header_size); |
| 533 return Load(MachineType::AnyTagged(), object, offset); | 537 return Load(MachineType::AnyTagged(), object, offset); |
| 534 } | 538 } |
| 535 | 539 |
| 536 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { | 540 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { |
| 537 return Load(MachineType::Uint8(), map, | 541 return Load(MachineType::Uint8(), map, |
| 538 IntPtrConstant(Map::kInstanceSizeOffset - kHeapObjectTag)); | 542 IntPtrConstant(Map::kInstanceSizeOffset - kHeapObjectTag)); |
| 539 } | 543 } |
| 540 | 544 |
| 541 Node* CodeStubAssembler::LoadFixedArrayElementSmiIndex(Node* object, | |
| 542 Node* smi_index, | |
| 543 int additional_offset) { | |
| 544 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; | |
| 545 Node* header_size = IntPtrConstant(additional_offset + | |
| 546 FixedArray::kHeaderSize - kHeapObjectTag); | |
| 547 Node* scaled_index = | |
| 548 (kSmiShiftBits > kPointerSizeLog2) | |
| 549 ? WordSar(smi_index, IntPtrConstant(kSmiShiftBits - kPointerSizeLog2)) | |
| 550 : WordShl(smi_index, | |
| 551 IntPtrConstant(kPointerSizeLog2 - kSmiShiftBits)); | |
| 552 Node* offset = IntPtrAdd(scaled_index, header_size); | |
| 553 return Load(MachineType::AnyTagged(), object, offset); | |
| 554 } | |
| 555 | |
| 556 Node* CodeStubAssembler::LoadFixedArrayElementConstantIndex(Node* object, | |
| 557 int index) { | |
| 558 Node* offset = IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag + | |
| 559 index * kPointerSize); | |
| 560 return Load(MachineType::AnyTagged(), object, offset); | |
| 561 } | |
| 562 | |
| 563 Node* CodeStubAssembler::LoadNativeContext(Node* context) { | 545 Node* CodeStubAssembler::LoadNativeContext(Node* context) { |
| 564 return LoadFixedArrayElementConstantIndex(context, | 546 return LoadFixedArrayElement(context, |
| 565 Context::NATIVE_CONTEXT_INDEX); | 547 Int32Constant(Context::NATIVE_CONTEXT_INDEX)); |
| 566 } | 548 } |
| 567 | 549 |
| 568 Node* CodeStubAssembler::LoadJSArrayElementsMap(ElementsKind kind, | 550 Node* CodeStubAssembler::LoadJSArrayElementsMap(ElementsKind kind, |
| 569 Node* native_context) { | 551 Node* native_context) { |
| 570 return LoadFixedArrayElementConstantIndex(native_context, | 552 return LoadFixedArrayElement(native_context, |
| 571 Context::ArrayMapIndex(kind)); | 553 Int32Constant(Context::ArrayMapIndex(kind))); |
| 572 } | 554 } |
| 573 | 555 |
| 574 Node* CodeStubAssembler::StoreHeapNumberValue(Node* object, Node* value) { | 556 Node* CodeStubAssembler::StoreHeapNumberValue(Node* object, Node* value) { |
| 575 return StoreNoWriteBarrier( | 557 return StoreNoWriteBarrier( |
| 576 MachineRepresentation::kFloat64, object, | 558 MachineRepresentation::kFloat64, object, |
| 577 IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag), value); | 559 IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag), value); |
| 578 } | 560 } |
| 579 | 561 |
| 580 Node* CodeStubAssembler::StoreObjectField( | 562 Node* CodeStubAssembler::StoreObjectField( |
| 581 Node* object, int offset, Node* value) { | 563 Node* object, int offset, Node* value) { |
| 582 return Store(MachineRepresentation::kTagged, object, | 564 return Store(MachineRepresentation::kTagged, object, |
| 583 IntPtrConstant(offset - kHeapObjectTag), value); | 565 IntPtrConstant(offset - kHeapObjectTag), value); |
| 584 } | 566 } |
| 585 | 567 |
| 586 Node* CodeStubAssembler::StoreObjectFieldNoWriteBarrier( | 568 Node* CodeStubAssembler::StoreObjectFieldNoWriteBarrier( |
| 587 Node* object, int offset, Node* value, MachineRepresentation rep) { | 569 Node* object, int offset, Node* value, MachineRepresentation rep) { |
| 588 return StoreNoWriteBarrier(rep, object, | 570 return StoreNoWriteBarrier(rep, object, |
| 589 IntPtrConstant(offset - kHeapObjectTag), value); | 571 IntPtrConstant(offset - kHeapObjectTag), value); |
| 590 } | 572 } |
| 591 | 573 |
| 592 Node* CodeStubAssembler::StoreMapNoWriteBarrier(Node* object, Node* map) { | 574 Node* CodeStubAssembler::StoreMapNoWriteBarrier(Node* object, Node* map) { |
| 593 return StoreNoWriteBarrier( | 575 return StoreNoWriteBarrier( |
| 594 MachineRepresentation::kTagged, object, | 576 MachineRepresentation::kTagged, object, |
| 595 IntPtrConstant(HeapNumber::kMapOffset - kHeapObjectTag), map); | 577 IntPtrConstant(HeapNumber::kMapOffset - kHeapObjectTag), map); |
| 596 } | 578 } |
| 597 | 579 |
| 598 Node* CodeStubAssembler::StoreFixedArrayElementNoWriteBarrier(Node* object, | 580 Node* CodeStubAssembler::StoreFixedArrayElement(Node* object, Node* index_node, |
| 599 Node* index, | 581 Node* value, |
| 600 Node* value) { | 582 WriteBarrierMode barrier_mode, |
| 601 index = ChangeInt32ToIntPtr(index); | 583 ParameterMode parameter_mode) { |
| 584 DCHECK(barrier_mode == SKIP_WRITE_BARRIER || |
| 585 barrier_mode == UPDATE_WRITE_BARRIER); |
| 602 Node* offset = | 586 Node* offset = |
| 603 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)), | 587 ElementOffsetFromIndex(index_node, FAST_HOLEY_ELEMENTS, parameter_mode, |
| 604 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); | 588 FixedArray::kHeaderSize - kHeapObjectTag); |
| 605 return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset, | 589 MachineRepresentation rep = MachineRepresentation::kTagged; |
| 606 value); | 590 if (barrier_mode == SKIP_WRITE_BARRIER) { |
| 591 return StoreNoWriteBarrier(rep, object, offset, value); |
| 592 } else { |
| 593 return Store(rep, object, offset, value); |
| 594 } |
| 607 } | 595 } |
| 608 | 596 |
| 609 Node* CodeStubAssembler::StoreFixedArrayElementInt32Index(Node* object, | 597 Node* CodeStubAssembler::StoreFixedDoubleArrayElement( |
| 610 Node* index, | 598 Node* object, Node* index_node, Node* value, ParameterMode parameter_mode) { |
| 611 Node* value) { | |
| 612 index = ChangeInt32ToIntPtr(index); | |
| 613 Node* offset = | 599 Node* offset = |
| 614 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)), | 600 ElementOffsetFromIndex(index_node, FAST_DOUBLE_ELEMENTS, parameter_mode, |
| 615 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); | 601 FixedArray::kHeaderSize - kHeapObjectTag); |
| 616 return Store(MachineRepresentation::kTagged, object, offset, value); | 602 MachineRepresentation rep = MachineRepresentation::kFloat64; |
| 617 } | 603 return StoreNoWriteBarrier(rep, object, offset, value); |
| 618 | |
| 619 Node* CodeStubAssembler::StoreFixedDoubleArrayElementInt32Index(Node* object, | |
| 620 Node* index, | |
| 621 Node* value) { | |
| 622 index = ChangeInt32ToIntPtr(index); | |
| 623 Node* offset = | |
| 624 IntPtrAdd(WordShl(index, IntPtrConstant(kPointerSizeLog2)), | |
| 625 IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag)); | |
| 626 return StoreNoWriteBarrier(MachineRepresentation::kFloat64, object, offset, | |
| 627 value); | |
| 628 } | |
| 629 | |
| 630 Node* CodeStubAssembler::StoreFixedArrayElementInt32Index(Node* object, | |
| 631 int index, | |
| 632 Node* value) { | |
| 633 Node* offset = IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag + | |
| 634 index * kPointerSize); | |
| 635 return Store(MachineRepresentation::kTagged, object, offset, value); | |
| 636 } | |
| 637 | |
| 638 Node* CodeStubAssembler::StoreFixedArrayElementNoWriteBarrier(Node* object, | |
| 639 int index, | |
| 640 Node* value) { | |
| 641 Node* offset = IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag + | |
| 642 index * kPointerSize); | |
| 643 return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset, | |
| 644 value); | |
| 645 } | |
| 646 | |
| 647 Node* CodeStubAssembler::StoreFixedDoubleArrayElementInt32Index(Node* object, | |
| 648 int index, | |
| 649 Node* value) { | |
| 650 Node* offset = IntPtrConstant(FixedDoubleArray::kHeaderSize - kHeapObjectTag + | |
| 651 index * kDoubleSize); | |
| 652 return StoreNoWriteBarrier(MachineRepresentation::kFloat64, object, offset, | |
| 653 value); | |
| 654 } | 604 } |
| 655 | 605 |
| 656 Node* CodeStubAssembler::AllocateHeapNumber() { | 606 Node* CodeStubAssembler::AllocateHeapNumber() { |
| 657 Node* result = Allocate(HeapNumber::kSize, kNone); | 607 Node* result = Allocate(HeapNumber::kSize, kNone); |
| 658 StoreMapNoWriteBarrier(result, HeapNumberMapConstant()); | 608 StoreMapNoWriteBarrier(result, HeapNumberMapConstant()); |
| 659 return result; | 609 return result; |
| 660 } | 610 } |
| 661 | 611 |
| 662 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value) { | 612 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value) { |
| 663 Node* result = AllocateHeapNumber(); | 613 Node* result = AllocateHeapNumber(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 679 Node* result = Allocate(SeqTwoByteString::SizeFor(length)); | 629 Node* result = Allocate(SeqTwoByteString::SizeFor(length)); |
| 680 StoreMapNoWriteBarrier(result, LoadRoot(Heap::kStringMapRootIndex)); | 630 StoreMapNoWriteBarrier(result, LoadRoot(Heap::kStringMapRootIndex)); |
| 681 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset, | 631 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset, |
| 682 SmiConstant(Smi::FromInt(length))); | 632 SmiConstant(Smi::FromInt(length))); |
| 683 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot, | 633 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot, |
| 684 IntPtrConstant(String::kEmptyHashField)); | 634 IntPtrConstant(String::kEmptyHashField)); |
| 685 return result; | 635 return result; |
| 686 } | 636 } |
| 687 | 637 |
| 688 Node* CodeStubAssembler::AllocateJSArray(ElementsKind kind, Node* array_map, | 638 Node* CodeStubAssembler::AllocateJSArray(ElementsKind kind, Node* array_map, |
| 689 int capacity, int length, | 639 Node* capacity_node, Node* length_node, |
| 690 compiler::Node* allocation_site) { | 640 compiler::Node* allocation_site, |
| 641 ParameterMode mode) { |
| 691 bool is_double = IsFastDoubleElementsKind(kind); | 642 bool is_double = IsFastDoubleElementsKind(kind); |
| 692 int element_size = is_double ? kDoubleSize : kPointerSize; | 643 int base_size = JSArray::kSize + FixedArray::kHeaderSize; |
| 693 int total_size = | |
| 694 JSArray::kSize + FixedArray::kHeaderSize + element_size * capacity; | |
| 695 int elements_offset = JSArray::kSize; | 644 int elements_offset = JSArray::kSize; |
| 696 | 645 |
| 697 if (allocation_site != nullptr) { | 646 if (allocation_site != nullptr) { |
| 698 total_size += AllocationMemento::kSize; | 647 base_size += AllocationMemento::kSize; |
| 699 elements_offset += AllocationMemento::kSize; | 648 elements_offset += AllocationMemento::kSize; |
| 700 } | 649 } |
| 701 | 650 |
| 651 int32_t capacity; |
| 652 bool constant_capacity = ToInt32Constant(capacity_node, capacity); |
| 653 Node* total_size = |
| 654 ElementOffsetFromIndex(capacity_node, kind, mode, base_size); |
| 655 |
| 702 // Allocate both array and elements object, and initialize the JSArray. | 656 // Allocate both array and elements object, and initialize the JSArray. |
| 703 Heap* heap = isolate()->heap(); | 657 Heap* heap = isolate()->heap(); |
| 704 Node* array = Allocate(total_size); | 658 Node* array = Allocate(total_size); |
| 705 StoreMapNoWriteBarrier(array, array_map); | 659 StoreMapNoWriteBarrier(array, array_map); |
| 706 Node* empty_properties = | 660 Node* empty_properties = |
| 707 HeapConstant(Handle<HeapObject>(heap->empty_fixed_array())); | 661 HeapConstant(Handle<HeapObject>(heap->empty_fixed_array())); |
| 708 StoreObjectFieldNoWriteBarrier(array, JSArray::kPropertiesOffset, | 662 StoreObjectFieldNoWriteBarrier(array, JSArray::kPropertiesOffset, |
| 709 empty_properties); | 663 empty_properties); |
| 710 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, | 664 StoreObjectFieldNoWriteBarrier( |
| 711 SmiConstant(Smi::FromInt(length))); | 665 array, JSArray::kLengthOffset, |
| 666 mode == SMI_PARAMETERS ? length_node : SmiTag(length_node)); |
| 712 | 667 |
| 713 if (allocation_site != nullptr) { | 668 if (allocation_site != nullptr) { |
| 714 InitializeAllocationMemento(array, JSArray::kSize, allocation_site); | 669 InitializeAllocationMemento(array, JSArray::kSize, allocation_site); |
| 715 } | 670 } |
| 716 | 671 |
| 717 // Setup elements object. | 672 // Setup elements object. |
| 718 Node* elements = InnerAllocate(array, elements_offset); | 673 Node* elements = InnerAllocate(array, elements_offset); |
| 719 StoreObjectFieldNoWriteBarrier(array, JSArray::kElementsOffset, elements); | 674 StoreObjectFieldNoWriteBarrier(array, JSArray::kElementsOffset, elements); |
| 720 Handle<Map> elements_map(is_double ? heap->fixed_double_array_map() | 675 Handle<Map> elements_map(is_double ? heap->fixed_double_array_map() |
| 721 : heap->fixed_array_map()); | 676 : heap->fixed_array_map()); |
| 722 StoreMapNoWriteBarrier(elements, HeapConstant(elements_map)); | 677 StoreMapNoWriteBarrier(elements, HeapConstant(elements_map)); |
| 723 StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, | 678 StoreObjectFieldNoWriteBarrier( |
| 724 SmiConstant(Smi::FromInt(capacity))); | 679 elements, FixedArray::kLengthOffset, |
| 680 mode == SMI_PARAMETERS ? capacity_node : SmiTag(capacity_node)); |
| 725 | 681 |
| 726 Node* double_hole = Float64Constant(bit_cast<double>(kHoleNanInt64)); | 682 int const first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag; |
| 727 Node* hole = HeapConstant(Handle<HeapObject>(heap->the_hole_value())); | 683 Node* hole = HeapConstant(Handle<HeapObject>(heap->the_hole_value())); |
| 728 if (capacity <= kElementLoopUnrollThreshold) { | 684 Node* double_hole = |
| 685 Is64() ? Int64Constant(kHoleNanInt64) : Int32Constant(kHoleNanLower32); |
| 686 DCHECK_EQ(kHoleNanLower32, kHoleNanUpper32); |
| 687 if (constant_capacity && capacity <= kElementLoopUnrollThreshold) { |
| 729 for (int i = 0; i < capacity; ++i) { | 688 for (int i = 0; i < capacity; ++i) { |
| 730 if (is_double) { | 689 if (is_double) { |
| 731 StoreFixedDoubleArrayElementInt32Index(elements, i, double_hole); | 690 Node* offset = ElementOffsetFromIndex(Int32Constant(i), kind, mode, |
| 691 first_element_offset); |
| 692 // Don't use doubles to store the hole double, since manipulating the |
| 693 // signaling NaN used for the hole in C++, e.g. with bit_cast, will |
| 694 // change its value on ia32 (the x87 stack is used to return values |
| 695 // and stores to the stack silently clear the signalling bit). |
| 696 // |
| 697 // TODO(danno): When we have a Float32/Float64 wrapper class that |
| 698 // preserves double bits during manipulation, remove this code/change |
| 699 // this to an indexed Float64 store. |
| 700 if (Is64()) { |
| 701 StoreNoWriteBarrier(MachineRepresentation::kWord64, elements, offset, |
| 702 double_hole); |
| 703 } else { |
| 704 StoreNoWriteBarrier(MachineRepresentation::kWord32, elements, offset, |
| 705 double_hole); |
| 706 offset = ElementOffsetFromIndex(Int32Constant(i), kind, mode, |
| 707 first_element_offset + kPointerSize); |
| 708 StoreNoWriteBarrier(MachineRepresentation::kWord32, elements, offset, |
| 709 double_hole); |
| 710 } |
| 732 } else { | 711 } else { |
| 733 StoreFixedArrayElementNoWriteBarrier(elements, i, hole); | 712 StoreFixedArrayElement(elements, Int32Constant(i), hole, |
| 713 SKIP_WRITE_BARRIER); |
| 734 } | 714 } |
| 735 } | 715 } |
| 736 } else { | 716 } else { |
| 737 // TODO(danno): Add a loop for initialization | 717 // TODO(danno): Add a loop for initialization |
| 738 UNIMPLEMENTED(); | 718 UNIMPLEMENTED(); |
| 739 } | 719 } |
| 740 | 720 |
| 741 return array; | 721 return array; |
| 742 } | 722 } |
| 743 | 723 |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1224 &if_codeisonebyte, &if_codeistwobyte); | 1204 &if_codeisonebyte, &if_codeistwobyte); |
| 1225 Bind(&if_codeisonebyte); | 1205 Bind(&if_codeisonebyte); |
| 1226 { | 1206 { |
| 1227 // Load the isolate wide single character string cache. | 1207 // Load the isolate wide single character string cache. |
| 1228 Node* cache = LoadRoot(Heap::kSingleCharacterStringCacheRootIndex); | 1208 Node* cache = LoadRoot(Heap::kSingleCharacterStringCacheRootIndex); |
| 1229 | 1209 |
| 1230 // Check if we have an entry for the {code} in the single character string | 1210 // Check if we have an entry for the {code} in the single character string |
| 1231 // cache already. | 1211 // cache already. |
| 1232 Label if_entryisundefined(this, Label::kDeferred), | 1212 Label if_entryisundefined(this, Label::kDeferred), |
| 1233 if_entryisnotundefined(this); | 1213 if_entryisnotundefined(this); |
| 1234 Node* entry = LoadFixedArrayElementInt32Index(cache, code); | 1214 Node* entry = LoadFixedArrayElement(cache, code); |
| 1235 Branch(WordEqual(entry, UndefinedConstant()), &if_entryisundefined, | 1215 Branch(WordEqual(entry, UndefinedConstant()), &if_entryisundefined, |
| 1236 &if_entryisnotundefined); | 1216 &if_entryisnotundefined); |
| 1237 | 1217 |
| 1238 Bind(&if_entryisundefined); | 1218 Bind(&if_entryisundefined); |
| 1239 { | 1219 { |
| 1240 // Allocate a new SeqOneByteString for {code} and store it in the {cache}. | 1220 // Allocate a new SeqOneByteString for {code} and store it in the {cache}. |
| 1241 Node* result = AllocateSeqOneByteString(1); | 1221 Node* result = AllocateSeqOneByteString(1); |
| 1242 StoreNoWriteBarrier( | 1222 StoreNoWriteBarrier( |
| 1243 MachineRepresentation::kWord8, result, | 1223 MachineRepresentation::kWord8, result, |
| 1244 IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag), code); | 1224 IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag), code); |
| 1245 StoreFixedArrayElementInt32Index(cache, code, result); | 1225 StoreFixedArrayElement(cache, code, result); |
| 1246 var_result.Bind(result); | 1226 var_result.Bind(result); |
| 1247 Goto(&if_done); | 1227 Goto(&if_done); |
| 1248 } | 1228 } |
| 1249 | 1229 |
| 1250 Bind(&if_entryisnotundefined); | 1230 Bind(&if_entryisnotundefined); |
| 1251 { | 1231 { |
| 1252 // Return the entry from the {cache}. | 1232 // Return the entry from the {cache}. |
| 1253 var_result.Bind(entry); | 1233 var_result.Bind(entry); |
| 1254 Goto(&if_done); | 1234 Goto(&if_done); |
| 1255 } | 1235 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1362 Bind(&loop); | 1342 Bind(&loop); |
| 1363 { | 1343 { |
| 1364 Node* index = var_descriptor.value(); | 1344 Node* index = var_descriptor.value(); |
| 1365 Node* offset = Int32Constant(DescriptorArray::ToKeyIndex(0)); | 1345 Node* offset = Int32Constant(DescriptorArray::ToKeyIndex(0)); |
| 1366 Node* factor = Int32Constant(DescriptorArray::kDescriptorSize); | 1346 Node* factor = Int32Constant(DescriptorArray::kDescriptorSize); |
| 1367 Label if_notdone(this); | 1347 Label if_notdone(this); |
| 1368 Branch(Word32Equal(index, nof), if_not_found, &if_notdone); | 1348 Branch(Word32Equal(index, nof), if_not_found, &if_notdone); |
| 1369 Bind(&if_notdone); | 1349 Bind(&if_notdone); |
| 1370 { | 1350 { |
| 1371 Node* array_index = Int32Add(offset, Int32Mul(index, factor)); | 1351 Node* array_index = Int32Add(offset, Int32Mul(index, factor)); |
| 1372 Node* current = LoadFixedArrayElementInt32Index(descriptors, array_index); | 1352 Node* current = LoadFixedArrayElement(descriptors, array_index); |
| 1373 Label if_unequal(this); | 1353 Label if_unequal(this); |
| 1374 Branch(WordEqual(current, name), if_found, &if_unequal); | 1354 Branch(WordEqual(current, name), if_found, &if_unequal); |
| 1375 Bind(&if_unequal); | 1355 Bind(&if_unequal); |
| 1376 | 1356 |
| 1377 var_descriptor.Bind(Int32Add(index, Int32Constant(1))); | 1357 var_descriptor.Bind(Int32Add(index, Int32Constant(1))); |
| 1378 Goto(&loop); | 1358 Goto(&loop); |
| 1379 } | 1359 } |
| 1380 } | 1360 } |
| 1381 } | 1361 } |
| 1382 | 1362 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1403 Bind(&if_isobjectorsmi); | 1383 Bind(&if_isobjectorsmi); |
| 1404 { | 1384 { |
| 1405 Node* elements = LoadElements(object); | 1385 Node* elements = LoadElements(object); |
| 1406 Node* length = LoadFixedArrayBaseLength(elements); | 1386 Node* length = LoadFixedArrayBaseLength(elements); |
| 1407 | 1387 |
| 1408 Label if_iskeyinrange(this); | 1388 Label if_iskeyinrange(this); |
| 1409 Branch(Int32LessThan(index, SmiToWord32(length)), &if_iskeyinrange, | 1389 Branch(Int32LessThan(index, SmiToWord32(length)), &if_iskeyinrange, |
| 1410 if_not_found); | 1390 if_not_found); |
| 1411 | 1391 |
| 1412 Bind(&if_iskeyinrange); | 1392 Bind(&if_iskeyinrange); |
| 1413 Node* element = LoadFixedArrayElementInt32Index(elements, index); | 1393 Node* element = LoadFixedArrayElement(elements, index); |
| 1414 Node* the_hole = LoadRoot(Heap::kTheHoleValueRootIndex); | 1394 Node* the_hole = LoadRoot(Heap::kTheHoleValueRootIndex); |
| 1415 Branch(WordEqual(element, the_hole), if_not_found, if_found); | 1395 Branch(WordEqual(element, the_hole), if_not_found, if_found); |
| 1416 } | 1396 } |
| 1417 } | 1397 } |
| 1418 | 1398 |
| 1419 Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, | 1399 Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, |
| 1420 Node* object) { | 1400 Node* object) { |
| 1421 Variable var_result(this, MachineRepresentation::kTagged); | 1401 Variable var_result(this, MachineRepresentation::kTagged); |
| 1422 Label return_false(this), return_true(this), | 1402 Label return_false(this), return_true(this), |
| 1423 return_runtime(this, Label::kDeferred), return_result(this); | 1403 return_runtime(this, Label::kDeferred), return_result(this); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1545 // Fallback to the runtime implementation. | 1525 // Fallback to the runtime implementation. |
| 1546 var_result.Bind( | 1526 var_result.Bind( |
| 1547 CallRuntime(Runtime::kOrdinaryHasInstance, context, callable, object)); | 1527 CallRuntime(Runtime::kOrdinaryHasInstance, context, callable, object)); |
| 1548 } | 1528 } |
| 1549 Goto(&return_result); | 1529 Goto(&return_result); |
| 1550 | 1530 |
| 1551 Bind(&return_result); | 1531 Bind(&return_result); |
| 1552 return var_result.value(); | 1532 return var_result.value(); |
| 1553 } | 1533 } |
| 1554 | 1534 |
| 1535 compiler::Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node, |
| 1536 ElementsKind kind, |
| 1537 ParameterMode mode, |
| 1538 int base_size) { |
| 1539 bool is_double = IsFastDoubleElementsKind(kind); |
| 1540 int element_size_shift = is_double ? kDoubleSizeLog2 : kPointerSizeLog2; |
| 1541 int element_size = 1 << element_size_shift; |
| 1542 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; |
| 1543 int32_t index = 0; |
| 1544 bool constant_index = false; |
| 1545 if (mode == SMI_PARAMETERS) { |
| 1546 element_size_shift -= kSmiShiftBits; |
| 1547 intptr_t temp = 0; |
| 1548 constant_index = ToIntPtrConstant(index_node, temp); |
| 1549 index = temp >> kSmiShiftBits; |
| 1550 } else { |
| 1551 constant_index = ToInt32Constant(index_node, index); |
| 1552 } |
| 1553 if (constant_index) { |
| 1554 return IntPtrConstant(base_size + element_size * index); |
| 1555 } |
| 1556 if (Is64() && mode == INTEGER_PARAMETERS) { |
| 1557 index_node = ChangeInt32ToInt64(index_node); |
| 1558 } |
| 1559 if (base_size == 0) { |
| 1560 return (element_size_shift >= 0) |
| 1561 ? WordShl(index_node, IntPtrConstant(element_size_shift)) |
| 1562 : WordShr(index_node, IntPtrConstant(-element_size_shift)); |
| 1563 } |
| 1564 return IntPtrAdd( |
| 1565 IntPtrConstant(base_size), |
| 1566 (element_size_shift >= 0) |
| 1567 ? WordShl(index_node, IntPtrConstant(element_size_shift)) |
| 1568 : WordShr(index_node, IntPtrConstant(-element_size_shift))); |
| 1569 } |
| 1570 |
| 1555 } // namespace internal | 1571 } // namespace internal |
| 1556 } // namespace v8 | 1572 } // namespace v8 |
| OLD | NEW |