OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 4254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4265 | 4265 |
4266 | 4266 |
4267 void MacroAssembler::RecordWriteField( | 4267 void MacroAssembler::RecordWriteField( |
4268 Register object, | 4268 Register object, |
4269 int offset, | 4269 int offset, |
4270 Register value, | 4270 Register value, |
4271 Register scratch, | 4271 Register scratch, |
4272 LinkRegisterStatus lr_status, | 4272 LinkRegisterStatus lr_status, |
4273 SaveFPRegsMode save_fp, | 4273 SaveFPRegsMode save_fp, |
4274 RememberedSetAction remembered_set_action, | 4274 RememberedSetAction remembered_set_action, |
4275 SmiCheck smi_check) { | 4275 SmiCheck smi_check, |
| 4276 PointersToHereCheck pointers_to_here_check_for_value) { |
4276 // First, check if a write barrier is even needed. The tests below | 4277 // First, check if a write barrier is even needed. The tests below |
4277 // catch stores of Smis. | 4278 // catch stores of Smis. |
4278 Label done; | 4279 Label done; |
4279 | 4280 |
4280 // Skip the barrier if writing a smi. | 4281 // Skip the barrier if writing a smi. |
4281 if (smi_check == INLINE_SMI_CHECK) { | 4282 if (smi_check == INLINE_SMI_CHECK) { |
4282 JumpIfSmi(value, &done); | 4283 JumpIfSmi(value, &done); |
4283 } | 4284 } |
4284 | 4285 |
4285 // Although the object register is tagged, the offset is relative to the start | 4286 // Although the object register is tagged, the offset is relative to the start |
4286 // of the object, so offset must be a multiple of kPointerSize. | 4287 // of the object, so offset must be a multiple of kPointerSize. |
4287 ASSERT(IsAligned(offset, kPointerSize)); | 4288 ASSERT(IsAligned(offset, kPointerSize)); |
4288 | 4289 |
4289 Add(scratch, object, offset - kHeapObjectTag); | 4290 Add(scratch, object, offset - kHeapObjectTag); |
4290 if (emit_debug_code()) { | 4291 if (emit_debug_code()) { |
4291 Label ok; | 4292 Label ok; |
4292 Tst(scratch, (1 << kPointerSizeLog2) - 1); | 4293 Tst(scratch, (1 << kPointerSizeLog2) - 1); |
4293 B(eq, &ok); | 4294 B(eq, &ok); |
4294 Abort(kUnalignedCellInWriteBarrier); | 4295 Abort(kUnalignedCellInWriteBarrier); |
4295 Bind(&ok); | 4296 Bind(&ok); |
4296 } | 4297 } |
4297 | 4298 |
4298 RecordWrite(object, | 4299 RecordWrite(object, |
4299 scratch, | 4300 scratch, |
4300 value, | 4301 value, |
4301 lr_status, | 4302 lr_status, |
4302 save_fp, | 4303 save_fp, |
4303 remembered_set_action, | 4304 remembered_set_action, |
4304 OMIT_SMI_CHECK); | 4305 OMIT_SMI_CHECK, |
| 4306 pointers_to_here_check_for_value); |
4305 | 4307 |
4306 Bind(&done); | 4308 Bind(&done); |
4307 | 4309 |
4308 // Clobber clobbered input registers when running with the debug-code flag | 4310 // Clobber clobbered input registers when running with the debug-code flag |
4309 // turned on to provoke errors. | 4311 // turned on to provoke errors. |
4310 if (emit_debug_code()) { | 4312 if (emit_debug_code()) { |
4311 Mov(value, Operand(BitCast<int64_t>(kZapValue + 4))); | 4313 Mov(value, Operand(BitCast<int64_t>(kZapValue + 4))); |
4312 Mov(scratch, Operand(BitCast<int64_t>(kZapValue + 8))); | 4314 Mov(scratch, Operand(BitCast<int64_t>(kZapValue + 8))); |
4313 } | 4315 } |
4314 } | 4316 } |
4315 | 4317 |
4316 | 4318 |
| 4319 // Will clobber: object, map, dst. |
| 4320 // If lr_status is kLRHasBeenSaved, lr will also be clobbered. |
| 4321 void MacroAssembler::RecordWriteForMap(Register object, |
| 4322 Register map, |
| 4323 Register dst, |
| 4324 LinkRegisterStatus lr_status, |
| 4325 SaveFPRegsMode fp_mode) { |
| 4326 ASM_LOCATION("MacroAssembler::RecordWrite"); |
| 4327 ASSERT(!AreAliased(object, map)); |
| 4328 |
| 4329 if (emit_debug_code()) { |
| 4330 UseScratchRegisterScope temps(this); |
| 4331 Register temp = temps.AcquireX(); |
| 4332 |
| 4333 CompareMap(map, temp, isolate()->factory()->meta_map()); |
| 4334 Check(eq, kWrongAddressOrValuePassedToRecordWrite); |
| 4335 } |
| 4336 |
| 4337 if (!FLAG_incremental_marking) { |
| 4338 return; |
| 4339 } |
| 4340 |
| 4341 if (emit_debug_code()) { |
| 4342 UseScratchRegisterScope temps(this); |
| 4343 Register temp = temps.AcquireX(); |
| 4344 |
| 4345 Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset)); |
| 4346 Cmp(temp, map); |
| 4347 Check(eq, kWrongAddressOrValuePassedToRecordWrite); |
| 4348 } |
| 4349 |
| 4350 // Count number of write barriers in generated code. |
| 4351 isolate()->counters()->write_barriers_static()->Increment(); |
| 4352 // TODO(mstarzinger): Dynamic counter missing. |
| 4353 |
| 4354 // First, check if a write barrier is even needed. The tests below |
| 4355 // catch stores of smis and stores into the young generation. |
| 4356 Label done; |
| 4357 |
| 4358 // A single check of the map's pages interesting flag suffices, since it is |
| 4359 // only set during incremental collection, and then it's also guaranteed that |
| 4360 // the from object's page's interesting flag is also set. This optimization |
| 4361 // relies on the fact that maps can never be in new space. |
| 4362 CheckPageFlagClear(map, |
| 4363 map, // Used as scratch. |
| 4364 MemoryChunk::kPointersToHereAreInterestingMask, |
| 4365 &done); |
| 4366 |
| 4367 // Record the actual write. |
| 4368 if (lr_status == kLRHasNotBeenSaved) { |
| 4369 Push(lr); |
| 4370 } |
| 4371 Add(dst, object, HeapObject::kMapOffset - kHeapObjectTag); |
| 4372 RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET, |
| 4373 fp_mode); |
| 4374 CallStub(&stub); |
| 4375 if (lr_status == kLRHasNotBeenSaved) { |
| 4376 Pop(lr); |
| 4377 } |
| 4378 |
| 4379 Bind(&done); |
| 4380 |
| 4381 // Clobber clobbered registers when running with the debug-code flag |
| 4382 // turned on to provoke errors. |
| 4383 if (emit_debug_code()) { |
| 4384 Mov(dst, Operand(BitCast<int64_t>(kZapValue + 12))); |
| 4385 Mov(map, Operand(BitCast<int64_t>(kZapValue + 16))); |
| 4386 } |
| 4387 } |
| 4388 |
| 4389 |
4317 // Will clobber: object, address, value. | 4390 // Will clobber: object, address, value. |
4318 // If lr_status is kLRHasBeenSaved, lr will also be clobbered. | 4391 // If lr_status is kLRHasBeenSaved, lr will also be clobbered. |
4319 // | 4392 // |
4320 // The register 'object' contains a heap object pointer. The heap object tag is | 4393 // The register 'object' contains a heap object pointer. The heap object tag is |
4321 // shifted away. | 4394 // shifted away. |
4322 void MacroAssembler::RecordWrite(Register object, | 4395 void MacroAssembler::RecordWrite( |
4323 Register address, | 4396 Register object, |
4324 Register value, | 4397 Register address, |
4325 LinkRegisterStatus lr_status, | 4398 Register value, |
4326 SaveFPRegsMode fp_mode, | 4399 LinkRegisterStatus lr_status, |
4327 RememberedSetAction remembered_set_action, | 4400 SaveFPRegsMode fp_mode, |
4328 SmiCheck smi_check) { | 4401 RememberedSetAction remembered_set_action, |
| 4402 SmiCheck smi_check, |
| 4403 PointersToHereCheck pointers_to_here_check_for_value) { |
4329 ASM_LOCATION("MacroAssembler::RecordWrite"); | 4404 ASM_LOCATION("MacroAssembler::RecordWrite"); |
4330 ASSERT(!AreAliased(object, value)); | 4405 ASSERT(!AreAliased(object, value)); |
4331 | 4406 |
4332 if (emit_debug_code()) { | 4407 if (emit_debug_code()) { |
4333 UseScratchRegisterScope temps(this); | 4408 UseScratchRegisterScope temps(this); |
4334 Register temp = temps.AcquireX(); | 4409 Register temp = temps.AcquireX(); |
4335 | 4410 |
4336 Ldr(temp, MemOperand(address)); | 4411 Ldr(temp, MemOperand(address)); |
4337 Cmp(temp, value); | 4412 Cmp(temp, value); |
4338 Check(eq, kWrongAddressOrValuePassedToRecordWrite); | 4413 Check(eq, kWrongAddressOrValuePassedToRecordWrite); |
4339 } | 4414 } |
4340 | 4415 |
4341 // Count number of write barriers in generated code. | 4416 // Count number of write barriers in generated code. |
4342 isolate()->counters()->write_barriers_static()->Increment(); | 4417 isolate()->counters()->write_barriers_static()->Increment(); |
4343 // TODO(mstarzinger): Dynamic counter missing. | 4418 // TODO(mstarzinger): Dynamic counter missing. |
4344 | 4419 |
4345 // First, check if a write barrier is even needed. The tests below | 4420 // First, check if a write barrier is even needed. The tests below |
4346 // catch stores of smis and stores into the young generation. | 4421 // catch stores of smis and stores into the young generation. |
4347 Label done; | 4422 Label done; |
4348 | 4423 |
4349 if (smi_check == INLINE_SMI_CHECK) { | 4424 if (smi_check == INLINE_SMI_CHECK) { |
4350 ASSERT_EQ(0, kSmiTag); | 4425 ASSERT_EQ(0, kSmiTag); |
4351 JumpIfSmi(value, &done); | 4426 JumpIfSmi(value, &done); |
4352 } | 4427 } |
4353 | 4428 |
4354 CheckPageFlagClear(value, | 4429 if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) { |
4355 value, // Used as scratch. | 4430 CheckPageFlagClear(value, |
4356 MemoryChunk::kPointersToHereAreInterestingMask, | 4431 value, // Used as scratch. |
4357 &done); | 4432 MemoryChunk::kPointersToHereAreInterestingMask, |
| 4433 &done); |
| 4434 } |
4358 CheckPageFlagClear(object, | 4435 CheckPageFlagClear(object, |
4359 value, // Used as scratch. | 4436 value, // Used as scratch. |
4360 MemoryChunk::kPointersFromHereAreInterestingMask, | 4437 MemoryChunk::kPointersFromHereAreInterestingMask, |
4361 &done); | 4438 &done); |
4362 | 4439 |
4363 // Record the actual write. | 4440 // Record the actual write. |
4364 if (lr_status == kLRHasNotBeenSaved) { | 4441 if (lr_status == kLRHasNotBeenSaved) { |
4365 Push(lr); | 4442 Push(lr); |
4366 } | 4443 } |
4367 RecordWriteStub stub(isolate(), object, value, address, remembered_set_action, | 4444 RecordWriteStub stub(isolate(), object, value, address, remembered_set_action, |
(...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5215 } | 5292 } |
5216 } | 5293 } |
5217 | 5294 |
5218 | 5295 |
5219 #undef __ | 5296 #undef __ |
5220 | 5297 |
5221 | 5298 |
5222 } } // namespace v8::internal | 5299 } } // namespace v8::internal |
5223 | 5300 |
5224 #endif // V8_TARGET_ARCH_ARM64 | 5301 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |