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

Side by Side Diff: test/cctest/test-api.cc

Issue 20536: Add test to check that RegExp-ia32 can survive a garbage collection during execution. (Closed)
Patch Set: Created 11 years, 10 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
« no previous file with comments | « src/regexp-macro-assembler-ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2007-2008 the V8 project authors. All rights reserved. 1 // Copyright 2007-2008 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 5640 matching lines...) Expand 10 before | Expand all | Expand 10 after
5651 context1->Global()->Set(v8_str("other"), context0->Global()); 5651 context1->Global()->Set(v8_str("other"), context0->Global());
5652 Local<Value> value = CompileRun("var instance = new other.C(); instance.x"); 5652 Local<Value> value = CompileRun("var instance = new other.C(); instance.x");
5653 CHECK(value->IsInt32()); 5653 CHECK(value->IsInt32());
5654 CHECK_EQ(42, value->Int32Value()); 5654 CHECK_EQ(42, value->Int32Value());
5655 context1->Exit(); 5655 context1->Exit();
5656 5656
5657 // Dispose the contexts to allow them to be garbage collected. 5657 // Dispose the contexts to allow them to be garbage collected.
5658 context0.Dispose(); 5658 context0.Dispose();
5659 context1.Dispose(); 5659 context1.Dispose();
5660 } 5660 }
5661
5662
5663 class RegExpInterruptTest {
5664 public:
5665 void RunTest() {
5666 block_ = i::OS::CreateSemaphore(0);
5667 gc_count_ = 0;
5668 gc_during_regexp_ = 0;
5669 regexp_success_ = false;
5670 gc_success_ = false;
5671 GCThread gc_thread(this);
5672 gc_thread.Start();
5673 v8::Locker::StartPreemption(1);
5674
5675 LongRunningRegExp();
5676 {
5677 v8::Unlocker unlock;
5678 gc_thread.Join();
5679 }
5680 v8::Locker::StopPreemption();
5681 CHECK(regexp_success_);
5682 CHECK(gc_success_);
5683 }
5684 private:
5685 // Number of garbage collections required.
5686 static const int kRequiredGCs = 5;
5687
5688 class GCThread : public i::Thread {
5689 public:
5690 explicit GCThread(RegExpInterruptTest* test)
5691 : test_(test) {}
5692 virtual void Run() {
5693 test_->CollectGarbage();
5694 }
5695 private:
5696 RegExpInterruptTest* test_;
5697 };
5698
5699 void CollectGarbage() {
5700 block_->Wait();
5701 while (gc_during_regexp_ < kRequiredGCs) {
5702 {
5703 v8::Locker lock;
5704 // TODO(lrn): Perhaps create some garbage before collecting.
5705 i::Heap::CollectAllGarbage();
5706 gc_count_++;
5707 }
5708 i::OS::Sleep(1);
5709 }
5710 gc_success_ = true;
5711 }
5712
5713 void LongRunningRegExp() {
5714 block_->Signal(); // Enable garbage collection thread on next preemption.
5715 int rounds = 0;
5716 while (gc_during_regexp_ < kRequiredGCs) {
5717 int gc_before = gc_count_;
5718 {
5719 // match 15-30 "a"'s against 14 and a "b".
5720 const char* c_source =
5721 "/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/"
5722 ".exec('aaaaaaaaaaaaaaab') === null";
5723 Local<String> source = String::New(c_source);
5724 Local<Script> script = Script::Compile(source);
5725 Local<Value> result = script->Run();
5726 if (!result->BooleanValue()) {
5727 gc_during_regexp_ = kRequiredGCs; // Allow gc thread to exit.
5728 return;
5729 }
5730 }
5731 {
5732 // match 15-30 "a"'s against 15 and a "b".
5733 const char* c_source =
5734 "/a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaa/"
5735 ".exec('aaaaaaaaaaaaaaaab')[0] === 'aaaaaaaaaaaaaaaa'";
5736 Local<String> source = String::New(c_source);
5737 Local<Script> script = Script::Compile(source);
5738 Local<Value> result = script->Run();
5739 if (!result->BooleanValue()) {
5740 gc_during_regexp_ = kRequiredGCs;
5741 return;
5742 }
5743 }
5744 int gc_after = gc_count_;
5745 gc_during_regexp_ += gc_after - gc_before;
5746 rounds++;
5747 i::OS::Sleep(1);
5748 }
5749 regexp_success_ = true;
5750 }
5751
5752 i::Semaphore* block_;
5753 int gc_count_;
5754 int gc_during_regexp_;
5755 bool regexp_success_;
5756 bool gc_success_;
5757 };
5758
5759
5760 // Test that a regular expression execution can be interrupted and
5761 // survive a garbage collection.
5762 TEST(RegExpInterruption) {
5763 v8::Locker lock;
5764 v8::V8::Initialize();
5765 v8::HandleScope scope;
5766 Local<Context> local_env;
5767 {
5768 LocalContext env;
5769 local_env = env.local();
5770 }
5771
5772 // Local context should still be live.
5773 CHECK(!local_env.IsEmpty());
5774 local_env->Enter();
5775
5776 // Should complete without problems.
5777 RegExpInterruptTest().RunTest();
5778
5779 local_env->Exit();
5780 }
OLDNEW
« no previous file with comments | « src/regexp-macro-assembler-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698