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)); |