Skip to content

Commit

Permalink
Add RegisterModule
Browse files Browse the repository at this point in the history
Some upstream (Hugo) benchmarks:

```
name                          old time/op    new time/op    delta
KatexStartStop/PoolSize1-10     19.5ms ± 6%    19.4ms ± 3%     ~     (p=1.000 n=4+4)
KatexStartStop/PoolSize8-10      116ms ± 6%      55ms ± 3%  -52.61%  (p=0.029 n=4+4)
KatexStartStop/PoolSize16-10     222ms ± 3%      95ms ± 6%  -57.07%  (p=0.029 n=4+4)

name                          old alloc/op   new alloc/op   delta
KatexStartStop/PoolSize1-10     12.2MB ± 0%    12.2MB ± 0%   -0.22%  (p=0.029 n=4+4)
KatexStartStop/PoolSize8-10     97.9MB ± 0%    73.9MB ± 0%  -24.46%  (p=0.029 n=4+4)
KatexStartStop/PoolSize16-10     196MB ± 0%     148MB ± 0%  -24.15%  (p=0.029 n=4+4)

name                          old allocs/op  new allocs/op  delta
KatexStartStop/PoolSize1-10      18.1k ± 0%     17.4k ± 0%   -3.45%  (p=0.029 n=4+4)
KatexStartStop/PoolSize8-10       144k ± 0%       18k ± 0%  -87.65%  (p=0.029 n=4+4)
KatexStartStop/PoolSize16-10      289k ± 0%       18k ± 0%  -93.67%  (p=0.029 n=4+4)
```

See tetratelabs#2293
  • Loading branch information
