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

Side by Side Diff: src/elements.cc

Issue 1847183004: [elements] Avoid using IsKey in loops (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: addressing comments Created 4 years, 8 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/builtins.cc ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/elements.h" 5 #include "src/elements.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/conversions.h" 8 #include "src/conversions.h"
9 #include "src/factory.h" 9 #include "src/factory.h"
10 #include "src/isolate-inl.h" 10 #include "src/isolate-inl.h"
(...skipping 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1185 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, entry); 1185 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, entry);
1186 USE(result); 1186 USE(result);
1187 DCHECK(result->IsTrue()); 1187 DCHECK(result->IsTrue());
1188 Handle<FixedArray> new_elements = 1188 Handle<FixedArray> new_elements =
1189 SeededNumberDictionary::Shrink(dict, index); 1189 SeededNumberDictionary::Shrink(dict, index);
1190 obj->set_elements(*new_elements); 1190 obj->set_elements(*new_elements);
1191 } 1191 }
1192 1192
1193 static bool HasAccessorsImpl(JSObject* holder, 1193 static bool HasAccessorsImpl(JSObject* holder,
1194 FixedArrayBase* backing_store) { 1194 FixedArrayBase* backing_store) {
1195 DisallowHeapAllocation no_gc;
1195 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); 1196 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store);
1196 if (!dict->requires_slow_elements()) return false; 1197 if (!dict->requires_slow_elements()) return false;
1197 int capacity = dict->Capacity(); 1198 int capacity = dict->Capacity();
1199 Heap* heap = holder->GetHeap();
1200 Object* undefined = heap->undefined_value();
1201 Object* the_hole = heap->the_hole_value();
1198 for (int i = 0; i < capacity; i++) { 1202 for (int i = 0; i < capacity; i++) {
1199 Object* key = dict->KeyAt(i); 1203 Object* key = dict->KeyAt(i);
1200 if (!dict->IsKey(key)) continue; 1204 if (key == the_hole || key == undefined) continue;
1201 DCHECK(!dict->IsDeleted(i)); 1205 DCHECK(!dict->IsDeleted(i));
1202 PropertyDetails details = dict->DetailsAt(i); 1206 PropertyDetails details = dict->DetailsAt(i);
1203 if (details.type() == ACCESSOR_CONSTANT) return true; 1207 if (details.type() == ACCESSOR_CONSTANT) return true;
1204 } 1208 }
1205 return false; 1209 return false;
1206 } 1210 }
1207 1211
1208 static Object* GetRaw(FixedArrayBase* store, uint32_t entry) { 1212 static Object* GetRaw(FixedArrayBase* store, uint32_t entry) {
1209 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); 1213 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
1210 return backing_store->ValueAt(entry); 1214 return backing_store->ValueAt(entry);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 1293
1290 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 1294 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
1291 return GetDetailsImpl(holder->elements(), entry); 1295 return GetDetailsImpl(holder->elements(), entry);
1292 } 1296 }
1293 1297
1294 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1298 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1295 uint32_t entry) { 1299 uint32_t entry) {
1296 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); 1300 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry);
1297 } 1301 }
1298 1302
1299 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary, 1303 static uint32_t FilterKey(Handle<SeededNumberDictionary> dictionary,
1300 int entry, PropertyFilter filter) { 1304 int entry, Object* raw_key, PropertyFilter filter) {
1301 DisallowHeapAllocation no_gc;
1302 Object* raw_key = dictionary->KeyAt(entry);
1303 if (!dictionary->IsKey(raw_key)) return kMaxUInt32;
1304 DCHECK(!dictionary->IsDeleted(entry)); 1305 DCHECK(!dictionary->IsDeleted(entry));
1305 DCHECK(raw_key->IsNumber()); 1306 DCHECK(raw_key->IsNumber());
1306 DCHECK_LE(raw_key->Number(), kMaxUInt32); 1307 DCHECK_LE(raw_key->Number(), kMaxUInt32);
1307 PropertyDetails details = dictionary->DetailsAt(entry); 1308 PropertyDetails details = dictionary->DetailsAt(entry);
1308 PropertyAttributes attr = details.attributes(); 1309 PropertyAttributes attr = details.attributes();
1309 if ((attr & filter) != 0) return kMaxUInt32; 1310 if ((attr & filter) != 0) return kMaxUInt32;
1310 return static_cast<uint32_t>(raw_key->Number()); 1311 return static_cast<uint32_t>(raw_key->Number());
1311 } 1312 }
1312 1313
1314 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary,
1315 int entry, PropertyFilter filter) {
1316 DisallowHeapAllocation no_gc;
1317 Object* raw_key = dictionary->KeyAt(entry);
1318 if (!dictionary->IsKey(raw_key)) return kMaxUInt32;
1319 return FilterKey(dictionary, entry, raw_key, filter);
1320 }
1321
1322 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary,
1323 int entry, PropertyFilter filter,
1324 Object* undefined, Object* the_hole) {
1325 DisallowHeapAllocation no_gc;
1326 Object* raw_key = dictionary->KeyAt(entry);
1327 // Replace the IsKey check with a direct comparison which is much faster.
1328 if (raw_key == undefined || raw_key == the_hole) {
1329 return kMaxUInt32;
1330 }
1331 return FilterKey(dictionary, entry, raw_key, filter);
1332 }
1333
1313 static void CollectElementIndicesImpl(Handle<JSObject> object, 1334 static void CollectElementIndicesImpl(Handle<JSObject> object,
1314 Handle<FixedArrayBase> backing_store, 1335 Handle<FixedArrayBase> backing_store,
1315 KeyAccumulator* keys, uint32_t range, 1336 KeyAccumulator* keys, uint32_t range,
1316 PropertyFilter filter, 1337 PropertyFilter filter,
1317 uint32_t offset) { 1338 uint32_t offset) {
1318 if (filter & SKIP_STRINGS) return; 1339 if (filter & SKIP_STRINGS) return;
1340 Isolate* isolate = keys->isolate();
1341 Handle<Object> undefined = isolate->factory()->undefined_value();
1342 Handle<Object> the_hole = isolate->factory()->the_hole_value();
1319 Handle<SeededNumberDictionary> dictionary = 1343 Handle<SeededNumberDictionary> dictionary =
1320 Handle<SeededNumberDictionary>::cast(backing_store); 1344 Handle<SeededNumberDictionary>::cast(backing_store);
1321 int capacity = dictionary->Capacity(); 1345 int capacity = dictionary->Capacity();
1322 for (int i = 0; i < capacity; i++) { 1346 for (int i = 0; i < capacity; i++) {
1323 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); 1347 uint32_t key =
1348 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole);
1324 if (key == kMaxUInt32) continue; 1349 if (key == kMaxUInt32) continue;
1325 keys->AddKey(key); 1350 keys->AddKey(key);
1326 } 1351 }
1327 1352
1328 keys->SortCurrentElementsList(); 1353 keys->SortCurrentElementsList();
1329 } 1354 }
1330 1355
1331 static Handle<FixedArray> DirectCollectElementIndicesImpl( 1356 static Handle<FixedArray> DirectCollectElementIndicesImpl(
1332 Isolate* isolate, Handle<JSObject> object, 1357 Isolate* isolate, Handle<JSObject> object,
1333 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, 1358 Handle<FixedArrayBase> backing_store, GetKeysConversion convert,
1334 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, 1359 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices,
1335 uint32_t insertion_index = 0) { 1360 uint32_t insertion_index = 0) {
1336 if (filter & SKIP_STRINGS) return list; 1361 if (filter & SKIP_STRINGS) return list;
1337 if (filter & ONLY_ALL_CAN_READ) return list; 1362 if (filter & ONLY_ALL_CAN_READ) return list;
1363
1364 Handle<Object> undefined = isolate->factory()->undefined_value();
1365 Handle<Object> the_hole = isolate->factory()->the_hole_value();
1338 Handle<SeededNumberDictionary> dictionary = 1366 Handle<SeededNumberDictionary> dictionary =
1339 Handle<SeededNumberDictionary>::cast(backing_store); 1367 Handle<SeededNumberDictionary>::cast(backing_store);
1340 uint32_t capacity = dictionary->Capacity(); 1368 uint32_t capacity = dictionary->Capacity();
1341 for (uint32_t i = 0; i < capacity; i++) { 1369 for (uint32_t i = 0; i < capacity; i++) {
1342 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); 1370 uint32_t key =
1371 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole);
1343 if (key == kMaxUInt32) continue; 1372 if (key == kMaxUInt32) continue;
1344 Handle<Object> index = isolate->factory()->NewNumberFromUint(key); 1373 Handle<Object> index = isolate->factory()->NewNumberFromUint(key);
1345 list->set(insertion_index, *index); 1374 list->set(insertion_index, *index);
1346 insertion_index++; 1375 insertion_index++;
1347 } 1376 }
1348 *nof_indices = insertion_index; 1377 *nof_indices = insertion_index;
1349 return list; 1378 return list;
1350 } 1379 }
1351 1380
1352 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 1381 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
1353 KeyAccumulator* accumulator, 1382 KeyAccumulator* accumulator,
1354 AddKeyConversion convert) { 1383 AddKeyConversion convert) {
1384 Isolate* isolate = accumulator->isolate();
1385 Handle<Object> undefined = isolate->factory()->undefined_value();
1386 Handle<Object> the_hole = isolate->factory()->the_hole_value();
1355 SeededNumberDictionary* dictionary = 1387 SeededNumberDictionary* dictionary =
1356 SeededNumberDictionary::cast(receiver->elements()); 1388 SeededNumberDictionary::cast(receiver->elements());
1357 int capacity = dictionary->Capacity(); 1389 int capacity = dictionary->Capacity();
1358 for (int i = 0; i < capacity; i++) { 1390 for (int i = 0; i < capacity; i++) {
1359 Object* k = dictionary->KeyAt(i); 1391 Object* k = dictionary->KeyAt(i);
1360 if (!dictionary->IsKey(k)) continue; 1392 if (k == *undefined) continue;
1393 if (k == *the_hole) continue;
1361 if (dictionary->IsDeleted(i)) continue; 1394 if (dictionary->IsDeleted(i)) continue;
1362 Object* value = dictionary->ValueAt(i); 1395 Object* value = dictionary->ValueAt(i);
1363 DCHECK(!value->IsTheHole()); 1396 DCHECK(!value->IsTheHole());
1364 DCHECK(!value->IsAccessorPair()); 1397 DCHECK(!value->IsAccessorPair());
1365 DCHECK(!value->IsAccessorInfo()); 1398 DCHECK(!value->IsAccessorInfo());
1366 accumulator->AddKey(value, convert); 1399 accumulator->AddKey(value, convert);
1367 } 1400 }
1368 } 1401 }
1369 }; 1402 };
1370 1403
(...skipping 1633 matching lines...) Expand 10 before | Expand all | Expand 10 after
3004 insertion_index += len; 3037 insertion_index += len;
3005 } 3038 }
3006 3039
3007 DCHECK_EQ(insertion_index, result_len); 3040 DCHECK_EQ(insertion_index, result_len);
3008 return result_array; 3041 return result_array;
3009 } 3042 }
3010 3043
3011 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 3044 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
3012 } // namespace internal 3045 } // namespace internal
3013 } // namespace v8 3046 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698