| 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 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |