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

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

Issue 2803603005: [regexp] Fix two more possible shape changes on fast path (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 | test/mjsunit/regress/regress-6210.js » ('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 2017 the V8 project authors. All rights reserved. 1 // Copyright 2017 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-gen.h" 5 #include "src/builtins/builtins-regexp-gen.h"
6 6
7 #include "src/builtins/builtins-constructor-gen.h" 7 #include "src/builtins/builtins-constructor-gen.h"
8 #include "src/builtins/builtins-utils-gen.h" 8 #include "src/builtins/builtins-utils-gen.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 2285 matching lines...) Expand 10 before | Expand all | Expand 10 after
2296 2296
2297 CSA_ASSERT(this, IsFastRegExp(context, regexp)); 2297 CSA_ASSERT(this, IsFastRegExp(context, regexp));
2298 CSA_ASSERT(this, IsString(string)); 2298 CSA_ASSERT(this, IsString(string));
2299 2299
2300 // TODO(jgruber): Even if map checks send us to the fast path, we still need 2300 // TODO(jgruber): Even if map checks send us to the fast path, we still need
2301 // to verify the constructor property and jump to the slow path if it has 2301 // to verify the constructor property and jump to the slow path if it has
2302 // been changed. 2302 // been changed.
2303 2303
2304 // Convert {maybe_limit} to a uint32, capping at the maximal smi value. 2304 // Convert {maybe_limit} to a uint32, capping at the maximal smi value.
2305 Variable var_limit(this, MachineRepresentation::kTagged); 2305 Variable var_limit(this, MachineRepresentation::kTagged);
2306 Label if_limitissmimax(this), limit_done(this); 2306 Label if_limitissmimax(this), limit_done(this), runtime(this);
2307 2307
2308 GotoIf(IsUndefined(maybe_limit), &if_limitissmimax); 2308 GotoIf(IsUndefined(maybe_limit), &if_limitissmimax);
2309 2309
2310 Node* const limit = ToUint32(context, maybe_limit);
Camillo Bruni 2017/04/06 14:54:15 future-nit: something like ToUint32(..., &was_fast
jgruber 2017/04/06 15:21:12 Sounds reasonable. I want to keep this CL small an
2310 { 2311 {
2311 Node* const limit = ToUint32(context, maybe_limit); 2312 // ToUint32(limit) could potentially change the shape of the RegExp
2313 // object. Recheck that we are still on the fast path and bail to runtime
2314 // otherwise.
2315 {
2316 Label next(this);
2317 BranchIfFastRegExp(context, regexp, LoadMap(regexp), &next, &runtime);
Camillo Bruni 2017/04/06 14:54:15 site-note: You'd probably be better off with a Got
jgruber 2017/04/06 15:21:12 Acknowledged.
2318 Bind(&next);
2319 }
2320
2312 GotoIfNot(TaggedIsSmi(limit), &if_limitissmimax); 2321 GotoIfNot(TaggedIsSmi(limit), &if_limitissmimax);
2313 2322
2314 var_limit.Bind(limit); 2323 var_limit.Bind(limit);
2315 Goto(&limit_done); 2324 Goto(&limit_done);
2316 } 2325 }
2317 2326
2318 Bind(&if_limitissmimax); 2327 Bind(&if_limitissmimax);
2319 { 2328 {
2320 // TODO(jgruber): In this case, we can probably avoid generation of limit 2329 // TODO(jgruber): In this case, we can probably avoid generation of limit
2321 // checks in Generate_RegExpPrototypeSplitBody. 2330 // checks in Generate_RegExpPrototypeSplitBody.
2322 var_limit.Bind(SmiConstant(Smi::kMaxValue)); 2331 var_limit.Bind(SmiConstant(Smi::kMaxValue));
2323 Goto(&limit_done); 2332 Goto(&limit_done);
2324 } 2333 }
2325 2334
2326 Bind(&limit_done); 2335 Bind(&limit_done);
2327 { 2336 {
2328 Node* const limit = var_limit.value(); 2337 Node* const limit = var_limit.value();
2329 RegExpPrototypeSplitBody(context, regexp, string, limit); 2338 RegExpPrototypeSplitBody(context, regexp, string, limit);
2330 } 2339 }
2340
2341 Bind(&runtime);
2342 {
2343 // The runtime call passes in limit to ensure the second ToUint32(limit)
2344 // call is not observable.
2345 CSA_ASSERT(this, IsHeapNumberMap(LoadReceiverMap(limit)));
Camillo Bruni 2017/04/06 14:54:15 nit: CSA_ASSERT(this, IsNumber(limit));
jgruber 2017/04/06 15:21:12 Can do in a follow-up (don't want to touch c-s-a.{
2346 Return(CallRuntime(Runtime::kRegExpSplit, context, regexp, string, limit));
2347 }
2331 } 2348 }
2332 2349
2333 // ES#sec-regexp.prototype-@@split 2350 // ES#sec-regexp.prototype-@@split
2334 // RegExp.prototype [ @@split ] ( string, limit ) 2351 // RegExp.prototype [ @@split ] ( string, limit )
2335 TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) { 2352 TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) {
2336 Node* const maybe_receiver = Parameter(Descriptor::kReceiver); 2353 Node* const maybe_receiver = Parameter(Descriptor::kReceiver);
2337 Node* const maybe_string = Parameter(Descriptor::kString); 2354 Node* const maybe_string = Parameter(Descriptor::kString);
2338 Node* const maybe_limit = Parameter(Descriptor::kLimit); 2355 Node* const maybe_limit = Parameter(Descriptor::kLimit);
2339 Node* const context = Parameter(Descriptor::kContext); 2356 Node* const context = Parameter(Descriptor::kContext);
2340 2357
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
2692 GotoIf(TaggedIsSmi(replace_value), &checkreplacestring); 2709 GotoIf(TaggedIsSmi(replace_value), &checkreplacestring);
2693 Branch(IsCallableMap(LoadMap(replace_value)), &if_iscallable, 2710 Branch(IsCallableMap(LoadMap(replace_value)), &if_iscallable,
2694 &checkreplacestring); 2711 &checkreplacestring);
2695 2712
2696 // 3. Does ToString({replace_value}) contain '$'? 2713 // 3. Does ToString({replace_value}) contain '$'?
2697 Bind(&checkreplacestring); 2714 Bind(&checkreplacestring);
2698 { 2715 {
2699 Node* const replace_string = 2716 Node* const replace_string =
2700 CallBuiltin(Builtins::kToString, context, replace_value); 2717 CallBuiltin(Builtins::kToString, context, replace_value);
2701 2718
2719 // ToString(replaceValue) could potentially change the shape of the RegExp
2720 // object. Recheck that we are still on the fast path and bail to runtime
2721 // otherwise.
2722 {
2723 Label next(this);
2724 BranchIfFastRegExp(context, regexp, LoadMap(regexp), &next, &runtime);
2725 Bind(&next);
2726 }
2727
2702 Node* const dollar_string = HeapConstant( 2728 Node* const dollar_string = HeapConstant(
2703 isolate()->factory()->LookupSingleCharacterStringFromCode('$')); 2729 isolate()->factory()->LookupSingleCharacterStringFromCode('$'));
2704 Node* const dollar_ix = 2730 Node* const dollar_ix =
2705 CallBuiltin(Builtins::kStringIndexOf, context, replace_string, 2731 CallBuiltin(Builtins::kStringIndexOf, context, replace_string,
2706 dollar_string, SmiConstant(0)); 2732 dollar_string, SmiConstant(0));
2707 GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime); 2733 GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime);
2708 2734
2709 Return( 2735 Return(
2710 ReplaceSimpleStringFastPath(context, regexp, string, replace_string)); 2736 ReplaceSimpleStringFastPath(context, regexp, string, replace_string));
2711 } 2737 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2811 Bind(&if_matched); 2837 Bind(&if_matched);
2812 { 2838 {
2813 Node* result = 2839 Node* result =
2814 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); 2840 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string);
2815 Return(result); 2841 Return(result);
2816 } 2842 }
2817 } 2843 }
2818 2844
2819 } // namespace internal 2845 } // namespace internal
2820 } // namespace v8 2846 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-6210.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698