Skip to content
This repository was archived by the owner on Apr 16, 2025. It is now read-only.

Expose pool allocation config in the C++ API #68

Merged
merged 2 commits into from
Apr 1, 2025
Merged
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
200 changes: 200 additions & 0 deletions include/wasmtime.hh
Original file line number Diff line number Diff line change
@@ -257,6 +257,199 @@ enum class ProfilingStrategy {
Vtune = WASMTIME_PROFILING_STRATEGY_VTUNE,
};

/**
* \brief Pool allocation configuration for Wasmtime.
*
* For more information be sure to consult the [rust
* documentation](https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html).
*/
class PoolAllocationConfig {
friend class Config;

struct deleter {
void operator()(wasmtime_pooling_allocation_config_t *p) const {
wasmtime_pooling_allocation_config_delete(p);
}
};

std::unique_ptr<wasmtime_pooling_allocation_config_t, deleter> ptr;

public:
PoolAllocationConfig() : ptr(wasmtime_pooling_allocation_config_new()) {}

/// \brief Configures the maximum number of “unused warm slots” to retain in
/// the pooling allocator.
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_unused_warm_slots.
void max_unused_warm_slots(uint32_t max) {
wasmtime_pooling_allocation_config_max_unused_warm_slots_set(ptr.get(),
max);
}

/// \brief The target number of decommits to do per batch.
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.decommit_batch_size.
void decommit_batch_size(size_t batch_size) {
wasmtime_pooling_allocation_config_decommit_batch_size_set(ptr.get(),
batch_size);
}

/// \brief How much memory, in bytes, to keep resident for async stacks
/// allocated with the pooling allocator.
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.async_stack_keep_resident.
void async_stack_keep_resident(size_t size) {
wasmtime_pooling_allocation_config_async_stack_keep_resident_set(ptr.get(),
size);
}

/// \brief How much memory, in bytes, to keep resident for each linear memory
/// after deallocation.
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.linear_memory_keep_resident.
void linear_memory_keep_resident(size_t size) {
wasmtime_pooling_allocation_config_linear_memory_keep_resident_set(
ptr.get(), size);
}

/// \brief How much memory, in bytes, to keep resident for each table after
/// deallocation.
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.table_keep_resident.
void table_keep_resident(size_t size) {
wasmtime_pooling_allocation_config_table_keep_resident_set(ptr.get(), size);
}

/// \brief The maximum number of concurrent component instances supported
/// (default is 1000).
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.total_component_instances.
void total_component_instances(uint32_t count) {
wasmtime_pooling_allocation_config_total_component_instances_set(ptr.get(),
count);
}

/// \brief The maximum size, in bytes, allocated for a component instance’s
/// VMComponentContext metadata.
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_component_instance_size.
void max_component_instance_size(size_t size) {
wasmtime_pooling_allocation_config_max_component_instance_size_set(
ptr.get(), size);
}

/// \brief The maximum number of core instances a single component may contain
/// (default is unlimited).
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_core_instances_per_component.
void max_core_instances_per_component(uint32_t count) {
wasmtime_pooling_allocation_config_max_core_instances_per_component_set(
ptr.get(), count);
}

/// \brief The maximum number of Wasm linear memories that a single component
/// may transitively contain (default is unlimited).
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_memories_per_component.
void max_memories_per_component(uint32_t count) {
wasmtime_pooling_allocation_config_max_memories_per_component_set(ptr.get(),
count);
}

/// \brief The maximum number of tables that a single component may
/// transitively contain (default is unlimited).
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_tables_per_component.
void max_tables_per_component(uint32_t count) {
wasmtime_pooling_allocation_config_max_tables_per_component_set(ptr.get(),
count);
}

/// \brief The maximum number of concurrent Wasm linear memories supported
/// (default is 1000).
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.total_memories.
void total_memories(uint32_t count) {
wasmtime_pooling_allocation_config_total_memories_set(ptr.get(), count);
}

/// \brief The maximum number of concurrent tables supported (default is
/// 1000).
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.total_tables.
void total_tables(uint32_t count) {
wasmtime_pooling_allocation_config_total_tables_set(ptr.get(), count);
}

/// \brief The maximum number of execution stacks allowed for asynchronous
/// execution, when enabled (default is 1000).
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.total_stacks.
void total_stacks(uint32_t count) {
wasmtime_pooling_allocation_config_total_stacks_set(ptr.get(), count);
}

/// \brief The maximum number of concurrent core instances supported (default
/// is 1000).
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.total_core_instances.
void total_core_instances(uint32_t count) {
wasmtime_pooling_allocation_config_total_core_instances_set(ptr.get(),
count);
}

/// \brief The maximum size, in bytes, allocated for a core instance’s
/// VMContext metadata.
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_core_instance_size.
void max_core_instance_size(size_t size) {
wasmtime_pooling_allocation_config_max_core_instance_size_set(ptr.get(),
size);
}

/// \brief The maximum number of defined tables for a core module (default is
/// 1).
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_tables_per_module.
void max_tables_per_module(uint32_t tables) {
wasmtime_pooling_allocation_config_max_tables_per_module_set(ptr.get(),
tables);
}

/// \brief The maximum table elements for any table defined in a module
/// (default is 20000).
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.table_elements.
void table_elements(size_t elements) {
wasmtime_pooling_allocation_config_table_elements_set(ptr.get(), elements);
}

/// \brief The maximum number of defined linear memories for a module (default
/// is 1).
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_memories_per_module.
void max_memories_per_module(uint32_t memories) {
wasmtime_pooling_allocation_config_max_memories_per_module_set(ptr.get(),
memories);
}

/// \brief The maximum byte size that any WebAssembly linear memory may grow
/// to.
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.max_memory_size.
void max_memory_size(size_t bytes) {
wasmtime_pooling_allocation_config_max_memory_size_set(ptr.get(), bytes);
}

/// \brief The maximum number of concurrent GC heaps supported (default is
/// 1000).
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.PoolingAllocationConfig.html#method.total_gc_heaps.
void total_gc_heaps(uint32_t count) {
wasmtime_pooling_allocation_config_total_gc_heaps_set(ptr.get(), count);
}
};

