Repository: dotnet/runtime
File: src/coreclr/tools/Common/Compiler/ObjectWriter/WasmObjectWriter.cs (C#)

Code before:
    }

    internal class WasmSection
    {
        public WasmSectionType Type { get; }
        public string Name { get; }
        public SectionData Data => _data;
        private SectionWriter? _writer;

        private SectionData _data;

        public Span<byte> Header
        {
            get
            {
                // Section header consists of:
                // 1 byte: section type
                // ULEB128: size of section
                ulong sectionSize = (ulong)_data.Length;
                var encodeLength = DwarfHelper.SizeOfULEB128(sectionSize);

                Span<byte> header = new byte[1+encodeLength];
                header[0] = (byte)Type;
                DwarfHelper.WriteULEB128(header.Slice(1), sectionSize);

                return header;
            }
        }

        public SectionWriter Writer
        {
            get
            {
                if (_writer == null)
                {
                    _writer = new SectionWriter(null, 0, _data);
                }
                return _writer.Value;
            }
        }

        public WasmSection(WasmSectionType type, SectionData data, string name)
        {
            Type = type;
            Name = name;
            _data = data;
        }
    }

    /// <summary>
    /// Wasm object file format writer.

Review comment (performance):
The `Header` property returns a `Span<byte>` backed by a new array allocation on each access. This causes unnecessary allocations when the property is accessed multiple times (lines 228 and 231). Consider changing the return type to `byte[]` or caching the header as a field to avoid redundant allocations.

Code after:
    {
        public WasmObjectWriter(NodeFactory factory, ObjectWritingOptions options, OutputInfoBuilder outputInfoBuilder)
            : base(factory, options, outputInfoBuilder)
        {
        }

        private void EmitWasmHeader(Stream outputFileStream)
        {
            outputFileStream.Write("\0asm"u8);
            outputFileStream.Write([0x1, 0x0, 0x0, 0x0]);
        }

        // TODO: for now, we are fully overriding EmitObject. As we support more features, we should
        // see if we can re-use the base, or refactor the base method to allow for code sharing.
        public override void EmitObject(Stream outputFileStream, IReadOnlyCollection<DependencyNode> nodes, IObjectDumper dumper, Logger logger)
        {
            ArrayBuilder<WasmFuncType> methodSignatures = new();
            ArrayBuilder<string> methodNames = new();
            ArrayBuilder<ObjectData> methodBodies = new();
            foreach (DependencyNode node in nodes)
            {
                if (node is not ObjectNode)
                {
                    continue;
                }

                if (node is IMethodBodyNode methodNode)
                {
                    ObjectNode methodObject = (ObjectNode)node;
                    methodSignatures.Add(WasmAbiContext.GetSignature(methodNode.Method));
                    methodNames.Add(methodNode.GetMangledName(_nodeFactory.NameMangler));
                    methodBodies.Add(methodObject.GetData(_nodeFactory));
                    // TODO: record relocations and attached data
                }
            }

            IEnumerable<WasmFuncType> uniqueSignatures = methodSignatures.ToArray().Distinct();
            Dictionary<WasmFuncType, int> signatureMap = uniqueSignatures.Select((sig, i) => (sig, i)).ToDictionary();

            // TODO: The EmitSection calls here can be moved to this class'  `EmitObjectFile` implementation
            // when we can share more code with the base class.
            EmitWasmHeader(outputFileStream);
            EmitSection(() => WriteTypeSection(uniqueSignatures, logger), outputFileStream, logger);
            EmitSection(() => WriteFunctionSection(methodSignatures, signatureMap, logger), outputFileStream, logger);
            EmitSection(() => WriteExportSection(methodBodies, methodSignatures, methodNames, signatureMap, logger), outputFileStream, logger);
            EmitSection(() => WriteCodeSection(methodBodies, logger), outputFileStream, logger);
        }

        private WasmSection WriteExportSection(ArrayBuilder<ObjectData> methodNodes, ArrayBuilder<WasmFuncType> methodSignatures,
            ArrayBuilder<string> methodNames, Dictionary<WasmFuncType, int> signatureMap, Logger logger)
        {