Linker.cpp (2339B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "jit/Linker.h" 8 9 #include "jit/JitZone.h" 10 #include "util/Memory.h" 11 12 #include "gc/StoreBuffer-inl.h" 13 14 namespace js { 15 namespace jit { 16 17 JitCode* Linker::newCode(JSContext* cx, CodeKind kind) { 18 JS::AutoAssertNoGC nogc(cx); 19 if (masm.oom()) { 20 return fail(cx); 21 } 22 23 static const size_t ExecutableAllocatorAlignment = sizeof(void*); 24 static_assert(CodeAlignment >= ExecutableAllocatorAlignment, 25 "Unexpected alignment requirements"); 26 27 // We require enough bytes for the code, header, and worst-case alignment 28 // padding. 29 size_t bytesNeeded = masm.bytesNeeded() + sizeof(JitCodeHeader) + 30 (CodeAlignment - ExecutableAllocatorAlignment); 31 if (bytesNeeded >= MAX_BUFFER_SIZE) { 32 return fail(cx); 33 } 34 35 // ExecutableAllocator requires bytesNeeded to be aligned. 36 bytesNeeded = AlignBytes(bytesNeeded, ExecutableAllocatorAlignment); 37 38 JitZone* jitZone = cx->zone()->getJitZone(cx); 39 if (!jitZone) { 40 // Note: don't call fail(cx) here, getJitZone reports OOM. 41 return nullptr; 42 } 43 44 ExecutablePool* pool; 45 uint8_t* result = 46 (uint8_t*)jitZone->execAlloc().alloc(cx, bytesNeeded, &pool, kind); 47 if (!result) { 48 return fail(cx); 49 } 50 51 // The JitCodeHeader will be stored right before the code buffer. 52 uint8_t* codeStart = result + sizeof(JitCodeHeader); 53 54 // Bump the code up to a nice alignment. 55 codeStart = (uint8_t*)AlignBytes((uintptr_t)codeStart, CodeAlignment); 56 MOZ_ASSERT(codeStart + masm.bytesNeeded() <= result + bytesNeeded); 57 uint32_t headerSize = codeStart - result; 58 JitCode* code = 59 JitCode::New<NoGC>(cx, codeStart, bytesNeeded, headerSize, pool, kind); 60 if (!code) { 61 return fail(cx); 62 } 63 if (masm.oom()) { 64 return fail(cx); 65 } 66 awjcf.emplace(code); 67 if (!awjcf->makeWritable()) { 68 return fail(cx); 69 } 70 code->copyFrom(masm); 71 masm.link(code); 72 if (masm.embedsNurseryPointers()) { 73 cx->runtime()->gc.storeBuffer().putWholeCell(code); 74 } 75 return code; 76 } 77 78 } // namespace jit 79 } // namespace js