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

Side by Side Diff: src/jsregexp.cc

Issue 10831126: Take advantage of batched results when matching global regexp. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 int to) { 271 int to) {
272 NoHandleAllocation no_handles; 272 NoHandleAllocation no_handles;
273 RegExpImpl::SetLastCaptureCount(array, 2); 273 RegExpImpl::SetLastCaptureCount(array, 2);
274 RegExpImpl::SetLastSubject(array, subject); 274 RegExpImpl::SetLastSubject(array, subject);
275 RegExpImpl::SetLastInput(array, subject); 275 RegExpImpl::SetLastInput(array, subject);
276 RegExpImpl::SetCapture(array, 0, from); 276 RegExpImpl::SetCapture(array, 0, from);
277 RegExpImpl::SetCapture(array, 1, to); 277 RegExpImpl::SetCapture(array, 1, to);
278 } 278 }
279 279
280 280
281 Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re, 281 int RegExpImpl::AtomExecRaw(Handle<JSRegExp> regexp,
282 Handle<String> subject, 282 Handle<String> subject,
283 int index, 283 int index,
284 Handle<JSArray> last_match_info) { 284 int32_t* output,
285 Isolate* isolate = re->GetIsolate(); 285 int output_size) {
286 Isolate* isolate = regexp->GetIsolate();
286 287
287 ASSERT(0 <= index); 288 ASSERT(0 <= index);
288 ASSERT(index <= subject->length()); 289 ASSERT(index <= subject->length());
289 290
290 if (!subject->IsFlat()) FlattenString(subject); 291 if (!subject->IsFlat()) FlattenString(subject);
291 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid 292 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
292 293
293 String* needle = String::cast(re->DataAt(JSRegExp::kAtomPatternIndex)); 294 String* needle = String::cast(regexp->DataAt(JSRegExp::kAtomPatternIndex));
294 int needle_len = needle->length(); 295 int needle_len = needle->length();
295 ASSERT(needle->IsFlat()); 296 ASSERT(needle->IsFlat());
297 ASSERT_LT(0, needle_len);
296 298
297 if (needle_len != 0) { 299 if (index + needle_len > subject->length()) {
298 if (index + needle_len > subject->length()) { 300 return RegExpImpl::RE_FAILURE;
299 return isolate->factory()->null_value(); 301 }
300 }
301 302
303 for (int i = 0; i < output_size; i += 2) {
302 String::FlatContent needle_content = needle->GetFlatContent(); 304 String::FlatContent needle_content = needle->GetFlatContent();
303 String::FlatContent subject_content = subject->GetFlatContent(); 305 String::FlatContent subject_content = subject->GetFlatContent();
304 ASSERT(needle_content.IsFlat()); 306 ASSERT(needle_content.IsFlat());
305 ASSERT(subject_content.IsFlat()); 307 ASSERT(subject_content.IsFlat());
306 // dispatch on type of strings 308 // dispatch on type of strings
307 index = (needle_content.IsAscii() 309 index = (needle_content.IsAscii()
308 ? (subject_content.IsAscii() 310 ? (subject_content.IsAscii()
309 ? SearchString(isolate, 311 ? SearchString(isolate,
310 subject_content.ToAsciiVector(), 312 subject_content.ToAsciiVector(),
311 needle_content.ToAsciiVector(), 313 needle_content.ToAsciiVector(),
312 index) 314 index)
313 : SearchString(isolate, 315 : SearchString(isolate,
314 subject_content.ToUC16Vector(), 316 subject_content.ToUC16Vector(),
315 needle_content.ToAsciiVector(), 317 needle_content.ToAsciiVector(),
316 index)) 318 index))
317 : (subject_content.IsAscii() 319 : (subject_content.IsAscii()
318 ? SearchString(isolate, 320 ? SearchString(isolate,
319 subject_content.ToAsciiVector(), 321 subject_content.ToAsciiVector(),
320 needle_content.ToUC16Vector(), 322 needle_content.ToUC16Vector(),
321 index) 323 index)
322 : SearchString(isolate, 324 : SearchString(isolate,
323 subject_content.ToUC16Vector(), 325 subject_content.ToUC16Vector(),
324 needle_content.ToUC16Vector(), 326 needle_content.ToUC16Vector(),
325 index))); 327 index)));
326 if (index == -1) return isolate->factory()->null_value(); 328 if (index == -1) {
329 return i / 2; // Return number of matches.
330 } else {
331 output[i] = index;
332 output[i+1] = index + needle_len;
333 index += needle_len;
334 }
327 } 335 }
328 ASSERT(last_match_info->HasFastObjectElements()); 336 return output_size / 2;
337 }
329 338
330 { 339
331 NoHandleAllocation no_handles; 340 Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
332 FixedArray* array = FixedArray::cast(last_match_info->elements()); 341 Handle<String> subject,
333 SetAtomLastCapture(array, *subject, index, index + needle_len); 342 int index,
334 } 343 Handle<JSArray> last_match_info) {
344 Isolate* isolate = re->GetIsolate();
345
346 static const int kNumRegisters = 2;
347 STATIC_ASSERT(kNumRegisters <= Isolate::kJSRegexpStaticOffsetsVectorSize);
348 int32_t* output_registers = isolate->jsregexp_static_offsets_vector();
349
350 int res = AtomExecRaw(re, subject, index, output_registers, kNumRegisters);
351
352 if (res == RegExpImpl::RE_FAILURE) return isolate->factory()->null_value();
353
354 ASSERT_EQ(res, RegExpImpl::RE_SUCCESS);
355 NoHandleAllocation no_handles;
356 FixedArray* array = FixedArray::cast(last_match_info->elements());
357 SetAtomLastCapture(array, *subject, output_registers[0], output_registers[1]);
335 return last_match_info; 358 return last_match_info;
336 } 359 }
337 360
338 361
339 // Irregexp implementation. 362 // Irregexp implementation.
340 363
341 // Ensures that the regexp object contains a compiled version of the 364 // Ensures that the regexp object contains a compiled version of the
342 // source for either ASCII or non-ASCII strings. 365 // source for either ASCII or non-ASCII strings.
343 // If the compiled version doesn't already exist, it is compiled 366 // If the compiled version doesn't already exist, it is compiled
344 // from the source pattern. 367 // from the source pattern.
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp, 527 int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp,
505 Handle<String> subject) { 528 Handle<String> subject) {
506 if (!subject->IsFlat()) FlattenString(subject); 529 if (!subject->IsFlat()) FlattenString(subject);
507 530
508 // Check the asciiness of the underlying storage. 531 // Check the asciiness of the underlying storage.
509 bool is_ascii = subject->IsAsciiRepresentationUnderneath(); 532 bool is_ascii = subject->IsAsciiRepresentationUnderneath();
510 if (!EnsureCompiledIrregexp(regexp, subject, is_ascii)) return -1; 533 if (!EnsureCompiledIrregexp(regexp, subject, is_ascii)) return -1;
511 534
512 #ifdef V8_INTERPRETED_REGEXP 535 #ifdef V8_INTERPRETED_REGEXP
513 // Byte-code regexp needs space allocated for all its registers. 536 // Byte-code regexp needs space allocated for all its registers.
514 return IrregexpNumberOfRegisters(FixedArray::cast(regexp->data())); 537 // The result captures are copied to the start of the registers array
538 // if the match succeeds. This way those registers are not clobbered
539 // when we set the last match info from last successful match.
540 return IrregexpNumberOfRegisters(FixedArray::cast(regexp->data())) +
541 (IrregexpNumberOfCaptures(FixedArray::cast(regexp->data())) + 1) * 2;
515 #else // V8_INTERPRETED_REGEXP 542 #else // V8_INTERPRETED_REGEXP
516 // Native regexp only needs room to output captures. Registers are handled 543 // Native regexp only needs room to output captures. Registers are handled
517 // internally. 544 // internally.
518 return (IrregexpNumberOfCaptures(FixedArray::cast(regexp->data())) + 1) * 2; 545 return (IrregexpNumberOfCaptures(FixedArray::cast(regexp->data())) + 1) * 2;
519 #endif // V8_INTERPRETED_REGEXP 546 #endif // V8_INTERPRETED_REGEXP
520 } 547 }
521 548
522 549
523 int RegExpImpl::GlobalOffsetsVectorSize(Handle<JSRegExp> regexp, 550 int RegExpImpl::GlobalOffsetsVectorSize(Handle<JSRegExp> regexp,
524 int registers_per_match, 551 int registers_per_match,
525 int* max_matches) { 552 int* max_matches) {
526 #ifdef V8_INTERPRETED_REGEXP 553 #ifdef V8_INTERPRETED_REGEXP
527 // Global loop in interpreted regexp is not implemented. Therefore we choose 554 // Global loop in interpreted regexp is not implemented. Therefore we choose
528 // the size of the offsets vector so that it can only store one match. 555 // the size of the offsets vector so that it can only store one match.
529 *max_matches = 1; 556 *max_matches = 1;
530 return registers_per_match; 557 return registers_per_match;
531 #else // V8_INTERPRETED_REGEXP 558 #else // V8_INTERPRETED_REGEXP
532 int size = Max(registers_per_match, OffsetsVector::kStaticOffsetsVectorSize); 559 int size =
560 Max(registers_per_match, Isolate::kJSRegexpStaticOffsetsVectorSize);
533 *max_matches = size / registers_per_match; 561 *max_matches = size / registers_per_match;
534 return size; 562 return size;
535 #endif // V8_INTERPRETED_REGEXP 563 #endif // V8_INTERPRETED_REGEXP
536 } 564 }
537 565
538 566
539 int RegExpImpl::IrregexpExecRaw( 567 int RegExpImpl::IrregexpExecRaw(Handle<JSRegExp> regexp,
540 Handle<JSRegExp> regexp, 568 Handle<String> subject,
541 Handle<String> subject, 569 int index,
542 int index, 570 int32_t* output,
543 Vector<int> output) { 571 int output_size) {
544 Isolate* isolate = regexp->GetIsolate(); 572 Isolate* isolate = regexp->GetIsolate();
545 573
546 Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()), isolate); 574 Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()), isolate);
547 575
548 ASSERT(index >= 0); 576 ASSERT(index >= 0);
549 ASSERT(index <= subject->length()); 577 ASSERT(index <= subject->length());
550 ASSERT(subject->IsFlat()); 578 ASSERT(subject->IsFlat());
551 579
552 bool is_ascii = subject->IsAsciiRepresentationUnderneath(); 580 bool is_ascii = subject->IsAsciiRepresentationUnderneath();
553 581
554 #ifndef V8_INTERPRETED_REGEXP 582 #ifndef V8_INTERPRETED_REGEXP
555 ASSERT(output.length() >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2); 583 ASSERT(output_size >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
556 do { 584 do {
557 EnsureCompiledIrregexp(regexp, subject, is_ascii); 585 EnsureCompiledIrregexp(regexp, subject, is_ascii);
558 Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii), isolate); 586 Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii), isolate);
587 // The stack is used to allocate registers for the compiled regexp code.
588 // This means that in case of failure, the output registers array is left
589 // untouched and contains the capture results from the previous successful
590 // match. We can use that to set the last match info lazily.
559 NativeRegExpMacroAssembler::Result res = 591 NativeRegExpMacroAssembler::Result res =
560 NativeRegExpMacroAssembler::Match(code, 592 NativeRegExpMacroAssembler::Match(code,
561 subject, 593 subject,
562 output.start(), 594 output,
563 output.length(), 595 output_size,
564 index, 596 index,
565 isolate); 597 isolate);
566 if (res != NativeRegExpMacroAssembler::RETRY) { 598 if (res != NativeRegExpMacroAssembler::RETRY) {
567 ASSERT(res != NativeRegExpMacroAssembler::EXCEPTION || 599 ASSERT(res != NativeRegExpMacroAssembler::EXCEPTION ||
568 isolate->has_pending_exception()); 600 isolate->has_pending_exception());
569 STATIC_ASSERT( 601 STATIC_ASSERT(
570 static_cast<int>(NativeRegExpMacroAssembler::SUCCESS) == RE_SUCCESS); 602 static_cast<int>(NativeRegExpMacroAssembler::SUCCESS) == RE_SUCCESS);
571 STATIC_ASSERT( 603 STATIC_ASSERT(
572 static_cast<int>(NativeRegExpMacroAssembler::FAILURE) == RE_FAILURE); 604 static_cast<int>(NativeRegExpMacroAssembler::FAILURE) == RE_FAILURE);
573 STATIC_ASSERT(static_cast<int>(NativeRegExpMacroAssembler::EXCEPTION) 605 STATIC_ASSERT(static_cast<int>(NativeRegExpMacroAssembler::EXCEPTION)
574 == RE_EXCEPTION); 606 == RE_EXCEPTION);
575 return static_cast<IrregexpResult>(res); 607 return static_cast<IrregexpResult>(res);
576 } 608 }
577 // If result is RETRY, the string has changed representation, and we 609 // If result is RETRY, the string has changed representation, and we
578 // must restart from scratch. 610 // must restart from scratch.
579 // In this case, it means we must make sure we are prepared to handle 611 // In this case, it means we must make sure we are prepared to handle
580 // the, potentially, different subject (the string can switch between 612 // the, potentially, different subject (the string can switch between
581 // being internal and external, and even between being ASCII and UC16, 613 // being internal and external, and even between being ASCII and UC16,
582 // but the characters are always the same). 614 // but the characters are always the same).
583 IrregexpPrepare(regexp, subject); 615 IrregexpPrepare(regexp, subject);
584 is_ascii = subject->IsAsciiRepresentationUnderneath(); 616 is_ascii = subject->IsAsciiRepresentationUnderneath();
585 } while (true); 617 } while (true);
586 UNREACHABLE(); 618 UNREACHABLE();
587 return RE_EXCEPTION; 619 return RE_EXCEPTION;
588 #else // V8_INTERPRETED_REGEXP 620 #else // V8_INTERPRETED_REGEXP
589 621
590 ASSERT(output.length() >= IrregexpNumberOfRegisters(*irregexp)); 622 ASSERT(output_size >= IrregexpNumberOfRegisters(*irregexp));
591 // We must have done EnsureCompiledIrregexp, so we can get the number of 623 // We must have done EnsureCompiledIrregexp, so we can get the number of
592 // registers. 624 // registers.
593 int* register_vector = output.start();
594 int number_of_capture_registers = 625 int number_of_capture_registers =
595 (IrregexpNumberOfCaptures(*irregexp) + 1) * 2; 626 (IrregexpNumberOfCaptures(*irregexp) + 1) * 2;
627 int32_t* raw_output = &output[number_of_capture_registers];
628 // We do not touch the actual capture result registers until we know there
629 // has been a match so that we can use those capture results to set the
630 // last match info.
596 for (int i = number_of_capture_registers - 1; i >= 0; i--) { 631 for (int i = number_of_capture_registers - 1; i >= 0; i--) {
597 register_vector[i] = -1; 632 raw_output[i] = -1;
598 } 633 }
599 Handle<ByteArray> byte_codes(IrregexpByteCode(*irregexp, is_ascii), isolate); 634 Handle<ByteArray> byte_codes(IrregexpByteCode(*irregexp, is_ascii), isolate);
600 635
601 IrregexpResult result = IrregexpInterpreter::Match(isolate, 636 IrregexpResult result = IrregexpInterpreter::Match(isolate,
602 byte_codes, 637 byte_codes,
603 subject, 638 subject,
604 register_vector, 639 raw_output,
605 index); 640 index);
641 if (result == RE_SUCCESS) {
642 // Copy capture results to the start of the registers array.
643 memcpy(output, raw_output, number_of_capture_registers * sizeof(int32_t));
644 }
606 if (result == RE_EXCEPTION) { 645 if (result == RE_EXCEPTION) {
607 ASSERT(!isolate->has_pending_exception()); 646 ASSERT(!isolate->has_pending_exception());
608 isolate->StackOverflow(); 647 isolate->StackOverflow();
609 } 648 }
610 return result; 649 return result;
611 #endif // V8_INTERPRETED_REGEXP 650 #endif // V8_INTERPRETED_REGEXP
612 } 651 }
613 652
614 653
615 Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp, 654 Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> regexp,
616 Handle<String> subject, 655 Handle<String> subject,
617 int previous_index, 656 int previous_index,
618 Handle<JSArray> last_match_info) { 657 Handle<JSArray> last_match_info) {
619 Isolate* isolate = jsregexp->GetIsolate(); 658 Isolate* isolate = regexp->GetIsolate();
620 ASSERT_EQ(jsregexp->TypeTag(), JSRegExp::IRREGEXP); 659 ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
621 660
622 // Prepare space for the return values. 661 // Prepare space for the return values.
623 #ifdef V8_INTERPRETED_REGEXP 662 #if defined(V8_INTERPRETED_REGEXP) && defined(DEBUG)
624 #ifdef DEBUG
625 if (FLAG_trace_regexp_bytecodes) { 663 if (FLAG_trace_regexp_bytecodes) {
626 String* pattern = jsregexp->Pattern(); 664 String* pattern = regexp->Pattern();
627 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString())); 665 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString()));
628 PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString())); 666 PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString()));
629 } 667 }
630 #endif 668 #endif
631 #endif 669 int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
632 int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject);
633 if (required_registers < 0) { 670 if (required_registers < 0) {
634 // Compiling failed with an exception. 671 // Compiling failed with an exception.
635 ASSERT(isolate->has_pending_exception()); 672 ASSERT(isolate->has_pending_exception());
636 return Handle<Object>::null(); 673 return Handle<Object>::null();
637 } 674 }
638 675
639 OffsetsVector registers(required_registers, isolate); 676 int32_t* output_registers;
677 if (required_registers > Isolate::kJSRegexpStaticOffsetsVectorSize) {
678 output_registers = NewArray<int32_t>(required_registers);
679 } else {
680 output_registers = isolate->jsregexp_static_offsets_vector();
681 }
640 682
641 int res = RegExpImpl::IrregexpExecRaw(jsregexp, subject, previous_index, 683 int res = RegExpImpl::IrregexpExecRaw(
642 Vector<int>(registers.vector(), 684 regexp, subject, previous_index, output_registers, required_registers);
643 registers.length()));
644 if (res == RE_SUCCESS) { 685 if (res == RE_SUCCESS) {
645 int capture_register_count = 686 int capture_count =
646 (IrregexpNumberOfCaptures(FixedArray::cast(jsregexp->data())) + 1) * 2; 687 IrregexpNumberOfCaptures(FixedArray::cast(regexp->data()));
647 last_match_info->EnsureSize(capture_register_count + kLastMatchOverhead); 688 return SetLastMatchInfo(
648 AssertNoAllocation no_gc; 689 last_match_info, subject, capture_count, output_registers);
649 int* register_vector = registers.vector();
650 FixedArray* array = FixedArray::cast(last_match_info->elements());
651 for (int i = 0; i < capture_register_count; i += 2) {
652 SetCapture(array, i, register_vector[i]);
653 SetCapture(array, i + 1, register_vector[i + 1]);
654 }
655 SetLastCaptureCount(array, capture_register_count);
656 SetLastSubject(array, *subject);
657 SetLastInput(array, *subject);
658 return last_match_info;
659 } 690 }
660 if (res == RE_EXCEPTION) { 691 if (res == RE_EXCEPTION) {
661 ASSERT(isolate->has_pending_exception()); 692 ASSERT(isolate->has_pending_exception());
662 return Handle<Object>::null(); 693 return Handle<Object>::null();
663 } 694 }
664 ASSERT(res == RE_FAILURE); 695 ASSERT(res == RE_FAILURE);
665 return isolate->factory()->null_value(); 696 return isolate->factory()->null_value();
666 } 697 }
667 698
668 699
700 Handle<JSArray> RegExpImpl::SetLastMatchInfo(Handle<JSArray> last_match_info,
701 Handle<String> subject,
702 int capture_count,
703 int32_t* match) {
704 int capture_register_count = (capture_count + 1) * 2;
705 last_match_info->EnsureSize(capture_register_count + kLastMatchOverhead);
706 AssertNoAllocation no_gc;
707 FixedArray* array = FixedArray::cast(last_match_info->elements());
708 if (match != NULL) {
709 for (int i = 0; i < capture_register_count; i += 2) {
710 SetCapture(array, i, match[i]);
711 SetCapture(array, i + 1, match[i + 1]);
712 }
713 }
714 SetLastCaptureCount(array, capture_register_count);
715 SetLastSubject(array, *subject);
716 SetLastInput(array, *subject);
717 return last_match_info;
718 }
719
720
721 int RegExpImpl::global_cache_num_matches_ = 0;
722 int RegExpImpl::global_cache_max_matches_ = 0;
723 int RegExpImpl::global_cache_current_match_index_ = 0;
724 int RegExpImpl::global_cache_registers_per_match_ = 0;
725 JSRegExp::Type RegExpImpl::global_cache_current_type_ = JSRegExp::ATOM;
726 int32_t* RegExpImpl::global_cache_register_array_ = NULL;
727 int RegExpImpl::global_cache_register_array_size_ = 0;
728
729
730 int RegExpImpl::GlobalCacheInitialize(Handle<JSRegExp> regexp,
731 Handle<String> subject,
732 bool is_global,
733 Isolate* isolate) {
734 int num_registers = 0;
735 #ifdef V8_INTERPRETED_REGEXP
736 bool interpreted = true;
737 #else
738 bool interpreted = false;
739 #endif // V8_INTERPRETED_REGEXP
740
741 global_cache_current_type_ = regexp->TypeTag();
742 if (global_cache_current_type_ == JSRegExp::ATOM) {
743 static const int kAtomRegistersPerMatch = 2;
744 global_cache_registers_per_match_ = kAtomRegistersPerMatch;
745 // There is no distinction between interpreted and native for atom regexps.
746 interpreted = false;
747 } else {
748 global_cache_registers_per_match_ =
749 RegExpImpl::IrregexpPrepare(regexp, subject);
750 if (global_cache_registers_per_match_ < 0) return RE_EXCEPTION;
751 }
752
753 if (is_global && !interpreted) {
754 num_registers = Max(global_cache_registers_per_match_,
755 Isolate::kJSRegexpStaticOffsetsVectorSize);
756 global_cache_max_matches_ =
757 num_registers / global_cache_registers_per_match_;
758 } else {
759 // Global loop in interpreted regexp is not implemented. We choose
760 // the size of the offsets vector so that it can only store one match.
761 num_registers = global_cache_registers_per_match_;
762 global_cache_max_matches_ = 1;
763 }
764
765 if (global_cache_register_array_size_ >
766 Isolate::kJSRegexpStaticOffsetsVectorSize) {
767 DeleteArray(global_cache_register_array_);
768 }
769
770 if (num_registers > Isolate::kJSRegexpStaticOffsetsVectorSize) {
771 global_cache_register_array_ = NewArray<int32_t>(num_registers);
772 } else {
773 global_cache_register_array_ = isolate->jsregexp_static_offsets_vector();
774 }
775
776 global_cache_register_array_size_ = num_registers;
777
778 // Set state so that fetching the results the first time triggers a call
779 // to the compiled regexp.
780 global_cache_current_match_index_ = global_cache_max_matches_;
781 global_cache_num_matches_ = global_cache_max_matches_;
782 int32_t* last_match =
783 &global_cache_register_array_[global_cache_register_array_size_ -
784 global_cache_registers_per_match_];
785 last_match[0] = -1;
786 last_match[1] = 0;
787 return RE_SUCCESS;
788 }
789
790
669 // ------------------------------------------------------------------- 791 // -------------------------------------------------------------------
670 // Implementation of the Irregexp regular expression engine. 792 // Implementation of the Irregexp regular expression engine.
671 // 793 //
672 // The Irregexp regular expression engine is intended to be a complete 794 // The Irregexp regular expression engine is intended to be a complete
673 // implementation of ECMAScript regular expressions. It generates either 795 // implementation of ECMAScript regular expressions. It generates either
674 // bytecodes or native code. 796 // bytecodes or native code.
675 797
676 // The Irregexp regexp engine is structured in three steps. 798 // The Irregexp regexp engine is structured in three steps.
677 // 1) The parser generates an abstract syntax tree. See ast.cc. 799 // 1) The parser generates an abstract syntax tree. See ast.cc.
678 // 2) From the AST a node network is created. The nodes are all 800 // 2) From the AST a node network is created. The nodes are all
(...skipping 5324 matching lines...) Expand 10 before | Expand all | Expand 10 after
6003 } 6125 }
6004 6126
6005 return compiler.Assemble(&macro_assembler, 6127 return compiler.Assemble(&macro_assembler,
6006 node, 6128 node,
6007 data->capture_count, 6129 data->capture_count,
6008 pattern); 6130 pattern);
6009 } 6131 }
6010 6132
6011 6133
6012 }} // namespace v8::internal 6134 }} // namespace v8::internal
OLDNEW
« src/jsregexp.h ('K') | « src/jsregexp.h ('k') | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698