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

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

Issue 6026017: Fix/implement new write barrier for x64. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 11 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
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) { 66 void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) {
67 cmpq(with, Operand(kRootRegister, index << kPointerSizeLog2)); 67 cmpq(with, Operand(kRootRegister, index << kPointerSizeLog2));
68 } 68 }
69 69
70 70
71 void MacroAssembler::CompareRoot(Operand with, Heap::RootListIndex index) { 71 void MacroAssembler::CompareRoot(Operand with, Heap::RootListIndex index) {
72 LoadRoot(kScratchRegister, index); 72 LoadRoot(kScratchRegister, index);
73 cmpq(with, kScratchRegister); 73 cmpq(with, kScratchRegister);
74 } 74 }
75 75
76 #ifdef ENABLE_CARDMARKING_WRITE_BARRIER 76
77 void MacroAssembler::RecordWriteHelper(Register object, 77 void MacroAssembler::RecordWriteHelper(Register object,
78 Register addr, 78 Register addr,
79 Register scratch) { 79 Register scratch,
80 SaveFPRegsMode save_fp) {
80 if (FLAG_debug_code) { 81 if (FLAG_debug_code) {
81 // Check that the object is not in new space. 82 // Check that the object is not in new space.
82 NearLabel not_in_new_space; 83 NearLabel not_in_new_space;
83 InNewSpace(object, scratch, not_equal, &not_in_new_space); 84 InNewSpace(object, scratch, not_equal, &not_in_new_space);
84 Abort("new-space object passed to RecordWriteHelper"); 85 Abort("new-space object passed to RecordWriteHelper");
85 bind(&not_in_new_space); 86 bind(&not_in_new_space);
86 } 87 }
87 88
88 // Compute the page start address from the heap object pointer, and reuse 89 // Load write buffer top.
89 // the 'object' register for it. 90 LoadRoot(scratch, Heap::kWriteBufferTopRootIndex);
90 and_(object, Immediate(~Page::kPageAlignmentMask)); 91 // Store pointer to buffer.
91 92 movq(Operand(scratch, 0), addr);
92 // Compute number of region covering addr. See Page::GetRegionNumberForAddress 93 // Increment buffer top.
93 // method for more details. 94 addq(scratch, Immediate(kPointerSize));
94 shrl(addr, Immediate(Page::kRegionSizeLog2)); 95 // Write back new top of buffer.
95 andl(addr, Immediate(Page::kPageAlignmentMask >> Page::kRegionSizeLog2)); 96 StoreRoot(scratch, Heap::kWriteBufferTopRootIndex);
96 97 // Call stub on end of buffer.
97 // Set dirty mark for region. 98 NearLabel no_overflow;
98 bts(Operand(object, Page::kDirtyFlagOffset), addr); 99 // Check for end of buffer.
100 testq(scratch, Immediate(WriteBuffer::kWriteBufferOverflowBit));
101 j(equal, &no_overflow);
102 WriteBufferOverflowStub write_buffer_overflow =
103 WriteBufferOverflowStub(save_fp);
104 CallStub(&write_buffer_overflow);
105 bind(&no_overflow);
99 } 106 }
100 107
101 108
102 void MacroAssembler::RecordWrite(Register object, 109 void MacroAssembler::RecordWrite(Register object,
103 int offset, 110 int offset,
104 Register value, 111 Register value,
105 Register index) { 112 Register index,
113 SaveFPRegsMode save_fp) {
106 // The compiled code assumes that record write doesn't change the 114 // The compiled code assumes that record write doesn't change the
107 // context register, so we check that none of the clobbered 115 // context register, so we check that none of the clobbered
108 // registers are rsi. 116 // registers are rsi.
109 ASSERT(!object.is(rsi) && !value.is(rsi) && !index.is(rsi)); 117 ASSERT(!object.is(rsi) && !value.is(rsi) && !index.is(rsi));
110 118
111 // First, check if a write barrier is even needed. The tests below 119 // First, check if a write barrier is even needed. The tests below
112 // catch stores of Smis and stores into young gen. 120 // catch stores of Smis and stores into young gen.
113 Label done; 121 Label done;
114 JumpIfSmi(value, &done); 122 JumpIfSmi(value, &done);
115 123
116 RecordWriteNonSmi(object, offset, value, index); 124 RecordWriteNonSmi(object, offset, value, index, save_fp);
117 bind(&done); 125 bind(&done);
118 126
119 // Clobber all input registers when running with the debug-code flag 127 // Clobber all input registers when running with the debug-code flag
120 // turned on to provoke errors. This clobbering repeats the 128 // turned on to provoke errors. This clobbering repeats the
121 // clobbering done inside RecordWriteNonSmi but it's necessary to 129 // clobbering done inside RecordWriteNonSmi but it's necessary to
122 // avoid having the fast case for smis leave the registers 130 // avoid having the fast case for smis leave the registers
123 // unchanged. 131 // unchanged.
124 if (FLAG_debug_code) { 132 if (FLAG_debug_code) {
125 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 133 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
126 movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 134 movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
127 movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 135 movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
128 } 136 }
129 } 137 }
130 138
131 139
132 void MacroAssembler::RecordWrite(Register object, 140 void MacroAssembler::RecordWrite(Register object,
133 Register address, 141 Register address,
134 Register value) { 142 Register value,
143 SaveFPRegsMode save_fp) {
135 // The compiled code assumes that record write doesn't change the 144 // The compiled code assumes that record write doesn't change the
136 // context register, so we check that none of the clobbered 145 // context register, so we check that none of the clobbered
137 // registers are esi. 146 // registers are esi.
138 ASSERT(!object.is(rsi) && !value.is(rsi) && !address.is(rsi)); 147 ASSERT(!object.is(rsi) && !value.is(rsi) && !address.is(rsi));
139 148
140 // First, check if a write barrier is even needed. The tests below 149 // First, check if a write barrier is even needed. The tests below
141 // catch stores of Smis and stores into young gen. 150 // catch stores of Smis and stores into young gen.
142 Label done; 151 Label done;
143 JumpIfSmi(value, &done); 152 JumpIfSmi(value, &done);
144 153
145 InNewSpace(object, value, equal, &done); 154 InNewSpace(object, value, equal, &done);
146 155
147 RecordWriteHelper(object, address, value); 156 RecordWriteHelper(object, address, value, save_fp);
148 157
149 bind(&done); 158 bind(&done);
150 159
151 // Clobber all input registers when running with the debug-code flag 160 // Clobber all input registers when running with the debug-code flag
152 // turned on to provoke errors. 161 // turned on to provoke errors.
153 if (FLAG_debug_code) { 162 if (FLAG_debug_code) {
154 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 163 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
155 movq(address, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 164 movq(address, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
156 movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 165 movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
157 } 166 }
158 } 167 }
159 168
160 169
161 void MacroAssembler::RecordWriteNonSmi(Register object, 170 void MacroAssembler::RecordWriteNonSmi(Register object,
162 int offset, 171 int offset,
163 Register scratch, 172 Register scratch,
164 Register index) { 173 Register index,
174 SaveFPRegsMode save_fp) {
165 Label done; 175 Label done;
166 176
167 if (FLAG_debug_code) { 177 if (FLAG_debug_code) {
168 NearLabel okay; 178 NearLabel okay;
169 JumpIfNotSmi(object, &okay); 179 JumpIfNotSmi(object, &okay);
170 Abort("MacroAssembler::RecordWriteNonSmi cannot deal with smis"); 180 Abort("MacroAssembler::RecordWriteNonSmi cannot deal with smis");
171 bind(&okay); 181 bind(&okay);
172 182
173 if (offset == 0) { 183 if (offset == 0) {
174 // index must be int32. 184 // index must be int32.
(...skipping 20 matching lines...) Expand all
195 if (offset != 0) { 205 if (offset != 0) {
196 lea(dst, Operand(object, offset)); 206 lea(dst, Operand(object, offset));
197 } else { 207 } else {
198 // array access: calculate the destination address in the same manner as 208 // array access: calculate the destination address in the same manner as
199 // KeyedStoreIC::GenerateGeneric. 209 // KeyedStoreIC::GenerateGeneric.
200 lea(dst, FieldOperand(object, 210 lea(dst, FieldOperand(object,
201 index, 211 index,
202 times_pointer_size, 212 times_pointer_size,
203 FixedArray::kHeaderSize)); 213 FixedArray::kHeaderSize));
204 } 214 }
205 RecordWriteHelper(object, dst, scratch); 215 RecordWriteHelper(object, dst, scratch, save_fp);
206 216
207 bind(&done); 217 bind(&done);
208 218
209 // Clobber all input registers when running with the debug-code flag 219 // Clobber all input registers when running with the debug-code flag
210 // turned on to provoke errors. 220 // turned on to provoke errors.
211 if (FLAG_debug_code) { 221 if (FLAG_debug_code) {
212 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 222 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
213 movq(scratch, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 223 movq(scratch, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
214 movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 224 movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
215 } 225 }
216 } 226 }
217 #endif 227
218 228
219 void MacroAssembler::Assert(Condition cc, const char* msg) { 229 void MacroAssembler::Assert(Condition cc, const char* msg) {
220 if (FLAG_debug_code) Check(cc, msg); 230 if (FLAG_debug_code) Check(cc, msg);
221 } 231 }
222 232
223 233
224 void MacroAssembler::AssertFastElements(Register elements) { 234 void MacroAssembler::AssertFastElements(Register elements) {
225 if (FLAG_debug_code) { 235 if (FLAG_debug_code) {
226 NearLabel ok; 236 NearLabel ok;
227 CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 237 CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
(...skipping 2119 matching lines...) Expand 10 before | Expand all | Expand 10 after
2347 CPU::FlushICache(address_, size_); 2357 CPU::FlushICache(address_, size_);
2348 2358
2349 // Check that the code was patched as expected. 2359 // Check that the code was patched as expected.
2350 ASSERT(masm_.pc_ == address_ + size_); 2360 ASSERT(masm_.pc_ == address_ + size_);
2351 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 2361 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
2352 } 2362 }
2353 2363
2354 } } // namespace v8::internal 2364 } } // namespace v8::internal
2355 2365
2356 #endif // V8_TARGET_ARCH_X64 2366 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698