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
This commit is contained in:
Colin Cross 2023-12-14 13:59:50 -08:00
parent ed49204e85
commit 8514b5c26d
3 changed files with 9 additions and 33 deletions

View file

@ -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 // 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 // provider was not set it returns nil and false. The return value should always be considered read-only.
// return value can always be type-asserted to the type of the provider. The return value should // It panics if called before the appropriate mutator or GenerateBuildActions pass for the provider on the
// always be considered read-only. It panics if called before the appropriate mutator or // module. The value returned may be a deep copy of the value originally passed to SetProvider.
// 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) { func (c *Context) ModuleProvider(logicModule Module, provider AnyProviderKey) (any, bool) {
module := c.moduleInfo[logicModule] module := c.moduleInfo[logicModule]
value, ok := c.provider(module, provider.provider()) return c.provider(module, provider.provider())
if value == nil {
value = provider.provider().zero
}
return value, ok
} }
func (c *Context) BlueprintFile(logicModule Module) string { func (c *Context) BlueprintFile(logicModule Module) string {

View file

@ -334,16 +334,14 @@ type BaseModuleContext interface {
OtherModuleReverseDependencyVariantExists(name string) bool OtherModuleReverseDependencyVariantExists(name string) bool
// OtherModuleProvider returns the value for a provider for the given module. If the value is // 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 // not set it returns nil and false. The value returned may be a deep copy of the value originally
// be type asserted to the type of the provider. The value returned may be a deep copy of the // passed to SetProvider.
// value originally passed to SetProvider.
// //
// This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead. // This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead.
OtherModuleProvider(m Module, provider AnyProviderKey) (any, bool) OtherModuleProvider(m Module, provider AnyProviderKey) (any, bool)
// Provider returns the value for a provider for the current module. If the value is // 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 // not set it returns nil and false. It panics if called before the appropriate
// be type asserted to the type of the provider. It panics if called before the appropriate
// mutator or GenerateBuildActions pass for the provider. The value returned may be a deep // mutator or GenerateBuildActions pass for the provider. The value returned may be a deep
// copy of the value originally passed to SetProvider. // 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) { func (m *baseModuleContext) OtherModuleProvider(logicModule Module, provider AnyProviderKey) (any, bool) {
module := m.context.moduleInfo[logicModule] module := m.context.moduleInfo[logicModule]
value, ok := m.context.provider(module, provider.provider()) return m.context.provider(module, provider.provider())
if value == nil {
value = provider.provider().zero
}
return value, ok
} }
func (m *baseModuleContext) Provider(provider AnyProviderKey) (any, bool) { func (m *baseModuleContext) Provider(provider AnyProviderKey) (any, bool) {
value, ok := m.context.provider(m.module, provider.provider()) return 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
} }
func (m *baseModuleContext) SetProvider(provider AnyProviderKey, value interface{}) { func (m *baseModuleContext) SetProvider(provider AnyProviderKey, value interface{}) {

View file

@ -48,7 +48,6 @@ type typedProviderKey[K any] struct {
type providerKey struct { type providerKey struct {
id int id int
typ string typ string
zero any
mutator string mutator string
} }
@ -84,7 +83,6 @@ func NewProvider[K any]() ProviderKey[K] {
func NewMutatorProvider[K any](mutator string) ProviderKey[K] { func NewMutatorProvider[K any](mutator string) ProviderKey[K] {
checkCalledFromInit() checkCalledFromInit()
zero := *new(K)
typ := fmt.Sprintf("%T", *new(K)) typ := fmt.Sprintf("%T", *new(K))
provider := ProviderKey[K]{ provider := ProviderKey[K]{
@ -92,7 +90,6 @@ func NewMutatorProvider[K any](mutator string) ProviderKey[K] {
providerKey: providerKey{ providerKey: providerKey{
id: len(providerRegistry), id: len(providerRegistry),
typ: typ, typ: typ,
zero: zero,
mutator: mutator, mutator: mutator,
}, },
}, },