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 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 809 return context->symbol_function()->initial_map(); | 809 return context->symbol_function()->initial_map(); |
| 810 } | 810 } |
| 811 if (heap_object->IsBoolean()) { | 811 if (heap_object->IsBoolean()) { |
| 812 return context->boolean_function()->initial_map(); | 812 return context->boolean_function()->initial_map(); |
| 813 } | 813 } |
| 814 return isolate->heap()->null_value()->map(); | 814 return isolate->heap()->null_value()->map(); |
| 815 } | 815 } |
| 816 | 816 |
| 817 | 817 |
| 818 Object* Object::GetHash() { | 818 Object* Object::GetHash() { |
| 819 Object* hash = GetSimpleHash(); | |
| 820 if (hash->IsSmi()) return hash; | |
| 821 | |
| 822 DCHECK(IsJSReceiver()); | |
| 823 return JSReceiver::cast(this)->GetIdentityHash(); | |
| 824 } | |
| 825 | |
| 826 | |
| 827 Object* Object::GetSimpleHash() { | |
| 819 // The object is either a Smi, a HeapNumber, a name, an odd-ball, | 828 // The object is either a Smi, a HeapNumber, a name, an odd-ball, |
| 820 // a real JS object, or a Harmony proxy. | 829 // a real JS object, or a Harmony proxy. |
| 821 if (IsSmi()) { | 830 if (IsSmi()) { |
| 822 uint32_t hash = ComputeIntegerHash(Smi::cast(this)->value(), kZeroHashSeed); | 831 uint32_t hash = ComputeIntegerHash(Smi::cast(this)->value(), kZeroHashSeed); |
| 823 return Smi::FromInt(hash & Smi::kMaxValue); | 832 return Smi::FromInt(hash & Smi::kMaxValue); |
| 824 } | 833 } |
| 825 if (IsHeapNumber()) { | 834 if (IsHeapNumber()) { |
| 826 double num = HeapNumber::cast(this)->value(); | 835 double num = HeapNumber::cast(this)->value(); |
| 827 if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue); | 836 if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue); |
| 828 if (i::IsMinusZero(num)) num = 0; | 837 if (i::IsMinusZero(num)) num = 0; |
| 829 if (IsSmiDouble(num)) { | 838 if (IsSmiDouble(num)) { |
| 830 return Smi::FromInt(FastD2I(num))->GetHash(); | 839 return Smi::FromInt(FastD2I(num))->GetHash(); |
| 831 } | 840 } |
| 832 uint32_t hash = ComputeLongHash(double_to_uint64(num)); | 841 uint32_t hash = ComputeLongHash(double_to_uint64(num)); |
| 833 return Smi::FromInt(hash & Smi::kMaxValue); | 842 return Smi::FromInt(hash & Smi::kMaxValue); |
| 834 } | 843 } |
| 835 if (IsName()) { | 844 if (IsName()) { |
| 836 uint32_t hash = Name::cast(this)->Hash(); | 845 uint32_t hash = Name::cast(this)->Hash(); |
| 837 return Smi::FromInt(hash); | 846 return Smi::FromInt(hash); |
| 838 } | 847 } |
| 839 if (IsOddball()) { | 848 if (IsOddball()) { |
| 840 uint32_t hash = Oddball::cast(this)->to_string()->Hash(); | 849 uint32_t hash = Oddball::cast(this)->to_string()->Hash(); |
| 841 return Smi::FromInt(hash); | 850 return Smi::FromInt(hash); |
| 842 } | 851 } |
| 843 | |
| 844 DCHECK(IsJSReceiver()); | 852 DCHECK(IsJSReceiver()); |
| 845 return JSReceiver::cast(this)->GetIdentityHash(); | 853 JSReceiver* receiver = JSReceiver::cast(this); |
| 854 return receiver->GetHeap()->undefined_value(); | |
| 846 } | 855 } |
| 847 | 856 |
| 848 | 857 |
| 849 Handle<Smi> Object::GetOrCreateHash(Isolate* isolate, Handle<Object> object) { | 858 Handle<Smi> Object::GetOrCreateHash(Isolate* isolate, Handle<Object> object) { |
| 850 Handle<Object> hash(object->GetHash(), isolate); | 859 Handle<Object> hash(object->GetSimpleHash(), isolate); |
| 851 if (hash->IsSmi()) return Handle<Smi>::cast(hash); | 860 if (hash->IsSmi()) return Handle<Smi>::cast(hash); |
| 852 | 861 |
| 853 DCHECK(object->IsJSReceiver()); | 862 DCHECK(object->IsJSReceiver()); |
| 854 return JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver>::cast(object)); | 863 return JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver>::cast(object)); |
| 855 } | 864 } |
| 856 | 865 |
| 857 | 866 |
| 858 bool Object::SameValue(Object* other) { | 867 bool Object::SameValue(Object* other) { |
| 859 if (other == this) return true; | 868 if (other == this) return true; |
| 860 | 869 |
| (...skipping 4152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5013 } while (hash_value == 0 && attempts < 30); | 5022 } while (hash_value == 0 && attempts < 30); |
| 5014 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 | 5023 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 |
| 5015 | 5024 |
| 5016 return Smi::FromInt(hash_value); | 5025 return Smi::FromInt(hash_value); |
| 5017 } | 5026 } |
| 5018 | 5027 |
| 5019 | 5028 |
| 5020 void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) { | 5029 void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) { |
| 5021 DCHECK(!object->IsJSGlobalProxy()); | 5030 DCHECK(!object->IsJSGlobalProxy()); |
| 5022 Isolate* isolate = object->GetIsolate(); | 5031 Isolate* isolate = object->GetIsolate(); |
| 5023 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash); | 5032 Handle<Name> hash_code_symbol(isolate->heap()->hash_code_symbol()); |
| 5033 JSObject::AddProperty(object, hash_code_symbol, hash, NONE); | |
| 5024 } | 5034 } |
| 5025 | 5035 |
| 5026 | 5036 |
| 5027 template<typename ProxyType> | 5037 template<typename ProxyType> |
| 5028 static Handle<Smi> GetOrCreateIdentityHashHelper(Handle<ProxyType> proxy) { | 5038 static Handle<Smi> GetOrCreateIdentityHashHelper(Handle<ProxyType> proxy) { |
| 5029 Isolate* isolate = proxy->GetIsolate(); | 5039 Isolate* isolate = proxy->GetIsolate(); |
| 5030 | 5040 |
| 5031 Handle<Object> maybe_hash(proxy->hash(), isolate); | 5041 Handle<Object> maybe_hash(proxy->hash(), isolate); |
| 5032 if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash); | 5042 if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash); |
| 5033 | 5043 |
| 5034 Handle<Smi> hash(GenerateIdentityHash(isolate), isolate); | 5044 Handle<Smi> hash(GenerateIdentityHash(isolate), isolate); |
| 5035 proxy->set_hash(*hash); | 5045 proxy->set_hash(*hash); |
| 5036 return hash; | 5046 return hash; |
| 5037 } | 5047 } |
| 5038 | 5048 |
| 5039 | 5049 |
| 5040 Object* JSObject::GetIdentityHash() { | 5050 Object* JSObject::GetIdentityHash() { |
| 5041 DisallowHeapAllocation no_gc; | 5051 DisallowHeapAllocation no_gc; |
| 5042 Isolate* isolate = GetIsolate(); | 5052 Isolate* isolate = GetIsolate(); |
| 5043 if (IsJSGlobalProxy()) { | 5053 if (IsJSGlobalProxy()) { |
| 5044 return JSGlobalProxy::cast(this)->hash(); | 5054 return JSGlobalProxy::cast(this)->hash(); |
| 5045 } | 5055 } |
| 5046 Object* stored_value = | 5056 Handle<Name> hash_code_symbol(isolate->heap()->hash_code_symbol()); |
| 5047 GetHiddenProperty(isolate->factory()->identity_hash_string()); | 5057 Handle<Object> stored_value = |
| 5048 return stored_value->IsSmi() | 5058 Object::GetPropertyOrElement(Handle<Object>(this, isolate), |
| 5049 ? stored_value | 5059 hash_code_symbol).ToHandleChecked(); |
| 5050 : isolate->heap()->undefined_value(); | 5060 return stored_value->IsSmi() ? *stored_value |
| 5061 : isolate->heap()->undefined_value(); | |
| 5051 } | 5062 } |
| 5052 | 5063 |
| 5053 | 5064 |
| 5054 Handle<Smi> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) { | 5065 Handle<Smi> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) { |
| 5055 if (object->IsJSGlobalProxy()) { | 5066 if (object->IsJSGlobalProxy()) { |
| 5056 return GetOrCreateIdentityHashHelper(Handle<JSGlobalProxy>::cast(object)); | 5067 return GetOrCreateIdentityHashHelper(Handle<JSGlobalProxy>::cast(object)); |
| 5057 } | 5068 } |
| 5058 | 5069 |
| 5059 Isolate* isolate = object->GetIsolate(); | 5070 Isolate* isolate = object->GetIsolate(); |
| 5060 | 5071 |
| 5061 Handle<Object> maybe_hash(object->GetIdentityHash(), isolate); | 5072 Handle<Object> maybe_hash(object->GetIdentityHash(), isolate); |
| 5062 if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash); | 5073 if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash); |
| 5063 | 5074 |
| 5064 Handle<Smi> hash(GenerateIdentityHash(isolate), isolate); | 5075 Handle<Smi> hash(GenerateIdentityHash(isolate), isolate); |
| 5065 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash); | 5076 Handle<Name> hash_code_symbol(isolate->heap()->hash_code_symbol()); |
| 5077 JSObject::AddProperty(object, hash_code_symbol, hash, NONE); | |
| 5066 return hash; | 5078 return hash; |
| 5067 } | 5079 } |
| 5068 | 5080 |
| 5069 | 5081 |
| 5070 Object* JSProxy::GetIdentityHash() { | 5082 Object* JSProxy::GetIdentityHash() { |
| 5071 return this->hash(); | 5083 return this->hash(); |
| 5072 } | 5084 } |
| 5073 | 5085 |
| 5074 | 5086 |
| 5075 Handle<Smi> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) { | 5087 Handle<Smi> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) { |
| 5076 return GetOrCreateIdentityHashHelper(proxy); | 5088 return GetOrCreateIdentityHashHelper(proxy); |
| 5077 } | 5089 } |
| 5078 | 5090 |
| 5079 | 5091 |
| 5080 Object* JSObject::GetHiddenProperty(Handle<Name> key) { | 5092 Object* JSObject::GetHiddenProperty(Handle<Name> key) { |
| 5081 DisallowHeapAllocation no_gc; | 5093 DisallowHeapAllocation no_gc; |
| 5082 DCHECK(key->IsUniqueName()); | 5094 DCHECK(key->IsUniqueName()); |
| 5083 if (IsJSGlobalProxy()) { | 5095 if (IsJSGlobalProxy()) { |
| 5084 // JSGlobalProxies store their hash internally. | |
| 5085 DCHECK(*key != GetHeap()->identity_hash_string()); | |
| 5086 // For a proxy, use the prototype as target object. | 5096 // For a proxy, use the prototype as target object. |
| 5087 PrototypeIterator iter(GetIsolate(), this); | 5097 PrototypeIterator iter(GetIsolate(), this); |
| 5088 // If the proxy is detached, return undefined. | 5098 // If the proxy is detached, return undefined. |
| 5089 if (iter.IsAtEnd()) return GetHeap()->the_hole_value(); | 5099 if (iter.IsAtEnd()) return GetHeap()->the_hole_value(); |
| 5090 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 5100 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); |
| 5091 return JSObject::cast(iter.GetCurrent())->GetHiddenProperty(key); | 5101 return JSObject::cast(iter.GetCurrent())->GetHiddenProperty(key); |
| 5092 } | 5102 } |
| 5093 DCHECK(!IsJSGlobalProxy()); | 5103 DCHECK(!IsJSGlobalProxy()); |
| 5094 Object* inline_value = GetHiddenPropertiesHashTable(); | 5104 Object* inline_value = GetHiddenPropertiesHashTable(); |
| 5095 | 5105 |
| 5096 if (inline_value->IsSmi()) { | 5106 DCHECK(!inline_value->IsSmi()); |
|
adamk
2015/05/21 19:11:32
I don't think this DCHECK will make much sense in
Erik Corry
2015/05/22 06:20:25
The cast is sufficient, removed.
| |
| 5097 // Handle inline-stored identity hash. | |
| 5098 if (*key == GetHeap()->identity_hash_string()) { | |
| 5099 return inline_value; | |
| 5100 } else { | |
| 5101 return GetHeap()->the_hole_value(); | |
| 5102 } | |
| 5103 } | |
| 5104 | |
| 5105 if (inline_value->IsUndefined()) return GetHeap()->the_hole_value(); | 5107 if (inline_value->IsUndefined()) return GetHeap()->the_hole_value(); |
| 5106 | 5108 |
| 5107 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); | 5109 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); |
| 5108 Object* entry = hashtable->Lookup(key); | 5110 Object* entry = hashtable->Lookup(key); |
| 5109 return entry; | 5111 return entry; |
| 5110 } | 5112 } |
| 5111 | 5113 |
| 5112 | 5114 |
| 5113 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, | 5115 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, |
| 5114 Handle<Name> key, | 5116 Handle<Name> key, |
| 5115 Handle<Object> value) { | 5117 Handle<Object> value) { |
| 5116 Isolate* isolate = object->GetIsolate(); | 5118 Isolate* isolate = object->GetIsolate(); |
| 5117 | 5119 |
| 5118 DCHECK(key->IsUniqueName()); | 5120 DCHECK(key->IsUniqueName()); |
| 5119 if (object->IsJSGlobalProxy()) { | 5121 if (object->IsJSGlobalProxy()) { |
| 5120 // JSGlobalProxies store their hash internally. | |
| 5121 DCHECK(*key != *isolate->factory()->identity_hash_string()); | |
| 5122 // For a proxy, use the prototype as target object. | 5122 // For a proxy, use the prototype as target object. |
| 5123 PrototypeIterator iter(isolate, object); | 5123 PrototypeIterator iter(isolate, object); |
| 5124 // If the proxy is detached, return undefined. | 5124 // If the proxy is detached, return undefined. |
| 5125 if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); | 5125 if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); |
| 5126 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5126 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 5127 return SetHiddenProperty( | 5127 return SetHiddenProperty( |
| 5128 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key, | 5128 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key, |
| 5129 value); | 5129 value); |
| 5130 } | 5130 } |
| 5131 DCHECK(!object->IsJSGlobalProxy()); | 5131 DCHECK(!object->IsJSGlobalProxy()); |
| 5132 | 5132 |
| 5133 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 5133 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); |
| 5134 | 5134 |
| 5135 // If there is no backing store yet, store the identity hash inline. | |
| 5136 if (value->IsSmi() && | |
| 5137 *key == *isolate->factory()->identity_hash_string() && | |
| 5138 (inline_value->IsUndefined() || inline_value->IsSmi())) { | |
| 5139 return JSObject::SetHiddenPropertiesHashTable(object, value); | |
| 5140 } | |
| 5141 | |
| 5142 Handle<ObjectHashTable> hashtable = | 5135 Handle<ObjectHashTable> hashtable = |
| 5143 GetOrCreateHiddenPropertiesHashtable(object); | 5136 GetOrCreateHiddenPropertiesHashtable(object); |
| 5144 | 5137 |
| 5145 // If it was found, check if the key is already in the dictionary. | 5138 // If it was found, check if the key is already in the dictionary. |
| 5146 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key, | 5139 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key, |
| 5147 value); | 5140 value); |
| 5148 if (*new_table != *hashtable) { | 5141 if (*new_table != *hashtable) { |
| 5149 // If adding the key expanded the dictionary (i.e., Add returned a new | 5142 // If adding the key expanded the dictionary (i.e., Add returned a new |
| 5150 // dictionary), store it back to the object. | 5143 // dictionary), store it back to the object. |
| 5151 SetHiddenPropertiesHashTable(object, new_table); | 5144 SetHiddenPropertiesHashTable(object, new_table); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 5163 if (object->IsJSGlobalProxy()) { | 5156 if (object->IsJSGlobalProxy()) { |
| 5164 PrototypeIterator iter(isolate, object); | 5157 PrototypeIterator iter(isolate, object); |
| 5165 if (iter.IsAtEnd()) return; | 5158 if (iter.IsAtEnd()) return; |
| 5166 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5159 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 5167 return DeleteHiddenProperty( | 5160 return DeleteHiddenProperty( |
| 5168 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key); | 5161 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key); |
| 5169 } | 5162 } |
| 5170 | 5163 |
| 5171 Object* inline_value = object->GetHiddenPropertiesHashTable(); | 5164 Object* inline_value = object->GetHiddenPropertiesHashTable(); |
| 5172 | 5165 |
| 5173 // We never delete (inline-stored) identity hashes. | 5166 DCHECK(!inline_value->IsSmi()); |
|
adamk
2015/05/21 19:11:32
Same thing here, this DCHECK will be weird in the
Erik Corry
2015/05/22 06:20:25
Removed.
| |
| 5174 DCHECK(*key != *isolate->factory()->identity_hash_string()); | 5167 if (inline_value->IsUndefined()) return; |
| 5175 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; | |
| 5176 | 5168 |
| 5177 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); | 5169 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); |
| 5178 bool was_present = false; | 5170 bool was_present = false; |
| 5179 ObjectHashTable::Remove(hashtable, key, &was_present); | 5171 ObjectHashTable::Remove(hashtable, key, &was_present); |
| 5180 } | 5172 } |
| 5181 | 5173 |
| 5182 | 5174 |
| 5183 bool JSObject::HasHiddenProperties(Handle<JSObject> object) { | 5175 bool JSObject::HasHiddenProperties(Handle<JSObject> object) { |
| 5184 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string(); | 5176 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string(); |
| 5185 LookupIterator it(object, hidden, LookupIterator::OWN_SKIP_INTERCEPTOR); | 5177 LookupIterator it(object, hidden, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5229 | 5221 |
| 5230 static const int kInitialCapacity = 4; | 5222 static const int kInitialCapacity = 4; |
| 5231 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 5223 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); |
| 5232 if (inline_value->IsHashTable()) { | 5224 if (inline_value->IsHashTable()) { |
| 5233 return Handle<ObjectHashTable>::cast(inline_value); | 5225 return Handle<ObjectHashTable>::cast(inline_value); |
| 5234 } | 5226 } |
| 5235 | 5227 |
| 5236 Handle<ObjectHashTable> hashtable = ObjectHashTable::New( | 5228 Handle<ObjectHashTable> hashtable = ObjectHashTable::New( |
| 5237 isolate, kInitialCapacity, USE_CUSTOM_MINIMUM_CAPACITY); | 5229 isolate, kInitialCapacity, USE_CUSTOM_MINIMUM_CAPACITY); |
| 5238 | 5230 |
| 5239 if (inline_value->IsSmi()) { | 5231 DCHECK(inline_value->IsUndefined()); |
| 5240 // We were storing the identity hash inline and now allocated an actual | |
| 5241 // dictionary. Put the identity hash into the new dictionary. | |
| 5242 hashtable = ObjectHashTable::Put(hashtable, | |
| 5243 isolate->factory()->identity_hash_string(), | |
| 5244 inline_value); | |
| 5245 } | |
| 5246 | |
| 5247 SetHiddenPropertiesHashTable(object, hashtable); | 5232 SetHiddenPropertiesHashTable(object, hashtable); |
| 5248 return hashtable; | 5233 return hashtable; |
| 5249 } | 5234 } |
| 5250 | 5235 |
| 5251 | 5236 |
| 5252 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object, | 5237 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object, |
| 5253 Handle<Object> value) { | 5238 Handle<Object> value) { |
| 5254 DCHECK(!object->IsJSGlobalProxy()); | 5239 DCHECK(!object->IsJSGlobalProxy()); |
| 5255 Isolate* isolate = object->GetIsolate(); | 5240 Isolate* isolate = object->GetIsolate(); |
| 5256 Handle<Name> name = isolate->factory()->hidden_string(); | 5241 Handle<Name> name = isolate->factory()->hidden_string(); |
| (...skipping 11039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16296 } | 16281 } |
| 16297 Heap* heap = Dictionary::GetHeap(); | 16282 Heap* heap = Dictionary::GetHeap(); |
| 16298 return heap->undefined_value(); | 16283 return heap->undefined_value(); |
| 16299 } | 16284 } |
| 16300 | 16285 |
| 16301 | 16286 |
| 16302 Object* ObjectHashTable::Lookup(Handle<Object> key) { | 16287 Object* ObjectHashTable::Lookup(Handle<Object> key) { |
| 16303 DisallowHeapAllocation no_gc; | 16288 DisallowHeapAllocation no_gc; |
| 16304 DCHECK(IsKey(*key)); | 16289 DCHECK(IsKey(*key)); |
| 16305 | 16290 |
| 16291 Isolate* isolate = GetIsolate(); | |
| 16292 | |
| 16306 // If the object does not have an identity hash, it was never used as a key. | 16293 // If the object does not have an identity hash, it was never used as a key. |
| 16307 Object* hash = key->GetHash(); | 16294 Object* hash = key->GetHash(); |
| 16308 if (hash->IsUndefined()) { | 16295 if (hash->IsUndefined()) { |
| 16309 return GetHeap()->the_hole_value(); | 16296 return isolate->heap()->the_hole_value(); |
| 16310 } | 16297 } |
| 16311 int entry = FindEntry(key); | 16298 int entry = FindEntry(isolate, key, Smi::cast(hash)->value()); |
|
adamk
2015/05/21 19:11:32
Can you just delegate to the two-arg form of Looku
Erik Corry
2015/05/22 06:20:25
Created a three-argument form to avoid looking up
| |
| 16312 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 16299 if (entry == kNotFound) return isolate->heap()->the_hole_value(); |
| 16313 return get(EntryToIndex(entry) + 1); | 16300 return get(EntryToIndex(entry) + 1); |
| 16314 } | 16301 } |
| 16315 | 16302 |
| 16303 | |
| 16304 Object* ObjectHashTable::Lookup(Handle<Object> key, int32_t hash) { | |
| 16305 DisallowHeapAllocation no_gc; | |
| 16306 DCHECK(IsKey(*key)); | |
| 16307 | |
| 16308 Isolate* isolate = GetIsolate(); | |
| 16309 | |
| 16310 int entry = FindEntry(isolate, key, hash); | |
| 16311 if (entry == kNotFound) return isolate->heap()->the_hole_value(); | |
| 16312 return get(EntryToIndex(entry) + 1); | |
| 16313 } | |
| 16314 | |
| 16316 | 16315 |
| 16317 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, | 16316 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, |
| 16318 Handle<Object> key, | 16317 Handle<Object> key, |
| 16319 Handle<Object> value) { | 16318 Handle<Object> value) { |
| 16320 DCHECK(table->IsKey(*key)); | 16319 DCHECK(table->IsKey(*key)); |
| 16321 DCHECK(!value->IsTheHole()); | 16320 DCHECK(!value->IsTheHole()); |
| 16322 | 16321 |
| 16323 Isolate* isolate = table->GetIsolate(); | 16322 Isolate* isolate = table->GetIsolate(); |
| 16323 // Make sure the key object has an identity hash code. | |
| 16324 int32_t hash = Object::GetOrCreateHash(isolate, key)->value(); | |
| 16325 | |
| 16326 return Put(table, key, value, hash); | |
| 16327 } | |
| 16328 | |
| 16329 | |
| 16330 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, | |
| 16331 Handle<Object> key, | |
| 16332 Handle<Object> value, | |
| 16333 int32_t hash) { | |
| 16334 DCHECK(table->IsKey(*key)); | |
| 16335 DCHECK(!value->IsTheHole()); | |
| 16336 | |
| 16337 Isolate* isolate = table->GetIsolate(); | |
| 16324 | 16338 |
| 16325 // Make sure the key object has an identity hash code. | 16339 int entry = table->FindEntry(isolate, key, hash); |
| 16326 Handle<Smi> hash = Object::GetOrCreateHash(isolate, key); | |
| 16327 | |
| 16328 int entry = table->FindEntry(key); | |
| 16329 | 16340 |
| 16330 // Key is already in table, just overwrite value. | 16341 // Key is already in table, just overwrite value. |
| 16331 if (entry != kNotFound) { | 16342 if (entry != kNotFound) { |
| 16332 table->set(EntryToIndex(entry) + 1, *value); | 16343 table->set(EntryToIndex(entry) + 1, *value); |
| 16333 return table; | 16344 return table; |
| 16334 } | 16345 } |
| 16335 | 16346 |
| 16336 // Check whether the hash table should be extended. | 16347 // Check whether the hash table should be extended. |
| 16337 table = EnsureCapacity(table, 1, key); | 16348 table = EnsureCapacity(table, 1, key); |
| 16338 table->AddEntry(table->FindInsertionEntry(hash->value()), | 16349 table->AddEntry(table->FindInsertionEntry(hash), *key, *value); |
| 16339 *key, | |
| 16340 *value); | |
| 16341 return table; | 16350 return table; |
| 16342 } | 16351 } |
| 16343 | 16352 |
| 16344 | 16353 |
| 16345 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, | 16354 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, |
| 16346 Handle<Object> key, | 16355 Handle<Object> key, |
| 16347 bool* was_present) { | 16356 bool* was_present) { |
| 16348 DCHECK(table->IsKey(*key)); | 16357 DCHECK(table->IsKey(*key)); |
| 16349 | 16358 |
| 16350 Object* hash = key->GetHash(); | 16359 Object* hash = key->GetHash(); |
| 16351 if (hash->IsUndefined()) { | 16360 if (hash->IsUndefined()) { |
| 16352 *was_present = false; | 16361 *was_present = false; |
| 16353 return table; | 16362 return table; |
| 16354 } | 16363 } |
| 16355 | 16364 |
| 16356 int entry = table->FindEntry(key); | 16365 return Remove(table, key, was_present, Smi::cast(hash)->value()); |
| 16366 } | |
| 16367 | |
| 16368 | |
| 16369 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, | |
| 16370 Handle<Object> key, | |
| 16371 bool* was_present, | |
| 16372 int32_t hash) { | |
| 16373 DCHECK(table->IsKey(*key)); | |
| 16374 | |
| 16375 int entry = table->FindEntry(table->GetIsolate(), key, hash); | |
| 16357 if (entry == kNotFound) { | 16376 if (entry == kNotFound) { |
| 16358 *was_present = false; | 16377 *was_present = false; |
| 16359 return table; | 16378 return table; |
| 16360 } | 16379 } |
| 16361 | 16380 |
| 16362 *was_present = true; | 16381 *was_present = true; |
| 16363 table->RemoveEntry(entry); | 16382 table->RemoveEntry(entry); |
| 16364 return Shrink(table, key); | 16383 return Shrink(table, key); |
| 16365 } | 16384 } |
| 16366 | 16385 |
| (...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 17260 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, | 17279 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, |
| 17261 Handle<Object> new_value) { | 17280 Handle<Object> new_value) { |
| 17262 if (cell->value() != *new_value) { | 17281 if (cell->value() != *new_value) { |
| 17263 cell->set_value(*new_value); | 17282 cell->set_value(*new_value); |
| 17264 Isolate* isolate = cell->GetIsolate(); | 17283 Isolate* isolate = cell->GetIsolate(); |
| 17265 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17284 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17266 isolate, DependentCode::kPropertyCellChangedGroup); | 17285 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17267 } | 17286 } |
| 17268 } | 17287 } |
| 17269 } } // namespace v8::internal | 17288 } } // namespace v8::internal |
| OLD | NEW |