Bug 1277562 - Part 3: Tiering for elemSegments, because they contain CodeRange indices. r=luke

--HG--
extra : rebase_source : cfaa202e98bc120fd33f97635e4cd097aab1e3a2
This commit is contained in:
Lars T Hansen 2017-06-16 15:31:16 +02:00
Родитель 39c2ce83e4
Коммит 6f41d4e35c
4 изменённых файлов: 100 добавлений и 58 удалений

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

@ -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