Line data Source code
1 : // Copyright 2016 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include <cmath>
6 : #include <iostream>
7 : #include <limits>
8 :
9 : #include "src/api-inl.h"
10 : #include "src/compiler.h"
11 : #include "src/objects-inl.h"
12 : #include "src/objects.h"
13 : #include "src/objects/hash-table-inl.h"
14 : #include "test/unittests/test-utils.h"
15 :
16 : #include "testing/gtest/include/gtest/gtest.h"
17 :
18 : namespace v8 {
19 : namespace internal {
20 :
21 : namespace {
22 :
23 183 : bool IsInStringInstanceTypeList(InstanceType instance_type) {
24 183 : switch (instance_type) {
25 : #define ASSERT_INSTANCE_TYPE(type, ...) \
26 : STATIC_ASSERT(InstanceType::type < InstanceType::FIRST_NONSTRING_TYPE);
27 : STRING_TYPE_LIST(ASSERT_INSTANCE_TYPE)
28 : #undef ASSERT_INSTANCE_TYPE
29 : #define TEST_INSTANCE_TYPE(type, ...) case InstanceType::type:
30 : STRING_TYPE_LIST(TEST_INSTANCE_TYPE)
31 : #undef TEST_INSTANCE_TYPE
32 : return true;
33 : default:
34 164 : EXPECT_LE(InstanceType::FIRST_NONSTRING_TYPE, instance_type);
35 164 : return false;
36 : }
37 : }
38 :
39 183 : void CheckOneInstanceType(InstanceType instance_type) {
40 183 : if (IsInStringInstanceTypeList(instance_type)) {
41 38 : EXPECT_TRUE((instance_type & kIsNotStringMask) == kStringTag)
42 0 : << "Failing IsString mask check for " << instance_type;
43 : } else {
44 328 : EXPECT_FALSE((instance_type & kIsNotStringMask) == kStringTag)
45 0 : << "Failing !IsString mask check for " << instance_type;
46 : }
47 183 : }
48 :
49 : } // namespace
50 :
51 15443 : TEST(Object, InstanceTypeList) {
52 : #define TEST_INSTANCE_TYPE(type) CheckOneInstanceType(InstanceType::type);
53 :
54 1 : INSTANCE_TYPE_LIST(TEST_INSTANCE_TYPE)
55 : #undef TEST_INSTANCE_TYPE
56 1 : }
57 :
58 15443 : TEST(Object, InstanceTypeListOrder) {
59 1 : int current = 0;
60 1 : int last = -1;
61 1 : InstanceType current_type = static_cast<InstanceType>(current);
62 2 : EXPECT_EQ(current_type, InstanceType::FIRST_TYPE);
63 2 : EXPECT_EQ(current_type, InstanceType::INTERNALIZED_STRING_TYPE);
64 : #define TEST_INSTANCE_TYPE(type) \
65 : current_type = InstanceType::type; \
66 : current = static_cast<int>(current_type); \
67 : if (current > static_cast<int>(LAST_NAME_TYPE)) { \
68 : EXPECT_LE(last + 1, current); \
69 : } \
70 : EXPECT_LT(last, current) << " INSTANCE_TYPE_LIST is not ordered: " \
71 : << "last = " << static_cast<InstanceType>(last) \
72 : << " vs. current = " << current_type; \
73 : last = current;
74 :
75 346 : INSTANCE_TYPE_LIST(TEST_INSTANCE_TYPE)
76 : #undef TEST_INSTANCE_TYPE
77 1 : }
78 :
79 15443 : TEST(Object, StructListOrder) {
80 1 : int current = static_cast<int>(InstanceType::ACCESS_CHECK_INFO_TYPE);
81 1 : int last = current - 1;
82 1 : ASSERT_LT(0, last);
83 : InstanceType current_type = static_cast<InstanceType>(current);
84 : #define TEST_STRUCT(TYPE, class, name) \
85 : current_type = InstanceType::TYPE; \
86 : current = static_cast<int>(current_type); \
87 : EXPECT_EQ(last + 1, current) \
88 : << " STRUCT_LIST is not ordered: " \
89 : << " last = " << static_cast<InstanceType>(last) \
90 : << " vs. current = " << current_type; \
91 : last = current;
92 :
93 70 : STRUCT_LIST(TEST_STRUCT)
94 : #undef TEST_STRUCT
95 : }
96 :
97 : typedef TestWithIsolate ObjectWithIsolate;
98 :
99 15444 : TEST_F(ObjectWithIsolate, DictionaryGrowth) {
100 1 : Handle<NumberDictionary> dict = NumberDictionary::New(isolate(), 1);
101 : Handle<Object> value = isolate()->factory()->null_value();
102 1 : PropertyDetails details = PropertyDetails::Empty();
103 :
104 : // This test documents the expected growth behavior of a dictionary getting
105 : // elements added to it one by one.
106 : STATIC_ASSERT(HashTableBase::kMinCapacity == 4);
107 : uint32_t i = 1;
108 : // 3 elements fit into the initial capacity.
109 7 : for (; i <= 3; i++) {
110 3 : dict = NumberDictionary::Add(isolate(), dict, i, value, details);
111 3 : CHECK_EQ(4, dict->Capacity());
112 : }
113 : // 4th element triggers growth.
114 : DCHECK_EQ(4, i);
115 5 : for (; i <= 5; i++) {
116 2 : dict = NumberDictionary::Add(isolate(), dict, i, value, details);
117 2 : CHECK_EQ(8, dict->Capacity());
118 : }
119 : // 6th element triggers growth.
120 : DCHECK_EQ(6, i);
121 13 : for (; i <= 11; i++) {
122 6 : dict = NumberDictionary::Add(isolate(), dict, i, value, details);
123 6 : CHECK_EQ(16, dict->Capacity());
124 : }
125 : // 12th element triggers growth.
126 : DCHECK_EQ(12, i);
127 21 : for (; i <= 21; i++) {
128 10 : dict = NumberDictionary::Add(isolate(), dict, i, value, details);
129 10 : CHECK_EQ(32, dict->Capacity());
130 : }
131 : // 22nd element triggers growth.
132 : DCHECK_EQ(22, i);
133 45 : for (; i <= 43; i++) {
134 22 : dict = NumberDictionary::Add(isolate(), dict, i, value, details);
135 22 : CHECK_EQ(64, dict->Capacity());
136 : }
137 : // 44th element triggers growth.
138 : DCHECK_EQ(44, i);
139 15 : for (; i <= 50; i++) {
140 7 : dict = NumberDictionary::Add(isolate(), dict, i, value, details);
141 7 : CHECK_EQ(128, dict->Capacity());
142 : }
143 :
144 : // If we grow by larger chunks, the next (sufficiently big) power of 2 is
145 : // chosen as the capacity.
146 1 : dict = NumberDictionary::New(isolate(), 1);
147 1 : dict = NumberDictionary::EnsureCapacity(isolate(), dict, 65);
148 1 : CHECK_EQ(128, dict->Capacity());
149 :
150 1 : dict = NumberDictionary::New(isolate(), 1);
151 1 : dict = NumberDictionary::EnsureCapacity(isolate(), dict, 30);
152 1 : CHECK_EQ(64, dict->Capacity());
153 1 : }
154 :
155 15444 : TEST_F(TestWithNativeContext, EmptyFunctionScopeInfo) {
156 : // Check that the empty_function has a properly set up ScopeInfo.
157 : Handle<JSFunction> function = RunJS<JSFunction>("(function(){})");
158 :
159 2 : Handle<ScopeInfo> scope_info(function->shared()->scope_info(),
160 1 : function->GetIsolate());
161 : Handle<ScopeInfo> empty_function_scope_info(
162 3 : isolate()->empty_function()->shared()->scope_info(),
163 1 : function->GetIsolate());
164 :
165 3 : EXPECT_EQ(scope_info->length(), empty_function_scope_info->length());
166 3 : EXPECT_EQ(scope_info->Flags(), empty_function_scope_info->Flags());
167 3 : EXPECT_EQ(scope_info->ParameterCount(),
168 0 : empty_function_scope_info->ParameterCount());
169 3 : EXPECT_EQ(scope_info->ContextLocalCount(),
170 0 : empty_function_scope_info->ContextLocalCount());
171 1 : }
172 :
173 : } // namespace internal
174 9264 : } // namespace v8
|