зеркало из https://github.com/mozilla/pjs.git
Allocate the next page to be used in a lirbuf early to avoid running OOM during a page overflow (471316, r=danderson).
This commit is contained in:
Родитель
82688c9a74
Коммит
fc407f7516
|
@ -112,13 +112,15 @@ namespace nanojit
|
|||
// free all the memory and clear the stats
|
||||
_frago->pagesRelease(_pages);
|
||||
NanoAssert(!_pages.size());
|
||||
_thresholdPage = 0;
|
||||
_unused = 0;
|
||||
_stats.lir = 0;
|
||||
_noMem = 0;
|
||||
for (int i = 0; i < NumSavedRegs; ++i)
|
||||
savedRegs[i] = NULL;
|
||||
explicitSavedRegs = false;
|
||||
// pre-allocate the next page we will be using
|
||||
_nextPage = pageAlloc();
|
||||
NanoAssert(_nextPage || _noMem);
|
||||
}
|
||||
|
||||
int32_t LirBuffer::insCount()
|
||||
|
@ -152,24 +154,16 @@ namespace nanojit
|
|||
{
|
||||
LInsp before = _buf->next();
|
||||
LInsp after = before+count+LIR_FAR_SLOTS;
|
||||
if (!samepage(before,after+LirBuffer::LIR_BUF_THRESHOLD))
|
||||
// transition to the next page?
|
||||
if (!samepage(before,after))
|
||||
{
|
||||
if (!_buf->_thresholdPage)
|
||||
{
|
||||
// LIR_BUF_THRESHOLD away from a new page but pre-alloc it, setting noMem for early OOM detection
|
||||
_buf->_thresholdPage = _buf->pageAlloc();
|
||||
NanoAssert(_buf->_thresholdPage || _buf->_noMem);
|
||||
}
|
||||
// transition to the next page?
|
||||
if (!samepage(before,after))
|
||||
{
|
||||
NanoAssert(_buf->_thresholdPage);
|
||||
_buf->_unused = &_buf->_thresholdPage->lir[0];
|
||||
_buf->_thresholdPage = 0; // pageAlloc() stored it in _pages already
|
||||
|
||||
// link LIR stream back to prior instruction (careful insLink relies on _unused...)
|
||||
insLinkTo(LIR_skip, before-1);
|
||||
}
|
||||
// we don't want this to fail, so we always have a page in reserve
|
||||
NanoAssert(_buf->_nextPage);
|
||||
_buf->_unused = &_buf->_nextPage->lir[0];
|
||||
// link LIR stream back to prior instruction (careful insLink relies on _unused...)
|
||||
insLinkTo(LIR_skip, before-1);
|
||||
_buf->_nextPage = _buf->pageAlloc();
|
||||
NanoAssert(_buf->_nextPage || _buf->_noMem);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -689,8 +689,6 @@ namespace nanojit
|
|||
class LirBuffer : public avmplus::GCFinalizedObject
|
||||
{
|
||||
public:
|
||||
static const uint32_t LIR_BUF_THRESHOLD = 1024/sizeof(LIns); // 1KB prior to running out of space we'll allocate a new page
|
||||
|
||||
DWB(Fragmento*) _frago;
|
||||
LirBuffer(Fragmento* frago, const CallInfo* functions);
|
||||
virtual ~LirBuffer();
|
||||
|
@ -724,7 +722,7 @@ namespace nanojit
|
|||
Page* pageAlloc();
|
||||
|
||||
PageList _pages;
|
||||
Page* _thresholdPage; // allocated in preperation of a needing to growing the buffer
|
||||
Page* _nextPage; // allocated in preperation of a needing to growing the buffer
|
||||
LInsp _unused; // next unused instruction slot
|
||||
int _noMem; // set if ran out of memory when writing to buffer
|
||||
};
|
||||
|
|
|
@ -3886,6 +3886,42 @@ testDoubleComparison.jitstats = {
|
|||
};
|
||||
test(testDoubleComparison);
|
||||
|
||||
function testLirBufOOM()
|
||||
{
|
||||
var a = [
|
||||
"12345678901234",
|
||||
"123456789012",
|
||||
"1234567890123456789012345678",
|
||||
"12345678901234567890123456789012345678901234567890123456",
|
||||
"f",
|
||||
"$",
|
||||
"",
|
||||
"f()",
|
||||
"(\\*)",
|
||||
"b()",
|
||||
"()",
|
||||
"(#)",
|
||||
"ABCDEFGHIJK",
|
||||
"ABCDEFGHIJKLM",
|
||||
"ABCDEFGHIJKLMNOPQ",
|
||||
"ABCDEFGH",
|
||||
"(.)",
|
||||
"(|)",
|
||||
"()$",
|
||||
"/()",
|
||||
"(.)$"
|
||||
];
|
||||
|
||||
for (var j = 0; j < 200; ++j) {
|
||||
var js = "" + j;
|
||||
for (var i = 0; i < a.length; i++)
|
||||
"".match(a[i] + js)
|
||||
}
|
||||
return "ok";
|
||||
}
|
||||
testLirBufOOM.expected = "ok";
|
||||
test(testLirBufOOM);
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* _____ _ _ _____ ______ _____ _______ *
|
||||
|
|
Загрузка…
Ссылка в новой задаче