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

Unified Diff: test/cctest/test-api.cc

Issue 1026283004: fix disposal of phantom handles in GlobalValueMap (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/api.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index dcb11be19d1c84a377b2381a7d3929aff4bbe3a1..4b0aa3bfaf397b32aa561cd2f72f77476b5087b5 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -3193,6 +3193,124 @@ TEST(PersistentValueMap) {
}
+namespace {
+
+void* IntKeyToVoidPointer(int key) { return reinterpret_cast<void*>(key << 1); }
+
+
+Local<v8::Object> NewObjectForIntKey(
+ v8::Isolate* isolate, const v8::Global<v8::ObjectTemplate>& templ,
+ int key) {
+ auto local = Local<v8::ObjectTemplate>::New(isolate, templ);
+ auto obj = local->NewInstance();
+ obj->SetAlignedPointerInInternalField(0, IntKeyToVoidPointer(key));
+ return obj;
+}
+
+
+template <typename K, typename V>
+class PhantomStdMapTraits : public v8::StdMapTraits<K, V> {
+ public:
+ typedef typename v8::GlobalValueMap<K, V, PhantomStdMapTraits<K, V>> MapType;
+ static const v8::PersistentContainerCallbackType kCallbackType =
+ v8::kWeakWithInternalFields;
+ struct WeakCallbackDataType {
+ MapType* map;
+ K key;
+ };
+ static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key,
+ Local<V> value) {
+ WeakCallbackDataType* data = new WeakCallbackDataType;
+ data->map = map;
+ data->key = key;
+ return data;
+ }
+ static MapType* MapFromWeakCallbackInfo(
+ const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {
+ return data.GetParameter()->map;
+ }
+ static K KeyFromWeakCallbackInfo(
+ const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {
+ return data.GetParameter()->key;
+ }
+ static void DisposeCallbackData(WeakCallbackDataType* data) { delete data; }
+ static void Dispose(v8::Isolate* isolate, v8::Global<V> value, K key) {
+ CHECK_EQ(IntKeyToVoidPointer(key),
+ v8::Object::GetAlignedPointerFromInternalField(value, 0));
+ }
+ static void DisposeWeak(
+ v8::Isolate* isolate,
+ const v8::WeakCallbackInfo<WeakCallbackDataType>& info, K key) {
+ CHECK_EQ(IntKeyToVoidPointer(key), info.GetInternalField(0));
+ }
+};
+}
+
+
+TEST(GlobalValueMap) {
+ typedef v8::GlobalValueMap<int, v8::Object,
+ PhantomStdMapTraits<int, v8::Object>> Map;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::Global<ObjectTemplate> templ;
+ {
+ HandleScope scope(isolate);
+ auto t = ObjectTemplate::New(isolate);
+ t->SetInternalFieldCount(1);
+ templ.Reset(isolate, t);
+ }
+ Map map(isolate);
+ v8::internal::GlobalHandles* global_handles =
+ reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
+ int initial_handle_count = global_handles->global_handles_count();
+ CHECK_EQ(0, static_cast<int>(map.Size()));
+ {
+ HandleScope scope(isolate);
+ Local<v8::Object> obj = map.Get(7);
+ CHECK(obj.IsEmpty());
+ Local<v8::Object> expected = v8::Object::New(isolate);
+ map.Set(7, expected);
+ CHECK_EQ(1, static_cast<int>(map.Size()));
+ obj = map.Get(7);
+ CHECK(expected->Equals(obj));
+ {
+ Map::PersistentValueReference ref = map.GetReference(7);
+ CHECK(expected->Equals(ref.NewLocal(isolate)));
+ }
+ v8::Global<v8::Object> removed = map.Remove(7);
+ CHECK_EQ(0, static_cast<int>(map.Size()));
+ CHECK(expected == removed);
+ removed = map.Remove(7);
+ CHECK(removed.IsEmpty());
+ map.Set(8, expected);
+ CHECK_EQ(1, static_cast<int>(map.Size()));
+ map.Set(8, expected);
+ CHECK_EQ(1, static_cast<int>(map.Size()));
+ {
+ Map::PersistentValueReference ref;
+ Local<v8::Object> expected2 = NewObjectForIntKey(isolate, templ, 8);
+ removed = map.Set(8, v8::Global<v8::Object>(isolate, expected2), &ref);
+ CHECK_EQ(1, static_cast<int>(map.Size()));
+ CHECK(expected == removed);
+ CHECK(expected2->Equals(ref.NewLocal(isolate)));
+ }
+ }
+ CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count());
+ CcTest::i_isolate()->heap()->CollectAllGarbage(
+ i::Heap::kAbortIncrementalMarkingMask);
+ CHECK_EQ(0, static_cast<int>(map.Size()));
+ CHECK_EQ(initial_handle_count, global_handles->global_handles_count());
+ {
+ HandleScope scope(isolate);
+ Local<v8::Object> value = NewObjectForIntKey(isolate, templ, 9);
+ map.Set(9, value);
+ map.Clear();
+ }
+ CHECK_EQ(0, static_cast<int>(map.Size()));
+ CHECK_EQ(initial_handle_count, global_handles->global_handles_count());
+}
+
+
TEST(PersistentValueVector) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
« no previous file with comments | « src/api.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698