Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |