canvas: Use non rooted variant of HTMLCanvasElementOrOffscreenCanvas type (#38970)

Any RenderingContext/OffscreenRenderingContext type has readonly
"canvas" attribute
and associated native-code DOM context objects have reference to target
DOM canvas objects.
https://html.spec.whatwg.org/multipage/canvas.html#renderingcontext
https://html.spec.whatwg.org/multipage/canvas.html#offscreenrenderingcontext

And currently the reference to DOM canvas object is the rooting pointer
on the stack,
which leads to the circular reference problem.

The SpiderMonkey's (SM) garbage collector will not be able to free the
DOM canvas and context
objects (unreacheble from JS) because of the rooting pointer on stack
(see STACK_ROOTS).

And these objects will be stored until the associated script
runtime/thread will be terminated.

SM -> JS Roots -> DOM Canvas* (on heap) -> DOM Context (on heap)
SM -> Rust Roots -> Dom Canvas* (on stack) <- as "canvas" member field

Let's replace the rooting pointer to the traceble pointer (DomRoot ->
Dom)
in the "canvas" member field of DOM context object, which allows to
broke circular referencing problem.

Testing: No changes in existed tests

Signed-off-by: Andrei Volykhin <volykhin.andrei@huawei.com>
Co-authored-by: Andrei Volykhin <volykhin.andrei@huawei.com>
This commit is contained in:
Andrei Volykhin 2025-09-03 22:24:48 +03:00 committed by GitHub
parent 2c7866eb24
commit 8a62984c2f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 191 additions and 116 deletions

View file

@ -10,14 +10,13 @@ use euclid::{Rect, Size2D};
use js::rust::HandleObject;
use webxr_api::{ContextId as WebXRContextId, LayerId, LayerInit, Viewport};
use crate::canvas_context::CanvasContext as _;
use crate::canvas_context::CanvasContext;
use crate::conversions::Convert;
use crate::dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants as constants;
use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods;
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::{
XRWebGLLayerInit, XRWebGLLayerMethods, XRWebGLRenderingContext,
};
use crate::dom::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas;
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite;
@ -125,14 +124,7 @@ impl XRWebGLLayer {
size.1.try_into().unwrap_or(0),
)
} else {
let size = match self.context().Canvas() {
HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(canvas) => canvas.get_size(),
HTMLCanvasElementOrOffscreenCanvas::OffscreenCanvas(canvas) => {
let size = canvas.get_size();
Size2D::new(size.width, size.height)
},
};
Size2D::from_untyped(size)
Size2D::from_untyped(self.context().size())
}
}