OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 | 102 |
103 Handle<JSObject> StubCache::StubHolder(Handle<JSObject> receiver, | 103 Handle<JSObject> StubCache::StubHolder(Handle<JSObject> receiver, |
104 Handle<JSObject> holder) { | 104 Handle<JSObject> holder) { |
105 InlineCacheHolderFlag cache_holder = | 105 InlineCacheHolderFlag cache_holder = |
106 IC::GetCodeCacheForObject(*receiver, *holder); | 106 IC::GetCodeCacheForObject(*receiver, *holder); |
107 return Handle<JSObject>(IC::GetCodeCacheHolder( | 107 return Handle<JSObject>(IC::GetCodeCacheHolder( |
108 isolate_, *receiver, cache_holder)); | 108 isolate_, *receiver, cache_holder)); |
109 } | 109 } |
110 | 110 |
111 | 111 |
112 Handle<Code> StubCache::FindStub(Handle<Name> name, | 112 Handle<Code> StubCache::FindIC(Handle<Name> name, |
113 Handle<JSObject> stub_holder, | 113 Handle<JSObject> stub_holder, |
114 Code::Kind kind, | 114 Code::Kind kind, |
115 Code::StubType type, | 115 Code::StubType type) { |
116 Code::IcFragment fragment) { | 116 Code::Flags flags = Code::ComputeMonomorphicFlags( |
117 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, fragment, type); | 117 kind, Code::kNoExtraICState, type); |
118 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), | 118 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), |
119 isolate_); | 119 isolate_); |
120 if (probe->IsCode()) return Handle<Code>::cast(probe); | 120 if (probe->IsCode()) return Handle<Code>::cast(probe); |
121 return Handle<Code>::null(); | 121 return Handle<Code>::null(); |
122 } | 122 } |
123 | 123 |
124 | 124 |
125 Handle<Code> StubCache::FindHandler(Handle<Name> name, | 125 Handle<Code> StubCache::FindStub(Handle<Name> name, |
126 Handle<JSObject> handler_holder, | 126 Handle<JSObject> stub_holder, |
127 Code::Kind kind, | 127 Code::Kind kind, |
128 Code::StubType type) { | 128 Code::StubType type) { |
129 return FindStub(name, handler_holder, kind, type, Code::HANDLER_FRAGMENT); | 129 ASSERT(type != Code::NORMAL); |
| 130 int extra_flags = -1; |
| 131 if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) { |
| 132 extra_flags = kind; |
| 133 kind = Code::STUB; |
| 134 } |
| 135 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 136 kind, Code::kNoExtraICState, type, extra_flags); |
| 137 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), |
| 138 isolate_); |
| 139 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 140 return Handle<Code>::null(); |
130 } | 141 } |
131 | 142 |
132 | 143 |
133 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<JSObject> receiver, | 144 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<JSObject> receiver, |
134 Handle<Code> handler, | 145 Handle<Code> handler, |
135 Handle<Name> name) { | 146 Handle<Name> name) { |
136 Handle<Code> ic = FindStub(name, receiver, Code::LOAD_IC, | 147 Handle<Code> ic = FindIC(name, receiver, Code::LOAD_IC, handler->type()); |
137 handler->type(), Code::IC_FRAGMENT); | |
138 if (!ic.is_null()) return ic; | 148 if (!ic.is_null()) return ic; |
139 | 149 |
140 LoadStubCompiler ic_compiler(isolate()); | 150 LoadStubCompiler ic_compiler(isolate()); |
141 ic = ic_compiler.CompileMonomorphicIC( | 151 ic = ic_compiler.CompileMonomorphicIC( |
142 Handle<Map>(receiver->map()), handler, name); | 152 Handle<Map>(receiver->map()), handler, name); |
143 | 153 |
144 JSObject::UpdateMapCodeCache(receiver, name, ic); | 154 JSObject::UpdateMapCodeCache(receiver, name, ic); |
145 return ic; | 155 return ic; |
146 } | 156 } |
147 | 157 |
148 | 158 |
149 Handle<Code> StubCache::ComputeKeyedMonomorphicIC(Handle<JSObject> receiver, | 159 Handle<Code> StubCache::ComputeKeyedMonomorphicIC(Handle<JSObject> receiver, |
150 Handle<Code> handler, | 160 Handle<Code> handler, |
151 Handle<Name> name) { | 161 Handle<Name> name) { |
152 Handle<Code> ic = FindStub(name, receiver, Code::KEYED_LOAD_IC, | 162 Handle<Code> ic = FindIC( |
153 handler->type(), Code::IC_FRAGMENT); | 163 name, receiver, Code::KEYED_LOAD_IC, handler->type()); |
154 if (!ic.is_null()) return ic; | 164 if (!ic.is_null()) return ic; |
155 | 165 |
156 KeyedLoadStubCompiler ic_compiler(isolate()); | 166 KeyedLoadStubCompiler ic_compiler(isolate()); |
157 ic = ic_compiler.CompileMonomorphicIC( | 167 ic = ic_compiler.CompileMonomorphicIC( |
158 Handle<Map>(receiver->map()), handler, name); | 168 Handle<Map>(receiver->map()), handler, name); |
159 | 169 |
160 JSObject::UpdateMapCodeCache(receiver, name, ic); | 170 JSObject::UpdateMapCodeCache(receiver, name, ic); |
161 return ic; | 171 return ic; |
162 } | 172 } |
163 | 173 |
(...skipping 16 matching lines...) Expand all Loading... |
180 if (current->IsGlobalObject()) { | 190 if (current->IsGlobalObject()) { |
181 global = Handle<GlobalObject>::cast(current); | 191 global = Handle<GlobalObject>::cast(current); |
182 cache_name = name; | 192 cache_name = name; |
183 } else if (!current->HasFastProperties()) { | 193 } else if (!current->HasFastProperties()) { |
184 cache_name = name; | 194 cache_name = name; |
185 } | 195 } |
186 } while (!next->IsNull()); | 196 } while (!next->IsNull()); |
187 | 197 |
188 // Compile the stub that is either shared for all names or | 198 // Compile the stub that is either shared for all names or |
189 // name specific if there are global objects involved. | 199 // name specific if there are global objects involved. |
190 Handle<Code> handler = FindHandler( | 200 Handle<Code> handler = FindStub( |
191 cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT); | 201 cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT); |
192 if (!handler.is_null()) return handler; | 202 if (!handler.is_null()) return handler; |
193 | 203 |
194 LoadStubCompiler compiler(isolate_); | 204 LoadStubCompiler compiler(isolate_); |
195 handler = | 205 handler = |
196 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); | 206 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); |
197 JSObject::UpdateMapCodeCache(receiver, cache_name, handler); | 207 JSObject::UpdateMapCodeCache(receiver, cache_name, handler); |
198 return handler; | 208 return handler; |
199 } | 209 } |
200 | 210 |
201 | 211 |
202 Handle<Code> StubCache::ComputeLoadField(Handle<Name> name, | 212 Handle<Code> StubCache::ComputeLoadField(Handle<Name> name, |
203 Handle<JSObject> receiver, | 213 Handle<JSObject> receiver, |
204 Handle<JSObject> holder, | 214 Handle<JSObject> holder, |
205 PropertyIndex field) { | 215 PropertyIndex field) { |
206 if (receiver.is_identical_to(holder)) { | 216 if (receiver.is_identical_to(holder)) { |
207 LoadFieldStub stub(LoadStubCompiler::receiver(), | 217 LoadFieldStub stub(LoadStubCompiler::receiver(), |
208 field.is_inobject(holder), | 218 field.is_inobject(holder), |
209 field.translate(holder)); | 219 field.translate(holder)); |
210 return stub.GetCode(isolate()); | 220 return stub.GetCode(isolate()); |
211 } | 221 } |
212 | 222 |
213 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 223 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
214 Handle<Code> stub = FindHandler( | 224 Handle<Code> stub = FindStub( |
215 name, stub_holder, Code::LOAD_IC, Code::FIELD); | 225 name, stub_holder, Code::LOAD_IC, Code::FIELD); |
216 if (!stub.is_null()) return stub; | 226 if (!stub.is_null()) return stub; |
217 | 227 |
218 LoadStubCompiler compiler(isolate_); | 228 LoadStubCompiler compiler(isolate_); |
219 Handle<Code> handler = | 229 Handle<Code> handler = |
220 compiler.CompileLoadField(receiver, holder, name, field); | 230 compiler.CompileLoadField(receiver, holder, name, field); |
221 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 231 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
222 return handler; | 232 return handler; |
223 } | 233 } |
224 | 234 |
225 | 235 |
226 Handle<Code> StubCache::ComputeLoadCallback( | 236 Handle<Code> StubCache::ComputeLoadCallback( |
227 Handle<Name> name, | 237 Handle<Name> name, |
228 Handle<JSObject> receiver, | 238 Handle<JSObject> receiver, |
229 Handle<JSObject> holder, | 239 Handle<JSObject> holder, |
230 Handle<ExecutableAccessorInfo> callback) { | 240 Handle<ExecutableAccessorInfo> callback) { |
231 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); | 241 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); |
232 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 242 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
233 Handle<Code> stub = FindHandler( | 243 Handle<Code> stub = FindStub( |
234 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); | 244 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); |
235 if (!stub.is_null()) return stub; | 245 if (!stub.is_null()) return stub; |
236 | 246 |
237 LoadStubCompiler compiler(isolate_); | 247 LoadStubCompiler compiler(isolate_); |
238 Handle<Code> handler = | 248 Handle<Code> handler = |
239 compiler.CompileLoadCallback(receiver, holder, name, callback); | 249 compiler.CompileLoadCallback(receiver, holder, name, callback); |
240 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 250 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
241 return handler; | 251 return handler; |
242 } | 252 } |
243 | 253 |
244 | 254 |
245 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name, | 255 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name, |
246 Handle<JSObject> receiver, | 256 Handle<JSObject> receiver, |
247 Handle<JSObject> holder, | 257 Handle<JSObject> holder, |
248 Handle<JSFunction> getter) { | 258 Handle<JSFunction> getter) { |
249 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 259 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
250 Handle<Code> stub = FindHandler( | 260 Handle<Code> stub = FindStub( |
251 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); | 261 name, stub_holder, Code::LOAD_IC, Code::CALLBACKS); |
252 if (!stub.is_null()) return stub; | 262 if (!stub.is_null()) return stub; |
253 | 263 |
254 LoadStubCompiler compiler(isolate_); | 264 LoadStubCompiler compiler(isolate_); |
255 Handle<Code> handler = | 265 Handle<Code> handler = |
256 compiler.CompileLoadViaGetter(receiver, holder, name, getter); | 266 compiler.CompileLoadViaGetter(receiver, holder, name, getter); |
257 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 267 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
258 return handler; | 268 return handler; |
259 } | 269 } |
260 | 270 |
261 | 271 |
262 Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name, | 272 Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name, |
263 Handle<JSObject> receiver, | 273 Handle<JSObject> receiver, |
264 Handle<JSObject> holder, | 274 Handle<JSObject> holder, |
265 Handle<JSFunction> value) { | 275 Handle<JSFunction> value) { |
266 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 276 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
267 Handle<Code> handler = FindHandler( | 277 Handle<Code> handler = FindStub( |
268 name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION); | 278 name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION); |
269 if (!handler.is_null()) return handler; | 279 if (!handler.is_null()) return handler; |
270 | 280 |
271 LoadStubCompiler compiler(isolate_); | 281 LoadStubCompiler compiler(isolate_); |
272 handler = compiler.CompileLoadConstant(receiver, holder, name, value); | 282 handler = compiler.CompileLoadConstant(receiver, holder, name, value); |
273 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 283 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
274 | 284 |
275 return handler; | 285 return handler; |
276 } | 286 } |
277 | 287 |
278 | 288 |
279 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name, | 289 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name, |
280 Handle<JSObject> receiver, | 290 Handle<JSObject> receiver, |
281 Handle<JSObject> holder) { | 291 Handle<JSObject> holder) { |
282 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 292 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
283 Handle<Code> stub = FindHandler( | 293 Handle<Code> stub = FindStub( |
284 name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR); | 294 name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR); |
285 if (!stub.is_null()) return stub; | 295 if (!stub.is_null()) return stub; |
286 | 296 |
287 LoadStubCompiler compiler(isolate_); | 297 LoadStubCompiler compiler(isolate_); |
288 Handle<Code> handler = | 298 Handle<Code> handler = |
289 compiler.CompileLoadInterceptor(receiver, holder, name); | 299 compiler.CompileLoadInterceptor(receiver, holder, name); |
290 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 300 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
291 return handler; | 301 return handler; |
292 } | 302 } |
293 | 303 |
294 | 304 |
295 Handle<Code> StubCache::ComputeLoadNormal(Handle<Name> name, | 305 Handle<Code> StubCache::ComputeLoadNormal(Handle<Name> name, |
296 Handle<JSObject> receiver) { | 306 Handle<JSObject> receiver) { |
297 return isolate_->builtins()->LoadIC_Normal(); | 307 return isolate_->builtins()->LoadIC_Normal(); |
298 } | 308 } |
299 | 309 |
300 | 310 |
301 Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name, | 311 Handle<Code> StubCache::ComputeLoadGlobal(Handle<Name> name, |
302 Handle<JSObject> receiver, | 312 Handle<JSObject> receiver, |
303 Handle<GlobalObject> holder, | 313 Handle<GlobalObject> holder, |
304 Handle<JSGlobalPropertyCell> cell, | 314 Handle<JSGlobalPropertyCell> cell, |
305 bool is_dont_delete) { | 315 bool is_dont_delete) { |
306 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 316 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
307 Handle<Code> stub = FindStub( | 317 Handle<Code> stub = FindIC(name, stub_holder, Code::LOAD_IC, Code::NORMAL); |
308 name, stub_holder, Code::LOAD_IC, Code::NORMAL, Code::IC_FRAGMENT); | |
309 if (!stub.is_null()) return stub; | 318 if (!stub.is_null()) return stub; |
310 | 319 |
311 LoadStubCompiler compiler(isolate_); | 320 LoadStubCompiler compiler(isolate_); |
312 Handle<Code> ic = | 321 Handle<Code> ic = |
313 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); | 322 compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); |
314 JSObject::UpdateMapCodeCache(stub_holder, name, ic); | 323 JSObject::UpdateMapCodeCache(stub_holder, name, ic); |
315 return ic; | 324 return ic; |
316 } | 325 } |
317 | 326 |
318 | 327 |
319 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name, | 328 Handle<Code> StubCache::ComputeKeyedLoadField(Handle<Name> name, |
320 Handle<JSObject> receiver, | 329 Handle<JSObject> receiver, |
321 Handle<JSObject> holder, | 330 Handle<JSObject> holder, |
322 PropertyIndex field) { | 331 PropertyIndex field) { |
323 if (receiver.is_identical_to(holder)) { | 332 if (receiver.is_identical_to(holder)) { |
324 LoadFieldStub stub(KeyedLoadStubCompiler::receiver(), | 333 LoadFieldStub stub(KeyedLoadStubCompiler::receiver(), |
325 field.is_inobject(holder), | 334 field.is_inobject(holder), |
326 field.translate(holder)); | 335 field.translate(holder)); |
327 return stub.GetCode(isolate()); | 336 return stub.GetCode(isolate()); |
328 } | 337 } |
329 | 338 |
330 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 339 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
331 Handle<Code> stub = FindHandler( | 340 Handle<Code> stub = FindStub( |
332 name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD); | 341 name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD); |
333 if (!stub.is_null()) return stub; | 342 if (!stub.is_null()) return stub; |
334 | 343 |
335 KeyedLoadStubCompiler compiler(isolate_); | 344 KeyedLoadStubCompiler compiler(isolate_); |
336 Handle<Code> handler = | 345 Handle<Code> handler = |
337 compiler.CompileLoadField(receiver, holder, name, field); | 346 compiler.CompileLoadField(receiver, holder, name, field); |
338 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 347 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
339 return handler; | 348 return handler; |
340 } | 349 } |
341 | 350 |
342 | 351 |
343 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name, | 352 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name, |
344 Handle<JSObject> receiver, | 353 Handle<JSObject> receiver, |
345 Handle<JSObject> holder, | 354 Handle<JSObject> holder, |
346 Handle<JSFunction> value) { | 355 Handle<JSFunction> value) { |
347 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 356 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
348 Handle<Code> handler = FindHandler( | 357 Handle<Code> handler = FindStub( |
349 name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION); | 358 name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION); |
350 if (!handler.is_null()) return handler; | 359 if (!handler.is_null()) return handler; |
351 | 360 |
352 KeyedLoadStubCompiler compiler(isolate_); | 361 KeyedLoadStubCompiler compiler(isolate_); |
353 handler = compiler.CompileLoadConstant(receiver, holder, name, value); | 362 handler = compiler.CompileLoadConstant(receiver, holder, name, value); |
354 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 363 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
355 return handler; | 364 return handler; |
356 } | 365 } |
357 | 366 |
358 | 367 |
359 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name, | 368 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name, |
360 Handle<JSObject> receiver, | 369 Handle<JSObject> receiver, |
361 Handle<JSObject> holder) { | 370 Handle<JSObject> holder) { |
362 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 371 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
363 Handle<Code> stub = FindHandler( | 372 Handle<Code> stub = FindStub( |
364 name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR); | 373 name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR); |
365 if (!stub.is_null()) return stub; | 374 if (!stub.is_null()) return stub; |
366 | 375 |
367 KeyedLoadStubCompiler compiler(isolate_); | 376 KeyedLoadStubCompiler compiler(isolate_); |
368 Handle<Code> handler = | 377 Handle<Code> handler = |
369 compiler.CompileLoadInterceptor(receiver, holder, name); | 378 compiler.CompileLoadInterceptor(receiver, holder, name); |
370 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 379 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
371 return handler; | 380 return handler; |
372 } | 381 } |
373 | 382 |
374 | 383 |
375 Handle<Code> StubCache::ComputeKeyedLoadCallback( | 384 Handle<Code> StubCache::ComputeKeyedLoadCallback( |
376 Handle<Name> name, | 385 Handle<Name> name, |
377 Handle<JSObject> receiver, | 386 Handle<JSObject> receiver, |
378 Handle<JSObject> holder, | 387 Handle<JSObject> holder, |
379 Handle<ExecutableAccessorInfo> callback) { | 388 Handle<ExecutableAccessorInfo> callback) { |
380 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 389 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
381 Handle<Code> stub = FindHandler( | 390 Handle<Code> stub = FindStub( |
382 name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS); | 391 name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS); |
383 if (!stub.is_null()) return stub; | 392 if (!stub.is_null()) return stub; |
384 | 393 |
385 KeyedLoadStubCompiler compiler(isolate_); | 394 KeyedLoadStubCompiler compiler(isolate_); |
386 Handle<Code> handler = | 395 Handle<Code> handler = |
387 compiler.CompileLoadCallback(receiver, holder, name, callback); | 396 compiler.CompileLoadCallback(receiver, holder, name, callback); |
388 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 397 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
389 return handler; | 398 return handler; |
390 } | 399 } |
391 | 400 |
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 | 897 |
889 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); | 898 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); |
890 return code; | 899 return code; |
891 } | 900 } |
892 | 901 |
893 | 902 |
894 Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps, | 903 Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps, |
895 CodeHandleList* handlers, | 904 CodeHandleList* handlers, |
896 Handle<Name> name) { | 905 Handle<Name> name) { |
897 LoadStubCompiler ic_compiler(isolate_); | 906 LoadStubCompiler ic_compiler(isolate_); |
| 907 Code::StubType type = handlers->length() == 1 ? handlers->at(0)->type() |
| 908 : Code::NORMAL; |
898 Handle<Code> ic = ic_compiler.CompilePolymorphicIC( | 909 Handle<Code> ic = ic_compiler.CompilePolymorphicIC( |
899 receiver_maps, handlers, name, Code::NORMAL, PROPERTY); | 910 receiver_maps, handlers, name, type, PROPERTY); |
900 return ic; | 911 return ic; |
901 } | 912 } |
902 | 913 |
903 | 914 |
904 Handle<Code> StubCache::ComputeStoreElementPolymorphic( | 915 Handle<Code> StubCache::ComputeStoreElementPolymorphic( |
905 MapHandleList* receiver_maps, | 916 MapHandleList* receiver_maps, |
906 KeyedAccessGrowMode grow_mode, | 917 KeyedAccessGrowMode grow_mode, |
907 StrictModeFlag strict_mode) { | 918 StrictModeFlag strict_mode) { |
908 Handle<PolymorphicCodeCache> cache = | 919 Handle<PolymorphicCodeCache> cache = |
909 isolate_->factory()->polymorphic_code_cache(); | 920 isolate_->factory()->polymorphic_code_cache(); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 } | 985 } |
975 | 986 |
976 | 987 |
977 void StubCache::CollectMatchingMaps(SmallMapList* types, | 988 void StubCache::CollectMatchingMaps(SmallMapList* types, |
978 Name* name, | 989 Name* name, |
979 Code::Flags flags, | 990 Code::Flags flags, |
980 Handle<Context> native_context, | 991 Handle<Context> native_context, |
981 Zone* zone) { | 992 Zone* zone) { |
982 for (int i = 0; i < kPrimaryTableSize; i++) { | 993 for (int i = 0; i < kPrimaryTableSize; i++) { |
983 if (primary_[i].key == name) { | 994 if (primary_[i].key == name) { |
984 Map* map = primary_[i].value->FindFirstMap(); | 995 Map* map = primary_[i].map; |
985 // Map can be NULL, if the stub is constant function call | 996 // Map can be NULL, if the stub is constant function call |
986 // with a primitive receiver. | 997 // with a primitive receiver. |
987 if (map == NULL) continue; | 998 if (map == NULL) continue; |
988 | 999 |
989 int offset = PrimaryOffset(name, flags, map); | 1000 int offset = PrimaryOffset(name, flags, map); |
990 if (entry(primary_, offset) == &primary_[i] && | 1001 if (entry(primary_, offset) == &primary_[i] && |
991 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) { | 1002 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) { |
992 types->Add(Handle<Map>(map), zone); | 1003 types->Add(Handle<Map>(map), zone); |
993 } | 1004 } |
994 } | 1005 } |
995 } | 1006 } |
996 | 1007 |
997 for (int i = 0; i < kSecondaryTableSize; i++) { | 1008 for (int i = 0; i < kSecondaryTableSize; i++) { |
998 if (secondary_[i].key == name) { | 1009 if (secondary_[i].key == name) { |
999 Map* map = secondary_[i].value->FindFirstMap(); | 1010 Map* map = secondary_[i].map; |
1000 // Map can be NULL, if the stub is constant function call | 1011 // Map can be NULL, if the stub is constant function call |
1001 // with a primitive receiver. | 1012 // with a primitive receiver. |
1002 if (map == NULL) continue; | 1013 if (map == NULL) continue; |
1003 | 1014 |
1004 // Lookup in primary table and skip duplicates. | 1015 // Lookup in primary table and skip duplicates. |
1005 int primary_offset = PrimaryOffset(name, flags, map); | 1016 int primary_offset = PrimaryOffset(name, flags, map); |
1006 Entry* primary_entry = entry(primary_, primary_offset); | 1017 Entry* primary_entry = entry(primary_, primary_offset); |
1007 if (primary_entry->key == name) { | 1018 if (primary_entry->key == name) { |
1008 Map* primary_map = primary_entry->value->FindFirstMap(); | 1019 Map* primary_map = primary_entry->map; |
1009 if (map == primary_map) continue; | 1020 if (map == primary_map) continue; |
1010 } | 1021 } |
1011 | 1022 |
1012 // Lookup in secondary table and add matches. | 1023 // Lookup in secondary table and add matches. |
1013 int offset = SecondaryOffset(name, flags, primary_offset); | 1024 int offset = SecondaryOffset(name, flags, primary_offset); |
1014 if (entry(secondary_, offset) == &secondary_[i] && | 1025 if (entry(secondary_, offset) == &secondary_[i] && |
1015 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) { | 1026 !TypeFeedbackOracle::CanRetainOtherContext(map, *native_context)) { |
1016 types->Add(Handle<Map>(map), zone); | 1027 types->Add(Handle<Map>(map), zone); |
1017 } | 1028 } |
1018 } | 1029 } |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1441 | 1452 |
1442 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); | 1453 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); |
1443 | 1454 |
1444 LoadFieldStub stub(reg, field.is_inobject(holder), field.translate(holder)); | 1455 LoadFieldStub stub(reg, field.is_inobject(holder), field.translate(holder)); |
1445 GenerateTailCall(stub.GetCode(isolate())); | 1456 GenerateTailCall(stub.GetCode(isolate())); |
1446 | 1457 |
1447 __ bind(&miss); | 1458 __ bind(&miss); |
1448 GenerateLoadMiss(masm(), kind()); | 1459 GenerateLoadMiss(masm(), kind()); |
1449 | 1460 |
1450 // Return the generated code. | 1461 // Return the generated code. |
1451 return GetCode(Code::HANDLER_FRAGMENT, Code::FIELD, name); | 1462 return GetCode(kind(), Code::FIELD, name); |
1452 } | 1463 } |
1453 | 1464 |
1454 | 1465 |
1455 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant( | 1466 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant( |
1456 Handle<JSObject> object, | 1467 Handle<JSObject> object, |
1457 Handle<JSObject> holder, | 1468 Handle<JSObject> holder, |
1458 Handle<Name> name, | 1469 Handle<Name> name, |
1459 Handle<JSFunction> value) { | 1470 Handle<JSFunction> value) { |
1460 Label success; | 1471 Label success; |
1461 HandlerFrontend(object, receiver(), holder, name, &success); | 1472 HandlerFrontend(object, receiver(), holder, name, &success); |
1462 __ bind(&success); | 1473 __ bind(&success); |
1463 GenerateLoadConstant(value); | 1474 GenerateLoadConstant(value); |
1464 | 1475 |
1465 // Return the generated code. | 1476 // Return the generated code. |
1466 return GetCode(Code::HANDLER_FRAGMENT, Code::CONSTANT_FUNCTION, name); | 1477 return GetCode(kind(), Code::CONSTANT_FUNCTION, name); |
1467 } | 1478 } |
1468 | 1479 |
1469 | 1480 |
1470 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( | 1481 Handle<Code> BaseLoadStubCompiler::CompileLoadCallback( |
1471 Handle<JSObject> object, | 1482 Handle<JSObject> object, |
1472 Handle<JSObject> holder, | 1483 Handle<JSObject> holder, |
1473 Handle<Name> name, | 1484 Handle<Name> name, |
1474 Handle<ExecutableAccessorInfo> callback) { | 1485 Handle<ExecutableAccessorInfo> callback) { |
1475 Label success; | 1486 Label success; |
1476 | 1487 |
1477 Register reg = CallbackHandlerFrontend( | 1488 Register reg = CallbackHandlerFrontend( |
1478 object, receiver(), holder, name, &success, callback); | 1489 object, receiver(), holder, name, &success, callback); |
1479 __ bind(&success); | 1490 __ bind(&success); |
1480 GenerateLoadCallback(reg, callback); | 1491 GenerateLoadCallback(reg, callback); |
1481 | 1492 |
1482 // Return the generated code. | 1493 // Return the generated code. |
1483 return GetCode(Code::HANDLER_FRAGMENT, Code::CALLBACKS, name); | 1494 return GetCode(kind(), Code::CALLBACKS, name); |
1484 } | 1495 } |
1485 | 1496 |
1486 | 1497 |
1487 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor( | 1498 Handle<Code> BaseLoadStubCompiler::CompileLoadInterceptor( |
1488 Handle<JSObject> object, | 1499 Handle<JSObject> object, |
1489 Handle<JSObject> holder, | 1500 Handle<JSObject> holder, |
1490 Handle<Name> name) { | 1501 Handle<Name> name) { |
1491 Label success; | 1502 Label success; |
1492 | 1503 |
1493 LookupResult lookup(isolate()); | 1504 LookupResult lookup(isolate()); |
1494 LookupPostInterceptor(holder, name, &lookup); | 1505 LookupPostInterceptor(holder, name, &lookup); |
1495 | 1506 |
1496 Register reg = HandlerFrontend(object, receiver(), holder, name, &success); | 1507 Register reg = HandlerFrontend(object, receiver(), holder, name, &success); |
1497 __ bind(&success); | 1508 __ bind(&success); |
1498 // TODO(368): Compile in the whole chain: all the interceptors in | 1509 // TODO(368): Compile in the whole chain: all the interceptors in |
1499 // prototypes and ultimate answer. | 1510 // prototypes and ultimate answer. |
1500 GenerateLoadInterceptor(reg, object, holder, &lookup, name); | 1511 GenerateLoadInterceptor(reg, object, holder, &lookup, name); |
1501 | 1512 |
1502 // Return the generated code. | 1513 // Return the generated code. |
1503 return GetCode(Code::HANDLER_FRAGMENT, Code::INTERCEPTOR, name); | 1514 return GetCode(kind(), Code::INTERCEPTOR, name); |
1504 } | 1515 } |
1505 | 1516 |
1506 | 1517 |
1507 void BaseLoadStubCompiler::GenerateLoadPostInterceptor( | 1518 void BaseLoadStubCompiler::GenerateLoadPostInterceptor( |
1508 Register interceptor_reg, | 1519 Register interceptor_reg, |
1509 Handle<JSObject> interceptor_holder, | 1520 Handle<JSObject> interceptor_holder, |
1510 Handle<Name> name, | 1521 Handle<Name> name, |
1511 LookupResult* lookup) { | 1522 LookupResult* lookup) { |
1512 Label success; | 1523 Label success; |
1513 Handle<JSObject> holder(lookup->holder()); | 1524 Handle<JSObject> holder(lookup->holder()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1560 Handle<JSObject> holder, | 1571 Handle<JSObject> holder, |
1561 Handle<Name> name, | 1572 Handle<Name> name, |
1562 Handle<JSFunction> getter) { | 1573 Handle<JSFunction> getter) { |
1563 Label success; | 1574 Label success; |
1564 HandlerFrontend(object, receiver(), holder, name, &success); | 1575 HandlerFrontend(object, receiver(), holder, name, &success); |
1565 | 1576 |
1566 __ bind(&success); | 1577 __ bind(&success); |
1567 GenerateLoadViaGetter(masm(), getter); | 1578 GenerateLoadViaGetter(masm(), getter); |
1568 | 1579 |
1569 // Return the generated code. | 1580 // Return the generated code. |
1570 return GetCode(Code::HANDLER_FRAGMENT, Code::CALLBACKS, name); | 1581 return GetCode(kind(), Code::CALLBACKS, name); |
1571 } | 1582 } |
1572 | 1583 |
1573 | 1584 |
1574 #undef __ | 1585 #undef __ |
1575 | 1586 |
1576 | 1587 |
1577 void LoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { | 1588 void LoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { |
1578 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); | 1589 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); |
1579 } | 1590 } |
1580 | 1591 |
1581 | 1592 |
1582 void KeyedLoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { | 1593 void KeyedLoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { |
1583 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); | 1594 GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); |
1584 } | 1595 } |
1585 | 1596 |
1586 | 1597 |
1587 Handle<Code> BaseLoadStubCompiler::GetCode(Code::IcFragment fragment, | 1598 Handle<Code> BaseLoadStubCompiler::GetICCode(Code::Kind kind, |
1588 Code::StubType type, | 1599 Code::StubType type, |
1589 Handle<Name> name, | 1600 Handle<Name> name, |
1590 InlineCacheState state) { | 1601 InlineCacheState state) { |
1591 Code::Flags flags = Code::ComputeFlags(kind(), state, fragment, type); | 1602 Code::Flags flags = Code::ComputeFlags( |
| 1603 kind, state, Code::kNoExtraICState, type); |
1592 Handle<Code> code = GetCodeWithFlags(flags, name); | 1604 Handle<Code> code = GetCodeWithFlags(flags, name); |
1593 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); | 1605 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); |
1594 JitEvent(name, code); | 1606 JitEvent(name, code); |
| 1607 return code; |
| 1608 } |
| 1609 |
| 1610 |
| 1611 Handle<Code> BaseLoadStubCompiler::GetCode(Code::Kind kind, |
| 1612 Code::StubType type, |
| 1613 Handle<Name> name) { |
| 1614 ASSERT(type != Code::NORMAL); |
| 1615 Code::Flags flags = Code::ComputeFlags( |
| 1616 Code::STUB, MONOMORPHIC, Code::kNoExtraICState, type, kind); |
| 1617 Handle<Code> code = GetCodeWithFlags(flags, name); |
| 1618 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); |
| 1619 JitEvent(name, code); |
1595 return code; | 1620 return code; |
1596 } | 1621 } |
1597 | 1622 |
1598 | 1623 |
1599 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps, | 1624 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps, |
1600 CodeHandleList* handlers) { | 1625 CodeHandleList* handlers) { |
1601 for (int i = 0; i < receiver_maps->length(); ++i) { | 1626 for (int i = 0; i < receiver_maps->length(); ++i) { |
1602 Handle<Map> receiver_map = receiver_maps->at(i); | 1627 Handle<Map> receiver_map = receiver_maps->at(i); |
1603 Handle<Code> cached_stub; | 1628 Handle<Code> cached_stub; |
1604 | 1629 |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1853 Handle<FunctionTemplateInfo>( | 1878 Handle<FunctionTemplateInfo>( |
1854 FunctionTemplateInfo::cast(signature->receiver())); | 1879 FunctionTemplateInfo::cast(signature->receiver())); |
1855 } | 1880 } |
1856 } | 1881 } |
1857 | 1882 |
1858 is_simple_api_call_ = true; | 1883 is_simple_api_call_ = true; |
1859 } | 1884 } |
1860 | 1885 |
1861 | 1886 |
1862 } } // namespace v8::internal | 1887 } } // namespace v8::internal |
OLD | NEW |