Chromium Code Reviews| Index: src/ia32/macro-assembler-ia32.cc |
| diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc |
| index 4b387402fe0244bfb1cd2d708817954f1db75f21..b7fc268e77eddc601602457af11649871b13b2c6 100644 |
| --- a/src/ia32/macro-assembler-ia32.cc |
| +++ b/src/ia32/macro-assembler-ia32.cc |
| @@ -571,6 +571,79 @@ void MacroAssembler::RecordWrite( |
| } |
| } |
| +void MacroAssembler::RecordWriteCodeEntryField(Register js_function, |
| + Register code_entry, |
| + 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.
|
| + const int offset = JSFunction::kCodeEntryOffset; |
| + |
| + // Since a code entry (value) is always in old space, we don't need to update |
| + // remembered set. If incremental marking is off, there is nothing for us to |
| + // do. |
| + if (!FLAG_incremental_marking) return; |
| + |
| + lea(dst, FieldOperand(js_function, offset)); |
| + |
| + DCHECK(!js_function.is(code_entry)); |
| + DCHECK(!js_function.is(dst)); |
| + DCHECK(!code_entry.is(dst)); |
| + AssertNotSmi(js_function); |
| + |
| + if (emit_debug_code()) { |
| + Label ok; |
| + cmp(code_entry, Operand(dst, 0)); |
| + j(equal, &ok, Label::kNear); |
| + int3(); |
| + bind(&ok); |
| + } |
| + |
| + // First, check if a write barrier is even needed. The tests below |
| + // catch stores of Smis and stores into young gen. |
| + Label done; |
| + |
| + CheckPageFlag(code_entry, |
| + code_entry, // Used as scratch. |
| + MemoryChunk::kPointersToHereAreInterestingMask, zero, &done, |
| + Label::kNear); |
| + CheckPageFlag(js_function, |
| + code_entry, // Used as scratch. |
| + MemoryChunk::kPointersFromHereAreInterestingMask, zero, &done, |
| + Label::kNear); |
| + |
| + // Save input registers. |
| + push(js_function); |
| + 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
|
| + |
| + // Save caller-saved registers. |
| + 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.
|
| + if (!js_function.is(ecx) && !code_entry.is(ecx)) push(ecx); |
| + if (!js_function.is(edx) && !code_entry.is(edx)) push(edx); |
| + |
| + int argument_count = 3; |
| + PrepareCallCFunction(argument_count, code_entry); |
| + mov(Operand(esp, 0 * kPointerSize), js_function); |
| + mov(Operand(esp, 1 * kPointerSize), dst); // Slot. |
| + mov(Operand(esp, 2 * kPointerSize), |
| + Immediate(ExternalReference::isolate_address(isolate()))); |
| + |
| + { |
| + AllowExternalCallThatCantCauseGC scope(this); |
| + CallCFunction( |
| + ExternalReference::incremental_marking_record_write_code_entry_function( |
| + isolate()), |
| + argument_count); |
| + } |
| + |
| + // Restore caller-saved registers. |
| + if (!js_function.is(edx) && !code_entry.is(edx)) pop(edx); |
| + if (!js_function.is(ecx) && !code_entry.is(ecx)) pop(ecx); |
| + if (!js_function.is(eax) && !code_entry.is(eax)) pop(eax); |
| + |
| + // Restore input registers. |
| + pop(code_entry); |
| + pop(js_function); |
| + |
| + bind(&done); |
| +} |
| void MacroAssembler::DebugBreak() { |
| Move(eax, Immediate(0)); |