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

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

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