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 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 code = Builtins::builtin(Builtins::LoadIC_Miss); | 355 code = Builtins::builtin(Builtins::LoadIC_Miss); |
356 } else { | 356 } else { |
357 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); | 357 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); |
358 } | 358 } |
359 | 359 |
360 Handle<Code> ic(code); | 360 Handle<Code> ic(code); |
361 __ Jump(ic, RelocInfo::CODE_TARGET); | 361 __ Jump(ic, RelocInfo::CODE_TARGET); |
362 } | 362 } |
363 | 363 |
364 | 364 |
| 365 static void GenerateCallFunction(MacroAssembler* masm, |
| 366 Object* object, |
| 367 const ParameterCount& arguments, |
| 368 Label* miss) { |
| 369 // ----------- S t a t e ------------- |
| 370 // -- r0: receiver |
| 371 // -- r1: function to call |
| 372 // ----------------------------------- |
| 373 |
| 374 // Check that the function really is a function. |
| 375 __ BranchOnSmi(r1, miss); |
| 376 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); |
| 377 __ b(ne, miss); |
| 378 |
| 379 // Patch the receiver on the stack with the global proxy if |
| 380 // necessary. |
| 381 if (object->IsGlobalObject()) { |
| 382 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); |
| 383 __ str(r3, MemOperand(sp, arguments.immediate() * kPointerSize)); |
| 384 } |
| 385 |
| 386 // Invoke the function. |
| 387 __ InvokeFunction(r1, arguments, JUMP_FUNCTION); |
| 388 } |
| 389 |
| 390 |
| 391 static void GenerateCallConstFunction(MacroAssembler* masm, |
| 392 JSFunction* function, |
| 393 const ParameterCount& arguments) { |
| 394 ASSERT(function->is_compiled()); |
| 395 |
| 396 // Get the function and setup the context. |
| 397 __ mov(r1, Operand(Handle<JSFunction>(function))); |
| 398 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 399 |
| 400 // Jump to the cached code (tail call). |
| 401 Handle<Code> code(function->code()); |
| 402 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 403 __ InvokeCode(code, expected, arguments, |
| 404 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
| 405 } |
| 406 |
| 407 |
| 408 template <class Compiler> |
| 409 static void CompileLoadInterceptor(Compiler* compiler, |
| 410 StubCompiler* stub_compiler, |
| 411 MacroAssembler* masm, |
| 412 JSObject* object, |
| 413 JSObject* holder, |
| 414 String* name, |
| 415 LookupResult* lookup, |
| 416 Register receiver, |
| 417 Register scratch1, |
| 418 Register scratch2, |
| 419 Label* miss) { |
| 420 ASSERT(holder->HasNamedInterceptor()); |
| 421 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
| 422 |
| 423 // Check that the receiver isn't a smi. |
| 424 __ BranchOnSmi(receiver, miss); |
| 425 |
| 426 // Check that the maps haven't changed. |
| 427 Register reg = |
| 428 stub_compiler->CheckPrototypes(object, receiver, holder, |
| 429 scratch1, scratch2, name, miss); |
| 430 |
| 431 if (lookup->IsValid() && lookup->IsCacheable()) { |
| 432 compiler->CompileCacheable(masm, |
| 433 stub_compiler, |
| 434 receiver, |
| 435 reg, |
| 436 scratch1, |
| 437 scratch2, |
| 438 holder, |
| 439 lookup, |
| 440 name, |
| 441 miss); |
| 442 } else { |
| 443 compiler->CompileRegular(masm, |
| 444 receiver, |
| 445 reg, |
| 446 scratch2, |
| 447 holder, |
| 448 miss); |
| 449 } |
| 450 } |
| 451 |
| 452 |
| 453 static void PushInterceptorArguments(MacroAssembler* masm, |
| 454 Register receiver, |
| 455 Register holder, |
| 456 Register name, |
| 457 JSObject* holder_obj) { |
| 458 __ push(receiver); |
| 459 __ push(holder); |
| 460 __ push(name); |
| 461 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); |
| 462 ASSERT(!Heap::InNewSpace(interceptor)); |
| 463 |
| 464 Register scratch = receiver; |
| 465 __ mov(scratch, Operand(Handle<Object>(interceptor))); |
| 466 __ push(scratch); |
| 467 __ ldr(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset)); |
| 468 __ push(scratch); |
| 469 } |
| 470 |
| 471 |
| 472 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, |
| 473 Register receiver, |
| 474 Register holder, |
| 475 Register name, |
| 476 JSObject* holder_obj) { |
| 477 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); |
| 478 |
| 479 ExternalReference ref = |
| 480 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly)); |
| 481 __ mov(r0, Operand(5)); |
| 482 __ mov(r1, Operand(ref)); |
| 483 |
| 484 CEntryStub stub(1); |
| 485 __ CallStub(&stub); |
| 486 } |
| 487 |
| 488 |
| 489 class LoadInterceptorCompiler BASE_EMBEDDED { |
| 490 public: |
| 491 explicit LoadInterceptorCompiler(Register name) : name_(name) {} |
| 492 |
| 493 void CompileCacheable(MacroAssembler* masm, |
| 494 StubCompiler* stub_compiler, |
| 495 Register receiver, |
| 496 Register holder, |
| 497 Register scratch1, |
| 498 Register scratch2, |
| 499 JSObject* holder_obj, |
| 500 LookupResult* lookup, |
| 501 String* name, |
| 502 Label* miss_label) { |
| 503 AccessorInfo* callback = 0; |
| 504 bool optimize = false; |
| 505 // So far the most popular follow ups for interceptor loads are FIELD |
| 506 // and CALLBACKS, so inline only them, other cases may be added |
| 507 // later. |
| 508 if (lookup->type() == FIELD) { |
| 509 optimize = true; |
| 510 } else if (lookup->type() == CALLBACKS) { |
| 511 Object* callback_object = lookup->GetCallbackObject(); |
| 512 if (callback_object->IsAccessorInfo()) { |
| 513 callback = AccessorInfo::cast(callback_object); |
| 514 optimize = callback->getter() != NULL; |
| 515 } |
| 516 } |
| 517 |
| 518 if (!optimize) { |
| 519 CompileRegular(masm, receiver, holder, scratch2, holder_obj, miss_label); |
| 520 return; |
| 521 } |
| 522 |
| 523 // Note: starting a frame here makes GC aware of pointers pushed below. |
| 524 __ EnterInternalFrame(); |
| 525 |
| 526 if (lookup->type() == CALLBACKS) { |
| 527 __ push(receiver); |
| 528 } |
| 529 __ push(holder); |
| 530 __ push(name_); |
| 531 |
| 532 CompileCallLoadPropertyWithInterceptor(masm, |
| 533 receiver, |
| 534 holder, |
| 535 name_, |
| 536 holder_obj); |
| 537 |
| 538 Label interceptor_failed; |
| 539 // Compare with no_interceptor_result_sentinel. |
| 540 __ LoadRoot(scratch1, Heap::kNoInterceptorResultSentinelRootIndex); |
| 541 __ cmp(r0, scratch1); |
| 542 __ b(eq, &interceptor_failed); |
| 543 __ LeaveInternalFrame(); |
| 544 __ Ret(); |
| 545 |
| 546 __ bind(&interceptor_failed); |
| 547 __ pop(name_); |
| 548 __ pop(holder); |
| 549 |
| 550 if (lookup->type() == CALLBACKS) { |
| 551 __ pop(receiver); |
| 552 } |
| 553 |
| 554 __ LeaveInternalFrame(); |
| 555 |
| 556 if (lookup->type() == FIELD) { |
| 557 holder = stub_compiler->CheckPrototypes(holder_obj, |
| 558 holder, |
| 559 lookup->holder(), |
| 560 scratch1, |
| 561 scratch2, |
| 562 name, |
| 563 miss_label); |
| 564 stub_compiler->GenerateFastPropertyLoad(masm, |
| 565 r0, |
| 566 holder, |
| 567 lookup->holder(), |
| 568 lookup->GetFieldIndex()); |
| 569 __ Ret(); |
| 570 } else { |
| 571 ASSERT(lookup->type() == CALLBACKS); |
| 572 ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); |
| 573 ASSERT(callback != NULL); |
| 574 ASSERT(callback->getter() != NULL); |
| 575 |
| 576 Label cleanup; |
| 577 __ pop(scratch2); |
| 578 __ push(receiver); |
| 579 __ push(scratch2); |
| 580 |
| 581 holder = stub_compiler->CheckPrototypes(holder_obj, holder, |
| 582 lookup->holder(), scratch1, |
| 583 scratch2, |
| 584 name, |
| 585 &cleanup); |
| 586 |
| 587 __ push(holder); |
| 588 __ Move(holder, Handle<AccessorInfo>(callback)); |
| 589 __ push(holder); |
| 590 __ ldr(scratch1, FieldMemOperand(holder, AccessorInfo::kDataOffset)); |
| 591 __ push(scratch1); |
| 592 __ push(name_); |
| 593 |
| 594 ExternalReference ref = |
| 595 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); |
| 596 __ TailCallRuntime(ref, 5, 1); |
| 597 |
| 598 __ bind(&cleanup); |
| 599 __ pop(scratch1); |
| 600 __ pop(scratch2); |
| 601 __ push(scratch1); |
| 602 } |
| 603 } |
| 604 |
| 605 |
| 606 void CompileRegular(MacroAssembler* masm, |
| 607 Register receiver, |
| 608 Register holder, |
| 609 Register scratch, |
| 610 JSObject* holder_obj, |
| 611 Label* miss_label) { |
| 612 PushInterceptorArguments(masm, receiver, holder, name_, holder_obj); |
| 613 |
| 614 ExternalReference ref = ExternalReference( |
| 615 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad)); |
| 616 __ TailCallRuntime(ref, 5, 1); |
| 617 } |
| 618 |
| 619 private: |
| 620 Register name_; |
| 621 }; |
| 622 |
| 623 |
| 624 class CallInterceptorCompiler BASE_EMBEDDED { |
| 625 public: |
| 626 CallInterceptorCompiler(const ParameterCount& arguments, Register name) |
| 627 : arguments_(arguments), argc_(arguments.immediate()), name_(name) {} |
| 628 |
| 629 void CompileCacheable(MacroAssembler* masm, |
| 630 StubCompiler* stub_compiler, |
| 631 Register receiver, |
| 632 Register holder, |
| 633 Register scratch1, |
| 634 Register scratch2, |
| 635 JSObject* holder_obj, |
| 636 LookupResult* lookup, |
| 637 String* name, |
| 638 Label* miss_label) { |
| 639 JSFunction* function = 0; |
| 640 bool optimize = false; |
| 641 // So far the most popular case for failed interceptor is |
| 642 // CONSTANT_FUNCTION sitting below. |
| 643 if (lookup->type() == CONSTANT_FUNCTION) { |
| 644 function = lookup->GetConstantFunction(); |
| 645 // JSArray holder is a special case for call constant function |
| 646 // (see the corresponding code). |
| 647 if (function->is_compiled() && !holder_obj->IsJSArray()) { |
| 648 optimize = true; |
| 649 } |
| 650 } |
| 651 |
| 652 if (!optimize) { |
| 653 CompileRegular(masm, receiver, holder, scratch2, holder_obj, miss_label); |
| 654 return; |
| 655 } |
| 656 |
| 657 // Constant functions cannot sit on global object. |
| 658 ASSERT(!lookup->holder()->IsGlobalObject()); |
| 659 |
| 660 __ EnterInternalFrame(); |
| 661 __ push(holder); // Save the holder. |
| 662 __ push(name_); // Save the name. |
| 663 |
| 664 CompileCallLoadPropertyWithInterceptor(masm, |
| 665 receiver, |
| 666 holder, |
| 667 name_, |
| 668 holder_obj); |
| 669 |
| 670 ASSERT(!r0.is(name_)); |
| 671 ASSERT(!r0.is(scratch1)); |
| 672 __ pop(name_); // Restore the name. |
| 673 __ pop(scratch1); // Restore the holder. |
| 674 __ LeaveInternalFrame(); |
| 675 |
| 676 // Compare with no_interceptor_result_sentinel. |
| 677 __ LoadRoot(scratch2, Heap::kNoInterceptorResultSentinelRootIndex); |
| 678 __ cmp(r0, scratch2); |
| 679 Label invoke; |
| 680 __ b(ne, &invoke); |
| 681 |
| 682 stub_compiler->CheckPrototypes(holder_obj, scratch1, |
| 683 lookup->holder(), scratch1, |
| 684 scratch2, |
| 685 name, |
| 686 miss_label); |
| 687 GenerateCallConstFunction(masm, function, arguments_); |
| 688 |
| 689 __ bind(&invoke); |
| 690 } |
| 691 |
| 692 void CompileRegular(MacroAssembler* masm, |
| 693 Register receiver, |
| 694 Register holder, |
| 695 Register scratch, |
| 696 JSObject* holder_obj, |
| 697 Label* miss_label) { |
| 698 __ EnterInternalFrame(); |
| 699 // Save the name_ register across the call. |
| 700 __ push(name_); |
| 701 |
| 702 PushInterceptorArguments(masm, |
| 703 receiver, |
| 704 holder, |
| 705 name_, |
| 706 holder_obj); |
| 707 |
| 708 ExternalReference ref = ExternalReference( |
| 709 IC_Utility(IC::kLoadPropertyWithInterceptorForCall)); |
| 710 __ mov(r0, Operand(5)); |
| 711 __ mov(r1, Operand(ref)); |
| 712 |
| 713 CEntryStub stub(1); |
| 714 __ CallStub(&stub); |
| 715 |
| 716 // Restore the name_ register. |
| 717 __ pop(name_); |
| 718 __ LeaveInternalFrame(); |
| 719 } |
| 720 |
| 721 private: |
| 722 const ParameterCount& arguments_; |
| 723 int argc_; |
| 724 Register name_; |
| 725 }; |
| 726 |
| 727 |
365 #undef __ | 728 #undef __ |
366 #define __ ACCESS_MASM(masm()) | 729 #define __ ACCESS_MASM(masm()) |
367 | 730 |
368 | 731 |
369 Register StubCompiler::CheckPrototypes(JSObject* object, | 732 Register StubCompiler::CheckPrototypes(JSObject* object, |
370 Register object_reg, | 733 Register object_reg, |
371 JSObject* holder, | 734 JSObject* holder, |
372 Register holder_reg, | 735 Register holder_reg, |
373 Register scratch, | 736 Register scratch, |
374 String* name, | 737 String* name, |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 | 847 |
485 void StubCompiler::GenerateLoadInterceptor(JSObject* object, | 848 void StubCompiler::GenerateLoadInterceptor(JSObject* object, |
486 JSObject* holder, | 849 JSObject* holder, |
487 LookupResult* lookup, | 850 LookupResult* lookup, |
488 Register receiver, | 851 Register receiver, |
489 Register name_reg, | 852 Register name_reg, |
490 Register scratch1, | 853 Register scratch1, |
491 Register scratch2, | 854 Register scratch2, |
492 String* name, | 855 String* name, |
493 Label* miss) { | 856 Label* miss) { |
494 // Check that the receiver isn't a smi. | 857 LoadInterceptorCompiler compiler(name_reg); |
495 __ tst(receiver, Operand(kSmiTagMask)); | 858 CompileLoadInterceptor(&compiler, |
496 __ b(eq, miss); | 859 this, |
497 | 860 masm(), |
498 // Check that the maps haven't changed. | 861 object, |
499 Register reg = | 862 holder, |
500 CheckPrototypes(object, receiver, holder, scratch1, scratch2, name, miss); | 863 name, |
501 | 864 lookup, |
502 // Push the arguments on the JS stack of the caller. | 865 receiver, |
503 __ push(receiver); // receiver | 866 scratch1, |
504 __ push(reg); // holder | 867 scratch2, |
505 __ push(name_reg); // name | 868 miss); |
506 | |
507 InterceptorInfo* interceptor = holder->GetNamedInterceptor(); | |
508 ASSERT(!Heap::InNewSpace(interceptor)); | |
509 __ mov(scratch1, Operand(Handle<Object>(interceptor))); | |
510 __ push(scratch1); | |
511 __ ldr(scratch2, FieldMemOperand(scratch1, InterceptorInfo::kDataOffset)); | |
512 __ push(scratch2); | |
513 | |
514 // Do tail-call to the runtime system. | |
515 ExternalReference load_ic_property = | |
516 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad)); | |
517 __ TailCallRuntime(load_ic_property, 5, 1); | |
518 } | 869 } |
519 | 870 |
520 | 871 |
521 Object* StubCompiler::CompileLazyCompile(Code::Flags flags) { | 872 Object* StubCompiler::CompileLazyCompile(Code::Flags flags) { |
522 // ----------- S t a t e ------------- | 873 // ----------- S t a t e ------------- |
523 // -- r1: function | 874 // -- r1: function |
524 // -- lr: return address | 875 // -- lr: return address |
525 // ----------------------------------- | 876 // ----------------------------------- |
526 | 877 |
527 // Enter an internal frame. | 878 // Enter an internal frame. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 916 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
566 // Check that the receiver isn't a smi. | 917 // Check that the receiver isn't a smi. |
567 __ tst(r0, Operand(kSmiTagMask)); | 918 __ tst(r0, Operand(kSmiTagMask)); |
568 __ b(eq, &miss); | 919 __ b(eq, &miss); |
569 | 920 |
570 // Do the right check and compute the holder register. | 921 // Do the right check and compute the holder register. |
571 Register reg = | 922 Register reg = |
572 CheckPrototypes(JSObject::cast(object), r0, holder, r3, r2, name, &miss); | 923 CheckPrototypes(JSObject::cast(object), r0, holder, r3, r2, name, &miss); |
573 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); | 924 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); |
574 | 925 |
575 // Check that the function really is a function. | 926 GenerateCallFunction(masm(), object, arguments(), &miss); |
576 __ tst(r1, Operand(kSmiTagMask)); | |
577 __ b(eq, &miss); | |
578 // Get the map. | |
579 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); | |
580 __ b(ne, &miss); | |
581 | |
582 // Patch the receiver on the stack with the global proxy if | |
583 // necessary. | |
584 if (object->IsGlobalObject()) { | |
585 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | |
586 __ str(r3, MemOperand(sp, argc * kPointerSize)); | |
587 } | |
588 | |
589 // Invoke the function. | |
590 __ InvokeFunction(r1, arguments(), JUMP_FUNCTION); | |
591 | 927 |
592 // Handle call cache miss. | 928 // Handle call cache miss. |
593 __ bind(&miss); | 929 __ bind(&miss); |
594 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 930 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); |
595 __ Jump(ic, RelocInfo::CODE_TARGET); | 931 __ Jump(ic, RelocInfo::CODE_TARGET); |
596 | 932 |
597 // Return the generated code. | 933 // Return the generated code. |
598 return GetCode(FIELD, name); | 934 return GetCode(FIELD, name); |
599 } | 935 } |
600 | 936 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); | 1044 __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); |
709 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); | 1045 __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); |
710 __ cmp(r2, ip); | 1046 __ cmp(r2, ip); |
711 __ b(ne, &miss); | 1047 __ b(ne, &miss); |
712 break; | 1048 break; |
713 | 1049 |
714 default: | 1050 default: |
715 UNREACHABLE(); | 1051 UNREACHABLE(); |
716 } | 1052 } |
717 | 1053 |
718 // Get the function and setup the context. | 1054 GenerateCallConstFunction(masm(), function, arguments()); |
719 __ mov(r1, Operand(Handle<JSFunction>(function))); | |
720 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | |
721 | |
722 // Jump to the cached code (tail call). | |
723 ASSERT(function->is_compiled()); | |
724 Handle<Code> code(function->code()); | |
725 ParameterCount expected(function->shared()->formal_parameter_count()); | |
726 __ InvokeCode(code, expected, arguments(), | |
727 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | |
728 | 1055 |
729 // Handle call cache miss. | 1056 // Handle call cache miss. |
730 __ bind(&miss); | 1057 __ bind(&miss); |
731 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 1058 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); |
732 __ Jump(ic, RelocInfo::CODE_TARGET); | 1059 __ Jump(ic, RelocInfo::CODE_TARGET); |
733 | 1060 |
734 // Return the generated code. | 1061 // Return the generated code. |
735 String* function_name = NULL; | 1062 String* function_name = NULL; |
736 if (function->shared()->name()->IsString()) { | 1063 if (function->shared()->name()->IsString()) { |
737 function_name = String::cast(function->shared()->name()); | 1064 function_name = String::cast(function->shared()->name()); |
738 } | 1065 } |
739 return GetCode(CONSTANT_FUNCTION, function_name); | 1066 return GetCode(CONSTANT_FUNCTION, function_name); |
740 } | 1067 } |
741 | 1068 |
742 | 1069 |
743 Object* CallStubCompiler::CompileCallInterceptor(Object* object, | 1070 Object* CallStubCompiler::CompileCallInterceptor(Object* object, |
744 JSObject* holder, | 1071 JSObject* holder, |
745 String* name) { | 1072 String* name) { |
746 // ----------- S t a t e ------------- | 1073 // ----------- S t a t e ------------- |
747 // -- lr: return address | 1074 // -- lr: return address |
748 // ----------------------------------- | 1075 // ----------------------------------- |
749 Label miss; | 1076 Label miss; |
750 | 1077 |
751 // TODO(1224669): Implement. | 1078 // Get the number of arguments. |
| 1079 const int argc = arguments().immediate(); |
| 1080 |
| 1081 LookupResult lookup; |
| 1082 LookupPostInterceptor(holder, name, &lookup); |
| 1083 |
| 1084 // Get the receiver from the stack into r0. |
| 1085 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 1086 // Load the name from the stack into r1. |
| 1087 __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize)); |
| 1088 |
| 1089 CallInterceptorCompiler compiler(arguments(), r1); |
| 1090 CompileLoadInterceptor(&compiler, |
| 1091 this, |
| 1092 masm(), |
| 1093 JSObject::cast(object), |
| 1094 holder, |
| 1095 name, |
| 1096 &lookup, |
| 1097 r0, |
| 1098 r2, |
| 1099 r3, |
| 1100 &miss); |
| 1101 |
| 1102 // Restore receiver. |
| 1103 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 1104 |
| 1105 GenerateCallFunction(masm(), object, arguments(), &miss); |
752 | 1106 |
753 // Handle call cache miss. | 1107 // Handle call cache miss. |
754 __ bind(&miss); | 1108 __ bind(&miss); |
755 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 1109 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); |
756 __ Jump(ic, RelocInfo::CODE_TARGET); | 1110 __ Jump(ic, RelocInfo::CODE_TARGET); |
757 | 1111 |
758 // Return the generated code. | 1112 // Return the generated code. |
759 return GetCode(INTERCEPTOR, name); | 1113 return GetCode(INTERCEPTOR, name); |
760 } | 1114 } |
761 | 1115 |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1092 // ----------- S t a t e ------------- | 1446 // ----------- S t a t e ------------- |
1093 // -- r2 : name | 1447 // -- r2 : name |
1094 // -- lr : return address | 1448 // -- lr : return address |
1095 // -- [sp] : receiver | 1449 // -- [sp] : receiver |
1096 // ----------------------------------- | 1450 // ----------------------------------- |
1097 Label miss; | 1451 Label miss; |
1098 | 1452 |
1099 __ ldr(r0, MemOperand(sp, 0)); | 1453 __ ldr(r0, MemOperand(sp, 0)); |
1100 | 1454 |
1101 LookupResult lookup; | 1455 LookupResult lookup; |
1102 holder->LocalLookupRealNamedProperty(name, &lookup); | 1456 LookupPostInterceptor(holder, name, &lookup); |
1103 GenerateLoadInterceptor(object, | 1457 GenerateLoadInterceptor(object, |
1104 holder, | 1458 holder, |
1105 &lookup, | 1459 &lookup, |
1106 r0, | 1460 r0, |
1107 r2, | 1461 r2, |
1108 r3, | 1462 r3, |
1109 r1, | 1463 r1, |
1110 name, | 1464 name, |
1111 &miss); | 1465 &miss); |
1112 __ bind(&miss); | 1466 __ bind(&miss); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1258 Label miss; | 1612 Label miss; |
1259 | 1613 |
1260 // Check the key is the cached one | 1614 // Check the key is the cached one |
1261 __ ldr(r2, MemOperand(sp, 0)); | 1615 __ ldr(r2, MemOperand(sp, 0)); |
1262 __ ldr(r0, MemOperand(sp, kPointerSize)); | 1616 __ ldr(r0, MemOperand(sp, kPointerSize)); |
1263 | 1617 |
1264 __ cmp(r2, Operand(Handle<String>(name))); | 1618 __ cmp(r2, Operand(Handle<String>(name))); |
1265 __ b(ne, &miss); | 1619 __ b(ne, &miss); |
1266 | 1620 |
1267 LookupResult lookup; | 1621 LookupResult lookup; |
1268 holder->LocalLookupRealNamedProperty(name, &lookup); | 1622 LookupPostInterceptor(holder, name, &lookup); |
1269 GenerateLoadInterceptor(receiver, | 1623 GenerateLoadInterceptor(receiver, |
1270 holder, | 1624 holder, |
1271 &lookup, | 1625 &lookup, |
1272 r0, | 1626 r0, |
1273 r2, | 1627 r2, |
1274 r3, | 1628 r3, |
1275 r1, | 1629 r1, |
1276 name, | 1630 name, |
1277 &miss); | 1631 &miss); |
1278 __ bind(&miss); | 1632 __ bind(&miss); |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1522 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 1876 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
1523 | 1877 |
1524 // Return the generated code. | 1878 // Return the generated code. |
1525 return GetCode(); | 1879 return GetCode(); |
1526 } | 1880 } |
1527 | 1881 |
1528 | 1882 |
1529 #undef __ | 1883 #undef __ |
1530 | 1884 |
1531 } } // namespace v8::internal | 1885 } } // namespace v8::internal |
OLD | NEW |