Commit c5005009 authored by jameslahm's avatar jameslahm Committed by V8 LUCI CQ

[test] Move cctest/test-hashcode to unittests/objects/

... hashcode-unittest.

Bug: v8:12781
Change-Id: I118ec1f2963abfaf6fbf738b97a984c9449d105d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3699498Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: 王澳 <wangao.james@bytedance.com>
Cr-Commit-Position: refs/heads/main@{#81103}
parent dc748570
...@@ -186,7 +186,6 @@ v8_source_set("cctest_sources") { ...@@ -186,7 +186,6 @@ v8_source_set("cctest_sources") {
"test-func-name-inference.cc", "test-func-name-inference.cc",
"test-global-handles.cc", "test-global-handles.cc",
"test-global-object.cc", "test-global-object.cc",
"test-hashcode.cc",
"test-heap-profiler.cc", "test-heap-profiler.cc",
"test-icache.cc", "test-icache.cc",
"test-identity-map.cc", "test-identity-map.cc",
......
...@@ -424,6 +424,7 @@ v8_source_set("unittests_sources") { ...@@ -424,6 +424,7 @@ v8_source_set("unittests_sources") {
"objects/concurrent-string-unittest.cc", "objects/concurrent-string-unittest.cc",
"objects/concurrent-transition-array-unittest.cc", "objects/concurrent-transition-array-unittest.cc",
"objects/elements-kind-unittest.cc", "objects/elements-kind-unittest.cc",
"objects/hashcode-unittest.cc",
"objects/managed-unittest.cc", "objects/managed-unittest.cc",
"objects/modules-unittest.cc", "objects/modules-unittest.cc",
"objects/object-unittest.cc", "objects/object-unittest.cc",
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include <stdlib.h> #include <stdlib.h>
#include <sstream> #include <sstream>
#include <utility> #include <utility>
...@@ -12,243 +13,216 @@ ...@@ -12,243 +13,216 @@
#include "src/objects/ordered-hash-table.h" #include "src/objects/ordered-hash-table.h"
#include "src/third_party/siphash/halfsiphash.h" #include "src/third_party/siphash/halfsiphash.h"
#include "src/utils/utils.h" #include "src/utils/utils.h"
#include "test/unittests/test-utils.h"
#include "test/cctest/cctest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
int AddToSetAndGetHash(Isolate* isolate, Handle<JSObject> obj, class HashcodeTest : public TestWithContext {
bool has_fast_properties) { public:
template <typename T>
inline Handle<T> GetGlobal(const char* name) {
Handle<String> str_name =
i_isolate()->factory()->InternalizeUtf8String(name);
Handle<Object> value =
Object::GetProperty(i_isolate(), i_isolate()->global_object(), str_name)
.ToHandleChecked();
return Handle<T>::cast(value);
}
int AddToSetAndGetHash(Handle<JSObject> obj, bool has_fast_properties) {
CHECK_EQ(has_fast_properties, obj->HasFastProperties()); CHECK_EQ(has_fast_properties, obj->HasFastProperties());
CHECK_EQ(ReadOnlyRoots(isolate).undefined_value(), obj->GetHash()); CHECK_EQ(ReadOnlyRoots(i_isolate()).undefined_value(), obj->GetHash());
Handle<OrderedHashSet> set = isolate->factory()->NewOrderedHashSet(); Handle<OrderedHashSet> set = i_isolate()->factory()->NewOrderedHashSet();
OrderedHashSet::Add(isolate, set, obj); OrderedHashSet::Add(i_isolate(), set, obj);
CHECK_EQ(has_fast_properties, obj->HasFastProperties()); CHECK_EQ(has_fast_properties, obj->HasFastProperties());
return Smi::ToInt(obj->GetHash()); return Smi::ToInt(obj->GetHash());
} }
int GetPropertyDictionaryHash(Handle<JSObject> obj) { int GetPropertyDictionaryHash(Handle<JSObject> obj) {
if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) { if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
return obj->property_dictionary_swiss().Hash(); return obj->property_dictionary_swiss().Hash();
} else { } else {
return obj->property_dictionary().Hash(); return obj->property_dictionary().Hash();
} }
} }
int GetPropertyDictionaryLength(Handle<JSObject> obj) { int GetPropertyDictionaryLength(Handle<JSObject> obj) {
if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) { if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
return obj->property_dictionary_swiss().Capacity(); return obj->property_dictionary_swiss().Capacity();
} else { } else {
return obj->property_dictionary().length(); return obj->property_dictionary().length();
} }
} }
void CheckIsDictionaryModeObject(Handle<JSObject> obj) { void CheckIsDictionaryModeObject(Handle<JSObject> obj) {
if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) { if (V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL) {
CHECK(obj->raw_properties_or_hash().IsSwissNameDictionary()); CHECK(obj->raw_properties_or_hash().IsSwissNameDictionary());
} else { } else {
CHECK(obj->raw_properties_or_hash().IsNameDictionary()); CHECK(obj->raw_properties_or_hash().IsNameDictionary());
} }
} }
void CheckFastObject(Handle<JSObject> obj, int hash) { void CheckFastObject(Handle<JSObject> obj, int hash) {
CHECK(obj->HasFastProperties()); CHECK(obj->HasFastProperties());
CHECK(obj->raw_properties_or_hash().IsPropertyArray()); CHECK(obj->raw_properties_or_hash().IsPropertyArray());
CHECK_EQ(Smi::FromInt(hash), obj->GetHash()); CHECK_EQ(Smi::FromInt(hash), obj->GetHash());
CHECK_EQ(hash, obj->property_array().Hash()); CHECK_EQ(hash, obj->property_array().Hash());
} }
void CheckDictionaryObject(Handle<JSObject> obj, int hash) { void CheckDictionaryObject(Handle<JSObject> obj, int hash) {
CHECK(!obj->HasFastProperties()); CHECK(!obj->HasFastProperties());
CheckIsDictionaryModeObject(obj); CheckIsDictionaryModeObject(obj);
CHECK_EQ(Smi::FromInt(hash), obj->GetHash()); CHECK_EQ(Smi::FromInt(hash), obj->GetHash());
CHECK_EQ(hash, GetPropertyDictionaryHash(obj)); CHECK_EQ(hash, GetPropertyDictionaryHash(obj));
} }
};
TEST(AddHashCodeToFastObjectWithoutProperties) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
TEST_F(HashcodeTest, AddHashCodeToFastObjectWithoutProperties) {
Handle<JSObject> obj = Handle<JSObject> obj =
isolate->factory()->NewJSObject(isolate->object_function()); i_isolate()->factory()->NewJSObject(i_isolate()->object_function());
CHECK(obj->HasFastProperties()); CHECK(obj->HasFastProperties());
int hash = AddToSetAndGetHash(isolate, obj, true); int hash = AddToSetAndGetHash(obj, true);
CHECK_EQ(Smi::FromInt(hash), obj->raw_properties_or_hash()); CHECK_EQ(Smi::FromInt(hash), obj->raw_properties_or_hash());
} }
TEST(AddHashCodeToFastObjectWithInObjectProperties) { TEST_F(HashcodeTest, AddHashCodeToFastObjectWithInObjectProperties) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source = " var x = { a: 1};"; const char* source = " var x = { a: 1};";
CompileRun(source); RunJS(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x"); Handle<JSObject> obj = GetGlobal<JSObject>("x");
CHECK_EQ(ReadOnlyRoots(isolate).empty_fixed_array(), CHECK_EQ(ReadOnlyRoots(i_isolate()).empty_fixed_array(),
obj->raw_properties_or_hash()); obj->raw_properties_or_hash());
int hash = AddToSetAndGetHash(isolate, obj, true); int hash = AddToSetAndGetHash(obj, true);
CHECK_EQ(Smi::FromInt(hash), obj->raw_properties_or_hash()); CHECK_EQ(Smi::FromInt(hash), obj->raw_properties_or_hash());
} }
TEST(AddHashCodeToFastObjectWithPropertiesArray) { TEST_F(HashcodeTest, AddHashCodeToFastObjectWithPropertiesArray) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source = const char* source =
" var x = {}; " " var x = {}; "
" x.a = 1; x.b = 2; x.c = 3; x.d = 4; x.e = 5; "; " x.a = 1; x.b = 2; x.c = 3; x.d = 4; x.e = 5; ";
CompileRun(source); RunJS(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x"); Handle<JSObject> obj = GetGlobal<JSObject>("x");
CHECK(obj->HasFastProperties()); CHECK(obj->HasFastProperties());
int hash = AddToSetAndGetHash(isolate, obj, true); int hash = AddToSetAndGetHash(obj, true);
CheckFastObject(obj, hash); CheckFastObject(obj, hash);
} }
TEST(AddHashCodeToSlowObject) { TEST_F(HashcodeTest, AddHashCodeToSlowObject) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<JSObject> obj = Handle<JSObject> obj =
isolate->factory()->NewJSObject(isolate->object_function()); i_isolate()->factory()->NewJSObject(i_isolate()->object_function());
CHECK(obj->HasFastProperties()); CHECK(obj->HasFastProperties());
JSObject::NormalizeProperties(isolate, obj, CLEAR_INOBJECT_PROPERTIES, 0, JSObject::NormalizeProperties(i_isolate(), obj, CLEAR_INOBJECT_PROPERTIES, 0,
"cctest/test-hashcode"); "cctest/test-hashcode");
CheckIsDictionaryModeObject(obj); CheckIsDictionaryModeObject(obj);
int hash = AddToSetAndGetHash(isolate, obj, false); int hash = AddToSetAndGetHash(obj, false);
CheckDictionaryObject(obj, hash); CheckDictionaryObject(obj, hash);
} }
TEST(TransitionFastWithInObjectToFastWithPropertyArray) { TEST_F(HashcodeTest, TransitionFastWithInObjectToFastWithPropertyArray) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source = const char* source =
" var x = { };" " var x = { };"
" x.a = 1; x.b = 2; x.c = 3; x.d = 4;"; " x.a = 1; x.b = 2; x.c = 3; x.d = 4;";
CompileRun(source); RunJS(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x"); Handle<JSObject> obj = GetGlobal<JSObject>("x");
CHECK(obj->HasFastProperties()); CHECK(obj->HasFastProperties());
int hash = AddToSetAndGetHash(isolate, obj, true); int hash = AddToSetAndGetHash(obj, true);
CHECK_EQ(Smi::FromInt(hash), obj->raw_properties_or_hash()); CHECK_EQ(Smi::FromInt(hash), obj->raw_properties_or_hash());
int length = obj->property_array().length(); int length = obj->property_array().length();
CompileRun("x.e = 5;"); RunJS("x.e = 5;");
CHECK(obj->property_array().length() > length); CHECK(obj->property_array().length() > length);
CheckFastObject(obj, hash); CheckFastObject(obj, hash);
} }
TEST(TransitionFastWithPropertyArray) { TEST_F(HashcodeTest, TransitionFastWithPropertyArray) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source = const char* source =
" var x = { };" " var x = { };"
" x.a = 1; x.b = 2; x.c = 3; x.d = 4; x.e = 5; "; " x.a = 1; x.b = 2; x.c = 3; x.d = 4; x.e = 5; ";
CompileRun(source); RunJS(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x"); Handle<JSObject> obj = GetGlobal<JSObject>("x");
CHECK(obj->raw_properties_or_hash().IsPropertyArray()); CHECK(obj->raw_properties_or_hash().IsPropertyArray());
int hash = AddToSetAndGetHash(isolate, obj, true); int hash = AddToSetAndGetHash(obj, true);
CHECK_EQ(hash, obj->property_array().Hash()); CHECK_EQ(hash, obj->property_array().Hash());
int length = obj->property_array().length(); int length = obj->property_array().length();
CompileRun("x.f = 2; x.g = 5; x.h = 2"); RunJS("x.f = 2; x.g = 5; x.h = 2");
CHECK(obj->property_array().length() > length); CHECK(obj->property_array().length() > length);
CheckFastObject(obj, hash); CheckFastObject(obj, hash);
} }
TEST(TransitionFastWithPropertyArrayToSlow) { TEST_F(HashcodeTest, TransitionFastWithPropertyArrayToSlow) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source = const char* source =
" var x = { };" " var x = { };"
" x.a = 1; x.b = 2; x.c = 3; x.d = 4; x.e = 5; "; " x.a = 1; x.b = 2; x.c = 3; x.d = 4; x.e = 5; ";
CompileRun(source); RunJS(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x"); Handle<JSObject> obj = GetGlobal<JSObject>("x");
CHECK(obj->raw_properties_or_hash().IsPropertyArray()); CHECK(obj->raw_properties_or_hash().IsPropertyArray());
int hash = AddToSetAndGetHash(isolate, obj, true); int hash = AddToSetAndGetHash(obj, true);
CHECK(obj->raw_properties_or_hash().IsPropertyArray()); CHECK(obj->raw_properties_or_hash().IsPropertyArray());
CHECK_EQ(hash, obj->property_array().Hash()); CHECK_EQ(hash, obj->property_array().Hash());
JSObject::NormalizeProperties(isolate, obj, KEEP_INOBJECT_PROPERTIES, 0, JSObject::NormalizeProperties(i_isolate(), obj, KEEP_INOBJECT_PROPERTIES, 0,
"cctest/test-hashcode"); "cctest/test-hashcode");
CheckDictionaryObject(obj, hash); CheckDictionaryObject(obj, hash);
} }
TEST(TransitionSlowToSlow) { TEST_F(HashcodeTest, TransitionSlowToSlow) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source = " var x = {}; "; const char* source = " var x = {}; ";
CompileRun(source); RunJS(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x"); Handle<JSObject> obj = GetGlobal<JSObject>("x");
JSObject::NormalizeProperties(isolate, obj, CLEAR_INOBJECT_PROPERTIES, 0, JSObject::NormalizeProperties(i_isolate(), obj, CLEAR_INOBJECT_PROPERTIES, 0,
"cctest/test-hashcode"); "cctest/test-hashcode");
CheckIsDictionaryModeObject(obj); CheckIsDictionaryModeObject(obj);
int hash = AddToSetAndGetHash(isolate, obj, false); int hash = AddToSetAndGetHash(obj, false);
CHECK_EQ(hash, GetPropertyDictionaryHash(obj)); CHECK_EQ(hash, GetPropertyDictionaryHash(obj));
int length = GetPropertyDictionaryLength(obj); int length = GetPropertyDictionaryLength(obj);
CompileRun("for(var i = 0; i < 10; i++) { x['f'+i] = i };"); RunJS("for(var i = 0; i < 10; i++) { x['f'+i] = i };");
CHECK(GetPropertyDictionaryLength(obj) > length); CHECK(GetPropertyDictionaryLength(obj) > length);
CheckDictionaryObject(obj, hash); CheckDictionaryObject(obj, hash);
} }
TEST(TransitionSlowToFastWithoutProperties) { TEST_F(HashcodeTest, TransitionSlowToFastWithoutProperties) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<JSObject> obj = Handle<JSObject> obj =
isolate->factory()->NewJSObject(isolate->object_function()); i_isolate()->factory()->NewJSObject(i_isolate()->object_function());
JSObject::NormalizeProperties(isolate, obj, CLEAR_INOBJECT_PROPERTIES, 0, JSObject::NormalizeProperties(i_isolate(), obj, CLEAR_INOBJECT_PROPERTIES, 0,
"cctest/test-hashcode"); "cctest/test-hashcode");
CheckIsDictionaryModeObject(obj); CheckIsDictionaryModeObject(obj);
int hash = AddToSetAndGetHash(isolate, obj, false); int hash = AddToSetAndGetHash(obj, false);
CHECK_EQ(hash, GetPropertyDictionaryHash(obj)); CHECK_EQ(hash, GetPropertyDictionaryHash(obj));
JSObject::MigrateSlowToFast(obj, 0, "cctest/test-hashcode"); JSObject::MigrateSlowToFast(obj, 0, "cctest/test-hashcode");
CHECK_EQ(Smi::FromInt(hash), obj->GetHash()); CHECK_EQ(Smi::FromInt(hash), obj->GetHash());
} }
TEST(TransitionSlowToFastWithPropertyArray) { TEST_F(HashcodeTest, TransitionSlowToFastWithPropertyArray) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source = const char* source =
" var x = Object.create(null); " " var x = Object.create(null); "
" for(var i = 0; i < 10; i++) { x['f'+i] = i }; "; " for(var i = 0; i < 10; i++) { x['f'+i] = i }; ";
CompileRun(source); RunJS(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x"); Handle<JSObject> obj = GetGlobal<JSObject>("x");
CheckIsDictionaryModeObject(obj); CheckIsDictionaryModeObject(obj);
int hash = AddToSetAndGetHash(isolate, obj, false); int hash = AddToSetAndGetHash(obj, false);
CHECK_EQ(hash, GetPropertyDictionaryHash(obj)); CHECK_EQ(hash, GetPropertyDictionaryHash(obj));
JSObject::MigrateSlowToFast(obj, 0, "cctest/test-hashcode"); JSObject::MigrateSlowToFast(obj, 0, "cctest/test-hashcode");
...@@ -316,11 +290,17 @@ void TestIntegerHashQuality(HashFunction hash_function) { ...@@ -316,11 +290,17 @@ void TestIntegerHashQuality(HashFunction hash_function) {
TestIntegerHashQuality(12, 5, 1, 0.2, hash_function); TestIntegerHashQuality(12, 5, 1, 0.2, hash_function);
} }
TEST(HalfSipHashQuality) { TestIntegerHashQuality(HalfSipHash); } TEST_F(HashcodeTest, HalfSipHashQuality) {
TestIntegerHashQuality(HalfSipHash);
}
TEST(JenkinsHashQuality) { TestIntegerHashQuality(JenkinsHash); } TEST_F(HashcodeTest, JenkinsHashQuality) {
TestIntegerHashQuality(JenkinsHash);
}
TEST(DefaultHashQuality) { TestIntegerHashQuality(DefaultHash); } TEST_F(HashcodeTest, DefaultHashQuality) {
TestIntegerHashQuality(DefaultHash);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
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