diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-05-28 18:03:08 +0200 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-05-28 18:22:48 +0200 |
commit | 528072c39363668b528b2bcfaaa6891b92caa8fa (patch) | |
tree | 6f26f37d0ee1c3fa13bac7d423addba6c9d9c376 | |
parent | 4ad94cfde9ffbb8b32b461ed288327e17ea936c9 (diff) | |
download | UXP-528072c39363668b528b2bcfaaa6891b92caa8fa.tar UXP-528072c39363668b528b2bcfaaa6891b92caa8fa.tar.gz UXP-528072c39363668b528b2bcfaaa6891b92caa8fa.tar.lz UXP-528072c39363668b528b2bcfaaa6891b92caa8fa.tar.xz UXP-528072c39363668b528b2bcfaaa6891b92caa8fa.zip |
Improve efficiency of (C++) heap allocations related to
BytecodeEmitter::code.
While there, also add some sanity checks and clean up code.
-rw-r--r-- | js/src/frontend/BytecodeEmitter.cpp | 28 | ||||
-rw-r--r-- | js/src/frontend/BytecodeEmitter.h | 10 |
2 files changed, 24 insertions, 14 deletions
diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index b3dd6d777..c524184d6 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -2260,12 +2260,14 @@ BytecodeEmitter::locationOfNameBoundInFunctionScope(JSAtom* name, EmitterScope* bool BytecodeEmitter::emitCheck(ptrdiff_t delta, ptrdiff_t* offset) { - *offset = code().length(); + size_t oldLength = code().length(); + *offset = ptrdiff_t(oldLength); - // Start it off moderately large to avoid repeated resizings early on. - // ~98% of cases fit within 1024 bytes. - if (code().capacity() == 0 && !code().reserve(1024)) - return false; + size_t newLength = oldLength + size_t(delta); + if (MOZ_UNLIKELY(newLength > MaxBytecodeLength)) { + ReportAllocationOverflow(cx); + return false; + } if (!code().growBy(delta)) { ReportOutOfMemory(cx); @@ -10697,17 +10699,19 @@ BytecodeEmitter::emitTreeInBranch(ParseNode* pn) static bool AllocSrcNote(ExclusiveContext* cx, SrcNotesVector& notes, unsigned* index) { - // Start it off moderately large to avoid repeated resizings early on. - // ~99% of cases fit within 256 bytes. - if (notes.capacity() == 0 && !notes.reserve(256)) - return false; + size_t oldLength = notes.length(); + if (MOZ_UNLIKELY(oldLength + 1 > MaxSrcNotesLength)) { + ReportAllocationOverflow(cx); + return false; + } + if (!notes.growBy(1)) { ReportOutOfMemory(cx); return false; } - *index = notes.length() - 1; + *index = oldLength; return true; } @@ -10833,6 +10837,10 @@ BytecodeEmitter::setSrcNoteOffset(unsigned index, unsigned which, ptrdiff_t offs /* Maybe this offset was already set to a four-byte value. */ if (!(*sn & SN_4BYTE_OFFSET_FLAG)) { /* Insert three dummy bytes that will be overwritten shortly. */ + if (MOZ_UNLIKELY(notes.length() + 3 > MaxSrcNotesLength)) {
+ ReportAllocationOverflow(cx);
+ return false; + } jssrcnote dummy = 0; if (!(sn = notes.insert(sn, dummy)) || !(sn = notes.insert(sn, dummy)) || diff --git a/js/src/frontend/BytecodeEmitter.h b/js/src/frontend/BytecodeEmitter.h index 32668a34c..814fa11d4 100644 --- a/js/src/frontend/BytecodeEmitter.h +++ b/js/src/frontend/BytecodeEmitter.h @@ -109,10 +109,12 @@ struct CGYieldOffsetList { void finish(YieldOffsetArray& array, uint32_t prologueLength); }; -// Use zero inline elements because these go on the stack and affect how many -// nested functions are possible. -typedef Vector<jsbytecode, 0> BytecodeVector; -typedef Vector<jssrcnote, 0> SrcNotesVector; +static size_t MaxBytecodeLength = INT32_MAX; +static size_t MaxSrcNotesLength = INT32_MAX; + +// Have a few inline elements to avoid heap allocation for tiny sequences. +typedef Vector<jsbytecode, 256> BytecodeVector; +typedef Vector<jssrcnote, 64> SrcNotesVector; // Linked list of jump instructions that need to be patched. The linked list is // stored in the bytes of the incomplete bytecode that will be patched, so no |