v8/test/cctest/test-hashcode.cc
Dan Elphick b19ccf7221 [explicit isolates] Convert src/* to ReadOnlyRoots
In future the RO_SPACE root accessors in Heap will become private, so
instead convert them all to use ReadOnlyRoots.

Bug: v8:7786
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: I2f2c031c03d56d360ef940fc925e0583e6ae31dc
Reviewed-on: https://chromium-review.googlesource.com/1125720
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54202}
2018-07-04 10:29:45 +00:00

233 lines
7.3 KiB
C++

// Copyright 2017 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 <stdlib.h>
#include <sstream>
#include <utility>
#include "src/api.h"
#include "src/objects-inl.h"
#include "src/objects.h"
#include "src/v8.h"
#include "test/cctest/cctest.h"
namespace v8 {
namespace internal {
int AddToSetAndGetHash(Isolate* isolate, Handle<JSObject> obj,
bool has_fast_properties) {
CHECK_EQ(has_fast_properties, obj->HasFastProperties());
CHECK_EQ(ReadOnlyRoots(isolate).undefined_value(), obj->GetHash());
Handle<OrderedHashSet> set = isolate->factory()->NewOrderedHashSet();
OrderedHashSet::Add(isolate, set, obj);
CHECK_EQ(has_fast_properties, obj->HasFastProperties());
return Smi::ToInt(obj->GetHash());
}
void CheckFastObject(Isolate* isolate, Handle<JSObject> obj, int hash) {
CHECK(obj->HasFastProperties());
CHECK(obj->raw_properties_or_hash()->IsPropertyArray());
CHECK_EQ(Smi::FromInt(hash), obj->GetHash());
CHECK_EQ(hash, obj->property_array()->Hash());
}
void CheckDictionaryObject(Isolate* isolate, Handle<JSObject> obj, int hash) {
CHECK(!obj->HasFastProperties());
CHECK(obj->raw_properties_or_hash()->IsDictionary());
CHECK_EQ(Smi::FromInt(hash), obj->GetHash());
CHECK_EQ(hash, obj->property_dictionary()->Hash());
}
TEST(AddHashCodeToFastObjectWithoutProperties) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<JSObject> obj =
isolate->factory()->NewJSObject(isolate->object_function());
CHECK(obj->HasFastProperties());
int hash = AddToSetAndGetHash(isolate, obj, true);
CHECK_EQ(Smi::FromInt(hash), obj->raw_properties_or_hash());
}
TEST(AddHashCodeToFastObjectWithInObjectProperties) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source = " var x = { a: 1};";
CompileRun(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x");
CHECK_EQ(ReadOnlyRoots(isolate).empty_fixed_array(),
obj->raw_properties_or_hash());
int hash = AddToSetAndGetHash(isolate, obj, true);
CHECK_EQ(Smi::FromInt(hash), obj->raw_properties_or_hash());
}
TEST(AddHashCodeToFastObjectWithPropertiesArray) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source =
" var x = {}; "
" x.a = 1; x.b = 2; x.c = 3; x.d = 4; x.e = 5; ";
CompileRun(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x");
CHECK(obj->HasFastProperties());
int hash = AddToSetAndGetHash(isolate, obj, true);
CheckFastObject(isolate, obj, hash);
}
TEST(AddHashCodeToSlowObject) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<JSObject> obj =
isolate->factory()->NewJSObject(isolate->object_function());
CHECK(obj->HasFastProperties());
JSObject::NormalizeProperties(obj, CLEAR_INOBJECT_PROPERTIES, 0,
"cctest/test-hashcode");
CHECK(obj->raw_properties_or_hash()->IsDictionary());
int hash = AddToSetAndGetHash(isolate, obj, false);
CheckDictionaryObject(isolate, obj, hash);
}
TEST(TransitionFastWithInObjectToFastWithPropertyArray) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source =
" var x = { };"
" x.a = 1; x.b = 2; x.c = 3; x.d = 4;";
CompileRun(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x");
CHECK(obj->HasFastProperties());
int hash = AddToSetAndGetHash(isolate, obj, true);
CHECK_EQ(Smi::FromInt(hash), obj->raw_properties_or_hash());
int length = obj->property_array()->length();
CompileRun("x.e = 5;");
CHECK(obj->property_array()->length() > length);
CheckFastObject(isolate, obj, hash);
}
TEST(TransitionFastWithPropertyArray) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source =
" var x = { };"
" x.a = 1; x.b = 2; x.c = 3; x.d = 4; x.e = 5; ";
CompileRun(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x");
CHECK(obj->raw_properties_or_hash()->IsPropertyArray());
int hash = AddToSetAndGetHash(isolate, obj, true);
CHECK_EQ(hash, obj->property_array()->Hash());
int length = obj->property_array()->length();
CompileRun("x.f = 2; x.g = 5; x.h = 2");
CHECK(obj->property_array()->length() > length);
CheckFastObject(isolate, obj, hash);
}
TEST(TransitionFastWithPropertyArrayToSlow) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source =
" var x = { };"
" x.a = 1; x.b = 2; x.c = 3; x.d = 4; x.e = 5; ";
CompileRun(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x");
CHECK(obj->raw_properties_or_hash()->IsPropertyArray());
int hash = AddToSetAndGetHash(isolate, obj, true);
CHECK(obj->raw_properties_or_hash()->IsPropertyArray());
CHECK_EQ(hash, obj->property_array()->Hash());
JSObject::NormalizeProperties(obj, KEEP_INOBJECT_PROPERTIES, 0,
"cctest/test-hashcode");
CheckDictionaryObject(isolate, obj, hash);
}
TEST(TransitionSlowToSlow) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source = " var x = {}; ";
CompileRun(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x");
JSObject::NormalizeProperties(obj, CLEAR_INOBJECT_PROPERTIES, 0,
"cctest/test-hashcode");
CHECK(obj->raw_properties_or_hash()->IsDictionary());
int hash = AddToSetAndGetHash(isolate, obj, false);
CHECK_EQ(hash, obj->property_dictionary()->Hash());
int length = obj->property_dictionary()->length();
CompileRun("for(var i = 0; i < 10; i++) { x['f'+i] = i };");
CHECK(obj->property_dictionary()->length() > length);
CheckDictionaryObject(isolate, obj, hash);
}
TEST(TransitionSlowToFastWithoutProperties) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
Handle<JSObject> obj =
isolate->factory()->NewJSObject(isolate->object_function());
JSObject::NormalizeProperties(obj, CLEAR_INOBJECT_PROPERTIES, 0,
"cctest/test-hashcode");
CHECK(obj->raw_properties_or_hash()->IsDictionary());
int hash = AddToSetAndGetHash(isolate, obj, false);
CHECK_EQ(hash, obj->property_dictionary()->Hash());
JSObject::MigrateSlowToFast(obj, 0, "cctest/test-hashcode");
CHECK_EQ(Smi::FromInt(hash), obj->GetHash());
}
TEST(TransitionSlowToFastWithPropertyArray) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
const char* source =
" var x = Object.create(null); "
" for(var i = 0; i < 10; i++) { x['f'+i] = i }; ";
CompileRun(source);
Handle<JSObject> obj = GetGlobal<JSObject>("x");
CHECK(obj->raw_properties_or_hash()->IsDictionary());
int hash = AddToSetAndGetHash(isolate, obj, false);
CHECK_EQ(hash, obj->property_dictionary()->Hash());
JSObject::MigrateSlowToFast(obj, 0, "cctest/test-hashcode");
CheckFastObject(isolate, obj, hash);
}
} // namespace internal
} // namespace v8