Skip to content

Commit

Permalink
Fix bugs in realloc where passed size is larger than the current one.
Browse files Browse the repository at this point in the history
* Also properly pad the size for large objects to a systempage.
  • Loading branch information
mlippautz committed Aug 28, 2015
1 parent 3c490fb commit cc88d5e
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 9 deletions.
10 changes: 7 additions & 3 deletions src/glue.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,18 @@ always_inline void* realloc(void* ptr, size_t size) {
return ptr;
}
new_obj = malloc(size);
memcpy(new_obj, ptr, old_size);
if (new_obj == nullptr) return nullptr;
memmove(new_obj, ptr, old_size);
free(ptr);
} else {
const size_t old_size = LargeObject::ObjectSize(ptr);
const size_t old_size = LargeObject::PayloadSize(ptr);
if (old_size >= size) {
return ptr;
}
new_obj = malloc(size);
memcpy(new_obj, ptr, old_size);
if (new_obj == nullptr) return nullptr;
memmove(new_obj, ptr, old_size);
free(ptr);
}
return new_obj;
}
Expand Down
17 changes: 11 additions & 6 deletions src/large-objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class LargeObject {
public:
static always_inline void* Allocate(size_t size);
static always_inline void Free(void* p);
static always_inline size_t ObjectSize(void* p);
static always_inline size_t PayloadSize(void* p);

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

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

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


void* LargeObject::Allocate(size_t size) {
const size_t actual_size = size + sizeof(LargeObject);
const size_t actual_size = PadSize(size + sizeof(LargeObject), kPageSize);
LargeObject* obj = new(SystemMmapFail(actual_size)) LargeObject(actual_size);
#ifdef DEBUG
// Force the check by going through the mutator pointer.
obj = LargeObject::FromMutatorPtr(obj->ObjectStart());
#endif // DEBUG
return obj->ObjectStart();
}


void LargeObject::Free(void* p) {
LargeObject* obj = FromMutatorPtr(p);
if (munmap(obj, obj->size()) != 0) {
if (munmap(obj, obj->actual_size()) != 0) {
Fatal("munmap failed");
}
}


size_t LargeObject::ObjectSize(void* p) {
size_t LargeObject::PayloadSize(void* p) {
LargeObject* obj = FromMutatorPtr(p);
return obj->size();
return obj->payload_size();
}


Expand Down

0 comments on commit cc88d5e

Please sign in to comment.