From 8514b5c26d7e99ef68fc6354649cbaa31ae473e7 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 14 Dec 2023 13:59:50 -0800 Subject: [PATCH] Optimize returning the zero value from provider APIs Now that nothing calls *Context.*Provider directly, make the blueprint methods return a nil any interface instead of the zero value that was constructed via reflection. The type-safe wrappers will return a zero value that can be constructed without any reflection or copying. Bug: 316410648 Test: provider_test.go Change-Id: I0abde5bacab9964a83f03c1644b51295a6c34d0b --- context.go | 14 ++++---------- module_ctx.go | 25 +++++-------------------- provider.go | 3 --- 3 files changed, 9 insertions(+), 33 deletions(-) diff --git a/context.go b/context.go index ca30874..1592154 100644 --- a/context.go +++ b/context.go @@ -4036,18 +4036,12 @@ func (c *Context) ModuleType(logicModule Module) string { } // ModuleProvider returns the value, if any, for the provider for a module. If the value for the -// provider was not set it returns the zero value of the type of the provider, which means the -// return value can always be type-asserted to the type of the provider. The return value should -// always be considered read-only. It panics if called before the appropriate mutator or -// GenerateBuildActions pass for the provider on the module. The value returned may be a deep -// copy of the value originally passed to SetProvider. +// provider was not set it returns nil and false. The return value should always be considered read-only. +// It panics if called before the appropriate mutator or GenerateBuildActions pass for the provider on the +// module. The value returned may be a deep copy of the value originally passed to SetProvider. func (c *Context) ModuleProvider(logicModule Module, provider AnyProviderKey) (any, bool) { module := c.moduleInfo[logicModule] - value, ok := c.provider(module, provider.provider()) - if value == nil { - value = provider.provider().zero - } - return value, ok + return c.provider(module, provider.provider()) } func (c *Context) BlueprintFile(logicModule Module) string { diff --git a/module_ctx.go b/module_ctx.go index fb65755..cb86f43 100644 --- a/module_ctx.go +++ b/module_ctx.go @@ -334,16 +334,14 @@ type BaseModuleContext interface { OtherModuleReverseDependencyVariantExists(name string) bool // OtherModuleProvider returns the value for a provider for the given module. If the value is - // not set it returns the zero value of the type of the provider, so the return value can always - // be type asserted to the type of the provider. The value returned may be a deep copy of the - // value originally passed to SetProvider. + // not set it returns nil and false. The value returned may be a deep copy of the value originally + // passed to SetProvider. // // This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead. OtherModuleProvider(m Module, provider AnyProviderKey) (any, bool) // Provider returns the value for a provider for the current module. If the value is - // not set it returns the zero value of the type of the provider, so the return value can always - // be type asserted to the type of the provider. It panics if called before the appropriate + // not set it returns nil and false. It panics if called before the appropriate // mutator or GenerateBuildActions pass for the provider. The value returned may be a deep // copy of the value originally passed to SetProvider. // @@ -611,24 +609,11 @@ func (m *baseModuleContext) OtherModuleReverseDependencyVariantExists(name strin func (m *baseModuleContext) OtherModuleProvider(logicModule Module, provider AnyProviderKey) (any, bool) { module := m.context.moduleInfo[logicModule] - value, ok := m.context.provider(module, provider.provider()) - if value == nil { - value = provider.provider().zero - } - return value, ok + return m.context.provider(module, provider.provider()) } func (m *baseModuleContext) Provider(provider AnyProviderKey) (any, bool) { - value, ok := m.context.provider(m.module, provider.provider()) - if value == nil { - value = provider.provider().zero - } - return value, ok -} - -func (m *baseModuleContext) HasProvider(provider AnyProviderKey) bool { - _, ok := m.context.provider(m.module, provider.provider()) - return ok + return m.context.provider(m.module, provider.provider()) } func (m *baseModuleContext) SetProvider(provider AnyProviderKey, value interface{}) { diff --git a/provider.go b/provider.go index 36411d8..48527b1 100644 --- a/provider.go +++ b/provider.go @@ -48,7 +48,6 @@ type typedProviderKey[K any] struct { type providerKey struct { id int typ string - zero any mutator string } @@ -84,7 +83,6 @@ func NewProvider[K any]() ProviderKey[K] { func NewMutatorProvider[K any](mutator string) ProviderKey[K] { checkCalledFromInit() - zero := *new(K) typ := fmt.Sprintf("%T", *new(K)) provider := ProviderKey[K]{ @@ -92,7 +90,6 @@ func NewMutatorProvider[K any](mutator string) ProviderKey[K] { providerKey: providerKey{ id: len(providerRegistry), typ: typ, - zero: zero, mutator: mutator, }, },