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 6811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6822 // Value in rcx is Smi encoded. | 6822 // Value in rcx is Smi encoded. |
6823 | 6823 |
6824 // Patch the arguments.length and the parameters pointer. | 6824 // Patch the arguments.length and the parameters pointer. |
6825 __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 6825 __ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
6826 __ movq(Operand(rsp, 1 * kPointerSize), rcx); | 6826 __ movq(Operand(rsp, 1 * kPointerSize), rcx); |
6827 __ lea(rdx, Operand(rdx, rcx, times_4, kDisplacement)); | 6827 __ lea(rdx, Operand(rdx, rcx, times_4, kDisplacement)); |
6828 __ movq(Operand(rsp, 2 * kPointerSize), rdx); | 6828 __ movq(Operand(rsp, 2 * kPointerSize), rdx); |
6829 | 6829 |
6830 // Do the runtime call to allocate the arguments object. | 6830 // Do the runtime call to allocate the arguments object. |
6831 __ bind(&runtime); | 6831 __ bind(&runtime); |
6832 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3); | 6832 Runtime::Function* f = Runtime::FunctionForId(Runtime::kNewArgumentsFast); |
6833 __ TailCallRuntime(ExternalReference(f), 3, f->result_size); | |
6833 } | 6834 } |
6834 | 6835 |
6835 | 6836 |
6836 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { | 6837 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { |
6837 // The key is in rdx and the parameter count is in rax. | 6838 // The key is in rdx and the parameter count is in rax. |
6838 | 6839 |
6839 // The displacement is used for skipping the frame pointer on the | 6840 // The displacement is used for skipping the frame pointer on the |
6840 // stack. It is the offset of the last parameter (if any) relative | 6841 // stack. It is the offset of the last parameter (if any) relative |
6841 // to the frame pointer. | 6842 // to the frame pointer. |
6842 static const int kDisplacement = 1 * kPointerSize; | 6843 static const int kDisplacement = 1 * kPointerSize; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6884 __ neg(rdx); | 6885 __ neg(rdx); |
6885 __ movq(rax, Operand(rbx, rdx, times_4, kDisplacement)); | 6886 __ movq(rax, Operand(rbx, rdx, times_4, kDisplacement)); |
6886 __ Ret(); | 6887 __ Ret(); |
6887 | 6888 |
6888 // Slow-case: Handle non-smi or out-of-bounds access to arguments | 6889 // Slow-case: Handle non-smi or out-of-bounds access to arguments |
6889 // by calling the runtime system. | 6890 // by calling the runtime system. |
6890 __ bind(&slow); | 6891 __ bind(&slow); |
6891 __ pop(rbx); // Return address. | 6892 __ pop(rbx); // Return address. |
6892 __ push(rdx); | 6893 __ push(rdx); |
6893 __ push(rbx); | 6894 __ push(rbx); |
6894 __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1); | 6895 Runtime::Function* f = |
6896 Runtime::FunctionForId(Runtime::kGetArgumentsProperty); | |
6897 __ TailCallRuntime(ExternalReference(f), 1, f->result_size); | |
6895 } | 6898 } |
6896 | 6899 |
6897 | 6900 |
6898 void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) { | 6901 void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) { |
6899 // Check if the calling frame is an arguments adaptor frame. | 6902 // Check if the calling frame is an arguments adaptor frame. |
6900 Label adaptor; | 6903 Label adaptor; |
6901 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); | 6904 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
6902 __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); | 6905 __ movq(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); |
6903 __ cmpq(rcx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 6906 __ cmpq(rcx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
6904 __ j(equal, &adaptor); | 6907 __ j(equal, &adaptor); |
6905 | 6908 |
6906 // Nothing to do: The formal number of parameters has already been | 6909 // Nothing to do: The formal number of parameters has already been |
6907 // passed in register rax by calling function. Just return it. | 6910 // passed in register rax by calling function. Just return it. |
6908 __ ret(0); | 6911 __ ret(0); |
6909 | 6912 |
6910 // Arguments adaptor case: Read the arguments length from the | 6913 // Arguments adaptor case: Read the arguments length from the |
6911 // adaptor frame and return it. | 6914 // adaptor frame and return it. |
6912 __ bind(&adaptor); | 6915 __ bind(&adaptor); |
6913 __ movq(rax, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 6916 __ movq(rax, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
6914 __ ret(0); | 6917 __ ret(0); |
6915 } | 6918 } |
6916 | 6919 |
6917 | 6920 |
6921 int CEntryStub::MinorKey() { | |
6922 ASSERT(result_size_ <= 2); | |
6923 #ifdef _WIN64 | |
6924 // Simple results returned in rax. | |
6925 // Complex results must be written to address passed as first argument. | |
6926 return (result_size_ < 2) ? 0 : result_size_ * 2; | |
William Hesse
2009/09/07 14:34:18
Why is the key 4 if the size is 2, and 0 if it is
Lasse Reichstein
2009/09/08 11:51:35
Previously, minor key 0 was used for CEntryStub an
| |
6927 #else | |
6928 // Results returned in rax or in rax+rdx by default. | |
Søren Thygesen Gjesse
2009/09/07 12:22:33
Maybe add something about this being compiler spec
Lasse Reichstein
2009/09/08 11:51:35
I'll say something.
It's calling convention specif
| |
6929 return 0; | |
6930 #endif | |
6931 } | |
6932 | |
6933 | |
6918 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { | 6934 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { |
6919 // Check that stack should contain next handler, frame pointer, state and | 6935 // Check that stack should contain next handler, frame pointer, state and |
6920 // return address in that order. | 6936 // return address in that order. |
6921 ASSERT_EQ(StackHandlerConstants::kFPOffset + kPointerSize, | 6937 ASSERT_EQ(StackHandlerConstants::kFPOffset + kPointerSize, |
6922 StackHandlerConstants::kStateOffset); | 6938 StackHandlerConstants::kStateOffset); |
6923 ASSERT_EQ(StackHandlerConstants::kStateOffset + kPointerSize, | 6939 ASSERT_EQ(StackHandlerConstants::kStateOffset + kPointerSize, |
6924 StackHandlerConstants::kPCOffset); | 6940 StackHandlerConstants::kPCOffset); |
6925 | 6941 |
6926 ExternalReference handler_address(Top::k_handler_address); | 6942 ExternalReference handler_address(Top::k_handler_address); |
6927 __ movq(kScratchRegister, handler_address); | 6943 __ movq(kScratchRegister, handler_address); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6979 __ movq(kScratchRegister, scope_depth); | 6995 __ movq(kScratchRegister, scope_depth); |
6980 __ incl(Operand(kScratchRegister, 0)); | 6996 __ incl(Operand(kScratchRegister, 0)); |
6981 } | 6997 } |
6982 | 6998 |
6983 // Call C function. | 6999 // Call C function. |
6984 #ifdef _WIN64 | 7000 #ifdef _WIN64 |
6985 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9 | 7001 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9 |
6986 // Store Arguments object on stack, below the 4 WIN64 ABI parameter slots. | 7002 // Store Arguments object on stack, below the 4 WIN64 ABI parameter slots. |
6987 __ movq(Operand(rsp, 4 * kPointerSize), r14); // argc. | 7003 __ movq(Operand(rsp, 4 * kPointerSize), r14); // argc. |
6988 __ movq(Operand(rsp, 5 * kPointerSize), r15); // argv. | 7004 __ movq(Operand(rsp, 5 * kPointerSize), r15); // argv. |
6989 // Pass a pointer to the Arguments object as the first argument. | 7005 if (result_size_ < 2) { |
Søren Thygesen Gjesse
2009/09/07 12:22:33
Why not == 1? We only have 1 and 2 right?
Lasse Reichstein
2009/09/08 11:51:35
I was expecting 0 to be allowed too (for a functio
| |
6990 __ lea(rcx, Operand(rsp, 4 * kPointerSize)); | 7006 // Pass a pointer to the Arguments object as the first argument. |
7007 // Return result in single register (rax). | |
7008 __ lea(rcx, Operand(rsp, 4 * kPointerSize)); | |
7009 } else { | |
7010 ASSERT_EQ(2, result_size_); | |
7011 // Pass a pointer to the result location as the first argument. | |
7012 __ lea(rcx, Operand(rsp, 6 * kPointerSize)); | |
7013 // Pass a pointer to the Arguments object as the second argument. | |
7014 __ lea(rdx, Operand(rsp, 4 * kPointerSize)); | |
7015 } | |
7016 | |
6991 #else // ! defined(_WIN64) | 7017 #else // ! defined(_WIN64) |
6992 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. | 7018 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. |
6993 __ movq(rdi, r14); // argc. | 7019 __ movq(rdi, r14); // argc. |
6994 __ movq(rsi, r15); // argv. | 7020 __ movq(rsi, r15); // argv. |
6995 #endif | 7021 #endif |
6996 __ call(rbx); | 7022 __ call(rbx); |
6997 // Result is in rax - do not destroy this register! | 7023 // Result is in rax - do not destroy this register! |
6998 | 7024 |
6999 if (always_allocate_scope) { | 7025 if (always_allocate_scope) { |
7000 __ movq(kScratchRegister, scope_depth); | 7026 __ movq(kScratchRegister, scope_depth); |
7001 __ decl(Operand(kScratchRegister, 0)); | 7027 __ decl(Operand(kScratchRegister, 0)); |
7002 } | 7028 } |
7003 | 7029 |
7004 // Check for failure result. | 7030 // Check for failure result. |
7005 Label failure_returned; | 7031 Label failure_returned; |
7006 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); | 7032 ASSERT(((kFailureTag + 1) & kFailureTagMask) == 0); |
7007 __ lea(rcx, Operand(rax, 1)); | 7033 __ lea(rcx, Operand(rax, 1)); |
7008 // Lower 2 bits of rcx are 0 iff rax has failure tag. | 7034 // Lower 2 bits of rcx are 0 iff rax has failure tag. |
7009 __ testl(rcx, Immediate(kFailureTagMask)); | 7035 __ testl(rcx, Immediate(kFailureTagMask)); |
7010 __ j(zero, &failure_returned); | 7036 __ j(zero, &failure_returned); |
7011 | 7037 |
7012 // Exit the JavaScript to C++ exit frame. | 7038 // Exit the JavaScript to C++ exit frame. |
7013 __ LeaveExitFrame(frame_type); | 7039 __ LeaveExitFrame(frame_type, result_size_); |
7014 __ ret(0); | 7040 __ ret(0); |
7015 | 7041 |
7016 // Handling of failure. | 7042 // Handling of failure. |
7017 __ bind(&failure_returned); | 7043 __ bind(&failure_returned); |
7018 | 7044 |
7019 Label retry; | 7045 Label retry; |
7020 // If the returned exception is RETRY_AFTER_GC continue at retry label | 7046 // If the returned exception is RETRY_AFTER_GC continue at retry label |
7021 ASSERT(Failure::RETRY_AFTER_GC == 0); | 7047 ASSERT(Failure::RETRY_AFTER_GC == 0); |
7022 __ testl(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); | 7048 __ testl(rax, Immediate(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); |
7023 __ j(zero, &retry); | 7049 __ j(zero, &retry); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7139 // NOTE: Invocations of builtins may return failure objects | 7165 // NOTE: Invocations of builtins may return failure objects |
7140 // instead of a proper result. The builtin entry handles | 7166 // instead of a proper result. The builtin entry handles |
7141 // this by performing a garbage collection and retrying the | 7167 // this by performing a garbage collection and retrying the |
7142 // builtin once. | 7168 // builtin once. |
7143 | 7169 |
7144 StackFrame::Type frame_type = is_debug_break ? | 7170 StackFrame::Type frame_type = is_debug_break ? |
7145 StackFrame::EXIT_DEBUG : | 7171 StackFrame::EXIT_DEBUG : |
7146 StackFrame::EXIT; | 7172 StackFrame::EXIT; |
7147 | 7173 |
7148 // Enter the exit frame that transitions from JavaScript to C++. | 7174 // Enter the exit frame that transitions from JavaScript to C++. |
7149 __ EnterExitFrame(frame_type); | 7175 __ EnterExitFrame(frame_type, result_size_); |
7150 | 7176 |
7151 // rax: Holds the context at this point, but should not be used. | 7177 // rax: Holds the context at this point, but should not be used. |
7152 // On entry to code generated by GenerateCore, it must hold | 7178 // On entry to code generated by GenerateCore, it must hold |
7153 // a failure result if the collect_garbage argument to GenerateCore | 7179 // a failure result if the collect_garbage argument to GenerateCore |
7154 // is true. This failure result can be the result of code | 7180 // is true. This failure result can be the result of code |
7155 // generated by a previous call to GenerateCore. The value | 7181 // generated by a previous call to GenerateCore. The value |
7156 // of rax is then passed to Runtime::PerformGC. | 7182 // of rax is then passed to Runtime::PerformGC. |
7157 // rbx: pointer to builtin function (C callee-saved). | 7183 // rbx: pointer to builtin function (C callee-saved). |
7158 // rbp: frame pointer of exit frame (restored after C call). | 7184 // rbp: frame pointer of exit frame (restored after C call). |
7159 // rsp: stack pointer (restored after C call). | 7185 // rsp: stack pointer (restored after C call). |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7326 void StackCheckStub::Generate(MacroAssembler* masm) { | 7352 void StackCheckStub::Generate(MacroAssembler* masm) { |
7327 // Because builtins always remove the receiver from the stack, we | 7353 // Because builtins always remove the receiver from the stack, we |
7328 // have to fake one to avoid underflowing the stack. The receiver | 7354 // have to fake one to avoid underflowing the stack. The receiver |
7329 // must be inserted below the return address on the stack so we | 7355 // must be inserted below the return address on the stack so we |
7330 // temporarily store that in a register. | 7356 // temporarily store that in a register. |
7331 __ pop(rax); | 7357 __ pop(rax); |
7332 __ push(Immediate(Smi::FromInt(0))); | 7358 __ push(Immediate(Smi::FromInt(0))); |
7333 __ push(rax); | 7359 __ push(rax); |
7334 | 7360 |
7335 // Do tail-call to runtime routine. | 7361 // Do tail-call to runtime routine. |
7336 __ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1); | 7362 Runtime::Function* f = Runtime::FunctionForId(Runtime::kStackGuard); |
7363 __ TailCallRuntime(ExternalReference(f), 1, f->result_size); | |
7337 } | 7364 } |
7338 | 7365 |
7339 | 7366 |
7340 void FloatingPointHelper::AllocateHeapNumber(MacroAssembler* masm, | 7367 void FloatingPointHelper::AllocateHeapNumber(MacroAssembler* masm, |
7341 Label* need_gc, | 7368 Label* need_gc, |
7342 Register scratch, | 7369 Register scratch, |
7343 Register result) { | 7370 Register result) { |
7344 // Allocate heap number in new space. | 7371 // Allocate heap number in new space. |
7345 __ AllocateObjectInNewSpace(HeapNumber::kSize, | 7372 __ AllocateObjectInNewSpace(HeapNumber::kSize, |
7346 result, | 7373 result, |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7905 int CompareStub::MinorKey() { | 7932 int CompareStub::MinorKey() { |
7906 // Encode the two parameters in a unique 16 bit value. | 7933 // Encode the two parameters in a unique 16 bit value. |
7907 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); | 7934 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); |
7908 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); | 7935 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); |
7909 } | 7936 } |
7910 | 7937 |
7911 | 7938 |
7912 #undef __ | 7939 #undef __ |
7913 | 7940 |
7914 } } // namespace v8::internal | 7941 } } // namespace v8::internal |
OLD | NEW |