| 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 2743 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2754     // Code will be set on the JavaScript side. | 2754     // Code will be set on the JavaScript side. | 
| 2755   } else { | 2755   } else { | 
| 2756     isolate->factory()->BecomeJSObject(self); | 2756     isolate->factory()->BecomeJSObject(self); | 
| 2757   } | 2757   } | 
| 2758   ASSERT(self->IsJSObject()); | 2758   ASSERT(self->IsJSObject()); | 
| 2759 | 2759 | 
| 2760   // Inherit identity, if it was present. | 2760   // Inherit identity, if it was present. | 
| 2761   Object* hash; | 2761   Object* hash; | 
| 2762   if (maybe_hash->To<Object>(&hash) && hash->IsSmi()) { | 2762   if (maybe_hash->To<Object>(&hash) && hash->IsSmi()) { | 
| 2763     Handle<JSObject> new_self(JSObject::cast(*self)); | 2763     Handle<JSObject> new_self(JSObject::cast(*self)); | 
| 2764     isolate->factory()->SetIdentityHash(new_self, hash); | 2764     isolate->factory()->SetIdentityHash(new_self, Smi::cast(hash)); | 
| 2765   } | 2765   } | 
| 2766 } | 2766 } | 
| 2767 | 2767 | 
| 2768 | 2768 | 
| 2769 MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(const char* name, | 2769 MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(const char* name, | 
| 2770                                                  Handle<Object> derived, | 2770                                                  Handle<Object> derived, | 
| 2771                                                  int argc, | 2771                                                  int argc, | 
| 2772                                                  Handle<Object> argv[]) { | 2772                                                  Handle<Object> argv[]) { | 
| 2773   Isolate* isolate = GetIsolate(); | 2773   Isolate* isolate = GetIsolate(); | 
| 2774   Handle<Object> handler(this->handler()); | 2774   Handle<Object> handler(this->handler()); | 
| (...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3498     // within a smi. | 3498     // within a smi. | 
| 3499     hash_value = V8::RandomPrivate(isolate) & Smi::kMaxValue; | 3499     hash_value = V8::RandomPrivate(isolate) & Smi::kMaxValue; | 
| 3500     attempts++; | 3500     attempts++; | 
| 3501   } while (hash_value == 0 && attempts < 30); | 3501   } while (hash_value == 0 && attempts < 30); | 
| 3502   hash_value = hash_value != 0 ? hash_value : 1;  // never return 0 | 3502   hash_value = hash_value != 0 ? hash_value : 1;  // never return 0 | 
| 3503 | 3503 | 
| 3504   return Smi::FromInt(hash_value); | 3504   return Smi::FromInt(hash_value); | 
| 3505 } | 3505 } | 
| 3506 | 3506 | 
| 3507 | 3507 | 
| 3508 MaybeObject* JSObject::SetIdentityHash(Object* hash, CreationFlag flag) { | 3508 MaybeObject* JSObject::SetIdentityHash(Smi* hash, CreationFlag flag) { | 
| 3509   MaybeObject* maybe = SetHiddenProperty(GetHeap()->identity_hash_symbol(), | 3509   MaybeObject* maybe = SetHiddenProperty(GetHeap()->identity_hash_symbol(), | 
| 3510                                          hash); | 3510                                          hash); | 
| 3511   if (maybe->IsFailure()) return maybe; | 3511   if (maybe->IsFailure()) return maybe; | 
| 3512   return this; | 3512   return this; | 
| 3513 } | 3513 } | 
| 3514 | 3514 | 
| 3515 | 3515 | 
| 3516 int JSObject::GetIdentityHash(Handle<JSObject> obj) { | 3516 int JSObject::GetIdentityHash(Handle<JSObject> obj) { | 
| 3517   CALL_AND_RETRY(obj->GetIsolate(), | 3517   CALL_AND_RETRY(obj->GetIsolate(), | 
| 3518                  obj->GetIdentityHash(ALLOW_CREATION), | 3518                  obj->GetIdentityHash(ALLOW_CREATION), | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 3544   Object* hash = this->hash(); | 3544   Object* hash = this->hash(); | 
| 3545   if (!hash->IsSmi() && flag == ALLOW_CREATION) { | 3545   if (!hash->IsSmi() && flag == ALLOW_CREATION) { | 
| 3546     hash = GenerateIdentityHash(); | 3546     hash = GenerateIdentityHash(); | 
| 3547     set_hash(hash); | 3547     set_hash(hash); | 
| 3548   } | 3548   } | 
| 3549   return hash; | 3549   return hash; | 
| 3550 } | 3550 } | 
| 3551 | 3551 | 
| 3552 | 3552 | 
| 3553 Object* JSObject::GetHiddenProperty(String* key) { | 3553 Object* JSObject::GetHiddenProperty(String* key) { | 
|  | 3554   ASSERT(key->IsSymbol()); | 
| 3554   if (IsJSGlobalProxy()) { | 3555   if (IsJSGlobalProxy()) { | 
| 3555     // For a proxy, use the prototype as target object. | 3556     // For a proxy, use the prototype as target object. | 
| 3556     Object* proxy_parent = GetPrototype(); | 3557     Object* proxy_parent = GetPrototype(); | 
| 3557     // If the proxy is detached, return undefined. | 3558     // If the proxy is detached, return undefined. | 
| 3558     if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); | 3559     if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); | 
| 3559     ASSERT(proxy_parent->IsJSGlobalObject()); | 3560     ASSERT(proxy_parent->IsJSGlobalObject()); | 
| 3560     return JSObject::cast(proxy_parent)->GetHiddenProperty(key); | 3561     return JSObject::cast(proxy_parent)->GetHiddenProperty(key); | 
| 3561   } | 3562   } | 
| 3562   ASSERT(!IsJSGlobalProxy()); | 3563   ASSERT(!IsJSGlobalProxy()); | 
| 3563   MaybeObject* hidden_lookup = GetHiddenPropertiesDictionary(false); | 3564   MaybeObject* hidden_lookup = | 
|  | 3565       GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE); | 
| 3564   ASSERT(!hidden_lookup->IsFailure());  // No failure when passing false as arg. | 3566   ASSERT(!hidden_lookup->IsFailure());  // No failure when passing false as arg. | 
| 3565   if (hidden_lookup->ToObjectUnchecked()->IsUndefined()) { | 3567   Object* inline_value = hidden_lookup->ToObjectUnchecked(); | 
| 3566     return GetHeap()->undefined_value(); | 3568 | 
|  | 3569   if (inline_value->IsSmi()) { | 
|  | 3570     // Handle inline-stored identity hash. | 
|  | 3571     if (key == GetHeap()->identity_hash_symbol()) { | 
|  | 3572       return inline_value; | 
|  | 3573     } else { | 
|  | 3574       return GetHeap()->undefined_value(); | 
|  | 3575     } | 
| 3567   } | 3576   } | 
| 3568   StringDictionary* dictionary = | 3577 | 
| 3569       StringDictionary::cast(hidden_lookup->ToObjectUnchecked()); | 3578   if (inline_value->IsUndefined()) return GetHeap()->undefined_value(); | 
| 3570   int entry = dictionary->FindEntry(key); | 3579 | 
| 3571   if (entry == StringDictionary::kNotFound) return GetHeap()->undefined_value(); | 3580   ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); | 
| 3572   return dictionary->ValueAt(entry); | 3581   Object* entry = hashtable->Lookup(key); | 
|  | 3582   if (entry->IsTheHole()) return GetHeap()->undefined_value(); | 
|  | 3583   return entry; | 
| 3573 } | 3584 } | 
| 3574 | 3585 | 
| 3575 | 3586 | 
| 3576 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj, | 3587 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj, | 
| 3577                                  Handle<String> key, | 3588                                            Handle<String> key, | 
| 3578                                  Handle<Object> value) { | 3589                                            Handle<Object> value) { | 
| 3579   CALL_HEAP_FUNCTION(obj->GetIsolate(), | 3590   CALL_HEAP_FUNCTION(obj->GetIsolate(), | 
| 3580                      obj->SetHiddenProperty(*key, *value), | 3591                      obj->SetHiddenProperty(*key, *value), | 
| 3581                      Object); | 3592                      Object); | 
| 3582 } | 3593 } | 
| 3583 | 3594 | 
| 3584 | 3595 | 
| 3585 MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) { | 3596 MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) { | 
|  | 3597   ASSERT(key->IsSymbol()); | 
| 3586   if (IsJSGlobalProxy()) { | 3598   if (IsJSGlobalProxy()) { | 
| 3587     // For a proxy, use the prototype as target object. | 3599     // For a proxy, use the prototype as target object. | 
| 3588     Object* proxy_parent = GetPrototype(); | 3600     Object* proxy_parent = GetPrototype(); | 
| 3589     // If the proxy is detached, return undefined. | 3601     // If the proxy is detached, return undefined. | 
| 3590     if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); | 3602     if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); | 
| 3591     ASSERT(proxy_parent->IsJSGlobalObject()); | 3603     ASSERT(proxy_parent->IsJSGlobalObject()); | 
| 3592     return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value); | 3604     return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value); | 
| 3593   } | 3605   } | 
| 3594   ASSERT(!IsJSGlobalProxy()); | 3606   ASSERT(!IsJSGlobalProxy()); | 
| 3595   MaybeObject* hidden_lookup = GetHiddenPropertiesDictionary(true); | 3607 | 
| 3596   StringDictionary* dictionary; | 3608   // If there is no backing store yet, store the identity hash inline. | 
| 3597   if (!hidden_lookup->To<StringDictionary>(&dictionary)) return hidden_lookup; | 3609   MaybeObject* hidden_lookup = | 
|  | 3610       GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE); | 
|  | 3611   ASSERT(!hidden_lookup->IsFailure()); | 
|  | 3612   Object* inline_value = hidden_lookup->ToObjectUnchecked(); | 
|  | 3613 | 
|  | 3614   if (value->IsSmi() && | 
|  | 3615       key == GetHeap()->identity_hash_symbol() && | 
|  | 3616       (inline_value->IsUndefined() || inline_value->IsSmi())) { | 
|  | 3617     return SetHiddenPropertiesHashTable(value); | 
|  | 3618   } | 
|  | 3619 | 
|  | 3620   hidden_lookup = GetHiddenPropertiesHashTable(CREATE_NEW_IF_ABSENT); | 
|  | 3621   ObjectHashTable* hashtable; | 
|  | 3622   if (!hidden_lookup->To(&hashtable)) return hidden_lookup; | 
| 3598 | 3623 | 
| 3599   // If it was found, check if the key is already in the dictionary. | 3624   // If it was found, check if the key is already in the dictionary. | 
| 3600   int entry = dictionary->FindEntry(key); | 3625   MaybeObject* insert_result = hashtable->Put(key, value); | 
| 3601   if (entry != StringDictionary::kNotFound) { | 3626   ObjectHashTable* new_table; | 
| 3602     // If key was found, just update the value. | 3627   if (!insert_result->To(&new_table)) return insert_result; | 
| 3603     dictionary->ValueAtPut(entry, value); | 3628   if (new_table != hashtable) { | 
| 3604     return this; |  | 
| 3605   } |  | 
| 3606   // Key was not already in the dictionary, so add the entry. |  | 
| 3607   MaybeObject* insert_result = dictionary->Add(key, |  | 
| 3608                                                value, |  | 
| 3609                                                PropertyDetails(NONE, NORMAL)); |  | 
| 3610   StringDictionary* new_dict; |  | 
| 3611   if (!insert_result->To<StringDictionary>(&new_dict)) return insert_result; |  | 
| 3612   if (new_dict != dictionary) { |  | 
| 3613     // If adding the key expanded the dictionary (i.e., Add returned a new | 3629     // If adding the key expanded the dictionary (i.e., Add returned a new | 
| 3614     // dictionary), store it back to the object. | 3630     // dictionary), store it back to the object. | 
| 3615     MaybeObject* store_result = SetHiddenPropertiesDictionary(new_dict); | 3631     MaybeObject* store_result = SetHiddenPropertiesHashTable(new_table); | 
| 3616     if (store_result->IsFailure()) return store_result; | 3632     if (store_result->IsFailure()) return store_result; | 
| 3617   } | 3633   } | 
| 3618   // Return this to mark success. | 3634   // Return this to mark success. | 
| 3619   return this; | 3635   return this; | 
| 3620 } | 3636 } | 
| 3621 | 3637 | 
| 3622 | 3638 | 
| 3623 void JSObject::DeleteHiddenProperty(String* key) { | 3639 void JSObject::DeleteHiddenProperty(String* key) { | 
|  | 3640   ASSERT(key->IsSymbol()); | 
| 3624   if (IsJSGlobalProxy()) { | 3641   if (IsJSGlobalProxy()) { | 
| 3625     // For a proxy, use the prototype as target object. | 3642     // For a proxy, use the prototype as target object. | 
| 3626     Object* proxy_parent = GetPrototype(); | 3643     Object* proxy_parent = GetPrototype(); | 
| 3627     // If the proxy is detached, return immediately. | 3644     // If the proxy is detached, return immediately. | 
| 3628     if (proxy_parent->IsNull()) return; | 3645     if (proxy_parent->IsNull()) return; | 
| 3629     ASSERT(proxy_parent->IsJSGlobalObject()); | 3646     ASSERT(proxy_parent->IsJSGlobalObject()); | 
| 3630     JSObject::cast(proxy_parent)->DeleteHiddenProperty(key); | 3647     JSObject::cast(proxy_parent)->DeleteHiddenProperty(key); | 
| 3631     return; | 3648     return; | 
| 3632   } | 3649   } | 
| 3633   MaybeObject* hidden_lookup = GetHiddenPropertiesDictionary(false); | 3650   MaybeObject* hidden_lookup = | 
|  | 3651       GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE); | 
| 3634   ASSERT(!hidden_lookup->IsFailure());  // No failure when passing false as arg. | 3652   ASSERT(!hidden_lookup->IsFailure());  // No failure when passing false as arg. | 
| 3635   if (hidden_lookup->ToObjectUnchecked()->IsUndefined()) return; | 3653   if (hidden_lookup->ToObjectUnchecked()->IsUndefined()) return; | 
| 3636   StringDictionary* dictionary = | 3654   // We never delete (inline-stored) identity hashes. | 
| 3637       StringDictionary::cast(hidden_lookup->ToObjectUnchecked()); | 3655   ASSERT(!hidden_lookup->ToObjectUnchecked()->IsSmi()); | 
| 3638   int entry = dictionary->FindEntry(key); | 3656 | 
| 3639   if (entry == StringDictionary::kNotFound) { | 3657   ObjectHashTable* hashtable = | 
| 3640     // Key wasn't in dictionary. Deletion is a success. | 3658       ObjectHashTable::cast(hidden_lookup->ToObjectUnchecked()); | 
| 3641     return; | 3659   MaybeObject* delete_result = hashtable->Put(key, GetHeap()->the_hole_value()); | 
| 3642   } | 3660   USE(delete_result); | 
| 3643   // Key was in the dictionary. Remove it. | 3661   ASSERT(!delete_result->IsFailure());  // Delete does not cause GC. | 
| 3644   dictionary->DeleteProperty(entry, JSReceiver::FORCE_DELETION); |  | 
| 3645 } | 3662 } | 
| 3646 | 3663 | 
| 3647 | 3664 | 
| 3648 bool JSObject::HasHiddenProperties() { | 3665 bool JSObject::HasHiddenProperties() { | 
| 3649   return GetPropertyAttributePostInterceptor(this, | 3666   return GetPropertyAttributePostInterceptor(this, | 
| 3650                                              GetHeap()->hidden_symbol(), | 3667                                              GetHeap()->hidden_symbol(), | 
| 3651                                              false) != ABSENT; | 3668                                              false) != ABSENT; | 
| 3652 } | 3669 } | 
| 3653 | 3670 | 
| 3654 | 3671 | 
| 3655 MaybeObject* JSObject::GetHiddenPropertiesDictionary(bool create_if_absent) { | 3672 MaybeObject* JSObject::GetHiddenPropertiesHashTable( | 
|  | 3673     InitializeHiddenProperties init_option) { | 
| 3656   ASSERT(!IsJSGlobalProxy()); | 3674   ASSERT(!IsJSGlobalProxy()); | 
|  | 3675   Object* inline_value; | 
| 3657   if (HasFastProperties()) { | 3676   if (HasFastProperties()) { | 
| 3658     // If the object has fast properties, check whether the first slot | 3677     // If the object has fast properties, check whether the first slot | 
| 3659     // in the descriptor array matches the hidden symbol. Since the | 3678     // in the descriptor array matches the hidden symbol. Since the | 
| 3660     // hidden symbols hash code is zero (and no other string has hash | 3679     // hidden symbols hash code is zero (and no other string has hash | 
| 3661     // code zero) it will always occupy the first entry if present. | 3680     // code zero) it will always occupy the first entry if present. | 
| 3662     DescriptorArray* descriptors = this->map()->instance_descriptors(); | 3681     DescriptorArray* descriptors = this->map()->instance_descriptors(); | 
| 3663     if ((descriptors->number_of_descriptors() > 0) && | 3682     if ((descriptors->number_of_descriptors() > 0) && | 
| 3664         (descriptors->GetKey(0) == GetHeap()->hidden_symbol())) { | 3683         (descriptors->GetKey(0) == GetHeap()->hidden_symbol())) { | 
| 3665       ASSERT(descriptors->GetType(0) == FIELD); | 3684       ASSERT(descriptors->GetType(0) == FIELD); | 
| 3666       Object* hidden_store = | 3685       inline_value = this->FastPropertyAt(descriptors->GetFieldIndex(0)); | 
| 3667           this->FastPropertyAt(descriptors->GetFieldIndex(0)); | 3686     } else { | 
| 3668       return StringDictionary::cast(hidden_store); | 3687       inline_value = GetHeap()->undefined_value(); | 
| 3669     } | 3688     } | 
| 3670   } else { | 3689   } else { | 
| 3671     PropertyAttributes attributes; | 3690     PropertyAttributes attributes; | 
| 3672     // You can't install a getter on a property indexed by the hidden symbol, | 3691     // You can't install a getter on a property indexed by the hidden symbol, | 
| 3673     // so we can be sure that GetLocalPropertyPostInterceptor returns a real | 3692     // so we can be sure that GetLocalPropertyPostInterceptor returns a real | 
| 3674     // object. | 3693     // object. | 
| 3675     Object* lookup = | 3694     inline_value = | 
| 3676         GetLocalPropertyPostInterceptor(this, | 3695         GetLocalPropertyPostInterceptor(this, | 
| 3677                                         GetHeap()->hidden_symbol(), | 3696                                         GetHeap()->hidden_symbol(), | 
| 3678                                         &attributes)->ToObjectUnchecked(); | 3697                                         &attributes)->ToObjectUnchecked(); | 
| 3679     if (!lookup->IsUndefined()) { |  | 
| 3680       return StringDictionary::cast(lookup); |  | 
| 3681     } |  | 
| 3682   } | 3698   } | 
| 3683   if (!create_if_absent) return GetHeap()->undefined_value(); | 3699 | 
| 3684   const int kInitialSize = 5; | 3700   if (init_option == ONLY_RETURN_INLINE_VALUE || | 
| 3685   MaybeObject* dict_alloc = StringDictionary::Allocate(kInitialSize); | 3701       inline_value->IsHashTable()) { | 
| 3686   StringDictionary* dictionary; | 3702     return inline_value; | 
| 3687   if (!dict_alloc->To<StringDictionary>(&dictionary)) return dict_alloc; | 3703   } | 
|  | 3704 | 
|  | 3705   ObjectHashTable* hashtable; | 
|  | 3706   static const int kInitialCapacity = 4; | 
|  | 3707   MaybeObject* maybe_obj = | 
|  | 3708       ObjectHashTable::Allocate(kInitialCapacity, | 
|  | 3709                                 ObjectHashTable::USE_CUSTOM_MINIMUM_CAPACITY); | 
|  | 3710   if (!maybe_obj->To<ObjectHashTable>(&hashtable)) return maybe_obj; | 
|  | 3711 | 
|  | 3712   if (inline_value->IsSmi()) { | 
|  | 3713     // We were storing the identity hash inline and now allocated an actual | 
|  | 3714     // dictionary.  Put the identity hash into the new dictionary. | 
|  | 3715     MaybeObject* insert_result = | 
|  | 3716         hashtable->Put(GetHeap()->identity_hash_symbol(), inline_value); | 
|  | 3717     ObjectHashTable* new_table; | 
|  | 3718     if (!insert_result->To(&new_table)) return insert_result; | 
|  | 3719     // We expect no resizing for the first insert. | 
|  | 3720     ASSERT_EQ(hashtable, new_table); | 
|  | 3721   } | 
|  | 3722 | 
| 3688   MaybeObject* store_result = | 3723   MaybeObject* store_result = | 
| 3689       SetPropertyPostInterceptor(GetHeap()->hidden_symbol(), | 3724       SetPropertyPostInterceptor(GetHeap()->hidden_symbol(), | 
| 3690                                  dictionary, | 3725                                  hashtable, | 
| 3691                                  DONT_ENUM, | 3726                                  DONT_ENUM, | 
| 3692                                  kNonStrictMode, | 3727                                  kNonStrictMode, | 
| 3693                                  OMIT_EXTENSIBILITY_CHECK); | 3728                                  OMIT_EXTENSIBILITY_CHECK); | 
| 3694   if (store_result->IsFailure()) return store_result; | 3729   if (store_result->IsFailure()) return store_result; | 
| 3695   return dictionary; | 3730   return hashtable; | 
| 3696 } | 3731 } | 
| 3697 | 3732 | 
| 3698 | 3733 | 
| 3699 MaybeObject* JSObject::SetHiddenPropertiesDictionary( | 3734 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { | 
| 3700     StringDictionary* dictionary) { |  | 
| 3701   ASSERT(!IsJSGlobalProxy()); | 3735   ASSERT(!IsJSGlobalProxy()); | 
| 3702   ASSERT(HasHiddenProperties()); | 3736   // We can store the identity hash inline iff there is no backing store | 
|  | 3737   // for hidden properties yet. | 
|  | 3738   ASSERT(HasHiddenProperties() != value->IsSmi()); | 
| 3703   if (HasFastProperties()) { | 3739   if (HasFastProperties()) { | 
| 3704     // If the object has fast properties, check whether the first slot | 3740     // If the object has fast properties, check whether the first slot | 
| 3705     // in the descriptor array matches the hidden symbol. Since the | 3741     // in the descriptor array matches the hidden symbol. Since the | 
| 3706     // hidden symbols hash code is zero (and no other string has hash | 3742     // hidden symbols hash code is zero (and no other string has hash | 
| 3707     // code zero) it will always occupy the first entry if present. | 3743     // code zero) it will always occupy the first entry if present. | 
| 3708     DescriptorArray* descriptors = this->map()->instance_descriptors(); | 3744     DescriptorArray* descriptors = this->map()->instance_descriptors(); | 
| 3709     if ((descriptors->number_of_descriptors() > 0) && | 3745     if ((descriptors->number_of_descriptors() > 0) && | 
| 3710         (descriptors->GetKey(0) == GetHeap()->hidden_symbol())) { | 3746         (descriptors->GetKey(0) == GetHeap()->hidden_symbol())) { | 
| 3711       ASSERT(descriptors->GetType(0) == FIELD); | 3747       ASSERT(descriptors->GetType(0) == FIELD); | 
| 3712       this->FastPropertyAtPut(descriptors->GetFieldIndex(0), dictionary); | 3748       this->FastPropertyAtPut(descriptors->GetFieldIndex(0), value); | 
| 3713       return this; | 3749       return this; | 
| 3714     } | 3750     } | 
| 3715   } | 3751   } | 
| 3716   MaybeObject* store_result = | 3752   MaybeObject* store_result = | 
| 3717       SetPropertyPostInterceptor(GetHeap()->hidden_symbol(), | 3753       SetPropertyPostInterceptor(GetHeap()->hidden_symbol(), | 
| 3718                                  dictionary, | 3754                                  value, | 
| 3719                                  DONT_ENUM, | 3755                                  DONT_ENUM, | 
| 3720                                  kNonStrictMode, | 3756                                  kNonStrictMode, | 
| 3721                                  OMIT_EXTENSIBILITY_CHECK); | 3757                                  OMIT_EXTENSIBILITY_CHECK); | 
| 3722   if (store_result->IsFailure()) return store_result; | 3758   if (store_result->IsFailure()) return store_result; | 
| 3723   return this; | 3759   return this; | 
| 3724 } | 3760 } | 
| 3725 | 3761 | 
| 3726 | 3762 | 
| 3727 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, | 3763 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, | 
| 3728                                                      DeleteMode mode) { | 3764                                                      DeleteMode mode) { | 
| (...skipping 7310 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 11039 template<typename Shape, typename Key> | 11075 template<typename Shape, typename Key> | 
| 11040 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) { | 11076 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) { | 
| 11041   IteratePointers(v, | 11077   IteratePointers(v, | 
| 11042                   kElementsStartOffset, | 11078                   kElementsStartOffset, | 
| 11043                   kHeaderSize + length() * kPointerSize); | 11079                   kHeaderSize + length() * kPointerSize); | 
| 11044 } | 11080 } | 
| 11045 | 11081 | 
| 11046 | 11082 | 
| 11047 template<typename Shape, typename Key> | 11083 template<typename Shape, typename Key> | 
| 11048 MaybeObject* HashTable<Shape, Key>::Allocate(int at_least_space_for, | 11084 MaybeObject* HashTable<Shape, Key>::Allocate(int at_least_space_for, | 
|  | 11085                                              MinimumCapacity capacity_option, | 
| 11049                                              PretenureFlag pretenure) { | 11086                                              PretenureFlag pretenure) { | 
| 11050   int capacity = ComputeCapacity(at_least_space_for); | 11087   ASSERT(!capacity_option || IS_POWER_OF_TWO(at_least_space_for)); | 
|  | 11088   int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) | 
|  | 11089                      ? at_least_space_for | 
|  | 11090                      : ComputeCapacity(at_least_space_for); | 
| 11051   if (capacity > HashTable::kMaxCapacity) { | 11091   if (capacity > HashTable::kMaxCapacity) { | 
| 11052     return Failure::OutOfMemoryException(); | 11092     return Failure::OutOfMemoryException(); | 
| 11053   } | 11093   } | 
| 11054 | 11094 | 
| 11055   Object* obj; | 11095   Object* obj; | 
| 11056   { MaybeObject* maybe_obj = Isolate::Current()->heap()-> | 11096   { MaybeObject* maybe_obj = Isolate::Current()->heap()-> | 
| 11057         AllocateHashTable(EntryToIndex(capacity), pretenure); | 11097         AllocateHashTable(EntryToIndex(capacity), pretenure); | 
| 11058     if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 11098     if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 
| 11059   } | 11099   } | 
| 11060   HashTable::cast(obj)->SetNumberOfElements(0); | 11100   HashTable::cast(obj)->SetNumberOfElements(0); | 
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 11149   if (nod <= (capacity - nof) >> 1) { | 11189   if (nod <= (capacity - nof) >> 1) { | 
| 11150     int needed_free = nof >> 1; | 11190     int needed_free = nof >> 1; | 
| 11151     if (nof + needed_free <= capacity) return this; | 11191     if (nof + needed_free <= capacity) return this; | 
| 11152   } | 11192   } | 
| 11153 | 11193 | 
| 11154   const int kMinCapacityForPretenure = 256; | 11194   const int kMinCapacityForPretenure = 256; | 
| 11155   bool pretenure = | 11195   bool pretenure = | 
| 11156       (capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this); | 11196       (capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this); | 
| 11157   Object* obj; | 11197   Object* obj; | 
| 11158   { MaybeObject* maybe_obj = | 11198   { MaybeObject* maybe_obj = | 
| 11159         Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); | 11199         Allocate(nof * 2, | 
|  | 11200                  USE_DEFAULT_MINIMUM_CAPACITY, | 
|  | 11201                  pretenure ? TENURED : NOT_TENURED); | 
| 11160     if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 11202     if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 
| 11161   } | 11203   } | 
| 11162 | 11204 | 
| 11163   return Rehash(HashTable::cast(obj), key); | 11205   return Rehash(HashTable::cast(obj), key); | 
| 11164 } | 11206 } | 
| 11165 | 11207 | 
| 11166 | 11208 | 
| 11167 template<typename Shape, typename Key> | 11209 template<typename Shape, typename Key> | 
| 11168 MaybeObject* HashTable<Shape, Key>::Shrink(Key key) { | 11210 MaybeObject* HashTable<Shape, Key>::Shrink(Key key) { | 
| 11169   int capacity = Capacity(); | 11211   int capacity = Capacity(); | 
| 11170   int nof = NumberOfElements(); | 11212   int nof = NumberOfElements(); | 
| 11171 | 11213 | 
| 11172   // Shrink to fit the number of elements if only a quarter of the | 11214   // Shrink to fit the number of elements if only a quarter of the | 
| 11173   // capacity is filled with elements. | 11215   // capacity is filled with elements. | 
| 11174   if (nof > (capacity >> 2)) return this; | 11216   if (nof > (capacity >> 2)) return this; | 
| 11175   // Allocate a new dictionary with room for at least the current | 11217   // Allocate a new dictionary with room for at least the current | 
| 11176   // number of elements. The allocation method will make sure that | 11218   // number of elements. The allocation method will make sure that | 
| 11177   // there is extra room in the dictionary for additions. Don't go | 11219   // there is extra room in the dictionary for additions. Don't go | 
| 11178   // lower than room for 16 elements. | 11220   // lower than room for 16 elements. | 
| 11179   int at_least_room_for = nof; | 11221   int at_least_room_for = nof; | 
| 11180   if (at_least_room_for < 16) return this; | 11222   if (at_least_room_for < 16) return this; | 
| 11181 | 11223 | 
| 11182   const int kMinCapacityForPretenure = 256; | 11224   const int kMinCapacityForPretenure = 256; | 
| 11183   bool pretenure = | 11225   bool pretenure = | 
| 11184       (at_least_room_for > kMinCapacityForPretenure) && | 11226       (at_least_room_for > kMinCapacityForPretenure) && | 
| 11185       !GetHeap()->InNewSpace(this); | 11227       !GetHeap()->InNewSpace(this); | 
| 11186   Object* obj; | 11228   Object* obj; | 
| 11187   { MaybeObject* maybe_obj = | 11229   { MaybeObject* maybe_obj = | 
| 11188         Allocate(at_least_room_for, pretenure ? TENURED : NOT_TENURED); | 11230         Allocate(at_least_room_for, | 
|  | 11231                  USE_DEFAULT_MINIMUM_CAPACITY, | 
|  | 11232                  pretenure ? TENURED : NOT_TENURED); | 
| 11189     if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 11233     if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 
| 11190   } | 11234   } | 
| 11191 | 11235 | 
| 11192   return Rehash(HashTable::cast(obj), key); | 11236   return Rehash(HashTable::cast(obj), key); | 
| 11193 } | 11237 } | 
| 11194 | 11238 | 
| 11195 | 11239 | 
| 11196 template<typename Shape, typename Key> | 11240 template<typename Shape, typename Key> | 
| 11197 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { | 11241 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { | 
| 11198   uint32_t capacity = Capacity(); | 11242   uint32_t capacity = Capacity(); | 
| (...skipping 1929 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 13128   set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13172   set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 
| 13129   set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13173   set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 
| 13130   set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13174   set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 
| 13131   set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13175   set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 
| 13132   set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13176   set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 
| 13133   set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13177   set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 
| 13134   set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13178   set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 
| 13135 } | 13179 } | 
| 13136 | 13180 | 
| 13137 } }  // namespace v8::internal | 13181 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|