Module: wine Branch: master Commit: 79a30a4e0ae3a7ef640fa38e3a9f77e1e73cc576 URL: http://source.winehq.org/git/wine.git/?a=commit;h=79a30a4e0ae3a7ef640fa38e3a...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Oct 26 13:28:17 2012 +0200
jscript: Optimize object refcount handling.
---
dlls/jscript/dispex.c | 78 ++++++++++++++++++++++++++++++------------------ dlls/jscript/jscript.h | 21 +++++++++++- 2 files changed, 68 insertions(+), 31 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 2a5225f..211ed8a 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -543,46 +543,23 @@ static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, return E_NOINTERFACE; }
- IUnknown_AddRef((IUnknown*)*ppv); + jsdisp_addref(This); return S_OK; }
static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface) { jsdisp_t *This = impl_from_IDispatchEx(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%d\n", This, ref); - - return ref; + jsdisp_addref(This); + return This->ref; }
static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface) { jsdisp_t *This = impl_from_IDispatchEx(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%d\n", This, ref); - - if(!ref) { - dispex_prop_t *prop; - - for(prop = This->props; prop < This->props+This->prop_cnt; prop++) { - if(prop->type == PROP_JSVAL) - jsval_release(prop->u.val); - heap_free(prop->name); - } - heap_free(This->props); - script_release(This->ctx); - if(This->prototype) - jsdisp_release(This->prototype); - - if(This->builtin_info->destructor) - This->builtin_info->destructor(This); - else - heap_free(This); - } - + ULONG ref = --This->ref; + if(!ref) + jsdisp_free(This); return ref; }
@@ -931,6 +908,49 @@ HRESULT create_dispex(script_ctx_t *ctx, const builtin_info_t *builtin_info, jsd return S_OK; }
+void jsdisp_free(jsdisp_t *obj) +{ + dispex_prop_t *prop; + + TRACE("(%p)\n", obj); + + for(prop = obj->props; prop < obj->props+obj->prop_cnt; prop++) { + if(prop->type == PROP_JSVAL) + jsval_release(prop->u.val); + heap_free(prop->name); + } + heap_free(obj->props); + script_release(obj->ctx); + if(obj->prototype) + jsdisp_release(obj->prototype); + + if(obj->builtin_info->destructor) + obj->builtin_info->destructor(obj); + else + heap_free(obj); +} + +#ifdef TRACE_REFCNT + +jsdisp_t *jsdisp_addref(jsdisp_t *jsdisp) +{ + ULONG ref = ++jsdisp->ref; + TRACE("(%p) ref=%d\n", jsdisp, ref); + return jsdisp; +} + +void jsdisp_release(jsdisp_t *jsdisp) +{ + ULONG ref = --jsdisp->ref; + + TRACE("(%p) ref=%d\n", jsdisp, ref); + + if(!ref) + jsdisp_free(jsdisp); +} + +#endif + HRESULT init_dispex_from_constr(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *constr) { jsdisp_t *prot = NULL; diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 2630ff0..18ac1db 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -223,18 +223,35 @@ static inline IDispatch *to_disp(jsdisp_t *jsdisp)
jsdisp_t *as_jsdisp(IDispatch*) DECLSPEC_HIDDEN; jsdisp_t *to_jsdisp(IDispatch*) DECLSPEC_HIDDEN; +void jsdisp_free(jsdisp_t*) DECLSPEC_HIDDEN;
+#ifndef TRACE_REFCNT + +/* + * We do a lot of refcount calls during script execution, so having an inline + * version is a nice perf win. Define TRACE_REFCNT macro when debugging + * refcount bugs to have traces. Also, since jsdisp_t is not thread safe anyways, + * there is no point in using atomic operations. + */ static inline jsdisp_t *jsdisp_addref(jsdisp_t *jsdisp) { - IDispatchEx_AddRef(&jsdisp->IDispatchEx_iface); + jsdisp->ref++; return jsdisp; }
static inline void jsdisp_release(jsdisp_t *jsdisp) { - IDispatchEx_Release(&jsdisp->IDispatchEx_iface); + if(!--jsdisp->ref) + jsdisp_free(jsdisp); }
+#else + +jsdisp_t *jsdisp_addref(jsdisp_t*) DECLSPEC_HIDDEN; +void jsdisp_release(jsdisp_t*) DECLSPEC_HIDDEN; + +#endif + HRESULT create_dispex(script_ctx_t*,const builtin_info_t*,jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN; HRESULT init_dispex(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*) DECLSPEC_HIDDEN; HRESULT init_dispex_from_constr(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*) DECLSPEC_HIDDEN;