Bug 1471500 - Complete initial implementation of the bulk-memory proposal. Part 4 of 10. r=bbouvier.

This patch moves |const DataSegmentVector dataSegments_| and |const
ElemSegmentVector elemSegments_| from class Module to class Code, so as to
make their lifetimes at least as long as that of any instance derived from the
originating module.  That is because they need to be reachable from an
Instance, in turn because they need to be consulted at runtime by the
implementation of {memory,table}.{init,drop}.

The change is mostly mechanical.  Functions that had to change include:

* "sizeOf" memory reporting functions

* serialisation/deserialisation functions

The only complication is in Module::instantiate.  In the case where
debugging is active, the resulting instantiation cannot share code with
other instantiations of the same module, and many structures are cloned.
This patch accordingly adds cloning of the data segments (easy) and the
element segments (not so easy) since ElemSegment has no copy constructor.

--HG--
extra : rebase_source : 3e3c74eefc04a742eed1606161ac2c7088870b3e
This commit is contained in:
Julian Seward 2018-09-10 15:09:32 +02:00
parent 7de5bc3b8e
commit 84c591be8c
5 changed files with 83 additions and 41 deletions

View File

@ -1143,11 +1143,15 @@ JumpTables::init(CompileMode mode, const ModuleSegment& ms, const CodeRangeVecto
return true;
}
Code::Code(UniqueCodeTier tier1, const Metadata& metadata, JumpTables&& maybeJumpTables)
Code::Code(UniqueCodeTier tier1, const Metadata& metadata,
JumpTables&& maybeJumpTables, DataSegmentVector&& dataSegments,
ElemSegmentVector&& elemSegments)
: tier1_(std::move(tier1)),
metadata_(&metadata),
profilingLabels_(mutexid::WasmCodeProfilingLabels, CacheableCharsVector()),
jumpTables_(std::move(maybeJumpTables))
jumpTables_(std::move(maybeJumpTables)),
dataSegments_(std::move(dataSegments)),
elemSegments_(std::move(elemSegments))
{}
bool
@ -1419,7 +1423,9 @@ Code::addSizeOfMiscIfNotSeen(MallocSizeOf mallocSizeOf,
*data += mallocSizeOf(this) +
metadata().sizeOfIncludingThisIfNotSeen(mallocSizeOf, seenMetadata) +
profilingLabels_.lock()->sizeOfExcludingThis(mallocSizeOf) +
jumpTables_.sizeOfMiscExcludingThis();
jumpTables_.sizeOfMiscExcludingThis() +
dataSegments_.sizeOfExcludingThis(mallocSizeOf) +
SizeOfVectorExcludingThis(elemSegments_, mallocSizeOf);
for (auto t : tiers())
codeTier(t).addSizeOfMisc(mallocSizeOf, code, data);
@ -1448,6 +1454,8 @@ size_t
Code::serializedSize() const
{
return metadata().serializedSize() +
SerializedPodVectorSize(dataSegments_) +
SerializedVectorSize(elemSegments_) +
codeTier(Tier::Serialized).serializedSize();
}
@ -1457,6 +1465,8 @@ Code::serialize(uint8_t* cursor, const LinkData& linkData) const
MOZ_RELEASE_ASSERT(!metadata().debugEnabled);
cursor = metadata().serialize(cursor);
cursor = SerializePodVector(cursor, dataSegments_);
cursor = SerializeVector(cursor, elemSegments_);
cursor = codeTier(Tier::Serialized).serialize(cursor, linkData);
return cursor;
}
@ -1472,6 +1482,16 @@ Code::deserialize(const uint8_t* cursor,
if (!cursor)
return nullptr;
DataSegmentVector dataSegments;
cursor = DeserializePodVector(cursor, &dataSegments);
if (!cursor)
return nullptr;
ElemSegmentVector elemSegments;
cursor = DeserializeVector(cursor, &elemSegments);
if (!cursor)
return nullptr;
UniqueCodeTier codeTier;
cursor = CodeTier::deserialize(cursor, linkData, &codeTier);
if (!cursor)
@ -1481,7 +1501,10 @@ Code::deserialize(const uint8_t* cursor,
if (!jumpTables.init(CompileMode::Once, codeTier->segment(), codeTier->metadata().codeRanges))
return nullptr;
MutableCode code = js_new<Code>(std::move(codeTier), metadata, std::move(jumpTables));
MutableCode code = js_new<Code>(std::move(codeTier), metadata,
std::move(jumpTables),
std::move(dataSegments),
std::move(elemSegments));
if (!code || !code->initialize(bytecode, linkData))
return nullptr;

View File

@ -745,9 +745,13 @@ class Code : public ShareableBase<Code>
SharedMetadata metadata_;
ExclusiveData<CacheableCharsVector> profilingLabels_;
JumpTables jumpTables_;
const DataSegmentVector dataSegments_;
const ElemSegmentVector elemSegments_;
public:
Code(UniqueCodeTier tier1, const Metadata& metadata, JumpTables&& maybeJumpTables);
Code(UniqueCodeTier tier1, const Metadata& metadata,
JumpTables&& maybeJumpTables, DataSegmentVector&& dataSegments,
ElemSegmentVector&& elemSegments);
bool initialized() const { return tier1_->initialized(); }
bool initialize(const ShareableBytes& bytecode, const LinkData& linkData);
@ -772,6 +776,8 @@ class Code : public ShareableBase<Code>
const CodeTier& codeTier(Tier tier) const;
const Metadata& metadata() const { return *metadata_; }
const DataSegmentVector& dataSegments() const { return dataSegments_; }
const ElemSegmentVector& elemSegments() const { return elemSegments_; }
const ModuleSegment& segment(Tier iter) const {
return codeTier(iter).segment();

View File

@ -954,7 +954,10 @@ ModuleGenerator::finishModule(const ShareableBytes& bytecode, UniqueLinkData* li
if (!codeTier)
return nullptr;
MutableCode code = js_new<Code>(std::move(codeTier), *metadata_, std::move(jumpTables));
MutableCode code = js_new<Code>(std::move(codeTier), *metadata_,
std::move(jumpTables),
std::move(env_->dataSegments),
std::move(env_->elemSegments));
if (!code || !code->initialize(bytecode, *linkData_))
return nullptr;
@ -982,8 +985,6 @@ ModuleGenerator::finishModule(const ShareableBytes& bytecode, UniqueLinkData* li
SharedModule module(js_new<Module>(*code,
std::move(env_->imports),
std::move(env_->exports),
std::move(env_->dataSegments),
std::move(env_->elemSegments),
std::move(structTypes),
bytecode,
std::move(debugUnlinkedCode),

View File

@ -89,8 +89,10 @@ Module::finishTier2(const LinkData& linkData, UniqueCodeTier tier2Arg, ModuleEnv
if (!code().setTier2(std::move(tier2Arg), *bytecode_, linkData))
return false;
for (uint32_t i = 0; i < elemSegments_.length(); i++)
elemSegments_[i].setTier2(std::move(env2.elemSegments[i].elemCodeRangeIndices(Tier::Ion)));
for (uint32_t i = 0; i < code().elemSegments().length(); i++) {
code().elemSegments()[i]
.setTier2(std::move(env2.elemSegments[i].elemCodeRangeIndices(Tier::Ion)));
}
// Before we can make tier-2 live, we need to compile tier2 versions of any
// extant tier1 lazy stubs (otherwise, tiering would break the assumption
@ -165,8 +167,6 @@ Module::serializedSize(const LinkData& linkData) const
return linkData.serializedSize() +
SerializedVectorSize(imports_) +
SerializedVectorSize(exports_) +
SerializedPodVectorSize(dataSegments_) +
SerializedVectorSize(elemSegments_) +
SerializedVectorSize(structTypes_) +
code_->serializedSize();
}
@ -182,8 +182,6 @@ Module::serialize(const LinkData& linkData, uint8_t* begin, size_t size) const
cursor = linkData.serialize(cursor);
cursor = SerializeVector(cursor, imports_);
cursor = SerializeVector(cursor, exports_);
cursor = SerializePodVector(cursor, dataSegments_);
cursor = SerializeVector(cursor, elemSegments_);
cursor = SerializeVector(cursor, structTypes_);
cursor = code_->serialize(cursor, linkData);
MOZ_RELEASE_ASSERT(cursor == begin + size);
@ -222,16 +220,6 @@ Module::deserialize(const uint8_t* begin, size_t size, Metadata* maybeMetadata)
if (!cursor)
return nullptr;
DataSegmentVector dataSegments;
cursor = DeserializePodVector(cursor, &dataSegments);
if (!cursor)
return nullptr;
ElemSegmentVector elemSegments;
cursor = DeserializeVector(cursor, &elemSegments);
if (!cursor)
return nullptr;
StructTypeVector structTypes;
cursor = DeserializeVector(cursor, &structTypes);
if (!cursor)
@ -248,8 +236,6 @@ Module::deserialize(const uint8_t* begin, size_t size, Metadata* maybeMetadata)
return js_new<Module>(*code,
std::move(imports),
std::move(exports),
std::move(dataSegments),
std::move(elemSegments),
std::move(structTypes),
*bytecode);
}
@ -344,8 +330,6 @@ Module::addSizeOfMisc(MallocSizeOf mallocSizeOf,
*data += mallocSizeOf(this) +
SizeOfVectorExcludingThis(imports_, mallocSizeOf) +
SizeOfVectorExcludingThis(exports_, mallocSizeOf) +
dataSegments_.sizeOfExcludingThis(mallocSizeOf) +
SizeOfVectorExcludingThis(elemSegments_, mallocSizeOf) +
SizeOfVectorExcludingThis(structTypes_, mallocSizeOf) +
bytecode_->sizeOfIncludingThisIfNotSeen(mallocSizeOf, seenBytes);
if (debugUnlinkedCode_)
@ -459,7 +443,7 @@ Module::initSegments(JSContext* cx,
// Perform all error checks up front so that this function does not perform
// partial initialization if an error is reported.
for (const ElemSegment& seg : elemSegments_) {
for (const ElemSegment& seg : code_->elemSegments()) {
uint32_t numElems = seg.elemCodeRangeIndices(tier).length();
uint32_t tableLength = tables[seg.tableIndex]->length();
@ -474,7 +458,7 @@ Module::initSegments(JSContext* cx,
if (memoryObj) {
uint32_t memoryLength = memoryObj->volatileMemoryLength();
for (const DataSegment& seg : dataSegments_) {
for (const DataSegment& seg : code_->dataSegments()) {
uint32_t offset = EvaluateInitExpr(globalImportValues, seg.offset);
if (offset > memoryLength || memoryLength - offset < seg.length) {
@ -484,13 +468,13 @@ Module::initSegments(JSContext* cx,
}
}
} else {
MOZ_ASSERT(dataSegments_.empty());
MOZ_ASSERT(code_->dataSegments().empty());
}
// Now that initialization can't fail partway through, write data/elem
// segments into memories/tables.
for (const ElemSegment& seg : elemSegments_) {
for (const ElemSegment& seg : code_->elemSegments()) {
Table& table = *tables[seg.tableIndex];
uint32_t offset = EvaluateInitExpr(globalImportValues, seg.offset);
const CodeRangeVector& codeRanges = metadata(tier).codeRanges;
@ -521,7 +505,7 @@ Module::initSegments(JSContext* cx,
if (memoryObj) {
uint8_t* memoryBase = memoryObj->buffer().dataPointerEither().unwrap(/* memcpy */);
for (const DataSegment& seg : dataSegments_) {
for (const DataSegment& seg : code_->dataSegments()) {
MOZ_ASSERT(seg.bytecodeOffset <= bytecode_->length());
MOZ_ASSERT(seg.length <= bytecode_->length() - seg.bytecodeOffset);
uint32_t offset = EvaluateInitExpr(globalImportValues, seg.offset);
@ -633,7 +617,7 @@ Module::instantiateMemory(JSContext* cx, MutableHandleWasmMemoryObject memory) c
{
if (!metadata().usesMemory()) {
MOZ_ASSERT(!memory);
MOZ_ASSERT(dataSegments_.empty());
MOZ_ASSERT(code_->dataSegments().empty());
return true;
}
@ -961,7 +945,41 @@ Module::instantiate(JSContext* cx,
if (!jumpTables.init(CompileMode::Once, codeTier->segment(), metadata(tier).codeRanges))
return false;
MutableCode debugCode = js_new<Code>(std::move(codeTier), metadata(), std::move(jumpTables));
DataSegmentVector dataSegments;
if (!dataSegments.appendAll(code_->dataSegments()))
return false;
ElemSegmentVector elemSegments;
for (const ElemSegment& eseg : code_->elemSegments()) {
// This (debugging) code path is called only for tier 1.
MOZ_ASSERT(eseg.elemCodeRangeIndices2_.empty());
// ElemSegment doesn't have a (fallible) copy constructor,
// so we have to clone it "by hand".
ElemSegment clone;
clone.tableIndex = eseg.tableIndex;
clone.offset = eseg.offset;
MOZ_ASSERT(clone.elemFuncIndices.empty());
if (!clone.elemFuncIndices.appendAll(eseg.elemFuncIndices))
return false;
MOZ_ASSERT(clone.elemCodeRangeIndices1_.empty());
if (!clone.elemCodeRangeIndices1_.appendAll(eseg.elemCodeRangeIndices1_))
return false;
MOZ_ASSERT(clone.elemCodeRangeIndices2_.empty());
if (!clone.elemCodeRangeIndices2_.appendAll(eseg.elemCodeRangeIndices2_))
return false;
if (!elemSegments.append(std::move(clone)))
return false;
}
MutableCode debugCode = js_new<Code>(std::move(codeTier), metadata(),
std::move(jumpTables),
std::move(dataSegments),
std::move(elemSegments));
if (!debugCode || !debugCode->initialize(*bytecode_, *debugLinkData_)) {
ReportOutOfMemory(cx);
return false;

View File

@ -51,8 +51,6 @@ class Module : public JS::WasmModule
const SharedCode code_;
const ImportVector imports_;
const ExportVector exports_;
const DataSegmentVector dataSegments_;
const ElemSegmentVector elemSegments_;
const StructTypeVector structTypes_;
const SharedBytes bytecode_;
@ -92,8 +90,6 @@ class Module : public JS::WasmModule
Module(const Code& code,
ImportVector&& imports,
ExportVector&& exports,
DataSegmentVector&& dataSegments,
ElemSegmentVector&& elemSegments,
StructTypeVector&& structTypes,
const ShareableBytes& bytecode,
UniqueConstBytes debugUnlinkedCode = nullptr,
@ -101,8 +97,6 @@ class Module : public JS::WasmModule
: code_(&code),
imports_(std::move(imports)),
exports_(std::move(exports)),
dataSegments_(std::move(dataSegments)),
elemSegments_(std::move(elemSegments)),
structTypes_(std::move(structTypes)),
bytecode_(&bytecode),
debugCodeClaimed_(false),