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

Side by Side Diff: src/regexp/jsregexp.cc

Issue 2415103002: [regexp] Turn last match info into a simple FixedArray (Closed)
Patch Set: Don't check instance type before map check Created 4 years, 2 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/regexp/jsregexp.h ('k') | src/regexp/regexp-utils.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/regexp/jsregexp.h" 5 #include "src/regexp/jsregexp.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/base/platform/platform.h" 9 #include "src/base/platform/platform.h"
10 #include "src/compilation-cache.h" 10 #include "src/compilation-cache.h"
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 // Compilation succeeded so the data is set on the regexp 187 // Compilation succeeded so the data is set on the regexp
188 // and we can store it in the cache. 188 // and we can store it in the cache.
189 Handle<FixedArray> data(FixedArray::cast(re->data())); 189 Handle<FixedArray> data(FixedArray::cast(re->data()));
190 compilation_cache->PutRegExp(pattern, flags, data); 190 compilation_cache->PutRegExp(pattern, flags, data);
191 191
192 return re; 192 return re;
193 } 193 }
194 194
195 MaybeHandle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp, 195 MaybeHandle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp,
196 Handle<String> subject, int index, 196 Handle<String> subject, int index,
197 Handle<JSObject> last_match_info) { 197 Handle<RegExpMatchInfo> last_match_info) {
198 switch (regexp->TypeTag()) { 198 switch (regexp->TypeTag()) {
199 case JSRegExp::ATOM: 199 case JSRegExp::ATOM:
200 return AtomExec(regexp, subject, index, last_match_info); 200 return AtomExec(regexp, subject, index, last_match_info);
201 case JSRegExp::IRREGEXP: { 201 case JSRegExp::IRREGEXP: {
202 return IrregexpExec(regexp, subject, index, last_match_info); 202 return IrregexpExec(regexp, subject, index, last_match_info);
203 } 203 }
204 default: 204 default:
205 UNREACHABLE(); 205 UNREACHABLE();
206 return MaybeHandle<Object>(); 206 return MaybeHandle<Object>();
207 } 207 }
208 } 208 }
209 209
210 210
211 // RegExp Atom implementation: Simple string search using indexOf. 211 // RegExp Atom implementation: Simple string search using indexOf.
212 212
213 213
214 void RegExpImpl::AtomCompile(Handle<JSRegExp> re, 214 void RegExpImpl::AtomCompile(Handle<JSRegExp> re,
215 Handle<String> pattern, 215 Handle<String> pattern,
216 JSRegExp::Flags flags, 216 JSRegExp::Flags flags,
217 Handle<String> match_pattern) { 217 Handle<String> match_pattern) {
218 re->GetIsolate()->factory()->SetRegExpAtomData(re, 218 re->GetIsolate()->factory()->SetRegExpAtomData(re,
219 JSRegExp::ATOM, 219 JSRegExp::ATOM,
220 pattern, 220 pattern,
221 flags, 221 flags,
222 match_pattern); 222 match_pattern);
223 } 223 }
224 224
225 225 static void SetAtomLastCapture(Handle<RegExpMatchInfo> last_match_info,
226 static void SetAtomLastCapture(FixedArray* array, 226 String* subject, int from, int to) {
227 String* subject, 227 SealHandleScope shs(last_match_info->GetIsolate());
228 int from, 228 last_match_info->SetNumberOfCaptureRegisters(2);
229 int to) { 229 last_match_info->SetLastSubject(subject);
230 SealHandleScope shs(array->GetIsolate()); 230 last_match_info->SetLastInput(subject);
231 RegExpImpl::SetLastCaptureCount(array, 2); 231 last_match_info->SetCapture(0, from);
232 RegExpImpl::SetLastSubject(array, subject); 232 last_match_info->SetCapture(1, to);
233 RegExpImpl::SetLastInput(array, subject);
234 RegExpImpl::SetCapture(array, 0, from);
235 RegExpImpl::SetCapture(array, 1, to);
236 } 233 }
237 234
238 235
239 int RegExpImpl::AtomExecRaw(Handle<JSRegExp> regexp, 236 int RegExpImpl::AtomExecRaw(Handle<JSRegExp> regexp,
240 Handle<String> subject, 237 Handle<String> subject,
241 int index, 238 int index,
242 int32_t* output, 239 int32_t* output,
243 int output_size) { 240 int output_size) {
244 Isolate* isolate = regexp->GetIsolate(); 241 Isolate* isolate = regexp->GetIsolate();
245 242
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 output[i] = index; 279 output[i] = index;
283 output[i+1] = index + needle_len; 280 output[i+1] = index + needle_len;
284 index += needle_len; 281 index += needle_len;
285 } 282 }
286 } 283 }
287 return output_size / 2; 284 return output_size / 2;
288 } 285 }
289 286
290 Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re, Handle<String> subject, 287 Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re, Handle<String> subject,
291 int index, 288 int index,
292 Handle<JSObject> last_match_info) { 289 Handle<RegExpMatchInfo> last_match_info) {
293 Isolate* isolate = re->GetIsolate(); 290 Isolate* isolate = re->GetIsolate();
294 291
295 static const int kNumRegisters = 2; 292 static const int kNumRegisters = 2;
296 STATIC_ASSERT(kNumRegisters <= Isolate::kJSRegexpStaticOffsetsVectorSize); 293 STATIC_ASSERT(kNumRegisters <= Isolate::kJSRegexpStaticOffsetsVectorSize);
297 int32_t* output_registers = isolate->jsregexp_static_offsets_vector(); 294 int32_t* output_registers = isolate->jsregexp_static_offsets_vector();
298 295
299 int res = AtomExecRaw(re, subject, index, output_registers, kNumRegisters); 296 int res = AtomExecRaw(re, subject, index, output_registers, kNumRegisters);
300 297
301 if (res == RegExpImpl::RE_FAILURE) return isolate->factory()->null_value(); 298 if (res == RegExpImpl::RE_FAILURE) return isolate->factory()->null_value();
302 299
303 DCHECK_EQ(res, RegExpImpl::RE_SUCCESS); 300 DCHECK_EQ(res, RegExpImpl::RE_SUCCESS);
304 SealHandleScope shs(isolate); 301 SealHandleScope shs(isolate);
305 FixedArray* array = FixedArray::cast(last_match_info->elements()); 302 SetAtomLastCapture(last_match_info, *subject, output_registers[0],
306 SetAtomLastCapture(array, *subject, output_registers[0], output_registers[1]); 303 output_registers[1]);
307 return last_match_info; 304 return last_match_info;
308 } 305 }
309 306
310 307
311 // Irregexp implementation. 308 // Irregexp implementation.
312 309
313 // Ensures that the regexp object contains a compiled version of the 310 // Ensures that the regexp object contains a compiled version of the
314 // source for either one-byte or two-byte subject strings. 311 // source for either one-byte or two-byte subject strings.
315 // If the compiled version doesn't already exist, it is compiled 312 // If the compiled version doesn't already exist, it is compiled
316 // from the source pattern. 313 // from the source pattern.
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 MemCopy(output, raw_output, number_of_capture_registers * sizeof(int32_t)); 556 MemCopy(output, raw_output, number_of_capture_registers * sizeof(int32_t));
560 } 557 }
561 if (result == RE_EXCEPTION) { 558 if (result == RE_EXCEPTION) {
562 DCHECK(!isolate->has_pending_exception()); 559 DCHECK(!isolate->has_pending_exception());
563 isolate->StackOverflow(); 560 isolate->StackOverflow();
564 } 561 }
565 return result; 562 return result;
566 #endif // V8_INTERPRETED_REGEXP 563 #endif // V8_INTERPRETED_REGEXP
567 } 564 }
568 565
569 MaybeHandle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp, 566 MaybeHandle<Object> RegExpImpl::IrregexpExec(
570 Handle<String> subject, 567 Handle<JSRegExp> regexp, Handle<String> subject, int previous_index,
571 int previous_index, 568 Handle<RegExpMatchInfo> last_match_info) {
572 Handle<JSObject> last_match_info) {
573 Isolate* isolate = regexp->GetIsolate(); 569 Isolate* isolate = regexp->GetIsolate();
574 DCHECK_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP); 570 DCHECK_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
575 571
576 // Prepare space for the return values. 572 // Prepare space for the return values.
577 #if defined(V8_INTERPRETED_REGEXP) && defined(DEBUG) 573 #if defined(V8_INTERPRETED_REGEXP) && defined(DEBUG)
578 if (FLAG_trace_regexp_bytecodes) { 574 if (FLAG_trace_regexp_bytecodes) {
579 String* pattern = regexp->Pattern(); 575 String* pattern = regexp->Pattern();
580 PrintF("\n\nRegexp match: /%s/\n\n", pattern->ToCString().get()); 576 PrintF("\n\nRegexp match: /%s/\n\n", pattern->ToCString().get());
581 PrintF("\n\nSubject string: '%s'\n\n", subject->ToCString().get()); 577 PrintF("\n\nSubject string: '%s'\n\n", subject->ToCString().get());
582 } 578 }
(...skipping 23 matching lines...) Expand all
606 last_match_info, subject, capture_count, output_registers); 602 last_match_info, subject, capture_count, output_registers);
607 } 603 }
608 if (res == RE_EXCEPTION) { 604 if (res == RE_EXCEPTION) {
609 DCHECK(isolate->has_pending_exception()); 605 DCHECK(isolate->has_pending_exception());
610 return MaybeHandle<Object>(); 606 return MaybeHandle<Object>();
611 } 607 }
612 DCHECK(res == RE_FAILURE); 608 DCHECK(res == RE_FAILURE);
613 return isolate->factory()->null_value(); 609 return isolate->factory()->null_value();
614 } 610 }
615 611
616 static void EnsureSize(Handle<JSObject> array, uint32_t minimum_size) { 612 Handle<RegExpMatchInfo> RegExpImpl::SetLastMatchInfo(
617 if (static_cast<uint32_t>(array->elements()->length()) < minimum_size) { 613 Handle<RegExpMatchInfo> last_match_info, Handle<String> subject,
618 array->GetElementsAccessor()->GrowCapacityAndConvert(array, minimum_size); 614 int capture_count, int32_t* match) {
615 // This is the only place where match infos can grow. If, after executing the
616 // regexp, RegExpExecStub finds that the match info is too small, it restarts
617 // execution in RegExpImpl::Exec, which finally grows the match info right
618 // here.
619
620 int capture_register_count = (capture_count + 1) * 2;
621 Handle<RegExpMatchInfo> result =
622 RegExpMatchInfo::ReserveCaptures(last_match_info, capture_register_count);
623 result->SetNumberOfCaptureRegisters(capture_register_count);
624
625 if (*result != *last_match_info) {
626 // The match info has been reallocated, update the corresponding reference
627 // on the native context.
628 Isolate* isolate = last_match_info->GetIsolate();
629 if (*last_match_info == *isolate->regexp_last_match_info()) {
630 isolate->native_context()->set_regexp_last_match_info(*result);
631 } else if (*last_match_info == *isolate->regexp_internal_match_info()) {
632 isolate->native_context()->set_regexp_internal_match_info(*result);
633 }
619 } 634 }
620 }
621 635
622 Handle<JSObject> RegExpImpl::SetLastMatchInfo(Handle<JSObject> last_match_info,
623 Handle<String> subject,
624 int capture_count,
625 int32_t* match) {
626 DCHECK(last_match_info->HasFastObjectElements());
627 int capture_register_count = (capture_count + 1) * 2;
628 EnsureSize(last_match_info, capture_register_count + kLastMatchOverhead);
629 DisallowHeapAllocation no_allocation; 636 DisallowHeapAllocation no_allocation;
630 FixedArray* array = FixedArray::cast(last_match_info->elements());
631 if (match != NULL) { 637 if (match != NULL) {
632 for (int i = 0; i < capture_register_count; i += 2) { 638 for (int i = 0; i < capture_register_count; i += 2) {
633 SetCapture(array, i, match[i]); 639 result->SetCapture(i, match[i]);
634 SetCapture(array, i + 1, match[i + 1]); 640 result->SetCapture(i + 1, match[i + 1]);
635 } 641 }
636 } 642 }
637 SetLastCaptureCount(array, capture_register_count); 643 result->SetLastSubject(*subject);
638 SetLastSubject(array, *subject); 644 result->SetLastInput(*subject);
639 SetLastInput(array, *subject); 645 return result;
640 return last_match_info;
641 } 646 }
642 647
643 648
644 RegExpImpl::GlobalCache::GlobalCache(Handle<JSRegExp> regexp, 649 RegExpImpl::GlobalCache::GlobalCache(Handle<JSRegExp> regexp,
645 Handle<String> subject, 650 Handle<String> subject,
646 Isolate* isolate) 651 Isolate* isolate)
647 : register_array_(NULL), 652 : register_array_(NULL),
648 register_array_size_(0), 653 register_array_size_(0),
649 regexp_(regexp), 654 regexp_(regexp),
650 subject_(subject) { 655 subject_(subject) {
(...skipping 6219 matching lines...) Expand 10 before | Expand all | Expand 10 after
6870 6875
6871 6876
6872 void RegExpResultsCache::Clear(FixedArray* cache) { 6877 void RegExpResultsCache::Clear(FixedArray* cache) {
6873 for (int i = 0; i < kRegExpResultsCacheSize; i++) { 6878 for (int i = 0; i < kRegExpResultsCacheSize; i++) {
6874 cache->set(i, Smi::kZero); 6879 cache->set(i, Smi::kZero);
6875 } 6880 }
6876 } 6881 }
6877 6882
6878 } // namespace internal 6883 } // namespace internal
6879 } // namespace v8 6884 } // namespace v8
OLDNEW
« no previous file with comments | « src/regexp/jsregexp.h ('k') | src/regexp/regexp-utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698