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

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
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 cmp(src, Immediate(0)); 385 cmp(src, Immediate(0));
386 ExternalReference uint32_bias = 386 ExternalReference uint32_bias =
387 ExternalReference::address_of_uint32_bias(); 387 ExternalReference::address_of_uint32_bias();
388 Cvtsi2sd(dst, src); 388 Cvtsi2sd(dst, src);
389 j(not_sign, &done, Label::kNear); 389 j(not_sign, &done, Label::kNear);
390 addsd(dst, Operand::StaticVariable(uint32_bias)); 390 addsd(dst, Operand::StaticVariable(uint32_bias));
391 bind(&done); 391 bind(&done);
392 } 392 }
393 393
394 394
395 void MacroAssembler::RecordWriteArray(Register object, 395 void MacroAssembler::RecordWriteArray(
396 Register value, 396 Register object,
397 Register index, 397 Register value,
398 SaveFPRegsMode save_fp, 398 Register index,
399 RememberedSetAction remembered_set_action, 399 SaveFPRegsMode save_fp,
400 SmiCheck smi_check) { 400 RememberedSetAction remembered_set_action,
401 SmiCheck smi_check,
402 PointersToHereCheck pointers_to_here_check_for_value) {
401 // First, check if a write barrier is even needed. The tests below 403 // First, check if a write barrier is even needed. The tests below
402 // catch stores of Smis. 404 // catch stores of Smis.
403 Label done; 405 Label done;
404 406
405 // Skip barrier if writing a smi. 407 // Skip barrier if writing a smi.
406 if (smi_check == INLINE_SMI_CHECK) { 408 if (smi_check == INLINE_SMI_CHECK) {
407 ASSERT_EQ(0, kSmiTag); 409 ASSERT_EQ(0, kSmiTag);
408 test(value, Immediate(kSmiTagMask)); 410 test(value, Immediate(kSmiTagMask));
409 j(zero, &done); 411 j(zero, &done);
410 } 412 }
411 413
412 // Array access: calculate the destination address in the same manner as 414 // Array access: calculate the destination address in the same manner as
413 // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset 415 // KeyedStoreIC::GenerateGeneric. Multiply a smi by 2 to get an offset
414 // into an array of words. 416 // into an array of words.
415 Register dst = index; 417 Register dst = index;
416 lea(dst, Operand(object, index, times_half_pointer_size, 418 lea(dst, Operand(object, index, times_half_pointer_size,
417 FixedArray::kHeaderSize - kHeapObjectTag)); 419 FixedArray::kHeaderSize - kHeapObjectTag));
418 420
419 RecordWrite( 421 RecordWrite(object, dst, value, save_fp, remembered_set_action,
420 object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK); 422 OMIT_SMI_CHECK, pointers_to_here_check_for_value);
421 423
422 bind(&done); 424 bind(&done);
423 425
424 // Clobber clobbered input registers when running with the debug-code flag 426 // Clobber clobbered input registers when running with the debug-code flag
425 // turned on to provoke errors. 427 // turned on to provoke errors.
426 if (emit_debug_code()) { 428 if (emit_debug_code()) {
427 mov(value, Immediate(BitCast<int32_t>(kZapValue))); 429 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
428 mov(index, Immediate(BitCast<int32_t>(kZapValue))); 430 mov(index, Immediate(BitCast<int32_t>(kZapValue)));
429 } 431 }
430 } 432 }
431 433
432 434
433 void MacroAssembler::RecordWriteField( 435 void MacroAssembler::RecordWriteField(
434 Register object, 436 Register object,
435 int offset, 437 int offset,
436 Register value, 438 Register value,
437 Register dst, 439 Register dst,
438 SaveFPRegsMode save_fp, 440 SaveFPRegsMode save_fp,
439 RememberedSetAction remembered_set_action, 441 RememberedSetAction remembered_set_action,
440 SmiCheck smi_check) { 442 SmiCheck smi_check,
443 PointersToHereCheck pointers_to_here_check_for_value) {
441 // First, check if a write barrier is even needed. The tests below 444 // First, check if a write barrier is even needed. The tests below
442 // catch stores of Smis. 445 // catch stores of Smis.
443 Label done; 446 Label done;
444 447
445 // Skip barrier if writing a smi. 448 // Skip barrier if writing a smi.
446 if (smi_check == INLINE_SMI_CHECK) { 449 if (smi_check == INLINE_SMI_CHECK) {
447 JumpIfSmi(value, &done, Label::kNear); 450 JumpIfSmi(value, &done, Label::kNear);
448 } 451 }
449 452
450 // Although the object register is tagged, the offset is relative to the start 453 // 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. 454 // of the object, so so offset must be a multiple of kPointerSize.
452 ASSERT(IsAligned(offset, kPointerSize)); 455 ASSERT(IsAligned(offset, kPointerSize));
453 456
454 lea(dst, FieldOperand(object, offset)); 457 lea(dst, FieldOperand(object, offset));
455 if (emit_debug_code()) { 458 if (emit_debug_code()) {
456 Label ok; 459 Label ok;
457 test_b(dst, (1 << kPointerSizeLog2) - 1); 460 test_b(dst, (1 << kPointerSizeLog2) - 1);
458 j(zero, &ok, Label::kNear); 461 j(zero, &ok, Label::kNear);
459 int3(); 462 int3();
460 bind(&ok); 463 bind(&ok);
461 } 464 }
462 465
463 RecordWrite( 466 RecordWrite(object, dst, value, save_fp, remembered_set_action,
464 object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK); 467 OMIT_SMI_CHECK, pointers_to_here_check_for_value);
465 468
466 bind(&done); 469 bind(&done);
467 470
468 // Clobber clobbered input registers when running with the debug-code flag 471 // Clobber clobbered input registers when running with the debug-code flag
469 // turned on to provoke errors. 472 // turned on to provoke errors.
470 if (emit_debug_code()) { 473 if (emit_debug_code()) {
471 mov(value, Immediate(BitCast<int32_t>(kZapValue))); 474 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
472 mov(dst, Immediate(BitCast<int32_t>(kZapValue))); 475 mov(dst, Immediate(BitCast<int32_t>(kZapValue)));
473 } 476 }
474 } 477 }
(...skipping 20 matching lines...) Expand all
495 498
496 ASSERT(!object.is(value)); 499 ASSERT(!object.is(value));
497 ASSERT(!object.is(address)); 500 ASSERT(!object.is(address));
498 ASSERT(!value.is(address)); 501 ASSERT(!value.is(address));
499 AssertNotSmi(object); 502 AssertNotSmi(object);
500 503
501 if (!FLAG_incremental_marking) { 504 if (!FLAG_incremental_marking) {
502 return; 505 return;
503 } 506 }
504 507
508 // Compute the address.
509 lea(address, FieldOperand(object, HeapObject::kMapOffset));
510
505 // Count number of write barriers in generated code. 511 // Count number of write barriers in generated code.
506 isolate()->counters()->write_barriers_static()->Increment(); 512 isolate()->counters()->write_barriers_static()->Increment();
507 IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 513 IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1);
508 514
509 // A single check of the map's pages interesting flag suffices, since it is 515 // 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 516 // 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 517 // 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. 518 // relies on the fact that maps can never be in new space.
513 ASSERT(!isolate()->heap()->InNewSpace(*map)); 519 ASSERT(!isolate()->heap()->InNewSpace(*map));
514 CheckPageFlagForMap(map, 520 CheckPageFlagForMap(map,
515 MemoryChunk::kPointersToHereAreInterestingMask, 521 MemoryChunk::kPointersToHereAreInterestingMask,
516 zero, 522 zero,
517 &done, 523 &done,
518 Label::kNear); 524 Label::kNear);
519 525
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, 526 RecordWriteStub stub(isolate(), object, value, address, OMIT_REMEMBERED_SET,
527 save_fp); 527 save_fp);
528 CallStub(&stub); 528 CallStub(&stub);
529 529
530 bind(&done); 530 bind(&done);
531 531
532 // Clobber clobbered input registers when running with the debug-code flag 532 // Clobber clobbered input registers when running with the debug-code flag
533 // turned on to provoke errors. 533 // turned on to provoke errors.
534 if (emit_debug_code()) { 534 if (emit_debug_code()) {
535 mov(value, Immediate(BitCast<int32_t>(kZapValue))); 535 mov(value, Immediate(BitCast<int32_t>(kZapValue)));
536 mov(scratch1, Immediate(BitCast<int32_t>(kZapValue))); 536 mov(scratch1, Immediate(BitCast<int32_t>(kZapValue)));
537 mov(scratch2, Immediate(BitCast<int32_t>(kZapValue))); 537 mov(scratch2, Immediate(BitCast<int32_t>(kZapValue)));
538 } 538 }
539 } 539 }
540 540
541 541
542 void MacroAssembler::RecordWrite(Register object, 542 void MacroAssembler::RecordWrite(
543 Register address, 543 Register object,
544 Register value, 544 Register address,
545 SaveFPRegsMode fp_mode, 545 Register value,
546 RememberedSetAction remembered_set_action, 546 SaveFPRegsMode fp_mode,
547 SmiCheck smi_check) { 547 RememberedSetAction remembered_set_action,
548 SmiCheck smi_check,
549 PointersToHereCheck pointers_to_here_check_for_value) {
548 ASSERT(!object.is(value)); 550 ASSERT(!object.is(value));
549 ASSERT(!object.is(address)); 551 ASSERT(!object.is(address));
550 ASSERT(!value.is(address)); 552 ASSERT(!value.is(address));
551 AssertNotSmi(object); 553 AssertNotSmi(object);
552 554
553 if (remembered_set_action == OMIT_REMEMBERED_SET && 555 if (remembered_set_action == OMIT_REMEMBERED_SET &&
554 !FLAG_incremental_marking) { 556 !FLAG_incremental_marking) {
555 return; 557 return;
556 } 558 }
557 559
(...skipping 11 matching lines...) Expand all
569 571
570 // First, check if a write barrier is even needed. The tests below 572 // First, check if a write barrier is even needed. The tests below
571 // catch stores of Smis and stores into young gen. 573 // catch stores of Smis and stores into young gen.
572 Label done; 574 Label done;
573 575
574 if (smi_check == INLINE_SMI_CHECK) { 576 if (smi_check == INLINE_SMI_CHECK) {
575 // Skip barrier if writing a smi. 577 // Skip barrier if writing a smi.
576 JumpIfSmi(value, &done, Label::kNear); 578 JumpIfSmi(value, &done, Label::kNear);
577 } 579 }
578 580
579 CheckPageFlag(value, 581 if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) {
580 value, // Used as scratch. 582 CheckPageFlag(value,
581 MemoryChunk::kPointersToHereAreInterestingMask, 583 value, // Used as scratch.
582 zero, 584 MemoryChunk::kPointersToHereAreInterestingMask,
583 &done, 585 zero,
584 Label::kNear); 586 &done,
587 Label::kNear);
588 }
585 CheckPageFlag(object, 589 CheckPageFlag(object,
586 value, // Used as scratch. 590 value, // Used as scratch.
587 MemoryChunk::kPointersFromHereAreInterestingMask, 591 MemoryChunk::kPointersFromHereAreInterestingMask,
588 zero, 592 zero,
589 &done, 593 &done,
590 Label::kNear); 594 Label::kNear);
591 595
592 RecordWriteStub stub(isolate(), object, value, address, remembered_set_action, 596 RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
593 fp_mode); 597 fp_mode);
594 CallStub(&stub); 598 CallStub(&stub);
(...skipping 2806 matching lines...) Expand 10 before | Expand all | Expand 10 after
3401 if (ms.shift() > 0) sar(edx, ms.shift()); 3405 if (ms.shift() > 0) sar(edx, ms.shift());
3402 mov(eax, dividend); 3406 mov(eax, dividend);
3403 shr(eax, 31); 3407 shr(eax, 31);
3404 add(edx, eax); 3408 add(edx, eax);
3405 } 3409 }
3406 3410
3407 3411
3408 } } // namespace v8::internal 3412 } } // namespace v8::internal
3409 3413
3410 #endif // V8_TARGET_ARCH_IA32 3414 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698