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

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

Issue 2745053003: [regexp] Add slow exec stub to reduce code size (Closed)
Patch Set: Created 3 years, 9 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/builtins/builtins.h ('k') | src/interface-descriptors.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/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 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 Node* const pending_exception = 448 Node* const pending_exception =
449 Load(MachineType::AnyTagged(), pending_exception_address); 449 Load(MachineType::AnyTagged(), pending_exception_address);
450 450
451 // If there is no pending exception, a 451 // If there is no pending exception, a
452 // stack overflow (on the backtrack stack) was detected in RegExp code. 452 // stack overflow (on the backtrack stack) was detected in RegExp code.
453 453
454 Label stack_overflow(this), rethrow(this); 454 Label stack_overflow(this), rethrow(this);
455 Branch(IsTheHole(pending_exception), &stack_overflow, &rethrow); 455 Branch(IsTheHole(pending_exception), &stack_overflow, &rethrow);
456 456
457 Bind(&stack_overflow); 457 Bind(&stack_overflow);
458 TailCallRuntime(Runtime::kThrowStackOverflow, context); 458 CallRuntime(Runtime::kThrowStackOverflow, context);
459 Unreachable();
459 460
460 Bind(&rethrow); 461 Bind(&rethrow);
461 TailCallRuntime(Runtime::kRegExpExecReThrow, context); 462 CallRuntime(Runtime::kRegExpExecReThrow, context);
463 Unreachable();
462 } 464 }
463 465
464 Bind(&runtime); 466 Bind(&runtime);
465 { 467 {
466 Node* const result = CallRuntime(Runtime::kRegExpExec, context, regexp, 468 Node* const result = CallRuntime(Runtime::kRegExpExec, context, regexp,
467 string, last_index, match_info); 469 string, last_index, match_info);
468 var_result.Bind(result); 470 var_result.Bind(result);
469 Goto(&out); 471 Goto(&out);
470 } 472 }
471 473
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 Label* if_isunmodified, 731 Label* if_isunmodified,
730 Label* if_ismodified) { 732 Label* if_ismodified) {
731 Node* const native_context = LoadNativeContext(context); 733 Node* const native_context = LoadNativeContext(context);
732 Node* const initial_regexp_result_map = 734 Node* const initial_regexp_result_map =
733 LoadContextElement(native_context, Context::REGEXP_RESULT_MAP_INDEX); 735 LoadContextElement(native_context, Context::REGEXP_RESULT_MAP_INDEX);
734 736
735 Branch(WordEqual(map, initial_regexp_result_map), if_isunmodified, 737 Branch(WordEqual(map, initial_regexp_result_map), if_isunmodified,
736 if_ismodified); 738 if_ismodified);
737 } 739 }
738 740
741 // Slow path stub for RegExpPrototypeExec to decrease code size.
742 TF_BUILTIN(RegExpPrototypeExecSlow, RegExpBuiltinsAssembler) {
743 typedef GenericTagged2Descriptor Descriptor;
744
745 Node* const regexp = Parameter(Descriptor::kFirst);
746 Node* const string = Parameter(Descriptor::kSecond);
747 Node* const context = Parameter(Descriptor::kContext);
748
749 Return(RegExpPrototypeExecBody(context, regexp, string, false));
750 }
751
739 // ES#sec-regexp.prototype.exec 752 // ES#sec-regexp.prototype.exec
740 // RegExp.prototype.exec ( string ) 753 // RegExp.prototype.exec ( string )
741 TF_BUILTIN(RegExpPrototypeExec, RegExpBuiltinsAssembler) { 754 TF_BUILTIN(RegExpPrototypeExec, RegExpBuiltinsAssembler) {
742 Node* const maybe_receiver = Parameter(0); 755 Node* const maybe_receiver = Parameter(0);
743 Node* const maybe_string = Parameter(1); 756 Node* const maybe_string = Parameter(1);
744 Node* const context = Parameter(4); 757 Node* const context = Parameter(4);
745 758
746 // Ensure {maybe_receiver} is a JSRegExp. 759 // Ensure {maybe_receiver} is a JSRegExp.
747 Node* const regexp_map = ThrowIfNotInstanceType( 760 Node* const regexp_map = ThrowIfNotInstanceType(
748 context, maybe_receiver, JS_REGEXP_TYPE, "RegExp.prototype.exec"); 761 context, maybe_receiver, JS_REGEXP_TYPE, "RegExp.prototype.exec");
749 Node* const receiver = maybe_receiver; 762 Node* const receiver = maybe_receiver;
750 763
751 // Convert {maybe_string} to a String. 764 // Convert {maybe_string} to a String.
752 Node* const string = ToString(context, maybe_string); 765 Node* const string = ToString(context, maybe_string);
753 766
754 Label if_isfastpath(this), if_isslowpath(this); 767 Label if_isfastpath(this), if_isslowpath(this);
755 Branch(IsInitialRegExpMap(context, regexp_map), &if_isfastpath, 768 Branch(IsInitialRegExpMap(context, regexp_map), &if_isfastpath,
756 &if_isslowpath); 769 &if_isslowpath);
757 770
758 Bind(&if_isfastpath); 771 Bind(&if_isfastpath);
759 { 772 {
760 Node* const result = 773 Node* const result =
761 RegExpPrototypeExecBody(context, receiver, string, true); 774 RegExpPrototypeExecBody(context, receiver, string, true);
762 Return(result); 775 Return(result);
763 } 776 }
764 777
765 Bind(&if_isslowpath); 778 Bind(&if_isslowpath);
766 { 779 {
767 Node* const result = 780 Handle<Code> code = isolate()->builtins()->RegExpPrototypeExecSlow();
768 RegExpPrototypeExecBody(context, receiver, string, false); 781 const auto desc = GenericTagged2Descriptor(isolate());
782 Callable callable(code, desc);
783
784 Node* const result = CallStub(callable, context, receiver, string);
769 Return(result); 785 Return(result);
770 } 786 }
771 } 787 }
772 788
773 Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context, 789 Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context,
774 Node* const regexp, 790 Node* const regexp,
775 bool is_fastpath) { 791 bool is_fastpath) {
776 Isolate* isolate = this->isolate(); 792 Isolate* isolate = this->isolate();
777 793
778 Node* const int_zero = IntPtrConstant(0); 794 Node* const int_zero = IntPtrConstant(0);
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
1472 Node* RegExpBuiltinsAssembler::RegExpExec(Node* context, Node* regexp, 1488 Node* RegExpBuiltinsAssembler::RegExpExec(Node* context, Node* regexp,
1473 Node* string) { 1489 Node* string) {
1474 Isolate* isolate = this->isolate(); 1490 Isolate* isolate = this->isolate();
1475 1491
1476 Node* const null = NullConstant(); 1492 Node* const null = NullConstant();
1477 1493
1478 Variable var_result(this, MachineRepresentation::kTagged); 1494 Variable var_result(this, MachineRepresentation::kTagged);
1479 Label out(this), if_isfastpath(this), if_isslowpath(this); 1495 Label out(this), if_isfastpath(this), if_isslowpath(this);
1480 1496
1481 Node* const map = LoadMap(regexp); 1497 Node* const map = LoadMap(regexp);
1482 BranchIfFastRegExp(context, map, &if_isfastpath, &if_isslowpath); 1498 BranchIfFastRegExp(context, map, &if_isfastpath, &if_isslowpath);
Igor Sheludko 2017/03/13 16:30:32 I guess it's better to skip this check and jump di
jgruber 2017/03/17 09:51:22 Done.
1483 1499
1484 Bind(&if_isfastpath); 1500 Bind(&if_isfastpath);
1485 { 1501 Unreachable();
1486 Node* const result = RegExpPrototypeExecBody(context, regexp, string, true);
1487 var_result.Bind(result);
1488 Goto(&out);
1489 }
1490 1502
1491 Bind(&if_isslowpath); 1503 Bind(&if_isslowpath);
1492 { 1504 {
1493 // Take the slow path of fetching the exec property, calling it, and 1505 // Take the slow path of fetching the exec property, calling it, and
1494 // verifying its return value. 1506 // verifying its return value.
1495 1507
1496 // Get the exec property. 1508 // Get the exec property.
1497 Node* const name = HeapConstant(isolate->factory()->exec_string()); 1509 Node* const name = HeapConstant(isolate->factory()->exec_string());
1498 Callable getproperty_callable = CodeFactory::GetProperty(isolate); 1510 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
1499 Node* const exec = CallStub(getproperty_callable, context, regexp, name); 1511 Node* const exec = CallStub(getproperty_callable, context, regexp, name);
(...skipping 18 matching lines...) Expand all
1518 MessageTemplate::kInvalidRegExpExecResult, "unused"); 1530 MessageTemplate::kInvalidRegExpExecResult, "unused");
1519 1531
1520 Goto(&out); 1532 Goto(&out);
1521 } 1533 }
1522 1534
1523 Bind(&if_isnotcallable); 1535 Bind(&if_isnotcallable);
1524 { 1536 {
1525 ThrowIfNotInstanceType(context, regexp, JS_REGEXP_TYPE, 1537 ThrowIfNotInstanceType(context, regexp, JS_REGEXP_TYPE,
1526 "RegExp.prototype.exec"); 1538 "RegExp.prototype.exec");
1527 1539
1528 Node* const result = 1540 Handle<Code> code = isolate->builtins()->RegExpPrototypeExecSlow();
1529 RegExpPrototypeExecBody(context, regexp, string, false); 1541 const auto desc = GenericTagged2Descriptor(isolate);
1542 Callable callable(code, desc);
1543
1544 Node* const result = CallStub(callable, context, regexp, string);
1530 var_result.Bind(result); 1545 var_result.Bind(result);
1531 Goto(&out); 1546 Goto(&out);
1532 } 1547 }
1533 } 1548 }
1534 1549
1535 Bind(&out); 1550 Bind(&out);
1536 return var_result.value(); 1551 return var_result.value();
1537 } 1552 }
1538 1553
1539 // ES#sec-regexp.prototype.test 1554 // ES#sec-regexp.prototype.test
(...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after
2821 Bind(&if_matched); 2836 Bind(&if_matched);
2822 { 2837 {
2823 Node* result = 2838 Node* result =
2824 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); 2839 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string);
2825 Return(result); 2840 Return(result);
2826 } 2841 }
2827 } 2842 }
2828 2843
2829 } // namespace internal 2844 } // namespace internal
2830 } // namespace v8 2845 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/interface-descriptors.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698