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

Side by Side Diff: src/jsregexp.cc

Issue 7282026: Introduce code flushing of RegExp code. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 5 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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 // from the source pattern. 288 // from the source pattern.
289 // If compilation fails, an exception is thrown and this function 289 // If compilation fails, an exception is thrown and this function
290 // returns false. 290 // returns false.
291 bool RegExpImpl::EnsureCompiledIrregexp(Handle<JSRegExp> re, bool is_ascii) { 291 bool RegExpImpl::EnsureCompiledIrregexp(Handle<JSRegExp> re, bool is_ascii) {
292 Object* compiled_code = re->DataAt(JSRegExp::code_index(is_ascii)); 292 Object* compiled_code = re->DataAt(JSRegExp::code_index(is_ascii));
293 #ifdef V8_INTERPRETED_REGEXP 293 #ifdef V8_INTERPRETED_REGEXP
294 if (compiled_code->IsByteArray()) return true; 294 if (compiled_code->IsByteArray()) return true;
295 #else // V8_INTERPRETED_REGEXP (RegExp native code) 295 #else // V8_INTERPRETED_REGEXP (RegExp native code)
296 if (compiled_code->IsCode()) return true; 296 if (compiled_code->IsCode()) return true;
297 #endif 297 #endif
298 // We could potentially have marked this as flushable, but have kept
299 // a saved version if we did not flush it yet.
300 Object* saved_code = re->DataAt(JSRegExp::saved_code_index(is_ascii));
301 if (saved_code->IsCode()) {
302 // Reinstate the code in the original place.
303 re->SetDataAt(JSRegExp::code_index(is_ascii), saved_code);
304 ASSERT(compiled_code->IsSmi());
305 return true;
306 }
298 return CompileIrregexp(re, is_ascii); 307 return CompileIrregexp(re, is_ascii);
299 } 308 }
300 309
301 310
311 static bool CreateRegExpErrorObjectAndThrow(Handle<JSRegExp> re,
312 bool is_ascii,
313 Handle<String> error_message,
314 Isolate* isolate) {
315 Factory* factory = isolate->factory();
316 Handle<FixedArray> elements = factory->NewFixedArray(2);
317 elements->set(0, re->Pattern());
318 elements->set(1, *error_message);
319 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
320 Handle<Object> regexp_err =
321 factory->NewSyntaxError("malformed_regexp", array);
322 isolate->Throw(*regexp_err);
323 return false;
324 }
325
326
302 bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, bool is_ascii) { 327 bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, bool is_ascii) {
303 // Compile the RegExp. 328 // Compile the RegExp.
304 Isolate* isolate = re->GetIsolate(); 329 Isolate* isolate = re->GetIsolate();
305 ZoneScope zone_scope(isolate, DELETE_ON_EXIT); 330 ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
306 PostponeInterruptsScope postpone(isolate); 331 PostponeInterruptsScope postpone(isolate);
332 // If we had a compilation error the last time this is saved at the
333 // saved code index.
307 Object* entry = re->DataAt(JSRegExp::code_index(is_ascii)); 334 Object* entry = re->DataAt(JSRegExp::code_index(is_ascii));
308 if (entry->IsJSObject()) { 335 // When arriving here entry can only be a smi, either representing an
309 // If it's a JSObject, a previous compilation failed and threw this object. 336 // uncompiled regexp, a previous compilation error, or code that has
310 // Re-throw the object without trying again. 337 // been flushed.
311 isolate->Throw(entry); 338 ASSERT(entry->IsSmi());
339 int entry_value = Smi::cast(entry)->value();
340 ASSERT(entry_value == JSRegExp::kUninitializedValue ||
341 entry_value == JSRegExp::kCompilationErrorValue ||
342 (entry_value < JSRegExp::kCodeAgeMask && entry_value >= 0));
343
344 if (entry_value == JSRegExp::kCompilationErrorValue) {
345 // A previous compilation failed and threw an error which we store in
346 // the saved code index (we store the error message, not the actual
347 // error). Recreate the error object and throw it.
348 Object* error_string = re->DataAt(JSRegExp::saved_code_index(is_ascii));
349 ASSERT(error_string->IsString());
350 Handle<String> error_message(String::cast(error_string));
351 CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate);
312 return false; 352 return false;
313 } 353 }
314 ASSERT(entry->IsTheHole());
315 354
316 JSRegExp::Flags flags = re->GetFlags(); 355 JSRegExp::Flags flags = re->GetFlags();
317 356
318 Handle<String> pattern(re->Pattern()); 357 Handle<String> pattern(re->Pattern());
319 if (!pattern->IsFlat()) { 358 if (!pattern->IsFlat()) {
320 FlattenString(pattern); 359 FlattenString(pattern);
321 } 360 }
322 361
323 RegExpCompileData compile_data; 362 RegExpCompileData compile_data;
324 FlatStringReader reader(isolate, pattern); 363 FlatStringReader reader(isolate, pattern);
325 if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(), 364 if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
326 &compile_data)) { 365 &compile_data)) {
327 // Throw an exception if we fail to parse the pattern. 366 // Throw an exception if we fail to parse the pattern.
328 // THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once. 367 // THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once.
329 ThrowRegExpException(re, 368 ThrowRegExpException(re,
330 pattern, 369 pattern,
331 compile_data.error, 370 compile_data.error,
332 "malformed_regexp"); 371 "malformed_regexp");
333 return false; 372 return false;
334 } 373 }
335 RegExpEngine::CompilationResult result = 374 RegExpEngine::CompilationResult result =
336 RegExpEngine::Compile(&compile_data, 375 RegExpEngine::Compile(&compile_data,
337 flags.is_ignore_case(), 376 flags.is_ignore_case(),
338 flags.is_multiline(), 377 flags.is_multiline(),
339 pattern, 378 pattern,
340 is_ascii); 379 is_ascii);
341 if (result.error_message != NULL) { 380 if (result.error_message != NULL) {
342 // Unable to compile regexp. 381 // Unable to compile regexp.
343 Factory* factory = isolate->factory();
344 Handle<FixedArray> elements = factory->NewFixedArray(2);
345 elements->set(0, *pattern);
346 Handle<String> error_message = 382 Handle<String> error_message =
347 factory->NewStringFromUtf8(CStrVector(result.error_message)); 383 isolate->factory()->NewStringFromUtf8(CStrVector(result.error_message));
348 elements->set(1, *error_message); 384 CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate);
349 Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
350 Handle<Object> regexp_err =
351 factory->NewSyntaxError("malformed_regexp", array);
352 isolate->Throw(*regexp_err);
353 re->SetDataAt(JSRegExp::code_index(is_ascii), *regexp_err);
354 return false; 385 return false;
355 } 386 }
356 387
357 Handle<FixedArray> data = Handle<FixedArray>(FixedArray::cast(re->data())); 388 Handle<FixedArray> data = Handle<FixedArray>(FixedArray::cast(re->data()));
358 data->set(JSRegExp::code_index(is_ascii), result.code); 389 data->set(JSRegExp::code_index(is_ascii), result.code);
359 int register_max = IrregexpMaxRegisterCount(*data); 390 int register_max = IrregexpMaxRegisterCount(*data);
360 if (result.num_registers > register_max) { 391 if (result.num_registers > register_max) {
361 SetIrregexpMaxRegisterCount(*data, result.num_registers); 392 SetIrregexpMaxRegisterCount(*data, result.num_registers);
362 } 393 }
363 394
(...skipping 4967 matching lines...) Expand 10 before | Expand all | Expand 10 after
5331 } 5362 }
5332 5363
5333 return compiler.Assemble(&macro_assembler, 5364 return compiler.Assemble(&macro_assembler,
5334 node, 5365 node,
5335 data->capture_count, 5366 data->capture_count,
5336 pattern); 5367 pattern);
5337 } 5368 }
5338 5369
5339 5370
5340 }} // namespace v8::internal 5371 }} // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/mark-compact.cc » ('j') | src/objects-debug.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698