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 |