From 9bcbb31b46224ecfa31fde45d7243172d5ab1953 Mon Sep 17 00:00:00 2001 From: Ted Campbell Date: Tue, 9 Jul 2019 16:13:10 +0000 Subject: [PATCH] Bug 1562272 - Split SharedScriptData::XDR and InitFromElement. r=jandem Both of these functions are now split into SharedScriptData and RuntimeScriptData variants. Differential Revision: https://phabricator.services.mozilla.com/D36354 --HG-- extra : moz-landing-system : lando --- js/src/vm/JSScript.cpp | 144 ++++++++++++++++++++++++++++------------- js/src/vm/JSScript.h | 22 ++++++- 2 files changed, 119 insertions(+), 47 deletions(-) diff --git a/js/src/vm/JSScript.cpp b/js/src/vm/JSScript.cpp index 5cdc21b377f42..9a82a5fabd979 100644 --- a/js/src/vm/JSScript.cpp +++ b/js/src/vm/JSScript.cpp @@ -807,7 +807,6 @@ SharedScriptData::SharedScriptData(uint32_t codeLength, uint32_t noteLength, template /* static */ XDRResult SharedScriptData::XDR(XDRState* xdr, HandleScript script) { - uint32_t natoms = 0; uint32_t codeLength = 0; uint32_t noteLength = 0; uint32_t numResumeOffsets = 0; @@ -815,14 +814,11 @@ XDRResult SharedScriptData::XDR(XDRState* xdr, HandleScript script) { uint32_t numTryNotes = 0; JSContext* cx = xdr->cx(); - RuntimeScriptData* rsd = nullptr; SharedScriptData* ssd = nullptr; if (mode == XDR_ENCODE) { - rsd = script->scriptData(); ssd = script->sharedScriptData(); - natoms = rsd->natoms(); codeLength = ssd->codeLength(); noteLength = ssd->noteLength(); @@ -831,7 +827,6 @@ XDRResult SharedScriptData::XDR(XDRState* xdr, HandleScript script) { numTryNotes = ssd->tryNotes().size(); } - MOZ_TRY(xdr->codeUint32(&natoms)); MOZ_TRY(xdr->codeUint32(&codeLength)); MOZ_TRY(xdr->codeUint32(¬eLength)); MOZ_TRY(xdr->codeUint32(&numResumeOffsets)); @@ -839,12 +834,12 @@ XDRResult SharedScriptData::XDR(XDRState* xdr, HandleScript script) { MOZ_TRY(xdr->codeUint32(&numTryNotes)); if (mode == XDR_DECODE) { - if (!script->createSharedScriptData(cx, codeLength, noteLength, natoms, + if (!script->createSharedScriptData(cx, codeLength, noteLength, numResumeOffsets, numScopeNotes, numTryNotes)) { return xdr->fail(JS::TranscodeResult_Throw); } - rsd = script->scriptData(); + ssd = script->sharedScriptData(); } @@ -864,21 +859,6 @@ XDRResult SharedScriptData::XDR(XDRState* xdr, HandleScript script) { MOZ_TRY(xdr->codeBytes(code, codeLength)); MOZ_TRY(xdr->codeBytes(notes, noteLength)); - { - RootedAtom atom(cx); - GCPtrAtom* vector = rsd->atoms(); - - for (uint32_t i = 0; i != natoms; ++i) { - if (mode == XDR_ENCODE) { - atom = vector[i]; - } - MOZ_TRY(XDRAtom(xdr, &atom)); - if (mode == XDR_DECODE) { - vector[i].init(atom); - } - } - } - for (uint32_t& elem : ssd->resumeOffsets()) { MOZ_TRY(xdr->codeUint32(&elem)); } @@ -938,6 +918,60 @@ RuntimeScriptData::RuntimeScriptData(uint32_t natoms) : natoms_(natoms) { MOZ_ASSERT(AllocationSize(natoms) == cursor); } +template +/* static */ +XDRResult RuntimeScriptData::XDR(XDRState* xdr, HandleScript script) { + uint32_t natoms = 0; + + JSContext* cx = xdr->cx(); + RuntimeScriptData* rsd = nullptr; + + if (mode == XDR_ENCODE) { + rsd = script->scriptData(); + + natoms = rsd->natoms(); + } + + MOZ_TRY(xdr->codeUint32(&natoms)); + + if (mode == XDR_DECODE) { + if (!script->createScriptData(cx, natoms)) { + return xdr->fail(JS::TranscodeResult_Throw); + } + + rsd = script->scriptData(); + } + + { + RootedAtom atom(cx); + GCPtrAtom* vector = rsd->atoms(); + + for (uint32_t i = 0; i != natoms; ++i) { + if (mode == XDR_ENCODE) { + atom = vector[i]; + } + MOZ_TRY(XDRAtom(xdr, &atom)); + if (mode == XDR_DECODE) { + vector[i].init(atom); + } + } + } + + MOZ_TRY(SharedScriptData::XDR(xdr, script)); + + return Ok(); +} + +template + /* static */ + XDRResult + RuntimeScriptData::XDR(XDRState* xdr, HandleScript script); + +template + /* static */ + XDRResult + RuntimeScriptData::XDR(XDRState* xdr, HandleScript script); + template XDRResult js::XDRScript(XDRState* xdr, HandleScope scriptEnclosingScope, HandleScriptSourceObject sourceObjectArg, @@ -1122,7 +1156,7 @@ XDRResult js::XDRScript(XDRState* xdr, HandleScope scriptEnclosingScope, // NOTE: The script data is rooted by the script. MOZ_TRY(PrivateScriptData::XDR(xdr, script, sourceObject, scriptEnclosingScope, fun)); - MOZ_TRY(SharedScriptData::XDR(xdr, script)); + MOZ_TRY(RuntimeScriptData::XDR(xdr, script)); if (mode == XDR_DECODE) { if (!script->shareScriptData(cx)) { @@ -1151,6 +1185,7 @@ XDRResult js::XDRScript(XDRState* xdr, HandleScope scriptEnclosingScope, } } + MOZ_ASSERT(script->code(), "Where's our bytecode?"); scriptDataGuard.release(); return Ok(); } @@ -3538,8 +3573,20 @@ RuntimeScriptData* js::RuntimeScriptData::new_(JSContext* cx, uint32_t natoms) { return new (raw) RuntimeScriptData(natoms); } +bool JSScript::createScriptData(JSContext* cx, uint32_t natoms) { + MOZ_ASSERT(!scriptData_); + + RefPtr rsd(RuntimeScriptData::new_(cx, natoms)); + if (!rsd) { + return false; + } + + scriptData_ = std::move(rsd); + return true; +} + bool JSScript::createSharedScriptData(JSContext* cx, uint32_t codeLength, - uint32_t noteLength, uint32_t natoms, + uint32_t noteLength, uint32_t numResumeOffsets, uint32_t numScopeNotes, uint32_t numTryNotes) { @@ -3552,12 +3599,7 @@ bool JSScript::createSharedScriptData(JSContext* cx, uint32_t codeLength, "Source notes should have been padded already"); #endif - MOZ_ASSERT(!scriptData_); - - RefPtr rsd(RuntimeScriptData::new_(cx, natoms)); - if (!rsd) { - return false; - } + MOZ_ASSERT(!scriptData_->ssd_); js::UniquePtr ssd( SharedScriptData::new_(cx, codeLength, noteLength, numResumeOffsets, @@ -3566,8 +3608,7 @@ bool JSScript::createSharedScriptData(JSContext* cx, uint32_t codeLength, return false; } - rsd->ssd_ = std::move(ssd); - scriptData_ = std::move(rsd); + scriptData_->ssd_ = std::move(ssd); return true; } @@ -3930,11 +3971,10 @@ bool JSScript::initFunctionPrototype(JSContext* cx, HandleScript script, uint32_t codeLength = 1; uint32_t noteLength = 3; - uint32_t numAtoms = 0; uint32_t numResumeOffsets = 0; uint32_t numScopeNotes = 0; uint32_t numTryNotes = 0; - if (!script->createSharedScriptData(cx, codeLength, noteLength, numAtoms, + if (!script->createSharedScriptData(cx, codeLength, noteLength, numResumeOffsets, numScopeNotes, numTryNotes)) { return false; @@ -3948,6 +3988,11 @@ bool JSScript::initFunctionPrototype(JSContext* cx, HandleScript script, notes[1] = SRC_NULL; notes[2] = SRC_NULL; + uint32_t numAtoms = 0; + if (!script->createScriptData(cx, numAtoms)) { + return false; + } + return script->shareScriptData(cx); } @@ -4057,8 +4102,8 @@ bool JSScript::fullyInitFromEmitter(JSContext* cx, HandleScript script, return false; } - // Create and initialize SharedScriptData - if (!SharedScriptData::InitFromEmitter(cx, script, bce, nslots)) { + // Create and initialize RuntimeScriptData/SharedScriptData + if (!RuntimeScriptData::InitFromEmitter(cx, script, bce, nslots)) { return false; } if (!script->shareScriptData(cx)) { @@ -4971,8 +5016,6 @@ bool JSScript::hasBreakpointsAt(jsbytecode* pc) { /* static */ bool SharedScriptData::InitFromEmitter( JSContext* cx, js::HandleScript script, frontend::BytecodeEmitter* bce, uint32_t nslots) { - uint32_t natoms = bce->perScriptData().atomIndices()->count(); - size_t codeLength = bce->bytecodeSection().code().length(); MOZ_RELEASE_ASSERT(codeLength <= frontend::MaxBytecodeLength); @@ -4990,14 +5033,12 @@ bool JSScript::hasBreakpointsAt(jsbytecode* pc) { uint32_t numScopeNotes = bce->bytecodeSection().scopeNoteList().length(); uint32_t numTryNotes = bce->bytecodeSection().tryNoteList().length(); - // Create and initialize SharedScriptData + // Allocate SharedScriptData if (!script->createSharedScriptData(cx, codeLength, noteLength + nullLength, - natoms, numResumeOffsets, numScopeNotes, + numResumeOffsets, numScopeNotes, numTryNotes)) { return false; } - - js::RuntimeScriptData* rsd = script->scriptData(); js::SharedScriptData* data = script->sharedScriptData(); // Initialize POD fields @@ -5024,11 +5065,26 @@ bool JSScript::hasBreakpointsAt(jsbytecode* pc) { bce->bytecodeSection().scopeNoteList().finish(data->scopeNotes()); bce->bytecodeSection().tryNoteList().finish(data->tryNotes()); - InitAtomMap(*bce->perScriptData().atomIndices(), rsd->atoms()); - return true; } +/* static */ bool RuntimeScriptData::InitFromEmitter( + JSContext* cx, js::HandleScript script, frontend::BytecodeEmitter* bce, + uint32_t nslots) { + uint32_t natoms = bce->perScriptData().atomIndices()->count(); + + // Allocate RuntimeScriptData + if (!script->createScriptData(cx, natoms)) { + return false; + } + js::RuntimeScriptData* data = script->scriptData(); + + // Initialize trailing arrays + InitAtomMap(*bce->perScriptData().atomIndices(), data->atoms()); + + return SharedScriptData::InitFromEmitter(cx, script, bce, nslots); +} + void RuntimeScriptData::traceChildren(JSTracer* trc) { MOZ_ASSERT(refCount() != 0); diff --git a/js/src/vm/JSScript.h b/js/src/vm/JSScript.h index 9dd135991d51f..e65cd0cc15a0f 100644 --- a/js/src/vm/JSScript.h +++ b/js/src/vm/JSScript.h @@ -1836,9 +1836,17 @@ class RuntimeScriptData final { void traceChildren(JSTracer* trc); + template + static MOZ_MUST_USE XDRResult XDR(js::XDRState* xdr, + js::HandleScript script); + // Mark this RuntimeScriptData for use in a new zone. void markForCrossZone(JSContext* cx); + static bool InitFromEmitter(JSContext* cx, js::HandleScript script, + js::frontend::BytecodeEmitter* bce, + uint32_t nslots); + size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) { return mallocSizeOf(this) + mallocSizeOf(ssd_.get()); } @@ -2149,10 +2157,18 @@ class JSScript : public js::gc::TenuredCell { js::HandleFunction fun, js::MutableHandleScript scriptp); + template + friend js::XDRResult js::RuntimeScriptData::XDR(js::XDRState* xdr, + js::HandleScript script); + template friend js::XDRResult js::SharedScriptData::XDR(js::XDRState* xdr, js::HandleScript script); + friend bool js::RuntimeScriptData::InitFromEmitter( + JSContext* cx, js::HandleScript script, + js::frontend::BytecodeEmitter* bce, uint32_t nslot); + friend bool js::SharedScriptData::InitFromEmitter( JSContext* cx, js::HandleScript script, js::frontend::BytecodeEmitter* bce, uint32_t nslot); @@ -2835,10 +2851,10 @@ class JSScript : public js::gc::TenuredCell { private: bool createJitScript(JSContext* cx); + bool createScriptData(JSContext* cx, uint32_t natoms); bool createSharedScriptData(JSContext* cx, uint32_t codeLength, - uint32_t noteLength, uint32_t natoms, - uint32_t numResumeOffsets, uint32_t numScopeNotes, - uint32_t numTryNotes); + uint32_t noteLength, uint32_t numResumeOffsets, + uint32_t numScopeNotes, uint32_t numTryNotes); bool shareScriptData(JSContext* cx); void freeScriptData();