OLD | NEW |
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 5996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6007 CHECK(!local_env.IsEmpty()); | 6007 CHECK(!local_env.IsEmpty()); |
6008 local_env->Enter(); | 6008 local_env->Enter(); |
6009 | 6009 |
6010 // Should complete without problems. | 6010 // Should complete without problems. |
6011 RegExpInterruptTest().RunTest(); | 6011 RegExpInterruptTest().RunTest(); |
6012 | 6012 |
6013 local_env->Exit(); | 6013 local_env->Exit(); |
6014 } | 6014 } |
6015 | 6015 |
6016 | 6016 |
| 6017 class ApplyInterruptTest { |
| 6018 public: |
| 6019 ApplyInterruptTest() : block_(NULL) {} |
| 6020 ~ApplyInterruptTest() { delete block_; } |
| 6021 void RunTest() { |
| 6022 block_ = i::OS::CreateSemaphore(0); |
| 6023 gc_count_ = 0; |
| 6024 gc_during_apply_ = 0; |
| 6025 apply_success_ = false; |
| 6026 gc_success_ = false; |
| 6027 GCThread gc_thread(this); |
| 6028 gc_thread.Start(); |
| 6029 v8::Locker::StartPreemption(1); |
| 6030 |
| 6031 LongRunningApply(); |
| 6032 { |
| 6033 v8::Unlocker unlock; |
| 6034 gc_thread.Join(); |
| 6035 } |
| 6036 v8::Locker::StopPreemption(); |
| 6037 CHECK(apply_success_); |
| 6038 CHECK(gc_success_); |
| 6039 } |
| 6040 private: |
| 6041 // Number of garbage collections required. |
| 6042 static const int kRequiredGCs = 2; |
| 6043 |
| 6044 class GCThread : public i::Thread { |
| 6045 public: |
| 6046 explicit GCThread(ApplyInterruptTest* test) |
| 6047 : test_(test) {} |
| 6048 virtual void Run() { |
| 6049 test_->CollectGarbage(); |
| 6050 } |
| 6051 private: |
| 6052 ApplyInterruptTest* test_; |
| 6053 }; |
| 6054 |
| 6055 void CollectGarbage() { |
| 6056 block_->Wait(); |
| 6057 while (gc_during_apply_ < kRequiredGCs) { |
| 6058 { |
| 6059 v8::Locker lock; |
| 6060 i::Heap::CollectAllGarbage(); |
| 6061 gc_count_++; |
| 6062 } |
| 6063 i::OS::Sleep(1); |
| 6064 } |
| 6065 gc_success_ = true; |
| 6066 } |
| 6067 |
| 6068 void LongRunningApply() { |
| 6069 block_->Signal(); |
| 6070 int rounds = 0; |
| 6071 while (gc_during_apply_ < kRequiredGCs) { |
| 6072 int gc_before = gc_count_; |
| 6073 { |
| 6074 const char* c_source = |
| 6075 "function do_very_little(bar) {" |
| 6076 " this.foo = bar;" |
| 6077 "}" |
| 6078 "for (var i = 0; i < 100000; i++) {" |
| 6079 " do_very_little.apply(this, ['bar']);" |
| 6080 "}"; |
| 6081 Local<String> source = String::New(c_source); |
| 6082 Local<Script> script = Script::Compile(source); |
| 6083 Local<Value> result = script->Run(); |
| 6084 } |
| 6085 int gc_after = gc_count_; |
| 6086 gc_during_apply_ += gc_after - gc_before; |
| 6087 rounds++; |
| 6088 } |
| 6089 apply_success_ = true; |
| 6090 } |
| 6091 |
| 6092 i::Semaphore* block_; |
| 6093 int gc_count_; |
| 6094 int gc_during_apply_; |
| 6095 bool apply_success_; |
| 6096 bool gc_success_; |
| 6097 }; |
| 6098 |
| 6099 |
| 6100 // Test that nothing bad happens if we get a preemption just when we were |
| 6101 // about to do an apply(). |
| 6102 TEST(ApplyInterruption) { |
| 6103 v8::Locker lock; |
| 6104 v8::V8::Initialize(); |
| 6105 v8::HandleScope scope; |
| 6106 Local<Context> local_env; |
| 6107 { |
| 6108 LocalContext env; |
| 6109 local_env = env.local(); |
| 6110 } |
| 6111 |
| 6112 // Local context should still be live. |
| 6113 CHECK(!local_env.IsEmpty()); |
| 6114 local_env->Enter(); |
| 6115 |
| 6116 // Should complete without problems. |
| 6117 ApplyInterruptTest().RunTest(); |
| 6118 |
| 6119 local_env->Exit(); |
| 6120 } |
| 6121 |
| 6122 |
6017 // Verify that we can clone an object | 6123 // Verify that we can clone an object |
6018 TEST(ObjectClone) { | 6124 TEST(ObjectClone) { |
6019 v8::HandleScope scope; | 6125 v8::HandleScope scope; |
6020 LocalContext env; | 6126 LocalContext env; |
6021 | 6127 |
6022 const char* sample = | 6128 const char* sample = |
6023 "var rv = {};" \ | 6129 "var rv = {};" \ |
6024 "rv.alpha = 'hello';" \ | 6130 "rv.alpha = 'hello';" \ |
6025 "rv.beta = 123;" \ | 6131 "rv.beta = 123;" \ |
6026 "rv;"; | 6132 "rv;"; |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6346 // the property | 6452 // the property |
6347 pass_on_get = false; | 6453 pass_on_get = false; |
6348 CHECK_EQ(3, global->Get(some_property)->Int32Value()); | 6454 CHECK_EQ(3, global->Get(some_property)->Int32Value()); |
6349 CHECK_EQ(1, force_set_set_count); | 6455 CHECK_EQ(1, force_set_set_count); |
6350 CHECK_EQ(5, force_set_get_count); | 6456 CHECK_EQ(5, force_set_get_count); |
6351 // The interceptor should also work for other properties | 6457 // The interceptor should also work for other properties |
6352 CHECK_EQ(3, global->Get(v8::String::New("b"))->Int32Value()); | 6458 CHECK_EQ(3, global->Get(v8::String::New("b"))->Int32Value()); |
6353 CHECK_EQ(1, force_set_set_count); | 6459 CHECK_EQ(1, force_set_set_count); |
6354 CHECK_EQ(6, force_set_get_count); | 6460 CHECK_EQ(6, force_set_get_count); |
6355 } | 6461 } |
OLD | NEW |