Skip to content

Commit f736faf

Browse files
committed
Update RFC to remove InstanceAllocator from the wasmtime crate.
Remove the `InstanceAllocator` trait and the `DefaultInstanceAllocator` struct from the `wasmtime` crate. Add the `InstanceAllocationStrategy` enum and update the related `Config` method.
1 parent 183e1e4 commit f736faf

File tree

1 file changed

+41
-75
lines changed

1 file changed

+41
-75
lines changed

accepted/wasmtime-instance-allocator.md

Lines changed: 41 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -238,12 +238,12 @@ impl Default for PoolingLimits { ... }
238238

239239
The values in this structure will ultimately determine how much total address space gets reserved by the pooling instance allocator in advance.
240240

241-
### The `PoolingAllocStrategy` enum
241+
### The `PoolingAllocationStrategy` enum
242242

243243
```rust
244244
/// The allocation strategy to use for the pooling instance allocator.
245245
#[derive(Clone)]
246-
pub enum PoolingAllocStrategy {
246+
pub enum PoolingAllocationStrategy {
247247
/// Allocate from the next available instance.
248248
NextAvailable,
249249
/// Allocate from a random available instance.
@@ -265,7 +265,7 @@ pub struct PoolingInstanceAllocator { ... }
265265

266266
impl PoolingInstanceAllocator {
267267
/// Creates a new pooling instance allocator with the given strategy and limits.
268-
pub fn new(strategy: PoolingAllocStrategy, limits: PoolingLimits) -> Result<Self>;
268+
pub fn new(strategy: PoolingAllocationStrategy, limits: PoolingLimits) -> Result<Self>;
269269
}
270270

271271
impl InstanceAllocator for PoolingInstanceAllocator { ... }
@@ -287,12 +287,6 @@ Page faults will be handled according to where they occur in the memory managed
287287

288288
Implementations for other platforms, such as Windows, might be required in the future.
289289

290-
### The `InstanceHandle` struct
291-
292-
The existing `InstanceHandle` structure will be modified to notify the allocator when an instance is deallocated via `InstanceHandle::dealloc`.
293-
294-
This will enable the pooling allocator to "free" the instance by adding it (and its associated resources) to a free list rather than actually deallocating any memory.
295-
296290
### The `Instance` struct
297291

298292
To minimize allocations, `Instance` will be modified to use `Vec` instead of boxed slices for storing the instance's lists of memories and tables. This will allow the pooling allocator to reuse capacity from previous instance allocations as needed.
@@ -305,101 +299,73 @@ Additional changes are required to enable storing the instance's tables in the m
305299

306300
## Changes to the `wasmtime` crate
307301

308-
### The `InstanceAllocator` trait
309-
310-
This trait is nearly identical to the trait in the runtime, except it only uses public Wasmtime API types:
311-
312-
```rust
313-
// Represents an instance allocator.
314-
pub trait InstanceAllocator: Send + Sync {
315-
/// Allocates an instance for the given module.
316-
fn allocate(
317-
&self,
318-
store: &Store,
319-
module: &Module,
320-
imports: &[Extern],
321-
) -> Result<Instance>;
322-
}
323-
```
324-
325-
Note that here `Instance` is the public type from the `wasmtime` crate.
326-
327-
### The `DefaultInstanceAllocator` struct
328-
329-
This struct is nearly identical to the struct of the same name in the runtime, except it only uses public Wasmtime API types:
330-
331-
```rust
332-
// Represents the default instance allocator.
333-
pub struct DefaultInstanceAllocator { ... }
334-
335-
impl DefaultInstanceAllocator {
336-
/// Creates a new default instance allocator.
337-
pub fn new(mem_creator: Option<Arc<dyn MemoryCreator>>) -> Self {
338-
}
339-
340-
impl InstanceAllocator for DefaultInstanceAllocator { ... }
341-
```
342-
343-
The implementation of this type will wrap the runtime's default instance allocator and perform the necessary translation from the public Wasmtime API types to the runtime types.
344-
345-
### The `PoolingInstanceAllocator` struct
302+
### The `userfault` feature
346303

347-
This struct is nearly identical to the struct of the same name in the runtime, except it only uses public Wasmtime API types:
304+
This feature will forward to the runtime's `userfault` feature to enable userfault handling in the runtime's pooling instance allocator.
348305

306+
### The `InstanceAllocationStrategy` enumeration
349307
```rust
350-
// Represents a pooling instance allocator.
351-
pub struct PoolingInstanceAllocator { ... }
352-
353-
impl PoolingInstanceAllocator {
354-
/// Creates a new pooling instance allocator with the given strategy and limits.
355-
pub fn new(strategy: PoolingAllocStrategy, limits: PoolingLimits) -> Result<Self>;
308+
// Represents the module instance allocation strategy to use.
309+
#[derive(Clone)]
310+
pub enum InstanceAllocationStrategy {
311+
/// The default Wasmtime module instance allocation strategy.
312+
///
313+
/// Resources related to a module instance are allocated at instantiation time and
314+
/// immediately deallocated when the `Store` referencing the instance is dropped.
315+
Default,
316+
/// The pooling instance allocation strategy.
317+
///
318+
/// A pool of resources is created in advance and module instantiation reuses resources
319+
/// from the pool. Resources are returned to the pool when the `Store` referencing the instance
320+
/// is dropped.
321+
Pooling {
322+
/// The allocation strategy to use for the pool's resources.
323+
strategy: PoolingAllocationStrategy,
324+
/// The limits to use for the pool's resources.
325+
limits: PoolingLimits,
326+
},
356327
}
357-
358-
impl InstanceAllocator for PoolingInstanceAllocator { ... }
359328
```
360329

361-
Here `PoolingAllocStrategy` and `PoolingLimits` are re-exports from `wasmtime_runtime`.
362-
363-
The implementation of this type will wrap the runtime's pooling instance allocator and perform the necessary translation from the public Wasmtime API types to the runtime types.
364-
365-
### The `userfault` feature
366-
367-
This feature will forward to the runtime's `userfault` feature to enable userfault handling in the runtime's pooling instance allocator.
368-
369330
### The `Config` struct
370331

371-
This proposal adds the following method to `Config`:
332+
This proposal adds the following method to `Config` for setting the instance allocation strategy to use:
372333

373334
```rust
374-
/// Set the instance allocator to use.
375-
fn with_instance_allocator(&mut self, allocator: Arc<dyn InstanceAllocator>) -> &mut Self;
335+
/// Sets the instance allocation strategy to use.
336+
pub fn with_instance_allocation_strategy(
337+
&mut self,
338+
strategy: InstanceAllocationStrategy,
339+
) -> Result<&mut Self>;
376340
```
377341

342+
All module instances created from the configuration will use the given strategy.
343+
378344
### The `MemoryCreator` trait
379345

380346
Today, users can implement the `MemoryCreator` trait to control how linear memories are allocated when Wasmtime instantiates a module or a user creates a host `Memory` object.
381347

382348
To enable custom host memory management, users call `with_host_memory` on the `Config` used to create an `Engine`. For backwards compatibility, this interface will not change.
383349

384-
However, the `with_host_memory` implementation will change to configure the "default" allocator associated with the configuration. The default allocator will be used for instance creation if `with_instance_allocator` is never called and for instantiation of any host objects (memories, globals, tables, and functions).
350+
Only the default instance allocation strategy will use memory creator for creating linear memories for new module instances.
385351

386-
This allows for host `Memory` objects to use the configured memory creator and also prevents instances created internally by Wasmtime when representing host objects from counting towards any instance allocator limits.
352+
Host `Memory` objects will continue to use the given memory creator for allocating memory.
387353

388354
### Re-exported types
389355

390356
The following types will be re-exported from `wasmtime_runtime`:
391357

392-
* `PoolingAllocStrategy`
358+
* `PoolingAllocationStrategy`
393359
* `PoolingLimits`
394360

395361
## API Example
396362

397363
```rust
398364
let mut config = Config::new();
399-
config.with_instance_allocator(Arc::new(PoolingInstanceAllocator::new(
400-
PoolingAllocStrategy::Random,
401-
PoolingLimits::default(),
402-
)?));
365+
config.with_instance_allocation_strategy(InstanceAllocationStrategy::Pooling {
366+
strategy: PoolingAllocationStrategy::Random,
367+
limits: PoolingLimits::default(),
368+
})?;
403369

404370
let engine = Engine::new(&config);
405371
let module = Module::new(&engine, r#"(module (func (export "run")) )"#);
@@ -424,7 +390,7 @@ Ideally the pooling instance allocator would be split off into its own crate, bu
424390
# Open questions
425391
[open-questions]: #open-questions
426392

427-
* Should the pooling instance allocator implementation be behind a cargo feature?
393+
* Should the pooling instance allocator implementation be behind a cargo feature or in a separate crate?
428394

429395
* The defaults for `PoolingLimits` are inspired by Lucet's default limits. Are these sufficient for general use?
430396

0 commit comments

Comments
 (0)