Chromium Code Reviews| Index: src/jsregexp.cc |
| =================================================================== |
| --- src/jsregexp.cc (revision 647) |
| +++ src/jsregexp.cc (working copy) |
| @@ -307,16 +307,57 @@ |
| } |
| -Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re, |
| - Handle<String> pattern, |
| - JSRegExp::Flags flags) { |
| +static inline Object* DoCompile(String* pattern, |
| + JSRegExp::Flags flags, |
| + unsigned* number_of_captures, |
| + const char** error_message, |
| + JscreRegExp** code) { |
| JSRegExpIgnoreCaseOption case_option = flags.is_ignore_case() |
| ? JSRegExpIgnoreCase |
| : JSRegExpDoNotIgnoreCase; |
| JSRegExpMultilineOption multiline_option = flags.is_multiline() |
| ? JSRegExpMultiline |
| : JSRegExpSingleLine; |
| + *code = NULL; |
|
Kevin Millikin (Chromium)
2008/10/30 11:10:11
Do you need this?
|
| + *error_message = NULL; |
| + malloc_failure = Failure::Exception(); |
| + *code = jsRegExpCompile(pattern->GetTwoByteData(), |
| + pattern->length(), |
| + case_option, |
| + multiline_option, |
| + number_of_captures, |
| + error_message, |
| + &JSREMalloc, |
| + &JSREFree); |
| + if (code == NULL && (malloc_failure->IsRetryAfterGC() || |
| + malloc_failure->IsOutOfMemoryFailure())) { |
| + return malloc_failure; |
| + } else { |
| + // It doesn't matter which object we return here, we just need to return |
| + // a non-failure to indicate to the GC-retry code that there was no |
| + // allocation failure. |
| + return pattern; |
| + } |
| +} |
| + |
| +void CompileWithRetryAfterGC(Handle<String> pattern, |
| + JSRegExp::Flags flags, |
| + unsigned* number_of_captures, |
| + const char** error_message, |
| + JscreRegExp** code) { |
| + CALL_HEAP_FUNCTION_VOID(DoCompile(*pattern, |
| + flags, |
| + number_of_captures, |
| + error_message, |
| + code)); |
| +} |
| + |
| + |
| +Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re, |
| + Handle<String> pattern, |
| + JSRegExp::Flags flags) { |
| + |
| Handle<String> two_byte_pattern = StringToTwoByte(pattern); |
| unsigned number_of_captures; |
| @@ -325,52 +366,33 @@ |
| JscreRegExp* code = NULL; |
| FlattenString(pattern); |
| - bool first_time = true; |
| + CompileWithRetryAfterGC(two_byte_pattern, |
| + flags, |
| + &number_of_captures, |
| + &error_message, |
| + &code); |
| - while (true) { |
| - malloc_failure = Failure::Exception(); |
| - code = jsRegExpCompile(two_byte_pattern->GetTwoByteData(), |
| - pattern->length(), case_option, |
| - multiline_option, &number_of_captures, |
| - &error_message, &JSREMalloc, &JSREFree); |
| - if (code == NULL) { |
| - if (first_time && malloc_failure->IsRetryAfterGC()) { |
| - first_time = false; |
| - if (!Heap::CollectGarbage(malloc_failure->requested(), |
| - malloc_failure->allocation_space())) { |
| - // TODO(1181417): Fix this. |
| - V8::FatalProcessOutOfMemory("RegExpImpl::JsreCompile"); |
| - } |
| - continue; |
| - } |
| - if (malloc_failure->IsRetryAfterGC() || |
| - malloc_failure->IsOutOfMemoryFailure()) { |
| - // TODO(1181417): Fix this. |
| - V8::FatalProcessOutOfMemory("RegExpImpl::JsreCompile"); |
| - } else { |
| - // Throw an exception. |
| - Handle<JSArray> array = Factory::NewJSArray(2); |
| - SetElement(array, 0, pattern); |
| - SetElement(array, 1, Factory::NewStringFromUtf8(CStrVector( |
| - (error_message == NULL) ? "Unknown regexp error" : error_message))); |
| - Handle<Object> regexp_err = |
| - Factory::NewSyntaxError("malformed_regexp", array); |
| - return Handle<Object>(Top::Throw(*regexp_err)); |
| - } |
| - } |
| + if (code == NULL) { |
| + // Throw an exception. |
| + Handle<JSArray> array = Factory::NewJSArray(2); |
| + SetElement(array, 0, pattern); |
| + SetElement(array, 1, Factory::NewStringFromUtf8(CStrVector( |
| + (error_message == NULL) ? "Unknown regexp error" : error_message))); |
| + Handle<Object> regexp_err = |
| + Factory::NewSyntaxError("malformed_regexp", array); |
| + return Handle<Object>(Top::Throw(*regexp_err)); |
| + } |
| - ASSERT(code != NULL); |
| - // Convert the return address to a ByteArray pointer. |
| - Handle<ByteArray> internal( |
| - ByteArray::FromDataStartAddress(reinterpret_cast<Address>(code))); |
| + // Convert the return address to a ByteArray pointer. |
| + Handle<ByteArray> internal( |
| + ByteArray::FromDataStartAddress(reinterpret_cast<Address>(code))); |
| - Handle<FixedArray> value = Factory::NewFixedArray(2); |
| - value->set(CAPTURE_INDEX, Smi::FromInt(number_of_captures)); |
| - value->set(INTERNAL_INDEX, *internal); |
| - Factory::SetRegExpData(re, JSRegExp::JSCRE, pattern, flags, value); |
| + Handle<FixedArray> value = Factory::NewFixedArray(2); |
| + value->set(CAPTURE_INDEX, Smi::FromInt(number_of_captures)); |
| + value->set(INTERNAL_INDEX, *internal); |
| + Factory::SetRegExpData(re, JSRegExp::JSCRE, pattern, flags, value); |
| - return re; |
| - } |
| + return re; |
| } |