changeset 766:be0e02948c1d

Improve resource management for coords, shapes and paints. - Make paint to use weak reference to release resource before collected. - Call Persistent<Object>::Dispose() before deleting the handle variable. Dispose() will real release Persistent handle. Handle variable is just a pointer to the handle.
author Thinker K.F. Li <thinker@codemud.net>
date Sun, 29 Aug 2010 13:34:40 +0800
parents a49358b040b5
children 9d430b084a13
files nodejs/coord.cc nodejs/paints.cc nodejs/paints.m4 nodejs/shapes.cc
diffstat 4 files changed, 55 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/nodejs/coord.cc	Sun Aug 29 00:42:16 2010 +0800
+++ b/nodejs/coord.cc	Sun Aug 29 13:34:40 2010 +0800
@@ -81,6 +81,7 @@
 						      PROP_JSOBJ);
 	SET(*child_hdl, "valid", _false);
 	WRAP(*child_hdl, NULL);
+	child_hdl->Dispose();
 	delete child_hdl;
 	
 	/* Invalidate members of a coord */
@@ -89,6 +90,7 @@
 							PROP_JSOBJ);
 	    SET(*mem_hdl, "valid", _false);
 	    WRAP(*mem_hdl, NULL);
+	    mem_hdl->Dispose();
 	    delete mem_hdl;
 	}
     }
--- a/nodejs/paints.cc	Sun Aug 29 00:42:16 2010 +0800
+++ b/nodejs/paints.cc	Sun Aug 29 13:34:40 2010 +0800
@@ -30,9 +30,37 @@
  * resource before it being collected.
  */
 static void
+xnjsmb_paint_recycle(Persistent<Value> obj, void *parameter) {
+    Persistent<Object> *paint_hdl = (Persistent<Object> *)parameter;
+    paint_t *paint;
+    Handle<Object> rt;
+    redraw_man_t *rdman;
+    
+    paint = (paint_t *)UNWRAP(*paint_hdl);
+    rt = GET(*paint_hdl, "mbrt")->ToObject();
+    rdman = xnjsmb_rt_rdman(rt);
+    
+    rdman_paint_free(rdman, paint);
+    
+    paint_hdl->Dispose();
+    delete paint_hdl;
+}
+
+static void
+xnjsmb_paint_mod(Handle<Object> self, void *paint) {
+    Persistent<Object> *paint_hdl;
+    
+    paint_hdl = new Persistent<Object>();
+    *paint_hdl = Persistent<Object>::New(self);
+
+    paint_hdl->MakeWeak(paint_hdl, xnjsmb_paint_recycle);
+}
+
+static void
 xnjsmb_paint_fill(paint_t *paint, Handle<Object> self, shape_t *sh) {
     Handle<Value> rt_v;
     Handle<Object> rt_o;
+    Handle<Object> sh_o;
     redraw_man_t *rdman;
 
     rt_v = GET(self, "mbrt");
@@ -43,12 +71,16 @@
     
     if(sh_get_coord(sh))
 	rdman_shape_changed(rdman, sh);
+
+    sh_o = *(Persistent<Object> *)mb_prop_get(&sh->obj.props, PROP_JSOBJ);
+    SET(sh_o, "_fill_by", self);
 }
 
 static void
 xnjsmb_paint_stroke(paint_t *paint, Handle<Object> self, shape_t *sh) {
     Handle<Value> rt_v;
     Handle<Object> rt_o;
+    Handle<Object> sh_o;
     redraw_man_t *rdman;
 
     rt_v = GET(self, "mbrt");
@@ -59,6 +91,9 @@
     
     if(sh_get_coord(sh))
 	rdman_shape_changed(rdman, sh);
+
+    sh_o = *(Persistent<Object> *)mb_prop_get(&sh->obj.props, PROP_JSOBJ);
+    SET(sh_o, "_stroke_by", self);
 }
 
 static void
--- a/nodejs/paints.m4	Sun Aug 29 00:42:16 2010 +0800
+++ b/nodejs/paints.m4	Sun Aug 29 13:34:40 2010 +0800
@@ -10,18 +10,22 @@
        [METHOD([set_color], [xnjsmb_paint_color_set_color],
        	       (SELF, NUMBER([r]), NUMBER([g]), NUMBER([b]), NUMBER([a])),
 	       4, [])],
-       (([INHERIT], [paint])))
+       (([INHERIT], [paint]),
+        ([STMOD], [xnjsmb_paint_mod])))
 
 STRUCT([paint_image], [paint_t], [],
        [],
-       (([INHERIT], [paint])))
+       (([INHERIT], [paint]),
+       ([STMOD], [xnjsmb_paint_mod])))
 
 STRUCT([paint_linear], [paint_t], [],
        [METHOD([set_stops], [xnjsmb_paint_linear_set_stops],
        (ARRAY([stops])), 1, [])],
-       (([INHERIT], [paint])))
+       (([INHERIT], [paint]),
+        ([STMOD], [xnjsmb_paint_mod])))
 
 STRUCT([paint_radial], [paint_t], [],
        [METHOD([set_stops], [xnjsmb_paint_radial_set_stops],
        (ARRAY([stops])), 1, [])],
-       (([INHERIT], [paint])))
+       (([INHERIT], [paint]),
+        ([STMOD], [xnjsmb_paint_mod])))
--- a/nodejs/shapes.cc	Sun Aug 29 00:42:16 2010 +0800
+++ b/nodejs/shapes.cc	Sun Aug 29 13:34:40 2010 +0800
@@ -42,12 +42,14 @@
     rdman_shape_changed(rdman, shape);
     rdman_shape_free(rdman, shape);
 
+    self_hdl->Dispose();
     delete self_hdl;
 }
 
 static void
 xnjsmb_shape_mod(Handle<Object> self, shape_t *sh) {
     Persistent<Object> *self_hdl;
+    static int count = 0;
     
     /* Keep associated js object in property store for retrieving,
      * later, without create new js object.
@@ -57,6 +59,13 @@
     mb_prop_set(&sh->obj.props, PROP_JSOBJ, self_hdl);
 
     self_hdl->MakeWeak(self_hdl, xnjsmb_shape_recycled);
+
+    /* XXX: should be remove.  It is for trace recycle of shape */
+    count++;
+    if(count > 10000) {
+	V8::LowMemoryNotification();
+	count = 0;
+    }
 }
 
 static void
@@ -178,6 +187,7 @@
     if(r != OK)
 	THROW_noret("Can not free a shape for unknown reason");
 
+    self_hdl->Dispose();
     delete self_hdl;
 }