michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef jit_MIRGenerator_h michael@0: #define jit_MIRGenerator_h michael@0: michael@0: // This file declares the data structures used to build a control-flow graph michael@0: // containing MIR. michael@0: michael@0: #include "mozilla/Atomics.h" michael@0: michael@0: #include michael@0: michael@0: #include "jscntxt.h" michael@0: #include "jscompartment.h" michael@0: michael@0: #include "jit/CompileInfo.h" michael@0: #include "jit/IonAllocPolicy.h" michael@0: #include "jit/JitCompartment.h" michael@0: #ifdef JS_ION_PERF michael@0: # include "jit/PerfSpewer.h" michael@0: #endif michael@0: #include "jit/RegisterSets.h" michael@0: michael@0: namespace js { michael@0: namespace jit { michael@0: michael@0: class MBasicBlock; michael@0: class MIRGraph; michael@0: class MStart; michael@0: class OptimizationInfo; michael@0: michael@0: class MIRGenerator michael@0: { michael@0: public: michael@0: MIRGenerator(CompileCompartment *compartment, const JitCompileOptions &options, michael@0: TempAllocator *alloc, MIRGraph *graph, michael@0: CompileInfo *info, const OptimizationInfo *optimizationInfo); michael@0: michael@0: TempAllocator &alloc() { michael@0: return *alloc_; michael@0: } michael@0: MIRGraph &graph() { michael@0: return *graph_; michael@0: } michael@0: bool ensureBallast() { michael@0: return alloc().ensureBallast(); michael@0: } michael@0: const JitRuntime *jitRuntime() const { michael@0: return GetIonContext()->runtime->jitRuntime(); michael@0: } michael@0: CompileInfo &info() { michael@0: return *info_; michael@0: } michael@0: const OptimizationInfo &optimizationInfo() const { michael@0: return *optimizationInfo_; michael@0: } michael@0: michael@0: template michael@0: T * allocate(size_t count = 1) { michael@0: if (count & mozilla::tl::MulOverflowMask::value) michael@0: return nullptr; michael@0: return reinterpret_cast(alloc().allocate(sizeof(T) * count)); michael@0: } michael@0: michael@0: // Set an error state and prints a message. Returns false so errors can be michael@0: // propagated up. michael@0: bool abort(const char *message, ...); michael@0: bool abortFmt(const char *message, va_list ap); michael@0: michael@0: bool errored() const { michael@0: return error_; michael@0: } michael@0: michael@0: bool instrumentedProfiling() { michael@0: return GetIonContext()->runtime->spsProfiler().enabled(); michael@0: } michael@0: michael@0: // Whether the main thread is trying to cancel this build. michael@0: bool shouldCancel(const char *why) { michael@0: return cancelBuild_; michael@0: } michael@0: void cancel() { michael@0: cancelBuild_ = true; michael@0: } michael@0: michael@0: bool compilingAsmJS() const { michael@0: return info_->script() == nullptr; michael@0: } michael@0: michael@0: uint32_t maxAsmJSStackArgBytes() const { michael@0: JS_ASSERT(compilingAsmJS()); michael@0: return maxAsmJSStackArgBytes_; michael@0: } michael@0: uint32_t resetAsmJSMaxStackArgBytes() { michael@0: JS_ASSERT(compilingAsmJS()); michael@0: uint32_t old = maxAsmJSStackArgBytes_; michael@0: maxAsmJSStackArgBytes_ = 0; michael@0: return old; michael@0: } michael@0: void setAsmJSMaxStackArgBytes(uint32_t n) { michael@0: JS_ASSERT(compilingAsmJS()); michael@0: maxAsmJSStackArgBytes_ = n; michael@0: } michael@0: void setPerformsCall() { michael@0: performsCall_ = true; michael@0: } michael@0: bool performsCall() const { michael@0: return performsCall_; michael@0: } michael@0: void setPerformsAsmJSCall() { michael@0: JS_ASSERT(compilingAsmJS()); michael@0: setPerformsCall(); michael@0: performsAsmJSCall_ = true; michael@0: } michael@0: bool performsAsmJSCall() const { michael@0: JS_ASSERT(compilingAsmJS()); michael@0: return performsAsmJSCall_; michael@0: } michael@0: void noteMinAsmJSHeapLength(uint32_t len) { michael@0: minAsmJSHeapLength_ = len; michael@0: } michael@0: uint32_t minAsmJSHeapLength() const { michael@0: return minAsmJSHeapLength_; michael@0: } michael@0: michael@0: bool modifiesFrameArguments() const { michael@0: return modifiesFrameArguments_; michael@0: } michael@0: michael@0: public: michael@0: CompileCompartment *compartment; michael@0: michael@0: protected: michael@0: CompileInfo *info_; michael@0: const OptimizationInfo *optimizationInfo_; michael@0: TempAllocator *alloc_; michael@0: JSFunction *fun_; michael@0: uint32_t nslots_; michael@0: MIRGraph *graph_; michael@0: bool error_; michael@0: mozilla::Atomic cancelBuild_; michael@0: michael@0: uint32_t maxAsmJSStackArgBytes_; michael@0: bool performsCall_; michael@0: bool performsAsmJSCall_; michael@0: uint32_t minAsmJSHeapLength_; michael@0: michael@0: // Keep track of whether frame arguments are modified during execution. michael@0: // RegAlloc needs to know this as spilling values back to their register michael@0: // slots is not compatible with that. michael@0: bool modifiesFrameArguments_; michael@0: michael@0: #if defined(JS_ION_PERF) michael@0: AsmJSPerfSpewer asmJSPerfSpewer_; michael@0: michael@0: public: michael@0: AsmJSPerfSpewer &perfSpewer() { return asmJSPerfSpewer_; } michael@0: #endif michael@0: michael@0: public: michael@0: const JitCompileOptions options; michael@0: }; michael@0: michael@0: } // namespace jit michael@0: } // namespace js michael@0: michael@0: #endif /* jit_MIRGenerator_h */