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 "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "accessors.h" | 7 #include "accessors.h" |
8 #include "allocation-site-scopes.h" | 8 #include "allocation-site-scopes.h" |
9 #include "api.h" | 9 #include "api.h" |
10 #include "arguments.h" | 10 #include "arguments.h" |
(...skipping 5050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5061 object->Print(); | 5061 object->Print(); |
5062 } | 5062 } |
5063 #endif | 5063 #endif |
5064 | 5064 |
5065 ASSERT(object->HasDictionaryElements() || | 5065 ASSERT(object->HasDictionaryElements() || |
5066 object->HasDictionaryArgumentsElements()); | 5066 object->HasDictionaryArgumentsElements()); |
5067 return dictionary; | 5067 return dictionary; |
5068 } | 5068 } |
5069 | 5069 |
5070 | 5070 |
5071 Smi* JSReceiver::GenerateIdentityHash() { | 5071 static Smi* GenerateIdentityHash(Isolate* isolate) { |
5072 Isolate* isolate = GetIsolate(); | |
5073 | |
5074 int hash_value; | 5072 int hash_value; |
5075 int attempts = 0; | 5073 int attempts = 0; |
5076 do { | 5074 do { |
5077 // Generate a random 32-bit hash value but limit range to fit | 5075 // Generate a random 32-bit hash value but limit range to fit |
5078 // within a smi. | 5076 // within a smi. |
5079 hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue; | 5077 hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue; |
5080 attempts++; | 5078 attempts++; |
5081 } while (hash_value == 0 && attempts < 30); | 5079 } while (hash_value == 0 && attempts < 30); |
5082 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 | 5080 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 |
5083 | 5081 |
5084 return Smi::FromInt(hash_value); | 5082 return Smi::FromInt(hash_value); |
5085 } | 5083 } |
5086 | 5084 |
5087 | 5085 |
5088 void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) { | 5086 void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) { |
| 5087 ASSERT(!object->IsJSGlobalProxy()); |
5089 Isolate* isolate = object->GetIsolate(); | 5088 Isolate* isolate = object->GetIsolate(); |
5090 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash); | 5089 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash); |
5091 } | 5090 } |
5092 | 5091 |
5093 | 5092 |
| 5093 template<typename ProxyType> |
| 5094 static Handle<Object> GetOrCreateIdentityHashHelper(Handle<ProxyType> proxy) { |
| 5095 Isolate* isolate = proxy->GetIsolate(); |
| 5096 |
| 5097 Handle<Object> hash(proxy->hash(), isolate); |
| 5098 if (hash->IsSmi()) return hash; |
| 5099 |
| 5100 hash = handle(GenerateIdentityHash(isolate), isolate); |
| 5101 proxy->set_hash(*hash); |
| 5102 return hash; |
| 5103 } |
| 5104 |
| 5105 |
5094 Object* JSObject::GetIdentityHash() { | 5106 Object* JSObject::GetIdentityHash() { |
5095 DisallowHeapAllocation no_gc; | 5107 DisallowHeapAllocation no_gc; |
5096 Isolate* isolate = GetIsolate(); | 5108 Isolate* isolate = GetIsolate(); |
| 5109 if (IsJSGlobalProxy()) { |
| 5110 return JSGlobalProxy::cast(this)->hash(); |
| 5111 } |
5097 Object* stored_value = | 5112 Object* stored_value = |
5098 GetHiddenProperty(isolate->factory()->identity_hash_string()); | 5113 GetHiddenProperty(isolate->factory()->identity_hash_string()); |
5099 return stored_value->IsSmi() | 5114 return stored_value->IsSmi() |
5100 ? stored_value | 5115 ? stored_value |
5101 : isolate->heap()->undefined_value(); | 5116 : isolate->heap()->undefined_value(); |
5102 } | 5117 } |
5103 | 5118 |
5104 | 5119 |
5105 Handle<Object> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) { | 5120 Handle<Object> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) { |
5106 Handle<Object> hash(object->GetIdentityHash(), object->GetIsolate()); | 5121 if (object->IsJSGlobalProxy()) { |
5107 if (hash->IsSmi()) | 5122 return GetOrCreateIdentityHashHelper(Handle<JSGlobalProxy>::cast(object)); |
5108 return hash; | 5123 } |
5109 | 5124 |
5110 Isolate* isolate = object->GetIsolate(); | 5125 Isolate* isolate = object->GetIsolate(); |
5111 | 5126 |
5112 hash = handle(object->GenerateIdentityHash(), isolate); | 5127 Handle<Object> hash(object->GetIdentityHash(), isolate); |
5113 Handle<Object> result = SetHiddenProperty(object, | 5128 if (hash->IsSmi()) return hash; |
5114 isolate->factory()->identity_hash_string(), hash); | |
5115 | 5129 |
5116 if (result->IsUndefined()) { | 5130 hash = handle(GenerateIdentityHash(isolate), isolate); |
5117 // Trying to get hash of detached proxy. | 5131 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash); |
5118 return handle(Smi::FromInt(0), isolate); | |
5119 } | |
5120 | |
5121 return hash; | 5132 return hash; |
5122 } | 5133 } |
5123 | 5134 |
5124 | 5135 |
5125 Object* JSProxy::GetIdentityHash() { | 5136 Object* JSProxy::GetIdentityHash() { |
5126 return this->hash(); | 5137 return this->hash(); |
5127 } | 5138 } |
5128 | 5139 |
5129 | 5140 |
5130 Handle<Object> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) { | 5141 Handle<Object> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) { |
5131 Isolate* isolate = proxy->GetIsolate(); | 5142 return GetOrCreateIdentityHashHelper(proxy); |
5132 | |
5133 Handle<Object> hash(proxy->GetIdentityHash(), isolate); | |
5134 if (hash->IsSmi()) | |
5135 return hash; | |
5136 | |
5137 hash = handle(proxy->GenerateIdentityHash(), isolate); | |
5138 proxy->set_hash(*hash); | |
5139 return hash; | |
5140 } | 5143 } |
5141 | 5144 |
5142 | 5145 |
5143 Object* JSObject::GetHiddenProperty(Handle<Name> key) { | 5146 Object* JSObject::GetHiddenProperty(Handle<Name> key) { |
5144 DisallowHeapAllocation no_gc; | 5147 DisallowHeapAllocation no_gc; |
5145 ASSERT(key->IsUniqueName()); | 5148 ASSERT(key->IsUniqueName()); |
5146 if (IsJSGlobalProxy()) { | 5149 if (IsJSGlobalProxy()) { |
| 5150 // JSGlobalProxies store their hash internally. |
| 5151 ASSERT(*key != GetHeap()->identity_hash_string()); |
5147 // For a proxy, use the prototype as target object. | 5152 // For a proxy, use the prototype as target object. |
5148 Object* proxy_parent = GetPrototype(); | 5153 Object* proxy_parent = GetPrototype(); |
5149 // If the proxy is detached, return undefined. | 5154 // If the proxy is detached, return undefined. |
5150 if (proxy_parent->IsNull()) return GetHeap()->the_hole_value(); | 5155 if (proxy_parent->IsNull()) return GetHeap()->the_hole_value(); |
5151 ASSERT(proxy_parent->IsJSGlobalObject()); | 5156 ASSERT(proxy_parent->IsJSGlobalObject()); |
5152 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); | 5157 return JSObject::cast(proxy_parent)->GetHiddenProperty(key); |
5153 } | 5158 } |
5154 ASSERT(!IsJSGlobalProxy()); | 5159 ASSERT(!IsJSGlobalProxy()); |
5155 Object* inline_value = GetHiddenPropertiesHashTable(); | 5160 Object* inline_value = GetHiddenPropertiesHashTable(); |
5156 | 5161 |
(...skipping 14 matching lines...) Expand all Loading... |
5171 } | 5176 } |
5172 | 5177 |
5173 | 5178 |
5174 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, | 5179 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, |
5175 Handle<Name> key, | 5180 Handle<Name> key, |
5176 Handle<Object> value) { | 5181 Handle<Object> value) { |
5177 Isolate* isolate = object->GetIsolate(); | 5182 Isolate* isolate = object->GetIsolate(); |
5178 | 5183 |
5179 ASSERT(key->IsUniqueName()); | 5184 ASSERT(key->IsUniqueName()); |
5180 if (object->IsJSGlobalProxy()) { | 5185 if (object->IsJSGlobalProxy()) { |
| 5186 // JSGlobalProxies store their hash internally. |
| 5187 ASSERT(*key != *isolate->factory()->identity_hash_string()); |
5181 // For a proxy, use the prototype as target object. | 5188 // For a proxy, use the prototype as target object. |
5182 Handle<Object> proxy_parent(object->GetPrototype(), isolate); | 5189 Handle<Object> proxy_parent(object->GetPrototype(), isolate); |
5183 // If the proxy is detached, return undefined. | 5190 // If the proxy is detached, return undefined. |
5184 if (proxy_parent->IsNull()) return isolate->factory()->undefined_value(); | 5191 if (proxy_parent->IsNull()) return isolate->factory()->undefined_value(); |
5185 ASSERT(proxy_parent->IsJSGlobalObject()); | 5192 ASSERT(proxy_parent->IsJSGlobalObject()); |
5186 return SetHiddenProperty(Handle<JSObject>::cast(proxy_parent), key, value); | 5193 return SetHiddenProperty(Handle<JSObject>::cast(proxy_parent), key, value); |
5187 } | 5194 } |
5188 ASSERT(!object->IsJSGlobalProxy()); | 5195 ASSERT(!object->IsJSGlobalProxy()); |
5189 | 5196 |
5190 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 5197 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); |
(...skipping 12067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17258 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17265 #define ERROR_MESSAGES_TEXTS(C, T) T, |
17259 static const char* error_messages_[] = { | 17266 static const char* error_messages_[] = { |
17260 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17267 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
17261 }; | 17268 }; |
17262 #undef ERROR_MESSAGES_TEXTS | 17269 #undef ERROR_MESSAGES_TEXTS |
17263 return error_messages_[reason]; | 17270 return error_messages_[reason]; |
17264 } | 17271 } |
17265 | 17272 |
17266 | 17273 |
17267 } } // namespace v8::internal | 17274 } } // namespace v8::internal |
OLD | NEW |