зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1277562 - Part 3: Tiering for elemSegments, because they contain CodeRange indices. r=luke
--HG-- extra : rebase_source : cfaa202e98bc120fd33f97635e4cd097aab1e3a2
This commit is contained in:
Родитель
39c2ce83e4
Коммит
6f41d4e35c
|
@ -1064,7 +1064,7 @@ ModuleGenerator::finishFuncDefs()
|
|||
// that all functions have been compiled.
|
||||
|
||||
for (ElemSegment& elems : env_->elemSegments) {
|
||||
Uint32Vector& codeRangeIndices = elems.elemCodeRangeIndices;
|
||||
Uint32Vector& codeRangeIndices = elems.elemCodeRangeIndices(tier_);
|
||||
|
||||
MOZ_ASSERT(codeRangeIndices.empty());
|
||||
if (!codeRangeIndices.reserve(elems.elemFuncIndices.length()))
|
||||
|
@ -1113,7 +1113,7 @@ ModuleGenerator::initSigTableElems(uint32_t sigIndex, Uint32Vector&& elemFuncInd
|
|||
if (!env_->elemSegments.emplaceBack(tableIndex, offset, Move(elemFuncIndices)))
|
||||
return false;
|
||||
|
||||
env_->elemSegments.back().elemCodeRangeIndices = Move(codeRangeIndices);
|
||||
env_->elemSegments.back().elemCodeRangeIndices(tier_) = Move(codeRangeIndices);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -580,11 +580,13 @@ Module::initSegments(JSContext* cx,
|
|||
Instance& instance = instanceObj->instance();
|
||||
const SharedTableVector& tables = instance.tables();
|
||||
|
||||
Tier tier = Tier::TBD;
|
||||
|
||||
// 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_) {
|
||||
uint32_t numElems = seg.elemCodeRangeIndices.length();
|
||||
uint32_t numElems = seg.elemCodeRangeIndices(tier).length();
|
||||
|
||||
uint32_t tableLength = tables[seg.tableIndex]->length();
|
||||
uint32_t offset = EvaluateInitExpr(globalImports, seg.offset);
|
||||
|
@ -617,11 +619,10 @@ Module::initSegments(JSContext* cx,
|
|||
for (const ElemSegment& seg : elemSegments_) {
|
||||
Table& table = *tables[seg.tableIndex];
|
||||
uint32_t offset = EvaluateInitExpr(globalImports, seg.offset);
|
||||
Tier tier = Tier::TBD;
|
||||
const CodeRangeVector& codeRanges = metadata(tier).codeRanges;
|
||||
uint8_t* codeBase = instance.codeBase(tier);
|
||||
|
||||
for (uint32_t i = 0; i < seg.elemCodeRangeIndices.length(); i++) {
|
||||
for (uint32_t i = 0; i < seg.elemCodeRangeIndices(tier).length(); i++) {
|
||||
uint32_t funcIndex = seg.elemFuncIndices[i];
|
||||
if (funcIndex < funcImports.length() && IsExportedWasmFunction(funcImports[funcIndex])) {
|
||||
MOZ_ASSERT(!metadata().isAsmJS());
|
||||
|
@ -634,7 +635,7 @@ Module::initSegments(JSContext* cx,
|
|||
Instance& exportInstance = exportInstanceObj->instance();
|
||||
table.set(offset + i, exportInstance.codeBase(exportTier) + cr.funcTableEntry(), exportInstance);
|
||||
} else {
|
||||
const CodeRange& cr = codeRanges[seg.elemCodeRangeIndices[i]];
|
||||
const CodeRange& cr = codeRanges[seg.elemCodeRangeIndices(tier)[i]];
|
||||
uint32_t entryOffset = table.isTypedFunction()
|
||||
? cr.funcNormalEntry()
|
||||
: cr.funcTableEntry();
|
||||
|
|
|
@ -385,7 +385,7 @@ ElemSegment::serializedSize() const
|
|||
return sizeof(tableIndex) +
|
||||
sizeof(offset) +
|
||||
SerializedPodVectorSize(elemFuncIndices) +
|
||||
SerializedPodVectorSize(elemCodeRangeIndices);
|
||||
SerializedPodVectorSize(elemCodeRangeIndices(Tier::Serialized));
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
|
@ -394,7 +394,7 @@ ElemSegment::serialize(uint8_t* cursor) const
|
|||
cursor = WriteBytes(cursor, &tableIndex, sizeof(tableIndex));
|
||||
cursor = WriteBytes(cursor, &offset, sizeof(offset));
|
||||
cursor = SerializePodVector(cursor, elemFuncIndices);
|
||||
cursor = SerializePodVector(cursor, elemCodeRangeIndices);
|
||||
cursor = SerializePodVector(cursor, elemCodeRangeIndices(Tier::Serialized));
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
@ -404,7 +404,7 @@ ElemSegment::deserialize(const uint8_t* cursor)
|
|||
(cursor = ReadBytes(cursor, &tableIndex, sizeof(tableIndex))) &&
|
||||
(cursor = ReadBytes(cursor, &offset, sizeof(offset))) &&
|
||||
(cursor = DeserializePodVector(cursor, &elemFuncIndices)) &&
|
||||
(cursor = DeserializePodVector(cursor, &elemCodeRangeIndices));
|
||||
(cursor = DeserializePodVector(cursor, &elemCodeRangeIndices(Tier::Serialized)));
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
@ -412,7 +412,7 @@ size_t
|
|||
ElemSegment::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
|
||||
{
|
||||
return elemFuncIndices.sizeOfExcludingThis(mallocSizeOf) +
|
||||
elemCodeRangeIndices.sizeOfExcludingThis(mallocSizeOf);
|
||||
elemCodeRangeIndices(Tier::Serialized).sizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
|
||||
Assumptions::Assumptions(JS::BuildIdCharVector&& buildId)
|
||||
|
|
|
@ -347,6 +347,53 @@ ToCString(ValType type)
|
|||
return ToCString(ToExprType(type));
|
||||
}
|
||||
|
||||
// Code can be compiled either with the Baseline compiler or the Ion compiler,
|
||||
// and tier-variant data are tagged with the Tier value.
|
||||
//
|
||||
// A tier value is used to request tier-variant aspects of code, metadata, or
|
||||
// linkdata. The tiers are normally explicit (Baseline and Ion); implicit tiers
|
||||
// can be obtained through accessors on Code objects (eg, stableTier).
|
||||
|
||||
enum class Tier
|
||||
{
|
||||
Baseline,
|
||||
Debug = Baseline,
|
||||
Ion,
|
||||
Serialized = Ion,
|
||||
|
||||
TBD // A placeholder while tiering is being implemented};
|
||||
};
|
||||
|
||||
// Iterator over tiers present in a tiered data structure.
|
||||
|
||||
class Tiers
|
||||
{
|
||||
Tier t_[2];
|
||||
uint32_t n_;
|
||||
|
||||
public:
|
||||
explicit Tiers() {
|
||||
n_ = 0;
|
||||
}
|
||||
explicit Tiers(Tier t) {
|
||||
t_[0] = t;
|
||||
n_ = 1;
|
||||
}
|
||||
explicit Tiers(Tier t, Tier u) {
|
||||
MOZ_ASSERT(t != u);
|
||||
t_[0] = t;
|
||||
t_[1] = u;
|
||||
n_ = 2;
|
||||
}
|
||||
|
||||
Tier* begin() {
|
||||
return t_;
|
||||
}
|
||||
Tier* end() {
|
||||
return t_ + n_;
|
||||
}
|
||||
};
|
||||
|
||||
// The Val class represents a single WebAssembly value of a given value type,
|
||||
// mostly for the purpose of numeric literals and initializers. A Val does not
|
||||
// directly map to a JS value since there is not (currently) a precise
|
||||
|
@ -681,22 +728,63 @@ typedef Vector<GlobalDesc, 0, SystemAllocPolicy> GlobalDescVector;
|
|||
|
||||
// ElemSegment represents an element segment in the module where each element
|
||||
// describes both its function index and its code range.
|
||||
//
|
||||
// The codeRangeIndices are laid out in a nondeterminstic order as a result of
|
||||
// parallel compilation.
|
||||
|
||||
struct ElemSegment
|
||||
{
|
||||
uint32_t tableIndex;
|
||||
InitExpr offset;
|
||||
Uint32Vector elemFuncIndices;
|
||||
Uint32Vector elemCodeRangeIndices;
|
||||
Uint32Vector elemCodeRangeIndices1_;
|
||||
mutable Uint32Vector elemCodeRangeIndices2_;
|
||||
|
||||
ElemSegment() = default;
|
||||
ElemSegment(uint32_t tableIndex, InitExpr offset, Uint32Vector&& elemFuncIndices)
|
||||
: tableIndex(tableIndex), offset(offset), elemFuncIndices(Move(elemFuncIndices))
|
||||
{}
|
||||
|
||||
Uint32Vector& elemCodeRangeIndices(Tier t) {
|
||||
switch (t) {
|
||||
case Tier::TBD:
|
||||
if (elemCodeRangeIndices1_.length() > 0)
|
||||
return elemCodeRangeIndices1_;
|
||||
return elemCodeRangeIndices2_;
|
||||
case Tier::Baseline:
|
||||
return elemCodeRangeIndices1_;
|
||||
case Tier::Ion:
|
||||
return elemCodeRangeIndices2_;
|
||||
default:
|
||||
MOZ_CRASH("No such tier");
|
||||
}
|
||||
}
|
||||
|
||||
const Uint32Vector& elemCodeRangeIndices(Tier t) const {
|
||||
switch (t) {
|
||||
case Tier::TBD:
|
||||
if (elemCodeRangeIndices1_.length() > 0)
|
||||
return elemCodeRangeIndices1_;
|
||||
return elemCodeRangeIndices2_;
|
||||
case Tier::Baseline:
|
||||
return elemCodeRangeIndices1_;
|
||||
case Tier::Ion:
|
||||
return elemCodeRangeIndices2_;
|
||||
default:
|
||||
MOZ_CRASH("No such tier");
|
||||
}
|
||||
}
|
||||
|
||||
void setTier2(Uint32Vector&& elemCodeRangeIndices) const {
|
||||
MOZ_ASSERT(elemCodeRangeIndices2_.length() == 0);
|
||||
elemCodeRangeIndices2_ = Move(elemCodeRangeIndices);
|
||||
}
|
||||
|
||||
WASM_DECLARE_SERIALIZABLE(ElemSegment)
|
||||
};
|
||||
|
||||
// The ElemSegmentVector is laid out in a deterministic order.
|
||||
|
||||
typedef Vector<ElemSegment, 0, SystemAllocPolicy> ElemSegmentVector;
|
||||
|
||||
// DataSegment describes the offset of a data segment in the bytecode that is
|
||||
|
@ -1178,53 +1266,6 @@ enum ModuleKind
|
|||
AsmJS
|
||||
};
|
||||
|
||||
// Code can be compiled either with the Baseline compiler or the Ion compiler,
|
||||
// and tier-variant data are tagged with the Tier value.
|
||||
//
|
||||
// A tier value is used to request tier-variant aspects of code, metadata, or
|
||||
// linkdata. The tiers are normally explicit (Baseline and Ion); implicit tiers
|
||||
// can be obtained through accessors on Code objects (eg, stableTier).
|
||||
|
||||
enum class Tier
|
||||
{
|
||||
Baseline,
|
||||
Debug = Baseline,
|
||||
Ion,
|
||||
Serialized = Ion,
|
||||
|
||||
TBD // A placeholder while tiering is being implemented
|
||||
};
|
||||
|
||||
// Iterator over tiers present in a tiered data structure.
|
||||
|
||||
class Tiers
|
||||
{
|
||||
Tier t_[2];
|
||||
uint32_t n_;
|
||||
|
||||
public:
|
||||
explicit Tiers() {
|
||||
n_ = 0;
|
||||
}
|
||||
explicit Tiers(Tier t) {
|
||||
t_[0] = t;
|
||||
n_ = 1;
|
||||
}
|
||||
explicit Tiers(Tier t, Tier u) {
|
||||
MOZ_ASSERT(t != u);
|
||||
t_[0] = t;
|
||||
t_[1] = u;
|
||||
n_ = 2;
|
||||
}
|
||||
|
||||
Tier* begin() {
|
||||
return t_;
|
||||
}
|
||||
Tier* end() {
|
||||
return t_ + n_;
|
||||
}
|
||||
};
|
||||
|
||||
// Represents the resizable limits of memories and tables.
|
||||
|
||||
struct Limits
|
||||
|
|
Загрузка…
Ссылка в новой задаче