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 2527963002: [regexp] Migrate @@match to TurboFan (Closed)
Patch Set: Adapt arguments 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
« no previous file with comments | « src/builtins/builtins.h ('k') | 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-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 7
8 #include "src/code-factory.h" 8 #include "src/code-factory.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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 Node* const proto_map = a->LoadMap(a->LoadMapPrototype(map)); 542 Node* const proto_map = a->LoadMap(a->LoadMapPrototype(map));
543 Node* const proto_has_initialmap = 543 Node* const proto_has_initialmap =
544 a->WordEqual(proto_map, initial_proto_initial_map); 544 a->WordEqual(proto_map, initial_proto_initial_map);
545 545
546 // TODO(ishell): Update this check once map changes for constant field 546 // TODO(ishell): Update this check once map changes for constant field
547 // tracking are landing. 547 // tracking are landing.
548 548
549 a->Branch(proto_has_initialmap, if_isunmodified, if_ismodified); 549 a->Branch(proto_has_initialmap, if_isunmodified, if_ismodified);
550 } 550 }
551 551
552 void BranchIfFastRegExpResult(CodeStubAssembler* a, Node* context, Node* map,
553 CLabel* if_isunmodified, CLabel* if_ismodified) {
554 Node* const native_context = a->LoadNativeContext(context);
555 Node* const initial_regexp_result_map =
556 a->LoadContextElement(native_context, Context::REGEXP_RESULT_MAP_INDEX);
557
558 a->Branch(a->WordEqual(map, initial_regexp_result_map), if_isunmodified,
559 if_ismodified);
560 }
561
552 } // namespace 562 } // namespace
553 563
554 void Builtins::Generate_RegExpPrototypeFlagsGetter(CodeAssemblerState* state) { 564 void Builtins::Generate_RegExpPrototypeFlagsGetter(CodeAssemblerState* state) {
555 CodeStubAssembler a(state); 565 CodeStubAssembler a(state);
556 566
557 Node* const receiver = a.Parameter(0); 567 Node* const receiver = a.Parameter(0);
558 Node* const context = a.Parameter(3); 568 Node* const context = a.Parameter(3);
559 569
560 Isolate* isolate = a.isolate(); 570 Isolate* isolate = a.isolate();
561 Node* const int_zero = a.IntPtrConstant(0); 571 Node* const int_zero = a.IntPtrConstant(0);
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 Node* FastFlagGetter(CodeStubAssembler* a, Node* const regexp, 766 Node* FastFlagGetter(CodeStubAssembler* a, Node* const regexp,
757 JSRegExp::Flag flag) { 767 JSRegExp::Flag flag) {
758 Node* const smi_zero = a->SmiConstant(Smi::kZero); 768 Node* const smi_zero = a->SmiConstant(Smi::kZero);
759 Node* const flags = a->LoadObjectField(regexp, JSRegExp::kFlagsOffset); 769 Node* const flags = a->LoadObjectField(regexp, JSRegExp::kFlagsOffset);
760 Node* const mask = a->SmiConstant(Smi::FromInt(flag)); 770 Node* const mask = a->SmiConstant(Smi::FromInt(flag));
761 Node* const is_flag_set = a->WordNotEqual(a->WordAnd(flags, mask), smi_zero); 771 Node* const is_flag_set = a->WordNotEqual(a->WordAnd(flags, mask), smi_zero);
762 772
763 return is_flag_set; 773 return is_flag_set;
764 } 774 }
765 775
776 // Load through the GetProperty stub.
777 compiler::Node* SlowFlagGetter(CodeStubAssembler* a,
778 compiler::Node* const context,
779 compiler::Node* const regexp,
780 JSRegExp::Flag flag) {
781 Factory* factory = a->isolate()->factory();
782
783 CLabel out(a);
784 CVariable var_result(a, MachineType::PointerRepresentation());
785
786 Node* name;
787
788 switch (flag) {
789 case JSRegExp::kGlobal:
790 name = a->HeapConstant(factory->global_string());
791 break;
792 case JSRegExp::kIgnoreCase:
793 name = a->HeapConstant(factory->ignoreCase_string());
794 break;
795 case JSRegExp::kMultiline:
796 name = a->HeapConstant(factory->multiline_string());
797 break;
798 case JSRegExp::kSticky:
799 name = a->HeapConstant(factory->sticky_string());
800 break;
801 case JSRegExp::kUnicode:
802 name = a->HeapConstant(factory->unicode_string());
803 break;
804 default:
805 UNREACHABLE();
806 }
807
808 Callable getproperty_callable = CodeFactory::GetProperty(a->isolate());
809 Node* const value = a->CallStub(getproperty_callable, context, regexp, name);
810
811 CLabel if_true(a), if_false(a);
812 a->BranchIfToBooleanIsTrue(value, &if_true, &if_false);
813
814 a->Bind(&if_true);
815 {
816 var_result.Bind(a->IntPtrConstant(1));
817 a->Goto(&out);
818 }
819
820 a->Bind(&if_false);
821 {
822 var_result.Bind(a->IntPtrConstant(0));
823 a->Goto(&out);
824 }
825
826 a->Bind(&out);
827 return var_result.value();
828 }
829
766 void Generate_FlagGetter(CodeStubAssembler* a, JSRegExp::Flag flag, 830 void Generate_FlagGetter(CodeStubAssembler* a, JSRegExp::Flag flag,
767 v8::Isolate::UseCounterFeature counter, 831 v8::Isolate::UseCounterFeature counter,
768 const char* method_name) { 832 const char* method_name) {
769 Node* const receiver = a->Parameter(0); 833 Node* const receiver = a->Parameter(0);
770 Node* const context = a->Parameter(3); 834 Node* const context = a->Parameter(3);
771 835
772 Isolate* isolate = a->isolate(); 836 Isolate* isolate = a->isolate();
773 837
774 // Check whether we have an unmodified regexp instance. 838 // Check whether we have an unmodified regexp instance.
775 CLabel if_isunmodifiedjsregexp(a), 839 CLabel if_isunmodifiedjsregexp(a),
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 1106
1043 // Call exec. 1107 // Call exec.
1044 Node* const match_indices = RegExpExec(&a, context, receiver, string); 1108 Node* const match_indices = RegExpExec(&a, context, receiver, string);
1045 1109
1046 // Return true iff exec matched successfully. 1110 // Return true iff exec matched successfully.
1047 Node* const result = a.Select(a.WordEqual(match_indices, a.NullConstant()), 1111 Node* const result = a.Select(a.WordEqual(match_indices, a.NullConstant()),
1048 a.FalseConstant(), a.TrueConstant()); 1112 a.FalseConstant(), a.TrueConstant());
1049 a.Return(result); 1113 a.Return(result);
1050 } 1114 }
1051 1115
1116 namespace {
1117
1118 Node* AdvanceStringIndex(CodeStubAssembler* a, Node* const string,
1119 Node* const index, Node* const is_unicode) {
1120 CVariable var_result(a, MachineRepresentation::kTagged);
1121
1122 // Default to last_index + 1.
1123 Node* const index_plus_one = a->SmiAdd(index, a->SmiConstant(1));
1124 var_result.Bind(index_plus_one);
1125
1126 CLabel if_isunicode(a), out(a);
1127 a->Branch(is_unicode, &if_isunicode, &out);
1128
1129 a->Bind(&if_isunicode);
1130 {
1131 Node* const string_length = a->LoadStringLength(string);
1132 a->GotoUnless(a->SmiLessThan(index_plus_one, string_length), &out);
1133
1134 Node* const lead = a->StringCharCodeAt(string, index);
1135 a->GotoUnless(a->Word32Equal(a->Word32And(lead, a->Int32Constant(0xFC00)),
1136 a->Int32Constant(0xD800)),
1137 &out);
1138
1139 Node* const trail = a->StringCharCodeAt(string, index_plus_one);
1140 a->GotoUnless(a->Word32Equal(a->Word32And(trail, a->Int32Constant(0xFC00)),
1141 a->Int32Constant(0xDC00)),
1142 &out);
1143
1144 // At a surrogate pair, return index + 2.
1145 Node* const index_plus_two = a->SmiAdd(index, a->SmiConstant(2));
1146 var_result.Bind(index_plus_two);
1147
1148 a->Goto(&out);
1149 }
1150
1151 a->Bind(&out);
1152 return var_result.value();
1153 }
1154
1155 Node* NewFixedArrayCapacity(CodeStubAssembler* a,
1156 Node* const current_capacity) {
1157 CSA_ASSERT(a, a->IntPtrGreaterThan(current_capacity, a->IntPtrConstant(0)));
1158
1159 // Growth rate is analog to JSObject::NewElementsCapacity:
1160 // new_capacity = (current_capacity + (current_capacity >> 1)) + 16.
1161
1162 Node* const new_capacity = a->IntPtrAdd(
1163 a->IntPtrAdd(current_capacity, a->WordShr(current_capacity, 1)),
1164 a->IntPtrConstant(16));
1165
1166 return new_capacity;
1167 }
1168
1169 Node* GrowFixedArray(CodeStubAssembler* a, Node* const from_array,
1170 Node* const current_capacity, Node* const new_capacity) {
1171 CSA_ASSERT(a, a->IntPtrGreaterThan(current_capacity, a->IntPtrConstant(0)));
1172 CSA_ASSERT(a, a->IntPtrGreaterThan(new_capacity, current_capacity));
1173
1174 ElementsKind kind = FAST_ELEMENTS;
1175 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER;
1176 CodeStubAssembler::ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS;
Igor Sheludko 2016/11/25 17:31:27 |mode| should be passed from outside for consisten
jgruber 2016/11/28 13:28:22 Done. Refactored growable array handling into a Gr
1177
1178 Node* const to_array = a->AllocateFixedArray(kind, new_capacity, mode);
1179 a->CopyFixedArrayElements(kind, from_array, kind, to_array, current_capacity,
1180 new_capacity, barrier_mode, mode);
1181
1182 return to_array;
1183 }
1184
1185 void Generate_RegExpPrototypeMatchBody(CodeStubAssembler* a,
1186 Node* const receiver, Node* const string,
1187 Node* const context,
1188 const bool is_fastpath) {
1189 Isolate* const isolate = a->isolate();
1190
1191 Node* const null = a->NullConstant();
1192 Node* const int_zero = a->IntPtrConstant(0);
1193 Node* const smi_zero = a->SmiConstant(Smi::kZero);
1194
1195 Node* const regexp = receiver;
1196 Node* const is_global =
1197 is_fastpath ? FastFlagGetter(a, regexp, JSRegExp::kGlobal)
Igor Sheludko 2016/11/25 17:31:27 Maybe it's worth adding FlagGetter(..., bool is_fa
jgruber 2016/11/28 13:28:22 Done.
1198 : SlowFlagGetter(a, context, regexp, JSRegExp::kGlobal);
1199
1200 CLabel if_isglobal(a), if_isnotglobal(a);
1201 a->Branch(is_global, &if_isglobal, &if_isnotglobal);
1202
1203 a->Bind(&if_isnotglobal);
1204 {
1205 Node* const result =
1206 is_fastpath ? RegExpPrototypeExecInternal(a, context, regexp, string)
1207 : RegExpExec(a, context, regexp, string);
1208 a->Return(result);
1209 }
1210
1211 a->Bind(&if_isglobal);
1212 {
1213 Node* const is_unicode =
1214 is_fastpath ? FastFlagGetter(a, regexp, JSRegExp::kUnicode)
1215 : SlowFlagGetter(a, context, regexp, JSRegExp::kUnicode);
1216
1217 if (is_fastpath) {
1218 FastStoreLastIndex(a, context, regexp, smi_zero);
1219 } else {
1220 SlowStoreLastIndex(a, context, regexp, smi_zero);
1221 }
1222
1223 // Allocate an array to store the resulting match strings.
1224
1225 const ElementsKind kind = FAST_ELEMENTS;
1226 const CodeStubAssembler::ParameterMode mode =
1227 CodeStubAssembler::INTPTR_PARAMETERS;
1228
1229 static const int kInitialArraySize = 8;
1230 Node* const initial_capacity = a->IntPtrConstant(kInitialArraySize);
1231 Node* const initial_array =
1232 a->AllocateFixedArray(kind, initial_capacity, mode);
1233
1234 a->FillFixedArrayWithValue(kind, initial_array, int_zero, initial_capacity,
1235 Heap::kTheHoleValueRootIndex, mode);
1236
1237 CVariable var_array(a, MachineRepresentation::kTagged);
1238 var_array.Bind(initial_array);
1239
1240 CVariable var_array_capacity(a, MachineType::PointerRepresentation());
1241 var_array_capacity.Bind(initial_capacity);
1242
1243 // Loop preparations. Within the loop, collect results from RegExpExec
1244 // and store match strings in the array.
1245
1246 CVariable var_i(a, MachineType::PointerRepresentation());
1247 var_i.Bind(int_zero);
1248
1249 CVariable* vars[] = {&var_i, &var_array, &var_array_capacity};
1250 CLabel loop(a, 3, vars), loop_done(a);
1251 a->Goto(&loop);
1252
1253 a->Bind(&loop);
1254 {
1255 Node* const i = var_i.value();
1256 Node* const array_capacity = var_array_capacity.value();
1257
1258 Node* const result =
1259 is_fastpath ? RegExpPrototypeExecInternal(a, context, regexp, string)
1260 : RegExpExec(a, context, regexp, string);
1261
1262 CLabel if_didmatch(a), if_didnotmatch(a);
1263 a->Branch(a->WordEqual(result, null), &if_didnotmatch, &if_didmatch);
1264
1265 a->Bind(&if_didnotmatch);
1266 {
1267 // Return null if there were no matches, otherwise just exit the loop.
1268 a->GotoUnless(a->IntPtrEqual(i, int_zero), &loop_done);
1269 a->Return(null);
1270 }
1271
1272 a->Bind(&if_didmatch);
1273 {
1274 CVariable var_match(a, MachineRepresentation::kTagged);
1275 CLabel fast_result(a), slow_result(a), match_loaded(a);
1276 BranchIfFastRegExpResult(a, context, a->LoadMap(result), &fast_result,
Igor Sheludko 2016/11/25 17:31:27 Is it possible that the RegExpPrototypeExecInterna
jgruber 2016/11/28 13:28:21 Done.
1277 &slow_result);
1278
1279 a->Bind(&fast_result);
1280 {
1281 // TODO(jgruber): We could optimize further here and in other
1282 // methods (e.g. @@search) by bypassing RegExp result construction.
1283 Node* const result_fixed_array = a->LoadElements(result);
1284 Node* const match =
1285 a->LoadFixedArrayElement(result_fixed_array, int_zero, 0, mode);
1286 var_match.Bind(match);
1287 a->Goto(&match_loaded);
1288 }
1289
1290 a->Bind(&slow_result);
1291 {
1292 Node* const name = a->HeapConstant(
Igor Sheludko 2016/11/25 17:31:27 You can use SmiConstant(0) here.
1293 isolate->factory()->NewStringFromAsciiChecked("0"));
1294 Callable getproperty_callable = CodeFactory::GetProperty(isolate);
Igor Sheludko 2016/11/25 17:31:27 // TODO(ishell): Use GetElement stub once it's ava
jgruber 2016/11/28 13:28:21 Done.
1295 Node* const match =
1296 a->CallStub(getproperty_callable, context, result, name);
1297
1298 var_match.Bind(match);
1299 a->Goto(&match_loaded);
1300 }
1301
1302 a->Bind(&match_loaded);
1303
1304 // The match is guaranteed to be a string on the fast path.
Igor Sheludko 2016/11/25 17:31:27 CSA_ASSERT that?
jgruber 2016/11/28 13:28:22 Done.
1305 Node* const match = is_fastpath
1306 ? var_match.value()
1307 : a->ToString(context, var_match.value());
1308
1309 // Store the match, growing the fixed array if needed.
1310
1311 CLabel grow_array(a), store_match(a);
1312 a->Branch(a->IntPtrEqual(array_capacity, i), &grow_array, &store_match);
1313
1314 a->Bind(&grow_array);
1315 {
1316 Node* const new_array_capacity =
1317 NewFixedArrayCapacity(a, array_capacity);
1318 Node* const new_array = GrowFixedArray(
1319 a, var_array.value(), array_capacity, new_array_capacity);
1320
1321 var_array_capacity.Bind(new_array_capacity);
1322 var_array.Bind(new_array);
1323 a->Goto(&store_match);
1324 }
1325
1326 a->Bind(&store_match);
1327
1328 Node* const array = var_array.value();
1329
1330 WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER;
1331 a->StoreFixedArrayElement(array, i, match, barrier_mode, 0, mode);
1332
1333 // Increment our index counter.
1334
1335 Node* const new_i = a->IntPtrAdd(i, a->IntPtrConstant(1));
1336 var_i.Bind(new_i);
1337
1338 // Advance last index if the match is the empty string.
1339
1340 Node* const match_length = a->LoadStringLength(match);
1341 a->GotoUnless(a->SmiEqual(match_length, smi_zero), &loop);
1342
1343 Node* last_index = is_fastpath ? FastLoadLastIndex(a, context, regexp)
1344 : SlowLoadLastIndex(a, context, regexp);
1345
1346 Callable tolength_callable = CodeFactory::ToLength(isolate);
1347 last_index = a->CallStub(tolength_callable, context, last_index);
1348
1349 Node* const new_last_index =
1350 AdvanceStringIndex(a, string, last_index, is_unicode);
1351
1352 if (is_fastpath) {
1353 FastStoreLastIndex(a, context, regexp, new_last_index);
1354 } else {
1355 SlowStoreLastIndex(a, context, regexp, new_last_index);
1356 }
1357
1358 a->Goto(&loop);
1359 }
1360 }
1361
1362 a->Bind(&loop_done);
1363 {
1364 // Wrap the match in a JSArray.
1365
1366 Node* const native_context = a->LoadNativeContext(context);
1367 Node* const array_map = a->LoadJSArrayElementsMap(kind, native_context);
1368 Node* const result_length = a->SmiTag(var_i.value());
1369 Node* const result = a->AllocateUninitializedJSArrayWithoutElements(
1370 kind, array_map, result_length, nullptr);
1371
1372 // Note: We do not currently shrink the fixed array.
1373
1374 a->StoreObjectField(result, JSObject::kElementsOffset, var_array.value());
1375
1376 a->Return(result);
1377 }
1378 }
1379 }
1380
1381 } // namespace
1382
1052 // ES#sec-regexp.prototype-@@match 1383 // ES#sec-regexp.prototype-@@match
1053 // RegExp.prototype [ @@match ] ( string ) 1384 // RegExp.prototype [ @@match ] ( string )
1054 BUILTIN(RegExpPrototypeMatch) { 1385 void Builtins::Generate_RegExpPrototypeMatch(CodeAssemblerState* state) {
1055 HandleScope scope(isolate); 1386 CodeStubAssembler a(state);
1056 CHECK_RECEIVER(JSReceiver, recv, "RegExp.prototype.@@match"); 1387
1057 1388 Node* const maybe_receiver = a.Parameter(0);
1058 Handle<Object> string_obj = args.atOrUndefined(isolate, 1); 1389 Node* const maybe_string = a.Parameter(1);
1059 1390 Node* const context = a.Parameter(4);
1060 Handle<String> string; 1391
1061 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, string, 1392 // Ensure {maybe_receiver} is a JSReceiver.
1062 Object::ToString(isolate, string_obj)); 1393 Node* const map = ThrowIfNotJSReceiver(
1063 1394 &a, a.isolate(), context, maybe_receiver,
1064 Handle<Object> global_obj; 1395 MessageTemplate::kIncompatibleMethodReceiver, "RegExp.prototype.@@match");
1065 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 1396 Node* const receiver = maybe_receiver;
1066 isolate, global_obj, 1397
1067 JSReceiver::GetProperty(recv, isolate->factory()->global_string())); 1398 // Convert {maybe_string} to a String.
1068 const bool global = global_obj->BooleanValue(); 1399 Node* const string = a.ToString(context, maybe_string);
1069 1400
1070 if (!global) { 1401 CLabel fast_path(&a), slow_path(&a);
1071 RETURN_RESULT_OR_FAILURE( 1402 BranchIfFastPath(&a, context, map, &fast_path, &slow_path);
1072 isolate, 1403
1073 RegExpUtils::RegExpExec(isolate, recv, string, 1404 a.Bind(&fast_path);
1074 isolate->factory()->undefined_value())); 1405 Generate_RegExpPrototypeMatchBody(&a, receiver, string, context, true);
1075 } 1406
1076 1407 a.Bind(&slow_path);
1077 Handle<Object> unicode_obj; 1408 Generate_RegExpPrototypeMatchBody(&a, receiver, string, context, false);
1078 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1079 isolate, unicode_obj,
1080 JSReceiver::GetProperty(recv, isolate->factory()->unicode_string()));
1081 const bool unicode = unicode_obj->BooleanValue();
1082
1083 RETURN_FAILURE_ON_EXCEPTION(isolate,
1084 RegExpUtils::SetLastIndex(isolate, recv, 0));
1085
1086 static const int kInitialArraySize = 8;
1087 Handle<FixedArray> elems =
1088 isolate->factory()->NewFixedArrayWithHoles(kInitialArraySize);
1089
1090 int n = 0;
1091 for (;; n++) {
1092 Handle<Object> result;
1093 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1094 isolate, result,
1095 RegExpUtils::RegExpExec(isolate, recv, string,
1096 isolate->factory()->undefined_value()));
1097
1098 if (result->IsNull(isolate)) {
1099 if (n == 0) return isolate->heap()->null_value();
1100 break;
1101 }
1102
1103 Handle<Object> match_obj;
1104 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, match_obj,
1105 Object::GetElement(isolate, result, 0));
1106
1107 Handle<String> match;
1108 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, match,
1109 Object::ToString(isolate, match_obj));
1110
1111 elems = FixedArray::SetAndGrow(elems, n, match);
1112
1113 if (match->length() == 0) {
1114 RETURN_FAILURE_ON_EXCEPTION(isolate, RegExpUtils::SetAdvancedStringIndex(
1115 isolate, recv, string, unicode));
1116 }
1117 }
1118
1119 elems->Shrink(n);
1120 return *isolate->factory()->NewJSArrayWithElements(elems);
1121 } 1409 }
1122 1410
1123 namespace { 1411 namespace {
1124 1412
1125 void Generate_RegExpPrototypeSearchBody(CodeStubAssembler* a, 1413 void Generate_RegExpPrototypeSearchBody(CodeStubAssembler* a,
1126 Node* const receiver, 1414 Node* const receiver,
1127 Node* const string, Node* const context, 1415 Node* const string, Node* const context,
1128 bool is_fastpath) { 1416 bool is_fastpath) {
1129 Isolate* const isolate = a->isolate(); 1417 Isolate* const isolate = a->isolate();
1130 1418
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 { 1459 {
1172 CLabel next(a); 1460 CLabel next(a);
1173 a->GotoUnless(a->WordEqual(match_indices, a->NullConstant()), &next); 1461 a->GotoUnless(a->WordEqual(match_indices, a->NullConstant()), &next);
1174 a->Return(a->SmiConstant(-1)); 1462 a->Return(a->SmiConstant(-1));
1175 a->Bind(&next); 1463 a->Bind(&next);
1176 } 1464 }
1177 1465
1178 // Return the index of the match. 1466 // Return the index of the match.
1179 { 1467 {
1180 CLabel fast_result(a), slow_result(a, CLabel::kDeferred); 1468 CLabel fast_result(a), slow_result(a, CLabel::kDeferred);
1181 1469 BranchIfFastRegExpResult(a, context, a->LoadMap(match_indices),
Igor Sheludko 2016/11/25 17:31:27 Same here.
jgruber 2016/11/28 13:28:22 Done.
1182 Node* const native_context = a->LoadNativeContext(context); 1470 &fast_result, &slow_result);
1183 Node* const initial_regexp_result_map =
1184 a->LoadContextElement(native_context, Context::REGEXP_RESULT_MAP_INDEX);
1185 Node* const match_indices_map = a->LoadMap(match_indices);
1186
1187 a->Branch(a->WordEqual(match_indices_map, initial_regexp_result_map),
1188 &fast_result, &slow_result);
1189 1471
1190 a->Bind(&fast_result); 1472 a->Bind(&fast_result);
1191 { 1473 {
1192 Node* const index = 1474 Node* const index =
1193 a->LoadObjectField(match_indices, JSRegExpResult::kIndexOffset, 1475 a->LoadObjectField(match_indices, JSRegExpResult::kIndexOffset,
1194 MachineType::AnyTagged()); 1476 MachineType::AnyTagged());
1195 a->Return(index); 1477 a->Return(index);
1196 } 1478 }
1197 1479
1198 a->Bind(&slow_result); 1480 a->Bind(&slow_result);
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after
2040 a.Bind(&if_matched); 2322 a.Bind(&if_matched);
2041 { 2323 {
2042 Node* result = ConstructNewResultFromMatchInfo(isolate, &a, context, 2324 Node* result = ConstructNewResultFromMatchInfo(isolate, &a, context,
2043 match_indices, string); 2325 match_indices, string);
2044 a.Return(result); 2326 a.Return(result);
2045 } 2327 }
2046 } 2328 }
2047 2329
2048 } // namespace internal 2330 } // namespace internal
2049 } // namespace v8 2331 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698