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 |