Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/code-stub-assembler.cc

Issue 2549773002: Internalize strings in-place (Closed)
Patch Set: forgot one Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include "src/code-stub-assembler.h" 4 #include "src/code-stub-assembler.h"
5 #include "src/code-factory.h" 5 #include "src/code-factory.h"
6 #include "src/frames-inl.h" 6 #include "src/frames-inl.h"
7 #include "src/frames.h" 7 #include "src/frames.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 1565 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value, 1576 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value,
1577 MutableMode mode) { 1577 MutableMode mode) {
1578 Node* result = AllocateHeapNumber(mode); 1578 Node* result = AllocateHeapNumber(mode);
1579 StoreHeapNumberValue(result, value); 1579 StoreHeapNumberValue(result, value);
1580 return result; 1580 return result;
1581 } 1581 }
1582 1582
1583 Node* CodeStubAssembler::AllocateSeqOneByteString(int length, 1583 Node* CodeStubAssembler::AllocateSeqOneByteString(int length,
1584 AllocationFlags flags) { 1584 AllocationFlags flags) {
1585 Comment("AllocateSeqOneByteString"); 1585 Comment("AllocateSeqOneByteString");
1586 if (length == 0) {
1587 return LoadRoot(Heap::kempty_stringRootIndex);
1588 }
1586 Node* result = Allocate(SeqOneByteString::SizeFor(length), flags); 1589 Node* result = Allocate(SeqOneByteString::SizeFor(length), flags);
1587 DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex)); 1590 DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex));
1588 StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex); 1591 StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex);
1589 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset, 1592 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset,
1590 SmiConstant(Smi::FromInt(length))); 1593 SmiConstant(Smi::FromInt(length)));
1591 // Initialize both used and unused parts of hash field slot at once. 1594 // Initialize both used and unused parts of hash field slot at once.
1592 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot, 1595 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot,
1593 IntPtrConstant(String::kEmptyHashField), 1596 IntPtrConstant(String::kEmptyHashField),
1594 MachineType::PointerRepresentation()); 1597 MachineType::PointerRepresentation());
1595 return result; 1598 return result;
1596 } 1599 }
1597 1600
1598 Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length, 1601 Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length,
1599 ParameterMode mode, 1602 ParameterMode mode,
1600 AllocationFlags flags) { 1603 AllocationFlags flags) {
1601 Comment("AllocateSeqOneByteString"); 1604 Comment("AllocateSeqOneByteString");
1602 Variable var_result(this, MachineRepresentation::kTagged); 1605 Variable var_result(this, MachineRepresentation::kTagged);
1603 1606
1604 // Compute the SeqOneByteString size and check if it fits into new space. 1607 // Compute the SeqOneByteString size and check if it fits into new space.
1605 Label if_sizeissmall(this), if_notsizeissmall(this, Label::kDeferred), 1608 Label if_lengthiszero(this), if_sizeissmall(this),
1606 if_join(this); 1609 if_notsizeissmall(this, Label::kDeferred), if_join(this);
1610 GotoIf(WordEqual(length, IntPtrOrSmiConstant(0, mode)), &if_lengthiszero);
1611
1607 Node* raw_size = GetArrayAllocationSize( 1612 Node* raw_size = GetArrayAllocationSize(
1608 length, UINT8_ELEMENTS, mode, 1613 length, UINT8_ELEMENTS, mode,
1609 SeqOneByteString::kHeaderSize + kObjectAlignmentMask); 1614 SeqOneByteString::kHeaderSize + kObjectAlignmentMask);
1610 Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); 1615 Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask));
1611 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), 1616 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)),
1612 &if_sizeissmall, &if_notsizeissmall); 1617 &if_sizeissmall, &if_notsizeissmall);
1613 1618
1614 Bind(&if_sizeissmall); 1619 Bind(&if_sizeissmall);
1615 { 1620 {
1616 // Just allocate the SeqOneByteString in new space. 1621 // Just allocate the SeqOneByteString in new space.
(...skipping 12 matching lines...) Expand all
1629 1634
1630 Bind(&if_notsizeissmall); 1635 Bind(&if_notsizeissmall);
1631 { 1636 {
1632 // We might need to allocate in large object space, go to the runtime. 1637 // We might need to allocate in large object space, go to the runtime.
1633 Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context, 1638 Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context,
1634 ParameterToTagged(length, mode)); 1639 ParameterToTagged(length, mode));
1635 var_result.Bind(result); 1640 var_result.Bind(result);
1636 Goto(&if_join); 1641 Goto(&if_join);
1637 } 1642 }
1638 1643
1644 Bind(&if_lengthiszero);
1645 {
1646 var_result.Bind(LoadRoot(Heap::kempty_stringRootIndex));
1647 Goto(&if_join);
1648 }
1649
1639 Bind(&if_join); 1650 Bind(&if_join);
1640 return var_result.value(); 1651 return var_result.value();
1641 } 1652 }
1642 1653
1643 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length, 1654 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length,
1644 AllocationFlags flags) { 1655 AllocationFlags flags) {
1645 Comment("AllocateSeqTwoByteString"); 1656 Comment("AllocateSeqTwoByteString");
1657 if (length == 0) {
1658 return LoadRoot(Heap::kempty_stringRootIndex);
1659 }
1646 Node* result = Allocate(SeqTwoByteString::SizeFor(length), flags); 1660 Node* result = Allocate(SeqTwoByteString::SizeFor(length), flags);
1647 DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex)); 1661 DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex));
1648 StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex); 1662 StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex);
1649 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset, 1663 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset,
1650 SmiConstant(Smi::FromInt(length))); 1664 SmiConstant(Smi::FromInt(length)));
1651 // Initialize both used and unused parts of hash field slot at once. 1665 // Initialize both used and unused parts of hash field slot at once.
1652 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot, 1666 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot,
1653 IntPtrConstant(String::kEmptyHashField), 1667 IntPtrConstant(String::kEmptyHashField),
1654 MachineType::PointerRepresentation()); 1668 MachineType::PointerRepresentation());
1655 return result; 1669 return result;
1656 } 1670 }
1657 1671
1658 Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length, 1672 Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length,
1659 ParameterMode mode, 1673 ParameterMode mode,
1660 AllocationFlags flags) { 1674 AllocationFlags flags) {
1661 Comment("AllocateSeqTwoByteString"); 1675 Comment("AllocateSeqTwoByteString");
1662 Variable var_result(this, MachineRepresentation::kTagged); 1676 Variable var_result(this, MachineRepresentation::kTagged);
1663 1677
1664 // Compute the SeqTwoByteString size and check if it fits into new space. 1678 // Compute the SeqTwoByteString size and check if it fits into new space.
1665 Label if_sizeissmall(this), if_notsizeissmall(this, Label::kDeferred), 1679 Label if_lengthiszero(this), if_sizeissmall(this),
1666 if_join(this); 1680 if_notsizeissmall(this, Label::kDeferred), if_join(this);
1681 GotoIf(WordEqual(length, IntPtrOrSmiConstant(0, mode)), &if_lengthiszero);
1682
1667 Node* raw_size = GetArrayAllocationSize( 1683 Node* raw_size = GetArrayAllocationSize(
1668 length, UINT16_ELEMENTS, mode, 1684 length, UINT16_ELEMENTS, mode,
1669 SeqOneByteString::kHeaderSize + kObjectAlignmentMask); 1685 SeqOneByteString::kHeaderSize + kObjectAlignmentMask);
1670 Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); 1686 Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask));
1671 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), 1687 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)),
1672 &if_sizeissmall, &if_notsizeissmall); 1688 &if_sizeissmall, &if_notsizeissmall);
1673 1689
1674 Bind(&if_sizeissmall); 1690 Bind(&if_sizeissmall);
1675 { 1691 {
1676 // Just allocate the SeqTwoByteString in new space. 1692 // Just allocate the SeqTwoByteString in new space.
(...skipping 14 matching lines...) Expand all
1691 Bind(&if_notsizeissmall); 1707 Bind(&if_notsizeissmall);
1692 { 1708 {
1693 // We might need to allocate in large object space, go to the runtime. 1709 // We might need to allocate in large object space, go to the runtime.
1694 Node* result = 1710 Node* result =
1695 CallRuntime(Runtime::kAllocateSeqTwoByteString, context, 1711 CallRuntime(Runtime::kAllocateSeqTwoByteString, context,
1696 mode == SMI_PARAMETERS ? length : SmiFromWord(length)); 1712 mode == SMI_PARAMETERS ? length : SmiFromWord(length));
1697 var_result.Bind(result); 1713 var_result.Bind(result);
1698 Goto(&if_join); 1714 Goto(&if_join);
1699 } 1715 }
1700 1716
1717 Bind(&if_lengthiszero);
1718 {
1719 var_result.Bind(LoadRoot(Heap::kempty_stringRootIndex));
1720 Goto(&if_join);
1721 }
1722
1701 Bind(&if_join); 1723 Bind(&if_join);
1702 return var_result.value(); 1724 return var_result.value();
1703 } 1725 }
1704 1726
1705 Node* CodeStubAssembler::AllocateSlicedString( 1727 Node* CodeStubAssembler::AllocateSlicedString(
1706 Heap::RootListIndex map_root_index, Node* length, Node* parent, 1728 Heap::RootListIndex map_root_index, Node* length, Node* parent,
1707 Node* offset) { 1729 Node* offset) {
1708 CSA_ASSERT(this, TaggedIsSmi(length)); 1730 CSA_ASSERT(this, TaggedIsSmi(length));
1709 Node* result = Allocate(SlicedString::kSize); 1731 Node* result = Allocate(SlicedString::kSize);
1710 DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); 1732 DCHECK(Heap::RootIsImmortalImmovable(map_root_index));
(...skipping 1431 matching lines...) Expand 10 before | Expand all | Expand 10 after
3142 // The {string} might be compressed, call the runtime. 3164 // The {string} might be compressed, call the runtime.
3143 var_result.Bind(SmiToWord32( 3165 var_result.Bind(SmiToWord32(
3144 CallRuntime(Runtime::kExternalStringGetChar, 3166 CallRuntime(Runtime::kExternalStringGetChar,
3145 NoContextConstant(), string, SmiTag(index)))); 3167 NoContextConstant(), string, SmiTag(index))));
3146 Goto(&done_loop); 3168 Goto(&done_loop);
3147 } 3169 }
3148 } 3170 }
3149 3171
3150 Bind(&if_stringisnotexternal); 3172 Bind(&if_stringisnotexternal);
3151 { 3173 {
3152 // The {string} is a SlicedString, continue with its parent. 3174 Label if_stringissliced(this), if_stringisthin(this);
3153 Node* string_offset = 3175 Branch(
3154 LoadAndUntagObjectField(string, SlicedString::kOffsetOffset); 3176 Word32Equal(Word32And(string_instance_type,
3155 Node* string_parent = 3177 Int32Constant(kStringRepresentationMask)),
3156 LoadObjectField(string, SlicedString::kParentOffset); 3178 Int32Constant(kSlicedStringTag)),
3157 var_index.Bind(IntPtrAdd(index, string_offset)); 3179 &if_stringissliced, &if_stringisthin);
3158 var_string.Bind(string_parent); 3180 Bind(&if_stringissliced);
3159 Goto(&loop); 3181 {
3182 // The {string} is a SlicedString, continue with its parent.
3183 Node* string_offset =
3184 LoadAndUntagObjectField(string, SlicedString::kOffsetOffset);
3185 Node* string_parent =
3186 LoadObjectField(string, SlicedString::kParentOffset);
3187 var_index.Bind(IntPtrAdd(index, string_offset));
3188 var_string.Bind(string_parent);
3189 Goto(&loop);
3190 }
3191 Bind(&if_stringisthin);
3192 {
3193 // The {string} is a ThinString, continue with its actual value.
3194 var_string.Bind(LoadObjectField(string, ThinString::kActualOffset));
3195 Goto(&loop);
3196 }
3160 } 3197 }
3161 } 3198 }
3162 } 3199 }
3163 } 3200 }
3164 3201
3165 Bind(&done_loop); 3202 Bind(&done_loop);
3166 return var_result.value(); 3203 return var_result.value();
3167 } 3204 }
3168 3205
3169 Node* CodeStubAssembler::StringFromCharCode(Node* code) { 3206 Node* CodeStubAssembler::StringFromCharCode(Node* code) {
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
3325 3362
3326 Label single_char(this); 3363 Label single_char(this);
3327 GotoIf(SmiEqual(substr_length, SmiConstant(Smi::FromInt(1))), &single_char); 3364 GotoIf(SmiEqual(substr_length, SmiConstant(Smi::FromInt(1))), &single_char);
3328 3365
3329 // TODO(jgruber): Add an additional case for substring of length == 0? 3366 // TODO(jgruber): Add an additional case for substring of length == 0?
3330 3367
3331 // Deal with different string types: update the index if necessary 3368 // Deal with different string types: update the index if necessary
3332 // and put the underlying string into var_string. 3369 // and put the underlying string into var_string.
3333 3370
3334 // If the string is not indirect, it can only be sequential or external. 3371 // If the string is not indirect, it can only be sequential or external.
3335 STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag)); 3372 STATIC_ASSERT(kIsIndirectStringMask ==
3373 (kSlicedStringTag & kConsStringTag & kThinStringTag));
3336 STATIC_ASSERT(kIsIndirectStringMask != 0); 3374 STATIC_ASSERT(kIsIndirectStringMask != 0);
3337 Label underlying_unpacked(this); 3375 Label underlying_unpacked(this);
3338 GotoIf(Word32Equal( 3376 GotoIf(Word32Equal(
3339 Word32And(instance_type, Int32Constant(kIsIndirectStringMask)), 3377 Word32And(instance_type, Int32Constant(kIsIndirectStringMask)),
3340 Int32Constant(0)), 3378 Int32Constant(0)),
3341 &underlying_unpacked); 3379 &underlying_unpacked);
3342 3380
3343 // The subject string is either a sliced or cons string. 3381 // The subject string is either a sliced or cons string.
Igor Sheludko 2016/12/20 23:46:58 or thin string.
Jakob Kummerow 2017/01/04 12:45:06 Done.
3344 3382
3345 Label sliced_string(this); 3383 Label sliced_string(this), thin_or_sliced(this);
3346 GotoIf(Word32NotEqual( 3384 GotoIf(Word32NotEqual(
3347 Word32And(instance_type, Int32Constant(kSlicedNotConsMask)), 3385 Word32And(instance_type, Int32Constant(kStringRepresentationMask)),
3348 Int32Constant(0)), 3386 Int32Constant(kConsStringTag)),
3349 &sliced_string); 3387 &thin_or_sliced);
3350 3388
3351 // Cons string. Check whether it is flat, then fetch first part. 3389 // Cons string. Check whether it is flat, then fetch first part.
3352 // Flat cons strings have an empty second part. 3390 // Flat cons strings have an empty second part.
3353 { 3391 {
3354 GotoIf(WordNotEqual(LoadObjectField(string, ConsString::kSecondOffset), 3392 GotoIf(WordNotEqual(LoadObjectField(string, ConsString::kSecondOffset),
3355 EmptyStringConstant()), 3393 EmptyStringConstant()),
3356 &runtime); 3394 &runtime);
3357 3395
3358 Node* first_string_part = LoadObjectField(string, ConsString::kFirstOffset); 3396 Node* first_string_part = LoadObjectField(string, ConsString::kFirstOffset);
3359 var_string.Bind(first_string_part); 3397 var_string.Bind(first_string_part);
3360 var_instance_type.Bind(LoadInstanceType(first_string_part)); 3398 var_instance_type.Bind(LoadInstanceType(first_string_part));
3361 3399
3362 Goto(&underlying_unpacked); 3400 Goto(&underlying_unpacked);
3363 } 3401 }
3364 3402
3403 Bind(&thin_or_sliced);
3404 {
3405 GotoIf(Word32Equal(Word32And(instance_type,
Igor Sheludko 2016/12/20 23:46:58 Maybe reuse the result of "Word32And(instance_type
Jakob Kummerow 2017/01/04 12:45:06 Done.
3406 Int32Constant(kStringRepresentationMask)),
3407 Int32Constant(kSlicedStringTag)),
3408 &sliced_string);
3409 Node* actual_string = LoadObjectField(string, ThinString::kActualOffset);
3410 var_string.Bind(actual_string);
3411 var_instance_type.Bind(LoadInstanceType(actual_string));
3412 Goto(&underlying_unpacked);
3413 }
3414
3365 Bind(&sliced_string); 3415 Bind(&sliced_string);
3366 { 3416 {
3367 // Fetch parent and correct start index by offset. 3417 // Fetch parent and correct start index by offset.
3368 Node* sliced_offset = LoadObjectField(string, SlicedString::kOffsetOffset); 3418 Node* sliced_offset = LoadObjectField(string, SlicedString::kOffsetOffset);
3369 var_from.Bind(SmiAdd(from, sliced_offset)); 3419 var_from.Bind(SmiAdd(from, sliced_offset));
3370 3420
3371 Node* slice_parent = LoadObjectField(string, SlicedString::kParentOffset); 3421 Node* slice_parent = LoadObjectField(string, SlicedString::kParentOffset);
3372 var_string.Bind(slice_parent); 3422 var_string.Bind(slice_parent);
3373 3423
3374 Node* slice_parent_instance_type = LoadInstanceType(slice_parent); 3424 Node* slice_parent_instance_type = LoadInstanceType(slice_parent);
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after
4311 variable.Bind( 4361 variable.Bind(
4312 IntPtrOrSmiAdd(variable.value(), IntPtrOrSmiConstant(value, mode), mode)); 4362 IntPtrOrSmiAdd(variable.value(), IntPtrOrSmiConstant(value, mode), mode));
4313 } 4363 }
4314 4364
4315 void CodeStubAssembler::Use(Label* label) { 4365 void CodeStubAssembler::Use(Label* label) {
4316 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); 4366 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label);
4317 } 4367 }
4318 4368
4319 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, 4369 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex,
4320 Variable* var_index, Label* if_keyisunique, 4370 Variable* var_index, Label* if_keyisunique,
4321 Label* if_bailout) { 4371 Variable* var_unique, Label* if_bailout) {
4322 DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep()); 4372 DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep());
4373 DCHECK_EQ(MachineRepresentation::kTagged, var_unique->rep());
4323 Comment("TryToName"); 4374 Comment("TryToName");
4324 4375
4325 Label if_hascachedindex(this), if_keyisnotindex(this); 4376 Label if_hascachedindex(this), if_keyisnotindex(this), if_thinstring(this);
4326 // Handle Smi and HeapNumber keys. 4377 // Handle Smi and HeapNumber keys.
4327 var_index->Bind(TryToIntptr(key, &if_keyisnotindex)); 4378 var_index->Bind(TryToIntptr(key, &if_keyisnotindex));
4328 Goto(if_keyisindex); 4379 Goto(if_keyisindex);
4329 4380
4330 Bind(&if_keyisnotindex); 4381 Bind(&if_keyisnotindex);
4331 Node* key_map = LoadMap(key); 4382 Node* key_map = LoadMap(key);
4383 var_unique->Bind(key);
4332 // Symbols are unique. 4384 // Symbols are unique.
4333 GotoIf(IsSymbolMap(key_map), if_keyisunique); 4385 GotoIf(IsSymbolMap(key_map), if_keyisunique);
4334 Node* key_instance_type = LoadMapInstanceType(key_map); 4386 Node* key_instance_type = LoadMapInstanceType(key_map);
4335 // Miss if |key| is not a String. 4387 // Miss if |key| is not a String.
4336 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); 4388 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
4337 GotoUnless(IsStringInstanceType(key_instance_type), if_bailout); 4389 GotoUnless(IsStringInstanceType(key_instance_type), if_bailout);
4338 // |key| is a String. Check if it has a cached array index. 4390 // |key| is a String. Check if it has a cached array index.
4339 Node* hash = LoadNameHashField(key); 4391 Node* hash = LoadNameHashField(key);
4340 Node* contains_index = 4392 Node* contains_index =
4341 Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask)); 4393 Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask));
4342 GotoIf(Word32Equal(contains_index, Int32Constant(0)), &if_hascachedindex); 4394 GotoIf(Word32Equal(contains_index, Int32Constant(0)), &if_hascachedindex);
4343 // No cached array index. If the string knows that it contains an index, 4395 // No cached array index. If the string knows that it contains an index,
4344 // then it must be an uncacheable index. Handle this case in the runtime. 4396 // then it must be an uncacheable index. Handle this case in the runtime.
4345 Node* not_an_index = 4397 Node* not_an_index =
4346 Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask)); 4398 Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask));
4347 GotoIf(Word32Equal(not_an_index, Int32Constant(0)), if_bailout); 4399 GotoIf(Word32Equal(not_an_index, Int32Constant(0)), if_bailout);
4400 // Check if we have a ThinString.
4401 GotoIf(Word32Equal(key_instance_type, Int32Constant(THIN_STRING_TYPE)),
4402 &if_thinstring);
4403 GotoIf(
4404 Word32Equal(key_instance_type, Int32Constant(THIN_ONE_BYTE_STRING_TYPE)),
4405 &if_thinstring);
4348 // Finally, check if |key| is internalized. 4406 // Finally, check if |key| is internalized.
4349 STATIC_ASSERT(kNotInternalizedTag != 0); 4407 STATIC_ASSERT(kNotInternalizedTag != 0);
4350 Node* not_internalized = 4408 Node* not_internalized =
4351 Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask)); 4409 Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask));
4352 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout); 4410 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout);
4353 Goto(if_keyisunique); 4411 Goto(if_keyisunique);
4354 4412
4413 Bind(&if_thinstring);
4414 var_unique->Bind(LoadObjectField(key, ThinString::kActualOffset));
4415 Goto(if_keyisunique);
4416
4355 Bind(&if_hascachedindex); 4417 Bind(&if_hascachedindex);
4356 var_index->Bind(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash)); 4418 var_index->Bind(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash));
4357 Goto(if_keyisindex); 4419 Goto(if_keyisindex);
4358 } 4420 }
4359 4421
4360 template <typename Dictionary> 4422 template <typename Dictionary>
4361 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { 4423 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) {
4362 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); 4424 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize));
4363 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + 4425 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex +
4364 field_index)); 4426 field_index));
(...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after
5194 Label if_objectisreceiver(this); 5256 Label if_objectisreceiver(this);
5195 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); 5257 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
5196 STATIC_ASSERT(FIRST_JS_RECEIVER_TYPE == JS_PROXY_TYPE); 5258 STATIC_ASSERT(FIRST_JS_RECEIVER_TYPE == JS_PROXY_TYPE);
5197 Branch( 5259 Branch(
5198 Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)), 5260 Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)),
5199 &if_objectisreceiver, if_bailout); 5261 &if_objectisreceiver, if_bailout);
5200 Bind(&if_objectisreceiver); 5262 Bind(&if_objectisreceiver);
5201 } 5263 }
5202 5264
5203 Variable var_index(this, MachineType::PointerRepresentation()); 5265 Variable var_index(this, MachineType::PointerRepresentation());
5266 Variable var_unique(this, MachineRepresentation::kTagged);
5204 5267
5205 Label if_keyisindex(this), if_iskeyunique(this); 5268 Label if_keyisindex(this), if_iskeyunique(this);
5206 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, if_bailout); 5269 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, &var_unique,
5270 if_bailout);
5207 5271
5208 Bind(&if_iskeyunique); 5272 Bind(&if_iskeyunique);
5209 { 5273 {
5210 Variable var_holder(this, MachineRepresentation::kTagged); 5274 Variable var_holder(this, MachineRepresentation::kTagged);
5211 Variable var_holder_map(this, MachineRepresentation::kTagged); 5275 Variable var_holder_map(this, MachineRepresentation::kTagged);
5212 Variable var_holder_instance_type(this, MachineRepresentation::kWord32); 5276 Variable var_holder_instance_type(this, MachineRepresentation::kWord32);
5213 5277
5214 Variable* merged_variables[] = {&var_holder, &var_holder_map, 5278 Variable* merged_variables[] = {&var_holder, &var_holder_map,
5215 &var_holder_instance_type}; 5279 &var_holder_instance_type};
5216 Label loop(this, arraysize(merged_variables), merged_variables); 5280 Label loop(this, arraysize(merged_variables), merged_variables);
5217 var_holder.Bind(receiver); 5281 var_holder.Bind(receiver);
5218 var_holder_map.Bind(map); 5282 var_holder_map.Bind(map);
5219 var_holder_instance_type.Bind(instance_type); 5283 var_holder_instance_type.Bind(instance_type);
5220 Goto(&loop); 5284 Goto(&loop);
5221 Bind(&loop); 5285 Bind(&loop);
5222 { 5286 {
5223 Node* holder_map = var_holder_map.value(); 5287 Node* holder_map = var_holder_map.value();
5224 Node* holder_instance_type = var_holder_instance_type.value(); 5288 Node* holder_instance_type = var_holder_instance_type.value();
5225 5289
5226 Label next_proto(this); 5290 Label next_proto(this);
5227 lookup_property_in_holder(receiver, var_holder.value(), holder_map, 5291 lookup_property_in_holder(receiver, var_holder.value(), holder_map,
5228 holder_instance_type, key, &next_proto, 5292 holder_instance_type, var_unique.value(),
5229 if_bailout); 5293 &next_proto, if_bailout);
5230 Bind(&next_proto); 5294 Bind(&next_proto);
5231 5295
5232 // Bailout if it can be an integer indexed exotic case. 5296 // Bailout if it can be an integer indexed exotic case.
5233 GotoIf( 5297 GotoIf(
5234 Word32Equal(holder_instance_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), 5298 Word32Equal(holder_instance_type, Int32Constant(JS_TYPED_ARRAY_TYPE)),
5235 if_bailout); 5299 if_bailout);
5236 5300
5237 Node* proto = LoadMapPrototype(holder_map); 5301 Node* proto = LoadMapPrototype(holder_map);
5238 5302
5239 Label if_not_null(this); 5303 Label if_not_null(this);
(...skipping 3053 matching lines...) Expand 10 before | Expand all | Expand 10 after
8293 Heap::kUndefinedValueRootIndex); 8357 Heap::kUndefinedValueRootIndex);
8294 StoreObjectFieldRoot(result, PromiseReactionJobInfo::kDebugNameOffset, 8358 StoreObjectFieldRoot(result, PromiseReactionJobInfo::kDebugNameOffset,
8295 Heap::kUndefinedValueRootIndex); 8359 Heap::kUndefinedValueRootIndex);
8296 StoreObjectFieldNoWriteBarrier(result, PromiseReactionJobInfo::kContextOffset, 8360 StoreObjectFieldNoWriteBarrier(result, PromiseReactionJobInfo::kContextOffset,
8297 context); 8361 context);
8298 return result; 8362 return result;
8299 } 8363 }
8300 8364
8301 } // namespace internal 8365 } // namespace internal
8302 } // namespace v8 8366 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698