diff options
Diffstat (limited to 'js/src/jit/MIRGenerator.h')
-rw-r--r-- | js/src/jit/MIRGenerator.h | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/js/src/jit/MIRGenerator.h b/js/src/jit/MIRGenerator.h new file mode 100644 index 000000000..d184bab1a --- /dev/null +++ b/js/src/jit/MIRGenerator.h @@ -0,0 +1,229 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * 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/Atomics.h" + +#include <stdarg.h> + +#include "jscntxt.h" +#include "jscompartment.h" + +#include "jit/CompileInfo.h" +#include "jit/JitAllocPolicy.h" +#include "jit/JitCompartment.h" +#include "jit/MIR.h" +#ifdef JS_ION_PERF +# include "jit/PerfSpewer.h" +#endif +#include "jit/RegisterSets.h" + +namespace js { +namespace jit { + +class MIRGraph; +class OptimizationInfo; + +class MIRGenerator +{ + public: + MIRGenerator(CompileCompartment* compartment, const JitCompileOptions& options, + TempAllocator* alloc, MIRGraph* graph, + const CompileInfo* info, const OptimizationInfo* optimizationInfo); + + void initMinWasmHeapLength(uint32_t init) { + minWasmHeapLength_ = init; + } + + TempAllocator& alloc() { + return *alloc_; + } + MIRGraph& graph() { + return *graph_; + } + MOZ_MUST_USE bool ensureBallast() { + return alloc().ensureBallast(); + } + const JitRuntime* jitRuntime() const { + return GetJitContext()->runtime->jitRuntime(); + } + const CompileInfo& info() const { + return *info_; + } + const OptimizationInfo& optimizationInfo() const { + return *optimizationInfo_; + } + + 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. + bool abort(const char* message, ...) MOZ_FORMAT_PRINTF(2, 3); // always returns false + bool abortFmt(const char* message, va_list ap); // always returns false + + bool errored() const { + return error_; + } + + MOZ_MUST_USE bool instrumentedProfiling() { + if (!instrumentedProfilingIsCached_) { + instrumentedProfiling_ = GetJitContext()->runtime->spsProfiler().enabled(); + instrumentedProfilingIsCached_ = true; + } + return instrumentedProfiling_; + } + + bool isProfilerInstrumentationEnabled() { + return !compilingWasm() && instrumentedProfiling(); + } + + bool isOptimizationTrackingEnabled() { + return isProfilerInstrumentationEnabled() && !info().isAnalysis(); + } + + bool safeForMinorGC() const { + return safeForMinorGC_; + } + void setNotSafeForMinorGC() { + safeForMinorGC_ = false; + } + + // Whether the main thread is trying to cancel this build. + bool shouldCancel(const char* why) { + maybePause(); + return cancelBuild_; + } + void cancel() { + cancelBuild_ = true; + } + + void maybePause() { + if (pauseBuild_ && *pauseBuild_) + PauseCurrentHelperThread(); + } + void setPauseFlag(mozilla::Atomic<bool, mozilla::Relaxed>* pauseBuild) { + pauseBuild_ = pauseBuild; + } + + void disable() { + abortReason_ = AbortReason_Disable; + } + AbortReason abortReason() { + return abortReason_; + } + + bool compilingWasm() const { + return info_->compilingWasm(); + } + + uint32_t wasmMaxStackArgBytes() const { + MOZ_ASSERT(compilingWasm()); + return wasmMaxStackArgBytes_; + } + void initWasmMaxStackArgBytes(uint32_t n) { + MOZ_ASSERT(compilingWasm()); + MOZ_ASSERT(wasmMaxStackArgBytes_ == 0); + wasmMaxStackArgBytes_ = n; + } + uint32_t minWasmHeapLength() const { + return minWasmHeapLength_; + } + void setPerformsCall() { + performsCall_ = true; + } + bool performsCall() const { + return performsCall_; + } + // Traverses the graph to find if there's any SIMD instruction. Costful but + // the value is cached, so don't worry about calling it several times. + bool usesSimd(); + + bool modifiesFrameArguments() const { + return modifiesFrameArguments_; + } + + typedef Vector<ObjectGroup*, 0, JitAllocPolicy> ObjectGroupVector; + + // When abortReason() == AbortReason_PreliminaryObjects, all groups with + // preliminary objects which haven't been analyzed yet. + const ObjectGroupVector& abortedPreliminaryGroups() const { + return abortedPreliminaryGroups_; + } + + public: + CompileCompartment* compartment; + + protected: + const CompileInfo* info_; + const OptimizationInfo* optimizationInfo_; + TempAllocator* alloc_; + MIRGraph* graph_; + AbortReason abortReason_; + bool shouldForceAbort_; // Force AbortReason_Disable + ObjectGroupVector abortedPreliminaryGroups_; + bool error_; + mozilla::Atomic<bool, mozilla::Relaxed>* pauseBuild_; + mozilla::Atomic<bool, mozilla::Relaxed> cancelBuild_; + + uint32_t wasmMaxStackArgBytes_; + bool performsCall_; + bool usesSimd_; + bool cachedUsesSimd_; + + // Keep track of whether frame arguments are modified during execution. + // RegAlloc needs to know this as spilling values back to their register + // slots is not compatible with that. + bool modifiesFrameArguments_; + + bool instrumentedProfiling_; + bool instrumentedProfilingIsCached_; + bool safeForMinorGC_; + + void addAbortedPreliminaryGroup(ObjectGroup* group); + + uint32_t minWasmHeapLength_; + + void setForceAbort() { + shouldForceAbort_ = true; + } + bool shouldForceAbort() { + return shouldForceAbort_; + } + +#if defined(JS_ION_PERF) + WasmPerfSpewer wasmPerfSpewer_; + + public: + WasmPerfSpewer& perfSpewer() { return wasmPerfSpewer_; } +#endif + + public: + const JitCompileOptions options; + + private: + GraphSpewer gs_; + + public: + GraphSpewer& graphSpewer() { + return gs_; + } +}; + +} // namespace jit +} // namespace js + +#endif /* jit_MIRGenerator_h */ |