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 |