| 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 1698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1709 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) { | 1709 for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) { |
| 1710 DwVfpRegister reg = DwVfpRegister::from_code(i); | 1710 DwVfpRegister reg = DwVfpRegister::from_code(i); |
| 1711 __ vldr(reg, MemOperand(sp, i * kDoubleSize)); | 1711 __ vldr(reg, MemOperand(sp, i * kDoubleSize)); |
| 1712 } | 1712 } |
| 1713 __ add(sp, sp, Operand(kDoubleSize * DwVfpRegister::kNumRegisters)); | 1713 __ add(sp, sp, Operand(kDoubleSize * DwVfpRegister::kNumRegisters)); |
| 1714 } | 1714 } |
| 1715 __ ldm(ia_w, sp, kCallerSaved | pc.bit()); // Also pop pc to get Ret(0). | 1715 __ ldm(ia_w, sp, kCallerSaved | pc.bit()); // Also pop pc to get Ret(0). |
| 1716 } | 1716 } |
| 1717 | 1717 |
| 1718 | 1718 |
| 1719 const char* UnaryOpStub::GetName() { | 1719 void UnaryOpStub::PrintName(StringStream* stream) { |
| 1720 if (name_ != NULL) return name_; | |
| 1721 const int kMaxNameLength = 100; | |
| 1722 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray( | |
| 1723 kMaxNameLength); | |
| 1724 if (name_ == NULL) return "OOM"; | |
| 1725 const char* op_name = Token::Name(op_); | 1720 const char* op_name = Token::Name(op_); |
| 1726 const char* overwrite_name = NULL; // Make g++ happy. | 1721 const char* overwrite_name = NULL; // Make g++ happy. |
| 1727 switch (mode_) { | 1722 switch (mode_) { |
| 1728 case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break; | 1723 case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break; |
| 1729 case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break; | 1724 case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break; |
| 1730 } | 1725 } |
| 1731 | 1726 stream->Add("UnaryOpStub_%s_%s_%s", |
| 1732 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), | 1727 op_name, |
| 1733 "UnaryOpStub_%s_%s_%s", | 1728 overwrite_name, |
| 1734 op_name, | 1729 UnaryOpIC::GetName(operand_type_)); |
| 1735 overwrite_name, | |
| 1736 UnaryOpIC::GetName(operand_type_)); | |
| 1737 return name_; | |
| 1738 } | 1730 } |
| 1739 | 1731 |
| 1740 | 1732 |
| 1741 // TODO(svenpanne): Use virtual functions instead of switch. | 1733 // TODO(svenpanne): Use virtual functions instead of switch. |
| 1742 void UnaryOpStub::Generate(MacroAssembler* masm) { | 1734 void UnaryOpStub::Generate(MacroAssembler* masm) { |
| 1743 switch (operand_type_) { | 1735 switch (operand_type_) { |
| 1744 case UnaryOpIC::UNINITIALIZED: | 1736 case UnaryOpIC::UNINITIALIZED: |
| 1745 GenerateTypeTransition(masm); | 1737 GenerateTypeTransition(masm); |
| 1746 break; | 1738 break; |
| 1747 case UnaryOpIC::SMI: | 1739 case UnaryOpIC::SMI: |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2063 break; | 2055 break; |
| 2064 case BinaryOpIC::GENERIC: | 2056 case BinaryOpIC::GENERIC: |
| 2065 GenerateGeneric(masm); | 2057 GenerateGeneric(masm); |
| 2066 break; | 2058 break; |
| 2067 default: | 2059 default: |
| 2068 UNREACHABLE(); | 2060 UNREACHABLE(); |
| 2069 } | 2061 } |
| 2070 } | 2062 } |
| 2071 | 2063 |
| 2072 | 2064 |
| 2073 const char* BinaryOpStub::GetName() { | 2065 void BinaryOpStub::PrintName(StringStream* stream) { |
| 2074 if (name_ != NULL) return name_; | |
| 2075 const int kMaxNameLength = 100; | |
| 2076 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray( | |
| 2077 kMaxNameLength); | |
| 2078 if (name_ == NULL) return "OOM"; | |
| 2079 const char* op_name = Token::Name(op_); | 2066 const char* op_name = Token::Name(op_); |
| 2080 const char* overwrite_name; | 2067 const char* overwrite_name; |
| 2081 switch (mode_) { | 2068 switch (mode_) { |
| 2082 case NO_OVERWRITE: overwrite_name = "Alloc"; break; | 2069 case NO_OVERWRITE: overwrite_name = "Alloc"; break; |
| 2083 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; | 2070 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; |
| 2084 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; | 2071 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; |
| 2085 default: overwrite_name = "UnknownOverwrite"; break; | 2072 default: overwrite_name = "UnknownOverwrite"; break; |
| 2086 } | 2073 } |
| 2087 | 2074 stream->Add("BinaryOpStub_%s_%s_%s", |
| 2088 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), | 2075 op_name, |
| 2089 "BinaryOpStub_%s_%s_%s", | 2076 overwrite_name, |
| 2090 op_name, | 2077 BinaryOpIC::GetName(operands_type_)); |
| 2091 overwrite_name, | |
| 2092 BinaryOpIC::GetName(operands_type_)); | |
| 2093 return name_; | |
| 2094 } | 2078 } |
| 2095 | 2079 |
| 2096 | 2080 |
| 2097 void BinaryOpStub::GenerateSmiSmiOperation(MacroAssembler* masm) { | 2081 void BinaryOpStub::GenerateSmiSmiOperation(MacroAssembler* masm) { |
| 2098 Register left = r1; | 2082 Register left = r1; |
| 2099 Register right = r0; | 2083 Register right = r0; |
| 2100 Register scratch1 = r7; | 2084 Register scratch1 = r7; |
| 2101 Register scratch2 = r9; | 2085 Register scratch2 = r9; |
| 2102 | 2086 |
| 2103 ASSERT(right.is(r0)); | 2087 ASSERT(right.is(r0)); |
| (...skipping 1484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3588 __ mov(r7, Operand(Smi::FromInt(marker))); | 3572 __ mov(r7, Operand(Smi::FromInt(marker))); |
| 3589 __ mov(r6, Operand(Smi::FromInt(marker))); | 3573 __ mov(r6, Operand(Smi::FromInt(marker))); |
| 3590 __ mov(r5, | 3574 __ mov(r5, |
| 3591 Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); | 3575 Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); |
| 3592 __ ldr(r5, MemOperand(r5)); | 3576 __ ldr(r5, MemOperand(r5)); |
| 3593 __ Push(r8, r7, r6, r5); | 3577 __ Push(r8, r7, r6, r5); |
| 3594 | 3578 |
| 3595 // Setup frame pointer for the frame to be pushed. | 3579 // Setup frame pointer for the frame to be pushed. |
| 3596 __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); | 3580 __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); |
| 3597 | 3581 |
| 3598 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 3599 // If this is the outermost JS call, set js_entry_sp value. | 3582 // If this is the outermost JS call, set js_entry_sp value. |
| 3600 Label non_outermost_js; | 3583 Label non_outermost_js; |
| 3601 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate); | 3584 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate); |
| 3602 __ mov(r5, Operand(ExternalReference(js_entry_sp))); | 3585 __ mov(r5, Operand(ExternalReference(js_entry_sp))); |
| 3603 __ ldr(r6, MemOperand(r5)); | 3586 __ ldr(r6, MemOperand(r5)); |
| 3604 __ cmp(r6, Operand(0)); | 3587 __ cmp(r6, Operand(0)); |
| 3605 __ b(ne, &non_outermost_js); | 3588 __ b(ne, &non_outermost_js); |
| 3606 __ str(fp, MemOperand(r5)); | 3589 __ str(fp, MemOperand(r5)); |
| 3607 __ mov(ip, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); | 3590 __ mov(ip, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); |
| 3608 Label cont; | 3591 Label cont; |
| 3609 __ b(&cont); | 3592 __ b(&cont); |
| 3610 __ bind(&non_outermost_js); | 3593 __ bind(&non_outermost_js); |
| 3611 __ mov(ip, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); | 3594 __ mov(ip, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); |
| 3612 __ bind(&cont); | 3595 __ bind(&cont); |
| 3613 __ push(ip); | 3596 __ push(ip); |
| 3614 #endif | |
| 3615 | 3597 |
| 3616 // Call a faked try-block that does the invoke. | 3598 // Call a faked try-block that does the invoke. |
| 3617 __ bl(&invoke); | 3599 __ bl(&invoke); |
| 3618 | 3600 |
| 3619 // Caught exception: Store result (exception) in the pending | 3601 // Caught exception: Store result (exception) in the pending |
| 3620 // exception field in the JSEnv and return a failure sentinel. | 3602 // exception field in the JSEnv and return a failure sentinel. |
| 3621 // Coming in here the fp will be invalid because the PushTryHandler below | 3603 // Coming in here the fp will be invalid because the PushTryHandler below |
| 3622 // sets it to 0 to signal the existence of the JSEntry frame. | 3604 // sets it to 0 to signal the existence of the JSEntry frame. |
| 3623 __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, | 3605 __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, |
| 3624 isolate))); | 3606 isolate))); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3665 // Branch and link to JSEntryTrampoline. We don't use the double underscore | 3647 // Branch and link to JSEntryTrampoline. We don't use the double underscore |
| 3666 // macro for the add instruction because we don't want the coverage tool | 3648 // macro for the add instruction because we don't want the coverage tool |
| 3667 // inserting instructions here after we read the pc. | 3649 // inserting instructions here after we read the pc. |
| 3668 __ mov(lr, Operand(pc)); | 3650 __ mov(lr, Operand(pc)); |
| 3669 masm->add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); | 3651 masm->add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 3670 | 3652 |
| 3671 // Unlink this frame from the handler chain. | 3653 // Unlink this frame from the handler chain. |
| 3672 __ PopTryHandler(); | 3654 __ PopTryHandler(); |
| 3673 | 3655 |
| 3674 __ bind(&exit); // r0 holds result | 3656 __ bind(&exit); // r0 holds result |
| 3675 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 3676 // Check if the current stack frame is marked as the outermost JS frame. | 3657 // Check if the current stack frame is marked as the outermost JS frame. |
| 3677 Label non_outermost_js_2; | 3658 Label non_outermost_js_2; |
| 3678 __ pop(r5); | 3659 __ pop(r5); |
| 3679 __ cmp(r5, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); | 3660 __ cmp(r5, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); |
| 3680 __ b(ne, &non_outermost_js_2); | 3661 __ b(ne, &non_outermost_js_2); |
| 3681 __ mov(r6, Operand(0)); | 3662 __ mov(r6, Operand(0)); |
| 3682 __ mov(r5, Operand(ExternalReference(js_entry_sp))); | 3663 __ mov(r5, Operand(ExternalReference(js_entry_sp))); |
| 3683 __ str(r6, MemOperand(r5)); | 3664 __ str(r6, MemOperand(r5)); |
| 3684 __ bind(&non_outermost_js_2); | 3665 __ bind(&non_outermost_js_2); |
| 3685 #endif | |
| 3686 | 3666 |
| 3687 // Restore the top frame descriptors from the stack. | 3667 // Restore the top frame descriptors from the stack. |
| 3688 __ pop(r3); | 3668 __ pop(r3); |
| 3689 __ mov(ip, | 3669 __ mov(ip, |
| 3690 Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); | 3670 Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); |
| 3691 __ str(r3, MemOperand(ip)); | 3671 __ str(r3, MemOperand(ip)); |
| 3692 | 3672 |
| 3693 // Reset the stack to the callee saved registers. | 3673 // Reset the stack to the callee saved registers. |
| 3694 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); | 3674 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); |
| 3695 | 3675 |
| (...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4777 CALL_AS_FUNCTION); | 4757 CALL_AS_FUNCTION); |
| 4778 | 4758 |
| 4779 // Slow-case: Non-function called. | 4759 // Slow-case: Non-function called. |
| 4780 __ bind(&slow); | 4760 __ bind(&slow); |
| 4781 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 4761 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead |
| 4782 // of the original receiver from the call site). | 4762 // of the original receiver from the call site). |
| 4783 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); | 4763 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); |
| 4784 __ mov(r0, Operand(argc_)); // Setup the number of arguments. | 4764 __ mov(r0, Operand(argc_)); // Setup the number of arguments. |
| 4785 __ mov(r2, Operand(0, RelocInfo::NONE)); | 4765 __ mov(r2, Operand(0, RelocInfo::NONE)); |
| 4786 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 4766 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
| 4767 __ SetCallKind(r5, CALL_AS_METHOD); |
| 4787 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 4768 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 4788 RelocInfo::CODE_TARGET); | 4769 RelocInfo::CODE_TARGET); |
| 4789 } | 4770 } |
| 4790 | 4771 |
| 4791 | 4772 |
| 4792 // Unfortunately you have to run without snapshots to see most of these | 4773 // Unfortunately you have to run without snapshots to see most of these |
| 4793 // names in the profile since most compare stubs end up in the snapshot. | 4774 // names in the profile since most compare stubs end up in the snapshot. |
| 4794 const char* CompareStub::GetName() { | 4775 void CompareStub::PrintName(StringStream* stream) { |
| 4795 ASSERT((lhs_.is(r0) && rhs_.is(r1)) || | 4776 ASSERT((lhs_.is(r0) && rhs_.is(r1)) || |
| 4796 (lhs_.is(r1) && rhs_.is(r0))); | 4777 (lhs_.is(r1) && rhs_.is(r0))); |
| 4797 | |
| 4798 if (name_ != NULL) return name_; | |
| 4799 const int kMaxNameLength = 100; | |
| 4800 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray( | |
| 4801 kMaxNameLength); | |
| 4802 if (name_ == NULL) return "OOM"; | |
| 4803 | |
| 4804 const char* cc_name; | 4778 const char* cc_name; |
| 4805 switch (cc_) { | 4779 switch (cc_) { |
| 4806 case lt: cc_name = "LT"; break; | 4780 case lt: cc_name = "LT"; break; |
| 4807 case gt: cc_name = "GT"; break; | 4781 case gt: cc_name = "GT"; break; |
| 4808 case le: cc_name = "LE"; break; | 4782 case le: cc_name = "LE"; break; |
| 4809 case ge: cc_name = "GE"; break; | 4783 case ge: cc_name = "GE"; break; |
| 4810 case eq: cc_name = "EQ"; break; | 4784 case eq: cc_name = "EQ"; break; |
| 4811 case ne: cc_name = "NE"; break; | 4785 case ne: cc_name = "NE"; break; |
| 4812 default: cc_name = "UnknownCondition"; break; | 4786 default: cc_name = "UnknownCondition"; break; |
| 4813 } | 4787 } |
| 4814 | 4788 bool is_equality = cc_ == eq || cc_ == ne; |
| 4815 const char* lhs_name = lhs_.is(r0) ? "_r0" : "_r1"; | 4789 stream->Add("CompareStub_%s", cc_name); |
| 4816 const char* rhs_name = rhs_.is(r0) ? "_r0" : "_r1"; | 4790 stream->Add(lhs_.is(r0) ? "_r0" : "_r1"); |
| 4817 | 4791 stream->Add(rhs_.is(r0) ? "_r0" : "_r1"); |
| 4818 const char* strict_name = ""; | 4792 if (strict_ && is_equality) stream->Add("_STRICT"); |
| 4819 if (strict_ && (cc_ == eq || cc_ == ne)) { | 4793 if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN"); |
| 4820 strict_name = "_STRICT"; | 4794 if (!include_number_compare_) stream->Add("_NO_NUMBER"); |
| 4821 } | 4795 if (!include_smi_compare_) stream->Add("_NO_SMI"); |
| 4822 | |
| 4823 const char* never_nan_nan_name = ""; | |
| 4824 if (never_nan_nan_ && (cc_ == eq || cc_ == ne)) { | |
| 4825 never_nan_nan_name = "_NO_NAN"; | |
| 4826 } | |
| 4827 | |
| 4828 const char* include_number_compare_name = ""; | |
| 4829 if (!include_number_compare_) { | |
| 4830 include_number_compare_name = "_NO_NUMBER"; | |
| 4831 } | |
| 4832 | |
| 4833 const char* include_smi_compare_name = ""; | |
| 4834 if (!include_smi_compare_) { | |
| 4835 include_smi_compare_name = "_NO_SMI"; | |
| 4836 } | |
| 4837 | |
| 4838 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), | |
| 4839 "CompareStub_%s%s%s%s%s%s", | |
| 4840 cc_name, | |
| 4841 lhs_name, | |
| 4842 rhs_name, | |
| 4843 strict_name, | |
| 4844 never_nan_nan_name, | |
| 4845 include_number_compare_name, | |
| 4846 include_smi_compare_name); | |
| 4847 return name_; | |
| 4848 } | 4796 } |
| 4849 | 4797 |
| 4850 | 4798 |
| 4851 int CompareStub::MinorKey() { | 4799 int CompareStub::MinorKey() { |
| 4852 // Encode the three parameters in a unique 16 bit value. To avoid duplicate | 4800 // Encode the three parameters in a unique 16 bit value. To avoid duplicate |
| 4853 // stubs the never NaN NaN condition is only taken into account if the | 4801 // stubs the never NaN NaN condition is only taken into account if the |
| 4854 // condition is equals. | 4802 // condition is equals. |
| 4855 ASSERT((static_cast<unsigned>(cc_) >> 28) < (1 << 12)); | 4803 ASSERT((static_cast<unsigned>(cc_) >> 28) < (1 << 12)); |
| 4856 ASSERT((lhs_.is(r0) && rhs_.is(r1)) || | 4804 ASSERT((lhs_.is(r0) && rhs_.is(r1)) || |
| 4857 (lhs_.is(r1) && rhs_.is(r0))); | 4805 (lhs_.is(r1) && rhs_.is(r0))); |
| (...skipping 1784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6642 } | 6590 } |
| 6643 __ Ret(); | 6591 __ Ret(); |
| 6644 } | 6592 } |
| 6645 | 6593 |
| 6646 | 6594 |
| 6647 #undef __ | 6595 #undef __ |
| 6648 | 6596 |
| 6649 } } // namespace v8::internal | 6597 } } // namespace v8::internal |
| 6650 | 6598 |
| 6651 #endif // V8_TARGET_ARCH_ARM | 6599 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |