Commit f42b1a5d authored by Seth Brenith's avatar Seth Brenith Committed by Commit Bot

[regexp] Use stricter bounds check to avoid additional iteration

The motivating example is JetStream 2's UniPoker test, which tests
whether a sorted string of Unicode playing cards contains a five-card
straight using a regular expression. In the top-level generated loop for
this RegExp, we see this loop exit condition:

00000350000C2067    27  83fffe         cmpl rdi,0xfe
00000350000C206A    2a  0f8da8e40000   jge 00000350000D0518  <+0xe4d8>

Meaning if the current position is pointing at the very last (16-bit)
character, then we exit the loop. Otherwise we go on and try to find
various matches starting at the current position. However, we can see
in the original expression that any possible match is at least 10
characters (5 astral-plane Unicode values), so we're wasting a lot of
time attempting to find matches in cases where we're too close to the
end of the string for any match to succeed.

This example might be a bit contrived, but I expect that an improvement
in this bounds check would help a larger family of regular expressions,
where the minimum match length is large relative to the string being
matched and we don't meet the other necessary criteria for fast Boyer-
Moore lookahead.

To get the desired bounds check in this case, this patch does the
following:
1. Compute accurate EatsAtLeast values for every node during the
   analysis phase. This could end up doing more work than the current
   implementation, but analysis already has to touch every node, so it
   seems like a cache-friendly time to compute these values. In some
   cases, this might be less total work than the current implementation,
   because the current implementation might recompute the same node
   multiple times.
2. When emitting a quick check, use the EatsAtLeast value from the
   predecessor ChoiceNode for the bounds check.

This improves the UniPoker score on my machine by about 4%, because it
cuts the time spent checking for straights roughly in half, and checking
for straights originally accounted for about 8% of the total time.

