mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 00:35:44 +00:00
Bug 1644243 - Allocate strings in the tenured heap if they will be atomized right after, and pass through InitialHeap to string allocation r=jonco
Differential Revision: https://phabricator.services.mozilla.com/D78806
This commit is contained in:
parent
3ca8acd1fb
commit
751343a79e
@ -2384,7 +2384,8 @@ JSAtom* ParserBase::prefixAccessorName(PropertyType propType,
|
||||
prefix = cx_->names().getPrefix;
|
||||
}
|
||||
|
||||
RootedString str(cx_, ConcatStrings<CanGC>(cx_, prefix, propAtom));
|
||||
RootedString str(
|
||||
cx_, ConcatStrings<CanGC>(cx_, prefix, propAtom, js::gc::TenuredHeap));
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -6049,10 +6049,12 @@ bool CacheIRCompiler::emitCallStringConcatResult(StringOperandId lhsId,
|
||||
|
||||
callvm.prepare();
|
||||
|
||||
masm.Push(static_cast<js::jit::Imm32>(js::gc::DefaultHeap));
|
||||
masm.Push(rhs);
|
||||
masm.Push(lhs);
|
||||
|
||||
using Fn = JSString* (*)(JSContext*, HandleString, HandleString);
|
||||
using Fn = JSString* (*)(JSContext*, HandleString, HandleString,
|
||||
js::gc::InitialHeap);
|
||||
callvm.call<Fn, ConcatStrings<CanGC>>();
|
||||
|
||||
return true;
|
||||
|
@ -9008,9 +9008,11 @@ void CodeGenerator::visitSameValueVM(LSameValueVM* lir) {
|
||||
|
||||
void CodeGenerator::emitConcat(LInstruction* lir, Register lhs, Register rhs,
|
||||
Register output) {
|
||||
using Fn = JSString* (*)(JSContext*, HandleString, HandleString);
|
||||
using Fn = JSString* (*)(JSContext*, HandleString, HandleString,
|
||||
js::gc::InitialHeap);
|
||||
OutOfLineCode* ool = oolCallVM<Fn, ConcatStrings<CanGC>>(
|
||||
lir, ArgList(lhs, rhs), StoreRegisterTo(output));
|
||||
lir, ArgList(lhs, rhs, static_cast<Imm32>(gc::DefaultHeap)),
|
||||
StoreRegisterTo(output));
|
||||
|
||||
const JitRealm* jitRealm = gen->realm->jitRealm();
|
||||
JitCode* stringConcatStub =
|
||||
|
@ -767,7 +767,8 @@ JSLinearString* js::Int32ToString(JSContext* cx, int32_t si) {
|
||||
BackfillInt32InBuffer(si, buffer, ArrayLength(buffer), &length);
|
||||
|
||||
mozilla::Range<const Latin1Char> chars(start, length);
|
||||
JSInlineString* str = NewInlineString<allowGC>(cx, chars);
|
||||
JSInlineString* str =
|
||||
NewInlineString<allowGC>(cx, chars, js::gc::TenuredHeap);
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -1549,7 +1550,8 @@ static JSString* NumberToStringWithBase(JSContext* cx, double d, int base) {
|
||||
numStrLen = strlen(numStr);
|
||||
}
|
||||
|
||||
JSLinearString* s = NewStringCopyN<allowGC>(cx, numStr, numStrLen);
|
||||
JSLinearString* s =
|
||||
NewStringCopyN<allowGC>(cx, numStr, numStrLen, js::gc::TenuredHeap);
|
||||
if (!s) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -1627,7 +1629,7 @@ JSLinearString* js::IndexToString(JSContext* cx, uint32_t index) {
|
||||
RangedPtr<Latin1Char> start = BackfillIndexInCharBuffer(index, end);
|
||||
|
||||
mozilla::Range<const Latin1Char> chars(start.get(), end - start);
|
||||
JSInlineString* str = NewInlineString<CanGC>(cx, chars);
|
||||
JSInlineString* str = NewInlineString<CanGC>(cx, chars, js::gc::TenuredHeap);
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -110,7 +110,9 @@ class MOZ_NON_PARAM InlineCharBuffer {
|
||||
return true;
|
||||
}
|
||||
|
||||
JSString* toStringDontDeflate(JSContext* cx, size_t length) {
|
||||
JSString* toStringDontDeflate(
|
||||
JSContext* cx, size_t length,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap) {
|
||||
MOZ_ASSERT(length == lastRequestedLength);
|
||||
|
||||
if (JSInlineString::lengthFits<CharT>(length)) {
|
||||
@ -123,16 +125,17 @@ class MOZ_NON_PARAM InlineCharBuffer {
|
||||
}
|
||||
|
||||
mozilla::Range<const CharT> range(inlineStorage, length);
|
||||
return NewInlineString<CanGC>(cx, range);
|
||||
return NewInlineString<CanGC>(cx, range, heap);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(heapStorage,
|
||||
"heap storage was not allocated for non-inline string");
|
||||
|
||||
return NewStringDontDeflate<CanGC>(cx, std::move(heapStorage), length);
|
||||
return NewStringDontDeflate<CanGC>(cx, std::move(heapStorage), length, heap);
|
||||
}
|
||||
|
||||
JSString* toString(JSContext* cx, size_t length) {
|
||||
JSString* toString(JSContext* cx, size_t length,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap) {
|
||||
MOZ_ASSERT(length == lastRequestedLength);
|
||||
|
||||
if (JSInlineString::lengthFits<CharT>(length)) {
|
||||
@ -140,13 +143,13 @@ class MOZ_NON_PARAM InlineCharBuffer {
|
||||
!heapStorage,
|
||||
"expected only inline storage when length fits in inline string");
|
||||
|
||||
return NewStringCopyN<CanGC>(cx, inlineStorage, length);
|
||||
return NewStringCopyN<CanGC>(cx, inlineStorage, length, heap);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(heapStorage,
|
||||
"heap storage was not allocated for non-inline string");
|
||||
|
||||
return NewString<CanGC>(cx, std::move(heapStorage), length);
|
||||
return NewString<CanGC>(cx, std::move(heapStorage), length, heap);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -876,14 +876,14 @@ struct AtomizeUTF8OrWTF8CharsWrapper {
|
||||
template <typename CharT>
|
||||
static MOZ_ALWAYS_INLINE JSLinearString* MakeLinearStringForAtomization(
|
||||
JSContext* cx, const CharT* chars, size_t length) {
|
||||
return NewStringCopyN<NoGC>(cx, chars, length);
|
||||
return NewStringCopyN<NoGC>(cx, chars, length, gc::TenuredHeap);
|
||||
}
|
||||
|
||||
// MakeLinearStringForAtomization has one further variant -- a non-template
|
||||
// overload accepting LittleEndianChars.
|
||||
static MOZ_ALWAYS_INLINE JSLinearString* MakeLinearStringForAtomization(
|
||||
JSContext* cx, LittleEndianChars chars, size_t length) {
|
||||
return NewStringFromLittleEndianNoGC(cx, chars, length);
|
||||
return NewStringFromLittleEndianNoGC(cx, chars, length, gc::TenuredHeap);
|
||||
}
|
||||
|
||||
template <typename CharT, typename WrapperT>
|
||||
@ -891,7 +891,8 @@ static MOZ_ALWAYS_INLINE JSLinearString* MakeUTF8AtomHelper(
|
||||
JSContext* cx, const WrapperT* chars, size_t length) {
|
||||
if (JSInlineString::lengthFits<CharT>(length)) {
|
||||
CharT* storage;
|
||||
JSInlineString* str = AllocateInlineString<NoGC>(cx, length, &storage);
|
||||
JSInlineString* str =
|
||||
AllocateInlineString<NoGC>(cx, length, &storage, gc::TenuredHeap);
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -914,7 +915,8 @@ static MOZ_ALWAYS_INLINE JSLinearString* MakeUTF8AtomHelper(
|
||||
InflateUTF8CharsToBufferAndTerminate(chars->utf8, newStr.get(), length,
|
||||
chars->encoding);
|
||||
|
||||
return JSLinearString::new_<NoGC>(cx, std::move(newStr), length);
|
||||
return JSLinearString::new_<NoGC>(cx, std::move(newStr), length,
|
||||
gc::TenuredHeap);
|
||||
}
|
||||
|
||||
// Another 2 variants of MakeLinearStringForAtomization.
|
||||
|
@ -27,13 +27,12 @@ namespace js {
|
||||
|
||||
// Allocate a thin inline string if possible, and a fat inline string if not.
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
static MOZ_ALWAYS_INLINE JSInlineString* AllocateInlineString(JSContext* cx,
|
||||
size_t len,
|
||||
CharT** chars) {
|
||||
static MOZ_ALWAYS_INLINE JSInlineString* AllocateInlineString(
|
||||
JSContext* cx, size_t len, CharT** chars, js::gc::InitialHeap heap) {
|
||||
MOZ_ASSERT(JSInlineString::lengthFits<CharT>(len));
|
||||
|
||||
if (JSThinInlineString::lengthFits<CharT>(len)) {
|
||||
JSThinInlineString* str = JSThinInlineString::new_<allowGC>(cx);
|
||||
JSThinInlineString* str = JSThinInlineString::new_<allowGC>(cx, heap);
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -41,7 +40,7 @@ static MOZ_ALWAYS_INLINE JSInlineString* AllocateInlineString(JSContext* cx,
|
||||
return str;
|
||||
}
|
||||
|
||||
JSFatInlineString* str = JSFatInlineString::new_<allowGC>(cx);
|
||||
JSFatInlineString* str = JSFatInlineString::new_<allowGC>(cx, heap);
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -52,7 +51,8 @@ static MOZ_ALWAYS_INLINE JSInlineString* AllocateInlineString(JSContext* cx,
|
||||
// Create a thin inline string if possible, and a fat inline string if not.
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
static MOZ_ALWAYS_INLINE JSInlineString* NewInlineString(
|
||||
JSContext* cx, mozilla::Range<const CharT> chars) {
|
||||
JSContext* cx, mozilla::Range<const CharT> chars,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap) {
|
||||
/*
|
||||
* Don't bother trying to find a static atom; measurement shows that not
|
||||
* many get here (for one, Atomize is catching them).
|
||||
@ -60,7 +60,7 @@ static MOZ_ALWAYS_INLINE JSInlineString* NewInlineString(
|
||||
|
||||
size_t len = chars.length();
|
||||
CharT* storage;
|
||||
JSInlineString* str = AllocateInlineString<allowGC>(cx, len, &storage);
|
||||
JSInlineString* str = AllocateInlineString<allowGC>(cx, len, &storage, heap);
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -72,11 +72,12 @@ static MOZ_ALWAYS_INLINE JSInlineString* NewInlineString(
|
||||
// Create a thin inline string if possible, and a fat inline string if not.
|
||||
template <typename CharT>
|
||||
static MOZ_ALWAYS_INLINE JSInlineString* NewInlineString(
|
||||
JSContext* cx, HandleLinearString base, size_t start, size_t length) {
|
||||
JSContext* cx, HandleLinearString base, size_t start, size_t length,
|
||||
js::gc::InitialHeap heap) {
|
||||
MOZ_ASSERT(JSInlineString::lengthFits<CharT>(length));
|
||||
|
||||
CharT* chars;
|
||||
JSInlineString* s = AllocateInlineString<CanGC>(cx, length, &chars);
|
||||
JSInlineString* s = AllocateInlineString<CanGC>(cx, length, &chars, heap);
|
||||
if (!s) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -194,7 +195,8 @@ MOZ_ALWAYS_INLINE void JSDependentString::init(JSContext* cx,
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE JSLinearString* JSDependentString::new_(
|
||||
JSContext* cx, JSLinearString* baseArg, size_t start, size_t length) {
|
||||
JSContext* cx, JSLinearString* baseArg, size_t start, size_t length,
|
||||
js::gc::InitialHeap heap) {
|
||||
/*
|
||||
* Try to avoid long chains of dependent strings. We can't avoid these
|
||||
* entirely, however, due to how ropes are flattened.
|
||||
@ -217,8 +219,9 @@ MOZ_ALWAYS_INLINE JSLinearString* JSDependentString::new_(
|
||||
if (useInline) {
|
||||
js::RootedLinearString base(cx, baseArg);
|
||||
return baseArg->hasLatin1Chars()
|
||||
? js::NewInlineString<JS::Latin1Char>(cx, base, start, length)
|
||||
: js::NewInlineString<char16_t>(cx, base, start, length);
|
||||
? js::NewInlineString<JS::Latin1Char>(cx, base, start, length,
|
||||
heap)
|
||||
: js::NewInlineString<char16_t>(cx, base, start, length, heap);
|
||||
}
|
||||
|
||||
JSDependentString* str =
|
||||
@ -256,8 +259,8 @@ MOZ_ALWAYS_INLINE void JSLinearString::init(const JS::Latin1Char* chars,
|
||||
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
MOZ_ALWAYS_INLINE JSLinearString* JSLinearString::new_(
|
||||
JSContext* cx, js::UniquePtr<CharT[], JS::FreePolicy> chars,
|
||||
size_t length) {
|
||||
JSContext* cx, js::UniquePtr<CharT[], JS::FreePolicy> chars, size_t length,
|
||||
js::gc::InitialHeap heap) {
|
||||
if (!validateLength(cx, length)) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -266,7 +269,7 @@ MOZ_ALWAYS_INLINE JSLinearString* JSLinearString::new_(
|
||||
if (cx->zone()->isAtomsZone()) {
|
||||
str = js::Allocate<js::NormalAtom, allowGC>(cx);
|
||||
} else {
|
||||
str = js::AllocateString<JSLinearString, allowGC>(cx, js::gc::DefaultHeap);
|
||||
str = js::AllocateString<JSLinearString, allowGC>(cx, heap);
|
||||
}
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
@ -310,17 +313,18 @@ inline js::PropertyName* JSLinearString::toPropertyName(JSContext* cx) {
|
||||
}
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
MOZ_ALWAYS_INLINE JSThinInlineString* JSThinInlineString::new_(JSContext* cx) {
|
||||
MOZ_ALWAYS_INLINE JSThinInlineString* JSThinInlineString::new_(
|
||||
JSContext* cx, js::gc::InitialHeap heap) {
|
||||
if (cx->zone()->isAtomsZone()) {
|
||||
return (JSThinInlineString*)(js::Allocate<js::NormalAtom, allowGC>(cx));
|
||||
}
|
||||
|
||||
return js::AllocateString<JSThinInlineString, allowGC>(cx,
|
||||
js::gc::DefaultHeap);
|
||||
return js::AllocateString<JSThinInlineString, allowGC>(cx, heap);
|
||||
}
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
MOZ_ALWAYS_INLINE JSFatInlineString* JSFatInlineString::new_(JSContext* cx) {
|
||||
MOZ_ALWAYS_INLINE JSFatInlineString* JSFatInlineString::new_(
|
||||
JSContext* cx, js::gc::InitialHeap heap) {
|
||||
if (cx->zone()->isAtomsZone()) {
|
||||
return (JSFatInlineString*)(js::Allocate<js::FatInlineAtom, allowGC>(cx));
|
||||
}
|
||||
@ -398,7 +402,8 @@ inline JSLinearString* js::StaticStrings::getUnitStringForElement(
|
||||
if (c < UNIT_STATIC_LIMIT) {
|
||||
return getUnit(c);
|
||||
}
|
||||
return js::NewInlineString<CanGC>(cx, mozilla::Range<const char16_t>(&c, 1));
|
||||
return js::NewInlineString<CanGC>(cx, mozilla::Range<const char16_t>(&c, 1),
|
||||
js::gc::DefaultHeap);
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE void JSString::finalize(JSFreeOp* fop) {
|
||||
|
@ -843,7 +843,8 @@ static JSLinearString* EnsureLinear(
|
||||
template <AllowGC allowGC>
|
||||
JSString* js::ConcatStrings(
|
||||
JSContext* cx, typename MaybeRooted<JSString*, allowGC>::HandleType left,
|
||||
typename MaybeRooted<JSString*, allowGC>::HandleType right) {
|
||||
typename MaybeRooted<JSString*, allowGC>::HandleType right,
|
||||
gc::InitialHeap heap) {
|
||||
MOZ_ASSERT_IF(!left->isAtom(), cx->isInsideCurrentZone(left));
|
||||
MOZ_ASSERT_IF(!right->isAtom(), cx->isInsideCurrentZone(right));
|
||||
|
||||
@ -874,8 +875,9 @@ JSString* js::ConcatStrings(
|
||||
Latin1Char* latin1Buf = nullptr; // initialize to silence GCC warning
|
||||
char16_t* twoByteBuf = nullptr; // initialize to silence GCC warning
|
||||
JSInlineString* str =
|
||||
isLatin1 ? AllocateInlineString<allowGC>(cx, wholeLength, &latin1Buf)
|
||||
: AllocateInlineString<allowGC>(cx, wholeLength, &twoByteBuf);
|
||||
isLatin1
|
||||
? AllocateInlineString<allowGC>(cx, wholeLength, &latin1Buf, heap)
|
||||
: AllocateInlineString<allowGC>(cx, wholeLength, &twoByteBuf, heap);
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -911,14 +913,16 @@ JSString* js::ConcatStrings(
|
||||
return str;
|
||||
}
|
||||
|
||||
return JSRope::new_<allowGC>(cx, left, right, wholeLength);
|
||||
return JSRope::new_<allowGC>(cx, left, right, wholeLength, heap);
|
||||
}
|
||||
|
||||
template JSString* js::ConcatStrings<CanGC>(JSContext* cx, HandleString left,
|
||||
HandleString right);
|
||||
HandleString right,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template JSString* js::ConcatStrings<NoGC>(JSContext* cx, JSString* const& left,
|
||||
JSString* const& right);
|
||||
JSString* const& right,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
/**
|
||||
* Copy |src[0..length]| to |dest[0..length]| when copying doesn't narrow and
|
||||
@ -1245,7 +1249,8 @@ bool StaticStrings::init(JSContext* cx) {
|
||||
|
||||
for (uint32_t i = 0; i < UNIT_STATIC_LIMIT; i++) {
|
||||
Latin1Char ch = Latin1Char(i);
|
||||
JSLinearString* s = NewInlineString<NoGC>(cx, Latin1Range(&ch, 1));
|
||||
JSLinearString* s =
|
||||
NewInlineString<NoGC>(cx, Latin1Range(&ch, 1), gc::TenuredHeap);
|
||||
if (!s) {
|
||||
return false;
|
||||
}
|
||||
@ -1255,7 +1260,8 @@ bool StaticStrings::init(JSContext* cx) {
|
||||
|
||||
for (uint32_t i = 0; i < NUM_SMALL_CHARS * NUM_SMALL_CHARS; i++) {
|
||||
Latin1Char buffer[] = {fromSmallChar(i >> 6), fromSmallChar(i & 0x3F)};
|
||||
JSLinearString* s = NewInlineString<NoGC>(cx, Latin1Range(buffer, 2));
|
||||
JSLinearString* s =
|
||||
NewInlineString<NoGC>(cx, Latin1Range(buffer, 2), gc::TenuredHeap);
|
||||
if (!s) {
|
||||
return false;
|
||||
}
|
||||
@ -1274,7 +1280,8 @@ bool StaticStrings::init(JSContext* cx) {
|
||||
Latin1Char buffer[] = {Latin1Char('0' + (i / 100)),
|
||||
Latin1Char('0' + ((i / 10) % 10)),
|
||||
Latin1Char('0' + (i % 10))};
|
||||
JSLinearString* s = NewInlineString<NoGC>(cx, Latin1Range(buffer, 3));
|
||||
JSLinearString* s =
|
||||
NewInlineString<NoGC>(cx, Latin1Range(buffer, 3), gc::TenuredHeap);
|
||||
if (!s) {
|
||||
return false;
|
||||
}
|
||||
@ -1465,7 +1472,8 @@ void JSExternalString::dumpRepresentation(js::GenericPrinter& out,
|
||||
#endif /* defined(DEBUG) || defined(JS_JITSPEW) */
|
||||
|
||||
JSLinearString* js::NewDependentString(JSContext* cx, JSString* baseArg,
|
||||
size_t start, size_t length) {
|
||||
size_t start, size_t length,
|
||||
gc::InitialHeap heap) {
|
||||
if (length == 0) {
|
||||
return cx->emptyString();
|
||||
}
|
||||
@ -1493,7 +1501,7 @@ JSLinearString* js::NewDependentString(JSContext* cx, JSString* baseArg,
|
||||
}
|
||||
}
|
||||
|
||||
return JSDependentString::new_(cx, base, start, length);
|
||||
return JSDependentString::new_(cx, base, start, length, heap);
|
||||
}
|
||||
|
||||
static inline bool CanStoreCharsAsLatin1(const char16_t* s, size_t length) {
|
||||
@ -1512,10 +1520,11 @@ static bool CanStoreCharsAsLatin1(LittleEndianChars chars, size_t length) {
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static MOZ_ALWAYS_INLINE JSInlineString* NewInlineStringDeflated(
|
||||
JSContext* cx, mozilla::Range<const char16_t> chars) {
|
||||
JSContext* cx, const mozilla::Range<const char16_t>& chars,
|
||||
gc::InitialHeap heap = gc::DefaultHeap) {
|
||||
size_t len = chars.length();
|
||||
Latin1Char* storage;
|
||||
JSInlineString* str = AllocateInlineString<allowGC>(cx, len, &storage);
|
||||
JSInlineString* str = AllocateInlineString<allowGC>(cx, len, &storage, heap);
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -1527,14 +1536,14 @@ static MOZ_ALWAYS_INLINE JSInlineString* NewInlineStringDeflated(
|
||||
|
||||
template <AllowGC allowGC>
|
||||
static JSLinearString* NewStringDeflated(JSContext* cx, const char16_t* s,
|
||||
size_t n) {
|
||||
size_t n, gc::InitialHeap heap) {
|
||||
if (JSLinearString* str = TryEmptyOrStaticString(cx, s, n)) {
|
||||
return str;
|
||||
}
|
||||
|
||||
if (JSInlineString::lengthFits<Latin1Char>(n)) {
|
||||
return NewInlineStringDeflated<allowGC>(
|
||||
cx, mozilla::Range<const char16_t>(s, n));
|
||||
cx, mozilla::Range<const char16_t>(s, n), heap);
|
||||
}
|
||||
|
||||
auto news = cx->make_pod_arena_array<Latin1Char>(js::StringBufferArena, n);
|
||||
@ -1548,16 +1557,18 @@ static JSLinearString* NewStringDeflated(JSContext* cx, const char16_t* s,
|
||||
MOZ_ASSERT(CanStoreCharsAsLatin1(s, n));
|
||||
FillFromCompatible(news.get(), s, n);
|
||||
|
||||
return JSLinearString::new_<allowGC>(cx, std::move(news), n);
|
||||
return JSLinearString::new_<allowGC>(cx, std::move(news), n, heap);
|
||||
}
|
||||
|
||||
static JSLinearString* NewStringDeflatedFromLittleEndianNoGC(
|
||||
JSContext* cx, LittleEndianChars chars, size_t length) {
|
||||
JSContext* cx, LittleEndianChars chars, size_t length,
|
||||
gc::InitialHeap heap) {
|
||||
MOZ_ASSERT(CanStoreCharsAsLatin1(chars, length));
|
||||
|
||||
if (JSInlineString::lengthFits<Latin1Char>(length)) {
|
||||
Latin1Char* storage;
|
||||
JSInlineString* str = AllocateInlineString<NoGC>(cx, length, &storage);
|
||||
JSInlineString* str =
|
||||
AllocateInlineString<NoGC>(cx, length, &storage, heap);
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -1575,12 +1586,13 @@ static JSLinearString* NewStringDeflatedFromLittleEndianNoGC(
|
||||
|
||||
FillFromCompatible(news.get(), chars, length);
|
||||
|
||||
return JSLinearString::new_<NoGC>(cx, std::move(news), length);
|
||||
return JSLinearString::new_<NoGC>(cx, std::move(news), length, heap);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
JSLinearString* js::NewStringDontDeflate(
|
||||
JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length) {
|
||||
JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length,
|
||||
gc::InitialHeap heap) {
|
||||
if (JSLinearString* str = TryEmptyOrStaticString(cx, chars.get(), length)) {
|
||||
return str;
|
||||
}
|
||||
@ -1592,106 +1604,118 @@ JSLinearString* js::NewStringDontDeflate(
|
||||
cx, mozilla::Range<const CharT>(chars.get(), length));
|
||||
}
|
||||
|
||||
return JSLinearString::new_<CanGC>(cx, std::move(chars), length);
|
||||
return JSLinearString::new_<CanGC>(cx, std::move(chars), length, heap);
|
||||
}
|
||||
|
||||
template JSLinearString* js::NewStringDontDeflate(JSContext* cx,
|
||||
UniqueTwoByteChars chars,
|
||||
size_t length);
|
||||
size_t length,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* js::NewStringDontDeflate(JSContext* cx,
|
||||
UniqueLatin1Chars chars,
|
||||
size_t length);
|
||||
size_t length,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template <typename CharT>
|
||||
JSLinearString* js::NewString(JSContext* cx,
|
||||
UniquePtr<CharT[], JS::FreePolicy> chars,
|
||||
size_t length) {
|
||||
size_t length, gc::InitialHeap heap) {
|
||||
if constexpr (std::is_same_v<CharT, char16_t>) {
|
||||
if (CanStoreCharsAsLatin1(chars.get(), length)) {
|
||||
// Deflating copies from |chars.get()| and lets |chars| be freed on
|
||||
// return.
|
||||
return NewStringDeflated<CanGC>(cx, chars.get(), length);
|
||||
return NewStringDeflated<CanGC>(cx, chars.get(), length, heap);
|
||||
}
|
||||
}
|
||||
|
||||
return NewStringDontDeflate(cx, std::move(chars), length);
|
||||
return NewStringDontDeflate(cx, std::move(chars), length, heap);
|
||||
}
|
||||
|
||||
template JSLinearString* js::NewString(JSContext* cx, UniqueTwoByteChars chars,
|
||||
size_t length);
|
||||
size_t length, gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* js::NewString(JSContext* cx, UniqueLatin1Chars chars,
|
||||
size_t length);
|
||||
size_t length, gc::InitialHeap heap);
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSLinearString* js::NewStringDontDeflate(
|
||||
JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length) {
|
||||
JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length,
|
||||
gc::InitialHeap heap) {
|
||||
if (JSLinearString* str = TryEmptyOrStaticString(cx, chars.get(), length)) {
|
||||
return str;
|
||||
}
|
||||
|
||||
if (JSInlineString::lengthFits<CharT>(length)) {
|
||||
return NewInlineString<allowGC>(
|
||||
cx, mozilla::Range<const CharT>(chars.get(), length));
|
||||
cx, mozilla::Range<const CharT>(chars.get(), length), heap);
|
||||
}
|
||||
|
||||
return JSLinearString::new_<allowGC>(cx, std::move(chars), length);
|
||||
return JSLinearString::new_<allowGC>(cx, std::move(chars), length, heap);
|
||||
}
|
||||
|
||||
template JSLinearString* js::NewStringDontDeflate<CanGC>(
|
||||
JSContext* cx, UniqueTwoByteChars chars, size_t length);
|
||||
JSContext* cx, UniqueTwoByteChars chars, size_t length,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* js::NewStringDontDeflate<NoGC>(
|
||||
JSContext* cx, UniqueTwoByteChars chars, size_t length);
|
||||
JSContext* cx, UniqueTwoByteChars chars, size_t length,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* js::NewStringDontDeflate<CanGC>(
|
||||
JSContext* cx, UniqueLatin1Chars chars, size_t length);
|
||||
JSContext* cx, UniqueLatin1Chars chars, size_t length,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* js::NewStringDontDeflate<NoGC>(JSContext* cx,
|
||||
UniqueLatin1Chars chars,
|
||||
size_t length);
|
||||
size_t length,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSLinearString* js::NewString(JSContext* cx,
|
||||
UniquePtr<CharT[], JS::FreePolicy> chars,
|
||||
size_t length) {
|
||||
size_t length, gc::InitialHeap heap) {
|
||||
if constexpr (std::is_same_v<CharT, char16_t>) {
|
||||
if (CanStoreCharsAsLatin1(chars.get(), length)) {
|
||||
return NewStringDeflated<allowGC>(cx, chars.get(), length);
|
||||
return NewStringDeflated<allowGC>(cx, chars.get(), length, heap);
|
||||
}
|
||||
}
|
||||
|
||||
return NewStringDontDeflate<allowGC>(cx, std::move(chars), length);
|
||||
return NewStringDontDeflate<allowGC>(cx, std::move(chars), length, heap);
|
||||
}
|
||||
|
||||
template JSLinearString* js::NewString<CanGC>(JSContext* cx,
|
||||
UniqueTwoByteChars chars,
|
||||
size_t length);
|
||||
size_t length,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* js::NewString<NoGC>(JSContext* cx,
|
||||
UniqueTwoByteChars chars,
|
||||
size_t length);
|
||||
size_t length,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* js::NewString<CanGC>(JSContext* cx,
|
||||
UniqueLatin1Chars chars,
|
||||
size_t length);
|
||||
size_t length,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* js::NewString<NoGC>(JSContext* cx,
|
||||
UniqueLatin1Chars chars,
|
||||
size_t length);
|
||||
size_t length,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
namespace js {
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSLinearString* NewStringCopyNDontDeflate(JSContext* cx, const CharT* s,
|
||||
size_t n) {
|
||||
size_t n, gc::InitialHeap heap) {
|
||||
if (JSLinearString* str = TryEmptyOrStaticString(cx, s, n)) {
|
||||
return str;
|
||||
}
|
||||
|
||||
if (JSInlineString::lengthFits<CharT>(n)) {
|
||||
return NewInlineString<allowGC>(cx, mozilla::Range<const CharT>(s, n));
|
||||
return NewInlineString<allowGC>(cx, mozilla::Range<const CharT>(s, n),
|
||||
heap);
|
||||
}
|
||||
|
||||
auto news = cx->make_pod_arena_array<CharT>(js::StringBufferArena, n);
|
||||
@ -1704,30 +1728,36 @@ JSLinearString* NewStringCopyNDontDeflate(JSContext* cx, const CharT* s,
|
||||
|
||||
FillChars(news.get(), s, n);
|
||||
|
||||
return JSLinearString::new_<allowGC>(cx, std::move(news), n);
|
||||
return JSLinearString::new_<allowGC>(cx, std::move(news), n, heap);
|
||||
}
|
||||
|
||||
template JSLinearString* NewStringCopyNDontDeflate<CanGC>(JSContext* cx,
|
||||
const char16_t* s,
|
||||
size_t n);
|
||||
size_t n,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* NewStringCopyNDontDeflate<NoGC>(JSContext* cx,
|
||||
const char16_t* s,
|
||||
size_t n);
|
||||
size_t n,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* NewStringCopyNDontDeflate<CanGC>(JSContext* cx,
|
||||
const Latin1Char* s,
|
||||
size_t n);
|
||||
size_t n,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* NewStringCopyNDontDeflate<NoGC>(JSContext* cx,
|
||||
const Latin1Char* s,
|
||||
size_t n);
|
||||
size_t n,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
static JSLinearString* NewUndeflatedStringFromLittleEndianNoGC(
|
||||
JSContext* cx, LittleEndianChars chars, size_t length) {
|
||||
JSContext* cx, LittleEndianChars chars, size_t length,
|
||||
gc::InitialHeap heap) {
|
||||
if (JSInlineString::lengthFits<char16_t>(length)) {
|
||||
char16_t* storage;
|
||||
JSInlineString* str = AllocateInlineString<NoGC>(cx, length, &storage);
|
||||
JSInlineString* str =
|
||||
AllocateInlineString<NoGC>(cx, length, &storage, heap);
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -1744,57 +1774,63 @@ static JSLinearString* NewUndeflatedStringFromLittleEndianNoGC(
|
||||
|
||||
FillChars(news.get(), chars, length);
|
||||
|
||||
return JSLinearString::new_<NoGC>(cx, std::move(news), length);
|
||||
return JSLinearString::new_<NoGC>(cx, std::move(news), length, heap);
|
||||
}
|
||||
|
||||
JSLinearString* NewLatin1StringZ(JSContext* cx, UniqueChars chars) {
|
||||
JSLinearString* NewLatin1StringZ(JSContext* cx, UniqueChars chars,
|
||||
gc::InitialHeap heap) {
|
||||
size_t length = strlen(chars.get());
|
||||
UniqueLatin1Chars latin1(reinterpret_cast<Latin1Char*>(chars.release()));
|
||||
return NewString<CanGC>(cx, std::move(latin1), length);
|
||||
return NewString<CanGC>(cx, std::move(latin1), length, heap);
|
||||
}
|
||||
|
||||
template <AllowGC allowGC, typename CharT>
|
||||
JSLinearString* NewStringCopyN(JSContext* cx, const CharT* s, size_t n) {
|
||||
JSLinearString* NewStringCopyN(JSContext* cx, const CharT* s, size_t n,
|
||||
gc::InitialHeap heap) {
|
||||
if constexpr (std::is_same_v<CharT, char16_t>) {
|
||||
if (CanStoreCharsAsLatin1(s, n)) {
|
||||
return NewStringDeflated<allowGC>(cx, s, n);
|
||||
return NewStringDeflated<allowGC>(cx, s, n, heap);
|
||||
}
|
||||
}
|
||||
|
||||
return NewStringCopyNDontDeflate<allowGC>(cx, s, n);
|
||||
return NewStringCopyNDontDeflate<allowGC>(cx, s, n, heap);
|
||||
}
|
||||
|
||||
template JSLinearString* NewStringCopyN<CanGC>(JSContext* cx, const char16_t* s,
|
||||
size_t n);
|
||||
size_t n, gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* NewStringCopyN<NoGC>(JSContext* cx, const char16_t* s,
|
||||
size_t n);
|
||||
size_t n, gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* NewStringCopyN<CanGC>(JSContext* cx,
|
||||
const Latin1Char* s, size_t n);
|
||||
const Latin1Char* s, size_t n,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
template JSLinearString* NewStringCopyN<NoGC>(JSContext* cx,
|
||||
const Latin1Char* s, size_t n);
|
||||
const Latin1Char* s, size_t n,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
JSLinearString* NewStringFromLittleEndianNoGC(JSContext* cx,
|
||||
LittleEndianChars chars,
|
||||
size_t length) {
|
||||
size_t length,
|
||||
gc::InitialHeap heap) {
|
||||
if (JSLinearString* str = TryEmptyOrStaticString(cx, chars, length)) {
|
||||
return str;
|
||||
}
|
||||
|
||||
if (CanStoreCharsAsLatin1(chars, length)) {
|
||||
return NewStringDeflatedFromLittleEndianNoGC(cx, chars, length);
|
||||
return NewStringDeflatedFromLittleEndianNoGC(cx, chars, length, heap);
|
||||
}
|
||||
|
||||
return NewUndeflatedStringFromLittleEndianNoGC(cx, chars, length);
|
||||
return NewUndeflatedStringFromLittleEndianNoGC(cx, chars, length, heap);
|
||||
}
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
JSLinearString* NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars utf8) {
|
||||
JSLinearString* NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars utf8,
|
||||
gc::InitialHeap heap) {
|
||||
JS::SmallestEncoding encoding = JS::FindSmallestEncoding(utf8);
|
||||
if (encoding == JS::SmallestEncoding::ASCII) {
|
||||
return NewStringCopyN<allowGC>(cx, utf8.begin().get(), utf8.length());
|
||||
return NewStringCopyN<allowGC>(cx, utf8.begin().get(), utf8.length(), heap);
|
||||
}
|
||||
|
||||
size_t length;
|
||||
@ -1806,7 +1842,7 @@ JSLinearString* NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars utf8) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return NewString<allowGC>(cx, std::move(latin1), length);
|
||||
return NewString<allowGC>(cx, std::move(latin1), length, heap);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(encoding == JS::SmallestEncoding::UTF16);
|
||||
@ -1818,11 +1854,12 @@ JSLinearString* NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars utf8) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return NewString<allowGC>(cx, std::move(utf16), length);
|
||||
return NewString<allowGC>(cx, std::move(utf16), length, heap);
|
||||
}
|
||||
|
||||
template JSLinearString* NewStringCopyUTF8N<CanGC>(JSContext* cx,
|
||||
const JS::UTF8Chars utf8);
|
||||
const JS::UTF8Chars utf8,
|
||||
gc::InitialHeap heap);
|
||||
|
||||
MOZ_ALWAYS_INLINE JSString* ExternalStringCache::lookup(const char16_t* chars,
|
||||
size_t len) const {
|
||||
@ -1865,7 +1902,8 @@ MOZ_ALWAYS_INLINE void ExternalStringCache::put(JSString* str) {
|
||||
|
||||
JSString* NewMaybeExternalString(JSContext* cx, const char16_t* s, size_t n,
|
||||
const JSExternalStringCallbacks* callbacks,
|
||||
bool* allocatedExternal) {
|
||||
bool* allocatedExternal,
|
||||
gc::InitialHeap heap) {
|
||||
if (JSString* str = TryEmptyOrStaticString(cx, s, n)) {
|
||||
*allocatedExternal = false;
|
||||
return str;
|
||||
@ -1875,7 +1913,7 @@ JSString* NewMaybeExternalString(JSContext* cx, const char16_t* s, size_t n,
|
||||
CanStoreCharsAsLatin1(s, n)) {
|
||||
*allocatedExternal = false;
|
||||
return NewInlineStringDeflated<AllowGC::CanGC>(
|
||||
cx, mozilla::Range<const char16_t>(s, n));
|
||||
cx, mozilla::Range<const char16_t>(s, n), heap);
|
||||
}
|
||||
|
||||
ExternalStringCache& cache = cx->zone()->externalStringCache();
|
||||
|
@ -781,7 +781,7 @@ class JSLinearString : public JSString {
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
static inline JSLinearString* new_(
|
||||
JSContext* cx, js::UniquePtr<CharT[], JS::FreePolicy> chars,
|
||||
size_t length);
|
||||
size_t length, js::gc::InitialHeap heap);
|
||||
|
||||
template <typename CharT>
|
||||
MOZ_ALWAYS_INLINE const CharT* nonInlineChars(
|
||||
@ -937,7 +937,8 @@ class JSDependentString : public JSLinearString {
|
||||
|
||||
public:
|
||||
static inline JSLinearString* new_(JSContext* cx, JSLinearString* base,
|
||||
size_t start, size_t length);
|
||||
size_t start, size_t length,
|
||||
js::gc::InitialHeap heap);
|
||||
|
||||
#if defined(DEBUG) || defined(JS_JITSPEW)
|
||||
void dumpRepresentation(js::GenericPrinter& out, int indent) const;
|
||||
@ -1022,7 +1023,8 @@ class JSThinInlineString : public JSInlineString {
|
||||
static const size_t MAX_LENGTH_TWO_BYTE = NUM_INLINE_CHARS_TWO_BYTE;
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
static inline JSThinInlineString* new_(JSContext* cx);
|
||||
static inline JSThinInlineString* new_(JSContext* cx,
|
||||
js::gc::InitialHeap heap);
|
||||
|
||||
template <typename CharT>
|
||||
inline CharT* init(size_t length);
|
||||
@ -1060,7 +1062,8 @@ class JSFatInlineString : public JSInlineString {
|
||||
|
||||
public:
|
||||
template <js::AllowGC allowGC>
|
||||
static inline JSFatInlineString* new_(JSContext* cx);
|
||||
static inline JSFatInlineString* new_(JSContext* cx,
|
||||
js::gc::InitialHeap heap);
|
||||
|
||||
static const size_t MAX_LENGTH_LATIN1 =
|
||||
JSString::NUM_INLINE_CHARS_LATIN1 + INLINE_EXTENSION_CHARS_LATIN1;
|
||||
@ -1445,88 +1448,107 @@ static inline UniqueChars StringToNewUTF8CharsZ(JSContext* maybecx,
|
||||
* Allocate a string with the given contents, potentially GCing in the process.
|
||||
*/
|
||||
template <typename CharT>
|
||||
extern JSLinearString* NewString(JSContext* cx,
|
||||
UniquePtr<CharT[], JS::FreePolicy> chars,
|
||||
size_t length);
|
||||
extern JSLinearString* NewString(
|
||||
JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap);
|
||||
|
||||
/* Like NewString, but doesn't attempt to deflate to Latin1. */
|
||||
template <typename CharT>
|
||||
extern JSLinearString* NewStringDontDeflate(
|
||||
JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length);
|
||||
JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap);
|
||||
|
||||
/**
|
||||
* Allocate a string with the given contents. If |allowGC == CanGC|, this may
|
||||
* trigger a GC.
|
||||
*/
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSLinearString* NewString(JSContext* cx,
|
||||
UniquePtr<CharT[], JS::FreePolicy> chars,
|
||||
size_t length);
|
||||
extern JSLinearString* NewString(
|
||||
JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap);
|
||||
|
||||
/* Like NewString, but doesn't try to deflate to Latin1. */
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSLinearString* NewStringDontDeflate(
|
||||
JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length);
|
||||
JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap);
|
||||
|
||||
extern JSLinearString* NewDependentString(JSContext* cx, JSString* base,
|
||||
size_t start, size_t length);
|
||||
extern JSLinearString* NewDependentString(
|
||||
JSContext* cx, JSString* base, size_t start, size_t length,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap);
|
||||
|
||||
/* Take ownership of an array of Latin1Chars. */
|
||||
extern JSLinearString* NewLatin1StringZ(JSContext* cx, UniqueChars chars);
|
||||
extern JSLinearString* NewLatin1StringZ(
|
||||
JSContext* cx, UniqueChars chars,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap);
|
||||
|
||||
/* Copy a counted string and GC-allocate a descriptor for it. */
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSLinearString* NewStringCopyN(JSContext* cx, const CharT* s, size_t n);
|
||||
extern JSLinearString* NewStringCopyN(
|
||||
JSContext* cx, const CharT* s, size_t n,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap);
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
inline JSLinearString* NewStringCopyN(JSContext* cx, const char* s, size_t n) {
|
||||
return NewStringCopyN<allowGC>(cx, reinterpret_cast<const Latin1Char*>(s), n);
|
||||
inline JSLinearString* NewStringCopyN(
|
||||
JSContext* cx, const char* s, size_t n,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap) {
|
||||
return NewStringCopyN<allowGC>(cx, reinterpret_cast<const Latin1Char*>(s), n,
|
||||
heap);
|
||||
}
|
||||
|
||||
/* Like NewStringCopyN, but doesn't try to deflate to Latin1. */
|
||||
template <js::AllowGC allowGC, typename CharT>
|
||||
extern JSLinearString* NewStringCopyNDontDeflate(JSContext* cx, const CharT* s,
|
||||
size_t n);
|
||||
extern JSLinearString* NewStringCopyNDontDeflate(
|
||||
JSContext* cx, const CharT* s, size_t n,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap);
|
||||
|
||||
/* Copy a C string and GC-allocate a descriptor for it. */
|
||||
template <js::AllowGC allowGC>
|
||||
inline JSLinearString* NewStringCopyZ(JSContext* cx, const char16_t* s) {
|
||||
return NewStringCopyN<allowGC>(cx, s, js_strlen(s));
|
||||
inline JSLinearString* NewStringCopyZ(
|
||||
JSContext* cx, const char16_t* s,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap) {
|
||||
return NewStringCopyN<allowGC>(cx, s, js_strlen(s), heap);
|
||||
}
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
inline JSLinearString* NewStringCopyZ(JSContext* cx, const char* s) {
|
||||
return NewStringCopyN<allowGC>(cx, s, strlen(s));
|
||||
inline JSLinearString* NewStringCopyZ(
|
||||
JSContext* cx, const char* s,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap) {
|
||||
return NewStringCopyN<allowGC>(cx, s, strlen(s), heap);
|
||||
}
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
extern JSLinearString* NewStringCopyUTF8N(JSContext* cx,
|
||||
const JS::UTF8Chars utf8);
|
||||
extern JSLinearString* NewStringCopyUTF8N(
|
||||
JSContext* cx, const JS::UTF8Chars utf8,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap);
|
||||
|
||||
template <js::AllowGC allowGC>
|
||||
inline JSLinearString* NewStringCopyUTF8Z(JSContext* cx,
|
||||
const JS::ConstUTF8CharsZ utf8) {
|
||||
inline JSLinearString* NewStringCopyUTF8Z(
|
||||
JSContext* cx, const JS::ConstUTF8CharsZ utf8,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap) {
|
||||
return NewStringCopyUTF8N<allowGC>(
|
||||
cx, JS::UTF8Chars(utf8.c_str(), strlen(utf8.c_str())));
|
||||
cx, JS::UTF8Chars(utf8.c_str(), strlen(utf8.c_str())), heap);
|
||||
}
|
||||
|
||||
JSString* NewMaybeExternalString(JSContext* cx, const char16_t* s, size_t n,
|
||||
const JSExternalStringCallbacks* callbacks,
|
||||
bool* allocatedExternal);
|
||||
JSString* NewMaybeExternalString(
|
||||
JSContext* cx, const char16_t* s, size_t n,
|
||||
const JSExternalStringCallbacks* callbacks, bool* allocatedExternal,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap);
|
||||
|
||||
/**
|
||||
* Allocate a new string consisting of |chars[0..length]| characters.
|
||||
*/
|
||||
extern JSLinearString* NewStringFromLittleEndianNoGC(JSContext* cx,
|
||||
LittleEndianChars chars,
|
||||
size_t length);
|
||||
extern JSLinearString* NewStringFromLittleEndianNoGC(
|
||||
JSContext* cx, LittleEndianChars chars, size_t length,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap);
|
||||
|
||||
static_assert(sizeof(HashNumber) == 4);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
extern JSString* ConcatStrings(
|
||||
JSContext* cx, typename MaybeRooted<JSString*, allowGC>::HandleType left,
|
||||
typename MaybeRooted<JSString*, allowGC>::HandleType right);
|
||||
typename MaybeRooted<JSString*, allowGC>::HandleType right,
|
||||
js::gc::InitialHeap heap = js::gc::DefaultHeap);
|
||||
|
||||
/*
|
||||
* Test if strings are equal. The caller can call the function even if str1
|
||||
|
@ -410,8 +410,8 @@ struct JSStructuredCloneReader {
|
||||
bool readTransferMap();
|
||||
|
||||
template <typename CharT>
|
||||
JSString* readStringImpl(uint32_t nchars);
|
||||
JSString* readString(uint32_t data);
|
||||
JSString* readStringImpl(uint32_t nchars, gc::InitialHeap heap);
|
||||
JSString* readString(uint32_t data, gc::InitialHeap heap = gc::DefaultHeap);
|
||||
|
||||
BigInt* readBigInt(uint32_t data);
|
||||
|
||||
@ -425,7 +425,8 @@ struct JSStructuredCloneReader {
|
||||
MOZ_MUST_USE bool readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems,
|
||||
MutableHandleValue vp);
|
||||
JSObject* readSavedFrame(uint32_t principalsTag);
|
||||
MOZ_MUST_USE bool startRead(MutableHandleValue vp);
|
||||
MOZ_MUST_USE bool startRead(MutableHandleValue vp,
|
||||
gc::InitialHeap strHeap = gc::DefaultHeap);
|
||||
|
||||
SCInput& in;
|
||||
|
||||
@ -2085,7 +2086,8 @@ bool JSStructuredCloneWriter::write(HandleValue v) {
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
JSString* JSStructuredCloneReader::readStringImpl(uint32_t nchars) {
|
||||
JSString* JSStructuredCloneReader::readStringImpl(uint32_t nchars,
|
||||
gc::InitialHeap heap) {
|
||||
if (nchars > JSString::MAX_LENGTH) {
|
||||
JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr,
|
||||
JSMSG_SC_BAD_SERIALIZED_DATA, "string length");
|
||||
@ -2097,14 +2099,15 @@ JSString* JSStructuredCloneReader::readStringImpl(uint32_t nchars) {
|
||||
!in.readChars(chars.get(), nchars)) {
|
||||
return nullptr;
|
||||
}
|
||||
return chars.toStringDontDeflate(context(), nchars);
|
||||
return chars.toStringDontDeflate(context(), nchars, heap);
|
||||
}
|
||||
|
||||
JSString* JSStructuredCloneReader::readString(uint32_t data) {
|
||||
JSString* JSStructuredCloneReader::readString(uint32_t data,
|
||||
gc::InitialHeap heap) {
|
||||
uint32_t nchars = data & BitMask(31);
|
||||
bool latin1 = data & (1 << 31);
|
||||
return latin1 ? readStringImpl<Latin1Char>(nchars)
|
||||
: readStringImpl<char16_t>(nchars);
|
||||
return latin1 ? readStringImpl<Latin1Char>(nchars, heap)
|
||||
: readStringImpl<char16_t>(nchars, heap);
|
||||
}
|
||||
|
||||
BigInt* JSStructuredCloneReader::readBigInt(uint32_t data) {
|
||||
@ -2453,7 +2456,8 @@ static bool PrimitiveToObject(JSContext* cx, MutableHandleValue vp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JSStructuredCloneReader::startRead(MutableHandleValue vp) {
|
||||
bool JSStructuredCloneReader::startRead(MutableHandleValue vp,
|
||||
gc::InitialHeap strHeap) {
|
||||
uint32_t tag, data;
|
||||
bool alreadAppended = false;
|
||||
|
||||
@ -2484,7 +2488,7 @@ bool JSStructuredCloneReader::startRead(MutableHandleValue vp) {
|
||||
|
||||
case SCTAG_STRING:
|
||||
case SCTAG_STRING_OBJECT: {
|
||||
JSString* str = readString(data);
|
||||
JSString* str = readString(data, strHeap);
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
@ -2558,7 +2562,7 @@ bool JSStructuredCloneReader::startRead(MutableHandleValue vp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JSString* str = readString(stringData);
|
||||
JSString* str = readString(stringData, gc::TenuredHeap);
|
||||
if (!str) {
|
||||
return false;
|
||||
}
|
||||
@ -2605,7 +2609,7 @@ bool JSStructuredCloneReader::startRead(MutableHandleValue vp) {
|
||||
case SCTAG_TRANSFER_MAP_HEADER:
|
||||
case SCTAG_TRANSFER_MAP_PENDING_ENTRY:
|
||||
// We should be past all the transfer map tags.
|
||||
JS_ReportErrorNumberASCII(context(), GetErrorMessage, NULL,
|
||||
JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr,
|
||||
JSMSG_SC_BAD_SERIALIZED_DATA, "invalid input");
|
||||
return false;
|
||||
|
||||
@ -2931,7 +2935,7 @@ JSObject* JSStructuredCloneReader::readSavedFrame(uint32_t principalsTag) {
|
||||
}
|
||||
|
||||
if (mutedErrors.isBoolean()) {
|
||||
if (!startRead(&source) || !source.isString()) {
|
||||
if (!startRead(&source, gc::TenuredHeap) || !source.isString()) {
|
||||
return nullptr;
|
||||
}
|
||||
} else if (mutedErrors.isString()) {
|
||||
@ -2975,7 +2979,13 @@ JSObject* JSStructuredCloneReader::readSavedFrame(uint32_t principalsTag) {
|
||||
savedFrame->initSourceId(0);
|
||||
|
||||
RootedValue name(context());
|
||||
if (!startRead(&name) || !(name.isString() || name.isNull())) {
|
||||
if (!startRead(&name, gc::TenuredHeap)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!(name.isString() || name.isNull())) {
|
||||
JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr,
|
||||
JSMSG_SC_BAD_SERIALIZED_DATA,
|
||||
"invalid saved frame cause");
|
||||
return nullptr;
|
||||
}
|
||||
JSAtom* atomName = nullptr;
|
||||
@ -2989,7 +2999,13 @@ JSObject* JSStructuredCloneReader::readSavedFrame(uint32_t principalsTag) {
|
||||
savedFrame->initFunctionDisplayName(atomName);
|
||||
|
||||
RootedValue cause(context());
|
||||
if (!startRead(&cause) || !(cause.isString() || cause.isNull())) {
|
||||
if (!startRead(&cause, gc::TenuredHeap)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!(cause.isString() || cause.isNull())) {
|
||||
JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr,
|
||||
JSMSG_SC_BAD_SERIALIZED_DATA,
|
||||
"invalid saved frame cause");
|
||||
return nullptr;
|
||||
}
|
||||
JSAtom* atomCause = nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user