mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 1317033 - Baldr: hoist mprotect out of MacroAssembler::patchCall/FarJump (r=sunfish)
MozReview-Commit-ID: Nejpro1fxc
This commit is contained in:
parent
19ae114a83
commit
392e723d67
@ -78,8 +78,7 @@ class PageProtectingVector final
|
||||
}
|
||||
|
||||
void protect() {
|
||||
MOZ_ASSERT(!regionUnprotected);
|
||||
if (protectionEnabled && unprotectedBytes >= intptr_t(pageSize)) {
|
||||
if (!regionUnprotected && protectionEnabled && unprotectedBytes >= intptr_t(pageSize)) {
|
||||
size_t toProtect = size_t(unprotectedBytes) & ~pageMask;
|
||||
uintptr_t addr = uintptr_t(vector.begin()) + offsetToPage + protectedBytes;
|
||||
gc::MakePagesReadOnly(reinterpret_cast<void*>(addr), toProtect);
|
||||
@ -89,9 +88,8 @@ class PageProtectingVector final
|
||||
}
|
||||
|
||||
void unprotect() {
|
||||
MOZ_ASSERT(!regionUnprotected);
|
||||
MOZ_ASSERT_IF(!protectionEnabled, !protectedBytes);
|
||||
if (protectedBytes) {
|
||||
if (!regionUnprotected && protectedBytes) {
|
||||
uintptr_t addr = uintptr_t(vector.begin()) + offsetToPage;
|
||||
gc::UnprotectPages(reinterpret_cast<void*>(addr), protectedBytes);
|
||||
unprotectedBytes += protectedBytes;
|
||||
|
@ -1536,6 +1536,10 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
// Instrumentation for entering and leaving the profiler.
|
||||
void profilerEnterFrame(Register framePtr, Register scratch);
|
||||
void profilerExitFrame();
|
||||
|
||||
struct AutoPrepareForPatching {
|
||||
explicit AutoPrepareForPatching(MacroAssemblerARMCompat&) {}
|
||||
};
|
||||
};
|
||||
|
||||
typedef MacroAssemblerARMCompat MacroAssemblerSpecific;
|
||||
|
@ -2316,6 +2316,10 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||
return nextOffset().getOffset();
|
||||
}
|
||||
|
||||
struct AutoPrepareForPatching {
|
||||
explicit AutoPrepareForPatching(MacroAssemblerCompat&) {}
|
||||
};
|
||||
|
||||
protected:
|
||||
bool buildOOLFakeExitFrame(void* fakeReturnAddr) {
|
||||
uint32_t descriptor = MakeFrameDescriptor(framePushed(), JitFrame_IonJS,
|
||||
|
@ -249,6 +249,11 @@ class MacroAssemblerMIPSShared : public Assembler
|
||||
void atomicExchange(int nbytes, bool signExtend, const BaseIndex& address, Register value,
|
||||
Register valueTemp, Register offsetTemp, Register maskTemp,
|
||||
Register output);
|
||||
|
||||
public:
|
||||
struct AutoPrepareForPatching {
|
||||
explicit AutoPrepareForPatching(MacroAssemblerMIPSShared&) {}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
|
@ -1057,17 +1057,24 @@ class AssemblerX86Shared : public AssemblerShared
|
||||
CodeOffset callWithPatch() {
|
||||
return CodeOffset(masm.call().offset());
|
||||
}
|
||||
|
||||
struct AutoPrepareForPatching : X86Encoding::AutoUnprotectAssemblerBufferRegion {
|
||||
explicit AutoPrepareForPatching(AssemblerX86Shared& masm)
|
||||
: X86Encoding::AutoUnprotectAssemblerBufferRegion(masm.masm, 0, masm.size())
|
||||
{}
|
||||
};
|
||||
|
||||
void patchCall(uint32_t callerOffset, uint32_t calleeOffset) {
|
||||
// The caller uses AutoUnprotectBuffer.
|
||||
unsigned char* code = masm.data();
|
||||
X86Encoding::AutoUnprotectAssemblerBufferRegion unprotect(masm, callerOffset - 4, 4);
|
||||
X86Encoding::SetRel32(code + callerOffset, code + calleeOffset);
|
||||
}
|
||||
CodeOffset farJumpWithPatch() {
|
||||
return CodeOffset(masm.jmp().offset());
|
||||
}
|
||||
void patchFarJump(CodeOffset farJump, uint32_t targetOffset) {
|
||||
// The caller uses AutoUnprotectBuffer.
|
||||
unsigned char* code = masm.data();
|
||||
X86Encoding::AutoUnprotectAssemblerBufferRegion unprotect(masm, farJump.offset() - 4, 4);
|
||||
X86Encoding::SetRel32(code + farJump.offset(), code + targetOffset);
|
||||
}
|
||||
static void repatchFarJump(uint8_t* code, uint32_t farJumpOffset, uint32_t targetOffset) {
|
||||
|
@ -250,6 +250,8 @@ typedef HashMap<uint32_t, uint32_t, DefaultHasher<uint32_t>, SystemAllocPolicy>
|
||||
bool
|
||||
ModuleGenerator::patchCallSites(TrapExitOffsetArray* maybeTrapExits)
|
||||
{
|
||||
MacroAssembler::AutoPrepareForPatching patching(masm_);
|
||||
|
||||
masm_.haltingAlign(CodeAlignment);
|
||||
|
||||
// Create far jumps for calls that have relative offsets that may otherwise
|
||||
@ -342,6 +344,24 @@ ModuleGenerator::patchCallSites(TrapExitOffsetArray* maybeTrapExits)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleGenerator::patchFarJumps(const TrapExitOffsetArray& trapExits)
|
||||
{
|
||||
MacroAssembler::AutoPrepareForPatching patching(masm_);
|
||||
|
||||
for (CallThunk& callThunk : metadata_->callThunks) {
|
||||
uint32_t funcIndex = callThunk.u.funcIndex;
|
||||
callThunk.u.codeRangeIndex = funcToCodeRange_[funcIndex];
|
||||
CodeOffset farJump(callThunk.offset);
|
||||
masm_.patchFarJump(farJump, funcCodeRange(funcIndex).funcNonProfilingEntry());
|
||||
}
|
||||
|
||||
for (const TrapFarJump& farJump : masm_.trapFarJumps())
|
||||
masm_.patchFarJump(farJump.jump, trapExits[farJump.trap].begin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleGenerator::finishTask(IonCompileTask* task)
|
||||
{
|
||||
@ -530,22 +550,15 @@ ModuleGenerator::finishCodegen()
|
||||
linkData_.outOfBoundsOffset = outOfBoundsExit.begin;
|
||||
linkData_.interruptOffset = interruptExit.begin;
|
||||
|
||||
// Now that all other code has been emitted, patch all remaining callsites.
|
||||
// Now that all other code has been emitted, patch all remaining callsites
|
||||
// then far jumps. Patching callsites can generate far jumps so there is an
|
||||
// ordering dependency.
|
||||
|
||||
if (!patchCallSites(&trapExits))
|
||||
return false;
|
||||
|
||||
// Now that all code has been generated, patch far jumps to destinations.
|
||||
|
||||
for (CallThunk& callThunk : metadata_->callThunks) {
|
||||
uint32_t funcIndex = callThunk.u.funcIndex;
|
||||
callThunk.u.codeRangeIndex = funcToCodeRange_[funcIndex];
|
||||
CodeOffset farJump(callThunk.offset);
|
||||
masm_.patchFarJump(farJump, funcCodeRange(funcIndex).funcNonProfilingEntry());
|
||||
}
|
||||
|
||||
for (const TrapFarJump& farJump : masm_.trapFarJumps())
|
||||
masm_.patchFarJump(farJump.jump, trapExits[farJump.trap].begin);
|
||||
if (!patchFarJumps(trapExits))
|
||||
return false;
|
||||
|
||||
// Code-generation is complete!
|
||||
|
||||
|
@ -118,6 +118,7 @@ class MOZ_STACK_CLASS ModuleGenerator
|
||||
bool funcIsCompiled(uint32_t funcIndex) const;
|
||||
const CodeRange& funcCodeRange(uint32_t funcIndex) const;
|
||||
MOZ_MUST_USE bool patchCallSites(TrapExitOffsetArray* maybeTrapExits = nullptr);
|
||||
MOZ_MUST_USE bool patchFarJumps(const TrapExitOffsetArray& trapExits);
|
||||
MOZ_MUST_USE bool finishTask(IonCompileTask* task);
|
||||
MOZ_MUST_USE bool finishOutstandingTask();
|
||||
MOZ_MUST_USE bool finishFuncExports();
|
||||
|
Loading…
Reference in New Issue
Block a user