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

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

Issue 2818683005: [regexp] Avoid side effects between map load and fast path check (Closed)
Patch Set: Created 3 years, 8 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 | « no previous file | no next file » | 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/builtins/builtins-regexp.h" 5 #include "src/builtins/builtins-regexp.h"
6 6
7 #include "src/builtins/builtins-constructor.h" 7 #include "src/builtins/builtins-constructor.h"
8 #include "src/builtins/builtins-utils.h" 8 #include "src/builtins/builtins-utils.h"
9 #include "src/builtins/builtins.h" 9 #include "src/builtins/builtins.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 } 507 }
508 508
509 // ES#sec-regexp.prototype.exec 509 // ES#sec-regexp.prototype.exec
510 // RegExp.prototype.exec ( string ) 510 // RegExp.prototype.exec ( string )
511 TF_BUILTIN(RegExpPrototypeExec, RegExpBuiltinsAssembler) { 511 TF_BUILTIN(RegExpPrototypeExec, RegExpBuiltinsAssembler) {
512 Node* const maybe_receiver = Parameter(0); 512 Node* const maybe_receiver = Parameter(0);
513 Node* const maybe_string = Parameter(1); 513 Node* const maybe_string = Parameter(1);
514 Node* const context = Parameter(4); 514 Node* const context = Parameter(4);
515 515
516 // Ensure {maybe_receiver} is a JSRegExp. 516 // Ensure {maybe_receiver} is a JSRegExp.
517 Node* const regexp_map = ThrowIfNotInstanceType( 517 ThrowIfNotInstanceType(context, maybe_receiver, JS_REGEXP_TYPE,
518 context, maybe_receiver, JS_REGEXP_TYPE, "RegExp.prototype.exec"); 518 "RegExp.prototype.exec");
519 Node* const receiver = maybe_receiver; 519 Node* const receiver = maybe_receiver;
520 520
521 // Convert {maybe_string} to a String. 521 // Convert {maybe_string} to a String.
522 Node* const string = ToString(context, maybe_string); 522 Node* const string = ToString(context, maybe_string);
523 523
524 Label if_isfastpath(this), if_isslowpath(this); 524 Label if_isfastpath(this), if_isslowpath(this);
525 Branch(IsInitialRegExpMap(context, receiver, regexp_map), &if_isfastpath, 525 Branch(IsInitialRegExpMap(context, receiver, LoadMap(receiver)),
526 &if_isslowpath); 526 &if_isfastpath, &if_isslowpath);
527 527
528 Bind(&if_isfastpath); 528 Bind(&if_isfastpath);
529 { 529 {
530 Node* const result = 530 Node* const result =
531 RegExpPrototypeExecBody(context, receiver, string, true); 531 RegExpPrototypeExecBody(context, receiver, string, true);
532 Return(result); 532 Return(result);
533 } 533 }
534 534
535 Bind(&if_isslowpath); 535 Bind(&if_isslowpath);
536 { 536 {
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 } 1308 }
1309 1309
1310 // ES#sec-regexp.prototype.test 1310 // ES#sec-regexp.prototype.test
1311 // RegExp.prototype.test ( S ) 1311 // RegExp.prototype.test ( S )
1312 TF_BUILTIN(RegExpPrototypeTest, RegExpBuiltinsAssembler) { 1312 TF_BUILTIN(RegExpPrototypeTest, RegExpBuiltinsAssembler) {
1313 Node* const maybe_receiver = Parameter(0); 1313 Node* const maybe_receiver = Parameter(0);
1314 Node* const maybe_string = Parameter(1); 1314 Node* const maybe_string = Parameter(1);
1315 Node* const context = Parameter(4); 1315 Node* const context = Parameter(4);
1316 1316
1317 // Ensure {maybe_receiver} is a JSReceiver. 1317 // Ensure {maybe_receiver} is a JSReceiver.
1318 Node* const map = ThrowIfNotJSReceiver( 1318 ThrowIfNotJSReceiver(context, maybe_receiver,
1319 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, 1319 MessageTemplate::kIncompatibleMethodReceiver,
1320 "RegExp.prototype.test"); 1320 "RegExp.prototype.test");
1321 Node* const receiver = maybe_receiver; 1321 Node* const receiver = maybe_receiver;
1322 1322
1323 // Convert {maybe_string} to a String. 1323 // Convert {maybe_string} to a String.
1324 Node* const string = ToString(context, maybe_string); 1324 Node* const string = ToString(context, maybe_string);
1325 1325
1326 Label fast_path(this), slow_path(this); 1326 Label fast_path(this), slow_path(this);
1327 BranchIfFastRegExp(context, receiver, map, &fast_path, &slow_path); 1327 BranchIfFastRegExp(context, receiver, LoadMap(receiver), &fast_path,
1328 &slow_path);
1328 1329
1329 Bind(&fast_path); 1330 Bind(&fast_path);
1330 { 1331 {
1331 Label if_didnotmatch(this); 1332 Label if_didnotmatch(this);
1332 RegExpPrototypeExecBodyWithoutResult(context, receiver, string, 1333 RegExpPrototypeExecBodyWithoutResult(context, receiver, string,
1333 &if_didnotmatch, true); 1334 &if_didnotmatch, true);
1334 Return(TrueConstant()); 1335 Return(TrueConstant());
1335 1336
1336 Bind(&if_didnotmatch); 1337 Bind(&if_didnotmatch);
1337 Return(FalseConstant()); 1338 Return(FalseConstant());
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1717 } 1718 }
1718 1719
1719 // ES#sec-regexp.prototype-@@match 1720 // ES#sec-regexp.prototype-@@match
1720 // RegExp.prototype [ @@match ] ( string ) 1721 // RegExp.prototype [ @@match ] ( string )
1721 TF_BUILTIN(RegExpPrototypeMatch, RegExpBuiltinsAssembler) { 1722 TF_BUILTIN(RegExpPrototypeMatch, RegExpBuiltinsAssembler) {
1722 Node* const maybe_receiver = Parameter(0); 1723 Node* const maybe_receiver = Parameter(0);
1723 Node* const maybe_string = Parameter(1); 1724 Node* const maybe_string = Parameter(1);
1724 Node* const context = Parameter(4); 1725 Node* const context = Parameter(4);
1725 1726
1726 // Ensure {maybe_receiver} is a JSReceiver. 1727 // Ensure {maybe_receiver} is a JSReceiver.
1727 Node* const map = ThrowIfNotJSReceiver( 1728 ThrowIfNotJSReceiver(context, maybe_receiver,
1728 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, 1729 MessageTemplate::kIncompatibleMethodReceiver,
1729 "RegExp.prototype.@@match"); 1730 "RegExp.prototype.@@match");
1730 Node* const receiver = maybe_receiver; 1731 Node* const receiver = maybe_receiver;
1731 1732
1732 // Convert {maybe_string} to a String. 1733 // Convert {maybe_string} to a String.
1733 Node* const string = ToString(context, maybe_string); 1734 Node* const string = ToString(context, maybe_string);
1734 1735
1735 Label fast_path(this), slow_path(this); 1736 Label fast_path(this), slow_path(this);
1736 BranchIfFastRegExp(context, receiver, map, &fast_path, &slow_path); 1737 BranchIfFastRegExp(context, receiver, LoadMap(receiver), &fast_path,
1738 &slow_path);
1737 1739
1738 Bind(&fast_path); 1740 Bind(&fast_path);
1739 RegExpPrototypeMatchBody(context, receiver, string, true); 1741 RegExpPrototypeMatchBody(context, receiver, string, true);
1740 1742
1741 Bind(&slow_path); 1743 Bind(&slow_path);
1742 RegExpPrototypeMatchBody(context, receiver, string, false); 1744 RegExpPrototypeMatchBody(context, receiver, string, false);
1743 } 1745 }
1744 1746
1745 void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast( 1747 void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast(
1746 Node* const context, Node* const regexp, Node* const string) { 1748 Node* const context, Node* const regexp, Node* const string) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1842 } 1844 }
1843 1845
1844 // ES#sec-regexp.prototype-@@search 1846 // ES#sec-regexp.prototype-@@search
1845 // RegExp.prototype [ @@search ] ( string ) 1847 // RegExp.prototype [ @@search ] ( string )
1846 TF_BUILTIN(RegExpPrototypeSearch, RegExpBuiltinsAssembler) { 1848 TF_BUILTIN(RegExpPrototypeSearch, RegExpBuiltinsAssembler) {
1847 Node* const maybe_receiver = Parameter(0); 1849 Node* const maybe_receiver = Parameter(0);
1848 Node* const maybe_string = Parameter(1); 1850 Node* const maybe_string = Parameter(1);
1849 Node* const context = Parameter(4); 1851 Node* const context = Parameter(4);
1850 1852
1851 // Ensure {maybe_receiver} is a JSReceiver. 1853 // Ensure {maybe_receiver} is a JSReceiver.
1852 Node* const map = ThrowIfNotJSReceiver( 1854 ThrowIfNotJSReceiver(context, maybe_receiver,
1853 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, 1855 MessageTemplate::kIncompatibleMethodReceiver,
1854 "RegExp.prototype.@@search"); 1856 "RegExp.prototype.@@search");
1855 Node* const receiver = maybe_receiver; 1857 Node* const receiver = maybe_receiver;
1856 1858
1857 // Convert {maybe_string} to a String. 1859 // Convert {maybe_string} to a String.
1858 Node* const string = ToString(context, maybe_string); 1860 Node* const string = ToString(context, maybe_string);
1859 1861
1860 Label fast_path(this), slow_path(this); 1862 Label fast_path(this), slow_path(this);
1861 BranchIfFastRegExp(context, receiver, map, &fast_path, &slow_path); 1863 BranchIfFastRegExp(context, receiver, LoadMap(receiver), &fast_path,
1864 &slow_path);
1862 1865
1863 Bind(&fast_path); 1866 Bind(&fast_path);
1864 RegExpPrototypeSearchBodyFast(context, receiver, string); 1867 RegExpPrototypeSearchBodyFast(context, receiver, string);
1865 1868
1866 Bind(&slow_path); 1869 Bind(&slow_path);
1867 RegExpPrototypeSearchBodySlow(context, receiver, string); 1870 RegExpPrototypeSearchBodySlow(context, receiver, string);
1868 } 1871 }
1869 1872
1870 // Generates the fast path for @@split. {regexp} is an unmodified JSRegExp, 1873 // Generates the fast path for @@split. {regexp} is an unmodified JSRegExp,
1871 // {string} is a String, and {limit} is a Smi. 1874 // {string} is a String, and {limit} is a Smi.
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
2178 2181
2179 // ES#sec-regexp.prototype-@@split 2182 // ES#sec-regexp.prototype-@@split
2180 // RegExp.prototype [ @@split ] ( string, limit ) 2183 // RegExp.prototype [ @@split ] ( string, limit )
2181 TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) { 2184 TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) {
2182 Node* const maybe_receiver = Parameter(0); 2185 Node* const maybe_receiver = Parameter(0);
2183 Node* const maybe_string = Parameter(1); 2186 Node* const maybe_string = Parameter(1);
2184 Node* const maybe_limit = Parameter(2); 2187 Node* const maybe_limit = Parameter(2);
2185 Node* const context = Parameter(5); 2188 Node* const context = Parameter(5);
2186 2189
2187 // Ensure {maybe_receiver} is a JSReceiver. 2190 // Ensure {maybe_receiver} is a JSReceiver.
2188 Node* const map = ThrowIfNotJSReceiver( 2191 ThrowIfNotJSReceiver(context, maybe_receiver,
2189 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, 2192 MessageTemplate::kIncompatibleMethodReceiver,
2190 "RegExp.prototype.@@split"); 2193 "RegExp.prototype.@@split");
2191 Node* const receiver = maybe_receiver; 2194 Node* const receiver = maybe_receiver;
2192 2195
2193 // Convert {maybe_string} to a String. 2196 // Convert {maybe_string} to a String.
2194 Node* const string = ToString(context, maybe_string); 2197 Node* const string = ToString(context, maybe_string);
2195 2198
2196 Label stub(this), runtime(this, Label::kDeferred); 2199 Label stub(this), runtime(this, Label::kDeferred);
2197 BranchIfFastRegExp(context, receiver, map, &stub, &runtime); 2200 BranchIfFastRegExp(context, receiver, LoadMap(receiver), &stub, &runtime);
2198 2201
2199 Bind(&stub); 2202 Bind(&stub);
2200 Callable split_callable = CodeFactory::RegExpSplit(isolate()); 2203 Callable split_callable = CodeFactory::RegExpSplit(isolate());
2201 Return(CallStub(split_callable, context, receiver, string, maybe_limit)); 2204 Return(CallStub(split_callable, context, receiver, string, maybe_limit));
2202 2205
2203 Bind(&runtime); 2206 Bind(&runtime);
2204 Return(CallRuntime(Runtime::kRegExpSplit, context, receiver, string, 2207 Return(CallRuntime(Runtime::kRegExpSplit, context, receiver, string,
2205 maybe_limit)); 2208 maybe_limit));
2206 } 2209 }
2207 2210
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
2602 // } 2605 // }
2603 // } else { 2606 // } else {
2604 // if (replace.contains("$")) { 2607 // if (replace.contains("$")) {
2605 // CallRuntime(RegExpReplace) 2608 // CallRuntime(RegExpReplace)
2606 // } else { 2609 // } else {
2607 // ReplaceSimpleStringFastPath() // Bails to runtime for global regexps. 2610 // ReplaceSimpleStringFastPath() // Bails to runtime for global regexps.
2608 // } 2611 // }
2609 // } 2612 // }
2610 2613
2611 // Ensure {maybe_receiver} is a JSReceiver. 2614 // Ensure {maybe_receiver} is a JSReceiver.
2612 Node* const map = ThrowIfNotJSReceiver( 2615 ThrowIfNotJSReceiver(context, maybe_receiver,
2613 context, maybe_receiver, MessageTemplate::kIncompatibleMethodReceiver, 2616 MessageTemplate::kIncompatibleMethodReceiver,
2614 "RegExp.prototype.@@replace"); 2617 "RegExp.prototype.@@replace");
2615 Node* const receiver = maybe_receiver; 2618 Node* const receiver = maybe_receiver;
2616 2619
2617 // Convert {maybe_string} to a String. 2620 // Convert {maybe_string} to a String.
2618 Callable tostring_callable = CodeFactory::ToString(isolate()); 2621 Callable tostring_callable = CodeFactory::ToString(isolate());
2619 Node* const string = CallStub(tostring_callable, context, maybe_string); 2622 Node* const string = CallStub(tostring_callable, context, maybe_string);
2620 2623
2621 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance? 2624 // Fast-path checks: 1. Is the {receiver} an unmodified JSRegExp instance?
2622 Label stub(this), runtime(this, Label::kDeferred); 2625 Label stub(this), runtime(this, Label::kDeferred);
2623 BranchIfFastRegExp(context, receiver, map, &stub, &runtime); 2626 BranchIfFastRegExp(context, receiver, LoadMap(receiver), &stub, &runtime);
2624 2627
2625 Bind(&stub); 2628 Bind(&stub);
2626 Callable replace_callable = CodeFactory::RegExpReplace(isolate()); 2629 Callable replace_callable = CodeFactory::RegExpReplace(isolate());
2627 Return(CallStub(replace_callable, context, receiver, string, replace_value)); 2630 Return(CallStub(replace_callable, context, receiver, string, replace_value));
2628 2631
2629 Bind(&runtime); 2632 Bind(&runtime);
2630 Return(CallRuntime(Runtime::kRegExpReplace, context, receiver, string, 2633 Return(CallRuntime(Runtime::kRegExpReplace, context, receiver, string,
2631 replace_value)); 2634 replace_value));
2632 } 2635 }
2633 2636
(...skipping 24 matching lines...) Expand all
2658 Bind(&if_matched); 2661 Bind(&if_matched);
2659 { 2662 {
2660 Node* result = 2663 Node* result =
2661 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); 2664 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string);
2662 Return(result); 2665 Return(result);
2663 } 2666 }
2664 } 2667 }
2665 2668
2666 } // namespace internal 2669 } // namespace internal
2667 } // namespace v8 2670 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698