TEST_END TEST_BEGIN(test_oom) { size_t hugemax, size, alignment; hugemax = get_huge_size(get_nhuge()-1); /* * It should be impossible to allocate two objects that each consume * more than half the virtual address space. */ { void *p; p = mallocx(hugemax, 0); if (p != NULL) { assert_ptr_null(mallocx(hugemax, 0), "Expected OOM for mallocx(size=%#zx, 0)", hugemax); dallocx(p, 0); } } #if LG_SIZEOF_PTR == 3 size = ZU(0x8000000000000000); alignment = ZU(0x8000000000000000); #else size = ZU(0x80000000); alignment = ZU(0x80000000); #endif assert_ptr_null(mallocx(size, MALLOCX_ALIGN(alignment)), "Expected OOM for mallocx(size=%#zx, MALLOCX_ALIGN(%#zx)", size, alignment); }
TEST_END TEST_BEGIN(test_extra_small) { size_t small0, small1, hugemax; void *p; /* Get size classes. */ small0 = get_small_size(0); small1 = get_small_size(1); hugemax = get_huge_size(get_nhuge()-1); p = mallocx(small0, 0); assert_ptr_not_null(p, "Unexpected mallocx() error"); assert_zu_eq(xallocx(p, small1, 0, 0), small0, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, small1, 0, 0), small0, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, small0, small1 - small0, 0), small0, "Unexpected xallocx() behavior"); /* Test size+extra overflow. */ assert_zu_eq(xallocx(p, small0, hugemax - small0 + 1, 0), small0, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, small0, SIZE_T_MAX - small0, 0), small0, "Unexpected xallocx() behavior"); dallocx(p, 0); }
TEST_END TEST_BEGIN(test_size_extra_overflow) { size_t small0, hugemax; void *p; /* Get size classes. */ small0 = get_small_size(0); hugemax = get_huge_size(get_nhuge()-1); p = mallocx(small0, 0); assert_ptr_not_null(p, "Unexpected mallocx() error"); /* Test overflows that can be resolved by clamping extra. */ assert_zu_le(xallocx(p, hugemax-1, 2, 0), hugemax, "Unexpected xallocx() behavior"); assert_zu_le(xallocx(p, hugemax, 1, 0), hugemax, "Unexpected xallocx() behavior"); /* Test overflow such that hugemax-size underflows. */ assert_zu_le(xallocx(p, hugemax+1, 2, 0), hugemax, "Unexpected xallocx() behavior"); assert_zu_le(xallocx(p, hugemax+2, 3, 0), hugemax, "Unexpected xallocx() behavior"); assert_zu_le(xallocx(p, SIZE_T_MAX-2, 2, 0), hugemax, "Unexpected xallocx() behavior"); assert_zu_le(xallocx(p, SIZE_T_MAX-1, 1, 0), hugemax, "Unexpected xallocx() behavior"); dallocx(p, 0); }
TEST_END TEST_BEGIN(test_oom) { size_t hugemax; bool oom; void *ptrs[3]; unsigned i; /* * It should be impossible to allocate three objects that each consume * nearly half the virtual address space. */ hugemax = get_huge_size(get_nhuge()-1); oom = false; for (i = 0; i < sizeof(ptrs) / sizeof(void *); i++) { ptrs[i] = mallocx(hugemax, 0); if (ptrs[i] == NULL) oom = true; } assert_true(oom, "Expected OOM during series of calls to mallocx(size=%zu, 0)", hugemax); for (i = 0; i < sizeof(ptrs) / sizeof(void *); i++) { if (ptrs[i] != NULL) dallocx(ptrs[i], 0); } #if LG_SIZEOF_PTR == 3 assert_ptr_null(mallocx(0x8000000000000000ULL, MALLOCX_ALIGN(0x8000000000000000ULL)), "Expected OOM for mallocx()"); assert_ptr_null(mallocx(0x8000000000000000ULL, MALLOCX_ALIGN(0x80000000)), "Expected OOM for mallocx()"); #else assert_ptr_null(mallocx(0x80000000UL, MALLOCX_ALIGN(0x80000000UL)), "Expected OOM for mallocx()"); #endif }
TEST_END TEST_BEGIN(test_extra_huge) { int flags = MALLOCX_ARENA(arena_ind()); size_t largemax, huge1, huge2, huge3, hugemax; void *p; /* Get size classes. */ largemax = get_large_size(get_nlarge()-1); huge1 = get_huge_size(1); huge2 = get_huge_size(2); huge3 = get_huge_size(3); hugemax = get_huge_size(get_nhuge()-1); p = mallocx(huge3, flags); assert_ptr_not_null(p, "Unexpected mallocx() error"); assert_zu_eq(xallocx(p, huge3, 0, flags), huge3, "Unexpected xallocx() behavior"); /* Test size decrease with zero extra. */ assert_zu_ge(xallocx(p, huge1, 0, flags), huge1, "Unexpected xallocx() behavior"); assert_zu_ge(xallocx(p, largemax, 0, flags), huge1, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, huge3, 0, flags), huge3, "Unexpected xallocx() behavior"); /* Test size decrease with non-zero extra. */ assert_zu_eq(xallocx(p, huge1, huge3 - huge1, flags), huge3, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, huge2, huge3 - huge2, flags), huge3, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, huge1, huge2 - huge1, flags), huge2, "Unexpected xallocx() behavior"); assert_zu_ge(xallocx(p, largemax, huge1 - largemax, flags), huge1, "Unexpected xallocx() behavior"); assert_zu_ge(xallocx(p, huge1, 0, flags), huge1, "Unexpected xallocx() behavior"); /* Test size increase with zero extra. */ assert_zu_le(xallocx(p, huge3, 0, flags), huge3, "Unexpected xallocx() behavior"); assert_zu_le(xallocx(p, hugemax+1, 0, flags), huge3, "Unexpected xallocx() behavior"); assert_zu_ge(xallocx(p, huge1, 0, flags), huge1, "Unexpected xallocx() behavior"); /* Test size increase with non-zero extra. */ assert_zu_le(xallocx(p, huge1, SIZE_T_MAX - huge1, flags), hugemax, "Unexpected xallocx() behavior"); assert_zu_ge(xallocx(p, huge1, 0, flags), huge1, "Unexpected xallocx() behavior"); /* Test size increase with non-zero extra. */ assert_zu_le(xallocx(p, huge1, huge3 - huge1, flags), huge3, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, huge3, 0, flags), huge3, "Unexpected xallocx() behavior"); /* Test size+extra overflow. */ assert_zu_le(xallocx(p, huge3, hugemax - huge3 + 1, flags), hugemax, "Unexpected xallocx() behavior"); dallocx(p, flags); }
TEST_END TEST_BEGIN(test_extra_large) { int flags = MALLOCX_ARENA(arena_ind()); size_t smallmax, large0, large1, large2, huge0, hugemax; void *p; /* Get size classes. */ smallmax = get_small_size(get_nsmall()-1); large0 = get_large_size(0); large1 = get_large_size(1); large2 = get_large_size(2); huge0 = get_huge_size(0); hugemax = get_huge_size(get_nhuge()-1); p = mallocx(large2, flags); assert_ptr_not_null(p, "Unexpected mallocx() error"); assert_zu_eq(xallocx(p, large2, 0, flags), large2, "Unexpected xallocx() behavior"); /* Test size decrease with zero extra. */ assert_zu_eq(xallocx(p, large0, 0, flags), large0, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, smallmax, 0, flags), large0, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, large2, 0, flags), large2, "Unexpected xallocx() behavior"); /* Test size decrease with non-zero extra. */ assert_zu_eq(xallocx(p, large0, large2 - large0, flags), large2, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, large1, large2 - large1, flags), large2, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, large0, large1 - large0, flags), large1, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, smallmax, large0 - smallmax, flags), large0, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, large0, 0, flags), large0, "Unexpected xallocx() behavior"); /* Test size increase with zero extra. */ assert_zu_eq(xallocx(p, large2, 0, flags), large2, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, huge0, 0, flags), large2, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, large0, 0, flags), large0, "Unexpected xallocx() behavior"); /* Test size increase with non-zero extra. */ assert_zu_lt(xallocx(p, large0, huge0 - large0, flags), huge0, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, large0, 0, flags), large0, "Unexpected xallocx() behavior"); /* Test size increase with non-zero extra. */ assert_zu_eq(xallocx(p, large0, large2 - large0, flags), large2, "Unexpected xallocx() behavior"); assert_zu_eq(xallocx(p, large2, 0, flags), large2, "Unexpected xallocx() behavior"); /* Test size+extra overflow. */ assert_zu_lt(xallocx(p, large2, hugemax - large2 + 1, flags), huge0, "Unexpected xallocx() behavior"); dallocx(p, flags); }