OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 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 3546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3557 // push. | 3557 // push. |
3558 | 3558 |
3559 // If the receiver is a smi trigger the slow case. | 3559 // If the receiver is a smi trigger the slow case. |
3560 ASSERT(kSmiTag == 0); | 3560 ASSERT(kSmiTag == 0); |
3561 __ testl(object.reg(), Immediate(kSmiTagMask)); | 3561 __ testl(object.reg(), Immediate(kSmiTagMask)); |
3562 __ j(zero, &slow_case); | 3562 __ j(zero, &slow_case); |
3563 | 3563 |
3564 // If the index is negative or non-smi trigger the slow case. | 3564 // If the index is negative or non-smi trigger the slow case. |
3565 ASSERT(kSmiTag == 0); | 3565 ASSERT(kSmiTag == 0); |
3566 __ testl(index.reg(), | 3566 __ testl(index.reg(), |
3567 Immediate(static_cast<int32_t>(kSmiTagMask | 0x80000000U))); | 3567 Immediate(static_cast<uint32_t>(kSmiTagMask | 0x80000000U))); |
3568 __ j(not_zero, &slow_case); | 3568 __ j(not_zero, &slow_case); |
3569 // Untag the index. | 3569 // Untag the index. |
3570 __ sarl(index.reg(), Immediate(kSmiTagSize)); | 3570 __ sarl(index.reg(), Immediate(kSmiTagSize)); |
3571 | 3571 |
3572 __ bind(&try_again_with_new_string); | 3572 __ bind(&try_again_with_new_string); |
3573 // Fetch the instance type of the receiver into rcx. | 3573 // Fetch the instance type of the receiver into rcx. |
3574 __ movq(rcx, FieldOperand(object.reg(), HeapObject::kMapOffset)); | 3574 __ movq(rcx, FieldOperand(object.reg(), HeapObject::kMapOffset)); |
3575 __ movzxbl(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); | 3575 __ movzxbl(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); |
3576 // If the receiver is not a string trigger the slow case. | 3576 // If the receiver is not a string trigger the slow case. |
3577 __ testb(rcx, Immediate(kIsNotStringMask)); | 3577 __ testb(rcx, Immediate(kIsNotStringMask)); |
(...skipping 1769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5347 (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) { | 5347 (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) { |
5348 operand->ToRegister(); | 5348 operand->ToRegister(); |
5349 frame_->Spill(operand->reg()); | 5349 frame_->Spill(operand->reg()); |
5350 DeferredCode* deferred = new DeferredInlineSmiOperation(op, | 5350 DeferredCode* deferred = new DeferredInlineSmiOperation(op, |
5351 operand->reg(), | 5351 operand->reg(), |
5352 operand->reg(), | 5352 operand->reg(), |
5353 smi_value, | 5353 smi_value, |
5354 overwrite_mode); | 5354 overwrite_mode); |
5355 // Check for negative or non-Smi left hand side. | 5355 // Check for negative or non-Smi left hand side. |
5356 __ testl(operand->reg(), | 5356 __ testl(operand->reg(), |
5357 Immediate(static_cast<int32_t>(kSmiTagMask | 0x80000000))); | 5357 Immediate(static_cast<uint32_t>(kSmiTagMask | 0x80000000))); |
5358 deferred->Branch(not_zero); | 5358 deferred->Branch(not_zero); |
5359 if (int_value < 0) int_value = -int_value; | 5359 if (int_value < 0) int_value = -int_value; |
5360 if (int_value == 1) { | 5360 if (int_value == 1) { |
5361 __ movl(operand->reg(), Immediate(Smi::FromInt(0))); | 5361 __ movl(operand->reg(), Immediate(Smi::FromInt(0))); |
5362 } else { | 5362 } else { |
5363 __ and_(operand->reg(), Immediate((int_value << kSmiTagSize) - 1)); | 5363 __ and_(operand->reg(), Immediate((int_value << kSmiTagSize) - 1)); |
5364 } | 5364 } |
5365 deferred->BindExit(); | 5365 deferred->BindExit(); |
5366 frame_->Push(operand); | 5366 frame_->Push(operand); |
5367 break; // This break only applies if we generated code for MOD. | 5367 break; // This break only applies if we generated code for MOD. |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5887 // Use masm-> here instead of the double underscore macro since extra | 5887 // Use masm-> here instead of the double underscore macro since extra |
5888 // coverage code can interfere with the patching. | 5888 // coverage code can interfere with the patching. |
5889 masm->movq(kScratchRegister, Factory::null_value(), | 5889 masm->movq(kScratchRegister, Factory::null_value(), |
5890 RelocInfo::EMBEDDED_OBJECT); | 5890 RelocInfo::EMBEDDED_OBJECT); |
5891 masm->cmpq(FieldOperand(receiver.reg(), HeapObject::kMapOffset), | 5891 masm->cmpq(FieldOperand(receiver.reg(), HeapObject::kMapOffset), |
5892 kScratchRegister); | 5892 kScratchRegister); |
5893 deferred->Branch(not_equal); | 5893 deferred->Branch(not_equal); |
5894 | 5894 |
5895 // Check that the key is a non-negative smi. | 5895 // Check that the key is a non-negative smi. |
5896 __ testl(key.reg(), | 5896 __ testl(key.reg(), |
5897 Immediate(static_cast<int32_t>(kSmiTagMask | 0x80000000u))); | 5897 Immediate(static_cast<uint32_t>(kSmiTagMask | 0x80000000u))); |
5898 deferred->Branch(not_zero); | 5898 deferred->Branch(not_zero); |
5899 | 5899 |
5900 // Get the elements array from the receiver and check that it | 5900 // Get the elements array from the receiver and check that it |
5901 // is not a dictionary. | 5901 // is not a dictionary. |
5902 __ movq(elements.reg(), | 5902 __ movq(elements.reg(), |
5903 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); | 5903 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); |
5904 __ Cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), | 5904 __ Cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), |
5905 Factory::fixed_array_map()); | 5905 Factory::fixed_array_map()); |
5906 deferred->Branch(not_equal); | 5906 deferred->Branch(not_equal); |
5907 | 5907 |
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6756 // rbx: pointer to C function (C callee-saved). | 6756 // rbx: pointer to C function (C callee-saved). |
6757 // rbp: frame pointer (restored after C call). | 6757 // rbp: frame pointer (restored after C call). |
6758 // rsp: stack pointer (restored after C call). | 6758 // rsp: stack pointer (restored after C call). |
6759 // r14: number of arguments including receiver (C callee-saved). | 6759 // r14: number of arguments including receiver (C callee-saved). |
6760 // r15: pointer to the first argument (C callee-saved). | 6760 // r15: pointer to the first argument (C callee-saved). |
6761 // This pointer is reused in LeaveExitFrame(), so it is stored in a | 6761 // This pointer is reused in LeaveExitFrame(), so it is stored in a |
6762 // callee-saved register. | 6762 // callee-saved register. |
6763 | 6763 |
6764 if (do_gc) { | 6764 if (do_gc) { |
6765 // Pass failure code returned from last attempt as first argument to GC. | 6765 // Pass failure code returned from last attempt as first argument to GC. |
6766 #ifdef __MSVC__ | 6766 #ifdef _WIN64 |
6767 __ movq(rcx, rax); // argc. | 6767 __ movq(rcx, rax); |
6768 #else // ! defined(__MSVC__) | 6768 #else // ! defined(_WIN64) |
6769 __ movq(rdi, rax); // argv. | 6769 __ movq(rdi, rax); |
6770 #endif | 6770 #endif |
6771 __ movq(kScratchRegister, | 6771 __ movq(kScratchRegister, |
6772 FUNCTION_ADDR(Runtime::PerformGC), | 6772 FUNCTION_ADDR(Runtime::PerformGC), |
6773 RelocInfo::RUNTIME_ENTRY); | 6773 RelocInfo::RUNTIME_ENTRY); |
6774 __ call(kScratchRegister); | 6774 __ call(kScratchRegister); |
6775 } | 6775 } |
6776 | 6776 |
6777 ExternalReference scope_depth = | 6777 ExternalReference scope_depth = |
6778 ExternalReference::heap_always_allocate_scope_depth(); | 6778 ExternalReference::heap_always_allocate_scope_depth(); |
6779 if (always_allocate_scope) { | 6779 if (always_allocate_scope) { |
6780 __ movq(kScratchRegister, scope_depth); | 6780 __ movq(kScratchRegister, scope_depth); |
6781 __ incl(Operand(kScratchRegister, 0)); | 6781 __ incl(Operand(kScratchRegister, 0)); |
6782 } | 6782 } |
6783 | 6783 |
6784 // Call C function. | 6784 // Call C function. |
6785 #ifdef __MSVC__ | 6785 #ifdef _WIN64 |
6786 // MSVC passes arguments in rcx, rdx, r8, r9 | 6786 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9 |
6787 __ movq(rcx, r14); // argc. | 6787 // Store Arguments object on stack |
6788 __ movq(rdx, r15); // argv. | 6788 __ movq(Operand(rsp, 1 * kPointerSize), r14); // argc. |
6789 #else // ! defined(__MSVC__) | 6789 __ movq(Operand(rsp, 2 * kPointerSize), r15); // argv. |
| 6790 // Pass a pointer to the Arguments object as the first argument. |
| 6791 __ lea(rcx, Operand(rsp, 1 * kPointerSize)); |
| 6792 #else // ! defined(_WIN64) |
6790 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. | 6793 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. |
6791 __ movq(rdi, r14); // argc. | 6794 __ movq(rdi, r14); // argc. |
6792 __ movq(rsi, r15); // argv. | 6795 __ movq(rsi, r15); // argv. |
6793 #endif | 6796 #endif |
6794 __ call(rbx); | 6797 __ call(rbx); |
6795 // Result is in rax - do not destroy this register! | 6798 // Result is in rax - do not destroy this register! |
6796 | 6799 |
6797 if (always_allocate_scope) { | 6800 if (always_allocate_scope) { |
6798 __ movq(kScratchRegister, scope_depth); | 6801 __ movq(kScratchRegister, scope_depth); |
6799 __ decl(Operand(kScratchRegister, 0)); | 6802 __ decl(Operand(kScratchRegister, 0)); |
(...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7698 int CompareStub::MinorKey() { | 7701 int CompareStub::MinorKey() { |
7699 // Encode the two parameters in a unique 16 bit value. | 7702 // Encode the two parameters in a unique 16 bit value. |
7700 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); | 7703 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); |
7701 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); | 7704 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); |
7702 } | 7705 } |
7703 | 7706 |
7704 | 7707 |
7705 #undef __ | 7708 #undef __ |
7706 | 7709 |
7707 } } // namespace v8::internal | 7710 } } // namespace v8::internal |
OLD | NEW |