Bug 1547478 - XDR BinAST metadata using deduplicated BinAST data so that pointers in the metadata will correctly point into the deduplicated data, not into user-provided data that hasn't been deduplicated yet. r=tcampbell

Depends on D29266

Differential Revision: https://phabricator.services.mozilla.com/D29547

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jeff Walden 2019-05-03 21:49:52 +00:00
Родитель 784cd8785e
Коммит 710d4d71ea
2 изменённых файлов: 23 добавлений и 35 удалений

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

@ -2186,25 +2186,6 @@ MOZ_MUST_USE bool ScriptSource::setBinASTSourceCopy(JSContext* cx,
return true;
}
MOZ_MUST_USE bool ScriptSource::initializeBinAST(
JSContext* cx, UniqueChars&& buf, size_t len,
MutableHandle<UniquePtr<frontend::BinASTSourceMetadata>> metadata) {
MOZ_ASSERT(data.is<Missing>(),
"should only be initializing a fresh ScriptSource");
MOZ_ASSERT(binASTMetadata_ == nullptr, "shouldn't have BinAST metadata yet");
auto& cache = cx->zone()->runtimeFromAnyThread()->sharedImmutableStrings();
auto deduped = cache.getOrCreate(std::move(buf), len);
if (!deduped) {
ReportOutOfMemory(cx);
return false;
}
data = SourceType(BinAST(std::move(*deduped)));
binASTMetadata_ = std::move(metadata.get());
return true;
}
const uint8_t* ScriptSource::binASTSource() {
MOZ_ASSERT(hasBinASTSource());
return reinterpret_cast<const uint8_t*>(data.as<BinAST>().string.chars());
@ -2764,14 +2745,22 @@ XDRResult ScriptSource::codeBinASTData(XDRState<mode>* const xdr,
MOZ_TRY(xdr->codeUint32(&binASTLength));
// XDR the BinAST data.
UniquePtr<char[], JS::FreePolicy> bytes;
Maybe<SharedImmutableString> binASTData;
if (mode == XDR_DECODE) {
bytes =
xdr->cx()->template make_pod_array<char>(Max<size_t>(binASTLength, 1));
auto bytes = xdr->cx()->template make_pod_array<char>(Max<size_t>(
binASTLength, 1));
if (!bytes) {
return xdr->fail(JS::TranscodeResult_Throw);
}
MOZ_TRY(xdr->codeBytes(bytes.get(), binASTLength));
auto& cache =
xdr->cx()->zone()->runtimeFromAnyThread()->sharedImmutableStrings();
binASTData = cache.getOrCreate(std::move(bytes), binASTLength);
if (!binASTData) {
ReportOutOfMemory(xdr->cx());
return xdr->fail(JS::TranscodeResult_Throw);
}
} else {
void* bytes = ss->binASTData();
MOZ_TRY(xdr->codeBytes(bytes, binASTLength));
@ -2830,7 +2819,7 @@ XDRResult ScriptSource::codeBinASTData(XDRState<mode>* const xdr,
JSAtom** atomsBase = binASTMetadata->atomsBase();
auto slices = binASTMetadata->sliceBase();
const char* sourceBase =
mode == XDR_ENCODE ? ss->data.as<BinAST>().string.chars() : bytes.get();
(mode == XDR_ENCODE ? ss->data.as<BinAST>().string : *binASTData).chars();
for (uint32_t i = 0; i < numStrings; i++) {
uint8_t isNull;
@ -2867,14 +2856,21 @@ XDRResult ScriptSource::codeBinASTData(XDRState<mode>* const xdr,
}
if (mode == XDR_DECODE) {
MOZ_ASSERT(binASTData.isSome());
MOZ_ASSERT(freshMetadata != nullptr);
if (!ss->initializeBinAST(xdr->cx(), std::move(bytes), binASTLength,
&freshMetadata)) {
return xdr->fail(JS::TranscodeResult_Throw);
}
MOZ_ASSERT(ss->data.is<Missing>(),
"should only be initializing a fresh ScriptSource");
MOZ_ASSERT(ss->binASTMetadata_ == nullptr,
"shouldn't have BinAST metadata yet");
ss->data = SourceType(BinAST(std::move(*binASTData)));
ss->binASTMetadata_ = std::move(freshMetadata.get());
}
MOZ_ASSERT(binASTData.isNothing());
MOZ_ASSERT(freshMetadata == nullptr);
MOZ_ASSERT(ss->data.is<BinAST>());
return Ok();
#endif // !defined(JS_BUILD_BINAST)

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

@ -1000,14 +1000,6 @@ class ScriptSource {
MOZ_MUST_USE bool setBinASTSourceCopy(JSContext* cx, const uint8_t* buf,
size_t len);
/*
* Initialize this as containing BinAST data for |buf|/|len|, using a shared,
* deduplicated version of |buf| if necessary.
*/
MOZ_MUST_USE bool initializeBinAST(
JSContext* cx, UniqueChars&& buf, size_t len,
JS::MutableHandle<UniquePtr<frontend::BinASTSourceMetadata>> metadata);
const uint8_t* binASTSource();
#endif /* JS_BUILD_BINAST */