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

Unified Diff: src/runtime.cc

Issue 10386090: Implement loop for global regexps in regexp assembler. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index 0b80effbf21e86138f7e66ea6290998d3922b7de..d2f73f0c445cdad076fe013d8c3d1cfe7c6a0d02 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -3795,7 +3795,7 @@ static bool SearchStringMultiple(Isolate* isolate,
}
-static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
+static int SearchRegExpNoCaptureMultiple(
Erik Corry 2012/05/11 11:01:00 I wonder if we can unify this and SearchRegExpMult
Yang 2012/05/16 14:58:47 I'll try this in another CL.
Isolate* isolate,
Handle<String> subject,
Handle<JSRegExp> regexp,
@@ -3808,41 +3808,53 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
if (required_registers < 0) return RegExpImpl::RE_EXCEPTION;
- OffsetsVector registers(required_registers, isolate);
+ OffsetsVector registers(OffsetsVector::kStaticOffsetsVectorSize, isolate);
+ static const int max_result_sets =
+ OffsetsVector::kStaticOffsetsVectorSize / 2;
Vector<int32_t> register_vector(registers.vector(), registers.length());
int subject_length = subject->length();
bool first = true;
-
for (;;) { // Break on failure, return on exception.
- RegExpImpl::IrregexpResult result =
+ int result =
Erik Corry 2012/05/11 11:01:00 How about giving this variable a name like number_
Yang 2012/05/16 14:58:47 Done.
RegExpImpl::IrregexpExecOnce(regexp,
subject,
pos,
register_vector);
- if (result == RegExpImpl::RE_SUCCESS) {
- match_start = register_vector[0];
- builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
- if (match_end < match_start) {
- ReplacementStringBuilder::AddSubjectSlice(builder,
- match_end,
- match_start);
- }
- match_end = register_vector[1];
- HandleScope loop_scope(isolate);
- if (!first) {
- builder->Add(*isolate->factory()->NewProperSubString(subject,
- match_start,
- match_end));
- } else {
- builder->Add(*isolate->factory()->NewSubString(subject,
- match_start,
- match_end));
+ if (result >= RegExpImpl::RE_SUCCESS) {
+ for (int result_index = 0; result_index < result; result_index++) {
+ int32_t* current_result_set = &register_vector[result_index * 2];
+ match_start = current_result_set[0];
+ builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
+ if (match_end < match_start) {
+ ReplacementStringBuilder::AddSubjectSlice(builder,
+ match_end,
+ match_start);
+ }
+ match_end = current_result_set[1];
+ HandleScope loop_scope(isolate);
+ if (!first) {
+ builder->Add(*isolate->factory()->NewProperSubString(subject,
+ match_start,
+ match_end));
+ } else {
+ builder->Add(*isolate->factory()->NewSubString(subject,
+ match_start,
+ match_end));
+ }
+ first = false;
}
+
+ // If we did not get the maximum number of resultsets, we can stop here
+ // since there are no matches left.
+ if (result < max_result_sets) break;
+
if (match_start != match_end) {
Erik Corry 2012/05/11 11:01:00 I don't see this logic replicated in the regexp-ma
pos = match_end;
} else {
pos = match_end + 1;
- if (pos > subject_length) break;
+ if (pos > subject_length) {
Erik Corry 2012/05/11 11:01:00 unneeded edit
+ break;
+ }
}
} else if (result == RegExpImpl::RE_FAILURE) {
break;
@@ -3850,7 +3862,6 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
return result;
}
- first = false;
}
if (match_start >= 0) {
@@ -3872,7 +3883,7 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
// Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
// separate last match info. See comment on that function.
-static RegExpImpl::IrregexpResult SearchRegExpMultiple(
+static int SearchRegExpMultiple(
Isolate* isolate,
Handle<String> subject,
Handle<JSRegExp> regexp,
@@ -3880,17 +3891,19 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
FixedArrayBuilder* builder) {
ASSERT(subject->IsFlat());
- int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
- if (required_registers < 0) return RegExpImpl::RE_EXCEPTION;
+ int registers_per_result_set = RegExpImpl::IrregexpPrepare(regexp, subject);
+ if (registers_per_result_set < 0) return RegExpImpl::RE_EXCEPTION;
- OffsetsVector registers(required_registers, isolate);
+ int num_registers = Min(OffsetsVector::kStaticOffsetsVectorSize,
+ registers_per_result_set);
+ int max_result_sets = num_registers / registers_per_result_set;
+ OffsetsVector registers(OffsetsVector::kStaticOffsetsVectorSize, isolate);
Vector<int32_t> register_vector(registers.vector(), registers.length());
- RegExpImpl::IrregexpResult result =
- RegExpImpl::IrregexpExecOnce(regexp,
- subject,
- 0,
- register_vector);
+ int result = RegExpImpl::IrregexpExecOnce(regexp,
+ subject,
+ 0,
+ register_vector);
int capture_count = regexp->CaptureCount();
int subject_length = subject->length();
@@ -3899,60 +3912,71 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
int pos = 0;
// End of previous match. Differs from pos if match was empty.
int match_end = 0;
- if (result == RegExpImpl::RE_SUCCESS) {
+ if (result >= RegExpImpl::RE_SUCCESS) {
bool first = true;
do {
- int match_start = register_vector[0];
- builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
- if (match_end < match_start) {
- ReplacementStringBuilder::AddSubjectSlice(builder,
- match_end,
- match_start);
- }
- match_end = register_vector[1];
-
- {
- // Avoid accumulating new handles inside loop.
- HandleScope temp_scope(isolate);
- // Arguments array to replace function is match, captures, index and
- // subject, i.e., 3 + capture count in total.
- Handle<FixedArray> elements =
- isolate->factory()->NewFixedArray(3 + capture_count);
- Handle<String> match;
- if (!first) {
- match = isolate->factory()->NewProperSubString(subject,
- match_start,
- match_end);
- } else {
- match = isolate->factory()->NewSubString(subject,
- match_start,
- match_end);
+ int match_start = 0;
+ for (int result_index = 0; result_index < result; result_index++) {
+ int32_t* current_result_set =
+ &register_vector[result_index * registers_per_result_set];
+ match_start = current_result_set[0];
+ builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
+ if (match_end < match_start) {
+ ReplacementStringBuilder::AddSubjectSlice(builder,
+ match_end,
+ match_start);
}
- elements->set(0, *match);
- for (int i = 1; i <= capture_count; i++) {
- int start = register_vector[i * 2];
- if (start >= 0) {
- int end = register_vector[i * 2 + 1];
- ASSERT(start <= end);
- Handle<String> substring;
- if (!first) {
- substring = isolate->factory()->NewProperSubString(subject,
- start,
- end);
+ match_end = current_result_set[1];
+
+ {
+ // Avoid accumulating new handles inside loop.
+ HandleScope temp_scope(isolate);
+ // Arguments array to replace function is match, captures, index and
+ // subject, i.e., 3 + capture count in total.
+ Handle<FixedArray> elements =
+ isolate->factory()->NewFixedArray(3 + capture_count);
+ Handle<String> match;
+ if (!first) {
+ match = isolate->factory()->NewProperSubString(subject,
Erik Corry 2012/05/11 11:01:00 Not sure why we need NewProperSubString here.
Yang 2012/05/16 14:58:47 For every substring save for the first one we know
+ match_start,
+ match_end);
+ } else {
+ match = isolate->factory()->NewSubString(subject,
+ match_start,
+ match_end);
+ }
+ elements->set(0, *match);
+ for (int i = 1; i <= capture_count; i++) {
Erik Corry 2012/05/11 11:01:00 I think you could just start this loop at 0 and re
Yang 2012/05/16 14:58:47 After removing the call to NewSubString here (firs
+ int start = current_result_set[i * 2];
+ if (start >= 0) {
+ int end = current_result_set[i * 2 + 1];
+ ASSERT(start <= end);
+ Handle<String> substring;
+ if (!first) {
+ substring = isolate->factory()->NewProperSubString(subject,
+ start,
+ end);
+ } else {
+ substring = isolate->factory()->NewSubString(subject,
+ start,
+ end);
+ }
+ elements->set(i, *substring);
} else {
- substring = isolate->factory()->NewSubString(subject, start, end);
+ ASSERT(current_result_set[i * 2 + 1] < 0);
+ elements->set(i, isolate->heap()->undefined_value());
}
- elements->set(i, *substring);
- } else {
- ASSERT(register_vector[i * 2 + 1] < 0);
- elements->set(i, isolate->heap()->undefined_value());
}
+ elements->set(capture_count + 1, Smi::FromInt(match_start));
+ elements->set(capture_count + 2, *subject);
+ builder->Add(*isolate->factory()->NewJSArrayWithElements(elements));
}
- elements->set(capture_count + 1, Smi::FromInt(match_start));
- elements->set(capture_count + 2, *subject);
- builder->Add(*isolate->factory()->NewJSArrayWithElements(elements));
}
+ // If we did not get the maximum number of resultsets, we can stop here
+ // since there are no matches left.
+ if (result < max_result_sets) break;
+
if (match_end > match_start) {
pos = match_end;
} else {
@@ -3967,7 +3991,7 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
pos,
register_vector);
first = false;
- } while (result == RegExpImpl::RE_SUCCESS);
+ } while (result >= RegExpImpl::RE_SUCCESS);
if (result != RegExpImpl::RE_EXCEPTION) {
// Finished matching, with at least one match.
@@ -4035,7 +4059,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
ASSERT_EQ(regexp->TypeTag(), JSRegExp::IRREGEXP);
- RegExpImpl::IrregexpResult result;
+ int result;
if (regexp->CaptureCount() == 0) {
result = SearchRegExpNoCaptureMultiple(isolate,
subject,
@@ -4049,7 +4073,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
last_match_info,
&builder);
}
- if (result == RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array);
+ if (result >= RegExpImpl::RE_SUCCESS) return *builder.ToJSArray(result_array);
if (result == RegExpImpl::RE_FAILURE) return isolate->heap()->null_value();
ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
return Failure::Exception();

Powered by Google App Engine
This is Rietveld 408576698