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

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

Issue 2375493002: Version 5.5.289.1 (cherry-pick) (Closed)
Patch Set: Created 4 years, 2 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.h » ('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 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
344 Node* CodeStubAssembler::SmiAboveOrEqual(Node* a, Node* b) { 340 Node* CodeStubAssembler::SmiAboveOrEqual(Node* a, Node* b) {
345 return UintPtrGreaterThanOrEqual(a, b); 341 return UintPtrGreaterThanOrEqual(a, b);
346 } 342 }
347 343
348 Node* CodeStubAssembler::SmiBelow(Node* a, Node* b) {
349 return UintPtrLessThan(a, b);
350 }
351
352 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) { 344 Node* CodeStubAssembler::SmiLessThan(Node* a, Node* b) {
353 return IntPtrLessThan(a, b); 345 return IntPtrLessThan(a, b);
354 } 346 }
355 347
356 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) { 348 Node* CodeStubAssembler::SmiLessThanOrEqual(Node* a, Node* b) {
357 return IntPtrLessThanOrEqual(a, b); 349 return IntPtrLessThanOrEqual(a, b);
358 } 350 }
359 351
360 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) { 352 Node* CodeStubAssembler::SmiMin(Node* a, Node* b) {
361 // TODO(bmeurer): Consider using Select once available. 353 // TODO(bmeurer): Consider using Select once available.
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 490
499 Node* CodeStubAssembler::WordIsSmi(Node* a) { 491 Node* CodeStubAssembler::WordIsSmi(Node* a) {
500 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask)), IntPtrConstant(0)); 492 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask)), IntPtrConstant(0));
501 } 493 }
502 494
503 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) { 495 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) {
504 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)), 496 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)),
505 IntPtrConstant(0)); 497 IntPtrConstant(0));
506 } 498 }
507 499
508 Node* CodeStubAssembler::WordIsNotPositiveSmi(Node* a) {
509 return WordNotEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)),
510 IntPtrConstant(0));
511 }
512
513 void CodeStubAssembler::BranchIfSameValueZero(Node* a, Node* b, Node* context, 500 void CodeStubAssembler::BranchIfSameValueZero(Node* a, Node* b, Node* context,
514 Label* if_true, Label* if_false) { 501 Label* if_true, Label* if_false) {
515 Node* number_map = HeapNumberMapConstant(); 502 Node* number_map = HeapNumberMapConstant();
516 Label a_isnumber(this), a_isnotnumber(this), b_isnumber(this), a_isnan(this), 503 Label a_isnumber(this), a_isnotnumber(this), b_isnumber(this), a_isnan(this),
517 float_not_equal(this); 504 float_not_equal(this);
518 // If register A and register B are identical, goto `if_true` 505 // If register A and register B are identical, goto `if_true`
519 GotoIf(WordEqual(a, b), if_true); 506 GotoIf(WordEqual(a, b), if_true);
520 // If either register A or B are Smis, goto `if_false` 507 // If either register A or B are Smis, goto `if_false`
521 GotoIf(Word32Or(WordIsSmi(a), WordIsSmi(b)), if_false); 508 GotoIf(Word32Or(WordIsSmi(a), WordIsSmi(b)), if_false);
522 // GotoIf(WordIsSmi(b), if_false); 509 // GotoIf(WordIsSmi(b), if_false);
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 Node* result = CallRuntime(Runtime::kAllocateSeqTwoByteString, context, 1375 Node* result = CallRuntime(Runtime::kAllocateSeqTwoByteString, context,
1389 SmiFromWord(length)); 1376 SmiFromWord(length));
1390 var_result.Bind(result); 1377 var_result.Bind(result);
1391 Goto(&if_join); 1378 Goto(&if_join);
1392 } 1379 }
1393 1380
1394 Bind(&if_join); 1381 Bind(&if_join);
1395 return var_result.value(); 1382 return var_result.value();
1396 } 1383 }
1397 1384
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
1432 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements( 1385 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements(
1433 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) { 1386 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) {
1434 Comment("begin allocation of JSArray without elements"); 1387 Comment("begin allocation of JSArray without elements");
1435 int base_size = JSArray::kSize; 1388 int base_size = JSArray::kSize;
1389
1436 if (allocation_site != nullptr) { 1390 if (allocation_site != nullptr) {
1437 base_size += AllocationMemento::kSize; 1391 base_size += AllocationMemento::kSize;
1438 } 1392 }
1439 1393
1440 Node* size = IntPtrConstant(base_size); 1394 Node* size = IntPtrConstant(base_size);
1441 Node* array = AllocateUninitializedJSArray(kind, array_map, length, 1395 Node* array = AllocateUninitializedJSArray(kind, array_map, length,
1442 allocation_site, size); 1396 allocation_site, size);
1443 return array; 1397 return array;
1444 } 1398 }
1445 1399
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1758 Bind(&next_iter); 1712 Bind(&next_iter);
1759 Node* compare = WordNotEqual(from_offset, limit_offset); 1713 Node* compare = WordNotEqual(from_offset, limit_offset);
1760 Branch(compare, &decrement, &done); 1714 Branch(compare, &decrement, &done);
1761 } 1715 }
1762 1716
1763 Bind(&done); 1717 Bind(&done);
1764 IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1); 1718 IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1);
1765 Comment("] CopyFixedArrayElements"); 1719 Comment("] CopyFixedArrayElements");
1766 } 1720 }
1767 1721
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
1837 Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array, 1722 Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array,
1838 Node* offset, 1723 Node* offset,
1839 ElementsKind from_kind, 1724 ElementsKind from_kind,
1840 ElementsKind to_kind, 1725 ElementsKind to_kind,
1841 Label* if_hole) { 1726 Label* if_hole) {
1842 if (IsFastDoubleElementsKind(from_kind)) { 1727 if (IsFastDoubleElementsKind(from_kind)) {
1843 Node* value = 1728 Node* value =
1844 LoadDoubleWithHoleCheck(array, offset, if_hole, MachineType::Float64()); 1729 LoadDoubleWithHoleCheck(array, offset, if_hole, MachineType::Float64());
1845 if (!IsFastDoubleElementsKind(to_kind)) { 1730 if (!IsFastDoubleElementsKind(to_kind)) {
1846 value = AllocateHeapNumberWithValue(value); 1731 value = AllocateHeapNumberWithValue(value);
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
2537 MachineRepresentation::kWord16, result, 2422 MachineRepresentation::kWord16, result,
2538 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), code); 2423 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), code);
2539 var_result.Bind(result); 2424 var_result.Bind(result);
2540 Goto(&if_done); 2425 Goto(&if_done);
2541 } 2426 }
2542 2427
2543 Bind(&if_done); 2428 Bind(&if_done);
2544 return var_result.value(); 2429 return var_result.value();
2545 } 2430 }
2546 2431
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));
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
2791 Node* CodeStubAssembler::StringToNumber(Node* context, Node* input) { 2432 Node* CodeStubAssembler::StringToNumber(Node* context, Node* input) {
2792 Label runtime(this, Label::kDeferred); 2433 Label runtime(this, Label::kDeferred);
2793 Label end(this); 2434 Label end(this);
2794 2435
2795 Variable var_result(this, MachineRepresentation::kTagged); 2436 Variable var_result(this, MachineRepresentation::kTagged);
2796 2437
2797 // Check if string has a cached array index. 2438 // Check if string has a cached array index.
2798 Node* hash = LoadNameHashField(input); 2439 Node* hash = LoadNameHashField(input);
2799 Node* bit = 2440 Node* bit =
2800 Word32And(hash, Int32Constant(String::kContainsCachedArrayIndexMask)); 2441 Word32And(hash, Int32Constant(String::kContainsCachedArrayIndexMask));
(...skipping 2857 matching lines...) Expand 10 before | Expand all | Expand 10 after
5658 Heap::kTheHoleValueRootIndex); 5299 Heap::kTheHoleValueRootIndex);
5659 5300
5660 // Store the WeakCell in the feedback vector. 5301 // Store the WeakCell in the feedback vector.
5661 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 5302 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER,
5662 CodeStubAssembler::SMI_PARAMETERS); 5303 CodeStubAssembler::SMI_PARAMETERS);
5663 return cell; 5304 return cell;
5664 } 5305 }
5665 5306
5666 } // namespace internal 5307 } // namespace internal
5667 } // namespace v8 5308 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698