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

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

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
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 29 matching lines...) Expand all
41 TAG_OBJECT = 1 << 0, 41 TAG_OBJECT = 1 << 0,
42 // The content of the result register already contains the allocation top in 42 // The content of the result register already contains the allocation top in
43 // new space. 43 // new space.
44 RESULT_CONTAINS_TOP = 1 << 1 44 RESULT_CONTAINS_TOP = 1 << 1
45 }; 45 };
46 46
47 // Default scratch register used by MacroAssembler (and other code that needs 47 // Default scratch register used by MacroAssembler (and other code that needs
48 // a spare register). The register isn't callee save, and not used by the 48 // a spare register). The register isn't callee save, and not used by the
49 // function calling convention. 49 // function calling convention.
50 static const Register kScratchRegister = { 10 }; // r10. 50 static const Register kScratchRegister = { 10 }; // r10.
51 static const Register kSmiConstantRegister = { 15 }; // r15 (callee save). 51 static const Register kSmiConstantRegister = { 12 }; // r12 (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 // Actual value of root register is offset from the root array's start
56 // to take advantage of negitive 8-bit displacement values.
57 static const int kRootRegisterBias = 128;
55 58
56 // Convenience for platform-independent signatures. 59 // Convenience for platform-independent signatures.
57 typedef Operand MemOperand; 60 typedef Operand MemOperand;
58 61
59 // Forward declaration. 62 // Forward declaration.
60 class JumpTarget; 63 class JumpTarget;
64 class CallWrapper;
61 65
62 struct SmiIndex { 66 struct SmiIndex {
63 SmiIndex(Register index_register, ScaleFactor scale) 67 SmiIndex(Register index_register, ScaleFactor scale)
64 : reg(index_register), 68 : reg(index_register),
65 scale(scale) {} 69 scale(scale) {}
66 Register reg; 70 Register reg;
67 ScaleFactor scale; 71 ScaleFactor scale;
68 }; 72 };
69 73
70 // MacroAssembler implements a collection of frequently used macros. 74 // MacroAssembler implements a collection of frequently used macros.
71 class MacroAssembler: public Assembler { 75 class MacroAssembler: public Assembler {
72 public: 76 public:
73 MacroAssembler(void* buffer, int size); 77 MacroAssembler(void* buffer, int size);
74 78
75 void LoadRoot(Register destination, Heap::RootListIndex index); 79 void LoadRoot(Register destination, Heap::RootListIndex index);
80 // Load a root value where the index (or part of it) is variable.
81 // The variable_offset register is added to the fixed_offset value
82 // to get the index into the root-array.
83 void LoadRootIndexed(Register destination,
84 Register variable_offset,
85 int fixed_offset);
76 void CompareRoot(Register with, Heap::RootListIndex index); 86 void CompareRoot(Register with, Heap::RootListIndex index);
77 void CompareRoot(const Operand& with, Heap::RootListIndex index); 87 void CompareRoot(const Operand& with, Heap::RootListIndex index);
78 void PushRoot(Heap::RootListIndex index); 88 void PushRoot(Heap::RootListIndex index);
79 void StoreRoot(Register source, Heap::RootListIndex index); 89 void StoreRoot(Register source, Heap::RootListIndex index);
80 90
81 // --------------------------------------------------------------------------- 91 // ---------------------------------------------------------------------------
82 // GC Support 92 // GC Support
83 93
84 // For page containing |object| mark region covering |addr| dirty. 94 // For page containing |object| mark region covering |addr| dirty.
85 // RecordWriteHelper only works if the object is not in new 95 // RecordWriteHelper only works if the object is not in new
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 // argument in register rsi. 177 // argument in register rsi.
168 void LeaveExitFrame(bool save_doubles = false); 178 void LeaveExitFrame(bool save_doubles = false);
169 179
170 // Leave the current exit frame. Expects/provides the return value in 180 // Leave the current exit frame. Expects/provides the return value in
171 // register rax (untouched). 181 // register rax (untouched).
172 void LeaveApiExitFrame(); 182 void LeaveApiExitFrame();
173 183
174 // Push and pop the registers that can hold pointers. 184 // Push and pop the registers that can hold pointers.
175 void PushSafepointRegisters() { Pushad(); } 185 void PushSafepointRegisters() { Pushad(); }
176 void PopSafepointRegisters() { Popad(); } 186 void PopSafepointRegisters() { Popad(); }
177 static int SafepointRegisterStackIndex(int reg_code) { 187 // Store the value in register src in the safepoint register stack
178 return kNumSafepointRegisters - 1 - 188 // slot for register dst.
179 kSafepointPushRegisterIndices[reg_code]; 189 void StoreToSafepointRegisterSlot(Register dst, Register src);
190 void LoadFromSafepointRegisterSlot(Register dst, Register src);
191
192 void InitializeRootRegister() {
193 ExternalReference roots_address = ExternalReference::roots_address();
194 movq(kRootRegister, roots_address);
195 addq(kRootRegister, Immediate(kRootRegisterBias));
180 } 196 }
181 197
182
183 // --------------------------------------------------------------------------- 198 // ---------------------------------------------------------------------------
184 // JavaScript invokes 199 // JavaScript invokes
185 200
186 // Invoke the JavaScript function code by either calling or jumping. 201 // Invoke the JavaScript function code by either calling or jumping.
187 void InvokeCode(Register code, 202 void InvokeCode(Register code,
188 const ParameterCount& expected, 203 const ParameterCount& expected,
189 const ParameterCount& actual, 204 const ParameterCount& actual,
190 InvokeFlag flag); 205 InvokeFlag flag,
206 CallWrapper* call_wrapper = NULL);
191 207
192 void InvokeCode(Handle<Code> code, 208 void InvokeCode(Handle<Code> code,
193 const ParameterCount& expected, 209 const ParameterCount& expected,
194 const ParameterCount& actual, 210 const ParameterCount& actual,
195 RelocInfo::Mode rmode, 211 RelocInfo::Mode rmode,
196 InvokeFlag flag); 212 InvokeFlag flag,
213 CallWrapper* call_wrapper = NULL);
197 214
198 // Invoke the JavaScript function in the given register. Changes the 215 // Invoke the JavaScript function in the given register. Changes the
199 // current context to the context in the function before invoking. 216 // current context to the context in the function before invoking.
200 void InvokeFunction(Register function, 217 void InvokeFunction(Register function,
201 const ParameterCount& actual, 218 const ParameterCount& actual,
202 InvokeFlag flag); 219 InvokeFlag flag,
220 CallWrapper* call_wrapper = NULL);
203 221
204 void InvokeFunction(JSFunction* function, 222 void InvokeFunction(JSFunction* function,
205 const ParameterCount& actual, 223 const ParameterCount& actual,
206 InvokeFlag flag); 224 InvokeFlag flag,
225 CallWrapper* call_wrapper = NULL);
207 226
208 // Invoke specified builtin JavaScript function. Adds an entry to 227 // Invoke specified builtin JavaScript function. Adds an entry to
209 // the unresolved list if the name does not resolve. 228 // the unresolved list if the name does not resolve.
210 void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag); 229 void InvokeBuiltin(Builtins::JavaScript id,
230 InvokeFlag flag,
231 CallWrapper* call_wrapper = NULL);
211 232
212 // Store the function for the given builtin in the target register. 233 // Store the function for the given builtin in the target register.
213 void GetBuiltinFunction(Register target, Builtins::JavaScript id); 234 void GetBuiltinFunction(Register target, Builtins::JavaScript id);
214 235
215 // Store the code object for the given builtin in the target register. 236 // Store the code object for the given builtin in the target register.
216 void GetBuiltinEntry(Register target, Builtins::JavaScript id); 237 void GetBuiltinEntry(Register target, Builtins::JavaScript id);
217 238
218 239
219 // --------------------------------------------------------------------------- 240 // ---------------------------------------------------------------------------
220 // Smi tagging, untagging and operations on tagged smis. 241 // Smi tagging, untagging and operations on tagged smis.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 Register src, 275 Register src,
255 int power); 276 int power);
256 277
257 // Divide a positive smi's integer value by a power of two. 278 // Divide a positive smi's integer value by a power of two.
258 // Provides result as 32-bit integer value. 279 // Provides result as 32-bit integer value.
259 void PositiveSmiDivPowerOfTwoToInteger32(Register dst, 280 void PositiveSmiDivPowerOfTwoToInteger32(Register dst,
260 Register src, 281 Register src,
261 int power); 282 int power);
262 283
263 284
264 // Simple comparison of smis. 285 // Simple comparison of smis. Both sides must be known smis to use these,
265 void SmiCompare(Register dst, Register src); 286 // otherwise use Cmp.
287 void SmiCompare(Register smi1, Register smi2);
266 void SmiCompare(Register dst, Smi* src); 288 void SmiCompare(Register dst, Smi* src);
267 void SmiCompare(Register dst, const Operand& src); 289 void SmiCompare(Register dst, const Operand& src);
268 void SmiCompare(const Operand& dst, Register src); 290 void SmiCompare(const Operand& dst, Register src);
269 void SmiCompare(const Operand& dst, Smi* src); 291 void SmiCompare(const Operand& dst, Smi* src);
270 // Compare the int32 in src register to the value of the smi stored at dst. 292 // Compare the int32 in src register to the value of the smi stored at dst.
271 void SmiCompareInteger32(const Operand& dst, Register src); 293 void SmiCompareInteger32(const Operand& dst, Register src);
272 // Sets sign and zero flags depending on value of smi in register. 294 // Sets sign and zero flags depending on value of smi in register.
273 void SmiTest(Register src); 295 void SmiTest(Register src);
274 296
275 // Functions performing a check on a known or potential smi. Returns 297 // Functions performing a check on a known or potential smi. Returns
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 void Set(const Operand& dst, int64_t x); 607 void Set(const Operand& dst, int64_t x);
586 608
587 // Move if the registers are not identical. 609 // Move if the registers are not identical.
588 void Move(Register target, Register source); 610 void Move(Register target, Register source);
589 611
590 // Handle support 612 // Handle support
591 void Move(Register dst, Handle<Object> source); 613 void Move(Register dst, Handle<Object> source);
592 void Move(const Operand& dst, Handle<Object> source); 614 void Move(const Operand& dst, Handle<Object> source);
593 void Cmp(Register dst, Handle<Object> source); 615 void Cmp(Register dst, Handle<Object> source);
594 void Cmp(const Operand& dst, Handle<Object> source); 616 void Cmp(const Operand& dst, Handle<Object> source);
617 void Cmp(Register dst, Smi* src);
618 void Cmp(const Operand& dst, Smi* src);
595 void Push(Handle<Object> source); 619 void Push(Handle<Object> source);
596 620
597 // Emit code to discard a non-negative number of pointer-sized elements 621 // Emit code to discard a non-negative number of pointer-sized elements
598 // from the stack, clobbering only the rsp register. 622 // from the stack, clobbering only the rsp register.
599 void Drop(int stack_elements); 623 void Drop(int stack_elements);
600 624
601 void Call(Label* target) { call(target); } 625 void Call(Label* target) { call(target); }
602 626
603 // Control Flow 627 // Control Flow
604 void Jump(Address destination, RelocInfo::Mode rmode); 628 void Jump(Address destination, RelocInfo::Mode rmode);
605 void Jump(ExternalReference ext); 629 void Jump(ExternalReference ext);
606 void Jump(Handle<Code> code_object, RelocInfo::Mode rmode); 630 void Jump(Handle<Code> code_object, RelocInfo::Mode rmode);
607 631
608 void Call(Address destination, RelocInfo::Mode rmode); 632 void Call(Address destination, RelocInfo::Mode rmode);
609 void Call(ExternalReference ext); 633 void Call(ExternalReference ext);
610 void Call(Handle<Code> code_object, RelocInfo::Mode rmode); 634 void Call(Handle<Code> code_object, RelocInfo::Mode rmode);
611 635
636 // The size of the code generated for different call instructions.
637 int CallSize(Address destination, RelocInfo::Mode rmode) {
638 return kCallInstructionLength;
639 }
640 int CallSize(ExternalReference ext) {
641 return kCallInstructionLength;
642 }
643 int CallSize(Handle<Code> code_object) {
644 // Code calls use 32-bit relative addressing.
645 return kShortCallInstructionLength;
646 }
647 int CallSize(Register target) {
648 // Opcode: REX_opt FF /2 m64
649 return (target.high_bit() != 0) ? 3 : 2;
650 }
651 int CallSize(const Operand& target) {
652 // Opcode: REX_opt FF /2 m64
653 return (target.requires_rex() ? 2 : 1) + target.operand_size();
654 }
655
612 // Emit call to the code we are currently generating. 656 // Emit call to the code we are currently generating.
613 void CallSelf() { 657 void CallSelf() {
614 Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location())); 658 Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
615 Call(self, RelocInfo::CODE_TARGET); 659 Call(self, RelocInfo::CODE_TARGET);
616 } 660 }
617 661
618 // Non-x64 instructions. 662 // Non-x64 instructions.
619 // Push/pop all general purpose registers. 663 // Push/pop all general purpose registers.
620 // Does not push rsp/rbp nor any of the assembler's special purpose registers 664 // Does not push rsp/rbp nor any of the assembler's special purpose registers
621 // (kScratchRegister, kSmiConstantRegister, kRootRegister). 665 // (kScratchRegister, kSmiConstantRegister, kRootRegister).
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 void FCmp(); 702 void FCmp();
659 703
660 // Abort execution if argument is not a number. Used in debug code. 704 // Abort execution if argument is not a number. Used in debug code.
661 void AbortIfNotNumber(Register object); 705 void AbortIfNotNumber(Register object);
662 706
663 // Abort execution if argument is a smi. Used in debug code. 707 // Abort execution if argument is a smi. Used in debug code.
664 void AbortIfSmi(Register object); 708 void AbortIfSmi(Register object);
665 709
666 // Abort execution if argument is not a smi. Used in debug code. 710 // Abort execution if argument is not a smi. Used in debug code.
667 void AbortIfNotSmi(Register object); 711 void AbortIfNotSmi(Register object);
712 void AbortIfNotSmi(const Operand& object);
668 713
669 // Abort execution if argument is a string. Used in debug code. 714 // Abort execution if argument is a string. Used in debug code.
670 void AbortIfNotString(Register object); 715 void AbortIfNotString(Register object);
671 716
672 // Abort execution if argument is not the root value with the given index. 717 // Abort execution if argument is not the root value with the given index.
673 void AbortIfNotRootValue(Register src, 718 void AbortIfNotRootValue(Register src,
674 Heap::RootListIndex root_value_index, 719 Heap::RootListIndex root_value_index,
675 const char* message); 720 const char* message);
676 721
677 // --------------------------------------------------------------------------- 722 // ---------------------------------------------------------------------------
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 942
898 // Prepares stack to put arguments (aligns and so on). 943 // Prepares stack to put arguments (aligns and so on).
899 // WIN64 calling convention requires to put the pointer to the return value 944 // WIN64 calling convention requires to put the pointer to the return value
900 // slot into rcx (rcx must be preserverd until TryCallApiFunctionAndReturn). 945 // slot into rcx (rcx must be preserverd until TryCallApiFunctionAndReturn).
901 // Saves context (rsi). Clobbers rax. Allocates arg_stack_space * kPointerSize 946 // Saves context (rsi). Clobbers rax. Allocates arg_stack_space * kPointerSize
902 // inside the exit frame (not GCed) accessible via StackSpaceOperand. 947 // inside the exit frame (not GCed) accessible via StackSpaceOperand.
903 void PrepareCallApiFunction(int arg_stack_space); 948 void PrepareCallApiFunction(int arg_stack_space);
904 949
905 // Calls an API function. Allocates HandleScope, extracts 950 // Calls an API function. Allocates HandleScope, extracts
906 // returned value from handle and propagates exceptions. 951 // returned value from handle and propagates exceptions.
907 // Clobbers r12, r14, rbx and caller-save registers. Restores context. 952 // Clobbers r14, r15, rbx and caller-save registers. Restores context.
908 // On return removes stack_space * kPointerSize (GCed). 953 // On return removes stack_space * kPointerSize (GCed).
909 MUST_USE_RESULT MaybeObject* TryCallApiFunctionAndReturn( 954 MUST_USE_RESULT MaybeObject* TryCallApiFunctionAndReturn(
910 ApiFunction* function, int stack_space); 955 ApiFunction* function, int stack_space);
911 956
912 // Before calling a C-function from generated code, align arguments on stack. 957 // Before calling a C-function from generated code, align arguments on stack.
913 // After aligning the frame, arguments must be stored in esp[0], esp[4], 958 // After aligning the frame, arguments must be stored in esp[0], esp[4],
914 // etc., not pushed. The argument count assumes all arguments are word sized. 959 // etc., not pushed. The argument count assumes all arguments are word sized.
915 // The number of slots reserved for arguments depends on platform. On Windows 960 // The number of slots reserved for arguments depends on platform. On Windows
916 // stack slots are reserved for the arguments passed in registers. On other 961 // stack slots are reserved for the arguments passed in registers. On other
917 // platforms stack slots are only reserved for the arguments actually passed 962 // platforms stack slots are only reserved for the arguments actually passed
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 void CheckStackAlignment(); 1014 void CheckStackAlignment();
970 1015
971 // Verify restrictions about code generated in stubs. 1016 // Verify restrictions about code generated in stubs.
972 void set_generating_stub(bool value) { generating_stub_ = value; } 1017 void set_generating_stub(bool value) { generating_stub_ = value; }
973 bool generating_stub() { return generating_stub_; } 1018 bool generating_stub() { return generating_stub_; }
974 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } 1019 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
975 bool allow_stub_calls() { return allow_stub_calls_; } 1020 bool allow_stub_calls() { return allow_stub_calls_; }
976 1021
977 private: 1022 private:
978 // Order general registers are pushed by Pushad. 1023 // Order general registers are pushed by Pushad.
979 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r12, r14. 1024 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15.
980 static int kSafepointPushRegisterIndices[Register::kNumRegisters]; 1025 static int kSafepointPushRegisterIndices[Register::kNumRegisters];
981 static const int kNumSafepointSavedRegisters = 11; 1026 static const int kNumSafepointSavedRegisters = 11;
982 1027
983 bool generating_stub_; 1028 bool generating_stub_;
984 bool allow_stub_calls_; 1029 bool allow_stub_calls_;
985 1030
986 // Returns a register holding the smi value. The register MUST NOT be 1031 // Returns a register holding the smi value. The register MUST NOT be
987 // modified. It may be the "smi 1 constant" register. 1032 // modified. It may be the "smi 1 constant" register.
988 Register GetSmiConstant(Smi* value); 1033 Register GetSmiConstant(Smi* value);
989 1034
990 // Moves the smi value to the destination register. 1035 // Moves the smi value to the destination register.
991 void LoadSmiConstant(Register dst, Smi* value); 1036 void LoadSmiConstant(Register dst, Smi* value);
992 1037
993 // This handle will be patched with the code object on installation. 1038 // This handle will be patched with the code object on installation.
994 Handle<Object> code_object_; 1039 Handle<Object> code_object_;
995 1040
996 // Helper functions for generating invokes. 1041 // Helper functions for generating invokes.
997 template <typename LabelType> 1042 template <typename LabelType>
998 void InvokePrologue(const ParameterCount& expected, 1043 void InvokePrologue(const ParameterCount& expected,
999 const ParameterCount& actual, 1044 const ParameterCount& actual,
1000 Handle<Code> code_constant, 1045 Handle<Code> code_constant,
1001 Register code_register, 1046 Register code_register,
1002 LabelType* done, 1047 LabelType* done,
1003 InvokeFlag flag); 1048 InvokeFlag flag,
1049 CallWrapper* call_wrapper);
1004 1050
1005 // Activation support. 1051 // Activation support.
1006 void EnterFrame(StackFrame::Type type); 1052 void EnterFrame(StackFrame::Type type);
1007 void LeaveFrame(StackFrame::Type type); 1053 void LeaveFrame(StackFrame::Type type);
1008 1054
1009 void EnterExitFramePrologue(bool save_rax); 1055 void EnterExitFramePrologue(bool save_rax);
1010 1056
1011 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack 1057 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack
1012 // accessible via StackSpaceOperand. 1058 // accessible via StackSpaceOperand.
1013 void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles); 1059 void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles);
(...skipping 10 matching lines...) Expand all
1024 // Update allocation top with value in result_end register. 1070 // Update allocation top with value in result_end register.
1025 // If scratch is valid, it contains the address of the allocation top. 1071 // If scratch is valid, it contains the address of the allocation top.
1026 void UpdateAllocationTopHelper(Register result_end, Register scratch); 1072 void UpdateAllocationTopHelper(Register result_end, Register scratch);
1027 1073
1028 // Helper for PopHandleScope. Allowed to perform a GC and returns 1074 // Helper for PopHandleScope. Allowed to perform a GC and returns
1029 // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and 1075 // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and
1030 // possibly returns a failure object indicating an allocation failure. 1076 // possibly returns a failure object indicating an allocation failure.
1031 Object* PopHandleScopeHelper(Register saved, 1077 Object* PopHandleScopeHelper(Register saved,
1032 Register scratch, 1078 Register scratch,
1033 bool gc_allowed); 1079 bool gc_allowed);
1080
1081
1082 // Compute memory operands for safepoint stack slots.
1083 Operand SafepointRegisterSlot(Register reg);
1084 static int SafepointRegisterStackIndex(int reg_code) {
1085 return kNumSafepointRegisters - kSafepointPushRegisterIndices[reg_code] - 1;
1086 }
1087
1088 // Needs access to SafepointRegisterStackIndex for optimized frame
1089 // traversal.
1090 friend class OptimizedFrame;
1034 }; 1091 };
1035 1092
1036 1093
1037 // The code patcher is used to patch (typically) small parts of code e.g. for 1094 // The code patcher is used to patch (typically) small parts of code e.g. for
1038 // debugging and other types of instrumentation. When using the code patcher 1095 // debugging and other types of instrumentation. When using the code patcher
1039 // the exact number of bytes specified must be emitted. Is not legal to emit 1096 // the exact number of bytes specified must be emitted. Is not legal to emit
1040 // relocation information. If any of these constraints are violated it causes 1097 // relocation information. If any of these constraints are violated it causes
1041 // an assertion. 1098 // an assertion.
1042 class CodePatcher { 1099 class CodePatcher {
1043 public: 1100 public:
1044 CodePatcher(byte* address, int size); 1101 CodePatcher(byte* address, int size);
1045 virtual ~CodePatcher(); 1102 virtual ~CodePatcher();
1046 1103
1047 // Macro assembler to emit code. 1104 // Macro assembler to emit code.
1048 MacroAssembler* masm() { return &masm_; } 1105 MacroAssembler* masm() { return &masm_; }
1049 1106
1050 private: 1107 private:
1051 byte* address_; // The address of the code being patched. 1108 byte* address_; // The address of the code being patched.
1052 int size_; // Number of bytes of the expected patch size. 1109 int size_; // Number of bytes of the expected patch size.
1053 MacroAssembler masm_; // Macro assembler used to generate the code. 1110 MacroAssembler masm_; // Macro assembler used to generate the code.
1054 }; 1111 };
1055 1112
1056 1113
1114 // Helper class for generating code or data associated with the code
1115 // right before or after a call instruction. As an example this can be used to
1116 // generate safepoint data after calls for crankshaft.
1117 class CallWrapper {
1118 public:
1119 CallWrapper() { }
1120 virtual ~CallWrapper() { }
1121 // Called just before emitting a call. Argument is the size of the generated
1122 // call code.
1123 virtual void BeforeCall(int call_size) = 0;
1124 // Called just after emitting a call, i.e., at the return site for the call.
1125 virtual void AfterCall() = 0;
1126 };
1127
1128
1057 // ----------------------------------------------------------------------------- 1129 // -----------------------------------------------------------------------------
1058 // Static helper functions. 1130 // Static helper functions.
1059 1131
1060 // Generate an Operand for loading a field from an object. 1132 // Generate an Operand for loading a field from an object.
1061 static inline Operand FieldOperand(Register object, int offset) { 1133 static inline Operand FieldOperand(Register object, int offset) {
1062 return Operand(object, offset - kHeapObjectTag); 1134 return Operand(object, offset - kHeapObjectTag);
1063 } 1135 }
1064 1136
1065 1137
1066 // Generate an Operand for loading an indexed field from an object. 1138 // Generate an Operand for loading an indexed field from an object.
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 } 1825 }
1754 } 1826 }
1755 1827
1756 1828
1757 template <typename LabelType> 1829 template <typename LabelType>
1758 void MacroAssembler::InvokePrologue(const ParameterCount& expected, 1830 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
1759 const ParameterCount& actual, 1831 const ParameterCount& actual,
1760 Handle<Code> code_constant, 1832 Handle<Code> code_constant,
1761 Register code_register, 1833 Register code_register,
1762 LabelType* done, 1834 LabelType* done,
1763 InvokeFlag flag) { 1835 InvokeFlag flag,
1836 CallWrapper* call_wrapper) {
1764 bool definitely_matches = false; 1837 bool definitely_matches = false;
1765 NearLabel invoke; 1838 NearLabel invoke;
1766 if (expected.is_immediate()) { 1839 if (expected.is_immediate()) {
1767 ASSERT(actual.is_immediate()); 1840 ASSERT(actual.is_immediate());
1768 if (expected.immediate() == actual.immediate()) { 1841 if (expected.immediate() == actual.immediate()) {
1769 definitely_matches = true; 1842 definitely_matches = true;
1770 } else { 1843 } else {
1771 Set(rax, actual.immediate()); 1844 Set(rax, actual.immediate());
1772 if (expected.immediate() == 1845 if (expected.immediate() ==
1773 SharedFunctionInfo::kDontAdaptArgumentsSentinel) { 1846 SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
(...skipping 29 matching lines...) Expand all
1803 Handle<Code> adaptor = 1876 Handle<Code> adaptor =
1804 Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); 1877 Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
1805 if (!code_constant.is_null()) { 1878 if (!code_constant.is_null()) {
1806 movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); 1879 movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT);
1807 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); 1880 addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag));
1808 } else if (!code_register.is(rdx)) { 1881 } else if (!code_register.is(rdx)) {
1809 movq(rdx, code_register); 1882 movq(rdx, code_register);
1810 } 1883 }
1811 1884
1812 if (flag == CALL_FUNCTION) { 1885 if (flag == CALL_FUNCTION) {
1886 if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(adaptor));
1813 Call(adaptor, RelocInfo::CODE_TARGET); 1887 Call(adaptor, RelocInfo::CODE_TARGET);
1888 if (call_wrapper != NULL) call_wrapper->AfterCall();
1814 jmp(done); 1889 jmp(done);
1815 } else { 1890 } else {
1816 Jump(adaptor, RelocInfo::CODE_TARGET); 1891 Jump(adaptor, RelocInfo::CODE_TARGET);
1817 } 1892 }
1818 bind(&invoke); 1893 bind(&invoke);
1819 } 1894 }
1820 } 1895 }
1821 1896
1822 1897
1823 } } // namespace v8::internal 1898 } } // namespace v8::internal
1824 1899
1825 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_ 1900 #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