[regexp] Remove unused DispatchTable and ZoneSplayTree
Bug: v8:9359 Change-Id: I237f16324ff036f2cbfb7ca97b4ac208442b06cc Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1664056 Auto-Submit: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Peter Marshall <petermarshall@chromium.org> Cr-Commit-Position: refs/heads/master@{#62268}
This commit is contained in:
parent
b3ce13f424
commit
3663e83424
1
BUILD.gn
1
BUILD.gn
@ -2929,7 +2929,6 @@ v8_source_set("v8_base_without_compiler") {
|
||||
"src/zone/zone-list-inl.h",
|
||||
"src/zone/zone-segment.cc",
|
||||
"src/zone/zone-segment.h",
|
||||
"src/zone/zone-splay-tree.h",
|
||||
"src/zone/zone.cc",
|
||||
"src/zone/zone.h",
|
||||
]
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "src/regexp/regexp-macro-assembler-tracer.h"
|
||||
#include "src/strings/unicode-inl.h"
|
||||
#include "src/utils/ostreams.h"
|
||||
#include "src/utils/splay-tree-inl.h"
|
||||
#include "src/zone/zone-list-inl.h"
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
@ -3319,106 +3318,6 @@ bool OutSet::Get(unsigned value) const {
|
||||
}
|
||||
}
|
||||
|
||||
const uc32 DispatchTable::Config::kNoKey = unibrow::Utf8::kBadChar;
|
||||
|
||||
void DispatchTable::AddRange(CharacterRange full_range, int value, Zone* zone) {
|
||||
CharacterRange current = full_range;
|
||||
if (tree()->is_empty()) {
|
||||
// If this is the first range we just insert into the table.
|
||||
ZoneSplayTree<Config>::Locator loc;
|
||||
bool inserted = tree()->Insert(current.from(), &loc);
|
||||
DCHECK(inserted);
|
||||
USE(inserted);
|
||||
loc.set_value(
|
||||
Entry(current.from(), current.to(), empty()->Extend(value, zone)));
|
||||
return;
|
||||
}
|
||||
// First see if there is a range to the left of this one that
|
||||
// overlaps.
|
||||
ZoneSplayTree<Config>::Locator loc;
|
||||
if (tree()->FindGreatestLessThan(current.from(), &loc)) {
|
||||
Entry* entry = &loc.value();
|
||||
// If we've found a range that overlaps with this one, and it
|
||||
// starts strictly to the left of this one, we have to fix it
|
||||
// because the following code only handles ranges that start on
|
||||
// or after the start point of the range we're adding.
|
||||
if (entry->from() < current.from() && entry->to() >= current.from()) {
|
||||
// Snap the overlapping range in half around the start point of
|
||||
// the range we're adding.
|
||||
CharacterRange left =
|
||||
CharacterRange::Range(entry->from(), current.from() - 1);
|
||||
CharacterRange right = CharacterRange::Range(current.from(), entry->to());
|
||||
// The left part of the overlapping range doesn't overlap.
|
||||
// Truncate the whole entry to be just the left part.
|
||||
entry->set_to(left.to());
|
||||
// The right part is the one that overlaps. We add this part
|
||||
// to the map and let the next step deal with merging it with
|
||||
// the range we're adding.
|
||||
ZoneSplayTree<Config>::Locator loc;
|
||||
bool inserted = tree()->Insert(right.from(), &loc);
|
||||
DCHECK(inserted);
|
||||
USE(inserted);
|
||||
loc.set_value(Entry(right.from(), right.to(), entry->out_set()));
|
||||
}
|
||||
}
|
||||
while (current.is_valid()) {
|
||||
if (tree()->FindLeastGreaterThan(current.from(), &loc) &&
|
||||
(loc.value().from() <= current.to()) &&
|
||||
(loc.value().to() >= current.from())) {
|
||||
Entry* entry = &loc.value();
|
||||
// We have overlap. If there is space between the start point of
|
||||
// the range we're adding and where the overlapping range starts
|
||||
// then we have to add a range covering just that space.
|
||||
if (current.from() < entry->from()) {
|
||||
ZoneSplayTree<Config>::Locator ins;
|
||||
bool inserted = tree()->Insert(current.from(), &ins);
|
||||
DCHECK(inserted);
|
||||
USE(inserted);
|
||||
ins.set_value(Entry(current.from(), entry->from() - 1,
|
||||
empty()->Extend(value, zone)));
|
||||
current.set_from(entry->from());
|
||||
}
|
||||
DCHECK_EQ(current.from(), entry->from());
|
||||
// If the overlapping range extends beyond the one we want to add
|
||||
// we have to snap the right part off and add it separately.
|
||||
if (entry->to() > current.to()) {
|
||||
ZoneSplayTree<Config>::Locator ins;
|
||||
bool inserted = tree()->Insert(current.to() + 1, &ins);
|
||||
DCHECK(inserted);
|
||||
USE(inserted);
|
||||
ins.set_value(Entry(current.to() + 1, entry->to(), entry->out_set()));
|
||||
entry->set_to(current.to());
|
||||
}
|
||||
DCHECK(entry->to() <= current.to());
|
||||
// The overlapping range is now completely contained by the range
|
||||
// we're adding so we can just update it and move the start point
|
||||
// of the range we're adding just past it.
|
||||
entry->AddValue(value, zone);
|
||||
DCHECK(entry->to() + 1 > current.from());
|
||||
current.set_from(entry->to() + 1);
|
||||
} else {
|
||||
// There is no overlap so we can just add the range
|
||||
ZoneSplayTree<Config>::Locator ins;
|
||||
bool inserted = tree()->Insert(current.from(), &ins);
|
||||
DCHECK(inserted);
|
||||
USE(inserted);
|
||||
ins.set_value(
|
||||
Entry(current.from(), current.to(), empty()->Extend(value, zone)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OutSet* DispatchTable::Get(uc32 value) {
|
||||
ZoneSplayTree<Config>::Locator loc;
|
||||
if (!tree()->FindGreatestLessThan(value, &loc)) return empty();
|
||||
Entry* entry = &loc.value();
|
||||
if (value <= entry->to())
|
||||
return entry->out_set();
|
||||
else
|
||||
return empty();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Analysis
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include "src/base/small-vector.h"
|
||||
#include "src/regexp/regexp-nodes.h"
|
||||
#include "src/zone/zone-splay-tree.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -104,67 +103,6 @@ class OutSet : public ZoneObject {
|
||||
friend class Trace;
|
||||
};
|
||||
|
||||
// A mapping from integers, specified as ranges, to a set of integers.
|
||||
// Used for mapping character ranges to choices.
|
||||
class DispatchTable : public ZoneObject {
|
||||
public:
|
||||
explicit DispatchTable(Zone* zone) : tree_(zone) {}
|
||||
|
||||
class Entry {
|
||||
public:
|
||||
Entry() : from_(0), to_(0), out_set_(nullptr) {}
|
||||
Entry(uc32 from, uc32 to, OutSet* out_set)
|
||||
: from_(from), to_(to), out_set_(out_set) {
|
||||
DCHECK(from <= to);
|
||||
}
|
||||
uc32 from() { return from_; }
|
||||
uc32 to() { return to_; }
|
||||
void set_to(uc32 value) { to_ = value; }
|
||||
void AddValue(int value, Zone* zone) {
|
||||
out_set_ = out_set_->Extend(value, zone);
|
||||
}
|
||||
OutSet* out_set() { return out_set_; }
|
||||
|
||||
private:
|
||||
uc32 from_;
|
||||
uc32 to_;
|
||||
OutSet* out_set_;
|
||||
};
|
||||
|
||||
class Config {
|
||||
public:
|
||||
using Key = uc32;
|
||||
using Value = Entry;
|
||||
static const uc32 kNoKey;
|
||||
static const Entry NoValue() { return Value(); }
|
||||
static inline int Compare(uc32 a, uc32 b) {
|
||||
if (a == b)
|
||||
return 0;
|
||||
else if (a < b)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
V8_EXPORT_PRIVATE void AddRange(CharacterRange range, int value, Zone* zone);
|
||||
V8_EXPORT_PRIVATE OutSet* Get(uc32 value);
|
||||
void Dump();
|
||||
|
||||
template <typename Callback>
|
||||
void ForEach(Callback* callback) {
|
||||
return tree()->ForEach(callback);
|
||||
}
|
||||
|
||||
private:
|
||||
// There can't be a static empty set since it allocates its
|
||||
// successors in a zone and caches them.
|
||||
OutSet* empty() { return &empty_; }
|
||||
OutSet empty_;
|
||||
ZoneSplayTree<Config>* tree() { return &tree_; }
|
||||
ZoneSplayTree<Config> tree_;
|
||||
};
|
||||
|
||||
// Details of a quick mask-compare check that can look ahead in the
|
||||
// input stream.
|
||||
class QuickCheckDetails {
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#include "src/regexp/regexp-compiler.h"
|
||||
#include "src/utils/ostreams.h"
|
||||
#include "src/utils/splay-tree-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -61,54 +60,6 @@ void DotPrinterImpl::PrintOnFailure(RegExpNode* from, RegExpNode* on_failure) {
|
||||
Visit(on_failure);
|
||||
}
|
||||
|
||||
class TableEntryBodyPrinter {
|
||||
public:
|
||||
TableEntryBodyPrinter(std::ostream& os, ChoiceNode* choice) // NOLINT
|
||||
: os_(os), choice_(choice) {}
|
||||
void Call(uc16 from, DispatchTable::Entry entry) {
|
||||
OutSet* out_set = entry.out_set();
|
||||
for (unsigned i = 0; i < OutSet::kFirstLimit; i++) {
|
||||
if (out_set->Get(i)) {
|
||||
os_ << " n" << choice() << ":s" << from << "o" << i << " -> n"
|
||||
<< choice()->alternatives()->at(i).node() << ";\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ChoiceNode* choice() { return choice_; }
|
||||
std::ostream& os_;
|
||||
ChoiceNode* choice_;
|
||||
};
|
||||
|
||||
class TableEntryHeaderPrinter {
|
||||
public:
|
||||
explicit TableEntryHeaderPrinter(std::ostream& os) // NOLINT
|
||||
: first_(true), os_(os) {}
|
||||
void Call(uc16 from, DispatchTable::Entry entry) {
|
||||
if (first_) {
|
||||
first_ = false;
|
||||
} else {
|
||||
os_ << "|";
|
||||
}
|
||||
os_ << "{\\" << AsUC16(from) << "-\\" << AsUC16(entry.to()) << "|{";
|
||||
OutSet* out_set = entry.out_set();
|
||||
int priority = 0;
|
||||
for (unsigned i = 0; i < OutSet::kFirstLimit; i++) {
|
||||
if (out_set->Get(i)) {
|
||||
if (priority > 0) os_ << "|";
|
||||
os_ << "<s" << from << "o" << i << "> " << priority;
|
||||
priority++;
|
||||
}
|
||||
}
|
||||
os_ << "}}";
|
||||
}
|
||||
|
||||
private:
|
||||
bool first_;
|
||||
std::ostream& os_;
|
||||
};
|
||||
|
||||
class AttributePrinter {
|
||||
public:
|
||||
explicit AttributePrinter(std::ostream& os) // NOLINT
|
||||
@ -279,38 +230,6 @@ void DotPrinterImpl::VisitAction(ActionNode* that) {
|
||||
Visit(successor);
|
||||
}
|
||||
|
||||
class DispatchTableDumper {
|
||||
public:
|
||||
explicit DispatchTableDumper(std::ostream& os) : os_(os) {}
|
||||
void Call(uc16 key, DispatchTable::Entry entry);
|
||||
|
||||
private:
|
||||
std::ostream& os_;
|
||||
};
|
||||
|
||||
void DispatchTableDumper::Call(uc16 key, DispatchTable::Entry entry) {
|
||||
os_ << "[" << AsUC16(key) << "-" << AsUC16(entry.to()) << "]: {";
|
||||
OutSet* set = entry.out_set();
|
||||
bool first = true;
|
||||
for (unsigned i = 0; i < OutSet::kFirstLimit; i++) {
|
||||
if (set->Get(i)) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
os_ << ", ";
|
||||
}
|
||||
os_ << i;
|
||||
}
|
||||
}
|
||||
os_ << "}\n";
|
||||
}
|
||||
|
||||
void DispatchTable::Dump() {
|
||||
OFStream os(stderr);
|
||||
DispatchTableDumper dumper(os);
|
||||
tree()->ForEach(&dumper);
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
void DotPrinter::DotPrint(const char* label, RegExpNode* node) {
|
||||
|
@ -13,7 +13,6 @@ namespace internal {
|
||||
|
||||
class AlternativeGenerationList;
|
||||
class BoyerMooreLookahead;
|
||||
class DispatchTable;
|
||||
class GreedyLoopState;
|
||||
class Label;
|
||||
class NodeVisitor;
|
||||
|
@ -1,38 +0,0 @@
|
||||
// Copyright 2019 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_ZONE_ZONE_SPLAY_TREE_H_
|
||||
#define V8_ZONE_ZONE_SPLAY_TREE_H_
|
||||
|
||||
#include "src/utils/splay-tree.h"
|
||||
#include "src/zone/zone.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// A zone splay tree. The config type parameter encapsulates the
|
||||
// different configurations of a concrete splay tree (see splay-tree.h).
|
||||
// The tree itself and all its elements are allocated in the Zone.
|
||||
template <typename Config>
|
||||
class ZoneSplayTree final : public SplayTree<Config, ZoneAllocationPolicy> {
|
||||
public:
|
||||
explicit ZoneSplayTree(Zone* zone)
|
||||
: SplayTree<Config, ZoneAllocationPolicy>(ZoneAllocationPolicy(zone)) {}
|
||||
~ZoneSplayTree() {
|
||||
// Reset the root to avoid unneeded iteration over all tree nodes
|
||||
// in the destructor. For a zone-allocated tree, nodes will be
|
||||
// freed by the Zone.
|
||||
SplayTree<Config, ZoneAllocationPolicy>::ResetRoot();
|
||||
}
|
||||
|
||||
void* operator new(size_t size, Zone* zone) { return zone->New(size); }
|
||||
|
||||
void operator delete(void* pointer) { UNREACHABLE(); }
|
||||
void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_ZONE_ZONE_SPLAY_TREE_H_
|
@ -46,7 +46,6 @@
|
||||
#include "src/strings/string-stream.h"
|
||||
#include "src/strings/unicode-inl.h"
|
||||
#include "src/utils/ostreams.h"
|
||||
#include "src/utils/splay-tree-inl.h"
|
||||
#include "src/zone/zone-list-inl.h"
|
||||
#include "test/cctest/cctest.h"
|
||||
|
||||
@ -564,122 +563,6 @@ static void Execute(const char* input, bool multiline, bool unicode,
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
|
||||
class TestConfig {
|
||||
public:
|
||||
using Key = int;
|
||||
using Value = int;
|
||||
static const int kNoKey;
|
||||
static int NoValue() { return 0; }
|
||||
static inline int Compare(int a, int b) {
|
||||
if (a < b)
|
||||
return -1;
|
||||
else if (a > b)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const int TestConfig::kNoKey = 0;
|
||||
|
||||
|
||||
static unsigned PseudoRandom(int i, int j) {
|
||||
return ~(~((i * 781) ^ (j * 329)));
|
||||
}
|
||||
|
||||
|
||||
TEST(SplayTreeSimple) {
|
||||
static const unsigned kLimit = 1000;
|
||||
Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
|
||||
ZoneSplayTree<TestConfig> tree(&zone);
|
||||
bool seen[kLimit];
|
||||
for (unsigned i = 0; i < kLimit; i++) seen[i] = false;
|
||||
#define CHECK_MAPS_EQUAL() do { \
|
||||
for (unsigned k = 0; k < kLimit; k++) \
|
||||
CHECK_EQ(seen[k], tree.Find(k, &loc)); \
|
||||
} while (false)
|
||||
for (int i = 0; i < 50; i++) {
|
||||
for (int j = 0; j < 50; j++) {
|
||||
int next = PseudoRandom(i, j) % kLimit;
|
||||
if (seen[next]) {
|
||||
// We've already seen this one. Check the value and remove
|
||||
// it.
|
||||
ZoneSplayTree<TestConfig>::Locator loc;
|
||||
CHECK(tree.Find(next, &loc));
|
||||
CHECK_EQ(next, loc.key());
|
||||
CHECK_EQ(3 * next, loc.value());
|
||||
tree.Remove(next);
|
||||
seen[next] = false;
|
||||
CHECK_MAPS_EQUAL();
|
||||
} else {
|
||||
// Check that it wasn't there already and then add it.
|
||||
ZoneSplayTree<TestConfig>::Locator loc;
|
||||
CHECK(!tree.Find(next, &loc));
|
||||
CHECK(tree.Insert(next, &loc));
|
||||
CHECK_EQ(next, loc.key());
|
||||
loc.set_value(3 * next);
|
||||
seen[next] = true;
|
||||
CHECK_MAPS_EQUAL();
|
||||
}
|
||||
int val = PseudoRandom(j, i) % kLimit;
|
||||
if (seen[val]) {
|
||||
ZoneSplayTree<TestConfig>::Locator loc;
|
||||
CHECK(tree.FindGreatestLessThan(val, &loc));
|
||||
CHECK_EQ(loc.key(), val);
|
||||
break;
|
||||
}
|
||||
val = PseudoRandom(i + j, i - j) % kLimit;
|
||||
if (seen[val]) {
|
||||
ZoneSplayTree<TestConfig>::Locator loc;
|
||||
CHECK(tree.FindLeastGreaterThan(val, &loc));
|
||||
CHECK_EQ(loc.key(), val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(DispatchTableConstruction) {
|
||||
// Initialize test data.
|
||||
static const int kLimit = 1000;
|
||||
static const int kRangeCount = 8;
|
||||
static const int kRangeSize = 16;
|
||||
uc16 ranges[kRangeCount][2 * kRangeSize];
|
||||
for (int i = 0; i < kRangeCount; i++) {
|
||||
Vector<uc16> range(ranges[i], 2 * kRangeSize);
|
||||
for (int j = 0; j < 2 * kRangeSize; j++) {
|
||||
range[j] = PseudoRandom(i + 25, j + 87) % kLimit;
|
||||
}
|
||||
std::sort(range.begin(), range.end());
|
||||
for (int j = 1; j < 2 * kRangeSize; j++) {
|
||||
CHECK(range[j-1] <= range[j]);
|
||||
}
|
||||
}
|
||||
// Enter test data into dispatch table.
|
||||
Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
|
||||
DispatchTable table(&zone);
|
||||
for (int i = 0; i < kRangeCount; i++) {
|
||||
uc16* range = ranges[i];
|
||||
for (int j = 0; j < 2 * kRangeSize; j += 2)
|
||||
table.AddRange(CharacterRange::Range(range[j], range[j + 1]), i, &zone);
|
||||
}
|
||||
// Check that the table looks as we would expect
|
||||
for (int p = 0; p < kLimit; p++) {
|
||||
OutSet* outs = table.Get(p);
|
||||
for (int j = 0; j < kRangeCount; j++) {
|
||||
uc16* range = ranges[j];
|
||||
bool is_on = false;
|
||||
for (int k = 0; !is_on && (k < 2 * kRangeSize); k += 2)
|
||||
is_on = (range[k] <= p && p <= range[k + 1]);
|
||||
CHECK_EQ(is_on, outs->Get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Test of debug-only syntax.
|
||||
#ifdef DEBUG
|
||||
|
||||
@ -1900,6 +1783,10 @@ TEST(UncachedExternalString) {
|
||||
ExpectString("external.substring(1).match(re)[1]", "z");
|
||||
}
|
||||
|
||||
#undef CHECK_PARSE_ERROR
|
||||
#undef CHECK_SIMPLE
|
||||
#undef CHECK_MIN_MAX
|
||||
|
||||
} // namespace test_regexp
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
Loading…
Reference in New Issue
Block a user