OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 3300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3311 explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) { } | 3311 explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) { } |
3312 int id() { return id_; } | 3312 int id() { return id_; } |
3313 void increment() { number_of_weak_calls_++; } | 3313 void increment() { number_of_weak_calls_++; } |
3314 int NumberOfWeakCalls() { return number_of_weak_calls_; } | 3314 int NumberOfWeakCalls() { return number_of_weak_calls_; } |
3315 private: | 3315 private: |
3316 int id_; | 3316 int id_; |
3317 int number_of_weak_calls_; | 3317 int number_of_weak_calls_; |
3318 }; | 3318 }; |
3319 | 3319 |
3320 | 3320 |
| 3321 template<typename T> |
3321 static void WeakPointerCallback(v8::Isolate* isolate, | 3322 static void WeakPointerCallback(v8::Isolate* isolate, |
3322 Persistent<Value>* handle, | 3323 Persistent<T>* handle, |
3323 WeakCallCounter* counter) { | 3324 WeakCallCounter* counter) { |
3324 CHECK_EQ(1234, counter->id()); | 3325 CHECK_EQ(1234, counter->id()); |
3325 counter->increment(); | 3326 counter->increment(); |
3326 handle->Dispose(); | 3327 handle->Dispose(); |
3327 } | 3328 } |
3328 | 3329 |
3329 | 3330 |
3330 static UniqueId MakeUniqueId(const Persistent<Value>& p) { | 3331 template<typename T> |
| 3332 static UniqueId MakeUniqueId(const Persistent<T>& p) { |
3331 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p))); | 3333 return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p))); |
3332 } | 3334 } |
3333 | 3335 |
3334 | 3336 |
3335 THREADED_TEST(ApiObjectGroups) { | 3337 THREADED_TEST(ApiObjectGroups) { |
3336 LocalContext env; | 3338 LocalContext env; |
3337 v8::Isolate* iso = env->GetIsolate(); | 3339 v8::Isolate* iso = env->GetIsolate(); |
3338 HandleScope scope(iso); | 3340 HandleScope scope(iso); |
3339 | 3341 |
3340 Persistent<Value> g1s1; | 3342 Persistent<Value> g1s1; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3418 | 3420 |
3419 // And now make children weak again and collect them. | 3421 // And now make children weak again and collect them. |
3420 g1c1.MakeWeak(&counter, &WeakPointerCallback); | 3422 g1c1.MakeWeak(&counter, &WeakPointerCallback); |
3421 g2c1.MakeWeak(&counter, &WeakPointerCallback); | 3423 g2c1.MakeWeak(&counter, &WeakPointerCallback); |
3422 | 3424 |
3423 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 3425 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
3424 CHECK_EQ(7, counter.NumberOfWeakCalls()); | 3426 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
3425 } | 3427 } |
3426 | 3428 |
3427 | 3429 |
| 3430 THREADED_TEST(ApiObjectGroupsForSubtypes) { |
| 3431 LocalContext env; |
| 3432 v8::Isolate* iso = env->GetIsolate(); |
| 3433 HandleScope scope(iso); |
| 3434 |
| 3435 Persistent<Object> g1s1; |
| 3436 Persistent<String> g1s2; |
| 3437 Persistent<String> g1c1; |
| 3438 Persistent<Object> g2s1; |
| 3439 Persistent<String> g2s2; |
| 3440 Persistent<String> g2c1; |
| 3441 |
| 3442 WeakCallCounter counter(1234); |
| 3443 |
| 3444 { |
| 3445 HandleScope scope(iso); |
| 3446 g1s1.Reset(iso, Object::New()); |
| 3447 g1s2.Reset(iso, String::New("foo1")); |
| 3448 g1c1.Reset(iso, String::New("foo2")); |
| 3449 g1s1.MakeWeak(&counter, &WeakPointerCallback); |
| 3450 g1s2.MakeWeak(&counter, &WeakPointerCallback); |
| 3451 g1c1.MakeWeak(&counter, &WeakPointerCallback); |
| 3452 |
| 3453 g2s1.Reset(iso, Object::New()); |
| 3454 g2s2.Reset(iso, String::New("foo3")); |
| 3455 g2c1.Reset(iso, String::New("foo4")); |
| 3456 g2s1.MakeWeak(&counter, &WeakPointerCallback); |
| 3457 g2s2.MakeWeak(&counter, &WeakPointerCallback); |
| 3458 g2c1.MakeWeak(&counter, &WeakPointerCallback); |
| 3459 } |
| 3460 |
| 3461 Persistent<Value> root(iso, g1s1); // make a root. |
| 3462 |
| 3463 // Connect group 1 and 2, make a cycle. |
| 3464 { |
| 3465 HandleScope scope(iso); |
| 3466 CHECK(Local<Object>::New(iso, g1s1)->Set(0, Local<Object>::New(iso, g2s1))); |
| 3467 CHECK(Local<Object>::New(iso, g2s1)->Set(0, Local<Object>::New(iso, g1s1))); |
| 3468 } |
| 3469 |
| 3470 { |
| 3471 UniqueId id1 = MakeUniqueId(g1s1); |
| 3472 UniqueId id2 = MakeUniqueId(g2s2); |
| 3473 iso->SetObjectGroupId(g1s1, id1); |
| 3474 iso->SetObjectGroupId(g1s2, id1); |
| 3475 iso->SetReference(g1s1, g1c1); |
| 3476 iso->SetObjectGroupId(g2s1, id2); |
| 3477 iso->SetObjectGroupId(g2s2, id2); |
| 3478 iso->SetReferenceFromGroup(id2, g2c1); |
| 3479 } |
| 3480 // Do a single full GC, ensure incremental marking is stopped. |
| 3481 v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( |
| 3482 iso)->heap(); |
| 3483 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
| 3484 |
| 3485 // All object should be alive. |
| 3486 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
| 3487 |
| 3488 // Weaken the root. |
| 3489 root.MakeWeak(&counter, &WeakPointerCallback); |
| 3490 // But make children strong roots---all the objects (except for children) |
| 3491 // should be collectable now. |
| 3492 g1c1.ClearWeak(); |
| 3493 g2c1.ClearWeak(); |
| 3494 |
| 3495 // Groups are deleted, rebuild groups. |
| 3496 { |
| 3497 UniqueId id1 = MakeUniqueId(g1s1); |
| 3498 UniqueId id2 = MakeUniqueId(g2s2); |
| 3499 iso->SetObjectGroupId(g1s1, id1); |
| 3500 iso->SetObjectGroupId(g1s2, id1); |
| 3501 iso->SetReference(g1s1, g1c1); |
| 3502 iso->SetObjectGroupId(g2s1, id2); |
| 3503 iso->SetObjectGroupId(g2s2, id2); |
| 3504 iso->SetReferenceFromGroup(id2, g2c1); |
| 3505 } |
| 3506 |
| 3507 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
| 3508 |
| 3509 // All objects should be gone. 5 global handles in total. |
| 3510 CHECK_EQ(5, counter.NumberOfWeakCalls()); |
| 3511 |
| 3512 // And now make children weak again and collect them. |
| 3513 g1c1.MakeWeak(&counter, &WeakPointerCallback); |
| 3514 g2c1.MakeWeak(&counter, &WeakPointerCallback); |
| 3515 |
| 3516 heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
| 3517 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
| 3518 } |
| 3519 |
| 3520 |
3428 THREADED_TEST(ApiObjectGroupsCycle) { | 3521 THREADED_TEST(ApiObjectGroupsCycle) { |
3429 LocalContext env; | 3522 LocalContext env; |
3430 v8::Isolate* iso = env->GetIsolate(); | 3523 v8::Isolate* iso = env->GetIsolate(); |
3431 HandleScope scope(iso); | 3524 HandleScope scope(iso); |
3432 | 3525 |
3433 WeakCallCounter counter(1234); | 3526 WeakCallCounter counter(1234); |
3434 | 3527 |
3435 Persistent<Value> g1s1; | 3528 Persistent<Value> g1s1; |
3436 Persistent<Value> g1s2; | 3529 Persistent<Value> g1s2; |
3437 Persistent<Value> g2s1; | 3530 Persistent<Value> g2s1; |
(...skipping 17099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20537 } | 20630 } |
20538 for (int i = 0; i < runs; i++) { | 20631 for (int i = 0; i < runs; i++) { |
20539 Local<String> expected; | 20632 Local<String> expected; |
20540 if (i != 0) { | 20633 if (i != 0) { |
20541 CHECK_EQ(v8_str("escape value"), values[i]); | 20634 CHECK_EQ(v8_str("escape value"), values[i]); |
20542 } else { | 20635 } else { |
20543 CHECK(values[i].IsEmpty()); | 20636 CHECK(values[i].IsEmpty()); |
20544 } | 20637 } |
20545 } | 20638 } |
20546 } | 20639 } |
OLD | NEW |