Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |