| 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 ASSERT(MemoryChunk::IN_TO_SPACE < 8); | 70 ASSERT(MemoryChunk::IN_TO_SPACE < 8); |
| 71 int mask = (1 << MemoryChunk::IN_FROM_SPACE) | 71 int mask = (1 << MemoryChunk::IN_FROM_SPACE) |
| 72 | (1 << MemoryChunk::IN_TO_SPACE); | 72 | (1 << MemoryChunk::IN_TO_SPACE); |
| 73 // If non-zero, the page belongs to new-space. | 73 // If non-zero, the page belongs to new-space. |
| 74 test_b(Operand(scratch, MemoryChunk::kFlagsOffset), | 74 test_b(Operand(scratch, MemoryChunk::kFlagsOffset), |
| 75 static_cast<uint8_t>(mask)); | 75 static_cast<uint8_t>(mask)); |
| 76 j(cc, condition_met, condition_met_distance); | 76 j(cc, condition_met, condition_met_distance); |
| 77 } | 77 } |
| 78 | 78 |
| 79 | 79 |
| 80 void MacroAssembler::IncrementalMarkingRecordWriteHelper( | |
| 81 Register object, | |
| 82 Register value, | |
| 83 Register address) { | |
| 84 ASSERT(!object.is(address)); | |
| 85 ASSERT(!value.is(address)); | |
| 86 ASSERT(!value.is(object)); | |
| 87 | |
| 88 bool preserve[Register::kNumRegisters]; | |
| 89 | |
| 90 for (int i = 0; i < Register::kNumRegisters; i++) preserve[i] = false; | |
| 91 | |
| 92 preserve[eax.code()] = true; | |
| 93 preserve[ecx.code()] = true; | |
| 94 preserve[edx.code()] = true; | |
| 95 preserve[object.code()] = true; | |
| 96 preserve[value.code()] = true; | |
| 97 preserve[address.code()] = true; | |
| 98 | |
| 99 for (int i = 0; i < Register::kNumRegisters; i++) { | |
| 100 if (preserve[i]) push(Register::from_code(i)); | |
| 101 } | |
| 102 | |
| 103 // TODO(gc) we are assuming that xmm registers are not modified by | |
| 104 // the C function we are calling. | |
| 105 PrepareCallCFunction(2, address); | |
| 106 mov(Operand(esp, 0 * kPointerSize), object); | |
| 107 mov(Operand(esp, 1 * kPointerSize), value); | |
| 108 CallCFunction( | |
| 109 ExternalReference::incremental_marking_record_write_function(isolate()), | |
| 110 2); | |
| 111 | |
| 112 for (int i = Register::kNumRegisters - 1; i >= 0; i--) { | |
| 113 if (preserve[i]) pop(Register::from_code(i)); | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 | |
| 118 void MacroAssembler::RememberedSetHelper( | 80 void MacroAssembler::RememberedSetHelper( |
| 119 Register addr, | 81 Register addr, |
| 120 Register scratch, | 82 Register scratch, |
| 121 SaveFPRegsMode save_fp, | 83 SaveFPRegsMode save_fp, |
| 122 MacroAssembler::RememberedSetFinalAction and_then) { | 84 MacroAssembler::RememberedSetFinalAction and_then) { |
| 123 Label done; | 85 Label done; |
| 124 if (FLAG_debug_code) { | 86 if (FLAG_debug_code) { |
| 125 Label ok; | 87 Label ok; |
| 126 JumpIfNotInNewSpace(addr, scratch, &ok, Label::kNear); | 88 JumpIfNotInNewSpace(addr, scratch, &ok, Label::kNear); |
| 127 int3(); | 89 int3(); |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 | 269 |
| 308 if (smi_check == INLINE_SMI_CHECK) { | 270 if (smi_check == INLINE_SMI_CHECK) { |
| 309 // Skip barrier if writing a smi. | 271 // Skip barrier if writing a smi. |
| 310 ASSERT_EQ(0, kSmiTag); | 272 ASSERT_EQ(0, kSmiTag); |
| 311 test(value, Immediate(kSmiTagMask)); | 273 test(value, Immediate(kSmiTagMask)); |
| 312 j(zero, &done, Label::kNear); | 274 j(zero, &done, Label::kNear); |
| 313 } | 275 } |
| 314 | 276 |
| 315 CheckPageFlag(value, | 277 CheckPageFlag(value, |
| 316 value, // Used as scratch. | 278 value, // Used as scratch. |
| 317 MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING, | 279 MemoryChunk::kPointersToHereAreInterestingMask, |
| 318 zero, | 280 zero, |
| 319 &done, | 281 &done, |
| 320 Label::kNear); | 282 Label::kNear); |
| 321 CheckPageFlag(object, | 283 CheckPageFlag(object, |
| 322 value, // Used as scratch. | 284 value, // Used as scratch. |
| 323 MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING, | 285 MemoryChunk::kPointersFromHereAreInterestingMask, |
| 324 zero, | 286 zero, |
| 325 &done, | 287 &done, |
| 326 Label::kNear); | 288 Label::kNear); |
| 327 | 289 |
| 328 RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode); | 290 RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode); |
| 329 CallStub(&stub); | 291 CallStub(&stub); |
| 330 | 292 |
| 331 bind(&done); | 293 bind(&done); |
| 332 | 294 |
| 333 // Clobber clobbered registers when running with the debug-code flag | 295 // Clobber clobbered registers when running with the debug-code flag |
| (...skipping 1929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2263 | 2225 |
| 2264 // Check that the code was patched as expected. | 2226 // Check that the code was patched as expected. |
| 2265 ASSERT(masm_.pc_ == address_ + size_); | 2227 ASSERT(masm_.pc_ == address_ + size_); |
| 2266 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 2228 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
| 2267 } | 2229 } |
| 2268 | 2230 |
| 2269 | 2231 |
| 2270 void MacroAssembler::CheckPageFlag( | 2232 void MacroAssembler::CheckPageFlag( |
| 2271 Register object, | 2233 Register object, |
| 2272 Register scratch, | 2234 Register scratch, |
| 2273 MemoryChunk::MemoryChunkFlags flag, | 2235 int mask, |
| 2274 Condition cc, | 2236 Condition cc, |
| 2275 Label* condition_met, | 2237 Label* condition_met, |
| 2276 Label::Distance condition_met_distance) { | 2238 Label::Distance condition_met_distance) { |
| 2277 ASSERT(cc == zero || cc == not_zero); | 2239 ASSERT(cc == zero || cc == not_zero); |
| 2278 if (scratch.is(object)) { | 2240 if (scratch.is(object)) { |
| 2279 and_(scratch, Immediate(~Page::kPageAlignmentMask)); | 2241 and_(scratch, Immediate(~Page::kPageAlignmentMask)); |
| 2280 } else { | 2242 } else { |
| 2281 mov(scratch, Immediate(~Page::kPageAlignmentMask)); | 2243 mov(scratch, Immediate(~Page::kPageAlignmentMask)); |
| 2282 and_(scratch, Operand(object)); | 2244 and_(scratch, Operand(object)); |
| 2283 } | 2245 } |
| 2284 if (flag < kBitsPerByte) { | 2246 if (mask < (1 << kBitsPerByte)) { |
| 2285 test_b(Operand(scratch, MemoryChunk::kFlagsOffset), | 2247 test_b(Operand(scratch, MemoryChunk::kFlagsOffset), |
| 2286 static_cast<uint8_t>(1u << flag)); | 2248 static_cast<uint8_t>(mask)); |
| 2287 } else { | 2249 } else { |
| 2288 test(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(1 << flag)); | 2250 test(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); |
| 2289 } | 2251 } |
| 2290 j(cc, condition_met, condition_met_distance); | 2252 j(cc, condition_met, condition_met_distance); |
| 2291 } | 2253 } |
| 2292 | 2254 |
| 2293 | 2255 |
| 2294 void MacroAssembler::JumpIfBlack(Register object, | 2256 void MacroAssembler::JumpIfBlack(Register object, |
| 2295 Register scratch0, | 2257 Register scratch0, |
| 2296 Register scratch1, | 2258 Register scratch1, |
| 2297 Label* on_black, | 2259 Label* on_black, |
| 2298 Label::Distance on_black_near) { | 2260 Label::Distance on_black_near) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2416 | 2378 |
| 2417 // Value is a data object, and it is white. Mark it black. Since we know | 2379 // Value is a data object, and it is white. Mark it black. Since we know |
| 2418 // that the object is white we can make it black by flipping one bit. | 2380 // that the object is white we can make it black by flipping one bit. |
| 2419 or_(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); | 2381 or_(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); |
| 2420 bind(&done); | 2382 bind(&done); |
| 2421 } | 2383 } |
| 2422 | 2384 |
| 2423 } } // namespace v8::internal | 2385 } } // namespace v8::internal |
| 2424 | 2386 |
| 2425 #endif // V8_TARGET_ARCH_IA32 | 2387 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |