Backed out 2 changesets (bug 1587738, bug 1588051) for build bustage on js/src/jsapi-tests/testBinASTReader.cpp. CLOSED TREE

Backed out changeset 0c6326559079 (bug 1588051)
Backed out changeset ded00ff91429 (bug 1587738)
This commit is contained in:
Dorel Luca 2019-10-15 16:41:59 +03:00
Родитель 92caaefe3b
Коммит c7518beb08
6 изменённых файлов: 75 добавлений и 13571 удалений

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

@ -1794,8 +1794,7 @@ JS::Result<Ok> GenericHuffmanTable::initStart(JSContext* cx,
// `largestBitLength`.
// ...hopefully, only one lookup.
if (largestBitLength <= SingleLookupHuffmanTable::MAX_BIT_LENGTH) {
implementation_ = {mozilla::VariantType<SingleLookupHuffmanTable>{}, cx,
SingleLookupHuffmanTable::Use::ToplevelTable};
implementation_ = {mozilla::VariantType<SingleLookupHuffmanTable>{}, cx};
return implementation_.template as<SingleLookupHuffmanTable>().initStart(
cx, numberOfSymbols, largestBitLength);
}
@ -2010,17 +2009,10 @@ JS::Result<Ok> SingleLookupHuffmanTable::initComplete() {
MOZ_ASSERT(largestBitLength_ == 0);
return Ok();
}
#ifdef DEBUG
bool foundMaxBitLength = false;
for (size_t i = 0; i < saturated_.length(); ++i) {
const uint8_t index = saturated_[i];
if (use_ != Use::ToplevelTable) {
// The table may not be full.
if (index >= values_.length()) {
continue;
}
}
MOZ_ASSERT(values_[index].key().bitLength_ <= largestBitLength_);
if (values_[index].key().bitLength_ == largestBitLength_) {
foundMaxBitLength = true;
@ -2028,7 +2020,6 @@ JS::Result<Ok> SingleLookupHuffmanTable::initComplete() {
}
MOZ_ASSERT(foundMaxBitLength);
#endif // DEBUG
return Ok();
}
@ -2080,12 +2071,6 @@ HuffmanLookupResult SingleLookupHuffmanTable::lookup(HuffmanLookup key) const {
// Invariants: `saturated_.length() == 1 << largestBitLength_`
// and `bits <= 1 << largestBitLength_`.
const size_t index = saturated_[bits];
if (index >= values_.length()) {
// This is useful only when the `SingleLookupHuffmanTable`
// is used as a cache inside a `MultiLookupHuffmanTable`.
MOZ_ASSERT(use_ == Use::ShortKeys);
return HuffmanLookupResult::notFound();
}
// Invariants: `saturated_[i] < values_.length()`.
const auto& entry = values_[index];
@ -2133,12 +2118,12 @@ JS::Result<Ok> MultiLookupHuffmanTable<Subtable, PrefixBitLength>::initStart(
static_assert(PrefixBitLength < MAX_CODE_BIT_LENGTH,
"Invalid PrefixBitLength");
MOZ_ASSERT(values_.empty()); // Make sure that we're initializing.
MOZ_ASSERT(suffixTables_.empty());
MOZ_ASSERT(subTables_.empty());
largestBitLength_ = largestBitLength;
if (MOZ_UNLIKELY(!values_.initCapacity(numberOfSymbols))) {
return cx->alreadyReportedError();
}
if (MOZ_UNLIKELY(!suffixTables_.initCapacity(1 << PrefixBitLength))) {
if (MOZ_UNLIKELY(!subTables_.initCapacity(1 << PrefixBitLength))) {
return cx->alreadyReportedError();
}
return Ok();
@ -2166,24 +2151,11 @@ MultiLookupHuffmanTable<Subtable, PrefixBitLength>::initComplete() {
Bucket() : largestBitLength_(0), numberOfSymbols_(0){};
uint8_t largestBitLength_;
uint32_t numberOfSymbols_;
void addSymbol(uint8_t bitLength) {
++numberOfSymbols_;
if (bitLength > largestBitLength_) {
largestBitLength_ = bitLength;
}
}
};
Vector<Bucket> buckets{cx_};
BINJS_TRY(buckets.resize(1 << PrefixBitLength));
Bucket shortKeysBucket;
for (const auto& entry : values_) {
if (entry.key().bitLength_ <= SingleLookupHuffmanTable::MAX_BIT_LENGTH) {
// If the key is short, we put it in `shortKeys_` instead of
// `suffixTables`.
shortKeysBucket.addSymbol(entry.key().bitLength_);
continue;
}
const HuffmanLookup lookup(entry.key().bits_, entry.key().bitLength_);
const auto split = lookup.split(PrefixBitLength);
MOZ_ASSERT_IF(split.suffix_.bitLength_ != 32,
@ -2195,46 +2167,34 @@ MultiLookupHuffmanTable<Subtable, PrefixBitLength>::initComplete() {
// (e.g. G, H in the documentation).
for (const auto index : lookup.suffixes(PrefixBitLength)) {
Bucket& bucket = buckets[index];
bucket.addSymbol(split.suffix_.bitLength_);
if (split.suffix_.bitLength_ >= bucket.largestBitLength_) {
bucket.largestBitLength_ = split.suffix_.bitLength_;
}
bucket.numberOfSymbols_++;
}
}
// We may now create the subtables.
for (auto& bucket : buckets) {
Subtable sub(cx_);
if (bucket.numberOfSymbols_ != 0) {
// Often, a subtable will end up empty because all the prefixes end up
// in `shortKeys_`. In such a case, we want to avoid initializing the
// table.
MOZ_TRY(sub.initStart(cx_,
/* numberOfSymbols = */ bucket.numberOfSymbols_,
/* maxBitLength = */ bucket.largestBitLength_));
}
BINJS_TRY(suffixTables_.append(std::move(sub)));
MOZ_TRY(sub.initStart(cx_,
/* numberOfSymbols = */ bucket.numberOfSymbols_,
/* largestBitLength = */ bucket.largestBitLength_));
BINJS_TRY(subTables_.append(std::move(sub)));
}
// Also, create the shortKeys_ fast lookup.
MOZ_TRY(shortKeys_.initStart(cx_, shortKeysBucket.numberOfSymbols_,
shortKeysBucket.largestBitLength_));
// Now that all the subtables are created, let's dispatch the values
// Now that the subtables are created, let's dispatch the values
// among these tables.
for (size_t i = 0; i < values_.length(); ++i) {
const auto& entry = values_[i];
if (entry.key().bitLength_ <= SingleLookupHuffmanTable::MAX_BIT_LENGTH) {
// The key fits in `shortKeys_`, let's use this table.
MOZ_TRY(shortKeys_.addSymbol(entry.key().bits_, entry.key().bitLength_,
BinASTSymbol::fromSubtableIndex(i)));
continue;
}
// Otherwise, use one of the suffix tables.
// Find the relevant subtables.
const HuffmanLookup lookup(entry.key().bits_, entry.key().bitLength_);
const auto split = lookup.split(PrefixBitLength);
MOZ_ASSERT_IF(split.suffix_.bitLength_ != 32,
split.suffix_.bits_ >> split.suffix_.bitLength_ == 0);
for (const auto index : lookup.suffixes(PrefixBitLength)) {
auto& sub = suffixTables_[index];
auto& sub = subTables_[index];
// We may now add a reference to `entry` into the sybtable.
MOZ_TRY(sub.addSymbol(split.suffix_.bits_, split.suffix_.bitLength_,
@ -2242,14 +2202,8 @@ MultiLookupHuffmanTable<Subtable, PrefixBitLength>::initComplete() {
}
}
// Finally, complete initialization of shortKeys_ and subtables.
MOZ_TRY(shortKeys_.initComplete());
for (size_t i = 0; i < buckets.length(); ++i) {
if (buckets[i].numberOfSymbols_ == 0) {
// Again, we don't want to initialize empty subtables.
continue;
}
auto& sub = suffixTables_[i];
// Finally, complete initialization of subtables.
for (auto& sub : subTables_) {
MOZ_TRY(sub.initComplete());
}
@ -2259,22 +2213,11 @@ MultiLookupHuffmanTable<Subtable, PrefixBitLength>::initComplete() {
template <typename Subtable, uint8_t PrefixBitLength>
HuffmanLookupResult MultiLookupHuffmanTable<Subtable, PrefixBitLength>::lookup(
HuffmanLookup key) const {
{
// Let's first look in shortkeys.
auto subResult = shortKeys_.lookup(key);
if (subResult.isFound()) {
// We have found a result in the shortKeys_ fastpath.
const auto& result = values_[subResult.value().toSubtableIndex()];
return HuffmanLookupResult::found(result.key().bitLength_,
&result.value());
}
}
const auto split = key.split(PrefixBitLength);
if (split.prefix_.bits_ >= suffixTables_.length()) {
if (split.prefix_.bits_ >= subTables_.length()) {
return HuffmanLookupResult::notFound();
}
const Subtable& subtable = suffixTables_[split.prefix_.bits_];
const Subtable& subtable = subTables_[split.prefix_.bits_];
auto subResult = subtable.lookup(split.suffix_);
if (!subResult.isFound()) {

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

@ -433,31 +433,11 @@ class SingleLookupHuffmanTable {
// used by the table.
using InternalIndex = uint8_t;
// An enum used to represent how this table is used.
// Used to perform additional DEBUG assertions.
enum Use {
// Used as a `Subtable` argument of a `MultiLookupHuffmanTable`.
LeafOfMultiLookupHuffmanTable,
// Used as its own table.
ToplevelTable,
// Used as a `shortKeys_` in a `MultiLookupHuffmanTable`.
ShortKeys,
};
// The largest bit length that may be represented by this table.
static const uint8_t MAX_BIT_LENGTH = sizeof(InternalIndex) * 8;
explicit SingleLookupHuffmanTable(
JSContext* cx, Use use = Use::LeafOfMultiLookupHuffmanTable)
: values_(cx),
saturated_(cx),
largestBitLength_(-1)
#ifdef DEBUG
,
use_(use)
#endif // DEBUG
{
}
explicit SingleLookupHuffmanTable(JSContext* cx)
: values_(cx), saturated_(cx), largestBitLength_(-1) {}
SingleLookupHuffmanTable(SingleLookupHuffmanTable&& other) = default;
// Initialize a Huffman table containing `numberOfSymbols`.
@ -528,10 +508,6 @@ class SingleLookupHuffmanTable {
// - `largestBitLength_ <= MAX_CODE_BIT_LENGTH`
uint8_t largestBitLength_;
#ifdef DEBUG
Use use_;
#endif // DEBUG
friend class HuffmanPreludeReader;
};
@ -545,13 +521,10 @@ class SingleLookupHuffmanTable {
/// # Time complexity
///
/// A lookup in `MultiLookupHuffmanTable` will also take constant time:
/// - a constant-time lookup in a `SingleLookupHuffmanTable`, in case we only
/// need to look for a small key;
/// - if the above lookup fails:
/// - a constant-time lookup to determine into which suffix table to perform
/// the lookup;
/// - a constant-time lookup into the suffix table;
///
/// - a constant-time lookup to determine into which sub-table to perform the
/// lookup;
/// - a constant-time lookup into the sub-table;
/// - a constant-time lookup into the array of values.
///
///
@ -575,100 +548,87 @@ class SingleLookupHuffmanTable {
/// G | 00 | 2
/// H | 01 | 2
///
/// Let us assume that we have somehow determined that:
/// With a prefix length of 3, we will precompute all possible 3-bit prefixes
/// and split the table across such prefixes. Note that we have picked a
/// length of 3 bits arbitrarily – in this case it is larger than the
/// bit length of some symbols.
///
/// - we wish to store all values with a bit length of 2
/// or less in a fast access table.
/// - we wish to use a prefix length of 4.
///
/// Note: These numbers of 2 and 4 are picked arbitrarily
/// for the example. Actual numbers used may vary.
///
/// We first extract all values with a bit length of <= 2:
///
/// Symbol | Binary Code | Bit Length
/// ------ | ------------ | ----------
/// G | 00 | 2
/// H | 01 | 2
///
/// We store these values in a `SingleLookupHuffmanTable` for fast access.
/// We are now done with these values. Let's deal with the remaining values.
///
/// Now, as our prefix length is 4, we precompute all possible 3-bit
/// prefixes and split the table across such prefixes.
///
/// Prefix | Int Value of Prefix | Symbols | Max bit length
/// ------- | ------------------- | --------- | --------------
/// 0000 | 0 | | 0
/// 0001 | 1 | | 0
/// 0010 | 2 | | 0
/// 0011 | 3 | | 0
/// 0100 | 4 | | 0
/// 0101 | 5 | | 0
/// 0110 | 6 | | 0
/// 0111 | 7 | | 0
/// 1000 | 8 | D | 0
/// 1001 | 9 | D | 0
/// 1010 | 10 | E | 0
/// 1011 | 11 | E | 0
/// 1100 | 12 | A, B | 1
/// 1101 | 13 | C | 0
/// 1110 | 14 | F | 0
/// 1111 | 15 | F | 0
/// Prefix | Int Value of Prefix | Symbols | Max bit length
/// ------ | ------------------- | --------- | --------------
/// 000 | 0 | G | 0
/// 001 | 1 | G | 0
/// 010 | 2 | H | 0
/// 011 | 3 | H | 0
/// 100 | 4 | D | 0
/// 101 | 5 | E | 0
/// 110 | 6 | A, B, C | 2
/// 111 | 7 | F | 0
///
/// For each prefix, we build the table containing the Symbols,
/// stripping prefix from the Binary Code.
/// - Prefixes 0000-01111
///
/// Empty tables.
/// - Prefix 000
///
/// - Prefixes 1000, 1001
/// Symbol | Binary Code | Bit Length | Total Bit Length
/// ------ | ----------- | ---------- | ----------------
/// G | (none) | 0 | 2
///
/// - Prefix 001
///
/// Symbol | Binary Code | Bit Length | Total Bit Length
/// ------ | ----------- | ---------- | ----------------
/// G | (none) | 0 | 2
///
/// - Prefix 010
///
/// Symbol | Binary Code | Bit Length | Total Bit Length
/// ------ | ----------- | ---------- | --------------
/// H | (none) | 0 | 2
///
/// - Prefix 11
///
/// Symbol | Binary Code | Bit Length | Total Bit Length
/// ------ | ----------- | ---------- | ----------------
/// H | (none) | 0 | 2
///
/// - Prefix 100
///
/// Symbol | Binary Code | Bit Length | Total Bit Length
/// ------ | ----------- | ---------- | ----------------
/// D | (none) | 0 | 3
///
/// - Prefixes 1010, 1011
/// - Prefix 101
///
/// Symbol | Binary Code | Bit Length | Total Bit Length
/// ------ | ----------- | ---------- | --------------
/// ------ | ----------- | ---------- | ----------------
/// E | (none) | 0 | 3
///
/// - Prefix 1100
/// - Prefix 110
///
/// Symbol | Binary Code | Bit Length | Total Bit Length
/// ------ | ----------- | ---------- | ----------------
/// A | 0 | 1 | 5
/// B | 1 | 1 | 5
/// A | 00 | 2 | 5
/// B | 01 | 2 | 5
/// C | 1 | 1 | 4
///
/// - Prefix 1101
/// - Prefix 111
///
/// Symbol | Binary Code | Bit Length | Total Bit Length
/// ------ | ----------- | ---------- | ----------------
/// C | (none) | 0 | 4
///
/// - Prefixes 1110, 1111
///
/// Symbol | Binary Code | Bit Length | Total Bit Length
/// ------ | ----------- | ---------- | ----------------
/// F | (none) | 0 | 4
///
/// F | (none) | 0 | 3
///
/// With this transformation, we have represented one table
/// with an initial max bit length of 5 as:
///
/// - 1 SingleLookupValue table with a max bit length of 3;
/// - 8 empty tables;
/// - 7 tables with a max bit length of 0;
/// - 1 table with a max bit length of 1;
/// - 1 table with a max bit length of 2;
/// - 7 tables with a max bit length of 0.
///
/// Consequently, instead of storing 2^5 = 32 internal references,
/// as we would have done with a SingleLookupHuffmanTable, we only
/// need to store:
///
/// - 1 subtable with 2^3 = 8 references;
/// - 7 subtables with 1 reference each;
/// - 1 subtable with 2^1 = 2 references.
/// - 1 subtable with 2^2 = 4 references.
template <typename Subtable, uint8_t PrefixBitLength>
class MultiLookupHuffmanTable {
public:
@ -677,11 +637,7 @@ class MultiLookupHuffmanTable {
PrefixBitLength + Subtable::MAX_BIT_LENGTH;
explicit MultiLookupHuffmanTable(JSContext* cx)
: cx_(cx),
shortKeys_(cx, SingleLookupHuffmanTable::Use::ShortKeys),
values_(cx),
suffixTables_(cx),
largestBitLength_(-1) {}
: cx_(cx), values_(cx), subTables_(cx), largestBitLength_(-1) {}
MultiLookupHuffmanTable(MultiLookupHuffmanTable&& other) = default;
// Initialize a Huffman table containing `numberOfSymbols`.
@ -740,10 +696,6 @@ class MultiLookupHuffmanTable {
private:
JSContext* cx_;
// Fast lookup for values whose keys fit within 8 bits.
// Such values are not added to `suffixTables`.
SingleLookupHuffmanTable shortKeys_;
// The entries in this Huffman Table, sorted in the order of insertion.
//
// Invariant (once `init*` has been called):
@ -761,7 +713,7 @@ class MultiLookupHuffmanTable {
// Note that, to allow the use of smaller tables, keys
// inside the subtables have been stripped
// from the prefix `HuffmanKey(i, prefixBitLen)`.
Vector<Subtable> suffixTables_;
Vector<Subtable> subTables_;
// The maximal bitlength of a value in this table.
//

Двоичный файл не отображается.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Двоичный файл не отображается.

Разница между файлами не показана из-за своего большого размера Загрузить разницу