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

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: fix 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
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 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); 1195 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store);
1196 if (!dict->requires_slow_elements()) return false; 1196 if (!dict->requires_slow_elements()) return false;
1197 int capacity = dict->Capacity(); 1197 int capacity = dict->Capacity();
1198 Heap* heap = holder->GetHeap();
Yang 2016/04/01 13:29:53 Can we have a disallow allocation scope here?
1199 Object* undefined = heap->undefined_value();
1200 Object* the_hole = heap->the_hole_value();
1198 for (int i = 0; i < capacity; i++) { 1201 for (int i = 0; i < capacity; i++) {
1199 Object* key = dict->KeyAt(i); 1202 Object* key = dict->KeyAt(i);
1200 if (!dict->IsKey(key)) continue; 1203 if (key == the_hole || key == undefined) continue;
1201 DCHECK(!dict->IsDeleted(i)); 1204 DCHECK(!dict->IsDeleted(i));
1202 PropertyDetails details = dict->DetailsAt(i); 1205 PropertyDetails details = dict->DetailsAt(i);
1203 if (details.type() == ACCESSOR_CONSTANT) return true; 1206 if (details.type() == ACCESSOR_CONSTANT) return true;
1204 } 1207 }
1205 return false; 1208 return false;
1206 } 1209 }
1207 1210
1208 static Object* GetRaw(FixedArrayBase* store, uint32_t entry) { 1211 static Object* GetRaw(FixedArrayBase* store, uint32_t entry) {
1209 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); 1212 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
1210 return backing_store->ValueAt(entry); 1213 return backing_store->ValueAt(entry);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 1292
1290 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 1293 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
1291 return GetDetailsImpl(holder->elements(), entry); 1294 return GetDetailsImpl(holder->elements(), entry);
1292 } 1295 }
1293 1296
1294 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1297 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1295 uint32_t entry) { 1298 uint32_t entry) {
1296 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); 1299 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry);
1297 } 1300 }
1298 1301
1299 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary, 1302 static uint32_t FilterKey(Handle<SeededNumberDictionary> dictionary,
1300 int entry, PropertyFilter filter) { 1303 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)); 1304 DCHECK(!dictionary->IsDeleted(entry));
1305 DCHECK(raw_key->IsNumber()); 1305 DCHECK(raw_key->IsNumber());
1306 DCHECK_LE(raw_key->Number(), kMaxUInt32); 1306 DCHECK_LE(raw_key->Number(), kMaxUInt32);
1307 PropertyDetails details = dictionary->DetailsAt(entry); 1307 PropertyDetails details = dictionary->DetailsAt(entry);
1308 PropertyAttributes attr = details.attributes(); 1308 PropertyAttributes attr = details.attributes();
1309 if ((attr & filter) != 0) return kMaxUInt32; 1309 if ((attr & filter) != 0) return kMaxUInt32;
1310 return static_cast<uint32_t>(raw_key->Number()); 1310 return static_cast<uint32_t>(raw_key->Number());
1311 } 1311 }
1312 1312
1313 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary,
1314 int entry, PropertyFilter filter) {
1315 DisallowHeapAllocation no_gc;
1316 Object* raw_key = dictionary->KeyAt(entry);
1317 if (!dictionary->IsKey(raw_key)) return kMaxUInt32;
1318 return FilterKey(dictionary, entry, raw_key, filter);
1319 }
1320
1321 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary,
1322 int entry, PropertyFilter filter,
1323 Object* undefined, Object* the_hole) {
1324 DisallowHeapAllocation no_gc;
1325 Object* raw_key = dictionary->KeyAt(entry);
1326 // Replace the IsKey check with a direct comparison which is much faster.
1327 if (raw_key == undefined || raw_key == the_hole) {
1328 return kMaxUInt32;
1329 }
1330 return FilterKey(dictionary, entry, raw_key, filter);
1331 }
1332
1313 static void CollectElementIndicesImpl(Handle<JSObject> object, 1333 static void CollectElementIndicesImpl(Handle<JSObject> object,
1314 Handle<FixedArrayBase> backing_store, 1334 Handle<FixedArrayBase> backing_store,
1315 KeyAccumulator* keys, uint32_t range, 1335 KeyAccumulator* keys, uint32_t range,
1316 PropertyFilter filter, 1336 PropertyFilter filter,
1317 uint32_t offset) { 1337 uint32_t offset) {
1318 if (filter & SKIP_STRINGS) return; 1338 if (filter & SKIP_STRINGS) return;
1339 Isolate* isolate = keys->isolate();
1340 Handle<Object> undefined = isolate->factory()->undefined_value();
1341 Handle<Object> the_hole = isolate->factory()->the_hole_value();
1319 Handle<SeededNumberDictionary> dictionary = 1342 Handle<SeededNumberDictionary> dictionary =
1320 Handle<SeededNumberDictionary>::cast(backing_store); 1343 Handle<SeededNumberDictionary>::cast(backing_store);
1321 int capacity = dictionary->Capacity(); 1344 int capacity = dictionary->Capacity();
1322 for (int i = 0; i < capacity; i++) { 1345 for (int i = 0; i < capacity; i++) {
1323 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); 1346 uint32_t key =
1347 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole);
1324 if (key == kMaxUInt32) continue; 1348 if (key == kMaxUInt32) continue;
1325 keys->AddKey(key); 1349 keys->AddKey(key);
1326 } 1350 }
1327 1351
1328 keys->SortCurrentElementsList(); 1352 keys->SortCurrentElementsList();
1329 } 1353 }
1330 1354
1331 static Handle<FixedArray> DirectCollectElementIndicesImpl( 1355 static Handle<FixedArray> DirectCollectElementIndicesImpl(
1332 Isolate* isolate, Handle<JSObject> object, 1356 Isolate* isolate, Handle<JSObject> object,
1333 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, 1357 Handle<FixedArrayBase> backing_store, GetKeysConversion convert,
1334 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, 1358 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices,
1335 uint32_t insertion_index = 0) { 1359 uint32_t insertion_index = 0) {
1336 if (filter & SKIP_STRINGS) return list; 1360 if (filter & SKIP_STRINGS) return list;
1337 if (filter & ONLY_ALL_CAN_READ) return list; 1361 if (filter & ONLY_ALL_CAN_READ) return list;
1362
1363 Handle<Object> undefined = isolate->factory()->undefined_value();
1364 Handle<Object> the_hole = isolate->factory()->the_hole_value();
1338 Handle<SeededNumberDictionary> dictionary = 1365 Handle<SeededNumberDictionary> dictionary =
1339 Handle<SeededNumberDictionary>::cast(backing_store); 1366 Handle<SeededNumberDictionary>::cast(backing_store);
1340 uint32_t capacity = dictionary->Capacity(); 1367 uint32_t capacity = dictionary->Capacity();
1341 for (uint32_t i = 0; i < capacity; i++) { 1368 for (uint32_t i = 0; i < capacity; i++) {
1342 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); 1369 uint32_t key =
1370 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole);
1343 if (key == kMaxUInt32) continue; 1371 if (key == kMaxUInt32) continue;
1344 Handle<Object> index = isolate->factory()->NewNumberFromUint(key); 1372 Handle<Object> index = isolate->factory()->NewNumberFromUint(key);
1345 list->set(insertion_index, *index); 1373 list->set(insertion_index, *index);
1346 insertion_index++; 1374 insertion_index++;
1347 } 1375 }
1348 *nof_indices = insertion_index; 1376 *nof_indices = insertion_index;
1349 return list; 1377 return list;
1350 } 1378 }
1351 1379
1352 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 1380 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
1353 KeyAccumulator* accumulator, 1381 KeyAccumulator* accumulator,
1354 AddKeyConversion convert) { 1382 AddKeyConversion convert) {
1383 Isolate* isolate = accumulator->isolate();
1384 Handle<Object> undefined = isolate->factory()->undefined_value();
1385 Handle<Object> the_hole = isolate->factory()->the_hole_value();
1355 SeededNumberDictionary* dictionary = 1386 SeededNumberDictionary* dictionary =
1356 SeededNumberDictionary::cast(receiver->elements()); 1387 SeededNumberDictionary::cast(receiver->elements());
1357 int capacity = dictionary->Capacity(); 1388 int capacity = dictionary->Capacity();
1358 for (int i = 0; i < capacity; i++) { 1389 for (int i = 0; i < capacity; i++) {
1359 Object* k = dictionary->KeyAt(i); 1390 Object* k = dictionary->KeyAt(i);
1360 if (!dictionary->IsKey(k)) continue; 1391 if (k == *undefined) continue;
1392 if (k == *the_hole) continue;
1361 if (dictionary->IsDeleted(i)) continue; 1393 if (dictionary->IsDeleted(i)) continue;
1362 Object* value = dictionary->ValueAt(i); 1394 Object* value = dictionary->ValueAt(i);
1363 DCHECK(!value->IsTheHole()); 1395 DCHECK(!value->IsTheHole());
1364 DCHECK(!value->IsAccessorPair()); 1396 DCHECK(!value->IsAccessorPair());
1365 DCHECK(!value->IsAccessorInfo()); 1397 DCHECK(!value->IsAccessorInfo());
1366 accumulator->AddKey(value, convert); 1398 accumulator->AddKey(value, convert);
1367 } 1399 }
1368 } 1400 }
1369 }; 1401 };
1370 1402
(...skipping 1633 matching lines...) Expand 10 before | Expand all | Expand 10 after
3004 insertion_index += len; 3036 insertion_index += len;
3005 } 3037 }
3006 3038
3007 DCHECK_EQ(insertion_index, result_len); 3039 DCHECK_EQ(insertion_index, result_len);
3008 return result_array; 3040 return result_array;
3009 } 3041 }
3010 3042
3011 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 3043 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
3012 } // namespace internal 3044 } // namespace internal
3013 } // namespace v8 3045 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698