Huw Davies : oleaut32: Use IMalloc_GetSize to determine the cache bucket.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Jan 21 11:22:05 CST 2016
Module: wine
Branch: master
Commit: 924cad5f3b7d7d3a2574ed6ff5396bcbd2f422ea
URL: http://source.winehq.org/git/wine.git/?a=commit;h=924cad5f3b7d7d3a2574ed6ff5396bcbd2f422ea
Author: Huw Davies <huw at codeweavers.com>
Date: Thu Jan 21 10:29:51 2016 +0000
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 at codeweavers.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/oleaut32/oleaut.c | 36 +++++++++++++++++++++++++++++++++---
dlls/oleaut32/tests/vartype.c | 10 ++++++++--
2 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/dlls/oleaut32/oleaut.c b/dlls/oleaut32/oleaut.c
index 07db9ff..00e6daf 100644
--- a/dlls/oleaut32/oleaut.c
+++ b/dlls/oleaut32/oleaut.c
@@ -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;
diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c
index f7df9c5..03f43ec 100644
--- a/dlls/oleaut32/tests/vartype.c
+++ b/dlls/oleaut32/tests/vartype.c
@@ -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]);
More information about the wine-cvs
mailing list