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

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

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