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

Side by Side Diff: src/ia32/macro-assembler-ia32.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 "v8.h" 5 #include "v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "bootstrapper.h" 9 #include "bootstrapper.h"
10 #include "codegen.h" 10 #include "codegen.h"
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 } 430 }
431 431
432 432
433 void MacroAssembler::RecordWriteField( 433 void MacroAssembler::RecordWriteField(
434 Register object, 434 Register object,
435 int offset, 435 int offset,
436 Register value, 436 Register value,
437 Register dst, 437 Register dst,
438 SaveFPRegsMode save_fp, 438 SaveFPRegsMode save_fp,
439 RememberedSetAction remembered_set_action, 439 RememberedSetAction remembered_set_action,
440 SmiCheck smi_check) { 440 SmiCheck smi_check,
441 bool value_is_in_new_space) {
441 // First, check if a write barrier is even needed. The tests below 442 // First, check if a write barrier is even needed. The tests below
442 // catch stores of Smis. 443 // catch stores of Smis.
443 Label done; 444 Label done;
444 445
445 // Skip barrier if writing a smi. 446 // Skip barrier if writing a smi.
446 if (smi_check == INLINE_SMI_CHECK) { 447 if (smi_check == INLINE_SMI_CHECK) {
447 JumpIfSmi(value, &done, Label::kNear); 448 JumpIfSmi(value, &done, Label::kNear);
448 } 449 }
449 450
450 // Although the object register is tagged, the offset is relative to the start 451 // Although the object register is tagged, the offset is relative to the start
451 // of the object, so so offset must be a multiple of kPointerSize. 452 // of the object, so so offset must be a multiple of kPointerSize.
452 ASSERT(IsAligned(offset, kPointerSize)); 453 ASSERT(IsAligned(offset, kPointerSize));
453 454
454 lea(dst, FieldOperand(object, offset)); 455 lea(dst, FieldOperand(object, offset));
455 if (emit_debug_code()) { 456 if (emit_debug_code()) {
456 Label ok; 457 Label ok;
457 test_b(dst, (1 << kPointerSizeLog2) - 1); 458 test_b(dst, (1 << kPointerSizeLog2) - 1);
458 j(zero, &ok, Label::kNear); 459 j(zero, &ok, Label::kNear);
459 int3(); 460 int3();
460 bind(&ok); 461 bind(&ok);
461 } 462 }
462 463
463 RecordWrite( 464 RecordWrite(
464 object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK); 465 object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK,
466 value_is_in_new_space);
465 467
466 bind(&done); 468 bind(&done);
467 469
468 // Clobber clobbered input registers when running with the debug-code flag 470 // Clobber clobbered input registers when running with the debug-code flag
469 // turned on to provoke errors. 471 // turned on to provoke errors.
470 if (emit_debug_code()) { 472 if (emit_debug_code()) {
471 mov(value, Immediate(BitCast<int32_t>(kZapValue))); 473 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
472 mov(dst, Immediate(BitCast<int32_t>(kZapValue))); 474 mov(dst, Immediate(BitCast<int32_t>(kZapValue)));
473 } 475 }
474 } 476 }
(...skipping 20 matching lines...) Expand all
495 497
496 ASSERT(!object.is(value)); 498 ASSERT(!object.is(value));
497 ASSERT(!object.is(address)); 499 ASSERT(!object.is(address));
498 ASSERT(!value.is(address)); 500 ASSERT(!value.is(address));
499 AssertNotSmi(object); 501 AssertNotSmi(object);
500 502
501 if (!FLAG_incremental_marking) { 503 if (!FLAG_incremental_marking) {
502 return; 504 return;
503 } 505 }
504 506
507 // Compute the address.
508 lea(address, FieldOperand(object, HeapObject::kMapOffset));
509
505 // Count number of write barriers in generated code. 510 // Count number of write barriers in generated code.
506 isolate()->counters()->write_barriers_static()->Increment(); 511 isolate()->counters()->write_barriers_static()->Increment();
507 IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 512 IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1);
508 513
509 // A single check of the map's pages interesting flag suffices, since it is 514 // A single check of the map's pages interesting flag suffices, since it is
510 // only set during incremental collection, and then it's also guaranteed that 515 // only set during incremental collection, and then it's also guaranteed that
511 // the from object's page's interesting flag is also set. This optimization 516 // the from object's page's interesting flag is also set. This optimization
512 // relies on the fact that maps can never be in new space. 517 // relies on the fact that maps can never be in new space.
513 ASSERT(!isolate()->heap()->InNewSpace(*map)); 518 ASSERT(!isolate()->heap()->InNewSpace(*map));
514 CheckPageFlagForMap(map, 519 CheckPageFlagForMap(map,
515 MemoryChunk::kPointersToHereAreInterestingMask, 520 MemoryChunk::kPointersToHereAreInterestingMask,
516 zero, 521 zero,
517 &done, 522 &done,
518 Label::kNear); 523 Label::kNear);
519 524
520 // Delay the initialization of |address| and |value| for the stub until it's
521 // known that the will be needed. Up until this point their values are not
522 // needed since they are embedded in the operands of instructions that need
523 // them.
524 lea(address, FieldOperand(object, HeapObject::kMapOffset));
525 mov(value, Immediate(map));
526 RecordWriteStub stub(isolate(), object, value, address, OMIT_REMEMBERED_SET, 525 RecordWriteStub stub(isolate(), object, value, address, OMIT_REMEMBERED_SET,
527 save_fp); 526 save_fp);
528 CallStub(&stub); 527 CallStub(&stub);
529 528
530 bind(&done); 529 bind(&done);
531 530
532 // Clobber clobbered input registers when running with the debug-code flag 531 // Clobber clobbered input registers when running with the debug-code flag
533 // turned on to provoke errors. 532 // turned on to provoke errors.
534 if (emit_debug_code()) { 533 if (emit_debug_code()) {
535 mov(value, Immediate(BitCast<int32_t>(kZapValue))); 534 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
536 mov(scratch1, Immediate(BitCast<int32_t>(kZapValue))); 535 mov(scratch1, Immediate(BitCast<int32_t>(kZapValue)));
537 mov(scratch2, Immediate(BitCast<int32_t>(kZapValue))); 536 mov(scratch2, Immediate(BitCast<int32_t>(kZapValue)));
538 } 537 }
539 } 538 }
540 539
541 540
542 void MacroAssembler::RecordWrite(Register object, 541 void MacroAssembler::RecordWrite(Register object,
543 Register address, 542 Register address,
544 Register value, 543 Register value,
545 SaveFPRegsMode fp_mode, 544 SaveFPRegsMode fp_mode,
546 RememberedSetAction remembered_set_action, 545 RememberedSetAction remembered_set_action,
547 SmiCheck smi_check) { 546 SmiCheck smi_check,
547 bool value_is_in_new_space) {
548 ASSERT(!object.is(value)); 548 ASSERT(!object.is(value));
549 ASSERT(!object.is(address)); 549 ASSERT(!object.is(address));
550 ASSERT(!value.is(address)); 550 ASSERT(!value.is(address));
551 AssertNotSmi(object); 551 AssertNotSmi(object);
552 552
553 if (remembered_set_action == OMIT_REMEMBERED_SET && 553 if (remembered_set_action == OMIT_REMEMBERED_SET &&
554 !FLAG_incremental_marking) { 554 !FLAG_incremental_marking) {
555 return; 555 return;
556 } 556 }
557 557
(...skipping 11 matching lines...) Expand all
569 569
570 // First, check if a write barrier is even needed. The tests below 570 // First, check if a write barrier is even needed. The tests below
571 // catch stores of Smis and stores into young gen. 571 // catch stores of Smis and stores into young gen.
572 Label done; 572 Label done;
573 573
574 if (smi_check == INLINE_SMI_CHECK) { 574 if (smi_check == INLINE_SMI_CHECK) {
575 // Skip barrier if writing a smi. 575 // Skip barrier if writing a smi.
576 JumpIfSmi(value, &done, Label::kNear); 576 JumpIfSmi(value, &done, Label::kNear);
577 } 577 }
578 578
579 CheckPageFlag(value, 579 if (!value_is_in_new_space) {
580 value, // Used as scratch. 580 CheckPageFlag(value,
581 MemoryChunk::kPointersToHereAreInterestingMask, 581 value, // Used as scratch.
582 zero, 582 MemoryChunk::kPointersToHereAreInterestingMask,
583 &done, 583 zero,
584 Label::kNear); 584 &done,
585 Label::kNear);
586 }
585 CheckPageFlag(object, 587 CheckPageFlag(object,
586 value, // Used as scratch. 588 value, // Used as scratch.
587 MemoryChunk::kPointersFromHereAreInterestingMask, 589 MemoryChunk::kPointersFromHereAreInterestingMask,
588 zero, 590 zero,
589 &done, 591 &done,
590 Label::kNear); 592 Label::kNear);
591 593
592 RecordWriteStub stub(isolate(), object, value, address, remembered_set_action, 594 RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
593 fp_mode); 595 fp_mode);
594 CallStub(&stub); 596 CallStub(&stub);
(...skipping 2841 matching lines...) Expand 10 before | Expand all | Expand 10 after
3436 if (ms.shift() > 0) sar(edx, ms.shift()); 3438 if (ms.shift() > 0) sar(edx, ms.shift());
3437 mov(eax, dividend); 3439 mov(eax, dividend);
3438 shr(eax, 31); 3440 shr(eax, 31);
3439 add(edx, eax); 3441 add(edx, eax);
3440 } 3442 }
3441 3443
3442 3444
3443 } } // namespace v8::internal 3445 } } // namespace v8::internal
3444 3446
3445 #endif // V8_TARGET_ARCH_IA32 3447 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/ia32/macro-assembler-ia32.h ('K') | « src/ia32/macro-assembler-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698