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

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

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

Powered by Google App Engine
This is Rietveld 408576698