Skip to content

Commit cc88d5e

Browse files
committed
Fix bugs in realloc where passed size is larger than the current one.
* Also properly pad the size for large objects to a systempage.
1 parent 3c490fb commit cc88d5e

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

src/glue.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,18 @@ always_inline void* realloc(void* ptr, size_t size) {
8282
return ptr;
8383
}
8484
new_obj = malloc(size);
85-
memcpy(new_obj, ptr, old_size);
85+
if (new_obj == nullptr) return nullptr;
86+
memmove(new_obj, ptr, old_size);
87+
free(ptr);
8688
} else {
87-
const size_t old_size = LargeObject::ObjectSize(ptr);
89+
const size_t old_size = LargeObject::PayloadSize(ptr);
8890
if (old_size >= size) {
8991
return ptr;
9092
}
9193
new_obj = malloc(size);
92-
memcpy(new_obj, ptr, old_size);
94+
if (new_obj == nullptr) return nullptr;
95+
memmove(new_obj, ptr, old_size);
96+
free(ptr);
9397
}
9498
return new_obj;
9599
}

src/large-objects.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class LargeObject {
1818
public:
1919
static always_inline void* Allocate(size_t size);
2020
static always_inline void Free(void* p);
21-
static always_inline size_t ObjectSize(void* p);
21+
static always_inline size_t PayloadSize(void* p);
2222

2323
private:
2424
static const uint64_t kMagic = 0xAAAAAAAAAAAAAAAA;
@@ -29,7 +29,8 @@ class LargeObject {
2929
always_inline void* ObjectStart();
3030
always_inline bool Validate();
3131

32-
always_inline size_t size() { return actual_size_; }
32+
always_inline size_t payload_size() { return actual_size_ - sizeof(*this); }
33+
always_inline size_t actual_size() { return actual_size_; }
3334

3435
size_t actual_size_;
3536
uint64_t magic_;
@@ -53,23 +54,27 @@ LargeObject* LargeObject::FromMutatorPtr(void* p) {
5354

5455

5556
void* LargeObject::Allocate(size_t size) {
56-
const size_t actual_size = size + sizeof(LargeObject);
57+
const size_t actual_size = PadSize(size + sizeof(LargeObject), kPageSize);
5758
LargeObject* obj = new(SystemMmapFail(actual_size)) LargeObject(actual_size);
59+
#ifdef DEBUG
60+
// Force the check by going through the mutator pointer.
61+
obj = LargeObject::FromMutatorPtr(obj->ObjectStart());
62+
#endif // DEBUG
5863
return obj->ObjectStart();
5964
}
6065

6166

6267
void LargeObject::Free(void* p) {
6368
LargeObject* obj = FromMutatorPtr(p);
64-
if (munmap(obj, obj->size()) != 0) {
69+
if (munmap(obj, obj->actual_size()) != 0) {
6570
Fatal("munmap failed");
6671
}
6772
}
6873

6974

70-
size_t LargeObject::ObjectSize(void* p) {
75+
size_t LargeObject::PayloadSize(void* p) {
7176
LargeObject* obj = FromMutatorPtr(p);
72-
return obj->size();
77+
return obj->payload_size();
7378
}
7479

7580

0 commit comments

Comments
 (0)