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

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 MIPS 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 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698