Module: wine Branch: master Commit: 924cad5f3b7d7d3a2574ed6ff5396bcbd2f422ea URL: http://source.winehq.org/git/wine.git/?a=commit;h=924cad5f3b7d7d3a2574ed6ff5...
Author: Huw Davies huw@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@codeweavers.com Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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]);