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

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: ready 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
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());
rafaelw 2013/11/04 15:12:01 Note that I've changed this for consistency with G
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 JSObject::SetHiddenProperty(
Michael Starzinger 2013/11/04 17:58:58 nit: The explicit name-space prefix "JSObject::" s
rafaelw 2013/11/05 09:56:54 Done.
4794 object->GetHeap()->identity_hash_string(), hash)); 4803 object, isolate->factory()->identity_hash_string(), hash);
4795 } 4804 }
4796 4805
4797 4806
4798 int JSObject::GetIdentityHash(Handle<JSObject> object) { 4807 int JSObject::GetIdentityHash(Handle<JSObject> object) {
4799 CALL_AND_RETRY_OR_DIE(object->GetIsolate(), 4808 Handle<Object> hash = JSObject::GetOrCreateIdentityHash(object);
rafaelw 2013/11/04 15:12:01 I *think* this is right. It's a bit hard for me to
Michael Starzinger 2013/11/04 17:58:58 AFAICT, the return value of JSObject::GetOrCreateI
rafaelw 2013/11/05 09:56:54 Done.
4800 object->GetIdentityHash(ALLOW_CREATION), 4809 return hash->IsSmi() ? Handle<Smi>::cast(hash)->value() : 0;
4801 return Smi::cast(__object__)->value(),
4802 return 0);
4803 } 4810 }
4804 4811
4805 4812
4806 MaybeObject* JSObject::GetIdentityHash(CreationFlag flag) { 4813 Object* JSObject::GetIdentityHash() {
4807 Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_string()); 4814 Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_string());
4808 if (stored_value->IsSmi()) return stored_value; 4815 return stored_value->IsSmi() ? stored_value : GetHeap()->undefined_value();
4816 }
4809 4817
4810 // Do not generate permanent identity hash code if not requested.
4811 if (flag == OMIT_CREATION) return GetHeap()->undefined_value();
4812 4818
4813 Smi* hash = GenerateIdentityHash(); 4819 Handle<Object> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) {
4814 MaybeObject* result = SetHiddenProperty(GetHeap()->identity_hash_string(), 4820 Handle<Object> hash(object->GetIdentityHash(), object->GetIsolate());
4815 hash); 4821 if (hash->IsSmi())
4816 if (result->IsFailure()) return result; 4822 return hash;
4817 if (result->ToObjectUnchecked()->IsUndefined()) { 4823
4824 Isolate* isolate = object->GetIsolate();
4825
4826 hash = handle(object->GenerateIdentityHash(), isolate);
4827 Handle<Object> result = JSObject::SetHiddenProperty(object,
4828 isolate->factory()->identity_hash_string(), hash);
4829
4830 if (result->IsUndefined()) {
4818 // Trying to get hash of detached proxy. 4831 // Trying to get hash of detached proxy.
4819 return Smi::FromInt(0); 4832 return handle(Smi::FromInt(0), isolate);
4820 } 4833 }
4834
4821 return hash; 4835 return hash;
4822 } 4836 }
4823 4837
4824 4838
4825 Handle<Object> JSProxy::GetIdentityHash(Handle<JSProxy> proxy, 4839 Object* JSProxy::GetIdentityHash() {
4826 CreationFlag flag) { 4840 return this->hash();
4827 CALL_HEAP_FUNCTION(proxy->GetIsolate(), proxy->GetIdentityHash(flag), Object);
4828 } 4841 }
4829 4842
4830 4843
4831 MaybeObject* JSProxy::GetIdentityHash(CreationFlag flag) { 4844 Handle<Object> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) {
4832 Object* hash = this->hash(); 4845 Isolate* isolate = proxy->GetIsolate();
4833 if (!hash->IsSmi() && flag == ALLOW_CREATION) { 4846
4834 hash = GenerateIdentityHash(); 4847 Handle<Object> hash(proxy->GetIdentityHash(), isolate);
4835 set_hash(hash); 4848 if (hash->IsSmi())
4836 } 4849 return hash;
4850
4851 hash = handle(proxy->GenerateIdentityHash(), isolate);
4852 proxy->set_hash(*hash);
4837 return hash; 4853 return hash;
4838 } 4854 }
4839 4855
4840 4856
4841 Object* JSObject::GetHiddenProperty(Name* key) { 4857 Object* JSObject::GetHiddenProperty(Name* key) {
4842 ASSERT(key->IsUniqueName()); 4858 ASSERT(key->IsUniqueName());
4843 if (IsJSGlobalProxy()) { 4859 if (IsJSGlobalProxy()) {
4844 // For a proxy, use the prototype as target object. 4860 // For a proxy, use the prototype as target object.
4845 Object* proxy_parent = GetPrototype(); 4861 Object* proxy_parent = GetPrototype();
4846 // If the proxy is detached, return undefined. 4862 // If the proxy is detached, return undefined.
4847 if (proxy_parent->IsNull()) return GetHeap()->the_hole_value(); 4863 if (proxy_parent->IsNull()) return GetHeap()->the_hole_value();
4848 ASSERT(proxy_parent->IsJSGlobalObject()); 4864 ASSERT(proxy_parent->IsJSGlobalObject());
4849 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); 4865 return JSObject::cast(proxy_parent)->GetHiddenProperty(key);
4850 } 4866 }
4851 ASSERT(!IsJSGlobalProxy()); 4867 ASSERT(!IsJSGlobalProxy());
4852 MaybeObject* hidden_lookup = 4868 Object* inline_value = GetHiddenPropertiesHashTable();
4853 GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE);
4854 Object* inline_value = hidden_lookup->ToObjectUnchecked();
4855 4869
4856 if (inline_value->IsSmi()) { 4870 if (inline_value->IsSmi()) {
4857 // Handle inline-stored identity hash. 4871 // Handle inline-stored identity hash.
4858 if (key == GetHeap()->identity_hash_string()) { 4872 if (key == GetHeap()->identity_hash_string()) {
4859 return inline_value; 4873 return inline_value;
4860 } else { 4874 } else {
4861 return GetHeap()->the_hole_value(); 4875 return GetHeap()->the_hole_value();
4862 } 4876 }
4863 } 4877 }
4864 4878
4865 if (inline_value->IsUndefined()) return GetHeap()->the_hole_value(); 4879 if (inline_value->IsUndefined()) return GetHeap()->the_hole_value();
4866 4880
4867 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); 4881 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value);
4868 Object* entry = hashtable->Lookup(key); 4882 Object* entry = hashtable->Lookup(key);
4869 return entry; 4883 return entry;
4870 } 4884 }
4871 4885
4872 4886
4873 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj, 4887 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object,
4874 Handle<Name> key, 4888 Handle<Name> key,
4875 Handle<Object> value) { 4889 Handle<Object> value) {
4876 CALL_HEAP_FUNCTION(obj->GetIsolate(), 4890 Isolate* isolate = object->GetIsolate();
4877 obj->SetHiddenProperty(*key, *value), 4891
4878 Object); 4892 ASSERT(key->IsUniqueName());
4893 if (object->IsJSGlobalProxy()) {
4894 // For a proxy, use the prototype as target object.
4895 Handle<Object> proxy_parent(object->GetPrototype(), isolate);
4896 // If the proxy is detached, return undefined.
4897 if (proxy_parent->IsNull()) return isolate->factory()->undefined_value();
4898 ASSERT(proxy_parent->IsJSGlobalObject());
4899 return JSObject::SetHiddenProperty(Handle<JSObject>::cast(proxy_parent),
4900 key,
4901 value);
4902 }
4903 ASSERT(!object->IsJSGlobalProxy());
4904
4905 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate);
4906
4907 // If there is no backing store yet, store the identity hash inline.
4908 if (value->IsSmi() &&
4909 *key == *isolate->factory()->identity_hash_string() &&
4910 (inline_value->IsUndefined() || inline_value->IsSmi())) {
4911 return JSObject::SetHiddenPropertiesHashTable(object, value);
4912 }
4913
4914 Handle<ObjectHashTable> hashtable =
4915 JSObject::GetOrCreateHiddenPropertiesHashtable(object);
4916
4917 // If it was found, check if the key is already in the dictionary.
4918 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key,
4919 value);
4920 if (*new_table != *hashtable) {
4921 // If adding the key expanded the dictionary (i.e., Add returned a new
4922 // dictionary), store it back to the object.
4923 JSObject::SetHiddenPropertiesHashTable(object, new_table);
4924 }
4925
4926 // Return this to mark success.
4927 return object;
4879 } 4928 }
4880 4929
4881 4930
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) { 4931 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) {
4924 Isolate* isolate = object->GetIsolate(); 4932 Isolate* isolate = object->GetIsolate();
4925 ASSERT(key->IsUniqueName()); 4933 ASSERT(key->IsUniqueName());
4926 4934
4927 if (object->IsJSGlobalProxy()) { 4935 if (object->IsJSGlobalProxy()) {
4928 Handle<Object> proto(object->GetPrototype(), isolate); 4936 Handle<Object> proto(object->GetPrototype(), isolate);
4929 if (proto->IsNull()) return; 4937 if (proto->IsNull()) return;
4930 ASSERT(proto->IsJSGlobalObject()); 4938 ASSERT(proto->IsJSGlobalObject());
4931 return DeleteHiddenProperty(Handle<JSObject>::cast(proto), key); 4939 return DeleteHiddenProperty(Handle<JSObject>::cast(proto), key);
4932 } 4940 }
4933 4941
4934 MaybeObject* hidden_lookup = 4942 Object* inline_value = object->GetHiddenPropertiesHashTable();
4935 object->GetHiddenPropertiesHashTable(ONLY_RETURN_INLINE_VALUE);
4936 Object* inline_value = hidden_lookup->ToObjectUnchecked();
4937 4943
4938 // We never delete (inline-stored) identity hashes. 4944 // We never delete (inline-stored) identity hashes.
4939 ASSERT(*key != isolate->heap()->identity_hash_string()); 4945 ASSERT(*key != *isolate->factory()->identity_hash_string());
4940 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; 4946 if (inline_value->IsUndefined() || inline_value->IsSmi()) return;
4941 4947
4942 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); 4948 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value));
4943 PutIntoObjectHashTable(hashtable, key, isolate->factory()->the_hole_value()); 4949 ObjectHashTable::Put(hashtable, key, isolate->factory()->the_hole_value());
4944 } 4950 }
4945 4951
4946 4952
4947 bool JSObject::HasHiddenProperties() { 4953 bool JSObject::HasHiddenProperties() {
4948 return GetPropertyAttributePostInterceptor(this, 4954 return GetPropertyAttributePostInterceptor(this,
4949 GetHeap()->hidden_string(), 4955 GetHeap()->hidden_string(),
4950 false) != ABSENT; 4956 false) != ABSENT;
4951 } 4957 }
4952 4958
4953 4959
4954 MaybeObject* JSObject::GetHiddenPropertiesHashTable( 4960 Object* JSObject::GetHiddenPropertiesHashTable() {
4955 InitializeHiddenProperties init_option) {
4956 ASSERT(!IsJSGlobalProxy()); 4961 ASSERT(!IsJSGlobalProxy());
4957 Object* inline_value; 4962 Object* inline_value;
Michael Starzinger 2013/11/04 17:58:58 nit: The local "inline_value" variable is (almost)
rafaelw 2013/11/05 09:56:54 Done.
4958 if (HasFastProperties()) { 4963 if (HasFastProperties()) {
4959 // If the object has fast properties, check whether the first slot 4964 // If the object has fast properties, check whether the first slot
4960 // in the descriptor array matches the hidden string. Since the 4965 // in the descriptor array matches the hidden string. Since the
4961 // hidden strings hash code is zero (and no other name has hash 4966 // hidden strings hash code is zero (and no other name has hash
4962 // code zero) it will always occupy the first entry if present. 4967 // code zero) it will always occupy the first entry if present.
4963 DescriptorArray* descriptors = this->map()->instance_descriptors(); 4968 DescriptorArray* descriptors = this->map()->instance_descriptors();
4964 if (descriptors->number_of_descriptors() > 0) { 4969 if (descriptors->number_of_descriptors() > 0) {
4965 int sorted_index = descriptors->GetSortedKeyIndex(0); 4970 int sorted_index = descriptors->GetSortedKeyIndex(0);
4966 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && 4971 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() &&
4967 sorted_index < map()->NumberOfOwnDescriptors()) { 4972 sorted_index < map()->NumberOfOwnDescriptors()) {
4968 ASSERT(descriptors->GetType(sorted_index) == FIELD); 4973 ASSERT(descriptors->GetType(sorted_index) == FIELD);
4969 ASSERT(descriptors->GetDetails(sorted_index).representation(). 4974 ASSERT(descriptors->GetDetails(sorted_index).representation().
4970 IsCompatibleForLoad(Representation::Tagged())); 4975 IsCompatibleForLoad(Representation::Tagged()));
4971 inline_value = this->RawFastPropertyAt( 4976 inline_value = this->RawFastPropertyAt(
4972 descriptors->GetFieldIndex(sorted_index)); 4977 descriptors->GetFieldIndex(sorted_index));
4978 return inline_value;
4973 } else { 4979 } else {
4974 inline_value = GetHeap()->undefined_value(); 4980 return GetHeap()->undefined_value();
4975 } 4981 }
4976 } else { 4982 } else {
4977 inline_value = GetHeap()->undefined_value(); 4983 return GetHeap()->undefined_value();
4978 } 4984 }
4979 } else { 4985 } else {
4980 PropertyAttributes attributes; 4986 PropertyAttributes attributes;
4981 // You can't install a getter on a property indexed by the hidden string, 4987 // 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 4988 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4983 // object. 4989 // object.
4984 inline_value = 4990 return GetLocalPropertyPostInterceptor(this,
4985 GetLocalPropertyPostInterceptor(this, 4991 GetHeap()->hidden_string(),
4986 GetHeap()->hidden_string(), 4992 &attributes)->ToObjectUnchecked();
4987 &attributes)->ToObjectUnchecked(); 4993 }
4994 }
4995
4996 Handle<ObjectHashTable> JSObject::GetOrCreateHiddenPropertiesHashtable(
4997 Handle<JSObject> object) {
4998 Isolate* isolate = object->GetIsolate();
4999
5000 static const int kInitialCapacity = 4;
5001 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate);
5002 if (inline_value->IsHashTable()) {
5003 return Handle<ObjectHashTable>::cast(inline_value);
4988 } 5004 }
4989 5005
4990 if (init_option == ONLY_RETURN_INLINE_VALUE || 5006 Handle<ObjectHashTable> hashtable = isolate->factory()->NewObjectHashTable(
4991 inline_value->IsHashTable()) { 5007 kInitialCapacity,
4992 return inline_value; 5008 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 5009
5003 if (inline_value->IsSmi()) { 5010 if (inline_value->IsSmi()) {
5004 // We were storing the identity hash inline and now allocated an actual 5011 // We were storing the identity hash inline and now allocated an actual
5005 // dictionary. Put the identity hash into the new dictionary. 5012 // dictionary. Put the identity hash into the new dictionary.
5006 MaybeObject* insert_result = 5013 hashtable = ObjectHashTable::Put(hashtable,
5007 hashtable->Put(GetHeap()->identity_hash_string(), inline_value); 5014 isolate->factory()->identity_hash_string(),
5008 ObjectHashTable* new_table; 5015 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 } 5016 }
5013 5017
5014 MaybeObject* store_result = SetLocalPropertyIgnoreAttributesTrampoline( 5018 JSObject::SetLocalPropertyIgnoreAttributes(
5015 GetHeap()->hidden_string(), 5019 object,
5020 isolate->factory()->hidden_string(),
5016 hashtable, 5021 hashtable,
5017 DONT_ENUM, 5022 DONT_ENUM,
5018 OPTIMAL_REPRESENTATION, 5023 OPTIMAL_REPRESENTATION,
5019 ALLOW_AS_CONSTANT, 5024 ALLOW_AS_CONSTANT,
5020 OMIT_EXTENSIBILITY_CHECK); 5025 OMIT_EXTENSIBILITY_CHECK);
5021 if (store_result->IsFailure()) return store_result; 5026
5022 return hashtable; 5027 return hashtable;
5023 } 5028 }
5024 5029
5025 5030
5026 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { 5031 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object,
5027 ASSERT(!IsJSGlobalProxy()); 5032 Handle<Object> value) {
5033 ASSERT(!object->IsJSGlobalProxy());
5034
5035 Isolate* isolate = object->GetIsolate();
5036
5028 // We can store the identity hash inline iff there is no backing store 5037 // We can store the identity hash inline iff there is no backing store
5029 // for hidden properties yet. 5038 // for hidden properties yet.
5030 ASSERT(HasHiddenProperties() != value->IsSmi()); 5039 ASSERT(object->HasHiddenProperties() != value->IsSmi());
5031 if (HasFastProperties()) { 5040 if (object->HasFastProperties()) {
5032 // If the object has fast properties, check whether the first slot 5041 // If the object has fast properties, check whether the first slot
5033 // in the descriptor array matches the hidden string. Since the 5042 // in the descriptor array matches the hidden string. Since the
5034 // hidden strings hash code is zero (and no other name has hash 5043 // hidden strings hash code is zero (and no other name has hash
5035 // code zero) it will always occupy the first entry if present. 5044 // code zero) it will always occupy the first entry if present.
5036 DescriptorArray* descriptors = this->map()->instance_descriptors(); 5045 DescriptorArray* descriptors = object->map()->instance_descriptors();
5037 if (descriptors->number_of_descriptors() > 0) { 5046 if (descriptors->number_of_descriptors() > 0) {
5038 int sorted_index = descriptors->GetSortedKeyIndex(0); 5047 int sorted_index = descriptors->GetSortedKeyIndex(0);
5039 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && 5048 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string()
5040 sorted_index < map()->NumberOfOwnDescriptors()) { 5049 && sorted_index < object->map()->NumberOfOwnDescriptors()) {
5041 ASSERT(descriptors->GetType(sorted_index) == FIELD); 5050 ASSERT(descriptors->GetType(sorted_index) == FIELD);
5042 FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), value); 5051 object->FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index),
5043 return this; 5052 *value);
5053 return object;
5044 } 5054 }
5045 } 5055 }
5046 } 5056 }
5047 MaybeObject* store_result = SetLocalPropertyIgnoreAttributesTrampoline( 5057
5048 GetHeap()->hidden_string(), 5058 JSObject::SetLocalPropertyIgnoreAttributes(
5059 object,
5060 isolate->factory()->hidden_string(),
5049 value, 5061 value,
5050 DONT_ENUM, 5062 DONT_ENUM,
5051 OPTIMAL_REPRESENTATION, 5063 OPTIMAL_REPRESENTATION,
5052 ALLOW_AS_CONSTANT, 5064 ALLOW_AS_CONSTANT,
5053 OMIT_EXTENSIBILITY_CHECK); 5065 OMIT_EXTENSIBILITY_CHECK);
5054 if (store_result->IsFailure()) return store_result; 5066 return object;
5055 return this;
5056 } 5067 }
5057 5068
5058 5069
5059 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, 5070 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object,
5060 Handle<Name> name, 5071 Handle<Name> name,
5061 DeleteMode mode) { 5072 DeleteMode mode) {
5062 // Check local property, ignore interceptor. 5073 // Check local property, ignore interceptor.
5063 Isolate* isolate = object->GetIsolate(); 5074 Isolate* isolate = object->GetIsolate();
5064 LookupResult result(isolate); 5075 LookupResult result(isolate);
5065 object->LocalLookupRealNamedProperty(*name, &result); 5076 object->LocalLookupRealNamedProperty(*name, &result);
(...skipping 10065 matching lines...) Expand 10 before | Expand all | Expand 10 after
15131 15142
15132 template<typename Shape, typename Key> 15143 template<typename Shape, typename Key>
15133 MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap, 15144 MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap,
15134 int at_least_space_for, 15145 int at_least_space_for,
15135 PretenureFlag pretenure) { 15146 PretenureFlag pretenure) {
15136 Object* obj; 15147 Object* obj;
15137 { MaybeObject* maybe_obj = 15148 { MaybeObject* maybe_obj =
15138 HashTable<Shape, Key>::Allocate( 15149 HashTable<Shape, Key>::Allocate(
15139 heap, 15150 heap,
15140 at_least_space_for, 15151 at_least_space_for,
15141 HashTable<Shape, Key>::USE_DEFAULT_MINIMUM_CAPACITY, 15152 USE_DEFAULT_MINIMUM_CAPACITY,
15142 pretenure); 15153 pretenure);
15143 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 15154 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
15144 } 15155 }
15145 // Initialize the next enumeration index. 15156 // Initialize the next enumeration index.
15146 Dictionary<Shape, Key>::cast(obj)-> 15157 Dictionary<Shape, Key>::cast(obj)->
15147 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); 15158 SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
15148 return obj; 15159 return obj;
15149 } 15160 }
15150 15161
15151 15162
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
15697 obj->set_properties(fields); 15708 obj->set_properties(fields);
15698 ASSERT(obj->IsJSObject()); 15709 ASSERT(obj->IsJSObject());
15699 15710
15700 // Check that it really works. 15711 // Check that it really works.
15701 ASSERT(obj->HasFastProperties()); 15712 ASSERT(obj->HasFastProperties());
15702 15713
15703 return obj; 15714 return obj;
15704 } 15715 }
15705 15716
15706 15717
15718 Handle<ObjectHashSet> ObjectHashSet::EnsureCapacity(
15719 Handle<ObjectHashSet> table,
15720 int n,
15721 Handle<Object> key,
15722 PretenureFlag pretenure) {
15723 Handle<HashTable<ObjectHashTableShape<1>, Object*> > table_base = table;
15724 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
15725 table_base->EnsureCapacity(n, *key, pretenure),
15726 ObjectHashSet);
15727 }
15728
15729
15730 Handle<ObjectHashSet> ObjectHashSet::Shrink(Handle<ObjectHashSet> table,
15731 Handle<Object> key) {
15732 Handle<HashTable<ObjectHashTableShape<1>, Object*> > table_base = table;
15733 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
15734 table_base->Shrink(*key),
15735 ObjectHashSet);
15736 }
15737
15738
15707 bool ObjectHashSet::Contains(Object* key) { 15739 bool ObjectHashSet::Contains(Object* key) {
15708 ASSERT(IsKey(key)); 15740 ASSERT(IsKey(key));
15709 15741
15710 // If the object does not have an identity hash, it was never used as a key. 15742 // If the object does not have an identity hash, it was never used as a key.
15711 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); 15743 Object* hash = key->GetHash();
15712 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return false; 15744 if (hash->IsUndefined()) return false;
15713 } 15745
15714 return (FindEntry(key) != kNotFound); 15746 return (FindEntry(key) != kNotFound);
15715 } 15747 }
15716 15748
15717 15749
15718 MaybeObject* ObjectHashSet::Add(Object* key) { 15750 Handle<ObjectHashSet> ObjectHashSet::Add(Handle<ObjectHashSet> table,
15719 ASSERT(IsKey(key)); 15751 Handle<Object> key) {
15752 ASSERT(table->IsKey(*key));
15720 15753
15721 // Make sure the key object has an identity hash code. 15754 // Make sure the key object has an identity hash code.
15722 int hash; 15755 Handle<Object> object_hash = Object::GetOrCreateHash(key,
15723 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); 15756 table->GetIsolate());
15724 if (maybe_hash->IsFailure()) return maybe_hash; 15757
15725 ASSERT(key->GetHash(OMIT_CREATION) == maybe_hash); 15758 int entry = table->FindEntry(*key);
15726 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
15727 }
15728 int entry = FindEntry(key);
15729 15759
15730 // Check whether key is already present. 15760 // Check whether key is already present.
15731 if (entry != kNotFound) return this; 15761 if (entry != kNotFound) return table;
15732 15762
15733 // Check whether the hash set should be extended and add entry. 15763 // Check whether the hash set should be extended and add entry.
15734 Object* obj; 15764 Handle<ObjectHashSet> new_table =
15735 { MaybeObject* maybe_obj = EnsureCapacity(1, key); 15765 ObjectHashSet::EnsureCapacity(table, 1, key);
15736 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 15766 entry = new_table->FindInsertionEntry(Smi::cast(*object_hash)->value());
15737 } 15767 new_table->set(ObjectHashSet::EntryToIndex(entry), *key);
15738 ObjectHashSet* table = ObjectHashSet::cast(obj); 15768 new_table->ElementAdded();
15739 entry = table->FindInsertionEntry(hash); 15769 return new_table;
15740 table->set(EntryToIndex(entry), key);
15741 table->ElementAdded();
15742 return table;
15743 } 15770 }
15744 15771
15745 15772
15746 MaybeObject* ObjectHashSet::Remove(Object* key) { 15773 Handle<ObjectHashSet> ObjectHashSet::Remove(Handle<ObjectHashSet> table,
15747 ASSERT(IsKey(key)); 15774 Handle<Object> key) {
15775 ASSERT(table->IsKey(*key));
15748 15776
15749 // If the object does not have an identity hash, it was never used as a key. 15777 // If the object does not have an identity hash, it was never used as a key.
15750 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); 15778 if (key->GetHash()->IsUndefined()) return table;
15751 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) return this; 15779
15752 } 15780 int entry = table->FindEntry(*key);
15753 int entry = FindEntry(key);
15754 15781
15755 // Check whether key is actually present. 15782 // Check whether key is actually present.
15756 if (entry == kNotFound) return this; 15783 if (entry == kNotFound) return table;
15757 15784
15758 // Remove entry and try to shrink this hash set. 15785 // Remove entry and try to shrink this hash set.
15759 set_the_hole(EntryToIndex(entry)); 15786 table->set_the_hole(ObjectHashSet::EntryToIndex(entry));
15760 ElementRemoved(); 15787 table->ElementRemoved();
15761 return Shrink(key); 15788
15789 return ObjectHashSet::Shrink(table, key);
15762 } 15790 }
15763 15791
15764 15792
15793 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity(
15794 Handle<ObjectHashTable> table,
15795 int n,
15796 Handle<Object> key,
15797 PretenureFlag pretenure) {
15798 Handle<HashTable<ObjectHashTableShape<2>, Object*> > table_base = table;
15799 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
15800 table_base->EnsureCapacity(n, *key, pretenure),
15801 ObjectHashTable);
15802 }
15803
15804
15805 Handle<ObjectHashTable> ObjectHashTable::Shrink(
15806 Handle<ObjectHashTable> table, Handle<Object> key) {
15807 Handle<HashTable<ObjectHashTableShape<2>, Object*> > table_base = table;
15808 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
15809 table_base->Shrink(*key),
15810 ObjectHashTable);
15811 }
15812
15813
15765 Object* ObjectHashTable::Lookup(Object* key) { 15814 Object* ObjectHashTable::Lookup(Object* key) {
15766 ASSERT(IsKey(key)); 15815 ASSERT(IsKey(key));
15767 15816
15768 // If the object does not have an identity hash, it was never used as a key. 15817 // If the object does not have an identity hash, it was never used as a key.
15769 { MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION); 15818 Object* hash = key->GetHash();
15770 if (maybe_hash->ToObjectUnchecked()->IsUndefined()) { 15819 if (hash->IsUndefined()) {
15771 return GetHeap()->the_hole_value(); 15820 return GetHeap()->the_hole_value();
15772 }
15773 } 15821 }
15774 int entry = FindEntry(key); 15822 int entry = FindEntry(key);
15775 if (entry == kNotFound) return GetHeap()->the_hole_value(); 15823 if (entry == kNotFound) return GetHeap()->the_hole_value();
15776 return get(EntryToIndex(entry) + 1); 15824 return get(EntryToIndex(entry) + 1);
15777 } 15825 }
15778 15826
15779 15827
15780 MaybeObject* ObjectHashTable::Put(Object* key, Object* value) { 15828 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table,
15781 ASSERT(IsKey(key)); 15829 Handle<Object> key,
15830 Handle<Object> value) {
15831 ASSERT(table->IsKey(*key));
15832
15833 Isolate* isolate = table->GetIsolate();
15782 15834
15783 // Make sure the key object has an identity hash code. 15835 // Make sure the key object has an identity hash code.
15784 int hash; 15836 Handle<Object> hash = Object::GetOrCreateHash(key, isolate);
15785 { MaybeObject* maybe_hash = key->GetHash(ALLOW_CREATION); 15837
15786 if (maybe_hash->IsFailure()) return maybe_hash; 15838 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 15839
15792 // Check whether to perform removal operation. 15840 // Check whether to perform removal operation.
15793 if (value->IsTheHole()) { 15841 if (value->IsTheHole()) {
15794 if (entry == kNotFound) return this; 15842 if (entry == kNotFound) return table;
15795 RemoveEntry(entry); 15843 table->RemoveEntry(entry);
15796 return Shrink(key); 15844 return ObjectHashTable::Shrink(table, key);
15797 } 15845 }
15798 15846
15799 // Key is already in table, just overwrite value. 15847 // Key is already in table, just overwrite value.
15800 if (entry != kNotFound) { 15848 if (entry != kNotFound) {
15801 set(EntryToIndex(entry) + 1, value); 15849 table->set(ObjectHashTable::EntryToIndex(entry) + 1, *value);
15802 return this; 15850 return table;
15803 } 15851 }
15804 15852
15805 // Check whether the hash table should be extended. 15853 // Check whether the hash table should be extended.
15806 Object* obj; 15854 table = ObjectHashTable::EnsureCapacity(table, 1, key);
15807 { MaybeObject* maybe_obj = EnsureCapacity(1, key); 15855 table->AddEntry(table->FindInsertionEntry(Handle<Smi>::cast(hash)->value()),
15808 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 15856 *key,
15809 } 15857 *value);
15810 ObjectHashTable* table = ObjectHashTable::cast(obj);
15811 table->AddEntry(table->FindInsertionEntry(hash), key, value);
15812 return table; 15858 return table;
15813 } 15859 }
15814 15860
15815 15861
15816 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { 15862 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) {
15817 set(EntryToIndex(entry), key); 15863 set(EntryToIndex(entry), key);
15818 set(EntryToIndex(entry) + 1, value); 15864 set(EntryToIndex(entry) + 1, value);
15819 ElementAdded(); 15865 ElementAdded();
15820 } 15866 }
15821 15867
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
16396 #define ERROR_MESSAGES_TEXTS(C, T) T, 16442 #define ERROR_MESSAGES_TEXTS(C, T) T,
16397 static const char* error_messages_[] = { 16443 static const char* error_messages_[] = {
16398 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16444 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16399 }; 16445 };
16400 #undef ERROR_MESSAGES_TEXTS 16446 #undef ERROR_MESSAGES_TEXTS
16401 return error_messages_[reason]; 16447 return error_messages_[reason];
16402 } 16448 }
16403 16449
16404 16450
16405 } } // namespace v8::internal 16451 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698