reduce flash footprint by smarter code generation #4163

This commit is contained in:
rusefillc 2022-12-04 00:21:17 -05:00
parent 032deea464
commit 751e7a6787
5 changed files with 28 additions and 70 deletions

View File

@ -0,0 +1,11 @@
package com.rusefi.core;
public class Tuple<Z> extends Pair<String, String> {
public final Z third;
public Tuple(String first, String second, Z third) {
super(first, second);
this.third = third;
}
}

Binary file not shown.

View File

@ -3,7 +3,7 @@ package com.rusefi.output;
import com.rusefi.ConfigField;
import com.rusefi.ReaderState;
import com.rusefi.TypesHelper;
import com.rusefi.core.Pair;
import com.rusefi.core.Tuple;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -18,7 +18,6 @@ import static com.rusefi.output.ConfigStructure.ALIGNMENT_FILL_AT;
import static com.rusefi.output.DataLogConsumer.UNUSED;
import static com.rusefi.output.GetOutputValueConsumer.getHashConflicts;
import static com.rusefi.output.GetOutputValueConsumer.wrapSwitchStatement;
import static com.rusefi.output.JavaSensorsConsumer.quote;
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
public class GetConfigValueConsumer implements ConfigurationConsumer {
@ -26,17 +25,6 @@ public class GetConfigValueConsumer implements ConfigurationConsumer {
private static final String ENGINE_CONFIGURATION = "engineConfiguration.";
static final String FILE_HEADER = "#include \"pch.h\"\n" +
"#include \"value_lookup.h\"\n";
private static final String FIND_METHOD =
"plain_get_float_s * findFloat(const char *name) {\n" +
"\tplain_get_float_s *currentF = &getF_plain[0];\n" +
"\twhile (currentF < getF_plain + efi::size(getF_plain)) {\n" +
"\t\tif (strEqualCaseInsensitive(name, currentF->token)) {\n" +
"\t\t\treturn currentF;\n" +
"\t\t}\n" +
"\t\tcurrentF++;\n" +
"\t}\n" +
"\treturn nullptr;\n" +
"}\n";
private static final String GET_METHOD_HEADER =
"float getConfigValueByName(const char *name) {\n" +
@ -52,10 +40,7 @@ public class GetConfigValueConsumer implements ConfigurationConsumer {
"\t}\n" +
"\n";
private static final String SET_METHOD_FOOTER = "}\n";
private final List<Pair<String, String>> getterPairs = new ArrayList<>();
private final List<Pair<String, String>> setterPairs = new ArrayList<>();
private final StringBuilder allFloatAddresses = new StringBuilder(
"static plain_get_float_s getF_plain[] = {\n");
private final List<Tuple<String>> variables = new ArrayList<>();
private final String outputFileName;
public GetConfigValueConsumer(String outputFileName) {
@ -102,16 +87,7 @@ public class GetConfigValueConsumer implements ConfigurationConsumer {
if (javaName.startsWith(CONFIG_ENGINE_CONFIGURATION))
javaName = "engineConfiguration->" + javaName.substring(CONFIG_ENGINE_CONFIGURATION.length());
getterPairs.add(new Pair<>(userName, javaName + cf.getName()));
if (TypesHelper.isFloat(cf.getType())) {
allFloatAddresses.append("\t{" + quote(userName) + ", &engineConfiguration->" + userName + "},\n");
} else {
setterPairs.add(new Pair<>(userName, javaName + cf.getName()));
}
variables.add(new Tuple<>(userName, javaName + cf.getName(), cf.getType()));
return "";
@ -131,8 +107,6 @@ public class GetConfigValueConsumer implements ConfigurationConsumer {
public String getHeaderAndGetter() {
return FILE_HEADER +
getFloatsSections() +
FIND_METHOD +
getCompleteGetterBody();
}
@ -140,7 +114,7 @@ public class GetConfigValueConsumer implements ConfigurationConsumer {
public String getCompleteGetterBody() {
StringBuilder switchBody = new StringBuilder();
StringBuilder getterBody = GetOutputValueConsumer.getGetters(switchBody, getterPairs);
StringBuilder getterBody = GetOutputValueConsumer.getGetters(switchBody, variables);
String fullSwitch = wrapSwitchStatement(switchBody);
@ -149,21 +123,19 @@ public class GetConfigValueConsumer implements ConfigurationConsumer {
getterBody + GET_METHOD_FOOTER;
}
@NotNull
public String getFloatsSections() {
return allFloatAddresses + "};\n\n";
}
public String getSetterBody() {
StringBuilder switchBody = new StringBuilder();
StringBuilder setterBody = new StringBuilder();
HashMap<Integer, AtomicInteger> hashConflicts = getHashConflicts(setterPairs);
HashMap<Integer, AtomicInteger> hashConflicts = getHashConflicts(variables);
for (Tuple<String> pair : variables) {
String cast = TypesHelper.isFloat(pair.third) ? "" : "(int)";
for (Pair<String, String> pair : setterPairs) {
int hash = HashUtil.hash(pair.first);
String str = getAssignment("(int)", pair.second);
String str = getAssignment(cast, pair.second);
if (hashConflicts.get(hash).get() == 1) {
switchBody.append("\t\tcase " + hash + ":\n");
switchBody.append(str);

View File

@ -82,7 +82,7 @@ public class GetOutputValueConsumer implements ConfigurationConsumer {
}
@NotNull
static StringBuilder getGetters(StringBuilder switchBody, List<Pair<String, String>> getterPairs) {
static StringBuilder getGetters(StringBuilder switchBody, List<? extends Pair<String, String>> getterPairs) {
HashMap<Integer, AtomicInteger> hashConflicts = getHashConflicts(getterPairs);
StringBuilder getterBody = new StringBuilder();
@ -102,7 +102,7 @@ public class GetOutputValueConsumer implements ConfigurationConsumer {
}
@NotNull
static HashMap<Integer, AtomicInteger> getHashConflicts(List<Pair<String, String>> getterPairs1) {
static HashMap<Integer, AtomicInteger> getHashConflicts(List<? extends Pair<String, String>> getterPairs1) {
HashMap<Integer, AtomicInteger> hashConflicts = new HashMap<>();
for (Pair<String, String> pair : getterPairs1) {
hashConflicts.computeIfAbsent(HashUtil.hash(pair.first), integer -> new AtomicInteger(0)).incrementAndGet();

View File

@ -22,12 +22,6 @@ public class GetConfigValueConsumerTest {
GetConfigValueConsumer getConfigValueConsumer = new GetConfigValueConsumer(null);
state.readBufferedReader(test, getConfigValueConsumer);
assertEquals(
"static plain_get_float_s getF_plain[] = {\n" +
"};\n\n"
, getConfigValueConsumer.getFloatsSections());
assertEquals(
"float getConfigValueByName(const char *name) {\n" +
"\t{\n" +
@ -54,6 +48,11 @@ public class GetConfigValueConsumerTest {
assertEquals("\tint hash = djb2lowerCase(name);\n" +
"\tswitch(hash) {\n" +
"\t\tcase -672272162:\n" +
"\t{\n" +
"\t\tconfig->iat.config.tempC_1 = value;\n" +
"\t\treturn;\n" +
"\t}\n" +
"\t\tcase -1237776078:\n" +
"\t{\n" +
"\t\tconfig->iat.adcChannel = (int)value;\n" +
@ -61,12 +60,6 @@ public class GetConfigValueConsumerTest {
"\t}\n" +
"\t}\n", getConfigValueConsumer.getSetterBody());
assertEquals(
"static plain_get_float_s getF_plain[] = {\n" +
"\t{\"iat.config.tempC_1\", &engineConfiguration->iat.config.tempC_1},\n" +
"};\n" +
"\n", getConfigValueConsumer.getFloatsSections());
assertEquals("float getConfigValueByName(const char *name) {\n" +
"\t{\n" +
"\tint hash = djb2lowerCase(name);\n" +
@ -137,24 +130,6 @@ public class GetConfigValueConsumerTest {
assertEquals("#include \"pch.h\"\n" +
"#include \"value_lookup.h\"\n" +
"static plain_get_float_s getF_plain[] = {\n" +
"\t{\"clt.config.tempC_1\", &engineConfiguration->clt.config.tempC_1},\n" +
"\t{\"clt.config.map.sensor.highValue\", &engineConfiguration->clt.config.map.sensor.highValue},\n" +
"\t{\"clt.config.injector.flow\", &engineConfiguration->clt.config.injector.flow},\n" +
"\t{\"clt.config.bias_resistor\", &engineConfiguration->clt.config.bias_resistor},\n" +
"\t{\"afr_type\", &engineConfiguration->afr_type},\n" +
"};\n" +
"\n" +
"plain_get_float_s * findFloat(const char *name) {\n" +
"\tplain_get_float_s *currentF = &getF_plain[0];\n" +
"\twhile (currentF < getF_plain + efi::size(getF_plain)) {\n" +
"\t\tif (strEqualCaseInsensitive(name, currentF->token)) {\n" +
"\t\t\treturn currentF;\n" +
"\t\t}\n" +
"\t\tcurrentF++;\n" +
"\t}\n" +
"\treturn nullptr;\n" +
"}\n" +
"float getConfigValueByName(const char *name) {\n" +
"\t{\n" +
"\tint hash = djb2lowerCase(name);\n" +