Skip to content

Commit 0b6e21d

Browse files
lavenzgfacebook-github-bot
authored andcommitted
Add support of allocating different sizes of storage in StorageProvider (facebook#1504)
Summary: Pull Request resolved: facebook#1504 Large segment needs to be backed by a large storage size. StorageProvider currently always allocate fixed size of storage determined by HERMESVM_LOG_HEAP_SEGMENT_SIZE. This diffs adds support of allocating larger storage with below changes: 1. `newStorage()` and `deleteStorage()` takes additional `sz` parameter. 2. For `MallocStorageProvider` and `VMAllocateStorageProvider`, simply change the previous fixed storage size to passed in `sz`. 3. For `ContiguousVAStorageProvider`, use a BitVector to manage allocations and deallocations. This can be improved later if we observe fragmentations. The support of enabling different sizes of heap segment will be added later. Differential Revision: D61676721
1 parent bab7714 commit 0b6e21d

10 files changed

+256
-133
lines changed

include/hermes/Support/ErrorHandling.h

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ enum class OOMError : int {
3737
Effective,
3838
// When an allocation is requested that is larger than a heap segment.
3939
SuperSegmentAlloc,
40+
// When requesting a segment that is too large to create.
41+
TooLargeSegmentRequest,
4042
// When a CopyableVector's capacity overflows what an integer can hold.
4143
CopyableVectorCapacityIntegerOverflow,
4244
// This happens when a unit test attempts to allocate more storages

include/hermes/VM/HeapRuntime.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class HeapRuntime {
2222
public:
2323
~HeapRuntime() {
2424
runtime_->~RT();
25-
sp_->deleteStorage(runtime_);
25+
sp_->deleteStorage(runtime_, kHeapRuntimeStorageSize);
2626
}
2727

2828
/// Allocate a segment and create an aliased shared_ptr that points to the
@@ -36,17 +36,16 @@ class HeapRuntime {
3636

3737
private:
3838
HeapRuntime(std::shared_ptr<StorageProvider> sp) : sp_{std::move(sp)} {
39-
auto ptrOrError = sp_->newStorage("hermes-rt");
39+
auto ptrOrError = sp_->newStorage(kHeapRuntimeStorageSize, "hermes-rt");
4040
if (!ptrOrError)
4141
hermes_fatal("Cannot initialize Runtime storage.", ptrOrError.getError());
42-
static_assert(
43-
sizeof(RT) < FixedSizeHeapSegment::storageSize(),
44-
"Segments too small.");
42+
static_assert(sizeof(RT) < kHeapRuntimeStorageSize, "Segments too small.");
4543
runtime_ = static_cast<RT *>(*ptrOrError);
4644
}
4745

4846
std::shared_ptr<StorageProvider> sp_;
4947
RT *runtime_;
48+
static constexpr size_t kHeapRuntimeStorageSize = FixedSizeHeapSegment::kSize;
5049
};
5150
} // namespace vm
5251
} // namespace hermes

include/hermes/VM/LimitedStorageProvider.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ class LimitedStorageProvider final : public StorageProvider {
2929
: delegate_(std::move(provider)), limit_(limit) {}
3030

3131
protected:
32-
llvh::ErrorOr<void *> newStorageImpl(const char *name) override;
32+
llvh::ErrorOr<void *> newStorageImpl(size_t sz, const char *name) override;
3333

34-
void deleteStorageImpl(void *storage) override;
34+
void deleteStorageImpl(void *storage, size_t sz) override;
3535
};
3636

3737
} // namespace vm

include/hermes/VM/StorageProvider.h

