Source code

Revision control

Copy as Markdown

Other Tools

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef jit_MIRGenerator_h
#define jit_MIRGenerator_h
// This file declares the data structures used to build a control-flow graph
// containing MIR.
#include "mozilla/Assertions.h"
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/Result.h"
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include "jit/CompilationDependencyTracker.h"
#include "jit/CompileInfo.h"
#include "jit/CompileWrappers.h"
#include "jit/JitAllocPolicy.h"
#include "jit/JitContext.h"
#include "jit/JitSpewer.h"
#include "jit/PerfSpewer.h"
#include "js/Utility.h"
#include "vm/GeckoProfiler.h"
namespace js {
namespace jit {
class JitRuntime;
class MIRGraph;
class OptimizationInfo;
class MIRGenerator final {
public:
MIRGenerator(CompileRealm* realm, const JitCompileOptions& options,
TempAllocator* alloc, MIRGraph* graph,
const CompileInfo* outerInfo,
const OptimizationInfo* optimizationInfo);
void initMinWasmMemory0Length(uint64_t init) { minWasmMemory0Length_ = init; }
TempAllocator& alloc() { return *alloc_; }
MIRGraph& graph() { return *graph_; }
[[nodiscard]] bool ensureBallast() { return alloc().ensureBallast(); }
const JitRuntime* jitRuntime() const { return runtime->jitRuntime(); }
const CompileInfo& outerInfo() const { return *outerInfo_; }
const OptimizationInfo& optimizationInfo() const {
return *optimizationInfo_;
}
bool hasProfilingScripts() const {
return runtime && runtime->profilingScripts();
}
template <typename T>
T* allocate(size_t count = 1) {
size_t bytes;
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(count, &bytes))) {
return nullptr;
}
return static_cast<T*>(alloc().allocate(bytes));
}
// Set an error state and prints a message. Returns false so errors can be
// propagated up.
mozilla::GenericErrorResult<AbortReason> abort(AbortReason r);
mozilla::GenericErrorResult<AbortReason> abort(AbortReason r,
const char* message, ...)
MOZ_FORMAT_PRINTF(3, 4);
mozilla::GenericErrorResult<AbortReason> abortFmt(AbortReason r,
const char* message,
va_list ap)
MOZ_FORMAT_PRINTF(3, 0);
// Collect the evaluation result of phases after WarpOracle, such that
// off-thread compilation can report what error got encountered.
void setOffThreadStatus(AbortReasonOr<Ok>&& result) {
MOZ_ASSERT(offThreadStatus_.isOk());
offThreadStatus_ = std::move(result);
}
const AbortReasonOr<Ok>& getOffThreadStatus() const {
return offThreadStatus_;
}
[[nodiscard]] bool instrumentedProfiling() {
if (!instrumentedProfilingIsCached_) {
instrumentedProfiling_ = runtime->geckoProfiler().enabled();
instrumentedProfilingIsCached_ = true;
}
return instrumentedProfiling_;
}
bool isProfilerInstrumentationEnabled() {
return !compilingWasm() && instrumentedProfiling();
}
gc::Heap initialStringHeap() const {
return stringsCanBeInNursery_ ? gc::Heap::Default : gc::Heap::Tenured;
}
gc::Heap initialBigIntHeap() const {
return bigIntsCanBeInNursery_ ? gc::Heap::Default : gc::Heap::Tenured;
}
// Whether the main thread is trying to cancel this build.
bool shouldCancel(const char* why) const { return cancelBuild_; }
void cancel() { cancelBuild_ = true; }
bool compilingWasm() const { return outerInfo_->compilingWasm(); }
uint32_t wasmMaxStackArgBytes() const {
MOZ_ASSERT(compilingWasm());
return wasmMaxStackArgBytes_;
}
void accumulateWasmMaxStackArgBytes(uint32_t n) {
MOZ_ASSERT(compilingWasm());
wasmMaxStackArgBytes_ = std::max(n, wasmMaxStackArgBytes_);
}
uint64_t minWasmMemory0Length() const { return minWasmMemory0Length_; }
void setNeedsOverrecursedCheck() { needsOverrecursedCheck_ = true; }
bool needsOverrecursedCheck() const { return needsOverrecursedCheck_; }
void setNeedsStaticStackAlignment() { needsStaticStackAlignment_ = true; }
bool needsStaticStackAlignment() const { return needsStaticStackAlignment_; }
public:
CompileRealm* realm;
CompileRuntime* runtime;
private:
// The CompileInfo for the outermost script.
const CompileInfo* outerInfo_;
const OptimizationInfo* optimizationInfo_;
TempAllocator* alloc_;
MIRGraph* graph_;
AbortReasonOr<Ok> offThreadStatus_;
mozilla::Atomic<bool, mozilla::Relaxed> cancelBuild_;
uint32_t wasmMaxStackArgBytes_;
bool needsOverrecursedCheck_;
bool needsStaticStackAlignment_;
bool instrumentedProfiling_;
bool instrumentedProfilingIsCached_;
bool stringsCanBeInNursery_;
bool bigIntsCanBeInNursery_;
bool disableLICM_ = false;
public:
void disableLICM() { disableLICM_ = true; }
bool licmEnabled() const;
bool branchHintingEnabled() const;
private:
uint64_t minWasmMemory0Length_;
IonPerfSpewer wasmPerfSpewer_;
public:
IonPerfSpewer& perfSpewer() { return wasmPerfSpewer_; }
public:
const JitCompileOptions options;
private:
GraphSpewer gs_;
public:
GraphSpewer& graphSpewer() { return gs_; }
CompilationDependencyTracker tracker;
};
} // namespace jit
} // namespace js
#endif /* jit_MIRGenerator_h */