Index: src/ppc/macro-assembler-ppc.cc |
diff --git a/src/ppc/macro-assembler-ppc.cc b/src/ppc/macro-assembler-ppc.cc |
index 49f9acffad16e2cfdb0db6f91d66692b695c8dfc..3424e9181f1b490659a65996144f4e788abaed4d 100644 |
--- a/src/ppc/macro-assembler-ppc.cc |
+++ b/src/ppc/macro-assembler-ppc.cc |
@@ -487,6 +487,68 @@ void MacroAssembler::RecordWrite( |
} |
} |
+void MacroAssembler::RecordWriteCodeEntryField(Register js_function, |
+ Register code_entry, |
+ Register scratch) { |
+ 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; |
+ |
+ DCHECK(js_function.is(r4)); |
+ DCHECK(code_entry.is(r7)); |
+ DCHECK(scratch.is(r8)); |
+ AssertNotSmi(js_function); |
+ |
+ if (emit_debug_code()) { |
+ addi(scratch, js_function, Operand(offset - kHeapObjectTag)); |
+ LoadP(ip, MemOperand(scratch)); |
+ cmp(ip, code_entry); |
+ Check(eq, kWrongAddressOrValuePassedToRecordWrite); |
+ } |
+ |
+ // 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, scratch, |
+ MemoryChunk::kPointersToHereAreInterestingMask, eq, &done); |
+ CheckPageFlag(js_function, scratch, |
+ MemoryChunk::kPointersFromHereAreInterestingMask, eq, &done); |
+ |
+ const Register dst = scratch; |
+ addi(dst, js_function, Operand(offset - kHeapObjectTag)); |
+ |
+ // Save caller-saved registers. js_function and code_entry are in the |
+ // caller-saved register list. |
+ DCHECK(kJSCallerSaved & js_function.bit()); |
+ DCHECK(kJSCallerSaved & code_entry.bit()); |
+ mflr(r0); |
+ MultiPush(kJSCallerSaved | r0.bit()); |
+ |
+ int argument_count = 3; |
+ PrepareCallCFunction(argument_count, code_entry); |
+ |
+ mr(r3, js_function); |
+ mr(r4, dst); |
+ mov(r5, Operand(ExternalReference::isolate_address(isolate()))); |
+ |
+ { |
+ AllowExternalCallThatCantCauseGC scope(this); |
+ CallCFunction( |
+ ExternalReference::incremental_marking_record_write_code_entry_function( |
+ isolate()), |
+ argument_count); |
+ } |
+ |
+ // Restore caller-saved registers (including js_function and code_entry). |
+ MultiPop(kJSCallerSaved | r0.bit()); |
+ mtlr(r0); |
+ |
+ bind(&done); |
+} |
void MacroAssembler::RememberedSetHelper(Register object, // For debug tests. |
Register address, Register scratch, |