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 6151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6162 } | 6162 } |
6163 #endif | 6163 #endif |
6164 | 6164 |
6165 DCHECK(object->HasDictionaryElements() || | 6165 DCHECK(object->HasDictionaryElements() || |
6166 object->HasSlowArgumentsElements() || | 6166 object->HasSlowArgumentsElements() || |
6167 object->HasSlowStringWrapperElements()); | 6167 object->HasSlowStringWrapperElements()); |
6168 return dictionary; | 6168 return dictionary; |
6169 } | 6169 } |
6170 | 6170 |
6171 | 6171 |
6172 static Smi* GenerateIdentityHash(Isolate* isolate) { | |
6173 int hash_value; | |
6174 int attempts = 0; | |
6175 do { | |
6176 // Generate a random 32-bit hash value but limit range to fit | |
6177 // within a smi. | |
6178 hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue; | |
6179 attempts++; | |
6180 } while (hash_value == 0 && attempts < 30); | |
6181 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 | |
6182 | |
6183 return Smi::FromInt(hash_value); | |
6184 } | |
6185 | |
6186 template <typename ProxyType> | 6172 template <typename ProxyType> |
6187 static Smi* GetOrCreateIdentityHashHelper(Isolate* isolate, | 6173 static Smi* GetOrCreateIdentityHashHelper(Isolate* isolate, |
6188 Handle<ProxyType> proxy) { | 6174 Handle<ProxyType> proxy) { |
6189 Object* maybe_hash = proxy->hash(); | 6175 Object* maybe_hash = proxy->hash(); |
6190 if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash); | 6176 if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash); |
6191 | 6177 |
6192 Smi* hash = GenerateIdentityHash(isolate); | 6178 Smi* hash = Smi::FromInt(isolate->GenerateIdentityHash(Smi::kMaxValue)); |
6193 proxy->set_hash(hash); | 6179 proxy->set_hash(hash); |
6194 return hash; | 6180 return hash; |
6195 } | 6181 } |
6196 | 6182 |
6197 // static | 6183 // static |
6198 Object* JSObject::GetIdentityHash(Isolate* isolate, Handle<JSObject> object) { | 6184 Object* JSObject::GetIdentityHash(Isolate* isolate, Handle<JSObject> object) { |
6199 if (object->IsJSGlobalProxy()) { | 6185 if (object->IsJSGlobalProxy()) { |
6200 return JSGlobalProxy::cast(*object)->hash(); | 6186 return JSGlobalProxy::cast(*object)->hash(); |
6201 } | 6187 } |
6202 Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol(); | 6188 Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol(); |
6203 return *JSReceiver::GetDataProperty(object, hash_code_symbol); | 6189 return *JSReceiver::GetDataProperty(object, hash_code_symbol); |
6204 } | 6190 } |
6205 | 6191 |
6206 // static | 6192 // static |
6207 Smi* JSObject::GetOrCreateIdentityHash(Isolate* isolate, | 6193 Smi* JSObject::GetOrCreateIdentityHash(Isolate* isolate, |
6208 Handle<JSObject> object) { | 6194 Handle<JSObject> object) { |
6209 if (object->IsJSGlobalProxy()) { | 6195 if (object->IsJSGlobalProxy()) { |
6210 return GetOrCreateIdentityHashHelper(isolate, | 6196 return GetOrCreateIdentityHashHelper(isolate, |
6211 Handle<JSGlobalProxy>::cast(object)); | 6197 Handle<JSGlobalProxy>::cast(object)); |
6212 } | 6198 } |
6213 | 6199 |
6214 Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol(); | 6200 Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol(); |
6215 LookupIterator it(object, hash_code_symbol, object, LookupIterator::OWN); | 6201 LookupIterator it(object, hash_code_symbol, object, LookupIterator::OWN); |
6216 if (it.IsFound()) { | 6202 if (it.IsFound()) { |
6217 DCHECK_EQ(LookupIterator::DATA, it.state()); | 6203 DCHECK_EQ(LookupIterator::DATA, it.state()); |
6218 Object* maybe_hash = *it.GetDataValue(); | 6204 Object* maybe_hash = *it.GetDataValue(); |
6219 if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash); | 6205 if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash); |
6220 } | 6206 } |
6221 | 6207 |
6222 Smi* hash = GenerateIdentityHash(isolate); | 6208 Smi* hash = Smi::FromInt(isolate->GenerateIdentityHash(Smi::kMaxValue)); |
6223 CHECK(AddDataProperty(&it, handle(hash, isolate), NONE, THROW_ON_ERROR, | 6209 CHECK(AddDataProperty(&it, handle(hash, isolate), NONE, THROW_ON_ERROR, |
6224 CERTAINLY_NOT_STORE_FROM_KEYED) | 6210 CERTAINLY_NOT_STORE_FROM_KEYED) |
6225 .IsJust()); | 6211 .IsJust()); |
6226 return hash; | 6212 return hash; |
6227 } | 6213 } |
6228 | 6214 |
6229 // static | 6215 // static |
6230 Object* JSProxy::GetIdentityHash(Handle<JSProxy> proxy) { | 6216 Object* JSProxy::GetIdentityHash(Handle<JSProxy> proxy) { |
6231 return proxy->hash(); | 6217 return proxy->hash(); |
6232 } | 6218 } |
(...skipping 13347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19580 if (value->IsTheHole(isolate)) { | 19566 if (value->IsTheHole(isolate)) { |
19581 THROW_NEW_ERROR( | 19567 THROW_NEW_ERROR( |
19582 isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object); | 19568 isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object); |
19583 } | 19569 } |
19584 | 19570 |
19585 return value; | 19571 return value; |
19586 } | 19572 } |
19587 | 19573 |
19588 namespace { | 19574 namespace { |
19589 | 19575 |
19590 template <typename T> | 19576 struct ModuleHandleHash { |
19591 struct HandleValueHash { | 19577 V8_INLINE size_t operator()(Handle<Module> module) const { |
19592 V8_INLINE size_t operator()(Handle<T> handle) const { return handle->Hash(); } | 19578 return module->hash(); |
| 19579 } |
19593 }; | 19580 }; |
19594 | 19581 |
19595 struct ModuleHandleEqual { | 19582 struct ModuleHandleEqual { |
19596 V8_INLINE bool operator()(Handle<Module> lhs, Handle<Module> rhs) const { | 19583 V8_INLINE bool operator()(Handle<Module> lhs, Handle<Module> rhs) const { |
19597 return *lhs == *rhs; | 19584 return *lhs == *rhs; |
19598 } | 19585 } |
19599 }; | 19586 }; |
19600 | 19587 |
| 19588 struct StringHandleHash { |
| 19589 V8_INLINE size_t operator()(Handle<String> string) const { |
| 19590 return string->Hash(); |
| 19591 } |
| 19592 }; |
| 19593 |
19601 struct StringHandleEqual { | 19594 struct StringHandleEqual { |
19602 V8_INLINE bool operator()(Handle<String> lhs, Handle<String> rhs) const { | 19595 V8_INLINE bool operator()(Handle<String> lhs, Handle<String> rhs) const { |
19603 return lhs->Equals(*rhs); | 19596 return lhs->Equals(*rhs); |
19604 } | 19597 } |
19605 }; | 19598 }; |
19606 | 19599 |
19607 class UnorderedStringSet | 19600 class UnorderedStringSet |
19608 : public std::unordered_set<Handle<String>, HandleValueHash<String>, | 19601 : public std::unordered_set<Handle<String>, StringHandleHash, |
19609 StringHandleEqual, | 19602 StringHandleEqual, |
19610 zone_allocator<Handle<String>>> { | 19603 zone_allocator<Handle<String>>> { |
19611 public: | 19604 public: |
19612 explicit UnorderedStringSet(Zone* zone) | 19605 explicit UnorderedStringSet(Zone* zone) |
19613 : std::unordered_set<Handle<String>, HandleValueHash<String>, | 19606 : std::unordered_set<Handle<String>, StringHandleHash, StringHandleEqual, |
19614 StringHandleEqual, zone_allocator<Handle<String>>>( | 19607 zone_allocator<Handle<String>>>( |
19615 2 /* bucket count */, HandleValueHash<String>(), | 19608 2 /* bucket count */, StringHandleHash(), StringHandleEqual(), |
19616 StringHandleEqual(), zone_allocator<Handle<String>>(zone)) {} | 19609 zone_allocator<Handle<String>>(zone)) {} |
19617 }; | 19610 }; |
19618 | 19611 |
19619 class UnorderedModuleSet | 19612 class UnorderedModuleSet |
19620 : public std::unordered_set<Handle<Module>, HandleValueHash<Module>, | 19613 : public std::unordered_set<Handle<Module>, ModuleHandleHash, |
19621 ModuleHandleEqual, | 19614 ModuleHandleEqual, |
19622 zone_allocator<Handle<Module>>> { | 19615 zone_allocator<Handle<Module>>> { |
19623 public: | 19616 public: |
19624 explicit UnorderedModuleSet(Zone* zone) | 19617 explicit UnorderedModuleSet(Zone* zone) |
19625 : std::unordered_set<Handle<Module>, HandleValueHash<Module>, | 19618 : std::unordered_set<Handle<Module>, ModuleHandleHash, ModuleHandleEqual, |
19626 ModuleHandleEqual, zone_allocator<Handle<Module>>>( | 19619 zone_allocator<Handle<Module>>>( |
19627 2 /* bucket count */, HandleValueHash<Module>(), | 19620 2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(), |
19628 ModuleHandleEqual(), zone_allocator<Handle<Module>>(zone)) {} | 19621 zone_allocator<Handle<Module>>(zone)) {} |
19629 }; | 19622 }; |
19630 | 19623 |
19631 class UnorderedStringMap | 19624 class UnorderedStringMap |
19632 : public std::unordered_map< | 19625 : public std::unordered_map< |
19633 Handle<String>, Handle<Object>, HandleValueHash<String>, | 19626 Handle<String>, Handle<Object>, StringHandleHash, StringHandleEqual, |
19634 StringHandleEqual, | |
19635 zone_allocator<std::pair<const Handle<String>, Handle<Object>>>> { | 19627 zone_allocator<std::pair<const Handle<String>, Handle<Object>>>> { |
19636 public: | 19628 public: |
19637 explicit UnorderedStringMap(Zone* zone) | 19629 explicit UnorderedStringMap(Zone* zone) |
19638 : std::unordered_map< | 19630 : std::unordered_map< |
19639 Handle<String>, Handle<Object>, HandleValueHash<String>, | 19631 Handle<String>, Handle<Object>, StringHandleHash, StringHandleEqual, |
19640 StringHandleEqual, | |
19641 zone_allocator<std::pair<const Handle<String>, Handle<Object>>>>( | 19632 zone_allocator<std::pair<const Handle<String>, Handle<Object>>>>( |
19642 2 /* bucket count */, HandleValueHash<String>(), | 19633 2 /* bucket count */, StringHandleHash(), StringHandleEqual(), |
19643 StringHandleEqual(), | |
19644 zone_allocator<std::pair<const Handle<String>, Handle<Object>>>( | 19634 zone_allocator<std::pair<const Handle<String>, Handle<Object>>>( |
19645 zone)) {} | 19635 zone)) {} |
19646 }; | 19636 }; |
19647 | 19637 |
19648 } // anonymous namespace | 19638 } // anonymous namespace |
19649 | 19639 |
19650 class Module::ResolveSet | 19640 class Module::ResolveSet |
19651 : public std::unordered_map< | 19641 : public std::unordered_map< |
19652 Handle<Module>, UnorderedStringSet*, HandleValueHash<Module>, | 19642 Handle<Module>, UnorderedStringSet*, ModuleHandleHash, |
19653 ModuleHandleEqual, zone_allocator<std::pair<const Handle<Module>, | 19643 ModuleHandleEqual, zone_allocator<std::pair<const Handle<Module>, |
19654 UnorderedStringSet*>>> { | 19644 UnorderedStringSet*>>> { |
19655 public: | 19645 public: |
19656 explicit ResolveSet(Zone* zone) | 19646 explicit ResolveSet(Zone* zone) |
19657 : std::unordered_map<Handle<Module>, UnorderedStringSet*, | 19647 : std::unordered_map<Handle<Module>, UnorderedStringSet*, |
19658 HandleValueHash<Module>, ModuleHandleEqual, | 19648 ModuleHandleHash, ModuleHandleEqual, |
19659 zone_allocator<std::pair<const Handle<Module>, | 19649 zone_allocator<std::pair<const Handle<Module>, |
19660 UnorderedStringSet*>>>( | 19650 UnorderedStringSet*>>>( |
19661 2 /* bucket count */, HandleValueHash<Module>(), | 19651 2 /* bucket count */, ModuleHandleHash(), ModuleHandleEqual(), |
19662 ModuleHandleEqual(), | |
19663 zone_allocator< | 19652 zone_allocator< |
19664 std::pair<const Handle<Module>, UnorderedStringSet*>>(zone)), | 19653 std::pair<const Handle<Module>, UnorderedStringSet*>>(zone)), |
19665 zone_(zone) {} | 19654 zone_(zone) {} |
19666 | 19655 |
19667 Zone* zone() const { return zone_; } | 19656 Zone* zone() const { return zone_; } |
19668 | 19657 |
19669 private: | 19658 private: |
19670 Zone* zone_; | 19659 Zone* zone_; |
19671 }; | 19660 }; |
19672 | 19661 |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20096 ns, Accessors::ModuleNamespaceEntryInfo(isolate, name, attr)) | 20085 ns, Accessors::ModuleNamespaceEntryInfo(isolate, name, attr)) |
20097 .Check(); | 20086 .Check(); |
20098 } | 20087 } |
20099 JSObject::PreventExtensions(ns, THROW_ON_ERROR).ToChecked(); | 20088 JSObject::PreventExtensions(ns, THROW_ON_ERROR).ToChecked(); |
20100 | 20089 |
20101 return ns; | 20090 return ns; |
20102 } | 20091 } |
20103 | 20092 |
20104 } // namespace internal | 20093 } // namespace internal |
20105 } // namespace v8 | 20094 } // namespace v8 |
OLD | NEW |