OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 10 matching lines...) Expand all Loading... |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #ifndef V8_STUB_CACHE_H_ | 28 #ifndef V8_STUB_CACHE_H_ |
29 #define V8_STUB_CACHE_H_ | 29 #define V8_STUB_CACHE_H_ |
30 | 30 |
| 31 #include "arguments.h" |
31 #include "macro-assembler.h" | 32 #include "macro-assembler.h" |
32 #include "zone-inl.h" | 33 #include "zone-inl.h" |
33 | 34 |
34 namespace v8 { | 35 namespace v8 { |
35 namespace internal { | 36 namespace internal { |
36 | 37 |
37 | 38 |
38 // The stub cache is used for megamorphic calls and property accesses. | 39 // The stub cache is used for megamorphic calls and property accesses. |
39 // It maps (map, name, type)->Code* | 40 // It maps (map, name, type)->Code* |
40 | 41 |
41 // The design of the table uses the inline cache stubs used for | 42 // The design of the table uses the inline cache stubs used for |
42 // mono-morphic calls. The beauty of this, we do not have to | 43 // mono-morphic calls. The beauty of this, we do not have to |
43 // invalidate the cache whenever a prototype map is changed. The stub | 44 // invalidate the cache whenever a prototype map is changed. The stub |
44 // validates the map chain as in the mono-morphic case. | 45 // validates the map chain as in the mono-morphic case. |
45 | 46 |
46 class SCTableReference; | 47 class StubCache; |
| 48 |
| 49 class SCTableReference { |
| 50 public: |
| 51 Address address() const { return address_; } |
| 52 |
| 53 private: |
| 54 explicit SCTableReference(Address address) : address_(address) {} |
| 55 |
| 56 Address address_; |
| 57 |
| 58 friend class StubCache; |
| 59 }; |
47 | 60 |
48 | 61 |
49 class StubCache : public AllStatic { | 62 class StubCache { |
50 public: | 63 public: |
51 struct Entry { | 64 struct Entry { |
52 String* key; | 65 String* key; |
53 Code* value; | 66 Code* value; |
54 }; | 67 }; |
55 | 68 |
| 69 void Initialize(bool create_heap_objects); |
56 | 70 |
57 static void Initialize(bool create_heap_objects); | |
58 | 71 |
59 // Computes the right stub matching. Inserts the result in the | 72 // Computes the right stub matching. Inserts the result in the |
60 // cache before returning. This might compile a stub if needed. | 73 // cache before returning. This might compile a stub if needed. |
61 MUST_USE_RESULT static MaybeObject* ComputeLoadNonexistent( | 74 MUST_USE_RESULT MaybeObject* ComputeLoadNonexistent( |
62 String* name, | 75 String* name, |
63 JSObject* receiver); | 76 JSObject* receiver); |
64 | 77 |
65 MUST_USE_RESULT static MaybeObject* ComputeLoadField(String* name, | 78 MUST_USE_RESULT MaybeObject* ComputeLoadField(String* name, |
66 JSObject* receiver, | 79 JSObject* receiver, |
67 JSObject* holder, | 80 JSObject* holder, |
68 int field_index); | 81 int field_index); |
69 | 82 |
70 MUST_USE_RESULT static MaybeObject* ComputeLoadCallback( | 83 MUST_USE_RESULT MaybeObject* ComputeLoadCallback( |
71 String* name, | 84 String* name, |
72 JSObject* receiver, | 85 JSObject* receiver, |
73 JSObject* holder, | 86 JSObject* holder, |
74 AccessorInfo* callback); | 87 AccessorInfo* callback); |
75 | 88 |
76 MUST_USE_RESULT static MaybeObject* ComputeLoadConstant(String* name, | 89 MUST_USE_RESULT MaybeObject* ComputeLoadConstant(String* name, |
77 JSObject* receiver, | 90 JSObject* receiver, |
78 JSObject* holder, | 91 JSObject* holder, |
79 Object* value); | 92 Object* value); |
80 | 93 |
81 MUST_USE_RESULT static MaybeObject* ComputeLoadInterceptor( | 94 MUST_USE_RESULT MaybeObject* ComputeLoadInterceptor( |
82 String* name, | 95 String* name, |
83 JSObject* receiver, | 96 JSObject* receiver, |
84 JSObject* holder); | 97 JSObject* holder); |
85 | 98 |
86 MUST_USE_RESULT static MaybeObject* ComputeLoadNormal(); | 99 MUST_USE_RESULT MaybeObject* ComputeLoadNormal(); |
87 | 100 |
88 | 101 |
89 MUST_USE_RESULT static MaybeObject* ComputeLoadGlobal( | 102 MUST_USE_RESULT MaybeObject* ComputeLoadGlobal( |
90 String* name, | 103 String* name, |
91 JSObject* receiver, | 104 JSObject* receiver, |
92 GlobalObject* holder, | 105 GlobalObject* holder, |
93 JSGlobalPropertyCell* cell, | 106 JSGlobalPropertyCell* cell, |
94 bool is_dont_delete); | 107 bool is_dont_delete); |
95 | 108 |
96 | 109 |
97 // --- | 110 // --- |
98 | 111 |
99 MUST_USE_RESULT static MaybeObject* ComputeKeyedLoadField(String* name, | 112 MUST_USE_RESULT MaybeObject* ComputeKeyedLoadField(String* name, |
100 JSObject* receiver, | 113 JSObject* receiver, |
101 JSObject* holder, | 114 JSObject* holder, |
102 int field_index); | 115 int field_index); |
103 | 116 |
104 MUST_USE_RESULT static MaybeObject* ComputeKeyedLoadCallback( | 117 MUST_USE_RESULT MaybeObject* ComputeKeyedLoadCallback( |
105 String* name, | 118 String* name, |
106 JSObject* receiver, | 119 JSObject* receiver, |
107 JSObject* holder, | 120 JSObject* holder, |
108 AccessorInfo* callback); | 121 AccessorInfo* callback); |
109 | 122 |
110 MUST_USE_RESULT static MaybeObject* ComputeKeyedLoadConstant( | 123 MUST_USE_RESULT MaybeObject* ComputeKeyedLoadConstant( |
111 String* name, | 124 String* name, |
112 JSObject* receiver, | 125 JSObject* receiver, |
113 JSObject* holder, | 126 JSObject* holder, |
114 Object* value); | 127 Object* value); |
115 | 128 |
116 MUST_USE_RESULT static MaybeObject* ComputeKeyedLoadInterceptor( | 129 MUST_USE_RESULT MaybeObject* ComputeKeyedLoadInterceptor( |
117 String* name, | 130 String* name, |
118 JSObject* receiver, | 131 JSObject* receiver, |
119 JSObject* holder); | 132 JSObject* holder); |
120 | 133 |
121 MUST_USE_RESULT static MaybeObject* ComputeKeyedLoadArrayLength( | 134 MUST_USE_RESULT MaybeObject* ComputeKeyedLoadArrayLength( |
122 String* name, | 135 String* name, |
123 JSArray* receiver); | 136 JSArray* receiver); |
124 | 137 |
125 MUST_USE_RESULT static MaybeObject* ComputeKeyedLoadStringLength( | 138 MUST_USE_RESULT MaybeObject* ComputeKeyedLoadStringLength( |
126 String* name, | 139 String* name, |
127 String* receiver); | 140 String* receiver); |
128 | 141 |
129 MUST_USE_RESULT static MaybeObject* ComputeKeyedLoadFunctionPrototype( | 142 MUST_USE_RESULT MaybeObject* ComputeKeyedLoadFunctionPrototype( |
130 String* name, | 143 String* name, |
131 JSFunction* receiver); | 144 JSFunction* receiver); |
132 | 145 |
133 MUST_USE_RESULT static MaybeObject* ComputeKeyedLoadSpecialized( | 146 MUST_USE_RESULT MaybeObject* ComputeKeyedLoadSpecialized( |
134 JSObject* receiver); | 147 JSObject* receiver); |
135 | 148 |
136 // --- | 149 // --- |
137 | 150 |
138 MUST_USE_RESULT static MaybeObject* ComputeStoreField( | 151 MUST_USE_RESULT MaybeObject* ComputeStoreField( |
139 String* name, | 152 String* name, |
140 JSObject* receiver, | 153 JSObject* receiver, |
141 int field_index, | 154 int field_index, |
142 Map* transition, | 155 Map* transition, |
143 StrictModeFlag strict_mode); | 156 StrictModeFlag strict_mode); |
144 | 157 |
145 MUST_USE_RESULT static MaybeObject* ComputeStoreNormal( | 158 MUST_USE_RESULT MaybeObject* ComputeStoreNormal( |
146 StrictModeFlag strict_mode); | 159 StrictModeFlag strict_mode); |
147 | 160 |
148 MUST_USE_RESULT static MaybeObject* ComputeStoreGlobal( | 161 MUST_USE_RESULT MaybeObject* ComputeStoreGlobal( |
149 String* name, | 162 String* name, |
150 GlobalObject* receiver, | 163 GlobalObject* receiver, |
151 JSGlobalPropertyCell* cell, | 164 JSGlobalPropertyCell* cell, |
152 StrictModeFlag strict_mode); | 165 StrictModeFlag strict_mode); |
153 | 166 |
154 MUST_USE_RESULT static MaybeObject* ComputeStoreCallback( | 167 MUST_USE_RESULT MaybeObject* ComputeStoreCallback( |
155 String* name, | 168 String* name, |
156 JSObject* receiver, | 169 JSObject* receiver, |
157 AccessorInfo* callback, | 170 AccessorInfo* callback, |
158 StrictModeFlag strict_mode); | 171 StrictModeFlag strict_mode); |
159 | 172 |
160 MUST_USE_RESULT static MaybeObject* ComputeStoreInterceptor( | 173 MUST_USE_RESULT MaybeObject* ComputeStoreInterceptor( |
161 String* name, | 174 String* name, |
162 JSObject* receiver, | 175 JSObject* receiver, |
163 StrictModeFlag strict_mode); | 176 StrictModeFlag strict_mode); |
164 | 177 |
165 // --- | 178 // --- |
166 | 179 |
167 MUST_USE_RESULT static MaybeObject* ComputeKeyedStoreField( | 180 MUST_USE_RESULT MaybeObject* ComputeKeyedStoreField( |
168 String* name, | 181 String* name, |
169 JSObject* receiver, | 182 JSObject* receiver, |
170 int field_index, | 183 int field_index, |
171 Map* transition, | 184 Map* transition, |
172 StrictModeFlag strict_mode); | 185 StrictModeFlag strict_mode); |
173 | 186 |
174 MUST_USE_RESULT static MaybeObject* ComputeKeyedStoreSpecialized( | 187 MUST_USE_RESULT MaybeObject* ComputeKeyedStoreSpecialized( |
175 JSObject* receiver, | 188 JSObject* receiver, |
176 StrictModeFlag strict_mode); | 189 StrictModeFlag strict_mode); |
177 | 190 |
178 MUST_USE_RESULT static MaybeObject* ComputeKeyedLoadOrStoreExternalArray( | 191 |
| 192 MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreExternalArray( |
179 JSObject* receiver, | 193 JSObject* receiver, |
180 bool is_store, | 194 bool is_store, |
181 StrictModeFlag strict_mode); | 195 StrictModeFlag strict_mode); |
182 | 196 |
183 // --- | 197 // --- |
184 | 198 |
185 MUST_USE_RESULT static MaybeObject* ComputeCallField(int argc, | 199 MUST_USE_RESULT MaybeObject* ComputeCallField(int argc, |
186 InLoopFlag in_loop, | 200 InLoopFlag in_loop, |
187 Code::Kind, | 201 Code::Kind, |
188 String* name, | 202 String* name, |
189 Object* object, | 203 Object* object, |
190 JSObject* holder, | 204 JSObject* holder, |
191 int index); | 205 int index); |
192 | 206 |
193 MUST_USE_RESULT static MaybeObject* ComputeCallConstant( | 207 MUST_USE_RESULT MaybeObject* ComputeCallConstant( |
194 int argc, | 208 int argc, |
195 InLoopFlag in_loop, | 209 InLoopFlag in_loop, |
196 Code::Kind, | 210 Code::Kind, |
197 Code::ExtraICState extra_ic_state, | 211 Code::ExtraICState extra_ic_state, |
198 String* name, | 212 String* name, |
199 Object* object, | 213 Object* object, |
200 JSObject* holder, | 214 JSObject* holder, |
201 JSFunction* function); | 215 JSFunction* function); |
202 | 216 |
203 MUST_USE_RESULT static MaybeObject* ComputeCallNormal(int argc, | 217 MUST_USE_RESULT MaybeObject* ComputeCallNormal(int argc, |
204 InLoopFlag in_loop, | 218 InLoopFlag in_loop, |
205 Code::Kind, | 219 Code::Kind, |
206 String* name, | 220 String* name, |
207 JSObject* receiver); | 221 JSObject* receiver); |
208 | 222 |
209 MUST_USE_RESULT static MaybeObject* ComputeCallInterceptor(int argc, | 223 MUST_USE_RESULT MaybeObject* ComputeCallInterceptor(int argc, |
210 Code::Kind, | 224 Code::Kind, |
211 String* name, | 225 String* name, |
212 Object* object, | 226 Object* object, |
213 JSObject* holder); | 227 JSObject* holder); |
214 | 228 |
215 MUST_USE_RESULT static MaybeObject* ComputeCallGlobal( | 229 MUST_USE_RESULT MaybeObject* ComputeCallGlobal( |
216 int argc, | 230 int argc, |
217 InLoopFlag in_loop, | 231 InLoopFlag in_loop, |
218 Code::Kind, | 232 Code::Kind, |
219 String* name, | 233 String* name, |
220 JSObject* receiver, | 234 JSObject* receiver, |
221 GlobalObject* holder, | 235 GlobalObject* holder, |
222 JSGlobalPropertyCell* cell, | 236 JSGlobalPropertyCell* cell, |
223 JSFunction* function); | 237 JSFunction* function); |
224 | 238 |
225 // --- | 239 // --- |
226 | 240 |
227 MUST_USE_RESULT static MaybeObject* ComputeCallInitialize(int argc, | 241 MUST_USE_RESULT MaybeObject* ComputeCallInitialize(int argc, |
228 InLoopFlag in_loop, | 242 InLoopFlag in_loop, |
229 Code::Kind kind); | 243 Code::Kind kind); |
230 | 244 |
231 static Handle<Code> ComputeCallInitialize(int argc, InLoopFlag in_loop); | 245 Handle<Code> ComputeCallInitialize(int argc, InLoopFlag in_loop); |
232 | 246 |
233 static Handle<Code> ComputeKeyedCallInitialize(int argc, InLoopFlag in_loop); | 247 Handle<Code> ComputeKeyedCallInitialize(int argc, InLoopFlag in_loop); |
234 | 248 |
235 MUST_USE_RESULT static MaybeObject* ComputeCallPreMonomorphic( | 249 MUST_USE_RESULT MaybeObject* ComputeCallPreMonomorphic( |
236 int argc, | 250 int argc, |
237 InLoopFlag in_loop, | 251 InLoopFlag in_loop, |
238 Code::Kind kind); | 252 Code::Kind kind); |
239 | 253 |
240 MUST_USE_RESULT static MaybeObject* ComputeCallNormal(int argc, | 254 MUST_USE_RESULT MaybeObject* ComputeCallNormal(int argc, |
241 InLoopFlag in_loop, | 255 InLoopFlag in_loop, |
242 Code::Kind kind); | 256 Code::Kind kind); |
243 | 257 |
244 MUST_USE_RESULT static MaybeObject* ComputeCallMegamorphic(int argc, | 258 MUST_USE_RESULT MaybeObject* ComputeCallMegamorphic(int argc, |
245 InLoopFlag in_loop, | 259 InLoopFlag in_loop, |
246 Code::Kind kind); | |
247 | |
248 MUST_USE_RESULT static MaybeObject* ComputeCallMiss(int argc, | |
249 Code::Kind kind); | 260 Code::Kind kind); |
250 | 261 |
| 262 MUST_USE_RESULT MaybeObject* ComputeCallMiss(int argc, Code::Kind kind); |
| 263 |
251 // Finds the Code object stored in the Heap::non_monomorphic_cache(). | 264 // Finds the Code object stored in the Heap::non_monomorphic_cache(). |
252 MUST_USE_RESULT static Code* FindCallInitialize(int argc, | 265 MUST_USE_RESULT Code* FindCallInitialize(int argc, |
253 InLoopFlag in_loop, | 266 InLoopFlag in_loop, |
254 Code::Kind kind); | 267 Code::Kind kind); |
255 | 268 |
256 #ifdef ENABLE_DEBUGGER_SUPPORT | 269 #ifdef ENABLE_DEBUGGER_SUPPORT |
257 MUST_USE_RESULT static MaybeObject* ComputeCallDebugBreak(int argc, | 270 MUST_USE_RESULT MaybeObject* ComputeCallDebugBreak(int argc, Code::Kind kind); |
258 Code::Kind kind); | |
259 | 271 |
260 MUST_USE_RESULT static MaybeObject* ComputeCallDebugPrepareStepIn( | 272 MUST_USE_RESULT MaybeObject* ComputeCallDebugPrepareStepIn(int argc, |
261 int argc, | 273 Code::Kind kind); |
262 Code::Kind kind); | |
263 #endif | 274 #endif |
264 | 275 |
265 // Update cache for entry hash(name, map). | 276 // Update cache for entry hash(name, map). |
266 static Code* Set(String* name, Map* map, Code* code); | 277 Code* Set(String* name, Map* map, Code* code); |
267 | 278 |
268 // Clear the lookup table (@ mark compact collection). | 279 // Clear the lookup table (@ mark compact collection). |
269 static void Clear(); | 280 void Clear(); |
270 | 281 |
271 // Collect all maps that match the name and flags. | 282 // Collect all maps that match the name and flags. |
272 static void CollectMatchingMaps(ZoneMapList* types, | 283 void CollectMatchingMaps(ZoneMapList* types, |
273 String* name, | 284 String* name, |
274 Code::Flags flags); | 285 Code::Flags flags); |
275 | 286 |
276 // Generate code for probing the stub cache table. | 287 // Generate code for probing the stub cache table. |
277 // Arguments extra and extra2 may be used to pass additional scratch | 288 // Arguments extra and extra2 may be used to pass additional scratch |
278 // registers. Set to no_reg if not needed. | 289 // registers. Set to no_reg if not needed. |
279 static void GenerateProbe(MacroAssembler* masm, | 290 void GenerateProbe(MacroAssembler* masm, |
280 Code::Flags flags, | 291 Code::Flags flags, |
281 Register receiver, | 292 Register receiver, |
282 Register name, | 293 Register name, |
283 Register scratch, | 294 Register scratch, |
284 Register extra, | 295 Register extra, |
285 Register extra2 = no_reg); | 296 Register extra2 = no_reg); |
286 | 297 |
287 enum Table { | 298 enum Table { |
288 kPrimary, | 299 kPrimary, |
289 kSecondary | 300 kSecondary |
290 }; | 301 }; |
291 | 302 |
| 303 |
| 304 SCTableReference key_reference(StubCache::Table table) { |
| 305 return SCTableReference( |
| 306 reinterpret_cast<Address>(&first_entry(table)->key)); |
| 307 } |
| 308 |
| 309 |
| 310 SCTableReference value_reference(StubCache::Table table) { |
| 311 return SCTableReference( |
| 312 reinterpret_cast<Address>(&first_entry(table)->value)); |
| 313 } |
| 314 |
| 315 |
| 316 StubCache::Entry* first_entry(StubCache::Table table) { |
| 317 switch (table) { |
| 318 case StubCache::kPrimary: return StubCache::primary_; |
| 319 case StubCache::kSecondary: return StubCache::secondary_; |
| 320 } |
| 321 UNREACHABLE(); |
| 322 return NULL; |
| 323 } |
| 324 |
| 325 |
292 private: | 326 private: |
| 327 explicit StubCache(Isolate* isolate); |
| 328 |
| 329 friend class Isolate; |
293 friend class SCTableReference; | 330 friend class SCTableReference; |
294 static const int kPrimaryTableSize = 2048; | 331 static const int kPrimaryTableSize = 2048; |
295 static const int kSecondaryTableSize = 512; | 332 static const int kSecondaryTableSize = 512; |
296 static Entry primary_[]; | 333 Entry primary_[kPrimaryTableSize]; |
297 static Entry secondary_[]; | 334 Entry secondary_[kSecondaryTableSize]; |
298 | 335 |
299 // Computes the hashed offsets for primary and secondary caches. | 336 // Computes the hashed offsets for primary and secondary caches. |
300 static int PrimaryOffset(String* name, Code::Flags flags, Map* map) { | 337 RLYSTC int PrimaryOffset(String* name, Code::Flags flags, Map* map) { |
301 // This works well because the heap object tag size and the hash | 338 // This works well because the heap object tag size and the hash |
302 // shift are equal. Shifting down the length field to get the | 339 // shift are equal. Shifting down the length field to get the |
303 // hash code would effectively throw away two bits of the hash | 340 // hash code would effectively throw away two bits of the hash |
304 // code. | 341 // code. |
305 ASSERT(kHeapObjectTagSize == String::kHashShift); | 342 ASSERT(kHeapObjectTagSize == String::kHashShift); |
306 // Compute the hash of the name (use entire hash field). | 343 // Compute the hash of the name (use entire hash field). |
307 ASSERT(name->HasHashCode()); | 344 ASSERT(name->HasHashCode()); |
308 uint32_t field = name->hash_field(); | 345 uint32_t field = name->hash_field(); |
309 // Using only the low bits in 64-bit mode is unlikely to increase the | 346 // Using only the low bits in 64-bit mode is unlikely to increase the |
310 // risk of collision even if the heap is spread over an area larger than | 347 // risk of collision even if the heap is spread over an area larger than |
311 // 4Gb (and not at all if it isn't). | 348 // 4Gb (and not at all if it isn't). |
312 uint32_t map_low32bits = | 349 uint32_t map_low32bits = |
313 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map)); | 350 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map)); |
314 // We always set the in_loop bit to zero when generating the lookup code | 351 // We always set the in_loop bit to zero when generating the lookup code |
315 // so do it here too so the hash codes match. | 352 // so do it here too so the hash codes match. |
316 uint32_t iflags = | 353 uint32_t iflags = |
317 (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup); | 354 (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup); |
318 // Base the offset on a simple combination of name, flags, and map. | 355 // Base the offset on a simple combination of name, flags, and map. |
319 uint32_t key = (map_low32bits + field) ^ iflags; | 356 uint32_t key = (map_low32bits + field) ^ iflags; |
320 return key & ((kPrimaryTableSize - 1) << kHeapObjectTagSize); | 357 return key & ((kPrimaryTableSize - 1) << kHeapObjectTagSize); |
321 } | 358 } |
322 | 359 |
323 static int SecondaryOffset(String* name, Code::Flags flags, int seed) { | 360 RLYSTC int SecondaryOffset(String* name, Code::Flags flags, int seed) { |
324 // Use the seed from the primary cache in the secondary cache. | 361 // Use the seed from the primary cache in the secondary cache. |
325 uint32_t string_low32bits = | 362 uint32_t string_low32bits = |
326 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name)); | 363 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name)); |
327 // We always set the in_loop bit to zero when generating the lookup code | 364 // We always set the in_loop bit to zero when generating the lookup code |
328 // so do it here too so the hash codes match. | 365 // so do it here too so the hash codes match. |
329 uint32_t iflags = | 366 uint32_t iflags = |
330 (static_cast<uint32_t>(flags) & ~Code::kFlagsICInLoopMask); | 367 (static_cast<uint32_t>(flags) & ~Code::kFlagsICInLoopMask); |
331 uint32_t key = seed - string_low32bits + iflags; | 368 uint32_t key = seed - string_low32bits + iflags; |
332 return key & ((kSecondaryTableSize - 1) << kHeapObjectTagSize); | 369 return key & ((kSecondaryTableSize - 1) << kHeapObjectTagSize); |
333 } | 370 } |
334 | 371 |
335 // Compute the entry for a given offset in exactly the same way as | 372 // Compute the entry for a given offset in exactly the same way as |
336 // we do in generated code. We generate an hash code that already | 373 // we do in generated code. We generate an hash code that already |
337 // ends in String::kHashShift 0s. Then we shift it so it is a multiple | 374 // ends in String::kHashShift 0s. Then we shift it so it is a multiple |
338 // of sizeof(Entry). This makes it easier to avoid making mistakes | 375 // of sizeof(Entry). This makes it easier to avoid making mistakes |
339 // in the hashed offset computations. | 376 // in the hashed offset computations. |
340 static Entry* entry(Entry* table, int offset) { | 377 RLYSTC Entry* entry(Entry* table, int offset) { |
341 const int shift_amount = kPointerSizeLog2 + 1 - String::kHashShift; | 378 const int shift_amount = kPointerSizeLog2 + 1 - String::kHashShift; |
342 return reinterpret_cast<Entry*>( | 379 return reinterpret_cast<Entry*>( |
343 reinterpret_cast<Address>(table) + (offset << shift_amount)); | 380 reinterpret_cast<Address>(table) + (offset << shift_amount)); |
344 } | 381 } |
| 382 |
| 383 Isolate* isolate_; |
| 384 |
| 385 DISALLOW_COPY_AND_ASSIGN(StubCache); |
345 }; | 386 }; |
346 | 387 |
347 | 388 |
348 class SCTableReference { | |
349 public: | |
350 static SCTableReference keyReference(StubCache::Table table) { | |
351 return SCTableReference( | |
352 reinterpret_cast<Address>(&first_entry(table)->key)); | |
353 } | |
354 | |
355 | |
356 static SCTableReference valueReference(StubCache::Table table) { | |
357 return SCTableReference( | |
358 reinterpret_cast<Address>(&first_entry(table)->value)); | |
359 } | |
360 | |
361 Address address() const { return address_; } | |
362 | |
363 private: | |
364 explicit SCTableReference(Address address) : address_(address) {} | |
365 | |
366 static StubCache::Entry* first_entry(StubCache::Table table) { | |
367 switch (table) { | |
368 case StubCache::kPrimary: return StubCache::primary_; | |
369 case StubCache::kSecondary: return StubCache::secondary_; | |
370 } | |
371 UNREACHABLE(); | |
372 return NULL; | |
373 } | |
374 | |
375 Address address_; | |
376 }; | |
377 | |
378 // ------------------------------------------------------------------------ | 389 // ------------------------------------------------------------------------ |
379 | 390 |
380 | 391 |
381 // Support functions for IC stubs for callbacks. | 392 // Support functions for IC stubs for callbacks. |
382 MaybeObject* LoadCallbackProperty(Arguments args); | 393 MaybeObject* LoadCallbackProperty(RUNTIME_CALLING_CONVENTION); |
383 MaybeObject* StoreCallbackProperty(Arguments args); | 394 MaybeObject* StoreCallbackProperty(RUNTIME_CALLING_CONVENTION); |
384 | 395 |
385 | 396 |
386 // Support functions for IC stubs for interceptors. | 397 // Support functions for IC stubs for interceptors. |
387 MaybeObject* LoadPropertyWithInterceptorOnly(Arguments args); | 398 MaybeObject* LoadPropertyWithInterceptorOnly(RUNTIME_CALLING_CONVENTION); |
388 MaybeObject* LoadPropertyWithInterceptorForLoad(Arguments args); | 399 MaybeObject* LoadPropertyWithInterceptorForLoad(RUNTIME_CALLING_CONVENTION); |
389 MaybeObject* LoadPropertyWithInterceptorForCall(Arguments args); | 400 MaybeObject* LoadPropertyWithInterceptorForCall(RUNTIME_CALLING_CONVENTION); |
390 MaybeObject* StoreInterceptorProperty(Arguments args); | 401 MaybeObject* StoreInterceptorProperty(RUNTIME_CALLING_CONVENTION); |
391 MaybeObject* CallInterceptorProperty(Arguments args); | 402 MaybeObject* CallInterceptorProperty(RUNTIME_CALLING_CONVENTION); |
392 MaybeObject* KeyedLoadPropertyWithInterceptor(Arguments args); | 403 MaybeObject* KeyedLoadPropertyWithInterceptor(RUNTIME_CALLING_CONVENTION); |
393 | 404 |
394 | 405 |
395 // The stub compiler compiles stubs for the stub cache. | 406 // The stub compiler compiles stubs for the stub cache. |
396 class StubCompiler BASE_EMBEDDED { | 407 class StubCompiler BASE_EMBEDDED { |
397 public: | 408 public: |
398 StubCompiler() : scope_(), masm_(NULL, 256), failure_(NULL) { } | 409 StubCompiler() : scope_(), masm_(NULL, 256), failure_(NULL) { } |
399 | 410 |
400 MUST_USE_RESULT MaybeObject* CompileCallInitialize(Code::Flags flags); | 411 MUST_USE_RESULT MaybeObject* CompileCallInitialize(Code::Flags flags); |
401 MUST_USE_RESULT MaybeObject* CompileCallPreMonomorphic(Code::Flags flags); | 412 MUST_USE_RESULT MaybeObject* CompileCallPreMonomorphic(Code::Flags flags); |
402 MUST_USE_RESULT MaybeObject* CompileCallNormal(Code::Flags flags); | 413 MUST_USE_RESULT MaybeObject* CompileCallNormal(Code::Flags flags); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 Register scratch1, | 551 Register scratch1, |
541 Register scratch2, | 552 Register scratch2, |
542 Register scratch3, | 553 Register scratch3, |
543 String* name, | 554 String* name, |
544 Label* miss); | 555 Label* miss); |
545 | 556 |
546 static void LookupPostInterceptor(JSObject* holder, | 557 static void LookupPostInterceptor(JSObject* holder, |
547 String* name, | 558 String* name, |
548 LookupResult* lookup); | 559 LookupResult* lookup); |
549 | 560 |
| 561 Isolate* isolate() { return scope_.isolate(); } |
| 562 |
550 private: | 563 private: |
551 HandleScope scope_; | 564 HandleScope scope_; |
552 MacroAssembler masm_; | 565 MacroAssembler masm_; |
553 Failure* failure_; | 566 Failure* failure_; |
554 }; | 567 }; |
555 | 568 |
556 | 569 |
557 class LoadStubCompiler: public StubCompiler { | 570 class LoadStubCompiler: public StubCompiler { |
558 public: | 571 public: |
559 MUST_USE_RESULT MaybeObject* CompileLoadNonexistent(String* name, | 572 MUST_USE_RESULT MaybeObject* CompileLoadNonexistent(String* name, |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 MUST_USE_RESULT MaybeObject* CompileKeyedStoreStub( | 852 MUST_USE_RESULT MaybeObject* CompileKeyedStoreStub( |
840 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags); | 853 JSObject* receiver, ExternalArrayType array_type, Code::Flags flags); |
841 | 854 |
842 private: | 855 private: |
843 MaybeObject* GetCode(Code::Flags flags); | 856 MaybeObject* GetCode(Code::Flags flags); |
844 }; | 857 }; |
845 | 858 |
846 } } // namespace v8::internal | 859 } } // namespace v8::internal |
847 | 860 |
848 #endif // V8_STUB_CACHE_H_ | 861 #endif // V8_STUB_CACHE_H_ |
OLD | NEW |