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

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

Issue 2355793003: [stubs] Port SubStringStub to TurboFan (Closed)
Patch Set: Address comments Created 4 years, 3 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
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 4
5 #include "src/code-stub-assembler.h" 5 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 6 #include "src/code-factory.h"
7 #include "src/frames-inl.h" 7 #include "src/frames-inl.h"
8 #include "src/frames.h" 8 #include "src/frames.h"
9 #include "src/ic/handler-configuration.h" 9 #include "src/ic/handler-configuration.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 } 330 }
331 331
332 Node* CodeStubAssembler::SmiSub(Node* a, Node* b) { return IntPtrSub(a, b); } 332 Node* CodeStubAssembler::SmiSub(Node* a, Node* b) { return IntPtrSub(a, b); }
333 333
334 Node* CodeStubAssembler::SmiSubWithOverflow(Node* a, Node* b) { 334 Node* CodeStubAssembler::SmiSubWithOverflow(Node* a, Node* b) {
335 return IntPtrSubWithOverflow(a, b); 335 return IntPtrSubWithOverflow(a, b);
336 } 336 }
337 337
338 Node* CodeStubAssembler::SmiEqual(Node* a, Node* b) { return WordEqual(a, b); } 338 Node* CodeStubAssembler::SmiEqual(Node* a, Node* b) { return WordEqual(a, b); }
339 339
340 Node* CodeStubAssembler::SmiAbove(Node* a, Node* b) {
341 return UintPtrGreaterThan(a, b);
342 }
343
340 Node* CodeStubAssembler::SmiAboveOrEqual(Node* a, Node* b) { 344 Node* CodeStubAssembler::SmiAboveOrEqual(Node* a, Node* b) {
341 return UintPtrGreaterThanOrEqual(a, b); 345 return UintPtrGreaterThanOrEqual(a, b);
342 } 346 }
343 347
348 Node* CodeStubAssembler::SmiBelow(Node* a, Node* b) {
349 return UintPtrLessThan(a, b);
350 }
351
344 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) { 352 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) {
345 return IntPtrLessThan(a, b); 353 return IntPtrLessThan(a, b);
346 } 354 }
347 355
348 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) { 356 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) {
349 return IntPtrLessThanOrEqual(a, b); 357 return IntPtrLessThanOrEqual(a, b);
350 } 358 }
351 359
352 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) { 360 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) {
353 // TODO(bmeurer): Consider using Select once available. 361 // TODO(bmeurer): Consider using Select once available.
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 498
491 Node* CodeStubAssembler::WordIsSmi(Node* a) { 499 Node* CodeStubAssembler::WordIsSmi(Node* a) {
492 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask)), IntPtrConstant(0)); 500 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask)), IntPtrConstant(0));
493 } 501 }
494 502
495 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) { 503 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) {
496 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)), 504 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)),
497 IntPtrConstant(0)); 505 IntPtrConstant(0));
498 } 506 }
499 507
508 Node* CodeStubAssembler::WordIsNotPositiveSmi(Node* a) {
509 return WordNotEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)),
510 IntPtrConstant(0));
511 }
512
500 void CodeStubAssembler::BranchIfSameValueZero(Node* a, Node* b, Node* context, 513 void CodeStubAssembler::BranchIfSameValueZero(Node* a, Node* b, Node* context,
501 Label* if_true, Label* if_false) { 514 Label* if_true, Label* if_false) {
502 Node* number_map = HeapNumberMapConstant(); 515 Node* number_map = HeapNumberMapConstant();
503 Label a_isnumber(this), a_isnotnumber(this), b_isnumber(this), a_isnan(this), 516 Label a_isnumber(this), a_isnotnumber(this), b_isnumber(this), a_isnan(this),
504 float_not_equal(this); 517 float_not_equal(this);
505 // If register A and register B are identical, goto `if_true` 518 // If register A and register B are identical, goto `if_true`
506 GotoIf(WordEqual(a, b), if_true); 519 GotoIf(WordEqual(a, b), if_true);
507 // If either register A or B are Smis, goto `if_false` 520 // If either register A or B are Smis, goto `if_false`
508 GotoIf(Word32Or(WordIsSmi(a), WordIsSmi(b)), if_false); 521 GotoIf(Word32Or(WordIsSmi(a), WordIsSmi(b)), if_false);
509 // GotoIf(WordIsSmi(b), if_false); 522 // GotoIf(WordIsSmi(b), if_false);
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 Node* result = CallRuntime(Runtime::kAllocateSeqTwoByteString, context, 1388 Node* result = CallRuntime(Runtime::kAllocateSeqTwoByteString, context,
1376 SmiFromWord(length)); 1389 SmiFromWord(length));
1377 var_result.Bind(result); 1390 var_result.Bind(result);
1378 Goto(&if_join); 1391 Goto(&if_join);
1379 } 1392 }
1380 1393
1381 Bind(&if_join); 1394 Bind(&if_join);
1382 return var_result.value(); 1395 return var_result.value();
1383 } 1396 }
1384 1397
1398 Node* CodeStubAssembler::AllocateSlicedOneByteString(Node* length, Node* parent,
1399 Node* offset) {
1400 Node* result = Allocate(SlicedString::kSize);
1401 Node* map = LoadRoot(Heap::kSlicedOneByteStringMapRootIndex);
1402 StoreMapNoWriteBarrier(result, map);
1403 StoreObjectFieldNoWriteBarrier(result, SlicedString::kLengthOffset, length,
1404 MachineRepresentation::kTagged);
1405 StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldOffset,
1406 Int32Constant(String::kEmptyHashField),
1407 MachineRepresentation::kWord32);
1408 StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent,
1409 MachineRepresentation::kTagged);
1410 StoreObjectFieldNoWriteBarrier(result, SlicedString::kOffsetOffset, offset,
1411 MachineRepresentation::kTagged);
1412 return result;
1413 }
1414
1415 Node* CodeStubAssembler::AllocateSlicedTwoByteString(Node* length, Node* parent,
1416 Node* offset) {
1417 Node* result = Allocate(SlicedString::kSize);
1418 Node* map = LoadRoot(Heap::kSlicedStringMapRootIndex);
1419 StoreMapNoWriteBarrier(result, map);
1420 StoreObjectFieldNoWriteBarrier(result, SlicedString::kLengthOffset, length,
1421 MachineRepresentation::kTagged);
1422 StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldOffset,
1423 Int32Constant(String::kEmptyHashField),
1424 MachineRepresentation::kWord32);
1425 StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent,
1426 MachineRepresentation::kTagged);
1427 StoreObjectFieldNoWriteBarrier(result, SlicedString::kOffsetOffset, offset,
1428 MachineRepresentation::kTagged);
1429 return result;
1430 }
1431
1385 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements( 1432 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements(
1386 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) { 1433 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) {
1387 Comment("begin allocation of JSArray without elements"); 1434 Comment("begin allocation of JSArray without elements");
1388 int base_size = JSArray::kSize; 1435 int base_size = JSArray::kSize;
1389
1390 if (allocation_site != nullptr) { 1436 if (allocation_site != nullptr) {
1391 base_size += AllocationMemento::kSize; 1437 base_size += AllocationMemento::kSize;
1392 } 1438 }
1393 1439
1394 Node* size = IntPtrConstant(base_size); 1440 Node* size = IntPtrConstant(base_size);
1395 Node* array = AllocateUninitializedJSArray(kind, array_map, length, 1441 Node* array = AllocateUninitializedJSArray(kind, array_map, length,
1396 allocation_site, size); 1442 allocation_site, size);
1397 return array; 1443 return array;
1398 } 1444 }
1399 1445
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1712 Bind(&next_iter); 1758 Bind(&next_iter);
1713 Node* compare = WordNotEqual(from_offset, limit_offset); 1759 Node* compare = WordNotEqual(from_offset, limit_offset);
1714 Branch(compare, &decrement, &done); 1760 Branch(compare, &decrement, &done);
1715 } 1761 }
1716 1762
1717 Bind(&done); 1763 Bind(&done);
1718 IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1); 1764 IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1);
1719 Comment("] CopyFixedArrayElements"); 1765 Comment("] CopyFixedArrayElements");
1720 } 1766 }
1721 1767
1768 void CodeStubAssembler::CopyStringCharacters(compiler::Node* from_string,
1769 compiler::Node* to_string,
1770 compiler::Node* from_index,
1771 compiler::Node* character_count,
1772 String::Encoding encoding) {
1773 Label out(this);
1774
1775 // Nothing to do for zero characters.
1776
1777 GotoIf(SmiLessThanOrEqual(character_count, SmiConstant(Smi::FromInt(0))),
1778 &out);
1779
1780 // Calculate offsets into the strings.
1781
1782 Node* from_offset;
1783 Node* limit_offset;
1784 Node* to_offset;
1785
1786 {
1787 Node* byte_count = SmiToWord32(character_count);
1788 Node* from_byte_index = SmiToWord32(from_index);
1789 if (encoding == String::ONE_BYTE_ENCODING) {
1790 const int offset = SeqOneByteString::kHeaderSize - kHeapObjectTag;
1791 from_offset = IntPtrAdd(IntPtrConstant(offset), from_byte_index);
1792 limit_offset = IntPtrAdd(from_offset, byte_count);
1793 to_offset = IntPtrConstant(offset);
1794 } else {
1795 STATIC_ASSERT(2 == sizeof(uc16));
1796 byte_count = WordShl(byte_count, 1);
1797 from_byte_index = WordShl(from_byte_index, 1);
1798
1799 const int offset = SeqTwoByteString::kHeaderSize - kHeapObjectTag;
1800 from_offset = IntPtrAdd(IntPtrConstant(offset), from_byte_index);
1801 limit_offset = IntPtrAdd(from_offset, byte_count);
1802 to_offset = IntPtrConstant(offset);
1803 }
1804 }
1805
1806 Variable var_from_offset(this, MachineType::PointerRepresentation());
1807 Variable var_to_offset(this, MachineType::PointerRepresentation());
1808
1809 var_from_offset.Bind(from_offset);
1810 var_to_offset.Bind(to_offset);
1811
1812 Variable* vars[] = {&var_from_offset, &var_to_offset};
1813 Label decrement(this, 2, vars);
1814
1815 Label loop(this, 2, vars);
1816 Goto(&loop);
1817 Bind(&loop);
1818 {
1819 from_offset = var_from_offset.value();
1820 to_offset = var_to_offset.value();
1821
1822 // TODO(jgruber): We could make this faster through larger copy unit sizes.
1823 Node* value = Load(MachineType::Uint8(), from_string, from_offset);
1824 StoreNoWriteBarrier(MachineRepresentation::kWord8, to_string, to_offset,
1825 value);
1826
1827 Node* new_from_offset = IntPtrAdd(from_offset, IntPtrConstant(1));
1828 var_from_offset.Bind(new_from_offset);
1829 var_to_offset.Bind(IntPtrAdd(to_offset, IntPtrConstant(1)));
1830
1831 Branch(WordNotEqual(new_from_offset, limit_offset), &loop, &out);
1832 }
1833
1834 Bind(&out);
1835 }
1836
1722 Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array, 1837 Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array,
1723 Node* offset, 1838 Node* offset,
1724 ElementsKind from_kind, 1839 ElementsKind from_kind,
1725 ElementsKind to_kind, 1840 ElementsKind to_kind,
1726 Label* if_hole) { 1841 Label* if_hole) {
1727 if (IsFastDoubleElementsKind(from_kind)) { 1842 if (IsFastDoubleElementsKind(from_kind)) {
1728 Node* value = 1843 Node* value =
1729 LoadDoubleWithHoleCheck(array, offset, if_hole, MachineType::Float64()); 1844 LoadDoubleWithHoleCheck(array, offset, if_hole, MachineType::Float64());
1730 if (!IsFastDoubleElementsKind(to_kind)) { 1845 if (!IsFastDoubleElementsKind(to_kind)) {
1731 value = AllocateHeapNumberWithValue(value); 1846 value = AllocateHeapNumberWithValue(value);
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
2422 MachineRepresentation::kWord16, result, 2537 MachineRepresentation::kWord16, result,
2423 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), code); 2538 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), code);
2424 var_result.Bind(result); 2539 var_result.Bind(result);
2425 Goto(&if_done); 2540 Goto(&if_done);
2426 } 2541 }
2427 2542
2428 Bind(&if_done); 2543 Bind(&if_done);
2429 return var_result.value(); 2544 return var_result.value();
2430 } 2545 }
2431 2546
2547 Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
2548 Node* to) {
2549 Label end(this);
2550 Label runtime(this);
2551
2552 Variable var_instance_type(this, MachineRepresentation::kWord8); // Int32.
2553 Variable var_result(this, MachineRepresentation::kTagged); // String.
2554 Variable var_from(this, MachineRepresentation::kTagged); // Smi.
2555 Variable var_string(this, MachineRepresentation::kTagged); // String.
2556
2557 var_instance_type.Bind(Int32Constant(0));
Igor Sheludko 2016/09/22 12:23:37 You could probably avoid this binding if you move
jgruber 2016/09/22 13:22:41 I'm not so sure - runtime (the label that complain
2558 var_string.Bind(string);
2559 var_from.Bind(from);
2560
2561 // Make sure first argument is a string.
2562
2563 // Bailout if receiver is a Smi.
2564 GotoIf(WordIsSmi(string), &runtime);
2565
2566 // Load the instance type of the {string}.
2567 Node* const instance_type = LoadInstanceType(string);
2568 var_instance_type.Bind(instance_type);
2569
2570 // Check if {string} is a String.
2571 GotoIf(Int32GreaterThanOrEqual(instance_type,
2572 Int32Constant(FIRST_NONSTRING_TYPE)),
2573 &runtime);
2574
2575 // Make sure that both from and to are non-negative smis.
2576
2577 GotoIf(WordIsNotPositiveSmi(from), &runtime);
2578 GotoIf(WordIsNotPositiveSmi(to), &runtime);
2579
2580 Node* const substr_length = SmiSub(to, from);
2581 Node* const string_length = LoadStringLength(string);
2582
2583 // Begin dispatching based on substring length.
2584
2585 Label original_string_or_invalid_length(this);
2586 GotoIf(SmiAboveOrEqual(substr_length, string_length),
2587 &original_string_or_invalid_length);
2588
2589 // A real substring (substr_length < string_length).
2590
2591 Label single_char(this);
2592 GotoIf(SmiEqual(substr_length, SmiConstant(Smi::FromInt(1))), &single_char);
2593
2594 // TODO(jgruber): Add an additional case for substring of length == 0?
2595
2596 // Deal with different string types: update the index if necessary
2597 // and put the underlying string into var_string.
2598
2599 // If the string is not indirect, it can only be sequential or external.
2600 STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag));
2601 STATIC_ASSERT(kIsIndirectStringMask != 0);
2602 Label underlying_unpacked(this);
2603 GotoIf(Word32Equal(
2604 Word32And(instance_type, Int32Constant(kIsIndirectStringMask)),
2605 Int32Constant(0)),
2606 &underlying_unpacked);
2607
2608 // The subject string is either a sliced or cons string.
2609
2610 Label sliced_string(this);
2611 GotoIf(Word32NotEqual(
2612 Word32And(instance_type, Int32Constant(kSlicedNotConsMask)),
2613 Int32Constant(0)),
2614 &sliced_string);
2615
2616 // Cons string. Check whether it is flat, then fetch first part.
2617 // Flat cons strings have an empty second part.
2618 {
2619 GotoIf(WordNotEqual(LoadObjectField(string, ConsString::kSecondOffset),
2620 EmptyStringConstant()),
2621 &runtime);
2622
2623 Node* first_string_part = LoadObjectField(string, ConsString::kFirstOffset);
2624 var_string.Bind(first_string_part);
2625 var_instance_type.Bind(LoadInstanceType(first_string_part));
2626
2627 Goto(&underlying_unpacked);
2628 }
2629
2630 Bind(&sliced_string);
2631 {
2632 // Fetch parent and correct start index by offset.
2633 Node* sliced_offset = LoadObjectField(string, SlicedString::kOffsetOffset);
2634 var_from.Bind(SmiAdd(from, sliced_offset));
2635
2636 Node* slice_parent = LoadObjectField(string, SlicedString::kParentOffset);
2637 var_string.Bind(slice_parent);
2638
2639 Node* slice_parent_instance_type = LoadInstanceType(slice_parent);
2640 var_instance_type.Bind(slice_parent_instance_type);
2641
2642 Goto(&underlying_unpacked);
2643 }
2644
2645 // The subject string can only be external or sequential string of either
2646 // encoding at this point.
2647 Bind(&underlying_unpacked);
2648
2649 if (FLAG_string_slices) {
2650 Label copy_routine(this);
2651
2652 // Short slice. Copy instead of slicing.
2653 GotoIf(SmiLessThan(substr_length,
2654 SmiConstant(Smi::FromInt(SlicedString::kMinLength))),
2655 &copy_routine);
2656
2657 // Allocate new sliced string.
2658
2659 Label two_byte_slice(this);
2660 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0);
2661 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
2662
2663 Counters* counters = isolate()->counters();
2664 IncrementCounter(counters->sub_string_native(), 1);
2665
2666 GotoIf(Word32Equal(Word32And(var_instance_type.value(),
2667 Int32Constant(kStringEncodingMask)),
2668 Int32Constant(0)),
2669 &two_byte_slice);
2670
2671 var_result.Bind(AllocateSlicedOneByteString(
2672 substr_length, var_string.value(), var_from.value()));
2673 Goto(&end);
2674
2675 Bind(&two_byte_slice);
2676
2677 var_result.Bind(AllocateSlicedTwoByteString(
2678 substr_length, var_string.value(), var_from.value()));
2679 Goto(&end);
2680
2681 Bind(&copy_routine);
2682 }
2683
2684 // The subject string can only be external or sequential string of either
2685 // encoding at this point.
2686 STATIC_ASSERT(kExternalStringTag != 0);
2687 STATIC_ASSERT(kSeqStringTag == 0);
2688 Label sequential_string(this);
2689 GotoIf(Word32Equal(Word32And(var_instance_type.value(),
2690 Int32Constant(kExternalStringTag)),
2691 Int32Constant(0)),
2692 &sequential_string);
2693
2694 // Handle external string.
2695 {
2696 // Rule out short external strings.
2697 STATIC_ASSERT(kShortExternalStringTag != 0);
2698 GotoIf(Word32NotEqual(Word32And(var_instance_type.value(),
2699 Int32Constant(kShortExternalStringMask)),
2700 Int32Constant(0)),
2701 &runtime);
2702
2703 // Move the pointer so that offset-wise, it looks like a sequential string.
2704 STATIC_ASSERT(SeqTwoByteString::kHeaderSize ==
2705 SeqOneByteString::kHeaderSize);
2706
2707 Node* resource_data =
2708 LoadObjectField(var_string.value(), ExternalString::kResourceDataOffset,
2709 MachineType::AnyTagged());
2710 var_string.Bind(IntPtrSub(
2711 resource_data,
2712 Int32Constant(SeqTwoByteString::kHeaderSize - kHeapObjectTag)));
2713
2714 Goto(&sequential_string);
2715 }
2716
2717 Label two_byte_sequential(this);
2718 Bind(&sequential_string);
2719 {
2720 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
2721 GotoIf(Word32Equal(Word32And(var_instance_type.value(),
2722 Int32Constant(kStringEncodingMask)),
2723 Int32Constant(0)),
2724 &two_byte_sequential);
2725 }
2726
2727 // The subject string is a sequential one-byte string.
2728 {
2729 Node* result = AllocateSeqOneByteString(context, SmiToWord(substr_length));
2730 CopyStringCharacters(var_string.value(), result, var_from.value(),
2731 substr_length, String::ONE_BYTE_ENCODING);
2732 var_result.Bind(result);
2733
2734 Counters* counters = isolate()->counters();
2735 IncrementCounter(counters->sub_string_native(), 1);
2736
2737 Goto(&end);
2738 }
2739
2740 // The subject string is a sequential two-byte string.
2741 Bind(&two_byte_sequential);
2742 {
2743 Node* result = AllocateSeqTwoByteString(context, SmiToWord(substr_length));
2744 CopyStringCharacters(var_string.value(), result, var_from.value(),
2745 substr_length, String::TWO_BYTE_ENCODING);
2746 var_result.Bind(result);
2747
2748 Counters* counters = isolate()->counters();
2749 IncrementCounter(counters->sub_string_native(), 1);
2750
2751 Goto(&end);
2752 }
2753
2754 // Substrings of length 1 are generated through CharCodeAt and FromCharCode.
2755 Bind(&single_char);
2756 {
2757 Node* char_code = StringCharCodeAt(var_string.value(), var_from.value());
2758 var_result.Bind(StringFromCharCode(char_code));
2759 Goto(&end);
2760 }
2761
2762 Bind(&original_string_or_invalid_length);
2763 {
2764 // Longer than original string's length or negative: unsafe arguments.
2765 GotoIf(SmiAbove(substr_length, string_length), &runtime);
2766
2767 // Equal length - check if {from, to} == {0, str.length}.
2768 GotoIf(SmiAbove(from, SmiConstant(Smi::FromInt(0))), &runtime);
2769
2770 // Return the original string (substr_length == string_length).
2771
2772 Counters* counters = isolate()->counters();
2773 IncrementCounter(counters->sub_string_native(), 1);
2774
2775 var_result.Bind(string);
2776 Goto(&end);
2777 }
2778
2779 // Fall back to a runtime call.
2780 Bind(&runtime);
2781 {
2782 var_result.Bind(
2783 CallRuntime(Runtime::kSubString, context, string, from, to));
2784 Goto(&end);
2785 }
2786
2787 Bind(&end);
2788 return var_result.value();
2789 }
2790
2432 Node* CodeStubAssembler::StringToNumber(Node* context, Node* input) { 2791 Node* CodeStubAssembler::StringToNumber(Node* context, Node* input) {
2433 Label runtime(this, Label::kDeferred); 2792 Label runtime(this, Label::kDeferred);
2434 Label end(this); 2793 Label end(this);
2435 2794
2436 Variable var_result(this, MachineRepresentation::kTagged); 2795 Variable var_result(this, MachineRepresentation::kTagged);
2437 2796
2438 // Check if string has a cached array index. 2797 // Check if string has a cached array index.
2439 Node* hash = LoadNameHashField(input); 2798 Node* hash = LoadNameHashField(input);
2440 Node* bit = 2799 Node* bit =
2441 Word32And(hash, Int32Constant(String::kContainsCachedArrayIndexMask)); 2800 Word32And(hash, Int32Constant(String::kContainsCachedArrayIndexMask));
(...skipping 2732 matching lines...) Expand 10 before | Expand all | Expand 10 after
5174 Heap::kTheHoleValueRootIndex); 5533 Heap::kTheHoleValueRootIndex);
5175 5534
5176 // Store the WeakCell in the feedback vector. 5535 // Store the WeakCell in the feedback vector.
5177 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 5536 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER,
5178 CodeStubAssembler::SMI_PARAMETERS); 5537 CodeStubAssembler::SMI_PARAMETERS);
5179 return cell; 5538 return cell;
5180 } 5539 }
5181 5540
5182 } // namespace internal 5541 } // namespace internal
5183 } // namespace v8 5542 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698