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

Side by Side Diff: test/cctest/test-code-stub-assembler.cc

Issue 2167493003: [ic] [stubs] Don't use Code::flags in megamorphic stub cache hash computations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@stub-cache-fix
Patch Set: Rebasing Created 4 years, 5 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 unified diff | Download patch
« no previous file with comments | « src/type-info.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/base/utils/random-number-generator.h" 5 #include "src/base/utils/random-number-generator.h"
6 #include "src/ic/stub-cache.h" 6 #include "src/ic/stub-cache.h"
7 #include "src/isolate.h" 7 #include "src/isolate.h"
8 #include "test/cctest/compiler/code-assembler-tester.h" 8 #include "test/cctest/compiler/code-assembler-tester.h"
9 #include "test/cctest/compiler/function-tester.h" 9 #include "test/cctest/compiler/function-tester.h"
10 10
(...skipping 1085 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 m.Bind(&block3); 1096 m.Bind(&block3);
1097 var_object.Bind(m.IntPtrConstant(66)); 1097 var_object.Bind(m.IntPtrConstant(66));
1098 m.Goto(&block1); 1098 m.Goto(&block1);
1099 } 1099 }
1100 m.Bind(&block1); 1100 m.Bind(&block1);
1101 CHECK(!m.GenerateCode().is_null()); 1101 CHECK(!m.GenerateCode().is_null());
1102 } 1102 }
1103 1103
1104 namespace { 1104 namespace {
1105 1105
1106 void TestStubCacheOffsetCalculation(StubCache::Table table, 1106 void TestStubCacheOffsetCalculation(StubCache::Table table) {
1107 Code::Kind handler_kind) {
1108 Isolate* isolate(CcTest::InitIsolateOnce()); 1107 Isolate* isolate(CcTest::InitIsolateOnce());
1109 const int kNumParams = 2; 1108 const int kNumParams = 2;
1110 CodeStubAssemblerTester m(isolate, kNumParams); 1109 CodeStubAssemblerTester m(isolate, kNumParams);
1111 1110
1112 Code::Flags code_flags =
1113 Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(handler_kind));
1114 { 1111 {
1115 Node* name = m.Parameter(0); 1112 Node* name = m.Parameter(0);
1116 Node* map = m.Parameter(1); 1113 Node* map = m.Parameter(1);
1117 Node* primary_offset = m.StubCachePrimaryOffset(name, code_flags, map); 1114 Node* primary_offset = m.StubCachePrimaryOffset(name, map);
1118 Node* result; 1115 Node* result;
1119 if (table == StubCache::kPrimary) { 1116 if (table == StubCache::kPrimary) {
1120 result = primary_offset; 1117 result = primary_offset;
1121 } else { 1118 } else {
1122 CHECK_EQ(StubCache::kSecondary, table); 1119 CHECK_EQ(StubCache::kSecondary, table);
1123 result = m.StubCacheSecondaryOffset(name, code_flags, primary_offset); 1120 result = m.StubCacheSecondaryOffset(name, primary_offset);
1124 } 1121 }
1125 m.Return(m.SmiFromWord32(result)); 1122 m.Return(m.SmiFromWord32(result));
1126 } 1123 }
1127 1124
1128 Handle<Code> code = m.GenerateCode(); 1125 Handle<Code> code = m.GenerateCode();
1129 FunctionTester ft(code, kNumParams); 1126 FunctionTester ft(code, kNumParams);
1130 1127
1131 Factory* factory = isolate->factory(); 1128 Factory* factory = isolate->factory();
1132 Handle<Name> names[] = { 1129 Handle<Name> names[] = {
1133 factory->NewSymbol(), 1130 factory->NewSymbol(),
(...skipping 22 matching lines...) Expand all
1156 factory->sloppy_arguments_elements_map(), 1153 factory->sloppy_arguments_elements_map(),
1157 }; 1154 };
1158 1155
1159 for (int name_index = 0; name_index < arraysize(names); name_index++) { 1156 for (int name_index = 0; name_index < arraysize(names); name_index++) {
1160 Handle<Name> name = names[name_index]; 1157 Handle<Name> name = names[name_index];
1161 for (int map_index = 0; map_index < arraysize(maps); map_index++) { 1158 for (int map_index = 0; map_index < arraysize(maps); map_index++) {
1162 Handle<Map> map = maps[map_index]; 1159 Handle<Map> map = maps[map_index];
1163 1160
1164 int expected_result; 1161 int expected_result;
1165 { 1162 {
1166 int primary_offset = 1163 int primary_offset = StubCache::PrimaryOffsetForTesting(*name, *map);
1167 StubCache::PrimaryOffsetForTesting(*name, code_flags, *map);
1168 if (table == StubCache::kPrimary) { 1164 if (table == StubCache::kPrimary) {
1169 expected_result = primary_offset; 1165 expected_result = primary_offset;
1170 } else { 1166 } else {
1171 expected_result = StubCache::SecondaryOffsetForTesting( 1167 expected_result =
1172 *name, code_flags, primary_offset); 1168 StubCache::SecondaryOffsetForTesting(*name, primary_offset);
1173 } 1169 }
1174 } 1170 }
1175 Handle<Object> result = ft.Call(name, map).ToHandleChecked(); 1171 Handle<Object> result = ft.Call(name, map).ToHandleChecked();
1176 1172
1177 Smi* expected = Smi::FromInt(expected_result & Smi::kMaxValue); 1173 Smi* expected = Smi::FromInt(expected_result & Smi::kMaxValue);
1178 CHECK_EQ(expected, Smi::cast(*result)); 1174 CHECK_EQ(expected, Smi::cast(*result));
1179 } 1175 }
1180 } 1176 }
1181 } 1177 }
1182 1178
1183 } // namespace 1179 } // namespace
1184 1180
1185 TEST(StubCachePrimaryOffsetLoadIC) { 1181 TEST(StubCachePrimaryOffset) {
1186 TestStubCacheOffsetCalculation(StubCache::kPrimary, Code::LOAD_IC); 1182 TestStubCacheOffsetCalculation(StubCache::kPrimary);
1187 } 1183 }
1188 1184
1189 TEST(StubCachePrimaryOffsetStoreIC) { 1185 TEST(StubCacheSecondaryOffset) {
1190 TestStubCacheOffsetCalculation(StubCache::kPrimary, Code::STORE_IC); 1186 TestStubCacheOffsetCalculation(StubCache::kSecondary);
1191 }
1192
1193 TEST(StubCacheSecondaryOffsetLoadIC) {
1194 TestStubCacheOffsetCalculation(StubCache::kSecondary, Code::LOAD_IC);
1195 }
1196
1197 TEST(StubCacheSecondaryOffsetStoreIC) {
1198 TestStubCacheOffsetCalculation(StubCache::kSecondary, Code::STORE_IC);
1199 } 1187 }
1200 1188
1201 namespace { 1189 namespace {
1202 1190
1203 Handle<Code> CreateCodeWithFlags(Code::Flags flags) { 1191 Handle<Code> CreateCodeWithFlags(Code::Flags flags) {
1204 Isolate* isolate(CcTest::InitIsolateOnce()); 1192 Isolate* isolate(CcTest::InitIsolateOnce());
1205 CodeStubAssemblerTester m(isolate, flags); 1193 CodeStubAssemblerTester m(isolate, flags);
1206 m.Return(m.UndefinedConstant()); 1194 m.Return(m.UndefinedConstant());
1207 return m.GenerateCodeCloseAndEscape(); 1195 return m.GenerateCodeCloseAndEscape();
1208 } 1196 }
1209 1197
1210 } // namespace 1198 } // namespace
1211 1199
1212 TEST(TryProbeStubCache) { 1200 TEST(TryProbeStubCache) {
1213 typedef CodeStubAssembler::Label Label; 1201 typedef CodeStubAssembler::Label Label;
1214 typedef CodeStubAssembler::Variable Variable; 1202 typedef CodeStubAssembler::Variable Variable;
1215 Isolate* isolate(CcTest::InitIsolateOnce()); 1203 Isolate* isolate(CcTest::InitIsolateOnce());
1216 const int kNumParams = 3; 1204 const int kNumParams = 3;
1217 CodeStubAssemblerTester m(isolate, kNumParams); 1205 CodeStubAssemblerTester m(isolate, kNumParams);
1218 1206
1219 Code::Kind ic_kind = Code::LOAD_IC; 1207 Code::Kind ic_kind = Code::LOAD_IC;
1220 Code::Flags flags_to_query =
1221 Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(ic_kind));
1222
1223 StubCache stub_cache(isolate, ic_kind); 1208 StubCache stub_cache(isolate, ic_kind);
1224 stub_cache.Clear(); 1209 stub_cache.Clear();
1225 1210
1226 { 1211 {
1227 Node* receiver = m.Parameter(0); 1212 Node* receiver = m.Parameter(0);
1228 Node* name = m.Parameter(1); 1213 Node* name = m.Parameter(1);
1229 Node* expected_handler = m.Parameter(2); 1214 Node* expected_handler = m.Parameter(2);
1230 1215
1231 Label passed(&m), failed(&m); 1216 Label passed(&m), failed(&m);
1232 1217
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 } 1277 }
1293 1278
1294 // Generate some number of receiver maps and receivers. 1279 // Generate some number of receiver maps and receivers.
1295 for (int i = 0; i < StubCache::kSecondaryTableSize / 2; i++) { 1280 for (int i = 0; i < StubCache::kSecondaryTableSize / 2; i++) {
1296 Handle<Map> map = Map::Create(isolate, 0); 1281 Handle<Map> map = Map::Create(isolate, 0);
1297 receivers.push_back(factory->NewJSObjectFromMap(map)); 1282 receivers.push_back(factory->NewJSObjectFromMap(map));
1298 } 1283 }
1299 1284
1300 // Generate some number of handlers. 1285 // Generate some number of handlers.
1301 for (int i = 0; i < 30; i++) { 1286 for (int i = 0; i < 30; i++) {
1302 Code::Kind code_kind;
1303 switch (rand_gen.NextInt(4)) {
1304 case 0:
1305 code_kind = Code::LOAD_IC;
1306 break;
1307 case 1:
1308 code_kind = Code::KEYED_LOAD_IC;
1309 break;
1310 case 2:
1311 code_kind = Code::STORE_IC;
1312 break;
1313 case 3:
1314 code_kind = Code::KEYED_STORE_IC;
1315 break;
1316 default:
1317 UNREACHABLE();
1318 }
1319 Code::Flags flags = 1287 Code::Flags flags =
1320 Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(code_kind)); 1288 Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(ic_kind));
1321 handlers.push_back(CreateCodeWithFlags(flags)); 1289 handlers.push_back(CreateCodeWithFlags(flags));
1322 } 1290 }
1323 1291
1324 // Ensure that GC does happen because from now on we are going to fill our 1292 // Ensure that GC does happen because from now on we are going to fill our
1325 // own stub cache instance with raw values. 1293 // own stub cache instance with raw values.
1326 DisallowHeapAllocation no_gc; 1294 DisallowHeapAllocation no_gc;
1327 1295
1328 // Populate {stub_cache}. 1296 // Populate {stub_cache}.
1329 const int N = StubCache::kPrimaryTableSize + StubCache::kSecondaryTableSize; 1297 const int N = StubCache::kPrimaryTableSize + StubCache::kSecondaryTableSize;
1330 for (int i = 0; i < N; i++) { 1298 for (int i = 0; i < N; i++) {
1331 int index = rand_gen.NextInt(); 1299 int index = rand_gen.NextInt();
1332 Handle<Name> name = names[index % names.size()]; 1300 Handle<Name> name = names[index % names.size()];
1333 Handle<JSObject> receiver = receivers[index % receivers.size()]; 1301 Handle<JSObject> receiver = receivers[index % receivers.size()];
1334 Handle<Code> handler = handlers[index % handlers.size()]; 1302 Handle<Code> handler = handlers[index % handlers.size()];
1335 stub_cache.Set(*name, receiver->map(), *handler); 1303 stub_cache.Set(*name, receiver->map(), *handler);
1336 } 1304 }
1337 1305
1338 // Perform some queries. 1306 // Perform some queries.
1339 bool queried_existing = false; 1307 bool queried_existing = false;
1340 bool queried_non_existing = false; 1308 bool queried_non_existing = false;
1341 for (int i = 0; i < N; i++) { 1309 for (int i = 0; i < N; i++) {
1342 int index = rand_gen.NextInt(); 1310 int index = rand_gen.NextInt();
1343 Handle<Name> name = names[index % names.size()]; 1311 Handle<Name> name = names[index % names.size()];
1344 Handle<JSObject> receiver = receivers[index % receivers.size()]; 1312 Handle<JSObject> receiver = receivers[index % receivers.size()];
1345 Code* handler = stub_cache.Get(*name, receiver->map(), flags_to_query); 1313 Code* handler = stub_cache.Get(*name, receiver->map());
1346 if (handler == nullptr) { 1314 if (handler == nullptr) {
1347 queried_non_existing = true; 1315 queried_non_existing = true;
1348 } else { 1316 } else {
1349 queried_existing = true; 1317 queried_existing = true;
1350 } 1318 }
1351 1319
1352 Handle<Code> expected_handler(handler, isolate); 1320 Handle<Code> expected_handler(handler, isolate);
1353 ft.CheckTrue(receiver, name, expected_handler); 1321 ft.CheckTrue(receiver, name, expected_handler);
1354 } 1322 }
1355 1323
1356 for (int i = 0; i < N; i++) { 1324 for (int i = 0; i < N; i++) {
1357 int index1 = rand_gen.NextInt(); 1325 int index1 = rand_gen.NextInt();
1358 int index2 = rand_gen.NextInt(); 1326 int index2 = rand_gen.NextInt();
1359 Handle<Name> name = names[index1 % names.size()]; 1327 Handle<Name> name = names[index1 % names.size()];
1360 Handle<JSObject> receiver = receivers[index2 % receivers.size()]; 1328 Handle<JSObject> receiver = receivers[index2 % receivers.size()];
1361 Code* handler = stub_cache.Get(*name, receiver->map(), flags_to_query); 1329 Code* handler = stub_cache.Get(*name, receiver->map());
1362 if (handler == nullptr) { 1330 if (handler == nullptr) {
1363 queried_non_existing = true; 1331 queried_non_existing = true;
1364 } else { 1332 } else {
1365 queried_existing = true; 1333 queried_existing = true;
1366 } 1334 }
1367 1335
1368 Handle<Code> expected_handler(handler, isolate); 1336 Handle<Code> expected_handler(handler, isolate);
1369 ft.CheckTrue(receiver, name, expected_handler); 1337 ft.CheckTrue(receiver, name, expected_handler);
1370 } 1338 }
1371 // Ensure we performed both kind of queries. 1339 // Ensure we performed both kind of queries.
1372 CHECK(queried_existing && queried_non_existing); 1340 CHECK(queried_existing && queried_non_existing);
1373 } 1341 }
1374 1342
1375 } // namespace internal 1343 } // namespace internal
1376 } // namespace v8 1344 } // namespace v8
OLDNEW
« no previous file with comments | « src/type-info.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698