Commit 4c3f7108 authored by jameslahm's avatar jameslahm Committed by V8 LUCI CQ

[test] Move cctest/test-identity-map to unittests/

... utils/identity-map-unittest.

Bug: v8:12781
Change-Id: I875de2b1e589ec72d724a6d0745a5d615344b510
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3724792Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: 王澳 <wangao.james@bytedance.com>
Cr-Commit-Position: refs/heads/main@{#81531}
parent f3f47a9f
...@@ -188,7 +188,6 @@ v8_source_set("cctest_sources") { ...@@ -188,7 +188,6 @@ v8_source_set("cctest_sources") {
"test-global-handles.cc", "test-global-handles.cc",
"test-heap-profiler.cc", "test-heap-profiler.cc",
"test-icache.cc", "test-icache.cc",
"test-identity-map.cc",
"test-ignition-statistics-extension.cc", "test-ignition-statistics-extension.cc",
"test-inobject-slack-tracking.cc", "test-inobject-slack-tracking.cc",
"test-inspector.cc", "test-inspector.cc",
......
...@@ -472,6 +472,7 @@ v8_source_set("unittests_sources") { ...@@ -472,6 +472,7 @@ v8_source_set("unittests_sources") {
"utils/allocation-unittest.cc", "utils/allocation-unittest.cc",
"utils/bit-vector-unittest.cc", "utils/bit-vector-unittest.cc",
"utils/detachable-vector-unittest.cc", "utils/detachable-vector-unittest.cc",
"utils/identity-map-unittest.cc",
"utils/locked-queue-unittest.cc", "utils/locked-queue-unittest.cc",
"utils/sparse-bit-vector-unittest.cc", "utils/sparse-bit-vector-unittest.cc",
"utils/utils-unittest.cc", "utils/utils-unittest.cc",
......
...@@ -2,29 +2,29 @@ ...@@ -2,29 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/utils/identity-map.h"
#include <set> #include <set>
#include "src/execution/isolate.h" #include "src/execution/isolate.h"
#include "src/heap/factory-inl.h" #include "src/heap/factory-inl.h"
#include "src/objects/heap-number-inl.h" #include "src/objects/heap-number-inl.h"
#include "src/utils/identity-map.h"
#include "src/objects/objects.h" #include "src/objects/objects.h"
#include "src/zone/zone.h" #include "src/zone/zone.h"
#include "test/cctest/cctest.h" #include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
// Helper for testing. A "friend" of the IdentityMapBase class, it is able to // Helper for testing. A "friend" of the IdentityMapBase class, it is able to
// "move" objects to simulate GC for testing the internals of the map. // "move" objects to simulate GC for testing the internals of the map.
class IdentityMapTester : public HandleAndZoneScope { class IdentityMapTester {
public: public:
IdentityMap<void*, ZoneAllocationPolicy> map; IdentityMap<void*, ZoneAllocationPolicy> map;
IdentityMapTester() : map(heap(), ZoneAllocationPolicy(main_zone())) {} IdentityMapTester(Heap* heap, Zone* zone)
: map(heap, ZoneAllocationPolicy(zone)) {}
Heap* heap() { return isolate()->heap(); }
Isolate* isolate() { return main_isolate(); }
void TestInsertFind(Handle<Object> key1, void* val1, Handle<Object> key2, void TestInsertFind(Handle<Object> key1, void* val1, Handle<Object> key2,
void* val2) { void* val2) {
...@@ -138,14 +138,6 @@ class IdentityMapTester : public HandleAndZoneScope { ...@@ -138,14 +138,6 @@ class IdentityMapTester : public HandleAndZoneScope {
} }
} }
Handle<Smi> smi(int value) {
return Handle<Smi>(Smi::FromInt(value), isolate());
}
Handle<Object> num(double value) {
return isolate()->factory()->NewNumber(value);
}
void SimulateGCByIncrementingSmisBy(int shift) { void SimulateGCByIncrementingSmisBy(int shift) {
for (int i = 0; i < map.capacity_; i++) { for (int i = 0; i < map.capacity_; i++) {
Address key = map.keys_[i]; Address key = map.keys_[i];
...@@ -190,85 +182,159 @@ class IdentityMapTester : public HandleAndZoneScope { ...@@ -190,85 +182,159 @@ class IdentityMapTester : public HandleAndZoneScope {
void Rehash() { map.Rehash(); } void Rehash() { map.Rehash(); }
}; };
TEST(Find_smi_not_found) { class IdentityMapTest : public TestWithIsolateAndZone {
IdentityMapTester t; public:
Handle<Smi> smi(int value) {
return Handle<Smi>(Smi::FromInt(value), isolate());
}
Handle<Object> num(double value) {
return isolate()->factory()->NewNumber(value);
}
void IterateCollisionTest(int stride) {
for (int load = 15; load <= 120; load = load * 2) {
IdentityMapTester t(isolate()->heap(), zone());
{ // Add entries to the map.
HandleScope scope(isolate());
int next = 1;
for (int i = 0; i < load; i++) {
t.map.Insert(smi(next), reinterpret_cast<void*>(next));
t.CheckFind(smi(next), reinterpret_cast<void*>(next));
next = next + stride;
}
}
// Iterate through the map and check we see all elements only once.
std::set<intptr_t> seen;
{
IdentityMap<void*, ZoneAllocationPolicy>::IteratableScope it_scope(
&t.map);
for (auto it = it_scope.begin(); it != it_scope.end(); ++it) {
CHECK(seen.find(reinterpret_cast<intptr_t>(**it)) == seen.end());
seen.insert(reinterpret_cast<intptr_t>(**it));
}
}
// Check get and find on map.
{
HandleScope scope(isolate());
int next = 1;
for (int i = 0; i < load; i++) {
CHECK(seen.find(next) != seen.end());
t.CheckFind(smi(next), reinterpret_cast<void*>(next));
t.CheckFindOrInsert(smi(next), reinterpret_cast<void*>(next));
next = next + stride;
}
}
}
}
void CollisionTest(int stride, bool rehash = false, bool resize = false) {
for (int load = 15; load <= 120; load = load * 2) {
IdentityMapTester t(isolate()->heap(), zone());
{ // Add entries to the map.
HandleScope scope(isolate());
int next = 1;
for (int i = 0; i < load; i++) {
t.map.Insert(smi(next), reinterpret_cast<void*>(next));
t.CheckFind(smi(next), reinterpret_cast<void*>(next));
next = next + stride;
}
}
if (resize) t.Resize(); // Explicit resize (internal method).
if (rehash) t.Rehash(); // Explicit rehash (internal method).
{ // Check find and get.
HandleScope scope(isolate());
int next = 1;
for (int i = 0; i < load; i++) {
t.CheckFind(smi(next), reinterpret_cast<void*>(next));
t.CheckFindOrInsert(smi(next), reinterpret_cast<void*>(next));
next = next + stride;
}
}
}
}
};
TEST_F(IdentityMapTest, Find_smi_not_found) {
IdentityMapTester t(isolate()->heap(), zone());
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
CHECK_NULL(t.map.Find(t.smi(i))); CHECK_NULL(t.map.Find(smi(i)));
} }
} }
TEST_F(IdentityMapTest, Find_num_not_found) {
TEST(Find_num_not_found) { IdentityMapTester t(isolate()->heap(), zone());
IdentityMapTester t;
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
CHECK_NULL(t.map.Find(t.num(i + 0.2))); CHECK_NULL(t.map.Find(num(i + 0.2)));
} }
} }
TEST(Delete_smi_not_found) { TEST_F(IdentityMapTest, Delete_smi_not_found) {
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
void* deleted_value = &t; void* deleted_value = &t;
CHECK(!t.map.Delete(t.smi(i), &deleted_value)); CHECK(!t.map.Delete(smi(i), &deleted_value));
CHECK_EQ(&t, deleted_value); CHECK_EQ(&t, deleted_value);
} }
} }
TEST(Delete_num_not_found) { TEST_F(IdentityMapTest, Delete_num_not_found) {
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
void* deleted_value = &t; void* deleted_value = &t;
CHECK(!t.map.Delete(t.num(i + 0.2), &deleted_value)); CHECK(!t.map.Delete(num(i + 0.2), &deleted_value));
CHECK_EQ(&t, deleted_value); CHECK_EQ(&t, deleted_value);
} }
} }
TEST(GetFind_smi_0) { TEST_F(IdentityMapTest, GetFind_smi_0) {
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
t.TestInsertFind(t.smi(0), t.isolate(), t.smi(1), t.heap()); t.TestInsertFind(smi(0), isolate(), smi(1), isolate()->heap());
} }
TEST(GetFind_smi_13) { TEST_F(IdentityMapTest, GetFind_smi_13) {
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
t.TestInsertFind(t.smi(13), t.isolate(), t.smi(17), t.heap()); t.TestInsertFind(smi(13), isolate(), smi(17), isolate()->heap());
} }
TEST(GetFind_num_13) { TEST_F(IdentityMapTest, GetFind_num_13) {
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
t.TestInsertFind(t.num(13.1), t.isolate(), t.num(17.1), t.heap()); t.TestInsertFind(num(13.1), isolate(), num(17.1), isolate()->heap());
} }
TEST(Delete_smi_13) { TEST_F(IdentityMapTest, Delete_smi_13) {
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
t.TestFindDelete(t.smi(13), t.isolate(), t.smi(17), t.heap()); t.TestFindDelete(smi(13), isolate(), smi(17), isolate()->heap());
CHECK(t.map.empty()); CHECK(t.map.empty());
} }
TEST(Delete_num_13) { TEST_F(IdentityMapTest, Delete_num_13) {
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
t.TestFindDelete(t.num(13.1), t.isolate(), t.num(17.1), t.heap()); t.TestFindDelete(num(13.1), isolate(), num(17.1), isolate()->heap());
CHECK(t.map.empty()); CHECK(t.map.empty());
} }
TEST(GetFind_smi_17m) { TEST_F(IdentityMapTest, GetFind_smi_17m) {
const int kInterval = 17; const int kInterval = 17;
const int kShift = 1099; const int kShift = 1099;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
for (int i = 1; i < 100; i += kInterval) { for (int i = 1; i < 100; i += kInterval) {
t.map.Insert(t.smi(i), reinterpret_cast<void*>(i + kShift)); t.map.Insert(smi(i), reinterpret_cast<void*>(i + kShift));
} }
for (int i = 1; i < 100; i += kInterval) { for (int i = 1; i < 100; i += kInterval) {
t.CheckFind(t.smi(i), reinterpret_cast<void*>(i + kShift)); t.CheckFind(smi(i), reinterpret_cast<void*>(i + kShift));
} }
for (int i = 1; i < 100; i += kInterval) { for (int i = 1; i < 100; i += kInterval) {
t.CheckFindOrInsert(t.smi(i), reinterpret_cast<void*>(i + kShift)); t.CheckFindOrInsert(smi(i), reinterpret_cast<void*>(i + kShift));
} }
for (int i = 1; i < 100; i++) { for (int i = 1; i < 100; i++) {
void** entry = t.map.Find(t.smi(i)); void** entry = t.map.Find(smi(i));
if ((i % kInterval) != 1) { if ((i % kInterval) != 1) {
CHECK_NULL(entry); CHECK_NULL(entry);
} else { } else {
...@@ -278,23 +344,23 @@ TEST(GetFind_smi_17m) { ...@@ -278,23 +344,23 @@ TEST(GetFind_smi_17m) {
} }
} }
TEST(Delete_smi_17m) { TEST_F(IdentityMapTest, Delete_smi_17m) {
const int kInterval = 17; const int kInterval = 17;
const int kShift = 1099; const int kShift = 1099;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
for (int i = 1; i < 100; i += kInterval) { for (int i = 1; i < 100; i += kInterval) {
t.map.Insert(t.smi(i), reinterpret_cast<void*>(i + kShift)); t.map.Insert(smi(i), reinterpret_cast<void*>(i + kShift));
} }
for (int i = 1; i < 100; i += kInterval) { for (int i = 1; i < 100; i += kInterval) {
t.CheckFind(t.smi(i), reinterpret_cast<void*>(i + kShift)); t.CheckFind(smi(i), reinterpret_cast<void*>(i + kShift));
} }
for (int i = 1; i < 100; i += kInterval) { for (int i = 1; i < 100; i += kInterval) {
t.CheckDelete(t.smi(i), reinterpret_cast<void*>(i + kShift)); t.CheckDelete(smi(i), reinterpret_cast<void*>(i + kShift));
for (int j = 1; j < 100; j += kInterval) { for (int j = 1; j < 100; j += kInterval) {
auto entry = t.map.Find(t.smi(j)); auto entry = t.map.Find(smi(j));
if (j <= i) { if (j <= i) {
CHECK_NULL(entry); CHECK_NULL(entry);
} else { } else {
...@@ -305,34 +371,34 @@ TEST(Delete_smi_17m) { ...@@ -305,34 +371,34 @@ TEST(Delete_smi_17m) {
} }
} }
TEST(GetFind_num_1000) { TEST_F(IdentityMapTest, GetFind_num_1000) {
const int kPrime = 137; const int kPrime = 137;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
int val1; int val1;
int val2; int val2;
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
t.TestInsertFind(t.smi(i * kPrime), &val1, t.smi(i * kPrime + 1), &val2); t.TestInsertFind(smi(i * kPrime), &val1, smi(i * kPrime + 1), &val2);
} }
} }
TEST(Delete_num_1000) { TEST_F(IdentityMapTest, Delete_num_1000) {
const int kPrime = 137; const int kPrime = 137;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
t.map.Insert(t.smi(i * kPrime), reinterpret_cast<void*>(i * kPrime)); t.map.Insert(smi(i * kPrime), reinterpret_cast<void*>(i * kPrime));
} }
// Delete every second value in reverse. // Delete every second value in reverse.
for (int i = 999; i >= 0; i -= 2) { for (int i = 999; i >= 0; i -= 2) {
void* entry; void* entry;
CHECK(t.map.Delete(t.smi(i * kPrime), &entry)); CHECK(t.map.Delete(smi(i * kPrime), &entry));
CHECK_EQ(reinterpret_cast<void*>(i * kPrime), entry); CHECK_EQ(reinterpret_cast<void*>(i * kPrime), entry);
} }
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
auto entry = t.map.Find(t.smi(i * kPrime)); auto entry = t.map.Find(smi(i * kPrime));
if (i % 2) { if (i % 2) {
CHECK_NULL(entry); CHECK_NULL(entry);
} else { } else {
...@@ -344,125 +410,124 @@ TEST(Delete_num_1000) { ...@@ -344,125 +410,124 @@ TEST(Delete_num_1000) {
// Delete the rest. // Delete the rest.
for (int i = 0; i < 1000; i += 2) { for (int i = 0; i < 1000; i += 2) {
void* entry; void* entry;
CHECK(t.map.Delete(t.smi(i * kPrime), &entry)); CHECK(t.map.Delete(smi(i * kPrime), &entry));
CHECK_EQ(reinterpret_cast<void*>(i * kPrime), entry); CHECK_EQ(reinterpret_cast<void*>(i * kPrime), entry);
} }
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
auto entry = t.map.Find(t.smi(i * kPrime)); auto entry = t.map.Find(smi(i * kPrime));
CHECK_NULL(entry); CHECK_NULL(entry);
} }
} }
TEST(GetFind_smi_gc) { TEST_F(IdentityMapTest, GetFind_smi_gc) {
const int kKey = 33; const int kKey = 33;
const int kShift = 1211; const int kShift = 1211;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
t.map.Insert(t.smi(kKey), &t); t.map.Insert(smi(kKey), &t);
t.SimulateGCByIncrementingSmisBy(kShift); t.SimulateGCByIncrementingSmisBy(kShift);
t.CheckFind(t.smi(kKey + kShift), &t); t.CheckFind(smi(kKey + kShift), &t);
t.CheckFindOrInsert(t.smi(kKey + kShift), &t); t.CheckFindOrInsert(smi(kKey + kShift), &t);
} }
TEST(Delete_smi_gc) { TEST_F(IdentityMapTest, Delete_smi_gc) {
const int kKey = 33; const int kKey = 33;
const int kShift = 1211; const int kShift = 1211;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
t.map.Insert(t.smi(kKey), &t); t.map.Insert(smi(kKey), &t);
t.SimulateGCByIncrementingSmisBy(kShift); t.SimulateGCByIncrementingSmisBy(kShift);
t.CheckDelete(t.smi(kKey + kShift), &t); t.CheckDelete(smi(kKey + kShift), &t);
} }
TEST(GetFind_smi_gc2) { TEST_F(IdentityMapTest, GetFind_smi_gc2) {
int kKey1 = 1; int kKey1 = 1;
int kKey2 = 33; int kKey2 = 33;
const int kShift = 1211; const int kShift = 1211;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
t.map.Insert(t.smi(kKey1), &kKey1); t.map.Insert(smi(kKey1), &kKey1);
t.map.Insert(t.smi(kKey2), &kKey2); t.map.Insert(smi(kKey2), &kKey2);
t.SimulateGCByIncrementingSmisBy(kShift); t.SimulateGCByIncrementingSmisBy(kShift);
t.CheckFind(t.smi(kKey1 + kShift), &kKey1); t.CheckFind(smi(kKey1 + kShift), &kKey1);
t.CheckFindOrInsert(t.smi(kKey1 + kShift), &kKey1); t.CheckFindOrInsert(smi(kKey1 + kShift), &kKey1);
t.CheckFind(t.smi(kKey2 + kShift), &kKey2); t.CheckFind(smi(kKey2 + kShift), &kKey2);
t.CheckFindOrInsert(t.smi(kKey2 + kShift), &kKey2); t.CheckFindOrInsert(smi(kKey2 + kShift), &kKey2);
} }
TEST(Delete_smi_gc2) { TEST_F(IdentityMapTest, Delete_smi_gc2) {
int kKey1 = 1; int kKey1 = 1;
int kKey2 = 33; int kKey2 = 33;
const int kShift = 1211; const int kShift = 1211;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
t.map.Insert(t.smi(kKey1), &kKey1); t.map.Insert(smi(kKey1), &kKey1);
t.map.Insert(t.smi(kKey2), &kKey2); t.map.Insert(smi(kKey2), &kKey2);
t.SimulateGCByIncrementingSmisBy(kShift); t.SimulateGCByIncrementingSmisBy(kShift);
t.CheckDelete(t.smi(kKey1 + kShift), &kKey1); t.CheckDelete(smi(kKey1 + kShift), &kKey1);
t.CheckDelete(t.smi(kKey2 + kShift), &kKey2); t.CheckDelete(smi(kKey2 + kShift), &kKey2);
} }
TEST(GetFind_smi_gc_n) { TEST_F(IdentityMapTest, GetFind_smi_gc_n) {
const int kShift = 12011; const int kShift = 12011;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
int keys[12] = {1, 2, 7, 8, 15, 23, int keys[12] = {1, 2, 7, 8, 15, 23,
1 + 32, 2 + 32, 7 + 32, 8 + 32, 15 + 32, 23 + 32}; 1 + 32, 2 + 32, 7 + 32, 8 + 32, 15 + 32, 23 + 32};
// Initialize the map first. // Initialize the map first.
for (size_t i = 0; i < arraysize(keys); i += 2) { for (size_t i = 0; i < arraysize(keys); i += 2) {
t.TestInsertFind(t.smi(keys[i]), &keys[i], t.smi(keys[i + 1]), t.TestInsertFind(smi(keys[i]), &keys[i], smi(keys[i + 1]), &keys[i + 1]);
&keys[i + 1]);
} }
// Check the above initialization. // Check the above initialization.
for (size_t i = 0; i < arraysize(keys); i++) { for (size_t i = 0; i < arraysize(keys); i++) {
t.CheckFind(t.smi(keys[i]), &keys[i]); t.CheckFind(smi(keys[i]), &keys[i]);
} }
// Simulate a GC by "moving" the smis in the internal keys array. // Simulate a GC by "moving" the smis in the internal keys array.
t.SimulateGCByIncrementingSmisBy(kShift); t.SimulateGCByIncrementingSmisBy(kShift);
// Check that searching for the incremented smis finds the same values. // Check that searching for the incremented smis finds the same values.
for (size_t i = 0; i < arraysize(keys); i++) { for (size_t i = 0; i < arraysize(keys); i++) {
t.CheckFind(t.smi(keys[i] + kShift), &keys[i]); t.CheckFind(smi(keys[i] + kShift), &keys[i]);
} }
// Check that searching for the incremented smis gets the same values. // Check that searching for the incremented smis gets the same values.
for (size_t i = 0; i < arraysize(keys); i++) { for (size_t i = 0; i < arraysize(keys); i++) {
t.CheckFindOrInsert(t.smi(keys[i] + kShift), &keys[i]); t.CheckFindOrInsert(smi(keys[i] + kShift), &keys[i]);
} }
} }
TEST(Delete_smi_gc_n) { TEST_F(IdentityMapTest, Delete_smi_gc_n) {
const int kShift = 12011; const int kShift = 12011;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
int keys[12] = {1, 2, 7, 8, 15, 23, int keys[12] = {1, 2, 7, 8, 15, 23,
1 + 32, 2 + 32, 7 + 32, 8 + 32, 15 + 32, 23 + 32}; 1 + 32, 2 + 32, 7 + 32, 8 + 32, 15 + 32, 23 + 32};
// Initialize the map first. // Initialize the map first.
for (size_t i = 0; i < arraysize(keys); i++) { for (size_t i = 0; i < arraysize(keys); i++) {
t.map.Insert(t.smi(keys[i]), &keys[i]); t.map.Insert(smi(keys[i]), &keys[i]);
} }
// Simulate a GC by "moving" the smis in the internal keys array. // Simulate a GC by "moving" the smis in the internal keys array.
t.SimulateGCByIncrementingSmisBy(kShift); t.SimulateGCByIncrementingSmisBy(kShift);
// Check that deleting for the incremented smis finds the same values. // Check that deleting for the incremented smis finds the same values.
for (size_t i = 0; i < arraysize(keys); i++) { for (size_t i = 0; i < arraysize(keys); i++) {
t.CheckDelete(t.smi(keys[i] + kShift), &keys[i]); t.CheckDelete(smi(keys[i] + kShift), &keys[i]);
} }
} }
TEST(GetFind_smi_num_gc_n) { TEST_F(IdentityMapTest, GetFind_smi_num_gc_n) {
const int kShift = 12019; const int kShift = 12019;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
int smi_keys[] = {1, 2, 7, 15, 23}; int smi_keys[] = {1, 2, 7, 15, 23};
Handle<Object> num_keys[] = {t.num(1.1), t.num(2.2), t.num(3.3), t.num(4.4), Handle<Object> num_keys[] = {num(1.1), num(2.2), num(3.3), num(4.4),
t.num(5.5), t.num(6.6), t.num(7.7), t.num(8.8), num(5.5), num(6.6), num(7.7), num(8.8),
t.num(9.9), t.num(10.1)}; num(9.9), num(10.1)};
// Initialize the map first. // Initialize the map first.
for (size_t i = 0; i < arraysize(smi_keys); i++) { for (size_t i = 0; i < arraysize(smi_keys); i++) {
t.map.Insert(t.smi(smi_keys[i]), &smi_keys[i]); t.map.Insert(smi(smi_keys[i]), &smi_keys[i]);
} }
for (size_t i = 0; i < arraysize(num_keys); i++) { for (size_t i = 0; i < arraysize(num_keys); i++) {
t.map.Insert(num_keys[i], &num_keys[i]); t.map.Insert(num_keys[i], &num_keys[i]);
} }
// Check the above initialization. // Check the above initialization.
for (size_t i = 0; i < arraysize(smi_keys); i++) { for (size_t i = 0; i < arraysize(smi_keys); i++) {
t.CheckFind(t.smi(smi_keys[i]), &smi_keys[i]); t.CheckFind(smi(smi_keys[i]), &smi_keys[i]);
} }
for (size_t i = 0; i < arraysize(num_keys); i++) { for (size_t i = 0; i < arraysize(num_keys); i++) {
t.CheckFind(num_keys[i], &num_keys[i]); t.CheckFind(num_keys[i], &num_keys[i]);
...@@ -474,8 +539,8 @@ TEST(GetFind_smi_num_gc_n) { ...@@ -474,8 +539,8 @@ TEST(GetFind_smi_num_gc_n) {
// Check that searching for the incremented smis finds the same values. // Check that searching for the incremented smis finds the same values.
for (size_t i = 0; i < arraysize(smi_keys); i++) { for (size_t i = 0; i < arraysize(smi_keys); i++) {
t.CheckFind(t.smi(smi_keys[i] + kShift), &smi_keys[i]); t.CheckFind(smi(smi_keys[i] + kShift), &smi_keys[i]);
t.CheckFindOrInsert(t.smi(smi_keys[i] + kShift), &smi_keys[i]); t.CheckFindOrInsert(smi(smi_keys[i] + kShift), &smi_keys[i]);
} }
// Check that searching for the numbers finds the same values. // Check that searching for the numbers finds the same values.
...@@ -485,16 +550,16 @@ TEST(GetFind_smi_num_gc_n) { ...@@ -485,16 +550,16 @@ TEST(GetFind_smi_num_gc_n) {
} }
} }
TEST(Delete_smi_num_gc_n) { TEST_F(IdentityMapTest, Delete_smi_num_gc_n) {
const int kShift = 12019; const int kShift = 12019;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
int smi_keys[] = {1, 2, 7, 15, 23}; int smi_keys[] = {1, 2, 7, 15, 23};
Handle<Object> num_keys[] = {t.num(1.1), t.num(2.2), t.num(3.3), t.num(4.4), Handle<Object> num_keys[] = {num(1.1), num(2.2), num(3.3), num(4.4),
t.num(5.5), t.num(6.6), t.num(7.7), t.num(8.8), num(5.5), num(6.6), num(7.7), num(8.8),
t.num(9.9), t.num(10.1)}; num(9.9), num(10.1)};
// Initialize the map first. // Initialize the map first.
for (size_t i = 0; i < arraysize(smi_keys); i++) { for (size_t i = 0; i < arraysize(smi_keys); i++) {
t.map.Insert(t.smi(smi_keys[i]), &smi_keys[i]); t.map.Insert(smi(smi_keys[i]), &smi_keys[i]);
} }
for (size_t i = 0; i < arraysize(num_keys); i++) { for (size_t i = 0; i < arraysize(num_keys); i++) {
t.map.Insert(num_keys[i], &num_keys[i]); t.map.Insert(num_keys[i], &num_keys[i]);
...@@ -506,7 +571,7 @@ TEST(Delete_smi_num_gc_n) { ...@@ -506,7 +571,7 @@ TEST(Delete_smi_num_gc_n) {
// Check that deleting for the incremented smis finds the same values. // Check that deleting for the incremented smis finds the same values.
for (size_t i = 0; i < arraysize(smi_keys); i++) { for (size_t i = 0; i < arraysize(smi_keys); i++) {
t.CheckDelete(t.smi(smi_keys[i] + kShift), &smi_keys[i]); t.CheckDelete(smi(smi_keys[i] + kShift), &smi_keys[i]);
} }
// Check that deleting the numbers finds the same values. // Check that deleting the numbers finds the same values.
...@@ -515,20 +580,20 @@ TEST(Delete_smi_num_gc_n) { ...@@ -515,20 +580,20 @@ TEST(Delete_smi_num_gc_n) {
} }
} }
TEST(Delete_smi_resizes) { TEST_F(IdentityMapTest, Delete_smi_resizes) {
const int kKeyCount = 1024; const int kKeyCount = 1024;
const int kValueOffset = 27; const int kValueOffset = 27;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
// Insert one element to initialize map. // Insert one element to initialize map.
t.map.Insert(t.smi(0), reinterpret_cast<void*>(kValueOffset)); t.map.Insert(smi(0), reinterpret_cast<void*>(kValueOffset));
int initial_capacity = t.map.capacity(); int initial_capacity = t.map.capacity();
CHECK_LT(initial_capacity, kKeyCount); CHECK_LT(initial_capacity, kKeyCount);
// Insert another kKeyCount - 1 keys. // Insert another kKeyCount - 1 keys.
for (int i = 1; i < kKeyCount; i++) { for (int i = 1; i < kKeyCount; i++) {
t.map.Insert(t.smi(i), reinterpret_cast<void*>(i + kValueOffset)); t.map.Insert(smi(i), reinterpret_cast<void*>(i + kValueOffset));
} }
// Check capacity increased. // Check capacity increased.
...@@ -537,22 +602,22 @@ TEST(Delete_smi_resizes) { ...@@ -537,22 +602,22 @@ TEST(Delete_smi_resizes) {
// Delete all the keys. // Delete all the keys.
for (int i = 0; i < kKeyCount; i++) { for (int i = 0; i < kKeyCount; i++) {
t.CheckDelete(t.smi(i), reinterpret_cast<void*>(i + kValueOffset)); t.CheckDelete(smi(i), reinterpret_cast<void*>(i + kValueOffset));
} }
// Should resize back to initial capacity. // Should resize back to initial capacity.
CHECK_EQ(t.map.capacity(), initial_capacity); CHECK_EQ(t.map.capacity(), initial_capacity);
} }
TEST(Iterator_smi_num) { TEST_F(IdentityMapTest, Iterator_smi_num) {
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
int smi_keys[] = {1, 2, 7, 15, 23}; int smi_keys[] = {1, 2, 7, 15, 23};
Handle<Object> num_keys[] = {t.num(1.1), t.num(2.2), t.num(3.3), t.num(4.4), Handle<Object> num_keys[] = {num(1.1), num(2.2), num(3.3), num(4.4),
t.num(5.5), t.num(6.6), t.num(7.7), t.num(8.8), num(5.5), num(6.6), num(7.7), num(8.8),
t.num(9.9), t.num(10.1)}; num(9.9), num(10.1)};
// Initialize the map. // Initialize the map.
for (size_t i = 0; i < arraysize(smi_keys); i++) { for (size_t i = 0; i < arraysize(smi_keys); i++) {
t.map.Insert(t.smi(smi_keys[i]), reinterpret_cast<void*>(i)); t.map.Insert(smi(smi_keys[i]), reinterpret_cast<void*>(i));
} }
for (size_t i = 0; i < arraysize(num_keys); i++) { for (size_t i = 0; i < arraysize(num_keys); i++) {
t.map.Insert(num_keys[i], reinterpret_cast<void*>(i + 5)); t.map.Insert(num_keys[i], reinterpret_cast<void*>(i + 5));
...@@ -572,16 +637,16 @@ TEST(Iterator_smi_num) { ...@@ -572,16 +637,16 @@ TEST(Iterator_smi_num) {
} }
} }
TEST(Iterator_smi_num_gc) { TEST_F(IdentityMapTest, Iterator_smi_num_gc) {
const int kShift = 16039; const int kShift = 16039;
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
int smi_keys[] = {1, 2, 7, 15, 23}; int smi_keys[] = {1, 2, 7, 15, 23};
Handle<Object> num_keys[] = {t.num(1.1), t.num(2.2), t.num(3.3), t.num(4.4), Handle<Object> num_keys[] = {num(1.1), num(2.2), num(3.3), num(4.4),
t.num(5.5), t.num(6.6), t.num(7.7), t.num(8.8), num(5.5), num(6.6), num(7.7), num(8.8),
t.num(9.9), t.num(10.1)}; num(9.9), num(10.1)};
// Initialize the map. // Initialize the map.
for (size_t i = 0; i < arraysize(smi_keys); i++) { for (size_t i = 0; i < arraysize(smi_keys); i++) {
t.map.Insert(t.smi(smi_keys[i]), reinterpret_cast<void*>(i)); t.map.Insert(smi(smi_keys[i]), reinterpret_cast<void*>(i));
} }
for (size_t i = 0; i < arraysize(num_keys); i++) { for (size_t i = 0; i < arraysize(num_keys); i++) {
t.map.Insert(num_keys[i], reinterpret_cast<void*>(i + 5)); t.map.Insert(num_keys[i], reinterpret_cast<void*>(i + 5));
...@@ -604,89 +669,25 @@ TEST(Iterator_smi_num_gc) { ...@@ -604,89 +669,25 @@ TEST(Iterator_smi_num_gc) {
} }
} }
void IterateCollisionTest(int stride) { TEST_F(IdentityMapTest, IterateCollisions_1) { IterateCollisionTest(1); }
for (int load = 15; load <= 120; load = load * 2) { TEST_F(IdentityMapTest, IterateCollisions_2) { IterateCollisionTest(2); }
IdentityMapTester t; TEST_F(IdentityMapTest, IterateCollisions_3) { IterateCollisionTest(3); }
TEST_F(IdentityMapTest, IterateCollisions_5) { IterateCollisionTest(5); }
{ // Add entries to the map. TEST_F(IdentityMapTest, IterateCollisions_7) { IterateCollisionTest(7); }
HandleScope scope(t.isolate());
int next = 1; TEST_F(IdentityMapTest, Collisions_1) { CollisionTest(1); }
for (int i = 0; i < load; i++) { TEST_F(IdentityMapTest, Collisions_2) { CollisionTest(2); }
t.map.Insert(t.smi(next), reinterpret_cast<void*>(next)); TEST_F(IdentityMapTest, Collisions_3) { CollisionTest(3); }
t.CheckFind(t.smi(next), reinterpret_cast<void*>(next)); TEST_F(IdentityMapTest, Collisions_5) { CollisionTest(5); }
next = next + stride; TEST_F(IdentityMapTest, Collisions_7) { CollisionTest(7); }
} TEST_F(IdentityMapTest, Resize) { CollisionTest(9, false, true); }
} TEST_F(IdentityMapTest, Rehash) { CollisionTest(11, true, false); }
// Iterate through the map and check we see all elements only once.
std::set<intptr_t> seen; TEST_F(IdentityMapTest, ExplicitGC) {
{ IdentityMapTester t(isolate()->heap(), zone());
IdentityMap<void*, ZoneAllocationPolicy>::IteratableScope it_scope( Handle<Object> num_keys[] = {num(2.1), num(2.4), num(3.3), num(4.3),
&t.map); num(7.5), num(6.4), num(7.3), num(8.3),
for (auto it = it_scope.begin(); it != it_scope.end(); ++it) { num(8.9), num(10.4)};
CHECK(seen.find(reinterpret_cast<intptr_t>(**it)) == seen.end());
seen.insert(reinterpret_cast<intptr_t>(**it));
}
}
// Check get and find on map.
{
HandleScope scope(t.isolate());
int next = 1;
for (int i = 0; i < load; i++) {
CHECK(seen.find(next) != seen.end());
t.CheckFind(t.smi(next), reinterpret_cast<void*>(next));
t.CheckFindOrInsert(t.smi(next), reinterpret_cast<void*>(next));
next = next + stride;
}
}
}
}
TEST(IterateCollisions_1) { IterateCollisionTest(1); }
TEST(IterateCollisions_2) { IterateCollisionTest(2); }
TEST(IterateCollisions_3) { IterateCollisionTest(3); }
TEST(IterateCollisions_5) { IterateCollisionTest(5); }
TEST(IterateCollisions_7) { IterateCollisionTest(7); }
void CollisionTest(int stride, bool rehash = false, bool resize = false) {
for (int load = 15; load <= 120; load = load * 2) {
IdentityMapTester t;
{ // Add entries to the map.
HandleScope scope(t.isolate());
int next = 1;
for (int i = 0; i < load; i++) {
t.map.Insert(t.smi(next), reinterpret_cast<void*>(next));
t.CheckFind(t.smi(next), reinterpret_cast<void*>(next));
next = next + stride;
}
}
if (resize) t.Resize(); // Explicit resize (internal method).
if (rehash) t.Rehash(); // Explicit rehash (internal method).
{ // Check find and get.
HandleScope scope(t.isolate());
int next = 1;
for (int i = 0; i < load; i++) {
t.CheckFind(t.smi(next), reinterpret_cast<void*>(next));
t.CheckFindOrInsert(t.smi(next), reinterpret_cast<void*>(next));
next = next + stride;
}
}
}
}
TEST(Collisions_1) { CollisionTest(1); }
TEST(Collisions_2) { CollisionTest(2); }
TEST(Collisions_3) { CollisionTest(3); }
TEST(Collisions_5) { CollisionTest(5); }
TEST(Collisions_7) { CollisionTest(7); }
TEST(Resize) { CollisionTest(9, false, true); }
TEST(Rehash) { CollisionTest(11, true, false); }
TEST(ExplicitGC) {
IdentityMapTester t;
Handle<Object> num_keys[] = {t.num(2.1), t.num(2.4), t.num(3.3), t.num(4.3),
t.num(7.5), t.num(6.4), t.num(7.3), t.num(8.3),
t.num(8.9), t.num(10.4)};
// Insert some objects that should be in new space. // Insert some objects that should be in new space.
for (size_t i = 0; i < arraysize(num_keys); i++) { for (size_t i = 0; i < arraysize(num_keys); i++) {
...@@ -694,7 +695,8 @@ TEST(ExplicitGC) { ...@@ -694,7 +695,8 @@ TEST(ExplicitGC) {
} }
// Do an explicit, real GC. // Do an explicit, real GC.
t.heap()->CollectGarbage(i::NEW_SPACE, i::GarbageCollectionReason::kTesting); isolate()->heap()->CollectGarbage(i::NEW_SPACE,
i::GarbageCollectionReason::kTesting);
// Check that searching for the numbers finds the same values. // Check that searching for the numbers finds the same values.
for (size_t i = 0; i < arraysize(num_keys); i++) { for (size_t i = 0; i < arraysize(num_keys); i++) {
...@@ -703,77 +705,77 @@ TEST(ExplicitGC) { ...@@ -703,77 +705,77 @@ TEST(ExplicitGC) {
} }
} }
TEST(CanonicalHandleScope) { TEST_F(IdentityMapTest, CanonicalHandleScope) {
Isolate* isolate = CcTest::i_isolate(); HandleScope outer(isolate());
Heap* heap = CcTest::heap(); CanonicalHandleScope outer_canonical(isolate());
HandleScope outer(isolate);
CanonicalHandleScope outer_canonical(isolate);
// Deduplicate smi handles. // Deduplicate smi handles.
std::vector<Handle<Object>> smi_handles; std::vector<Handle<Object>> smi_handles;
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
smi_handles.push_back(Handle<Object>(Smi::FromInt(i), isolate)); smi_handles.push_back(Handle<Object>(Smi::FromInt(i), isolate()));
} }
Address* next_handle = isolate->handle_scope_data()->next; Address* next_handle = isolate()->handle_scope_data()->next;
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
Handle<Object> new_smi = Handle<Object>(Smi::FromInt(i), isolate); Handle<Object> new_smi = Handle<Object>(Smi::FromInt(i), isolate());
Handle<Object> old_smi = smi_handles[i]; Handle<Object> old_smi = smi_handles[i];
CHECK_EQ(new_smi.location(), old_smi.location()); CHECK_EQ(new_smi.location(), old_smi.location());
} }
// Check that no new handles have been allocated. // Check that no new handles have been allocated.
CHECK_EQ(next_handle, isolate->handle_scope_data()->next); CHECK_EQ(next_handle, isolate()->handle_scope_data()->next);
// Deduplicate root list items. // Deduplicate root list items.
Handle<String> empty_string(ReadOnlyRoots(heap).empty_string(), isolate); Handle<String> empty_string(ReadOnlyRoots(isolate()->heap()).empty_string(),
Handle<Map> free_space_map(ReadOnlyRoots(heap).free_space_map(), isolate); isolate());
Handle<Map> free_space_map(ReadOnlyRoots(isolate()->heap()).free_space_map(),
isolate());
Handle<Symbol> uninitialized_symbol( Handle<Symbol> uninitialized_symbol(
ReadOnlyRoots(heap).uninitialized_symbol(), isolate); ReadOnlyRoots(isolate()->heap()).uninitialized_symbol(), isolate());
CHECK_EQ(isolate->factory()->empty_string().location(), CHECK_EQ(isolate()->factory()->empty_string().location(),
empty_string.location()); empty_string.location());
CHECK_EQ(isolate->factory()->free_space_map().location(), CHECK_EQ(isolate()->factory()->free_space_map().location(),
free_space_map.location()); free_space_map.location());
CHECK_EQ(isolate->factory()->uninitialized_symbol().location(), CHECK_EQ(isolate()->factory()->uninitialized_symbol().location(),
uninitialized_symbol.location()); uninitialized_symbol.location());
// Check that no new handles have been allocated. // Check that no new handles have been allocated.
CHECK_EQ(next_handle, isolate->handle_scope_data()->next); CHECK_EQ(next_handle, isolate()->handle_scope_data()->next);
// Test ordinary heap objects. // Test ordinary heap objects.
Handle<HeapNumber> number1 = isolate->factory()->NewHeapNumber(3.3); Handle<HeapNumber> number1 = isolate()->factory()->NewHeapNumber(3.3);
Handle<String> string1 = Handle<String> string1 =
isolate->factory()->NewStringFromAsciiChecked("test"); isolate()->factory()->NewStringFromAsciiChecked("test");
next_handle = isolate->handle_scope_data()->next; next_handle = isolate()->handle_scope_data()->next;
Handle<HeapNumber> number2(*number1, isolate); Handle<HeapNumber> number2(*number1, isolate());
Handle<String> string2(*string1, isolate); Handle<String> string2(*string1, isolate());
CHECK_EQ(number1.location(), number2.location()); CHECK_EQ(number1.location(), number2.location());
CHECK_EQ(string1.location(), string2.location()); CHECK_EQ(string1.location(), string2.location());
CcTest::CollectAllGarbage(); CollectAllGarbage();
Handle<HeapNumber> number3(*number2, isolate); Handle<HeapNumber> number3(*number2, isolate());
Handle<String> string3(*string2, isolate); Handle<String> string3(*string2, isolate());
CHECK_EQ(number1.location(), number3.location()); CHECK_EQ(number1.location(), number3.location());
CHECK_EQ(string1.location(), string3.location()); CHECK_EQ(string1.location(), string3.location());
// Check that no new handles have been allocated. // Check that no new handles have been allocated.
CHECK_EQ(next_handle, isolate->handle_scope_data()->next); CHECK_EQ(next_handle, isolate()->handle_scope_data()->next);
// Inner handle scope do not create canonical handles. // Inner handle scope do not create canonical handles.
{ {
HandleScope inner(isolate); HandleScope inner(isolate());
Handle<HeapNumber> number4(*number1, isolate); Handle<HeapNumber> number4(*number1, isolate());
Handle<String> string4(*string1, isolate); Handle<String> string4(*string1, isolate());
CHECK_NE(number1.location(), number4.location()); CHECK_NE(number1.location(), number4.location());
CHECK_NE(string1.location(), string4.location()); CHECK_NE(string1.location(), string4.location());
// Nested canonical scope does not conflict with outer canonical scope, // Nested canonical scope does not conflict with outer canonical scope,
// but does not canonicalize across scopes. // but does not canonicalize across scopes.
CanonicalHandleScope inner_canonical(isolate); CanonicalHandleScope inner_canonical(isolate());
Handle<HeapNumber> number5(*number4, isolate); Handle<HeapNumber> number5(*number4, isolate());
Handle<String> string5(*string4, isolate); Handle<String> string5(*string4, isolate());
CHECK_NE(number4.location(), number5.location()); CHECK_NE(number4.location(), number5.location());
CHECK_NE(string4.location(), string5.location()); CHECK_NE(string4.location(), string5.location());
CHECK_NE(number1.location(), number5.location()); CHECK_NE(number1.location(), number5.location());
CHECK_NE(string1.location(), string5.location()); CHECK_NE(string1.location(), string5.location());
Handle<HeapNumber> number6(*number1, isolate); Handle<HeapNumber> number6(*number1, isolate());
Handle<String> string6(*string1, isolate); Handle<String> string6(*string1, isolate());
CHECK_NE(number4.location(), number6.location()); CHECK_NE(number4.location(), number6.location());
CHECK_NE(string4.location(), string6.location()); CHECK_NE(string4.location(), string6.location());
CHECK_NE(number1.location(), number6.location()); CHECK_NE(number1.location(), number6.location());
...@@ -783,14 +785,13 @@ TEST(CanonicalHandleScope) { ...@@ -783,14 +785,13 @@ TEST(CanonicalHandleScope) {
} }
} }
TEST(GCShortCutting) { TEST_F(IdentityMapTest, GCShortCutting) {
if (FLAG_single_generation) return; if (FLAG_single_generation) return;
// We don't create ThinStrings immediately when using the forwarding table. // We don't create ThinStrings immediately when using the forwarding table.
if (FLAG_always_use_string_forwarding_table) return; if (FLAG_always_use_string_forwarding_table) return;
ManualGCScope manual_gc_scope; ManualGCScope manual_gc_scope(isolate());
IdentityMapTester t; IdentityMapTester t(isolate()->heap(), zone());
Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate()->factory();
Factory* factory = isolate->factory();
const int kDummyValue = 0; const int kDummyValue = 0;
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
...@@ -799,7 +800,7 @@ TEST(GCShortCutting) { ...@@ -799,7 +800,7 @@ TEST(GCShortCutting) {
// greater to capacity_ if not corrected by IdentityMap // greater to capacity_ if not corrected by IdentityMap
// (see crbug.com/704132). // (see crbug.com/704132).
for (int j = 0; j < i; j++) { for (int j = 0; j < i; j++) {
t.map.Insert(t.smi(j), reinterpret_cast<void*>(kDummyValue)); t.map.Insert(smi(j), reinterpret_cast<void*>(kDummyValue));
} }
Handle<String> thin_string = Handle<String> thin_string =
...@@ -815,8 +816,8 @@ TEST(GCShortCutting) { ...@@ -815,8 +816,8 @@ TEST(GCShortCutting) {
// Do an explicit, real GC, this should short-cut the thin string to point // Do an explicit, real GC, this should short-cut the thin string to point
// to the internalized string. // to the internalized string.
t.heap()->CollectGarbage(i::NEW_SPACE, isolate()->heap()->CollectGarbage(i::NEW_SPACE,
i::GarbageCollectionReason::kTesting); i::GarbageCollectionReason::kTesting);
DCHECK_IMPLIES(!FLAG_optimize_for_size, DCHECK_IMPLIES(!FLAG_optimize_for_size,
*thin_string == *internalized_string); *thin_string == *internalized_string);
...@@ -830,7 +831,7 @@ TEST(GCShortCutting) { ...@@ -830,7 +831,7 @@ TEST(GCShortCutting) {
// Trigger resize. // Trigger resize.
for (int j = 0; j < 16; j++) { for (int j = 0; j < 16; j++) {
t.map.Insert(t.smi(j + 16), reinterpret_cast<void*>(kDummyValue)); t.map.Insert(smi(j + 16), reinterpret_cast<void*>(kDummyValue));
} }
t.map.Clear(); t.map.Clear();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment