Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: src/objects.cc

Issue 2031533002: [dictionaries] Use IsKey(Isolate* i, Object* o) everywhere (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: use new IsTheHole Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <sstream> 9 #include <sstream>
10 10
(...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 Context* native_context = isolate->context()->native_context(); 1513 Context* native_context = isolate->context()->native_context();
1514 JSFunction* constructor_function = 1514 JSFunction* constructor_function =
1515 JSFunction::cast(native_context->get(constructor_function_index)); 1515 JSFunction::cast(native_context->get(constructor_function_index));
1516 return constructor_function->initial_map(); 1516 return constructor_function->initial_map();
1517 } 1517 }
1518 return isolate->heap()->null_value()->map(); 1518 return isolate->heap()->null_value()->map();
1519 } 1519 }
1520 1520
1521 1521
1522 Object* Object::GetHash() { 1522 Object* Object::GetHash() {
1523 DisallowHeapAllocation no_gc;
1523 Object* hash = GetSimpleHash(); 1524 Object* hash = GetSimpleHash();
1524 if (hash->IsSmi()) return hash; 1525 if (hash->IsSmi()) return hash;
1525 1526
1526 DisallowHeapAllocation no_gc;
1527 DCHECK(IsJSReceiver()); 1527 DCHECK(IsJSReceiver());
1528 JSReceiver* receiver = JSReceiver::cast(this); 1528 JSReceiver* receiver = JSReceiver::cast(this);
1529 Isolate* isolate = receiver->GetIsolate(); 1529 Isolate* isolate = receiver->GetIsolate();
1530 return *JSReceiver::GetIdentityHash(isolate, handle(receiver, isolate)); 1530 return *JSReceiver::GetIdentityHash(isolate, handle(receiver, isolate));
1531 } 1531 }
1532 1532
1533 1533
1534 Object* Object::GetSimpleHash() { 1534 Object* Object::GetSimpleHash() {
1535 // The object is either a Smi, a HeapNumber, a name, an odd-ball, 1535 // The object is either a Smi, a HeapNumber, a name, an odd-ball,
1536 // a SIMD value type, a real JS object, or a Harmony proxy. 1536 // a SIMD value type, a real JS object, or a Harmony proxy.
(...skipping 4145 matching lines...) Expand 10 before | Expand all | Expand 10 after
5682 } else { 5682 } else {
5683 iteration_order = NameDictionary::BuildIterationIndicesArray(dictionary); 5683 iteration_order = NameDictionary::BuildIterationIndicesArray(dictionary);
5684 } 5684 }
5685 5685
5686 int instance_descriptor_length = iteration_order->length(); 5686 int instance_descriptor_length = iteration_order->length();
5687 int number_of_fields = 0; 5687 int number_of_fields = 0;
5688 5688
5689 // Compute the length of the instance descriptor. 5689 // Compute the length of the instance descriptor.
5690 for (int i = 0; i < instance_descriptor_length; i++) { 5690 for (int i = 0; i < instance_descriptor_length; i++) {
5691 int index = Smi::cast(iteration_order->get(i))->value(); 5691 int index = Smi::cast(iteration_order->get(i))->value();
5692 DCHECK(dictionary->IsKey(dictionary->KeyAt(index))); 5692 DCHECK(dictionary->IsKey(isolate, dictionary->KeyAt(index)));
5693 5693
5694 Object* value = dictionary->ValueAt(index); 5694 Object* value = dictionary->ValueAt(index);
5695 PropertyType type = dictionary->DetailsAt(index).type(); 5695 PropertyType type = dictionary->DetailsAt(index).type();
5696 if (type == DATA && !value->IsJSFunction()) { 5696 if (type == DATA && !value->IsJSFunction()) {
5697 number_of_fields += 1; 5697 number_of_fields += 1;
5698 } 5698 }
5699 } 5699 }
5700 5700
5701 Handle<Map> old_map(object->map(), isolate); 5701 Handle<Map> old_map(object->map(), isolate);
5702 5702
(...skipping 1914 matching lines...) Expand 10 before | Expand all | Expand 10 after
7617 return iter.GetCurrent<JSObject>()->map()->is_extensible(); 7617 return iter.GetCurrent<JSObject>()->map()->is_extensible();
7618 } 7618 }
7619 return object->map()->is_extensible(); 7619 return object->map()->is_extensible();
7620 } 7620 }
7621 7621
7622 7622
7623 template <typename Dictionary> 7623 template <typename Dictionary>
7624 static void ApplyAttributesToDictionary(Dictionary* dictionary, 7624 static void ApplyAttributesToDictionary(Dictionary* dictionary,
7625 const PropertyAttributes attributes) { 7625 const PropertyAttributes attributes) {
7626 int capacity = dictionary->Capacity(); 7626 int capacity = dictionary->Capacity();
7627 Isolate* isolate = dictionary->GetIsolate();
7627 for (int i = 0; i < capacity; i++) { 7628 for (int i = 0; i < capacity; i++) {
7628 Object* k = dictionary->KeyAt(i); 7629 Object* k = dictionary->KeyAt(i);
7629 if (dictionary->IsKey(k) && 7630 if (dictionary->IsKey(isolate, k) &&
7630 !(k->IsSymbol() && Symbol::cast(k)->is_private())) { 7631 !(k->IsSymbol() && Symbol::cast(k)->is_private())) {
7631 PropertyDetails details = dictionary->DetailsAt(i); 7632 PropertyDetails details = dictionary->DetailsAt(i);
7632 int attrs = attributes; 7633 int attrs = attributes;
7633 // READ_ONLY is an invalid attribute for JS setters/getters. 7634 // READ_ONLY is an invalid attribute for JS setters/getters.
7634 if ((attributes & READ_ONLY) && details.type() == ACCESSOR_CONSTANT) { 7635 if ((attributes & READ_ONLY) && details.type() == ACCESSOR_CONSTANT) {
7635 Object* v = dictionary->ValueAt(i); 7636 Object* v = dictionary->ValueAt(i);
7636 if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value(); 7637 if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value();
7637 if (v->IsAccessorPair()) attrs &= ~READ_ONLY; 7638 if (v->IsAccessorPair()) attrs &= ~READ_ONLY;
7638 } 7639 }
7639 details = details.CopyAddAttributes( 7640 details = details.CopyAddAttributes(
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
7946 } 7947 }
7947 } 7948 }
7948 break; 7949 break;
7949 } 7950 }
7950 case DICTIONARY_ELEMENTS: { 7951 case DICTIONARY_ELEMENTS: {
7951 Handle<SeededNumberDictionary> element_dictionary( 7952 Handle<SeededNumberDictionary> element_dictionary(
7952 copy->element_dictionary()); 7953 copy->element_dictionary());
7953 int capacity = element_dictionary->Capacity(); 7954 int capacity = element_dictionary->Capacity();
7954 for (int i = 0; i < capacity; i++) { 7955 for (int i = 0; i < capacity; i++) {
7955 Object* k = element_dictionary->KeyAt(i); 7956 Object* k = element_dictionary->KeyAt(i);
7956 if (element_dictionary->IsKey(k)) { 7957 if (element_dictionary->IsKey(isolate, k)) {
7957 Handle<Object> value(element_dictionary->ValueAt(i), isolate); 7958 Handle<Object> value(element_dictionary->ValueAt(i), isolate);
7958 if (value->IsJSObject()) { 7959 if (value->IsJSObject()) {
7959 Handle<JSObject> result; 7960 Handle<JSObject> result;
7960 ASSIGN_RETURN_ON_EXCEPTION( 7961 ASSIGN_RETURN_ON_EXCEPTION(
7961 isolate, result, 7962 isolate, result,
7962 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), 7963 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
7963 JSObject); 7964 JSObject);
7964 if (copying) { 7965 if (copying) {
7965 element_dictionary->ValueAtPut(i, *result); 7966 element_dictionary->ValueAtPut(i, *result);
7966 } 7967 }
(...skipping 7364 matching lines...) Expand 10 before | Expand all | Expand 10 after
15331 15332
15332 15333
15333 // Certain compilers request function template instantiation when they 15334 // Certain compilers request function template instantiation when they
15334 // see the definition of the other template functions in the 15335 // see the definition of the other template functions in the
15335 // class. This requires us to have the template functions put 15336 // class. This requires us to have the template functions put
15336 // together, so even though this function belongs in objects-debug.cc, 15337 // together, so even though this function belongs in objects-debug.cc,
15337 // we keep it here instead to satisfy certain compilers. 15338 // we keep it here instead to satisfy certain compilers.
15338 #ifdef OBJECT_PRINT 15339 #ifdef OBJECT_PRINT
15339 template <typename Derived, typename Shape, typename Key> 15340 template <typename Derived, typename Shape, typename Key>
15340 void Dictionary<Derived, Shape, Key>::Print(std::ostream& os) { // NOLINT 15341 void Dictionary<Derived, Shape, Key>::Print(std::ostream& os) { // NOLINT
15342 Isolate* isolate = this->GetIsolate();
15341 int capacity = this->Capacity(); 15343 int capacity = this->Capacity();
15342 for (int i = 0; i < capacity; i++) { 15344 for (int i = 0; i < capacity; i++) {
15343 Object* k = this->KeyAt(i); 15345 Object* k = this->KeyAt(i);
15344 if (this->IsKey(k)) { 15346 if (this->IsKey(isolate, k)) {
15345 os << "\n "; 15347 os << "\n ";
15346 if (k->IsString()) { 15348 if (k->IsString()) {
15347 String::cast(k)->StringPrint(os); 15349 String::cast(k)->StringPrint(os);
15348 } else { 15350 } else {
15349 os << Brief(k); 15351 os << Brief(k);
15350 } 15352 }
15351 os << ": " << Brief(this->ValueAt(i)) << " " << this->DetailsAt(i); 15353 os << ": " << Brief(this->ValueAt(i)) << " " << this->DetailsAt(i);
15352 } 15354 }
15353 } 15355 }
15354 } 15356 }
15355 template <typename Derived, typename Shape, typename Key> 15357 template <typename Derived, typename Shape, typename Key>
15356 void Dictionary<Derived, Shape, Key>::Print() { 15358 void Dictionary<Derived, Shape, Key>::Print() {
15357 OFStream os(stdout); 15359 OFStream os(stdout);
15358 Print(os); 15360 Print(os);
15359 } 15361 }
15360 #endif 15362 #endif
15361 15363
15362 15364
15363 template<typename Derived, typename Shape, typename Key> 15365 template<typename Derived, typename Shape, typename Key>
15364 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { 15366 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) {
15367 Isolate* isolate = this->GetIsolate();
15365 int pos = 0; 15368 int pos = 0;
15366 int capacity = this->Capacity(); 15369 int capacity = this->Capacity();
15367 DisallowHeapAllocation no_gc; 15370 DisallowHeapAllocation no_gc;
15368 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); 15371 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
15369 for (int i = 0; i < capacity; i++) { 15372 for (int i = 0; i < capacity; i++) {
15370 Object* k = this->KeyAt(i); 15373 Object* k = this->KeyAt(i);
15371 if (this->IsKey(k)) { 15374 if (this->IsKey(isolate, k)) {
15372 elements->set(pos++, this->ValueAt(i), mode); 15375 elements->set(pos++, this->ValueAt(i), mode);
15373 } 15376 }
15374 } 15377 }
15375 DCHECK(pos == elements->length()); 15378 DCHECK(pos == elements->length());
15376 } 15379 }
15377 15380
15378 15381
15379 MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it, 15382 MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
15380 bool* done) { 15383 bool* done) {
15381 *done = false; 15384 *done = false;
(...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after
16166 for (int j = 0; j < Shape::kEntrySize; j++) { 16169 for (int j = 0; j < Shape::kEntrySize; j++) {
16167 set(index2 + j, temp[j], mode); 16170 set(index2 + j, temp[j], mode);
16168 } 16171 }
16169 } 16172 }
16170 16173
16171 16174
16172 template<typename Derived, typename Shape, typename Key> 16175 template<typename Derived, typename Shape, typename Key>
16173 void HashTable<Derived, Shape, Key>::Rehash(Key key) { 16176 void HashTable<Derived, Shape, Key>::Rehash(Key key) {
16174 DisallowHeapAllocation no_gc; 16177 DisallowHeapAllocation no_gc;
16175 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); 16178 WriteBarrierMode mode = GetWriteBarrierMode(no_gc);
16179 Isolate* isolate = GetIsolate();
16176 uint32_t capacity = Capacity(); 16180 uint32_t capacity = Capacity();
16177 bool done = false; 16181 bool done = false;
16178 for (int probe = 1; !done; probe++) { 16182 for (int probe = 1; !done; probe++) {
16179 // All elements at entries given by one of the first _probe_ probes 16183 // All elements at entries given by one of the first _probe_ probes
16180 // are placed correctly. Other elements might need to be moved. 16184 // are placed correctly. Other elements might need to be moved.
16181 done = true; 16185 done = true;
16182 for (uint32_t current = 0; current < capacity; current++) { 16186 for (uint32_t current = 0; current < capacity; current++) {
16183 Object* current_key = get(EntryToIndex(current)); 16187 Object* current_key = get(EntryToIndex(current));
16184 if (IsKey(current_key)) { 16188 if (IsKey(isolate, current_key)) {
16185 uint32_t target = EntryForProbe(key, current_key, probe, current); 16189 uint32_t target = EntryForProbe(key, current_key, probe, current);
16186 if (current == target) continue; 16190 if (current == target) continue;
16187 Object* target_key = get(EntryToIndex(target)); 16191 Object* target_key = get(EntryToIndex(target));
16188 if (!IsKey(target_key) || 16192 if (!IsKey(target_key) ||
16189 EntryForProbe(key, target_key, probe, target) != target) { 16193 EntryForProbe(key, target_key, probe, target) != target) {
16190 // Put the current element into the correct position. 16194 // Put the current element into the correct position.
16191 Swap(current, target, mode); 16195 Swap(current, target, mode);
16192 // The other element will be processed on the next iteration. 16196 // The other element will be processed on the next iteration.
16193 current--; 16197 current--;
16194 } else { 16198 } else {
16195 // The place for the current element is occupied. Leave the element 16199 // The place for the current element is occupied. Leave the element
16196 // for the next probe. 16200 // for the next probe.
16197 done = false; 16201 done = false;
16198 } 16202 }
16199 } 16203 }
16200 } 16204 }
16201 } 16205 }
16202 // Wipe deleted entries. 16206 // Wipe deleted entries.
16203 Heap* heap = GetHeap(); 16207 Object* the_hole = isolate->heap()->the_hole_value();
16204 Object* the_hole = heap->the_hole_value(); 16208 Object* undefined = isolate->heap()->undefined_value();
16205 Object* undefined = heap->undefined_value();
16206 for (uint32_t current = 0; current < capacity; current++) { 16209 for (uint32_t current = 0; current < capacity; current++) {
16207 if (get(EntryToIndex(current)) == the_hole) { 16210 if (get(EntryToIndex(current)) == the_hole) {
16208 set(EntryToIndex(current), undefined); 16211 set(EntryToIndex(current), undefined);
16209 } 16212 }
16210 } 16213 }
16211 SetNumberOfDeletedElements(0); 16214 SetNumberOfDeletedElements(0);
16212 } 16215 }
16213 16216
16214 16217
16215 template<typename Derived, typename Shape, typename Key> 16218 template<typename Derived, typename Shape, typename Key>
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
16286 return new_table; 16289 return new_table;
16287 } 16290 }
16288 16291
16289 16292
16290 template<typename Derived, typename Shape, typename Key> 16293 template<typename Derived, typename Shape, typename Key>
16291 uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) { 16294 uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) {
16292 uint32_t capacity = Capacity(); 16295 uint32_t capacity = Capacity();
16293 uint32_t entry = FirstProbe(hash, capacity); 16296 uint32_t entry = FirstProbe(hash, capacity);
16294 uint32_t count = 1; 16297 uint32_t count = 1;
16295 // EnsureCapacity will guarantee the hash table is never full. 16298 // EnsureCapacity will guarantee the hash table is never full.
16296 Heap* heap = GetHeap(); 16299 Isolate* isolate = GetIsolate();
16297 Object* the_hole = heap->the_hole_value();
16298 Object* undefined = heap->undefined_value();
16299 while (true) { 16300 while (true) {
16300 Object* element = KeyAt(entry); 16301 Object* element = KeyAt(entry);
16301 if (element == the_hole || element == undefined) break; 16302 if (!IsKey(isolate, element)) break;
16302 entry = NextProbe(entry, count++, capacity); 16303 entry = NextProbe(entry, count++, capacity);
16303 } 16304 }
16304 return entry; 16305 return entry;
16305 } 16306 }
16306 16307
16307 16308
16308 // Force instantiation of template instances class. 16309 // Force instantiation of template instances class.
16309 // Please note this list is compiler dependent. 16310 // Please note this list is compiler dependent.
16310 16311
16311 template class HashTable<StringTable, StringTableShape, HashTableKey*>; 16312 template class HashTable<StringTable, StringTableShape, HashTableKey*>;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
16483 16484
16484 uint32_t pos = 0; 16485 uint32_t pos = 0;
16485 uint32_t undefs = 0; 16486 uint32_t undefs = 0;
16486 int capacity = dict->Capacity(); 16487 int capacity = dict->Capacity();
16487 Handle<Smi> bailout(Smi::FromInt(-1), isolate); 16488 Handle<Smi> bailout(Smi::FromInt(-1), isolate);
16488 // Entry to the new dictionary does not cause it to grow, as we have 16489 // Entry to the new dictionary does not cause it to grow, as we have
16489 // allocated one that is large enough for all entries. 16490 // allocated one that is large enough for all entries.
16490 DisallowHeapAllocation no_gc; 16491 DisallowHeapAllocation no_gc;
16491 for (int i = 0; i < capacity; i++) { 16492 for (int i = 0; i < capacity; i++) {
16492 Object* k = dict->KeyAt(i); 16493 Object* k = dict->KeyAt(i);
16493 if (!dict->IsKey(k)) continue; 16494 if (!dict->IsKey(isolate, k)) continue;
16494 16495
16495 DCHECK(k->IsNumber()); 16496 DCHECK(k->IsNumber());
16496 DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0); 16497 DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0);
16497 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); 16498 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0);
16498 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); 16499 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32);
16499 16500
16500 HandleScope scope(isolate); 16501 HandleScope scope(isolate);
16501 Handle<Object> value(dict->ValueAt(i), isolate); 16502 Handle<Object> value(dict->ValueAt(i), isolate);
16502 PropertyDetails details = dict->DetailsAt(i); 16503 PropertyDetails details = dict->DetailsAt(i);
16503 if (details.type() == ACCESSOR_CONSTANT || details.IsReadOnly()) { 16504 if (details.type() == ACCESSOR_CONSTANT || details.IsReadOnly()) {
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after
17122 17123
17123 // Initialize the next enumeration index. 17124 // Initialize the next enumeration index.
17124 dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex); 17125 dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
17125 return dict; 17126 return dict;
17126 } 17127 }
17127 17128
17128 17129
17129 template <typename Derived, typename Shape, typename Key> 17130 template <typename Derived, typename Shape, typename Key>
17130 Handle<FixedArray> Dictionary<Derived, Shape, Key>::BuildIterationIndicesArray( 17131 Handle<FixedArray> Dictionary<Derived, Shape, Key>::BuildIterationIndicesArray(
17131 Handle<Derived> dictionary) { 17132 Handle<Derived> dictionary) {
17132 Factory* factory = dictionary->GetIsolate()->factory(); 17133 Isolate* isolate = dictionary->GetIsolate();
17134 Factory* factory = isolate->factory();
17133 int length = dictionary->NumberOfElements(); 17135 int length = dictionary->NumberOfElements();
17134 17136
17135 Handle<FixedArray> iteration_order = factory->NewFixedArray(length); 17137 Handle<FixedArray> iteration_order = factory->NewFixedArray(length);
17136 Handle<FixedArray> enumeration_order = factory->NewFixedArray(length); 17138 Handle<FixedArray> enumeration_order = factory->NewFixedArray(length);
17137 17139
17138 // Fill both the iteration order array and the enumeration order array 17140 // Fill both the iteration order array and the enumeration order array
17139 // with property details. 17141 // with property details.
17140 int capacity = dictionary->Capacity(); 17142 int capacity = dictionary->Capacity();
17141 int pos = 0; 17143 int pos = 0;
17142 for (int i = 0; i < capacity; i++) { 17144 for (int i = 0; i < capacity; i++) {
17143 if (dictionary->IsKey(dictionary->KeyAt(i))) { 17145 if (dictionary->IsKey(isolate, dictionary->KeyAt(i))) {
17144 int index = dictionary->DetailsAt(i).dictionary_index(); 17146 int index = dictionary->DetailsAt(i).dictionary_index();
17145 iteration_order->set(pos, Smi::FromInt(i)); 17147 iteration_order->set(pos, Smi::FromInt(i));
17146 enumeration_order->set(pos, Smi::FromInt(index)); 17148 enumeration_order->set(pos, Smi::FromInt(index));
17147 pos++; 17149 pos++;
17148 } 17150 }
17149 } 17151 }
17150 DCHECK(pos == length); 17152 DCHECK(pos == length);
17151 17153
17152 // Sort the arrays wrt. enumeration order. 17154 // Sort the arrays wrt. enumeration order.
17153 iteration_order->SortPairs(*enumeration_order, enumeration_order->length()); 17155 iteration_order->SortPairs(*enumeration_order, enumeration_order->length());
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
17280 dictionary->SetNextEnumerationIndex(index + 1); 17282 dictionary->SetNextEnumerationIndex(index + 1);
17281 } 17283 }
17282 dictionary->SetEntry(entry, k, value, details); 17284 dictionary->SetEntry(entry, k, value, details);
17283 DCHECK((dictionary->KeyAt(entry)->IsNumber() || 17285 DCHECK((dictionary->KeyAt(entry)->IsNumber() ||
17284 dictionary->KeyAt(entry)->IsName())); 17286 dictionary->KeyAt(entry)->IsName()));
17285 dictionary->ElementAdded(); 17287 dictionary->ElementAdded();
17286 } 17288 }
17287 17289
17288 bool SeededNumberDictionary::HasComplexElements() { 17290 bool SeededNumberDictionary::HasComplexElements() {
17289 if (!requires_slow_elements()) return false; 17291 if (!requires_slow_elements()) return false;
17292 Isolate* isolate = this->GetIsolate();
17290 int capacity = this->Capacity(); 17293 int capacity = this->Capacity();
17291 for (int i = 0; i < capacity; i++) { 17294 for (int i = 0; i < capacity; i++) {
17292 Object* k = this->KeyAt(i); 17295 Object* k = this->KeyAt(i);
17293 if (this->IsKey(k)) { 17296 if (!this->IsKey(isolate, k)) continue;
17294 DCHECK(!IsDeleted(i)); 17297 DCHECK(!IsDeleted(i));
17295 PropertyDetails details = this->DetailsAt(i); 17298 PropertyDetails details = this->DetailsAt(i);
17296 if (details.type() == ACCESSOR_CONSTANT) return true; 17299 if (details.type() == ACCESSOR_CONSTANT) return true;
17297 PropertyAttributes attr = details.attributes(); 17300 PropertyAttributes attr = details.attributes();
17298 if (attr & ALL_ATTRIBUTES_MASK) return true; 17301 if (attr & ALL_ATTRIBUTES_MASK) return true;
17299 }
17300 } 17302 }
17301 return false; 17303 return false;
17302 } 17304 }
17303 17305
17304 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key, 17306 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key,
17305 bool used_as_prototype) { 17307 bool used_as_prototype) {
17306 DisallowHeapAllocation no_allocation; 17308 DisallowHeapAllocation no_allocation;
17307 // If the dictionary requires slow elements an element has already 17309 // If the dictionary requires slow elements an element has already
17308 // been added at a high index. 17310 // been added at a high index.
17309 if (requires_slow_elements()) return; 17311 if (requires_slow_elements()) return;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
17385 Handle<Object> object_key = 17387 Handle<Object> object_key =
17386 UnseededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key); 17388 UnseededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key);
17387 dictionary->SetEntry(entry, object_key, value); 17389 dictionary->SetEntry(entry, object_key, value);
17388 return dictionary; 17390 return dictionary;
17389 } 17391 }
17390 17392
17391 17393
17392 template <typename Derived, typename Shape, typename Key> 17394 template <typename Derived, typename Shape, typename Key>
17393 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( 17395 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes(
17394 PropertyFilter filter) { 17396 PropertyFilter filter) {
17397 Isolate* isolate = this->GetIsolate();
17395 int capacity = this->Capacity(); 17398 int capacity = this->Capacity();
17396 int result = 0; 17399 int result = 0;
17397 for (int i = 0; i < capacity; i++) { 17400 for (int i = 0; i < capacity; i++) {
17398 Object* k = this->KeyAt(i); 17401 Object* k = this->KeyAt(i);
17399 if (this->IsKey(k) && !k->FilterKey(filter)) { 17402 if (this->IsKey(isolate, k) && !k->FilterKey(filter)) {
17400 if (this->IsDeleted(i)) continue; 17403 if (this->IsDeleted(i)) continue;
17401 PropertyDetails details = this->DetailsAt(i); 17404 PropertyDetails details = this->DetailsAt(i);
17402 PropertyAttributes attr = details.attributes(); 17405 PropertyAttributes attr = details.attributes();
17403 if ((attr & filter) == 0) result++; 17406 if ((attr & filter) == 0) result++;
17404 } 17407 }
17405 } 17408 }
17406 return result; 17409 return result;
17407 } 17410 }
17408 17411
17409 17412
17410 template <typename Dictionary> 17413 template <typename Dictionary>
17411 struct EnumIndexComparator { 17414 struct EnumIndexComparator {
17412 explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {} 17415 explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {}
17413 bool operator() (Smi* a, Smi* b) { 17416 bool operator() (Smi* a, Smi* b) {
17414 PropertyDetails da(dict->DetailsAt(a->value())); 17417 PropertyDetails da(dict->DetailsAt(a->value()));
17415 PropertyDetails db(dict->DetailsAt(b->value())); 17418 PropertyDetails db(dict->DetailsAt(b->value()));
17416 return da.dictionary_index() < db.dictionary_index(); 17419 return da.dictionary_index() < db.dictionary_index();
17417 } 17420 }
17418 Dictionary* dict; 17421 Dictionary* dict;
17419 }; 17422 };
17420 17423
17421 17424
17422 template <typename Derived, typename Shape, typename Key> 17425 template <typename Derived, typename Shape, typename Key>
17423 void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) { 17426 void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) {
17427 Isolate* isolate = this->GetIsolate();
17424 int length = storage->length(); 17428 int length = storage->length();
17425 int capacity = this->Capacity(); 17429 int capacity = this->Capacity();
17426 int properties = 0; 17430 int properties = 0;
17427 for (int i = 0; i < capacity; i++) { 17431 for (int i = 0; i < capacity; i++) {
17428 Object* k = this->KeyAt(i); 17432 Object* k = this->KeyAt(i);
17429 if (this->IsKey(k) && !k->IsSymbol()) { 17433 if (this->IsKey(isolate, k) && !k->IsSymbol()) {
17430 PropertyDetails details = this->DetailsAt(i); 17434 PropertyDetails details = this->DetailsAt(i);
17431 if (details.IsDontEnum() || this->IsDeleted(i)) continue; 17435 if (details.IsDontEnum() || this->IsDeleted(i)) continue;
17432 storage->set(properties, Smi::FromInt(i)); 17436 storage->set(properties, Smi::FromInt(i));
17433 properties++; 17437 properties++;
17434 if (properties == length) break; 17438 if (properties == length) break;
17435 } 17439 }
17436 } 17440 }
17437 CHECK_EQ(length, properties); 17441 CHECK_EQ(length, properties);
17438 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(this)); 17442 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(this));
17439 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); 17443 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress());
17440 std::sort(start, start + length, cmp); 17444 std::sort(start, start + length, cmp);
17441 for (int i = 0; i < length; i++) { 17445 for (int i = 0; i < length; i++) {
17442 int index = Smi::cast(storage->get(i))->value(); 17446 int index = Smi::cast(storage->get(i))->value();
17443 storage->set(i, this->KeyAt(index)); 17447 storage->set(i, this->KeyAt(index));
17444 } 17448 }
17445 } 17449 }
17446 17450
17447 template <typename Derived, typename Shape, typename Key> 17451 template <typename Derived, typename Shape, typename Key>
17448 void Dictionary<Derived, Shape, Key>::CollectKeysTo( 17452 void Dictionary<Derived, Shape, Key>::CollectKeysTo(
17449 Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys, 17453 Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys,
17450 PropertyFilter filter) { 17454 PropertyFilter filter) {
17455 Isolate* isolate = keys->isolate();
17451 int capacity = dictionary->Capacity(); 17456 int capacity = dictionary->Capacity();
17452 Handle<FixedArray> array = 17457 Handle<FixedArray> array =
17453 keys->isolate()->factory()->NewFixedArray(dictionary->NumberOfElements()); 17458 isolate->factory()->NewFixedArray(dictionary->NumberOfElements());
17454 int array_size = 0; 17459 int array_size = 0;
17455 17460
17456 { 17461 {
17457 DisallowHeapAllocation no_gc; 17462 DisallowHeapAllocation no_gc;
17458 Dictionary<Derived, Shape, Key>* raw_dict = *dictionary; 17463 Dictionary<Derived, Shape, Key>* raw_dict = *dictionary;
17459 for (int i = 0; i < capacity; i++) { 17464 for (int i = 0; i < capacity; i++) {
17460 Object* k = raw_dict->KeyAt(i); 17465 Object* k = raw_dict->KeyAt(i);
17461 if (!raw_dict->IsKey(k) || k->FilterKey(filter)) continue; 17466 if (!raw_dict->IsKey(isolate, k) || k->FilterKey(filter)) continue;
17462 if (raw_dict->IsDeleted(i)) continue; 17467 if (raw_dict->IsDeleted(i)) continue;
17463 PropertyDetails details = raw_dict->DetailsAt(i); 17468 PropertyDetails details = raw_dict->DetailsAt(i);
17464 if ((details.attributes() & filter) != 0) continue; 17469 if ((details.attributes() & filter) != 0) continue;
17465 if (filter & ONLY_ALL_CAN_READ) { 17470 if (filter & ONLY_ALL_CAN_READ) {
17466 if (details.kind() != kAccessor) continue; 17471 if (details.kind() != kAccessor) continue;
17467 Object* accessors = raw_dict->ValueAt(i); 17472 Object* accessors = raw_dict->ValueAt(i);
17468 if (accessors->IsPropertyCell()) { 17473 if (accessors->IsPropertyCell()) {
17469 accessors = PropertyCell::cast(accessors)->value(); 17474 accessors = PropertyCell::cast(accessors)->value();
17470 } 17475 }
17471 if (!accessors->IsAccessorInfo()) continue; 17476 if (!accessors->IsAccessorInfo()) continue;
(...skipping 24 matching lines...) Expand all
17496 if (!key->IsSymbol()) continue; 17501 if (!key->IsSymbol()) continue;
17497 keys->AddKey(key, DO_NOT_CONVERT); 17502 keys->AddKey(key, DO_NOT_CONVERT);
17498 } 17503 }
17499 } 17504 }
17500 } 17505 }
17501 17506
17502 17507
17503 // Backwards lookup (slow). 17508 // Backwards lookup (slow).
17504 template<typename Derived, typename Shape, typename Key> 17509 template<typename Derived, typename Shape, typename Key>
17505 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { 17510 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) {
17511 Isolate* isolate = this->GetIsolate();
17506 int capacity = this->Capacity(); 17512 int capacity = this->Capacity();
17507 for (int i = 0; i < capacity; i++) { 17513 for (int i = 0; i < capacity; i++) {
17508 Object* k = this->KeyAt(i); 17514 Object* k = this->KeyAt(i);
17509 if (this->IsKey(k)) { 17515 if (!this->IsKey(isolate, k)) continue;
17510 Object* e = this->ValueAt(i); 17516 Object* e = this->ValueAt(i);
17511 // TODO(dcarney): this should be templatized. 17517 // TODO(dcarney): this should be templatized.
17512 if (e->IsPropertyCell()) { 17518 if (e->IsPropertyCell()) {
17513 e = PropertyCell::cast(e)->value(); 17519 e = PropertyCell::cast(e)->value();
17514 }
17515 if (e == value) return k;
17516 } 17520 }
17521 if (e == value) return k;
17517 } 17522 }
17518 Heap* heap = Dictionary::GetHeap(); 17523 return isolate->heap()->undefined_value();
17519 return heap->undefined_value();
17520 } 17524 }
17521 17525
17522 17526
17523 Object* ObjectHashTable::Lookup(Isolate* isolate, Handle<Object> key, 17527 Object* ObjectHashTable::Lookup(Isolate* isolate, Handle<Object> key,
17524 int32_t hash) { 17528 int32_t hash) {
17525 DisallowHeapAllocation no_gc; 17529 DisallowHeapAllocation no_gc;
17526 DCHECK(IsKey(*key)); 17530 DCHECK(IsKey(isolate, *key));
17527 17531
17528 int entry = FindEntry(isolate, key, hash); 17532 int entry = FindEntry(isolate, key, hash);
17529 if (entry == kNotFound) return isolate->heap()->the_hole_value(); 17533 if (entry == kNotFound) return isolate->heap()->the_hole_value();
17530 return get(EntryToIndex(entry) + 1); 17534 return get(EntryToIndex(entry) + 1);
17531 } 17535 }
17532 17536
17533 17537
17534 Object* ObjectHashTable::Lookup(Handle<Object> key) { 17538 Object* ObjectHashTable::Lookup(Handle<Object> key) {
17535 DisallowHeapAllocation no_gc; 17539 DisallowHeapAllocation no_gc;
17536 DCHECK(IsKey(*key));
17537 17540
17538 Isolate* isolate = GetIsolate(); 17541 Isolate* isolate = GetIsolate();
17542 DCHECK(IsKey(isolate, *key));
17539 17543
17540 // If the object does not have an identity hash, it was never used as a key. 17544 // If the object does not have an identity hash, it was never used as a key.
17541 Object* hash = key->GetHash(); 17545 Object* hash = key->GetHash();
17542 if (hash->IsUndefined(isolate)) { 17546 if (hash->IsUndefined(isolate)) {
17543 return isolate->heap()->the_hole_value(); 17547 return isolate->heap()->the_hole_value();
17544 } 17548 }
17545 return Lookup(isolate, key, Smi::cast(hash)->value()); 17549 return Lookup(isolate, key, Smi::cast(hash)->value());
17546 } 17550 }
17547 17551
17548 17552
17549 Object* ObjectHashTable::Lookup(Handle<Object> key, int32_t hash) { 17553 Object* ObjectHashTable::Lookup(Handle<Object> key, int32_t hash) {
17550 return Lookup(GetIsolate(), key, hash); 17554 return Lookup(GetIsolate(), key, hash);
17551 } 17555 }
17552 17556
17553 17557
17554 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, 17558 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
17555 Handle<Object> key, 17559 Handle<Object> key,
17556 Handle<Object> value) { 17560 Handle<Object> value) {
17557 Isolate* isolate = table->GetIsolate(); 17561 Isolate* isolate = table->GetIsolate();
17558 17562 DCHECK(table->IsKey(isolate, *key));
17559 DCHECK(table->IsKey(*key));
17560 DCHECK(!value->IsTheHole(isolate)); 17563 DCHECK(!value->IsTheHole(isolate));
17561 17564
17562 // Make sure the key object has an identity hash code. 17565 // Make sure the key object has an identity hash code.
17563 int32_t hash = Object::GetOrCreateHash(isolate, key)->value(); 17566 int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
17564 17567
17565 return Put(table, key, value, hash); 17568 return Put(table, key, value, hash);
17566 } 17569 }
17567 17570
17568 17571
17569 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, 17572 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
17570 Handle<Object> key, 17573 Handle<Object> key,
17571 Handle<Object> value, 17574 Handle<Object> value,
17572 int32_t hash) { 17575 int32_t hash) {
17573 Isolate* isolate = table->GetIsolate(); 17576 Isolate* isolate = table->GetIsolate();
17574 17577 DCHECK(table->IsKey(isolate, *key));
17575 DCHECK(table->IsKey(*key));
17576 DCHECK(!value->IsTheHole(isolate)); 17578 DCHECK(!value->IsTheHole(isolate));
17577 17579
17578 int entry = table->FindEntry(isolate, key, hash); 17580 int entry = table->FindEntry(isolate, key, hash);
17579 17581
17580 // Key is already in table, just overwrite value. 17582 // Key is already in table, just overwrite value.
17581 if (entry != kNotFound) { 17583 if (entry != kNotFound) {
17582 table->set(EntryToIndex(entry) + 1, *value); 17584 table->set(EntryToIndex(entry) + 1, *value);
17583 return table; 17585 return table;
17584 } 17586 }
17585 17587
17586 // Rehash if more than 33% of the entries are deleted entries. 17588 // Rehash if more than 33% of the entries are deleted entries.
17587 // TODO(jochen): Consider to shrink the fixed array in place. 17589 // TODO(jochen): Consider to shrink the fixed array in place.
17588 if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) { 17590 if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) {
17589 table->Rehash(isolate->factory()->undefined_value()); 17591 table->Rehash(isolate->factory()->undefined_value());
17590 } 17592 }
17591 17593
17592 // Check whether the hash table should be extended. 17594 // Check whether the hash table should be extended.
17593 table = EnsureCapacity(table, 1, key); 17595 table = EnsureCapacity(table, 1, key);
17594 table->AddEntry(table->FindInsertionEntry(hash), *key, *value); 17596 table->AddEntry(table->FindInsertionEntry(hash), *key, *value);
17595 return table; 17597 return table;
17596 } 17598 }
17597 17599
17598 17600
17599 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, 17601 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table,
17600 Handle<Object> key, 17602 Handle<Object> key,
17601 bool* was_present) { 17603 bool* was_present) {
17602 DCHECK(table->IsKey(*key)); 17604 DCHECK(table->IsKey(table->GetIsolate(), *key));
17603 17605
17604 Object* hash = key->GetHash(); 17606 Object* hash = key->GetHash();
17605 if (hash->IsUndefined(table->GetIsolate())) { 17607 if (hash->IsUndefined(table->GetIsolate())) {
17606 *was_present = false; 17608 *was_present = false;
17607 return table; 17609 return table;
17608 } 17610 }
17609 17611
17610 return Remove(table, key, was_present, Smi::cast(hash)->value()); 17612 return Remove(table, key, was_present, Smi::cast(hash)->value());
17611 } 17613 }
17612 17614
17613 17615
17614 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, 17616 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table,
17615 Handle<Object> key, 17617 Handle<Object> key,
17616 bool* was_present, 17618 bool* was_present,
17617 int32_t hash) { 17619 int32_t hash) {
17618 DCHECK(table->IsKey(*key)); 17620 Isolate* isolate = table->GetIsolate();
17621 DCHECK(table->IsKey(isolate, *key));
17619 17622
17620 int entry = table->FindEntry(table->GetIsolate(), key, hash); 17623 int entry = table->FindEntry(isolate, key, hash);
17621 if (entry == kNotFound) { 17624 if (entry == kNotFound) {
17622 *was_present = false; 17625 *was_present = false;
17623 return table; 17626 return table;
17624 } 17627 }
17625 17628
17626 *was_present = true; 17629 *was_present = true;
17627 table->RemoveEntry(entry); 17630 table->RemoveEntry(entry);
17628 return Shrink(table, key); 17631 return Shrink(table, key);
17629 } 17632 }
17630 17633
17631 17634
17632 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { 17635 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
17633 set(EntryToIndex(entry), key); 17636 set(EntryToIndex(entry), key);
17634 set(EntryToIndex(entry) + 1, value); 17637 set(EntryToIndex(entry) + 1, value);
17635 ElementAdded(); 17638 ElementAdded();
17636 } 17639 }
17637 17640
17638 17641
17639 void ObjectHashTable::RemoveEntry(int entry) { 17642 void ObjectHashTable::RemoveEntry(int entry) {
17640 set_the_hole(EntryToIndex(entry)); 17643 set_the_hole(EntryToIndex(entry));
17641 set_the_hole(EntryToIndex(entry) + 1); 17644 set_the_hole(EntryToIndex(entry) + 1);
17642 ElementRemoved(); 17645 ElementRemoved();
17643 } 17646 }
17644 17647
17645 17648
17646 Object* WeakHashTable::Lookup(Handle<HeapObject> key) { 17649 Object* WeakHashTable::Lookup(Handle<HeapObject> key) {
17647 DisallowHeapAllocation no_gc; 17650 DisallowHeapAllocation no_gc;
17648 DCHECK(IsKey(*key)); 17651 Isolate* isolate = GetIsolate();
17652 DCHECK(IsKey(isolate, *key));
17649 int entry = FindEntry(key); 17653 int entry = FindEntry(key);
17650 if (entry == kNotFound) return GetHeap()->the_hole_value(); 17654 if (entry == kNotFound) return isolate->heap()->the_hole_value();
17651 return get(EntryToValueIndex(entry)); 17655 return get(EntryToValueIndex(entry));
17652 } 17656 }
17653 17657
17654 17658
17655 Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table, 17659 Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table,
17656 Handle<HeapObject> key, 17660 Handle<HeapObject> key,
17657 Handle<HeapObject> value) { 17661 Handle<HeapObject> value) {
17658 DCHECK(table->IsKey(*key)); 17662 Isolate* isolate = key->GetIsolate();
17663 DCHECK(table->IsKey(isolate, *key));
17659 int entry = table->FindEntry(key); 17664 int entry = table->FindEntry(key);
17660 // Key is already in table, just overwrite value. 17665 // Key is already in table, just overwrite value.
17661 if (entry != kNotFound) { 17666 if (entry != kNotFound) {
17662 table->set(EntryToValueIndex(entry), *value); 17667 table->set(EntryToValueIndex(entry), *value);
17663 return table; 17668 return table;
17664 } 17669 }
17665 17670
17666 Handle<WeakCell> key_cell = key->GetIsolate()->factory()->NewWeakCell(key); 17671 Handle<WeakCell> key_cell = isolate->factory()->NewWeakCell(key);
17667 17672
17668 // Check whether the hash table should be extended. 17673 // Check whether the hash table should be extended.
17669 table = EnsureCapacity(table, 1, key, TENURED); 17674 table = EnsureCapacity(table, 1, key, TENURED);
17670 17675
17671 table->AddEntry(table->FindInsertionEntry(table->Hash(key)), key_cell, value); 17676 table->AddEntry(table->FindInsertionEntry(table->Hash(key)), key_cell, value);
17672 return table; 17677 return table;
17673 } 17678 }
17674 17679
17675 17680
17676 void WeakHashTable::AddEntry(int entry, Handle<WeakCell> key_cell, 17681 void WeakHashTable::AddEntry(int entry, Handle<WeakCell> key_cell,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
17750 17755
17751 table->SetNextTable(*new_table); 17756 table->SetNextTable(*new_table);
17752 table->SetNumberOfDeletedElements(kClearedTableSentinel); 17757 table->SetNumberOfDeletedElements(kClearedTableSentinel);
17753 17758
17754 return new_table; 17759 return new_table;
17755 } 17760 }
17756 17761
17757 template <class Derived, class Iterator, int entrysize> 17762 template <class Derived, class Iterator, int entrysize>
17758 bool OrderedHashTable<Derived, Iterator, entrysize>::HasKey( 17763 bool OrderedHashTable<Derived, Iterator, entrysize>::HasKey(
17759 Handle<Derived> table, Handle<Object> key) { 17764 Handle<Derived> table, Handle<Object> key) {
17760 int entry = table->KeyToFirstEntry(*key); 17765 DisallowHeapAllocation no_gc;
17766 Isolate* isolate = table->GetIsolate();
17767 Object* raw_key = *key;
17768 int entry = table->KeyToFirstEntry(isolate, raw_key);
17761 // Walk the chain in the bucket to find the key. 17769 // Walk the chain in the bucket to find the key.
17762 while (entry != kNotFound) { 17770 while (entry != kNotFound) {
17763 Object* candidate_key = table->KeyAt(entry); 17771 Object* candidate_key = table->KeyAt(entry);
17764 if (candidate_key->SameValueZero(*key)) return true; 17772 if (candidate_key->SameValueZero(raw_key)) return true;
17765 entry = table->NextChainEntry(entry); 17773 entry = table->NextChainEntry(entry);
17766 } 17774 }
17767 return false; 17775 return false;
17768 } 17776 }
17769 17777
17770 17778
17771 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table, 17779 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table,
17772 Handle<Object> key) { 17780 Handle<Object> key) {
17773 int hash = Object::GetOrCreateHash(table->GetIsolate(), key)->value(); 17781 int hash = Object::GetOrCreateHash(table->GetIsolate(), key)->value();
17774 int entry = table->HashToEntry(hash); 17782 int entry = table->HashToEntry(hash);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
17814 result->set(i, key); 17822 result->set(i, key);
17815 } 17823 }
17816 result->Shrink(length); 17824 result->Shrink(length);
17817 return result; 17825 return result;
17818 } 17826 }
17819 17827
17820 template<class Derived, class Iterator, int entrysize> 17828 template<class Derived, class Iterator, int entrysize>
17821 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( 17829 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash(
17822 Handle<Derived> table, int new_capacity) { 17830 Handle<Derived> table, int new_capacity) {
17823 Isolate* isolate = table->GetIsolate(); 17831 Isolate* isolate = table->GetIsolate();
17824 Heap* heap = isolate->heap();
17825 DCHECK(!table->IsObsolete()); 17832 DCHECK(!table->IsObsolete());
17826 17833
17827 Handle<Derived> new_table = Allocate( 17834 Handle<Derived> new_table =
17828 isolate, new_capacity, heap->InNewSpace(*table) ? NOT_TENURED : TENURED); 17835 Allocate(isolate, new_capacity,
17836 isolate->heap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
17829 int nof = table->NumberOfElements(); 17837 int nof = table->NumberOfElements();
17830 int nod = table->NumberOfDeletedElements(); 17838 int nod = table->NumberOfDeletedElements();
17831 int new_buckets = new_table->NumberOfBuckets(); 17839 int new_buckets = new_table->NumberOfBuckets();
17832 int new_entry = 0; 17840 int new_entry = 0;
17833 int removed_holes_index = 0; 17841 int removed_holes_index = 0;
17834 17842
17835 DisallowHeapAllocation no_gc; 17843 DisallowHeapAllocation no_gc;
17836 Object* the_hole = heap->the_hole_value();
17837 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) { 17844 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) {
17838 Object* key = table->KeyAt(old_entry); 17845 Object* key = table->KeyAt(old_entry);
17839 if (key == the_hole) { 17846 if (key->IsTheHole(isolate)) {
17840 table->SetRemovedIndexAt(removed_holes_index++, old_entry); 17847 table->SetRemovedIndexAt(removed_holes_index++, old_entry);
17841 continue; 17848 continue;
17842 } 17849 }
17843 17850
17844 Object* hash = key->GetHash(); 17851 Object* hash = key->GetHash();
17845 int bucket = Smi::cast(hash)->value() & (new_buckets - 1); 17852 int bucket = Smi::cast(hash)->value() & (new_buckets - 1);
17846 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket); 17853 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket);
17847 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry)); 17854 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
17848 int new_index = new_table->EntryToIndex(new_entry); 17855 int new_index = new_table->EntryToIndex(new_entry);
17849 int old_index = table->EntryToIndex(old_entry); 17856 int old_index = table->EntryToIndex(old_entry);
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after
18774 if (cell->value() != *new_value) { 18781 if (cell->value() != *new_value) {
18775 cell->set_value(*new_value); 18782 cell->set_value(*new_value);
18776 Isolate* isolate = cell->GetIsolate(); 18783 Isolate* isolate = cell->GetIsolate();
18777 cell->dependent_code()->DeoptimizeDependentCodeGroup( 18784 cell->dependent_code()->DeoptimizeDependentCodeGroup(
18778 isolate, DependentCode::kPropertyCellChangedGroup); 18785 isolate, DependentCode::kPropertyCellChangedGroup);
18779 } 18786 }
18780 } 18787 }
18781 18788
18782 } // namespace internal 18789 } // namespace internal
18783 } // namespace v8 18790 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698