/**
* \brief Configuration for Wasmtime.
*
@@ -433,6 +626,13 @@ public:
}
return std::monostate();
}

/// \brief Enables and configures the pooling allocation strategy.
///
/// https://docs.wasmtime.dev/api/wasmtime/struct.Config.html#method.allocation_strategy
void pooling_allocation_strategy(const PoolAllocationConfig &config) {
wasmtime_pooling_allocation_strategy_set(ptr.get(), config.ptr.get());
}
};

/**
30 changes: 30 additions & 0 deletions tests/simple.cc
Original file line number Diff line number Diff line change
@@ -31,6 +31,33 @@ TEST(Engine, Smoke) {
engine = Engine(std::move(config));
}

TEST(PoolAllocationConfig, Smoke) {
PoolAllocationConfig config;
config.max_unused_warm_slots(1);
config.decommit_batch_size(2);
config.async_stack_keep_resident(3);
config.linear_memory_keep_resident(4);
config.table_keep_resident(5);
config.total_component_instances(6);
config.max_component_instance_size(7);
config.max_core_instances_per_component(8);
config.max_memories_per_component(9);
config.max_tables_per_component(10);
config.total_memories(11);
config.total_tables(12);
config.total_stacks(13);
config.total_core_instances(14);
config.max_core_instance_size(15);
config.max_tables_per_module(16);
config.table_elements(17);
config.max_memories_per_module(18);
config.max_memory_size(19);
config.total_gc_heaps(20);

PoolAllocationConfig config2 = std::move(config);
PoolAllocationConfig config3(std::move(config));
}

TEST(Config, Smoke) {
Config config;
config.debug_info(false);
@@ -51,6 +78,9 @@ TEST(Config, Smoke) {
auto result = config.cache_load_default();
config.cache_load("nonexistent").err();

PoolAllocationConfig pooling_config;
config.pooling_allocation_strategy(pooling_config);

Config config2 = std::move(config);
Config config3(std::move(config));
}