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; |
} |