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

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

Issue 2624203002: Version 5.7.440.1 (cherry-pick) (Closed)
Patch Set: Created 3 years, 11 months 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
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after
1558 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value, 1558 Node* CodeStubAssembler::AllocateHeapNumberWithValue(Node* value,
1559 MutableMode mode) { 1559 MutableMode mode) {
1560 Node* result = AllocateHeapNumber(mode); 1560 Node* result = AllocateHeapNumber(mode);
1561 StoreHeapNumberValue(result, value); 1561 StoreHeapNumberValue(result, value);
1562 return result; 1562 return result;
1563 } 1563 }
1564 1564
1565 Node* CodeStubAssembler::AllocateSeqOneByteString(int length, 1565 Node* CodeStubAssembler::AllocateSeqOneByteString(int length,
1566 AllocationFlags flags) { 1566 AllocationFlags flags) {
1567 Comment("AllocateSeqOneByteString"); 1567 Comment("AllocateSeqOneByteString");
1568 if (length == 0) {
1569 return LoadRoot(Heap::kempty_stringRootIndex);
1570 }
1571 Node* result = Allocate(SeqOneByteString::SizeFor(length), flags); 1568 Node* result = Allocate(SeqOneByteString::SizeFor(length), flags);
1572 DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex)); 1569 DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex));
1573 StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex); 1570 StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex);
1574 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset, 1571 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset,
1575 SmiConstant(Smi::FromInt(length))); 1572 SmiConstant(Smi::FromInt(length)));
1576 // Initialize both used and unused parts of hash field slot at once. 1573 // Initialize both used and unused parts of hash field slot at once.
1577 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot, 1574 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot,
1578 IntPtrConstant(String::kEmptyHashField), 1575 IntPtrConstant(String::kEmptyHashField),
1579 MachineType::PointerRepresentation()); 1576 MachineType::PointerRepresentation());
1580 return result; 1577 return result;
1581 } 1578 }
1582 1579
1583 Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length, 1580 Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length,
1584 ParameterMode mode, 1581 ParameterMode mode,
1585 AllocationFlags flags) { 1582 AllocationFlags flags) {
1586 Comment("AllocateSeqOneByteString"); 1583 Comment("AllocateSeqOneByteString");
1587 Variable var_result(this, MachineRepresentation::kTagged); 1584 Variable var_result(this, MachineRepresentation::kTagged);
1588 1585
1589 // Compute the SeqOneByteString size and check if it fits into new space. 1586 // Compute the SeqOneByteString size and check if it fits into new space.
1590 Label if_lengthiszero(this), if_sizeissmall(this), 1587 Label if_sizeissmall(this), if_notsizeissmall(this, Label::kDeferred),
1591 if_notsizeissmall(this, Label::kDeferred), if_join(this); 1588 if_join(this);
1592 GotoIf(WordEqual(length, IntPtrOrSmiConstant(0, mode)), &if_lengthiszero);
1593
1594 Node* raw_size = GetArrayAllocationSize( 1589 Node* raw_size = GetArrayAllocationSize(
1595 length, UINT8_ELEMENTS, mode, 1590 length, UINT8_ELEMENTS, mode,
1596 SeqOneByteString::kHeaderSize + kObjectAlignmentMask); 1591 SeqOneByteString::kHeaderSize + kObjectAlignmentMask);
1597 Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); 1592 Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask));
1598 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), 1593 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)),
1599 &if_sizeissmall, &if_notsizeissmall); 1594 &if_sizeissmall, &if_notsizeissmall);
1600 1595
1601 Bind(&if_sizeissmall); 1596 Bind(&if_sizeissmall);
1602 { 1597 {
1603 // Just allocate the SeqOneByteString in new space. 1598 // Just allocate the SeqOneByteString in new space.
(...skipping 12 matching lines...) Expand all
1616 1611
1617 Bind(&if_notsizeissmall); 1612 Bind(&if_notsizeissmall);
1618 { 1613 {
1619 // We might need to allocate in large object space, go to the runtime. 1614 // We might need to allocate in large object space, go to the runtime.
1620 Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context, 1615 Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context,
1621 ParameterToTagged(length, mode)); 1616 ParameterToTagged(length, mode));
1622 var_result.Bind(result); 1617 var_result.Bind(result);
1623 Goto(&if_join); 1618 Goto(&if_join);
1624 } 1619 }
1625 1620
1626 Bind(&if_lengthiszero);
1627 {
1628 var_result.Bind(LoadRoot(Heap::kempty_stringRootIndex));
1629 Goto(&if_join);
1630 }
1631
1632 Bind(&if_join); 1621 Bind(&if_join);
1633 return var_result.value(); 1622 return var_result.value();
1634 } 1623 }
1635 1624
1636 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length, 1625 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length,
1637 AllocationFlags flags) { 1626 AllocationFlags flags) {
1638 Comment("AllocateSeqTwoByteString"); 1627 Comment("AllocateSeqTwoByteString");
1639 if (length == 0) {
1640 return LoadRoot(Heap::kempty_stringRootIndex);
1641 }
1642 Node* result = Allocate(SeqTwoByteString::SizeFor(length), flags); 1628 Node* result = Allocate(SeqTwoByteString::SizeFor(length), flags);
1643 DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex)); 1629 DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex));
1644 StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex); 1630 StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex);
1645 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset, 1631 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset,
1646 SmiConstant(Smi::FromInt(length))); 1632 SmiConstant(Smi::FromInt(length)));
1647 // Initialize both used and unused parts of hash field slot at once. 1633 // Initialize both used and unused parts of hash field slot at once.
1648 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot, 1634 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot,
1649 IntPtrConstant(String::kEmptyHashField), 1635 IntPtrConstant(String::kEmptyHashField),
1650 MachineType::PointerRepresentation()); 1636 MachineType::PointerRepresentation());
1651 return result; 1637 return result;
1652 } 1638 }
1653 1639
1654 Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length, 1640 Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length,
1655 ParameterMode mode, 1641 ParameterMode mode,
1656 AllocationFlags flags) { 1642 AllocationFlags flags) {
1657 Comment("AllocateSeqTwoByteString"); 1643 Comment("AllocateSeqTwoByteString");
1658 Variable var_result(this, MachineRepresentation::kTagged); 1644 Variable var_result(this, MachineRepresentation::kTagged);
1659 1645
1660 // Compute the SeqTwoByteString size and check if it fits into new space. 1646 // Compute the SeqTwoByteString size and check if it fits into new space.
1661 Label if_lengthiszero(this), if_sizeissmall(this), 1647 Label if_sizeissmall(this), if_notsizeissmall(this, Label::kDeferred),
1662 if_notsizeissmall(this, Label::kDeferred), if_join(this); 1648 if_join(this);
1663 GotoIf(WordEqual(length, IntPtrOrSmiConstant(0, mode)), &if_lengthiszero);
1664
1665 Node* raw_size = GetArrayAllocationSize( 1649 Node* raw_size = GetArrayAllocationSize(
1666 length, UINT16_ELEMENTS, mode, 1650 length, UINT16_ELEMENTS, mode,
1667 SeqOneByteString::kHeaderSize + kObjectAlignmentMask); 1651 SeqOneByteString::kHeaderSize + kObjectAlignmentMask);
1668 Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); 1652 Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask));
1669 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), 1653 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)),
1670 &if_sizeissmall, &if_notsizeissmall); 1654 &if_sizeissmall, &if_notsizeissmall);
1671 1655
1672 Bind(&if_sizeissmall); 1656 Bind(&if_sizeissmall);
1673 { 1657 {
1674 // Just allocate the SeqTwoByteString in new space. 1658 // Just allocate the SeqTwoByteString in new space.
(...skipping 14 matching lines...) Expand all
1689 Bind(&if_notsizeissmall); 1673 Bind(&if_notsizeissmall);
1690 { 1674 {
1691 // We might need to allocate in large object space, go to the runtime. 1675 // We might need to allocate in large object space, go to the runtime.
1692 Node* result = 1676 Node* result =
1693 CallRuntime(Runtime::kAllocateSeqTwoByteString, context, 1677 CallRuntime(Runtime::kAllocateSeqTwoByteString, context,
1694 mode == SMI_PARAMETERS ? length : SmiFromWord(length)); 1678 mode == SMI_PARAMETERS ? length : SmiFromWord(length));
1695 var_result.Bind(result); 1679 var_result.Bind(result);
1696 Goto(&if_join); 1680 Goto(&if_join);
1697 } 1681 }
1698 1682
1699 Bind(&if_lengthiszero);
1700 {
1701 var_result.Bind(LoadRoot(Heap::kempty_stringRootIndex));
1702 Goto(&if_join);
1703 }
1704
1705 Bind(&if_join); 1683 Bind(&if_join);
1706 return var_result.value(); 1684 return var_result.value();
1707 } 1685 }
1708 1686
1709 Node* CodeStubAssembler::AllocateSlicedString( 1687 Node* CodeStubAssembler::AllocateSlicedString(
1710 Heap::RootListIndex map_root_index, Node* length, Node* parent, 1688 Heap::RootListIndex map_root_index, Node* length, Node* parent,
1711 Node* offset) { 1689 Node* offset) {
1712 CSA_ASSERT(this, TaggedIsSmi(length)); 1690 CSA_ASSERT(this, TaggedIsSmi(length));
1713 Node* result = Allocate(SlicedString::kSize); 1691 Node* result = Allocate(SlicedString::kSize);
1714 DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); 1692 DCHECK(Heap::RootIsImmortalImmovable(map_root_index));
(...skipping 1282 matching lines...) Expand 10 before | Expand all | Expand 10 after
2997 Node* CodeStubAssembler::IsJSFunction(Node* object) { 2975 Node* CodeStubAssembler::IsJSFunction(Node* object) {
2998 return HasInstanceType(object, JS_FUNCTION_TYPE); 2976 return HasInstanceType(object, JS_FUNCTION_TYPE);
2999 } 2977 }
3000 2978
3001 Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index, 2979 Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index,
3002 ParameterMode parameter_mode) { 2980 ParameterMode parameter_mode) {
3003 CSA_ASSERT(this, IsString(string)); 2981 CSA_ASSERT(this, IsString(string));
3004 // Translate the {index} into a Word. 2982 // Translate the {index} into a Word.
3005 index = ParameterToWord(index, parameter_mode); 2983 index = ParameterToWord(index, parameter_mode);
3006 2984
3007 // We may need to loop in case of cons, thin, or sliced strings. 2985 // We may need to loop in case of cons or sliced strings.
3008 Variable var_index(this, MachineType::PointerRepresentation()); 2986 Variable var_index(this, MachineType::PointerRepresentation());
3009 Variable var_result(this, MachineRepresentation::kWord32); 2987 Variable var_result(this, MachineRepresentation::kWord32);
3010 Variable var_string(this, MachineRepresentation::kTagged); 2988 Variable var_string(this, MachineRepresentation::kTagged);
3011 Variable* loop_vars[] = {&var_index, &var_string}; 2989 Variable* loop_vars[] = {&var_index, &var_string};
3012 Label done_loop(this, &var_result), loop(this, 2, loop_vars); 2990 Label done_loop(this, &var_result), loop(this, 2, loop_vars);
3013 var_string.Bind(string); 2991 var_string.Bind(string);
3014 var_index.Bind(index); 2992 var_index.Bind(index);
3015 Goto(&loop); 2993 Goto(&loop);
3016 Bind(&loop); 2994 Bind(&loop);
3017 { 2995 {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
3149 // The {string} might be compressed, call the runtime. 3127 // The {string} might be compressed, call the runtime.
3150 var_result.Bind(SmiToWord32( 3128 var_result.Bind(SmiToWord32(
3151 CallRuntime(Runtime::kExternalStringGetChar, 3129 CallRuntime(Runtime::kExternalStringGetChar,
3152 NoContextConstant(), string, SmiTag(index)))); 3130 NoContextConstant(), string, SmiTag(index))));
3153 Goto(&done_loop); 3131 Goto(&done_loop);
3154 } 3132 }
3155 } 3133 }
3156 3134
3157 Bind(&if_stringisnotexternal); 3135 Bind(&if_stringisnotexternal);
3158 { 3136 {
3159 Label if_stringissliced(this), if_stringisthin(this); 3137 // The {string} is a SlicedString, continue with its parent.
3160 Branch( 3138 Node* string_offset =
3161 Word32Equal(Word32And(string_instance_type, 3139 LoadAndUntagObjectField(string, SlicedString::kOffsetOffset);
3162 Int32Constant(kStringRepresentationMask)), 3140 Node* string_parent =
3163 Int32Constant(kSlicedStringTag)), 3141 LoadObjectField(string, SlicedString::kParentOffset);
3164 &if_stringissliced, &if_stringisthin); 3142 var_index.Bind(IntPtrAdd(index, string_offset));
3165 Bind(&if_stringissliced); 3143 var_string.Bind(string_parent);
3166 { 3144 Goto(&loop);
3167 // The {string} is a SlicedString, continue with its parent.
3168 Node* string_offset =
3169 LoadAndUntagObjectField(string, SlicedString::kOffsetOffset);
3170 Node* string_parent =
3171 LoadObjectField(string, SlicedString::kParentOffset);
3172 var_index.Bind(IntPtrAdd(index, string_offset));
3173 var_string.Bind(string_parent);
3174 Goto(&loop);
3175 }
3176 Bind(&if_stringisthin);
3177 {
3178 // The {string} is a ThinString, continue with its actual value.
3179 var_string.Bind(LoadObjectField(string, ThinString::kActualOffset));
3180 Goto(&loop);
3181 }
3182 } 3145 }
3183 } 3146 }
3184 } 3147 }
3185 } 3148 }
3186 3149
3187 Bind(&done_loop); 3150 Bind(&done_loop);
3188 return var_result.value(); 3151 return var_result.value();
3189 } 3152 }
3190 3153
3191 Node* CodeStubAssembler::StringFromCharCode(Node* code) { 3154 Node* CodeStubAssembler::StringFromCharCode(Node* code) {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3302 } 3265 }
3303 3266
3304 } // namespace 3267 } // namespace
3305 3268
3306 Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from, 3269 Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
3307 Node* to) { 3270 Node* to) {
3308 Label end(this); 3271 Label end(this);
3309 Label runtime(this); 3272 Label runtime(this);
3310 3273
3311 Variable var_instance_type(this, MachineRepresentation::kWord32); // Int32. 3274 Variable var_instance_type(this, MachineRepresentation::kWord32); // Int32.
3312 Variable var_representation(this, MachineRepresentation::kWord32); // Int32.
3313 Variable var_result(this, MachineRepresentation::kTagged); // String. 3275 Variable var_result(this, MachineRepresentation::kTagged); // String.
3314 Variable var_from(this, MachineRepresentation::kTagged); // Smi. 3276 Variable var_from(this, MachineRepresentation::kTagged); // Smi.
3315 Variable var_string(this, MachineRepresentation::kTagged); // String. 3277 Variable var_string(this, MachineRepresentation::kTagged); // String.
3316 3278
3317 var_instance_type.Bind(Int32Constant(0)); 3279 var_instance_type.Bind(Int32Constant(0));
3318 var_representation.Bind(Int32Constant(0));
3319 var_string.Bind(string); 3280 var_string.Bind(string);
3320 var_from.Bind(from); 3281 var_from.Bind(from);
3321 3282
3322 // Make sure first argument is a string. 3283 // Make sure first argument is a string.
3323 3284
3324 // Bailout if receiver is a Smi. 3285 // Bailout if receiver is a Smi.
3325 GotoIf(TaggedIsSmi(string), &runtime); 3286 GotoIf(TaggedIsSmi(string), &runtime);
3326 3287
3327 // Load the instance type of the {string}. 3288 // Load the instance type of the {string}.
3328 Node* const instance_type = LoadInstanceType(string); 3289 Node* const instance_type = LoadInstanceType(string);
(...skipping 20 matching lines...) Expand all
3349 3310
3350 Label single_char(this); 3311 Label single_char(this);
3351 GotoIf(SmiEqual(substr_length, SmiConstant(Smi::FromInt(1))), &single_char); 3312 GotoIf(SmiEqual(substr_length, SmiConstant(Smi::FromInt(1))), &single_char);
3352 3313
3353 // TODO(jgruber): Add an additional case for substring of length == 0? 3314 // TODO(jgruber): Add an additional case for substring of length == 0?
3354 3315
3355 // Deal with different string types: update the index if necessary 3316 // Deal with different string types: update the index if necessary
3356 // and put the underlying string into var_string. 3317 // and put the underlying string into var_string.
3357 3318
3358 // If the string is not indirect, it can only be sequential or external. 3319 // If the string is not indirect, it can only be sequential or external.
3359 STATIC_ASSERT(kIsIndirectStringMask == 3320 STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag));
3360 (kSlicedStringTag & kConsStringTag & kThinStringTag));
3361 STATIC_ASSERT(kIsIndirectStringMask != 0); 3321 STATIC_ASSERT(kIsIndirectStringMask != 0);
3362 Label underlying_unpacked(this); 3322 Label underlying_unpacked(this);
3363 GotoIf(Word32Equal( 3323 GotoIf(Word32Equal(
3364 Word32And(instance_type, Int32Constant(kIsIndirectStringMask)), 3324 Word32And(instance_type, Int32Constant(kIsIndirectStringMask)),
3365 Int32Constant(0)), 3325 Int32Constant(0)),
3366 &underlying_unpacked); 3326 &underlying_unpacked);
3367 3327
3368 // The subject string is a sliced, cons, or thin string. 3328 // The subject string is either a sliced or cons string.
3369 3329
3370 Label sliced_string(this), thin_or_sliced(this); 3330 Label sliced_string(this);
3371 var_representation.Bind( 3331 GotoIf(Word32NotEqual(
3372 Word32And(instance_type, Int32Constant(kStringRepresentationMask))); 3332 Word32And(instance_type, Int32Constant(kSlicedNotConsMask)),
3373 GotoIf( 3333 Int32Constant(0)),
3374 Word32NotEqual(var_representation.value(), Int32Constant(kConsStringTag)), 3334 &sliced_string);
3375 &thin_or_sliced);
3376 3335
3377 // Cons string. Check whether it is flat, then fetch first part. 3336 // Cons string. Check whether it is flat, then fetch first part.
3378 // Flat cons strings have an empty second part. 3337 // Flat cons strings have an empty second part.
3379 { 3338 {
3380 GotoIf(WordNotEqual(LoadObjectField(string, ConsString::kSecondOffset), 3339 GotoIf(WordNotEqual(LoadObjectField(string, ConsString::kSecondOffset),
3381 EmptyStringConstant()), 3340 EmptyStringConstant()),
3382 &runtime); 3341 &runtime);
3383 3342
3384 Node* first_string_part = LoadObjectField(string, ConsString::kFirstOffset); 3343 Node* first_string_part = LoadObjectField(string, ConsString::kFirstOffset);
3385 var_string.Bind(first_string_part); 3344 var_string.Bind(first_string_part);
3386 var_instance_type.Bind(LoadInstanceType(first_string_part)); 3345 var_instance_type.Bind(LoadInstanceType(first_string_part));
3387 var_representation.Bind(Word32And(
3388 var_instance_type.value(), Int32Constant(kStringRepresentationMask)));
3389 3346
3390 // The loaded first part might be a thin string.
3391 Branch(Word32Equal(Word32And(var_instance_type.value(),
3392 Int32Constant(kIsIndirectStringMask)),
3393 Int32Constant(0)),
3394 &underlying_unpacked, &thin_or_sliced);
3395 }
3396
3397 Bind(&thin_or_sliced);
3398 {
3399 GotoIf(Word32Equal(var_representation.value(),
3400 Int32Constant(kSlicedStringTag)),
3401 &sliced_string);
3402 Node* actual_string =
3403 LoadObjectField(var_string.value(), ThinString::kActualOffset);
3404 var_string.Bind(actual_string);
3405 var_instance_type.Bind(LoadInstanceType(actual_string));
3406 Goto(&underlying_unpacked); 3347 Goto(&underlying_unpacked);
3407 } 3348 }
3408 3349
3409 Bind(&sliced_string); 3350 Bind(&sliced_string);
3410 { 3351 {
3411 // Fetch parent and correct start index by offset. 3352 // Fetch parent and correct start index by offset.
3412 Node* sliced_offset = 3353 Node* sliced_offset = LoadObjectField(string, SlicedString::kOffsetOffset);
3413 LoadObjectField(var_string.value(), SlicedString::kOffsetOffset);
3414 var_from.Bind(SmiAdd(from, sliced_offset)); 3354 var_from.Bind(SmiAdd(from, sliced_offset));
3415 3355
3416 Node* slice_parent = LoadObjectField(string, SlicedString::kParentOffset); 3356 Node* slice_parent = LoadObjectField(string, SlicedString::kParentOffset);
3417 var_string.Bind(slice_parent); 3357 var_string.Bind(slice_parent);
3418 3358
3419 Node* slice_parent_instance_type = LoadInstanceType(slice_parent); 3359 Node* slice_parent_instance_type = LoadInstanceType(slice_parent);
3420 var_instance_type.Bind(slice_parent_instance_type); 3360 var_instance_type.Bind(slice_parent_instance_type);
3421 3361
3422 Goto(&underlying_unpacked); 3362 Goto(&underlying_unpacked);
3423 } 3363 }
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
4176 Bind(&runtime); 4116 Bind(&runtime);
4177 { 4117 {
4178 result.Bind(CallRuntime(Runtime::kToString, context, input)); 4118 result.Bind(CallRuntime(Runtime::kToString, context, input));
4179 Goto(&done); 4119 Goto(&done);
4180 } 4120 }
4181 4121
4182 Bind(&done); 4122 Bind(&done);
4183 return result.value(); 4123 return result.value();
4184 } 4124 }
4185 4125
4126 Node* CodeStubAssembler::FlattenString(Node* string) {
4127 CSA_ASSERT(this, IsString(string));
4128 Variable var_result(this, MachineRepresentation::kTagged);
4129 var_result.Bind(string);
4130
4131 Node* instance_type = LoadInstanceType(string);
4132
4133 // Check if the {string} is not a ConsString (i.e. already flat).
4134 Label is_cons(this, Label::kDeferred), is_flat_in_cons(this), end(this);
4135 {
4136 GotoUnless(Word32Equal(Word32And(instance_type,
4137 Int32Constant(kStringRepresentationMask)),
4138 Int32Constant(kConsStringTag)),
4139 &end);
4140
4141 // Check whether the right hand side is the empty string (i.e. if
4142 // this is really a flat string in a cons string).
4143 Node* rhs = LoadObjectField(string, ConsString::kSecondOffset);
4144 Branch(WordEqual(rhs, EmptyStringConstant()), &is_flat_in_cons, &is_cons);
4145 }
4146
4147 // Bail out to the runtime.
4148 Bind(&is_cons);
4149 {
4150 var_result.Bind(
4151 CallRuntime(Runtime::kFlattenString, NoContextConstant(), string));
4152 Goto(&end);
4153 }
4154
4155 Bind(&is_flat_in_cons);
4156 {
4157 var_result.Bind(LoadObjectField(string, ConsString::kFirstOffset));
4158 Goto(&end);
4159 }
4160
4161 Bind(&end);
4162 return var_result.value();
4163 }
4164
4186 Node* CodeStubAssembler::JSReceiverToPrimitive(Node* context, Node* input) { 4165 Node* CodeStubAssembler::JSReceiverToPrimitive(Node* context, Node* input) {
4187 Label if_isreceiver(this, Label::kDeferred), if_isnotreceiver(this); 4166 Label if_isreceiver(this, Label::kDeferred), if_isnotreceiver(this);
4188 Variable result(this, MachineRepresentation::kTagged); 4167 Variable result(this, MachineRepresentation::kTagged);
4189 Label done(this, &result); 4168 Label done(this, &result);
4190 4169
4191 BranchIfJSReceiver(input, &if_isreceiver, &if_isnotreceiver); 4170 BranchIfJSReceiver(input, &if_isreceiver, &if_isnotreceiver);
4192 4171
4193 Bind(&if_isreceiver); 4172 Bind(&if_isreceiver);
4194 { 4173 {
4195 // Convert {input} to a primitive first passing Number hint. 4174 // Convert {input} to a primitive first passing Number hint.
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
4317 variable.Bind( 4296 variable.Bind(
4318 IntPtrOrSmiAdd(variable.value(), IntPtrOrSmiConstant(value, mode), mode)); 4297 IntPtrOrSmiAdd(variable.value(), IntPtrOrSmiConstant(value, mode), mode));
4319 } 4298 }
4320 4299
4321 void CodeStubAssembler::Use(Label* label) { 4300 void CodeStubAssembler::Use(Label* label) {
4322 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); 4301 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label);
4323 } 4302 }
4324 4303
4325 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, 4304 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex,
4326 Variable* var_index, Label* if_keyisunique, 4305 Variable* var_index, Label* if_keyisunique,
4327 Variable* var_unique, Label* if_bailout) { 4306 Label* if_bailout) {
4328 DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep()); 4307 DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep());
4329 DCHECK_EQ(MachineRepresentation::kTagged, var_unique->rep());
4330 Comment("TryToName"); 4308 Comment("TryToName");
4331 4309
4332 Label if_hascachedindex(this), if_keyisnotindex(this), if_thinstring(this); 4310 Label if_hascachedindex(this), if_keyisnotindex(this);
4333 // Handle Smi and HeapNumber keys. 4311 // Handle Smi and HeapNumber keys.
4334 var_index->Bind(TryToIntptr(key, &if_keyisnotindex)); 4312 var_index->Bind(TryToIntptr(key, &if_keyisnotindex));
4335 Goto(if_keyisindex); 4313 Goto(if_keyisindex);
4336 4314
4337 Bind(&if_keyisnotindex); 4315 Bind(&if_keyisnotindex);
4338 Node* key_map = LoadMap(key); 4316 Node* key_map = LoadMap(key);
4339 var_unique->Bind(key);
4340 // Symbols are unique. 4317 // Symbols are unique.
4341 GotoIf(IsSymbolMap(key_map), if_keyisunique); 4318 GotoIf(IsSymbolMap(key_map), if_keyisunique);
4342 Node* key_instance_type = LoadMapInstanceType(key_map); 4319 Node* key_instance_type = LoadMapInstanceType(key_map);
4343 // Miss if |key| is not a String. 4320 // Miss if |key| is not a String.
4344 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); 4321 STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE);
4345 GotoUnless(IsStringInstanceType(key_instance_type), if_bailout); 4322 GotoUnless(IsStringInstanceType(key_instance_type), if_bailout);
4346 // |key| is a String. Check if it has a cached array index. 4323 // |key| is a String. Check if it has a cached array index.
4347 Node* hash = LoadNameHashField(key); 4324 Node* hash = LoadNameHashField(key);
4348 Node* contains_index = 4325 Node* contains_index =
4349 Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask)); 4326 Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask));
4350 GotoIf(Word32Equal(contains_index, Int32Constant(0)), &if_hascachedindex); 4327 GotoIf(Word32Equal(contains_index, Int32Constant(0)), &if_hascachedindex);
4351 // No cached array index. If the string knows that it contains an index, 4328 // No cached array index. If the string knows that it contains an index,
4352 // then it must be an uncacheable index. Handle this case in the runtime. 4329 // then it must be an uncacheable index. Handle this case in the runtime.
4353 Node* not_an_index = 4330 Node* not_an_index =
4354 Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask)); 4331 Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask));
4355 GotoIf(Word32Equal(not_an_index, Int32Constant(0)), if_bailout); 4332 GotoIf(Word32Equal(not_an_index, Int32Constant(0)), if_bailout);
4356 // Check if we have a ThinString.
4357 GotoIf(Word32Equal(key_instance_type, Int32Constant(THIN_STRING_TYPE)),
4358 &if_thinstring);
4359 GotoIf(
4360 Word32Equal(key_instance_type, Int32Constant(THIN_ONE_BYTE_STRING_TYPE)),
4361 &if_thinstring);
4362 // Finally, check if |key| is internalized. 4333 // Finally, check if |key| is internalized.
4363 STATIC_ASSERT(kNotInternalizedTag != 0); 4334 STATIC_ASSERT(kNotInternalizedTag != 0);
4364 Node* not_internalized = 4335 Node* not_internalized =
4365 Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask)); 4336 Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask));
4366 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout); 4337 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout);
4367 Goto(if_keyisunique); 4338 Goto(if_keyisunique);
4368 4339
4369 Bind(&if_thinstring);
4370 var_unique->Bind(LoadObjectField(key, ThinString::kActualOffset));
4371 Goto(if_keyisunique);
4372
4373 Bind(&if_hascachedindex); 4340 Bind(&if_hascachedindex);
4374 var_index->Bind(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash)); 4341 var_index->Bind(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash));
4375 Goto(if_keyisindex); 4342 Goto(if_keyisindex);
4376 } 4343 }
4377 4344
4378 template <typename Dictionary> 4345 template <typename Dictionary>
4379 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { 4346 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) {
4380 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); 4347 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize));
4381 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + 4348 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex +
4382 field_index)); 4349 field_index));
(...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after
5212 Label if_objectisreceiver(this); 5179 Label if_objectisreceiver(this);
5213 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); 5180 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
5214 STATIC_ASSERT(FIRST_JS_RECEIVER_TYPE == JS_PROXY_TYPE); 5181 STATIC_ASSERT(FIRST_JS_RECEIVER_TYPE == JS_PROXY_TYPE);
5215 Branch( 5182 Branch(
5216 Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)), 5183 Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)),
5217 &if_objectisreceiver, if_bailout); 5184 &if_objectisreceiver, if_bailout);
5218 Bind(&if_objectisreceiver); 5185 Bind(&if_objectisreceiver);
5219 } 5186 }
5220 5187
5221 Variable var_index(this, MachineType::PointerRepresentation()); 5188 Variable var_index(this, MachineType::PointerRepresentation());
5222 Variable var_unique(this, MachineRepresentation::kTagged);
5223 5189
5224 Label if_keyisindex(this), if_iskeyunique(this); 5190 Label if_keyisindex(this), if_iskeyunique(this);
5225 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, &var_unique, 5191 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, if_bailout);
5226 if_bailout);
5227 5192
5228 Bind(&if_iskeyunique); 5193 Bind(&if_iskeyunique);
5229 { 5194 {
5230 Variable var_holder(this, MachineRepresentation::kTagged); 5195 Variable var_holder(this, MachineRepresentation::kTagged);
5231 Variable var_holder_map(this, MachineRepresentation::kTagged); 5196 Variable var_holder_map(this, MachineRepresentation::kTagged);
5232 Variable var_holder_instance_type(this, MachineRepresentation::kWord32); 5197 Variable var_holder_instance_type(this, MachineRepresentation::kWord32);
5233 5198
5234 Variable* merged_variables[] = {&var_holder, &var_holder_map, 5199 Variable* merged_variables[] = {&var_holder, &var_holder_map,
5235 &var_holder_instance_type}; 5200 &var_holder_instance_type};
5236 Label loop(this, arraysize(merged_variables), merged_variables); 5201 Label loop(this, arraysize(merged_variables), merged_variables);
5237 var_holder.Bind(receiver); 5202 var_holder.Bind(receiver);
5238 var_holder_map.Bind(map); 5203 var_holder_map.Bind(map);
5239 var_holder_instance_type.Bind(instance_type); 5204 var_holder_instance_type.Bind(instance_type);
5240 Goto(&loop); 5205 Goto(&loop);
5241 Bind(&loop); 5206 Bind(&loop);
5242 { 5207 {
5243 Node* holder_map = var_holder_map.value(); 5208 Node* holder_map = var_holder_map.value();
5244 Node* holder_instance_type = var_holder_instance_type.value(); 5209 Node* holder_instance_type = var_holder_instance_type.value();
5245 5210
5246 Label next_proto(this); 5211 Label next_proto(this);
5247 lookup_property_in_holder(receiver, var_holder.value(), holder_map, 5212 lookup_property_in_holder(receiver, var_holder.value(), holder_map,
5248 holder_instance_type, var_unique.value(), 5213 holder_instance_type, key, &next_proto,
5249 &next_proto, if_bailout); 5214 if_bailout);
5250 Bind(&next_proto); 5215 Bind(&next_proto);
5251 5216
5252 // Bailout if it can be an integer indexed exotic case. 5217 // Bailout if it can be an integer indexed exotic case.
5253 GotoIf( 5218 GotoIf(
5254 Word32Equal(holder_instance_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), 5219 Word32Equal(holder_instance_type, Int32Constant(JS_TYPED_ARRAY_TYPE)),
5255 if_bailout); 5220 if_bailout);
5256 5221
5257 Node* proto = LoadMapPrototype(holder_map); 5222 Node* proto = LoadMapPrototype(holder_map);
5258 5223
5259 Label if_not_null(this); 5224 Label if_not_null(this);
(...skipping 3012 matching lines...) Expand 10 before | Expand all | Expand 10 after
8272 StoreObjectFieldNoWriteBarrier(result, 8237 StoreObjectFieldNoWriteBarrier(result,
8273 PromiseReactionJobInfo::kDebugNameOffset, 8238 PromiseReactionJobInfo::kDebugNameOffset,
8274 SmiConstant(kDebugNotActive)); 8239 SmiConstant(kDebugNotActive));
8275 StoreObjectFieldNoWriteBarrier(result, PromiseReactionJobInfo::kContextOffset, 8240 StoreObjectFieldNoWriteBarrier(result, PromiseReactionJobInfo::kContextOffset,
8276 context); 8241 context);
8277 return result; 8242 return result;
8278 } 8243 }
8279 8244
8280 } // namespace internal 8245 } // namespace internal
8281 } // namespace v8 8246 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698