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 11 matching lines...) Expand all Loading... |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_ | 28 #ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_ |
29 #define V8_IA32_MACRO_ASSEMBLER_IA32_H_ | 29 #define V8_IA32_MACRO_ASSEMBLER_IA32_H_ |
30 | 30 |
31 #include "assembler.h" | 31 #include "assembler.h" |
| 32 #include "frames.h" |
32 #include "v8globals.h" | 33 #include "v8globals.h" |
33 | 34 |
34 namespace v8 { | 35 namespace v8 { |
35 namespace internal { | 36 namespace internal { |
36 | 37 |
37 // Flags used for the AllocateInNewSpace functions. | 38 // Flags used for the AllocateInNewSpace functions. |
38 enum AllocationFlags { | 39 enum AllocationFlags { |
39 // No special flags. | 40 // No special flags. |
40 NO_ALLOCATION_FLAGS = 0, | 41 NO_ALLOCATION_FLAGS = 0, |
41 // Return the pointer to the allocated already tagged as a heap object. | 42 // Return the pointer to the allocated already tagged as a heap object. |
42 TAG_OBJECT = 1 << 0, | 43 TAG_OBJECT = 1 << 0, |
43 // The content of the result register already contains the allocation top in | 44 // The content of the result register already contains the allocation top in |
44 // new space. | 45 // new space. |
45 RESULT_CONTAINS_TOP = 1 << 1 | 46 RESULT_CONTAINS_TOP = 1 << 1 |
46 }; | 47 }; |
47 | 48 |
48 | 49 |
49 // Convenience for platform-independent signatures. We do not normally | 50 // Convenience for platform-independent signatures. We do not normally |
50 // distinguish memory operands from other operands on ia32. | 51 // distinguish memory operands from other operands on ia32. |
51 typedef Operand MemOperand; | 52 typedef Operand MemOperand; |
52 | 53 |
| 54 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; |
| 55 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; |
| 56 |
| 57 |
| 58 bool AreAliased(Register r1, Register r2, Register r3, Register r4); |
| 59 |
| 60 |
53 // MacroAssembler implements a collection of frequently used macros. | 61 // MacroAssembler implements a collection of frequently used macros. |
54 class MacroAssembler: public Assembler { | 62 class MacroAssembler: public Assembler { |
55 public: | 63 public: |
56 // The isolate parameter can be NULL if the macro assembler should | 64 // The isolate parameter can be NULL if the macro assembler should |
57 // not use isolate-dependent functionality. In this case, it's the | 65 // not use isolate-dependent functionality. In this case, it's the |
58 // responsibility of the caller to never invoke such function on the | 66 // responsibility of the caller to never invoke such function on the |
59 // macro assembler. | 67 // macro assembler. |
60 MacroAssembler(Isolate* isolate, void* buffer, int size); | 68 MacroAssembler(Isolate* isolate, void* buffer, int size); |
61 | 69 |
62 // --------------------------------------------------------------------------- | 70 // --------------------------------------------------------------------------- |
63 // GC Support | 71 // GC Support |
| 72 enum RememberedSetFinalAction { |
| 73 kReturnAtEnd, |
| 74 kFallThroughAtEnd |
| 75 }; |
64 | 76 |
65 // For page containing |object| mark region covering |addr| dirty. | 77 // Record in the remembered set the fact that we have a pointer to new space |
66 // RecordWriteHelper only works if the object is not in new | 78 // at the address pointed to by the addr register. Only works if addr is not |
67 // space. | 79 // in new space. |
68 void RecordWriteHelper(Register object, | 80 void RememberedSetHelper(Register object, // Used for debug code. |
69 Register addr, | 81 Register addr, |
70 Register scratch); | 82 Register scratch, |
| 83 SaveFPRegsMode save_fp, |
| 84 RememberedSetFinalAction and_then); |
71 | 85 |
72 // Check if object is in new space. | 86 void CheckPageFlag(Register object, |
73 // scratch can be object itself, but it will be clobbered. | 87 Register scratch, |
74 void InNewSpace(Register object, | 88 int mask, |
75 Register scratch, | 89 Condition cc, |
76 Condition cc, // equal for new space, not_equal otherwise. | 90 Label* condition_met, |
77 Label* branch, | 91 Label::Distance condition_met_distance = Label::kFar); |
78 Label::Distance branch_near = Label::kFar); | |
79 | 92 |
80 // For page containing |object| mark region covering [object+offset] | 93 // Check if object is in new space. Jumps if the object is not in new space. |
81 // dirty. |object| is the object being stored into, |value| is the | 94 // The register scratch can be object itself, but scratch will be clobbered. |
82 // object being stored. If offset is zero, then the scratch register | 95 void JumpIfNotInNewSpace(Register object, |
83 // contains the array index into the elements array represented as a | 96 Register scratch, |
84 // Smi. All registers are clobbered by the operation. RecordWrite | 97 Label* branch, |
| 98 Label::Distance distance = Label::kFar) { |
| 99 InNewSpace(object, scratch, zero, branch, distance); |
| 100 } |
| 101 |
| 102 // Check if object is in new space. Jumps if the object is in new space. |
| 103 // The register scratch can be object itself, but it will be clobbered. |
| 104 void JumpIfInNewSpace(Register object, |
| 105 Register scratch, |
| 106 Label* branch, |
| 107 Label::Distance distance = Label::kFar) { |
| 108 InNewSpace(object, scratch, not_zero, branch, distance); |
| 109 } |
| 110 |
| 111 // Check if an object has a given incremental marking color. Also uses ecx! |
| 112 void HasColor(Register object, |
| 113 Register scratch0, |
| 114 Register scratch1, |
| 115 Label* has_color, |
| 116 Label::Distance has_color_distance, |
| 117 int first_bit, |
| 118 int second_bit); |
| 119 |
| 120 void JumpIfBlack(Register object, |
| 121 Register scratch0, |
| 122 Register scratch1, |
| 123 Label* on_black, |
| 124 Label::Distance on_black_distance = Label::kFar); |
| 125 |
| 126 // Checks the color of an object. If the object is already grey or black |
| 127 // then we just fall through, since it is already live. If it is white and |
| 128 // we can determine that it doesn't need to be scanned, then we just mark it |
| 129 // black and fall through. For the rest we jump to the label so the |
| 130 // incremental marker can fix its assumptions. |
| 131 void EnsureNotWhite(Register object, |
| 132 Register scratch1, |
| 133 Register scratch2, |
| 134 Label* object_is_white_and_not_data, |
| 135 Label::Distance distance); |
| 136 |
| 137 // Notify the garbage collector that we wrote a pointer into an object. |
| 138 // |object| is the object being stored into, |value| is the object being |
| 139 // stored. value and scratch registers are clobbered by the operation. |
| 140 // The offset is the offset from the start of the object, not the offset from |
| 141 // the tagged HeapObject pointer. For use with FieldOperand(reg, off). |
| 142 void RecordWriteField( |
| 143 Register object, |
| 144 int offset, |
| 145 Register value, |
| 146 Register scratch, |
| 147 SaveFPRegsMode save_fp, |
| 148 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
| 149 SmiCheck smi_check = INLINE_SMI_CHECK); |
| 150 |
| 151 // As above, but the offset has the tag presubtracted. For use with |
| 152 // Operand(reg, off). |
| 153 void RecordWriteContextSlot( |
| 154 Register context, |
| 155 int offset, |
| 156 Register value, |
| 157 Register scratch, |
| 158 SaveFPRegsMode save_fp, |
| 159 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
| 160 SmiCheck smi_check = INLINE_SMI_CHECK) { |
| 161 RecordWriteField(context, |
| 162 offset + kHeapObjectTag, |
| 163 value, |
| 164 scratch, |
| 165 save_fp, |
| 166 remembered_set_action, |
| 167 smi_check); |
| 168 } |
| 169 |
| 170 // Notify the garbage collector that we wrote a pointer into a fixed array. |
| 171 // |array| is the array being stored into, |value| is the |
| 172 // object being stored. |index| is the array index represented as a |
| 173 // Smi. All registers are clobbered by the operation RecordWriteArray |
85 // filters out smis so it does not update the write barrier if the | 174 // filters out smis so it does not update the write barrier if the |
86 // value is a smi. | 175 // value is a smi. |
87 void RecordWrite(Register object, | 176 void RecordWriteArray( |
88 int offset, | 177 Register array, |
89 Register value, | 178 Register value, |
90 Register scratch); | 179 Register index, |
| 180 SaveFPRegsMode save_fp, |
| 181 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
| 182 SmiCheck smi_check = INLINE_SMI_CHECK); |
91 | 183 |
92 // For page containing |object| mark region covering |address| | 184 // For page containing |object| mark region covering |address| |
93 // dirty. |object| is the object being stored into, |value| is the | 185 // dirty. |object| is the object being stored into, |value| is the |
94 // object being stored. All registers are clobbered by the | 186 // object being stored. The address and value registers are clobbered by the |
95 // operation. RecordWrite filters out smis so it does not update the | 187 // operation. RecordWrite filters out smis so it does not update the |
96 // write barrier if the value is a smi. | 188 // write barrier if the value is a smi. |
97 void RecordWrite(Register object, | 189 void RecordWrite( |
98 Register address, | 190 Register object, |
99 Register value); | 191 Register address, |
| 192 Register value, |
| 193 SaveFPRegsMode save_fp, |
| 194 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
| 195 SmiCheck smi_check = INLINE_SMI_CHECK); |
100 | 196 |
101 #ifdef ENABLE_DEBUGGER_SUPPORT | 197 #ifdef ENABLE_DEBUGGER_SUPPORT |
102 // --------------------------------------------------------------------------- | 198 // --------------------------------------------------------------------------- |
103 // Debugger Support | 199 // Debugger Support |
104 | 200 |
105 void DebugBreak(); | 201 void DebugBreak(); |
106 #endif | 202 #endif |
107 | 203 |
108 // --------------------------------------------------------------------------- | |
109 // Activation frames | |
110 | |
111 void EnterInternalFrame() { EnterFrame(StackFrame::INTERNAL); } | |
112 void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); } | |
113 | |
114 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); } | |
115 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); } | |
116 | |
117 // Enter specific kind of exit frame. Expects the number of | 204 // Enter specific kind of exit frame. Expects the number of |
118 // arguments in register eax and sets up the number of arguments in | 205 // arguments in register eax and sets up the number of arguments in |
119 // register edi and the pointer to the first argument in register | 206 // register edi and the pointer to the first argument in register |
120 // esi. | 207 // esi. |
121 void EnterExitFrame(bool save_doubles); | 208 void EnterExitFrame(bool save_doubles); |
122 | 209 |
123 void EnterApiExitFrame(int argc); | 210 void EnterApiExitFrame(int argc); |
124 | 211 |
125 // Leave the current exit frame. Expects the return value in | 212 // Leave the current exit frame. Expects the return value in |
126 // register eax:edx (untouched) and the pointer to the first | 213 // register eax:edx (untouched) and the pointer to the first |
(...skipping 25 matching lines...) Expand all Loading... |
152 | 239 |
153 // --------------------------------------------------------------------------- | 240 // --------------------------------------------------------------------------- |
154 // JavaScript invokes | 241 // JavaScript invokes |
155 | 242 |
156 // Setup call kind marking in ecx. The method takes ecx as an | 243 // Setup call kind marking in ecx. The method takes ecx as an |
157 // explicit first parameter to make the code more readable at the | 244 // explicit first parameter to make the code more readable at the |
158 // call sites. | 245 // call sites. |
159 void SetCallKind(Register dst, CallKind kind); | 246 void SetCallKind(Register dst, CallKind kind); |
160 | 247 |
161 // Invoke the JavaScript function code by either calling or jumping. | 248 // Invoke the JavaScript function code by either calling or jumping. |
| 249 void InvokeCode(Register code, |
| 250 const ParameterCount& expected, |
| 251 const ParameterCount& actual, |
| 252 InvokeFlag flag, |
| 253 const CallWrapper& call_wrapper, |
| 254 CallKind call_kind) { |
| 255 InvokeCode(Operand(code), expected, actual, flag, call_wrapper, call_kind); |
| 256 } |
| 257 |
162 void InvokeCode(const Operand& code, | 258 void InvokeCode(const Operand& code, |
163 const ParameterCount& expected, | 259 const ParameterCount& expected, |
164 const ParameterCount& actual, | 260 const ParameterCount& actual, |
165 InvokeFlag flag, | 261 InvokeFlag flag, |
166 const CallWrapper& call_wrapper, | 262 const CallWrapper& call_wrapper, |
167 CallKind call_kind); | 263 CallKind call_kind); |
168 | 264 |
169 void InvokeCode(Handle<Code> code, | 265 void InvokeCode(Handle<Code> code, |
170 const ParameterCount& expected, | 266 const ParameterCount& expected, |
171 const ParameterCount& actual, | 267 const ParameterCount& actual, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 | 314 |
219 // Compare instance type for map. | 315 // Compare instance type for map. |
220 void CmpInstanceType(Register map, InstanceType type); | 316 void CmpInstanceType(Register map, InstanceType type); |
221 | 317 |
222 // Check if a map for a JSObject indicates that the object has fast elements. | 318 // Check if a map for a JSObject indicates that the object has fast elements. |
223 // Jump to the specified label if it does not. | 319 // Jump to the specified label if it does not. |
224 void CheckFastElements(Register map, | 320 void CheckFastElements(Register map, |
225 Label* fail, | 321 Label* fail, |
226 Label::Distance distance = Label::kFar); | 322 Label::Distance distance = Label::kFar); |
227 | 323 |
| 324 // Check if a map for a JSObject indicates that the object can have both smi |
| 325 // and HeapObject elements. Jump to the specified label if it does not. |
| 326 void CheckFastObjectElements(Register map, |
| 327 Label* fail, |
| 328 Label::Distance distance = Label::kFar); |
| 329 |
| 330 // Check if a map for a JSObject indicates that the object has fast smi only |
| 331 // elements. Jump to the specified label if it does not. |
| 332 void CheckFastSmiOnlyElements(Register map, |
| 333 Label* fail, |
| 334 Label::Distance distance = Label::kFar); |
| 335 |
| 336 // Check to see if maybe_number can be stored as a double in |
| 337 // FastDoubleElements. If it can, store it at the index specified by key in |
| 338 // the FastDoubleElements array elements, otherwise jump to fail. |
| 339 void StoreNumberToDoubleElements(Register maybe_number, |
| 340 Register elements, |
| 341 Register key, |
| 342 Register scratch1, |
| 343 XMMRegister scratch2, |
| 344 Label* fail, |
| 345 bool specialize_for_processor); |
| 346 |
228 // Check if the map of an object is equal to a specified map and branch to | 347 // Check if the map of an object is equal to a specified map and branch to |
229 // label if not. Skip the smi check if not required (object is known to be a | 348 // label if not. Skip the smi check if not required (object is known to be a |
230 // heap object) | 349 // heap object) |
231 void CheckMap(Register obj, | 350 void CheckMap(Register obj, |
232 Handle<Map> map, | 351 Handle<Map> map, |
233 Label* fail, | 352 Label* fail, |
234 SmiCheckType smi_check_type); | 353 SmiCheckType smi_check_type); |
235 | 354 |
236 // Check if the map of an object is equal to a specified map and branch to a | 355 // Check if the map of an object is equal to a specified map and branch to a |
237 // specified target if equal. Skip the smi check if not required (object is | 356 // specified target if equal. Skip the smi check if not required (object is |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 | 389 |
271 void ClampDoubleToUint8(XMMRegister input_reg, | 390 void ClampDoubleToUint8(XMMRegister input_reg, |
272 XMMRegister scratch_reg, | 391 XMMRegister scratch_reg, |
273 Register result_reg); | 392 Register result_reg); |
274 | 393 |
275 | 394 |
276 // Smi tagging support. | 395 // Smi tagging support. |
277 void SmiTag(Register reg) { | 396 void SmiTag(Register reg) { |
278 STATIC_ASSERT(kSmiTag == 0); | 397 STATIC_ASSERT(kSmiTag == 0); |
279 STATIC_ASSERT(kSmiTagSize == 1); | 398 STATIC_ASSERT(kSmiTagSize == 1); |
280 add(reg, Operand(reg)); | 399 add(reg, reg); |
281 } | 400 } |
282 void SmiUntag(Register reg) { | 401 void SmiUntag(Register reg) { |
283 sar(reg, kSmiTagSize); | 402 sar(reg, kSmiTagSize); |
284 } | 403 } |
285 | 404 |
286 // Modifies the register even if it does not contain a Smi! | 405 // Modifies the register even if it does not contain a Smi! |
287 void SmiUntag(Register reg, Label* is_smi) { | 406 void SmiUntag(Register reg, Label* is_smi) { |
288 STATIC_ASSERT(kSmiTagSize == 1); | 407 STATIC_ASSERT(kSmiTagSize == 1); |
289 sar(reg, kSmiTagSize); | 408 sar(reg, kSmiTagSize); |
290 STATIC_ASSERT(kSmiTag == 0); | 409 STATIC_ASSERT(kSmiTag == 0); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 Label* gc_required); | 577 Label* gc_required); |
459 | 578 |
460 // Copy memory, byte-by-byte, from source to destination. Not optimized for | 579 // Copy memory, byte-by-byte, from source to destination. Not optimized for |
461 // long or aligned copies. | 580 // long or aligned copies. |
462 // The contents of index and scratch are destroyed. | 581 // The contents of index and scratch are destroyed. |
463 void CopyBytes(Register source, | 582 void CopyBytes(Register source, |
464 Register destination, | 583 Register destination, |
465 Register length, | 584 Register length, |
466 Register scratch); | 585 Register scratch); |
467 | 586 |
| 587 // Initialize fields with filler values. Fields starting at |start_offset| |
| 588 // not including end_offset are overwritten with the value in |filler|. At |
| 589 // the end the loop, |start_offset| takes the value of |end_offset|. |
| 590 void InitializeFieldsWithFiller(Register start_offset, |
| 591 Register end_offset, |
| 592 Register filler); |
| 593 |
468 // --------------------------------------------------------------------------- | 594 // --------------------------------------------------------------------------- |
469 // Support functions. | 595 // Support functions. |
470 | 596 |
471 // Check if result is zero and op is negative. | 597 // Check if result is zero and op is negative. |
472 void NegativeZeroTest(Register result, Register op, Label* then_label); | 598 void NegativeZeroTest(Register result, Register op, Label* then_label); |
473 | 599 |
474 // Check if result is zero and any of op1 and op2 are negative. | 600 // Check if result is zero and any of op1 and op2 are negative. |
475 // Register scratch is destroyed, and it must be different from op2. | 601 // Register scratch is destroyed, and it must be different from op2. |
476 void NegativeZeroTest(Register result, Register op1, Register op2, | 602 void NegativeZeroTest(Register result, Register op1, Register op2, |
477 Register scratch, Label* then_label); | 603 Register scratch, Label* then_label); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 void Abort(const char* msg); | 786 void Abort(const char* msg); |
661 | 787 |
662 // Check that the stack is aligned. | 788 // Check that the stack is aligned. |
663 void CheckStackAlignment(); | 789 void CheckStackAlignment(); |
664 | 790 |
665 // Verify restrictions about code generated in stubs. | 791 // Verify restrictions about code generated in stubs. |
666 void set_generating_stub(bool value) { generating_stub_ = value; } | 792 void set_generating_stub(bool value) { generating_stub_ = value; } |
667 bool generating_stub() { return generating_stub_; } | 793 bool generating_stub() { return generating_stub_; } |
668 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } | 794 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } |
669 bool allow_stub_calls() { return allow_stub_calls_; } | 795 bool allow_stub_calls() { return allow_stub_calls_; } |
| 796 void set_has_frame(bool value) { has_frame_ = value; } |
| 797 bool has_frame() { return has_frame_; } |
| 798 inline bool AllowThisStubCall(CodeStub* stub); |
670 | 799 |
671 // --------------------------------------------------------------------------- | 800 // --------------------------------------------------------------------------- |
672 // String utilities. | 801 // String utilities. |
673 | 802 |
674 // Check whether the instance type represents a flat ascii string. Jump to the | 803 // Check whether the instance type represents a flat ascii string. Jump to the |
675 // label if not. If the instance type can be scratched specify same register | 804 // label if not. If the instance type can be scratched specify same register |
676 // for both instance type and scratch. | 805 // for both instance type and scratch. |
677 void JumpIfInstanceTypeIsNotSequentialAscii(Register instance_type, | 806 void JumpIfInstanceTypeIsNotSequentialAscii(Register instance_type, |
678 Register scratch, | 807 Register scratch, |
679 Label* on_not_flat_ascii_string); | 808 Label* on_not_flat_ascii_string); |
680 | 809 |
681 // Checks if both objects are sequential ASCII strings, and jumps to label | 810 // Checks if both objects are sequential ASCII strings, and jumps to label |
682 // if either is not. | 811 // if either is not. |
683 void JumpIfNotBothSequentialAsciiStrings(Register object1, | 812 void JumpIfNotBothSequentialAsciiStrings(Register object1, |
684 Register object2, | 813 Register object2, |
685 Register scratch1, | 814 Register scratch1, |
686 Register scratch2, | 815 Register scratch2, |
687 Label* on_not_flat_ascii_strings); | 816 Label* on_not_flat_ascii_strings); |
688 | 817 |
689 static int SafepointRegisterStackIndex(Register reg) { | 818 static int SafepointRegisterStackIndex(Register reg) { |
690 return SafepointRegisterStackIndex(reg.code()); | 819 return SafepointRegisterStackIndex(reg.code()); |
691 } | 820 } |
692 | 821 |
| 822 // Activation support. |
| 823 void EnterFrame(StackFrame::Type type); |
| 824 void LeaveFrame(StackFrame::Type type); |
| 825 |
693 private: | 826 private: |
694 bool generating_stub_; | 827 bool generating_stub_; |
695 bool allow_stub_calls_; | 828 bool allow_stub_calls_; |
| 829 bool has_frame_; |
696 // This handle will be patched with the code object on installation. | 830 // This handle will be patched with the code object on installation. |
697 Handle<Object> code_object_; | 831 Handle<Object> code_object_; |
698 | 832 |
699 // Helper functions for generating invokes. | 833 // Helper functions for generating invokes. |
700 void InvokePrologue(const ParameterCount& expected, | 834 void InvokePrologue(const ParameterCount& expected, |
701 const ParameterCount& actual, | 835 const ParameterCount& actual, |
702 Handle<Code> code_constant, | 836 Handle<Code> code_constant, |
703 const Operand& code_operand, | 837 const Operand& code_operand, |
704 Label* done, | 838 Label* done, |
705 InvokeFlag flag, | 839 InvokeFlag flag, |
706 Label::Distance done_near = Label::kFar, | 840 Label::Distance done_distance, |
707 const CallWrapper& call_wrapper = NullCallWrapper(), | 841 const CallWrapper& call_wrapper = NullCallWrapper(), |
708 CallKind call_kind = CALL_AS_METHOD); | 842 CallKind call_kind = CALL_AS_METHOD); |
709 | 843 |
710 // Activation support. | |
711 void EnterFrame(StackFrame::Type type); | |
712 void LeaveFrame(StackFrame::Type type); | |
713 | |
714 void EnterExitFramePrologue(); | 844 void EnterExitFramePrologue(); |
715 void EnterExitFrameEpilogue(int argc, bool save_doubles); | 845 void EnterExitFrameEpilogue(int argc, bool save_doubles); |
716 | 846 |
717 void LeaveExitFrameEpilogue(); | 847 void LeaveExitFrameEpilogue(); |
718 | 848 |
719 // Allocation support helpers. | 849 // Allocation support helpers. |
720 void LoadAllocationTopHelper(Register result, | 850 void LoadAllocationTopHelper(Register result, |
721 Register scratch, | 851 Register scratch, |
722 AllocationFlags flags); | 852 AllocationFlags flags); |
723 void UpdateAllocationTopHelper(Register result_end, Register scratch); | 853 void UpdateAllocationTopHelper(Register result_end, Register scratch); |
724 | 854 |
725 // Helper for PopHandleScope. Allowed to perform a GC and returns | 855 // Helper for PopHandleScope. Allowed to perform a GC and returns |
726 // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and | 856 // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and |
727 // possibly returns a failure object indicating an allocation failure. | 857 // possibly returns a failure object indicating an allocation failure. |
728 MUST_USE_RESULT MaybeObject* PopHandleScopeHelper(Register saved, | 858 MUST_USE_RESULT MaybeObject* PopHandleScopeHelper(Register saved, |
729 Register scratch, | 859 Register scratch, |
730 bool gc_allowed); | 860 bool gc_allowed); |
731 | 861 |
| 862 // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace. |
| 863 void InNewSpace(Register object, |
| 864 Register scratch, |
| 865 Condition cc, |
| 866 Label* condition_met, |
| 867 Label::Distance condition_met_distance = Label::kFar); |
| 868 |
| 869 // Helper for finding the mark bits for an address. Afterwards, the |
| 870 // bitmap register points at the word with the mark bits and the mask |
| 871 // the position of the first bit. Uses ecx as scratch and leaves addr_reg |
| 872 // unchanged. |
| 873 inline void GetMarkBits(Register addr_reg, |
| 874 Register bitmap_reg, |
| 875 Register mask_reg); |
732 | 876 |
733 // Compute memory operands for safepoint stack slots. | 877 // Compute memory operands for safepoint stack slots. |
734 Operand SafepointRegisterSlot(Register reg); | 878 Operand SafepointRegisterSlot(Register reg); |
735 static int SafepointRegisterStackIndex(int reg_code); | 879 static int SafepointRegisterStackIndex(int reg_code); |
736 | 880 |
737 // Needs access to SafepointRegisterStackIndex for optimized frame | 881 // Needs access to SafepointRegisterStackIndex for optimized frame |
738 // traversal. | 882 // traversal. |
739 friend class OptimizedFrame; | 883 friend class OptimizedFrame; |
740 }; | 884 }; |
741 | 885 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 } \ | 954 } \ |
811 masm-> | 955 masm-> |
812 #else | 956 #else |
813 #define ACCESS_MASM(masm) masm-> | 957 #define ACCESS_MASM(masm) masm-> |
814 #endif | 958 #endif |
815 | 959 |
816 | 960 |
817 } } // namespace v8::internal | 961 } } // namespace v8::internal |
818 | 962 |
819 #endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_ | 963 #endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_ |
OLD | NEW |