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

Side by Side Diff: src/objects.cc

Issue 48913008: Remove calls to JSObject::SetLocalPropertyIgnoreAttributesTrampoline within objects.cc (Closed) Base URL: https://github.com/v8/v8.git@bleeding_edge
Patch Set: last one Created 7 years, 1 month 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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 return context->symbol_function()->instance_prototype(); 1021 return context->symbol_function()->instance_prototype();
1022 } 1022 }
1023 if (heap_object->IsBoolean()) { 1023 if (heap_object->IsBoolean()) {
1024 return context->boolean_function()->instance_prototype(); 1024 return context->boolean_function()->instance_prototype();
1025 } else { 1025 } else {
1026 return isolate->heap()->null_value(); 1026 return isolate->heap()->null_value();
1027 } 1027 }
1028 } 1028 }
1029 1029
1030 1030
1031 MaybeObject* Object::GetHash(CreationFlag flag) { 1031 Object* Object::GetHash() {
1032 // The object is either a number, a name, an odd-ball, 1032 // The object is either a number, a name, an odd-ball,
1033 // a real JS object, or a Harmony proxy. 1033 // a real JS object, or a Harmony proxy.
1034 if (IsNumber()) { 1034 if (IsNumber()) {
1035 uint32_t hash = ComputeLongHash(double_to_uint64(Number())); 1035 uint32_t hash = ComputeLongHash(double_to_uint64(Number()));
1036 return Smi::FromInt(hash & Smi::kMaxValue); 1036 return Smi::FromInt(hash & Smi::kMaxValue);
1037 } 1037 }
1038 if (IsName()) { 1038 if (IsName()) {
1039 uint32_t hash = Name::cast(this)->Hash(); 1039 uint32_t hash = Name::cast(this)->Hash();
1040 return Smi::FromInt(hash); 1040 return Smi::FromInt(hash);
1041 } 1041 }
1042 if (IsOddball()) { 1042 if (IsOddball()) {
1043 uint32_t hash = Oddball::cast(this)->to_string()->Hash(); 1043 uint32_t hash = Oddball::cast(this)->to_string()->Hash();
1044 return Smi::FromInt(hash); 1044 return Smi::FromInt(hash);
1045 } 1045 }
1046 if (IsJSReceiver()) {
1047 return JSReceiver::cast(this)->GetIdentityHash(flag);
1048 }
1049 1046
1050 UNREACHABLE(); 1047 ASSERT(IsJSReceiver());
1051 return Smi::FromInt(0); 1048 return JSReceiver::cast(this)->GetIdentityHash();
1052 } 1049 }
1053 1050
1054 1051
1052 Handle<Object> Object::GetOrCreateHash(Handle<Object> object,
1053 Isolate* isolate) {
1054 Handle<Object> hash(object->GetHash(), isolate);
1055 if (hash->IsSmi())
1056 return hash;
1057
1058 ASSERT(object->IsJSReceiver());
1059 return JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver>::cast(object));
1060 }
1061
1062
1055 bool Object::SameValue(Object* other) { 1063 bool Object::SameValue(Object* other) {
1056 if (other == this) return true; 1064 if (other == this) return true;
1057 1065
1058 // The object is either a number, a name, an odd-ball, 1066 // The object is either a number, a name, an odd-ball,
1059 // a real JS object, or a Harmony proxy. 1067 // a real JS object, or a Harmony proxy.
1060 if (IsNumber() && other->IsNumber()) { 1068 if (IsNumber() && other->IsNumber()) {
1061 double this_value = Number(); 1069 double this_value = Number();
1062 double other_value = other->Number(); 1070 double other_value = other->Number();
1063 bool equal = this_value == other_value; 1071 bool equal = this_value == other_value;
1064 // SameValue(NaN, NaN) is true. 1072 // SameValue(NaN, NaN) is true.
(...skipping 2683 matching lines...) Expand 10 before | Expand all | Expand 10 after
3748 Handle<JSReceiver> receiver(receiver_raw); 3756 Handle<JSReceiver> receiver(receiver_raw);
3749 Handle<String> name = isolate->factory()->Uint32ToString(index); 3757 Handle<String> name = isolate->factory()->Uint32ToString(index);
3750 return proxy->GetPropertyAttributeWithHandler(*receiver, *name); 3758 return proxy->GetPropertyAttributeWithHandler(*receiver, *name);
3751 } 3759 }
3752 3760
3753 3761
3754 void JSProxy::Fix(Handle<JSProxy> proxy) { 3762 void JSProxy::Fix(Handle<JSProxy> proxy) {
3755 Isolate* isolate = proxy->GetIsolate(); 3763 Isolate* isolate = proxy->GetIsolate();
3756 3764
3757 // Save identity hash. 3765 // Save identity hash.
3758 Handle<Object> hash = JSProxy::GetIdentityHash(proxy, OMIT_CREATION); 3766 Handle<Object> hash(proxy->GetIdentityHash(), isolate);
3759 3767
3760 if (proxy->IsJSFunctionProxy()) { 3768 if (proxy->IsJSFunctionProxy()) {
3761 isolate->factory()->BecomeJSFunction(proxy); 3769 isolate->factory()->BecomeJSFunction(proxy);
3762 // Code will be set on the JavaScript side. 3770 // Code will be set on the JavaScript side.
3763 } else { 3771 } else {
3764 isolate->factory()->BecomeJSObject(proxy); 3772 isolate->factory()->BecomeJSObject(proxy);
3765 } 3773 }
3766 ASSERT(proxy->IsJSObject()); 3774 ASSERT(proxy->IsJSObject());
3767 3775
3768 // Inherit identity, if it was present. 3776 // Inherit identity, if it was present.
3769 if (hash->IsSmi()) { 3777 if (hash->IsSmi()) {
3770 JSObject::SetIdentityHash(Handle<JSObject>::cast(proxy), Smi::cast(*hash)); 3778 JSObject::SetIdentityHash(Handle<JSObject>::cast(proxy),
3779 Handle<Smi>::cast(hash));
3771 } 3780 }
3772 } 3781 }
3773 3782
3774 3783
3775 MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(const char* name, 3784 MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(const char* name,
3776 Handle<Object> derived, 3785 Handle<Object> derived,
3777 int argc, 3786 int argc,
3778 Handle<Object> argv[]) { 3787 Handle<Object> argv[]) {
3779 Isolate* isolate = GetIsolate(); 3788 Isolate* isolate = GetIsolate();
3780 Handle<Object> handler(this->handler(), isolate); 3789 Handle<Object> handler(this->handler(), isolate);
(...skipping 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after
4781 // within a smi. 4790 // within a smi.
4782 hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue; 4791 hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue;
4783 attempts++; 4792 attempts++;
4784 } while (hash_value == 0 && attempts < 30); 4793 } while (hash_value == 0 && attempts < 30);
4785 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 4794 hash_value = hash_value != 0 ? hash_value : 1; // never return 0
4786 4795
4787 return Smi::FromInt(hash_value); 4796 return Smi::FromInt(hash_value);
4788 } 4797 }
4789 4798
4790 4799
4791 void JSObject::SetIdentityHash(Handle<JSObject> object, Smi* hash) { 4800 void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) {
4792 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), 4801 Isolate* isolate = object->GetIsolate();
4793 object->SetHiddenProperty( 4802 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash);
4794 object->GetHeap()->identity_hash_string(), hash));
4795 } 4803 }
4796 4804
4797 4805
4798 int JSObject::GetIdentityHash(Handle<JSObject> object) { 4806 Object* JSObject::GetIdentityHash() {
4799 CALL_AND_RETRY_OR_DIE(object->GetIsolate(), 4807 Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_string());
4800 object->GetIdentityHash(ALLOW_CREATION), 4808 return stored_value->IsSmi() ? stored_value : GetHeap()->undefined_value();
4801 return Smi::cast(__object__)->value(),
4802 return 0);
4803 } 4809 }
4804 4810
4805 4811
4806 MaybeObject* JSObject::GetIdentityHash(CreationFlag flag) { 4812 Handle<Object> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) {
4807 Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_string()); 4813 Handle<Object> hash(object->GetIdentityHash(), object->GetIsolate());
4808 if (stored_value->IsSmi()) return stored_value; 4814 if (hash->IsSmi())
4815 return hash;
4809 4816
4810 // Do not generate permanent identity hash code if not requested. 4817 Isolate* isolate = object->GetIsolate();
4811 if (flag == OMIT_CREATION) return GetHeap()->undefined_value();
4812 4818
4813 Smi* hash = GenerateIdentityHash(); 4819 hash = handle(object->GenerateIdentityHash(), isolate);
4814 MaybeObject* result = SetHiddenProperty(GetHeap()->identity_hash_string(), 4820 Handle<Object> result = SetHiddenProperty(object,
4815 hash); 4821 isolate->factory()->identity_hash_string(), hash);
4816 if (result->IsFailure()) return result; 4822
4817 if (result->ToObjectUnchecked()->IsUndefined()) { 4823 if (result->IsUndefined()) {
4818 // Trying to get hash of detached proxy. 4824 // Trying to get hash of detached proxy.
4819 return Smi::FromInt(0); 4825 return handle(Smi::FromInt(0), isolate);
4820 } 4826 }
4827
4821 return hash; 4828 return hash;
4822 } 4829 }
4823 4830
4824 4831
4825 Handle<Object> JSProxy::GetIdentityHash(Handle<JSProxy> proxy, 4832 Object* JSProxy::GetIdentityHash() {
4826 CreationFlag flag) { 4833 return this->hash();
4827 CALL_HEAP_FUNCTION(proxy->GetIsolate(), proxy->GetIdentityHash(flag), Object);
4828 } 4834 }
4829 4835
4830 4836
4831 MaybeObject* JSProxy::GetIdentityHash(CreationFlag flag) { 4837 Handle<Object> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) {
4832 Object* hash = this->hash(); 4838 Isolate* isolate = proxy->GetIsolate();
4833 if (!hash->IsSmi() && flag == ALLOW_CREATION) { 4839
4834 hash = GenerateIdentityHash(); 4840 Handle<Object> hash(proxy->GetIdentityHash(), isolate);
4835 set_hash(hash); 4841 if (hash->IsSmi())
4836 } 4842 return hash;
4843
4844 hash = handle(proxy->GenerateIdentityHash(), isolate);
4845 proxy->set_hash(*hash);
4837 return hash; 4846 return hash;
4838 } 4847 }
4839 4848
4840 4849
4841 Object* JSObject::GetHiddenProperty(Name* key) { 4850 Object* JSObject::GetHiddenProperty(Name* key) {
4842 ASSERT(key->IsUniqueName()); 4851 ASSERT(key->IsUniqueName());
4843 if (IsJSGlobalProxy()) { 4852 if (IsJSGlobalProxy()) {
4844 // For a proxy, use the prototype as target object. 4853 // For a proxy, use the prototype as target object.
4845 Object* proxy_parent = GetPrototype(); 4854 Object* proxy_parent = GetPrototype();
4846 // If the proxy is detached, return undefined. 4855 // If the proxy is detached, return undefined.
4847 if (proxy_parent->IsNull()) return GetHeap()->the_hole_value(); 4856 if (proxy_parent->IsNull()) return GetHeap()->the_hole_value();
4848 ASSERT(proxy_parent->IsJSGlobalObject()); 4857 ASSERT(proxy_parent->IsJSGlobalObject());
4849 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); 4858 return JSObject::cast(proxy_parent)->GetHiddenProperty(key);
4850 } 4859 }
4851 ASSERT(!IsJSGlobalProxy()); 4860 ASSERT(!IsJSGlobalProxy());
4852 MaybeObject* hidden_lookup = 4861 Object* inline_value = GetHiddenPropertiesHashTable();
4853 GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE);
4854 Object* inline_value = hidden_lookup->ToObjectUnchecked();
4855 4862
4856 if (inline_value->IsSmi()) { 4863 if (inline_value->IsSmi()) {
4857 // Handle inline-stored identity hash. 4864 // Handle inline-stored identity hash.
4858 if (key == GetHeap()->identity_hash_string()) { 4865 if (key == GetHeap()->identity_hash_string()) {
4859 return inline_value; 4866 return inline_value;
4860 } else { 4867 } else {
4861 return GetHeap()->the_hole_value(); 4868 return GetHeap()->the_hole_value();
4862 } 4869 }
4863 } 4870 }
4864 4871
4865 if (inline_value->IsUndefined()) return GetHeap()->the_hole_value(); 4872 if (inline_value->IsUndefined()) return GetHeap()->the_hole_value();
4866 4873
4867 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); 4874 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value);
4868 Object* entry = hashtable->Lookup(key); 4875 Object* entry = hashtable->Lookup(key);
4869 return entry; 4876 return entry;
4870 } 4877 }
4871 4878
4872 4879
4873 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj, 4880 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object,
4874 Handle<Name> key, 4881 Handle<Name> key,
4875 Handle<Object> value) { 4882 Handle<Object> value) {
4876 CALL_HEAP_FUNCTION(obj->GetIsolate(), 4883 Isolate* isolate = object->GetIsolate();
4877 obj->SetHiddenProperty(*key, *value), 4884
4878 Object); 4885 ASSERT(key->IsUniqueName());
4886 if (object->IsJSGlobalProxy()) {
4887 // For a proxy, use the prototype as target object.
4888 Handle<Object> proxy_parent(object->GetPrototype(), isolate);
4889 // If the proxy is detached, return undefined.
4890 if (proxy_parent->IsNull()) return isolate->factory()->undefined_value();
4891 ASSERT(proxy_parent->IsJSGlobalObject());
4892 return SetHiddenProperty(Handle<JSObject>::cast(proxy_parent), key, value);
4893 }
4894 ASSERT(!object->IsJSGlobalProxy());
4895
4896 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate);
4897
4898 // If there is no backing store yet, store the identity hash inline.
4899 if (value->IsSmi() &&
4900 *key == *isolate->factory()->identity_hash_string() &&
4901 (inline_value->IsUndefined() || inline_value->IsSmi())) {
4902 return JSObject::SetHiddenPropertiesHashTable(object, value);
4903 }
4904
4905 Handle<ObjectHashTable> hashtable =
4906 GetOrCreateHiddenPropertiesHashtable(object);
4907
4908 // If it was found, check if the key is already in the dictionary.
4909 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key,
4910 value);
4911 if (*new_table != *hashtable) {
4912 // If adding the key expanded the dictionary (i.e., Add returned a new
4913 // dictionary), store it back to the object.
4914 SetHiddenPropertiesHashTable(object, new_table);
4915 }
4916
4917 // Return this to mark success.
4918 return object;
4879 } 4919 }
4880 4920
4881 4921
4882 MaybeObject* JSObject::SetHiddenProperty(Name* key, Object* value) {
4883 ASSERT(key->IsUniqueName());
4884 if (IsJSGlobalProxy()) {
4885 // For a proxy, use the prototype as target object.
4886 Object* proxy_parent = GetPrototype();
4887 // If the proxy is detached, return undefined.
4888 if (proxy_parent->IsNull()) return GetHeap()->undefined_value();
4889 ASSERT(proxy_parent->IsJSGlobalObject());
4890 return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value);
4891 }
4892 ASSERT(!IsJSGlobalProxy());
4893 MaybeObject* hidden_lookup =
4894 GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE);
4895 Object* inline_value = hidden_lookup->ToObjectUnchecked();
4896
4897 // If there is no backing store yet, store the identity hash inline.
4898 if (value->IsSmi() &&
4899 key == GetHeap()->identity_hash_string() &&
4900 (inline_value->IsUndefined() || inline_value->IsSmi())) {
4901 return SetHiddenPropertiesHashTable(value);
4902 }
4903
4904 hidden_lookup = GetHiddenPropertiesHashTable(CREATE_NEW_IF_ABSENT);
4905 ObjectHashTable* hashtable;
4906 if (!hidden_lookup->To(&hashtable)) return hidden_lookup;
4907
4908 // If it was found, check if the key is already in the dictionary.
4909 MaybeObject* insert_result = hashtable->Put(key, value);
4910 ObjectHashTable* new_table;
4911 if (!insert_result->To(&new_table)) return insert_result;
4912 if (new_table != hashtable) {
4913 // If adding the key expanded the dictionary (i.e., Add returned a new
4914 // dictionary), store it back to the object.
4915 MaybeObject* store_result = SetHiddenPropertiesHashTable(new_table);
4916 if (store_result->IsFailure()) return store_result;
4917 }
4918 // Return this to mark success.
4919 return this;
4920 }
4921
4922
4923 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { 4922 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) {
4924 Isolate* isolate = object->GetIsolate(); 4923 Isolate* isolate = object->GetIsolate();
4925 ASSERT(key->IsUniqueName()); 4924 ASSERT(key->IsUniqueName());
4926 4925
4927 if (object->IsJSGlobalProxy()) { 4926 if (object->IsJSGlobalProxy()) {
4928 Handle<Object> proto(object->GetPrototype(), isolate); 4927 Handle<Object> proto(object->GetPrototype(), isolate);
4929 if (proto->IsNull()) return; 4928 if (proto->IsNull()) return;
4930 ASSERT(proto->IsJSGlobalObject()); 4929 ASSERT(proto->IsJSGlobalObject());
4931 return DeleteHiddenProperty(Handle<JSObject>::cast(proto), key); 4930 return DeleteHiddenProperty(Handle<JSObject>::cast(proto), key);
4932 } 4931 }
4933 4932
4934 MaybeObject* hidden_lookup = 4933 Object* inline_value = object->GetHiddenPropertiesHashTable();
4935 object->GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE);
4936 Object* inline_value = hidden_lookup->ToObjectUnchecked();
4937 4934
4938 // We never delete (inline-stored) identity hashes. 4935 // We never delete (inline-stored) identity hashes.
4939 ASSERT(*key != isolate->heap()->identity_hash_string()); 4936 ASSERT(*key != *isolate->factory()->identity_hash_string());
4940 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; 4937 if (inline_value->IsUndefined() || inline_value->IsSmi()) return;
4941 4938
4942 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); 4939 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value));
4943 PutIntoObjectHashTable(hashtable, key, isolate->factory()->the_hole_value()); 4940 ObjectHashTable::Put(hashtable, key, isolate->factory()->the_hole_value());
4944 } 4941 }
4945 4942
4946 4943
4947 bool JSObject::HasHiddenProperties() { 4944 bool JSObject::HasHiddenProperties() {
4948 return GetPropertyAttributePostInterceptor(this, 4945 return GetPropertyAttributePostInterceptor(this,
4949 GetHeap()->hidden_string(), 4946 GetHeap()->hidden_string(),
4950 false) != ABSENT; 4947 false) != ABSENT;
4951 } 4948 }
4952 4949
4953 4950
4954 MaybeObject* JSObject::GetHiddenPropertiesHashTable( 4951 Object* JSObject::GetHiddenPropertiesHashTable() {
4955 InitializeHiddenProperties init_option) {
4956 ASSERT(!IsJSGlobalProxy()); 4952 ASSERT(!IsJSGlobalProxy());
4957 Object* inline_value;
4958 if (HasFastProperties()) { 4953 if (HasFastProperties()) {
4959 // If the object has fast properties, check whether the first slot 4954 // If the object has fast properties, check whether the first slot
4960 // in the descriptor array matches the hidden string. Since the 4955 // in the descriptor array matches the hidden string. Since the
4961 // hidden strings hash code is zero (and no other name has hash 4956 // hidden strings hash code is zero (and no other name has hash
4962 // code zero) it will always occupy the first entry if present. 4957 // code zero) it will always occupy the first entry if present.
4963 DescriptorArray* descriptors = this->map()->instance_descriptors(); 4958 DescriptorArray* descriptors = this->map()->instance_descriptors();
4964 if (descriptors->number_of_descriptors() > 0) { 4959 if (descriptors->number_of_descriptors() > 0) {
4965 int sorted_index = descriptors->GetSortedKeyIndex(0); 4960 int sorted_index = descriptors->GetSortedKeyIndex(0);
4966 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && 4961 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() &&
4967 sorted_index < map()->NumberOfOwnDescriptors()) { 4962 sorted_index < map()->NumberOfOwnDescriptors()) {
4968 ASSERT(descriptors->GetType(sorted_index) == FIELD); 4963 ASSERT(descriptors->GetType(sorted_index) == FIELD);
4969 ASSERT(descriptors->GetDetails(sorted_index).representation(). 4964 ASSERT(descriptors->GetDetails(sorted_index).representation().
4970 IsCompatibleForLoad(Representation::Tagged())); 4965 IsCompatibleForLoad(Representation::Tagged()));
4971 inline_value = this->RawFastPropertyAt( 4966 return this->RawFastPropertyAt(
4972 descriptors->GetFieldIndex(sorted_index)); 4967 descriptors->GetFieldIndex(sorted_index));
4973 } else { 4968 } else {
4974 inline_value = GetHeap()->undefined_value(); 4969 return GetHeap()->undefined_value();
4975 } 4970 }
4976 } else { 4971 } else {
4977 inline_value = GetHeap()->undefined_value(); 4972 return GetHeap()->undefined_value();
4978 } 4973 }
4979 } else { 4974 } else {
4980 PropertyAttributes attributes; 4975 PropertyAttributes attributes;
4981 // You can't install a getter on a property indexed by the hidden string, 4976 // You can't install a getter on a property indexed by the hidden string,
4982 // so we can be sure that GetLocalPropertyPostInterceptor returns a real 4977 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4983 // object. 4978 // object.
4984 inline_value = 4979 return GetLocalPropertyPostInterceptor(this,
4985 GetLocalPropertyPostInterceptor(this, 4980 GetHeap()->hidden_string(),
4986 GetHeap()->hidden_string(), 4981 &attributes)->ToObjectUnchecked();
4987 &attributes)->ToObjectUnchecked(); 4982 }
4983 }
4984
4985 Handle<ObjectHashTable> JSObject::GetOrCreateHiddenPropertiesHashtable(
4986 Handle<JSObject> object) {
4987 Isolate* isolate = object->GetIsolate();
4988
4989 static const int kInitialCapacity = 4;
4990 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate);
4991 if (inline_value->IsHashTable()) {
4992 return Handle<ObjectHashTable>::cast(inline_value);
4988 } 4993 }
4989 4994
4990 if (init_option == ONLY_RETURN_INLINE_VALUE || 4995 Handle<ObjectHashTable> hashtable = isolate->factory()->NewObjectHashTable(
4991 inline_value->IsHashTable()) { 4996 kInitialCapacity,
4992 return inline_value; 4997 USE_CUSTOM_MINIMUM_CAPACITY);
4993 }
4994
4995 ObjectHashTable* hashtable;
4996 static const int kInitialCapacity = 4;
4997 MaybeObject* maybe_obj =
4998 ObjectHashTable::Allocate(GetHeap(),
4999 kInitialCapacity,
5000 ObjectHashTable::USE_CUSTOM_MINIMUM_CAPACITY);
5001 if (!maybe_obj->To<ObjectHashTable>(&hashtable)) return maybe_obj;
5002 4998
5003 if (inline_value->IsSmi()) { 4999 if (inline_value->IsSmi()) {
5004 // We were storing the identity hash inline and now allocated an actual 5000 // We were storing the identity hash inline and now allocated an actual
5005 // dictionary. Put the identity hash into the new dictionary. 5001 // dictionary. Put the identity hash into the new dictionary.
5006 MaybeObject* insert_result = 5002 hashtable = ObjectHashTable::Put(hashtable,
5007 hashtable->Put(GetHeap()->identity_hash_string(), inline_value); 5003 isolate->factory()->identity_hash_string(),
5008 ObjectHashTable* new_table; 5004 inline_value);
5009 if (!insert_result->To(&new_table)) return insert_result;
5010 // We expect no resizing for the first insert.
5011 ASSERT_EQ(hashtable, new_table);
5012 } 5005 }
5013 5006
5014 MaybeObject* store_result = SetLocalPropertyIgnoreAttributesTrampoline( 5007 JSObject::SetLocalPropertyIgnoreAttributes(
5015 GetHeap()->hidden_string(), 5008 object,
5009 isolate->factory()->hidden_string(),
5016 hashtable, 5010 hashtable,
5017 DONT_ENUM, 5011 DONT_ENUM,
5018 OPTIMAL_REPRESENTATION, 5012 OPTIMAL_REPRESENTATION,
5019 ALLOW_AS_CONSTANT, 5013 ALLOW_AS_CONSTANT,
5020 OMIT_EXTENSIBILITY_CHECK); 5014 OMIT_EXTENSIBILITY_CHECK);
5021 if (store_result->IsFailure()) return store_result; 5015
5022 return hashtable; 5016 return hashtable;
5023 } 5017 }
5024 5018
5025 5019
5026 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { 5020 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object,
5027 ASSERT(!IsJSGlobalProxy()); 5021 Handle<Object> value) {
5022 ASSERT(!object->IsJSGlobalProxy());
5023
5024 Isolate* isolate = object->GetIsolate();
5025
5028 // We can store the identity hash inline iff there is no backing store 5026 // We can store the identity hash inline iff there is no backing store
5029 // for hidden properties yet. 5027 // for hidden properties yet.
5030 ASSERT(HasHiddenProperties() != value->IsSmi()); 5028 ASSERT(object->HasHiddenProperties() != value->IsSmi());
5031 if (HasFastProperties()) { 5029 if (object->HasFastProperties()) {
5032 // If the object has fast properties, check whether the first slot 5030 // If the object has fast properties, check whether the first slot
5033 // in the descriptor array matches the hidden string. Since the 5031 // in the descriptor array matches the hidden string. Since the
5034 // hidden strings hash code is zero (and no other name has hash 5032 // hidden strings hash code is zero (and no other name has hash
5035 // code zero) it will always occupy the first entry if present. 5033 // code zero) it will always occupy the first entry if present.
5036 DescriptorArray* descriptors = this->map()->instance_descriptors(); 5034 DescriptorArray* descriptors = object->map()->instance_descriptors();
5037 if (descriptors->number_of_descriptors() > 0) { 5035 if (descriptors->number_of_descriptors() > 0) {
5038 int sorted_index = descriptors->GetSortedKeyIndex(0); 5036 int sorted_index = descriptors->GetSortedKeyIndex(0);
5039 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && 5037 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string()
5040 sorted_index < map()->NumberOfOwnDescriptors()) { 5038 && sorted_index < object->map()->NumberOfOwnDescriptors()) {
5041 ASSERT(descriptors->GetType(sorted_index) == FIELD); 5039 ASSERT(descriptors->GetType(sorted_index) == FIELD);
5042 FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), value); 5040 object->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index),
5043 return this; 5041 *value);
5042 return object;
5044 } 5043 }
5045 } 5044 }
5046 } 5045 }
5047 MaybeObject* store_result = SetLocalPropertyIgnoreAttributesTrampoline( 5046
5048 GetHeap()->hidden_string(), 5047 SetLocalPropertyIgnoreAttributes(object,
5049 value, 5048 isolate->factory()->hidden_string(),
5050 DONT_ENUM, 5049 value,
5051 OPTIMAL_REPRESENTATION, 5050 DONT_ENUM,
5052 ALLOW_AS_CONSTANT, 5051 OPTIMAL_REPRESENTATION,
5053 OMIT_EXTENSIBILITY_CHECK); 5052 ALLOW_AS_CONSTANT,
5054 if (store_result->IsFailure()) return store_result; 5053 OMIT_EXTENSIBILITY_CHECK);
5055 return this; 5054 return object;
5056 } 5055 }
5057 5056
5058 5057
5059 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, 5058 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object,
5060 Handle<Name> name, 5059 Handle<Name> name,
5061 DeleteMode mode) { 5060 DeleteMode mode) {
5062 // Check local property, ignore interceptor. 5061 // Check local property, ignore interceptor.
5063 Isolate* isolate = object->GetIsolate(); 5062 Isolate* isolate = object->GetIsolate();
5064 LookupResult result(isolate); 5063 LookupResult result(isolate);
5065 object->LocalLookupRealNamedProperty(*name, &result); 5064 object->LocalLookupRealNamedProperty(*name, &result);
(...skipping 10065 matching lines...) Expand 10 before | Expand all | Expand 10 after
15131 15130
15132 template<typename Shape, typename Key> 15131 template<typename Shape, typename Key>
15133 MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap, 15132 MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap,
15134 int at_least_space_for, 15133 int at_least_space_for,
15135 PretenureFlag pretenure) { 15134 PretenureFlag pretenure) {
15136 Object* obj; 15135 Object* obj;
15137 { MaybeObject* maybe_obj = 15136 { MaybeObject* maybe_obj =
15138 HashTable<Shape, Key>::Allocate( 15137 HashTable<Shape, Key>::Allocate(
15139 heap, 15138 heap,
15140 at_least_space_for, 15139 at_least_space_for,
15141 HashTable<Shape, Key>::USE_DEFAULT_MINIMUM_CAPACITY, 15140 USE_DEFAULT_MINIMUM_CAPACITY,
15142 pretenure); 15141 pretenure);
15143 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 15142 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
15144 } 15143 }
15145 // Initialize the next enumeration index. 15144 // Initialize the next enumeration index.
15146 Dictionary<Shape, Key>::cast(obj)-> 15145 Dictionary<Shape, Key>::cast(obj)->
15147 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); 15146 SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
15148 return obj; 15147 return obj;
15149 } 15148 }
15150 15149
15151 15150
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
15697 obj->set_properties(fields); 15696 obj->set_properties(fields);
15698 ASSERT(obj->IsJSObject()); 15697 ASSERT(obj->IsJSObject());
15699 15698
15700 // Check that it really works. 15699 // Check that it really works.
15701 ASSERT(obj->HasFastProperties()); 15700 ASSERT(obj->HasFastProperties());
15702 15701
15703 return obj; 15702 return obj;
15704 } 15703 }
15705 15704
15706 15705
15706 Handle<ObjectHashSet> ObjectHashSet::EnsureCapacity(
15707 Handle<ObjectHashSet> table,
15708 int n,
15709 Handle<Object> key,
15710 PretenureFlag pretenure) {
15711 Handle<HashTable<ObjectHashTableShape<1>, Object*> > table_base = table;
15712 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
15713 table_base->EnsureCapacity(n, *key, pretenure),
15714 ObjectHashSet);
15715 }
15716
15717
15718 Handle<ObjectHashSet> ObjectHashSet::Shrink(Handle<ObjectHashSet> table,
15719 Handle<Object> key) {
15720 Handle<HashTable<ObjectHashTableShape<1>, Object*> > table_base = table;
15721 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
15722 table_base->Shrink(*key),
15723 ObjectHashSet);
15724 }
15725
15726
15707 bool ObjectHashSet::Contains(Object* key) { 15727 bool ObjectHashSet::Contains(Object* key) {
15708 ASSERT(IsKey(key)); 15728 ASSERT(IsKey(key));
15709 15729
15710 // If the object does not have an identity hash, it was never used as a key. 15730 // If the object does not have an identity hash, it was never used as a key.
15711 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); 15731 Object* hash = key->GetHash();
15712 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return false; 15732 if (hash->IsUndefined()) return false;
15713 } 15733
15714 return (FindEntry(key) != kNotFound); 15734 return (FindEntry(key) != kNotFound);
15715 } 15735 }
15716 15736
15717 15737
15718 MaybeObject* ObjectHashSet::Add(Object* key) { 15738 Handle<ObjectHashSet> ObjectHashSet::Add(Handle<ObjectHashSet> table,
15719 ASSERT(IsKey(key)); 15739 Handle<Object> key) {
15740 ASSERT(table->IsKey(*key));
15720 15741
15721 // Make sure the key object has an identity hash code. 15742 // Make sure the key object has an identity hash code.
15722 int hash; 15743 Handle<Object> object_hash = Object::GetOrCreateHash(key,
15723 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); 15744 table->GetIsolate());
15724 if (maybe_hash->IsFailure()) return maybe_hash; 15745
15725 ASSERT(key->GetHash(OMIT_CREATION) == maybe_hash); 15746 int entry = table->FindEntry(*key);
15726 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
15727 }
15728 int entry = FindEntry(key);
15729 15747
15730 // Check whether key is already present. 15748 // Check whether key is already present.
15731 if (entry != kNotFound) return this; 15749 if (entry != kNotFound) return table;
15732 15750
15733 // Check whether the hash set should be extended and add entry. 15751 // Check whether the hash set should be extended and add entry.
15734 Object* obj; 15752 Handle<ObjectHashSet> new_table =
15735 { MaybeObject* maybe_obj = EnsureCapacity(1, key); 15753 ObjectHashSet::EnsureCapacity(table, 1, key);
15736 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 15754 entry = new_table->FindInsertionEntry(Smi::cast(*object_hash)->value());
15737 } 15755 new_table->set(EntryToIndex(entry), *key);
15738 ObjectHashSet* table = ObjectHashSet::cast(obj); 15756 new_table->ElementAdded();
15739 entry = table->FindInsertionEntry(hash); 15757 return new_table;
15740 table->set(EntryToIndex(entry), key);
15741 table->ElementAdded();
15742 return table;
15743 } 15758 }
15744 15759
15745 15760
15746 MaybeObject* ObjectHashSet::Remove(Object* key) { 15761 Handle<ObjectHashSet> ObjectHashSet::Remove(Handle<ObjectHashSet> table,
15747 ASSERT(IsKey(key)); 15762 Handle<Object> key) {
15763 ASSERT(table->IsKey(*key));
15748 15764
15749 // If the object does not have an identity hash, it was never used as a key. 15765 // If the object does not have an identity hash, it was never used as a key.
15750 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); 15766 if (key->GetHash()->IsUndefined()) return table;
15751 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return this; 15767
15752 } 15768 int entry = table->FindEntry(*key);
15753 int entry = FindEntry(key);
15754 15769
15755 // Check whether key is actually present. 15770 // Check whether key is actually present.
15756 if (entry == kNotFound) return this; 15771 if (entry == kNotFound) return table;
15757 15772
15758 // Remove entry and try to shrink this hash set. 15773 // Remove entry and try to shrink this hash set.
15759 set_the_hole(EntryToIndex(entry)); 15774 table->set_the_hole(EntryToIndex(entry));
15760 ElementRemoved(); 15775 table->ElementRemoved();
15761 return Shrink(key); 15776
15777 return ObjectHashSet::Shrink(table, key);
15762 } 15778 }
15763 15779
15764 15780
15781 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity(
15782 Handle<ObjectHashTable> table,
15783 int n,
15784 Handle<Object> key,
15785 PretenureFlag pretenure) {
15786 Handle<HashTable<ObjectHashTableShape<2>, Object*> > table_base = table;
15787 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
15788 table_base->EnsureCapacity(n, *key, pretenure),
15789 ObjectHashTable);
15790 }
15791
15792
15793 Handle<ObjectHashTable> ObjectHashTable::Shrink(
15794 Handle<ObjectHashTable> table, Handle<Object> key) {
15795 Handle<HashTable<ObjectHashTableShape<2>, Object*> > table_base = table;
15796 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
15797 table_base->Shrink(*key),
15798 ObjectHashTable);
15799 }
15800
15801
15765 Object* ObjectHashTable::Lookup(Object* key) { 15802 Object* ObjectHashTable::Lookup(Object* key) {
15766 ASSERT(IsKey(key)); 15803 ASSERT(IsKey(key));
15767 15804
15768 // If the object does not have an identity hash, it was never used as a key. 15805 // If the object does not have an identity hash, it was never used as a key.
15769 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); 15806 Object* hash = key->GetHash();
15770 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) { 15807 if (hash->IsUndefined()) {
15771 return GetHeap()->the_hole_value(); 15808 return GetHeap()->the_hole_value();
15772 }
15773 } 15809 }
15774 int entry = FindEntry(key); 15810 int entry = FindEntry(key);
15775 if (entry == kNotFound) return GetHeap()->the_hole_value(); 15811 if (entry == kNotFound) return GetHeap()->the_hole_value();
15776 return get(EntryToIndex(entry) + 1); 15812 return get(EntryToIndex(entry) + 1);
15777 } 15813 }
15778 15814
15779 15815
15780 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) { 15816 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
15781 ASSERT(IsKey(key)); 15817 Handle<Object> key,
15818 Handle<Object> value) {
15819 ASSERT(table->IsKey(*key));
15820
15821 Isolate* isolate = table->GetIsolate();
15782 15822
15783 // Make sure the key object has an identity hash code. 15823 // Make sure the key object has an identity hash code.
15784 int hash; 15824 Handle<Object> hash = Object::GetOrCreateHash(key, isolate);
15785 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); 15825
15786 if (maybe_hash->IsFailure()) return maybe_hash; 15826 int entry = table->FindEntry(*key);
15787 ASSERT(key->GetHash(OMIT_CREATION) == maybe_hash);
15788 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
15789 }
15790 int entry = FindEntry(key);
15791 15827
15792 // Check whether to perform removal operation. 15828 // Check whether to perform removal operation.
15793 if (value->IsTheHole()) { 15829 if (value->IsTheHole()) {
15794 if (entry == kNotFound) return this; 15830 if (entry == kNotFound) return table;
15795 RemoveEntry(entry); 15831 table->RemoveEntry(entry);
15796 return Shrink(key); 15832 return Shrink(table, key);
15797 } 15833 }
15798 15834
15799 // Key is already in table, just overwrite value. 15835 // Key is already in table, just overwrite value.
15800 if (entry != kNotFound) { 15836 if (entry != kNotFound) {
15801 set(EntryToIndex(entry) + 1, value); 15837 table->set(EntryToIndex(entry) + 1, *value);
15802 return this; 15838 return table;
15803 } 15839 }
15804 15840
15805 // Check whether the hash table should be extended. 15841 // Check whether the hash table should be extended.
15806 Object* obj; 15842 table = EnsureCapacity(table, 1, key);
15807 { MaybeObject* maybe_obj = EnsureCapacity(1, key); 15843 table->AddEntry(table->FindInsertionEntry(Handle<Smi>::cast(hash)->value()),
15808 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 15844 *key,
15809 } 15845 *value);
15810 ObjectHashTable* table = ObjectHashTable::cast(obj);
15811 table->AddEntry(table->FindInsertionEntry(hash), key, value);
15812 return table; 15846 return table;
15813 } 15847 }
15814 15848
15815 15849
15816 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { 15850 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
15817 set(EntryToIndex(entry), key); 15851 set(EntryToIndex(entry), key);
15818 set(EntryToIndex(entry) + 1, value); 15852 set(EntryToIndex(entry) + 1, value);
15819 ElementAdded(); 15853 ElementAdded();
15820 } 15854 }
15821 15855
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
16396 #define ERROR_MESSAGES_TEXTS(C, T) T, 16430 #define ERROR_MESSAGES_TEXTS(C, T) T,
16397 static const char* error_messages_[] = { 16431 static const char* error_messages_[] = {
16398 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16432 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16399 }; 16433 };
16400 #undef ERROR_MESSAGES_TEXTS 16434 #undef ERROR_MESSAGES_TEXTS
16401 return error_messages_[reason]; 16435 return error_messages_[reason];
16402 } 16436 }
16403 16437
16404 16438
16405 } } // namespace v8::internal 16439 } } // namespace v8::internal
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