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 |