mirror of
https://github.com/corda/corda.git
synced 2025-06-11 03:41:41 +00:00
fail quickly if an object allocation cannot be satisfied
Previously, we would blithely exceed the heap ceiling and force the next allocation to deal with the problem, including a major GC and possible OutOfMemoryError. As of this commit, we throw an error immediately if we find that the allocation will push us over the ceiling.
This commit is contained in:
parent
23bb2e8743
commit
e8f8ebdc67
40
src/heap.cpp
40
src/heap.cpp
@ -1895,21 +1895,43 @@ class MyHeap: public Heap {
|
||||
local::collect(&c);
|
||||
}
|
||||
|
||||
virtual void* allocateFixed(Allocator* allocator, unsigned sizeInWords,
|
||||
bool objectMask, unsigned* totalInBytes)
|
||||
void* tryAllocateFixed(Allocator* allocator, unsigned sizeInWords,
|
||||
bool objectMask, unsigned* totalInBytes,
|
||||
Fixie** handle, bool immortal)
|
||||
{
|
||||
*totalInBytes = Fixie::totalSize(sizeInWords, objectMask);
|
||||
return (new (allocator->allocate(*totalInBytes))
|
||||
Fixie(&c, sizeInWords, objectMask, &(c.fixies), false))->body();
|
||||
*totalInBytes = 0;
|
||||
|
||||
if (limitExceeded()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void* allocateImmortalFixed(Allocator* allocator,
|
||||
unsigned total = Fixie::totalSize(sizeInWords, objectMask);
|
||||
void* p = allocator->tryAllocate(total);
|
||||
if (p == 0) {
|
||||
return 0;
|
||||
} else if (limitExceeded()) {
|
||||
allocator->free(p, total);
|
||||
return 0;
|
||||
} else {
|
||||
*totalInBytes = total;
|
||||
return (new (p) Fixie(&c, sizeInWords, objectMask, handle, immortal))
|
||||
->body();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void* tryAllocateFixed(Allocator* allocator, unsigned sizeInWords,
|
||||
bool objectMask, unsigned* totalInBytes)
|
||||
{
|
||||
return tryAllocateFixed
|
||||
(allocator, sizeInWords, objectMask, totalInBytes, &(c.fixies), false);
|
||||
}
|
||||
|
||||
virtual void* tryAllocateImmortalFixed(Allocator* allocator,
|
||||
unsigned sizeInWords, bool objectMask,
|
||||
unsigned* totalInBytes)
|
||||
{
|
||||
*totalInBytes = Fixie::totalSize(sizeInWords, objectMask);
|
||||
return (new (allocator->allocate(*totalInBytes))
|
||||
Fixie(&c, sizeInWords, objectMask, 0, true))->body();
|
||||
return tryAllocateFixed
|
||||
(allocator, sizeInWords, objectMask, totalInBytes, 0, true);
|
||||
}
|
||||
|
||||
bool needsMark(void* p) {
|
||||
|
@ -62,9 +62,9 @@ class Heap: public Allocator {
|
||||
virtual unsigned limit() = 0;
|
||||
virtual bool limitExceeded() = 0;
|
||||
virtual void collect(CollectionType type, unsigned footprint) = 0;
|
||||
virtual void* allocateFixed(Allocator* allocator, unsigned sizeInWords,
|
||||
virtual void* tryAllocateFixed(Allocator* allocator, unsigned sizeInWords,
|
||||
bool objectMask, unsigned* totalInBytes) = 0;
|
||||
virtual void* allocateImmortalFixed(Allocator* allocator,
|
||||
virtual void* tryAllocateImmortalFixed(Allocator* allocator,
|
||||
unsigned sizeInWords, bool objectMask,
|
||||
unsigned* totalInBytes) = 0;
|
||||
virtual void mark(void* p, unsigned offset, unsigned count) = 0;
|
||||
|
@ -3540,9 +3540,10 @@ allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type,
|
||||
case Machine::FixedAllocation: {
|
||||
unsigned total;
|
||||
object o = static_cast<object>
|
||||
(t->m->heap->allocateFixed
|
||||
(t->m->heap->tryAllocateFixed
|
||||
(allocator, ceiling(sizeInBytes, BytesPerWord), objectMask, &total));
|
||||
|
||||
if (o) {
|
||||
memset(o, 0, sizeInBytes);
|
||||
|
||||
alias(o, 0) = FixedMark;
|
||||
@ -3550,19 +3551,26 @@ allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type,
|
||||
t->m->fixedFootprint += total;
|
||||
|
||||
return o;
|
||||
} else {
|
||||
throw_(t, root(t, Machine::OutOfMemoryError));
|
||||
}
|
||||
}
|
||||
|
||||
case Machine::ImmortalAllocation: {
|
||||
unsigned total;
|
||||
object o = static_cast<object>
|
||||
(t->m->heap->allocateImmortalFixed
|
||||
(t->m->heap->tryAllocateImmortalFixed
|
||||
(allocator, ceiling(sizeInBytes, BytesPerWord), objectMask, &total));
|
||||
|
||||
if (o) {
|
||||
memset(o, 0, sizeInBytes);
|
||||
|
||||
alias(o, 0) = FixedMark;
|
||||
|
||||
return o;
|
||||
} else {
|
||||
throw_(t, root(t, Machine::OutOfMemoryError));
|
||||
}
|
||||
}
|
||||
|
||||
default: abort(t);
|
||||
|
@ -1784,8 +1784,8 @@ class FixedAllocator: public Allocator {
|
||||
s(s), base(base), offset(0), capacity(capacity)
|
||||
{ }
|
||||
|
||||
virtual void* tryAllocate(unsigned) {
|
||||
abort(s);
|
||||
virtual void* tryAllocate(unsigned size) {
|
||||
return allocate(size);
|
||||
}
|
||||
|
||||
void* allocate(unsigned size, unsigned padAlignment) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user