oleaut32: Use IMalloc_GetSize to determine the cache bucket.
This also has the effect of ignoring non-allocated memory blocks. Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
36f454cda0
commit
924cad5f3b
|
@ -120,14 +120,27 @@ static inline bstr_t *bstr_from_str(BSTR str)
|
|||
return CONTAINING_RECORD(str, bstr_t, u.str);
|
||||
}
|
||||
|
||||
static inline bstr_cache_entry_t *get_cache_entry(size_t size)
|
||||
static inline bstr_cache_entry_t *get_cache_entry_from_idx(unsigned cache_idx)
|
||||
{
|
||||
unsigned cache_idx = FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)-1])/BUCKET_SIZE;
|
||||
return bstr_cache_enabled && cache_idx < sizeof(bstr_cache)/sizeof(*bstr_cache)
|
||||
? bstr_cache + cache_idx
|
||||
: NULL;
|
||||
}
|
||||
|
||||
static inline bstr_cache_entry_t *get_cache_entry(size_t size)
|
||||
{
|
||||
unsigned cache_idx = FIELD_OFFSET(bstr_t, u.ptr[size+sizeof(WCHAR)-1])/BUCKET_SIZE;
|
||||
return get_cache_entry_from_idx(cache_idx);
|
||||
}
|
||||
|
||||
static inline bstr_cache_entry_t *get_cache_entry_from_alloc_size(SIZE_T alloc_size)
|
||||
{
|
||||
unsigned cache_idx;
|
||||
if (alloc_size < BUCKET_SIZE) return NULL;
|
||||
cache_idx = (alloc_size - BUCKET_SIZE) / BUCKET_SIZE;
|
||||
return get_cache_entry_from_idx(cache_idx);
|
||||
}
|
||||
|
||||
static bstr_t *alloc_bstr(size_t size)
|
||||
{
|
||||
bstr_cache_entry_t *cache_entry = get_cache_entry(size);
|
||||
|
@ -234,6 +247,16 @@ BSTR WINAPI SysAllocString(LPCOLESTR str)
|
|||
return SysAllocStringLen(str, lstrlenW(str));
|
||||
}
|
||||
|
||||
static inline IMalloc *get_malloc(void)
|
||||
{
|
||||
static IMalloc *malloc;
|
||||
|
||||
if (!malloc)
|
||||
CoGetMalloc(1, &malloc);
|
||||
|
||||
return malloc;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* SysFreeString [OLEAUT32.6]
|
||||
*
|
||||
|
@ -253,12 +276,19 @@ void WINAPI SysFreeString(BSTR str)
|
|||
{
|
||||
bstr_cache_entry_t *cache_entry;
|
||||
bstr_t *bstr;
|
||||
IMalloc *malloc = get_malloc();
|
||||
SIZE_T alloc_size;
|
||||
|
||||
if(!str)
|
||||
return;
|
||||
|
||||
bstr = bstr_from_str(str);
|
||||
cache_entry = get_cache_entry(bstr->size);
|
||||
|
||||
alloc_size = IMalloc_GetSize(malloc, bstr);
|
||||
if (alloc_size == ~0UL)
|
||||
return;
|
||||
|
||||
cache_entry = get_cache_entry_from_alloc_size(alloc_size);
|
||||
if(cache_entry) {
|
||||
unsigned i;
|
||||
|
||||
|
|
|
@ -6369,9 +6369,15 @@ static void test_bstr_cache(void)
|
|||
ok(str == str2, "str != str2\n");
|
||||
SysFreeString(str2);
|
||||
|
||||
/* Fill the bucket with cached entries. */
|
||||
/* Fill the bucket with cached entries.
|
||||
We roll our own, to show that the cache doesn't use
|
||||
the bstr length field to determine bucket allocation. */
|
||||
for(i=0; i < sizeof(strs)/sizeof(*strs); i++)
|
||||
strs[i] = SysAllocStringLen(NULL, 24);
|
||||
{
|
||||
DWORD_PTR *ptr = CoTaskMemAlloc(64);
|
||||
ptr[0] = 0;
|
||||
strs[i] = (BSTR)(ptr + 1);
|
||||
}
|
||||
for(i=0; i < sizeof(strs)/sizeof(*strs); i++)
|
||||
SysFreeString(strs[i]);
|
||||
|
||||
|
|
Loading…
Reference in New Issue