pipegenruntime_p.h (3719B)
1 // This file is part of Blend2D project <https://blend2d.com> 2 // 3 // See blend2d.h or LICENSE.md for license and copyright information 4 // SPDX-License-Identifier: Zlib 5 6 #ifndef BLEND2D_PIPELINE_JIT_PIPEGENRUNTIME_P_H_INCLUDED 7 #define BLEND2D_PIPELINE_JIT_PIPEGENRUNTIME_P_H_INCLUDED 8 9 #include "../../support/arenaallocator_p.h" 10 #include "../../support/arenahashmap_p.h" 11 #include "../../support/wrap_p.h" 12 #include "../../threading/mutex_p.h" 13 #include "../../pipeline/piperuntime_p.h" 14 #include "../../pipeline/jit/pipecompiler_p.h" 15 #include "../../pipeline/jit/pipeprimitives_p.h" 16 17 //! \cond INTERNAL 18 //! \addtogroup blend2d_pipeline_jit 19 //! \{ 20 21 namespace bl::Pipeline::JIT { 22 23 //! PipeGen function cache. 24 //! 25 //! \note No locking is preformed implicitly as `BLPipeGenRuntime` synchronizes the access on its own. 26 class FunctionCache { 27 public: 28 struct FuncNode : public ArenaHashMapNode { 29 //! Function pointer. 30 void* _func; 31 32 BL_INLINE FuncNode(uint32_t signature, void* func) noexcept 33 : ArenaHashMapNode(signature) { 34 _custom_data = signature; 35 _func = func; 36 } 37 38 BL_INLINE void* func() const noexcept { return _func; } 39 BL_INLINE uint32_t signature() const noexcept { return _custom_data; } 40 }; 41 42 struct FuncMatcher { 43 uint32_t _signature; 44 45 BL_INLINE explicit FuncMatcher(uint32_t signature) noexcept 46 : _signature(signature) {} 47 48 BL_INLINE uint32_t hash_code() const noexcept { return _signature; } 49 BL_INLINE bool matches(const FuncNode* node) const noexcept { return node->signature() == _signature; } 50 }; 51 52 ArenaAllocator _allocator; 53 ArenaHashMap<FuncNode> _func_map; 54 55 FunctionCache() noexcept; 56 ~FunctionCache() noexcept; 57 58 BL_INLINE void* get(uint32_t signature) const noexcept { 59 const FuncNode* node = _func_map.get(FuncMatcher(signature)); 60 return node ? node->func() : nullptr; 61 } 62 63 BLResult put(uint32_t signature, void* func) noexcept; 64 }; 65 66 //! JIT pipeline runtime. 67 class PipeDynamicRuntime : public PipeRuntime { 68 public: 69 //! JIT runtime (stores JIT functions). 70 asmjit::JitRuntime _jit_runtime; 71 //! Read/write lock used to read/write function cache. 72 BLSharedMutex _mutex; 73 //! Function cache (caches JIT functions). 74 FunctionCache _function_cache; 75 //! Count of cached pipelines. 76 std::atomic<size_t> _pipeline_count; 77 78 //! CPU features to use (either detected or restricted by the user). 79 asmjit::CpuFeatures _cpu_features; 80 //! Optimization flags. 81 asmjit::CpuHints _cpu_hints; 82 //! Maximum pixels at a time, 0 if no limit (debug). 83 uint32_t _max_pixels; 84 85 //! Whether to turn on asmjit's logging feature. 86 bool _logger_enabled; 87 //! Whether to emit correct stack frames to make debugging easier. Disabled by default, because it consumes 88 //! one GP register, which is always useful. 89 bool _emit_stack_frames; 90 91 explicit PipeDynamicRuntime(PipeRuntimeFlags runtime_flags = PipeRuntimeFlags::kNone) noexcept; 92 ~PipeDynamicRuntime() noexcept; 93 94 void _init_cpu_info(const asmjit::CpuInfo& cpu_info) noexcept; 95 96 //! Restricts CPU features not provided in the given mask. This function is only used by isolated runtimes 97 //! to setup the runtime. It should never be used after the runtime is in use. 98 void _restrict_features(uint32_t mask) noexcept; 99 100 BL_INLINE uint32_t max_pixels() const noexcept { return _max_pixels; } 101 BL_INLINE void set_max_pixel_step(uint32_t value) noexcept { _max_pixels = value; } 102 BL_INLINE void set_logger_enabled(bool value) noexcept { _logger_enabled = value; } 103 104 FillFunc _compile_fill_func(uint32_t signature) noexcept; 105 106 static Wrap<PipeDynamicRuntime> _global; 107 }; 108 109 } // {bl::Pipeline::JIT} 110 111 //! \} 112 //! \endcond 113 114 #endif // BLEND2D_PIPELINE_JIT_PIPEGENRUNTIME_P_H_INCLUDED