+15-15
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,17 @@ class StorageProvider {
3737

3838
/// @}
3939

40-
/// Create a new segment memory space.
41-
llvh::ErrorOr<void *> newStorage() {
42-
return newStorage(nullptr);
43-
}
44-
/// Create a new segment memory space and give this memory the name \p name.
45-
/// \return A pointer to a block of memory that has
46-
/// FixedSizeHeapSegment::storageSize() bytes, and is aligned on
47-
/// FixedSizeHeapSegment::storageSize().
48-
llvh::ErrorOr<void *> newStorage(const char *name);
40+
/// \return A pointer to a block of memory that has \p sz bytes, and is
41+
/// aligned on AlignedHeapSegment::kSegmentUnitSize. Note that \p sz must
42+
/// be non-zero and equals to a multiple of
43+
/// AlignedHeapSegment::kSegmentUnitSize.
44+
llvh::ErrorOr<void *> newStorage(size_t sz, const char *name = nullptr);
4945

5046
/// Delete the given segment's memory space, and make it available for re-use.
51-
/// \post Nothing in the range [storage, storage +
52-
/// FixedSizeHeapSegment::storageSize()) is valid memory to be read or
53-
/// written.
54-
void deleteStorage(void *storage);
47+
/// Note that \p sz must be the same as used to allocating \p storage.
48+
/// \post Nothing in the range [storage, storage + sz) is valid memory to be
49+
/// read or written.
50+
void deleteStorage(void *storage, size_t sz);
5551

5652
/// The number of storages this provider has allocated in its lifetime.
5753
size_t numSucceededAllocs() const;
@@ -68,8 +64,12 @@ class StorageProvider {
6864
size_t numLiveAllocs() const;
6965

7066
protected:
71-
virtual llvh::ErrorOr<void *> newStorageImpl(const char *name) = 0;
72-
virtual void deleteStorageImpl(void *storage) = 0;
67+
/// \pre \p sz is non-zero and equal to a multiple of
68+
/// AlignedHeapSegment::kSegmentUnitSize.
69+
virtual llvh::ErrorOr<void *> newStorageImpl(size_t sz, const char *name) = 0;
70+
/// \pre \p sz is non-zero and equal to a multiple of
71+
/// AlignedHeapSegment::kSegmentUnitSize.
72+
virtual void deleteStorageImpl(void *storage, size_t sz) = 0;
7373

7474
private:
7575
size_t numSucceededAllocs_{0};

lib/Support/ErrorHandling.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ const std::error_category &oom_category() {
2929
return "Effective OOM";
3030
case OOMError::SuperSegmentAlloc:
3131
return "Allocation occurred that was larger than a heap segment";
32+
case OOMError::TooLargeSegmentRequest:
33+
return "Requesting a heap segment that is too large to create";
3234
case OOMError::CopyableVectorCapacityIntegerOverflow:
3335
return "CopyableVector capacity integer overflow";
3436
case OOMError::TestVMLimitReached:

lib/VM/LimitedStorageProvider.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,22 @@
1313
namespace hermes {
1414
namespace vm {
1515

16-
llvh::ErrorOr<void *> LimitedStorageProvider::newStorageImpl(const char *name) {
16+
llvh::ErrorOr<void *> LimitedStorageProvider::newStorageImpl(
17+
size_t sz,
18+
const char *name) {
1719
if (limit_ < FixedSizeHeapSegment::storageSize()) {
1820
return make_error_code(OOMError::TestVMLimitReached);
1921
}
20-
limit_ -= FixedSizeHeapSegment::storageSize();
21-
return delegate_->newStorage(name);
22+
limit_ -= sz;
23+
return delegate_->newStorage(sz, name);
2224
}
2325

24-
void LimitedStorageProvider::deleteStorageImpl(void *storage) {
26+
void LimitedStorageProvider::deleteStorageImpl(void *storage, size_t sz) {
2527
if (!storage) {
2628
return;
2729
}
28-
delegate_->deleteStorage(storage);
29-
limit_ += FixedSizeHeapSegment::storageSize();
30+
delegate_->deleteStorage(storage, sz);
31+
limit_ += sz;
3032
}
3133

3234
} // namespace vm

0 commit comments

Comments
 (0)