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

Side by Side Diff: src/objects.cc

Issue 1149863005: Move hash code from hidden string to a private symbol (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix global object hash code. This eated about 5% of weak collection performance Created 5 years, 7 months 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 // 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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698