Chromium Code Reviews| Index: src/jsregexp.cc |
| =================================================================== |
| --- src/jsregexp.cc (revision 8501) |
| +++ src/jsregexp.cc (working copy) |
| @@ -295,6 +295,15 @@ |
| #else // V8_INTERPRETED_REGEXP (RegExp native code) |
| if (compiled_code->IsCode()) return true; |
| #endif |
| + // We could potentially have marked this as flushable, but have kept |
| + // a saved version if we did not flush it yet. |
| + Object* saved_code = re->DataAt(JSRegExp::saved_code_index(is_ascii)); |
| + if (saved_code->IsCode()) { |
| + // Reinstate the code in the original place. |
| + re->SetDataAt(JSRegExp::code_index(is_ascii), saved_code); |
| + ASSERT(compiled_code->IsSmi()); |
| + return true; |
| + } |
| return CompileIrregexp(re, is_ascii); |
| } |
| @@ -304,14 +313,26 @@ |
| Isolate* isolate = re->GetIsolate(); |
| ZoneScope zone_scope(isolate, DELETE_ON_EXIT); |
| PostponeInterruptsScope postpone(isolate); |
| + // If we had a compilation error the last time this is saved at the |
| + // saved code index. |
| Object* entry = re->DataAt(JSRegExp::code_index(is_ascii)); |
| - if (entry->IsJSObject()) { |
| - // If it's a JSObject, a previous compilation failed and threw this object. |
| - // Re-throw the object without trying again. |
| - isolate->Throw(entry); |
| + // When arriving here entry can only be a smi, either representing an |
| + // uncompiled regexp, a previous compilation error, or code that has |
| + // been flushed. |
| + ASSERT(entry->IsSmi()); |
| + int entry_value = Smi::cast(entry)->value(); |
| + ASSERT(entry_value == JSRegExp::kUninitializedValue || |
| + entry_value == JSRegExp::kCompilationErrorValue || |
| + (entry_value < JSRegExp::kCodeAgeMask && entry_value >= 0)); |
| + |
| + if (entry_value == JSRegExp::kCompilationErrorValue) { |
| + // A previous compilation failed and threw an error which we store in |
| + // the saved code index. We rethrow the error which we never flush. |
| + Object* error = re->DataAt(JSRegExp::saved_code_index(is_ascii)); |
| + ASSERT(error->IsJSObject()); |
| + isolate->Throw(error); |
| return false; |
| } |
| - ASSERT(entry->IsTheHole()); |
| JSRegExp::Flags flags = re->GetFlags(); |
| @@ -350,7 +371,10 @@ |
| Handle<Object> regexp_err = |
| factory->NewSyntaxError("malformed_regexp", array); |
| isolate->Throw(*regexp_err); |
| - re->SetDataAt(JSRegExp::code_index(is_ascii), *regexp_err); |
| + // Put the error object into the saved_code index, and put the |
| + // kCompilationErrorValue into the code index. This way, the fast |
| + // case code only needs to check the code. |
| + re->SetDataAt(JSRegExp::saved_code_index(is_ascii), *regexp_err); |
|
Erik Corry
2011/07/01 09:05:23
Shouldn't you be setting the kCompilationErrorValu
Rico
2011/07/01 09:38:26
Done.
|
| return false; |
| } |