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