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

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

Issue 2398423002: [regexp] Port RegExp.prototype[@@replace] (Closed)
Patch Set: Smi::kZero 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/contexts.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 1332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldOffset, 1343 StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldOffset,
1344 Int32Constant(String::kEmptyHashField), 1344 Int32Constant(String::kEmptyHashField),
1345 MachineRepresentation::kWord32); 1345 MachineRepresentation::kWord32);
1346 StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent, 1346 StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent,
1347 MachineRepresentation::kTagged); 1347 MachineRepresentation::kTagged);
1348 StoreObjectFieldNoWriteBarrier(result, SlicedString::kOffsetOffset, offset, 1348 StoreObjectFieldNoWriteBarrier(result, SlicedString::kOffsetOffset, offset,
1349 MachineRepresentation::kTagged); 1349 MachineRepresentation::kTagged);
1350 return result; 1350 return result;
1351 } 1351 }
1352 1352
1353 Node* CodeStubAssembler::AllocateOneByteConsString(Node* length, Node* first,
1354 Node* second) {
1355 Node* result = Allocate(ConsString::kSize);
1356 Node* map = LoadRoot(Heap::kConsOneByteStringMapRootIndex);
1357 StoreMapNoWriteBarrier(result, map);
1358 StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length,
1359 MachineRepresentation::kTagged);
1360 StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset,
1361 Int32Constant(String::kEmptyHashField),
1362 MachineRepresentation::kWord32);
1363 StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, first,
1364 MachineRepresentation::kTagged);
1365 StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, second,
1366 MachineRepresentation::kTagged);
1367 return result;
1368 }
1369
1370 Node* CodeStubAssembler::AllocateTwoByteConsString(Node* length, Node* first,
1371 Node* second) {
1372 Node* result = Allocate(ConsString::kSize);
1373 Node* map = LoadRoot(Heap::kConsStringMapRootIndex);
1374 StoreMapNoWriteBarrier(result, map);
1375 StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length,
1376 MachineRepresentation::kTagged);
1377 StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset,
1378 Int32Constant(String::kEmptyHashField),
1379 MachineRepresentation::kWord32);
1380 StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, first,
1381 MachineRepresentation::kTagged);
1382 StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, second,
1383 MachineRepresentation::kTagged);
1384 return result;
1385 }
1386
1353 Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length, 1387 Node* CodeStubAssembler::AllocateRegExpResult(Node* context, Node* length,
1354 Node* index, Node* input) { 1388 Node* index, Node* input) {
1355 Node* const max_length = 1389 Node* const max_length =
1356 SmiConstant(Smi::FromInt(JSArray::kInitialMaxFastElementArray)); 1390 SmiConstant(Smi::FromInt(JSArray::kInitialMaxFastElementArray));
1357 Assert(SmiLessThanOrEqual(length, max_length)); 1391 Assert(SmiLessThanOrEqual(length, max_length));
1358 1392
1359 // Allocate the JSRegExpResult. 1393 // Allocate the JSRegExpResult.
1360 // TODO(jgruber): Fold JSArray and FixedArray allocations, then remove 1394 // TODO(jgruber): Fold JSArray and FixedArray allocations, then remove
1361 // unneeded store of elements. 1395 // unneeded store of elements.
1362 Node* const result = Allocate(JSRegExpResult::kSize); 1396 Node* const result = Allocate(JSRegExpResult::kSize);
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 } 1714 }
1681 1715
1682 Bind(&done); 1716 Bind(&done);
1683 IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1); 1717 IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1);
1684 Comment("] CopyFixedArrayElements"); 1718 Comment("] CopyFixedArrayElements");
1685 } 1719 }
1686 1720
1687 void CodeStubAssembler::CopyStringCharacters(compiler::Node* from_string, 1721 void CodeStubAssembler::CopyStringCharacters(compiler::Node* from_string,
1688 compiler::Node* to_string, 1722 compiler::Node* to_string,
1689 compiler::Node* from_index, 1723 compiler::Node* from_index,
1724 compiler::Node* to_index,
1690 compiler::Node* character_count, 1725 compiler::Node* character_count,
1691 String::Encoding encoding) { 1726 String::Encoding encoding) {
1692 Label out(this); 1727 Label out(this);
1693 1728
1694 // Nothing to do for zero characters. 1729 // Nothing to do for zero characters.
1695 1730
1696 GotoIf(SmiLessThanOrEqual(character_count, SmiConstant(Smi::kZero)), &out); 1731 GotoIf(SmiLessThanOrEqual(character_count, SmiConstant(Smi::kZero)), &out);
1697 1732
1698 // Calculate offsets into the strings. 1733 // Calculate offsets into the strings.
1699 1734
1700 Node* from_offset; 1735 Node* from_offset;
1701 Node* limit_offset; 1736 Node* limit_offset;
1702 Node* to_offset; 1737 Node* to_offset;
1703 1738
1704 { 1739 {
1705 Node* byte_count = SmiUntag(character_count); 1740 Node* byte_count = SmiUntag(character_count);
1706 Node* from_byte_index = SmiUntag(from_index); 1741 Node* from_byte_index = SmiUntag(from_index);
1742 Node* to_byte_index = SmiUntag(to_index);
1707 if (encoding == String::ONE_BYTE_ENCODING) { 1743 if (encoding == String::ONE_BYTE_ENCODING) {
1708 const int offset = SeqOneByteString::kHeaderSize - kHeapObjectTag; 1744 const int offset = SeqOneByteString::kHeaderSize - kHeapObjectTag;
1709 from_offset = IntPtrAdd(IntPtrConstant(offset), from_byte_index); 1745 from_offset = IntPtrAdd(IntPtrConstant(offset), from_byte_index);
1710 limit_offset = IntPtrAdd(from_offset, byte_count); 1746 limit_offset = IntPtrAdd(from_offset, byte_count);
1711 to_offset = IntPtrConstant(offset); 1747 to_offset = IntPtrAdd(IntPtrConstant(offset), to_byte_index);
1712 } else { 1748 } else {
1713 STATIC_ASSERT(2 == sizeof(uc16)); 1749 STATIC_ASSERT(2 == sizeof(uc16));
1714 byte_count = WordShl(byte_count, 1); 1750 byte_count = WordShl(byte_count, 1);
1715 from_byte_index = WordShl(from_byte_index, 1); 1751 from_byte_index = WordShl(from_byte_index, 1);
1752 to_byte_index = WordShl(to_byte_index, 1);
1716 1753
1717 const int offset = SeqTwoByteString::kHeaderSize - kHeapObjectTag; 1754 const int offset = SeqTwoByteString::kHeaderSize - kHeapObjectTag;
1718 from_offset = IntPtrAdd(IntPtrConstant(offset), from_byte_index); 1755 from_offset = IntPtrAdd(IntPtrConstant(offset), from_byte_index);
1719 limit_offset = IntPtrAdd(from_offset, byte_count); 1756 limit_offset = IntPtrAdd(from_offset, byte_count);
1720 to_offset = IntPtrConstant(offset); 1757 to_offset = IntPtrAdd(IntPtrConstant(offset), to_byte_index);
1721 } 1758 }
1722 } 1759 }
1723 1760
1724 Variable var_from_offset(this, MachineType::PointerRepresentation()); 1761 Variable var_from_offset(this, MachineType::PointerRepresentation());
1725 Variable var_to_offset(this, MachineType::PointerRepresentation()); 1762 Variable var_to_offset(this, MachineType::PointerRepresentation());
1726 1763
1727 var_from_offset.Bind(from_offset); 1764 var_from_offset.Bind(from_offset);
1728 var_to_offset.Bind(to_offset); 1765 var_to_offset.Bind(to_offset);
1729 1766
1730 Variable* vars[] = {&var_from_offset, &var_to_offset}; 1767 Variable* vars[] = {&var_from_offset, &var_to_offset};
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after
2508 // 0 <= |from_index| <= |from_index| + |character_count| < from_string.length. 2545 // 0 <= |from_index| <= |from_index| + |character_count| < from_string.length.
2509 Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context, 2546 Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
2510 Node* from, Node* from_instance_type, 2547 Node* from, Node* from_instance_type,
2511 Node* from_index, Node* character_count) { 2548 Node* from_index, Node* character_count) {
2512 typedef CodeStubAssembler::Label Label; 2549 typedef CodeStubAssembler::Label Label;
2513 typedef CodeStubAssembler::Variable Variable; 2550 typedef CodeStubAssembler::Variable Variable;
2514 2551
2515 Label end(a), two_byte_sequential(a); 2552 Label end(a), two_byte_sequential(a);
2516 Variable var_result(a, MachineRepresentation::kTagged); 2553 Variable var_result(a, MachineRepresentation::kTagged);
2517 2554
2555 Node* const smi_zero = a->SmiConstant(Smi::kZero);
2556
2518 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); 2557 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
2519 a->GotoIf(a->Word32Equal(a->Word32And(from_instance_type, 2558 a->GotoIf(a->Word32Equal(a->Word32And(from_instance_type,
2520 a->Int32Constant(kStringEncodingMask)), 2559 a->Int32Constant(kStringEncodingMask)),
2521 a->Int32Constant(0)), 2560 a->Int32Constant(0)),
2522 &two_byte_sequential); 2561 &two_byte_sequential);
2523 2562
2524 // The subject string is a sequential one-byte string. 2563 // The subject string is a sequential one-byte string.
2525 { 2564 {
2526 Node* result = 2565 Node* result =
2527 a->AllocateSeqOneByteString(context, a->SmiToWord(character_count)); 2566 a->AllocateSeqOneByteString(context, a->SmiToWord(character_count));
2528 a->CopyStringCharacters(from, result, from_index, character_count, 2567 a->CopyStringCharacters(from, result, from_index, smi_zero, character_count,
2529 String::ONE_BYTE_ENCODING); 2568 String::ONE_BYTE_ENCODING);
2530 var_result.Bind(result); 2569 var_result.Bind(result);
2531 2570
2532 a->Goto(&end); 2571 a->Goto(&end);
2533 } 2572 }
2534 2573
2535 // The subject string is a sequential two-byte string. 2574 // The subject string is a sequential two-byte string.
2536 a->Bind(&two_byte_sequential); 2575 a->Bind(&two_byte_sequential);
2537 { 2576 {
2538 Node* result = 2577 Node* result =
2539 a->AllocateSeqTwoByteString(context, a->SmiToWord(character_count)); 2578 a->AllocateSeqTwoByteString(context, a->SmiToWord(character_count));
2540 a->CopyStringCharacters(from, result, from_index, character_count, 2579 a->CopyStringCharacters(from, result, from_index, smi_zero, character_count,
2541 String::TWO_BYTE_ENCODING); 2580 String::TWO_BYTE_ENCODING);
2542 var_result.Bind(result); 2581 var_result.Bind(result);
2543 2582
2544 a->Goto(&end); 2583 a->Goto(&end);
2545 } 2584 }
2546 2585
2547 a->Bind(&end); 2586 a->Bind(&end);
2548 return var_result.value(); 2587 return var_result.value();
2549 } 2588 }
2550 2589
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
2765 { 2804 {
2766 var_result.Bind( 2805 var_result.Bind(
2767 CallRuntime(Runtime::kSubString, context, string, from, to)); 2806 CallRuntime(Runtime::kSubString, context, string, from, to));
2768 Goto(&end); 2807 Goto(&end);
2769 } 2808 }
2770 2809
2771 Bind(&end); 2810 Bind(&end);
2772 return var_result.value(); 2811 return var_result.value();
2773 } 2812 }
2774 2813
2814 Node* CodeStubAssembler::StringConcat(Node* context, Node* first,
2815 Node* second) {
2816 Variable var_result(this, MachineRepresentation::kTagged);
2817
2818 Label out(this), runtime(this, Label::kDeferred);
2819
2820 // TODO(jgruber): Handle indirect, external, and two-byte strings.
2821
2822 Node* const one_byte_seq_mask = Int32Constant(
2823 kIsIndirectStringMask | kExternalStringTag | kStringEncodingMask);
2824 Node* const expected_masked = Int32Constant(kOneByteStringTag);
2825
2826 Node* const first_instance_type = LoadInstanceType(first);
2827 GotoUnless(Word32Equal(Word32And(first_instance_type, one_byte_seq_mask),
2828 expected_masked),
2829 &runtime);
2830
2831 Node* const second_instance_type = LoadInstanceType(second);
2832 GotoUnless(Word32Equal(Word32And(second_instance_type, one_byte_seq_mask),
2833 expected_masked),
2834 &runtime);
2835
2836 Node* const smi_zero = SmiConstant(Smi::kZero);
2837 Node* const first_length = LoadStringLength(first);
2838 Node* const second_length = LoadStringLength(second);
2839 Node* const length = SmiAdd(first_length, second_length);
2840
2841 Label if_makeseqstring(this), if_makeconsstring(this);
2842 Node* const min_cons_length =
2843 SmiConstant(Smi::FromInt(ConsString::kMinLength));
2844 Branch(SmiLessThan(length, min_cons_length), &if_makeseqstring,
2845 &if_makeconsstring);
2846
2847 Bind(&if_makeseqstring);
2848 {
2849 Node* result = AllocateSeqOneByteString(context, SmiToWord(length));
2850
2851 CopyStringCharacters(first, result, smi_zero, smi_zero, first_length,
2852 String::ONE_BYTE_ENCODING);
2853 CopyStringCharacters(second, result, smi_zero, first_length, second_length,
2854 String::ONE_BYTE_ENCODING);
2855
2856 var_result.Bind(result);
2857 Goto(&out);
2858 }
2859
2860 Bind(&if_makeconsstring);
2861 {
2862 Node* result = AllocateOneByteConsString(length, first, second);
2863 var_result.Bind(result);
2864 Goto(&out);
2865 }
2866
2867 Bind(&runtime);
2868 {
2869 Node* const result =
2870 CallRuntime(Runtime::kStringAdd, context, first, second);
2871 var_result.Bind(result);
2872 Goto(&out);
2873 }
2874
2875 Bind(&out);
2876 return var_result.value();
2877 }
2878
2879 Node* CodeStubAssembler::StringIndexOfChar(Node* context, Node* string,
2880 Node* needle_char, Node* from) {
2881 Variable var_result(this, MachineRepresentation::kTagged);
2882
2883 Label out(this), runtime(this, Label::kDeferred);
2884
2885 // Let runtime handle non-one-byte {needle_char}.
2886
2887 Node* const one_byte_char_mask = IntPtrConstant(0xFF);
2888 GotoUnless(WordEqual(WordAnd(needle_char, one_byte_char_mask), needle_char),
2889 &runtime);
2890
2891 // TODO(jgruber): Handle external and two-byte strings.
2892
2893 Node* const one_byte_seq_mask = Int32Constant(
2894 kIsIndirectStringMask | kExternalStringTag | kStringEncodingMask);
2895 Node* const expected_masked = Int32Constant(kOneByteStringTag);
2896
2897 Node* const string_instance_type = LoadInstanceType(string);
2898 GotoUnless(Word32Equal(Word32And(string_instance_type, one_byte_seq_mask),
2899 expected_masked),
2900 &runtime);
2901
2902 // If we reach this, {string} is a non-indirect, non-external one-byte string.
2903
2904 Node* const length = LoadStringLength(string);
2905 Node* const search_range_length = SmiUntag(SmiSub(length, from));
2906
2907 const int offset = SeqOneByteString::kHeaderSize - kHeapObjectTag;
2908 Node* const begin = IntPtrConstant(offset);
2909 Node* const cursor = IntPtrAdd(begin, SmiUntag(from));
2910 Node* const end = IntPtrAdd(cursor, search_range_length);
2911
2912 Variable var_cursor(this, MachineType::PointerRepresentation());
2913 Variable* vars[] = {&var_cursor};
2914 Label loop(this, 1, vars), loop_tail(this);
2915
2916 var_cursor.Bind(cursor);
2917 var_result.Bind(SmiConstant(Smi::FromInt(-1)));
2918
2919 Goto(&loop);
2920 Bind(&loop);
2921 {
2922 Node* const cursor = var_cursor.value();
2923
2924 Node* value = Load(MachineType::Uint8(), string, cursor);
2925 GotoUnless(WordEqual(value, needle_char), &loop_tail);
2926
2927 // Found a match.
2928 Node* index = SmiTag(IntPtrSub(cursor, begin));
2929 var_result.Bind(index);
2930 Goto(&out);
2931
2932 Bind(&loop_tail);
2933 {
2934 Node* const new_cursor = IntPtrAdd(cursor, IntPtrConstant(1));
2935 var_cursor.Bind(new_cursor);
2936 Branch(IntPtrLessThan(new_cursor, end), &loop, &out);
2937 }
2938 }
2939
2940 Bind(&runtime);
2941 {
2942 Node* const pattern = StringFromCharCode(needle_char);
2943 Node* const result =
2944 CallRuntime(Runtime::kStringIndexOf, context, string, pattern, from);
2945 var_result.Bind(result);
2946 var_cursor.Bind(IntPtrConstant(0));
2947 Goto(&out);
2948 }
2949
2950 Bind(&out);
2951 return var_result.value();
2952 }
2953
2775 Node* CodeStubAssembler::StringFromCodePoint(compiler::Node* codepoint, 2954 Node* CodeStubAssembler::StringFromCodePoint(compiler::Node* codepoint,
2776 UnicodeEncoding encoding) { 2955 UnicodeEncoding encoding) {
2777 Variable var_result(this, MachineRepresentation::kTagged); 2956 Variable var_result(this, MachineRepresentation::kTagged);
2778 var_result.Bind(EmptyStringConstant()); 2957 var_result.Bind(EmptyStringConstant());
2779 2958
2780 Label if_isword16(this), if_isword32(this), return_result(this); 2959 Label if_isword16(this), if_isword32(this), return_result(this);
2781 2960
2782 Branch(Uint32LessThan(codepoint, Int32Constant(0x10000)), &if_isword16, 2961 Branch(Uint32LessThan(codepoint, Int32Constant(0x10000)), &if_isword16,
2783 &if_isword32); 2962 &if_isword32);
2784 2963
(...skipping 4452 matching lines...) Expand 10 before | Expand all | Expand 10 after
7237 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable)); 7416 result.Bind(CallRuntime(Runtime::kInstanceOf, context, object, callable));
7238 Goto(&end); 7417 Goto(&end);
7239 } 7418 }
7240 7419
7241 Bind(&end); 7420 Bind(&end);
7242 return result.value(); 7421 return result.value();
7243 } 7422 }
7244 7423
7245 } // namespace internal 7424 } // namespace internal
7246 } // namespace v8 7425 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/contexts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698