Repository: tetratelabs/wazero
Pull request #1271 (2023-03-22 08:56:23)

Removes unnecessary uint64 allocation on callContext


Patch:
diff --git a/internal/wasm/call_context.go b/internal/wasm/call_context.go
index 5a9c74f8..2db75788 100644
--- a/internal/wasm/call_context.go
+++ b/internal/wasm/call_context.go
@@ -15,8 +15,7 @@ import (
 var _ api.Module = &CallContext{}
 
 func NewCallContext(s *Store, instance *ModuleInstance, sys *internalsys.Context) *CallContext {
-	zero := uint64(0)
-	return &CallContext{memory: instance.Memory, module: instance, s: s, Sys: sys, Closed: &zero}
+	return &CallContext{memory: instance.Memory, module: instance, s: s, Sys: sys, Closed: 0}
 }
 
 // CallContext is a function call context bound to a module. This is important as one module's functions can call
@@ -53,7 +52,7 @@ type CallContext struct {
 	//
 	// Note: Exclusively reading and updating this with atomics guarantees cross-goroutine observations.
 	// See /RATIONALE.md
-	Closed *uint64
+	Closed uint64
 
 	// CodeCloser is non-nil when the code should be closed after this module.
 	CodeCloser api.Closer
@@ -61,7 +60,7 @@ type CallContext struct {
 
 // FailIfClosed returns a sys.ExitError if CloseWithExitCode was called.
 func (m *CallContext) FailIfClosed() (err error) {
-	if closed := atomic.LoadUint64(m.Closed); closed != 0 {
+	if closed := atomic.LoadUint64(&m.Closed); closed != 0 {
 		return sys.NewExitError(m.module.Name, uint32(closed>>32)) // Unpack the high order bits as the exit code.
 	}
 	return nil
@@ -149,7 +148,7 @@ func (m *CallContext) closeWithExitCode(ctx context.Context, exitCode uint32) (e
 
 func (m *CallContext) setExitCode(exitCode uint32) bool {
 	closed := uint64(1) + uint64(exitCode)<<32 // Store exitCode as high-order bits.
-	return atomic.CompareAndSwapUint64(m.Closed, 0, closed)
+	return atomic.CompareAndSwapUint64(&m.Closed, 0, closed)
 }
 
 // ensureResourcesClosed ensures that resources assigned to CallContext is released.


Test patch:
diff --git a/internal/wasm/call_context_test.go b/internal/wasm/call_context_test.go
index 99619410..4718401e 100644
--- a/internal/wasm/call_context_test.go
+++ b/internal/wasm/call_context_test.go
@@ -93,7 +93,7 @@ func TestCallContext_Close(t *testing.T) {
 				// Closing should not err.
 				require.NoError(t, tc.closer(ctx, m))
 
-				require.Equal(t, tc.expectedClosed, *m.Closed)
+				require.Equal(t, tc.expectedClosed, m.Closed)
 
 				// Verify our intended side-effect
 				require.Nil(t, s.Module(moduleName))
@@ -197,7 +197,7 @@ func TestCallContext_CallDynamic(t *testing.T) {
 				// Closing should not err.
 				require.NoError(t, tc.closer(ctx, m))
 
-				require.Equal(t, tc.expectedClosed, *m.Closed)
+				require.Equal(t, tc.expectedClosed, m.Closed)
 
 				// Verify our intended side-effect
 				require.Nil(t, s.Module(moduleName))
@@ -259,7 +259,7 @@ func TestCallContext_CallDynamic(t *testing.T) {
 func TestCallContext_CloseModuleOnCanceledOrTimeout(t *testing.T) {
 	s := newStore()
 	t.Run("timeout", func(t *testing.T) {
-		cc := &CallContext{Closed: new(uint64), module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
 		const duration = time.Second
 		ctx, cancel := context.WithTimeout(context.Background(), duration)
 		defer cancel()
@@ -272,7 +272,7 @@ func TestCallContext_CloseModuleOnCanceledOrTimeout(t *testing.T) {
 	})
 
 	t.Run("cancel", func(t *testing.T) {
-		cc := &CallContext{Closed: new(uint64), module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
 		ctx, cancel := context.WithCancel(context.Background())
 		done := cc.CloseModuleOnCanceledOrTimeout(context.WithValue(ctx, struct{}{}, 1)) // Wrapping arbitrary context.
 		cancel()
@@ -287,7 +287,7 @@ func TestCallContext_CloseModuleOnCanceledOrTimeout(t *testing.T) {
 	})
 
 	t.Run("timeout over cancel", func(t *testing.T) {
-		cc := &CallContext{Closed: new(uint64), module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
 		const duration = time.Second
 		ctx, cancel := context.WithCancel(context.Background())
 		defer cancel()
@@ -300,7 +300,7 @@ func TestCallContext_CloseModuleOnCanceledOrTimeout(t *testing.T) {
 	})
 
 	t.Run("cancel over timeout", func(t *testing.T) {
-		cc := &CallContext{Closed: new(uint64), module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
 		ctx, cancel := context.WithCancel(context.Background())
 		// Wrap the timeout context by cancel context.
 		var timeoutDone context.CancelFunc
@@ -317,7 +317,7 @@ func TestCallContext_CloseModuleOnCanceledOrTimeout(t *testing.T) {
 	})
 
 	t.Run("cancel works", func(t *testing.T) {
-		cc := &CallContext{Closed: new(uint64), module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
 		cancelChan := make(chan struct{})
 		var wg sync.WaitGroup
 		wg.Add(1)
@@ -332,7 +332,7 @@ func TestCallContext_CloseModuleOnCanceledOrTimeout(t *testing.T) {
 	})
 
 	t.Run("no close on all resources canceled", func(t *testing.T) {
-		cc := &CallContext{Closed: new(uint64), module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
 		cancelChan := make(chan struct{})
 		close(cancelChan)
 		ctx, cancel := context.WithCancel(context.Background())
@@ -349,7 +349,7 @@ func TestCallContext_CloseWithCtxErr(t *testing.T) {
 	s := newStore()
 
 	t.Run("context canceled", func(t *testing.T) {
-		cc := &CallContext{Closed: new(uint64), module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
 		ctx, cancel := context.WithCancel(context.Background())
 		cancel()
 
@@ -360,7 +360,7 @@ func TestCallContext_CloseWithCtxErr(t *testing.T) {
 	})
 
 	t.Run("context timeout", func(t *testing.T) {
-		cc := &CallContext{Closed: new(uint64), module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
 		duration := time.Second
 		ctx, cancel := context.WithTimeout(context.Background(), duration)
 		defer cancel()
@@ -374,7 +374,7 @@ func TestCallContext_CloseWithCtxErr(t *testing.T) {
 	})
 
 	t.Run("no error", func(t *testing.T) {
-		cc := &CallContext{Closed: new(uint64), module: &ModuleInstance{Name: "test"}, s: s}
+		cc := &CallContext{Closed: 0, module: &ModuleInstance{Name: "test"}, s: s}
 
 		cc.CloseWithCtxErr(context.Background())