v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
test-thread-termination.cc
Go to the documentation of this file.
1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include "v8.h"
29 #include "platform.h"
30 #include "cctest.h"
31 
32 
33 v8::internal::Semaphore* semaphore = NULL;
34 
35 
37  semaphore->Signal();
38 }
39 
40 
44 }
45 
46 
48  CHECK(false);
49 }
50 
51 
55  args.GetIsolate(), "try { doloop(); fail(); } catch(e) { fail(); }");
56  v8::Handle<v8::Value> result = v8::Script::Compile(source)->Run();
57  CHECK(result.IsEmpty());
59 }
60 
61 
63  v8::TryCatch try_catch;
66  "function f() {"
67  " var term = true;"
68  " try {"
69  " while(true) {"
70  " if (term) terminate();"
71  " term = false;"
72  " }"
73  " fail();"
74  " } catch(e) {"
75  " fail();"
76  " }"
77  "}"
78  "f()"))->Run();
79  CHECK(try_catch.HasCaught());
80  CHECK(try_catch.Exception()->IsNull());
81  CHECK(try_catch.Message().IsEmpty());
82  CHECK(!try_catch.CanContinue());
84 }
85 
86 
88  v8::TryCatch try_catch;
91  "var term = true;"
92  "while(true) {"
93  " if (term) terminate();"
94  " term = false;"
95  "}"))->Run();
96  CHECK(try_catch.HasCaught());
97  CHECK(try_catch.Exception()->IsNull());
98  CHECK(try_catch.Message().IsEmpty());
99  CHECK(!try_catch.CanContinue());
101 }
102 
103 
105  v8::Isolate* isolate,
106  v8::FunctionCallback terminate,
107  v8::FunctionCallback doloop) {
109  global->Set(v8::String::NewFromUtf8(isolate, "terminate"),
110  v8::FunctionTemplate::New(isolate, terminate));
111  global->Set(v8::String::NewFromUtf8(isolate, "fail"),
112  v8::FunctionTemplate::New(isolate, Fail));
113  global->Set(v8::String::NewFromUtf8(isolate, "loop"),
114  v8::FunctionTemplate::New(isolate, Loop));
115  global->Set(v8::String::NewFromUtf8(isolate, "doloop"),
116  v8::FunctionTemplate::New(isolate, doloop));
117  return global;
118 }
119 
120 
121 // Test that a single thread of JavaScript execution can terminate
122 // itself.
123 TEST(TerminateOnlyV8ThreadFromThreadItself) {
127  v8::Handle<v8::Context> context =
129  v8::Context::Scope context_scope(context);
131  // Run a loop that will be infinite if thread termination does not work.
133  CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }");
134  v8::Script::Compile(source)->Run();
135  // Test that we can run the code again after thread termination.
137  v8::Script::Compile(source)->Run();
138 }
139 
140 
141 // Test that a single thread of JavaScript execution can terminate
142 // itself in a loop that performs no calls.
143 TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) {
147  v8::Handle<v8::Context> context =
149  v8::Context::Scope context_scope(context);
151  // Run a loop that will be infinite if thread termination does not work.
153  CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }");
154  v8::Script::Compile(source)->Run();
156  // Test that we can run the code again after thread termination.
157  v8::Script::Compile(source)->Run();
158 }
159 
160 
162  public:
163  explicit TerminatorThread(i::Isolate* isolate)
164  : Thread("TerminatorThread"),
165  isolate_(reinterpret_cast<v8::Isolate*>(isolate)) { }
166  void Run() {
167  semaphore->Wait();
169  v8::V8::TerminateExecution(isolate_);
170  }
171 
172  private:
173  v8::Isolate* isolate_;
174 };
175 
176 
177 // Test that a single thread of JavaScript execution can be terminated
178 // from the side by another thread.
179 TEST(TerminateOnlyV8ThreadFromOtherThread) {
180  semaphore = new v8::internal::Semaphore(0);
182  thread.Start();
183 
187  v8::Handle<v8::Context> context =
189  v8::Context::Scope context_scope(context);
191  // Run a loop that will be infinite if thread termination does not work.
193  CcTest::isolate(), "try { loop(); fail(); } catch(e) { fail(); }");
194  v8::Script::Compile(source)->Run();
195 
196  thread.Join();
197  delete semaphore;
198  semaphore = NULL;
199 }
200 
201 
202 int call_count = 0;
203 
204 
206  if (++call_count == 10) {
209  return;
210  }
212  result->Set(v8::String::NewFromUtf8(args.GetIsolate(), "x"),
213  v8::Integer::New(args.GetIsolate(), 42));
214  args.GetReturnValue().Set(result);
215 }
216 
217 
219  v8::TryCatch try_catch;
223  "function f() {"
224  " try {"
225  " while(true) {"
226  " terminate_or_return_object().x;"
227  " }"
228  " fail();"
229  " } catch(e) {"
230  " fail();"
231  " }"
232  "}"
233  "f()"))->Run();
234  CHECK(try_catch.HasCaught());
235  CHECK(try_catch.Exception()->IsNull());
236  CHECK(try_catch.Message().IsEmpty());
237  CHECK(!try_catch.CanContinue());
239 }
240 
241 
242 // Test that we correctly handle termination exceptions if they are
243 // triggered by the creation of error objects in connection with ICs.
244 TEST(TerminateLoadICException) {
245  v8::Isolate* isolate = CcTest::isolate();
246  v8::HandleScope scope(isolate);
248  global->Set(
249  v8::String::NewFromUtf8(isolate, "terminate_or_return_object"),
251  global->Set(v8::String::NewFromUtf8(isolate, "fail"),
252  v8::FunctionTemplate::New(isolate, Fail));
253  global->Set(v8::String::NewFromUtf8(isolate, "loop"),
255 
256  v8::Handle<v8::Context> context =
257  v8::Context::New(isolate, NULL, global);
258  v8::Context::Scope context_scope(context);
260  // Run a loop that will be infinite if thread termination does not work.
262  isolate, "try { loop(); fail(); } catch(e) { fail(); }");
263  call_count = 0;
264  v8::Script::Compile(source)->Run();
265  // Test that we can run the code again after thread termination.
267  call_count = 0;
268  v8::Script::Compile(source)->Run();
269 }
270 
271 
273  v8::TryCatch try_catch;
276  "function f() {"
277  " var term = true;"
278  " try {"
279  " while(true) {"
280  " if (term) terminate();"
281  " term = false;"
282  " }"
283  " fail();"
284  " } catch(e) {"
285  " fail();"
286  " }"
287  "}"
288  "f()"))->Run();
289  CHECK(try_catch.HasCaught());
290  CHECK(try_catch.Exception()->IsNull());
291  CHECK(try_catch.Message().IsEmpty());
292  CHECK(!try_catch.CanContinue());
295  "function f() { fail(); } f()"))
296  ->Run();
297 }
298 
299 
300 // Test that reentry into V8 while the termination exception is still pending
301 // (has not yet unwound the 0-level JS frame) does not crash.
302 TEST(TerminateAndReenterFromThreadItself) {
303  v8::Isolate* isolate = CcTest::isolate();
304  v8::HandleScope scope(isolate);
307  v8::Handle<v8::Context> context =
308  v8::Context::New(isolate, NULL, global);
309  v8::Context::Scope context_scope(context);
312  isolate, "try { loop(); fail(); } catch(e) { fail(); }");
313  v8::Script::Compile(source)->Run();
315  // Check we can run JS again after termination.
317  v8::String::NewFromUtf8(isolate,
318  "function f() { return true; }"
319  "f()"))
320  ->Run()
321  ->IsTrue());
322 }
323 
324 
326  v8::TryCatch try_catch;
329  "var term = true;"
330  "while(true) {"
331  " if (term) terminate();"
332  " term = false;"
333  "}"
334  "fail();"))->Run();
335  CHECK(try_catch.HasCaught());
336  CHECK(try_catch.Exception()->IsNull());
337  CHECK(try_catch.Message().IsEmpty());
338  CHECK(!try_catch.CanContinue());
340  CHECK(try_catch.HasTerminated());
343 }
344 
345 
346 // Test that a single thread of JavaScript execution can terminate
347 // itself and then resume execution.
348 TEST(TerminateCancelTerminateFromThreadItself) {
349  v8::Isolate* isolate = CcTest::isolate();
350  v8::HandleScope scope(isolate);
353  v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global);
354  v8::Context::Scope context_scope(context);
357  isolate, "try { doloop(); } catch(e) { fail(); } 'completed';");
358  // Check that execution completed with correct return value.
359  CHECK(v8::Script::Compile(source)->Run()->Equals(v8_str("completed")));
360 }
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
void Fail(const v8::FunctionCallbackInfo< v8::Value > &args)
TerminatorThread(i::Isolate *isolate)
static bool IsExecutionTerminating(Isolate *isolate=NULL)
Definition: api.cc:6541
void Signal(const v8::FunctionCallbackInfo< v8::Value > &args)
Thread(const Options &options)
Local< Value > Exception() const
Definition: api.cc:1923
static void CancelTerminateExecution(Isolate *isolate)
Definition: api.cc:6548
void(* FunctionCallback)(const FunctionCallbackInfo< Value > &info)
Definition: v8.h:2603
V8_INLINE Isolate * GetIsolate() const
Definition: v8.h:6061
bool HasCaught() const
Definition: api.cc:1901
V8_INLINE ReturnValue< T > GetReturnValue() const
Definition: v8.h:6067
static Local< Integer > New(Isolate *isolate, int32_t value)
Definition: api.cc:6233
#define CHECK(condition)
Definition: checks.h:75
void Set(Handle< String > name, Handle< Data > value, PropertyAttribute attributes=None)
Definition: api.cc:841
bool HasTerminated() const
Definition: api.cc:1911
static void TerminateExecution(Isolate *isolate=NULL)
Definition: api.cc:6531
static Local< ObjectTemplate > New()
Definition: api.cc:1286
void DoLoopNoCall(const v8::FunctionCallbackInfo< v8::Value > &args)
static Local< FunctionTemplate > New(Isolate *isolate, FunctionCallback callback=0, Handle< Value > data=Handle< Value >(), Handle< Signature > signature=Handle< Signature >(), int length=0)
Definition: api.cc:942
void TerminateCurrentThread(const v8::FunctionCallbackInfo< v8::Value > &args)
static Local< Script > Compile(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *script_data=NULL)
Definition: api.cc:1832
static i::Isolate * i_isolate()
Definition: cctest.h:102
v8::Handle< v8::ObjectTemplate > CreateGlobalTemplate(v8::Isolate *isolate, v8::FunctionCallback terminate, v8::FunctionCallback doloop)
static Local< Object > New(Isolate *isolate)
Definition: api.cc:5589
bool CanContinue() const
Definition: api.cc:1906
static Local< Context > New(Isolate *isolate, ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
Definition: api.cc:5188
void Loop(const v8::FunctionCallbackInfo< v8::Value > &args)
void DoLoopCancelTerminate(const v8::FunctionCallbackInfo< v8::Value > &args)
void LoopGetProperty(const v8::FunctionCallbackInfo< v8::Value > &args)
void TerminateOrReturnObject(const v8::FunctionCallbackInfo< v8::Value > &args)
void DoLoop(const v8::FunctionCallbackInfo< v8::Value > &args)
TEST(TerminateOnlyV8ThreadFromThreadItself)
Definition: v8.h:124
Local< v8::Message > Message() const
Definition: api.cc:1953
v8::internal::Semaphore * semaphore
void ReenterAfterTermination(const v8::FunctionCallbackInfo< v8::Value > &args)
bool Set(Handle< Value > key, Handle< Value > value, PropertyAttribute attribs=None)
Definition: api.cc:3044
static v8::Isolate * isolate()
Definition: cctest.h:96
static Local< String > NewFromUtf8(Isolate *isolate, const char *data, NewStringType type=kNormalString, int length=-1)
Definition: api.cc:5417