# HG changeset patch # User Thinker K.F. Li # Date 1283060080 -28800 # Node ID be0e02948c1d54a07554a66427231961547c483b # Parent a49358b040b5227c979daa748202d19983eed9b9 Improve resource management for coords, shapes and paints. - Make paint to use weak reference to release resource before collected. - Call Persistent::Dispose() before deleting the handle variable. Dispose() will real release Persistent handle. Handle variable is just a pointer to the handle. diff -r a49358b040b5 -r be0e02948c1d nodejs/coord.cc --- 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; } } diff -r a49358b040b5 -r be0e02948c1d nodejs/paints.cc --- 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 obj, void *parameter) { + Persistent *paint_hdl = (Persistent *)parameter; + paint_t *paint; + Handle 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 self, void *paint) { + Persistent *paint_hdl; + + paint_hdl = new Persistent(); + *paint_hdl = Persistent::New(self); + + paint_hdl->MakeWeak(paint_hdl, xnjsmb_paint_recycle); +} + +static void xnjsmb_paint_fill(paint_t *paint, Handle self, shape_t *sh) { Handle rt_v; Handle rt_o; + Handle 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 *)mb_prop_get(&sh->obj.props, PROP_JSOBJ); + SET(sh_o, "_fill_by", self); } static void xnjsmb_paint_stroke(paint_t *paint, Handle self, shape_t *sh) { Handle rt_v; Handle rt_o; + Handle 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 *)mb_prop_get(&sh->obj.props, PROP_JSOBJ); + SET(sh_o, "_stroke_by", self); } static void diff -r a49358b040b5 -r be0e02948c1d nodejs/paints.m4 --- 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]))) diff -r a49358b040b5 -r be0e02948c1d nodejs/shapes.cc --- 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 self, shape_t *sh) { Persistent *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; }