PPC: Write barrier for storing a code entry, and usage in CompileLazy builtin.
Port 477e133698
R=mvstanton@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=
Review URL: https://codereview.chromium.org/1668233003
Cr-Commit-Position: refs/heads/master@{#33755}
This commit is contained in:
parent
bedb3344aa
commit
ca255fd5e6
@ -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,
|
||||
|
@ -250,6 +250,11 @@ class MacroAssembler : public Assembler {
|
||||
pointers_to_here_check_for_value);
|
||||
}
|
||||
|
||||
// Notify the garbage collector that we wrote a code entry into a
|
||||
// JSFunction. Only scratch is clobbered by the operation.
|
||||
void RecordWriteCodeEntryField(Register js_function, Register code_entry,
|
||||
Register scratch);
|
||||
|
||||
void RecordWriteForMap(Register object, Register map, Register dst,
|
||||
LinkRegisterStatus lr_status, SaveFPRegsMode save_fp);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user