bep committed Jul 28, 2024
1 parent 22b92a5 commit 125c42c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 7 deletions.
2 changes: 1 addition & 1 deletion internal/wasm/global_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ func TestPublicModule_Global(t *testing.T) {
s := newStore()
t.Run(tc.name, func(t *testing.T) {
// Instantiate the module and get the export of the above global
module, err := s.Instantiate(context.Background(), tc.module, t.Name(), nil, nil)
module, err := s.Instantiate(context.Background(), tc.module, t.Name(), nil, nil, nil)
require.NoError(t, err)

if global := module.ExportedGlobal("global"); tc.expected != nil {
Expand Down
19 changes: 15 additions & 4 deletions internal/wasm/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,10 @@ func (s *Store) Instantiate(
name string,
sys *internalsys.Context,
typeIDs []FunctionTypeID,
lazyInstansiateImport func(moduleName string) (*ModuleInstance, error),
) (*ModuleInstance, error) {
// Instantiate the module and add it to the store so that other modules can import it.
m, err := s.instantiate(ctx, module, name, sys, typeIDs)
m, err := s.instantiate(ctx, module, name, sys, typeIDs, lazyInstansiateImport)
if err != nil {
return nil, err
}
Expand All @@ -342,6 +343,7 @@ func (s *Store) instantiate(
name string,
sysCtx *internalsys.Context,
typeIDs []FunctionTypeID,
lazyInstansiateImport func(moduleName string) (*ModuleInstance, error),
) (m *ModuleInstance, err error) {
m = &ModuleInstance{ModuleName: name, TypeIDs: typeIDs, Sys: sysCtx, s: s, Source: module}

Expand All @@ -352,7 +354,7 @@ func (s *Store) instantiate(
return nil, err
}

if err = m.resolveImports(module); err != nil {
if err = m.resolveImports(lazyInstansiateImport, module); err != nil {
return nil, err
}

Expand Down Expand Up @@ -410,12 +412,21 @@ func (s *Store) instantiate(
return
}

func (m *ModuleInstance) resolveImports(module *Module) (err error) {
func (m *ModuleInstance) resolveImports(lazyInstansiateImport func(moduleName string) (*ModuleInstance, error), module *Module) (err error) {
for moduleName, imports := range module.ImportPerModule {
var importedModule *ModuleInstance
importedModule, err = m.s.module(moduleName)
if err != nil {
return err
if lazyInstansiateImport != nil {
importedModule, err = lazyInstansiateImport(moduleName)
// Add it to the store's module list so it can be closed.
/*if err = m.s.addToModuleList(importedModule); err != nil {
return
}*/
}
if err != nil {
return err
}
}

for _, i := range imports {
Expand Down
6 changes: 5 additions & 1 deletion internal/wasm/store_module_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,18 @@ func (s *Store) registerModule(m *ModuleInstance) error {

if m.ModuleName != "" {
if _, ok := s.nameToModule[m.ModuleName]; ok {
return fmt.Errorf("module[%s] has already been instantiated", m.ModuleName)
fmt.Errorf("module[%s] has already been instantiated", m.ModuleName)
}
s.nameToModule[m.ModuleName] = m
if len(s.nameToModule) > s.nameToModuleCap {
s.nameToModuleCap = len(s.nameToModule)
}
}

return s.addToModuleList(m)
}

func (s *Store) addToModuleList(m *ModuleInstance) error {
// Add the newest node to the moduleNamesList as the head.
m.next = s.moduleList
if m.next != nil {
Expand Down
34 changes: 33 additions & 1 deletion runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ type Runtime interface {
// and/or compilation.
InstantiateWithConfig(ctx context.Context, source []byte, config ModuleConfig) (api.Module, error)

// TODO1
RegisterModule(ctx context.Context, name string, compiledModule CompiledModule) error

// NewHostModuleBuilder lets you create modules out of functions defined in Go.
//
// Below defines and instantiates a module named "env" with one function:
Expand Down Expand Up @@ -162,6 +165,7 @@ func NewRuntimeWithConfig(ctx context.Context, rConfig RuntimeConfig) Runtime {
return &runtime{
cache: cacheImpl,
store: store,
namedCompiledModules: make(map[string]CompiledModule),
enabledFeatures: config.enabledFeatures,
memoryLimitPages: config.memoryLimitPages,
memoryCapacityFromMax: config.memoryCapacityFromMax,
Expand All @@ -181,6 +185,8 @@ type runtime struct {
dwarfDisabled bool
storeCustomSections bool

namedCompiledModules map[string]CompiledModule

// closed is the pointer used both to guard moduleEngine.CloseWithExitCode and to store the exit code.
//
// The update value is 1 + exitCode << 32. This ensures an exit code of zero isn't mistaken for never closed.
Expand All @@ -192,6 +198,11 @@ type runtime struct {
ensureTermination bool
}

func (r *runtime) RegisterModule(ctx context.Context, name string, compiledModule CompiledModule) error {
r.namedCompiledModules[name] = compiledModule
return nil
}

// Module implements Runtime.Module.
func (r *runtime) Module(moduleName string) api.Module {
if len(moduleName) == 0 {
Expand Down Expand Up @@ -314,8 +325,29 @@ func (r *runtime) InstantiateModule(
name = code.module.NameSection.ModuleName
}

var lazyInsansiateImport func(name string) (*wasm.ModuleInstance, error)
lazyInsansiateImport = func(name string) (*wasm.ModuleInstance, error) {
compiled, found := r.namedCompiledModules[name]
if !found {
return nil, fmt.Errorf("module[%s] not found", name)
}
code := compiled.(*compiledModule)
if sysCtx, err = config.toSysContext(); err != nil {
return nil, err
}

mod, err = r.store.Instantiate(ctx, code.module, name, sysCtx, code.typeIDs, lazyInsansiateImport)
if err != nil {
if code.closeWithModule {
_ = code.Close(ctx) // don't overwrite the error
}
return nil, err
}
return mod.(*wasm.ModuleInstance), nil
}

// Instantiate the module.
mod, err = r.store.Instantiate(ctx, code.module, name, sysCtx, code.typeIDs)
mod, err = r.store.Instantiate(ctx, code.module, name, sysCtx, code.typeIDs, lazyInsansiateImport)
if err != nil {
// If there was an error, don't leak the compiled module.
if code.closeWithModule {
Expand Down

0 comments on commit 125c42c

Please sign in to comment.