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

Side by Side Diff: src/objects.cc

Issue 10827040: Limit initial size of hidden properties and store identity hashes inline. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix comments in test cases Created 8 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 2742 matching lines...) Expand 10 before | Expand all | Expand 10 after
2753 // Code will be set on the JavaScript side. 2753 // Code will be set on the JavaScript side.
2754 } else { 2754 } else {
2755 isolate->factory()->BecomeJSObject(self); 2755 isolate->factory()->BecomeJSObject(self);
2756 } 2756 }
2757 ASSERT(self->IsJSObject()); 2757 ASSERT(self->IsJSObject());
2758 2758
2759 // Inherit identity, if it was present. 2759 // Inherit identity, if it was present.
2760 Object* hash; 2760 Object* hash;
2761 if (maybe_hash->To<Object>(&hash) && hash->IsSmi()) { 2761 if (maybe_hash->To<Object>(&hash) && hash->IsSmi()) {
2762 Handle<JSObject> new_self(JSObject::cast(*self)); 2762 Handle<JSObject> new_self(JSObject::cast(*self));
2763 isolate->factory()->SetIdentityHash(new_self, hash); 2763 isolate->factory()->SetIdentityHash(new_self, Smi::cast(hash));
2764 } 2764 }
2765 } 2765 }
2766 2766
2767 2767
2768 MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(const char* name, 2768 MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(const char* name,
2769 Handle<Object> derived, 2769 Handle<Object> derived,
2770 int argc, 2770 int argc,
2771 Handle<Object> argv[]) { 2771 Handle<Object> argv[]) {
2772 Isolate* isolate = GetIsolate(); 2772 Isolate* isolate = GetIsolate();
2773 Handle<Object> handler(this->handler()); 2773 Handle<Object> handler(this->handler());
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
3497 // within a smi. 3497 // within a smi.
3498 hash_value = V8::RandomPrivate(isolate) & Smi::kMaxValue; 3498 hash_value = V8::RandomPrivate(isolate) & Smi::kMaxValue;
3499 attempts++; 3499 attempts++;
3500 } while (hash_value == 0 && attempts < 30); 3500 } while (hash_value == 0 && attempts < 30);
3501 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 3501 hash_value = hash_value != 0 ? hash_value : 1; // never return 0
3502 3502
3503 return Smi::FromInt(hash_value); 3503 return Smi::FromInt(hash_value);
3504 } 3504 }
3505 3505
3506 3506
3507 MaybeObject* JSObject::SetIdentityHash(Object* hash, CreationFlag flag) { 3507 MaybeObject* JSObject::SetIdentityHash(Smi* hash, CreationFlag flag) {
3508 MaybeObject* maybe = SetHiddenProperty(GetHeap()->identity_hash_symbol(), 3508 MaybeObject* maybe = SetHiddenProperty(GetHeap()->identity_hash_symbol(),
3509 hash); 3509 hash);
3510 if (maybe->IsFailure()) return maybe; 3510 if (maybe->IsFailure()) return maybe;
3511 return this; 3511 return this;
3512 } 3512 }
3513 3513
3514 3514
3515 int JSObject::GetIdentityHash(Handle<JSObject> obj) { 3515 int JSObject::GetIdentityHash(Handle<JSObject> obj) {
3516 CALL_AND_RETRY(obj->GetIsolate(), 3516 CALL_AND_RETRY(obj->GetIsolate(),
3517 obj->GetIdentityHash(ALLOW_CREATION), 3517 obj->GetIdentityHash(ALLOW_CREATION),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3552 Object* JSObject::GetHiddenProperty(String* key) { 3552 Object* JSObject::GetHiddenProperty(String* key) {
3553 if (IsJSGlobalProxy()) { 3553 if (IsJSGlobalProxy()) {
3554 // For a proxy, use the prototype as target object. 3554 // For a proxy, use the prototype as target object.
3555 Object* proxy_parent = GetPrototype(); 3555 Object* proxy_parent = GetPrototype();
3556 // If the proxy is detached, return undefined. 3556 // If the proxy is detached, return undefined.
3557 if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); 3557 if (proxy_parent->IsNull()) return GetHeap()->undefined_value();
3558 ASSERT(proxy_parent->IsJSGlobalObject()); 3558 ASSERT(proxy_parent->IsJSGlobalObject());
3559 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); 3559 return JSObject::cast(proxy_parent)->GetHiddenProperty(key);
3560 } 3560 }
3561 ASSERT(!IsJSGlobalProxy()); 3561 ASSERT(!IsJSGlobalProxy());
3562 MaybeObject* hidden_lookup = GetHiddenPropertiesDictionary(false); 3562 MaybeObject* hidden_lookup = GetHiddenPropertiesHashTable(false);
Toon Verwaest 2012/07/30 09:13:23 Can we make an enum out of the bool argument?
3563 ASSERT(!hidden_lookup->IsFailure()); // No failure when passing false as arg. 3563 ASSERT(!hidden_lookup->IsFailure()); // No failure when passing false as arg.
3564 Object* inline_value = hidden_lookup->ToObjectUnchecked();
3565
3566 if (inline_value->IsSmi()) {
3567 // Handle inline-stored identity hash.
3568 if (key == GetHeap()->identity_hash_symbol()) {
3569 return inline_value;
3570 } else {
3571 return GetHeap()->undefined_value();
3572 }
3573 }
3574
3564 if (hidden_lookup->ToObjectUnchecked()->IsUndefined()) { 3575 if (hidden_lookup->ToObjectUnchecked()->IsUndefined()) {
Toon Verwaest 2012/07/30 09:13:23 Replace hidden_lookup->ToObjectUnchecked() by inli
3565 return GetHeap()->undefined_value(); 3576 return GetHeap()->undefined_value();
3566 } 3577 }
3567 StringDictionary* dictionary = 3578
3568 StringDictionary::cast(hidden_lookup->ToObjectUnchecked()); 3579 ObjectHashTable* hashtable =
3569 int entry = dictionary->FindEntry(key); 3580 ObjectHashTable::cast(hidden_lookup->ToObjectUnchecked());
Toon Verwaest 2012/07/30 09:13:23 Replace hidden_lookup->ToObjectUnchecked() by inli
3570 if (entry == StringDictionary::kNotFound) return GetHeap()->undefined_value(); 3581 Object* entry = hashtable->Lookup(key);
Toon Verwaest 2012/07/30 09:13:23 The API for hidden values does not convert strings
3571 return dictionary->ValueAt(entry); 3582 if (entry->IsTheHole()) return GetHeap()->undefined_value();
3583 return entry;
3572 } 3584 }
3573 3585
3574 3586
3575 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj, 3587 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj,
3576 Handle<String> key, 3588 Handle<String> key,
3577 Handle<Object> value) { 3589 Handle<Object> value) {
3578 CALL_HEAP_FUNCTION(obj->GetIsolate(), 3590 CALL_HEAP_FUNCTION(obj->GetIsolate(),
3579 obj->SetHiddenProperty(*key, *value), 3591 obj->SetHiddenProperty(*key, *value),
3580 Object); 3592 Object);
3581 } 3593 }
3582 3594
3583 3595
3584 MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) { 3596 MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) {
3585 if (IsJSGlobalProxy()) { 3597 if (IsJSGlobalProxy()) {
3586 // For a proxy, use the prototype as target object. 3598 // For a proxy, use the prototype as target object.
3587 Object* proxy_parent = GetPrototype(); 3599 Object* proxy_parent = GetPrototype();
3588 // If the proxy is detached, return undefined. 3600 // If the proxy is detached, return undefined.
3589 if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); 3601 if (proxy_parent->IsNull()) return GetHeap()->undefined_value();
3590 ASSERT(proxy_parent->IsJSGlobalObject()); 3602 ASSERT(proxy_parent->IsJSGlobalObject());
3591 return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value); 3603 return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value);
3592 } 3604 }
3593 ASSERT(!IsJSGlobalProxy()); 3605 ASSERT(!IsJSGlobalProxy());
3594 MaybeObject* hidden_lookup = GetHiddenPropertiesDictionary(true); 3606
3595 StringDictionary* dictionary; 3607 // If there is no backing store yet, store the identity hash inline.
3596 if (!hidden_lookup->To<StringDictionary>(&dictionary)) return hidden_lookup; 3608 MaybeObject* hidden_lookup = GetHiddenPropertiesHashTable(false);
3609 ASSERT(!hidden_lookup->IsFailure());
3610 Object* inline_value = hidden_lookup->ToObjectUnchecked();
3611
3612 if (value->IsSmi() &&
3613 key == GetHeap()->identity_hash_symbol() &&
3614 (inline_value->IsUndefined() || inline_value->IsSmi())) {
3615 return SetHiddenPropertiesHashTable(value);
3616 }
3617
3618 hidden_lookup = GetHiddenPropertiesHashTable(true);
3619 ObjectHashTable* hashtable;
3620 if (!hidden_lookup->To<ObjectHashTable>(&hashtable)) return hidden_lookup;
Toon Verwaest 2012/07/30 09:13:23 You don't need the <ObjectHashTable> afaik.
3597 3621
3598 // If it was found, check if the key is already in the dictionary. 3622 // If it was found, check if the key is already in the dictionary.
3599 int entry = dictionary->FindEntry(key); 3623 MaybeObject* insert_result = hashtable->Put(key, value);
3600 if (entry != StringDictionary::kNotFound) { 3624 ObjectHashTable* new_table;
3601 // If key was found, just update the value. 3625 if (!insert_result->To<ObjectHashTable>(&new_table)) return insert_result;
Toon Verwaest 2012/07/30 09:13:24 Don't need the <ObjectHashTable>.
3602 dictionary->ValueAtPut(entry, value); 3626 if (new_table != hashtable) {
3603 return this;
3604 }
3605 // Key was not already in the dictionary, so add the entry.
3606 MaybeObject* insert_result = dictionary->Add(key,
3607 value,
3608 PropertyDetails(NONE, NORMAL));
3609 StringDictionary* new_dict;
3610 if (!insert_result->To<StringDictionary>(&new_dict)) return insert_result;
3611 if (new_dict != dictionary) {
3612 // If adding the key expanded the dictionary (i.e., Add returned a new 3627 // If adding the key expanded the dictionary (i.e., Add returned a new
3613 // dictionary), store it back to the object. 3628 // dictionary), store it back to the object.
3614 MaybeObject* store_result = SetHiddenPropertiesDictionary(new_dict); 3629 MaybeObject* store_result = SetHiddenPropertiesHashTable(new_table);
3615 if (store_result->IsFailure()) return store_result; 3630 if (store_result->IsFailure()) return store_result;
3616 } 3631 }
3617 // Return this to mark success. 3632 // Return this to mark success.
3618 return this; 3633 return this;
3619 } 3634 }
3620 3635
3621 3636
3622 void JSObject::DeleteHiddenProperty(String* key) { 3637 void JSObject::DeleteHiddenProperty(String* key) {
3623 if (IsJSGlobalProxy()) { 3638 if (IsJSGlobalProxy()) {
3624 // For a proxy, use the prototype as target object. 3639 // For a proxy, use the prototype as target object.
3625 Object* proxy_parent = GetPrototype(); 3640 Object* proxy_parent = GetPrototype();
3626 // If the proxy is detached, return immediately. 3641 // If the proxy is detached, return immediately.
3627 if (proxy_parent->IsNull()) return; 3642 if (proxy_parent->IsNull()) return;
3628 ASSERT(proxy_parent->IsJSGlobalObject()); 3643 ASSERT(proxy_parent->IsJSGlobalObject());
3629 JSObject::cast(proxy_parent)->DeleteHiddenProperty(key); 3644 JSObject::cast(proxy_parent)->DeleteHiddenProperty(key);
3630 return; 3645 return;
3631 } 3646 }
3632 MaybeObject* hidden_lookup = GetHiddenPropertiesDictionary(false); 3647 MaybeObject* hidden_lookup = GetHiddenPropertiesHashTable(false);
3633 ASSERT(!hidden_lookup->IsFailure()); // No failure when passing false as arg. 3648 ASSERT(!hidden_lookup->IsFailure()); // No failure when passing false as arg.
3634 if (hidden_lookup->ToObjectUnchecked()->IsUndefined()) return; 3649 if (hidden_lookup->ToObjectUnchecked()->IsUndefined()) return;
3635 StringDictionary* dictionary = 3650 // We never delete (inline-stored) identity hashes.
3636 StringDictionary::cast(hidden_lookup->ToObjectUnchecked()); 3651 ASSERT(!hidden_lookup->ToObjectUnchecked()->IsSmi());
3637 int entry = dictionary->FindEntry(key); 3652
3638 if (entry == StringDictionary::kNotFound) { 3653 ObjectHashTable* hashtable =
3639 // Key wasn't in dictionary. Deletion is a success. 3654 ObjectHashTable::cast(hidden_lookup->ToObjectUnchecked());
3640 return; 3655 MaybeObject* delete_result = hashtable->Put(key, GetHeap()->the_hole_value());
3641 } 3656 ASSERT(!delete_result->IsFailure()); // Delete does not cause GC.
3642 // Key was in the dictionary. Remove it.
3643 dictionary->DeleteProperty(entry, JSReceiver::FORCE_DELETION);
3644 } 3657 }
3645 3658
3646 3659
3647 bool JSObject::HasHiddenProperties() { 3660 bool JSObject::HasHiddenProperties() {
3648 return GetPropertyAttributePostInterceptor(this, 3661 return GetPropertyAttributePostInterceptor(this,
3649 GetHeap()->hidden_symbol(), 3662 GetHeap()->hidden_symbol(),
3650 false) != ABSENT; 3663 false) != ABSENT;
3651 } 3664 }
3652 3665
3653 3666
3654 MaybeObject* JSObject::GetHiddenPropertiesDictionary(bool create_if_absent) { 3667 MaybeObject* JSObject::GetHiddenPropertiesHashTable(bool create_if_absent) {
3655 ASSERT(!IsJSGlobalProxy()); 3668 ASSERT(!IsJSGlobalProxy());
3669 Object* inline_value;
3656 if (HasFastProperties()) { 3670 if (HasFastProperties()) {
3657 // If the object has fast properties, check whether the first slot 3671 // If the object has fast properties, check whether the first slot
3658 // in the descriptor array matches the hidden symbol. Since the 3672 // in the descriptor array matches the hidden symbol. Since the
3659 // hidden symbols hash code is zero (and no other string has hash 3673 // hidden symbols hash code is zero (and no other string has hash
3660 // code zero) it will always occupy the first entry if present. 3674 // code zero) it will always occupy the first entry if present.
3661 DescriptorArray* descriptors = this->map()->instance_descriptors(); 3675 DescriptorArray* descriptors = this->map()->instance_descriptors();
3662 if ((descriptors->number_of_descriptors() > 0) && 3676 if ((descriptors->number_of_descriptors() > 0) &&
3663 (descriptors->GetKey(0) == GetHeap()->hidden_symbol())) { 3677 (descriptors->GetKey(0) == GetHeap()->hidden_symbol())) {
3664 ASSERT(descriptors->GetType(0) == FIELD); 3678 ASSERT(descriptors->GetType(0) == FIELD);
3665 Object* hidden_store = 3679 inline_value = this->FastPropertyAt(descriptors->GetFieldIndex(0));
3666 this->FastPropertyAt(descriptors->GetFieldIndex(0)); 3680 } else {
3667 return StringDictionary::cast(hidden_store); 3681 inline_value = GetHeap()->undefined_value();
3668 } 3682 }
3669 } else { 3683 } else {
3670 PropertyAttributes attributes; 3684 PropertyAttributes attributes;
3671 // You can't install a getter on a property indexed by the hidden symbol, 3685 // You can't install a getter on a property indexed by the hidden symbol,
3672 // so we can be sure that GetLocalPropertyPostInterceptor returns a real 3686 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3673 // object. 3687 // object.
3674 Object* lookup = 3688 inline_value =
3675 GetLocalPropertyPostInterceptor(this, 3689 GetLocalPropertyPostInterceptor(this,
3676 GetHeap()->hidden_symbol(), 3690 GetHeap()->hidden_symbol(),
3677 &attributes)->ToObjectUnchecked(); 3691 &attributes)->ToObjectUnchecked();
3678 if (!lookup->IsUndefined()) {
3679 return StringDictionary::cast(lookup);
3680 }
3681 } 3692 }
3682 if (!create_if_absent) return GetHeap()->undefined_value(); 3693
3683 const int kInitialSize = 5; 3694 if (!create_if_absent || inline_value->IsHashTable()) return inline_value;
3684 MaybeObject* dict_alloc = StringDictionary::Allocate(kInitialSize); 3695
3685 StringDictionary* dictionary; 3696 ObjectHashTable* hashtable;
3686 if (!dict_alloc->To<StringDictionary>(&dictionary)) return dict_alloc; 3697 static const int kInitialCapacity = 4;
3698 { MaybeObject* maybe_obj = ObjectHashTable::Allocate(kInitialCapacity, true);
3699 if (!maybe_obj->To<ObjectHashTable>(&hashtable)) return maybe_obj;
3700 }
Toon Verwaest 2012/07/30 09:13:24 Please remove the { ... } around the MaybeObject.
3701
3702 if (inline_value->IsSmi()) {
3703 // We were storing the identity hash inline and now allocated an actual
3704 // dictionary. Put the identity hash into the new dictionary.
3705 MaybeObject* insert_result =
3706 hashtable->Put(GetHeap()->identity_hash_symbol(), inline_value);
3707 ObjectHashTable* new_table;
3708 if (!insert_result->To<ObjectHashTable>(&new_table)) return insert_result;
Toon Verwaest 2012/07/30 09:13:24 Remove the <ObjectHashTable>
3709 // We expect no resizing for the first insert.
3710 ASSERT_EQ(hashtable, new_table);
3711 }
3712
3687 MaybeObject* store_result = 3713 MaybeObject* store_result =
3688 SetPropertyPostInterceptor(GetHeap()->hidden_symbol(), 3714 SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
3689 dictionary, 3715 hashtable,
3690 DONT_ENUM, 3716 DONT_ENUM,
3691 kNonStrictMode, 3717 kNonStrictMode,
3692 OMIT_EXTENSIBILITY_CHECK); 3718 OMIT_EXTENSIBILITY_CHECK);
3693 if (store_result->IsFailure()) return store_result; 3719 if (store_result->IsFailure()) return store_result;
3694 return dictionary; 3720 return hashtable;
3695 } 3721 }
3696 3722
3697 3723
3698 MaybeObject* JSObject::SetHiddenPropertiesDictionary( 3724 MaybeObject* JSObject::SetHiddenPropertiesHashTable(
3699 StringDictionary* dictionary) { 3725 Object* hidden) {
Toon Verwaest 2012/07/30 09:13:24 Can we rename hidden to hidden_properties or so? P
3700 ASSERT(!IsJSGlobalProxy()); 3726 ASSERT(!IsJSGlobalProxy());
3701 ASSERT(HasHiddenProperties()); 3727 ASSERT(HasHiddenProperties() || hidden->IsSmi());
3702 if (HasFastProperties()) { 3728 if (HasFastProperties()) {
3703 // If the object has fast properties, check whether the first slot 3729 // If the object has fast properties, check whether the first slot
3704 // in the descriptor array matches the hidden symbol. Since the 3730 // in the descriptor array matches the hidden symbol. Since the
3705 // hidden symbols hash code is zero (and no other string has hash 3731 // hidden symbols hash code is zero (and no other string has hash
3706 // code zero) it will always occupy the first entry if present. 3732 // code zero) it will always occupy the first entry if present.
3707 DescriptorArray* descriptors = this->map()->instance_descriptors(); 3733 DescriptorArray* descriptors = this->map()->instance_descriptors();
3708 if ((descriptors->number_of_descriptors() > 0) && 3734 if ((descriptors->number_of_descriptors() > 0) &&
3709 (descriptors->GetKey(0) == GetHeap()->hidden_symbol())) { 3735 (descriptors->GetKey(0) == GetHeap()->hidden_symbol())) {
3710 ASSERT(descriptors->GetType(0) == FIELD); 3736 ASSERT(descriptors->GetType(0) == FIELD);
3711 this->FastPropertyAtPut(descriptors->GetFieldIndex(0), dictionary); 3737 this->FastPropertyAtPut(descriptors->GetFieldIndex(0), hidden);
3712 return this; 3738 return this;
3713 } 3739 }
3714 } 3740 }
3715 MaybeObject* store_result = 3741 MaybeObject* store_result =
3716 SetPropertyPostInterceptor(GetHeap()->hidden_symbol(), 3742 SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
3717 dictionary, 3743 hidden,
3718 DONT_ENUM, 3744 DONT_ENUM,
3719 kNonStrictMode, 3745 kNonStrictMode,
3720 OMIT_EXTENSIBILITY_CHECK); 3746 OMIT_EXTENSIBILITY_CHECK);
3721 if (store_result->IsFailure()) return store_result; 3747 if (store_result->IsFailure()) return store_result;
3722 return this; 3748 return this;
3723 } 3749 }
3724 3750
3725 3751
3726 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, 3752 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name,
3727 DeleteMode mode) { 3753 DeleteMode mode) {
(...skipping 7305 matching lines...) Expand 10 before | Expand all | Expand 10 after
11033 template<typename Shape, typename Key> 11059 template<typename Shape, typename Key>
11034 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) { 11060 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) {
11035 IteratePointers(v, 11061 IteratePointers(v,
11036 kElementsStartOffset, 11062 kElementsStartOffset,
11037 kHeaderSize + length() * kPointerSize); 11063 kHeaderSize + length() * kPointerSize);
11038 } 11064 }
11039 11065
11040 11066
11041 template<typename Shape, typename Key> 11067 template<typename Shape, typename Key>
11042 MaybeObject* HashTable<Shape, Key>::Allocate(int at_least_space_for, 11068 MaybeObject* HashTable<Shape, Key>::Allocate(int at_least_space_for,
11069 bool force_capacity,
Toon Verwaest 2012/07/30 09:13:24 Please use an enum.
11043 PretenureFlag pretenure) { 11070 PretenureFlag pretenure) {
11044 int capacity = ComputeCapacity(at_least_space_for); 11071 ASSERT(!force_capacity || IS_POWER_OF_TWO(at_least_space_for));
11072 int capacity = force_capacity ? at_least_space_for
11073 : ComputeCapacity(at_least_space_for);
11045 if (capacity > HashTable::kMaxCapacity) { 11074 if (capacity > HashTable::kMaxCapacity) {
11046 return Failure::OutOfMemoryException(); 11075 return Failure::OutOfMemoryException();
11047 } 11076 }
11048 11077
11049 Object* obj; 11078 Object* obj;
11050 { MaybeObject* maybe_obj = Isolate::Current()->heap()-> 11079 { MaybeObject* maybe_obj = Isolate::Current()->heap()->
11051 AllocateHashTable(EntryToIndex(capacity), pretenure); 11080 AllocateHashTable(EntryToIndex(capacity), pretenure);
11052 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 11081 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
11053 } 11082 }
11054 HashTable::cast(obj)->SetNumberOfElements(0); 11083 HashTable::cast(obj)->SetNumberOfElements(0);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
11143 if (nod <= (capacity - nof) >> 1) { 11172 if (nod <= (capacity - nof) >> 1) {
11144 int needed_free = nof >> 1; 11173 int needed_free = nof >> 1;
11145 if (nof + needed_free <= capacity) return this; 11174 if (nof + needed_free <= capacity) return this;
11146 } 11175 }
11147 11176
11148 const int kMinCapacityForPretenure = 256; 11177 const int kMinCapacityForPretenure = 256;
11149 bool pretenure = 11178 bool pretenure =
11150 (capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this); 11179 (capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this);
11151 Object* obj; 11180 Object* obj;
11152 { MaybeObject* maybe_obj = 11181 { MaybeObject* maybe_obj =
11153 Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); 11182 Allocate(nof * 2, false, pretenure ? TENURED : NOT_TENURED);
Toon Verwaest 2012/07/30 09:13:24 enum.
11154 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 11183 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
11155 } 11184 }
11156 11185
11157 return Rehash(HashTable::cast(obj), key); 11186 return Rehash(HashTable::cast(obj), key);
11158 } 11187 }
11159 11188
11160 11189
11161 template<typename Shape, typename Key> 11190 template<typename Shape, typename Key>
11162 MaybeObject* HashTable<Shape, Key>::Shrink(Key key) { 11191 MaybeObject* HashTable<Shape, Key>::Shrink(Key key) {
11163 int capacity = Capacity(); 11192 int capacity = Capacity();
11164 int nof = NumberOfElements(); 11193 int nof = NumberOfElements();
11165 11194
11166 // Shrink to fit the number of elements if only a quarter of the 11195 // Shrink to fit the number of elements if only a quarter of the
11167 // capacity is filled with elements. 11196 // capacity is filled with elements.
11168 if (nof > (capacity >> 2)) return this; 11197 if (nof > (capacity >> 2)) return this;
11169 // Allocate a new dictionary with room for at least the current 11198 // Allocate a new dictionary with room for at least the current
11170 // number of elements. The allocation method will make sure that 11199 // number of elements. The allocation method will make sure that
11171 // there is extra room in the dictionary for additions. Don't go 11200 // there is extra room in the dictionary for additions. Don't go
11172 // lower than room for 16 elements. 11201 // lower than room for 16 elements.
11173 int at_least_room_for = nof; 11202 int at_least_room_for = nof;
11174 if (at_least_room_for < 16) return this; 11203 if (at_least_room_for < 16) return this;
11175 11204
11176 const int kMinCapacityForPretenure = 256; 11205 const int kMinCapacityForPretenure = 256;
11177 bool pretenure = 11206 bool pretenure =
11178 (at_least_room_for > kMinCapacityForPretenure) && 11207 (at_least_room_for > kMinCapacityForPretenure) &&
11179 !GetHeap()->InNewSpace(this); 11208 !GetHeap()->InNewSpace(this);
11180 Object* obj; 11209 Object* obj;
11181 { MaybeObject* maybe_obj = 11210 { MaybeObject* maybe_obj =
11182 Allocate(at_least_room_for, pretenure ? TENURED : NOT_TENURED); 11211 Allocate(at_least_room_for, false, pretenure ? TENURED : NOT_TENURED);
Toon Verwaest 2012/07/30 09:13:24 enum.
11183 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 11212 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
11184 } 11213 }
11185 11214
11186 return Rehash(HashTable::cast(obj), key); 11215 return Rehash(HashTable::cast(obj), key);
11187 } 11216 }
11188 11217
11189 11218
11190 template<typename Shape, typename Key> 11219 template<typename Shape, typename Key>
11191 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { 11220 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) {
11192 uint32_t capacity = Capacity(); 11221 uint32_t capacity = Capacity();
(...skipping 1929 matching lines...) Expand 10 before | Expand all | Expand 10 after
13122 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13151 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13123 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13152 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13124 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13153 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13125 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13154 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13126 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13155 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13127 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13156 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13128 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13157 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13129 } 13158 }
13130 13159
13131 } } // namespace v8::internal 13160 } } // namespace v8::internal
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | test/cctest/test-dictionary.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698