Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add AOT data segment size using llvm-size tool
  • Loading branch information
pavelsavara committed Jan 17, 2023
commit d362ab8c9056293a153802bd18ef2ce7ee90b1aa
44 changes: 35 additions & 9 deletions src/mono/wasm/build/WasmApp.Native.targets
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,6 @@
<Error Condition="'$(_IsEMSDKMissing)' == 'true'"
Text="$(_EMSDKMissingErrorMessage) Emscripten SDK is required for building native files." />

<WasmCalculateInitialHeapSize Assemblies="@(WasmAssembliesToBundle)">
<Output TaskParameter="TotalSize" PropertyName="_WasmCalculatedInitialHeapSize" />
</WasmCalculateInitialHeapSize>

<PropertyGroup>
<_MonoAotCrossCompilerPath>@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','browser-wasm'))</_MonoAotCrossCompilerPath>
<_EmccDefaultFlagsRsp>$([MSBuild]::NormalizePath($(_WasmRuntimePackSrcDir), 'emcc-default.rsp'))</_EmccDefaultFlagsRsp>
Expand Down Expand Up @@ -191,9 +187,6 @@
<_EmccCompileBitcodeRsp>$(_WasmIntermediateOutputPath)emcc-compile-bc.rsp</_EmccCompileBitcodeRsp>
<_EmccLinkRsp>$(_WasmIntermediateOutputPath)emcc-link.rsp</_EmccLinkRsp>

<EmccInitialHeapSize Condition="'$(EmccInitialHeapSize)' == ''">$(EmccTotalMemory)</EmccInitialHeapSize>
<EmccInitialHeapSize Condition="'$(EmccInitialHeapSize)' == '' and '$(_WasmCalculatedInitialHeapSize)' != '' and $(_WasmCalculatedInitialHeapSize) > 16777216">$(_WasmCalculatedInitialHeapSize)</EmccInitialHeapSize>
<EmccInitialHeapSize Condition="'$(EmccInitialHeapSize)' == ''">16777216</EmccInitialHeapSize>
</PropertyGroup>

<ItemGroup>
Expand Down Expand Up @@ -236,7 +229,6 @@
<_EmccLDFlags Include="-s ASSERTIONS=$(_EmccAssertionLevelDefault)" Condition="'$(_WasmDevel)' == 'true'" />
<_EmccLDFlags Include="@(_EmccCommonFlags)" />
<_EmccLDSFlags Include="-Wl,--allow-undefined" />
<_EmccLDSFlags Include="-s INITIAL_MEMORY=$(EmccInitialHeapSize)" />

<!-- ILLinker should have removed unused imports, so error for Publish -->
<_EmccLDSFlags Include="-s ERROR_ON_UNDEFINED_SYMBOLS=0" Condition="'$(WasmBuildingForNestedPublish)' != 'true'" />
Expand Down Expand Up @@ -377,7 +369,41 @@
</ItemGroup>
</Target>

<Target Name="_WasmWriteRspFilesForLinking" DependsOnTargets="_CheckEmccIsExpectedVersion">
<Target Name="_WasmCalculateMemorySize" DependsOnTargets="_CheckEmccIsExpectedVersion">
<ItemGroup>
<_AOTObjectFile Include="%(_BitcodeFile.ObjectFile)" />
</ItemGroup>

<!-- for AOT builds we use llvm-size tool to collect size of the DATA segment in each object file -->
<Exec Command="llvm-size$(_ExeExt) -d --format=sysv @(_AOTObjectFile, ' ')"
Condition="'$(_WasmShouldAOT)' == 'true'"
IgnoreStandardErrorWarningFormat="true"
ConsoleToMsBuild="true"
StandardOutputImportance="low" StandardErrorImportance="low"
EnvironmentVariables="@(EmscriptenEnvVars)" >
<Output TaskParameter="ConsoleOutput" ItemName="LlvmAotSizeOutput" />
</Exec>
<ItemGroup Condition="'$(_WasmShouldAOT)' == 'true'">
<AOTDataSegments Condition="$([System.String]::Copy('%(LlvmAotSizeOutput.Identity)').StartsWith('DATA '))"
Include="$([System.String]::Copy('%(LlvmAotSizeOutput.Identity)').Replace(&quot;DATA &quot;, &quot;&quot;).Replace(&quot; 0&quot;, &quot;&quot;).Trim())" />
</ItemGroup>

<WasmCalculateInitialHeapSize
Assemblies="@(WasmAssembliesToBundle)"
AOTDataSegments="@(AOTDataSegments)">
<Output TaskParameter="InitialHeapSize" PropertyName="_WasmCalculatedInitialHeapSize" />
</WasmCalculateInitialHeapSize>
<PropertyGroup>
<EmccInitialHeapSize Condition="'$(EmccInitialHeapSize)' == ''">$(EmccTotalMemory)</EmccInitialHeapSize>
<EmccInitialHeapSize Condition="'$(EmccInitialHeapSize)' == '' and '$(_WasmCalculatedInitialHeapSize)' != '' and $(_WasmCalculatedInitialHeapSize) > 16777216">$(_WasmCalculatedInitialHeapSize)</EmccInitialHeapSize>
<EmccInitialHeapSize Condition="'$(EmccInitialHeapSize)' == ''">16777216</EmccInitialHeapSize>
</PropertyGroup>
<ItemGroup>
<_EmccLDSFlags Include="-s INITIAL_MEMORY=$(EmccInitialHeapSize)" />
</ItemGroup>
</Target>

<Target Name="_WasmWriteRspFilesForLinking" DependsOnTargets="_CheckEmccIsExpectedVersion;_WasmCalculateMemorySize">
<PropertyGroup>
<_WasmEHLib Condition="'$(WasmEnableExceptionHandling)' == 'true'">libmono-wasm-eh-wasm.a</_WasmEHLib>
<_WasmEHLib Condition="'$(WasmEnableExceptionHandling)' != 'true'">libmono-wasm-eh-js.a</_WasmEHLib>
Expand Down
23 changes: 19 additions & 4 deletions src/tasks/WasmAppBuilder/WasmCalculateInitialHeapSize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,24 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

/// <summary>estimate the total memory needed for the assemblies.</summary>
/// <summary>estimate the total memory needed for the assemblies and AOT data segments.</summary>
public class WasmCalculateInitialHeapSize : Task
{
[Required]
[NotNull]
public string[]? Assemblies { get; set; }

[Required]
public string[]? AOTDataSegments { get; set; }

[Output]
public long? TotalSize { get; private set; }
public long? InitialHeapSize { get; private set; }

public override bool Execute ()
{
long totalDllSize=0;
long totalDataSize=0;

foreach (var asm in Assemblies)
{
var info = new FileInfo(asm);
Expand All @@ -34,12 +39,22 @@ public override bool Execute ()
totalDllSize += info.Length;
}

// during non-AOT builds, AOTDataSegments is null
if (AOTDataSegments != null)
{
foreach (var segment in AOTDataSegments)
{
totalDataSize += long.Parse(segment);
}
}

// this is arbitrary guess about memory overhead of the runtime, after the assemblies are loaded
const double extraMemoryRatio = 1.2;
long memorySize = (long) (totalDllSize * extraMemoryRatio);
// plus size of data segments generated by AOT
long memorySize = totalDataSize + (long) (totalDllSize * extraMemoryRatio);

// round it up to 64KB page size for wasm
TotalSize = (memorySize + 0x10000) & 0xFFFF0000;
InitialHeapSize = (memorySize + 0x10000) & 0xFFFF0000;

return true;
}
Expand Down