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 */