OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |