зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
5aaa999a0c
Коммит
65e44b52e5
|
@ -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>
|
||||
|
|
Загрузка…
Ссылка в новой задаче