tor-browser

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

AutoWritableJitCode.h (2256B)


      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 #ifndef jit_AutoWritableJitCode_h
      8 #define jit_AutoWritableJitCode_h
      9 
     10 #include "mozilla/Assertions.h"
     11 #include "mozilla/Attributes.h"
     12 #include "mozilla/TimeStamp.h"
     13 
     14 #include <stddef.h>
     15 
     16 #include "jit/ExecutableAllocator.h"
     17 #include "jit/JitCode.h"
     18 #include "jit/JitOptions.h"
     19 #include "jit/ProcessExecutableMemory.h"
     20 #include "vm/JSContext.h"
     21 #include "vm/Realm.h"
     22 #include "vm/Runtime.h"
     23 
     24 namespace js::jit {
     25 
     26 // This class ensures JIT code is executable on its destruction. Creators
     27 // must call makeWritable(), and not attempt to write to the buffer if it fails.
     28 //
     29 // AutoWritableJitCodeFallible may only fail to make code writable; it cannot
     30 // fail to make JIT code executable (because the creating code has no chance to
     31 // recover from a failed destructor).
     32 class MOZ_RAII AutoWritableJitCodeFallible {
     33  JSRuntime* rt_;
     34  void* addr_;
     35  size_t size_;
     36  AutoMarkJitCodeWritableForThread writableForThread_;
     37 
     38 public:
     39  explicit AutoWritableJitCodeFallible(JitCode* code)
     40      : rt_(code->runtimeFromMainThread()),
     41        addr_(code->allocatedMemory()),
     42        size_(code->allocatedSize()) {
     43    rt_->toggleAutoWritableJitCodeActive(true);
     44  }
     45 
     46  [[nodiscard]] bool makeWritable() {
     47    return ExecutableAllocator::makeWritable(addr_, size_);
     48  }
     49 
     50  ~AutoWritableJitCodeFallible() {
     51    if (!ExecutableAllocator::makeExecutableAndFlushICache(addr_, size_)) {
     52      MOZ_CRASH();
     53    }
     54    rt_->toggleAutoWritableJitCodeActive(false);
     55  }
     56 };
     57 
     58 // Infallible variant of AutoWritableJitCodeFallible, ensures writable during
     59 // construction
     60 class MOZ_RAII AutoWritableJitCode : private AutoWritableJitCodeFallible {
     61 public:
     62  explicit AutoWritableJitCode(JitCode* code)
     63      : AutoWritableJitCodeFallible(code) {
     64    AutoEnterOOMUnsafeRegion oomUnsafe;
     65    if (!makeWritable()) {
     66      oomUnsafe.crash("Failed to mmap. Likely no mappings available.");
     67    }
     68  }
     69 };
     70 
     71 }  // namespace js::jit
     72 
     73 #endif /* jit_AutoWritableJitCode_h */