code_relocation: Cache list of obj files
As part of relocation, this script matches each source file to its corresponding object file. This matching is done inside of get_obj_filename which is called once per source file. get_obj_filename traverses the entire build directory on every invocation. This is unnecessary since built object files don't change. On a sufficiently large project (like mine), this script takes over a minute and the majority of that time is spent needlessly traversing the build directory again and again. Caching the list of object files enables this script to run in less than a second. I tested by building my project (which enables the relocation script) and comparing memory breakdown before / after. Signed-off-by: Galen Krulce <gkrulce@meta.com>
This commit is contained in:
parent
bf22fa697b
commit
5ae9f44825
1 changed files with 9 additions and 10 deletions
|
@ -44,7 +44,6 @@ this will place data and bss inside SRAM2.
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
|
||||||
import glob
|
import glob
|
||||||
import re
|
import re
|
||||||
import warnings
|
import warnings
|
||||||
|
@ -491,19 +490,18 @@ def parse_args():
|
||||||
help="Verbose Output")
|
help="Verbose Output")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
def gen_all_obj_files(searchpath):
|
||||||
|
return list(Path(searchpath).rglob('*.o')) + list(Path(searchpath).rglob('*.obj'))
|
||||||
|
|
||||||
# return the absolute path for the object file.
|
# return the absolute path for the object file.
|
||||||
def get_obj_filename(searchpath, filename):
|
def get_obj_filename(all_obj_files, filename):
|
||||||
# get the object file name which is almost always pended with .obj
|
# get the object file name which is almost always pended with .obj
|
||||||
obj_filename = filename.split("/")[-1] + ".obj"
|
obj_filename = filename.split("/")[-1] + ".obj"
|
||||||
|
|
||||||
for dirpath, _, files in os.walk(searchpath):
|
for obj_file in all_obj_files:
|
||||||
for filename1 in files:
|
if obj_file.name == obj_filename:
|
||||||
if filename1 == obj_filename:
|
if filename.split("/")[-2] in obj_file.parent.name:
|
||||||
if filename.split("/")[-2] in dirpath.split("/")[-1]:
|
return str(obj_file)
|
||||||
fullname = os.path.join(dirpath, filename1)
|
|
||||||
return fullname
|
|
||||||
|
|
||||||
|
|
||||||
# Extracts all possible components for the input string:
|
# Extracts all possible components for the input string:
|
||||||
# <mem_region>[\ :program_header]:<flag_1>[;<flag_2>...]:<file_1>[;<file_2>...][,filter]
|
# <mem_region>[\ :program_header]:<flag_1>[;<flag_2>...]:<file_1>[;<file_2>...][,filter]
|
||||||
|
@ -587,6 +585,7 @@ def main():
|
||||||
mpu_align = {}
|
mpu_align = {}
|
||||||
parse_args()
|
parse_args()
|
||||||
searchpath = args.directory
|
searchpath = args.directory
|
||||||
|
all_obj_files = gen_all_obj_files(searchpath)
|
||||||
linker_file = args.output
|
linker_file = args.output
|
||||||
sram_data_linker_file = args.output_sram_data
|
sram_data_linker_file = args.output_sram_data
|
||||||
sram_bss_linker_file = args.output_sram_bss
|
sram_bss_linker_file = args.output_sram_bss
|
||||||
|
@ -602,7 +601,7 @@ def main():
|
||||||
full_list_of_sections: 'dict[SectionKind, list[OutputSection]]' = defaultdict(list)
|
full_list_of_sections: 'dict[SectionKind, list[OutputSection]]' = defaultdict(list)
|
||||||
|
|
||||||
for filename, symbol_filter in files:
|
for filename, symbol_filter in files:
|
||||||
obj_filename = get_obj_filename(searchpath, filename)
|
obj_filename = get_obj_filename(all_obj_files, filename)
|
||||||
# the obj file wasn't found. Probably not compiled.
|
# the obj file wasn't found. Probably not compiled.
|
||||||
if not obj_filename:
|
if not obj_filename:
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue