OLD | NEW |
---|---|
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
164 __ ldr(dst, FieldMemOperand(src, offset)); | 164 __ ldr(dst, FieldMemOperand(src, offset)); |
165 } else { | 165 } else { |
166 // Calculate the offset into the properties array. | 166 // Calculate the offset into the properties array. |
167 int offset = index * kPointerSize + Array::kHeaderSize; | 167 int offset = index * kPointerSize + Array::kHeaderSize; |
168 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); | 168 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); |
169 __ ldr(dst, FieldMemOperand(dst, offset)); | 169 __ ldr(dst, FieldMemOperand(dst, offset)); |
170 } | 170 } |
171 } | 171 } |
172 | 172 |
173 | 173 |
174 void StubCompiler::GenerateLoadField(MacroAssembler* masm, | |
175 JSObject* object, | |
176 JSObject* holder, | |
177 Register receiver, | |
178 Register scratch1, | |
179 Register scratch2, | |
180 int index, | |
181 Label* miss_label) { | |
182 // Check that the receiver isn't a smi. | |
183 __ tst(receiver, Operand(kSmiTagMask)); | |
184 __ b(eq, miss_label); | |
185 | |
186 // Check that the maps haven't changed. | |
187 Register reg = | |
188 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | |
189 GenerateFastPropertyLoad(masm, r0, reg, holder, index); | |
190 __ Ret(); | |
191 } | |
192 | |
193 | |
194 void StubCompiler::GenerateLoadConstant(MacroAssembler* masm, | |
195 JSObject* object, | |
196 JSObject* holder, | |
197 Register receiver, | |
198 Register scratch1, | |
199 Register scratch2, | |
200 Object* value, | |
201 Label* miss_label) { | |
202 // Check that the receiver isn't a smi. | |
203 __ tst(receiver, Operand(kSmiTagMask)); | |
204 __ b(eq, miss_label); | |
205 | |
206 // Check that the maps haven't changed. | |
207 Register reg = | |
208 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | |
209 | |
210 // Return the constant value. | |
211 __ mov(r0, Operand(Handle<Object>(value))); | |
212 __ Ret(); | |
213 } | |
214 | |
215 | |
216 void StubCompiler::GenerateLoadCallback(MacroAssembler* masm, | |
217 JSObject* object, | |
218 JSObject* holder, | |
219 Register receiver, | |
220 Register name, | |
221 Register scratch1, | |
222 Register scratch2, | |
223 AccessorInfo* callback, | |
224 Label* miss_label) { | |
225 // Check that the receiver isn't a smi. | |
226 __ tst(receiver, Operand(kSmiTagMask)); | |
227 __ b(eq, miss_label); | |
228 | |
229 // Check that the maps haven't changed. | |
230 Register reg = | |
231 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | |
232 | |
233 // Push the arguments on the JS stack of the caller. | |
234 __ push(receiver); // receiver | |
235 __ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback data | |
236 __ push(ip); | |
237 __ push(name); // name | |
238 __ push(reg); // holder | |
239 | |
240 // Do tail-call to the runtime system. | |
241 ExternalReference load_callback_property = | |
242 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | |
243 __ TailCallRuntime(load_callback_property, 4); | |
244 } | |
245 | |
246 | |
247 void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm, | |
248 JSObject* object, | |
249 JSObject* holder, | |
250 Smi* lookup_hint, | |
251 Register receiver, | |
252 Register name, | |
253 Register scratch1, | |
254 Register scratch2, | |
255 Label* miss_label) { | |
256 // Check that the receiver isn't a smi. | |
257 __ tst(receiver, Operand(kSmiTagMask)); | |
258 __ b(eq, miss_label); | |
259 | |
260 // Check that the maps haven't changed. | |
261 Register reg = | |
262 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | |
263 | |
264 // Push the arguments on the JS stack of the caller. | |
265 __ push(receiver); // receiver | |
266 __ push(reg); // holder | |
267 __ push(name); // name | |
268 __ mov(scratch1, Operand(lookup_hint)); | |
269 __ push(scratch1); | |
270 | |
271 // Do tail-call to the runtime system. | |
272 ExternalReference load_ic_property = | |
273 ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); | |
274 __ TailCallRuntime(load_ic_property, 4); | |
275 } | |
276 | |
277 | |
278 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, | 174 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, |
279 Register receiver, | 175 Register receiver, |
280 Register scratch, | 176 Register scratch, |
281 Label* miss_label) { | 177 Label* miss_label) { |
282 // Check that the receiver isn't a smi. | 178 // Check that the receiver isn't a smi. |
283 __ tst(receiver, Operand(kSmiTagMask)); | 179 __ tst(receiver, Operand(kSmiTagMask)); |
284 __ b(eq, miss_label); | 180 __ b(eq, miss_label); |
285 | 181 |
286 // Check that the object is a JS array. | 182 // Check that the object is a JS array. |
287 __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE); | 183 __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
455 | 351 |
456 Handle<Code> ic(code); | 352 Handle<Code> ic(code); |
457 __ Jump(ic, RelocInfo::CODE_TARGET); | 353 __ Jump(ic, RelocInfo::CODE_TARGET); |
458 } | 354 } |
459 | 355 |
460 | 356 |
461 #undef __ | 357 #undef __ |
462 #define __ ACCESS_MASM(masm()) | 358 #define __ ACCESS_MASM(masm()) |
463 | 359 |
464 | 360 |
361 Register StubCompiler::CheckPrototypes(JSObject* object, | |
antonm
2009/07/10 09:28:43
maybe it should go to macro-assembler?
| |
362 Register object_reg, | |
363 JSObject* holder, | |
364 Register holder_reg, | |
365 Register scratch, | |
366 String* name, | |
367 Label* miss) { | |
368 // Check that the maps haven't changed. | |
369 Register result = | |
370 masm()->CheckMaps(object, object_reg, holder, holder_reg, scratch, miss); | |
371 | |
372 // If we've skipped any global objects, it's not enough to verify | |
373 // that their maps haven't changed. | |
374 while (object != holder) { | |
375 if (object->IsGlobalObject()) { | |
antonm
2009/07/10 09:28:43
just curious, I guess there might be only single g
| |
376 GlobalObject* global = GlobalObject::cast(object); | |
377 Object* probe = global->EnsurePropertyCell(name); | |
378 if (probe->IsFailure()) { | |
379 set_failure(Failure::cast(probe)); | |
380 return result; | |
381 } | |
382 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); | |
antonm
2009/07/10 09:28:43
for my education: why it must be the hole?
| |
383 ASSERT(cell->value()->IsTheHole()); | |
384 __ mov(scratch, Operand(Handle<Object>(cell))); | |
antonm
2009/07/10 09:28:43
cell always live not in new space, correct?
| |
385 __ ldr(scratch, | |
386 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | |
387 __ cmp(scratch, Operand(Factory::the_hole_value())); | |
388 __ b(ne, miss); | |
389 } | |
390 object = JSObject::cast(object->GetPrototype()); | |
antonm
2009/07/10 09:28:43
just for my education: it's always safe to assume
| |
391 } | |
392 | |
393 // Return the register containin the holder. | |
394 return result; | |
395 } | |
396 | |
397 | |
398 void StubCompiler::GenerateLoadField(JSObject* object, | |
antonm
2009/07/10 09:28:43
cosmetic issue: is the move of methods needed---if
| |
399 JSObject* holder, | |
400 Register receiver, | |
401 Register scratch1, | |
402 Register scratch2, | |
403 int index, | |
404 String* name, | |
405 Label* miss) { | |
406 // Check that the receiver isn't a smi. | |
407 __ tst(receiver, Operand(kSmiTagMask)); | |
408 __ b(eq, miss); | |
409 | |
410 // Check that the maps haven't changed. | |
411 Register reg = | |
412 CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); | |
413 GenerateFastPropertyLoad(masm(), r0, reg, holder, index); | |
414 __ Ret(); | |
415 } | |
416 | |
417 | |
418 void StubCompiler::GenerateLoadConstant(JSObject* object, | |
419 JSObject* holder, | |
420 Register receiver, | |
421 Register scratch1, | |
422 Register scratch2, | |
423 Object* value, | |
424 String* name, | |
425 Label* miss) { | |
426 // Check that the receiver isn't a smi. | |
427 __ tst(receiver, Operand(kSmiTagMask)); | |
428 __ b(eq, miss); | |
429 | |
430 // Check that the maps haven't changed. | |
431 Register reg = | |
432 CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); | |
433 | |
434 // Return the constant value. | |
435 __ mov(r0, Operand(Handle<Object>(value))); | |
436 __ Ret(); | |
437 } | |
438 | |
439 | |
440 void StubCompiler::GenerateLoadCallback(JSObject* object, | |
441 JSObject* holder, | |
442 Register receiver, | |
443 Register name_reg, | |
444 Register scratch1, | |
445 Register scratch2, | |
446 AccessorInfo* callback, | |
447 String* name, | |
448 Label* miss) { | |
449 // Check that the receiver isn't a smi. | |
450 __ tst(receiver, Operand(kSmiTagMask)); | |
451 __ b(eq, miss); | |
452 | |
453 // Check that the maps haven't changed. | |
454 Register reg = | |
455 CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); | |
456 | |
457 // Push the arguments on the JS stack of the caller. | |
458 __ push(receiver); // receiver | |
459 __ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback data | |
460 __ push(ip); | |
461 __ push(name_reg); // name | |
462 __ push(reg); // holder | |
463 | |
464 // Do tail-call to the runtime system. | |
465 ExternalReference load_callback_property = | |
466 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | |
467 __ TailCallRuntime(load_callback_property, 4); | |
468 } | |
469 | |
470 | |
471 void StubCompiler::GenerateLoadInterceptor(JSObject* object, | |
472 JSObject* holder, | |
473 Smi* lookup_hint, | |
474 Register receiver, | |
475 Register name_reg, | |
476 Register scratch1, | |
477 Register scratch2, | |
478 String* name, | |
479 Label* miss) { | |
480 // Check that the receiver isn't a smi. | |
481 __ tst(receiver, Operand(kSmiTagMask)); | |
482 __ b(eq, miss); | |
483 | |
484 // Check that the maps haven't changed. | |
485 Register reg = | |
486 CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); | |
487 | |
488 // Push the arguments on the JS stack of the caller. | |
489 __ push(receiver); // receiver | |
490 __ push(reg); // holder | |
491 __ push(name_reg); // name | |
492 __ mov(scratch1, Operand(lookup_hint)); | |
493 __ push(scratch1); | |
494 | |
495 // Do tail-call to the runtime system. | |
496 ExternalReference load_ic_property = | |
497 ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); | |
498 __ TailCallRuntime(load_ic_property, 4); | |
499 } | |
500 | |
501 | |
465 Object* StubCompiler::CompileLazyCompile(Code::Flags flags) { | 502 Object* StubCompiler::CompileLazyCompile(Code::Flags flags) { |
466 // ----------- S t a t e ------------- | 503 // ----------- S t a t e ------------- |
467 // -- r1: function | 504 // -- r1: function |
468 // -- lr: return address | 505 // -- lr: return address |
469 // ----------------------------------- | 506 // ----------------------------------- |
470 | 507 |
471 // Enter an internal frame. | 508 // Enter an internal frame. |
472 __ EnterInternalFrame(); | 509 __ EnterInternalFrame(); |
473 | 510 |
474 // Preserve the function. | 511 // Preserve the function. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
506 const int argc = arguments().immediate(); | 543 const int argc = arguments().immediate(); |
507 | 544 |
508 // Get the receiver of the function from the stack into r0. | 545 // Get the receiver of the function from the stack into r0. |
509 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 546 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
510 // Check that the receiver isn't a smi. | 547 // Check that the receiver isn't a smi. |
511 __ tst(r0, Operand(kSmiTagMask)); | 548 __ tst(r0, Operand(kSmiTagMask)); |
512 __ b(eq, &miss); | 549 __ b(eq, &miss); |
513 | 550 |
514 // Do the right check and compute the holder register. | 551 // Do the right check and compute the holder register. |
515 Register reg = | 552 Register reg = |
516 masm()->CheckMaps(JSObject::cast(object), r0, holder, r3, r2, &miss); | 553 CheckPrototypes(JSObject::cast(object), r0, holder, r3, r2, name, &miss); |
517 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); | 554 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); |
518 | 555 |
519 // Check that the function really is a function. | 556 // Check that the function really is a function. |
520 __ tst(r1, Operand(kSmiTagMask)); | 557 __ tst(r1, Operand(kSmiTagMask)); |
521 __ b(eq, &miss); | 558 __ b(eq, &miss); |
522 // Get the map. | 559 // Get the map. |
523 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); | 560 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
524 __ b(ne, &miss); | 561 __ b(ne, &miss); |
525 | 562 |
526 // Patch the receiver on the stack with the global proxy if | 563 // Patch the receiver on the stack with the global proxy if |
(...skipping 12 matching lines...) Expand all Loading... | |
539 __ Jump(ic, RelocInfo::CODE_TARGET); | 576 __ Jump(ic, RelocInfo::CODE_TARGET); |
540 | 577 |
541 // Return the generated code. | 578 // Return the generated code. |
542 return GetCode(FIELD, name); | 579 return GetCode(FIELD, name); |
543 } | 580 } |
544 | 581 |
545 | 582 |
546 Object* CallStubCompiler::CompileCallConstant(Object* object, | 583 Object* CallStubCompiler::CompileCallConstant(Object* object, |
547 JSObject* holder, | 584 JSObject* holder, |
548 JSFunction* function, | 585 JSFunction* function, |
586 String* name, | |
549 CheckType check) { | 587 CheckType check) { |
550 // ----------- S t a t e ------------- | 588 // ----------- S t a t e ------------- |
551 // -- lr: return address | 589 // -- lr: return address |
552 // ----------------------------------- | 590 // ----------------------------------- |
553 Label miss; | 591 Label miss; |
554 | 592 |
555 // Get the receiver from the stack | 593 // Get the receiver from the stack |
556 const int argc = arguments().immediate(); | 594 const int argc = arguments().immediate(); |
557 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 595 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
558 | 596 |
559 // Check that the receiver isn't a smi. | 597 // Check that the receiver isn't a smi. |
560 if (check != NUMBER_CHECK) { | 598 if (check != NUMBER_CHECK) { |
561 __ tst(r1, Operand(kSmiTagMask)); | 599 __ tst(r1, Operand(kSmiTagMask)); |
562 __ b(eq, &miss); | 600 __ b(eq, &miss); |
563 } | 601 } |
564 | 602 |
565 // Make sure that it's okay not to patch the on stack receiver | 603 // Make sure that it's okay not to patch the on stack receiver |
566 // unless we're doing a receiver map check. | 604 // unless we're doing a receiver map check. |
567 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 605 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
568 | 606 |
569 switch (check) { | 607 switch (check) { |
570 case RECEIVER_MAP_CHECK: | 608 case RECEIVER_MAP_CHECK: |
571 // Check that the maps haven't changed. | 609 // Check that the maps haven't changed. |
572 __ CheckMaps(JSObject::cast(object), r1, holder, r3, r2, &miss); | 610 CheckPrototypes(JSObject::cast(object), r1, holder, r3, r2, name, &miss); |
573 | 611 |
574 // Patch the receiver on the stack with the global proxy if | 612 // Patch the receiver on the stack with the global proxy if |
575 // necessary. | 613 // necessary. |
576 if (object->IsGlobalObject()) { | 614 if (object->IsGlobalObject()) { |
577 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 615 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
578 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 616 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
579 } | 617 } |
580 break; | 618 break; |
581 | 619 |
582 case STRING_CHECK: | 620 case STRING_CHECK: |
583 // Check that the object is a two-byte string or a symbol. | 621 // Check that the object is a two-byte string or a symbol. |
584 __ CompareObjectType(r1, r2, r2, FIRST_NONSTRING_TYPE); | 622 __ CompareObjectType(r1, r2, r2, FIRST_NONSTRING_TYPE); |
585 __ b(hs, &miss); | 623 __ b(hs, &miss); |
586 // Check that the maps starting from the prototype haven't changed. | 624 // Check that the maps starting from the prototype haven't changed. |
587 GenerateLoadGlobalFunctionPrototype(masm(), | 625 GenerateLoadGlobalFunctionPrototype(masm(), |
588 Context::STRING_FUNCTION_INDEX, | 626 Context::STRING_FUNCTION_INDEX, |
589 r2); | 627 r2); |
590 __ CheckMaps(JSObject::cast(object->GetPrototype()), | 628 CheckPrototypes(JSObject::cast(object->GetPrototype()), r2, holder, r3, |
591 r2, holder, r3, r1, &miss); | 629 r1, name, &miss); |
592 break; | 630 break; |
593 | 631 |
594 case NUMBER_CHECK: { | 632 case NUMBER_CHECK: { |
595 Label fast; | 633 Label fast; |
596 // Check that the object is a smi or a heap number. | 634 // Check that the object is a smi or a heap number. |
597 __ tst(r1, Operand(kSmiTagMask)); | 635 __ tst(r1, Operand(kSmiTagMask)); |
598 __ b(eq, &fast); | 636 __ b(eq, &fast); |
599 __ CompareObjectType(r1, r2, r2, HEAP_NUMBER_TYPE); | 637 __ CompareObjectType(r1, r2, r2, HEAP_NUMBER_TYPE); |
600 __ b(ne, &miss); | 638 __ b(ne, &miss); |
601 __ bind(&fast); | 639 __ bind(&fast); |
602 // Check that the maps starting from the prototype haven't changed. | 640 // Check that the maps starting from the prototype haven't changed. |
603 GenerateLoadGlobalFunctionPrototype(masm(), | 641 GenerateLoadGlobalFunctionPrototype(masm(), |
604 Context::NUMBER_FUNCTION_INDEX, | 642 Context::NUMBER_FUNCTION_INDEX, |
605 r2); | 643 r2); |
606 __ CheckMaps(JSObject::cast(object->GetPrototype()), | 644 CheckPrototypes(JSObject::cast(object->GetPrototype()), r2, holder, r3, |
607 r2, holder, r3, r1, &miss); | 645 r1, name, &miss); |
608 break; | 646 break; |
609 } | 647 } |
610 | 648 |
611 case BOOLEAN_CHECK: { | 649 case BOOLEAN_CHECK: { |
612 Label fast; | 650 Label fast; |
613 // Check that the object is a boolean. | 651 // Check that the object is a boolean. |
614 __ cmp(r1, Operand(Factory::true_value())); | 652 __ cmp(r1, Operand(Factory::true_value())); |
615 __ b(eq, &fast); | 653 __ b(eq, &fast); |
616 __ cmp(r1, Operand(Factory::false_value())); | 654 __ cmp(r1, Operand(Factory::false_value())); |
617 __ b(ne, &miss); | 655 __ b(ne, &miss); |
618 __ bind(&fast); | 656 __ bind(&fast); |
619 // Check that the maps starting from the prototype haven't changed. | 657 // Check that the maps starting from the prototype haven't changed. |
620 GenerateLoadGlobalFunctionPrototype(masm(), | 658 GenerateLoadGlobalFunctionPrototype(masm(), |
621 Context::BOOLEAN_FUNCTION_INDEX, | 659 Context::BOOLEAN_FUNCTION_INDEX, |
622 r2); | 660 r2); |
623 __ CheckMaps(JSObject::cast(object->GetPrototype()), | 661 CheckPrototypes(JSObject::cast(object->GetPrototype()), r2, holder, r3, |
624 r2, holder, r3, r1, &miss); | 662 r1, name, &miss); |
625 break; | 663 break; |
626 } | 664 } |
627 | 665 |
628 case JSARRAY_HAS_FAST_ELEMENTS_CHECK: | 666 case JSARRAY_HAS_FAST_ELEMENTS_CHECK: |
629 __ CheckMaps(JSObject::cast(object), r1, holder, r3, r2, &miss); | 667 CheckPrototypes(JSObject::cast(object), r1, holder, r3, r2, name, &miss); |
630 // Make sure object->elements()->map() != Heap::hash_table_map() | 668 // Make sure object->elements()->map() != Heap::hash_table_map() |
631 // Get the elements array of the object. | 669 // Get the elements array of the object. |
632 __ ldr(r3, FieldMemOperand(r1, JSObject::kElementsOffset)); | 670 __ ldr(r3, FieldMemOperand(r1, JSObject::kElementsOffset)); |
633 // Check that the object is in fast mode (not dictionary). | 671 // Check that the object is in fast mode (not dictionary). |
634 __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); | 672 __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); |
635 __ cmp(r2, Operand(Factory::hash_table_map())); | 673 __ cmp(r2, Operand(Factory::hash_table_map())); |
636 __ b(eq, &miss); | 674 __ b(eq, &miss); |
637 break; | 675 break; |
638 | 676 |
639 default: | 677 default: |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
705 | 743 |
706 // If the object is the holder then we know that it's a global | 744 // If the object is the holder then we know that it's a global |
707 // object which can only happen for contextual calls. In this case, | 745 // object which can only happen for contextual calls. In this case, |
708 // the receiver cannot be a smi. | 746 // the receiver cannot be a smi. |
709 if (object != holder) { | 747 if (object != holder) { |
710 __ tst(r0, Operand(kSmiTagMask)); | 748 __ tst(r0, Operand(kSmiTagMask)); |
711 __ b(eq, &miss); | 749 __ b(eq, &miss); |
712 } | 750 } |
713 | 751 |
714 // Check that the maps haven't changed. | 752 // Check that the maps haven't changed. |
715 masm()->CheckMaps(object, r0, holder, r3, r2, &miss); | 753 CheckPrototypes(object, r0, holder, r3, r2, name, &miss); |
716 | 754 |
717 // Get the value from the cell. | 755 // Get the value from the cell. |
718 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); | 756 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); |
719 __ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | 757 __ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); |
720 | 758 |
721 // Check that the cell contains the same function. | 759 // Check that the cell contains the same function. |
722 __ cmp(r1, Operand(Handle<JSFunction>(function))); | 760 __ cmp(r1, Operand(Handle<JSFunction>(function))); |
723 __ b(ne, &miss); | 761 __ b(ne, &miss); |
724 | 762 |
725 // Patch the receiver on the stack with the global proxy if | 763 // Patch the receiver on the stack with the global proxy if |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
934 String* name) { | 972 String* name) { |
935 // ----------- S t a t e ------------- | 973 // ----------- S t a t e ------------- |
936 // -- r2 : name | 974 // -- r2 : name |
937 // -- lr : return address | 975 // -- lr : return address |
938 // -- [sp] : receiver | 976 // -- [sp] : receiver |
939 // ----------------------------------- | 977 // ----------------------------------- |
940 Label miss; | 978 Label miss; |
941 | 979 |
942 __ ldr(r0, MemOperand(sp, 0)); | 980 __ ldr(r0, MemOperand(sp, 0)); |
943 | 981 |
944 GenerateLoadField(masm(), object, holder, r0, r3, r1, index, &miss); | 982 GenerateLoadField(object, holder, r0, r3, r1, index, name, &miss); |
945 __ bind(&miss); | 983 __ bind(&miss); |
946 GenerateLoadMiss(masm(), Code::LOAD_IC); | 984 GenerateLoadMiss(masm(), Code::LOAD_IC); |
947 | 985 |
948 // Return the generated code. | 986 // Return the generated code. |
949 return GetCode(FIELD, name); | 987 return GetCode(FIELD, name); |
950 } | 988 } |
951 | 989 |
952 | 990 |
953 Object* LoadStubCompiler::CompileLoadCallback(JSObject* object, | 991 Object* LoadStubCompiler::CompileLoadCallback(JSObject* object, |
954 JSObject* holder, | 992 JSObject* holder, |
955 AccessorInfo* callback, | 993 AccessorInfo* callback, |
956 String* name) { | 994 String* name) { |
957 // ----------- S t a t e ------------- | 995 // ----------- S t a t e ------------- |
958 // -- r2 : name | 996 // -- r2 : name |
959 // -- lr : return address | 997 // -- lr : return address |
960 // -- [sp] : receiver | 998 // -- [sp] : receiver |
961 // ----------------------------------- | 999 // ----------------------------------- |
962 Label miss; | 1000 Label miss; |
963 | 1001 |
964 __ ldr(r0, MemOperand(sp, 0)); | 1002 __ ldr(r0, MemOperand(sp, 0)); |
965 GenerateLoadCallback(masm(), object, holder, r0, r2, r3, r1, callback, &miss); | 1003 GenerateLoadCallback(object, holder, r0, r2, r3, r1, callback, name, &miss); |
966 __ bind(&miss); | 1004 __ bind(&miss); |
967 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1005 GenerateLoadMiss(masm(), Code::LOAD_IC); |
968 | 1006 |
969 // Return the generated code. | 1007 // Return the generated code. |
970 return GetCode(CALLBACKS, name); | 1008 return GetCode(CALLBACKS, name); |
971 } | 1009 } |
972 | 1010 |
973 | 1011 |
974 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 1012 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, |
975 JSObject* holder, | 1013 JSObject* holder, |
976 Object* value, | 1014 Object* value, |
977 String* name) { | 1015 String* name) { |
978 // ----------- S t a t e ------------- | 1016 // ----------- S t a t e ------------- |
979 // -- r2 : name | 1017 // -- r2 : name |
980 // -- lr : return address | 1018 // -- lr : return address |
981 // -- [sp] : receiver | 1019 // -- [sp] : receiver |
982 // ----------------------------------- | 1020 // ----------------------------------- |
983 Label miss; | 1021 Label miss; |
984 | 1022 |
985 __ ldr(r0, MemOperand(sp, 0)); | 1023 __ ldr(r0, MemOperand(sp, 0)); |
986 | 1024 |
987 GenerateLoadConstant(masm(), object, holder, r0, r3, r1, value, &miss); | 1025 GenerateLoadConstant(object, holder, r0, r3, r1, value, name, &miss); |
988 __ bind(&miss); | 1026 __ bind(&miss); |
989 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1027 GenerateLoadMiss(masm(), Code::LOAD_IC); |
990 | 1028 |
991 // Return the generated code. | 1029 // Return the generated code. |
992 return GetCode(CONSTANT_FUNCTION, name); | 1030 return GetCode(CONSTANT_FUNCTION, name); |
993 } | 1031 } |
994 | 1032 |
995 | 1033 |
996 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, | 1034 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, |
997 JSObject* holder, | 1035 JSObject* holder, |
998 String* name) { | 1036 String* name) { |
999 // ----------- S t a t e ------------- | 1037 // ----------- S t a t e ------------- |
1000 // -- r2 : name | 1038 // -- r2 : name |
1001 // -- lr : return address | 1039 // -- lr : return address |
1002 // -- [sp] : receiver | 1040 // -- [sp] : receiver |
1003 // ----------------------------------- | 1041 // ----------------------------------- |
1004 Label miss; | 1042 Label miss; |
1005 | 1043 |
1006 __ ldr(r0, MemOperand(sp, 0)); | 1044 __ ldr(r0, MemOperand(sp, 0)); |
1007 | 1045 |
1008 GenerateLoadInterceptor(masm(), | 1046 GenerateLoadInterceptor(object, |
1009 object, | |
1010 holder, | 1047 holder, |
1011 holder->InterceptorPropertyLookupHint(name), | 1048 holder->InterceptorPropertyLookupHint(name), |
1012 r0, | 1049 r0, |
1013 r2, | 1050 r2, |
1014 r3, | 1051 r3, |
1015 r1, | 1052 r1, |
1053 name, | |
1016 &miss); | 1054 &miss); |
1017 __ bind(&miss); | 1055 __ bind(&miss); |
1018 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1056 GenerateLoadMiss(masm(), Code::LOAD_IC); |
1019 | 1057 |
1020 // Return the generated code. | 1058 // Return the generated code. |
1021 return GetCode(INTERCEPTOR, name); | 1059 return GetCode(INTERCEPTOR, name); |
1022 } | 1060 } |
1023 | 1061 |
1024 | 1062 |
1025 Object* LoadStubCompiler::CompileLoadGlobal(JSObject* object, | 1063 Object* LoadStubCompiler::CompileLoadGlobal(JSObject* object, |
(...skipping 15 matching lines...) Expand all Loading... | |
1041 | 1079 |
1042 // If the object is the holder then we know that it's a global | 1080 // If the object is the holder then we know that it's a global |
1043 // object which can only happen for contextual calls. In this case, | 1081 // object which can only happen for contextual calls. In this case, |
1044 // the receiver cannot be a smi. | 1082 // the receiver cannot be a smi. |
1045 if (object != holder) { | 1083 if (object != holder) { |
1046 __ tst(r1, Operand(kSmiTagMask)); | 1084 __ tst(r1, Operand(kSmiTagMask)); |
1047 __ b(eq, &miss); | 1085 __ b(eq, &miss); |
1048 } | 1086 } |
1049 | 1087 |
1050 // Check that the map of the global has not changed. | 1088 // Check that the map of the global has not changed. |
1051 masm()->CheckMaps(object, r1, holder, r3, r0, &miss); | 1089 CheckPrototypes(object, r1, holder, r3, r0, name, &miss); |
1052 | 1090 |
1053 // Get the value from the cell. | 1091 // Get the value from the cell. |
1054 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); | 1092 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); |
1055 __ ldr(r0, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); | 1093 __ ldr(r0, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); |
1056 | 1094 |
1057 // Check for deleted property if property can actually be deleted. | 1095 // Check for deleted property if property can actually be deleted. |
1058 if (!is_dont_delete) { | 1096 if (!is_dont_delete) { |
1059 __ cmp(r0, Operand(Factory::the_hole_value())); | 1097 __ cmp(r0, Operand(Factory::the_hole_value())); |
1060 __ b(eq, &miss); | 1098 __ b(eq, &miss); |
1061 } | 1099 } |
(...skipping 22 matching lines...) Expand all Loading... | |
1084 // -- sp[4] : receiver | 1122 // -- sp[4] : receiver |
1085 // ----------------------------------- | 1123 // ----------------------------------- |
1086 Label miss; | 1124 Label miss; |
1087 | 1125 |
1088 __ ldr(r2, MemOperand(sp, 0)); | 1126 __ ldr(r2, MemOperand(sp, 0)); |
1089 __ ldr(r0, MemOperand(sp, kPointerSize)); | 1127 __ ldr(r0, MemOperand(sp, kPointerSize)); |
1090 | 1128 |
1091 __ cmp(r2, Operand(Handle<String>(name))); | 1129 __ cmp(r2, Operand(Handle<String>(name))); |
1092 __ b(ne, &miss); | 1130 __ b(ne, &miss); |
1093 | 1131 |
1094 GenerateLoadField(masm(), receiver, holder, r0, r3, r1, index, &miss); | 1132 GenerateLoadField(receiver, holder, r0, r3, r1, index, name, &miss); |
1095 __ bind(&miss); | 1133 __ bind(&miss); |
1096 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1134 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1097 | 1135 |
1098 return GetCode(FIELD, name); | 1136 return GetCode(FIELD, name); |
1099 } | 1137 } |
1100 | 1138 |
1101 | 1139 |
1102 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, | 1140 Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, |
1103 JSObject* receiver, | 1141 JSObject* receiver, |
1104 JSObject* holder, | 1142 JSObject* holder, |
1105 AccessorInfo* callback) { | 1143 AccessorInfo* callback) { |
1106 // ----------- S t a t e ------------- | 1144 // ----------- S t a t e ------------- |
1107 // -- lr : return address | 1145 // -- lr : return address |
1108 // -- sp[0] : key | 1146 // -- sp[0] : key |
1109 // -- sp[4] : receiver | 1147 // -- sp[4] : receiver |
1110 // ----------------------------------- | 1148 // ----------------------------------- |
1111 Label miss; | 1149 Label miss; |
1112 | 1150 |
1113 __ ldr(r2, MemOperand(sp, 0)); | 1151 __ ldr(r2, MemOperand(sp, 0)); |
1114 __ ldr(r0, MemOperand(sp, kPointerSize)); | 1152 __ ldr(r0, MemOperand(sp, kPointerSize)); |
1115 | 1153 |
1116 __ cmp(r2, Operand(Handle<String>(name))); | 1154 __ cmp(r2, Operand(Handle<String>(name))); |
1117 __ b(ne, &miss); | 1155 __ b(ne, &miss); |
1118 | 1156 |
1119 GenerateLoadCallback(masm(), receiver, holder, r0, r2, r3, | 1157 GenerateLoadCallback(receiver, holder, r0, r2, r3, r1, callback, name, &miss); |
1120 r1, callback, &miss); | |
1121 __ bind(&miss); | 1158 __ bind(&miss); |
1122 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1159 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1123 | 1160 |
1124 return GetCode(CALLBACKS, name); | 1161 return GetCode(CALLBACKS, name); |
1125 } | 1162 } |
1126 | 1163 |
1127 | 1164 |
1128 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, | 1165 Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, |
1129 JSObject* receiver, | 1166 JSObject* receiver, |
1130 JSObject* holder, | 1167 JSObject* holder, |
1131 Object* value) { | 1168 Object* value) { |
1132 // ----------- S t a t e ------------- | 1169 // ----------- S t a t e ------------- |
1133 // -- lr : return address | 1170 // -- lr : return address |
1134 // -- sp[0] : key | 1171 // -- sp[0] : key |
1135 // -- sp[4] : receiver | 1172 // -- sp[4] : receiver |
1136 // ----------------------------------- | 1173 // ----------------------------------- |
1137 Label miss; | 1174 Label miss; |
1138 | 1175 |
1139 // Check the key is the cached one | 1176 // Check the key is the cached one |
1140 __ ldr(r2, MemOperand(sp, 0)); | 1177 __ ldr(r2, MemOperand(sp, 0)); |
1141 __ ldr(r0, MemOperand(sp, kPointerSize)); | 1178 __ ldr(r0, MemOperand(sp, kPointerSize)); |
1142 | 1179 |
1143 __ cmp(r2, Operand(Handle<String>(name))); | 1180 __ cmp(r2, Operand(Handle<String>(name))); |
1144 __ b(ne, &miss); | 1181 __ b(ne, &miss); |
1145 | 1182 |
1146 GenerateLoadConstant(masm(), receiver, holder, r0, r3, r1, value, &miss); | 1183 GenerateLoadConstant(receiver, holder, r0, r3, r1, value, name, &miss); |
1147 __ bind(&miss); | 1184 __ bind(&miss); |
1148 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1185 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1149 | 1186 |
1150 // Return the generated code. | 1187 // Return the generated code. |
1151 return GetCode(CONSTANT_FUNCTION, name); | 1188 return GetCode(CONSTANT_FUNCTION, name); |
1152 } | 1189 } |
1153 | 1190 |
1154 | 1191 |
1155 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 1192 Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
1156 JSObject* holder, | 1193 JSObject* holder, |
1157 String* name) { | 1194 String* name) { |
1158 // ----------- S t a t e ------------- | 1195 // ----------- S t a t e ------------- |
1159 // -- lr : return address | 1196 // -- lr : return address |
1160 // -- sp[0] : key | 1197 // -- sp[0] : key |
1161 // -- sp[4] : receiver | 1198 // -- sp[4] : receiver |
1162 // ----------------------------------- | 1199 // ----------------------------------- |
1163 Label miss; | 1200 Label miss; |
1164 | 1201 |
1165 // Check the key is the cached one | 1202 // Check the key is the cached one |
1166 __ ldr(r2, MemOperand(sp, 0)); | 1203 __ ldr(r2, MemOperand(sp, 0)); |
1167 __ ldr(r0, MemOperand(sp, kPointerSize)); | 1204 __ ldr(r0, MemOperand(sp, kPointerSize)); |
1168 | 1205 |
1169 __ cmp(r2, Operand(Handle<String>(name))); | 1206 __ cmp(r2, Operand(Handle<String>(name))); |
1170 __ b(ne, &miss); | 1207 __ b(ne, &miss); |
1171 | 1208 |
1172 GenerateLoadInterceptor(masm(), | 1209 GenerateLoadInterceptor(receiver, |
1173 receiver, | |
1174 holder, | 1210 holder, |
1175 Smi::FromInt(JSObject::kLookupInHolder), | 1211 Smi::FromInt(JSObject::kLookupInHolder), |
1176 r0, | 1212 r0, |
1177 r2, | 1213 r2, |
1178 r3, | 1214 r3, |
1179 r1, | 1215 r1, |
1216 name, | |
1180 &miss); | 1217 &miss); |
1181 __ bind(&miss); | 1218 __ bind(&miss); |
1182 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1219 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1183 | 1220 |
1184 return GetCode(INTERCEPTOR, name); | 1221 return GetCode(INTERCEPTOR, name); |
1185 } | 1222 } |
1186 | 1223 |
1187 | 1224 |
1188 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { | 1225 Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { |
1189 // ----------- S t a t e ------------- | 1226 // ----------- S t a t e ------------- |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1282 __ Jump(ic, RelocInfo::CODE_TARGET); | 1319 __ Jump(ic, RelocInfo::CODE_TARGET); |
1283 | 1320 |
1284 // Return the generated code. | 1321 // Return the generated code. |
1285 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 1322 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
1286 } | 1323 } |
1287 | 1324 |
1288 | 1325 |
1289 #undef __ | 1326 #undef __ |
1290 | 1327 |
1291 } } // namespace v8::internal | 1328 } } // namespace v8::internal |
OLD | NEW |