mirror of
https://github.com/corda/corda.git
synced 2025-06-10 19:31:46 +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
44
src/heap.cpp
44
src/heap.cpp
@ -1895,21 +1895,43 @@ class MyHeap: public Heap {
|
|||||||
local::collect(&c);
|
local::collect(&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* allocateFixed(Allocator* allocator, unsigned sizeInWords,
|
void* tryAllocateFixed(Allocator* allocator, unsigned sizeInWords,
|
||||||
bool objectMask, unsigned* totalInBytes)
|
bool objectMask, unsigned* totalInBytes,
|
||||||
|
Fixie** handle, bool immortal)
|
||||||
{
|
{
|
||||||
*totalInBytes = Fixie::totalSize(sizeInWords, objectMask);
|
*totalInBytes = 0;
|
||||||
return (new (allocator->allocate(*totalInBytes))
|
|
||||||
Fixie(&c, sizeInWords, objectMask, &(c.fixies), false))->body();
|
if (limitExceeded()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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* allocateImmortalFixed(Allocator* allocator,
|
virtual void* tryAllocateFixed(Allocator* allocator, unsigned sizeInWords,
|
||||||
unsigned sizeInWords, bool objectMask,
|
bool objectMask, unsigned* totalInBytes)
|
||||||
unsigned* totalInBytes)
|
|
||||||
{
|
{
|
||||||
*totalInBytes = Fixie::totalSize(sizeInWords, objectMask);
|
return tryAllocateFixed
|
||||||
return (new (allocator->allocate(*totalInBytes))
|
(allocator, sizeInWords, objectMask, totalInBytes, &(c.fixies), false);
|
||||||
Fixie(&c, sizeInWords, objectMask, 0, true))->body();
|
}
|
||||||
|
|
||||||
|
virtual void* tryAllocateImmortalFixed(Allocator* allocator,
|
||||||
|
unsigned sizeInWords, bool objectMask,
|
||||||
|
unsigned* totalInBytes)
|
||||||
|
{
|
||||||
|
return tryAllocateFixed
|
||||||
|
(allocator, sizeInWords, objectMask, totalInBytes, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needsMark(void* p) {
|
bool needsMark(void* p) {
|
||||||
|
10
src/heap.h
10
src/heap.h
@ -62,11 +62,11 @@ class Heap: public Allocator {
|
|||||||
virtual unsigned limit() = 0;
|
virtual unsigned limit() = 0;
|
||||||
virtual bool limitExceeded() = 0;
|
virtual bool limitExceeded() = 0;
|
||||||
virtual void collect(CollectionType type, unsigned footprint) = 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;
|
bool objectMask, unsigned* totalInBytes) = 0;
|
||||||
virtual void* allocateImmortalFixed(Allocator* allocator,
|
virtual void* tryAllocateImmortalFixed(Allocator* allocator,
|
||||||
unsigned sizeInWords, bool objectMask,
|
unsigned sizeInWords, bool objectMask,
|
||||||
unsigned* totalInBytes) = 0;
|
unsigned* totalInBytes) = 0;
|
||||||
virtual void mark(void* p, unsigned offset, unsigned count) = 0;
|
virtual void mark(void* p, unsigned offset, unsigned count) = 0;
|
||||||
virtual void pad(void* p) = 0;
|
virtual void pad(void* p) = 0;
|
||||||
virtual void* follow(void* p) = 0;
|
virtual void* follow(void* p) = 0;
|
||||||
|
@ -3531,7 +3531,7 @@ allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type,
|
|||||||
} while (type == Machine::MovableAllocation
|
} while (type == Machine::MovableAllocation
|
||||||
and t->heapIndex + ceiling(sizeInBytes, BytesPerWord)
|
and t->heapIndex + ceiling(sizeInBytes, BytesPerWord)
|
||||||
> ThreadHeapSizeInWords);
|
> ThreadHeapSizeInWords);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Machine::MovableAllocation: {
|
case Machine::MovableAllocation: {
|
||||||
return allocateSmall(t, sizeInBytes);
|
return allocateSmall(t, sizeInBytes);
|
||||||
@ -3540,29 +3540,37 @@ allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type,
|
|||||||
case Machine::FixedAllocation: {
|
case Machine::FixedAllocation: {
|
||||||
unsigned total;
|
unsigned total;
|
||||||
object o = static_cast<object>
|
object o = static_cast<object>
|
||||||
(t->m->heap->allocateFixed
|
(t->m->heap->tryAllocateFixed
|
||||||
(allocator, ceiling(sizeInBytes, BytesPerWord), objectMask, &total));
|
(allocator, ceiling(sizeInBytes, BytesPerWord), objectMask, &total));
|
||||||
|
|
||||||
memset(o, 0, sizeInBytes);
|
if (o) {
|
||||||
|
memset(o, 0, sizeInBytes);
|
||||||
|
|
||||||
alias(o, 0) = FixedMark;
|
alias(o, 0) = FixedMark;
|
||||||
|
|
||||||
t->m->fixedFootprint += total;
|
t->m->fixedFootprint += total;
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
|
} else {
|
||||||
|
throw_(t, root(t, Machine::OutOfMemoryError));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case Machine::ImmortalAllocation: {
|
case Machine::ImmortalAllocation: {
|
||||||
unsigned total;
|
unsigned total;
|
||||||
object o = static_cast<object>
|
object o = static_cast<object>
|
||||||
(t->m->heap->allocateImmortalFixed
|
(t->m->heap->tryAllocateImmortalFixed
|
||||||
(allocator, ceiling(sizeInBytes, BytesPerWord), objectMask, &total));
|
(allocator, ceiling(sizeInBytes, BytesPerWord), objectMask, &total));
|
||||||
|
|
||||||
memset(o, 0, sizeInBytes);
|
if (o) {
|
||||||
|
memset(o, 0, sizeInBytes);
|
||||||
|
|
||||||
alias(o, 0) = FixedMark;
|
alias(o, 0) = FixedMark;
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
|
} else {
|
||||||
|
throw_(t, root(t, Machine::OutOfMemoryError));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default: abort(t);
|
default: abort(t);
|
||||||
|
@ -1784,8 +1784,8 @@ class FixedAllocator: public Allocator {
|
|||||||
s(s), base(base), offset(0), capacity(capacity)
|
s(s), base(base), offset(0), capacity(capacity)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void* tryAllocate(unsigned) {
|
virtual void* tryAllocate(unsigned size) {
|
||||||
abort(s);
|
return allocate(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* allocate(unsigned size, unsigned padAlignment) {
|
void* allocate(unsigned size, unsigned padAlignment) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user