| 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 |