Bug 1421445 - Don't waste space allocating jit code buffer. r=jandem

When computing worst-case alignment padding, we don't take into account
the buffer already being partially aligned. This saves one word per
JitCode buffer allocation.

MozReview-Commit-ID: ZMwBzp97xy
This commit is contained in:
Ted Campbell 2017-11-28 17:23:47 -05:00
Родитель 295da27e19
Коммит 77e7cddb35
3 изменённых файлов: 35 добавлений и 10 удалений

Просмотреть файл

@ -767,9 +767,10 @@ JitCode::New<NoGC>(JSContext* cx, uint8_t* code, uint32_t bufferSize, uint32_t h
void
JitCode::copyFrom(MacroAssembler& masm)
{
// Store the JitCode pointer right before the code buffer, so we can
// recover the gcthing from relocation tables.
*(JitCode**)(code_ - sizeof(JitCode*)) = this;
// Store the JitCode pointer in the JitCodeHeader so we can recover the
// gcthing from relocation tables.
JitCodeHeader::FromExecutable(code_)->init(this);
insnSize_ = masm.instructionsSize();
masm.executableCopy(code_);

Просмотреть файл

@ -29,10 +29,26 @@ class MacroAssembler;
class PatchableBackedge;
class IonBuilder;
class IonICEntry;
class JitCode;
typedef Vector<JSObject*, 4, JitAllocPolicy> ObjectVector;
typedef Vector<TraceLoggerEvent, 0, SystemAllocPolicy> TraceLoggerEventVector;
// Header at start of raw code buffer
struct JitCodeHeader
{
// Link back to corresponding gcthing
JitCode* jitCode_;
void init(JitCode* jitCode) {
jitCode_ = jitCode;
}
static JitCodeHeader* FromExecutable(uint8_t* buffer) {
return (JitCodeHeader*)(buffer - sizeof(JitCodeHeader));
}
};
class JitCode : public gc::TenuredCell
{
protected:
@ -129,7 +145,7 @@ class JitCode : public gc::TenuredCell
void copyFrom(MacroAssembler& masm);
static JitCode* FromExecutable(uint8_t* buffer) {
JitCode* code = *(JitCode**)(buffer - sizeof(JitCode*));
JitCode* code = JitCodeHeader::FromExecutable(buffer)->jitCode_;
MOZ_ASSERT(code->raw() == buffer);
return code;
}

Просмотреть файл

@ -23,27 +23,35 @@ Linker::newCode(JSContext* cx, CodeKind kind, bool hasPatchableBackedges /* = fa
if (masm.oom())
return fail(cx);
ExecutablePool* pool;
size_t bytesNeeded = masm.bytesNeeded() + sizeof(JitCode*) + CodeAlignment;
static const size_t ExecutableAllocatorAlignment = sizeof(void*);
static_assert(CodeAlignment >= ExecutableAllocatorAlignment,
"Unexpected alignment requirements");
// We require enough bytes for the code, header, and worst-case alignment padding.
size_t bytesNeeded = masm.bytesNeeded() +
sizeof(JitCodeHeader) +
(CodeAlignment - ExecutableAllocatorAlignment);
if (bytesNeeded >= MAX_BUFFER_SIZE)
return fail(cx);
// ExecutableAllocator requires bytesNeeded to be word-size aligned.
bytesNeeded = AlignBytes(bytesNeeded, sizeof(void*));
// ExecutableAllocator requires bytesNeeded to be aligned.
bytesNeeded = AlignBytes(bytesNeeded, ExecutableAllocatorAlignment);
ExecutableAllocator& execAlloc = hasPatchableBackedges
? cx->runtime()->jitRuntime()->backedgeExecAlloc()
: cx->runtime()->jitRuntime()->execAlloc();
ExecutablePool* pool;
uint8_t* result = (uint8_t*)execAlloc.alloc(cx, bytesNeeded, &pool, kind);
if (!result)
return fail(cx);
// The JitCode pointer will be stored right before the code buffer.
uint8_t* codeStart = result + sizeof(JitCode*);
// The JitCodeHeader will be stored right before the code buffer.
uint8_t* codeStart = result + sizeof(JitCodeHeader);
// Bump the code up to a nice alignment.
codeStart = (uint8_t*)AlignBytes((uintptr_t)codeStart, CodeAlignment);
MOZ_ASSERT(codeStart + masm.bytesNeeded() <= result + bytesNeeded);
uint32_t headerSize = codeStart - result;
JitCode* code = JitCode::New<allowGC>(cx, codeStart, bytesNeeded - headerSize,
headerSize, pool, kind);