| OLD | NEW |
| 1 // Copyright 2007-2011 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2011 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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 CHECK_EQ(30, static_cast<int>(v->NumberValue())); | 89 CHECK_EQ(30, static_cast<int>(v->NumberValue())); |
| 90 } | 90 } |
| 91 isolate_->Dispose(); | 91 isolate_->Dispose(); |
| 92 } | 92 } |
| 93 | 93 |
| 94 private: | 94 private: |
| 95 v8::Isolate* isolate_; | 95 v8::Isolate* isolate_; |
| 96 Persistent<v8::Context> context_; | 96 Persistent<v8::Context> context_; |
| 97 }; | 97 }; |
| 98 | 98 |
| 99 |
| 99 // Migrates an isolate from one thread to another | 100 // Migrates an isolate from one thread to another |
| 100 TEST(KangarooIsolates) { | 101 TEST(KangarooIsolates) { |
| 101 v8::Isolate* isolate = v8::Isolate::New(); | 102 v8::Isolate* isolate = v8::Isolate::New(); |
| 102 i::SmartPointer<KangarooThread> thread1; | 103 i::SmartPointer<KangarooThread> thread1; |
| 103 { | 104 { |
| 104 v8::Locker locker(isolate); | 105 v8::Locker locker(isolate); |
| 105 v8::Isolate::Scope isolate_scope(isolate); | 106 v8::Isolate::Scope isolate_scope(isolate); |
| 106 v8::HandleScope handle_scope(isolate); | 107 v8::HandleScope handle_scope(isolate); |
| 107 v8::Local<v8::Context> context = v8::Context::New(isolate); | 108 v8::Local<v8::Context> context = v8::Context::New(isolate); |
| 108 v8::Context::Scope context_scope(context); | 109 v8::Context::Scope context_scope(context); |
| 109 CHECK_EQ(isolate, v8::internal::Isolate::Current()); | 110 CHECK_EQ(isolate, v8::internal::Isolate::Current()); |
| 110 CompileRun("function getValue() { return 30; }"); | 111 CompileRun("function getValue() { return 30; }"); |
| 111 thread1.Reset(new KangarooThread(isolate, context)); | 112 thread1.Reset(new KangarooThread(isolate, context)); |
| 112 } | 113 } |
| 113 thread1->Start(); | 114 thread1->Start(); |
| 114 thread1->Join(); | 115 thread1->Join(); |
| 115 } | 116 } |
| 116 | 117 |
| 118 |
| 117 static void CalcFibAndCheck() { | 119 static void CalcFibAndCheck() { |
| 118 Local<Value> v = CompileRun("function fib(n) {" | 120 Local<Value> v = CompileRun("function fib(n) {" |
| 119 " if (n <= 2) return 1;" | 121 " if (n <= 2) return 1;" |
| 120 " return fib(n-1) + fib(n-2);" | 122 " return fib(n-1) + fib(n-2);" |
| 121 "}" | 123 "}" |
| 122 "fib(10)"); | 124 "fib(10)"); |
| 123 CHECK(v->IsNumber()); | 125 CHECK(v->IsNumber()); |
| 124 CHECK_EQ(55, static_cast<int>(v->NumberValue())); | 126 CHECK_EQ(55, static_cast<int>(v->NumberValue())); |
| 125 } | 127 } |
| 126 | 128 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 v8::Isolate::Scope isolate_scope(isolate_); | 187 v8::Isolate::Scope isolate_scope(isolate_); |
| 186 v8::HandleScope handle_scope(isolate_); | 188 v8::HandleScope handle_scope(isolate_); |
| 187 LocalContext local_context; | 189 LocalContext local_context; |
| 188 CHECK_EQ(isolate_, v8::internal::Isolate::Current()); | 190 CHECK_EQ(isolate_, v8::internal::Isolate::Current()); |
| 189 CalcFibAndCheck(); | 191 CalcFibAndCheck(); |
| 190 } | 192 } |
| 191 private: | 193 private: |
| 192 v8::Isolate* isolate_; | 194 v8::Isolate* isolate_; |
| 193 }; | 195 }; |
| 194 | 196 |
| 197 |
| 195 static void StartJoinAndDeleteThreads(const i::List<JoinableThread*>& threads) { | 198 static void StartJoinAndDeleteThreads(const i::List<JoinableThread*>& threads) { |
| 196 for (int i = 0; i < threads.length(); i++) { | 199 for (int i = 0; i < threads.length(); i++) { |
| 197 threads[i]->Start(); | 200 threads[i]->Start(); |
| 198 } | 201 } |
| 199 for (int i = 0; i < threads.length(); i++) { | 202 for (int i = 0; i < threads.length(); i++) { |
| 200 threads[i]->Join(); | 203 threads[i]->Join(); |
| 201 } | 204 } |
| 202 for (int i = 0; i < threads.length(); i++) { | 205 for (int i = 0; i < threads.length(); i++) { |
| 203 delete threads[i]; | 206 delete threads[i]; |
| 204 } | 207 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 235 v8::Handle<v8::Context> context = v8::Context::New(isolate); | 238 v8::Handle<v8::Context> context = v8::Context::New(isolate); |
| 236 v8::Context::Scope context_scope(context); | 239 v8::Context::Scope context_scope(context); |
| 237 CHECK_EQ(isolate, v8::internal::Isolate::Current()); | 240 CHECK_EQ(isolate, v8::internal::Isolate::Current()); |
| 238 CalcFibAndCheck(); | 241 CalcFibAndCheck(); |
| 239 } | 242 } |
| 240 isolate->Dispose(); | 243 isolate->Dispose(); |
| 241 } | 244 } |
| 242 private: | 245 private: |
| 243 }; | 246 }; |
| 244 | 247 |
| 248 |
| 245 // Run many threads each accessing its own isolate without locking | 249 // Run many threads each accessing its own isolate without locking |
| 246 TEST(MultithreadedParallelIsolates) { | 250 TEST(MultithreadedParallelIsolates) { |
| 247 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS | 251 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS |
| 248 const int kNThreads = 10; | 252 const int kNThreads = 10; |
| 249 #else | 253 #else |
| 250 const int kNThreads = 50; | 254 const int kNThreads = 50; |
| 251 #endif | 255 #endif |
| 252 i::List<JoinableThread*> threads(kNThreads); | 256 i::List<JoinableThread*> threads(kNThreads); |
| 253 for (int i = 0; i < kNThreads; i++) { | 257 for (int i = 0; i < kNThreads; i++) { |
| 254 threads.Add(new IsolateNonlockingThread()); | 258 threads.Add(new IsolateNonlockingThread()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 273 } | 277 } |
| 274 { | 278 { |
| 275 v8::Locker another_lock(isolate_); | 279 v8::Locker another_lock(isolate_); |
| 276 CalcFibAndCheck(); | 280 CalcFibAndCheck(); |
| 277 } | 281 } |
| 278 } | 282 } |
| 279 private: | 283 private: |
| 280 v8::Isolate* isolate_; | 284 v8::Isolate* isolate_; |
| 281 }; | 285 }; |
| 282 | 286 |
| 287 |
| 283 // Run many threads with nested locks | 288 // Run many threads with nested locks |
| 284 TEST(IsolateNestedLocking) { | 289 TEST(IsolateNestedLocking) { |
| 285 #if V8_TARGET_ARCH_MIPS | 290 #if V8_TARGET_ARCH_MIPS |
| 286 const int kNThreads = 50; | 291 const int kNThreads = 50; |
| 287 #else | 292 #else |
| 288 const int kNThreads = 100; | 293 const int kNThreads = 100; |
| 289 #endif | 294 #endif |
| 290 v8::Isolate* isolate = v8::Isolate::New(); | 295 v8::Isolate* isolate = v8::Isolate::New(); |
| 291 i::List<JoinableThread*> threads(kNThreads); | 296 i::List<JoinableThread*> threads(kNThreads); |
| 292 for (int i = 0; i < kNThreads; i++) { | 297 for (int i = 0; i < kNThreads; i++) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 314 IsolateLockingThreadWithLocalContext threadB(isolate2_); | 319 IsolateLockingThreadWithLocalContext threadB(isolate2_); |
| 315 threadB.Start(); | 320 threadB.Start(); |
| 316 CalcFibAndCheck(); | 321 CalcFibAndCheck(); |
| 317 threadB.Join(); | 322 threadB.Join(); |
| 318 } | 323 } |
| 319 private: | 324 private: |
| 320 v8::Isolate* isolate1_; | 325 v8::Isolate* isolate1_; |
| 321 v8::Isolate* isolate2_; | 326 v8::Isolate* isolate2_; |
| 322 }; | 327 }; |
| 323 | 328 |
| 329 |
| 324 // Run parallel threads that lock and access different isolates in parallel | 330 // Run parallel threads that lock and access different isolates in parallel |
| 325 TEST(SeparateIsolatesLocksNonexclusive) { | 331 TEST(SeparateIsolatesLocksNonexclusive) { |
| 326 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS | 332 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS |
| 327 const int kNThreads = 50; | 333 const int kNThreads = 50; |
| 328 #else | 334 #else |
| 329 const int kNThreads = 100; | 335 const int kNThreads = 100; |
| 330 #endif | 336 #endif |
| 331 v8::Isolate* isolate1 = v8::Isolate::New(); | 337 v8::Isolate* isolate1 = v8::Isolate::New(); |
| 332 v8::Isolate* isolate2 = v8::Isolate::New(); | 338 v8::Isolate* isolate2 = v8::Isolate::New(); |
| 333 i::List<JoinableThread*> threads(kNThreads); | 339 i::List<JoinableThread*> threads(kNThreads); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 { | 396 { |
| 391 v8::Context::Scope context_scope(context); | 397 v8::Context::Scope context_scope(context); |
| 392 CalcFibAndCheck(); | 398 CalcFibAndCheck(); |
| 393 } | 399 } |
| 394 } | 400 } |
| 395 | 401 |
| 396 private: | 402 private: |
| 397 v8::Isolate* isolate_; | 403 v8::Isolate* isolate_; |
| 398 }; | 404 }; |
| 399 | 405 |
| 406 |
| 400 // Use unlocker inside of a Locker, multiple threads. | 407 // Use unlocker inside of a Locker, multiple threads. |
| 401 TEST(LockerUnlocker) { | 408 TEST(LockerUnlocker) { |
| 402 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS | 409 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS |
| 403 const int kNThreads = 50; | 410 const int kNThreads = 50; |
| 404 #else | 411 #else |
| 405 const int kNThreads = 100; | 412 const int kNThreads = 100; |
| 406 #endif | 413 #endif |
| 407 i::List<JoinableThread*> threads(kNThreads); | 414 i::List<JoinableThread*> threads(kNThreads); |
| 408 v8::Isolate* isolate = v8::Isolate::New(); | 415 v8::Isolate* isolate = v8::Isolate::New(); |
| 409 for (int i = 0; i < kNThreads; i++) { | 416 for (int i = 0; i < kNThreads; i++) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 { | 450 { |
| 444 v8::Context::Scope context_scope(context); | 451 v8::Context::Scope context_scope(context); |
| 445 CalcFibAndCheck(); | 452 CalcFibAndCheck(); |
| 446 } | 453 } |
| 447 } | 454 } |
| 448 | 455 |
| 449 private: | 456 private: |
| 450 v8::Isolate* isolate_; | 457 v8::Isolate* isolate_; |
| 451 }; | 458 }; |
| 452 | 459 |
| 460 |
| 453 // Use Unlocker inside two Lockers. | 461 // Use Unlocker inside two Lockers. |
| 454 TEST(LockTwiceAndUnlock) { | 462 TEST(LockTwiceAndUnlock) { |
| 455 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS | 463 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS |
| 456 const int kNThreads = 50; | 464 const int kNThreads = 50; |
| 457 #else | 465 #else |
| 458 const int kNThreads = 100; | 466 const int kNThreads = 100; |
| 459 #endif | 467 #endif |
| 460 i::List<JoinableThread*> threads(kNThreads); | 468 i::List<JoinableThread*> threads(kNThreads); |
| 461 v8::Isolate* isolate = v8::Isolate::New(); | 469 v8::Isolate* isolate = v8::Isolate::New(); |
| 462 for (int i = 0; i < kNThreads; i++) { | 470 for (int i = 0; i < kNThreads; i++) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 CalcFibAndCheck(); | 518 CalcFibAndCheck(); |
| 511 thread->Join(); | 519 thread->Join(); |
| 512 } | 520 } |
| 513 } | 521 } |
| 514 | 522 |
| 515 private: | 523 private: |
| 516 v8::Isolate* isolate1_; | 524 v8::Isolate* isolate1_; |
| 517 v8::Isolate* isolate2_; | 525 v8::Isolate* isolate2_; |
| 518 }; | 526 }; |
| 519 | 527 |
| 528 |
| 520 // Lock two isolates and unlock one of them. | 529 // Lock two isolates and unlock one of them. |
| 521 TEST(LockAndUnlockDifferentIsolates) { | 530 TEST(LockAndUnlockDifferentIsolates) { |
| 522 v8::Isolate* isolate1 = v8::Isolate::New(); | 531 v8::Isolate* isolate1 = v8::Isolate::New(); |
| 523 v8::Isolate* isolate2 = v8::Isolate::New(); | 532 v8::Isolate* isolate2 = v8::Isolate::New(); |
| 524 LockAndUnlockDifferentIsolatesThread thread(isolate1, isolate2); | 533 LockAndUnlockDifferentIsolatesThread thread(isolate1, isolate2); |
| 525 thread.Start(); | 534 thread.Start(); |
| 526 thread.Join(); | 535 thread.Join(); |
| 527 isolate2->Dispose(); | 536 isolate2->Dispose(); |
| 528 isolate1->Dispose(); | 537 isolate1->Dispose(); |
| 529 } | 538 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 CalcFibAndCheck(); | 573 CalcFibAndCheck(); |
| 565 } | 574 } |
| 566 } | 575 } |
| 567 } | 576 } |
| 568 | 577 |
| 569 private: | 578 private: |
| 570 v8::Isolate* isolate_; | 579 v8::Isolate* isolate_; |
| 571 v8::Persistent<v8::Context> context_; | 580 v8::Persistent<v8::Context> context_; |
| 572 }; | 581 }; |
| 573 | 582 |
| 583 |
| 574 // Locker inside an Unlocker inside a Locker. | 584 // Locker inside an Unlocker inside a Locker. |
| 575 TEST(LockUnlockLockMultithreaded) { | 585 TEST(LockUnlockLockMultithreaded) { |
| 576 #if V8_TARGET_ARCH_MIPS | 586 #if V8_TARGET_ARCH_MIPS |
| 577 const int kNThreads = 50; | 587 const int kNThreads = 50; |
| 578 #else | 588 #else |
| 579 const int kNThreads = 100; | 589 const int kNThreads = 100; |
| 580 #endif | 590 #endif |
| 581 v8::Isolate* isolate = v8::Isolate::New(); | 591 v8::Isolate* isolate = v8::Isolate::New(); |
| 582 i::List<JoinableThread*> threads(kNThreads); | 592 i::List<JoinableThread*> threads(kNThreads); |
| 583 { | 593 { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 v8::Context::Scope context_scope(context); | 629 v8::Context::Scope context_scope(context); |
| 620 CalcFibAndCheck(); | 630 CalcFibAndCheck(); |
| 621 } | 631 } |
| 622 } | 632 } |
| 623 } | 633 } |
| 624 | 634 |
| 625 private: | 635 private: |
| 626 v8::Persistent<v8::Context> context_; | 636 v8::Persistent<v8::Context> context_; |
| 627 }; | 637 }; |
| 628 | 638 |
| 639 |
| 629 // Locker inside an Unlocker inside a Locker for default isolate. | 640 // Locker inside an Unlocker inside a Locker for default isolate. |
| 630 TEST(LockUnlockLockDefaultIsolateMultithreaded) { | 641 TEST(LockUnlockLockDefaultIsolateMultithreaded) { |
| 631 #if V8_TARGET_ARCH_MIPS | 642 #if V8_TARGET_ARCH_MIPS |
| 632 const int kNThreads = 50; | 643 const int kNThreads = 50; |
| 633 #else | 644 #else |
| 634 const int kNThreads = 100; | 645 const int kNThreads = 100; |
| 635 #endif | 646 #endif |
| 636 Local<v8::Context> context; | 647 Local<v8::Context> context; |
| 637 i::List<JoinableThread*> threads(kNThreads); | 648 i::List<JoinableThread*> threads(kNThreads); |
| 638 { | 649 { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 v8::Context::New(isolate, &extensions); | 700 v8::Context::New(isolate, &extensions); |
| 690 CHECK(i::Isolate::Current()->has_installed_extensions()); | 701 CHECK(i::Isolate::Current()->has_installed_extensions()); |
| 691 } | 702 } |
| 692 isolate->Dispose(); | 703 isolate->Dispose(); |
| 693 } | 704 } |
| 694 private: | 705 private: |
| 695 int count_; | 706 int count_; |
| 696 const char** extension_names_; | 707 const char** extension_names_; |
| 697 }; | 708 }; |
| 698 | 709 |
| 710 |
| 699 // Test installing extensions in separate isolates concurrently. | 711 // Test installing extensions in separate isolates concurrently. |
| 700 // http://code.google.com/p/v8/issues/detail?id=1821 | 712 // http://code.google.com/p/v8/issues/detail?id=1821 |
| 701 TEST(ExtensionsRegistration) { | 713 TEST(ExtensionsRegistration) { |
| 702 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS | 714 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS |
| 703 const int kNThreads = 10; | 715 const int kNThreads = 10; |
| 704 #else | 716 #else |
| 705 const int kNThreads = 40; | 717 const int kNThreads = 40; |
| 706 #endif | 718 #endif |
| 707 v8::RegisterExtension(new v8::Extension("test0", | 719 v8::RegisterExtension(new v8::Extension("test0", |
| 708 kSimpleExtensionSource)); | 720 kSimpleExtensionSource)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 722 kSimpleExtensionSource)); | 734 kSimpleExtensionSource)); |
| 723 const char* extension_names[] = { "test0", "test1", | 735 const char* extension_names[] = { "test0", "test1", |
| 724 "test2", "test3", "test4", | 736 "test2", "test3", "test4", |
| 725 "test5", "test6", "test7" }; | 737 "test5", "test6", "test7" }; |
| 726 i::List<JoinableThread*> threads(kNThreads); | 738 i::List<JoinableThread*> threads(kNThreads); |
| 727 for (int i = 0; i < kNThreads; i++) { | 739 for (int i = 0; i < kNThreads; i++) { |
| 728 threads.Add(new IsolateGenesisThread(8, extension_names)); | 740 threads.Add(new IsolateGenesisThread(8, extension_names)); |
| 729 } | 741 } |
| 730 StartJoinAndDeleteThreads(threads); | 742 StartJoinAndDeleteThreads(threads); |
| 731 } | 743 } |
| OLD | NEW |