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

Side by Side Diff: src/builtins/builtins-regexp.cc

Issue 2573573004: [stubs] Enable graph verification for builtins. (Closed)
Patch Set: Created 4 years 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/builtins/builtins-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/code-stub-assembler.h" 8 #include "src/code-stub-assembler.h"
9 #include "src/regexp/jsregexp.h" 9 #include "src/regexp/jsregexp.h"
10 #include "src/regexp/regexp-utils.h" 10 #include "src/regexp/regexp-utils.h"
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 var_to_cursor.Bind(IntPtrConstant(1)); 176 var_to_cursor.Bind(IntPtrConstant(1));
177 177
178 Variable* vars[] = {&var_from_cursor, &var_to_cursor}; 178 Variable* vars[] = {&var_from_cursor, &var_to_cursor};
179 Label loop(this, 2, vars); 179 Label loop(this, 2, vars);
180 180
181 Goto(&loop); 181 Goto(&loop);
182 Bind(&loop); 182 Bind(&loop);
183 { 183 {
184 Node* const from_cursor = var_from_cursor.value(); 184 Node* const from_cursor = var_from_cursor.value();
185 Node* const to_cursor = var_to_cursor.value(); 185 Node* const to_cursor = var_to_cursor.value();
186 Node* const start = LoadFixedArrayElement(match_info, from_cursor); 186 Node* const start =
187 LoadFixedArrayElement(match_info, from_cursor, 0, INTPTR_PARAMETERS);
187 188
188 Label next_iter(this); 189 Label next_iter(this);
189 GotoIf(SmiEqual(start, SmiConstant(Smi::FromInt(-1))), &next_iter); 190 GotoIf(SmiEqual(start, SmiConstant(Smi::FromInt(-1))), &next_iter);
190 191
191 Node* const from_cursor_plus1 = IntPtrAdd(from_cursor, IntPtrConstant(1)); 192 Node* const from_cursor_plus1 = IntPtrAdd(from_cursor, IntPtrConstant(1));
192 Node* const end = LoadFixedArrayElement(match_info, from_cursor_plus1); 193 Node* const end = LoadFixedArrayElement(match_info, from_cursor_plus1, 0,
194 INTPTR_PARAMETERS);
193 195
194 Node* const capture = SubString(context, string, start, end); 196 Node* const capture = SubString(context, string, start, end);
195 StoreFixedArrayElement(result_elements, to_cursor, capture); 197 StoreFixedArrayElement(result_elements, to_cursor, capture,
198 UPDATE_WRITE_BARRIER, 0, INTPTR_PARAMETERS);
196 Goto(&next_iter); 199 Goto(&next_iter);
197 200
198 Bind(&next_iter); 201 Bind(&next_iter);
199 var_from_cursor.Bind(IntPtrAdd(from_cursor, IntPtrConstant(2))); 202 var_from_cursor.Bind(IntPtrAdd(from_cursor, IntPtrConstant(2)));
200 var_to_cursor.Bind(IntPtrAdd(to_cursor, IntPtrConstant(1))); 203 var_to_cursor.Bind(IntPtrAdd(to_cursor, IntPtrConstant(1)));
201 Branch(UintPtrLessThan(var_from_cursor.value(), limit), &loop, &out); 204 Branch(UintPtrLessThan(var_from_cursor.value(), limit), &loop, &out);
202 } 205 }
203 206
204 Bind(&out); 207 Bind(&out);
205 return result; 208 return result;
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 Node* const flags_intptr = var_flags.value(); 562 Node* const flags_intptr = var_flags.value();
560 563
561 Variable var_offset(this, MachineType::PointerRepresentation()); 564 Variable var_offset(this, MachineType::PointerRepresentation());
562 var_offset.Bind( 565 var_offset.Bind(
563 IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 566 IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag));
564 567
565 #define CASE_FOR_FLAG(FLAG, CHAR) \ 568 #define CASE_FOR_FLAG(FLAG, CHAR) \
566 do { \ 569 do { \
567 Label next(this); \ 570 Label next(this); \
568 GotoUnless(IsSetWord(flags_intptr, FLAG), &next); \ 571 GotoUnless(IsSetWord(flags_intptr, FLAG), &next); \
569 Node* const value = IntPtrConstant(CHAR); \ 572 Node* const value = Int32Constant(CHAR); \
570 StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \ 573 StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \
571 var_offset.value(), value); \ 574 var_offset.value(), value); \
572 var_offset.Bind(IntPtrAdd(var_offset.value(), int_one)); \ 575 var_offset.Bind(IntPtrAdd(var_offset.value(), int_one)); \
573 Goto(&next); \ 576 Goto(&next); \
574 Bind(&next); \ 577 Bind(&next); \
575 } while (false) 578 } while (false)
576 579
577 CASE_FOR_FLAG(JSRegExp::kGlobal, 'g'); 580 CASE_FOR_FLAG(JSRegExp::kGlobal, 'g');
578 CASE_FOR_FLAG(JSRegExp::kIgnoreCase, 'i'); 581 CASE_FOR_FLAG(JSRegExp::kIgnoreCase, 'i');
579 CASE_FOR_FLAG(JSRegExp::kMultiline, 'm'); 582 CASE_FOR_FLAG(JSRegExp::kMultiline, 'm');
580 CASE_FOR_FLAG(JSRegExp::kUnicode, 'u'); 583 CASE_FOR_FLAG(JSRegExp::kUnicode, 'u');
581 CASE_FOR_FLAG(JSRegExp::kSticky, 'y'); 584 CASE_FOR_FLAG(JSRegExp::kSticky, 'y');
582 #undef CASE_FOR_FLAG 585 #undef CASE_FOR_FLAG
583 586
584 return result; 587 return result;
585 } 588 }
586 } 589 }
587 590
588 // ES#sec-isregexp IsRegExp ( argument ) 591 // ES#sec-isregexp IsRegExp ( argument )
589 Node* RegExpBuiltinsAssembler::IsRegExp(Node* const context, 592 Node* RegExpBuiltinsAssembler::IsRegExp(Node* const context,
590 Node* const maybe_receiver) { 593 Node* const maybe_receiver) {
591 Label out(this), if_isregexp(this); 594 Label out(this), if_isregexp(this);
592 595
593 Variable var_result(this, MachineType::PointerRepresentation()); 596 Variable var_result(this, MachineRepresentation::kWord32);
594 var_result.Bind(IntPtrConstant(0)); 597 var_result.Bind(Int32Constant(0));
595 598
596 GotoIf(TaggedIsSmi(maybe_receiver), &out); 599 GotoIf(TaggedIsSmi(maybe_receiver), &out);
597 GotoUnless(IsJSReceiver(maybe_receiver), &out); 600 GotoUnless(IsJSReceiver(maybe_receiver), &out);
598 601
599 Node* const receiver = maybe_receiver; 602 Node* const receiver = maybe_receiver;
600 603
601 // Check @@match. 604 // Check @@match.
602 { 605 {
603 Callable getproperty_callable = CodeFactory::GetProperty(isolate()); 606 Callable getproperty_callable = CodeFactory::GetProperty(isolate());
604 Node* const name = HeapConstant(isolate()->factory()->match_symbol()); 607 Node* const name = HeapConstant(isolate()->factory()->match_symbol());
605 Node* const value = CallStub(getproperty_callable, context, receiver, name); 608 Node* const value = CallStub(getproperty_callable, context, receiver, name);
606 609
607 Label match_isundefined(this), match_isnotundefined(this); 610 Label match_isundefined(this), match_isnotundefined(this);
608 Branch(IsUndefined(value), &match_isundefined, &match_isnotundefined); 611 Branch(IsUndefined(value), &match_isundefined, &match_isnotundefined);
609 612
610 Bind(&match_isundefined); 613 Bind(&match_isundefined);
611 Branch(HasInstanceType(receiver, JS_REGEXP_TYPE), &if_isregexp, &out); 614 Branch(HasInstanceType(receiver, JS_REGEXP_TYPE), &if_isregexp, &out);
612 615
613 Bind(&match_isnotundefined); 616 Bind(&match_isnotundefined);
614 BranchIfToBooleanIsTrue(value, &if_isregexp, &out); 617 BranchIfToBooleanIsTrue(value, &if_isregexp, &out);
615 } 618 }
616 619
617 Bind(&if_isregexp); 620 Bind(&if_isregexp);
618 var_result.Bind(IntPtrConstant(1)); 621 var_result.Bind(Int32Constant(1));
619 Goto(&out); 622 Goto(&out);
620 623
621 Bind(&out); 624 Bind(&out);
622 return var_result.value(); 625 return var_result.value();
623 } 626 }
624 627
625 // ES#sec-regexpinitialize 628 // ES#sec-regexpinitialize
626 // Runtime Semantics: RegExpInitialize ( obj, pattern, flags ) 629 // Runtime Semantics: RegExpInitialize ( obj, pattern, flags )
627 Node* RegExpBuiltinsAssembler::RegExpInitialize(Node* const context, 630 Node* RegExpBuiltinsAssembler::RegExpInitialize(Node* const context,
628 Node* const regexp, 631 Node* const regexp,
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 Node* const receiver = Parameter(0); 958 Node* const receiver = Parameter(0);
956 Return(receiver); 959 Return(receiver);
957 } 960 }
958 961
959 // Fast-path implementation for flag checks on an unmodified JSRegExp instance. 962 // Fast-path implementation for flag checks on an unmodified JSRegExp instance.
960 Node* RegExpBuiltinsAssembler::FastFlagGetter(Node* const regexp, 963 Node* RegExpBuiltinsAssembler::FastFlagGetter(Node* const regexp,
961 JSRegExp::Flag flag) { 964 JSRegExp::Flag flag) {
962 Node* const smi_zero = SmiConstant(Smi::kZero); 965 Node* const smi_zero = SmiConstant(Smi::kZero);
963 Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset); 966 Node* const flags = LoadObjectField(regexp, JSRegExp::kFlagsOffset);
964 Node* const mask = SmiConstant(Smi::FromInt(flag)); 967 Node* const mask = SmiConstant(Smi::FromInt(flag));
965 Node* const is_flag_set = WordNotEqual(WordAnd(flags, mask), smi_zero); 968 Node* const is_flag_set = WordNotEqual(SmiAnd(flags, mask), smi_zero);
966 969
967 return is_flag_set; 970 return is_flag_set;
968 } 971 }
969 972
970 // Load through the GetProperty stub. 973 // Load through the GetProperty stub.
971 Node* RegExpBuiltinsAssembler::SlowFlagGetter(Node* const context, 974 Node* RegExpBuiltinsAssembler::SlowFlagGetter(Node* const context,
972 Node* const regexp, 975 Node* const regexp,
973 JSRegExp::Flag flag) { 976 JSRegExp::Flag flag) {
974 Factory* factory = isolate()->factory(); 977 Factory* factory = isolate()->factory();
975 978
976 Label out(this); 979 Label out(this);
977 Variable var_result(this, MachineType::PointerRepresentation()); 980 Variable var_result(this, MachineRepresentation::kWord32);
978 981
979 Node* name; 982 Node* name;
980 983
981 switch (flag) { 984 switch (flag) {
982 case JSRegExp::kGlobal: 985 case JSRegExp::kGlobal:
983 name = HeapConstant(factory->global_string()); 986 name = HeapConstant(factory->global_string());
984 break; 987 break;
985 case JSRegExp::kIgnoreCase: 988 case JSRegExp::kIgnoreCase:
986 name = HeapConstant(factory->ignoreCase_string()); 989 name = HeapConstant(factory->ignoreCase_string());
987 break; 990 break;
(...skipping 11 matching lines...) Expand all
999 } 1002 }
1000 1003
1001 Callable getproperty_callable = CodeFactory::GetProperty(isolate()); 1004 Callable getproperty_callable = CodeFactory::GetProperty(isolate());
1002 Node* const value = CallStub(getproperty_callable, context, regexp, name); 1005 Node* const value = CallStub(getproperty_callable, context, regexp, name);
1003 1006
1004 Label if_true(this), if_false(this); 1007 Label if_true(this), if_false(this);
1005 BranchIfToBooleanIsTrue(value, &if_true, &if_false); 1008 BranchIfToBooleanIsTrue(value, &if_true, &if_false);
1006 1009
1007 Bind(&if_true); 1010 Bind(&if_true);
1008 { 1011 {
1009 var_result.Bind(IntPtrConstant(1)); 1012 var_result.Bind(Int32Constant(1));
1010 Goto(&out); 1013 Goto(&out);
1011 } 1014 }
1012 1015
1013 Bind(&if_false); 1016 Bind(&if_false);
1014 { 1017 {
1015 var_result.Bind(IntPtrConstant(0)); 1018 var_result.Bind(Int32Constant(0));
1016 Goto(&out); 1019 Goto(&out);
1017 } 1020 }
1018 1021
1019 Bind(&out); 1022 Bind(&out);
1020 return var_result.value(); 1023 return var_result.value();
1021 } 1024 }
1022 1025
1023 Node* RegExpBuiltinsAssembler::FlagGetter(Node* const context, 1026 Node* RegExpBuiltinsAssembler::FlagGetter(Node* const context,
1024 Node* const regexp, 1027 Node* const regexp,
1025 JSRegExp::Flag flag, 1028 JSRegExp::Flag flag,
(...skipping 1216 matching lines...) Expand 10 before | Expand all | Expand 10 after
2242 Bind(&if_isstring); 2245 Bind(&if_isstring);
2243 { 2246 {
2244 CSA_ASSERT(this, IsStringInstanceType(LoadInstanceType(elem))); 2247 CSA_ASSERT(this, IsStringInstanceType(LoadInstanceType(elem)));
2245 2248
2246 Callable call_callable = CodeFactory::Call(isolate); 2249 Callable call_callable = CodeFactory::Call(isolate);
2247 Node* const replacement_obj = 2250 Node* const replacement_obj =
2248 CallJS(call_callable, context, replace_callable, undefined, elem, 2251 CallJS(call_callable, context, replace_callable, undefined, elem,
2249 var_match_start.value(), string); 2252 var_match_start.value(), string);
2250 2253
2251 Node* const replacement_str = ToString(context, replacement_obj); 2254 Node* const replacement_str = ToString(context, replacement_obj);
2252 StoreFixedArrayElement(res_elems, i, replacement_str); 2255 StoreFixedArrayElement(res_elems, i, replacement_str,
2256 UPDATE_WRITE_BARRIER, 0, mode);
2253 2257
2254 Node* const elem_length = LoadStringLength(elem); 2258 Node* const elem_length = LoadStringLength(elem);
2255 Node* const new_match_start = 2259 Node* const new_match_start =
2256 SmiAdd(var_match_start.value(), elem_length); 2260 SmiAdd(var_match_start.value(), elem_length);
2257 var_match_start.Bind(new_match_start); 2261 var_match_start.Bind(new_match_start);
2258 2262
2259 Goto(&loop_epilogue); 2263 Goto(&loop_epilogue);
2260 } 2264 }
2261 2265
2262 Bind(&loop_epilogue); 2266 Bind(&loop_epilogue);
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2432 } 2436 }
2433 2437
2434 // ES#sec-regexp.prototype-@@replace 2438 // ES#sec-regexp.prototype-@@replace
2435 // RegExp.prototype [ @@replace ] ( string, replaceValue ) 2439 // RegExp.prototype [ @@replace ] ( string, replaceValue )
2436 TF_BUILTIN(RegExpPrototypeReplace, RegExpBuiltinsAssembler) { 2440 TF_BUILTIN(RegExpPrototypeReplace, RegExpBuiltinsAssembler) {
2437 Node* const maybe_receiver = Parameter(0); 2441 Node* const maybe_receiver = Parameter(0);
2438 Node* const maybe_string = Parameter(1); 2442 Node* const maybe_string = Parameter(1);
2439 Node* const replace_value = Parameter(2); 2443 Node* const replace_value = Parameter(2);
2440 Node* const context = Parameter(5); 2444 Node* const context = Parameter(5);
2441 2445
2442 Node* const int_zero = IntPtrConstant(0);
2443
2444 // Ensure {maybe_receiver} is a JSReceiver. 2446 // Ensure {maybe_receiver} is a JSReceiver.
2445 Node* const map = ThrowIfNotJSReceiver( 2447 Node* const map = ThrowIfNotJSReceiver(
2446 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, 2448 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver,
2447 "RegExp.prototype.@@replace"); 2449 "RegExp.prototype.@@replace");
2448 Node* const receiver = maybe_receiver; 2450 Node* const receiver = maybe_receiver;
2449 2451
2450 // Convert {maybe_string} to a String. 2452 // Convert {maybe_string} to a String.
2451 Callable tostring_callable = CodeFactory::ToString(isolate()); 2453 Callable tostring_callable = CodeFactory::ToString(isolate());
2452 Node* const string = CallStub(tostring_callable, context, maybe_string); 2454 Node* const string = CallStub(tostring_callable, context, maybe_string);
2453 2455
(...skipping 11 matching lines...) Expand all
2465 2467
2466 Node* const replace_value_map = LoadMap(replace_value); 2468 Node* const replace_value_map = LoadMap(replace_value);
2467 Branch(IsCallableMap(replace_value_map), &if_iscallable, &checkreplacestring); 2469 Branch(IsCallableMap(replace_value_map), &if_iscallable, &checkreplacestring);
2468 2470
2469 // 3. Does ToString({replace_value}) contain '$'? 2471 // 3. Does ToString({replace_value}) contain '$'?
2470 Bind(&checkreplacestring); 2472 Bind(&checkreplacestring);
2471 { 2473 {
2472 Node* const replace_string = 2474 Node* const replace_string =
2473 CallStub(tostring_callable, context, replace_value); 2475 CallStub(tostring_callable, context, replace_value);
2474 2476
2475 Node* const dollar_char = IntPtrConstant('$'); 2477 Node* const dollar_char = Int32Constant('$');
2476 Node* const smi_minusone = SmiConstant(Smi::FromInt(-1)); 2478 Node* const smi_minusone = SmiConstant(Smi::FromInt(-1));
2477 GotoUnless(SmiEqual(StringIndexOfChar(context, replace_string, dollar_char, 2479 GotoUnless(SmiEqual(StringIndexOfChar(context, replace_string, dollar_char,
2478 int_zero), 2480 SmiConstant(0)),
2479 smi_minusone), 2481 smi_minusone),
2480 &runtime); 2482 &runtime);
2481 2483
2482 Return( 2484 Return(
2483 ReplaceSimpleStringFastPath(context, regexp, string, replace_string)); 2485 ReplaceSimpleStringFastPath(context, regexp, string, replace_string));
2484 } 2486 }
2485 2487
2486 // {regexp} is unmodified and {replace_value} is callable. 2488 // {regexp} is unmodified and {replace_value} is callable.
2487 Bind(&if_iscallable); 2489 Bind(&if_iscallable);
2488 { 2490 {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2544 Bind(&if_matched); 2546 Bind(&if_matched);
2545 { 2547 {
2546 Node* result = 2548 Node* result =
2547 ConstructNewResultFromMatchInfo(context, match_indices, string); 2549 ConstructNewResultFromMatchInfo(context, match_indices, string);
2548 Return(result); 2550 Return(result);
2549 } 2551 }
2550 } 2552 }
2551 2553
2552 } // namespace internal 2554 } // namespace internal
2553 } // namespace v8 2555 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698