2017-02-21 17:23:38 +00:00
|
|
|
// Copyright 2016 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2021-09-17 14:40:54 +00:00
|
|
|
#include "src/objects/managed-inl.h"
|
2019-05-23 08:51:46 +00:00
|
|
|
#include "src/objects/objects-inl.h"
|
2022-06-01 02:48:05 +00:00
|
|
|
#include "test/unittests/test-utils.h"
|
|
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
2017-02-21 17:23:38 +00:00
|
|
|
|
2017-08-11 11:22:28 +00:00
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
2017-02-21 17:23:38 +00:00
|
|
|
|
2022-06-01 02:48:05 +00:00
|
|
|
using ManagedTest = TestWithIsolate;
|
|
|
|
|
2018-04-26 14:37:05 +00:00
|
|
|
class DeleteCounter {
|
2017-02-21 17:23:38 +00:00
|
|
|
public:
|
2018-04-26 14:37:05 +00:00
|
|
|
explicit DeleteCounter(int* deleted) : deleted_(deleted) { *deleted_ = 0; }
|
|
|
|
~DeleteCounter() { (*deleted_)++; }
|
|
|
|
static void Deleter(void* arg) {
|
|
|
|
delete reinterpret_cast<DeleteCounter*>(arg);
|
2017-02-21 17:23:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-04-26 14:37:05 +00:00
|
|
|
int* deleted_;
|
2017-02-21 17:23:38 +00:00
|
|
|
};
|
|
|
|
|
2022-06-01 02:48:05 +00:00
|
|
|
TEST_F(ManagedTest, GCCausesDestruction) {
|
2018-04-26 14:37:05 +00:00
|
|
|
int deleted1 = 0;
|
|
|
|
int deleted2 = 0;
|
|
|
|
DeleteCounter* d1 = new DeleteCounter(&deleted1);
|
|
|
|
DeleteCounter* d2 = new DeleteCounter(&deleted2);
|
2017-02-21 17:23:38 +00:00
|
|
|
{
|
2022-06-01 02:48:05 +00:00
|
|
|
HandleScope scope(isolate());
|
|
|
|
auto handle = Managed<DeleteCounter>::FromRawPtr(isolate(), 0, d1);
|
2017-02-21 17:23:38 +00:00
|
|
|
USE(handle);
|
|
|
|
}
|
|
|
|
|
2022-06-01 02:48:05 +00:00
|
|
|
CollectAllAvailableGarbage();
|
2017-02-21 17:23:38 +00:00
|
|
|
|
2018-04-26 14:37:05 +00:00
|
|
|
CHECK_EQ(1, deleted1);
|
|
|
|
CHECK_EQ(0, deleted2);
|
2017-02-21 17:23:38 +00:00
|
|
|
delete d2;
|
2018-04-26 14:37:05 +00:00
|
|
|
CHECK_EQ(1, deleted2);
|
2017-02-21 17:23:38 +00:00
|
|
|
}
|
|
|
|
|
2022-06-01 02:48:05 +00:00
|
|
|
TEST_F(ManagedTest, DisposeCausesDestruction1) {
|
2017-02-21 17:23:38 +00:00
|
|
|
v8::Isolate::CreateParams create_params;
|
2022-06-01 02:48:05 +00:00
|
|
|
create_params.array_buffer_allocator = isolate()->array_buffer_allocator();
|
2017-02-21 17:23:38 +00:00
|
|
|
|
|
|
|
v8::Isolate* isolate = v8::Isolate::New(create_params);
|
2018-04-26 14:37:05 +00:00
|
|
|
Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
2017-02-21 17:23:38 +00:00
|
|
|
isolate->Enter();
|
2018-04-26 14:37:05 +00:00
|
|
|
int deleted1 = 0;
|
|
|
|
DeleteCounter* d1 = new DeleteCounter(&deleted1);
|
|
|
|
{
|
|
|
|
HandleScope scope(i_isolate);
|
2018-05-30 09:48:05 +00:00
|
|
|
auto handle = Managed<DeleteCounter>::FromRawPtr(i_isolate, 0, d1);
|
2018-04-26 14:37:05 +00:00
|
|
|
USE(handle);
|
|
|
|
}
|
|
|
|
isolate->Exit();
|
|
|
|
isolate->Dispose();
|
|
|
|
CHECK_EQ(1, deleted1);
|
|
|
|
}
|
|
|
|
|
2022-06-01 02:48:05 +00:00
|
|
|
TEST_F(ManagedTest, DisposeCausesDestruction2) {
|
2018-04-26 14:37:05 +00:00
|
|
|
v8::Isolate::CreateParams create_params;
|
2022-06-01 02:48:05 +00:00
|
|
|
create_params.array_buffer_allocator = isolate()->array_buffer_allocator();
|
2018-04-26 14:37:05 +00:00
|
|
|
|
|
|
|
v8::Isolate* isolate = v8::Isolate::New(create_params);
|
2017-02-21 17:23:38 +00:00
|
|
|
Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
2018-04-26 14:37:05 +00:00
|
|
|
isolate->Enter();
|
|
|
|
int deleted1 = 0;
|
|
|
|
int deleted2 = 0;
|
|
|
|
DeleteCounter* d1 = new DeleteCounter(&deleted1);
|
|
|
|
DeleteCounter* d2 = new DeleteCounter(&deleted2);
|
2017-02-21 17:23:38 +00:00
|
|
|
{
|
|
|
|
HandleScope scope(i_isolate);
|
2018-05-30 09:48:05 +00:00
|
|
|
auto handle = Managed<DeleteCounter>::FromRawPtr(i_isolate, 0, d1);
|
2017-02-21 17:23:38 +00:00
|
|
|
USE(handle);
|
|
|
|
}
|
2018-04-26 14:37:05 +00:00
|
|
|
ManagedPtrDestructor* destructor =
|
2018-05-30 09:48:05 +00:00
|
|
|
new ManagedPtrDestructor(0, d2, DeleteCounter::Deleter);
|
2018-04-26 14:37:05 +00:00
|
|
|
i_isolate->RegisterManagedPtrDestructor(destructor);
|
2017-02-21 17:23:38 +00:00
|
|
|
|
|
|
|
isolate->Exit();
|
|
|
|
isolate->Dispose();
|
2018-04-26 14:37:05 +00:00
|
|
|
CHECK_EQ(1, deleted1);
|
|
|
|
CHECK_EQ(1, deleted2);
|
2017-02-21 17:23:38 +00:00
|
|
|
}
|
2017-08-11 11:22:28 +00:00
|
|
|
|
2022-06-01 02:48:05 +00:00
|
|
|
TEST_F(ManagedTest, DisposeWithAnotherSharedPtr) {
|
2018-04-26 14:37:05 +00:00
|
|
|
v8::Isolate::CreateParams create_params;
|
2022-06-01 02:48:05 +00:00
|
|
|
create_params.array_buffer_allocator = isolate()->array_buffer_allocator();
|
2018-04-06 11:31:44 +00:00
|
|
|
|
2018-04-26 14:37:05 +00:00
|
|
|
v8::Isolate* isolate = v8::Isolate::New(create_params);
|
|
|
|
Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
|
|
|
isolate->Enter();
|
|
|
|
int deleted1 = 0;
|
|
|
|
DeleteCounter* d1 = new DeleteCounter(&deleted1);
|
2018-04-06 11:31:44 +00:00
|
|
|
{
|
2018-04-26 14:37:05 +00:00
|
|
|
std::shared_ptr<DeleteCounter> shared1(d1);
|
|
|
|
{
|
|
|
|
HandleScope scope(i_isolate);
|
2018-05-30 09:48:05 +00:00
|
|
|
auto handle =
|
|
|
|
Managed<DeleteCounter>::FromSharedPtr(i_isolate, 0, shared1);
|
2018-04-26 14:37:05 +00:00
|
|
|
USE(handle);
|
|
|
|
}
|
|
|
|
isolate->Exit();
|
|
|
|
isolate->Dispose();
|
|
|
|
CHECK_EQ(0, deleted1);
|
2018-04-06 11:31:44 +00:00
|
|
|
}
|
2018-04-26 14:37:05 +00:00
|
|
|
// Should be deleted after the second shared pointer is destroyed.
|
|
|
|
CHECK_EQ(1, deleted1);
|
|
|
|
}
|
|
|
|
|
2022-06-01 02:48:05 +00:00
|
|
|
TEST_F(ManagedTest, DisposeAcrossIsolates) {
|
2018-04-26 14:37:05 +00:00
|
|
|
v8::Isolate::CreateParams create_params;
|
2022-06-01 02:48:05 +00:00
|
|
|
create_params.array_buffer_allocator = isolate()->array_buffer_allocator();
|
2018-04-26 14:37:05 +00:00
|
|
|
|
|
|
|
int deleted = 0;
|
|
|
|
DeleteCounter* delete_counter = new DeleteCounter(&deleted);
|
|
|
|
|
|
|
|
v8::Isolate* isolate1 = v8::Isolate::New(create_params);
|
|
|
|
Isolate* i_isolate1 = reinterpret_cast<i::Isolate*>(isolate1);
|
|
|
|
isolate1->Enter();
|
|
|
|
{
|
|
|
|
HandleScope scope1(i_isolate1);
|
|
|
|
auto handle1 =
|
2018-05-30 09:48:05 +00:00
|
|
|
Managed<DeleteCounter>::FromRawPtr(i_isolate1, 0, delete_counter);
|
2018-04-26 14:37:05 +00:00
|
|
|
|
|
|
|
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
|
|
|
|
Isolate* i_isolate2 = reinterpret_cast<i::Isolate*>(isolate2);
|
|
|
|
isolate2->Enter();
|
|
|
|
{
|
|
|
|
HandleScope scope(i_isolate2);
|
|
|
|
auto handle2 =
|
2018-05-30 09:48:05 +00:00
|
|
|
Managed<DeleteCounter>::FromSharedPtr(i_isolate2, 0, handle1->get());
|
2018-04-26 14:37:05 +00:00
|
|
|
USE(handle2);
|
|
|
|
}
|
|
|
|
isolate2->Exit();
|
|
|
|
isolate2->Dispose();
|
|
|
|
CHECK_EQ(0, deleted);
|
|
|
|
}
|
|
|
|
// Should be deleted after the first isolate is destroyed.
|
|
|
|
isolate1->Exit();
|
|
|
|
isolate1->Dispose();
|
|
|
|
CHECK_EQ(1, deleted);
|
|
|
|
}
|
|
|
|
|
2022-06-01 02:48:05 +00:00
|
|
|
TEST_F(ManagedTest, CollectAcrossIsolates) {
|
2018-04-26 14:37:05 +00:00
|
|
|
v8::Isolate::CreateParams create_params;
|
2022-06-01 02:48:05 +00:00
|
|
|
create_params.array_buffer_allocator = isolate()->array_buffer_allocator();
|
2018-04-26 14:37:05 +00:00
|
|
|
|
|
|
|
int deleted = 0;
|
|
|
|
DeleteCounter* delete_counter = new DeleteCounter(&deleted);
|
2018-04-06 11:31:44 +00:00
|
|
|
|
2018-04-26 14:37:05 +00:00
|
|
|
v8::Isolate* isolate1 = v8::Isolate::New(create_params);
|
|
|
|
Isolate* i_isolate1 = reinterpret_cast<i::Isolate*>(isolate1);
|
|
|
|
isolate1->Enter();
|
|
|
|
{
|
|
|
|
HandleScope scope1(i_isolate1);
|
|
|
|
auto handle1 =
|
2018-05-30 09:48:05 +00:00
|
|
|
Managed<DeleteCounter>::FromRawPtr(i_isolate1, 0, delete_counter);
|
2018-04-26 14:37:05 +00:00
|
|
|
|
|
|
|
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
|
|
|
|
Isolate* i_isolate2 = reinterpret_cast<i::Isolate*>(isolate2);
|
|
|
|
isolate2->Enter();
|
|
|
|
{
|
|
|
|
HandleScope scope(i_isolate2);
|
|
|
|
auto handle2 =
|
2018-05-30 09:48:05 +00:00
|
|
|
Managed<DeleteCounter>::FromSharedPtr(i_isolate2, 0, handle1->get());
|
2018-04-26 14:37:05 +00:00
|
|
|
USE(handle2);
|
|
|
|
}
|
2022-09-01 17:40:05 +00:00
|
|
|
CollectAllAvailableGarbage(i_isolate2);
|
2018-04-26 14:37:05 +00:00
|
|
|
CHECK_EQ(0, deleted);
|
|
|
|
isolate2->Exit();
|
|
|
|
isolate2->Dispose();
|
|
|
|
CHECK_EQ(0, deleted);
|
|
|
|
}
|
|
|
|
// Should be deleted after the first isolate is destroyed.
|
2022-09-01 17:40:05 +00:00
|
|
|
CollectAllAvailableGarbage(i_isolate1);
|
2018-04-26 14:37:05 +00:00
|
|
|
CHECK_EQ(1, deleted);
|
|
|
|
isolate1->Exit();
|
|
|
|
isolate1->Dispose();
|
|
|
|
CHECK_EQ(1, deleted);
|
2018-04-06 11:31:44 +00:00
|
|
|
}
|
|
|
|
|
2017-08-11 11:22:28 +00:00
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|