stack-memory.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import path from "path";
  2. import fs from "fs/promises";
  3. import { BenchData, StackMemory, spawn } from "../scripts/utils";
  4. const IDL = require("../target/idl/bench.json");
  5. describe("Stack memory", () => {
  6. const stackMemory: StackMemory = {};
  7. const STACK_CONTENT = [
  8. "",
  9. `let stack_limit: [u16; 2048] = [1; 2048];`,
  10. `msg!("{}", stack_limit[2047]);`,
  11. "",
  12. ].join("\n\t\t");
  13. it("Measure stack memory usage", async () => {
  14. const libPath = path.join("programs", IDL.metadata.name, "src", "lib.rs");
  15. const lib = await fs.readFile(libPath, "utf8");
  16. const indices = [...lib.matchAll(/fn\s[\w\d]+\(/g)]
  17. .map((match) => match.index)
  18. .filter(Boolean) as number[];
  19. let modifiedLib = lib;
  20. let cumulativeIndex = 0;
  21. for (const index of indices) {
  22. const curlyIndex = index + lib.slice(index).indexOf("{");
  23. const nextLineIndex =
  24. curlyIndex + lib.slice(curlyIndex).indexOf("\n") + cumulativeIndex;
  25. modifiedLib =
  26. modifiedLib.slice(0, nextLineIndex) +
  27. STACK_CONTENT +
  28. modifiedLib.slice(nextLineIndex);
  29. cumulativeIndex += STACK_CONTENT.length;
  30. }
  31. // Write the modified file
  32. await fs.writeFile(libPath, modifiedLib);
  33. // Expected error:
  34. // Error: Function _ZN5bench9__private8__global13account_info117h88e5c10f03de9fddE
  35. // Stack offset of 4424 exceeded max offset of 4096 by 328 bytes
  36. const buildResult = spawn("anchor", ["build", "--skip-lint"]);
  37. const output = buildResult.output.toString();
  38. const matches = output.matchAll(
  39. /global[\d]+([\w\d]+?)17.*by\s(\d+)\sbytes/g
  40. );
  41. for (const match of matches) {
  42. const ixName = match[1];
  43. const stackUsage = match[2];
  44. stackMemory[ixName] = +stackUsage;
  45. }
  46. // Restore to the original file
  47. await fs.writeFile(libPath, lib);
  48. });
  49. after(async () => {
  50. const bench = await BenchData.open();
  51. await bench.update({ stackMemory });
  52. });
  53. });