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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 // 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 |
45 // new space. | 45 // new space. |
46 RESULT_CONTAINS_TOP = 1 << 1 | 46 RESULT_CONTAINS_TOP = 1 << 1 |
47 }; | 47 }; |
48 | 48 |
49 | 49 |
50 // Convenience for platform-independent signatures. We do not normally | 50 // Convenience for platform-independent signatures. We do not normally |
51 // distinguish memory operands from other operands on ia32. | 51 // distinguish memory operands from other operands on ia32. |
52 typedef Operand MemOperand; | 52 typedef Operand MemOperand; |
53 | 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 |
54 // MacroAssembler implements a collection of frequently used macros. | 61 // MacroAssembler implements a collection of frequently used macros. |
55 class MacroAssembler: public Assembler { | 62 class MacroAssembler: public Assembler { |
56 public: | 63 public: |
57 // The isolate parameter can be NULL if the macro assembler should | 64 // The isolate parameter can be NULL if the macro assembler should |
58 // not use isolate-dependent functionality. In this case, it's the | 65 // not use isolate-dependent functionality. In this case, it's the |
59 // responsibility of the caller to never invoke such function on the | 66 // responsibility of the caller to never invoke such function on the |
60 // macro assembler. | 67 // macro assembler. |
61 MacroAssembler(Isolate* isolate, void* buffer, int size); | 68 MacroAssembler(Isolate* isolate, void* buffer, int size); |
62 | 69 |
63 // --------------------------------------------------------------------------- | 70 // --------------------------------------------------------------------------- |
64 // GC Support | 71 // GC Support |
| 72 enum RememberedSetFinalAction { |
| 73 kReturnAtEnd, |
| 74 kFallThroughAtEnd |
| 75 }; |
65 | 76 |
66 // 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 |
67 // 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 |
68 // space. | 79 // in new space. |
69 void RecordWriteHelper(Register object, | 80 void RememberedSetHelper(Register addr, |
70 Register addr, | 81 Register scratch, |
71 Register scratch); | 82 SaveFPRegsMode save_fp, |
| 83 RememberedSetFinalAction and_then); |
72 | 84 |
73 // Check if object is in new space. | 85 void CheckPageFlag(Register object, |
74 // scratch can be object itself, but it will be clobbered. | 86 Register scratch, |
75 void InNewSpace(Register object, | 87 int mask, |
76 Register scratch, | 88 Condition cc, |
77 Condition cc, // equal for new space, not_equal otherwise. | 89 Label* condition_met, |
78 Label* branch, | 90 Label::Distance condition_met_distance = Label::kFar); |
79 Label::Distance branch_near = Label::kFar); | |
80 | 91 |
81 // For page containing |object| mark region covering [object+offset] | 92 // Check if object is in new space. Jumps if the object is not in new space. |
82 // dirty. |object| is the object being stored into, |value| is the | 93 // The register scratch can be object itself, but it will be clobbered. |
83 // object being stored. If offset is zero, then the scratch register | 94 void JumpIfNotInNewSpace(Register object, |
84 // contains the array index into the elements array represented as a | 95 Register scratch, |
85 // Smi. All registers are clobbered by the operation. RecordWrite | 96 Label* branch, |
| 97 Label::Distance distance = Label::kFar) { |
| 98 InNewSpace(object, scratch, zero, branch, distance); |
| 99 } |
| 100 |
| 101 // Check if object is in new space. Jumps if the object is in new space. |
| 102 // The register scratch can be object itself, but it will be clobbered. |
| 103 void JumpIfInNewSpace(Register object, |
| 104 Register scratch, |
| 105 Label* branch, |
| 106 Label::Distance distance = Label::kFar) { |
| 107 InNewSpace(object, scratch, not_zero, branch, distance); |
| 108 } |
| 109 |
| 110 // Check if an object has a given incremental marking color. Also uses ecx! |
| 111 void HasColor(Register object, |
| 112 Register scratch0, |
| 113 Register scratch1, |
| 114 Label* has_color, |
| 115 Label::Distance has_color_distance, |
| 116 int first_bit, |
| 117 int second_bit); |
| 118 |
| 119 void JumpIfBlack(Register object, |
| 120 Register scratch0, |
| 121 Register scratch1, |
| 122 Label* on_black, |
| 123 Label::Distance on_black_distance = Label::kFar); |
| 124 |
| 125 // Checks the color of an object. If the object is already grey or black |
| 126 // then we just fall through, since it is already live. If it is white and |
| 127 // we can determine that it doesn't need to be scanned, then we just mark it |
| 128 // black and fall through. For the rest we jump to the label so the |
| 129 // incremental marker can fix its assumptions. |
| 130 void EnsureNotWhite(Register object, |
| 131 Register scratch1, |
| 132 Register scratch2, |
| 133 Label* object_is_white_and_not_data, |
| 134 Label::Distance distance); |
| 135 |
| 136 // Notify the garbage collector that we wrote a pointer into an object. |
| 137 // |object| is the object being stored into, |value| is the object being |
| 138 // stored. value and scratch registers are clobbered by the operation. |
| 139 // The offset is the offset from the start of the object, not the offset from |
| 140 // the tagged HeapObject pointer. For use with FieldOperand(reg, off). |
| 141 void RecordWriteField( |
| 142 Register object, |
| 143 int offset, |
| 144 Register value, |
| 145 Register scratch, |
| 146 SaveFPRegsMode save_fp, |
| 147 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
| 148 SmiCheck smi_check = INLINE_SMI_CHECK); |
| 149 |
| 150 // As above, but the offset has the tag presubtracted. For use with |
| 151 // Operand(reg, off). |
| 152 void RecordWriteContextSlot( |
| 153 Register context, |
| 154 int offset, |
| 155 Register value, |
| 156 Register scratch, |
| 157 SaveFPRegsMode save_fp, |
| 158 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
| 159 SmiCheck smi_check = INLINE_SMI_CHECK) { |
| 160 RecordWriteField(context, |
| 161 offset + kHeapObjectTag, |
| 162 value, |
| 163 scratch, |
| 164 save_fp, |
| 165 remembered_set_action, |
| 166 smi_check); |
| 167 } |
| 168 |
| 169 // Notify the garbage collector that we wrote a pointer into a fixed array. |
| 170 // |array| is the array being stored into, |value| is the |
| 171 // object being stored. |index| is the array index represented as a |
| 172 // Smi. All registers are clobbered by the operation RecordWriteArray |
86 // filters out smis so it does not update the write barrier if the | 173 // filters out smis so it does not update the write barrier if the |
87 // value is a smi. | 174 // value is a smi. |
88 void RecordWrite(Register object, | 175 void RecordWriteArray( |
89 int offset, | 176 Register array, |
90 Register value, | 177 Register value, |
91 Register scratch); | 178 Register index, |
| 179 SaveFPRegsMode save_fp, |
| 180 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
| 181 SmiCheck smi_check = INLINE_SMI_CHECK); |
92 | 182 |
93 // For page containing |object| mark region covering |address| | 183 // For page containing |object| mark region covering |address| |
94 // dirty. |object| is the object being stored into, |value| is the | 184 // dirty. |object| is the object being stored into, |value| is the |
95 // object being stored. All registers are clobbered by the | 185 // object being stored. All registers are clobbered by the |
96 // operation. RecordWrite filters out smis so it does not update the | 186 // operation. RecordWrite filters out smis so it does not update the |
97 // write barrier if the value is a smi. | 187 // write barrier if the value is a smi. |
98 void RecordWrite(Register object, | 188 void RecordWrite( |
99 Register address, | 189 Register object, |
100 Register value); | 190 Register address, |
| 191 Register value, |
| 192 SaveFPRegsMode save_fp, |
| 193 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, |
| 194 SmiCheck smi_check = INLINE_SMI_CHECK); |
101 | 195 |
102 #ifdef ENABLE_DEBUGGER_SUPPORT | 196 #ifdef ENABLE_DEBUGGER_SUPPORT |
103 // --------------------------------------------------------------------------- | 197 // --------------------------------------------------------------------------- |
104 // Debugger Support | 198 // Debugger Support |
105 | 199 |
106 void DebugBreak(); | 200 void DebugBreak(); |
107 #endif | 201 #endif |
108 | 202 |
109 // Enter specific kind of exit frame. Expects the number of | 203 // Enter specific kind of exit frame. Expects the number of |
110 // arguments in register eax and sets up the number of arguments in | 204 // arguments in register eax and sets up the number of arguments in |
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 // This handle will be patched with the code object on installation. | 790 // This handle will be patched with the code object on installation. |
697 Handle<Object> code_object_; | 791 Handle<Object> code_object_; |
698 | 792 |
699 // Helper functions for generating invokes. | 793 // Helper functions for generating invokes. |
700 void InvokePrologue(const ParameterCount& expected, | 794 void InvokePrologue(const ParameterCount& expected, |
701 const ParameterCount& actual, | 795 const ParameterCount& actual, |
702 Handle<Code> code_constant, | 796 Handle<Code> code_constant, |
703 const Operand& code_operand, | 797 const Operand& code_operand, |
704 Label* done, | 798 Label* done, |
705 InvokeFlag flag, | 799 InvokeFlag flag, |
706 Label::Distance done_near = Label::kFar, | 800 Label::Distance done_distance, |
707 const CallWrapper& call_wrapper = NullCallWrapper(), | 801 const CallWrapper& call_wrapper = NullCallWrapper(), |
708 CallKind call_kind = CALL_AS_METHOD); | 802 CallKind call_kind = CALL_AS_METHOD); |
709 | 803 |
710 void EnterExitFramePrologue(); | 804 void EnterExitFramePrologue(); |
711 void EnterExitFrameEpilogue(int argc, bool save_doubles); | 805 void EnterExitFrameEpilogue(int argc, bool save_doubles); |
712 | 806 |
713 void LeaveExitFrameEpilogue(); | 807 void LeaveExitFrameEpilogue(); |
714 | 808 |
715 // Allocation support helpers. | 809 // Allocation support helpers. |
716 void LoadAllocationTopHelper(Register result, | 810 void LoadAllocationTopHelper(Register result, |
717 Register scratch, | 811 Register scratch, |
718 AllocationFlags flags); | 812 AllocationFlags flags); |
719 void UpdateAllocationTopHelper(Register result_end, Register scratch); | 813 void UpdateAllocationTopHelper(Register result_end, Register scratch); |
720 | 814 |
721 // Helper for PopHandleScope. Allowed to perform a GC and returns | 815 // Helper for PopHandleScope. Allowed to perform a GC and returns |
722 // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and | 816 // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and |
723 // possibly returns a failure object indicating an allocation failure. | 817 // possibly returns a failure object indicating an allocation failure. |
724 MUST_USE_RESULT MaybeObject* PopHandleScopeHelper(Register saved, | 818 MUST_USE_RESULT MaybeObject* PopHandleScopeHelper(Register saved, |
725 Register scratch, | 819 Register scratch, |
726 bool gc_allowed); | 820 bool gc_allowed); |
727 | 821 |
| 822 // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace. |
| 823 void InNewSpace(Register object, |
| 824 Register scratch, |
| 825 Condition cc, |
| 826 Label* condition_met, |
| 827 Label::Distance condition_met_distance = Label::kFar); |
| 828 |
| 829 // Helper for finding the mark bits for an address. Afterwards, the |
| 830 // bitmap register points at the word with the mark bits and the mask |
| 831 // the position of the first bit. Uses ecx as scratch and leaves addr_reg |
| 832 // unchanged. |
| 833 inline void GetMarkBits(Register addr_reg, |
| 834 Register bitmap_reg, |
| 835 Register mask_reg); |
728 | 836 |
729 // Compute memory operands for safepoint stack slots. | 837 // Compute memory operands for safepoint stack slots. |
730 Operand SafepointRegisterSlot(Register reg); | 838 Operand SafepointRegisterSlot(Register reg); |
731 static int SafepointRegisterStackIndex(int reg_code); | 839 static int SafepointRegisterStackIndex(int reg_code); |
732 | 840 |
733 // Needs access to SafepointRegisterStackIndex for optimized frame | 841 // Needs access to SafepointRegisterStackIndex for optimized frame |
734 // traversal. | 842 // traversal. |
735 friend class OptimizedFrame; | 843 friend class OptimizedFrame; |
736 }; | 844 }; |
737 | 845 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 } \ | 914 } \ |
807 masm-> | 915 masm-> |
808 #else | 916 #else |
809 #define ACCESS_MASM(masm) masm-> | 917 #define ACCESS_MASM(masm) masm-> |
810 #endif | 918 #endif |
811 | 919 |
812 | 920 |
813 } } // namespace v8::internal | 921 } } // namespace v8::internal |
814 | 922 |
815 #endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_ | 923 #endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_ |
OLD | NEW |