Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 14305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14316 // result has the 'x' property. | 14316 // result has the 'x' property. | 
| 14317 context1->Enter(); | 14317 context1->Enter(); | 
| 14318 context1->Global()->Set(v8_str("other"), context0->Global()); | 14318 context1->Global()->Set(v8_str("other"), context0->Global()); | 
| 14319 Local<Value> value = CompileRun("var instance = new other.C(); instance.x"); | 14319 Local<Value> value = CompileRun("var instance = new other.C(); instance.x"); | 
| 14320 CHECK(value->IsInt32()); | 14320 CHECK(value->IsInt32()); | 
| 14321 CHECK_EQ(42, value->Int32Value()); | 14321 CHECK_EQ(42, value->Int32Value()); | 
| 14322 context1->Exit(); | 14322 context1->Exit(); | 
| 14323 } | 14323 } | 
| 14324 | 14324 | 
| 14325 | 14325 | 
| 14326 class RegExpInterruptTest { | |
| 14327 public: | |
| 14328 RegExpInterruptTest() : block_(0) {} | |
| 14329 ~RegExpInterruptTest() {} | |
| 14330 void RunTest() { | |
| 14331 gc_count_ = 0; | |
| 14332 gc_during_regexp_ = 0; | |
| 14333 regexp_success_ = false; | |
| 14334 gc_success_ = false; | |
| 14335 GCThread gc_thread(this); | |
| 14336 gc_thread.Start(); | |
| 14337 v8::Isolate* isolate = CcTest::isolate(); | |
| 14338 v8::Locker::StartPreemption(isolate, 1); | |
| 14339 | |
| 14340 LongRunningRegExp(); | |
| 14341 { | |
| 14342 v8::Unlocker unlock(isolate); | |
| 14343 gc_thread.Join(); | |
| 14344 } | |
| 14345 v8::Locker::StopPreemption(isolate); | |
| 14346 CHECK(regexp_success_); | |
| 14347 CHECK(gc_success_); | |
| 14348 } | |
| 14349 | |
| 14350 private: | |
| 14351 // Number of garbage collections required. | |
| 14352 static const int kRequiredGCs = 5; | |
| 14353 | |
| 14354 class GCThread : public i::Thread { | |
| 14355 public: | |
| 14356 explicit GCThread(RegExpInterruptTest* test) | |
| 14357 : Thread("GCThread"), test_(test) {} | |
| 14358 virtual void Run() { | |
| 14359 test_->CollectGarbage(); | |
| 14360 } | |
| 14361 private: | |
| 14362 RegExpInterruptTest* test_; | |
| 14363 }; | |
| 14364 | |
| 14365 void CollectGarbage() { | |
| 14366 block_.Wait(); | |
| 14367 while (gc_during_regexp_ < kRequiredGCs) { | |
| 14368 { | |
| 14369 v8::Locker lock(CcTest::isolate()); | |
| 14370 v8::Isolate::Scope isolate_scope(CcTest::isolate()); | |
| 14371 // TODO(lrn): Perhaps create some garbage before collecting. | |
| 14372 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | |
| 14373 gc_count_++; | |
| 14374 } | |
| 14375 i::OS::Sleep(1); | |
| 14376 } | |
| 14377 gc_success_ = true; | |
| 14378 } | |
| 14379 | |
| 14380 void LongRunningRegExp() { | |
| 14381 block_.Signal(); // Enable garbage collection thread on next preemption. | |
| 14382 int rounds = 0; | |
| 14383 while (gc_during_regexp_ < kRequiredGCs) { | |
| 14384 int gc_before = gc_count_; | |
| 14385 { | |
| 14386 // Match 15-30 "a"'s against 14 and a "b". | |
| 14387 const char* c_source = | |
| 14388 "/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/" | |
| 14389 ".exec('aaaaaaaaaaaaaaab') === null"; | |
| 14390 Local<String> source = String::New(c_source); | |
| 14391 Local<Script> script = Script::Compile(source); | |
| 14392 Local<Value> result = script->Run(); | |
| 14393 if (!result->BooleanValue()) { | |
| 14394 gc_during_regexp_ = kRequiredGCs; // Allow gc thread to exit. | |
| 14395 return; | |
| 14396 } | |
| 14397 } | |
| 14398 { | |
| 14399 // Match 15-30 "a"'s against 15 and a "b". | |
| 14400 const char* c_source = | |
| 14401 "/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/" | |
| 14402 ".exec('aaaaaaaaaaaaaaaab')[0] === 'aaaaaaaaaaaaaaaa'"; | |
| 14403 Local<String> source = String::New(c_source); | |
| 14404 Local<Script> script = Script::Compile(source); | |
| 14405 Local<Value> result = script->Run(); | |
| 14406 if (!result->BooleanValue()) { | |
| 14407 gc_during_regexp_ = kRequiredGCs; | |
| 14408 return; | |
| 14409 } | |
| 14410 } | |
| 14411 int gc_after = gc_count_; | |
| 14412 gc_during_regexp_ += gc_after - gc_before; | |
| 14413 rounds++; | |
| 14414 i::OS::Sleep(1); | |
| 14415 } | |
| 14416 regexp_success_ = true; | |
| 14417 } | |
| 14418 | |
| 14419 i::Semaphore block_; | |
| 14420 int gc_count_; | |
| 14421 int gc_during_regexp_; | |
| 14422 bool regexp_success_; | |
| 14423 bool gc_success_; | |
| 14424 }; | |
| 14425 | |
| 14426 | |
| 14427 // Test that a regular expression execution can be interrupted and | |
| 14428 // survive a garbage collection. | |
| 14429 TEST(RegExpInterruption) { | |
| 14430 v8::Locker lock(CcTest::isolate()); | |
| 14431 v8::HandleScope scope(CcTest::isolate()); | |
| 14432 Local<Context> local_env; | |
| 14433 { | |
| 14434 LocalContext env; | |
| 14435 local_env = env.local(); | |
| 14436 } | |
| 14437 | |
| 14438 // Local context should still be live. | |
| 14439 CHECK(!local_env.IsEmpty()); | |
| 14440 local_env->Enter(); | |
| 14441 | |
| 14442 // Should complete without problems. | |
| 14443 RegExpInterruptTest().RunTest(); | |
| 14444 | |
| 14445 local_env->Exit(); | |
| 14446 } | |
| 14447 | |
| 14448 | |
| 14449 class ApplyInterruptTest { | 14326 class ApplyInterruptTest { | 
| 
 
jochen (gone - plz use gerrit)
2013/10/11 18:31:06
this and another test in this file also use the pr
 
 | |
| 14450 public: | 14327 public: | 
| 14451 ApplyInterruptTest() : block_(0) {} | 14328 ApplyInterruptTest() : block_(0) {} | 
| 14452 ~ApplyInterruptTest() {} | 14329 ~ApplyInterruptTest() {} | 
| 14453 void RunTest() { | 14330 void RunTest() { | 
| 14454 gc_count_ = 0; | 14331 gc_count_ = 0; | 
| 14455 gc_during_apply_ = 0; | 14332 gc_during_apply_ = 0; | 
| 14456 apply_success_ = false; | 14333 apply_success_ = false; | 
| 14457 gc_success_ = false; | 14334 gc_success_ = false; | 
| 14458 GCThread gc_thread(this); | 14335 GCThread gc_thread(this); | 
| 14459 gc_thread.Start(); | 14336 gc_thread.Start(); | 
| (...skipping 6265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 20725 } | 20602 } | 
| 20726 for (int i = 0; i < runs; i++) { | 20603 for (int i = 0; i < runs; i++) { | 
| 20727 Local<String> expected; | 20604 Local<String> expected; | 
| 20728 if (i != 0) { | 20605 if (i != 0) { | 
| 20729 CHECK_EQ(v8_str("escape value"), values[i]); | 20606 CHECK_EQ(v8_str("escape value"), values[i]); | 
| 20730 } else { | 20607 } else { | 
| 20731 CHECK(values[i].IsEmpty()); | 20608 CHECK(values[i].IsEmpty()); | 
| 20732 } | 20609 } | 
| 20733 } | 20610 } | 
| 20734 } | 20611 } | 
| OLD | NEW |