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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 Handle<Code> StubCache::FindIC(Handle<Name> name, | 126 Handle<Code> StubCache::FindIC(Handle<Name> name, |
127 Handle<JSObject> stub_holder, | 127 Handle<JSObject> stub_holder, |
128 Code::Kind kind, | 128 Code::Kind kind, |
129 Code::StubType type, | 129 Code::StubType type, |
130 Code::ExtraICState extra_ic_state) { | 130 Code::ExtraICState extra_ic_state) { |
131 return FindIC(name, Handle<Map>(stub_holder->map()), kind, | 131 return FindIC(name, Handle<Map>(stub_holder->map()), kind, |
132 type, extra_ic_state); | 132 type, extra_ic_state); |
133 } | 133 } |
134 | 134 |
135 | 135 |
136 Handle<Code> StubCache::FindHandler(Handle<Name> name, | 136 Handle<Code> StubCache::FindLoadHandler(Handle<Name> name, |
137 Handle<JSObject> receiver, | 137 Handle<JSObject> receiver, |
138 Handle<JSObject> stub_holder, | 138 Handle<JSObject> stub_holder, |
139 Code::Kind kind, | 139 Code::Kind kind, |
140 Code::StubType type) { | 140 Code::StubType type) { |
141 Code::ExtraICState extra_ic_state = Code::ComputeExtraICState( | 141 Code::ExtraICState extra_ic_state = Code::ComputeExtraICState( |
142 receiver.is_identical_to(stub_holder) ? Code::OWN_STUB | 142 receiver.is_identical_to(stub_holder) ? Code::OWN_STUB |
143 : Code::PROTOTYPE_STUB); | 143 : Code::PROTOTYPE_STUB); |
144 ASSERT(type != Code::NORMAL); | 144 ASSERT(type != Code::NORMAL); |
145 Code::Flags flags = Code::ComputeMonomorphicFlags( | 145 Code::Flags flags = Code::ComputeMonomorphicFlags( |
146 Code::STUB, extra_ic_state, type, kind); | 146 Code::STUB, extra_ic_state, type, kind); |
147 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), | 147 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), |
148 isolate_); | 148 isolate_); |
149 if (probe->IsCode()) return Handle<Code>::cast(probe); | 149 if (probe->IsCode()) return Handle<Code>::cast(probe); |
150 return Handle<Code>::null(); | 150 return Handle<Code>::null(); |
151 } | 151 } |
152 | 152 |
153 | 153 |
154 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<JSObject> receiver, | 154 Handle<Code> StubCache::FindStoreHandler(Handle<Name> name, |
155 Handle<Code> handler, | 155 Handle<JSObject> receiver, |
156 Handle<Name> name) { | 156 Code::Kind kind, |
| 157 Code::StubType type, |
| 158 StrictModeFlag strict_mode) { |
| 159 Code::ExtraICState extra_ic_state = Code::ComputeExtraICState( |
| 160 STANDARD_STORE, strict_mode); |
| 161 ASSERT(type != Code::NORMAL); |
| 162 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 163 Code::STUB, extra_ic_state, type, kind); |
| 164 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), |
| 165 isolate_); |
| 166 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 167 return Handle<Code>::null(); |
| 168 } |
| 169 |
| 170 |
| 171 Handle<Code> StubCache::ComputeMonomorphicLoadIC(Handle<JSObject> receiver, |
| 172 Handle<Code> handler, |
| 173 Handle<Name> name) { |
157 Handle<Code> ic = FindIC(name, receiver, Code::LOAD_IC, handler->type()); | 174 Handle<Code> ic = FindIC(name, receiver, Code::LOAD_IC, handler->type()); |
158 if (!ic.is_null()) return ic; | 175 if (!ic.is_null()) return ic; |
159 | 176 |
160 LoadStubCompiler ic_compiler(isolate()); | 177 LoadStubCompiler ic_compiler(isolate()); |
161 ic = ic_compiler.CompileMonomorphicIC( | 178 ic = ic_compiler.CompileMonomorphicIC( |
162 Handle<Map>(receiver->map()), handler, name); | 179 Handle<Map>(receiver->map()), handler, name); |
163 | 180 |
164 JSObject::UpdateMapCodeCache(receiver, name, ic); | 181 JSObject::UpdateMapCodeCache(receiver, name, ic); |
165 return ic; | 182 return ic; |
166 } | 183 } |
167 | 184 |
168 | 185 |
169 Handle<Code> StubCache::ComputeKeyedMonomorphicIC(Handle<JSObject> receiver, | 186 Handle<Code> StubCache::ComputeMonomorphicKeyedLoadIC(Handle<JSObject> receiver, |
170 Handle<Code> handler, | 187 Handle<Code> handler, |
171 Handle<Name> name) { | 188 Handle<Name> name) { |
172 Handle<Code> ic = FindIC( | 189 Handle<Code> ic = FindIC( |
173 name, receiver, Code::KEYED_LOAD_IC, handler->type()); | 190 name, receiver, Code::KEYED_LOAD_IC, handler->type()); |
174 if (!ic.is_null()) return ic; | 191 if (!ic.is_null()) return ic; |
175 | 192 |
176 KeyedLoadStubCompiler ic_compiler(isolate()); | 193 KeyedLoadStubCompiler ic_compiler(isolate()); |
177 ic = ic_compiler.CompileMonomorphicIC( | 194 ic = ic_compiler.CompileMonomorphicIC( |
178 Handle<Map>(receiver->map()), handler, name); | 195 Handle<Map>(receiver->map()), handler, name); |
179 | 196 |
180 JSObject::UpdateMapCodeCache(receiver, name, ic); | 197 JSObject::UpdateMapCodeCache(receiver, name, ic); |
181 return ic; | 198 return ic; |
182 } | 199 } |
183 | 200 |
184 | 201 |
| 202 Handle<Code> StubCache::ComputeMonomorphicStoreIC(Handle<JSObject> receiver, |
| 203 Handle<Code> handler, |
| 204 Handle<Name> name, |
| 205 StrictModeFlag strict_mode) { |
| 206 Handle<Code> ic = FindIC( |
| 207 name, receiver, Code::STORE_IC, handler->type(), strict_mode); |
| 208 if (!ic.is_null()) return ic; |
| 209 |
| 210 StoreStubCompiler ic_compiler(isolate(), strict_mode); |
| 211 ic = ic_compiler.CompileMonomorphicIC( |
| 212 Handle<Map>(receiver->map()), handler, name); |
| 213 |
| 214 JSObject::UpdateMapCodeCache(receiver, name, ic); |
| 215 return ic; |
| 216 } |
| 217 |
| 218 |
| 219 Handle<Code> StubCache::ComputeMonomorphicKeyedStoreIC( |
| 220 Handle<JSObject> receiver, |
| 221 Handle<Code> handler, |
| 222 Handle<Name> name, |
| 223 StrictModeFlag strict_mode) { |
| 224 Handle<Code> ic = FindIC( |
| 225 name, receiver, Code::KEYED_STORE_IC, handler->type(), strict_mode); |
| 226 if (!ic.is_null()) return ic; |
| 227 |
| 228 KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE); |
| 229 ic = ic_compiler.CompileMonomorphicIC( |
| 230 Handle<Map>(receiver->map()), handler, name); |
| 231 |
| 232 JSObject::UpdateMapCodeCache(receiver, name, ic); |
| 233 return ic; |
| 234 } |
| 235 |
| 236 |
185 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, | 237 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, |
186 Handle<JSObject> receiver) { | 238 Handle<JSObject> receiver) { |
187 // If no global objects are present in the prototype chain, the load | 239 // If no global objects are present in the prototype chain, the load |
188 // nonexistent IC stub can be shared for all names for a given map | 240 // nonexistent IC stub can be shared for all names for a given map |
189 // and we use the empty string for the map cache in that case. If | 241 // and we use the empty string for the map cache in that case. If |
190 // there are global objects involved, we need to check global | 242 // there are global objects involved, we need to check global |
191 // property cells in the stub and therefore the stub will be | 243 // property cells in the stub and therefore the stub will be |
192 // specific to the name. | 244 // specific to the name. |
193 Handle<Name> cache_name = factory()->empty_string(); | 245 Handle<Name> cache_name = factory()->empty_string(); |
194 Handle<JSObject> current; | 246 Handle<JSObject> current; |
195 Handle<Object> next = receiver; | 247 Handle<Object> next = receiver; |
196 Handle<GlobalObject> global; | 248 Handle<GlobalObject> global; |
197 do { | 249 do { |
198 current = Handle<JSObject>::cast(next); | 250 current = Handle<JSObject>::cast(next); |
199 next = Handle<Object>(current->GetPrototype(), isolate_); | 251 next = Handle<Object>(current->GetPrototype(), isolate_); |
200 if (current->IsGlobalObject()) { | 252 if (current->IsGlobalObject()) { |
201 global = Handle<GlobalObject>::cast(current); | 253 global = Handle<GlobalObject>::cast(current); |
202 cache_name = name; | 254 cache_name = name; |
203 } else if (!current->HasFastProperties()) { | 255 } else if (!current->HasFastProperties()) { |
204 cache_name = name; | 256 cache_name = name; |
205 } | 257 } |
206 } while (!next->IsNull()); | 258 } while (!next->IsNull()); |
207 | 259 |
208 // Compile the stub that is either shared for all names or | 260 // Compile the stub that is either shared for all names or |
209 // name specific if there are global objects involved. | 261 // name specific if there are global objects involved. |
210 Handle<Code> handler = FindHandler( | 262 Handle<Code> handler = FindLoadHandler( |
211 cache_name, receiver, receiver, Code::LOAD_IC, Code::NONEXISTENT); | 263 cache_name, receiver, receiver, Code::LOAD_IC, Code::NONEXISTENT); |
212 if (!handler.is_null()) return handler; | 264 if (!handler.is_null()) return handler; |
213 | 265 |
214 LoadStubCompiler compiler(isolate_); | 266 LoadStubCompiler compiler(isolate_); |
215 handler = | 267 handler = |
216 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); | 268 compiler.CompileLoadNonexistent(receiver, current, cache_name, global); |
217 JSObject::UpdateMapCodeCache(receiver, cache_name, handler); | 269 JSObject::UpdateMapCodeCache(receiver, cache_name, handler); |
218 return handler; | 270 return handler; |
219 } | 271 } |
220 | 272 |
221 | 273 |
222 Handle<Code> StubCache::ComputeLoadField(Handle<Name> name, | 274 Handle<Code> StubCache::ComputeLoadField(Handle<Name> name, |
223 Handle<JSObject> receiver, | 275 Handle<JSObject> receiver, |
224 Handle<JSObject> holder, | 276 Handle<JSObject> holder, |
225 PropertyIndex field, | 277 PropertyIndex field, |
226 Representation representation) { | 278 Representation representation) { |
227 if (receiver.is_identical_to(holder)) { | 279 if (receiver.is_identical_to(holder)) { |
228 LoadFieldStub stub(field.is_inobject(holder), | 280 LoadFieldStub stub(field.is_inobject(holder), |
229 field.translate(holder), | 281 field.translate(holder), |
230 representation); | 282 representation); |
231 return stub.GetCode(isolate()); | 283 return stub.GetCode(isolate()); |
232 } | 284 } |
233 | 285 |
234 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 286 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
235 Handle<Code> stub = FindHandler( | 287 Handle<Code> stub = FindLoadHandler( |
236 name, receiver, stub_holder, Code::LOAD_IC, Code::FIELD); | 288 name, receiver, stub_holder, Code::LOAD_IC, Code::FIELD); |
237 if (!stub.is_null()) return stub; | 289 if (!stub.is_null()) return stub; |
238 | 290 |
239 LoadStubCompiler compiler(isolate_); | 291 LoadStubCompiler compiler(isolate_); |
240 Handle<Code> handler = | 292 Handle<Code> handler = |
241 compiler.CompileLoadField(receiver, holder, name, field, representation); | 293 compiler.CompileLoadField(receiver, holder, name, field, representation); |
242 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 294 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
243 return handler; | 295 return handler; |
244 } | 296 } |
245 | 297 |
246 | 298 |
247 Handle<Code> StubCache::ComputeLoadCallback( | 299 Handle<Code> StubCache::ComputeLoadCallback( |
248 Handle<Name> name, | 300 Handle<Name> name, |
249 Handle<JSObject> receiver, | 301 Handle<JSObject> receiver, |
250 Handle<JSObject> holder, | 302 Handle<JSObject> holder, |
251 Handle<ExecutableAccessorInfo> callback) { | 303 Handle<ExecutableAccessorInfo> callback) { |
252 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); | 304 ASSERT(v8::ToCData<Address>(callback->getter()) != 0); |
253 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 305 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
254 Handle<Code> stub = FindHandler( | 306 Handle<Code> stub = FindLoadHandler( |
255 name, receiver, stub_holder, Code::LOAD_IC, Code::CALLBACKS); | 307 name, receiver, stub_holder, Code::LOAD_IC, Code::CALLBACKS); |
256 if (!stub.is_null()) return stub; | 308 if (!stub.is_null()) return stub; |
257 | 309 |
258 LoadStubCompiler compiler(isolate_); | 310 LoadStubCompiler compiler(isolate_); |
259 Handle<Code> handler = | 311 Handle<Code> handler = |
260 compiler.CompileLoadCallback(receiver, holder, name, callback); | 312 compiler.CompileLoadCallback(receiver, holder, name, callback); |
261 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 313 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
262 return handler; | 314 return handler; |
263 } | 315 } |
264 | 316 |
265 | 317 |
266 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name, | 318 Handle<Code> StubCache::ComputeLoadViaGetter(Handle<Name> name, |
267 Handle<JSObject> receiver, | 319 Handle<JSObject> receiver, |
268 Handle<JSObject> holder, | 320 Handle<JSObject> holder, |
269 Handle<JSFunction> getter) { | 321 Handle<JSFunction> getter) { |
270 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 322 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
271 Handle<Code> stub = FindHandler( | 323 Handle<Code> stub = FindLoadHandler( |
272 name, receiver, stub_holder, Code::LOAD_IC, Code::CALLBACKS); | 324 name, receiver, stub_holder, Code::LOAD_IC, Code::CALLBACKS); |
273 if (!stub.is_null()) return stub; | 325 if (!stub.is_null()) return stub; |
274 | 326 |
275 LoadStubCompiler compiler(isolate_); | 327 LoadStubCompiler compiler(isolate_); |
276 Handle<Code> handler = | 328 Handle<Code> handler = |
277 compiler.CompileLoadViaGetter(receiver, holder, name, getter); | 329 compiler.CompileLoadViaGetter(receiver, holder, name, getter); |
278 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 330 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
279 return handler; | 331 return handler; |
280 } | 332 } |
281 | 333 |
282 | 334 |
283 Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name, | 335 Handle<Code> StubCache::ComputeLoadConstant(Handle<Name> name, |
284 Handle<JSObject> receiver, | 336 Handle<JSObject> receiver, |
285 Handle<JSObject> holder, | 337 Handle<JSObject> holder, |
286 Handle<JSFunction> value) { | 338 Handle<JSFunction> value) { |
287 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 339 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
288 Handle<Code> handler = FindHandler( | 340 Handle<Code> handler = FindLoadHandler( |
289 name, receiver, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION); | 341 name, receiver, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION); |
290 if (!handler.is_null()) return handler; | 342 if (!handler.is_null()) return handler; |
291 | 343 |
292 LoadStubCompiler compiler(isolate_); | 344 LoadStubCompiler compiler(isolate_); |
293 handler = compiler.CompileLoadConstant(receiver, holder, name, value); | 345 handler = compiler.CompileLoadConstant(receiver, holder, name, value); |
294 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 346 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
295 | 347 |
296 return handler; | 348 return handler; |
297 } | 349 } |
298 | 350 |
299 | 351 |
300 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name, | 352 Handle<Code> StubCache::ComputeLoadInterceptor(Handle<Name> name, |
301 Handle<JSObject> receiver, | 353 Handle<JSObject> receiver, |
302 Handle<JSObject> holder) { | 354 Handle<JSObject> holder) { |
303 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 355 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
304 Handle<Code> stub = FindHandler( | 356 Handle<Code> stub = FindLoadHandler( |
305 name, receiver, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR); | 357 name, receiver, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR); |
306 if (!stub.is_null()) return stub; | 358 if (!stub.is_null()) return stub; |
307 | 359 |
308 LoadStubCompiler compiler(isolate_); | 360 LoadStubCompiler compiler(isolate_); |
309 Handle<Code> handler = | 361 Handle<Code> handler = |
310 compiler.CompileLoadInterceptor(receiver, holder, name); | 362 compiler.CompileLoadInterceptor(receiver, holder, name); |
311 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 363 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
312 return handler; | 364 return handler; |
313 } | 365 } |
314 | 366 |
(...skipping 28 matching lines...) Expand all Loading... |
343 Representation representation) { | 395 Representation representation) { |
344 if (receiver.is_identical_to(holder)) { | 396 if (receiver.is_identical_to(holder)) { |
345 // TODO(titzer): this should use an HObjectAccess | 397 // TODO(titzer): this should use an HObjectAccess |
346 KeyedLoadFieldStub stub(field.is_inobject(holder), | 398 KeyedLoadFieldStub stub(field.is_inobject(holder), |
347 field.translate(holder), | 399 field.translate(holder), |
348 representation); | 400 representation); |
349 return stub.GetCode(isolate()); | 401 return stub.GetCode(isolate()); |
350 } | 402 } |
351 | 403 |
352 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 404 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
353 Handle<Code> stub = FindHandler( | 405 Handle<Code> stub = FindLoadHandler( |
354 name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD); | 406 name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD); |
355 if (!stub.is_null()) return stub; | 407 if (!stub.is_null()) return stub; |
356 | 408 |
357 KeyedLoadStubCompiler compiler(isolate_); | 409 KeyedLoadStubCompiler compiler(isolate_); |
358 Handle<Code> handler = | 410 Handle<Code> handler = |
359 compiler.CompileLoadField(receiver, holder, name, field, representation); | 411 compiler.CompileLoadField(receiver, holder, name, field, representation); |
360 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 412 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
361 return handler; | 413 return handler; |
362 } | 414 } |
363 | 415 |
364 | 416 |
365 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name, | 417 Handle<Code> StubCache::ComputeKeyedLoadConstant(Handle<Name> name, |
366 Handle<JSObject> receiver, | 418 Handle<JSObject> receiver, |
367 Handle<JSObject> holder, | 419 Handle<JSObject> holder, |
368 Handle<JSFunction> value) { | 420 Handle<JSFunction> value) { |
369 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 421 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
370 Handle<Code> handler = FindHandler( | 422 Handle<Code> handler = FindLoadHandler( |
371 name, receiver, stub_holder, Code::KEYED_LOAD_IC, | 423 name, receiver, stub_holder, Code::KEYED_LOAD_IC, |
372 Code::CONSTANT_FUNCTION); | 424 Code::CONSTANT_FUNCTION); |
373 if (!handler.is_null()) return handler; | 425 if (!handler.is_null()) return handler; |
374 | 426 |
375 KeyedLoadStubCompiler compiler(isolate_); | 427 KeyedLoadStubCompiler compiler(isolate_); |
376 handler = compiler.CompileLoadConstant(receiver, holder, name, value); | 428 handler = compiler.CompileLoadConstant(receiver, holder, name, value); |
377 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 429 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
378 return handler; | 430 return handler; |
379 } | 431 } |
380 | 432 |
381 | 433 |
382 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name, | 434 Handle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<Name> name, |
383 Handle<JSObject> receiver, | 435 Handle<JSObject> receiver, |
384 Handle<JSObject> holder) { | 436 Handle<JSObject> holder) { |
385 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 437 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
386 Handle<Code> stub = FindHandler( | 438 Handle<Code> stub = FindLoadHandler( |
387 name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR); | 439 name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR); |
388 if (!stub.is_null()) return stub; | 440 if (!stub.is_null()) return stub; |
389 | 441 |
390 KeyedLoadStubCompiler compiler(isolate_); | 442 KeyedLoadStubCompiler compiler(isolate_); |
391 Handle<Code> handler = | 443 Handle<Code> handler = |
392 compiler.CompileLoadInterceptor(receiver, holder, name); | 444 compiler.CompileLoadInterceptor(receiver, holder, name); |
393 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 445 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
394 return handler; | 446 return handler; |
395 } | 447 } |
396 | 448 |
397 | 449 |
398 Handle<Code> StubCache::ComputeKeyedLoadCallback( | 450 Handle<Code> StubCache::ComputeKeyedLoadCallback( |
399 Handle<Name> name, | 451 Handle<Name> name, |
400 Handle<JSObject> receiver, | 452 Handle<JSObject> receiver, |
401 Handle<JSObject> holder, | 453 Handle<JSObject> holder, |
402 Handle<ExecutableAccessorInfo> callback) { | 454 Handle<ExecutableAccessorInfo> callback) { |
403 Handle<JSObject> stub_holder = StubHolder(receiver, holder); | 455 Handle<JSObject> stub_holder = StubHolder(receiver, holder); |
404 Handle<Code> stub = FindHandler( | 456 Handle<Code> stub = FindLoadHandler( |
405 name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS); | 457 name, receiver, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS); |
406 if (!stub.is_null()) return stub; | 458 if (!stub.is_null()) return stub; |
407 | 459 |
408 KeyedLoadStubCompiler compiler(isolate_); | 460 KeyedLoadStubCompiler compiler(isolate_); |
409 Handle<Code> handler = | 461 Handle<Code> handler = |
410 compiler.CompileLoadCallback(receiver, holder, name, callback); | 462 compiler.CompileLoadCallback(receiver, holder, name, callback); |
411 JSObject::UpdateMapCodeCache(stub_holder, name, handler); | 463 JSObject::UpdateMapCodeCache(stub_holder, name, handler); |
412 return handler; | 464 return handler; |
413 } | 465 } |
414 | 466 |
415 | 467 |
416 Handle<Code> StubCache::ComputeStoreField(Handle<Name> name, | 468 Handle<Code> StubCache::ComputeStoreField(Handle<Name> name, |
417 Handle<JSObject> receiver, | 469 Handle<JSObject> receiver, |
418 LookupResult* lookup, | 470 LookupResult* lookup, |
419 StrictModeFlag strict_mode) { | 471 StrictModeFlag strict_mode) { |
420 Handle<Code> stub = FindIC( | 472 Handle<Code> stub = FindStoreHandler( |
421 name, receiver, Code::STORE_IC, Code::FIELD, strict_mode); | 473 name, receiver, Code::STORE_IC, Code::FIELD, strict_mode); |
422 if (!stub.is_null()) return stub; | 474 if (!stub.is_null()) return stub; |
423 | 475 |
424 StoreStubCompiler compiler(isolate_, strict_mode); | 476 StoreStubCompiler compiler(isolate_, strict_mode); |
425 Handle<Code> code = compiler.CompileStoreField(receiver, lookup, name); | 477 Handle<Code> handler = compiler.CompileStoreField(receiver, lookup, name); |
426 JSObject::UpdateMapCodeCache(receiver, name, code); | 478 JSObject::UpdateMapCodeCache(receiver, name, handler); |
427 return code; | 479 return handler; |
428 } | 480 } |
429 | 481 |
430 | 482 |
431 Handle<Code> StubCache::ComputeStoreTransition(Handle<Name> name, | 483 Handle<Code> StubCache::ComputeStoreTransition(Handle<Name> name, |
432 Handle<JSObject> receiver, | 484 Handle<JSObject> receiver, |
433 LookupResult* lookup, | 485 LookupResult* lookup, |
434 Handle<Map> transition, | 486 Handle<Map> transition, |
435 StrictModeFlag strict_mode) { | 487 StrictModeFlag strict_mode) { |
436 Handle<Code> stub = FindIC( | 488 Handle<Code> stub = FindStoreHandler( |
437 name, receiver, Code::STORE_IC, Code::MAP_TRANSITION, strict_mode); | 489 name, receiver, Code::STORE_IC, Code::MAP_TRANSITION, strict_mode); |
438 if (!stub.is_null()) return stub; | 490 if (!stub.is_null()) return stub; |
439 | 491 |
440 StoreStubCompiler compiler(isolate_, strict_mode); | 492 StoreStubCompiler compiler(isolate_, strict_mode); |
441 Handle<Code> code = | 493 Handle<Code> handler = |
442 compiler.CompileStoreTransition(receiver, lookup, transition, name); | 494 compiler.CompileStoreTransition(receiver, lookup, transition, name); |
443 JSObject::UpdateMapCodeCache(receiver, name, code); | 495 JSObject::UpdateMapCodeCache(receiver, name, handler); |
444 return code; | 496 return handler; |
445 } | 497 } |
446 | 498 |
447 | 499 |
448 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { | 500 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { |
449 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); | 501 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); |
450 Handle<Name> name = | 502 Handle<Name> name = |
451 isolate()->factory()->KeyedLoadElementMonomorphic_string(); | 503 isolate()->factory()->KeyedLoadElementMonomorphic_string(); |
452 | 504 |
453 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); | 505 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); |
454 if (probe->IsCode()) return Handle<Code>::cast(probe); | 506 if (probe->IsCode()) return Handle<Code>::cast(probe); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 } | 579 } |
528 | 580 |
529 | 581 |
530 Handle<Code> StubCache::ComputeStoreCallback( | 582 Handle<Code> StubCache::ComputeStoreCallback( |
531 Handle<Name> name, | 583 Handle<Name> name, |
532 Handle<JSObject> receiver, | 584 Handle<JSObject> receiver, |
533 Handle<JSObject> holder, | 585 Handle<JSObject> holder, |
534 Handle<ExecutableAccessorInfo> callback, | 586 Handle<ExecutableAccessorInfo> callback, |
535 StrictModeFlag strict_mode) { | 587 StrictModeFlag strict_mode) { |
536 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); | 588 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); |
537 Handle<Code> stub = FindIC( | 589 Handle<Code> stub = FindStoreHandler( |
538 name, receiver, Code::STORE_IC, Code::CALLBACKS, strict_mode); | 590 name, receiver, Code::STORE_IC, Code::CALLBACKS, strict_mode); |
539 if (!stub.is_null()) return stub; | 591 if (!stub.is_null()) return stub; |
540 | 592 |
541 StoreStubCompiler compiler(isolate_, strict_mode); | 593 StoreStubCompiler compiler(isolate_, strict_mode); |
542 Handle<Code> code = | 594 Handle<Code> handler = compiler.CompileStoreCallback( |
543 compiler.CompileStoreCallback(name, receiver, holder, callback); | 595 receiver, holder, name, callback); |
544 JSObject::UpdateMapCodeCache(receiver, name, code); | 596 JSObject::UpdateMapCodeCache(receiver, name, handler); |
545 return code; | 597 return handler; |
546 } | 598 } |
547 | 599 |
548 | 600 |
549 Handle<Code> StubCache::ComputeStoreViaSetter(Handle<Name> name, | 601 Handle<Code> StubCache::ComputeStoreViaSetter(Handle<Name> name, |
550 Handle<JSObject> receiver, | 602 Handle<JSObject> receiver, |
551 Handle<JSObject> holder, | 603 Handle<JSObject> holder, |
552 Handle<JSFunction> setter, | 604 Handle<JSFunction> setter, |
553 StrictModeFlag strict_mode) { | 605 StrictModeFlag strict_mode) { |
554 Handle<Code> stub = FindIC( | 606 Handle<Code> stub = FindStoreHandler( |
555 name, receiver, Code::STORE_IC, Code::CALLBACKS, strict_mode); | 607 name, receiver, Code::STORE_IC, Code::CALLBACKS, strict_mode); |
556 if (!stub.is_null()) return stub; | 608 if (!stub.is_null()) return stub; |
557 | 609 |
558 StoreStubCompiler compiler(isolate_, strict_mode); | 610 StoreStubCompiler compiler(isolate_, strict_mode); |
559 Handle<Code> code = | 611 Handle<Code> handler = compiler.CompileStoreViaSetter( |
560 compiler.CompileStoreViaSetter(name, receiver, holder, setter); | 612 receiver, holder, name, setter); |
561 JSObject::UpdateMapCodeCache(receiver, name, code); | 613 JSObject::UpdateMapCodeCache(receiver, name, handler); |
562 return code; | 614 return handler; |
563 } | 615 } |
564 | 616 |
565 | 617 |
566 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<Name> name, | 618 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<Name> name, |
567 Handle<JSObject> receiver, | 619 Handle<JSObject> receiver, |
568 StrictModeFlag strict_mode) { | 620 StrictModeFlag strict_mode) { |
569 Handle<Code> stub = FindIC( | 621 Handle<Code> stub = FindStoreHandler( |
570 name, receiver, Code::STORE_IC, Code::INTERCEPTOR, strict_mode); | 622 name, receiver, Code::STORE_IC, Code::INTERCEPTOR, strict_mode); |
571 if (!stub.is_null()) return stub; | 623 if (!stub.is_null()) return stub; |
572 | 624 |
573 StoreStubCompiler compiler(isolate_, strict_mode); | 625 StoreStubCompiler compiler(isolate_, strict_mode); |
574 Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name); | 626 Handle<Code> handler = compiler.CompileStoreInterceptor(receiver, name); |
575 JSObject::UpdateMapCodeCache(receiver, name, code); | 627 JSObject::UpdateMapCodeCache(receiver, name, handler); |
576 return code; | 628 return handler; |
577 } | 629 } |
578 | 630 |
579 | 631 |
580 Handle<Code> StubCache::ComputeKeyedStoreField(Handle<Name> name, | 632 Handle<Code> StubCache::ComputeKeyedStoreField(Handle<Name> name, |
581 Handle<JSObject> receiver, | 633 Handle<JSObject> receiver, |
582 LookupResult* lookup, | 634 LookupResult* lookup, |
583 StrictModeFlag strict_mode) { | 635 StrictModeFlag strict_mode) { |
584 Handle<Code> stub = FindIC( | 636 Handle<Code> stub = FindStoreHandler( |
585 name, receiver, Code::KEYED_STORE_IC, Code::FIELD, strict_mode); | 637 name, receiver, Code::KEYED_STORE_IC, Code::FIELD, strict_mode); |
586 if (!stub.is_null()) return stub; | 638 if (!stub.is_null()) return stub; |
587 | 639 |
588 KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE); | 640 KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE); |
589 Handle<Code> code = compiler.CompileStoreField(receiver, lookup, name); | 641 Handle<Code> handler = compiler.CompileStoreField(receiver, lookup, name); |
590 JSObject::UpdateMapCodeCache(receiver, name, code); | 642 JSObject::UpdateMapCodeCache(receiver, name, handler); |
591 return code; | 643 return handler; |
592 } | 644 } |
593 | 645 |
594 | 646 |
595 Handle<Code> StubCache::ComputeKeyedStoreTransition( | 647 Handle<Code> StubCache::ComputeKeyedStoreTransition( |
596 Handle<Name> name, | 648 Handle<Name> name, |
597 Handle<JSObject> receiver, | 649 Handle<JSObject> receiver, |
598 LookupResult* lookup, | 650 LookupResult* lookup, |
599 Handle<Map> transition, | 651 Handle<Map> transition, |
600 StrictModeFlag strict_mode) { | 652 StrictModeFlag strict_mode) { |
601 Handle<Code> stub = FindIC( | 653 Handle<Code> stub = FindStoreHandler( |
602 name, receiver, Code::KEYED_STORE_IC, Code::MAP_TRANSITION, strict_mode); | 654 name, receiver, Code::KEYED_STORE_IC, Code::MAP_TRANSITION, strict_mode); |
603 if (!stub.is_null()) return stub; | 655 if (!stub.is_null()) return stub; |
604 | 656 |
605 KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE); | 657 KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE); |
606 Handle<Code> code = | 658 Handle<Code> handler = |
607 compiler.CompileStoreTransition(receiver, lookup, transition, name); | 659 compiler.CompileStoreTransition(receiver, lookup, transition, name); |
608 JSObject::UpdateMapCodeCache(receiver, name, code); | 660 JSObject::UpdateMapCodeCache(receiver, name, handler); |
609 return code; | 661 return handler; |
610 } | 662 } |
611 | 663 |
612 | 664 |
613 #define CALL_LOGGER_TAG(kind, type) \ | 665 #define CALL_LOGGER_TAG(kind, type) \ |
614 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) | 666 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) |
615 | 667 |
616 Handle<Code> StubCache::ComputeCallConstant(int argc, | 668 Handle<Code> StubCache::ComputeCallConstant(int argc, |
617 Code::Kind kind, | 669 Code::Kind kind, |
618 Code::ExtraICState extra_state, | 670 Code::ExtraICState extra_state, |
619 Handle<Name> name, | 671 Handle<Name> name, |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 receiver_maps, &handlers, factory()->empty_string(), | 1015 receiver_maps, &handlers, factory()->empty_string(), |
964 Code::NORMAL, ELEMENT); | 1016 Code::NORMAL, ELEMENT); |
965 | 1017 |
966 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); | 1018 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); |
967 | 1019 |
968 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); | 1020 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); |
969 return code; | 1021 return code; |
970 } | 1022 } |
971 | 1023 |
972 | 1024 |
973 Handle<Code> StubCache::ComputePolymorphicIC(MapHandleList* receiver_maps, | 1025 Handle<Code> StubCache::ComputePolymorphicLoadIC(MapHandleList* receiver_maps, |
974 CodeHandleList* handlers, | 1026 CodeHandleList* handlers, |
975 int number_of_valid_maps, | 1027 int number_of_valid_maps, |
976 Handle<Name> name) { | 1028 Handle<Name> name) { |
977 LoadStubCompiler ic_compiler(isolate_); | 1029 LoadStubCompiler ic_compiler(isolate_); |
978 Code::StubType type = number_of_valid_maps == 1 ? handlers->at(0)->type() | 1030 Code::StubType type = number_of_valid_maps == 1 ? handlers->at(0)->type() |
979 : Code::NORMAL; | 1031 : Code::NORMAL; |
980 Handle<Code> ic = ic_compiler.CompilePolymorphicIC( | 1032 Handle<Code> ic = ic_compiler.CompilePolymorphicIC( |
981 receiver_maps, handlers, name, type, PROPERTY); | 1033 receiver_maps, handlers, name, type, PROPERTY); |
982 return ic; | 1034 return ic; |
983 } | 1035 } |
984 | 1036 |
985 | 1037 |
| 1038 Handle<Code> StubCache::ComputePolymorphicStoreIC(MapHandleList* receiver_maps, |
| 1039 CodeHandleList* handlers, |
| 1040 int number_of_valid_maps, |
| 1041 Handle<Name> name, |
| 1042 StrictModeFlag strict_mode) { |
| 1043 StoreStubCompiler ic_compiler(isolate_, strict_mode); |
| 1044 Code::StubType type = number_of_valid_maps == 1 ? handlers->at(0)->type() |
| 1045 : Code::NORMAL; |
| 1046 Handle<Code> ic = ic_compiler.CompilePolymorphicIC( |
| 1047 receiver_maps, handlers, name, type, PROPERTY); |
| 1048 return ic; |
| 1049 } |
| 1050 |
| 1051 |
986 Handle<Code> StubCache::ComputeStoreElementPolymorphic( | 1052 Handle<Code> StubCache::ComputeStoreElementPolymorphic( |
987 MapHandleList* receiver_maps, | 1053 MapHandleList* receiver_maps, |
988 KeyedAccessStoreMode store_mode, | 1054 KeyedAccessStoreMode store_mode, |
989 StrictModeFlag strict_mode) { | 1055 StrictModeFlag strict_mode) { |
990 ASSERT(store_mode == STANDARD_STORE || | 1056 ASSERT(store_mode == STANDARD_STORE || |
991 store_mode == STORE_AND_GROW_NO_TRANSITION || | 1057 store_mode == STORE_AND_GROW_NO_TRANSITION || |
992 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || | 1058 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
993 store_mode == STORE_NO_TRANSITION_HANDLE_COW); | 1059 store_mode == STORE_NO_TRANSITION_HANDLE_COW); |
994 Handle<PolymorphicCodeCache> cache = | 1060 Handle<PolymorphicCodeCache> cache = |
995 isolate_->factory()->polymorphic_code_cache(); | 1061 isolate_->factory()->polymorphic_code_cache(); |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 holder->LocalLookupRealNamedProperty(*name, lookup); | 1549 holder->LocalLookupRealNamedProperty(*name, lookup); |
1484 if (lookup->IsFound()) return; | 1550 if (lookup->IsFound()) return; |
1485 if (holder->GetPrototype()->IsNull()) return; | 1551 if (holder->GetPrototype()->IsNull()) return; |
1486 holder->GetPrototype()->Lookup(*name, lookup); | 1552 holder->GetPrototype()->Lookup(*name, lookup); |
1487 } | 1553 } |
1488 | 1554 |
1489 | 1555 |
1490 #define __ ACCESS_MASM(masm()) | 1556 #define __ ACCESS_MASM(masm()) |
1491 | 1557 |
1492 | 1558 |
1493 Register BaseLoadStubCompiler::HandlerFrontendHeader(Handle<JSObject> object, | 1559 Register BaseLoadStubCompiler::HandlerFrontendHeader( |
1494 Register object_reg, | 1560 Handle<JSObject> object, |
1495 Handle<JSObject> holder, | 1561 Register object_reg, |
1496 Handle<Name> name, | 1562 Handle<JSObject> holder, |
1497 Label* miss) { | 1563 Handle<Name> name, |
1498 // Check the prototype chain. | 1564 Label* miss) { |
1499 return CheckPrototypes(object, object_reg, holder, | 1565 return CheckPrototypes(object, object_reg, holder, |
1500 scratch1(), scratch2(), scratch3(), | 1566 scratch1(), scratch2(), scratch3(), |
1501 name, miss, SKIP_RECEIVER); | 1567 name, miss, SKIP_RECEIVER); |
1502 } | 1568 } |
1503 | 1569 |
1504 | 1570 |
1505 Register BaseLoadStubCompiler::HandlerFrontend(Handle<JSObject> object, | 1571 // HandlerFrontend for store uses the name register. It has to be restored |
1506 Register object_reg, | 1572 // before a miss. |
1507 Handle<JSObject> holder, | 1573 Register BaseStoreStubCompiler::HandlerFrontendHeader( |
1508 Handle<Name> name, | 1574 Handle<JSObject> object, |
1509 Label* success) { | 1575 Register object_reg, |
| 1576 Handle<JSObject> holder, |
| 1577 Handle<Name> name, |
| 1578 Label* miss) { |
| 1579 return CheckPrototypes(object, object_reg, holder, |
| 1580 this->name(), scratch1(), scratch2(), |
| 1581 name, miss, SKIP_RECEIVER); |
| 1582 } |
| 1583 |
| 1584 |
| 1585 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<JSObject> object, |
| 1586 Register object_reg, |
| 1587 Handle<JSObject> holder, |
| 1588 Handle<Name> name, |
| 1589 Label* success) { |
1510 Label miss; | 1590 Label miss; |
1511 | 1591 |
1512 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); | 1592 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); |
1513 | 1593 |
1514 HandlerFrontendFooter(success, &miss); | 1594 HandlerFrontendFooter(name, success, &miss); |
1515 return reg; | 1595 return reg; |
1516 } | 1596 } |
1517 | 1597 |
1518 | 1598 |
1519 Handle<Code> BaseLoadStubCompiler::CompileLoadField( | 1599 Handle<Code> BaseLoadStubCompiler::CompileLoadField( |
1520 Handle<JSObject> object, | 1600 Handle<JSObject> object, |
1521 Handle<JSObject> holder, | 1601 Handle<JSObject> holder, |
1522 Handle<Name> name, | 1602 Handle<Name> name, |
1523 PropertyIndex field, | 1603 PropertyIndex field, |
1524 Representation representation) { | 1604 Representation representation) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1618 ASSERT(callback->getter() != NULL); | 1698 ASSERT(callback->getter() != NULL); |
1619 | 1699 |
1620 Register reg = CallbackHandlerFrontend( | 1700 Register reg = CallbackHandlerFrontend( |
1621 interceptor_holder, interceptor_reg, holder, name, &success, callback); | 1701 interceptor_holder, interceptor_reg, holder, name, &success, callback); |
1622 __ bind(&success); | 1702 __ bind(&success); |
1623 GenerateLoadCallback(reg, callback); | 1703 GenerateLoadCallback(reg, callback); |
1624 } | 1704 } |
1625 } | 1705 } |
1626 | 1706 |
1627 | 1707 |
1628 Handle<Code> BaseLoadStubCompiler::CompileMonomorphicIC( | 1708 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC( |
1629 Handle<Map> receiver_map, | 1709 Handle<Map> receiver_map, |
1630 Handle<Code> handler, | 1710 Handle<Code> handler, |
1631 Handle<Name> name) { | 1711 Handle<Name> name) { |
1632 MapHandleList receiver_maps(1); | 1712 MapHandleList receiver_maps(1); |
1633 receiver_maps.Add(receiver_map); | 1713 receiver_maps.Add(receiver_map); |
1634 CodeHandleList handlers(1); | 1714 CodeHandleList handlers(1); |
1635 handlers.Add(handler); | 1715 handlers.Add(handler); |
1636 Code::StubType type = handler->type(); | 1716 Code::StubType type = handler->type(); |
1637 return CompilePolymorphicIC(&receiver_maps, &handlers, name, type, PROPERTY); | 1717 return CompilePolymorphicIC(&receiver_maps, &handlers, name, type, PROPERTY); |
1638 } | 1718 } |
(...skipping 13 matching lines...) Expand all Loading... |
1652 // Return the generated code. | 1732 // Return the generated code. |
1653 return GetCode(kind(), Code::CALLBACKS, name); | 1733 return GetCode(kind(), Code::CALLBACKS, name); |
1654 } | 1734 } |
1655 | 1735 |
1656 | 1736 |
1657 Handle<Code> BaseStoreStubCompiler::CompileStoreTransition( | 1737 Handle<Code> BaseStoreStubCompiler::CompileStoreTransition( |
1658 Handle<JSObject> object, | 1738 Handle<JSObject> object, |
1659 LookupResult* lookup, | 1739 LookupResult* lookup, |
1660 Handle<Map> transition, | 1740 Handle<Map> transition, |
1661 Handle<Name> name) { | 1741 Handle<Name> name) { |
1662 Label miss, miss_restore_name, slow; | 1742 Label miss, slow; |
1663 | 1743 |
1664 GenerateNameCheck(name, this->name(), &miss); | 1744 // Ensure no transitions to deprecated maps are followed. |
| 1745 __ CheckMapDeprecated(transition, scratch1(), &miss); |
| 1746 |
| 1747 // Check that we are allowed to write this. |
| 1748 if (object->GetPrototype()->IsJSObject()) { |
| 1749 Handle<JSObject> holder; |
| 1750 // holder == object indicates that no property was found. |
| 1751 if (lookup->holder() != *object) { |
| 1752 holder = Handle<JSObject>(lookup->holder()); |
| 1753 } else { |
| 1754 // Find the top object. |
| 1755 holder = object; |
| 1756 do { |
| 1757 holder = Handle<JSObject>(JSObject::cast(holder->GetPrototype())); |
| 1758 } while (holder->GetPrototype()->IsJSObject()); |
| 1759 } |
| 1760 |
| 1761 Register holder_reg = |
| 1762 HandlerFrontendHeader(object, receiver(), holder, name, &miss); |
| 1763 |
| 1764 // If no property was found, and the holder (the last object in the |
| 1765 // prototype chain) is in slow mode, we need to do a negative lookup on the |
| 1766 // holder. |
| 1767 if (lookup->holder() == *object) { |
| 1768 GenerateNegativeHolderLookup(masm(), holder, holder_reg, name, &miss); |
| 1769 } |
| 1770 } |
1665 | 1771 |
1666 GenerateStoreTransition(masm(), | 1772 GenerateStoreTransition(masm(), |
1667 object, | 1773 object, |
1668 lookup, | 1774 lookup, |
1669 transition, | 1775 transition, |
1670 name, | 1776 name, |
1671 receiver(), this->name(), value(), | 1777 receiver(), this->name(), value(), |
1672 scratch1(), scratch2(), scratch3(), | 1778 scratch1(), scratch2(), scratch3(), |
1673 &miss, | 1779 &miss, |
1674 &miss_restore_name, | |
1675 &slow); | 1780 &slow); |
1676 | 1781 |
1677 // Handle store cache miss. | 1782 // Handle store cache miss. |
1678 GenerateRestoreName(masm(), &miss_restore_name, name); | 1783 GenerateRestoreName(masm(), &miss, name); |
1679 __ bind(&miss); | |
1680 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1784 TailCallBuiltin(masm(), MissBuiltin(kind())); |
1681 | 1785 |
1682 GenerateRestoreName(masm(), &slow, name); | 1786 GenerateRestoreName(masm(), &slow, name); |
1683 TailCallBuiltin(masm(), SlowBuiltin(kind())); | 1787 TailCallBuiltin(masm(), SlowBuiltin(kind())); |
1684 | 1788 |
1685 // Return the generated code. | 1789 // Return the generated code. |
1686 return GetICCode(kind(), Code::MAP_TRANSITION, name); | 1790 return GetCode(kind(), Code::MAP_TRANSITION, name); |
1687 } | 1791 } |
1688 | 1792 |
1689 | 1793 |
1690 Handle<Code> BaseStoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 1794 Handle<Code> BaseStoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
1691 LookupResult* lookup, | 1795 LookupResult* lookup, |
1692 Handle<Name> name) { | 1796 Handle<Name> name) { |
1693 Label miss; | 1797 Label miss; |
1694 | 1798 |
1695 GenerateNameCheck(name, this->name(), &miss); | 1799 HandlerFrontendHeader(object, receiver(), object, name, &miss); |
1696 | 1800 |
1697 // Generate store field code. | 1801 // Generate store field code. |
1698 GenerateStoreField(masm(), | 1802 GenerateStoreField(masm(), |
1699 object, | 1803 object, |
1700 lookup, | 1804 lookup, |
1701 receiver(), this->name(), value(), scratch1(), scratch2(), | 1805 receiver(), this->name(), value(), scratch1(), scratch2(), |
1702 &miss); | 1806 &miss); |
1703 | 1807 |
1704 // Handle store cache miss. | 1808 // Handle store cache miss. |
1705 __ bind(&miss); | 1809 __ bind(&miss); |
1706 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1810 TailCallBuiltin(masm(), MissBuiltin(kind())); |
1707 | 1811 |
1708 // Return the generated code. | 1812 // Return the generated code. |
1709 return GetICCode(kind(), Code::FIELD, name); | 1813 return GetCode(kind(), Code::FIELD, name); |
1710 } | 1814 } |
1711 | 1815 |
1712 | 1816 |
1713 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | 1817 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( |
1714 Handle<Name> name, | |
1715 Handle<JSObject> object, | 1818 Handle<JSObject> object, |
1716 Handle<JSObject> holder, | 1819 Handle<JSObject> holder, |
| 1820 Handle<Name> name, |
1717 Handle<JSFunction> setter) { | 1821 Handle<JSFunction> setter) { |
1718 Label miss, miss_restore_name; | 1822 Label success; |
| 1823 HandlerFrontend(object, receiver(), holder, name, &success); |
1719 | 1824 |
1720 // Check that the maps haven't changed, preserving the name register. | 1825 __ bind(&success); |
1721 __ JumpIfSmi(receiver(), &miss); | |
1722 CheckPrototypes(object, receiver(), holder, | |
1723 this->name(), scratch1(), scratch2(), | |
1724 name, &miss_restore_name); | |
1725 | |
1726 GenerateStoreViaSetter(masm(), setter); | 1826 GenerateStoreViaSetter(masm(), setter); |
1727 | 1827 |
1728 GenerateRestoreName(masm(), &miss_restore_name, name); | 1828 return GetCode(kind(), Code::CALLBACKS, name); |
1729 | |
1730 __ bind(&miss); | |
1731 TailCallBuiltin(masm(), MissBuiltin(kind())); | |
1732 | |
1733 // Return the generated code. | |
1734 return GetICCode(kind(), Code::CALLBACKS, name); | |
1735 } | 1829 } |
1736 | 1830 |
1737 | 1831 |
1738 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( | 1832 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( |
1739 Handle<Map> receiver_map) { | 1833 Handle<Map> receiver_map) { |
1740 ElementsKind elements_kind = receiver_map->elements_kind(); | 1834 ElementsKind elements_kind = receiver_map->elements_kind(); |
1741 if (receiver_map->has_fast_elements() || | 1835 if (receiver_map->has_fast_elements() || |
1742 receiver_map->has_external_array_elements()) { | 1836 receiver_map->has_external_array_elements()) { |
1743 Handle<Code> stub = KeyedLoadFastElementStub( | 1837 Handle<Code> stub = KeyedLoadFastElementStub( |
1744 receiver_map->instance_type() == JS_ARRAY_TYPE, | 1838 receiver_map->instance_type() == JS_ARRAY_TYPE, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1806 void StoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { | 1900 void StoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { |
1807 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); | 1901 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); |
1808 } | 1902 } |
1809 | 1903 |
1810 | 1904 |
1811 void KeyedStoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { | 1905 void KeyedStoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) { |
1812 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); | 1906 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); |
1813 } | 1907 } |
1814 | 1908 |
1815 | 1909 |
1816 Handle<Code> BaseLoadStubCompiler::GetICCode(Code::Kind kind, | 1910 Handle<Code> BaseLoadStoreStubCompiler::GetICCode(Code::Kind kind, |
1817 Code::StubType type, | 1911 Code::StubType type, |
1818 Handle<Name> name, | 1912 Handle<Name> name, |
1819 InlineCacheState state) { | 1913 InlineCacheState state) { |
1820 Code::Flags flags = Code::ComputeFlags( | 1914 Code::Flags flags = Code::ComputeFlags( |
1821 kind, state, Code::kNoExtraICState, type); | 1915 kind, state, extra_state(), type); |
1822 Handle<Code> code = GetCodeWithFlags(flags, name); | 1916 Handle<Code> code = GetCodeWithFlags(flags, name); |
1823 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); | 1917 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); |
1824 JitEvent(name, code); | 1918 JitEvent(name, code); |
1825 return code; | 1919 return code; |
1826 } | 1920 } |
1827 | 1921 |
1828 | 1922 |
1829 Handle<Code> BaseLoadStubCompiler::GetCode(Code::Kind kind, | 1923 Handle<Code> BaseLoadStubCompiler::GetCode(Code::Kind kind, |
1830 Code::StubType type, | 1924 Code::StubType type, |
1831 Handle<Name> name) { | 1925 Handle<Name> name) { |
1832 ASSERT(type != Code::NORMAL); | 1926 ASSERT(type != Code::NORMAL); |
1833 Code::Flags flags = Code::ComputeFlags( | 1927 Code::Flags flags = Code::ComputeFlags( |
1834 Code::STUB, MONOMORPHIC, Code::kNoExtraICState, type, kind); | 1928 Code::STUB, MONOMORPHIC, Code::kNoExtraICState, type, kind); |
1835 Handle<Code> code = GetCodeWithFlags(flags, name); | 1929 Handle<Code> code = GetCodeWithFlags(flags, name); |
1836 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); | 1930 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); |
1837 JitEvent(name, code); | 1931 JitEvent(name, code); |
1838 return code; | 1932 return code; |
1839 } | 1933 } |
1840 | 1934 |
1841 | 1935 |
1842 Handle<Code> BaseStoreStubCompiler::GetICCode(Code::Kind kind, | |
1843 Code::StubType type, | |
1844 Handle<Name> name, | |
1845 InlineCacheState state) { | |
1846 Code::Flags flags = Code::ComputeFlags( | |
1847 kind, state, extra_state(), type); | |
1848 Handle<Code> code = GetCodeWithFlags(flags, name); | |
1849 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); | |
1850 JitEvent(name, code); | |
1851 return code; | |
1852 } | |
1853 | |
1854 | |
1855 Handle<Code> BaseStoreStubCompiler::GetCode(Code::Kind kind, | 1936 Handle<Code> BaseStoreStubCompiler::GetCode(Code::Kind kind, |
1856 Code::StubType type, | 1937 Code::StubType type, |
1857 Handle<Name> name) { | 1938 Handle<Name> name) { |
1858 ASSERT(type != Code::NORMAL); | 1939 ASSERT(type != Code::NORMAL); |
1859 Code::Flags flags = Code::ComputeFlags( | 1940 Code::Flags flags = Code::ComputeFlags( |
1860 Code::STUB, MONOMORPHIC, extra_state(), type, kind); | 1941 Code::STUB, MONOMORPHIC, extra_state(), type, kind); |
1861 Handle<Code> code = GetCodeWithFlags(flags, name); | 1942 Handle<Code> code = GetCodeWithFlags(flags, name); |
1862 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); | 1943 PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name)); |
1863 JitEvent(name, code); | 1944 JitEvent(name, code); |
1864 return code; | 1945 return code; |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2112 Handle<FunctionTemplateInfo>( | 2193 Handle<FunctionTemplateInfo>( |
2113 FunctionTemplateInfo::cast(signature->receiver())); | 2194 FunctionTemplateInfo::cast(signature->receiver())); |
2114 } | 2195 } |
2115 } | 2196 } |
2116 | 2197 |
2117 is_simple_api_call_ = true; | 2198 is_simple_api_call_ = true; |
2118 } | 2199 } |
2119 | 2200 |
2120 | 2201 |
2121 } } // namespace v8::internal | 2202 } } // namespace v8::internal |
OLD | NEW |