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

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: Add fast-path before ToUint32 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 2277 matching lines...) Expand 10 before | Expand all | Expand 10 after
2288 Node* const context = Parameter(Descriptor::kContext); 2288 Node* const context = Parameter(Descriptor::kContext);
2289 2289
2290 CSA_ASSERT(this, IsFastRegExp(context, regexp)); 2290 CSA_ASSERT(this, IsFastRegExp(context, regexp));
2291 CSA_ASSERT(this, IsString(string)); 2291 CSA_ASSERT(this, IsString(string));
2292 2292
2293 // TODO(jgruber): Even if map checks send us to the fast path, we still need 2293 // TODO(jgruber): Even if map checks send us to the fast path, we still need
2294 // to verify the constructor property and jump to the slow path if it has 2294 // to verify the constructor property and jump to the slow path if it has
2295 // been changed. 2295 // been changed.
2296 2296
2297 // Convert {maybe_limit} to a uint32, capping at the maximal smi value. 2297 // Convert {maybe_limit} to a uint32, capping at the maximal smi value.
2298 Variable var_limit(this, MachineRepresentation::kTagged); 2298 Variable var_limit(this, MachineRepresentation::kTagged, maybe_limit);
2299 Label if_limitissmimax(this), limit_done(this); 2299 Label if_limitissmimax(this), limit_done(this), runtime(this);
2300 2300
2301 GotoIf(IsUndefined(maybe_limit), &if_limitissmimax); 2301 GotoIf(IsUndefined(maybe_limit), &if_limitissmimax);
2302 GotoIf(TaggedIsPositiveSmi(maybe_limit), &limit_done);
2302 2303
2304 Node* const limit = ToUint32(context, maybe_limit);
2303 { 2305 {
2304 Node* const limit = ToUint32(context, maybe_limit); 2306 // ToUint32(limit) could potentially change the shape of the RegExp
2307 // object. Recheck that we are still on the fast path and bail to runtime
2308 // otherwise.
2309 {
2310 Label next(this);
2311 BranchIfFastRegExp(context, regexp, LoadMap(regexp), &next, &runtime);
2312 Bind(&next);
2313 }
2314
2305 GotoIfNot(TaggedIsSmi(limit), &if_limitissmimax); 2315 GotoIfNot(TaggedIsSmi(limit), &if_limitissmimax);
2306 2316
2307 var_limit.Bind(limit); 2317 var_limit.Bind(limit);
2308 Goto(&limit_done); 2318 Goto(&limit_done);
2309 } 2319 }
2310 2320
2311 BIND(&if_limitissmimax); 2321 BIND(&if_limitissmimax);
2312 { 2322 {
2313 // TODO(jgruber): In this case, we can probably avoid generation of limit 2323 // TODO(jgruber): In this case, we can probably avoid generation of limit
2314 // checks in Generate_RegExpPrototypeSplitBody. 2324 // checks in Generate_RegExpPrototypeSplitBody.
2315 var_limit.Bind(SmiConstant(Smi::kMaxValue)); 2325 var_limit.Bind(SmiConstant(Smi::kMaxValue));
2316 Goto(&limit_done); 2326 Goto(&limit_done);
2317 } 2327 }
2318 2328
2319 BIND(&limit_done); 2329 BIND(&limit_done);
2320 { 2330 {
2321 Node* const limit = var_limit.value(); 2331 Node* const limit = var_limit.value();
2322 RegExpPrototypeSplitBody(context, regexp, string, limit); 2332 RegExpPrototypeSplitBody(context, regexp, string, limit);
2323 } 2333 }
2334
2335 Bind(&runtime);
2336 {
2337 // The runtime call passes in limit to ensure the second ToUint32(limit)
2338 // call is not observable.
2339 CSA_ASSERT(this, IsHeapNumberMap(LoadReceiverMap(limit)));
2340 Return(CallRuntime(Runtime::kRegExpSplit, context, regexp, string, limit));
2341 }
2324 } 2342 }
2325 2343
2326 // ES#sec-regexp.prototype-@@split 2344 // ES#sec-regexp.prototype-@@split
2327 // RegExp.prototype [ @@split ] ( string, limit ) 2345 // RegExp.prototype [ @@split ] ( string, limit )
2328 TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) { 2346 TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) {
2329 Node* const maybe_receiver = Parameter(Descriptor::kReceiver); 2347 Node* const maybe_receiver = Parameter(Descriptor::kReceiver);
2330 Node* const maybe_string = Parameter(Descriptor::kString); 2348 Node* const maybe_string = Parameter(Descriptor::kString);
2331 Node* const maybe_limit = Parameter(Descriptor::kLimit); 2349 Node* const maybe_limit = Parameter(Descriptor::kLimit);
2332 Node* const context = Parameter(Descriptor::kContext); 2350 Node* const context = Parameter(Descriptor::kContext);
2333 2351
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
2685 GotoIf(TaggedIsSmi(replace_value), &checkreplacestring); 2703 GotoIf(TaggedIsSmi(replace_value), &checkreplacestring);
2686 Branch(IsCallableMap(LoadMap(replace_value)), &if_iscallable, 2704 Branch(IsCallableMap(LoadMap(replace_value)), &if_iscallable,
2687 &checkreplacestring); 2705 &checkreplacestring);
2688 2706
2689 // 3. Does ToString({replace_value}) contain '$'? 2707 // 3. Does ToString({replace_value}) contain '$'?
2690 BIND(&checkreplacestring); 2708 BIND(&checkreplacestring);
2691 { 2709 {
2692 Node* const replace_string = 2710 Node* const replace_string =
2693 CallBuiltin(Builtins::kToString, context, replace_value); 2711 CallBuiltin(Builtins::kToString, context, replace_value);
2694 2712
2713 // ToString(replaceValue) could potentially change the shape of the RegExp
2714 // object. Recheck that we are still on the fast path and bail to runtime
2715 // otherwise.
2716 {
2717 Label next(this);
2718 BranchIfFastRegExp(context, regexp, LoadMap(regexp), &next, &runtime);
2719 Bind(&next);
2720 }
2721
2695 Node* const dollar_string = HeapConstant( 2722 Node* const dollar_string = HeapConstant(
2696 isolate()->factory()->LookupSingleCharacterStringFromCode('$')); 2723 isolate()->factory()->LookupSingleCharacterStringFromCode('$'));
2697 Node* const dollar_ix = 2724 Node* const dollar_ix =
2698 CallBuiltin(Builtins::kStringIndexOf, context, replace_string, 2725 CallBuiltin(Builtins::kStringIndexOf, context, replace_string,
2699 dollar_string, SmiConstant(0)); 2726 dollar_string, SmiConstant(0));
2700 GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime); 2727 GotoIfNot(SmiEqual(dollar_ix, SmiConstant(-1)), &runtime);
2701 2728
2702 Return( 2729 Return(
2703 ReplaceSimpleStringFastPath(context, regexp, string, replace_string)); 2730 ReplaceSimpleStringFastPath(context, regexp, string, replace_string));
2704 } 2731 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2804 BIND(&if_matched); 2831 BIND(&if_matched);
2805 { 2832 {
2806 Node* result = 2833 Node* result =
2807 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); 2834 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string);
2808 Return(result); 2835 Return(result);
2809 } 2836 }
2810 } 2837 }
2811 2838
2812 } // namespace internal 2839 } // namespace internal
2813 } // namespace v8 2840 } // 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