jscript: Optimize object refcount handling.
This commit is contained in:
parent
90c6f57fa9
commit
79a30a4e0a
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue