[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:
Jakob Gruber 2019-06-18 10:20:31 +02:00 committed by Commit Bot
parent b3ce13f424
commit 3663e83424
7 changed files with 4 additions and 401 deletions

View File

@ -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",
]

View File

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

View File

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

View File

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

View File

@ -13,7 +13,6 @@ namespace internal {
class AlternativeGenerationList;
class BoyerMooreLookahead;
class DispatchTable;
class GreedyLoopState;
class Label;
class NodeVisitor;

View File

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

View File

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