Bug 1688884 - Part 2: Use LifoAlloc and XDR buffer for BigIntStencil source. r=tcampbell

When compiling, source is allocated in LifoAlloc.
When decoding, source points XDR buffer.

Depends on D103159

Differential Revision: https://phabricator.services.mozilla.com/D103160
This commit is contained in:
Tooru Fujisawa 2021-01-27 18:18:51 +00:00
Родитель 5aaa999a0c
Коммит 65e44b52e5
4 изменённых файлов: 41 добавлений и 36 удалений

Просмотреть файл

@ -10464,6 +10464,10 @@ BigIntLiteral* Parser<FullParseHandler, Unit>::newBigInt() {
// BigIntLiteralSuffix (the trailing "n"). Note that NonDecimalIntegerLiteral
// productions start with 0[bBoOxX], indicating binary/octal/hex.
const auto& chars = tokenStream.getCharBuffer();
if (chars.length() > UINT32_MAX) {
ReportAllocationOverflow(cx_);
return null();
}
BigIntIndex index(this->stencil_.bigIntData.length());
if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
@ -10475,7 +10479,8 @@ BigIntLiteral* Parser<FullParseHandler, Unit>::newBigInt() {
return null();
}
if (!this->stencil_.bigIntData[index].init(this->cx_, chars)) {
if (!this->stencil_.bigIntData[index].init(this->cx_, this->stencilAlloc(),
chars)) {
return null();
}

Просмотреть файл

@ -7,9 +7,11 @@
#include "frontend/Stencil.h"
#include "mozilla/OperatorNewExtensions.h" // mozilla::KnownNotNull
#include "mozilla/PodOperations.h" // mozilla::PodCopy
#include "mozilla/RefPtr.h" // RefPtr
#include "mozilla/Sprintf.h" // SprintfLiteral
#include "ds/LifoAlloc.h" // LifoAlloc
#include "frontend/AbstractScopePtr.h" // ScopeIndex
#include "frontend/BytecodeCompilation.h" // CanLazilyParse
#include "frontend/BytecodeSection.h" // EmitScriptThingsVector
@ -1214,6 +1216,26 @@ mozilla::Span<TaggedScriptThingIndex> ScriptStencil::gcthings(
return stencil.gcThingData.Subspan(gcThingsOffset, gcThingsLength);
}
MOZ_MUST_USE bool BigIntStencil::init(JSContext* cx, LifoAlloc& alloc,
const Vector<char16_t, 32>& buf) {
#ifdef DEBUG
// Assert we have no separators; if we have a separator then the algorithm
// used in BigInt::literalIsZero will be incorrect.
for (char16_t c : buf) {
MOZ_ASSERT(c != '_');
}
#endif
size_t length = buf.length();
char16_t* p = alloc.template newArrayUninitialized<char16_t>(length);
if (!p) {
ReportOutOfMemory(cx);
return false;
}
mozilla::PodCopy(p, buf.begin(), length);
source_ = mozilla::Span(p, length);
return true;
}
#if defined(DEBUG) || defined(JS_JITSPEW)
void frontend::DumpTaggedParserAtomIndex(js::JSONPrinter& json,
@ -1346,8 +1368,8 @@ void BigIntStencil::dump(js::JSONPrinter& json) {
}
void BigIntStencil::dumpCharsNoQuote(GenericPrinter& out) {
for (size_t i = 0; i < length_; i++) {
out.putChar(char(buf_[i]));
for (char16_t c : source_) {
out.putChar(char(c));
}
}

Просмотреть файл

@ -212,33 +212,23 @@ class RegExpStencil {
class BigIntStencil {
friend class StencilXDR;
UniqueTwoByteChars buf_;
size_t length_ = 0;
// Source of the BigInt literal.
// It's not null-terminated, and also trailing 'n' suffix is not included.
mozilla::Span<char16_t> source_;
public:
BigIntStencil() = default;
MOZ_MUST_USE bool init(JSContext* cx, const Vector<char16_t, 32>& buf) {
#ifdef DEBUG
// Assert we have no separators; if we have a separator then the algorithm
// used in BigInt::literalIsZero will be incorrect.
for (char16_t c : buf) {
MOZ_ASSERT(c != '_');
}
#endif
length_ = buf.length();
buf_ = js::DuplicateString(cx, buf.begin(), buf.length());
return buf_ != nullptr;
}
MOZ_MUST_USE bool init(JSContext* cx, LifoAlloc& alloc,
const Vector<char16_t, 32>& buf);
BigInt* createBigInt(JSContext* cx) const {
mozilla::Range<const char16_t> source(buf_.get(), length_);
mozilla::Range<const char16_t> source(source_.data(), source_.size());
return js::ParseBigIntLiteral(cx, source);
}
bool isZero() const {
mozilla::Range<const char16_t> source(buf_.get(), length_);
mozilla::Range<const char16_t> source(source_.data(), source_.size());
return js::BigIntLiteralIsZero(source);
}

Просмотреть файл

@ -312,25 +312,13 @@ template <XDRMode mode>
template <XDRMode mode>
/* static */ XDRResult StencilXDR::BigInt(XDRState<mode>* xdr,
BigIntStencil& stencil) {
uint64_t length;
uint32_t size;
if (mode == XDR_ENCODE) {
length = stencil.length_;
size = stencil.source_.size();
}
MOZ_TRY(xdr->codeUint32(&size));
MOZ_TRY(xdr->codeUint64(&length));
XDRTranscodeString<char16_t> chars;
if (mode == XDR_DECODE) {
stencil.buf_ = xdr->cx()->template make_pod_array<char16_t>(length);
if (!stencil.buf_) {
return xdr->fail(JS::TranscodeResult_Throw);
}
stencil.length_ = length;
}
return xdr->codeChars(stencil.buf_.get(), stencil.length_);
return XDRSpanContent(xdr, stencil.source_, size);
}
template <XDRMode mode>