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
// 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 {

View file

@ -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{}) {

View file

@ -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,
},
},