OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 cmpq(with, kScratchRegister); | 65 cmpq(with, kScratchRegister); |
66 } | 66 } |
67 | 67 |
68 | 68 |
69 void MacroAssembler::StackLimitCheck(Label* on_stack_overflow) { | 69 void MacroAssembler::StackLimitCheck(Label* on_stack_overflow) { |
70 CompareRoot(rsp, Heap::kStackLimitRootIndex); | 70 CompareRoot(rsp, Heap::kStackLimitRootIndex); |
71 j(below, on_stack_overflow); | 71 j(below, on_stack_overflow); |
72 } | 72 } |
73 | 73 |
74 | 74 |
75 static void RecordWriteHelper(MacroAssembler* masm, | 75 void MacroAssembler::RecordWriteHelper(Register object, |
76 Register object, | 76 Register addr, |
77 Register addr, | 77 Register scratch) { |
78 Register scratch) { | |
79 Label fast; | 78 Label fast; |
80 | 79 |
81 // Compute the page start address from the heap object pointer, and reuse | 80 // Compute the page start address from the heap object pointer, and reuse |
82 // the 'object' register for it. | 81 // the 'object' register for it. |
83 ASSERT(is_int32(~Page::kPageAlignmentMask)); | 82 ASSERT(is_int32(~Page::kPageAlignmentMask)); |
84 masm->and_(object, | 83 and_(object, |
85 Immediate(static_cast<int32_t>(~Page::kPageAlignmentMask))); | 84 Immediate(static_cast<int32_t>(~Page::kPageAlignmentMask))); |
86 Register page_start = object; | 85 Register page_start = object; |
87 | 86 |
88 // Compute the bit addr in the remembered set/index of the pointer in the | 87 // Compute the bit addr in the remembered set/index of the pointer in the |
89 // page. Reuse 'addr' as pointer_offset. | 88 // page. Reuse 'addr' as pointer_offset. |
90 masm->subq(addr, page_start); | 89 subq(addr, page_start); |
91 masm->shr(addr, Immediate(kPointerSizeLog2)); | 90 shr(addr, Immediate(kPointerSizeLog2)); |
92 Register pointer_offset = addr; | 91 Register pointer_offset = addr; |
93 | 92 |
94 // If the bit offset lies beyond the normal remembered set range, it is in | 93 // If the bit offset lies beyond the normal remembered set range, it is in |
95 // the extra remembered set area of a large object. | 94 // the extra remembered set area of a large object. |
96 masm->cmpq(pointer_offset, Immediate(Page::kPageSize / kPointerSize)); | 95 cmpq(pointer_offset, Immediate(Page::kPageSize / kPointerSize)); |
97 masm->j(less, &fast); | 96 j(less, &fast); |
98 | 97 |
99 // Adjust 'page_start' so that addressing using 'pointer_offset' hits the | 98 // Adjust 'page_start' so that addressing using 'pointer_offset' hits the |
100 // extra remembered set after the large object. | 99 // extra remembered set after the large object. |
101 | 100 |
102 // Load the array length into 'scratch'. | 101 // Load the array length into 'scratch'. |
103 masm->movl(scratch, | 102 movl(scratch, |
104 Operand(page_start, | 103 Operand(page_start, |
105 Page::kObjectStartOffset + FixedArray::kLengthOffset)); | 104 Page::kObjectStartOffset + FixedArray::kLengthOffset)); |
106 Register array_length = scratch; | 105 Register array_length = scratch; |
107 | 106 |
108 // Extra remembered set starts right after the large object (a FixedArray), at | 107 // Extra remembered set starts right after the large object (a FixedArray), at |
109 // page_start + kObjectStartOffset + objectSize | 108 // page_start + kObjectStartOffset + objectSize |
110 // where objectSize is FixedArray::kHeaderSize + kPointerSize * array_length. | 109 // where objectSize is FixedArray::kHeaderSize + kPointerSize * array_length. |
111 // Add the delta between the end of the normal RSet and the start of the | 110 // Add the delta between the end of the normal RSet and the start of the |
112 // extra RSet to 'page_start', so that addressing the bit using | 111 // extra RSet to 'page_start', so that addressing the bit using |
113 // 'pointer_offset' hits the extra RSet words. | 112 // 'pointer_offset' hits the extra RSet words. |
114 masm->lea(page_start, | 113 lea(page_start, |
115 Operand(page_start, array_length, times_pointer_size, | 114 Operand(page_start, array_length, times_pointer_size, |
116 Page::kObjectStartOffset + FixedArray::kHeaderSize | 115 Page::kObjectStartOffset + FixedArray::kHeaderSize |
117 - Page::kRSetEndOffset)); | 116 - Page::kRSetEndOffset)); |
118 | 117 |
119 // NOTE: For now, we use the bit-test-and-set (bts) x86 instruction | 118 // NOTE: For now, we use the bit-test-and-set (bts) x86 instruction |
120 // to limit code size. We should probably evaluate this decision by | 119 // to limit code size. We should probably evaluate this decision by |
121 // measuring the performance of an equivalent implementation using | 120 // measuring the performance of an equivalent implementation using |
122 // "simpler" instructions | 121 // "simpler" instructions |
123 masm->bind(&fast); | 122 bind(&fast); |
124 masm->bts(Operand(page_start, Page::kRSetOffset), pointer_offset); | 123 bts(Operand(page_start, Page::kRSetOffset), pointer_offset); |
125 } | |
126 | |
127 | |
128 class RecordWriteStub : public CodeStub { | |
129 public: | |
130 RecordWriteStub(Register object, Register addr, Register scratch) | |
131 : object_(object), addr_(addr), scratch_(scratch) { } | |
132 | |
133 void Generate(MacroAssembler* masm); | |
134 | |
135 private: | |
136 Register object_; | |
137 Register addr_; | |
138 Register scratch_; | |
139 | |
140 #ifdef DEBUG | |
141 void Print() { | |
142 PrintF("RecordWriteStub (object reg %d), (addr reg %d), (scratch reg %d)\n", | |
143 object_.code(), addr_.code(), scratch_.code()); | |
144 } | |
145 #endif | |
146 | |
147 // Minor key encoding in 12 bits of three registers (object, address and | |
148 // scratch) OOOOAAAASSSS. | |
149 class ScratchBits : public BitField<uint32_t, 0, 4> {}; | |
150 class AddressBits : public BitField<uint32_t, 4, 4> {}; | |
151 class ObjectBits : public BitField<uint32_t, 8, 4> {}; | |
152 | |
153 Major MajorKey() { return RecordWrite; } | |
154 | |
155 int MinorKey() { | |
156 // Encode the registers. | |
157 return ObjectBits::encode(object_.code()) | | |
158 AddressBits::encode(addr_.code()) | | |
159 ScratchBits::encode(scratch_.code()); | |
160 } | |
161 }; | |
162 | |
163 | |
164 void RecordWriteStub::Generate(MacroAssembler* masm) { | |
165 RecordWriteHelper(masm, object_, addr_, scratch_); | |
166 masm->ret(0); | |
167 } | 124 } |
168 | 125 |
169 | 126 |
170 void MacroAssembler::InNewSpace(Register object, | 127 void MacroAssembler::InNewSpace(Register object, |
171 Register scratch, | 128 Register scratch, |
172 Condition cc, | 129 Condition cc, |
173 Label* branch) { | 130 Label* branch) { |
174 ASSERT(cc == equal || cc == not_equal); | 131 ASSERT(cc == equal || cc == not_equal); |
175 if (!scratch.is(object)) { | 132 if (!scratch.is(object)) { |
176 movq(scratch, object); | 133 movq(scratch, object); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 // KeyedStoreIC::GenerateGeneric. | 229 // KeyedStoreIC::GenerateGeneric. |
273 SmiIndex index = SmiToIndex(smi_index, smi_index, kPointerSizeLog2); | 230 SmiIndex index = SmiToIndex(smi_index, smi_index, kPointerSizeLog2); |
274 lea(dst, Operand(object, | 231 lea(dst, Operand(object, |
275 index.reg, | 232 index.reg, |
276 index.scale, | 233 index.scale, |
277 FixedArray::kHeaderSize - kHeapObjectTag)); | 234 FixedArray::kHeaderSize - kHeapObjectTag)); |
278 } | 235 } |
279 // If we are already generating a shared stub, not inlining the | 236 // If we are already generating a shared stub, not inlining the |
280 // record write code isn't going to save us any memory. | 237 // record write code isn't going to save us any memory. |
281 if (generating_stub()) { | 238 if (generating_stub()) { |
282 RecordWriteHelper(this, object, dst, scratch); | 239 RecordWriteHelper(object, dst, scratch); |
283 } else { | 240 } else { |
284 RecordWriteStub stub(object, dst, scratch); | 241 RecordWriteStub stub(object, dst, scratch); |
285 CallStub(&stub); | 242 CallStub(&stub); |
286 } | 243 } |
287 } | 244 } |
288 | 245 |
289 bind(&done); | 246 bind(&done); |
290 | 247 |
291 // Clobber all input registers when running with the debug-code flag | 248 // Clobber all input registers when running with the debug-code flag |
292 // turned on to provoke errors. | 249 // turned on to provoke errors. |
(...skipping 2419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2712 CodePatcher::~CodePatcher() { | 2669 CodePatcher::~CodePatcher() { |
2713 // Indicate that code has changed. | 2670 // Indicate that code has changed. |
2714 CPU::FlushICache(address_, size_); | 2671 CPU::FlushICache(address_, size_); |
2715 | 2672 |
2716 // Check that the code was patched as expected. | 2673 // Check that the code was patched as expected. |
2717 ASSERT(masm_.pc_ == address_ + size_); | 2674 ASSERT(masm_.pc_ == address_ + size_); |
2718 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2675 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
2719 } | 2676 } |
2720 | 2677 |
2721 } } // namespace v8::internal | 2678 } } // namespace v8::internal |
OLD | NEW |