asmjit 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/asmjit.gemspec +1 -1
- data/ext/asmjit/asmjit/.editorconfig +10 -0
- data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
- data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
- data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
- data/ext/asmjit/asmjit/.gitignore +6 -0
- data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
- data/ext/asmjit/asmjit/LICENSE.md +17 -0
- data/ext/asmjit/asmjit/README.md +69 -0
- data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
- data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
- data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
- data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
- data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
- data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
- data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
- data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
- data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
- data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
- data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
- data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
- data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
- data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
- data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
- data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
- data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
- data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
- data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
- data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
- data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
- data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
- data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
- data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
- data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
- data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
- data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
- data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
- data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
- data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
- data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
- data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
- data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
- data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
- data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
- data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
- data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
- data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
- data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
- data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
- data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
- data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
- data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
- data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
- data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
- data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
- data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
- data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
- data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
- data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
- data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
- data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
- data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
- data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
- data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
- data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
- data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
- data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
- data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
- data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
- data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
- data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
- data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
- data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
- data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
- data/ext/asmjit/asmjit/test/broken.cpp +312 -0
- data/ext/asmjit/asmjit/test/broken.h +148 -0
- data/ext/asmjit/asmjit/test/cmdline.h +61 -0
- data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
- data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
- data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
- data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
- data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
- data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
- data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
- data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
- data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
- data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
- data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
- data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
- data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
- data/ext/asmjit/asmjit.cc +18 -0
- data/lib/asmjit/version.rb +1 -1
- metadata +197 -2
@@ -0,0 +1,261 @@
|
|
1
|
+
// This file is part of AsmJit project <https://asmjit.com>
|
2
|
+
//
|
3
|
+
// See asmjit.h or LICENSE.md for license and copyright information
|
4
|
+
// SPDX-License-Identifier: Zlib
|
5
|
+
|
6
|
+
#ifndef ASMJIT_CORE_JITALLOCATOR_H_INCLUDED
|
7
|
+
#define ASMJIT_CORE_JITALLOCATOR_H_INCLUDED
|
8
|
+
|
9
|
+
#include "../core/api-config.h"
|
10
|
+
#ifndef ASMJIT_NO_JIT
|
11
|
+
|
12
|
+
#include "../core/globals.h"
|
13
|
+
#include "../core/virtmem.h"
|
14
|
+
|
15
|
+
ASMJIT_BEGIN_NAMESPACE
|
16
|
+
|
17
|
+
//! \addtogroup asmjit_virtual_memory
|
18
|
+
//! \{
|
19
|
+
|
20
|
+
//! Options used by \ref JitAllocator.
|
21
|
+
enum class JitAllocatorOptions : uint32_t {
|
22
|
+
//! No options.
|
23
|
+
kNone = 0,
|
24
|
+
|
25
|
+
//! Enables the use of an anonymous memory-mapped memory that is mapped into two buffers having a different pointer.
|
26
|
+
//! The first buffer has read and execute permissions and the second buffer has read+write permissions.
|
27
|
+
//!
|
28
|
+
//! See \ref VirtMem::allocDualMapping() for more details about this feature.
|
29
|
+
kUseDualMapping = 0x00000001u,
|
30
|
+
|
31
|
+
//! Enables the use of multiple pools with increasing granularity instead of a single pool. This flag would enable
|
32
|
+
//! 3 internal pools in total having 64, 128, and 256 bytes granularity.
|
33
|
+
//!
|
34
|
+
//! This feature is only recommended for users that generate a lot of code and would like to minimize the overhead
|
35
|
+
//! of `JitAllocator` itself by having blocks of different allocation granularities. Using this feature only for
|
36
|
+
//! few allocations won't pay off as the allocator may need to create more blocks initially before it can take the
|
37
|
+
//! advantage of variable block granularity.
|
38
|
+
kUseMultiplePools = 0x00000002u,
|
39
|
+
|
40
|
+
//! Always fill reserved memory by a fill-pattern.
|
41
|
+
//!
|
42
|
+
//! Causes a new block to be cleared by the fill pattern and freshly released memory to be cleared before making
|
43
|
+
//! it ready for another use.
|
44
|
+
kFillUnusedMemory = 0x00000004u,
|
45
|
+
|
46
|
+
//! When this flag is set the allocator would immediately release unused blocks during `release()` or `reset()`.
|
47
|
+
//! When this flag is not set the allocator would keep one empty block in each pool to prevent excessive virtual
|
48
|
+
//! memory allocations and deallocations in border cases, which involve constantly allocating and deallocating a
|
49
|
+
//! single block caused by repetitive calling `alloc()` and `release()` when the allocator has either no blocks
|
50
|
+
//! or have all blocks fully occupied.
|
51
|
+
kImmediateRelease = 0x00000008u,
|
52
|
+
|
53
|
+
//! Use a custom fill pattern, must be combined with `kFlagFillUnusedMemory`.
|
54
|
+
kCustomFillPattern = 0x10000000u
|
55
|
+
};
|
56
|
+
ASMJIT_DEFINE_ENUM_FLAGS(JitAllocatorOptions)
|
57
|
+
|
58
|
+
//! A simple implementation of memory manager that uses `asmjit::VirtMem`
|
59
|
+
//! functions to manage virtual memory for JIT compiled code.
|
60
|
+
//!
|
61
|
+
//! Implementation notes:
|
62
|
+
//!
|
63
|
+
//! - Granularity of allocated blocks is different than granularity for a typical C malloc. In addition, the allocator
|
64
|
+
//! can use several memory pools having a different granularity to minimize the maintenance overhead. Multiple pools
|
65
|
+
//! feature requires `kFlagUseMultiplePools` flag to be set.
|
66
|
+
//!
|
67
|
+
//! - The allocator doesn't store any information in executable memory, instead, the implementation uses two
|
68
|
+
//! bit-vectors to manage allocated memory of each allocator-block. The first bit-vector called 'used' is used to
|
69
|
+
//! track used memory (where each bit represents memory size defined by granularity) and the second bit vector called
|
70
|
+
//! 'stop' is used as a sentinel to mark where the allocated area ends.
|
71
|
+
//!
|
72
|
+
//! - Internally, the allocator also uses RB tree to keep track of all blocks across all pools. Each inserted block is
|
73
|
+
//! added to the tree so it can be matched fast during `release()` and `shrink()`.
|
74
|
+
class JitAllocator {
|
75
|
+
public:
|
76
|
+
ASMJIT_NONCOPYABLE(JitAllocator)
|
77
|
+
|
78
|
+
struct Impl {
|
79
|
+
//! Allocator options.
|
80
|
+
JitAllocatorOptions options;
|
81
|
+
//! Base block size (0 if the allocator is not initialized).
|
82
|
+
uint32_t blockSize;
|
83
|
+
//! Base granularity (0 if the allocator is not initialized).
|
84
|
+
uint32_t granularity;
|
85
|
+
//! A pattern that is used to fill unused memory if secure mode is enabled.
|
86
|
+
uint32_t fillPattern;
|
87
|
+
};
|
88
|
+
|
89
|
+
//! Allocator implementation (private).
|
90
|
+
Impl* _impl;
|
91
|
+
|
92
|
+
//! \name Construction & Destruction
|
93
|
+
//! \{
|
94
|
+
|
95
|
+
//! Parameters that can be passed to `JitAllocator` constructor.
|
96
|
+
//!
|
97
|
+
//! Use it like this:
|
98
|
+
//!
|
99
|
+
//! ```
|
100
|
+
//! // Zero initialize (zero means the default value) and change what you need.
|
101
|
+
//! JitAllocator::CreateParams params {};
|
102
|
+
//! params.blockSize = 1024 * 1024;
|
103
|
+
//!
|
104
|
+
//! // Create the allocator.
|
105
|
+
//! JitAllocator allocator(¶ms);
|
106
|
+
//! ```
|
107
|
+
struct CreateParams {
|
108
|
+
//! Allocator options.
|
109
|
+
//!
|
110
|
+
//! No options are used by default.
|
111
|
+
JitAllocatorOptions options = JitAllocatorOptions::kNone;
|
112
|
+
|
113
|
+
//! Base size of a single block in bytes (default 64kB).
|
114
|
+
//!
|
115
|
+
//! \remarks Block size must be equal to or greater than page size and must be power of 2. If the input is not
|
116
|
+
//! valid then the default block size will be used instead.
|
117
|
+
uint32_t blockSize = 0;
|
118
|
+
|
119
|
+
//! Base granularity (and also natural alignment) of allocations in bytes (default 64).
|
120
|
+
//!
|
121
|
+
//! Since the `JitAllocator` uses bit-arrays to mark used memory the granularity also specifies how many bytes
|
122
|
+
//! correspond to a single bit in such bit-array. Higher granularity means more waste of virtual memory (as it
|
123
|
+
//! increases the natural alignment), but smaller bit-arrays as less bits would be required per a single block.
|
124
|
+
uint32_t granularity = 0;
|
125
|
+
|
126
|
+
//! Patter to use to fill unused memory.
|
127
|
+
//!
|
128
|
+
//! Only used if \ref JitAllocatorOptions::kCustomFillPattern is set.
|
129
|
+
uint32_t fillPattern = 0;
|
130
|
+
|
131
|
+
// Reset the content of `CreateParams`.
|
132
|
+
inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
|
133
|
+
};
|
134
|
+
|
135
|
+
//! Creates a `JitAllocator` instance.
|
136
|
+
ASMJIT_API explicit JitAllocator(const CreateParams* params = nullptr) noexcept;
|
137
|
+
//! Destroys the `JitAllocator` instance and release all blocks held.
|
138
|
+
ASMJIT_API ~JitAllocator() noexcept;
|
139
|
+
|
140
|
+
inline bool isInitialized() const noexcept { return _impl->blockSize == 0; }
|
141
|
+
|
142
|
+
//! Free all allocated memory - makes all pointers returned by `alloc()` invalid.
|
143
|
+
//!
|
144
|
+
//! \remarks This function is not thread-safe as it's designed to be used when nobody else is using allocator.
|
145
|
+
//! The reason is that there is no point of calling `reset()` when the allocator is still in use.
|
146
|
+
ASMJIT_API void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept;
|
147
|
+
|
148
|
+
//! \}
|
149
|
+
|
150
|
+
//! \name Accessors
|
151
|
+
//! \{
|
152
|
+
|
153
|
+
//! Returns allocator options, see `Flags`.
|
154
|
+
inline JitAllocatorOptions options() const noexcept { return _impl->options; }
|
155
|
+
//! Tests whether the allocator has the given `option` set.
|
156
|
+
inline bool hasOption(JitAllocatorOptions option) const noexcept { return uint32_t(_impl->options & option) != 0; }
|
157
|
+
|
158
|
+
//! Returns a base block size (a minimum size of block that the allocator would allocate).
|
159
|
+
inline uint32_t blockSize() const noexcept { return _impl->blockSize; }
|
160
|
+
//! Returns granularity of the allocator.
|
161
|
+
inline uint32_t granularity() const noexcept { return _impl->granularity; }
|
162
|
+
//! Returns pattern that is used to fill unused memory if `kFlagUseFillPattern` is set.
|
163
|
+
inline uint32_t fillPattern() const noexcept { return _impl->fillPattern; }
|
164
|
+
|
165
|
+
//! \}
|
166
|
+
|
167
|
+
//! \name Alloc & Release
|
168
|
+
//! \{
|
169
|
+
|
170
|
+
//! Allocates a new memory block of the requested `size`.
|
171
|
+
//!
|
172
|
+
//! When the function is successful it stores two pointers in `rxPtrOut` and `rwPtrOut`. The pointers will be
|
173
|
+
//! different only if `kOptionUseDualMapping` was used to setup the allocator (in that case the `rxPtrOut` would
|
174
|
+
//! point to a Read+Execute region and `rwPtrOut` would point to a Read+Write region of the same memory-mapped block.
|
175
|
+
ASMJIT_API Error alloc(void** rxPtrOut, void** rwPtrOut, size_t size) noexcept;
|
176
|
+
|
177
|
+
//! Releases a memory block returned by `alloc()`.
|
178
|
+
//!
|
179
|
+
//! \remarks This function is thread-safe.
|
180
|
+
ASMJIT_API Error release(void* rxPtr) noexcept;
|
181
|
+
|
182
|
+
//! Frees extra memory allocated with `rxPtr` by shrinking it to the given `newSize`.
|
183
|
+
//!
|
184
|
+
//! \remarks This function is thread-safe.
|
185
|
+
ASMJIT_API Error shrink(void* rxPtr, size_t newSize) noexcept;
|
186
|
+
|
187
|
+
//! Queries information about an allocated memory block that contains the given `rxPtr`.
|
188
|
+
//!
|
189
|
+
//! The function returns `kErrorOk` when `rxPtr` is matched and fills `rxPtrOut`, `rwPtrOut`, and `sizeOut` output
|
190
|
+
//! arguments. The returned `rxPtrOut` and `rwPtrOut` pointers point to the beginning of the block, and `sizeOut`
|
191
|
+
//! describes the total amount of bytes this allocation uses - `sizeOut` will always be aligned to the allocation
|
192
|
+
//! granularity, so for example if an allocation was 1 byte and the size granularity is 64, the returned `sizeOut`
|
193
|
+
//! will be 64 bytes, because that's what the allocator sees.
|
194
|
+
ASMJIT_API Error query(void* rxPtr, void** rxPtrOut, void** rwPtrOut, size_t* sizeOut) const noexcept;
|
195
|
+
|
196
|
+
//! \}
|
197
|
+
|
198
|
+
//! \name Statistics
|
199
|
+
//! \{
|
200
|
+
|
201
|
+
//! Statistics about `JitAllocator`.
|
202
|
+
struct Statistics {
|
203
|
+
//! Number of blocks `JitAllocator` maintains.
|
204
|
+
size_t _blockCount;
|
205
|
+
//! Number of active allocations.
|
206
|
+
size_t _allocationCount;
|
207
|
+
//! How many bytes are currently used / allocated.
|
208
|
+
size_t _usedSize;
|
209
|
+
//! How many bytes are currently reserved by the allocator.
|
210
|
+
size_t _reservedSize;
|
211
|
+
//! Allocation overhead (in bytes) required to maintain all blocks.
|
212
|
+
size_t _overheadSize;
|
213
|
+
|
214
|
+
inline void reset() noexcept {
|
215
|
+
_blockCount = 0;
|
216
|
+
_usedSize = 0;
|
217
|
+
_reservedSize = 0;
|
218
|
+
_overheadSize = 0;
|
219
|
+
}
|
220
|
+
|
221
|
+
//! Returns count of blocks managed by `JitAllocator` at the moment.
|
222
|
+
inline size_t blockCount() const noexcept { return _blockCount; }
|
223
|
+
//! Returns the number of active allocations.
|
224
|
+
inline size_t allocationCount() const noexcept { return _allocationCount; }
|
225
|
+
|
226
|
+
//! Returns how many bytes are currently used.
|
227
|
+
inline size_t usedSize() const noexcept { return _usedSize; }
|
228
|
+
//! Returns the number of bytes unused by the allocator at the moment.
|
229
|
+
inline size_t unusedSize() const noexcept { return _reservedSize - _usedSize; }
|
230
|
+
//! Returns the total number of bytes bytes reserved by the allocator (sum of sizes of all blocks).
|
231
|
+
inline size_t reservedSize() const noexcept { return _reservedSize; }
|
232
|
+
//! Returns the number of bytes the allocator needs to manage the allocated memory.
|
233
|
+
inline size_t overheadSize() const noexcept { return _overheadSize; }
|
234
|
+
|
235
|
+
inline double usedSizeAsPercent() const noexcept {
|
236
|
+
return (double(usedSize()) / (double(reservedSize()) + 1e-16)) * 100.0;
|
237
|
+
}
|
238
|
+
|
239
|
+
inline double unusedSizeAsPercent() const noexcept {
|
240
|
+
return (double(unusedSize()) / (double(reservedSize()) + 1e-16)) * 100.0;
|
241
|
+
}
|
242
|
+
|
243
|
+
inline double overheadSizeAsPercent() const noexcept {
|
244
|
+
return (double(overheadSize()) / (double(reservedSize()) + 1e-16)) * 100.0;
|
245
|
+
}
|
246
|
+
};
|
247
|
+
|
248
|
+
//! Returns JIT allocator statistics.
|
249
|
+
//!
|
250
|
+
//! \remarks This function is thread-safe.
|
251
|
+
ASMJIT_API Statistics statistics() const noexcept;
|
252
|
+
|
253
|
+
//! \}
|
254
|
+
};
|
255
|
+
|
256
|
+
//! \}
|
257
|
+
|
258
|
+
ASMJIT_END_NAMESPACE
|
259
|
+
|
260
|
+
#endif
|
261
|
+
#endif
|
@@ -0,0 +1,80 @@
|
|
1
|
+
// This file is part of AsmJit project <https://asmjit.com>
|
2
|
+
//
|
3
|
+
// See asmjit.h or LICENSE.md for license and copyright information
|
4
|
+
// SPDX-License-Identifier: Zlib
|
5
|
+
|
6
|
+
#include "../core/api-build_p.h"
|
7
|
+
#ifndef ASMJIT_NO_JIT
|
8
|
+
|
9
|
+
#include "../core/cpuinfo.h"
|
10
|
+
#include "../core/jitruntime.h"
|
11
|
+
|
12
|
+
ASMJIT_BEGIN_NAMESPACE
|
13
|
+
|
14
|
+
JitRuntime::JitRuntime(const JitAllocator::CreateParams* params) noexcept
|
15
|
+
: _allocator(params) {
|
16
|
+
_environment = Environment::host();
|
17
|
+
_environment.setObjectFormat(ObjectFormat::kJIT);
|
18
|
+
}
|
19
|
+
|
20
|
+
JitRuntime::~JitRuntime() noexcept {}
|
21
|
+
|
22
|
+
Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept {
|
23
|
+
*dst = nullptr;
|
24
|
+
|
25
|
+
ASMJIT_PROPAGATE(code->flatten());
|
26
|
+
ASMJIT_PROPAGATE(code->resolveUnresolvedLinks());
|
27
|
+
|
28
|
+
size_t estimatedCodeSize = code->codeSize();
|
29
|
+
if (ASMJIT_UNLIKELY(estimatedCodeSize == 0))
|
30
|
+
return DebugUtils::errored(kErrorNoCodeGenerated);
|
31
|
+
|
32
|
+
uint8_t* rx;
|
33
|
+
uint8_t* rw;
|
34
|
+
ASMJIT_PROPAGATE(_allocator.alloc((void**)&rx, (void**)&rw, estimatedCodeSize));
|
35
|
+
|
36
|
+
// Relocate the code.
|
37
|
+
Error err = code->relocateToBase(uintptr_t((void*)rx));
|
38
|
+
if (ASMJIT_UNLIKELY(err)) {
|
39
|
+
_allocator.release(rx);
|
40
|
+
return err;
|
41
|
+
}
|
42
|
+
|
43
|
+
// Recalculate the final code size and shrink the memory we allocated for it
|
44
|
+
// in case that some relocations didn't require records in an address table.
|
45
|
+
size_t codeSize = code->codeSize();
|
46
|
+
if (codeSize < estimatedCodeSize)
|
47
|
+
_allocator.shrink(rx, codeSize);
|
48
|
+
|
49
|
+
if (codeSize < estimatedCodeSize)
|
50
|
+
_allocator.shrink(rx, codeSize);
|
51
|
+
|
52
|
+
{
|
53
|
+
VirtMem::ProtectJitReadWriteScope rwScope(rx, codeSize);
|
54
|
+
|
55
|
+
for (Section* section : code->_sections) {
|
56
|
+
size_t offset = size_t(section->offset());
|
57
|
+
size_t bufferSize = size_t(section->bufferSize());
|
58
|
+
size_t virtualSize = size_t(section->virtualSize());
|
59
|
+
|
60
|
+
ASMJIT_ASSERT(offset + bufferSize <= codeSize);
|
61
|
+
memcpy(rw + offset, section->data(), bufferSize);
|
62
|
+
|
63
|
+
if (virtualSize > bufferSize) {
|
64
|
+
ASMJIT_ASSERT(offset + virtualSize <= codeSize);
|
65
|
+
memset(rw + offset + bufferSize, 0, virtualSize - bufferSize);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
*dst = rx;
|
71
|
+
return kErrorOk;
|
72
|
+
}
|
73
|
+
|
74
|
+
Error JitRuntime::_release(void* p) noexcept {
|
75
|
+
return _allocator.release(p);
|
76
|
+
}
|
77
|
+
|
78
|
+
ASMJIT_END_NAMESPACE
|
79
|
+
|
80
|
+
#endif
|
@@ -0,0 +1,89 @@
|
|
1
|
+
// This file is part of AsmJit project <https://asmjit.com>
|
2
|
+
//
|
3
|
+
// See asmjit.h or LICENSE.md for license and copyright information
|
4
|
+
// SPDX-License-Identifier: Zlib
|
5
|
+
|
6
|
+
#ifndef ASMJIT_CORE_JITRUNTIME_H_INCLUDED
|
7
|
+
#define ASMJIT_CORE_JITRUNTIME_H_INCLUDED
|
8
|
+
|
9
|
+
#include "../core/api-config.h"
|
10
|
+
#ifndef ASMJIT_NO_JIT
|
11
|
+
|
12
|
+
#include "../core/codeholder.h"
|
13
|
+
#include "../core/jitallocator.h"
|
14
|
+
#include "../core/target.h"
|
15
|
+
|
16
|
+
ASMJIT_BEGIN_NAMESPACE
|
17
|
+
|
18
|
+
class CodeHolder;
|
19
|
+
|
20
|
+
//! \addtogroup asmjit_virtual_memory
|
21
|
+
//! \{
|
22
|
+
|
23
|
+
//! JIT execution runtime is a special `Target` that is designed to store and
|
24
|
+
//! execute the generated code.
|
25
|
+
class ASMJIT_VIRTAPI JitRuntime : public Target {
|
26
|
+
public:
|
27
|
+
ASMJIT_NONCOPYABLE(JitRuntime)
|
28
|
+
|
29
|
+
//! Virtual memory allocator.
|
30
|
+
JitAllocator _allocator;
|
31
|
+
|
32
|
+
//! \name Construction & Destruction
|
33
|
+
//! \{
|
34
|
+
|
35
|
+
//! Creates a `JitRuntime` instance.
|
36
|
+
ASMJIT_API explicit JitRuntime(const JitAllocator::CreateParams* params = nullptr) noexcept;
|
37
|
+
//! Destroys the `JitRuntime` instance.
|
38
|
+
ASMJIT_API virtual ~JitRuntime() noexcept;
|
39
|
+
|
40
|
+
inline void reset(ResetPolicy resetPolicy = ResetPolicy::kSoft) noexcept {
|
41
|
+
_allocator.reset(resetPolicy);
|
42
|
+
}
|
43
|
+
|
44
|
+
//! \}
|
45
|
+
|
46
|
+
//! \name Accessors
|
47
|
+
//! \{
|
48
|
+
|
49
|
+
//! Returns the associated `JitAllocator`.
|
50
|
+
inline JitAllocator* allocator() const noexcept { return const_cast<JitAllocator*>(&_allocator); }
|
51
|
+
|
52
|
+
//! \}
|
53
|
+
|
54
|
+
//! \name Utilities
|
55
|
+
//! \{
|
56
|
+
|
57
|
+
// NOTE: To allow passing function pointers to `add()` and `release()` the
|
58
|
+
// virtual methods are prefixed with `_` and called from templates instead.
|
59
|
+
|
60
|
+
//! Allocates memory needed for a code stored in the `CodeHolder` and relocates the code to the pointer allocated.
|
61
|
+
//!
|
62
|
+
//! The beginning of the memory allocated for the function is returned in `dst`. If failed `Error` code is returned
|
63
|
+
//! and `dst` is explicitly set to `nullptr` (this means that you don't have to set it to null before calling `add()`).
|
64
|
+
template<typename Func>
|
65
|
+
inline Error add(Func* dst, CodeHolder* code) noexcept {
|
66
|
+
return _add(Support::ptr_cast_impl<void**, Func*>(dst), code);
|
67
|
+
}
|
68
|
+
|
69
|
+
//! Releases `p` which was obtained by calling `add()`.
|
70
|
+
template<typename Func>
|
71
|
+
inline Error release(Func p) noexcept {
|
72
|
+
return _release(Support::ptr_cast_impl<void*, Func>(p));
|
73
|
+
}
|
74
|
+
|
75
|
+
//! Type-unsafe version of `add()`.
|
76
|
+
ASMJIT_API virtual Error _add(void** dst, CodeHolder* code) noexcept;
|
77
|
+
|
78
|
+
//! Type-unsafe version of `release()`.
|
79
|
+
ASMJIT_API virtual Error _release(void* p) noexcept;
|
80
|
+
|
81
|
+
//! \}
|
82
|
+
};
|
83
|
+
|
84
|
+
//! \}
|
85
|
+
|
86
|
+
ASMJIT_END_NAMESPACE
|
87
|
+
|
88
|
+
#endif
|
89
|
+
#endif
|
@@ -0,0 +1,69 @@
|
|
1
|
+
// This file is part of AsmJit project <https://asmjit.com>
|
2
|
+
//
|
3
|
+
// See asmjit.h or LICENSE.md for license and copyright information
|
4
|
+
// SPDX-License-Identifier: Zlib
|
5
|
+
|
6
|
+
#include "../core/api-build_p.h"
|
7
|
+
#ifndef ASMJIT_NO_LOGGING
|
8
|
+
|
9
|
+
#include "../core/logger.h"
|
10
|
+
#include "../core/string.h"
|
11
|
+
#include "../core/support.h"
|
12
|
+
|
13
|
+
ASMJIT_BEGIN_NAMESPACE
|
14
|
+
|
15
|
+
// Logger - Implementation
|
16
|
+
// =======================
|
17
|
+
|
18
|
+
Logger::Logger() noexcept
|
19
|
+
: _options() {}
|
20
|
+
Logger::~Logger() noexcept {}
|
21
|
+
|
22
|
+
Error Logger::logf(const char* fmt, ...) noexcept {
|
23
|
+
Error err;
|
24
|
+
va_list ap;
|
25
|
+
|
26
|
+
va_start(ap, fmt);
|
27
|
+
err = logv(fmt, ap);
|
28
|
+
va_end(ap);
|
29
|
+
|
30
|
+
return err;
|
31
|
+
}
|
32
|
+
|
33
|
+
Error Logger::logv(const char* fmt, va_list ap) noexcept {
|
34
|
+
StringTmp<2048> sb;
|
35
|
+
ASMJIT_PROPAGATE(sb.appendVFormat(fmt, ap));
|
36
|
+
return log(sb);
|
37
|
+
}
|
38
|
+
|
39
|
+
// FileLogger - Implementation
|
40
|
+
// ===========================
|
41
|
+
|
42
|
+
FileLogger::FileLogger(FILE* file) noexcept
|
43
|
+
: _file(file) {}
|
44
|
+
FileLogger::~FileLogger() noexcept {}
|
45
|
+
|
46
|
+
Error FileLogger::_log(const char* data, size_t size) noexcept {
|
47
|
+
if (!_file)
|
48
|
+
return kErrorOk;
|
49
|
+
|
50
|
+
if (size == SIZE_MAX)
|
51
|
+
size = strlen(data);
|
52
|
+
|
53
|
+
fwrite(data, 1, size, _file);
|
54
|
+
return kErrorOk;
|
55
|
+
}
|
56
|
+
|
57
|
+
// StringLogger - Implementation
|
58
|
+
// =============================
|
59
|
+
|
60
|
+
StringLogger::StringLogger() noexcept {}
|
61
|
+
StringLogger::~StringLogger() noexcept {}
|
62
|
+
|
63
|
+
Error StringLogger::_log(const char* data, size_t size) noexcept {
|
64
|
+
return _content.append(data, size);
|
65
|
+
}
|
66
|
+
|
67
|
+
ASMJIT_END_NAMESPACE
|
68
|
+
|
69
|
+
#endif
|
@@ -0,0 +1,198 @@
|
|
1
|
+
// This file is part of AsmJit project <https://asmjit.com>
|
2
|
+
//
|
3
|
+
// See asmjit.h or LICENSE.md for license and copyright information
|
4
|
+
// SPDX-License-Identifier: Zlib
|
5
|
+
|
6
|
+
#ifndef ASMJIT_CORE_LOGGING_H_INCLUDED
|
7
|
+
#define ASMJIT_CORE_LOGGING_H_INCLUDED
|
8
|
+
|
9
|
+
#include "../core/inst.h"
|
10
|
+
#include "../core/string.h"
|
11
|
+
#include "../core/formatter.h"
|
12
|
+
|
13
|
+
#ifndef ASMJIT_NO_LOGGING
|
14
|
+
|
15
|
+
ASMJIT_BEGIN_NAMESPACE
|
16
|
+
|
17
|
+
//! \addtogroup asmjit_logging
|
18
|
+
//! \{
|
19
|
+
|
20
|
+
//! Logging interface.
|
21
|
+
//!
|
22
|
+
//! This class can be inherited and reimplemented to fit into your own logging needs. When reimplementing a logger
|
23
|
+
//! use \ref Logger::_log() method to log customize the output.
|
24
|
+
//!
|
25
|
+
//! There are two `Logger` implementations offered by AsmJit:
|
26
|
+
//! - \ref FileLogger - logs into a `FILE*`.
|
27
|
+
//! - \ref StringLogger - concatenates all logs into a \ref String.
|
28
|
+
class ASMJIT_VIRTAPI Logger {
|
29
|
+
public:
|
30
|
+
ASMJIT_BASE_CLASS(Logger)
|
31
|
+
ASMJIT_NONCOPYABLE(Logger)
|
32
|
+
|
33
|
+
//! Format options.
|
34
|
+
FormatOptions _options;
|
35
|
+
|
36
|
+
//! \name Construction & Destruction
|
37
|
+
//! \{
|
38
|
+
|
39
|
+
//! Creates a `Logger` instance.
|
40
|
+
ASMJIT_API Logger() noexcept;
|
41
|
+
//! Destroys the `Logger` instance.
|
42
|
+
ASMJIT_API virtual ~Logger() noexcept;
|
43
|
+
|
44
|
+
//! \}
|
45
|
+
|
46
|
+
//! \name Format Options
|
47
|
+
//! \{
|
48
|
+
|
49
|
+
//! Returns \ref FormatOptions of this logger.
|
50
|
+
inline FormatOptions& options() noexcept { return _options; }
|
51
|
+
//! \overload
|
52
|
+
inline const FormatOptions& options() const noexcept { return _options; }
|
53
|
+
//! Sets formatting options of this Logger to `options`.
|
54
|
+
inline void setOptions(const FormatOptions& options) noexcept { _options = options; }
|
55
|
+
//! Resets formatting options of this Logger to defaults.
|
56
|
+
inline void resetOptions() noexcept { _options.reset(); }
|
57
|
+
|
58
|
+
//! Returns formatting flags.
|
59
|
+
inline FormatFlags flags() const noexcept { return _options.flags(); }
|
60
|
+
//! Tests whether the logger has the given `flag` enabled.
|
61
|
+
inline bool hasFlag(FormatFlags flag) const noexcept { return _options.hasFlag(flag); }
|
62
|
+
//! Sets formatting flags to `flags`.
|
63
|
+
inline void setFlags(FormatFlags flags) noexcept { _options.setFlags(flags); }
|
64
|
+
//! Enables the given formatting `flags`.
|
65
|
+
inline void addFlags(FormatFlags flags) noexcept { _options.addFlags(flags); }
|
66
|
+
//! Disables the given formatting `flags`.
|
67
|
+
inline void clearFlags(FormatFlags flags) noexcept { _options.clearFlags(flags); }
|
68
|
+
|
69
|
+
//! Returns indentation of a given indentation `group`.
|
70
|
+
inline uint32_t indentation(FormatIndentationGroup type) const noexcept { return _options.indentation(type); }
|
71
|
+
//! Sets indentation of the given indentation `group` to `n` spaces.
|
72
|
+
inline void setIndentation(FormatIndentationGroup type, uint32_t n) noexcept { _options.setIndentation(type, n); }
|
73
|
+
//! Resets indentation of the given indentation `group` to 0 spaces.
|
74
|
+
inline void resetIndentation(FormatIndentationGroup type) noexcept { _options.resetIndentation(type); }
|
75
|
+
|
76
|
+
//! Returns padding of a given padding `group`.
|
77
|
+
inline size_t padding(FormatPaddingGroup type) const noexcept { return _options.padding(type); }
|
78
|
+
//! Sets padding of a given padding `group` to `n`.
|
79
|
+
inline void setPadding(FormatPaddingGroup type, uint32_t n) noexcept { _options.setPadding(type, n); }
|
80
|
+
//! Resets padding of a given padding `group` to 0, which means that a default will be used.
|
81
|
+
inline void resetPadding(FormatPaddingGroup type) noexcept { _options.resetPadding(type); }
|
82
|
+
|
83
|
+
//! \}
|
84
|
+
|
85
|
+
//! \name Logging Interface
|
86
|
+
//! \{
|
87
|
+
|
88
|
+
//! Logs `str` - must be reimplemented.
|
89
|
+
//!
|
90
|
+
//! The function can accept either a null terminated string if `size` is `SIZE_MAX` or a non-null terminated
|
91
|
+
//! string of the given `size`. The function cannot assume that the data is null terminated and must handle
|
92
|
+
//! non-null terminated inputs.
|
93
|
+
virtual Error _log(const char* data, size_t size) noexcept = 0;
|
94
|
+
|
95
|
+
//! Logs string `str`, which is either null terminated or having size `size`.
|
96
|
+
inline Error log(const char* data, size_t size = SIZE_MAX) noexcept { return _log(data, size); }
|
97
|
+
//! Logs content of a string `str`.
|
98
|
+
inline Error log(const String& str) noexcept { return _log(str.data(), str.size()); }
|
99
|
+
|
100
|
+
//! Formats the message by using `snprintf()` and then passes the formatted string to \ref _log().
|
101
|
+
ASMJIT_API Error logf(const char* fmt, ...) noexcept;
|
102
|
+
|
103
|
+
//! Formats the message by using `vsnprintf()` and then passes the formatted string to \ref _log().
|
104
|
+
ASMJIT_API Error logv(const char* fmt, va_list ap) noexcept;
|
105
|
+
|
106
|
+
//! \}
|
107
|
+
};
|
108
|
+
|
109
|
+
//! Logger that can log to a `FILE*`.
|
110
|
+
class ASMJIT_VIRTAPI FileLogger : public Logger {
|
111
|
+
public:
|
112
|
+
ASMJIT_NONCOPYABLE(FileLogger)
|
113
|
+
|
114
|
+
FILE* _file;
|
115
|
+
|
116
|
+
//! \name Construction & Destruction
|
117
|
+
//! \{
|
118
|
+
|
119
|
+
//! Creates a new `FileLogger` that logs to `FILE*`.
|
120
|
+
ASMJIT_API FileLogger(FILE* file = nullptr) noexcept;
|
121
|
+
//! Destroys the `FileLogger`.
|
122
|
+
ASMJIT_API virtual ~FileLogger() noexcept;
|
123
|
+
|
124
|
+
//! \}
|
125
|
+
|
126
|
+
//! \name Accessors
|
127
|
+
//! \{
|
128
|
+
|
129
|
+
//! Returns the logging output stream or null if the logger has no output stream.
|
130
|
+
inline FILE* file() const noexcept { return _file; }
|
131
|
+
|
132
|
+
//! Sets the logging output stream to `stream` or null.
|
133
|
+
//!
|
134
|
+
//! \note If the `file` is null the logging will be disabled. When a logger is attached to `CodeHolder` or any
|
135
|
+
//! emitter the logging API will always be called regardless of the output file. This means that if you really
|
136
|
+
//! want to disable logging at emitter level you must not attach a logger to it.
|
137
|
+
inline void setFile(FILE* file) noexcept { _file = file; }
|
138
|
+
|
139
|
+
//! \}
|
140
|
+
|
141
|
+
ASMJIT_API Error _log(const char* data, size_t size = SIZE_MAX) noexcept override;
|
142
|
+
};
|
143
|
+
|
144
|
+
//! Logger that stores everything in an internal string buffer.
|
145
|
+
class ASMJIT_VIRTAPI StringLogger : public Logger {
|
146
|
+
public:
|
147
|
+
ASMJIT_NONCOPYABLE(StringLogger)
|
148
|
+
|
149
|
+
//! Logger data as string.
|
150
|
+
String _content;
|
151
|
+
|
152
|
+
//! \name Construction & Destruction
|
153
|
+
//! \{
|
154
|
+
|
155
|
+
//! Create new `StringLogger`.
|
156
|
+
ASMJIT_API StringLogger() noexcept;
|
157
|
+
//! Destroys the `StringLogger`.
|
158
|
+
ASMJIT_API virtual ~StringLogger() noexcept;
|
159
|
+
|
160
|
+
//! \}
|
161
|
+
|
162
|
+
//! \name Logger Data Accessors
|
163
|
+
//! \{
|
164
|
+
|
165
|
+
//! Returns the content of the logger as \ref String.
|
166
|
+
//!
|
167
|
+
//! It can be moved, if desired.
|
168
|
+
inline String& content() noexcept { return _content; }
|
169
|
+
//! \overload
|
170
|
+
inline const String& content() const noexcept { return _content; }
|
171
|
+
|
172
|
+
//! Returns aggregated logger data as `char*` pointer.
|
173
|
+
//!
|
174
|
+
//! The pointer is owned by `StringLogger`, it can't be modified or freed.
|
175
|
+
inline const char* data() const noexcept { return _content.data(); }
|
176
|
+
//! Returns size of the data returned by `data()`.
|
177
|
+
inline size_t dataSize() const noexcept { return _content.size(); }
|
178
|
+
|
179
|
+
//! \}
|
180
|
+
|
181
|
+
//! \name Logger Data Manipulation
|
182
|
+
//! \{
|
183
|
+
|
184
|
+
//! Clears the accumulated logger data.
|
185
|
+
inline void clear() noexcept { _content.clear(); }
|
186
|
+
|
187
|
+
//! \}
|
188
|
+
|
189
|
+
ASMJIT_API Error _log(const char* data, size_t size = SIZE_MAX) noexcept override;
|
190
|
+
};
|
191
|
+
|
192
|
+
//! \}
|
193
|
+
|
194
|
+
ASMJIT_END_NAMESPACE
|
195
|
+
|
196
|
+
#endif
|
197
|
+
|
198
|
+
#endif // ASMJIT_CORE_LOGGER_H_INCLUDED
|