| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 static const int kSmiConstantRegisterValue = 1; | 54 static const int kSmiConstantRegisterValue = 1; |
| 55 // Actual value of root register is offset from the root array's start | 55 // Actual value of root register is offset from the root array's start |
| 56 // to take advantage of negitive 8-bit displacement values. | 56 // to take advantage of negitive 8-bit displacement values. |
| 57 static const int kRootRegisterBias = 128; | 57 static const int kRootRegisterBias = 128; |
| 58 | 58 |
| 59 // Convenience for platform-independent signatures. | 59 // Convenience for platform-independent signatures. |
| 60 typedef Operand MemOperand; | 60 typedef Operand MemOperand; |
| 61 | 61 |
| 62 // Forward declaration. | 62 // Forward declaration. |
| 63 class JumpTarget; | 63 class JumpTarget; |
| 64 class PostCallGenerator; | 64 class CallWrapper; |
| 65 | 65 |
| 66 struct SmiIndex { | 66 struct SmiIndex { |
| 67 SmiIndex(Register index_register, ScaleFactor scale) | 67 SmiIndex(Register index_register, ScaleFactor scale) |
| 68 : reg(index_register), | 68 : reg(index_register), |
| 69 scale(scale) {} | 69 scale(scale) {} |
| 70 Register reg; | 70 Register reg; |
| 71 ScaleFactor scale; | 71 ScaleFactor scale; |
| 72 }; | 72 }; |
| 73 | 73 |
| 74 // MacroAssembler implements a collection of frequently used macros. | 74 // MacroAssembler implements a collection of frequently used macros. |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 } | 192 } |
| 193 | 193 |
| 194 // --------------------------------------------------------------------------- | 194 // --------------------------------------------------------------------------- |
| 195 // JavaScript invokes | 195 // JavaScript invokes |
| 196 | 196 |
| 197 // Invoke the JavaScript function code by either calling or jumping. | 197 // Invoke the JavaScript function code by either calling or jumping. |
| 198 void InvokeCode(Register code, | 198 void InvokeCode(Register code, |
| 199 const ParameterCount& expected, | 199 const ParameterCount& expected, |
| 200 const ParameterCount& actual, | 200 const ParameterCount& actual, |
| 201 InvokeFlag flag, | 201 InvokeFlag flag, |
| 202 PostCallGenerator* post_call_generator = NULL); | 202 CallWrapper* call_wrapper = NULL); |
| 203 | 203 |
| 204 void InvokeCode(Handle<Code> code, | 204 void InvokeCode(Handle<Code> code, |
| 205 const ParameterCount& expected, | 205 const ParameterCount& expected, |
| 206 const ParameterCount& actual, | 206 const ParameterCount& actual, |
| 207 RelocInfo::Mode rmode, | 207 RelocInfo::Mode rmode, |
| 208 InvokeFlag flag, | 208 InvokeFlag flag, |
| 209 PostCallGenerator* post_call_generator = NULL); | 209 CallWrapper* call_wrapper = NULL); |
| 210 | 210 |
| 211 // Invoke the JavaScript function in the given register. Changes the | 211 // Invoke the JavaScript function in the given register. Changes the |
| 212 // current context to the context in the function before invoking. | 212 // current context to the context in the function before invoking. |
| 213 void InvokeFunction(Register function, | 213 void InvokeFunction(Register function, |
| 214 const ParameterCount& actual, | 214 const ParameterCount& actual, |
| 215 InvokeFlag flag, | 215 InvokeFlag flag, |
| 216 PostCallGenerator* post_call_generator = NULL); | 216 CallWrapper* call_wrapper = NULL); |
| 217 | 217 |
| 218 void InvokeFunction(JSFunction* function, | 218 void InvokeFunction(JSFunction* function, |
| 219 const ParameterCount& actual, | 219 const ParameterCount& actual, |
| 220 InvokeFlag flag, | 220 InvokeFlag flag, |
| 221 PostCallGenerator* post_call_generator = NULL); | 221 CallWrapper* call_wrapper = NULL); |
| 222 | 222 |
| 223 // Invoke specified builtin JavaScript function. Adds an entry to | 223 // Invoke specified builtin JavaScript function. Adds an entry to |
| 224 // the unresolved list if the name does not resolve. | 224 // the unresolved list if the name does not resolve. |
| 225 void InvokeBuiltin(Builtins::JavaScript id, | 225 void InvokeBuiltin(Builtins::JavaScript id, |
| 226 InvokeFlag flag, | 226 InvokeFlag flag, |
| 227 PostCallGenerator* post_call_generator = NULL); | 227 CallWrapper* call_wrapper = NULL); |
| 228 | 228 |
| 229 // Store the function for the given builtin in the target register. | 229 // Store the function for the given builtin in the target register. |
| 230 void GetBuiltinFunction(Register target, Builtins::JavaScript id); | 230 void GetBuiltinFunction(Register target, Builtins::JavaScript id); |
| 231 | 231 |
| 232 // Store the code object for the given builtin in the target register. | 232 // Store the code object for the given builtin in the target register. |
| 233 void GetBuiltinEntry(Register target, Builtins::JavaScript id); | 233 void GetBuiltinEntry(Register target, Builtins::JavaScript id); |
| 234 | 234 |
| 235 | 235 |
| 236 // --------------------------------------------------------------------------- | 236 // --------------------------------------------------------------------------- |
| 237 // Smi tagging, untagging and operations on tagged smis. | 237 // Smi tagging, untagging and operations on tagged smis. |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 | 619 |
| 620 // Control Flow | 620 // Control Flow |
| 621 void Jump(Address destination, RelocInfo::Mode rmode); | 621 void Jump(Address destination, RelocInfo::Mode rmode); |
| 622 void Jump(ExternalReference ext); | 622 void Jump(ExternalReference ext); |
| 623 void Jump(Handle<Code> code_object, RelocInfo::Mode rmode); | 623 void Jump(Handle<Code> code_object, RelocInfo::Mode rmode); |
| 624 | 624 |
| 625 void Call(Address destination, RelocInfo::Mode rmode); | 625 void Call(Address destination, RelocInfo::Mode rmode); |
| 626 void Call(ExternalReference ext); | 626 void Call(ExternalReference ext); |
| 627 void Call(Handle<Code> code_object, RelocInfo::Mode rmode); | 627 void Call(Handle<Code> code_object, RelocInfo::Mode rmode); |
| 628 | 628 |
| 629 // The size of the code generated for different call instructions. |
| 630 int CallSize(Address destination, RelocInfo::Mode rmode) { |
| 631 return kCallInstructionLength; |
| 632 } |
| 633 int CallSize(ExternalReference ext) { |
| 634 return kCallInstructionLength; |
| 635 } |
| 636 int CallSize(Handle<Code> code_object) { |
| 637 // Code calls use 32-bit relative addressing. |
| 638 return kShortCallInstructionLength; |
| 639 } |
| 640 int CallSize(Register target) { |
| 641 // Opcode: REX_opt FF /2 m64 |
| 642 return (target.high_bit() != 0) ? 3 : 2; |
| 643 } |
| 644 int CallSize(const Operand& target) { |
| 645 // Opcode: REX_opt FF /2 m64 |
| 646 return (target.requires_rex() ? 2 : 1) + target.operand_size(); |
| 647 } |
| 648 |
| 629 // Emit call to the code we are currently generating. | 649 // Emit call to the code we are currently generating. |
| 630 void CallSelf() { | 650 void CallSelf() { |
| 631 Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location())); | 651 Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location())); |
| 632 Call(self, RelocInfo::CODE_TARGET); | 652 Call(self, RelocInfo::CODE_TARGET); |
| 633 } | 653 } |
| 634 | 654 |
| 635 // Non-x64 instructions. | 655 // Non-x64 instructions. |
| 636 // Push/pop all general purpose registers. | 656 // Push/pop all general purpose registers. |
| 637 // Does not push rsp/rbp nor any of the assembler's special purpose registers | 657 // Does not push rsp/rbp nor any of the assembler's special purpose registers |
| 638 // (kScratchRegister, kSmiConstantRegister, kRootRegister). | 658 // (kScratchRegister, kSmiConstantRegister, kRootRegister). |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1011 Handle<Object> code_object_; | 1031 Handle<Object> code_object_; |
| 1012 | 1032 |
| 1013 // Helper functions for generating invokes. | 1033 // Helper functions for generating invokes. |
| 1014 template <typename LabelType> | 1034 template <typename LabelType> |
| 1015 void InvokePrologue(const ParameterCount& expected, | 1035 void InvokePrologue(const ParameterCount& expected, |
| 1016 const ParameterCount& actual, | 1036 const ParameterCount& actual, |
| 1017 Handle<Code> code_constant, | 1037 Handle<Code> code_constant, |
| 1018 Register code_register, | 1038 Register code_register, |
| 1019 LabelType* done, | 1039 LabelType* done, |
| 1020 InvokeFlag flag, | 1040 InvokeFlag flag, |
| 1021 PostCallGenerator* post_call_generator); | 1041 CallWrapper* call_wrapper); |
| 1022 | 1042 |
| 1023 // Activation support. | 1043 // Activation support. |
| 1024 void EnterFrame(StackFrame::Type type); | 1044 void EnterFrame(StackFrame::Type type); |
| 1025 void LeaveFrame(StackFrame::Type type); | 1045 void LeaveFrame(StackFrame::Type type); |
| 1026 | 1046 |
| 1027 void EnterExitFramePrologue(bool save_rax); | 1047 void EnterExitFramePrologue(bool save_rax); |
| 1028 | 1048 |
| 1029 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack | 1049 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack |
| 1030 // accessible via StackSpaceOperand. | 1050 // accessible via StackSpaceOperand. |
| 1031 void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles); | 1051 void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1077 MacroAssembler* masm() { return &masm_; } | 1097 MacroAssembler* masm() { return &masm_; } |
| 1078 | 1098 |
| 1079 private: | 1099 private: |
| 1080 byte* address_; // The address of the code being patched. | 1100 byte* address_; // The address of the code being patched. |
| 1081 int size_; // Number of bytes of the expected patch size. | 1101 int size_; // Number of bytes of the expected patch size. |
| 1082 MacroAssembler masm_; // Macro assembler used to generate the code. | 1102 MacroAssembler masm_; // Macro assembler used to generate the code. |
| 1083 }; | 1103 }; |
| 1084 | 1104 |
| 1085 | 1105 |
| 1086 // Helper class for generating code or data associated with the code | 1106 // Helper class for generating code or data associated with the code |
| 1087 // right after a call instruction. As an example this can be used to | 1107 // right before or after a call instruction. As an example this can be used to |
| 1088 // generate safepoint data after calls for crankshaft. | 1108 // generate safepoint data after calls for crankshaft. |
| 1089 class PostCallGenerator { | 1109 class CallWrapper { |
| 1090 public: | 1110 public: |
| 1091 PostCallGenerator() { } | 1111 CallWrapper() { } |
| 1092 virtual ~PostCallGenerator() { } | 1112 virtual ~CallWrapper() { } |
| 1093 virtual void Generate() = 0; | 1113 // Called just before emitting a call. Argument is the size of the generated |
| 1114 // call code. |
| 1115 virtual void BeforeCall(int call_size) = 0; |
| 1116 // Called just after emitting a call, i.e., at the return site for the call. |
| 1117 virtual void AfterCall() = 0; |
| 1094 }; | 1118 }; |
| 1095 | 1119 |
| 1096 | 1120 |
| 1097 // ----------------------------------------------------------------------------- | 1121 // ----------------------------------------------------------------------------- |
| 1098 // Static helper functions. | 1122 // Static helper functions. |
| 1099 | 1123 |
| 1100 // Generate an Operand for loading a field from an object. | 1124 // Generate an Operand for loading a field from an object. |
| 1101 static inline Operand FieldOperand(Register object, int offset) { | 1125 static inline Operand FieldOperand(Register object, int offset) { |
| 1102 return Operand(object, offset - kHeapObjectTag); | 1126 return Operand(object, offset - kHeapObjectTag); |
| 1103 } | 1127 } |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1794 } | 1818 } |
| 1795 | 1819 |
| 1796 | 1820 |
| 1797 template <typename LabelType> | 1821 template <typename LabelType> |
| 1798 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 1822 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
| 1799 const ParameterCount& actual, | 1823 const ParameterCount& actual, |
| 1800 Handle<Code> code_constant, | 1824 Handle<Code> code_constant, |
| 1801 Register code_register, | 1825 Register code_register, |
| 1802 LabelType* done, | 1826 LabelType* done, |
| 1803 InvokeFlag flag, | 1827 InvokeFlag flag, |
| 1804 PostCallGenerator* post_call_generator) { | 1828 CallWrapper* call_wrapper) { |
| 1805 bool definitely_matches = false; | 1829 bool definitely_matches = false; |
| 1806 NearLabel invoke; | 1830 NearLabel invoke; |
| 1807 if (expected.is_immediate()) { | 1831 if (expected.is_immediate()) { |
| 1808 ASSERT(actual.is_immediate()); | 1832 ASSERT(actual.is_immediate()); |
| 1809 if (expected.immediate() == actual.immediate()) { | 1833 if (expected.immediate() == actual.immediate()) { |
| 1810 definitely_matches = true; | 1834 definitely_matches = true; |
| 1811 } else { | 1835 } else { |
| 1812 Set(rax, actual.immediate()); | 1836 Set(rax, actual.immediate()); |
| 1813 if (expected.immediate() == | 1837 if (expected.immediate() == |
| 1814 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { | 1838 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1844 Handle<Code> adaptor = | 1868 Handle<Code> adaptor = |
| 1845 Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); | 1869 Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); |
| 1846 if (!code_constant.is_null()) { | 1870 if (!code_constant.is_null()) { |
| 1847 movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); | 1871 movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); |
| 1848 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 1872 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 1849 } else if (!code_register.is(rdx)) { | 1873 } else if (!code_register.is(rdx)) { |
| 1850 movq(rdx, code_register); | 1874 movq(rdx, code_register); |
| 1851 } | 1875 } |
| 1852 | 1876 |
| 1853 if (flag == CALL_FUNCTION) { | 1877 if (flag == CALL_FUNCTION) { |
| 1878 if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(adaptor)); |
| 1854 Call(adaptor, RelocInfo::CODE_TARGET); | 1879 Call(adaptor, RelocInfo::CODE_TARGET); |
| 1855 if (post_call_generator != NULL) post_call_generator->Generate(); | 1880 if (call_wrapper != NULL) call_wrapper->AfterCall(); |
| 1856 jmp(done); | 1881 jmp(done); |
| 1857 } else { | 1882 } else { |
| 1858 Jump(adaptor, RelocInfo::CODE_TARGET); | 1883 Jump(adaptor, RelocInfo::CODE_TARGET); |
| 1859 } | 1884 } |
| 1860 bind(&invoke); | 1885 bind(&invoke); |
| 1861 } | 1886 } |
| 1862 } | 1887 } |
| 1863 | 1888 |
| 1864 | 1889 |
| 1865 } } // namespace v8::internal | 1890 } } // namespace v8::internal |
| 1866 | 1891 |
| 1867 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_ | 1892 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_ |
| OLD | NEW |