| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 "src/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 6149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6160 } | 6160 } |
| 6161 #endif | 6161 #endif |
| 6162 | 6162 |
| 6163 DCHECK(object->HasDictionaryElements() || | 6163 DCHECK(object->HasDictionaryElements() || |
| 6164 object->HasSlowArgumentsElements() || | 6164 object->HasSlowArgumentsElements() || |
| 6165 object->HasSlowStringWrapperElements()); | 6165 object->HasSlowStringWrapperElements()); |
| 6166 return dictionary; | 6166 return dictionary; |
| 6167 } | 6167 } |
| 6168 | 6168 |
| 6169 | 6169 |
| 6170 static Smi* GenerateIdentityHash(Isolate* isolate) { | |
| 6171 int hash_value; | |
| 6172 int attempts = 0; | |
| 6173 do { | |
| 6174 // Generate a random 32-bit hash value but limit range to fit | |
| 6175 // within a smi. | |
| 6176 hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue; | |
| 6177 attempts++; | |
| 6178 } while (hash_value == 0 && attempts < 30); | |
| 6179 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 | |
| 6180 | |
| 6181 return Smi::FromInt(hash_value); | |
| 6182 } | |
| 6183 | |
| 6184 template <typename ProxyType> | 6170 template <typename ProxyType> |
| 6185 static Smi* GetOrCreateIdentityHashHelper(Isolate* isolate, | 6171 static Smi* GetOrCreateIdentityHashHelper(Isolate* isolate, |
| 6186 Handle<ProxyType> proxy) { | 6172 Handle<ProxyType> proxy) { |
| 6187 Object* maybe_hash = proxy->hash(); | 6173 Object* maybe_hash = proxy->hash(); |
| 6188 if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash); | 6174 if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash); |
| 6189 | 6175 |
| 6190 Smi* hash = GenerateIdentityHash(isolate); | 6176 Smi* hash = Smi::FromInt(isolate->GenerateIdentityHash(Smi::kMaxValue)); |
| 6191 proxy->set_hash(hash); | 6177 proxy->set_hash(hash); |
| 6192 return hash; | 6178 return hash; |
| 6193 } | 6179 } |
| 6194 | 6180 |
| 6195 // static | 6181 // static |
| 6196 Object* JSObject::GetIdentityHash(Isolate* isolate, Handle<JSObject> object) { | 6182 Object* JSObject::GetIdentityHash(Isolate* isolate, Handle<JSObject> object) { |
| 6197 if (object->IsJSGlobalProxy()) { | 6183 if (object->IsJSGlobalProxy()) { |
| 6198 return JSGlobalProxy::cast(*object)->hash(); | 6184 return JSGlobalProxy::cast(*object)->hash(); |
| 6199 } | 6185 } |
| 6200 Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol(); | 6186 Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol(); |
| 6201 return *JSReceiver::GetDataProperty(object, hash_code_symbol); | 6187 return *JSReceiver::GetDataProperty(object, hash_code_symbol); |
| 6202 } | 6188 } |
| 6203 | 6189 |
| 6204 // static | 6190 // static |
| 6205 Smi* JSObject::GetOrCreateIdentityHash(Isolate* isolate, | 6191 Smi* JSObject::GetOrCreateIdentityHash(Isolate* isolate, |
| 6206 Handle<JSObject> object) { | 6192 Handle<JSObject> object) { |
| 6207 if (object->IsJSGlobalProxy()) { | 6193 if (object->IsJSGlobalProxy()) { |
| 6208 return GetOrCreateIdentityHashHelper(isolate, | 6194 return GetOrCreateIdentityHashHelper(isolate, |
| 6209 Handle<JSGlobalProxy>::cast(object)); | 6195 Handle<JSGlobalProxy>::cast(object)); |
| 6210 } | 6196 } |
| 6211 | 6197 |
| 6212 Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol(); | 6198 Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol(); |
| 6213 LookupIterator it(object, hash_code_symbol, object, LookupIterator::OWN); | 6199 LookupIterator it(object, hash_code_symbol, object, LookupIterator::OWN); |
| 6214 if (it.IsFound()) { | 6200 if (it.IsFound()) { |
| 6215 DCHECK_EQ(LookupIterator::DATA, it.state()); | 6201 DCHECK_EQ(LookupIterator::DATA, it.state()); |
| 6216 Object* maybe_hash = *it.GetDataValue(); | 6202 Object* maybe_hash = *it.GetDataValue(); |
| 6217 if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash); | 6203 if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash); |
| 6218 } | 6204 } |
| 6219 | 6205 |
| 6220 Smi* hash = GenerateIdentityHash(isolate); | 6206 Smi* hash = Smi::FromInt(isolate->GenerateIdentityHash(Smi::kMaxValue)); |
| 6221 CHECK(AddDataProperty(&it, handle(hash, isolate), NONE, THROW_ON_ERROR, | 6207 CHECK(AddDataProperty(&it, handle(hash, isolate), NONE, THROW_ON_ERROR, |
| 6222 CERTAINLY_NOT_STORE_FROM_KEYED) | 6208 CERTAINLY_NOT_STORE_FROM_KEYED) |
| 6223 .IsJust()); | 6209 .IsJust()); |
| 6224 return hash; | 6210 return hash; |
| 6225 } | 6211 } |
| 6226 | 6212 |
| 6227 // static | 6213 // static |
| 6228 Object* JSProxy::GetIdentityHash(Handle<JSProxy> proxy) { | 6214 Object* JSProxy::GetIdentityHash(Handle<JSProxy> proxy) { |
| 6229 return proxy->hash(); | 6215 return proxy->hash(); |
| 6230 } | 6216 } |
| (...skipping 13348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19579 for (PrototypeIterator iter(isolate, this, kStartAtReceiver, | 19565 for (PrototypeIterator iter(isolate, this, kStartAtReceiver, |
| 19580 PrototypeIterator::END_AT_NULL); | 19566 PrototypeIterator::END_AT_NULL); |
| 19581 !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) { | 19567 !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) { |
| 19582 if (iter.GetCurrent<Object>()->IsJSProxy()) return true; | 19568 if (iter.GetCurrent<Object>()->IsJSProxy()) return true; |
| 19583 } | 19569 } |
| 19584 return false; | 19570 return false; |
| 19585 } | 19571 } |
| 19586 | 19572 |
| 19587 namespace { | 19573 namespace { |
| 19588 | 19574 |
| 19589 template <typename T> | 19575 struct ModuleHandleHash { |
| 19590 struct HandleValueHash { | 19576 V8_INLINE size_t operator()(Handle<Module> module) const { |
| 19591 V8_INLINE size_t operator()(Handle<T> handle) const { return handle->Hash(); } | 19577 return module->hash(); |
| 19578 } |
| 19592 }; | 19579 }; |
| 19593 | 19580 |
| 19594 struct ModuleHandleEqual { | 19581 struct ModuleHandleEqual { |
| 19595 V8_INLINE bool operator()(Handle<Module> lhs, Handle<Module> rhs) const { | 19582 V8_INLINE bool operator()(Handle<Module> lhs, Handle<Module> rhs) const { |
| 19596 return *lhs == *rhs; | 19583 return *lhs == *rhs; |
| 19597 } | 19584 } |
| 19598 }; | 19585 }; |
| 19599 | 19586 |
| 19587 struct StringHandleHash { |
| 19588 V8_INLINE size_t operator()(Handle<String> string) const { |
| 19589 return string->Hash(); |
| 19590 } |
| 19591 }; |
| 19592 |
| 19600 struct StringHandleEqual { | 19593 struct StringHandleEqual { |
| 19601 V8_INLINE bool operator()(Handle<String> lhs, Handle<String> rhs) const { | 19594 V8_INLINE bool operator()(Handle<String> lhs, Handle<String> rhs) const { |
| 19602 return lhs->Equals(*rhs); | 19595 return lhs->Equals(*rhs); |
| 19603 } | 19596 } |
| 19604 }; | 19597 }; |
| 19605 | 19598 |
| 19606 class UnorderedStringSet | 19599 class UnorderedStringSet |
| 19607 : public std::unordered_set<Handle<String>, HandleValueHash<String>, | 19600 : public std::unordered_set<Handle<String>, StringHandleHash, |
| 19608 StringHandleEqual, | 19601 StringHandleEqual, |
| 19609 zone_allocator<Handle<String>>> { | 19602 zone_allocator<Handle<String>>> { |
| 19610 public: | 19603 public: |
| 19611 explicit UnorderedStringSet(Zone* zone) | 19604 explicit UnorderedStringSet(Zone* zone) |
| 19612 : std::unordered_set<Handle<String>, HandleValueHash<String>, | 19605 : std::unordered_set<Handle<String>, StringHandleHash, StringHandleEqual, |
| 19613 StringHandleEqual, zone_allocator<Handle<String>>>( | 19606 zone_allocator<Handle<String>>>( |
| 19614 2 /* bucket count */, HandleValueHash<String>(), | 19607 2 /* bucket count */, StringHandleHash(), StringHandleEqual(), |
| 19615 StringHandleEqual(), zone_allocator<Handle<String>>(zone)) {} | 19608 zone_allocator<Handle<String>>(zone)) {} |
| 19616 }; | 19609 }; |
| 19617 | 19610 |
| 19618 } // anonymous namespace | 19611 } // anonymous namespace |
| 19619 | 19612 |
| 19620 class Module::ResolveSet | 19613 class Module::ResolveSet |
| 19621 : public std::unordered_map< | 19614 : public std::unordered_map< |
| 19622 Handle<Module>, UnorderedStringSet*, HandleValueHash<Module>, | 19615 Handle<Module>, UnorderedStringSet*, ModuleHandleHash, |
| 19623 ModuleHandleEqual, zone_allocator<std::pair<const Handle<Module>, | 19616 ModuleHandleEqual, zone_allocator<std::pair<const Handle<Module>, |
| 19624 UnorderedStringSet*>>> { | 19617 UnorderedStringSet*>>> { |
| 19625 public: | 19618 public: |
| 19626 explicit ResolveSet(Zone* zone) | 19619 explicit ResolveSet(Zone* zone) |
| 19627 : std::unordered_map<Handle<Module>, UnorderedStringSet*, | 19620 : std::unordered_map<Handle<Module>, UnorderedStringSet*, |
| 19628 HandleValueHash<Module>, ModuleHandleEqual, | 19621 ModuleHandleHash, ModuleHandleEqual, |
| 19629 zone_allocator<std::pair<const Handle<Module>, | 19622 zone_allocator<std::pair<const Handle<Module>, |
| 19630 UnorderedStringSet*>>>( | 19623 UnorderedStringSet*>>>( |
| 19631 2 /* bucket count */, HandleValueHash<Module>(), | 19624 2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(), |
| 19632 ModuleHandleEqual(), | |
| 19633 zone_allocator< | 19625 zone_allocator< |
| 19634 std::pair<const Handle<Module>, UnorderedStringSet*>>(zone)), | 19626 std::pair<const Handle<Module>, UnorderedStringSet*>>(zone)), |
| 19635 zone_(zone) {} | 19627 zone_(zone) {} |
| 19636 | 19628 |
| 19637 Zone* zone() const { return zone_; } | 19629 Zone* zone() const { return zone_; } |
| 19638 | 19630 |
| 19639 private: | 19631 private: |
| 19640 Zone* zone_; | 19632 Zone* zone_; |
| 19641 }; | 19633 }; |
| 19642 | 19634 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19933 } | 19925 } |
| 19934 | 19926 |
| 19935 // Evaluation of module body. | 19927 // Evaluation of module body. |
| 19936 Handle<JSFunction> resume( | 19928 Handle<JSFunction> resume( |
| 19937 isolate->native_context()->generator_next_internal(), isolate); | 19929 isolate->native_context()->generator_next_internal(), isolate); |
| 19938 return Execution::Call(isolate, resume, generator, 0, nullptr); | 19930 return Execution::Call(isolate, resume, generator, 0, nullptr); |
| 19939 } | 19931 } |
| 19940 | 19932 |
| 19941 } // namespace internal | 19933 } // namespace internal |
| 19942 } // namespace v8 | 19934 } // namespace v8 |
| OLD | NEW |