/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 | } |