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

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

Issue 1647123002: Write barrier for storing a code entry, and usage in CompileLazy builtin. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Just the macro instruction. Created 4 years, 10 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
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 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/base/division-by-constant.h" 8 #include "src/base/division-by-constant.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 500 IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1);
501 501
502 // Clobber clobbered registers when running with the debug-code flag 502 // Clobber clobbered registers when running with the debug-code flag
503 // turned on to provoke errors. 503 // turned on to provoke errors.
504 if (emit_debug_code()) { 504 if (emit_debug_code()) {
505 Move(address, kZapValue, Assembler::RelocInfoNone()); 505 Move(address, kZapValue, Assembler::RelocInfoNone());
506 Move(value, kZapValue, Assembler::RelocInfoNone()); 506 Move(value, kZapValue, Assembler::RelocInfoNone());
507 } 507 }
508 } 508 }
509 509
510 void MacroAssembler::RecordWriteCodeEntryField(Register js_function,
511 Register code_entry,
512 Register scratch) {
513 const int offset = JSFunction::kCodeEntryOffset;
514
515 // Since a code entry (value) is always in old space, we don't need to update
516 // remembered set. If incremental marking is off, there is nothing for us to
517 // do.
518 if (!FLAG_incremental_marking) return;
519
520 AssertNotSmi(js_function);
521
522 if (emit_debug_code()) {
523 Label ok;
524 leap(scratch, FieldOperand(js_function, offset));
525 cmpp(code_entry, Operand(scratch, 0));
526 j(equal, &ok, Label::kNear);
527 int3();
528 bind(&ok);
529 }
530
531 // First, check if a write barrier is even needed. The tests below
532 // catch stores of Smis and stores into young gen.
533 Label done;
534
535 CheckPageFlag(code_entry, scratch,
536 MemoryChunk::kPointersToHereAreInterestingMask, zero, &done,
537 Label::kNear);
538 CheckPageFlag(js_function, scratch,
539 MemoryChunk::kPointersFromHereAreInterestingMask, zero, &done,
540 Label::kNear);
541
542 // Save input registers.
543 Push(js_function);
544 Push(code_entry);
545
546 const Register dst = scratch;
547 leap(dst, FieldOperand(js_function, offset));
548
549 // Save caller-saved registers.
550 PushCallerSaved(kDontSaveFPRegs, js_function, code_entry);
551
552 int argument_count = 3;
553 PrepareCallCFunction(argument_count);
554
555 // Load the argument registers. It's easier if the input registers are fixed.
556 DCHECK(js_function.is(rdi));
ulan 2016/02/04 07:00:52 Let's move this up, to make it clear that it is a
mvstanton 2016/02/04 07:47:22 Done.
557 DCHECK(code_entry.is(rcx));
558 DCHECK(dst.is(rax));
559
560 if (arg_reg_1.is(rcx)) {
561 // Windows calling convention.
562 DCHECK(arg_reg_2.is(rdx) && arg_reg_3.is(r8));
563
564 movp(arg_reg_1, js_function); // rcx gets rdi.
565 movp(arg_reg_2, dst); // rdx gets rax.
566 } else if (arg_reg_1.is(rdi)) {
567 // AMD64 calling convention.
ulan 2016/02/04 07:00:52 no need for "if", just DCHECK(arg_reg_1.is(rdi));
mvstanton 2016/02/04 07:47:22 Done.
568 DCHECK(arg_reg_2.is(rsi) && arg_reg_3.is(rdx));
569
570 // rdi is already loaded with js_function.
571 movp(arg_reg_2, dst); // rsi gets rax.
572 } else {
573 // There are no other calling conventions.
574 UNREACHABLE();
575 }
576 Move(arg_reg_3, ExternalReference::isolate_address(isolate()));
577
578 {
579 AllowExternalCallThatCantCauseGC scope(this);
580 CallCFunction(
581 ExternalReference::incremental_marking_record_write_code_entry_function(
582 isolate()),
583 argument_count);
584 }
585
586 // Restore caller-saved registers.
587 PopCallerSaved(kDontSaveFPRegs, js_function, code_entry);
588
589 // Restore input registers.
590 Pop(code_entry);
591 Pop(js_function);
592
593 bind(&done);
594 }
510 595
511 void MacroAssembler::Assert(Condition cc, BailoutReason reason) { 596 void MacroAssembler::Assert(Condition cc, BailoutReason reason) {
512 if (emit_debug_code()) Check(cc, reason); 597 if (emit_debug_code()) Check(cc, reason);
513 } 598 }
514 599
515 600
516 void MacroAssembler::AssertFastElements(Register elements) { 601 void MacroAssembler::AssertFastElements(Register elements) {
517 if (emit_debug_code()) { 602 if (emit_debug_code()) {
518 Label ok; 603 Label ok;
519 CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 604 CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
(...skipping 4991 matching lines...) Expand 10 before | Expand all | Expand 10 after
5511 movl(rax, dividend); 5596 movl(rax, dividend);
5512 shrl(rax, Immediate(31)); 5597 shrl(rax, Immediate(31));
5513 addl(rdx, rax); 5598 addl(rdx, rax);
5514 } 5599 }
5515 5600
5516 5601
5517 } // namespace internal 5602 } // namespace internal
5518 } // namespace v8 5603 } // namespace v8
5519 5604
5520 #endif // V8_TARGET_ARCH_X64 5605 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698