| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1668 case JS_GENERATOR_OBJECT_TYPE: | 1668 case JS_GENERATOR_OBJECT_TYPE: |
| 1669 case JS_MODULE_TYPE: | 1669 case JS_MODULE_TYPE: |
| 1670 case JS_VALUE_TYPE: | 1670 case JS_VALUE_TYPE: |
| 1671 case JS_DATE_TYPE: | 1671 case JS_DATE_TYPE: |
| 1672 case JS_ARRAY_TYPE: | 1672 case JS_ARRAY_TYPE: |
| 1673 case JS_ARRAY_BUFFER_TYPE: | 1673 case JS_ARRAY_BUFFER_TYPE: |
| 1674 case JS_TYPED_ARRAY_TYPE: | 1674 case JS_TYPED_ARRAY_TYPE: |
| 1675 case JS_DATA_VIEW_TYPE: | 1675 case JS_DATA_VIEW_TYPE: |
| 1676 case JS_SET_TYPE: | 1676 case JS_SET_TYPE: |
| 1677 case JS_MAP_TYPE: | 1677 case JS_MAP_TYPE: |
| 1678 case JS_SET_ITERATOR_TYPE: | |
| 1679 case JS_MAP_ITERATOR_TYPE: | |
| 1680 case JS_WEAK_MAP_TYPE: | 1678 case JS_WEAK_MAP_TYPE: |
| 1681 case JS_WEAK_SET_TYPE: | 1679 case JS_WEAK_SET_TYPE: |
| 1682 case JS_REGEXP_TYPE: | 1680 case JS_REGEXP_TYPE: |
| 1683 case JS_GLOBAL_PROXY_TYPE: | 1681 case JS_GLOBAL_PROXY_TYPE: |
| 1684 case JS_GLOBAL_OBJECT_TYPE: | 1682 case JS_GLOBAL_OBJECT_TYPE: |
| 1685 case JS_BUILTINS_OBJECT_TYPE: | 1683 case JS_BUILTINS_OBJECT_TYPE: |
| 1686 case JS_MESSAGE_OBJECT_TYPE: | 1684 case JS_MESSAGE_OBJECT_TYPE: |
| 1687 JSObject::BodyDescriptor::IterateBody(this, object_size, v); | 1685 JSObject::BodyDescriptor::IterateBody(this, object_size, v); |
| 1688 break; | 1686 break; |
| 1689 case JS_FUNCTION_TYPE: | 1687 case JS_FUNCTION_TYPE: |
| (...skipping 14639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16329 } | 16327 } |
| 16330 | 16328 |
| 16331 | 16329 |
| 16332 void WeakHashTable::AddEntry(int entry, Object* key, Object* value) { | 16330 void WeakHashTable::AddEntry(int entry, Object* key, Object* value) { |
| 16333 set(EntryToIndex(entry), key); | 16331 set(EntryToIndex(entry), key); |
| 16334 set(EntryToValueIndex(entry), value); | 16332 set(EntryToValueIndex(entry), value); |
| 16335 ElementAdded(); | 16333 ElementAdded(); |
| 16336 } | 16334 } |
| 16337 | 16335 |
| 16338 | 16336 |
| 16339 template<class Derived, class Iterator, int entrysize> | 16337 template<class Derived, int entrysize> |
| 16340 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate( | 16338 Handle<Derived> OrderedHashTable<Derived, entrysize>::Allocate( |
| 16341 Isolate* isolate, int capacity, PretenureFlag pretenure) { | 16339 Isolate* isolate, int capacity, PretenureFlag pretenure) { |
| 16342 // Capacity must be a power of two, since we depend on being able | 16340 // Capacity must be a power of two, since we depend on being able |
| 16343 // to divide and multiple by 2 (kLoadFactor) to derive capacity | 16341 // to divide and multiple by 2 (kLoadFactor) to derive capacity |
| 16344 // from number of buckets. If we decide to change kLoadFactor | 16342 // from number of buckets. If we decide to change kLoadFactor |
| 16345 // to something other than 2, capacity should be stored as another | 16343 // to something other than 2, capacity should be stored as another |
| 16346 // field of this object. | 16344 // field of this object. |
| 16345 const int kMinCapacity = 4; |
| 16347 capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity)); | 16346 capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity)); |
| 16348 if (capacity > kMaxCapacity) { | 16347 if (capacity > kMaxCapacity) { |
| 16349 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); | 16348 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); |
| 16350 } | 16349 } |
| 16351 int num_buckets = capacity / kLoadFactor; | 16350 int num_buckets = capacity / kLoadFactor; |
| 16352 Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray( | 16351 Handle<FixedArray> backing_store = isolate->factory()->NewFixedArray( |
| 16353 kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure); | 16352 kHashTableStartIndex + num_buckets + (capacity * kEntrySize), pretenure); |
| 16354 backing_store->set_map_no_write_barrier( | 16353 backing_store->set_map_no_write_barrier( |
| 16355 isolate->heap()->ordered_hash_table_map()); | 16354 isolate->heap()->ordered_hash_table_map()); |
| 16356 Handle<Derived> table = Handle<Derived>::cast(backing_store); | 16355 Handle<Derived> table = Handle<Derived>::cast(backing_store); |
| 16357 for (int i = 0; i < num_buckets; ++i) { | 16356 for (int i = 0; i < num_buckets; ++i) { |
| 16358 table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound)); | 16357 table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound)); |
| 16359 } | 16358 } |
| 16360 table->SetNumberOfBuckets(num_buckets); | 16359 table->SetNumberOfBuckets(num_buckets); |
| 16361 table->SetNumberOfElements(0); | 16360 table->SetNumberOfElements(0); |
| 16362 table->SetNumberOfDeletedElements(0); | 16361 table->SetNumberOfDeletedElements(0); |
| 16363 table->set_iterators(isolate->heap()->undefined_value()); | |
| 16364 return table; | 16362 return table; |
| 16365 } | 16363 } |
| 16366 | 16364 |
| 16367 | 16365 |
| 16368 template<class Derived, class Iterator, int entrysize> | 16366 template<class Derived, int entrysize> |
| 16369 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::EnsureGrowable( | 16367 Handle<Derived> OrderedHashTable<Derived, entrysize>::EnsureGrowable( |
| 16370 Handle<Derived> table) { | 16368 Handle<Derived> table) { |
| 16371 int nof = table->NumberOfElements(); | 16369 int nof = table->NumberOfElements(); |
| 16372 int nod = table->NumberOfDeletedElements(); | 16370 int nod = table->NumberOfDeletedElements(); |
| 16373 int capacity = table->Capacity(); | 16371 int capacity = table->Capacity(); |
| 16374 if ((nof + nod) < capacity) return table; | 16372 if ((nof + nod) < capacity) return table; |
| 16375 // Don't need to grow if we can simply clear out deleted entries instead. | 16373 // Don't need to grow if we can simply clear out deleted entries instead. |
| 16376 // Note that we can't compact in place, though, so we always allocate | 16374 // Note that we can't compact in place, though, so we always allocate |
| 16377 // a new table. | 16375 // a new table. |
| 16378 return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity); | 16376 return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity); |
| 16379 } | 16377 } |
| 16380 | 16378 |
| 16381 | 16379 |
| 16382 template<class Derived, class Iterator, int entrysize> | 16380 template<class Derived, int entrysize> |
| 16383 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Shrink( | 16381 Handle<Derived> OrderedHashTable<Derived, entrysize>::Shrink( |
| 16384 Handle<Derived> table) { | 16382 Handle<Derived> table) { |
| 16385 int nof = table->NumberOfElements(); | 16383 int nof = table->NumberOfElements(); |
| 16386 int capacity = table->Capacity(); | 16384 int capacity = table->Capacity(); |
| 16387 if (nof > (capacity >> 2)) return table; | 16385 if (nof > (capacity >> 2)) return table; |
| 16388 return Rehash(table, capacity / 2); | 16386 return Rehash(table, capacity / 2); |
| 16389 } | 16387 } |
| 16390 | 16388 |
| 16391 | 16389 |
| 16392 template<class Derived, class Iterator, int entrysize> | 16390 template<class Derived, int entrysize> |
| 16393 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear( | 16391 Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash( |
| 16394 Handle<Derived> table) { | |
| 16395 Handle<Derived> new_table = | |
| 16396 Allocate(table->GetIsolate(), | |
| 16397 kMinCapacity, | |
| 16398 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); | |
| 16399 | |
| 16400 new_table->set_iterators(table->iterators()); | |
| 16401 table->set_iterators(table->GetHeap()->undefined_value()); | |
| 16402 | |
| 16403 DisallowHeapAllocation no_allocation; | |
| 16404 for (Object* object = new_table->iterators(); | |
| 16405 !object->IsUndefined(); | |
| 16406 object = Iterator::cast(object)->next_iterator()) { | |
| 16407 Iterator::cast(object)->TableCleared(); | |
| 16408 Iterator::cast(object)->set_table(*new_table); | |
| 16409 } | |
| 16410 | |
| 16411 return new_table; | |
| 16412 } | |
| 16413 | |
| 16414 | |
| 16415 template<class Derived, class Iterator, int entrysize> | |
| 16416 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( | |
| 16417 Handle<Derived> table, int new_capacity) { | 16392 Handle<Derived> table, int new_capacity) { |
| 16418 Handle<Derived> new_table = | 16393 Handle<Derived> new_table = |
| 16419 Allocate(table->GetIsolate(), | 16394 Allocate(table->GetIsolate(), |
| 16420 new_capacity, | 16395 new_capacity, |
| 16421 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); | 16396 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); |
| 16422 int nof = table->NumberOfElements(); | 16397 int nof = table->NumberOfElements(); |
| 16423 int nod = table->NumberOfDeletedElements(); | 16398 int nod = table->NumberOfDeletedElements(); |
| 16424 int new_buckets = new_table->NumberOfBuckets(); | 16399 int new_buckets = new_table->NumberOfBuckets(); |
| 16425 int new_entry = 0; | 16400 int new_entry = 0; |
| 16426 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) { | 16401 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) { |
| 16427 Object* key = table->KeyAt(old_entry); | 16402 Object* key = table->KeyAt(old_entry); |
| 16428 if (key->IsTheHole()) continue; | 16403 if (key->IsTheHole()) continue; |
| 16429 Object* hash = key->GetHash(); | 16404 Object* hash = key->GetHash(); |
| 16430 int bucket = Smi::cast(hash)->value() & (new_buckets - 1); | 16405 int bucket = Smi::cast(hash)->value() & (new_buckets - 1); |
| 16431 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket); | 16406 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket); |
| 16432 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry)); | 16407 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry)); |
| 16433 int new_index = new_table->EntryToIndex(new_entry); | 16408 int new_index = new_table->EntryToIndex(new_entry); |
| 16434 int old_index = table->EntryToIndex(old_entry); | 16409 int old_index = table->EntryToIndex(old_entry); |
| 16435 for (int i = 0; i < entrysize; ++i) { | 16410 for (int i = 0; i < entrysize; ++i) { |
| 16436 Object* value = table->get(old_index + i); | 16411 Object* value = table->get(old_index + i); |
| 16437 new_table->set(new_index + i, value); | 16412 new_table->set(new_index + i, value); |
| 16438 } | 16413 } |
| 16439 new_table->set(new_index + kChainOffset, chain_entry); | 16414 new_table->set(new_index + kChainOffset, chain_entry); |
| 16440 ++new_entry; | 16415 ++new_entry; |
| 16441 } | 16416 } |
| 16442 new_table->SetNumberOfElements(nof); | 16417 new_table->SetNumberOfElements(nof); |
| 16443 | |
| 16444 new_table->set_iterators(table->iterators()); | |
| 16445 table->set_iterators(table->GetHeap()->undefined_value()); | |
| 16446 | |
| 16447 DisallowHeapAllocation no_allocation; | |
| 16448 for (Object* object = new_table->iterators(); | |
| 16449 !object->IsUndefined(); | |
| 16450 object = Iterator::cast(object)->next_iterator()) { | |
| 16451 Iterator::cast(object)->TableCompacted(); | |
| 16452 Iterator::cast(object)->set_table(*new_table); | |
| 16453 } | |
| 16454 | |
| 16455 return new_table; | 16418 return new_table; |
| 16456 } | 16419 } |
| 16457 | 16420 |
| 16458 | 16421 |
| 16459 template<class Derived, class Iterator, int entrysize> | 16422 template<class Derived, int entrysize> |
| 16460 int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry(Object* key) { | 16423 int OrderedHashTable<Derived, entrysize>::FindEntry(Object* key) { |
| 16461 ASSERT(!key->IsTheHole()); | 16424 ASSERT(!key->IsTheHole()); |
| 16462 Object* hash = key->GetHash(); | 16425 Object* hash = key->GetHash(); |
| 16463 if (hash->IsUndefined()) return kNotFound; | 16426 if (hash->IsUndefined()) return kNotFound; |
| 16464 for (int entry = HashToEntry(Smi::cast(hash)->value()); | 16427 for (int entry = HashToEntry(Smi::cast(hash)->value()); |
| 16465 entry != kNotFound; | 16428 entry != kNotFound; |
| 16466 entry = ChainAt(entry)) { | 16429 entry = ChainAt(entry)) { |
| 16467 Object* candidate = KeyAt(entry); | 16430 Object* candidate = KeyAt(entry); |
| 16468 if (candidate->SameValue(key)) | 16431 if (candidate->SameValue(key)) |
| 16469 return entry; | 16432 return entry; |
| 16470 } | 16433 } |
| 16471 return kNotFound; | 16434 return kNotFound; |
| 16472 } | 16435 } |
| 16473 | 16436 |
| 16474 | 16437 |
| 16475 template<class Derived, class Iterator, int entrysize> | 16438 template<class Derived, int entrysize> |
| 16476 int OrderedHashTable<Derived, Iterator, entrysize>::AddEntry(int hash) { | 16439 int OrderedHashTable<Derived, entrysize>::AddEntry(int hash) { |
| 16477 int entry = UsedCapacity(); | 16440 int entry = NumberOfElements() + NumberOfDeletedElements(); |
| 16478 int bucket = HashToBucket(hash); | 16441 int bucket = HashToBucket(hash); |
| 16479 int index = EntryToIndex(entry); | 16442 int index = EntryToIndex(entry); |
| 16480 Object* chain_entry = get(kHashTableStartIndex + bucket); | 16443 Object* chain_entry = get(kHashTableStartIndex + bucket); |
| 16481 set(kHashTableStartIndex + bucket, Smi::FromInt(entry)); | 16444 set(kHashTableStartIndex + bucket, Smi::FromInt(entry)); |
| 16482 set(index + kChainOffset, chain_entry); | 16445 set(index + kChainOffset, chain_entry); |
| 16483 SetNumberOfElements(NumberOfElements() + 1); | 16446 SetNumberOfElements(NumberOfElements() + 1); |
| 16484 return index; | 16447 return index; |
| 16485 } | 16448 } |
| 16486 | 16449 |
| 16487 | 16450 |
| 16488 template<class Derived, class Iterator, int entrysize> | 16451 template<class Derived, int entrysize> |
| 16489 void OrderedHashTable<Derived, Iterator, entrysize>::RemoveEntry(int entry) { | 16452 void OrderedHashTable<Derived, entrysize>::RemoveEntry(int entry) { |
| 16490 int index = EntryToIndex(entry); | 16453 int index = EntryToIndex(entry); |
| 16491 for (int i = 0; i < entrysize; ++i) { | 16454 for (int i = 0; i < entrysize; ++i) { |
| 16492 set_the_hole(index + i); | 16455 set_the_hole(index + i); |
| 16493 } | 16456 } |
| 16494 SetNumberOfElements(NumberOfElements() - 1); | 16457 SetNumberOfElements(NumberOfElements() - 1); |
| 16495 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); | 16458 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); |
| 16496 | |
| 16497 DisallowHeapAllocation no_allocation; | |
| 16498 for (Object* object = iterators(); | |
| 16499 !object->IsUndefined(); | |
| 16500 object = Iterator::cast(object)->next_iterator()) { | |
| 16501 Iterator::cast(object)->EntryRemoved(entry); | |
| 16502 } | |
| 16503 } | 16459 } |
| 16504 | 16460 |
| 16505 | 16461 |
| 16506 template int OrderedHashTable<OrderedHashSet, JSSetIterator, | 16462 template class OrderedHashTable<OrderedHashSet, 1>; |
| 16507 1>::FindEntry(Object* key); | 16463 template class OrderedHashTable<OrderedHashMap, 2>; |
| 16508 template int OrderedHashTable<OrderedHashMap, JSMapIterator, | |
| 16509 2>::FindEntry(Object* key); | |
| 16510 | |
| 16511 | |
| 16512 template class OrderedHashTable<OrderedHashSet, JSSetIterator, 1>; | |
| 16513 template class OrderedHashTable<OrderedHashMap, JSMapIterator, 2>; | |
| 16514 | 16464 |
| 16515 | 16465 |
| 16516 bool OrderedHashSet::Contains(Object* key) { | 16466 bool OrderedHashSet::Contains(Object* key) { |
| 16517 return FindEntry(key) != kNotFound; | 16467 return FindEntry(key) != kNotFound; |
| 16518 } | 16468 } |
| 16519 | 16469 |
| 16520 | 16470 |
| 16521 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table, | 16471 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table, |
| 16522 Handle<Object> key) { | 16472 Handle<Object> key) { |
| 16523 if (table->FindEntry(*key) != kNotFound) return table; | 16473 if (table->FindEntry(*key) != kNotFound) return table; |
| 16524 | 16474 |
| 16525 table = EnsureGrowable(table); | 16475 table = EnsureGrowable(table); |
| 16526 | 16476 |
| 16527 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); | 16477 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); |
| 16528 int index = table->AddEntry(Smi::cast(*hash)->value()); | 16478 int index = table->AddEntry(Smi::cast(*hash)->value()); |
| 16529 table->set(index, *key); | 16479 table->set(index, *key); |
| 16530 return table; | 16480 return table; |
| 16531 } | 16481 } |
| 16532 | 16482 |
| 16533 | 16483 |
| 16534 Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table, | 16484 Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table, |
| 16535 Handle<Object> key) { | 16485 Handle<Object> key) { |
| 16536 int entry = table->FindEntry(*key); | 16486 int entry = table->FindEntry(*key); |
| 16537 if (entry == kNotFound) return table; | 16487 if (entry == kNotFound) return table; |
| 16538 table->RemoveEntry(entry); | 16488 table->RemoveEntry(entry); |
| 16489 // TODO(adamk): Don't shrink if we're being iterated over |
| 16539 return Shrink(table); | 16490 return Shrink(table); |
| 16540 } | 16491 } |
| 16541 | 16492 |
| 16542 | 16493 |
| 16543 Object* OrderedHashMap::Lookup(Object* key) { | 16494 Object* OrderedHashMap::Lookup(Object* key) { |
| 16544 int entry = FindEntry(key); | 16495 int entry = FindEntry(key); |
| 16545 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 16496 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
| 16546 return ValueAt(entry); | 16497 return ValueAt(entry); |
| 16547 } | 16498 } |
| 16548 | 16499 |
| 16549 | 16500 |
| 16550 Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table, | 16501 Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table, |
| 16551 Handle<Object> key, | 16502 Handle<Object> key, |
| 16552 Handle<Object> value) { | 16503 Handle<Object> value) { |
| 16553 int entry = table->FindEntry(*key); | 16504 int entry = table->FindEntry(*key); |
| 16554 | 16505 |
| 16555 if (value->IsTheHole()) { | 16506 if (value->IsTheHole()) { |
| 16556 if (entry == kNotFound) return table; | 16507 if (entry == kNotFound) return table; |
| 16557 table->RemoveEntry(entry); | 16508 table->RemoveEntry(entry); |
| 16509 // TODO(adamk): Only shrink if not iterating |
| 16558 return Shrink(table); | 16510 return Shrink(table); |
| 16559 } | 16511 } |
| 16560 | 16512 |
| 16561 if (entry != kNotFound) { | 16513 if (entry != kNotFound) { |
| 16562 table->set(table->EntryToIndex(entry) + kValueOffset, *value); | 16514 table->set(table->EntryToIndex(entry) + kValueOffset, *value); |
| 16563 return table; | 16515 return table; |
| 16564 } | 16516 } |
| 16565 | 16517 |
| 16566 table = EnsureGrowable(table); | 16518 table = EnsureGrowable(table); |
| 16567 | 16519 |
| 16568 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); | 16520 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); |
| 16569 int index = table->AddEntry(Smi::cast(*hash)->value()); | 16521 int index = table->AddEntry(Smi::cast(*hash)->value()); |
| 16570 table->set(index, *key); | 16522 table->set(index, *key); |
| 16571 table->set(index + kValueOffset, *value); | 16523 table->set(index + kValueOffset, *value); |
| 16572 return table; | 16524 return table; |
| 16573 } | 16525 } |
| 16574 | 16526 |
| 16575 | 16527 |
| 16576 template<class Derived, class TableType> | |
| 16577 void OrderedHashTableIterator<Derived, TableType>::EntryRemoved(int index) { | |
| 16578 int i = this->index()->value(); | |
| 16579 if (index < i) { | |
| 16580 set_count(Smi::FromInt(count()->value() - 1)); | |
| 16581 } | |
| 16582 if (index == i) { | |
| 16583 Seek(); | |
| 16584 } | |
| 16585 } | |
| 16586 | |
| 16587 | |
| 16588 template<class Derived, class TableType> | |
| 16589 void OrderedHashTableIterator<Derived, TableType>::Close() { | |
| 16590 if (Closed()) return; | |
| 16591 | |
| 16592 DisallowHeapAllocation no_allocation; | |
| 16593 | |
| 16594 Object* undefined = GetHeap()->undefined_value(); | |
| 16595 TableType* table = TableType::cast(this->table()); | |
| 16596 Object* previous = previous_iterator(); | |
| 16597 Object* next = next_iterator(); | |
| 16598 | |
| 16599 if (previous == undefined) { | |
| 16600 ASSERT_EQ(table->iterators(), this); | |
| 16601 table->set_iterators(next); | |
| 16602 } else { | |
| 16603 ASSERT_EQ(Derived::cast(previous)->next_iterator(), this); | |
| 16604 Derived::cast(previous)->set_next_iterator(next); | |
| 16605 } | |
| 16606 | |
| 16607 if (!next->IsUndefined()) { | |
| 16608 ASSERT_EQ(Derived::cast(next)->previous_iterator(), this); | |
| 16609 Derived::cast(next)->set_previous_iterator(previous); | |
| 16610 } | |
| 16611 | |
| 16612 set_previous_iterator(undefined); | |
| 16613 set_next_iterator(undefined); | |
| 16614 set_table(undefined); | |
| 16615 } | |
| 16616 | |
| 16617 | |
| 16618 template<class Derived, class TableType> | |
| 16619 void OrderedHashTableIterator<Derived, TableType>::Seek() { | |
| 16620 ASSERT(!Closed()); | |
| 16621 | |
| 16622 DisallowHeapAllocation no_allocation; | |
| 16623 | |
| 16624 int index = this->index()->value(); | |
| 16625 | |
| 16626 TableType* table = TableType::cast(this->table()); | |
| 16627 int used_capacity = table->UsedCapacity(); | |
| 16628 | |
| 16629 while (index < used_capacity && table->KeyAt(index)->IsTheHole()) { | |
| 16630 index++; | |
| 16631 } | |
| 16632 set_index(Smi::FromInt(index)); | |
| 16633 } | |
| 16634 | |
| 16635 | |
| 16636 template<class Derived, class TableType> | |
| 16637 void OrderedHashTableIterator<Derived, TableType>::MoveNext() { | |
| 16638 ASSERT(!Closed()); | |
| 16639 | |
| 16640 set_index(Smi::FromInt(index()->value() + 1)); | |
| 16641 set_count(Smi::FromInt(count()->value() + 1)); | |
| 16642 Seek(); | |
| 16643 } | |
| 16644 | |
| 16645 | |
| 16646 template<class Derived, class TableType> | |
| 16647 Handle<JSObject> OrderedHashTableIterator<Derived, TableType>::Next( | |
| 16648 Handle<Derived> iterator) { | |
| 16649 Isolate* isolate = iterator->GetIsolate(); | |
| 16650 Factory* factory = isolate->factory(); | |
| 16651 | |
| 16652 Handle<Object> object(iterator->table(), isolate); | |
| 16653 | |
| 16654 if (!object->IsUndefined()) { | |
| 16655 Handle<TableType> table = Handle<TableType>::cast(object); | |
| 16656 int index = iterator->index()->value(); | |
| 16657 if (index < table->UsedCapacity()) { | |
| 16658 int entry_index = table->EntryToIndex(index); | |
| 16659 iterator->MoveNext(); | |
| 16660 Handle<Object> value = Derived::ValueForKind(iterator, entry_index); | |
| 16661 return factory->NewIteratorResultObject(value, false); | |
| 16662 } else { | |
| 16663 iterator->Close(); | |
| 16664 } | |
| 16665 } | |
| 16666 | |
| 16667 return factory->NewIteratorResultObject(factory->undefined_value(), true); | |
| 16668 } | |
| 16669 | |
| 16670 | |
| 16671 template<class Derived, class TableType> | |
| 16672 Handle<Derived> OrderedHashTableIterator<Derived, TableType>::CreateInternal( | |
| 16673 Handle<Map> map, | |
| 16674 Handle<TableType> table, | |
| 16675 int kind) { | |
| 16676 Isolate* isolate = table->GetIsolate(); | |
| 16677 | |
| 16678 Handle<Object> undefined = isolate->factory()->undefined_value(); | |
| 16679 | |
| 16680 Handle<Derived> new_iterator = Handle<Derived>::cast( | |
| 16681 isolate->factory()->NewJSObjectFromMap(map)); | |
| 16682 new_iterator->set_previous_iterator(*undefined); | |
| 16683 new_iterator->set_table(*table); | |
| 16684 new_iterator->set_index(Smi::FromInt(0)); | |
| 16685 new_iterator->set_count(Smi::FromInt(0)); | |
| 16686 new_iterator->set_kind(Smi::FromInt(kind)); | |
| 16687 | |
| 16688 Handle<Object> old_iterator(table->iterators(), isolate); | |
| 16689 if (!old_iterator->IsUndefined()) { | |
| 16690 Handle<Derived>::cast(old_iterator)->set_previous_iterator(*new_iterator); | |
| 16691 new_iterator->set_next_iterator(*old_iterator); | |
| 16692 } else { | |
| 16693 new_iterator->set_next_iterator(*undefined); | |
| 16694 } | |
| 16695 | |
| 16696 table->set_iterators(*new_iterator); | |
| 16697 | |
| 16698 return new_iterator; | |
| 16699 } | |
| 16700 | |
| 16701 | |
| 16702 template Handle<JSObject> OrderedHashTableIterator<JSSetIterator, | |
| 16703 OrderedHashSet>::Next(Handle<JSSetIterator> iterator); | |
| 16704 template Handle<JSObject> OrderedHashTableIterator<JSMapIterator, | |
| 16705 OrderedHashMap>::Next(Handle<JSMapIterator> iterator); | |
| 16706 | |
| 16707 | |
| 16708 template class OrderedHashTableIterator<JSSetIterator, OrderedHashSet>; | |
| 16709 template class OrderedHashTableIterator<JSMapIterator, OrderedHashMap>; | |
| 16710 | |
| 16711 | |
| 16712 Handle<Object> JSSetIterator::ValueForKind( | |
| 16713 Handle<JSSetIterator> iterator, int entry_index) { | |
| 16714 int kind = iterator->kind()->value(); | |
| 16715 // Set.prototype only has values and entries. | |
| 16716 ASSERT(kind == kKindValues || kind == kKindEntries); | |
| 16717 | |
| 16718 Isolate* isolate = iterator->GetIsolate(); | |
| 16719 Factory* factory = isolate->factory(); | |
| 16720 | |
| 16721 Handle<OrderedHashSet> table( | |
| 16722 OrderedHashSet::cast(iterator->table()), isolate); | |
| 16723 Handle<Object> value = Handle<Object>(table->get(entry_index), isolate); | |
| 16724 | |
| 16725 if (kind == kKindEntries) { | |
| 16726 Handle<FixedArray> array = factory->NewFixedArray(2); | |
| 16727 array->set(0, *value); | |
| 16728 array->set(1, *value); | |
| 16729 return factory->NewJSArrayWithElements(array); | |
| 16730 } | |
| 16731 | |
| 16732 return value; | |
| 16733 } | |
| 16734 | |
| 16735 | |
| 16736 Handle<Object> JSMapIterator::ValueForKind( | |
| 16737 Handle<JSMapIterator> iterator, int entry_index) { | |
| 16738 int kind = iterator->kind()->value(); | |
| 16739 ASSERT(kind == kKindKeys || kind == kKindValues || kind == kKindEntries); | |
| 16740 | |
| 16741 Isolate* isolate = iterator->GetIsolate(); | |
| 16742 Factory* factory = isolate->factory(); | |
| 16743 | |
| 16744 Handle<OrderedHashMap> table( | |
| 16745 OrderedHashMap::cast(iterator->table()), isolate); | |
| 16746 | |
| 16747 switch (kind) { | |
| 16748 case kKindKeys: | |
| 16749 return Handle<Object>(table->get(entry_index), isolate); | |
| 16750 | |
| 16751 case kKindValues: | |
| 16752 return Handle<Object>(table->get(entry_index + 1), isolate); | |
| 16753 | |
| 16754 case kKindEntries: { | |
| 16755 Handle<Object> key(table->get(entry_index), isolate); | |
| 16756 Handle<Object> value(table->get(entry_index + 1), isolate); | |
| 16757 Handle<FixedArray> array = factory->NewFixedArray(2); | |
| 16758 array->set(0, *key); | |
| 16759 array->set(1, *value); | |
| 16760 return factory->NewJSArrayWithElements(array); | |
| 16761 } | |
| 16762 } | |
| 16763 | |
| 16764 UNREACHABLE(); | |
| 16765 return factory->undefined_value(); | |
| 16766 } | |
| 16767 | |
| 16768 | |
| 16769 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( | 16528 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( |
| 16770 DeclaredAccessorDescriptor* descriptor) | 16529 DeclaredAccessorDescriptor* descriptor) |
| 16771 : array_(descriptor->serialized_data()->GetDataStartAddress()), | 16530 : array_(descriptor->serialized_data()->GetDataStartAddress()), |
| 16772 length_(descriptor->serialized_data()->length()), | 16531 length_(descriptor->serialized_data()->length()), |
| 16773 offset_(0) { | 16532 offset_(0) { |
| 16774 } | 16533 } |
| 16775 | 16534 |
| 16776 | 16535 |
| 16777 const DeclaredAccessorDescriptorData* | 16536 const DeclaredAccessorDescriptorData* |
| 16778 DeclaredAccessorDescriptorIterator::Next() { | 16537 DeclaredAccessorDescriptorIterator::Next() { |
| (...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17352 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17111 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 17353 static const char* error_messages_[] = { | 17112 static const char* error_messages_[] = { |
| 17354 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17113 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 17355 }; | 17114 }; |
| 17356 #undef ERROR_MESSAGES_TEXTS | 17115 #undef ERROR_MESSAGES_TEXTS |
| 17357 return error_messages_[reason]; | 17116 return error_messages_[reason]; |
| 17358 } | 17117 } |
| 17359 | 17118 |
| 17360 | 17119 |
| 17361 } } // namespace v8::internal | 17120 } } // namespace v8::internal |
| OLD | NEW |