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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
| 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 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 564 IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); | 564 IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); |
| 565 | 565 |
| 566 // Clobber clobbered registers when running with the debug-code flag | 566 // Clobber clobbered registers when running with the debug-code flag |
| 567 // turned on to provoke errors. | 567 // turned on to provoke errors. |
| 568 if (emit_debug_code()) { | 568 if (emit_debug_code()) { |
| 569 mov(address, Immediate(bit_cast<int32_t>(kZapValue))); | 569 mov(address, Immediate(bit_cast<int32_t>(kZapValue))); |
| 570 mov(value, Immediate(bit_cast<int32_t>(kZapValue))); | 570 mov(value, Immediate(bit_cast<int32_t>(kZapValue))); |
| 571 } | 571 } |
| 572 } | 572 } |
| 573 | 573 |
| 574 void MacroAssembler::RecordWriteCodeEntryField(Register js_function, | |
| 575 Register code_entry, | |
| 576 Register dst) { | |
|
ulan
2016/02/01 17:20:49
Let's keep argument names consistent with the head
mvstanton
2016/02/03 14:23:17
Done.
| |
| 577 const int offset = JSFunction::kCodeEntryOffset; | |
| 578 | |
| 579 // Since a code entry (value) is always in old space, we don't need to update | |
| 580 // remembered set. If incremental marking is off, there is nothing for us to | |
| 581 // do. | |
| 582 if (!FLAG_incremental_marking) return; | |
| 583 | |
| 584 lea(dst, FieldOperand(js_function, offset)); | |
| 585 | |
| 586 DCHECK(!js_function.is(code_entry)); | |
| 587 DCHECK(!js_function.is(dst)); | |
| 588 DCHECK(!code_entry.is(dst)); | |
| 589 AssertNotSmi(js_function); | |
| 590 | |
| 591 if (emit_debug_code()) { | |
| 592 Label ok; | |
| 593 cmp(code_entry, Operand(dst, 0)); | |
| 594 j(equal, &ok, Label::kNear); | |
| 595 int3(); | |
| 596 bind(&ok); | |
| 597 } | |
| 598 | |
| 599 // First, check if a write barrier is even needed. The tests below | |
| 600 // catch stores of Smis and stores into young gen. | |
| 601 Label done; | |
| 602 | |
| 603 CheckPageFlag(code_entry, | |
| 604 code_entry, // Used as scratch. | |
| 605 MemoryChunk::kPointersToHereAreInterestingMask, zero, &done, | |
| 606 Label::kNear); | |
| 607 CheckPageFlag(js_function, | |
| 608 code_entry, // Used as scratch. | |
| 609 MemoryChunk::kPointersFromHereAreInterestingMask, zero, &done, | |
| 610 Label::kNear); | |
| 611 | |
| 612 // Save input registers. | |
| 613 push(js_function); | |
| 614 push(code_entry); | |
|
ulan
2016/02/01 17:20:49
At this point the code_entry is already clobbered
mvstanton
2016/02/03 14:23:17
I changed things so that we don't clobber code_ent
| |
| 615 | |
| 616 // Save caller-saved registers. | |
| 617 if (!js_function.is(eax) && !code_entry.is(eax)) push(eax); | |
|
ulan
2016/02/01 17:20:49
Since this sequence is now used in two places. Sho
mvstanton
2016/02/03 14:23:17
Absolutely, done.
| |
| 618 if (!js_function.is(ecx) && !code_entry.is(ecx)) push(ecx); | |
| 619 if (!js_function.is(edx) && !code_entry.is(edx)) push(edx); | |
| 620 | |
| 621 int argument_count = 3; | |
| 622 PrepareCallCFunction(argument_count, code_entry); | |
| 623 mov(Operand(esp, 0 * kPointerSize), js_function); | |
| 624 mov(Operand(esp, 1 * kPointerSize), dst); // Slot. | |
| 625 mov(Operand(esp, 2 * kPointerSize), | |
| 626 Immediate(ExternalReference::isolate_address(isolate()))); | |
| 627 | |
| 628 { | |
| 629 AllowExternalCallThatCantCauseGC scope(this); | |
| 630 CallCFunction( | |
| 631 ExternalReference::incremental_marking_record_write_code_entry_function( | |
| 632 isolate()), | |
| 633 argument_count); | |
| 634 } | |
| 635 | |
| 636 // Restore caller-saved registers. | |
| 637 if (!js_function.is(edx) && !code_entry.is(edx)) pop(edx); | |
| 638 if (!js_function.is(ecx) && !code_entry.is(ecx)) pop(ecx); | |
| 639 if (!js_function.is(eax) && !code_entry.is(eax)) pop(eax); | |
| 640 | |
| 641 // Restore input registers. | |
| 642 pop(code_entry); | |
| 643 pop(js_function); | |
| 644 | |
| 645 bind(&done); | |
| 646 } | |
| 574 | 647 |
| 575 void MacroAssembler::DebugBreak() { | 648 void MacroAssembler::DebugBreak() { |
| 576 Move(eax, Immediate(0)); | 649 Move(eax, Immediate(0)); |
| 577 mov(ebx, Immediate(ExternalReference(Runtime::kHandleDebuggerStatement, | 650 mov(ebx, Immediate(ExternalReference(Runtime::kHandleDebuggerStatement, |
| 578 isolate()))); | 651 isolate()))); |
| 579 CEntryStub ces(isolate(), 1); | 652 CEntryStub ces(isolate(), 1); |
| 580 call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT); | 653 call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT); |
| 581 } | 654 } |
| 582 | 655 |
| 583 | 656 |
| (...skipping 2520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3104 mov(eax, dividend); | 3177 mov(eax, dividend); |
| 3105 shr(eax, 31); | 3178 shr(eax, 31); |
| 3106 add(edx, eax); | 3179 add(edx, eax); |
| 3107 } | 3180 } |
| 3108 | 3181 |
| 3109 | 3182 |
| 3110 } // namespace internal | 3183 } // namespace internal |
| 3111 } // namespace v8 | 3184 } // namespace v8 |
| 3112 | 3185 |
| 3113 #endif // V8_TARGET_ARCH_IA32 | 3186 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |