| 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 1665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1676 // Return 1/0 for true/false in tos_. | 1676 // Return 1/0 for true/false in tos_. |
| 1677 __ bind(&true_result); | 1677 __ bind(&true_result); |
| 1678 __ mov(tos_, Operand(1, RelocInfo::NONE)); | 1678 __ mov(tos_, Operand(1, RelocInfo::NONE)); |
| 1679 __ Ret(); | 1679 __ Ret(); |
| 1680 __ bind(&false_result); | 1680 __ bind(&false_result); |
| 1681 __ mov(tos_, Operand(0, RelocInfo::NONE)); | 1681 __ mov(tos_, Operand(0, RelocInfo::NONE)); |
| 1682 __ Ret(); | 1682 __ Ret(); |
| 1683 } | 1683 } |
| 1684 | 1684 |
| 1685 | 1685 |
| 1686 const char* UnaryOpStub::GetName() { | 1686 void UnaryOpStub::PrintName(StringStream* stream) { |
| 1687 if (name_ != NULL) return name_; | |
| 1688 const int kMaxNameLength = 100; | |
| 1689 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray( | |
| 1690 kMaxNameLength); | |
| 1691 if (name_ == NULL) return "OOM"; | |
| 1692 const char* op_name = Token::Name(op_); | 1687 const char* op_name = Token::Name(op_); |
| 1693 const char* overwrite_name = NULL; // Make g++ happy. | 1688 const char* overwrite_name = NULL; // Make g++ happy. |
| 1694 switch (mode_) { | 1689 switch (mode_) { |
| 1695 case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break; | 1690 case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break; |
| 1696 case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break; | 1691 case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break; |
| 1697 } | 1692 } |
| 1698 | 1693 stream->Add("UnaryOpStub_%s_%s_%s", |
| 1699 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), | 1694 op_name, |
| 1700 "UnaryOpStub_%s_%s_%s", | 1695 overwrite_name, |
| 1701 op_name, | 1696 UnaryOpIC::GetName(operand_type_)); |
| 1702 overwrite_name, | |
| 1703 UnaryOpIC::GetName(operand_type_)); | |
| 1704 return name_; | |
| 1705 } | 1697 } |
| 1706 | 1698 |
| 1707 | 1699 |
| 1708 // TODO(svenpanne): Use virtual functions instead of switch. | 1700 // TODO(svenpanne): Use virtual functions instead of switch. |
| 1709 void UnaryOpStub::Generate(MacroAssembler* masm) { | 1701 void UnaryOpStub::Generate(MacroAssembler* masm) { |
| 1710 switch (operand_type_) { | 1702 switch (operand_type_) { |
| 1711 case UnaryOpIC::UNINITIALIZED: | 1703 case UnaryOpIC::UNINITIALIZED: |
| 1712 GenerateTypeTransition(masm); | 1704 GenerateTypeTransition(masm); |
| 1713 break; | 1705 break; |
| 1714 case UnaryOpIC::SMI: | 1706 case UnaryOpIC::SMI: |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2030 break; | 2022 break; |
| 2031 case BinaryOpIC::GENERIC: | 2023 case BinaryOpIC::GENERIC: |
| 2032 GenerateGeneric(masm); | 2024 GenerateGeneric(masm); |
| 2033 break; | 2025 break; |
| 2034 default: | 2026 default: |
| 2035 UNREACHABLE(); | 2027 UNREACHABLE(); |
| 2036 } | 2028 } |
| 2037 } | 2029 } |
| 2038 | 2030 |
| 2039 | 2031 |
| 2040 const char* BinaryOpStub::GetName() { | 2032 void BinaryOpStub::PrintName(StringStream* stream) { |
| 2041 if (name_ != NULL) return name_; | |
| 2042 const int kMaxNameLength = 100; | |
| 2043 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray( | |
| 2044 kMaxNameLength); | |
| 2045 if (name_ == NULL) return "OOM"; | |
| 2046 const char* op_name = Token::Name(op_); | 2033 const char* op_name = Token::Name(op_); |
| 2047 const char* overwrite_name; | 2034 const char* overwrite_name; |
| 2048 switch (mode_) { | 2035 switch (mode_) { |
| 2049 case NO_OVERWRITE: overwrite_name = "Alloc"; break; | 2036 case NO_OVERWRITE: overwrite_name = "Alloc"; break; |
| 2050 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; | 2037 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; |
| 2051 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; | 2038 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; |
| 2052 default: overwrite_name = "UnknownOverwrite"; break; | 2039 default: overwrite_name = "UnknownOverwrite"; break; |
| 2053 } | 2040 } |
| 2054 | 2041 stream->Add("BinaryOpStub_%s_%s_%s", |
| 2055 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), | 2042 op_name, |
| 2056 "BinaryOpStub_%s_%s_%s", | 2043 overwrite_name, |
| 2057 op_name, | 2044 BinaryOpIC::GetName(operands_type_)); |
| 2058 overwrite_name, | |
| 2059 BinaryOpIC::GetName(operands_type_)); | |
| 2060 return name_; | |
| 2061 } | 2045 } |
| 2062 | 2046 |
| 2063 | 2047 |
| 2064 void BinaryOpStub::GenerateSmiSmiOperation(MacroAssembler* masm) { | 2048 void BinaryOpStub::GenerateSmiSmiOperation(MacroAssembler* masm) { |
| 2065 Register left = r1; | 2049 Register left = r1; |
| 2066 Register right = r0; | 2050 Register right = r0; |
| 2067 Register scratch1 = r7; | 2051 Register scratch1 = r7; |
| 2068 Register scratch2 = r9; | 2052 Register scratch2 = r9; |
| 2069 | 2053 |
| 2070 ASSERT(right.is(r0)); | 2054 ASSERT(right.is(r0)); |
| (...skipping 1484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3555 __ mov(r7, Operand(Smi::FromInt(marker))); | 3539 __ mov(r7, Operand(Smi::FromInt(marker))); |
| 3556 __ mov(r6, Operand(Smi::FromInt(marker))); | 3540 __ mov(r6, Operand(Smi::FromInt(marker))); |
| 3557 __ mov(r5, | 3541 __ mov(r5, |
| 3558 Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); | 3542 Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); |
| 3559 __ ldr(r5, MemOperand(r5)); | 3543 __ ldr(r5, MemOperand(r5)); |
| 3560 __ Push(r8, r7, r6, r5); | 3544 __ Push(r8, r7, r6, r5); |
| 3561 | 3545 |
| 3562 // Setup frame pointer for the frame to be pushed. | 3546 // Setup frame pointer for the frame to be pushed. |
| 3563 __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); | 3547 __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); |
| 3564 | 3548 |
| 3565 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 3566 // If this is the outermost JS call, set js_entry_sp value. | 3549 // If this is the outermost JS call, set js_entry_sp value. |
| 3567 Label non_outermost_js; | 3550 Label non_outermost_js; |
| 3568 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate); | 3551 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate); |
| 3569 __ mov(r5, Operand(ExternalReference(js_entry_sp))); | 3552 __ mov(r5, Operand(ExternalReference(js_entry_sp))); |
| 3570 __ ldr(r6, MemOperand(r5)); | 3553 __ ldr(r6, MemOperand(r5)); |
| 3571 __ cmp(r6, Operand(0)); | 3554 __ cmp(r6, Operand(0)); |
| 3572 __ b(ne, &non_outermost_js); | 3555 __ b(ne, &non_outermost_js); |
| 3573 __ str(fp, MemOperand(r5)); | 3556 __ str(fp, MemOperand(r5)); |
| 3574 __ mov(ip, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); | 3557 __ mov(ip, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); |
| 3575 Label cont; | 3558 Label cont; |
| 3576 __ b(&cont); | 3559 __ b(&cont); |
| 3577 __ bind(&non_outermost_js); | 3560 __ bind(&non_outermost_js); |
| 3578 __ mov(ip, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); | 3561 __ mov(ip, Operand(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); |
| 3579 __ bind(&cont); | 3562 __ bind(&cont); |
| 3580 __ push(ip); | 3563 __ push(ip); |
| 3581 #endif | |
| 3582 | 3564 |
| 3583 // Call a faked try-block that does the invoke. | 3565 // Call a faked try-block that does the invoke. |
| 3584 __ bl(&invoke); | 3566 __ bl(&invoke); |
| 3585 | 3567 |
| 3586 // Caught exception: Store result (exception) in the pending | 3568 // Caught exception: Store result (exception) in the pending |
| 3587 // exception field in the JSEnv and return a failure sentinel. | 3569 // exception field in the JSEnv and return a failure sentinel. |
| 3588 // Coming in here the fp will be invalid because the PushTryHandler below | 3570 // Coming in here the fp will be invalid because the PushTryHandler below |
| 3589 // sets it to 0 to signal the existence of the JSEntry frame. | 3571 // sets it to 0 to signal the existence of the JSEntry frame. |
| 3590 __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, | 3572 __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, |
| 3591 isolate))); | 3573 isolate))); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3632 // Branch and link to JSEntryTrampoline. We don't use the double underscore | 3614 // Branch and link to JSEntryTrampoline. We don't use the double underscore |
| 3633 // macro for the add instruction because we don't want the coverage tool | 3615 // macro for the add instruction because we don't want the coverage tool |
| 3634 // inserting instructions here after we read the pc. | 3616 // inserting instructions here after we read the pc. |
| 3635 __ mov(lr, Operand(pc)); | 3617 __ mov(lr, Operand(pc)); |
| 3636 masm->add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); | 3618 masm->add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 3637 | 3619 |
| 3638 // Unlink this frame from the handler chain. | 3620 // Unlink this frame from the handler chain. |
| 3639 __ PopTryHandler(); | 3621 __ PopTryHandler(); |
| 3640 | 3622 |
| 3641 __ bind(&exit); // r0 holds result | 3623 __ bind(&exit); // r0 holds result |
| 3642 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 3643 // Check if the current stack frame is marked as the outermost JS frame. | 3624 // Check if the current stack frame is marked as the outermost JS frame. |
| 3644 Label non_outermost_js_2; | 3625 Label non_outermost_js_2; |
| 3645 __ pop(r5); | 3626 __ pop(r5); |
| 3646 __ cmp(r5, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); | 3627 __ cmp(r5, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); |
| 3647 __ b(ne, &non_outermost_js_2); | 3628 __ b(ne, &non_outermost_js_2); |
| 3648 __ mov(r6, Operand(0)); | 3629 __ mov(r6, Operand(0)); |
| 3649 __ mov(r5, Operand(ExternalReference(js_entry_sp))); | 3630 __ mov(r5, Operand(ExternalReference(js_entry_sp))); |
| 3650 __ str(r6, MemOperand(r5)); | 3631 __ str(r6, MemOperand(r5)); |
| 3651 __ bind(&non_outermost_js_2); | 3632 __ bind(&non_outermost_js_2); |
| 3652 #endif | |
| 3653 | 3633 |
| 3654 // Restore the top frame descriptors from the stack. | 3634 // Restore the top frame descriptors from the stack. |
| 3655 __ pop(r3); | 3635 __ pop(r3); |
| 3656 __ mov(ip, | 3636 __ mov(ip, |
| 3657 Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); | 3637 Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); |
| 3658 __ str(r3, MemOperand(ip)); | 3638 __ str(r3, MemOperand(ip)); |
| 3659 | 3639 |
| 3660 // Reset the stack to the callee saved registers. | 3640 // Reset the stack to the callee saved registers. |
| 3661 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); | 3641 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); |
| 3662 | 3642 |
| (...skipping 1079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4742 __ mov(r0, Operand(argc_)); // Setup the number of arguments. | 4722 __ mov(r0, Operand(argc_)); // Setup the number of arguments. |
| 4743 __ mov(r2, Operand(0, RelocInfo::NONE)); | 4723 __ mov(r2, Operand(0, RelocInfo::NONE)); |
| 4744 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 4724 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
| 4745 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 4725 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
| 4746 RelocInfo::CODE_TARGET); | 4726 RelocInfo::CODE_TARGET); |
| 4747 } | 4727 } |
| 4748 | 4728 |
| 4749 | 4729 |
| 4750 // Unfortunately you have to run without snapshots to see most of these | 4730 // Unfortunately you have to run without snapshots to see most of these |
| 4751 // names in the profile since most compare stubs end up in the snapshot. | 4731 // names in the profile since most compare stubs end up in the snapshot. |
| 4752 const char* CompareStub::GetName() { | 4732 void CompareStub::PrintName(StringStream* stream) { |
| 4753 ASSERT((lhs_.is(r0) && rhs_.is(r1)) || | 4733 ASSERT((lhs_.is(r0) && rhs_.is(r1)) || |
| 4754 (lhs_.is(r1) && rhs_.is(r0))); | 4734 (lhs_.is(r1) && rhs_.is(r0))); |
| 4755 | |
| 4756 if (name_ != NULL) return name_; | |
| 4757 const int kMaxNameLength = 100; | |
| 4758 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray( | |
| 4759 kMaxNameLength); | |
| 4760 if (name_ == NULL) return "OOM"; | |
| 4761 | |
| 4762 const char* cc_name; | 4735 const char* cc_name; |
| 4763 switch (cc_) { | 4736 switch (cc_) { |
| 4764 case lt: cc_name = "LT"; break; | 4737 case lt: cc_name = "LT"; break; |
| 4765 case gt: cc_name = "GT"; break; | 4738 case gt: cc_name = "GT"; break; |
| 4766 case le: cc_name = "LE"; break; | 4739 case le: cc_name = "LE"; break; |
| 4767 case ge: cc_name = "GE"; break; | 4740 case ge: cc_name = "GE"; break; |
| 4768 case eq: cc_name = "EQ"; break; | 4741 case eq: cc_name = "EQ"; break; |
| 4769 case ne: cc_name = "NE"; break; | 4742 case ne: cc_name = "NE"; break; |
| 4770 default: cc_name = "UnknownCondition"; break; | 4743 default: cc_name = "UnknownCondition"; break; |
| 4771 } | 4744 } |
| 4772 | 4745 bool is_equality = cc_ == eq || cc_ == ne; |
| 4773 const char* lhs_name = lhs_.is(r0) ? "_r0" : "_r1"; | 4746 stream->Add("CompareStub_%s", cc_name); |
| 4774 const char* rhs_name = rhs_.is(r0) ? "_r0" : "_r1"; | 4747 stream->Add(lhs_.is(r0) ? "_r0" : "_r1"); |
| 4775 | 4748 stream->Add(rhs_.is(r0) ? "_r0" : "_r1"); |
| 4776 const char* strict_name = ""; | 4749 if (strict_ && is_equality) stream->Add("_STRICT"); |
| 4777 if (strict_ && (cc_ == eq || cc_ == ne)) { | 4750 if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN"); |
| 4778 strict_name = "_STRICT"; | 4751 if (!include_number_compare_) stream->Add("_NO_NUMBER"); |
| 4779 } | 4752 if (!include_smi_compare_) stream->Add("_NO_SMI"); |
| 4780 | |
| 4781 const char* never_nan_nan_name = ""; | |
| 4782 if (never_nan_nan_ && (cc_ == eq || cc_ == ne)) { | |
| 4783 never_nan_nan_name = "_NO_NAN"; | |
| 4784 } | |
| 4785 | |
| 4786 const char* include_number_compare_name = ""; | |
| 4787 if (!include_number_compare_) { | |
| 4788 include_number_compare_name = "_NO_NUMBER"; | |
| 4789 } | |
| 4790 | |
| 4791 const char* include_smi_compare_name = ""; | |
| 4792 if (!include_smi_compare_) { | |
| 4793 include_smi_compare_name = "_NO_SMI"; | |
| 4794 } | |
| 4795 | |
| 4796 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), | |
| 4797 "CompareStub_%s%s%s%s%s%s", | |
| 4798 cc_name, | |
| 4799 lhs_name, | |
| 4800 rhs_name, | |
| 4801 strict_name, | |
| 4802 never_nan_nan_name, | |
| 4803 include_number_compare_name, | |
| 4804 include_smi_compare_name); | |
| 4805 return name_; | |
| 4806 } | 4753 } |
| 4807 | 4754 |
| 4808 | 4755 |
| 4809 int CompareStub::MinorKey() { | 4756 int CompareStub::MinorKey() { |
| 4810 // Encode the three parameters in a unique 16 bit value. To avoid duplicate | 4757 // Encode the three parameters in a unique 16 bit value. To avoid duplicate |
| 4811 // stubs the never NaN NaN condition is only taken into account if the | 4758 // stubs the never NaN NaN condition is only taken into account if the |
| 4812 // condition is equals. | 4759 // condition is equals. |
| 4813 ASSERT((static_cast<unsigned>(cc_) >> 28) < (1 << 12)); | 4760 ASSERT((static_cast<unsigned>(cc_) >> 28) < (1 << 12)); |
| 4814 ASSERT((lhs_.is(r0) && rhs_.is(r1)) || | 4761 ASSERT((lhs_.is(r0) && rhs_.is(r1)) || |
| 4815 (lhs_.is(r1) && rhs_.is(r0))); | 4762 (lhs_.is(r1) && rhs_.is(r0))); |
| (...skipping 1771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6587 __ mov(result, Operand(0)); | 6534 __ mov(result, Operand(0)); |
| 6588 __ Ret(); | 6535 __ Ret(); |
| 6589 } | 6536 } |
| 6590 | 6537 |
| 6591 | 6538 |
| 6592 #undef __ | 6539 #undef __ |
| 6593 | 6540 |
| 6594 } } // namespace v8::internal | 6541 } } // namespace v8::internal |
| 6595 | 6542 |
| 6596 #endif // V8_TARGET_ARCH_ARM | 6543 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |