229 lines
6.0 KiB
C++
229 lines
6.0 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* 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 */
|