Coverage Report

Created: 2024-09-14 07:19

/src/skia/src/base/SkContainers.cpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2019 Google LLC.
2
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3
4
#include "include/private/base/SkContainers.h"
5
6
#include "include/private/base/SkAlign.h"
7
#include "include/private/base/SkAssert.h"
8
#include "include/private/base/SkMalloc.h"
9
#include "include/private/base/SkTo.h"
10
11
#include <algorithm>
12
#include <cstddef>
13
14
namespace {
15
// Return at least as many bytes to keep malloc aligned.
16
constexpr size_t kMinBytes = alignof(max_align_t);
17
18
76.7M
SkSpan<std::byte> complete_size(void* ptr, size_t size) {
19
76.7M
    if (ptr == nullptr) {
20
0
        return {};
21
0
    }
22
23
76.7M
    return {static_cast<std::byte*>(ptr), sk_malloc_size(ptr, size)};
24
76.7M
}
25
}  // namespace
26
27
76.7M
SkSpan<std::byte> SkContainerAllocator::allocate(int capacity, double growthFactor) {
28
76.7M
    SkASSERT(capacity >= 0);
29
76.7M
    SkASSERT(growthFactor >= 1.0);
30
76.7M
    SkASSERT_RELEASE(capacity <= fMaxCapacity);
31
32
76.7M
    if (growthFactor > 1.0 && capacity > 0) {
33
15.8M
        capacity = this->growthFactorCapacity(capacity, growthFactor);
34
15.8M
    }
35
36
76.7M
    return sk_allocate_throw(capacity * fSizeOfT);
37
76.7M
}
SkContainerAllocator::allocate(int, double)
Line
Count
Source
27
76.7M
SkSpan<std::byte> SkContainerAllocator::allocate(int capacity, double growthFactor) {
28
76.7M
    SkASSERT(capacity >= 0);
29
76.7M
    SkASSERT(growthFactor >= 1.0);
30
76.7M
    SkASSERT_RELEASE(capacity <= fMaxCapacity);
31
32
76.7M
    if (growthFactor > 1.0 && capacity > 0) {
33
15.8M
        capacity = this->growthFactorCapacity(capacity, growthFactor);
34
15.8M
    }
35
36
76.7M
    return sk_allocate_throw(capacity * fSizeOfT);
37
76.7M
}
SkContainerAllocator::allocate(int, double)
Line
Count
Source
27
20
SkSpan<std::byte> SkContainerAllocator::allocate(int capacity, double growthFactor) {
28
20
    SkASSERT(capacity >= 0);
29
20
    SkASSERT(growthFactor >= 1.0);
30
20
    SkASSERT_RELEASE(capacity <= fMaxCapacity);
31
32
20
    if (growthFactor > 1.0 && capacity > 0) {
33
20
        capacity = this->growthFactorCapacity(capacity, growthFactor);
34
20
    }
35
36
20
    return sk_allocate_throw(capacity * fSizeOfT);
37
20
}
38
39
15.8M
size_t SkContainerAllocator::roundUpCapacity(int64_t capacity) const {
40
15.8M
    SkASSERT(capacity >= 0);
41
42
    // If round will not go above fMaxCapacity return rounded capacity.
43
15.8M
    if (capacity < fMaxCapacity - kCapacityMultiple) {
44
15.8M
        return SkAlignTo(capacity, kCapacityMultiple);
45
15.8M
    }
46
47
0
    return SkToSizeT(fMaxCapacity);
48
15.8M
}
SkContainerAllocator::roundUpCapacity(long) const
Line
Count
Source
39
15.8M
size_t SkContainerAllocator::roundUpCapacity(int64_t capacity) const {
40
15.8M
    SkASSERT(capacity >= 0);
41
42
    // If round will not go above fMaxCapacity return rounded capacity.
43
15.8M
    if (capacity < fMaxCapacity - kCapacityMultiple) {
44
15.8M
        return SkAlignTo(capacity, kCapacityMultiple);
45
15.8M
    }
46
47
0
    return SkToSizeT(fMaxCapacity);
48
15.8M
}
SkContainerAllocator::roundUpCapacity(long) const
Line
Count
Source
39
20
size_t SkContainerAllocator::roundUpCapacity(int64_t capacity) const {
40
20
    SkASSERT(capacity >= 0);
41
42
    // If round will not go above fMaxCapacity return rounded capacity.
43
20
    if (capacity < fMaxCapacity - kCapacityMultiple) {
44
20
        return SkAlignTo(capacity, kCapacityMultiple);
45
20
    }
46
47
0
    return SkToSizeT(fMaxCapacity);
48
20
}
49
50
15.8M
size_t SkContainerAllocator::growthFactorCapacity(int capacity, double growthFactor) const {
51
15.8M
    SkASSERT(capacity >= 0);
52
15.8M
    SkASSERT(growthFactor >= 1.0);
53
    // Multiply by the growthFactor. Remember this must be done in 64-bit ints and not
54
    // size_t because size_t changes.
55
15.8M
    const int64_t capacityGrowth = static_cast<int64_t>(capacity * growthFactor);
56
57
    // Notice that for small values of capacity, rounding up will provide most of the growth.
58
15.8M
    return this->roundUpCapacity(capacityGrowth);
59
15.8M
}
SkContainerAllocator::growthFactorCapacity(int, double) const
Line
Count
Source
50
15.8M
size_t SkContainerAllocator::growthFactorCapacity(int capacity, double growthFactor) const {
51
15.8M
    SkASSERT(capacity >= 0);
52
15.8M
    SkASSERT(growthFactor >= 1.0);
53
    // Multiply by the growthFactor. Remember this must be done in 64-bit ints and not
54
    // size_t because size_t changes.
55
15.8M
    const int64_t capacityGrowth = static_cast<int64_t>(capacity * growthFactor);
56
57
    // Notice that for small values of capacity, rounding up will provide most of the growth.
58
15.8M
    return this->roundUpCapacity(capacityGrowth);
59
15.8M
}
SkContainerAllocator::growthFactorCapacity(int, double) const
Line
Count
Source
50
20
size_t SkContainerAllocator::growthFactorCapacity(int capacity, double growthFactor) const {
51
20
    SkASSERT(capacity >= 0);
52
20
    SkASSERT(growthFactor >= 1.0);
53
    // Multiply by the growthFactor. Remember this must be done in 64-bit ints and not
54
    // size_t because size_t changes.
55
20
    const int64_t capacityGrowth = static_cast<int64_t>(capacity * growthFactor);
56
57
    // Notice that for small values of capacity, rounding up will provide most of the growth.
58
20
    return this->roundUpCapacity(capacityGrowth);
59
20
}
60
61
62
0
SkSpan<std::byte> sk_allocate_canfail(size_t size) {
63
    // Make sure to ask for at least the minimum number of bytes.
64
0
    const size_t adjustedSize = std::max(size, kMinBytes);
65
0
    void* ptr = sk_malloc_canfail(adjustedSize);
66
0
    return complete_size(ptr, adjustedSize);
67
0
}
68
69
76.7M
SkSpan<std::byte> sk_allocate_throw(size_t size) {
70
76.7M
    if (size == 0) {
71
31.3k
        return {};
72
31.3k
    }
73
    // Make sure to ask for at least the minimum number of bytes.
74
76.7M
    const size_t adjustedSize = std::max(size, kMinBytes);
75
76.7M
    void* ptr = sk_malloc_throw(adjustedSize);
76
76.7M
    return complete_size(ptr, adjustedSize);
77
76.7M
}
78
79
0
void sk_report_container_overflow_and_die() {
80
0
    SK_ABORT("Requested capacity is too large.");
81
0
}