Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <iomanip> | 5 #include <iomanip> |
| 6 #include <sstream> | 6 #include <sstream> |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
| (...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 803 return context->symbol_function()->initial_map(); | 803 return context->symbol_function()->initial_map(); |
| 804 } | 804 } |
| 805 if (heap_object->IsBoolean()) { | 805 if (heap_object->IsBoolean()) { |
| 806 return context->boolean_function()->initial_map(); | 806 return context->boolean_function()->initial_map(); |
| 807 } | 807 } |
| 808 return isolate->heap()->null_value()->map(); | 808 return isolate->heap()->null_value()->map(); |
| 809 } | 809 } |
| 810 | 810 |
| 811 | 811 |
| 812 Object* Object::GetHash() { | 812 Object* Object::GetHash() { |
| 813 Object* hash = GetSimpleHash(); | |
| 814 if (hash->IsSmi()) return hash; | |
| 815 | |
| 816 DCHECK(IsJSReceiver()); | |
| 817 return JSReceiver::cast(this)->GetIdentityHash(); | |
| 818 } | |
| 819 | |
| 820 | |
| 821 Object* Object::GetSimpleHash() { | |
| 813 // The object is either a Smi, a HeapNumber, a name, an odd-ball, | 822 // The object is either a Smi, a HeapNumber, a name, an odd-ball, |
| 814 // a real JS object, or a Harmony proxy. | 823 // a real JS object, or a Harmony proxy. |
| 815 if (IsSmi()) { | 824 if (IsSmi()) { |
| 816 uint32_t hash = ComputeIntegerHash(Smi::cast(this)->value(), kZeroHashSeed); | 825 uint32_t hash = ComputeIntegerHash(Smi::cast(this)->value(), kZeroHashSeed); |
| 817 return Smi::FromInt(hash & Smi::kMaxValue); | 826 return Smi::FromInt(hash & Smi::kMaxValue); |
| 818 } | 827 } |
| 819 if (IsHeapNumber()) { | 828 if (IsHeapNumber()) { |
| 820 double num = HeapNumber::cast(this)->value(); | 829 double num = HeapNumber::cast(this)->value(); |
| 821 if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue); | 830 if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue); |
| 822 if (i::IsMinusZero(num)) num = 0; | 831 if (i::IsMinusZero(num)) num = 0; |
| 823 if (IsSmiDouble(num)) { | 832 if (IsSmiDouble(num)) { |
| 824 return Smi::FromInt(FastD2I(num))->GetHash(); | 833 return Smi::FromInt(FastD2I(num))->GetHash(); |
| 825 } | 834 } |
| 826 uint32_t hash = ComputeLongHash(double_to_uint64(num)); | 835 uint32_t hash = ComputeLongHash(double_to_uint64(num)); |
| 827 return Smi::FromInt(hash & Smi::kMaxValue); | 836 return Smi::FromInt(hash & Smi::kMaxValue); |
| 828 } | 837 } |
| 829 if (IsName()) { | 838 if (IsName()) { |
| 830 uint32_t hash = Name::cast(this)->Hash(); | 839 uint32_t hash = Name::cast(this)->Hash(); |
| 831 return Smi::FromInt(hash); | 840 return Smi::FromInt(hash); |
| 832 } | 841 } |
| 833 if (IsOddball()) { | 842 if (IsOddball()) { |
| 834 uint32_t hash = Oddball::cast(this)->to_string()->Hash(); | 843 uint32_t hash = Oddball::cast(this)->to_string()->Hash(); |
| 835 return Smi::FromInt(hash); | 844 return Smi::FromInt(hash); |
| 836 } | 845 } |
| 837 | |
| 838 DCHECK(IsJSReceiver()); | 846 DCHECK(IsJSReceiver()); |
| 839 return JSReceiver::cast(this)->GetIdentityHash(); | 847 JSReceiver* receiver = JSReceiver::cast(this); |
| 848 return receiver->GetHeap()->undefined_value(); | |
| 840 } | 849 } |
| 841 | 850 |
| 842 | 851 |
| 843 Handle<Smi> Object::GetOrCreateHash(Isolate* isolate, Handle<Object> object) { | 852 Handle<Smi> Object::GetOrCreateHash(Isolate* isolate, Handle<Object> object) { |
| 844 Handle<Object> hash(object->GetHash(), isolate); | 853 Handle<Object> hash(object->GetSimpleHash(), isolate); |
| 845 if (hash->IsSmi()) return Handle<Smi>::cast(hash); | 854 if (hash->IsSmi()) return Handle<Smi>::cast(hash); |
| 846 | 855 |
| 847 DCHECK(object->IsJSReceiver()); | 856 DCHECK(object->IsJSReceiver()); |
| 848 return JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver>::cast(object)); | 857 return JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver>::cast(object)); |
| 849 } | 858 } |
| 850 | 859 |
| 851 | 860 |
| 852 bool Object::SameValue(Object* other) { | 861 bool Object::SameValue(Object* other) { |
| 853 if (other == this) return true; | 862 if (other == this) return true; |
| 854 | 863 |
| (...skipping 4170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5025 // within a smi. | 5034 // within a smi. |
| 5026 hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue; | 5035 hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue; |
| 5027 attempts++; | 5036 attempts++; |
| 5028 } while (hash_value == 0 && attempts < 30); | 5037 } while (hash_value == 0 && attempts < 30); |
| 5029 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 | 5038 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 |
| 5030 | 5039 |
| 5031 return Smi::FromInt(hash_value); | 5040 return Smi::FromInt(hash_value); |
| 5032 } | 5041 } |
| 5033 | 5042 |
| 5034 | 5043 |
| 5035 void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) { | 5044 void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) { |
|
Toon Verwaest
2015/05/26 09:06:26
Perhaps you should rename this to AddIdentityHash
| |
| 5036 DCHECK(!object->IsJSGlobalProxy()); | 5045 DCHECK(!object->IsJSGlobalProxy()); |
| 5037 Isolate* isolate = object->GetIsolate(); | 5046 Isolate* isolate = object->GetIsolate(); |
| 5038 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash); | 5047 Handle<Name> hash_code_symbol(isolate->heap()->hash_code_symbol()); |
| 5048 JSObject::AddProperty(object, hash_code_symbol, hash, NONE); | |
| 5039 } | 5049 } |
| 5040 | 5050 |
| 5041 | 5051 |
| 5042 template<typename ProxyType> | 5052 template<typename ProxyType> |
| 5043 static Handle<Smi> GetOrCreateIdentityHashHelper(Handle<ProxyType> proxy) { | 5053 static Handle<Smi> GetOrCreateIdentityHashHelper(Handle<ProxyType> proxy) { |
| 5044 Isolate* isolate = proxy->GetIsolate(); | 5054 Isolate* isolate = proxy->GetIsolate(); |
| 5045 | 5055 |
| 5046 Handle<Object> maybe_hash(proxy->hash(), isolate); | 5056 Handle<Object> maybe_hash(proxy->hash(), isolate); |
| 5047 if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash); | 5057 if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash); |
| 5048 | 5058 |
| 5049 Handle<Smi> hash(GenerateIdentityHash(isolate), isolate); | 5059 Handle<Smi> hash(GenerateIdentityHash(isolate), isolate); |
| 5050 proxy->set_hash(*hash); | 5060 proxy->set_hash(*hash); |
| 5051 return hash; | 5061 return hash; |
| 5052 } | 5062 } |
| 5053 | 5063 |
| 5054 | 5064 |
| 5055 Object* JSObject::GetIdentityHash() { | 5065 Object* JSObject::GetIdentityHash() { |
| 5056 DisallowHeapAllocation no_gc; | 5066 DisallowHeapAllocation no_gc; |
| 5057 Isolate* isolate = GetIsolate(); | 5067 Isolate* isolate = GetIsolate(); |
| 5058 if (IsJSGlobalProxy()) { | 5068 if (IsJSGlobalProxy()) { |
| 5059 return JSGlobalProxy::cast(this)->hash(); | 5069 return JSGlobalProxy::cast(this)->hash(); |
| 5060 } | 5070 } |
| 5061 Object* stored_value = | 5071 Handle<Name> hash_code_symbol(isolate->heap()->hash_code_symbol()); |
| 5062 GetHiddenProperty(isolate->factory()->identity_hash_string()); | 5072 Handle<Object> stored_value = |
| 5063 return stored_value->IsSmi() | 5073 Object::GetPropertyOrElement(Handle<Object>(this, isolate), |
| 5064 ? stored_value | 5074 hash_code_symbol).ToHandleChecked(); |
| 5065 : isolate->heap()->undefined_value(); | 5075 return stored_value->IsSmi() ? *stored_value |
| 5076 : isolate->heap()->undefined_value(); | |
| 5066 } | 5077 } |
| 5067 | 5078 |
| 5068 | 5079 |
| 5069 Handle<Smi> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) { | 5080 Handle<Smi> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) { |
| 5070 if (object->IsJSGlobalProxy()) { | 5081 if (object->IsJSGlobalProxy()) { |
| 5071 return GetOrCreateIdentityHashHelper(Handle<JSGlobalProxy>::cast(object)); | 5082 return GetOrCreateIdentityHashHelper(Handle<JSGlobalProxy>::cast(object)); |
| 5072 } | 5083 } |
| 5073 | 5084 |
| 5074 Isolate* isolate = object->GetIsolate(); | 5085 Isolate* isolate = object->GetIsolate(); |
| 5075 | 5086 |
| 5076 Handle<Object> maybe_hash(object->GetIdentityHash(), isolate); | 5087 Handle<Object> maybe_hash(object->GetIdentityHash(), isolate); |
| 5077 if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash); | 5088 if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash); |
| 5078 | 5089 |
| 5079 Handle<Smi> hash(GenerateIdentityHash(isolate), isolate); | 5090 Handle<Smi> hash(GenerateIdentityHash(isolate), isolate); |
| 5080 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash); | 5091 Handle<Name> hash_code_symbol(isolate->heap()->hash_code_symbol()); |
| 5092 JSObject::AddProperty(object, hash_code_symbol, hash, NONE); | |
| 5081 return hash; | 5093 return hash; |
| 5082 } | 5094 } |
| 5083 | 5095 |
| 5084 | 5096 |
| 5085 Object* JSProxy::GetIdentityHash() { | 5097 Object* JSProxy::GetIdentityHash() { |
| 5086 return this->hash(); | 5098 return this->hash(); |
| 5087 } | 5099 } |
| 5088 | 5100 |
| 5089 | 5101 |
| 5090 Handle<Smi> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) { | 5102 Handle<Smi> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) { |
| 5091 return GetOrCreateIdentityHashHelper(proxy); | 5103 return GetOrCreateIdentityHashHelper(proxy); |
| 5092 } | 5104 } |
| 5093 | 5105 |
| 5094 | 5106 |
| 5095 Object* JSObject::GetHiddenProperty(Handle<Name> key) { | 5107 Object* JSObject::GetHiddenProperty(Handle<Name> key) { |
| 5096 DisallowHeapAllocation no_gc; | 5108 DisallowHeapAllocation no_gc; |
| 5097 DCHECK(key->IsUniqueName()); | 5109 DCHECK(key->IsUniqueName()); |
| 5098 if (IsJSGlobalProxy()) { | 5110 if (IsJSGlobalProxy()) { |
| 5099 // JSGlobalProxies store their hash internally. | |
| 5100 DCHECK(*key != GetHeap()->identity_hash_string()); | |
| 5101 // For a proxy, use the prototype as target object. | 5111 // For a proxy, use the prototype as target object. |
| 5102 PrototypeIterator iter(GetIsolate(), this); | 5112 PrototypeIterator iter(GetIsolate(), this); |
| 5103 // If the proxy is detached, return undefined. | 5113 // If the proxy is detached, return undefined. |
| 5104 if (iter.IsAtEnd()) return GetHeap()->the_hole_value(); | 5114 if (iter.IsAtEnd()) return GetHeap()->the_hole_value(); |
| 5105 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 5115 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); |
| 5106 return JSObject::cast(iter.GetCurrent())->GetHiddenProperty(key); | 5116 return JSObject::cast(iter.GetCurrent())->GetHiddenProperty(key); |
| 5107 } | 5117 } |
| 5108 DCHECK(!IsJSGlobalProxy()); | 5118 DCHECK(!IsJSGlobalProxy()); |
| 5109 Object* inline_value = GetHiddenPropertiesHashTable(); | 5119 Object* inline_value = GetHiddenPropertiesHashTable(); |
| 5110 | 5120 |
| 5111 if (inline_value->IsSmi()) { | |
| 5112 // Handle inline-stored identity hash. | |
| 5113 if (*key == GetHeap()->identity_hash_string()) { | |
| 5114 return inline_value; | |
| 5115 } else { | |
| 5116 return GetHeap()->the_hole_value(); | |
| 5117 } | |
| 5118 } | |
| 5119 | |
| 5120 if (inline_value->IsUndefined()) return GetHeap()->the_hole_value(); | 5121 if (inline_value->IsUndefined()) return GetHeap()->the_hole_value(); |
| 5121 | 5122 |
| 5122 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); | 5123 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); |
| 5123 Object* entry = hashtable->Lookup(key); | 5124 Object* entry = hashtable->Lookup(key); |
| 5124 return entry; | 5125 return entry; |
| 5125 } | 5126 } |
| 5126 | 5127 |
| 5127 | 5128 |
| 5128 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, | 5129 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, |
| 5129 Handle<Name> key, | 5130 Handle<Name> key, |
| 5130 Handle<Object> value) { | 5131 Handle<Object> value) { |
| 5131 Isolate* isolate = object->GetIsolate(); | 5132 Isolate* isolate = object->GetIsolate(); |
| 5132 | 5133 |
| 5133 DCHECK(key->IsUniqueName()); | 5134 DCHECK(key->IsUniqueName()); |
| 5134 if (object->IsJSGlobalProxy()) { | 5135 if (object->IsJSGlobalProxy()) { |
| 5135 // JSGlobalProxies store their hash internally. | |
| 5136 DCHECK(*key != *isolate->factory()->identity_hash_string()); | |
| 5137 // For a proxy, use the prototype as target object. | 5136 // For a proxy, use the prototype as target object. |
| 5138 PrototypeIterator iter(isolate, object); | 5137 PrototypeIterator iter(isolate, object); |
| 5139 // If the proxy is detached, return undefined. | 5138 // If the proxy is detached, return undefined. |
| 5140 if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); | 5139 if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); |
| 5141 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5140 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 5142 return SetHiddenProperty( | 5141 return SetHiddenProperty( |
| 5143 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key, | 5142 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key, |
| 5144 value); | 5143 value); |
| 5145 } | 5144 } |
| 5146 DCHECK(!object->IsJSGlobalProxy()); | 5145 DCHECK(!object->IsJSGlobalProxy()); |
| 5147 | 5146 |
| 5148 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 5147 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); |
| 5149 | 5148 |
| 5150 // If there is no backing store yet, store the identity hash inline. | |
| 5151 if (value->IsSmi() && | |
| 5152 *key == *isolate->factory()->identity_hash_string() && | |
| 5153 (inline_value->IsUndefined() || inline_value->IsSmi())) { | |
| 5154 return JSObject::SetHiddenPropertiesHashTable(object, value); | |
| 5155 } | |
| 5156 | |
| 5157 Handle<ObjectHashTable> hashtable = | 5149 Handle<ObjectHashTable> hashtable = |
| 5158 GetOrCreateHiddenPropertiesHashtable(object); | 5150 GetOrCreateHiddenPropertiesHashtable(object); |
| 5159 | 5151 |
| 5160 // If it was found, check if the key is already in the dictionary. | 5152 // If it was found, check if the key is already in the dictionary. |
| 5161 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key, | 5153 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key, |
| 5162 value); | 5154 value); |
| 5163 if (*new_table != *hashtable) { | 5155 if (*new_table != *hashtable) { |
| 5164 // If adding the key expanded the dictionary (i.e., Add returned a new | 5156 // If adding the key expanded the dictionary (i.e., Add returned a new |
| 5165 // dictionary), store it back to the object. | 5157 // dictionary), store it back to the object. |
| 5166 SetHiddenPropertiesHashTable(object, new_table); | 5158 SetHiddenPropertiesHashTable(object, new_table); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 5178 if (object->IsJSGlobalProxy()) { | 5170 if (object->IsJSGlobalProxy()) { |
| 5179 PrototypeIterator iter(isolate, object); | 5171 PrototypeIterator iter(isolate, object); |
| 5180 if (iter.IsAtEnd()) return; | 5172 if (iter.IsAtEnd()) return; |
| 5181 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5173 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 5182 return DeleteHiddenProperty( | 5174 return DeleteHiddenProperty( |
| 5183 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key); | 5175 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key); |
| 5184 } | 5176 } |
| 5185 | 5177 |
| 5186 Object* inline_value = object->GetHiddenPropertiesHashTable(); | 5178 Object* inline_value = object->GetHiddenPropertiesHashTable(); |
| 5187 | 5179 |
| 5188 // We never delete (inline-stored) identity hashes. | 5180 if (inline_value->IsUndefined()) return; |
| 5189 DCHECK(*key != *isolate->factory()->identity_hash_string()); | |
| 5190 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; | |
| 5191 | 5181 |
| 5192 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); | 5182 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); |
| 5193 bool was_present = false; | 5183 bool was_present = false; |
| 5194 ObjectHashTable::Remove(hashtable, key, &was_present); | 5184 ObjectHashTable::Remove(hashtable, key, &was_present); |
| 5195 } | 5185 } |
| 5196 | 5186 |
| 5197 | 5187 |
| 5198 bool JSObject::HasHiddenProperties(Handle<JSObject> object) { | 5188 bool JSObject::HasHiddenProperties(Handle<JSObject> object) { |
| 5199 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string(); | 5189 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string(); |
| 5200 LookupIterator it(object, hidden, LookupIterator::OWN_SKIP_INTERCEPTOR); | 5190 LookupIterator it(object, hidden, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5244 | 5234 |
| 5245 static const int kInitialCapacity = 4; | 5235 static const int kInitialCapacity = 4; |
| 5246 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 5236 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); |
| 5247 if (inline_value->IsHashTable()) { | 5237 if (inline_value->IsHashTable()) { |
| 5248 return Handle<ObjectHashTable>::cast(inline_value); | 5238 return Handle<ObjectHashTable>::cast(inline_value); |
| 5249 } | 5239 } |
| 5250 | 5240 |
| 5251 Handle<ObjectHashTable> hashtable = ObjectHashTable::New( | 5241 Handle<ObjectHashTable> hashtable = ObjectHashTable::New( |
| 5252 isolate, kInitialCapacity, USE_CUSTOM_MINIMUM_CAPACITY); | 5242 isolate, kInitialCapacity, USE_CUSTOM_MINIMUM_CAPACITY); |
| 5253 | 5243 |
| 5254 if (inline_value->IsSmi()) { | 5244 DCHECK(inline_value->IsUndefined()); |
| 5255 // We were storing the identity hash inline and now allocated an actual | |
| 5256 // dictionary. Put the identity hash into the new dictionary. | |
| 5257 hashtable = ObjectHashTable::Put(hashtable, | |
| 5258 isolate->factory()->identity_hash_string(), | |
| 5259 inline_value); | |
| 5260 } | |
| 5261 | |
| 5262 SetHiddenPropertiesHashTable(object, hashtable); | 5245 SetHiddenPropertiesHashTable(object, hashtable); |
| 5263 return hashtable; | 5246 return hashtable; |
| 5264 } | 5247 } |
| 5265 | 5248 |
| 5266 | 5249 |
| 5267 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object, | 5250 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object, |
| 5268 Handle<Object> value) { | 5251 Handle<Object> value) { |
| 5269 DCHECK(!object->IsJSGlobalProxy()); | 5252 DCHECK(!object->IsJSGlobalProxy()); |
| 5270 Isolate* isolate = object->GetIsolate(); | 5253 Isolate* isolate = object->GetIsolate(); |
| 5271 Handle<Name> name = isolate->factory()->hidden_string(); | 5254 Handle<Name> name = isolate->factory()->hidden_string(); |
| (...skipping 11042 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16314 e = PropertyCell::cast(e)->value(); | 16297 e = PropertyCell::cast(e)->value(); |
| 16315 } | 16298 } |
| 16316 if (e == value) return k; | 16299 if (e == value) return k; |
| 16317 } | 16300 } |
| 16318 } | 16301 } |
| 16319 Heap* heap = Dictionary::GetHeap(); | 16302 Heap* heap = Dictionary::GetHeap(); |
| 16320 return heap->undefined_value(); | 16303 return heap->undefined_value(); |
| 16321 } | 16304 } |
| 16322 | 16305 |
| 16323 | 16306 |
| 16307 Object* ObjectHashTable::Lookup(Isolate* isolate, Handle<Object> key, | |
| 16308 int32_t hash) { | |
| 16309 DisallowHeapAllocation no_gc; | |
| 16310 DCHECK(IsKey(*key)); | |
| 16311 | |
| 16312 int entry = FindEntry(isolate, key, hash); | |
| 16313 if (entry == kNotFound) return isolate->heap()->the_hole_value(); | |
| 16314 return get(EntryToIndex(entry) + 1); | |
| 16315 } | |
| 16316 | |
| 16317 | |
| 16324 Object* ObjectHashTable::Lookup(Handle<Object> key) { | 16318 Object* ObjectHashTable::Lookup(Handle<Object> key) { |
| 16325 DisallowHeapAllocation no_gc; | 16319 DisallowHeapAllocation no_gc; |
| 16326 DCHECK(IsKey(*key)); | 16320 DCHECK(IsKey(*key)); |
| 16327 | 16321 |
| 16322 Isolate* isolate = GetIsolate(); | |
| 16323 | |
| 16328 // If the object does not have an identity hash, it was never used as a key. | 16324 // If the object does not have an identity hash, it was never used as a key. |
| 16329 Object* hash = key->GetHash(); | 16325 Object* hash = key->GetHash(); |
| 16330 if (hash->IsUndefined()) { | 16326 if (hash->IsUndefined()) { |
| 16331 return GetHeap()->the_hole_value(); | 16327 return isolate->heap()->the_hole_value(); |
| 16332 } | 16328 } |
| 16333 int entry = FindEntry(key); | 16329 return Lookup(isolate, key, Smi::cast(hash)->value()); |
| 16334 if (entry == kNotFound) return GetHeap()->the_hole_value(); | |
| 16335 return get(EntryToIndex(entry) + 1); | |
| 16336 } | 16330 } |
| 16337 | 16331 |
| 16338 | 16332 |
| 16333 Object* ObjectHashTable::Lookup(Handle<Object> key, int32_t hash) { | |
| 16334 return Lookup(GetIsolate(), key, hash); | |
| 16335 } | |
| 16336 | |
| 16337 | |
| 16339 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, | 16338 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, |
| 16340 Handle<Object> key, | 16339 Handle<Object> key, |
| 16341 Handle<Object> value) { | 16340 Handle<Object> value) { |
| 16342 DCHECK(table->IsKey(*key)); | 16341 DCHECK(table->IsKey(*key)); |
| 16343 DCHECK(!value->IsTheHole()); | 16342 DCHECK(!value->IsTheHole()); |
| 16344 | 16343 |
| 16345 Isolate* isolate = table->GetIsolate(); | 16344 Isolate* isolate = table->GetIsolate(); |
| 16345 // Make sure the key object has an identity hash code. | |
| 16346 int32_t hash = Object::GetOrCreateHash(isolate, key)->value(); | |
| 16347 | |
| 16348 return Put(table, key, value, hash); | |
| 16349 } | |
| 16350 | |
| 16351 | |
| 16352 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, | |
| 16353 Handle<Object> key, | |
| 16354 Handle<Object> value, | |
| 16355 int32_t hash) { | |
| 16356 DCHECK(table->IsKey(*key)); | |
| 16357 DCHECK(!value->IsTheHole()); | |
| 16358 | |
| 16359 Isolate* isolate = table->GetIsolate(); | |
| 16346 | 16360 |
| 16347 // Make sure the key object has an identity hash code. | 16361 int entry = table->FindEntry(isolate, key, hash); |
| 16348 Handle<Smi> hash = Object::GetOrCreateHash(isolate, key); | |
| 16349 | |
| 16350 int entry = table->FindEntry(key); | |
| 16351 | 16362 |
| 16352 // Key is already in table, just overwrite value. | 16363 // Key is already in table, just overwrite value. |
| 16353 if (entry != kNotFound) { | 16364 if (entry != kNotFound) { |
| 16354 table->set(EntryToIndex(entry) + 1, *value); | 16365 table->set(EntryToIndex(entry) + 1, *value); |
| 16355 return table; | 16366 return table; |
| 16356 } | 16367 } |
| 16357 | 16368 |
| 16358 // Check whether the hash table should be extended. | 16369 // Check whether the hash table should be extended. |
| 16359 table = EnsureCapacity(table, 1, key); | 16370 table = EnsureCapacity(table, 1, key); |
| 16360 table->AddEntry(table->FindInsertionEntry(hash->value()), | 16371 table->AddEntry(table->FindInsertionEntry(hash), *key, *value); |
| 16361 *key, | |
| 16362 *value); | |
| 16363 return table; | 16372 return table; |
| 16364 } | 16373 } |
| 16365 | 16374 |
| 16366 | 16375 |
| 16367 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, | 16376 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, |
| 16368 Handle<Object> key, | 16377 Handle<Object> key, |
| 16369 bool* was_present) { | 16378 bool* was_present) { |
| 16370 DCHECK(table->IsKey(*key)); | 16379 DCHECK(table->IsKey(*key)); |
| 16371 | 16380 |
| 16372 Object* hash = key->GetHash(); | 16381 Object* hash = key->GetHash(); |
| 16373 if (hash->IsUndefined()) { | 16382 if (hash->IsUndefined()) { |
| 16374 *was_present = false; | 16383 *was_present = false; |
| 16375 return table; | 16384 return table; |
| 16376 } | 16385 } |
| 16377 | 16386 |
| 16378 int entry = table->FindEntry(key); | 16387 return Remove(table, key, was_present, Smi::cast(hash)->value()); |
| 16388 } | |
| 16389 | |
| 16390 | |
| 16391 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, | |
| 16392 Handle<Object> key, | |
| 16393 bool* was_present, | |
| 16394 int32_t hash) { | |
| 16395 DCHECK(table->IsKey(*key)); | |
| 16396 | |
| 16397 int entry = table->FindEntry(table->GetIsolate(), key, hash); | |
| 16379 if (entry == kNotFound) { | 16398 if (entry == kNotFound) { |
| 16380 *was_present = false; | 16399 *was_present = false; |
| 16381 return table; | 16400 return table; |
| 16382 } | 16401 } |
| 16383 | 16402 |
| 16384 *was_present = true; | 16403 *was_present = true; |
| 16385 table->RemoveEntry(entry); | 16404 table->RemoveEntry(entry); |
| 16386 return Shrink(table, key); | 16405 return Shrink(table, key); |
| 16387 } | 16406 } |
| 16388 | 16407 |
| (...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 17325 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, | 17344 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, |
| 17326 Handle<Object> new_value) { | 17345 Handle<Object> new_value) { |
| 17327 if (cell->value() != *new_value) { | 17346 if (cell->value() != *new_value) { |
| 17328 cell->set_value(*new_value); | 17347 cell->set_value(*new_value); |
| 17329 Isolate* isolate = cell->GetIsolate(); | 17348 Isolate* isolate = cell->GetIsolate(); |
| 17330 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17349 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17331 isolate, DependentCode::kPropertyCellChangedGroup); | 17350 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17332 } | 17351 } |
| 17333 } | 17352 } |
| 17334 } } // namespace v8::internal | 17353 } } // namespace v8::internal |
| OLD | NEW |