Bug 1867190 - Add prefs for PHC probablities r=glandium
[gecko.git] / js / src / jit / AutoWritableJitCode.h
blobe7a1632a1e8718fa86e1f75312e414467aac2d68
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/. */
7 #ifndef jit_AutoWritableJitCode_h
8 #define jit_AutoWritableJitCode_h
10 #include "mozilla/Assertions.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/ScopeExit.h"
13 #include "mozilla/TimeStamp.h"
15 #include <stddef.h>
17 #include "jit/ExecutableAllocator.h"
18 #include "jit/JitCode.h"
19 #include "jit/JitOptions.h"
20 #include "jit/ProcessExecutableMemory.h"
21 #include "vm/JSContext.h"
22 #include "vm/Realm.h"
23 #include "vm/Runtime.h"
25 namespace js::jit {
27 // This class ensures JIT code is executable on its destruction. Creators
28 // must call makeWritable(), and not attempt to write to the buffer if it fails.
30 // AutoWritableJitCodeFallible may only fail to make code writable; it cannot
31 // fail to make JIT code executable (because the creating code has no chance to
32 // recover from a failed destructor).
33 class MOZ_RAII AutoWritableJitCodeFallible {
34 JSRuntime* rt_;
35 void* addr_;
36 size_t size_;
37 AutoMarkJitCodeWritableForThread writableForThread_;
39 public:
40 AutoWritableJitCodeFallible(JSRuntime* rt, void* addr, size_t size)
41 : rt_(rt), addr_(addr), size_(size) {
42 rt_->toggleAutoWritableJitCodeActive(true);
45 AutoWritableJitCodeFallible(void* addr, size_t size)
46 : AutoWritableJitCodeFallible(TlsContext.get()->runtime(), addr, size) {}
48 explicit AutoWritableJitCodeFallible(JitCode* code)
49 : AutoWritableJitCodeFallible(code->runtimeFromMainThread(), code->raw(),
50 code->bufferSize()) {}
52 [[nodiscard]] bool makeWritable() {
53 return ExecutableAllocator::makeWritable(addr_, size_);
56 ~AutoWritableJitCodeFallible() {
57 // Taking TimeStamps frequently can be expensive, and there's no point
58 // measuring this if write protection is disabled.
59 const bool measuringTime = JitOptions.writeProtectCode;
60 const mozilla::TimeStamp startTime =
61 measuringTime ? mozilla::TimeStamp::Now() : mozilla::TimeStamp();
62 auto timer = mozilla::MakeScopeExit([&] {
63 if (measuringTime) {
64 if (Realm* realm = rt_->mainContextFromOwnThread()->realm()) {
65 realm->timers.protectTime += mozilla::TimeStamp::Now() - startTime;
68 });
70 if (!ExecutableAllocator::makeExecutableAndFlushICache(addr_, size_)) {
71 MOZ_CRASH();
73 rt_->toggleAutoWritableJitCodeActive(false);
77 // Infallible variant of AutoWritableJitCodeFallible, ensures writable during
78 // construction
79 class MOZ_RAII AutoWritableJitCode : private AutoWritableJitCodeFallible {
80 public:
81 AutoWritableJitCode(JSRuntime* rt, void* addr, size_t size)
82 : AutoWritableJitCodeFallible(rt, addr, size) {
83 AutoEnterOOMUnsafeRegion oomUnsafe;
84 if (!makeWritable()) {
85 oomUnsafe.crash("Failed to mmap. Likely no mappings available.");
89 AutoWritableJitCode(void* addr, size_t size)
90 : AutoWritableJitCode(TlsContext.get()->runtime(), addr, size) {}
92 explicit AutoWritableJitCode(JitCode* code)
93 : AutoWritableJitCode(code->runtimeFromMainThread(), code->raw(),
94 code->bufferSize()) {}
97 } // namespace js::jit
99 #endif /* jit_AutoWritableJitCode_h */