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

Side by Side Diff: test/cctest/test-thread-termination.cc

Issue 795003: Version 2.1.2.7... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 10 years, 9 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
« no previous file with comments | « src/version.cc ('k') | test/mjsunit/regress/regress-636.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 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 22 matching lines...) Expand all
33 v8::internal::Semaphore* semaphore = NULL; 33 v8::internal::Semaphore* semaphore = NULL;
34 34
35 35
36 v8::Handle<v8::Value> Signal(const v8::Arguments& args) { 36 v8::Handle<v8::Value> Signal(const v8::Arguments& args) {
37 semaphore->Signal(); 37 semaphore->Signal();
38 return v8::Undefined(); 38 return v8::Undefined();
39 } 39 }
40 40
41 41
42 v8::Handle<v8::Value> TerminateCurrentThread(const v8::Arguments& args) { 42 v8::Handle<v8::Value> TerminateCurrentThread(const v8::Arguments& args) {
43 CHECK(!v8::V8::IsExecutionTerminating());
44 v8::V8::TerminateExecution(); 43 v8::V8::TerminateExecution();
45 return v8::Undefined(); 44 return v8::Undefined();
46 } 45 }
47 46
48 47
49 v8::Handle<v8::Value> Fail(const v8::Arguments& args) { 48 v8::Handle<v8::Value> Fail(const v8::Arguments& args) {
50 CHECK(false); 49 CHECK(false);
51 return v8::Undefined(); 50 return v8::Undefined();
52 } 51 }
53 52
54 53
55 v8::Handle<v8::Value> Loop(const v8::Arguments& args) { 54 v8::Handle<v8::Value> Loop(const v8::Arguments& args) {
56 CHECK(!v8::V8::IsExecutionTerminating());
57 v8::Handle<v8::String> source = 55 v8::Handle<v8::String> source =
58 v8::String::New("try { doloop(); fail(); } catch(e) { fail(); }"); 56 v8::String::New("try { doloop(); fail(); } catch(e) { fail(); }");
59 v8::Handle<v8::Value> result = v8::Script::Compile(source)->Run(); 57 v8::Script::Compile(source)->Run();
60 CHECK(result.IsEmpty());
61 CHECK(v8::V8::IsExecutionTerminating());
62 return v8::Undefined(); 58 return v8::Undefined();
63 } 59 }
64 60
65 61
66 v8::Handle<v8::Value> DoLoop(const v8::Arguments& args) { 62 v8::Handle<v8::Value> DoLoop(const v8::Arguments& args) {
67 v8::TryCatch try_catch; 63 v8::TryCatch try_catch;
68 CHECK(!v8::V8::IsExecutionTerminating());
69 v8::Script::Compile(v8::String::New("function f() {" 64 v8::Script::Compile(v8::String::New("function f() {"
70 " var term = true;" 65 " var term = true;"
71 " try {" 66 " try {"
72 " while(true) {" 67 " while(true) {"
73 " if (term) terminate();" 68 " if (term) terminate();"
74 " term = false;" 69 " term = false;"
75 " }" 70 " }"
76 " fail();" 71 " fail();"
77 " } catch(e) {" 72 " } catch(e) {"
78 " fail();" 73 " fail();"
79 " }" 74 " }"
80 "}" 75 "}"
81 "f()"))->Run(); 76 "f()"))->Run();
82 CHECK(try_catch.HasCaught()); 77 CHECK(try_catch.HasCaught());
83 CHECK(try_catch.Exception()->IsNull()); 78 CHECK(try_catch.Exception()->IsNull());
84 CHECK(try_catch.Message().IsEmpty()); 79 CHECK(try_catch.Message().IsEmpty());
85 CHECK(!try_catch.CanContinue()); 80 CHECK(!try_catch.CanContinue());
86 CHECK(v8::V8::IsExecutionTerminating());
87 return v8::Undefined(); 81 return v8::Undefined();
88 } 82 }
89 83
90 84
91 v8::Handle<v8::Value> DoLoopNoCall(const v8::Arguments& args) { 85 v8::Handle<v8::Value> DoLoopNoCall(const v8::Arguments& args) {
92 v8::TryCatch try_catch; 86 v8::TryCatch try_catch;
93 CHECK(!v8::V8::IsExecutionTerminating());
94 v8::Script::Compile(v8::String::New("var term = true;" 87 v8::Script::Compile(v8::String::New("var term = true;"
95 "while(true) {" 88 "while(true) {"
96 " if (term) terminate();" 89 " if (term) terminate();"
97 " term = false;" 90 " term = false;"
98 "}"))->Run(); 91 "}"))->Run();
99 CHECK(try_catch.HasCaught()); 92 CHECK(try_catch.HasCaught());
100 CHECK(try_catch.Exception()->IsNull()); 93 CHECK(try_catch.Exception()->IsNull());
101 CHECK(try_catch.Message().IsEmpty()); 94 CHECK(try_catch.Message().IsEmpty());
102 CHECK(!try_catch.CanContinue()); 95 CHECK(!try_catch.CanContinue());
103 CHECK(v8::V8::IsExecutionTerminating());
104 return v8::Undefined(); 96 return v8::Undefined();
105 } 97 }
106 98
107 99
108 v8::Handle<v8::ObjectTemplate> CreateGlobalTemplate( 100 v8::Handle<v8::ObjectTemplate> CreateGlobalTemplate(
109 v8::InvocationCallback terminate, 101 v8::InvocationCallback terminate,
110 v8::InvocationCallback doloop) { 102 v8::InvocationCallback doloop) {
111 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); 103 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
112 global->Set(v8::String::New("terminate"), 104 global->Set(v8::String::New("terminate"),
113 v8::FunctionTemplate::New(terminate)); 105 v8::FunctionTemplate::New(terminate));
114 global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail)); 106 global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail));
115 global->Set(v8::String::New("loop"), v8::FunctionTemplate::New(Loop)); 107 global->Set(v8::String::New("loop"), v8::FunctionTemplate::New(Loop));
116 global->Set(v8::String::New("doloop"), v8::FunctionTemplate::New(doloop)); 108 global->Set(v8::String::New("doloop"), v8::FunctionTemplate::New(doloop));
117 return global; 109 return global;
118 } 110 }
119 111
120 112
121 // Test that a single thread of JavaScript execution can terminate 113 // Test that a single thread of JavaScript execution can terminate
122 // itself. 114 // itself.
123 TEST(TerminateOnlyV8ThreadFromThreadItself) { 115 TEST(TerminateOnlyV8ThreadFromThreadItself) {
124 v8::HandleScope scope; 116 v8::HandleScope scope;
125 v8::Handle<v8::ObjectTemplate> global = 117 v8::Handle<v8::ObjectTemplate> global =
126 CreateGlobalTemplate(TerminateCurrentThread, DoLoop); 118 CreateGlobalTemplate(TerminateCurrentThread, DoLoop);
127 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); 119 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
128 v8::Context::Scope context_scope(context); 120 v8::Context::Scope context_scope(context);
129 CHECK(!v8::V8::IsExecutionTerminating());
130 // Run a loop that will be infinite if thread termination does not work. 121 // Run a loop that will be infinite if thread termination does not work.
131 v8::Handle<v8::String> source = 122 v8::Handle<v8::String> source =
132 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); 123 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
133 v8::Script::Compile(source)->Run(); 124 v8::Script::Compile(source)->Run();
134 // Test that we can run the code again after thread termination. 125 // Test that we can run the code again after thread termination.
135 CHECK(!v8::V8::IsExecutionTerminating());
136 v8::Script::Compile(source)->Run(); 126 v8::Script::Compile(source)->Run();
137 context.Dispose(); 127 context.Dispose();
138 } 128 }
139 129
140 130
141 // Test that a single thread of JavaScript execution can terminate 131 // Test that a single thread of JavaScript execution can terminate
142 // itself in a loop that performs no calls. 132 // itself in a loop that performs no calls.
143 TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) { 133 TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) {
144 v8::HandleScope scope; 134 v8::HandleScope scope;
145 v8::Handle<v8::ObjectTemplate> global = 135 v8::Handle<v8::ObjectTemplate> global =
146 CreateGlobalTemplate(TerminateCurrentThread, DoLoopNoCall); 136 CreateGlobalTemplate(TerminateCurrentThread, DoLoopNoCall);
147 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); 137 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
148 v8::Context::Scope context_scope(context); 138 v8::Context::Scope context_scope(context);
149 CHECK(!v8::V8::IsExecutionTerminating());
150 // Run a loop that will be infinite if thread termination does not work. 139 // Run a loop that will be infinite if thread termination does not work.
151 v8::Handle<v8::String> source = 140 v8::Handle<v8::String> source =
152 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); 141 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
153 v8::Script::Compile(source)->Run(); 142 v8::Script::Compile(source)->Run();
154 CHECK(!v8::V8::IsExecutionTerminating());
155 // Test that we can run the code again after thread termination. 143 // Test that we can run the code again after thread termination.
156 v8::Script::Compile(source)->Run(); 144 v8::Script::Compile(source)->Run();
157 context.Dispose(); 145 context.Dispose();
158 } 146 }
159 147
160 148
161 class TerminatorThread : public v8::internal::Thread { 149 class TerminatorThread : public v8::internal::Thread {
162 void Run() { 150 void Run() {
163 semaphore->Wait(); 151 semaphore->Wait();
164 CHECK(!v8::V8::IsExecutionTerminating());
165 v8::V8::TerminateExecution(); 152 v8::V8::TerminateExecution();
166 } 153 }
167 }; 154 };
168 155
169 156
170 // Test that a single thread of JavaScript execution can be terminated 157 // Test that a single thread of JavaScript execution can be terminated
171 // from the side by another thread. 158 // from the side by another thread.
172 TEST(TerminateOnlyV8ThreadFromOtherThread) { 159 TEST(TerminateOnlyV8ThreadFromOtherThread) {
173 semaphore = v8::internal::OS::CreateSemaphore(0); 160 semaphore = v8::internal::OS::CreateSemaphore(0);
174 TerminatorThread thread; 161 TerminatorThread thread;
175 thread.Start(); 162 thread.Start();
176 163
177 v8::HandleScope scope; 164 v8::HandleScope scope;
178 v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(Signal, DoLoop); 165 v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(Signal, DoLoop);
179 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); 166 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
180 v8::Context::Scope context_scope(context); 167 v8::Context::Scope context_scope(context);
181 CHECK(!v8::V8::IsExecutionTerminating());
182 // Run a loop that will be infinite if thread termination does not work. 168 // Run a loop that will be infinite if thread termination does not work.
183 v8::Handle<v8::String> source = 169 v8::Handle<v8::String> source =
184 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); 170 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
185 v8::Script::Compile(source)->Run(); 171 v8::Script::Compile(source)->Run();
186 172
187 thread.Join(); 173 thread.Join();
188 delete semaphore; 174 delete semaphore;
189 semaphore = NULL; 175 semaphore = NULL;
190 context.Dispose(); 176 context.Dispose();
191 } 177 }
192 178
193 179
194 class LoopingThread : public v8::internal::Thread { 180 class LoopingThread : public v8::internal::Thread {
195 public: 181 public:
196 void Run() { 182 void Run() {
197 v8::Locker locker; 183 v8::Locker locker;
198 v8::HandleScope scope; 184 v8::HandleScope scope;
199 v8_thread_id_ = v8::V8::GetCurrentThreadId(); 185 v8_thread_id_ = v8::V8::GetCurrentThreadId();
200 v8::Handle<v8::ObjectTemplate> global = 186 v8::Handle<v8::ObjectTemplate> global =
201 CreateGlobalTemplate(Signal, DoLoop); 187 CreateGlobalTemplate(Signal, DoLoop);
202 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); 188 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
203 v8::Context::Scope context_scope(context); 189 v8::Context::Scope context_scope(context);
204 CHECK(!v8::V8::IsExecutionTerminating());
205 // Run a loop that will be infinite if thread termination does not work. 190 // Run a loop that will be infinite if thread termination does not work.
206 v8::Handle<v8::String> source = 191 v8::Handle<v8::String> source =
207 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); 192 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
208 v8::Script::Compile(source)->Run(); 193 v8::Script::Compile(source)->Run();
209 context.Dispose(); 194 context.Dispose();
210 } 195 }
211 196
212 int GetV8ThreadId() { return v8_thread_id_; } 197 int GetV8ThreadId() { return v8_thread_id_; }
213 198
214 private: 199 private:
(...skipping 28 matching lines...) Expand all
243 delete semaphore; 228 delete semaphore;
244 semaphore = NULL; 229 semaphore = NULL;
245 } 230 }
246 231
247 232
248 int call_count = 0; 233 int call_count = 0;
249 234
250 235
251 v8::Handle<v8::Value> TerminateOrReturnObject(const v8::Arguments& args) { 236 v8::Handle<v8::Value> TerminateOrReturnObject(const v8::Arguments& args) {
252 if (++call_count == 10) { 237 if (++call_count == 10) {
253 CHECK(!v8::V8::IsExecutionTerminating());
254 v8::V8::TerminateExecution(); 238 v8::V8::TerminateExecution();
255 return v8::Undefined(); 239 return v8::Undefined();
256 } 240 }
257 v8::Local<v8::Object> result = v8::Object::New(); 241 v8::Local<v8::Object> result = v8::Object::New();
258 result->Set(v8::String::New("x"), v8::Integer::New(42)); 242 result->Set(v8::String::New("x"), v8::Integer::New(42));
259 return result; 243 return result;
260 } 244 }
261 245
262 246
263 v8::Handle<v8::Value> LoopGetProperty(const v8::Arguments& args) { 247 v8::Handle<v8::Value> LoopGetProperty(const v8::Arguments& args) {
264 v8::TryCatch try_catch; 248 v8::TryCatch try_catch;
265 CHECK(!v8::V8::IsExecutionTerminating());
266 v8::Script::Compile(v8::String::New("function f() {" 249 v8::Script::Compile(v8::String::New("function f() {"
267 " try {" 250 " try {"
268 " while(true) {" 251 " while(true) {"
269 " terminate_or_return_object().x;" 252 " terminate_or_return_object().x;"
270 " }" 253 " }"
271 " fail();" 254 " fail();"
272 " } catch(e) {" 255 " } catch(e) {"
273 " fail();" 256 " fail();"
274 " }" 257 " }"
275 "}" 258 "}"
276 "f()"))->Run(); 259 "f()"))->Run();
277 CHECK(try_catch.HasCaught()); 260 CHECK(try_catch.HasCaught());
278 CHECK(try_catch.Exception()->IsNull()); 261 CHECK(try_catch.Exception()->IsNull());
279 CHECK(try_catch.Message().IsEmpty()); 262 CHECK(try_catch.Message().IsEmpty());
280 CHECK(!try_catch.CanContinue()); 263 CHECK(!try_catch.CanContinue());
281 CHECK(v8::V8::IsExecutionTerminating());
282 return v8::Undefined(); 264 return v8::Undefined();
283 } 265 }
284 266
285 267
286 // Test that we correctly handle termination exceptions if they are 268 // Test that we correctly handle termination exceptions if they are
287 // triggered by the creation of error objects in connection with ICs. 269 // triggered by the creation of error objects in connection with ICs.
288 TEST(TerminateLoadICException) { 270 TEST(TerminateLoadICException) {
289 v8::HandleScope scope; 271 v8::HandleScope scope;
290 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); 272 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
291 global->Set(v8::String::New("terminate_or_return_object"), 273 global->Set(v8::String::New("terminate_or_return_object"),
292 v8::FunctionTemplate::New(TerminateOrReturnObject)); 274 v8::FunctionTemplate::New(TerminateOrReturnObject));
293 global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail)); 275 global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail));
294 global->Set(v8::String::New("loop"), 276 global->Set(v8::String::New("loop"),
295 v8::FunctionTemplate::New(LoopGetProperty)); 277 v8::FunctionTemplate::New(LoopGetProperty));
296 278
297 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global); 279 v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
298 v8::Context::Scope context_scope(context); 280 v8::Context::Scope context_scope(context);
299 CHECK(!v8::V8::IsExecutionTerminating());
300 // Run a loop that will be infinite if thread termination does not work. 281 // Run a loop that will be infinite if thread termination does not work.
301 v8::Handle<v8::String> source = 282 v8::Handle<v8::String> source =
302 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }"); 283 v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
303 call_count = 0; 284 call_count = 0;
304 v8::Script::Compile(source)->Run(); 285 v8::Script::Compile(source)->Run();
305 // Test that we can run the code again after thread termination. 286 // Test that we can run the code again after thread termination.
306 CHECK(!v8::V8::IsExecutionTerminating());
307 call_count = 0; 287 call_count = 0;
308 v8::Script::Compile(source)->Run(); 288 v8::Script::Compile(source)->Run();
309 context.Dispose(); 289 context.Dispose();
310 } 290 }
OLDNEW
« no previous file with comments | « src/version.cc ('k') | test/mjsunit/regress/regress-636.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698