浏览代码

Fix memory leak in core

Evan Almloff 1 年之前
父节点
当前提交
943c76b1da
共有 3 个文件被更改,包括 15 次插入10 次删除
  1. 6 2
      packages/core/src/create.rs
  2. 7 7
      packages/core/src/nodes.rs
  3. 2 1
      packages/rsx/src/lib.rs

+ 6 - 2
packages/core/src/create.rs

@@ -87,8 +87,12 @@ impl<'b> VirtualDom {
             }
         }
 
-        // Intialize the root nodes slice
-        *node.root_ids.borrow_mut() = vec![ElementId(0); node.template.get().roots.len()];
+        // Initialize the root nodes slice
+        {
+            let mut nodes_mut = node.root_ids.borrow_mut();
+            let len = node.template.get().roots.len();
+            nodes_mut.resize(len, ElementId::default());
+        };
 
         // The best renderers will have templates prehydrated and registered
         // Just in case, let's create the template using instructions anyways

+ 7 - 7
packages/core/src/nodes.rs

@@ -54,7 +54,7 @@ pub struct VNode<'a> {
 
     /// The IDs for the roots of this template - to be used when moving the template around and removing it from
     /// the actual Dom
-    pub root_ids: RefCell<Vec<ElementId>>,
+    pub root_ids: RefCell<bumpalo::collections::Vec<'a, ElementId>>,
 
     /// The dynamic parts of the template
     pub dynamic_nodes: &'a [DynamicNode<'a>],
@@ -65,11 +65,11 @@ pub struct VNode<'a> {
 
 impl<'a> VNode<'a> {
     /// Create a template with no nodes that will be skipped over during diffing
-    pub fn empty() -> Element<'a> {
+    pub fn empty(cx: &'a ScopeState) -> Element<'a> {
         Some(VNode {
             key: None,
             parent: None,
-            root_ids: Default::default(),
+            root_ids: RefCell::new(bumpalo::collections::Vec::new_in(cx.bump())),
             dynamic_nodes: &[],
             dynamic_attrs: &[],
             template: Cell::new(Template {
@@ -698,7 +698,7 @@ impl<'a, 'b> IntoDynNode<'a> for LazyNodes<'a, 'b> {
 impl<'a, 'b> IntoDynNode<'b> for &'a str {
     fn into_vnode(self, cx: &'b ScopeState) -> DynamicNode<'b> {
         DynamicNode::Text(VText {
-            value: bumpalo::collections::String::from_str_in(self, cx.bump()).into_bump_str(),
+            value: cx.bump().alloc_str(self),
             id: Default::default(),
         })
     }
@@ -741,10 +741,10 @@ impl<'a> IntoTemplate<'a> for VNode<'a> {
     }
 }
 impl<'a> IntoTemplate<'a> for Element<'a> {
-    fn into_template(self, _cx: &'a ScopeState) -> VNode<'a> {
+    fn into_template(self, cx: &'a ScopeState) -> VNode<'a> {
         match self {
-            Some(val) => val.into_template(_cx),
-            _ => VNode::empty().unwrap(),
+            Some(val) => val.into_template(cx),
+            _ => VNode::empty(cx).unwrap(),
         }
     }
 }

+ 2 - 1
packages/rsx/src/lib.rs

@@ -231,6 +231,7 @@ impl<'a> ToTokens for TemplateRenderer<'a> {
 
         // Render and release the mutable borrow on context
         let roots = quote! { #( #root_printer ),* };
+        let root_count = self.roots.len();
         let node_printer = &context.dynamic_nodes;
         let dyn_attr_printer = &context.dynamic_attributes;
         let node_paths = context.node_paths.iter().map(|it| quote!(&[#(#it),*]));
@@ -247,7 +248,7 @@ impl<'a> ToTokens for TemplateRenderer<'a> {
                 parent: None,
                 key: #key_tokens,
                 template: std::cell::Cell::new(TEMPLATE),
-                root_ids: Default::default(),
+                root_ids: dioxus::core::exports::bumpalo::collections::Vec::with_capacity_in(#root_count, __cx.bump()).into(),
                 dynamic_nodes: __cx.bump().alloc([ #( #node_printer ),* ]),
                 dynamic_attrs: __cx.bump().alloc([ #( #dyn_attr_printer ),* ]),
             }