From d7cc959ec2bd6784985af70466fe284ccfae17ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Thu, 21 May 2026 23:41:59 +0200 Subject: [PATCH] Fix text truncation for frames named after Object.prototype methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TextMeasurement's width cache was a plain object, so looking up `_cache["toString"]` returned Object.prototype.toString instead of undefined. getFittedText treated that function as a cached width, which collapsed the truncation algorithm and produced just "…". This affected JS frames whose names collide with Object.prototype: toString, hasOwnProperty, valueOf, constructor, isPrototypeOf, propertyIsEnumerable, toLocaleString, __proto__. Visible in the flame graph, stack chart, marker chart, and js-tracer canvases. Switching the cache to a Map solves this problem. --- src/utils/text-measurement.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils/text-measurement.ts b/src/utils/text-measurement.ts index 71c6fde133..319915df8b 100644 --- a/src/utils/text-measurement.ts +++ b/src/utils/text-measurement.ts @@ -14,14 +14,14 @@ */ class TextMeasurement { _ctx: CanvasRenderingContext2D; - _cache: { [id: string]: number }; + _cache: Map; _averageCharWidth: number; overflowChar: string; minWidth: number; constructor(ctx: CanvasRenderingContext2D) { this._ctx = ctx; - this._cache = {}; + this._cache = new Map(); this._averageCharWidth = this._calcAverageCharWidth(); // TODO - L10N @@ -50,12 +50,12 @@ class TextMeasurement { * @return {number} The text width. */ getTextWidth(text: string): number { - const cachedWidth = this._cache[text]; + const cachedWidth = this._cache.get(text); if (cachedWidth !== undefined) { return cachedWidth; } const metrics = this._ctx.measureText(text); - this._cache[text] = metrics.width; + this._cache.set(text, metrics.width); return metrics.width; }