Index: lib/sanitizer_common/sanitizer_allocator_primary64.h =================================================================== --- lib/sanitizer_common/sanitizer_allocator_primary64.h +++ lib/sanitizer_common/sanitizer_allocator_primary64.h @@ -94,6 +94,13 @@ return P >= SpaceBeg() && P < SpaceEnd(); } + uptr GetRegionBegin(const void *p) { + if (kUsingConstantSpaceBeg) + return reinterpret_cast(p) & ~(kRegionSize - 1); + uptr space_beg = SpaceBeg(); + return ((reinterpret_cast(p) - space_beg) & ~(kRegionSize - 1)) + space_beg; + } + uptr GetSizeClass(const void *p) { if (kUsingConstantSpaceBeg && (kSpaceBeg % kSpaceSize) == 0) return ((reinterpret_cast(p)) / kRegionSize) % kNumClassesRounded; @@ -106,7 +113,7 @@ uptr size = SizeClassMap::Size(class_id); if (!size) return nullptr; uptr chunk_idx = GetChunkIdx((uptr)p, size); - uptr reg_beg = (uptr)p & ~(kRegionSize - 1); + uptr reg_beg = GetRegionBegin(p); uptr beg = chunk_idx * size; uptr next_beg = beg + size; if (class_id >= kNumClasses) return nullptr; @@ -258,7 +265,10 @@ return ®ions[class_id]; } - static uptr GetChunkIdx(uptr chunk, uptr size) { + uptr GetChunkIdx(uptr chunk, uptr size) { + if (!kUsingConstantSpaceBeg) + chunk -= SpaceBeg(); + uptr offset = chunk % kRegionSize; // Here we divide by a non-constant. This is costly. // size always fits into 32-bits. If the offset fits too, use 32-bit div. Index: lib/sanitizer_common/sanitizer_win.cc =================================================================== --- lib/sanitizer_common/sanitizer_win.cc +++ lib/sanitizer_common/sanitizer_win.cc @@ -221,8 +221,12 @@ } void *MmapNoAccess(uptr size) { - // FIXME: unsupported. - return nullptr; + void *res = VirtualAlloc(nullptr, size, MEM_RESERVE, PAGE_NOACCESS); + if (res == 0) + Report("WARNING: %s failed to " + "mprotect %p (%zd) bytes (error code: %d)\n", + SanitizerToolName, size, size, GetLastError()); + return res; } bool MprotectNoAccess(uptr addr, uptr size) { Index: lib/sanitizer_common/tests/sanitizer_allocator_test.cc =================================================================== --- lib/sanitizer_common/tests/sanitizer_allocator_test.cc +++ lib/sanitizer_common/tests/sanitizer_allocator_test.cc @@ -30,7 +30,10 @@ #if SANITIZER_CAN_USE_ALLOCATOR64 #if SANITIZER_WINDOWS -static const uptr kAllocatorSpace = 0x10000000000ULL; +// On Windows 64-bit there is no easy way to find a large enough fixed address +// space that is always available. Thus, a dynamically allocated address space +// is used instead (i.e. ~(uptr)0). +static const uptr kAllocatorSpace = ~(uptr)0; static const uptr kAllocatorSize = 0x10000000000ULL; // 1T. static const u64 kAddressSpaceSize = 1ULL << 40; #else @@ -41,6 +44,8 @@ typedef SizeClassAllocator64< kAllocatorSpace, kAllocatorSize, 16, DefaultSizeClassMap> Allocator64; +typedef SizeClassAllocator64< + ~(uptr)0, kAllocatorSize, 16, DefaultSizeClassMap> Allocator64Dynamic; typedef SizeClassAllocator64< kAllocatorSpace, kAllocatorSize, 16, CompactSizeClassMap> Allocator64Compact; @@ -158,6 +163,10 @@ TestSizeClassAllocator(); } +TEST(SanitizerCommon, SizeClassAllocator64Dynamic) { + TestSizeClassAllocator(); +} + TEST(SanitizerCommon, SizeClassAllocator64Compact) { TestSizeClassAllocator(); } @@ -202,6 +211,10 @@ SizeClassAllocatorMetadataStress(); } +TEST(SanitizerCommon, SizeClassAllocator64DynamicMetadataStress) { + SizeClassAllocatorMetadataStress(); +} + TEST(SanitizerCommon, SizeClassAllocator64CompactMetadataStress) { SizeClassAllocatorMetadataStress(); } @@ -238,6 +251,9 @@ TEST(SanitizerCommon, SizeClassAllocator64GetBlockBegin) { SizeClassAllocatorGetBlockBeginStress(); } +TEST(SanitizerCommon, SizeClassAllocator64DynamicGetBlockBegin) { + SizeClassAllocatorGetBlockBeginStress(); +} TEST(SanitizerCommon, SizeClassAllocator64CompactGetBlockBegin) { SizeClassAllocatorGetBlockBeginStress(); } @@ -484,6 +500,12 @@ SizeClassAllocatorLocalCache > (); } +TEST(SanitizerCommon, CombinedAllocator64Dynamic) { + TestCombinedAllocator, + SizeClassAllocatorLocalCache > (); +} + TEST(SanitizerCommon, CombinedAllocator64Compact) { TestCombinedAllocator, @@ -537,6 +559,11 @@ SizeClassAllocatorLocalCache >(); } +TEST(SanitizerCommon, SizeClassAllocator64DynamicLocalCache) { + TestSizeClassAllocatorLocalCache< + SizeClassAllocatorLocalCache >(); +} + TEST(SanitizerCommon, SizeClassAllocator64CompactLocalCache) { TestSizeClassAllocatorLocalCache< SizeClassAllocatorLocalCache >(); @@ -710,6 +737,9 @@ TEST(SanitizerCommon, SizeClassAllocator64Iteration) { TestSizeClassAllocatorIteration(); } +TEST(SanitizerCommon, SizeClassAllocator64DynamicIteration) { + TestSizeClassAllocatorIteration(); +} #endif TEST(SanitizerCommon, SizeClassAllocator32Iteration) {