tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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