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

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

Issue 2541843006: [stubs] Add LoadFixedArrayElements with int index (Closed)
Patch Set: Address comments 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-array.cc ('k') | src/builtins/builtins-string.cc » ('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-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 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 219
220 void StoreLastIndex(CodeStubAssembler* a, Node* context, Node* regexp, 220 void StoreLastIndex(CodeStubAssembler* a, Node* context, Node* regexp,
221 Node* value, bool is_fastpath) { 221 Node* value, bool is_fastpath) {
222 if (is_fastpath) { 222 if (is_fastpath) {
223 FastStoreLastIndex(a, regexp, value); 223 FastStoreLastIndex(a, regexp, value);
224 } else { 224 } else {
225 SlowStoreLastIndex(a, context, regexp, value); 225 SlowStoreLastIndex(a, context, regexp, value);
226 } 226 }
227 } 227 }
228 228
229 Node* LoadMatchInfoField(CodeStubAssembler* a, Node* const match_info,
230 const int index) {
231 const ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS;
232 Node* const result =
233 a->LoadFixedArrayElement(match_info, a->IntPtrConstant(index), 0, mode);
234 return result;
235 }
236
237 Node* ConstructNewResultFromMatchInfo(Isolate* isolate, CodeStubAssembler* a, 229 Node* ConstructNewResultFromMatchInfo(Isolate* isolate, CodeStubAssembler* a,
238 Node* context, Node* match_info, 230 Node* context, Node* match_info,
239 Node* string) { 231 Node* string) {
240 CLabel out(a); 232 CLabel out(a);
241 233
242 Node* const num_indices = a->SmiUntag(LoadMatchInfoField( 234 Node* const num_indices = a->SmiUntag(a->LoadFixedArrayElement(
243 a, match_info, RegExpMatchInfo::kNumberOfCapturesIndex)); 235 match_info, RegExpMatchInfo::kNumberOfCapturesIndex));
244 Node* const num_results = a->SmiTag(a->WordShr(num_indices, 1)); 236 Node* const num_results = a->SmiTag(a->WordShr(num_indices, 1));
245 Node* const start = 237 Node* const start =
246 LoadMatchInfoField(a, match_info, RegExpMatchInfo::kFirstCaptureIndex); 238 a->LoadFixedArrayElement(match_info, RegExpMatchInfo::kFirstCaptureIndex);
247 Node* const end = LoadMatchInfoField(a, match_info, 239 Node* const end = a->LoadFixedArrayElement(
248 RegExpMatchInfo::kFirstCaptureIndex + 1); 240 match_info, RegExpMatchInfo::kFirstCaptureIndex + 1);
249 241
250 // Calculate the substring of the first match before creating the result array 242 // Calculate the substring of the first match before creating the result array
251 // to avoid an unnecessary write barrier storing the first result. 243 // to avoid an unnecessary write barrier storing the first result.
252 Node* const first = a->SubString(context, string, start, end); 244 Node* const first = a->SubString(context, string, start, end);
253 245
254 Node* const result = 246 Node* const result =
255 a->AllocateRegExpResult(context, num_results, start, string); 247 a->AllocateRegExpResult(context, num_results, start, string);
256 Node* const result_elements = a->LoadElements(result); 248 Node* const result_elements = a->LoadElements(result);
257 249
258 a->StoreFixedArrayElement(result_elements, 0, first, SKIP_WRITE_BARRIER); 250 a->StoreFixedArrayElement(result_elements, 0, first, SKIP_WRITE_BARRIER);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 405
414 StoreLastIndex(a, context, regexp, smi_zero, is_fastpath); 406 StoreLastIndex(a, context, regexp, smi_zero, is_fastpath);
415 a->Goto(if_didnotmatch); 407 a->Goto(if_didnotmatch);
416 } 408 }
417 409
418 a->Bind(&successful_match); 410 a->Bind(&successful_match);
419 { 411 {
420 a->GotoUnless(should_update_last_index, &out); 412 a->GotoUnless(should_update_last_index, &out);
421 413
422 // Update the new last index from {match_indices}. 414 // Update the new last index from {match_indices}.
423 Node* const new_lastindex = LoadMatchInfoField( 415 Node* const new_lastindex = a->LoadFixedArrayElement(
424 a, match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1); 416 match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1);
425 417
426 StoreLastIndex(a, context, regexp, new_lastindex, is_fastpath); 418 StoreLastIndex(a, context, regexp, new_lastindex, is_fastpath);
427 a->Goto(&out); 419 a->Goto(&out);
428 } 420 }
429 421
430 a->Bind(&out); 422 a->Bind(&out);
431 return var_result.value(); 423 return var_result.value();
432 } 424 }
433 425
434 // ES#sec-regexp.prototype.exec 426 // ES#sec-regexp.prototype.exec
(...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after
1382 { 1374 {
1383 CVariable var_match(a, MachineRepresentation::kTagged); 1375 CVariable var_match(a, MachineRepresentation::kTagged);
1384 1376
1385 CLabel if_didmatch(a), if_didnotmatch(a); 1377 CLabel if_didmatch(a), if_didnotmatch(a);
1386 if (is_fastpath) { 1378 if (is_fastpath) {
1387 // On the fast path, grab the matching string from the raw match index 1379 // On the fast path, grab the matching string from the raw match index
1388 // array. 1380 // array.
1389 Node* const match_indices = RegExpPrototypeExecBodyWithoutResult( 1381 Node* const match_indices = RegExpPrototypeExecBodyWithoutResult(
1390 a, context, regexp, string, &if_didnotmatch, true); 1382 a, context, regexp, string, &if_didnotmatch, true);
1391 1383
1392 Node* const match_from = LoadMatchInfoField( 1384 Node* const match_from = a->LoadFixedArrayElement(
1393 a, match_indices, RegExpMatchInfo::kFirstCaptureIndex); 1385 match_indices, RegExpMatchInfo::kFirstCaptureIndex);
1394 Node* const match_to = LoadMatchInfoField( 1386 Node* const match_to = a->LoadFixedArrayElement(
1395 a, match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1); 1387 match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1);
1396 1388
1397 Node* match = a->SubString(context, string, match_from, match_to); 1389 Node* match = a->SubString(context, string, match_from, match_to);
1398 var_match.Bind(match); 1390 var_match.Bind(match);
1399 1391
1400 a->Goto(&if_didmatch); 1392 a->Goto(&if_didmatch);
1401 } else { 1393 } else {
1402 DCHECK(!is_fastpath); 1394 DCHECK(!is_fastpath);
1403 Node* const result = RegExpExec(a, context, regexp, string); 1395 Node* const result = RegExpExec(a, context, regexp, string);
1404 1396
1405 CLabel load_match(a); 1397 CLabel load_match(a);
1406 a->Branch(a->WordEqual(result, null), &if_didnotmatch, &load_match); 1398 a->Branch(a->WordEqual(result, null), &if_didnotmatch, &load_match);
1407 1399
1408 a->Bind(&load_match); 1400 a->Bind(&load_match);
1409 { 1401 {
1410 CLabel fast_result(a), slow_result(a); 1402 CLabel fast_result(a), slow_result(a);
1411 BranchIfFastRegExpResult(a, context, a->LoadMap(result), &fast_result, 1403 BranchIfFastRegExpResult(a, context, a->LoadMap(result), &fast_result,
1412 &slow_result); 1404 &slow_result);
1413 1405
1414 a->Bind(&fast_result); 1406 a->Bind(&fast_result);
1415 { 1407 {
1416 Node* const result_fixed_array = a->LoadElements(result); 1408 Node* const result_fixed_array = a->LoadElements(result);
1417 const ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS; 1409 Node* const match = a->LoadFixedArrayElement(result_fixed_array, 0);
1418 Node* const match =
1419 a->LoadFixedArrayElement(result_fixed_array, int_zero, 0, mode);
1420 1410
1421 // The match is guaranteed to be a string on the fast path. 1411 // The match is guaranteed to be a string on the fast path.
1422 CSA_ASSERT(a, a->IsStringInstanceType(a->LoadInstanceType(match))); 1412 CSA_ASSERT(a, a->IsStringInstanceType(a->LoadInstanceType(match)));
1423 1413
1424 var_match.Bind(match); 1414 var_match.Bind(match);
1425 a->Goto(&if_didmatch); 1415 a->Goto(&if_didmatch);
1426 } 1416 }
1427 1417
1428 a->Bind(&slow_result); 1418 a->Bind(&slow_result);
1429 { 1419 {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1527 CLabel if_didnotmatch(a); 1517 CLabel if_didnotmatch(a);
1528 Node* const match_indices = RegExpPrototypeExecBodyWithoutResult( 1518 Node* const match_indices = RegExpPrototypeExecBodyWithoutResult(
1529 a, context, receiver, string, &if_didnotmatch, true); 1519 a, context, receiver, string, &if_didnotmatch, true);
1530 1520
1531 // Successful match. 1521 // Successful match.
1532 { 1522 {
1533 // Reset last index. 1523 // Reset last index.
1534 FastStoreLastIndex(a, receiver, previous_last_index); 1524 FastStoreLastIndex(a, receiver, previous_last_index);
1535 1525
1536 // Return the index of the match. 1526 // Return the index of the match.
1537 Node* const index = LoadMatchInfoField(a, match_indices, 1527 Node* const index = a->LoadFixedArrayElement(
1538 RegExpMatchInfo::kFirstCaptureIndex); 1528 match_indices, RegExpMatchInfo::kFirstCaptureIndex);
1539 a->Return(index); 1529 a->Return(index);
1540 } 1530 }
1541 1531
1542 a->Bind(&if_didnotmatch); 1532 a->Bind(&if_didnotmatch);
1543 { 1533 {
1544 // Reset last index and return -1. 1534 // Reset last index and return -1.
1545 FastStoreLastIndex(a, receiver, previous_last_index); 1535 FastStoreLastIndex(a, receiver, previous_last_index);
1546 a->Return(a->SmiConstant(-1)); 1536 a->Return(a->SmiConstant(-1));
1547 } 1537 }
1548 } 1538 }
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 a->CallStub(exec_callable, context, regexp, string, next_search_from, 1746 a->CallStub(exec_callable, context, regexp, string, next_search_from,
1757 last_match_info); 1747 last_match_info);
1758 1748
1759 // We're done if no match was found. 1749 // We're done if no match was found.
1760 { 1750 {
1761 CLabel next(a); 1751 CLabel next(a);
1762 a->Branch(a->WordEqual(match_indices, null), &push_suffix_and_out, &next); 1752 a->Branch(a->WordEqual(match_indices, null), &push_suffix_and_out, &next);
1763 a->Bind(&next); 1753 a->Bind(&next);
1764 } 1754 }
1765 1755
1766 Node* const match_from = LoadMatchInfoField( 1756 Node* const match_from = a->LoadFixedArrayElement(
1767 a, match_indices, RegExpMatchInfo::kFirstCaptureIndex); 1757 match_indices, RegExpMatchInfo::kFirstCaptureIndex);
1768 1758
1769 // We're done if the match starts beyond the string. 1759 // We're done if the match starts beyond the string.
1770 { 1760 {
1771 CLabel next(a); 1761 CLabel next(a);
1772 a->Branch(a->WordEqual(match_from, string_length), &push_suffix_and_out, 1762 a->Branch(a->WordEqual(match_from, string_length), &push_suffix_and_out,
1773 &next); 1763 &next);
1774 a->Bind(&next); 1764 a->Bind(&next);
1775 } 1765 }
1776 1766
1777 Node* const match_to = LoadMatchInfoField( 1767 Node* const match_to = a->LoadFixedArrayElement(
1778 a, match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1); 1768 match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1);
1779 1769
1780 // Advance index and continue if the match is empty. 1770 // Advance index and continue if the match is empty.
1781 { 1771 {
1782 CLabel next(a); 1772 CLabel next(a);
1783 1773
1784 a->GotoUnless(a->SmiEqual(match_to, next_search_from), &next); 1774 a->GotoUnless(a->SmiEqual(match_to, next_search_from), &next);
1785 a->GotoUnless(a->SmiEqual(match_to, last_matched_until), &next); 1775 a->GotoUnless(a->SmiEqual(match_to, last_matched_until), &next);
1786 1776
1787 Node* const is_unicode = FastFlagGetter(a, regexp, JSRegExp::kUnicode); 1777 Node* const is_unicode = FastFlagGetter(a, regexp, JSRegExp::kUnicode);
1788 Node* const new_next_search_from = 1778 Node* const new_next_search_from =
(...skipping 10 matching lines...) Expand all
1799 Node* const to = match_from; 1789 Node* const to = match_from;
1800 1790
1801 Node* const substr = a->SubString(context, string, from, to); 1791 Node* const substr = a->SubString(context, string, from, to);
1802 array.Push(substr); 1792 array.Push(substr);
1803 1793
1804 a->GotoIf(a->WordEqual(array.length(), int_limit), &out); 1794 a->GotoIf(a->WordEqual(array.length(), int_limit), &out);
1805 } 1795 }
1806 1796
1807 // Add all captures to the array. 1797 // Add all captures to the array.
1808 { 1798 {
1809 Node* const num_registers = LoadMatchInfoField( 1799 Node* const num_registers = a->LoadFixedArrayElement(
1810 a, match_indices, RegExpMatchInfo::kNumberOfCapturesIndex); 1800 match_indices, RegExpMatchInfo::kNumberOfCapturesIndex);
1811 Node* const int_num_registers = a->SmiUntag(num_registers); 1801 Node* const int_num_registers = a->SmiUntag(num_registers);
1812 1802
1813 CVariable var_reg(a, MachineType::PointerRepresentation()); 1803 CVariable var_reg(a, MachineType::PointerRepresentation());
1814 var_reg.Bind(a->IntPtrConstant(2)); 1804 var_reg.Bind(a->IntPtrConstant(2));
1815 1805
1816 CVariable* vars[] = {array.var_array(), array.var_length(), 1806 CVariable* vars[] = {array.var_array(), array.var_length(),
1817 array.var_capacity(), &var_reg}; 1807 array.var_capacity(), &var_reg};
1818 const int vars_count = sizeof(vars) / sizeof(vars[0]); 1808 const int vars_count = sizeof(vars) / sizeof(vars[0]);
1819 CLabel nested_loop(a, vars_count, vars), nested_loop_out(a); 1809 CLabel nested_loop(a, vars_count, vars), nested_loop_out(a);
1820 a->Branch(a->IntPtrLessThan(var_reg.value(), int_num_registers), 1810 a->Branch(a->IntPtrLessThan(var_reg.value(), int_num_registers),
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
2018 a->GotoIf(a->WordEqual(res, null), &out); 2008 a->GotoIf(a->WordEqual(res, null), &out);
2019 2009
2020 // Reload last match info since it might have changed. 2010 // Reload last match info since it might have changed.
2021 last_match_info = a->LoadContextElement( 2011 last_match_info = a->LoadContextElement(
2022 native_context, Context::REGEXP_LAST_MATCH_INFO_INDEX); 2012 native_context, Context::REGEXP_LAST_MATCH_INFO_INDEX);
2023 2013
2024 Node* const res_length = a->LoadJSArrayLength(res); 2014 Node* const res_length = a->LoadJSArrayLength(res);
2025 Node* const res_elems = a->LoadElements(res); 2015 Node* const res_elems = a->LoadElements(res);
2026 CSA_ASSERT(a, a->HasInstanceType(res_elems, FIXED_ARRAY_TYPE)); 2016 CSA_ASSERT(a, a->HasInstanceType(res_elems, FIXED_ARRAY_TYPE));
2027 2017
2028 Node* const num_capture_registers = LoadMatchInfoField( 2018 Node* const num_capture_registers = a->LoadFixedArrayElement(
2029 a, last_match_info, RegExpMatchInfo::kNumberOfCapturesIndex); 2019 last_match_info, RegExpMatchInfo::kNumberOfCapturesIndex);
2030 2020
2031 CLabel if_hasexplicitcaptures(a), if_noexplicitcaptures(a), create_result(a); 2021 CLabel if_hasexplicitcaptures(a), if_noexplicitcaptures(a), create_result(a);
2032 a->Branch(a->SmiEqual(num_capture_registers, a->SmiConstant(Smi::FromInt(2))), 2022 a->Branch(a->SmiEqual(num_capture_registers, a->SmiConstant(Smi::FromInt(2))),
2033 &if_noexplicitcaptures, &if_hasexplicitcaptures); 2023 &if_noexplicitcaptures, &if_hasexplicitcaptures);
2034 2024
2035 a->Bind(&if_noexplicitcaptures); 2025 a->Bind(&if_noexplicitcaptures);
2036 { 2026 {
2037 // If the number of captures is two then there are no explicit captures in 2027 // If the number of captures is two then there are no explicit captures in
2038 // the regexp, just the implicit capture that captures the whole match. In 2028 // the regexp, just the implicit capture that captures the whole match. In
2039 // this case we can simplify quite a bit and end up with something faster. 2029 // this case we can simplify quite a bit and end up with something faster.
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
2234 a->Bind(&if_didnotmatch); 2224 a->Bind(&if_didnotmatch);
2235 { 2225 {
2236 FastStoreLastIndex(a, regexp, smi_zero); 2226 FastStoreLastIndex(a, regexp, smi_zero);
2237 var_result.Bind(subject_string); 2227 var_result.Bind(subject_string);
2238 a->Goto(&out); 2228 a->Goto(&out);
2239 } 2229 }
2240 2230
2241 a->Bind(&if_matched); 2231 a->Bind(&if_matched);
2242 { 2232 {
2243 Node* const subject_start = smi_zero; 2233 Node* const subject_start = smi_zero;
2244 Node* const match_start = LoadMatchInfoField( 2234 Node* const match_start = a->LoadFixedArrayElement(
2245 a, match_indices, RegExpMatchInfo::kFirstCaptureIndex); 2235 match_indices, RegExpMatchInfo::kFirstCaptureIndex);
2246 Node* const match_end = LoadMatchInfoField( 2236 Node* const match_end = a->LoadFixedArrayElement(
2247 a, match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1); 2237 match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1);
2248 Node* const subject_end = a->LoadStringLength(subject_string); 2238 Node* const subject_end = a->LoadStringLength(subject_string);
2249 2239
2250 CLabel if_replaceisempty(a), if_replaceisnotempty(a); 2240 CLabel if_replaceisempty(a), if_replaceisnotempty(a);
2251 Node* const replace_length = a->LoadStringLength(replace_string); 2241 Node* const replace_length = a->LoadStringLength(replace_string);
2252 a->Branch(a->SmiEqual(replace_length, smi_zero), &if_replaceisempty, 2242 a->Branch(a->SmiEqual(replace_length, smi_zero), &if_replaceisempty,
2253 &if_replaceisnotempty); 2243 &if_replaceisnotempty);
2254 2244
2255 a->Bind(&if_replaceisempty); 2245 a->Bind(&if_replaceisempty);
2256 { 2246 {
2257 // TODO(jgruber): We could skip many of the checks that using SubString 2247 // TODO(jgruber): We could skip many of the checks that using SubString
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
2412 a.Bind(&if_matched); 2402 a.Bind(&if_matched);
2413 { 2403 {
2414 Node* result = ConstructNewResultFromMatchInfo(isolate, &a, context, 2404 Node* result = ConstructNewResultFromMatchInfo(isolate, &a, context,
2415 match_indices, string); 2405 match_indices, string);
2416 a.Return(result); 2406 a.Return(result);
2417 } 2407 }
2418 } 2408 }
2419 2409
2420 } // namespace internal 2410 } // namespace internal
2421 } // namespace v8 2411 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-array.cc ('k') | src/builtins/builtins-string.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698