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 |