pebble/sdk/waftools/report_memory_usage.py

114 lines
5.1 KiB
Python
Raw Permalink Normal View History

# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from waflib import Logs, Task
from waflib.TaskGen import after_method, feature
from binutils import size
from memory_reports import (app_memory_report, app_resource_memory_error,
app_appstore_resource_memory_error,
bytecode_memory_report, simple_memory_report)
from sdk_helpers import is_sdk_2x
class memory_usage_report(Task.Task):
"""
Task class to print a memory usage report for the specified binary and resources, if any
"""
def run(self):
"""
This method executes when the memory usage report task runs
:return: None
"""
bin_type = self.bin_type
platform = self.generator.env.PLATFORM_NAME
if bin_type == 'rocky':
env = self.generator.bld.all_envs[self.env.PLATFORM_NAME]
Logs.pprint(*bytecode_memory_report(platform, env.SNAPSHOT_SIZE, env.SNAPSHOT_MAX))
return
bin_path = self.inputs[0].abspath()
resources_path = self.inputs[1].abspath() if len(self.inputs) > 1 else None
max_ram, max_resources, max_appstore_resources = self.max_sizes
# Handle zero-size binaries (more common with packages)
ram_size = sum(size(bin_path)) if size(bin_path) != 0 else 0
resource_size = os.stat(resources_path).st_size if resources_path else None
if resource_size and max_resources and max_appstore_resources:
if resource_size > max_resources:
Logs.pprint(*app_appstore_resource_memory_error(platform, resource_size,
max_resources))
return -1
elif resource_size > max_appstore_resources:
Logs.pprint(*app_appstore_resource_memory_error(platform, resource_size,
max_appstore_resources))
if max_ram:
# resource_size and max_appstore_resources are optional
free_ram = max_ram - ram_size
Logs.pprint(*app_memory_report(platform, bin_type, ram_size, max_ram,
free_ram, resource_size, max_appstore_resources))
else:
# resource_size is optional
Logs.pprint(*simple_memory_report(platform, ram_size, resource_size))
@feature('memory_usage')
@after_method('cprogram', 'cstlib', 'process_rocky_js')
def generate_memory_usage_report(task_gen):
"""
Generates and prints a report of the project's memory usage (binary + resources, if applicable).
Keyword arguments:
app -- The path to the app elf file, if this is an app being evaluated
worker - The path to the worker elf file, if this is a worker being evaluated
lib - The path to the library archive file, if this is a library being evaluated
resources - The path to the resource pack or resource ball, if resources exist for this bin_type
:param task_gen: the task generator instance
:return: None
"""
app, worker, lib, resources = (getattr(task_gen, attr, None)
for attr in ('app', 'worker', 'lib', 'resources'))
max_resources = task_gen.env.PLATFORM["MAX_RESOURCES_SIZE"]
max_resources_appstore = task_gen.env.PLATFORM["MAX_RESOURCES_SIZE_APPSTORE"]
app_max_ram = task_gen.env.PLATFORM["MAX_APP_MEMORY_SIZE"] if app else None
worker_max_ram = task_gen.env.PLATFORM["MAX_WORKER_MEMORY_SIZE"] if worker else None
if app:
app_task = task_gen.create_task('memory_usage_report',
[task_gen.to_nodes(app)[0],
task_gen.to_nodes(resources)[0]])
app_task.max_sizes = (app_max_ram, max_resources, max_resources_appstore)
app_task.bin_type = 'app'
if worker:
worker_task = task_gen.create_task('memory_usage_report',
task_gen.to_nodes(worker)[0])
worker_task.max_sizes = (worker_max_ram, None, None)
worker_task.bin_type = 'worker'
if lib:
lib_task = task_gen.create_task('memory_usage_report',
[task_gen.to_nodes(lib)[0],
task_gen.to_nodes(resources)[0]])
lib_task.max_sizes = (None, None, None)
lib_task.bin_type = 'lib'
if getattr(task_gen, 'bin_type', None) == 'rocky':
rocky_task = task_gen.create_task('memory_usage_report', task_gen.env.JS_RESO)
rocky_task.bin_type = 'rocky'
rocky_task.vars = ['PLATFORM_NAME']