The property squashing functions were performing 19% of all allocations
and allocating 3.43 GB, most of which was used to track the name of the
property, but the name of the property is only used to print errors.
Keep the elements of the name in a preallocated slice instead, and only
compute the name when an error occurs.
Calling reflect.Value.Interface() was also expensive, and only passed
to filter and order functions, none of which use the values. Modify
the signature of the filter and order functions to remove the interfaces
and the property name.
Test: extend_test.go
Change-Id: I517f89daf251bb43f7cfefa6f1e83951c0e271b7
Recurse into embedded anonymous structs and the BlueprintEmbed
workaround structs when looking for properties in
extendPropertiesRecursive.
Test: proptools/extend_test.go
Change-Id: I975651a64e5173747403629a09263562761f1495
This support enables specifying properties of the type "map" within a
Soong module, but explicitly does not allow them to be used within a bp
file.
This means that rather than specifying each arch/os/target within a
struct to support arch-variant properties/attributes, we can use a map.
This allows us to simplify the implementation of LabelAttribute,
StringListAttribute, and LabelListAttribute as the number of select
statements supported becoming large and hard results in a lot of
duplication.
Test: go test blueprint tests
Test: m nothing
Change-Id: I88cc5952a6bdb60a2344fa0737216f016086cea5
override_* in Soong requires a module to override certain properties of
other module. In that case, values of a slice property (e.g. []string)
should be replaced by the same property value in the overriding module.
However, since proptools only supports Append and Prepend orders where
the original values are kept for slice properties, the behavior
couldn't be implemented. To support the use case, Replace order is
introduced, in which case slice property values are completely replaced.
For other types of properties, the Replace order behaves exactly the
same as the Append order.
Bug: 144338929
Test: m
Change-Id: Iae9feda035177fe6a22e6e8319c0fdaa9e08e85e
Support int64 number instead of int to be more fixed to bit size so
that the underlying arch won't affect overflow cases. Besides,
refection: func (v Value) Int() int64 always cast to int64 no matter the
input is int, int16, int32. Currently we always treat "-" as negative
sign to bind to next value, and "+" as plus operator to add operands
together.
So we allow:
a = 5 + -4 + 5 or a = -4 + 5
But we don't allow:
a = +5 + 4 + -4 since we don't treat "+" as a positive sign, otherwise,
a = 5 + +5 would exist which looks pretty weird. In the future, we may
want fully support number calculator logic eg, "+"/"-" can be
positive/negative sign or operator, and "(" and ")" will be considered
to group expressions with a higher precedence.
int & uint properties within struct keeps unchanged, which is only
allowed when tagged with 'blueprint:mutated'. We only allow *int64
property instead of int64 property within struct since it does't make
sense to do prepending or appending to int64.
Change-Id: I565e046dbd268af3538aee148cd7300037e56523
Blueprint was using "replace" semantics when unpacking properties
into property structs, meaning if a module factory pre-set property
values they would be overwritten by whatever was in the Blueprint
file. This is different than what would happen if the same property
was updated using the Append*Properties functions in proptools, which
would use "append" semantics, which append strings and lists,
logically ORs booleans and replaces pointers to strings and booleans.
Replace unpack's semantics with append semantics for consistency.
Any previous users of pre-set properties can move to using a pointer
to a string or boolean if they want the old behavior.
Test: unpack_test.go
Test: extend_test.go
Change-Id: I02eebe80916e578938142f8e76889bd985223afc
Allow using ExtendMatchingProperties to extend pointer to a struct or an
interface containing a pointer to a struct using a struct, and
vice-versa.
Also fixes a pre-existing bug where extending a nested structure could
fail if there were multiple possible destnations and some of them did
not have a matching nested property.
Change-Id: I6e69d78eb6595ba7dd2603e3aa7dd8de3f292744
Allow primary builders to reduce allocations of empty structures by
allowing nil pointers to concrete struct types. Property readers will
not recurse into nil pointers, property writers will replace the nil
pointer with a pointer to the zero value of the pointer element type.
Allows a >50% primary builder time improvement with a trivial change in
Soong.
Change-Id: If6ad674bf7bf2a694c335378a074643a97d3c50b
proptools cloning and extending are a significant portion of the run
time for Soong. Optimize out calls to reflect.Type.Field(), which must
allocate a []int to store the index, by caching all the fields of each
type as it is seen, and by iterating over a slice of cached fields
instead of calling Field(i) for each one. Also avoid calling
reflect.Value.Interface() twice on the same Value.
Change-Id: I4e13fc85f30d8614a5586283e928c0a6d7f24809
ExtendProperties is the same as AppendProperties or PrependProperties,
but takes a function that determines whether each property should be
appended or prepended.
Change-Id: I26e400d56d75a88bab9c27c382ee5321bc623ee5
This makes *string values act like *bool values -- instead of appending
or prepending the contents of the string, the entire string is replaced.
The use case here is for overriding filenames, where appending doesn't
work.
The only append semantics for bool that result in a no-op when the zero
value is appended is to OR the two values together, but that is rarely
the desired semantics. Add support for *bool and *string as property
types, where appending a nil pointer is a no-op. For *bool, appending a
non-nil pointer replaces the destination with the value. For *string,
appending a non-nil pointer appends the value.
This also provides a more reliable replacement for
ModuleContext.ContainsProperty, as the build logic can tell that the
property was set, even if it was set by a mutator and not by the
blueprints file, by testing against nil.
[]string already provides these semantics for lists.
Setting a *bool or *string property from a blueprints file is the same
syntax as setting a bool or a string property.
It is common for a mutator to append or prepend property structs
together. Add helper functions to append or prepend properties in property
structs. The append operation is defined as appending string and slices
of strings normally, OR-ing bool values, and recursing into embedded
structs, pointers to structs, and interfaces containing pointers to
structs. Appending or prepending the zero value of a property will
always be a no-op.