OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/lookup.h" | 5 #include "src/lookup.h" |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/deoptimizer.h" | 8 #include "src/deoptimizer.h" |
9 #include "src/elements.h" | 9 #include "src/elements.h" |
10 #include "src/field-type.h" | 10 #include "src/field-type.h" |
11 #include "src/isolate-inl.h" | 11 #include "src/isolate-inl.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 void DescriptorLookupCache::Clear() { | |
17 for (int index = 0; index < kLength; index++) keys_[index].source = NULL; | |
18 } | |
19 | |
20 int KeyedLookupCache::Hash(Handle<Map> map, Handle<Name> name) { | |
21 DisallowHeapAllocation no_gc; | |
22 // Uses only lower 32 bits if pointers are larger. | |
23 uintptr_t addr_hash = | |
24 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(*map)) >> kMapHashShift; | |
25 return static_cast<uint32_t>((addr_hash ^ name->Hash()) & kCapacityMask); | |
26 } | |
27 | |
28 int KeyedLookupCache::Lookup(Handle<Map> map, Handle<Name> name) { | |
29 DisallowHeapAllocation no_gc; | |
30 int index = (Hash(map, name) & kHashMask); | |
31 for (int i = 0; i < kEntriesPerBucket; i++) { | |
32 Key& key = keys_[index + i]; | |
33 if ((key.map == *map) && key.name->Equals(*name)) { | |
34 return field_offsets_[index + i]; | |
35 } | |
36 } | |
37 return kNotFound; | |
38 } | |
39 | |
40 void KeyedLookupCache::Update(Handle<Map> map, Handle<Name> name, | |
41 int field_offset) { | |
42 DisallowHeapAllocation no_gc; | |
43 if (!name->IsUniqueName()) { | |
44 if (!StringTable::InternalizeStringIfExists(name->GetIsolate(), | |
45 Handle<String>::cast(name)) | |
46 .ToHandle(&name)) { | |
47 return; | |
48 } | |
49 } | |
50 // This cache is cleared only between mark compact passes, so we expect the | |
51 // cache to only contain old space names. | |
52 DCHECK(!map->GetIsolate()->heap()->InNewSpace(*name)); | |
53 | |
54 int index = (Hash(map, name) & kHashMask); | |
55 // After a GC there will be free slots, so we use them in order (this may | |
56 // help to get the most frequently used one in position 0). | |
57 for (int i = 0; i < kEntriesPerBucket; i++) { | |
58 Key& key = keys_[index]; | |
59 Object* free_entry_indicator = NULL; | |
60 if (key.map == free_entry_indicator) { | |
61 key.map = *map; | |
62 key.name = *name; | |
63 field_offsets_[index + i] = field_offset; | |
64 return; | |
65 } | |
66 } | |
67 // No free entry found in this bucket, so we move them all down one and | |
68 // put the new entry at position zero. | |
69 for (int i = kEntriesPerBucket - 1; i > 0; i--) { | |
70 Key& key = keys_[index + i]; | |
71 Key& key2 = keys_[index + i - 1]; | |
72 key = key2; | |
73 field_offsets_[index + i] = field_offsets_[index + i - 1]; | |
74 } | |
75 | |
76 // Write the new first entry. | |
77 Key& key = keys_[index]; | |
78 key.map = *map; | |
79 key.name = *name; | |
80 field_offsets_[index] = field_offset; | |
81 } | |
82 | |
83 void KeyedLookupCache::Clear() { | |
84 for (int index = 0; index < kLength; index++) keys_[index].map = NULL; | |
85 } | |
86 | |
87 // static | 16 // static |
88 LookupIterator LookupIterator::PropertyOrElement(Isolate* isolate, | 17 LookupIterator LookupIterator::PropertyOrElement(Isolate* isolate, |
89 Handle<Object> receiver, | 18 Handle<Object> receiver, |
90 Handle<Object> key, | 19 Handle<Object> key, |
91 bool* success, | 20 bool* success, |
92 Configuration configuration) { | 21 Configuration configuration) { |
93 uint32_t index = 0; | 22 uint32_t index = 0; |
94 if (key->ToArrayIndex(&index)) { | 23 if (key->ToArrayIndex(&index)) { |
95 *success = true; | 24 *success = true; |
96 return LookupIterator(isolate, receiver, index, configuration); | 25 return LookupIterator(isolate, receiver, index, configuration); |
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 : access_check_info->named_interceptor(); | 830 : access_check_info->named_interceptor(); |
902 if (interceptor) { | 831 if (interceptor) { |
903 return handle(InterceptorInfo::cast(interceptor), isolate_); | 832 return handle(InterceptorInfo::cast(interceptor), isolate_); |
904 } | 833 } |
905 } | 834 } |
906 return Handle<InterceptorInfo>(); | 835 return Handle<InterceptorInfo>(); |
907 } | 836 } |
908 | 837 |
909 } // namespace internal | 838 } // namespace internal |
910 } // namespace v8 | 839 } // namespace v8 |
OLD | NEW |