Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,8 @@ static inline int count_consecutive_shift(rv_insn_t *ir)
}

/* Allocate and rewrite a fused sequence.
* Returns true on success, false on malloc failure (graceful degradation).
* Returns true on success, false on allocation failure (graceful degradation).
* Uses pooled allocation for fuse arrays up to FUSE_MAX_ENTRIES.
*/
static inline bool try_fuse_sequence(riscv_t *rv,
block_t *block,
Expand All @@ -1249,11 +1250,13 @@ static inline bool try_fuse_sequence(riscv_t *rv,
if (count <= 1)
return false;

/* Overflow check for allocation size */
if (unlikely((size_t) count > SIZE_MAX / sizeof(opcode_fuse_t)))
/* Reject sequences exceeding pool slot size - rare case with diminishing
* returns. This also handles the overflow check implicitly.
*/
if (unlikely(count > FUSE_MAX_ENTRIES))
return false;

opcode_fuse_t *fuse_data = malloc((size_t) count * sizeof(opcode_fuse_t));
opcode_fuse_t *fuse_data = mpool_alloc(rv->fuse_mp);
if (unlikely(!fuse_data))
return false;

Expand Down Expand Up @@ -1857,7 +1860,7 @@ static block_t *block_find_or_translate(riscv_t *rv)
next_ir = ir->next;

if (ir->fuse)
free(ir->fuse);
mpool_free(rv->fuse_mp, ir->fuse);

mpool_free(rv->block_ir_mp, ir);
}
Expand Down
13 changes: 12 additions & 1 deletion src/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ void block_map_clear(riscv_t *rv)
rv_insn_t *ir, *next;
for (idx = 0, ir = block->ir_head; idx < block->n_insn;
idx++, ir = next) {
free(ir->fuse);
if (ir->fuse)
mpool_free(rv->fuse_mp, ir->fuse);
free(ir->branch_table);
next = ir->next;
mpool_free(rv->block_ir_mp, ir);
Expand All @@ -88,6 +89,7 @@ static void block_map_destroy(riscv_t *rv)

mpool_destroy(rv->block_mp);
mpool_destroy(rv->block_ir_mp);
mpool_destroy(rv->fuse_mp);
}
#endif

Expand Down Expand Up @@ -825,6 +827,11 @@ riscv_t *rv_create(riscv_user_t rv_attr)
sizeof(block_t));
rv->block_ir_mp = mpool_create(
sizeof(rv_insn_t) << BLOCK_IR_MAP_CAPACITY_BITS, sizeof(rv_insn_t));
/* Fuse pool: fixed-size slots for macro-op fusion arrays.
* Each slot holds up to FUSE_MAX_ENTRIES opcode_fuse_t structures.
*/
rv->fuse_mp = mpool_create(FUSE_SLOT_SIZE << BLOCK_IR_MAP_CAPACITY_BITS,
FUSE_SLOT_SIZE);

#if !RV32_HAS(JIT)
/* initialize the block map */
Expand Down Expand Up @@ -870,6 +877,7 @@ riscv_t *rv_create(riscv_user_t rv_attr)
fail_jit_state:
mpool_destroy(rv->block_ir_mp);
mpool_destroy(rv->block_mp);
mpool_destroy(rv->fuse_mp);
map_delete(attr->fd_map);
memory_delete(attr->mem);
free(rv);
Expand Down Expand Up @@ -992,6 +1000,9 @@ void rv_delete(riscv_t *rv)
#endif
jit_state_exit(rv->jit_state);
cache_free(rv->block_cache);
mpool_destroy(rv->block_ir_mp);
mpool_destroy(rv->block_mp);
mpool_destroy(rv->fuse_mp);
#endif
#if RV32_HAS(SYSTEM_MMIO)
u8250_delete(attr->uart);
Expand Down
8 changes: 7 additions & 1 deletion src/riscv_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@

#define PRIV(x) ((vm_attr_t *) x->data)

/* Maximum entries per fuse slot - limits fusion to 16 consecutive instructions.
* Larger sequences are rare and provide diminishing returns.
*/
#define FUSE_MAX_ENTRIES 16
#define FUSE_SLOT_SIZE (FUSE_MAX_ENTRIES * sizeof(opcode_fuse_t))

/* CSRs */
enum {
/* floating point */
Expand Down Expand Up @@ -258,7 +264,7 @@ struct riscv_internal {
void *jit_state;
void *jit_cache;
#endif
struct mpool *block_mp, *block_ir_mp;
struct mpool *block_mp, *block_ir_mp, *fuse_mp;

#if RV32_HAS(GDBSTUB)
/* gdbstub instance */
Expand Down
Loading