| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 } | 472 } |
| 473 | 473 |
| 474 | 474 |
| 475 // Defined in ic.cc. | 475 // Defined in ic.cc. |
| 476 Object* CallIC_Miss(Arguments args); | 476 Object* CallIC_Miss(Arguments args); |
| 477 | 477 |
| 478 // The generated code does not accept smi keys. | 478 // The generated code does not accept smi keys. |
| 479 // The generated code falls through if both probes miss. | 479 // The generated code falls through if both probes miss. |
| 480 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, | 480 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, |
| 481 int argc, | 481 int argc, |
| 482 Code::Kind kind) { | 482 Code::Kind kind, |
| 483 Code::ExtraICState extra_ic_state) { |
| 483 // ----------- S t a t e ------------- | 484 // ----------- S t a t e ------------- |
| 484 // -- r1 : receiver | 485 // -- r1 : receiver |
| 485 // -- r2 : name | 486 // -- r2 : name |
| 486 // ----------------------------------- | 487 // ----------------------------------- |
| 487 Label number, non_number, non_string, boolean, probe, miss; | 488 Label number, non_number, non_string, boolean, probe, miss; |
| 488 | 489 |
| 489 // Probe the stub cache. | 490 // Probe the stub cache. |
| 490 Code::Flags flags = Code::ComputeFlags(kind, | 491 Code::Flags flags = Code::ComputeFlags(kind, |
| 491 NOT_IN_LOOP, | 492 NOT_IN_LOOP, |
| 492 MONOMORPHIC, | 493 MONOMORPHIC, |
| 493 Code::kNoExtraICState, | 494 extra_ic_state, |
| 494 NORMAL, | 495 NORMAL, |
| 495 argc); | 496 argc); |
| 496 Isolate::Current()->stub_cache()->GenerateProbe( | 497 Isolate::Current()->stub_cache()->GenerateProbe( |
| 497 masm, flags, r1, r2, r3, r4, r5); | 498 masm, flags, r1, r2, r3, r4, r5); |
| 498 | 499 |
| 499 // If the stub cache probing failed, the receiver might be a value. | 500 // If the stub cache probing failed, the receiver might be a value. |
| 500 // For value objects, we use the map of the prototype objects for | 501 // For value objects, we use the map of the prototype objects for |
| 501 // the corresponding JSValue for the cache and that is what we need | 502 // the corresponding JSValue for the cache and that is what we need |
| 502 // to probe. | 503 // to probe. |
| 503 // | 504 // |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 // r0: elements | 576 // r0: elements |
| 576 // Search the dictionary - put result in register r1. | 577 // Search the dictionary - put result in register r1. |
| 577 GenerateDictionaryLoad(masm, &miss, r0, r2, r1, r3, r4); | 578 GenerateDictionaryLoad(masm, &miss, r0, r2, r1, r3, r4); |
| 578 | 579 |
| 579 GenerateFunctionTailCall(masm, argc, &miss, r4); | 580 GenerateFunctionTailCall(masm, argc, &miss, r4); |
| 580 | 581 |
| 581 __ bind(&miss); | 582 __ bind(&miss); |
| 582 } | 583 } |
| 583 | 584 |
| 584 | 585 |
| 585 static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) { | 586 static void GenerateCallMiss(MacroAssembler* masm, |
| 587 int argc, |
| 588 IC::UtilityId id, |
| 589 Code::ExtraICState extra_ic_state) { |
| 586 // ----------- S t a t e ------------- | 590 // ----------- S t a t e ------------- |
| 587 // -- r2 : name | 591 // -- r2 : name |
| 588 // -- lr : return address | 592 // -- lr : return address |
| 589 // ----------------------------------- | 593 // ----------------------------------- |
| 590 Isolate* isolate = masm->isolate(); | 594 Isolate* isolate = masm->isolate(); |
| 591 | 595 |
| 592 if (id == IC::kCallIC_Miss) { | 596 if (id == IC::kCallIC_Miss) { |
| 593 __ IncrementCounter(isolate->counters()->call_miss(), 1, r3, r4); | 597 __ IncrementCounter(isolate->counters()->call_miss(), 1, r3, r4); |
| 594 } else { | 598 } else { |
| 595 __ IncrementCounter(isolate->counters()->keyed_call_miss(), 1, r3, r4); | 599 __ IncrementCounter(isolate->counters()->keyed_call_miss(), 1, r3, r4); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 __ b(ne, &invoke); | 631 __ b(ne, &invoke); |
| 628 | 632 |
| 629 // Patch the receiver on the stack. | 633 // Patch the receiver on the stack. |
| 630 __ bind(&global); | 634 __ bind(&global); |
| 631 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); | 635 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); |
| 632 __ str(r2, MemOperand(sp, argc * kPointerSize)); | 636 __ str(r2, MemOperand(sp, argc * kPointerSize)); |
| 633 __ bind(&invoke); | 637 __ bind(&invoke); |
| 634 } | 638 } |
| 635 | 639 |
| 636 // Invoke the function. | 640 // Invoke the function. |
| 641 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state) |
| 642 ? CALL_AS_FUNCTION |
| 643 : CALL_AS_METHOD; |
| 637 ParameterCount actual(argc); | 644 ParameterCount actual(argc); |
| 638 __ InvokeFunction(r1, actual, JUMP_FUNCTION); | 645 __ InvokeFunction(r1, |
| 646 actual, |
| 647 JUMP_FUNCTION, |
| 648 NullCallWrapper(), |
| 649 call_kind); |
| 639 } | 650 } |
| 640 | 651 |
| 641 | 652 |
| 642 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) { | 653 void CallIC::GenerateMiss(MacroAssembler* masm, |
| 654 int argc, |
| 655 Code::ExtraICState extra_ic_state) { |
| 643 // ----------- S t a t e ------------- | 656 // ----------- S t a t e ------------- |
| 644 // -- r2 : name | 657 // -- r2 : name |
| 645 // -- lr : return address | 658 // -- lr : return address |
| 646 // ----------------------------------- | 659 // ----------------------------------- |
| 647 | 660 |
| 648 GenerateCallMiss(masm, argc, IC::kCallIC_Miss); | 661 GenerateCallMiss(masm, argc, IC::kCallIC_Miss, extra_ic_state); |
| 649 } | 662 } |
| 650 | 663 |
| 651 | 664 |
| 652 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { | 665 void CallIC::GenerateMegamorphic(MacroAssembler* masm, |
| 666 int argc, |
| 667 Code::ExtraICState extra_ic_state) { |
| 653 // ----------- S t a t e ------------- | 668 // ----------- S t a t e ------------- |
| 654 // -- r2 : name | 669 // -- r2 : name |
| 655 // -- lr : return address | 670 // -- lr : return address |
| 656 // ----------------------------------- | 671 // ----------------------------------- |
| 657 | 672 |
| 658 // Get the receiver of the function from the stack into r1. | 673 // Get the receiver of the function from the stack into r1. |
| 659 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 674 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 660 GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC); | 675 GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, extra_ic_state); |
| 661 GenerateMiss(masm, argc); | 676 GenerateMiss(masm, argc, extra_ic_state); |
| 662 } | 677 } |
| 663 | 678 |
| 664 | 679 |
| 665 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 680 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
| 666 // ----------- S t a t e ------------- | 681 // ----------- S t a t e ------------- |
| 667 // -- r2 : name | 682 // -- r2 : name |
| 668 // -- lr : return address | 683 // -- lr : return address |
| 669 // ----------------------------------- | 684 // ----------------------------------- |
| 670 | 685 |
| 671 GenerateCallNormal(masm, argc); | 686 GenerateCallNormal(masm, argc); |
| 672 GenerateMiss(masm, argc); | 687 GenerateMiss(masm, argc, Code::kNoExtraICState); |
| 673 } | 688 } |
| 674 | 689 |
| 675 | 690 |
| 676 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { | 691 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { |
| 677 // ----------- S t a t e ------------- | 692 // ----------- S t a t e ------------- |
| 678 // -- r2 : name | 693 // -- r2 : name |
| 679 // -- lr : return address | 694 // -- lr : return address |
| 680 // ----------------------------------- | 695 // ----------------------------------- |
| 681 | 696 |
| 682 GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss); | 697 GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss, Code::kNoExtraICState); |
| 683 } | 698 } |
| 684 | 699 |
| 685 | 700 |
| 686 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { | 701 void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { |
| 687 // ----------- S t a t e ------------- | 702 // ----------- S t a t e ------------- |
| 688 // -- r2 : name | 703 // -- r2 : name |
| 689 // -- lr : return address | 704 // -- lr : return address |
| 690 // ----------------------------------- | 705 // ----------------------------------- |
| 691 | 706 |
| 692 // Get the receiver of the function from the stack into r1. | 707 // Get the receiver of the function from the stack into r1. |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 773 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
| 759 __ cmp(r3, ip); | 774 __ cmp(r3, ip); |
| 760 __ b(ne, &lookup_monomorphic_cache); | 775 __ b(ne, &lookup_monomorphic_cache); |
| 761 | 776 |
| 762 GenerateDictionaryLoad(masm, &slow_load, r0, r2, r1, r3, r4); | 777 GenerateDictionaryLoad(masm, &slow_load, r0, r2, r1, r3, r4); |
| 763 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1, r0, r3); | 778 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1, r0, r3); |
| 764 __ jmp(&do_call); | 779 __ jmp(&do_call); |
| 765 | 780 |
| 766 __ bind(&lookup_monomorphic_cache); | 781 __ bind(&lookup_monomorphic_cache); |
| 767 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1, r0, r3); | 782 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1, r0, r3); |
| 768 GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC); | 783 GenerateMonomorphicCacheProbe(masm, |
| 784 argc, |
| 785 Code::KEYED_CALL_IC, |
| 786 Code::kNoExtraICState); |
| 769 // Fall through on miss. | 787 // Fall through on miss. |
| 770 | 788 |
| 771 __ bind(&slow_call); | 789 __ bind(&slow_call); |
| 772 // This branch is taken if: | 790 // This branch is taken if: |
| 773 // - the receiver requires boxing or access check, | 791 // - the receiver requires boxing or access check, |
| 774 // - the key is neither smi nor symbol, | 792 // - the key is neither smi nor symbol, |
| 775 // - the value loaded is not a function, | 793 // - the value loaded is not a function, |
| 776 // - there is hope that the runtime will create a monomorphic call stub | 794 // - there is hope that the runtime will create a monomorphic call stub |
| 777 // that will get fetched next time. | 795 // that will get fetched next time. |
| 778 __ IncrementCounter(counters->keyed_call_generic_slow(), 1, r0, r3); | 796 __ IncrementCounter(counters->keyed_call_generic_slow(), 1, r0, r3); |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1535 Register reg = Assembler::GetRn(instr_at_patch); | 1553 Register reg = Assembler::GetRn(instr_at_patch); |
| 1536 patcher.masm()->tst(reg, Operand(kSmiTagMask)); | 1554 patcher.masm()->tst(reg, Operand(kSmiTagMask)); |
| 1537 patcher.EmitCondition(eq); | 1555 patcher.EmitCondition(eq); |
| 1538 } | 1556 } |
| 1539 } | 1557 } |
| 1540 | 1558 |
| 1541 | 1559 |
| 1542 } } // namespace v8::internal | 1560 } } // namespace v8::internal |
| 1543 | 1561 |
| 1544 #endif // V8_TARGET_ARCH_ARM | 1562 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |