aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/gopkg.in/olebedev/go-duktape.v3/duk_alloc_pool.h
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2017-12-21 19:56:11 +0800
committerGitHub <noreply@github.com>2017-12-21 19:56:11 +0800
commit5258785c81959109138ebeca613f12c277188abc (patch)
treeb3d21fc2f38927841f44541a3717b69f5a3c5ec1 /vendor/gopkg.in/olebedev/go-duktape.v3/duk_alloc_pool.h
parent1a5425779b026587e36f5d21a6e50efe17cc6a9d (diff)
downloadgo-tangerine-5258785c81959109138ebeca613f12c277188abc.tar
go-tangerine-5258785c81959109138ebeca613f12c277188abc.tar.gz
go-tangerine-5258785c81959109138ebeca613f12c277188abc.tar.bz2
go-tangerine-5258785c81959109138ebeca613f12c277188abc.tar.lz
go-tangerine-5258785c81959109138ebeca613f12c277188abc.tar.xz
go-tangerine-5258785c81959109138ebeca613f12c277188abc.tar.zst
go-tangerine-5258785c81959109138ebeca613f12c277188abc.zip
cmd, core, eth/tracers: support fancier js tracing (#15516)
* cmd, core, eth/tracers: support fancier js tracing * eth, internal/web3ext: rework trace API, concurrency, chain tracing * eth/tracers: add three more JavaScript tracers * eth/tracers, vendor: swap ottovm to duktape for tracing * core, eth, internal: finalize call tracer and needed extras * eth, tests: prestate tracer, call test suite, rewinding * vendor: fix windows builds for tracer js engine * vendor: temporary duktape fix * eth/tracers: fix up 4byte and evmdis tracer * vendor: pull in latest duktape with my upstream fixes * eth: fix some review comments * eth: rename rewind to reexec to make it more obvious * core/vm: terminate tracing using defers
Diffstat (limited to 'vendor/gopkg.in/olebedev/go-duktape.v3/duk_alloc_pool.h')
-rwxr-xr-xvendor/gopkg.in/olebedev/go-duktape.v3/duk_alloc_pool.h223
1 files changed, 223 insertions, 0 deletions
diff --git a/vendor/gopkg.in/olebedev/go-duktape.v3/duk_alloc_pool.h b/vendor/gopkg.in/olebedev/go-duktape.v3/duk_alloc_pool.h
new file mode 100755
index 000000000..286ec0166
--- /dev/null
+++ b/vendor/gopkg.in/olebedev/go-duktape.v3/duk_alloc_pool.h
@@ -0,0 +1,223 @@
+#if !defined(DUK_ALLOC_POOL_H_INCLUDED)
+#define DUK_ALLOC_POOL_H_INCLUDED
+
+#include "duktape.h"
+
+/* 32-bit (big endian) marker used at the end of pool entries so that wasted
+ * space can be detected. Waste tracking must be enabled explicitly.
+ */
+#if defined(DUK_ALLOC_POOL_TRACK_WASTE)
+#define DUK_ALLOC_POOL_WASTE_MARKER 0xedcb2345UL
+#endif
+
+/* Pointer compression with ROM strings/objects:
+ *
+ * For now, use DUK_USE_ROM_OBJECTS to signal the need for compressed ROM
+ * pointers. DUK_USE_ROM_PTRCOMP_FIRST is provided for the ROM pointer
+ * compression range minimum to avoid duplication in user code.
+ */
+#if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16)
+#define DUK_ALLOC_POOL_ROMPTR_COMPRESSION
+#define DUK_ALLOC_POOL_ROMPTR_FIRST DUK_USE_ROM_PTRCOMP_FIRST
+
+/* This extern declaration is provided by duktape.h, array provided by duktape.c.
+ * Because duk_config.h may include this file (to get the inline functions) we
+ * need to forward declare this also here.
+ */
+extern const void * const duk_rom_compressed_pointers[];
+#endif
+
+/* Pool configuration for a certain block size. */
+typedef struct {
+ unsigned int size; /* must be divisible by 4 and >= sizeof(void *) */
+ unsigned int a; /* bytes (not count) to allocate: a*t + b, t is an arbitrary scale parameter */
+ unsigned int b;
+} duk_pool_config;
+
+/* Freelist entry, must fit into the smallest block size. */
+struct duk_pool_free;
+typedef struct duk_pool_free duk_pool_free;
+struct duk_pool_free {
+ duk_pool_free *next;
+};
+
+/* Pool state for a certain block size. */
+typedef struct {
+ duk_pool_free *first;
+ char *alloc_end;
+ unsigned int size;
+ unsigned int count;
+#if defined(DUK_ALLOC_POOL_TRACK_HIGHWATER)
+ unsigned int hwm_used_count;
+#endif
+} duk_pool_state;
+
+/* Statistics for a certain pool. */
+typedef struct {
+ size_t used_count;
+ size_t used_bytes;
+ size_t free_count;
+ size_t free_bytes;
+ size_t waste_bytes;
+ size_t hwm_used_count;
+} duk_pool_stats;
+
+/* Top level state for all pools. Pointer to this struct is used as the allocator
+ * userdata pointer.
+ */
+typedef struct {
+ int num_pools;
+ duk_pool_state *states;
+#if defined(DUK_ALLOC_POOL_TRACK_HIGHWATER)
+ size_t hwm_used_bytes;
+ size_t hwm_waste_bytes;
+#endif
+} duk_pool_global;
+
+/* Statistics for the entire set of pools. */
+typedef struct {
+ size_t used_bytes;
+ size_t free_bytes;
+ size_t waste_bytes;
+ size_t hwm_used_bytes;
+ size_t hwm_waste_bytes;
+} duk_pool_global_stats;
+
+/* Initialize a pool allocator, arguments:
+ * - buffer and size: continuous region to use for pool, must align to 4
+ * - config: configuration for pools in ascending block size
+ * - state: state for pools, matches config order
+ * - num_pools: number of entries in 'config' and 'state'
+ * - global: global state structure
+ *
+ * The 'config', 'state', and 'global' pointers must be valid beyond the init
+ * call, as long as the pool is used.
+ *
+ * Returns a void pointer to be used as userdata for the allocator functions.
+ * Concretely the return value will be "(void *) global", i.e. the global
+ * state struct. If pool init fails, the return value will be NULL.
+ */
+void *duk_alloc_pool_init(char *buffer,
+ size_t size,
+ const duk_pool_config *configs,
+ duk_pool_state *states,
+ int num_pools,
+ duk_pool_global *global);
+
+/* Duktape allocation providers. Typing matches Duktape requirements. */
+void *duk_alloc_pool(void *udata, duk_size_t size);
+void *duk_realloc_pool(void *udata, void *ptr, duk_size_t size);
+void duk_free_pool(void *udata, void *ptr);
+
+/* Stats. */
+void duk_alloc_pool_get_pool_stats(duk_pool_state *s, duk_pool_stats *res);
+void duk_alloc_pool_get_global_stats(duk_pool_global *g, duk_pool_global_stats *res);
+
+/* Duktape pointer compression global state (assumes single pool). */
+#if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16)
+extern const void *duk_alloc_pool_romptr_low;
+extern const void *duk_alloc_pool_romptr_high;
+duk_uint16_t duk_alloc_pool_enc16_rom(void *ptr);
+#endif
+#if defined(DUK_USE_HEAPPTR16)
+extern void *duk_alloc_pool_ptrcomp_base;
+#endif
+
+#if 0
+duk_uint16_t duk_alloc_pool_enc16(void *ptr);
+void *duk_alloc_pool_dec16(duk_uint16_t val);
+#endif
+
+/* Inlined pointer compression functions. Gcc and clang -Os won't in
+ * practice inline these without an "always inline" attribute because it's
+ * more size efficient (by a few kB) to use explicit calls instead. Having
+ * these defined inline here allows performance optimized builds to inline
+ * pointer compression operations.
+ *
+ * Pointer compression assumes there's a single globally registered memory
+ * pool which makes pointer compression more efficient. This would be easy
+ * to fix by adding a userdata pointer to the compression functions and
+ * plumbing the heap userdata from the compression/decompression macros.
+ */
+
+/* DUK_ALWAYS_INLINE is not a public API symbol so it may go away in even a
+ * minor update. But it's pragmatic for this extra because it handles many
+ * compilers via duk_config.h detection. Check that the macro exists so that
+ * if it's gone, we can still compile.
+ */
+#if defined(DUK_ALWAYS_INLINE)
+#define DUK__ALLOC_POOL_ALWAYS_INLINE DUK_ALWAYS_INLINE
+#else
+#define DUK__ALLOC_POOL_ALWAYS_INLINE /* nop */
+#endif
+
+#if defined(DUK_USE_HEAPPTR16)
+static DUK__ALLOC_POOL_ALWAYS_INLINE duk_uint16_t duk_alloc_pool_enc16(void *ptr) {
+ if (ptr == NULL) {
+ /* With 'return 0' gcc and clang -Os generate inefficient code.
+ * For example, gcc -Os generates:
+ *
+ * 0804911d <duk_alloc_pool_enc16>:
+ * 804911d: 55 push %ebp
+ * 804911e: 85 c0 test %eax,%eax
+ * 8049120: 89 e5 mov %esp,%ebp
+ * 8049122: 74 0b je 804912f <duk_alloc_pool_enc16+0x12>
+ * 8049124: 2b 05 e4 90 07 08 sub 0x80790e4,%eax
+ * 804912a: c1 e8 02 shr $0x2,%eax
+ * 804912d: eb 02 jmp 8049131 <duk_alloc_pool_enc16+0x14>
+ * 804912f: 31 c0 xor %eax,%eax
+ * 8049131: 5d pop %ebp
+ * 8049132: c3 ret
+ *
+ * The NULL path checks %eax for zero; if it is zero, a zero
+ * is unnecessarily loaded into %eax again. The non-zero path
+ * has an unnecessary jump as a side effect of this.
+ *
+ * Using 'return (duk_uint16_t) (intptr_t) ptr;' generates similarly
+ * inefficient code; not sure how to make the result better.
+ */
+ return 0;
+ }
+#if defined(DUK_ALLOC_POOL_ROMPTR_COMPRESSION)
+ if (ptr >= duk_alloc_pool_romptr_low && ptr <= duk_alloc_pool_romptr_high) {
+ /* This is complex enough now to need a separate function. */
+ return duk_alloc_pool_enc16_rom(ptr);
+ }
+#endif
+ return (duk_uint16_t) (((size_t) ((char *) ptr - (char *) duk_alloc_pool_ptrcomp_base)) >> 2);
+}
+
+static DUK__ALLOC_POOL_ALWAYS_INLINE void *duk_alloc_pool_dec16(duk_uint16_t val) {
+ if (val == 0) {
+ /* As with enc16 the gcc and clang -Os output is inefficient,
+ * e.g. gcc -Os:
+ *
+ * 08049133 <duk_alloc_pool_dec16>:
+ * 8049133: 55 push %ebp
+ * 8049134: 66 85 c0 test %ax,%ax
+ * 8049137: 89 e5 mov %esp,%ebp
+ * 8049139: 74 0e je 8049149 <duk_alloc_pool_dec16+0x16>
+ * 804913b: 8b 15 e4 90 07 08 mov 0x80790e4,%edx
+ * 8049141: 0f b7 c0 movzwl %ax,%eax
+ * 8049144: 8d 04 82 lea (%edx,%eax,4),%eax
+ * 8049147: eb 02 jmp 804914b <duk_alloc_pool_dec16+0x18>
+ * 8049149: 31 c0 xor %eax,%eax
+ * 804914b: 5d pop %ebp
+ * 804914c: c3 ret
+ */
+ return NULL;
+ }
+#if defined(DUK_ALLOC_POOL_ROMPTR_COMPRESSION)
+ if (val >= DUK_ALLOC_POOL_ROMPTR_FIRST) {
+ /* This is a blind lookup, could check index validity.
+ * Duktape should never decompress a pointer which would
+ * be out-of-bounds here.
+ */
+ return (void *) (intptr_t) (duk_rom_compressed_pointers[val - DUK_ALLOC_POOL_ROMPTR_FIRST]);
+ }
+#endif
+ return (void *) ((char *) duk_alloc_pool_ptrcomp_base + (((size_t) val) << 2));
+}
+#endif
+
+#endif /* DUK_ALLOC_POOL_H_INCLUDED */