Split the runtime arch property structs into 3
Instead of creating a runtime generated struct type:
struct {
Arch struct {
Arm struct {
Armv7-a struct {
...
}
}
...
}
Multilib struct {
Lib32 struct {
...
}
...
}
Target struct {
Android struct {
...
}
...
}
}
Replace it with a top-level struct of empty interfaces:
type archPropRoot struct {
Arch, Multilib, Target interface{}
}
And then embed nil pointers to smaller structs inside it:
struct {
Arm struct {
Armv7-a struct {
...
}
}
...
}
This reduces the maximum number of times the archecture specific
properties are embedded in a runtime generated struct from 139
to 97, which makes it easier to avoid hitting the runtime generated
struct name size limit of 64kB.
Bug: 146234651
Test: all soong tests
Change-Id: I901c434ac9a1d99c74fc2370c5e6803b3682dc73
diff --git a/android/arch.go b/android/arch.go
index b5b8a8f..a79685c 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -926,16 +926,24 @@
return targets
}
-// createArchType takes a reflect.Type that is either a struct or a pointer to a struct, and returns a list of
-// reflect.Type that contains the arch-variant properties inside structs for each architecture, os, target, multilib,
-// etc.
-func createArchType(props reflect.Type) []reflect.Type {
+type archPropTypeDesc struct {
+ arch, multilib, target reflect.Type
+}
+
+type archPropRoot struct {
+ Arch, Multilib, Target interface{}
+}
+
+// createArchPropTypeDesc takes a reflect.Type that is either a struct or a pointer to a struct, and
+// returns lists of reflect.Types that contains the arch-variant properties inside structs for each
+// arch, multilib and target property.
+func createArchPropTypeDesc(props reflect.Type) []archPropTypeDesc {
propShards, _ := proptools.FilterPropertyStructSharded(props, filterArchStruct)
if len(propShards) == 0 {
return nil
}
- var ret []reflect.Type
+ var ret []archPropTypeDesc
for _, props := range propShards {
variantFields := func(names []string) []reflect.StructField {
@@ -1011,20 +1019,12 @@
}
targetType := reflect.StructOf(variantFields(targets))
- ret = append(ret, reflect.StructOf([]reflect.StructField{
- {
- Name: "Arch",
- Type: archType,
- },
- {
- Name: "Multilib",
- Type: multilibType,
- },
- {
- Name: "Target",
- Type: targetType,
- },
- }))
+
+ ret = append(ret, archPropTypeDesc{
+ arch: reflect.PtrTo(archType),
+ multilib: reflect.PtrTo(multilibType),
+ target: reflect.PtrTo(targetType),
+ })
}
return ret
}
@@ -1069,12 +1069,16 @@
}
archPropTypes := archPropTypeMap.Once(NewCustomOnceKey(t), func() interface{} {
- return createArchType(t)
- }).([]reflect.Type)
+ return createArchPropTypeDesc(t)
+ }).([]archPropTypeDesc)
var archProperties []interface{}
for _, t := range archPropTypes {
- archProperties = append(archProperties, reflect.New(t).Interface())
+ archProperties = append(archProperties, &archPropRoot{
+ Arch: reflect.Zero(t.arch).Interface(),
+ Multilib: reflect.Zero(t.multilib).Interface(),
+ Target: reflect.Zero(t.target).Interface(),
+ })
}
base.archProperties = append(base.archProperties, archProperties)
m.AddProperties(archProperties...)
@@ -1088,6 +1092,13 @@
func (m *ModuleBase) appendProperties(ctx BottomUpMutatorContext,
dst interface{}, src reflect.Value, field, srcPrefix string) reflect.Value {
+ if src.Kind() == reflect.Ptr {
+ if src.IsNil() {
+ return src
+ }
+ src = src.Elem()
+ }
+
src = src.FieldByName(field)
if !src.IsValid() {
ctx.ModuleErrorf("field %q does not exist", srcPrefix)
@@ -1134,7 +1145,7 @@
for _, archProperties := range m.archProperties[i] {
archPropValues := reflect.ValueOf(archProperties).Elem()
- targetProp := archPropValues.FieldByName("Target")
+ targetProp := archPropValues.FieldByName("Target").Elem()
// Handle host-specific properties in the form:
// target: {
@@ -1229,9 +1240,9 @@
for _, archProperties := range m.archProperties[i] {
archPropValues := reflect.ValueOf(archProperties).Elem()
- archProp := archPropValues.FieldByName("Arch")
- multilibProp := archPropValues.FieldByName("Multilib")
- targetProp := archPropValues.FieldByName("Target")
+ archProp := archPropValues.FieldByName("Arch").Elem()
+ multilibProp := archPropValues.FieldByName("Multilib").Elem()
+ targetProp := archPropValues.FieldByName("Target").Elem()
// Handle arch-specific properties in the form:
// arch: {