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

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

Issue 297763006: Improve write barriers in optimized code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE Created 6 years, 6 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 <limits.h> // For LONG_MIN, LONG_MAX. 5 #include <limits.h> // For LONG_MIN, LONG_MAX.
6 6
7 #include "v8.h" 7 #include "v8.h"
8 8
9 #if V8_TARGET_ARCH_ARM 9 #if V8_TARGET_ARCH_ARM
10 10
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 446
447 447
448 void MacroAssembler::RecordWriteField( 448 void MacroAssembler::RecordWriteField(
449 Register object, 449 Register object,
450 int offset, 450 int offset,
451 Register value, 451 Register value,
452 Register dst, 452 Register dst,
453 LinkRegisterStatus lr_status, 453 LinkRegisterStatus lr_status,
454 SaveFPRegsMode save_fp, 454 SaveFPRegsMode save_fp,
455 RememberedSetAction remembered_set_action, 455 RememberedSetAction remembered_set_action,
456 SmiCheck smi_check) { 456 SmiCheck smi_check,
457 bool value_is_in_new_space) {
457 // First, check if a write barrier is even needed. The tests below 458 // First, check if a write barrier is even needed. The tests below
458 // catch stores of Smis. 459 // catch stores of Smis.
459 Label done; 460 Label done;
460 461
461 // Skip barrier if writing a smi. 462 // Skip barrier if writing a smi.
462 if (smi_check == INLINE_SMI_CHECK) { 463 if (smi_check == INLINE_SMI_CHECK) {
463 JumpIfSmi(value, &done); 464 JumpIfSmi(value, &done);
464 } 465 }
465 466
466 // Although the object register is tagged, the offset is relative to the start 467 // Although the object register is tagged, the offset is relative to the start
467 // of the object, so so offset must be a multiple of kPointerSize. 468 // of the object, so so offset must be a multiple of kPointerSize.
468 ASSERT(IsAligned(offset, kPointerSize)); 469 ASSERT(IsAligned(offset, kPointerSize));
469 470
470 add(dst, object, Operand(offset - kHeapObjectTag)); 471 add(dst, object, Operand(offset - kHeapObjectTag));
471 if (emit_debug_code()) { 472 if (emit_debug_code()) {
472 Label ok; 473 Label ok;
473 tst(dst, Operand((1 << kPointerSizeLog2) - 1)); 474 tst(dst, Operand((1 << kPointerSizeLog2) - 1));
474 b(eq, &ok); 475 b(eq, &ok);
475 stop("Unaligned cell in write barrier"); 476 stop("Unaligned cell in write barrier");
476 bind(&ok); 477 bind(&ok);
477 } 478 }
478 479
479 RecordWrite(object, 480 RecordWrite(object,
480 dst, 481 dst,
481 value, 482 value,
482 lr_status, 483 lr_status,
483 save_fp, 484 save_fp,
484 remembered_set_action, 485 remembered_set_action,
485 OMIT_SMI_CHECK); 486 OMIT_SMI_CHECK,
487 value_is_in_new_space);
486 488
487 bind(&done); 489 bind(&done);
488 490
489 // Clobber clobbered input registers when running with the debug-code flag 491 // Clobber clobbered input registers when running with the debug-code flag
490 // turned on to provoke errors. 492 // turned on to provoke errors.
491 if (emit_debug_code()) { 493 if (emit_debug_code()) {
492 mov(value, Operand(BitCast<int32_t>(kZapValue + 4))); 494 mov(value, Operand(BitCast<int32_t>(kZapValue + 4)));
493 mov(dst, Operand(BitCast<int32_t>(kZapValue + 8))); 495 mov(dst, Operand(BitCast<int32_t>(kZapValue + 8)));
494 } 496 }
495 } 497 }
496 498
497 499
500 // Will clobber 4 registers: object, map, dst, ip. The
501 // register 'object' contains a heap object pointer.
502 void MacroAssembler::RecordWriteForMap(Register object,
503 Register map,
504 Register dst,
505 LinkRegisterStatus lr_status,
506 SaveFPRegsMode fp_mode) {
507 Label done;
508
509 if (emit_debug_code()) {
510 ldr(dst, FieldMemOperand(map, HeapObject::kMapOffset));
511 cmp(dst, Operand(isolate()->factory()->meta_map()));
512 Check(eq, kWrongAddressOrValuePassedToRecordWrite);
513 }
514
515 // Count number of write barriers in generated code.
516 isolate()->counters()->write_barriers_static()->Increment();
517 // TODO(mstarzinger): Dynamic counter missing.
Hannes Payer (out of office) 2014/06/03 05:51:48 why TODO?
Benedikt Meurer 2014/06/03 07:48:02 I just copied the TODO.
518
519 if (emit_debug_code()) {
520 ldr(ip, FieldMemOperand(object, HeapObject::kMapOffset));
521 cmp(ip, map);
522 Check(eq, kWrongAddressOrValuePassedToRecordWrite);
523 }
524
525 // A single check of the map's pages interesting flag suffices, since it is
526 // only set during incremental collection, and then it's also guaranteed that
527 // the from object's page's interesting flag is also set. This optimization
528 // relies on the fact that maps can never be in new space.
529 CheckPageFlag(map,
530 map, // Used as scratch.
531 MemoryChunk::kPointersToHereAreInterestingMask,
532 eq,
533 &done);
534
535 add(dst, object, Operand(HeapObject::kMapOffset - kHeapObjectTag));
536 if (emit_debug_code()) {
537 Label ok;
538 tst(dst, Operand((1 << kPointerSizeLog2) - 1));
539 b(eq, &ok);
540 stop("Unaligned cell in write barrier");
541 bind(&ok);
542 }
543
544 // Record the actual write.
545 if (lr_status == kLRHasNotBeenSaved) {
546 push(lr);
547 }
548 RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET,
549 fp_mode);
550 CallStub(&stub);
551 if (lr_status == kLRHasNotBeenSaved) {
552 pop(lr);
553 }
554
555 bind(&done);
556
557 // Clobber clobbered registers when running with the debug-code flag
558 // turned on to provoke errors.
559 if (emit_debug_code()) {
560 mov(dst, Operand(BitCast<int32_t>(kZapValue + 12)));
561 mov(map, Operand(BitCast<int32_t>(kZapValue + 16)));
562 }
563 }
564
565
498 // Will clobber 4 registers: object, address, scratch, ip. The 566 // Will clobber 4 registers: object, address, scratch, ip. The
499 // register 'object' contains a heap object pointer. The heap object 567 // register 'object' contains a heap object pointer. The heap object
500 // tag is shifted away. 568 // tag is shifted away.
501 void MacroAssembler::RecordWrite(Register object, 569 void MacroAssembler::RecordWrite(Register object,
502 Register address, 570 Register address,
503 Register value, 571 Register value,
504 LinkRegisterStatus lr_status, 572 LinkRegisterStatus lr_status,
505 SaveFPRegsMode fp_mode, 573 SaveFPRegsMode fp_mode,
506 RememberedSetAction remembered_set_action, 574 RememberedSetAction remembered_set_action,
507 SmiCheck smi_check) { 575 SmiCheck smi_check,
576 bool value_is_in_new_space) {
508 ASSERT(!object.is(value)); 577 ASSERT(!object.is(value));
509 if (emit_debug_code()) { 578 if (emit_debug_code()) {
510 ldr(ip, MemOperand(address)); 579 ldr(ip, MemOperand(address));
511 cmp(ip, value); 580 cmp(ip, value);
512 Check(eq, kWrongAddressOrValuePassedToRecordWrite); 581 Check(eq, kWrongAddressOrValuePassedToRecordWrite);
513 } 582 }
514 583
515 // Count number of write barriers in generated code. 584 // Count number of write barriers in generated code.
516 isolate()->counters()->write_barriers_static()->Increment(); 585 isolate()->counters()->write_barriers_static()->Increment();
517 // TODO(mstarzinger): Dynamic counter missing. 586 // TODO(mstarzinger): Dynamic counter missing.
518 587
519 // First, check if a write barrier is even needed. The tests below 588 // First, check if a write barrier is even needed. The tests below
520 // catch stores of smis and stores into the young generation. 589 // catch stores of smis and stores into the young generation.
521 Label done; 590 Label done;
522 591
523 if (smi_check == INLINE_SMI_CHECK) { 592 if (smi_check == INLINE_SMI_CHECK) {
524 JumpIfSmi(value, &done); 593 JumpIfSmi(value, &done);
525 } 594 }
526 595
527 CheckPageFlag(value, 596 if (!value_is_in_new_space) {
528 value, // Used as scratch. 597 CheckPageFlag(value,
529 MemoryChunk::kPointersToHereAreInterestingMask, 598 value, // Used as scratch.
530 eq, 599 MemoryChunk::kPointersToHereAreInterestingMask,
531 &done); 600 eq,
601 &done);
602 }
532 CheckPageFlag(object, 603 CheckPageFlag(object,
533 value, // Used as scratch. 604 value, // Used as scratch.
534 MemoryChunk::kPointersFromHereAreInterestingMask, 605 MemoryChunk::kPointersFromHereAreInterestingMask,
535 eq, 606 eq,
536 &done); 607 &done);
537 608
538 // Record the actual write. 609 // Record the actual write.
539 if (lr_status == kLRHasNotBeenSaved) { 610 if (lr_status == kLRHasNotBeenSaved) {
540 push(lr); 611 push(lr);
541 } 612 }
(...skipping 3498 matching lines...) Expand 10 before | Expand all | Expand 10 after
4040 sub(result, result, Operand(dividend)); 4111 sub(result, result, Operand(dividend));
4041 } 4112 }
4042 if (ms.shift() > 0) mov(result, Operand(result, ASR, ms.shift())); 4113 if (ms.shift() > 0) mov(result, Operand(result, ASR, ms.shift()));
4043 add(result, result, Operand(dividend, LSR, 31)); 4114 add(result, result, Operand(dividend, LSR, 31));
4044 } 4115 }
4045 4116
4046 4117
4047 } } // namespace v8::internal 4118 } } // namespace v8::internal
4048 4119
4049 #endif // V8_TARGET_ARCH_ARM 4120 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698