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

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

Issue 6794052: Combine the incremental-marking write barrier and the remembered-set... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 8 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/ia32/macro-assembler-ia32.h ('k') | src/ia32/stub-cache-ia32.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 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 : Assembler(buffer, size), 45 : Assembler(buffer, size),
46 generating_stub_(false), 46 generating_stub_(false),
47 allow_stub_calls_(true), 47 allow_stub_calls_(true),
48 code_object_(Heap::undefined_value()) { 48 code_object_(Heap::undefined_value()) {
49 } 49 }
50 50
51 51
52 void MacroAssembler::IncrementalMarkingRecordWriteHelper( 52 void MacroAssembler::IncrementalMarkingRecordWriteHelper(
53 Register object, 53 Register object,
54 Register value, 54 Register value,
55 Register scratch, 55 Register address) {
56 ObjectMode object_mode, 56 ASSERT(!object.is(address));
57 ValueMode value_mode, 57 ASSERT(!value.is(address));
58 ScratchMode scratch_mode) {
59 ASSERT(!object.is(scratch));
60 ASSERT(!value.is(scratch));
61 ASSERT(!value.is(object)); 58 ASSERT(!value.is(object));
62 59
63 bool preserve[Register::kNumRegisters]; 60 bool preserve[Register::kNumRegisters];
64 61
65 for (int i = 0; i < Register::kNumRegisters; i++) preserve[i] = false; 62 for (int i = 0; i < Register::kNumRegisters; i++) preserve[i] = false;
66 63
67 preserve[eax.code()] = true; 64 preserve[eax.code()] = true;
68 preserve[ecx.code()] = true; 65 preserve[ecx.code()] = true;
69 preserve[edx.code()] = true; 66 preserve[edx.code()] = true;
70 preserve[object.code()] = (object_mode == PRESERVE_OBJECT); 67 preserve[object.code()] = true;
71 preserve[value.code()] = (value_mode == PRESERVE_VALUE); 68 preserve[value.code()] = true;
72 preserve[scratch.code()] = (scratch_mode == PRESERVE_SCRATCH); 69 preserve[address.code()] = true;
73 70
74 for (int i = 0; i < Register::kNumRegisters; i++) { 71 for (int i = 0; i < Register::kNumRegisters; i++) {
75 if (preserve[i]) push(Register::from_code(i)); 72 if (preserve[i]) push(Register::from_code(i));
76 } 73 }
77 74
78 // TODO(gc) we are assuming that xmm registers are not modified by 75 // TODO(gc) we are assuming that xmm registers are not modified by
79 // the C function we are calling. 76 // the C function we are calling.
80 PrepareCallCFunction(2, scratch); 77 PrepareCallCFunction(2, address);
81 mov(Operand(esp, 0 * kPointerSize), object); 78 mov(Operand(esp, 0 * kPointerSize), object);
82 mov(Operand(esp, 1 * kPointerSize), value); 79 mov(Operand(esp, 1 * kPointerSize), value);
83 CallCFunction( 80 CallCFunction(
84 ExternalReference::incremental_marking_record_write_function(), 2); 81 ExternalReference::incremental_marking_record_write_function(), 2);
85 82
86 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { 83 for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
87 if (preserve[i]) pop(Register::from_code(i)); 84 if (preserve[i]) pop(Register::from_code(i));
88 } 85 }
89 } 86 }
90 87
91 88
92 void MacroAssembler::IncrementalMarkingRecordWrite(Register object, 89 void MacroAssembler::RememberedSetHelper(Register object,
93 Register value, 90 Register addr,
94 Register scratch, 91 Register scratch,
95 SmiCheck smi_check, 92 SaveFPRegsMode save_fp) {
96 ObjectMode object_mode,
97 ValueMode value_mode,
98 ScratchMode scratch_mode) {
99 if (FLAG_incremental_marking) {
100 Label done;
101
102 if (smi_check == INLINE_SMI_CHECK) {
103 ASSERT_EQ(0, kSmiTag);
104 test(value, Immediate(kSmiTagMask));
105 j(zero, &done);
106 }
107
108 IncrementalMarkingRecordWriteStub stub(
109 object, value, scratch, object_mode, value_mode, scratch_mode);
110 CallStub(&stub);
111
112 if (smi_check == INLINE_SMI_CHECK) {
113 bind(&done);
114 }
115 }
116 }
117
118
119 void MacroAssembler::RecordWriteHelper(Register object,
120 Register addr,
121 Register scratch,
122 SaveFPRegsMode save_fp) {
123 if (emit_debug_code()) { 93 if (emit_debug_code()) {
124 // Check that the object is not in new space. 94 // Check that the object is not in new space.
125 Label not_in_new_space; 95 Label not_in_new_space;
126 InNewSpace(object, scratch, not_equal, &not_in_new_space); 96 InNewSpace(object, scratch, not_equal, &not_in_new_space);
127 Abort("new-space object passed to RecordWriteHelper"); 97 Abort("new-space object passed to RememberedSetHelper");
128 bind(&not_in_new_space); 98 bind(&not_in_new_space);
129 } 99 }
130 100
131 // Load store buffer top. 101 // Load store buffer top.
132 ExternalReference store_buffer = ExternalReference::store_buffer_top(); 102 ExternalReference store_buffer = ExternalReference::store_buffer_top();
133 mov(scratch, Operand::StaticVariable(store_buffer)); 103 mov(scratch, Operand::StaticVariable(store_buffer));
134 // Store pointer to buffer. 104 // Store pointer to buffer.
135 mov(Operand(scratch, 0), addr); 105 mov(Operand(scratch, 0), addr);
136 // Increment buffer top. 106 // Increment buffer top.
137 add(Operand(scratch), Immediate(kPointerSize)); 107 add(Operand(scratch), Immediate(kPointerSize));
138 // Write back new top of buffer. 108 // Write back new top of buffer.
139 mov(Operand::StaticVariable(store_buffer), scratch); 109 mov(Operand::StaticVariable(store_buffer), scratch);
140 // Call stub on end of buffer. 110 // Call stub on end of buffer.
141 NearLabel no_overflow; 111 NearLabel no_overflow;
142 // Check for end of buffer. 112 // Check for end of buffer.
143 test(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit)); 113 test(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit));
144 j(equal, &no_overflow); 114 j(equal, &no_overflow);
145 StoreBufferOverflowStub store_buffer_overflow = 115 StoreBufferOverflowStub store_buffer_overflow =
146 StoreBufferOverflowStub(save_fp); 116 StoreBufferOverflowStub(save_fp);
147 CallStub(&store_buffer_overflow); 117 CallStub(&store_buffer_overflow);
148 bind(&no_overflow); 118 bind(&no_overflow);
149 } 119 }
150 120
151 121
152 void MacroAssembler::RecordWrite(Register object, 122 void MacroAssembler::RecordWrite(Register object,
153 int offset, 123 int offset,
154 Register value, 124 Register value,
155 Register scratch, 125 Register dst,
156 SaveFPRegsMode save_fp) { 126 SaveFPRegsMode save_fp) {
157 // First, check if a write barrier is even needed. The tests below 127 // First, check if a write barrier is even needed. The tests below
158 // catch stores of Smis and stores into young gen. 128 // catch stores of Smis and stores into young gen.
159 Label done; 129 NearLabel done;
160 130
161 // Skip barrier if writing a smi. 131 // Skip barrier if writing a smi.
162 ASSERT_EQ(0, kSmiTag); 132 ASSERT_EQ(0, kSmiTag);
163 test(value, Immediate(kSmiTagMask)); 133 test(value, Immediate(kSmiTagMask));
164 j(zero, &done); 134 j(zero, &done);
165 135
166 IncrementalMarkingRecordWrite(object,
167 value,
168 scratch,
169 OMIT_SMI_CHECK,
170 PRESERVE_OBJECT,
171 DESTROY_VALUE,
172 (offset == 0) ? PRESERVE_SCRATCH
173 : DESTROY_SCRATCH);
174
175 InNewSpace(object, value, equal, &done);
176
177 // The offset is relative to a tagged or untagged HeapObject pointer, 136 // The offset is relative to a tagged or untagged HeapObject pointer,
178 // so either offset or offset + kHeapObjectTag must be a 137 // so either offset or offset + kHeapObjectTag must be a
179 // multiple of kPointerSize. 138 // multiple of kPointerSize.
180 ASSERT(IsAligned(offset, kPointerSize) || 139 ASSERT(IsAligned(offset, kPointerSize) ||
181 IsAligned(offset + kHeapObjectTag, kPointerSize)); 140 IsAligned(offset + kHeapObjectTag, kPointerSize));
182 141
183 Register dst = scratch;
184 if (offset != 0) { 142 if (offset != 0) {
143 // If offset is unspecified, then dst is a scratch register. We use it
144 // to store the address of the cell that is being stored to.
185 lea(dst, Operand(object, offset)); 145 lea(dst, Operand(object, offset));
186 } else { 146 } else {
187 // Array access: calculate the destination address in the same manner as 147 // Array access: calculate the destination address in the same manner as
188 // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset 148 // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset
189 // into an array of words. 149 // into an array of words.
190 ASSERT_EQ(1, kSmiTagSize); 150 ASSERT_EQ(1, kSmiTagSize);
191 ASSERT_EQ(0, kSmiTag); 151 ASSERT_EQ(0, kSmiTag);
192 lea(dst, Operand(object, dst, times_half_pointer_size, 152 lea(dst, Operand(object, dst, times_half_pointer_size,
193 FixedArray::kHeaderSize - kHeapObjectTag)); 153 FixedArray::kHeaderSize - kHeapObjectTag));
194 } 154 }
195 RecordWriteHelper(object, dst, value, save_fp); 155
156 RecordWrite(object, dst, value, EMIT_REMEMBERED_SET, save_fp, OMIT_SMI_CHECK);
196 157
197 bind(&done); 158 bind(&done);
198 159
199 // Clobber all input registers when running with the debug-code flag 160 // Clobber all input registers when running with the debug-code flag
200 // turned on to provoke errors. 161 // turned on to provoke errors.
201 if (emit_debug_code()) { 162 if (emit_debug_code()) {
202 mov(object, Immediate(BitCast<int32_t>(kZapValue))); 163 mov(object, Immediate(BitCast<int32_t>(kZapValue)));
203 mov(value, Immediate(BitCast<int32_t>(kZapValue))); 164 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
204 mov(scratch, Immediate(BitCast<int32_t>(kZapValue))); 165 mov(dst, Immediate(BitCast<int32_t>(kZapValue)));
205 } 166 }
206 } 167 }
207 168
208 169
209 void MacroAssembler::RecordWrite(Register object, 170 void MacroAssembler::RecordWrite(Register object,
210 Register address, 171 Register address,
211 Register value, 172 Register value,
212 SaveFPRegsMode save_fp) { 173 EmitRememberedSet emit_remembered_set,
174 SaveFPRegsMode fp_mode,
175 SmiCheck smi_check) {
176 if (emit_remembered_set == OMIT_REMEMBERED_SET &&
177 FLAG_incremental_marking == false) {
178 return;
179 }
213 // First, check if a write barrier is even needed. The tests below 180 // First, check if a write barrier is even needed. The tests below
214 // catch stores of Smis and stores into young gen. 181 // catch stores of Smis and stores into young gen.
215 Label done; 182 NearLabel done;
216 183
217 // Skip barrier if writing a smi. 184 if (smi_check == INLINE_SMI_CHECK) {
218 ASSERT_EQ(0, kSmiTag); 185 // Skip barrier if writing a smi.
219 test(value, Immediate(kSmiTagMask)); 186 ASSERT_EQ(0, kSmiTag);
220 j(zero, &done); 187 test(value, Immediate(kSmiTagMask));
188 j(zero, &done);
189 }
221 190
222 IncrementalMarkingRecordWrite(object, 191 RecordWriteStub stub(object, value, address, emit_remembered_set, fp_mode);
223 value, 192 CallStub(&stub);
224 address,
225 OMIT_SMI_CHECK,
226 PRESERVE_OBJECT,
227 DESTROY_VALUE,
228 PRESERVE_SCRATCH);
229 193
230 InNewSpace(object, value, equal, &done); 194 if (smi_check == INLINE_SMI_CHECK) {
231 195 bind(&done);
232 RecordWriteHelper(object, address, value, save_fp); 196 }
233
234 bind(&done);
235 197
236 // Clobber all input registers when running with the debug-code flag 198 // Clobber all input registers when running with the debug-code flag
237 // turned on to provoke errors. 199 // turned on to provoke errors.
238 if (emit_debug_code()) { 200 if (emit_debug_code()) {
239 mov(object, Immediate(BitCast<int32_t>(kZapValue))); 201 mov(object, Immediate(BitCast<int32_t>(kZapValue)));
240 mov(address, Immediate(BitCast<int32_t>(kZapValue))); 202 mov(address, Immediate(BitCast<int32_t>(kZapValue)));
241 mov(value, Immediate(BitCast<int32_t>(kZapValue))); 203 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
242 } 204 }
243 } 205 }
244 206
(...skipping 1870 matching lines...) Expand 10 before | Expand all | Expand 10 after
2115 2077
2116 // Check that the code was patched as expected. 2078 // Check that the code was patched as expected.
2117 ASSERT(masm_.pc_ == address_ + size_); 2079 ASSERT(masm_.pc_ == address_ + size_);
2118 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 2080 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
2119 } 2081 }
2120 2082
2121 2083
2122 } } // namespace v8::internal 2084 } } // namespace v8::internal
2123 2085
2124 #endif // V8_TARGET_ARCH_IA32 2086 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698