Bug: v8:9305
Change-Id: I110b190c2578f73b2263259d5aa5750e921b01be
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1702125
Commit-Queue: Seth Brenith <seth.brenith@microsoft.com>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62919}
parent 801930f5
......@@ -929,15 +929,19 @@ RegExpMacroAssembler::IrregexpImplementation
return kARMImplementation;
}
void RegExpMacroAssemblerARM::LoadCurrentCharacterImpl(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters,
int eats_at_least) {
// It's possible to preload a small number of characters when each success
// path requires a large number of characters, but not the reverse.
DCHECK_GE(eats_at_least, characters);
void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters) {
DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
if (check_bounds) {
if (cp_offset >= 0) {
CheckPosition(cp_offset + characters - 1, on_end_of_input);
CheckPosition(cp_offset + eats_at_least - 1, on_end_of_input);
} else {
CheckPosition(cp_offset, on_end_of_input);
}
......@@ -945,7 +949,6 @@ void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset,
LoadCurrentCharacterUnchecked(cp_offset, characters);
}
void RegExpMacroAssemblerARM::PopCurrentPosition() {
Pop(current_input_offset());
}
......
......@@ -67,10 +67,9 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerARM
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
virtual void IfRegisterEqPos(int reg, Label* if_eq);
virtual IrregexpImplementation Implementation();
virtual void LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds = true,
int characters = 1);
virtual void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input,
bool check_bounds, int characters,
int eats_at_least);
virtual void PopCurrentPosition();
virtual void PopRegister(int register_index);
virtual void PushBacktrack(Label* label);
......
......@@ -1106,18 +1106,22 @@ RegExpMacroAssembler::IrregexpImplementation
return kARM64Implementation;
}
void RegExpMacroAssemblerARM64::LoadCurrentCharacterImpl(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters,
int eats_at_least) {
// It's possible to preload a small number of characters when each success
// path requires a large number of characters, but not the reverse.
DCHECK_GE(eats_at_least, characters);
void RegExpMacroAssemblerARM64::LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters) {
// TODO(pielan): Make sure long strings are caught before this, and not
// just asserted in debug mode.
// Be sane! (And ensure that an int32_t can be used to index the string)
DCHECK(cp_offset < (1<<30));
if (check_bounds) {
if (cp_offset >= 0) {
CheckPosition(cp_offset + characters - 1, on_end_of_input);
CheckPosition(cp_offset + eats_at_least - 1, on_end_of_input);
} else {
CheckPosition(cp_offset, on_end_of_input);
}
......@@ -1125,7 +1129,6 @@ void RegExpMacroAssemblerARM64::LoadCurrentCharacter(int cp_offset,
LoadCurrentCharacterUnchecked(cp_offset, characters);
}
void RegExpMacroAssemblerARM64::PopCurrentPosition() {
Pop(current_input_offset());
}
......
......@@ -72,10 +72,9 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerARM64
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
virtual void IfRegisterEqPos(int reg, Label* if_eq);
virtual IrregexpImplementation Implementation();
virtual void LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds = true,
int characters = 1);
virtual void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input,
bool check_bounds, int characters,
int eats_at_least);
virtual void PopCurrentPosition();
virtual void PopRegister(int register_index);
virtual void PushBacktrack(Label* label);
......
......@@ -971,15 +971,19 @@ RegExpMacroAssembler::IrregexpImplementation
return kIA32Implementation;
}
void RegExpMacroAssemblerIA32::LoadCurrentCharacterImpl(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters,
int eats_at_least) {
// It's possible to preload a small number of characters when each success
// path requires a large number of characters, but not the reverse.
DCHECK_GE(eats_at_least, characters);
void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters) {
DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
if (check_bounds) {
if (cp_offset >= 0) {
CheckPosition(cp_offset + characters - 1, on_end_of_input);
CheckPosition(cp_offset + eats_at_least - 1, on_end_of_input);
} else {
CheckPosition(cp_offset, on_end_of_input);
}
......@@ -987,7 +991,6 @@ void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset,
LoadCurrentCharacterUnchecked(cp_offset, characters);
}
void RegExpMacroAssemblerIA32::PopCurrentPosition() {
Pop(edi);
}
......
......@@ -66,10 +66,9 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerIA32
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
virtual void IfRegisterEqPos(int reg, Label* if_eq);
virtual IrregexpImplementation Implementation();
virtual void LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds = true,
int characters = 1);
virtual void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input,
bool check_bounds, int characters,
int eats_at_least);
virtual void PopCurrentPosition();
virtual void PopRegister(int register_index);
virtual void PushBacktrack(Label* label);
......
......@@ -946,15 +946,19 @@ RegExpMacroAssembler::IrregexpImplementation
return kMIPSImplementation;
}
void RegExpMacroAssemblerMIPS::LoadCurrentCharacterImpl(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters,
int eats_at_least) {
// It's possible to preload a small number of characters when each success
// path requires a large number of characters, but not the reverse.
DCHECK_GE(eats_at_least, characters);
void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters) {
DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works).
if (check_bounds) {
if (cp_offset >= 0) {
CheckPosition(cp_offset + characters - 1, on_end_of_input);
CheckPosition(cp_offset + eats_at_least - 1, on_end_of_input);
} else {
CheckPosition(cp_offset, on_end_of_input);
}
......@@ -962,7 +966,6 @@ void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset,
LoadCurrentCharacterUnchecked(cp_offset, characters);
}
void RegExpMacroAssemblerMIPS::PopCurrentPosition() {
Pop(current_input_offset());
}
......
......@@ -67,10 +67,9 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
virtual void IfRegisterEqPos(int reg, Label* if_eq);
virtual IrregexpImplementation Implementation();
virtual void LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds = true,
int characters = 1);
virtual void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input,
bool check_bounds, int characters,
int eats_at_least);
virtual void PopCurrentPosition();
virtual void PopRegister(int register_index);
virtual void PushBacktrack(Label* label);
......
......@@ -983,15 +983,19 @@ RegExpMacroAssembler::IrregexpImplementation
return kMIPSImplementation;
}
void RegExpMacroAssemblerMIPS::LoadCurrentCharacterImpl(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters,
int eats_at_least) {
// It's possible to preload a small number of characters when each success
// path requires a large number of characters, but not the reverse.
DCHECK_GE(eats_at_least, characters);
void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters) {
DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works).
if (check_bounds) {
if (cp_offset >= 0) {
CheckPosition(cp_offset + characters - 1, on_end_of_input);
CheckPosition(cp_offset + eats_at_least - 1, on_end_of_input);
} else {
CheckPosition(cp_offset, on_end_of_input);
}
......@@ -999,7 +1003,6 @@ void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset,
LoadCurrentCharacterUnchecked(cp_offset, characters);
}
void RegExpMacroAssemblerMIPS::PopCurrentPosition() {
Pop(current_input_offset());
}
......
......@@ -67,10 +67,9 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
virtual void IfRegisterEqPos(int reg, Label* if_eq);
virtual IrregexpImplementation Implementation();
virtual void LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds = true,
int characters = 1);
virtual void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input,
bool check_bounds, int characters,
int eats_at_least);
virtual void PopCurrentPosition();
virtual void PopRegister(int register_index);
virtual void PushBacktrack(Label* label);
......
......@@ -978,15 +978,19 @@ RegExpMacroAssemblerPPC::Implementation() {
return kPPCImplementation;
}
void RegExpMacroAssemblerPPC::LoadCurrentCharacterImpl(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters,
int eats_at_least) {
// It's possible to preload a small number of characters when each success
// path requires a large number of characters, but not the reverse.
DCHECK_GE(eats_at_least, characters);
void RegExpMacroAssemblerPPC::LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters) {
DCHECK(cp_offset < (1 << 30)); // Be sane! (And ensure negation works)
if (check_bounds) {
if (cp_offset >= 0) {
CheckPosition(cp_offset + characters - 1, on_end_of_input);
CheckPosition(cp_offset + eats_at_least - 1, on_end_of_input);
} else {
CheckPosition(cp_offset, on_end_of_input);
}
......@@ -994,7 +998,6 @@ void RegExpMacroAssemblerPPC::LoadCurrentCharacter(int cp_offset,
LoadCurrentCharacterUnchecked(cp_offset, characters);
}
void RegExpMacroAssemblerPPC::PopCurrentPosition() {
Pop(current_input_offset());
}
......
......@@ -59,9 +59,9 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerPPC
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
virtual void IfRegisterEqPos(int reg, Label* if_eq);
virtual IrregexpImplementation Implementation();
virtual void LoadCurrentCharacter(int cp_offset, Label* on_end_of_input,
bool check_bounds = true,
int characters = 1);
virtual void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input,
bool check_bounds, int characters,
int eats_at_least);
virtual void PopCurrentPosition();
virtual void PopRegister(int register_index);
virtual void PushBacktrack(Label* label);
......
......@@ -171,10 +171,13 @@ void RegExpBytecodeGenerator::CheckGreedyLoop(
EmitOrLink(on_tos_equals_current_position);
}
void RegExpBytecodeGenerator::LoadCurrentCharacter(int cp_offset,
Label* on_failure,
bool check_bounds,
int characters) {
void RegExpBytecodeGenerator::LoadCurrentCharacterImpl(int cp_offset,
Label* on_failure,
bool check_bounds,
int characters,
int eats_at_least) {
// TODO(v8:9305): Make use of eats_at_least value to perform a bigger bounds-
// check if it doesn't match the number of preloaded characters.
DCHECK_LE(kMinCPOffset, cp_offset);
DCHECK_GE(kMaxCPOffset, cp_offset);
int bytecode;
......
......@@ -46,9 +46,9 @@ class V8_EXPORT_PRIVATE RegExpBytecodeGenerator : public RegExpMacroAssembler {
virtual void ReadCurrentPositionFromRegister(int reg);
virtual void WriteStackPointerToRegister(int reg);
virtual void ReadStackPointerFromRegister(int reg);
virtual void LoadCurrentCharacter(int cp_offset, Label* on_end_of_input,
bool check_bounds = true,
int characters = 1);
virtual void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input,
bool check_bounds, int characters,
int eats_at_least);
virtual void CheckCharacter(unsigned c, Label* on_equal);
virtual void CheckCharacterAfterAnd(unsigned c, unsigned mask,
Label* on_equal);
......
This diff is collapsed.
......@@ -419,45 +419,13 @@ struct PreloadState {
void init() { eats_at_least_ = kEatsAtLeastNotYetInitialized; }
};
// Assertion propagation moves information about assertions such as
// \b to the affected nodes. For instance, in /.\b./ information must
// be propagated to the first '.' that whatever follows needs to know
// if it matched a word or a non-word, and to the second '.' that it
// has to check if it succeeds a word or non-word. In this case the
// result will be something like:
// Analysis performs assertion propagation and computes eats_at_least_ values.
// See the comments on AssertionPropagator and EatsAtLeastPropagator for more
// details.
//
// +-------+ +------------+
// | . | | . |
// +-------+ ---> +------------+
// | word? | | check word |
// +-------+ +------------+
class Analysis : public NodeVisitor {
public:
Analysis(Isolate* isolate, bool is_one_byte)
: isolate_(isolate), is_one_byte_(is_one_byte), error_message_(nullptr) {}
void EnsureAnalyzed(RegExpNode* node);
#define DECLARE_VISIT(Type) void Visit##Type(Type##Node* that) override;
FOR_EACH_NODE_TYPE(DECLARE_VISIT)
#undef DECLARE_VISIT
void VisitLoopChoice(LoopChoiceNode* that) override;
bool has_failed() { return error_message_ != nullptr; }
const char* error_message() {
DCHECK(error_message_ != nullptr);
return error_message_;
}
void fail(const char* error_message) { error_message_ = error_message; }
Isolate* isolate() const { return isolate_; }
private:
Isolate* isolate_;
bool is_one_byte_;
const char* error_message_;
DISALLOW_IMPLICIT_CONSTRUCTORS(Analysis);
};
// This method returns nullptr on success or a null-terminated failure message
// on failure.
const char* AnalyzeRegExp(Isolate* isolate, bool is_one_byte, RegExpNode* node);
class FrequencyCollator {
public:
......
......@@ -114,6 +114,15 @@ void DotPrinterImpl::VisitChoice(ChoiceNode* that) {
}
}
void DotPrinterImpl::VisitLoopChoice(LoopChoiceNode* that) {
VisitChoice(that);
}
void DotPrinterImpl::VisitNegativeLookaroundChoice(
NegativeLookaroundChoiceNode* that) {
VisitChoice(that);
}
void DotPrinterImpl::VisitText(TextNode* that) {
Zone* zone = that->zone();
os_ << " n" << that << " [label=\"";
......
......@@ -162,24 +162,19 @@ void RegExpMacroAssemblerTracer::ReadStackPointerFromRegister(int reg) {
assembler_->ReadStackPointerFromRegister(reg);
}
void RegExpMacroAssemblerTracer::LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters) {
void RegExpMacroAssemblerTracer::LoadCurrentCharacterImpl(
int cp_offset, Label* on_end_of_input, bool check_bounds, int characters,
int eats_at_least) {
const char* check_msg = check_bounds ? "" : " (unchecked)";
PrintF(" LoadCurrentCharacter(cp_offset=%d, label[%08x]%s (%d chars));\n",
cp_offset,
LabelToInt(on_end_of_input),
check_msg,
characters);
assembler_->LoadCurrentCharacter(cp_offset,
on_end_of_input,
check_bounds,
characters);
PrintF(
" LoadCurrentCharacter(cp_offset=%d, label[%08x]%s (%d chars) (eats at "
"least %d));\n",
cp_offset, LabelToInt(on_end_of_input), check_msg, characters,
eats_at_least);
assembler_->LoadCurrentCharacter(cp_offset, on_end_of_input, check_bounds,
characters, eats_at_least);
}
class PrintablePrinter {
public:
explicit PrintablePrinter(uc16 character) : character_(character) { }
......
......@@ -53,9 +53,9 @@ class RegExpMacroAssemblerTracer: public RegExpMacroAssembler {
void IfRegisterLT(int reg, int comparand, Label* if_lt) override;
void IfRegisterEqPos(int reg, Label* if_eq) override;
IrregexpImplementation Implementation() override;
void LoadCurrentCharacter(int cp_offset, Label* on_end_of_input,
bool check_bounds = true,
int characters = 1) override;
void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input,
bool check_bounds, int characters,
int eats_at_least) override;
void PopCurrentPosition() override;
void PopRegister(int register_index) override;
void PushBacktrack(Label* label) override;
......
......@@ -85,6 +85,20 @@ void RegExpMacroAssembler::CheckPosition(int cp_offset,
LoadCurrentCharacter(cp_offset, on_outside_input, true);
}
void RegExpMacroAssembler::LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters,
int eats_at_least) {
// By default, eats_at_least = characters.
if (eats_at_least == kUseCharactersValue) {
eats_at_least = characters;
}
LoadCurrentCharacterImpl(cp_offset, on_end_of_input, check_bounds, characters,
eats_at_least);
}
bool RegExpMacroAssembler::CheckSpecialCharacterClass(uc16 type,
Label* on_no_match) {
return false;
......
......@@ -36,6 +36,8 @@ class RegExpMacroAssembler {
static const int kTableSize = 1 << kTableSizeBits;
static const int kTableMask = kTableSize - 1;
static constexpr int kUseCharactersValue = -1;
enum IrregexpImplementation {
kIA32Implementation,
kARMImplementation,
......@@ -133,10 +135,12 @@ class RegExpMacroAssembler {
// label if it is.
virtual void IfRegisterEqPos(int reg, Label* if_eq) = 0;
virtual IrregexpImplementation Implementation() = 0;
virtual void LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds = true,
int characters = 1) = 0;
V8_EXPORT_PRIVATE void LoadCurrentCharacter(
int cp_offset, Label* on_end_of_input, bool check_bounds = true,
int characters = 1, int eats_at_least = kUseCharactersValue);
virtual void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input,
bool check_bounds, int characters,
int eats_at_least) = 0;
virtual void PopCurrentPosition() = 0;
virtual void PopRegister(int register_index) = 0;
// Pushes the label on the backtrack stack, so that a following Backtrack
......
This diff is collapsed.
......@@ -702,11 +702,8 @@ bool RegExpImpl::Compile(Isolate* isolate, Zone* zone, RegExpCompileData* data,
if (node == nullptr) node = new (zone) EndNode(EndNode::BACKTRACK, zone);
data->node = node;
Analysis analysis(isolate, is_one_byte);
analysis.EnsureAnalyzed(node);
if (analysis.has_failed()) {
data->error =
isolate->factory()->NewStringFromAsciiChecked(analysis.error_message());
if (const char* error_message = AnalyzeRegExp(isolate, is_one_byte, node)) {
data->error = isolate->factory()->NewStringFromAsciiChecked(error_message);
return false;
}
......
......@@ -965,14 +965,19 @@ RegExpMacroAssemblerS390::Implementation() {
return kS390Implementation;
}
void RegExpMacroAssemblerS390::LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters) {
void RegExpMacroAssemblerS390::LoadCurrentCharacterImpl(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters,
int eats_at_least) {
// It's possible to preload a small number of characters when each success
// path requires a large number of characters, but not the reverse.
DCHECK_GE(eats_at_least, characters);
DCHECK(cp_offset < (1 << 30)); // Be sane! (And ensure negation works)
if (check_bounds) {
if (cp_offset >= 0) {
CheckPosition(cp_offset + characters - 1, on_end_of_input);
CheckPosition(cp_offset + eats_at_least - 1, on_end_of_input);
} else {
CheckPosition(cp_offset, on_end_of_input);
}
......
......@@ -59,9 +59,9 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerS390
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
virtual void IfRegisterEqPos(int reg, Label* if_eq);
virtual IrregexpImplementation Implementation();
virtual void LoadCurrentCharacter(int cp_offset, Label* on_end_of_input,
bool check_bounds = true,
int characters = 1);
virtual void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input,
bool check_bounds, int characters,
int eats_at_least);
virtual void PopCurrentPosition();
virtual void PopRegister(int register_index);
virtual void PushBacktrack(Label* label);
......
......@@ -1035,15 +1035,19 @@ RegExpMacroAssembler::IrregexpImplementation
return kX64Implementation;
}
void RegExpMacroAssemblerX64::LoadCurrentCharacterImpl(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters,
int eats_at_least) {
// It's possible to preload a small number of characters when each success
// path requires a large number of characters, but not the reverse.
DCHECK_GE(eats_at_least, characters);
void RegExpMacroAssemblerX64::LoadCurrentCharacter(int cp_offset,
Label* on_end_of_input,
bool check_bounds,
int characters) {
DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
if (check_bounds) {
if (cp_offset >= 0) {
CheckPosition(cp_offset + characters - 1, on_end_of_input);
CheckPosition(cp_offset + eats_at_least - 1, on_end_of_input);
} else {
CheckPosition(cp_offset, on_end_of_input);
}
......@@ -1051,7 +1055,6 @@ void RegExpMacroAssemblerX64::LoadCurrentCharacter(int cp_offset,
LoadCurrentCharacterUnchecked(cp_offset, characters);
}
void RegExpMacroAssemblerX64::PopCurrentPosition() {
Pop(rdi);
}
......
......@@ -60,9 +60,9 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerX64
void IfRegisterLT(int reg, int comparand, Label* if_lt) override;
void IfRegisterEqPos(int reg, Label* if_eq) override;
IrregexpImplementation Implementation() override;
void LoadCurrentCharacter(int cp_offset, Label* on_end_of_input,
bool check_bounds = true,
int characters = 1) override;
void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input,
bool check_bounds, int characters,
int eats_at_least) override;
void PopCurrentPosition() override;
void PopRegister(int register_index) override;
void PushBacktrack(Label* label) override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment