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 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 SeededNumberDictionary::Shrink(dict, index); | 1179 SeededNumberDictionary::Shrink(dict, index); |
1180 obj->set_elements(*new_elements); | 1180 obj->set_elements(*new_elements); |
1181 } | 1181 } |
1182 | 1182 |
1183 static bool HasAccessorsImpl(JSObject* holder, | 1183 static bool HasAccessorsImpl(JSObject* holder, |
1184 FixedArrayBase* backing_store) { | 1184 FixedArrayBase* backing_store) { |
1185 DisallowHeapAllocation no_gc; | 1185 DisallowHeapAllocation no_gc; |
1186 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); | 1186 SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); |
1187 if (!dict->requires_slow_elements()) return false; | 1187 if (!dict->requires_slow_elements()) return false; |
1188 int capacity = dict->Capacity(); | 1188 int capacity = dict->Capacity(); |
1189 Heap* heap = holder->GetHeap(); | 1189 Isolate* isolate = dict->GetIsolate(); |
1190 Object* undefined = heap->undefined_value(); | |
1191 Object* the_hole = heap->the_hole_value(); | |
1192 for (int i = 0; i < capacity; i++) { | 1190 for (int i = 0; i < capacity; i++) { |
1193 Object* key = dict->KeyAt(i); | 1191 Object* key = dict->KeyAt(i); |
1194 if (key == the_hole || key == undefined) continue; | 1192 if (!dict->IsKey(isolate, key)) continue; |
1195 DCHECK(!dict->IsDeleted(i)); | 1193 DCHECK(!dict->IsDeleted(i)); |
1196 PropertyDetails details = dict->DetailsAt(i); | 1194 PropertyDetails details = dict->DetailsAt(i); |
1197 if (details.type() == ACCESSOR_CONSTANT) return true; | 1195 if (details.type() == ACCESSOR_CONSTANT) return true; |
1198 } | 1196 } |
1199 return false; | 1197 return false; |
1200 } | 1198 } |
1201 | 1199 |
1202 static Object* GetRaw(FixedArrayBase* store, uint32_t entry) { | 1200 static Object* GetRaw(FixedArrayBase* store, uint32_t entry) { |
1203 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); | 1201 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); |
1204 return backing_store->ValueAt(entry); | 1202 return backing_store->ValueAt(entry); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 int entry, Object* raw_key, PropertyFilter filter) { | 1292 int entry, Object* raw_key, PropertyFilter filter) { |
1295 DCHECK(!dictionary->IsDeleted(entry)); | 1293 DCHECK(!dictionary->IsDeleted(entry)); |
1296 DCHECK(raw_key->IsNumber()); | 1294 DCHECK(raw_key->IsNumber()); |
1297 DCHECK_LE(raw_key->Number(), kMaxUInt32); | 1295 DCHECK_LE(raw_key->Number(), kMaxUInt32); |
1298 PropertyDetails details = dictionary->DetailsAt(entry); | 1296 PropertyDetails details = dictionary->DetailsAt(entry); |
1299 PropertyAttributes attr = details.attributes(); | 1297 PropertyAttributes attr = details.attributes(); |
1300 if ((attr & filter) != 0) return kMaxUInt32; | 1298 if ((attr & filter) != 0) return kMaxUInt32; |
1301 return static_cast<uint32_t>(raw_key->Number()); | 1299 return static_cast<uint32_t>(raw_key->Number()); |
1302 } | 1300 } |
1303 | 1301 |
1304 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary, | 1302 static uint32_t GetKeyForEntryImpl(Isolate* isolate, |
| 1303 Handle<SeededNumberDictionary> dictionary, |
1305 int entry, PropertyFilter filter) { | 1304 int entry, PropertyFilter filter) { |
1306 DisallowHeapAllocation no_gc; | 1305 DisallowHeapAllocation no_gc; |
1307 Object* raw_key = dictionary->KeyAt(entry); | 1306 Object* raw_key = dictionary->KeyAt(entry); |
1308 if (!dictionary->IsKey(raw_key)) return kMaxUInt32; | 1307 if (!dictionary->IsKey(isolate, raw_key)) return kMaxUInt32; |
1309 return FilterKey(dictionary, entry, raw_key, filter); | 1308 return FilterKey(dictionary, entry, raw_key, filter); |
1310 } | 1309 } |
1311 | 1310 |
1312 static uint32_t GetKeyForEntryImpl(Handle<SeededNumberDictionary> dictionary, | |
1313 int entry, PropertyFilter filter, | |
1314 Object* undefined, Object* the_hole) { | |
1315 DisallowHeapAllocation no_gc; | |
1316 Object* raw_key = dictionary->KeyAt(entry); | |
1317 // Replace the IsKey check with a direct comparison which is much faster. | |
1318 if (raw_key == undefined || raw_key == the_hole) { | |
1319 return kMaxUInt32; | |
1320 } | |
1321 return FilterKey(dictionary, entry, raw_key, filter); | |
1322 } | |
1323 | |
1324 static void CollectElementIndicesImpl(Handle<JSObject> object, | 1311 static void CollectElementIndicesImpl(Handle<JSObject> object, |
1325 Handle<FixedArrayBase> backing_store, | 1312 Handle<FixedArrayBase> backing_store, |
1326 KeyAccumulator* keys) { | 1313 KeyAccumulator* keys) { |
1327 if (keys->filter() & SKIP_STRINGS) return; | 1314 if (keys->filter() & SKIP_STRINGS) return; |
1328 Factory* factory = keys->isolate()->factory(); | 1315 Isolate* isolate = keys->isolate(); |
1329 Handle<Object> undefined = factory->undefined_value(); | |
1330 Handle<Object> the_hole = factory->the_hole_value(); | |
1331 Handle<SeededNumberDictionary> dictionary = | 1316 Handle<SeededNumberDictionary> dictionary = |
1332 Handle<SeededNumberDictionary>::cast(backing_store); | 1317 Handle<SeededNumberDictionary>::cast(backing_store); |
1333 int capacity = dictionary->Capacity(); | 1318 int capacity = dictionary->Capacity(); |
1334 Handle<FixedArray> elements = | 1319 Handle<FixedArray> elements = isolate->factory()->NewFixedArray( |
1335 factory->NewFixedArray(GetMaxNumberOfEntries(*object, *backing_store)); | 1320 GetMaxNumberOfEntries(*object, *backing_store)); |
1336 int insertion_index = 0; | 1321 int insertion_index = 0; |
1337 PropertyFilter filter = keys->filter(); | 1322 PropertyFilter filter = keys->filter(); |
1338 for (int i = 0; i < capacity; i++) { | 1323 for (int i = 0; i < capacity; i++) { |
1339 uint32_t key = | 1324 uint32_t key = GetKeyForEntryImpl(isolate, dictionary, i, filter); |
1340 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole); | |
1341 if (key == kMaxUInt32) continue; | 1325 if (key == kMaxUInt32) continue; |
1342 Handle<Object> key_handle = factory->NewNumberFromUint(key); | 1326 Handle<Object> key_handle = isolate->factory()->NewNumberFromUint(key); |
1343 elements->set(insertion_index, *key_handle); | 1327 elements->set(insertion_index, *key_handle); |
1344 insertion_index++; | 1328 insertion_index++; |
1345 } | 1329 } |
1346 SortIndices(elements, insertion_index); | 1330 SortIndices(elements, insertion_index); |
1347 for (int i = 0; i < insertion_index; i++) { | 1331 for (int i = 0; i < insertion_index; i++) { |
1348 keys->AddKey(elements->get(i)); | 1332 keys->AddKey(elements->get(i)); |
1349 } | 1333 } |
1350 } | 1334 } |
1351 | 1335 |
1352 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 1336 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
1353 Isolate* isolate, Handle<JSObject> object, | 1337 Isolate* isolate, Handle<JSObject> object, |
1354 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 1338 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
1355 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, | 1339 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
1356 uint32_t insertion_index = 0) { | 1340 uint32_t insertion_index = 0) { |
1357 if (filter & SKIP_STRINGS) return list; | 1341 if (filter & SKIP_STRINGS) return list; |
1358 if (filter & ONLY_ALL_CAN_READ) return list; | 1342 if (filter & ONLY_ALL_CAN_READ) return list; |
1359 | 1343 |
1360 Handle<Object> undefined = isolate->factory()->undefined_value(); | |
1361 Handle<Object> the_hole = isolate->factory()->the_hole_value(); | |
1362 Handle<SeededNumberDictionary> dictionary = | 1344 Handle<SeededNumberDictionary> dictionary = |
1363 Handle<SeededNumberDictionary>::cast(backing_store); | 1345 Handle<SeededNumberDictionary>::cast(backing_store); |
1364 uint32_t capacity = dictionary->Capacity(); | 1346 uint32_t capacity = dictionary->Capacity(); |
1365 for (uint32_t i = 0; i < capacity; i++) { | 1347 for (uint32_t i = 0; i < capacity; i++) { |
1366 uint32_t key = | 1348 uint32_t key = GetKeyForEntryImpl(isolate, dictionary, i, filter); |
1367 GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole); | |
1368 if (key == kMaxUInt32) continue; | 1349 if (key == kMaxUInt32) continue; |
1369 Handle<Object> index = isolate->factory()->NewNumberFromUint(key); | 1350 Handle<Object> index = isolate->factory()->NewNumberFromUint(key); |
1370 list->set(insertion_index, *index); | 1351 list->set(insertion_index, *index); |
1371 insertion_index++; | 1352 insertion_index++; |
1372 } | 1353 } |
1373 *nof_indices = insertion_index; | 1354 *nof_indices = insertion_index; |
1374 return list; | 1355 return list; |
1375 } | 1356 } |
1376 | 1357 |
1377 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 1358 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
(...skipping 1665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3043 insertion_index += len; | 3024 insertion_index += len; |
3044 } | 3025 } |
3045 | 3026 |
3046 DCHECK_EQ(insertion_index, result_len); | 3027 DCHECK_EQ(insertion_index, result_len); |
3047 return result_array; | 3028 return result_array; |
3048 } | 3029 } |
3049 | 3030 |
3050 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3031 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
3051 } // namespace internal | 3032 } // namespace internal |
3052 } // namespace v8 | 3033 } // namespace v8 |
OLD | NEW |