@@ -2296,7 +2296,7 @@ buddy_allocator_proc :: proc(
22962296// on the old size to work.
22972297//
22982298// The overhead of this allocator is an extra max(alignment, size_of(Header)) bytes allocated for each allocation, these bytes are
2299- // used to store the size and original pointer .
2299+ // used to store the size and alignment .
23002300Compat_Allocator :: struct {
23012301 parent: Allocator,
23022302}
@@ -2316,52 +2316,88 @@ compat_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
23162316 size, alignment: int ,
23172317 old_memory: rawptr , old_size: int ,
23182318 location := #caller_location ) -> (data: []byte , err: Allocator_Error) {
2319- size, old_size := size, old_size
2320-
23212319 Header :: struct {
2322- size: int ,
2323- ptr: rawptr ,
2320+ size: int ,
2321+ alignment: int ,
2322+ }
2323+
2324+ @(no_sanitize_address)
2325+ get_unpoisoned_header :: #force_inline proc (ptr: rawptr ) -> Header {
2326+ header := ([^]Header)(ptr)[-1 ]
2327+ a := max (header.alignment, size_of (Header))
2328+ sanitizer.address_unpoison (rawptr (uintptr (ptr)-uintptr (a)), a)
2329+ return header
23242330 }
23252331
23262332 rra := (^Compat_Allocator)(allocator_data)
23272333 switch mode {
23282334 case .Alloc, .Alloc_Non_Zeroed:
2329- a := max (alignment, size_of (Header))
2330- size += a
2331- assert (size >= 0 , " overflow" )
2335+ a := max (alignment, size_of (Header))
2336+ req_size := size + a
2337+ assert (req_size >= 0 , " overflow" )
23322338
2333- allocation := rra.parent.procedure (rra.parent.data, mode, size , alignment, old_memory, old_size, location) or_return
2339+ allocation := rra.parent.procedure (rra.parent.data, mode, req_size , alignment, old_memory, old_size, location) or_return
23342340 #no_bounds_check data = allocation[a:]
23352341
23362342 ([^]Header)(raw_data (data))[-1 ] = {
2337- size = size,
2338- ptr = raw_data (allocation) ,
2343+ size = size,
2344+ alignment = alignment ,
23392345 }
2346+
2347+ sanitizer.address_poison (raw_data (allocation), a)
23402348 return
23412349
23422350 case .Free:
2343- header := ([^]Header)(old_memory)[-1 ]
2344- return rra.parent.procedure (rra.parent.data, mode, size, alignment, header.ptr, header.size, location)
2351+ header := get_unpoisoned_header (old_memory)
2352+ a := max (header.alignment, size_of (Header))
2353+ orig_ptr := rawptr (uintptr (old_memory)-uintptr (a))
2354+ orig_size := header.size + a
2355+
2356+ return rra.parent.procedure (rra.parent.data, mode, orig_size, header.alignment, orig_ptr, orig_size, location)
23452357
23462358 case .Resize, .Resize_Non_Zeroed:
2347- header := ([^]Header)(old_memory)[-1 ]
2359+ header := get_unpoisoned_header (old_memory)
2360+ orig_a := max (header.alignment, size_of (Header))
2361+ orig_ptr := rawptr (uintptr (old_memory)-uintptr (orig_a))
2362+ orig_size := header.size + orig_a
2363+
2364+ new_alignment := max (header.alignment, alignment)
23482365
2349- a := max (alignment , size_of (header))
2350- size += a
2366+ a := max (new_alignment , size_of (header))
2367+ req_size := size + a
23512368 assert (size >= 0 , " overflow" )
23522369
2353- allocation := rra.parent.procedure (rra.parent.data, mode, size, alignment, header.ptr, header.size , location) or_return
2370+ allocation := rra.parent.procedure (rra.parent.data, mode, req_size, new_alignment, orig_ptr, orig_size , location) or_return
23542371 #no_bounds_check data = allocation[a:]
23552372
23562373 ([^]Header)(raw_data (data))[-1 ] = {
2357- size = size,
2358- ptr = raw_data (allocation) ,
2374+ size = size,
2375+ alignment = new_alignment ,
23592376 }
2377+
2378+ sanitizer.address_poison (raw_data (allocation), a)
23602379 return
23612380
2362- case .Free_All, .Query_Info, .Query_Features :
2381+ case .Free_All:
23632382 return rra.parent.procedure (rra.parent.data, mode, size, alignment, old_memory, old_size, location)
23642383
2384+ case .Query_Info:
2385+ info := (^Allocator_Query_Info)(old_memory)
2386+ if info != nil && info.pointer != nil {
2387+ header := get_unpoisoned_header (info.pointer)
2388+ info.size = header.size
2389+ info.alignment = header.alignment
2390+ }
2391+ return
2392+
2393+ case .Query_Features:
2394+ data, err = rra.parent.procedure (rra.parent.data, mode, size, alignment, old_memory, old_size, location)
2395+ if err != nil {
2396+ set := (^Allocator_Mode_Set)(old_memory)
2397+ set^ += {.Query_Info}
2398+ }
2399+ return
2400+
23652401 case : unreachable ()
23662402 }
23672403}
0 commit comments