Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(336)

Side by Side Diff: src/x64/macro-assembler-x64.h

Issue 6614010: [Isolates] Merge 6700:7030 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/lithium-x64.cc ('k') | src/x64/macro-assembler-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 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
11 // with the distribution. 11 // with the distribution.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 static const Register kSmiConstantRegister = { 15 }; // r15 (callee save). 51 static const Register kSmiConstantRegister = { 15 }; // r15 (callee save).
52 static const Register kRootRegister = { 13 }; // r13 (callee save). 52 static const Register kRootRegister = { 13 }; // r13 (callee save).
53 // Value of smi in kSmiConstantRegister. 53 // Value of smi in kSmiConstantRegister.
54 static const int kSmiConstantRegisterValue = 1; 54 static const int kSmiConstantRegisterValue = 1;
55 55
56 // Convenience for platform-independent signatures. 56 // Convenience for platform-independent signatures.
57 typedef Operand MemOperand; 57 typedef Operand MemOperand;
58 58
59 // Forward declaration. 59 // Forward declaration.
60 class JumpTarget; 60 class JumpTarget;
61 class PostCallGenerator;
61 62
62 struct SmiIndex { 63 struct SmiIndex {
63 SmiIndex(Register index_register, ScaleFactor scale) 64 SmiIndex(Register index_register, ScaleFactor scale)
64 : reg(index_register), 65 : reg(index_register),
65 scale(scale) {} 66 scale(scale) {}
66 Register reg; 67 Register reg;
67 ScaleFactor scale; 68 ScaleFactor scale;
68 }; 69 };
69 70
70 // MacroAssembler implements a collection of frequently used macros. 71 // MacroAssembler implements a collection of frequently used macros.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 // argument in register rsi. 164 // argument in register rsi.
164 void LeaveExitFrame(bool save_doubles = false); 165 void LeaveExitFrame(bool save_doubles = false);
165 166
166 // Leave the current exit frame. Expects/provides the return value in 167 // Leave the current exit frame. Expects/provides the return value in
167 // register rax (untouched). 168 // register rax (untouched).
168 void LeaveApiExitFrame(); 169 void LeaveApiExitFrame();
169 170
170 // Push and pop the registers that can hold pointers. 171 // Push and pop the registers that can hold pointers.
171 void PushSafepointRegisters() { Pushad(); } 172 void PushSafepointRegisters() { Pushad(); }
172 void PopSafepointRegisters() { Popad(); } 173 void PopSafepointRegisters() { Popad(); }
173 static int SafepointRegisterStackIndex(int reg_code) { 174 // Store the value in register src in the safepoint register stack
174 return kSafepointPushRegisterIndices[reg_code]; 175 // slot for register dst.
175 } 176 void StoreToSafepointRegisterSlot(Register dst, Register src);
176 177 void LoadFromSafepointRegisterSlot(Register dst, Register src);
177 178
178 // --------------------------------------------------------------------------- 179 // ---------------------------------------------------------------------------
179 // JavaScript invokes 180 // JavaScript invokes
180 181
181 // Invoke the JavaScript function code by either calling or jumping. 182 // Invoke the JavaScript function code by either calling or jumping.
182 void InvokeCode(Register code, 183 void InvokeCode(Register code,
183 const ParameterCount& expected, 184 const ParameterCount& expected,
184 const ParameterCount& actual, 185 const ParameterCount& actual,
185 InvokeFlag flag); 186 InvokeFlag flag,
187 PostCallGenerator* post_call_generator = NULL);
186 188
187 void InvokeCode(Handle<Code> code, 189 void InvokeCode(Handle<Code> code,
188 const ParameterCount& expected, 190 const ParameterCount& expected,
189 const ParameterCount& actual, 191 const ParameterCount& actual,
190 RelocInfo::Mode rmode, 192 RelocInfo::Mode rmode,
191 InvokeFlag flag); 193 InvokeFlag flag,
194 PostCallGenerator* post_call_generator = NULL);
192 195
193 // Invoke the JavaScript function in the given register. Changes the 196 // Invoke the JavaScript function in the given register. Changes the
194 // current context to the context in the function before invoking. 197 // current context to the context in the function before invoking.
195 void InvokeFunction(Register function, 198 void InvokeFunction(Register function,
196 const ParameterCount& actual, 199 const ParameterCount& actual,
197 InvokeFlag flag); 200 InvokeFlag flag,
201 PostCallGenerator* post_call_generator = NULL);
198 202
199 void InvokeFunction(JSFunction* function, 203 void InvokeFunction(JSFunction* function,
200 const ParameterCount& actual, 204 const ParameterCount& actual,
201 InvokeFlag flag); 205 InvokeFlag flag,
206 PostCallGenerator* post_call_generator = NULL);
202 207
203 // Invoke specified builtin JavaScript function. Adds an entry to 208 // Invoke specified builtin JavaScript function. Adds an entry to
204 // the unresolved list if the name does not resolve. 209 // the unresolved list if the name does not resolve.
205 void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag); 210 void InvokeBuiltin(Builtins::JavaScript id,
211 InvokeFlag flag,
212 PostCallGenerator* post_call_generator = NULL);
206 213
207 // Store the function for the given builtin in the target register. 214 // Store the function for the given builtin in the target register.
208 void GetBuiltinFunction(Register target, Builtins::JavaScript id); 215 void GetBuiltinFunction(Register target, Builtins::JavaScript id);
209 216
210 // Store the code object for the given builtin in the target register. 217 // Store the code object for the given builtin in the target register.
211 void GetBuiltinEntry(Register target, Builtins::JavaScript id); 218 void GetBuiltinEntry(Register target, Builtins::JavaScript id);
212 219
213 220
214 // --------------------------------------------------------------------------- 221 // ---------------------------------------------------------------------------
215 // Smi tagging, untagging and operations on tagged smis. 222 // Smi tagging, untagging and operations on tagged smis.
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 661
655 // Abort execution if argument is not a number. Used in debug code. 662 // Abort execution if argument is not a number. Used in debug code.
656 void AbortIfNotNumber(Register object); 663 void AbortIfNotNumber(Register object);
657 664
658 // Abort execution if argument is a smi. Used in debug code. 665 // Abort execution if argument is a smi. Used in debug code.
659 void AbortIfSmi(Register object); 666 void AbortIfSmi(Register object);
660 667
661 // Abort execution if argument is not a smi. Used in debug code. 668 // Abort execution if argument is not a smi. Used in debug code.
662 void AbortIfNotSmi(Register object); 669 void AbortIfNotSmi(Register object);
663 670
671 // Abort execution if argument is a string. Used in debug code.
672 void AbortIfNotString(Register object);
673
664 // Abort execution if argument is not the root value with the given index. 674 // Abort execution if argument is not the root value with the given index.
665 void AbortIfNotRootValue(Register src, 675 void AbortIfNotRootValue(Register src,
666 Heap::RootListIndex root_value_index, 676 Heap::RootListIndex root_value_index,
667 const char* message); 677 const char* message);
668 678
669 // --------------------------------------------------------------------------- 679 // ---------------------------------------------------------------------------
670 // Exception handling 680 // Exception handling
671 681
672 // Push a new try handler and link into try handler chain. The return 682 // Push a new try handler and link into try handler chain. The return
673 // address must be pushed before calling this helper. 683 // address must be pushed before calling this helper.
674 void PushTryHandler(CodeLocation try_location, HandlerType type); 684 void PushTryHandler(CodeLocation try_location, HandlerType type);
675 685
676 // Unlink the stack handler on top of the stack from the try handler chain. 686 // Unlink the stack handler on top of the stack from the try handler chain.
677 void PopTryHandler(); 687 void PopTryHandler();
678 688
689 // Activate the top handler in the try hander chain and pass the
690 // thrown value.
691 void Throw(Register value);
692
693 // Propagate an uncatchable exception out of the current JS stack.
694 void ThrowUncatchable(UncatchableExceptionType type, Register value);
695
679 // --------------------------------------------------------------------------- 696 // ---------------------------------------------------------------------------
680 // Inline caching support 697 // Inline caching support
681 698
682 // Generate code for checking access rights - used for security checks 699 // Generate code for checking access rights - used for security checks
683 // on access to global objects across environments. The holder register 700 // on access to global objects across environments. The holder register
684 // is left untouched, but the scratch register and kScratchRegister, 701 // is left untouched, but the scratch register and kScratchRegister,
685 // which must be different, are clobbered. 702 // which must be different, are clobbered.
686 void CheckAccessGlobalProxy(Register holder_reg, 703 void CheckAccessGlobalProxy(Register holder_reg,
687 Register scratch, 704 Register scratch,
688 Label* miss); 705 Label* miss);
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 // Verify restrictions about code generated in stubs. 973 // Verify restrictions about code generated in stubs.
957 void set_generating_stub(bool value) { generating_stub_ = value; } 974 void set_generating_stub(bool value) { generating_stub_ = value; }
958 bool generating_stub() { return generating_stub_; } 975 bool generating_stub() { return generating_stub_; }
959 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } 976 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
960 bool allow_stub_calls() { return allow_stub_calls_; } 977 bool allow_stub_calls() { return allow_stub_calls_; }
961 978
962 private: 979 private:
963 // Order general registers are pushed by Pushad. 980 // Order general registers are pushed by Pushad.
964 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r12, r14. 981 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r12, r14.
965 static int kSafepointPushRegisterIndices[Register::kNumRegisters]; 982 static int kSafepointPushRegisterIndices[Register::kNumRegisters];
983 static const int kNumSafepointSavedRegisters = 11;
984
966 bool generating_stub_; 985 bool generating_stub_;
967 bool allow_stub_calls_; 986 bool allow_stub_calls_;
968 987
969 // Returns a register holding the smi value. The register MUST NOT be 988 // Returns a register holding the smi value. The register MUST NOT be
970 // modified. It may be the "smi 1 constant" register. 989 // modified. It may be the "smi 1 constant" register.
971 Register GetSmiConstant(Smi* value); 990 Register GetSmiConstant(Smi* value);
972 991
973 // Moves the smi value to the destination register. 992 // Moves the smi value to the destination register.
974 void LoadSmiConstant(Register dst, Smi* value); 993 void LoadSmiConstant(Register dst, Smi* value);
975 994
976 // This handle will be patched with the code object on installation. 995 // This handle will be patched with the code object on installation.
977 Handle<Object> code_object_; 996 Handle<Object> code_object_;
978 997
979 // Helper functions for generating invokes. 998 // Helper functions for generating invokes.
980 template <typename LabelType> 999 template <typename LabelType>
981 void InvokePrologue(const ParameterCount& expected, 1000 void InvokePrologue(const ParameterCount& expected,
982 const ParameterCount& actual, 1001 const ParameterCount& actual,
983 Handle<Code> code_constant, 1002 Handle<Code> code_constant,
984 Register code_register, 1003 Register code_register,
985 LabelType* done, 1004 LabelType* done,
986 InvokeFlag flag); 1005 InvokeFlag flag,
1006 PostCallGenerator* post_call_generator);
987 1007
988 // Activation support. 1008 // Activation support.
989 void EnterFrame(StackFrame::Type type); 1009 void EnterFrame(StackFrame::Type type);
990 void LeaveFrame(StackFrame::Type type); 1010 void LeaveFrame(StackFrame::Type type);
991 1011
992 void EnterExitFramePrologue(bool save_rax); 1012 void EnterExitFramePrologue(bool save_rax);
993 1013
994 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack 1014 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack
995 // accessible via StackSpaceOperand. 1015 // accessible via StackSpaceOperand.
996 void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles); 1016 void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles);
(...skipping 10 matching lines...) Expand all
1007 // Update allocation top with value in result_end register. 1027 // Update allocation top with value in result_end register.
1008 // If scratch is valid, it contains the address of the allocation top. 1028 // If scratch is valid, it contains the address of the allocation top.
1009 void UpdateAllocationTopHelper(Register result_end, Register scratch); 1029 void UpdateAllocationTopHelper(Register result_end, Register scratch);
1010 1030
1011 // Helper for PopHandleScope. Allowed to perform a GC and returns 1031 // Helper for PopHandleScope. Allowed to perform a GC and returns
1012 // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and 1032 // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and
1013 // possibly returns a failure object indicating an allocation failure. 1033 // possibly returns a failure object indicating an allocation failure.
1014 Object* PopHandleScopeHelper(Register saved, 1034 Object* PopHandleScopeHelper(Register saved,
1015 Register scratch, 1035 Register scratch,
1016 bool gc_allowed); 1036 bool gc_allowed);
1037
1038
1039 // Compute memory operands for safepoint stack slots.
1040 Operand SafepointRegisterSlot(Register reg);
1041 static int SafepointRegisterStackIndex(int reg_code) {
1042 return kNumSafepointRegisters - kSafepointPushRegisterIndices[reg_code] - 1;
1043 }
1044
1045 // Needs access to SafepointRegisterStackIndex for optimized frame
1046 // traversal.
1047 friend class OptimizedFrame;
1017 }; 1048 };
1018 1049
1019 1050
1020 // The code patcher is used to patch (typically) small parts of code e.g. for 1051 // The code patcher is used to patch (typically) small parts of code e.g. for
1021 // debugging and other types of instrumentation. When using the code patcher 1052 // debugging and other types of instrumentation. When using the code patcher
1022 // the exact number of bytes specified must be emitted. Is not legal to emit 1053 // the exact number of bytes specified must be emitted. Is not legal to emit
1023 // relocation information. If any of these constraints are violated it causes 1054 // relocation information. If any of these constraints are violated it causes
1024 // an assertion. 1055 // an assertion.
1025 class CodePatcher { 1056 class CodePatcher {
1026 public: 1057 public:
1027 CodePatcher(byte* address, int size); 1058 CodePatcher(byte* address, int size);
1028 virtual ~CodePatcher(); 1059 virtual ~CodePatcher();
1029 1060
1030 // Macro assembler to emit code. 1061 // Macro assembler to emit code.
1031 MacroAssembler* masm() { return &masm_; } 1062 MacroAssembler* masm() { return &masm_; }
1032 1063
1033 private: 1064 private:
1034 byte* address_; // The address of the code being patched. 1065 byte* address_; // The address of the code being patched.
1035 int size_; // Number of bytes of the expected patch size. 1066 int size_; // Number of bytes of the expected patch size.
1036 MacroAssembler masm_; // Macro assembler used to generate the code. 1067 MacroAssembler masm_; // Macro assembler used to generate the code.
1037 }; 1068 };
1038 1069
1039 1070
1071 // Helper class for generating code or data associated with the code
1072 // right after a call instruction. As an example this can be used to
1073 // generate safepoint data after calls for crankshaft.
1074 class PostCallGenerator {
1075 public:
1076 PostCallGenerator() { }
1077 virtual ~PostCallGenerator() { }
1078 virtual void Generate() = 0;
1079 };
1080
1081
1040 // ----------------------------------------------------------------------------- 1082 // -----------------------------------------------------------------------------
1041 // Static helper functions. 1083 // Static helper functions.
1042 1084
1043 // Generate an Operand for loading a field from an object. 1085 // Generate an Operand for loading a field from an object.
1044 static inline Operand FieldOperand(Register object, int offset) { 1086 static inline Operand FieldOperand(Register object, int offset) {
1045 return Operand(object, offset - kHeapObjectTag); 1087 return Operand(object, offset - kHeapObjectTag);
1046 } 1088 }
1047 1089
1048 1090
1049 // Generate an Operand for loading an indexed field from an object. 1091 // Generate an Operand for loading an indexed field from an object.
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
1736 } 1778 }
1737 } 1779 }
1738 1780
1739 1781
1740 template <typename LabelType> 1782 template <typename LabelType>
1741 void MacroAssembler::InvokePrologue(const ParameterCount& expected, 1783 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
1742 const ParameterCount& actual, 1784 const ParameterCount& actual,
1743 Handle<Code> code_constant, 1785 Handle<Code> code_constant,
1744 Register code_register, 1786 Register code_register,
1745 LabelType* done, 1787 LabelType* done,
1746 InvokeFlag flag) { 1788 InvokeFlag flag,
1789 PostCallGenerator* post_call_generator) {
1747 bool definitely_matches = false; 1790 bool definitely_matches = false;
1748 NearLabel invoke; 1791 NearLabel invoke;
1749 if (expected.is_immediate()) { 1792 if (expected.is_immediate()) {
1750 ASSERT(actual.is_immediate()); 1793 ASSERT(actual.is_immediate());
1751 if (expected.immediate() == actual.immediate()) { 1794 if (expected.immediate() == actual.immediate()) {
1752 definitely_matches = true; 1795 definitely_matches = true;
1753 } else { 1796 } else {
1754 Set(rax, actual.immediate()); 1797 Set(rax, actual.immediate());
1755 if (expected.immediate() == 1798 if (expected.immediate() ==
1756 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { 1799 SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1788 Builtins::ArgumentsAdaptorTrampoline)); 1831 Builtins::ArgumentsAdaptorTrampoline));
1789 if (!code_constant.is_null()) { 1832 if (!code_constant.is_null()) {
1790 movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); 1833 movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT);
1791 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); 1834 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag));
1792 } else if (!code_register.is(rdx)) { 1835 } else if (!code_register.is(rdx)) {
1793 movq(rdx, code_register); 1836 movq(rdx, code_register);
1794 } 1837 }
1795 1838
1796 if (flag == CALL_FUNCTION) { 1839 if (flag == CALL_FUNCTION) {
1797 Call(adaptor, RelocInfo::CODE_TARGET); 1840 Call(adaptor, RelocInfo::CODE_TARGET);
1841 if (post_call_generator != NULL) post_call_generator->Generate();
1798 jmp(done); 1842 jmp(done);
1799 } else { 1843 } else {
1800 Jump(adaptor, RelocInfo::CODE_TARGET); 1844 Jump(adaptor, RelocInfo::CODE_TARGET);
1801 } 1845 }
1802 bind(&invoke); 1846 bind(&invoke);
1803 } 1847 }
1804 } 1848 }
1805 1849
1806 1850
1807 } } // namespace v8::internal 1851 } } // namespace v8::internal
1808 1852
1809 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_ 1853 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_
OLDNEW
« no previous file with comments | « src/x64/lithium-x64.cc ('k') | src/x64/macro-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698