Commit 6b2809df authored by Lu Yahan's avatar Lu Yahan Committed by V8 LUCI CQ

[riscv64][regexp] Compact codegen for large character classes

Port 8bbb44e5
Port 7c08633b

Change-Id: Iebc3e223a0a7bc5f31ef0f21d8589e60ccdc0833
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3233695
Auto-Submit: Yahan Lu <yahan@iscas.ac.cn>
Commit-Queue: ji qiu <qiuji@iscas.ac.cn>
Reviewed-by: 's avatarji qiu <qiuji@iscas.ac.cn>
Cr-Commit-Position: refs/heads/main@{#77485}
parent c3f346b7
......@@ -219,6 +219,55 @@ void RegExpMacroAssemblerRISCV::CheckGreedyLoop(Label* on_equal) {
BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0));
}
// Push (pop) caller-saved registers used by irregexp.
void RegExpMacroAssemblerRISCV::PushCallerSavedRegisters() {
RegList caller_saved_regexp =
current_input_offset().bit() | current_character().bit() |
end_of_input_address().bit() | backtrack_stackpointer().bit();
__ MultiPush(caller_saved_regexp);
}
void RegExpMacroAssemblerRISCV::PopCallerSavedRegisters() {
RegList caller_saved_regexp =
current_input_offset().bit() | current_character().bit() |
end_of_input_address().bit() | backtrack_stackpointer().bit();
__ MultiPop(caller_saved_regexp);
}
void RegExpMacroAssemblerRISCV::CallIsCharacterInRangeArray(
const ZoneList<CharacterRange>* ranges) {
PushCallerSavedRegisters();
static const int kNumArguments = 3;
__ PrepareCallCFunction(kNumArguments, a0);
__ mv(a0, current_character());
__ li(a1, Operand(GetOrAddRangeArray(ranges)));
__ li(a2, Operand(ExternalReference::isolate_address(isolate())));
{
// We have a frame (set up in GetCode), but the assembler doesn't know.
FrameScope scope(masm_.get(), StackFrame::MANUAL);
__ CallCFunction(ExternalReference::re_is_character_in_range_array(),
kNumArguments);
}
PopCallerSavedRegisters();
__ li(code_pointer(), Operand(masm_->CodeObject()));
}
bool RegExpMacroAssemblerRISCV::CheckCharacterInRangeArray(
const ZoneList<CharacterRange>* ranges, Label* on_in_range) {
CallIsCharacterInRangeArray(ranges);
BranchOrBacktrack(on_in_range, ne, a0, Operand(zero_reg));
return true;
}
bool RegExpMacroAssemblerRISCV::CheckCharacterNotInRangeArray(
const ZoneList<CharacterRange>* ranges, Label* on_not_in_range) {
CallIsCharacterInRangeArray(ranges);
BranchOrBacktrack(on_not_in_range, eq, a0, Operand(zero_reg));
return true;
}
void RegExpMacroAssemblerRISCV::CheckNotBackReferenceIgnoreCase(
int start_reg, bool read_backward, bool unicode, Label* on_no_match) {
Label fallthrough;
......@@ -299,11 +348,7 @@ void RegExpMacroAssemblerRISCV::CheckNotBackReferenceIgnoreCase(
}
} else {
DCHECK(mode_ == UC16);
// Put regexp engine registers on stack.
RegList regexp_registers_to_retain = current_input_offset().bit() |
current_character().bit() |
backtrack_stackpointer().bit();
__ MultiPush(regexp_registers_to_retain);
PushCallerSavedRegisters();
int argument_count = 4;
__ PrepareCallCFunction(argument_count, a2);
......@@ -342,7 +387,7 @@ void RegExpMacroAssemblerRISCV::CheckNotBackReferenceIgnoreCase(
}
// Restore regexp engine registers.
__ MultiPop(regexp_registers_to_retain);
PopCallerSavedRegisters();
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
__ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
......@@ -900,12 +945,9 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
SafeCallTarget(&check_preempt_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
// Put regexp engine registers on stack.
RegList regexp_registers_to_retain = current_input_offset().bit() |
current_character().bit() |
backtrack_stackpointer().bit();
__ MultiPush(regexp_registers_to_retain);
PushCallerSavedRegisters();
CallCheckStackGuardState(a0);
__ MultiPop(regexp_registers_to_retain);
PopCallerSavedRegisters();
// If returning non-zero, we should end execution with the given
// result as return value.
__ Branch(&return_a0, ne, a0, Operand(zero_reg));
......
......@@ -18,68 +18,72 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerRISCV
public:
RegExpMacroAssemblerRISCV(Isolate* isolate, Zone* zone, Mode mode,
int registers_to_save);
virtual ~RegExpMacroAssemblerRISCV();
virtual int stack_limit_slack();
virtual void AdvanceCurrentPosition(int by);
virtual void AdvanceRegister(int reg, int by);
virtual void Backtrack();
virtual void Bind(Label* label);
virtual void CheckAtStart(int cp_offset, Label* on_at_start);
virtual void CheckCharacter(uint32_t c, Label* on_equal);
virtual void CheckCharacterAfterAnd(uint32_t c, uint32_t mask,
Label* on_equal);
virtual void CheckCharacterGT(base::uc16 limit, Label* on_greater);
virtual void CheckCharacterLT(base::uc16 limit, Label* on_less);
~RegExpMacroAssemblerRISCV() override;
int stack_limit_slack() override;
void AdvanceCurrentPosition(int by) override;
void AdvanceRegister(int reg, int by) override;
void Backtrack() override;
void Bind(Label* label) override;
void CheckAtStart(int cp_offset, Label* on_at_start) override;
void CheckCharacter(uint32_t c, Label* on_equal) override;
void CheckCharacterAfterAnd(uint32_t c, uint32_t mask,
Label* on_equal) override;
void CheckCharacterGT(base::uc16 limit, Label* on_greater) override;
void CheckCharacterLT(base::uc16 limit, Label* on_less) override;
// A "greedy loop" is a loop that is both greedy and with a simple
// body. It has a particularly simple implementation.
virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
virtual void CheckNotAtStart(int cp_offset, Label* on_not_at_start);
virtual void CheckNotBackReference(int start_reg, bool read_backward,
Label* on_no_match);
virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
bool read_backward, bool unicode,
Label* on_no_match);
virtual void CheckNotCharacter(uint32_t c, Label* on_not_equal);
virtual void CheckNotCharacterAfterAnd(uint32_t c, uint32_t mask,
Label* on_not_equal);
virtual void CheckNotCharacterAfterMinusAnd(base::uc16 c, base::uc16 minus,
base::uc16 mask,
Label* on_not_equal);
virtual void CheckCharacterInRange(base::uc16 from, base::uc16 to,
Label* on_in_range);
virtual void CheckCharacterNotInRange(base::uc16 from, base::uc16 to,
Label* on_not_in_range);
virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set);
void CheckGreedyLoop(Label* on_tos_equals_current_position) override;
void CheckNotAtStart(int cp_offset, Label* on_not_at_start) override;
void CheckNotBackReference(int start_reg, bool read_backward,
Label* on_no_match) override;
void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
bool unicode,
Label* on_no_match) override;
void CheckNotCharacter(uint32_t c, Label* on_not_equal) override;
void CheckNotCharacterAfterAnd(uint32_t c, uint32_t mask,
Label* on_not_equal) override;
void CheckNotCharacterAfterMinusAnd(base::uc16 c, base::uc16 minus,
base::uc16 mask,
Label* on_not_equal) override;
void CheckCharacterInRange(base::uc16 from, base::uc16 to,
Label* on_in_range) override;
void CheckCharacterNotInRange(base::uc16 from, base::uc16 to,
Label* on_not_in_range) override;
bool CheckCharacterInRangeArray(const ZoneList<CharacterRange>* ranges,
Label* on_in_range) override;
bool CheckCharacterNotInRangeArray(const ZoneList<CharacterRange>* ranges,
Label* on_not_in_range) override;
void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set) override;
// Checks whether the given offset from the current position is before
// the end of the string.
virtual void CheckPosition(int cp_offset, Label* on_outside_input);
virtual bool CheckSpecialCharacterClass(StandardCharacterSet type,
Label* on_no_match);
virtual void Fail();
virtual Handle<HeapObject> GetCode(Handle<String> source);
virtual void GoTo(Label* label);
virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
virtual void IfRegisterEqPos(int reg, Label* if_eq);
virtual IrregexpImplementation Implementation();
virtual void LoadCurrentCharacterUnchecked(int cp_offset,
int character_count);
virtual void PopCurrentPosition();
virtual void PopRegister(int register_index);
virtual void PushBacktrack(Label* label);
virtual void PushCurrentPosition();
virtual void PushRegister(int register_index,
StackCheckFlag check_stack_limit);
virtual void ReadCurrentPositionFromRegister(int reg);
virtual void ReadStackPointerFromRegister(int reg);
virtual void SetCurrentPositionFromEnd(int by);
virtual void SetRegister(int register_index, int to);
virtual bool Succeed();
virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
virtual void ClearRegisters(int reg_from, int reg_to);
virtual void WriteStackPointerToRegister(int reg);
virtual bool CanReadUnaligned() const;
void CheckPosition(int cp_offset, Label* on_outside_input) override;
bool CheckSpecialCharacterClass(StandardCharacterSet type,
Label* on_no_match) override;
void Fail() override;
Handle<HeapObject> GetCode(Handle<String> source) override;
void GoTo(Label* label) override;
void IfRegisterGE(int reg, int comparand, Label* if_ge) override;
void IfRegisterLT(int reg, int comparand, Label* if_lt) override;
void IfRegisterEqPos(int reg, Label* if_eq) override;
IrregexpImplementation Implementation() override;
void LoadCurrentCharacterUnchecked(int cp_offset,
int character_count) override;
void PopCurrentPosition() override;
void PopRegister(int register_index) override;
void PushBacktrack(Label* label) override;
void PushCurrentPosition() override;
void PushRegister(int register_index,
StackCheckFlag check_stack_limit) override;
void ReadCurrentPositionFromRegister(int reg) override;
void ReadStackPointerFromRegister(int reg) override;
void SetCurrentPositionFromEnd(int by) override;
void SetRegister(int register_index, int to) override;
bool Succeed() override;
void WriteCurrentPositionToRegister(int reg, int cp_offset) override;
void ClearRegisters(int reg_from, int reg_to) override;
void WriteStackPointerToRegister(int reg) override;
bool CanReadUnaligned() const override;
// Called from RegExp if the stack-guard is triggered.
// If the code object is relocated, the return address is fixed before
......@@ -134,14 +138,17 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerRISCV
// Initial size of code buffer.
static const int kRegExpCodeSize = 1024;
void PushCallerSavedRegisters();
void PopCallerSavedRegisters();
// Check whether preemption has been requested.
void CheckPreemption();
// Check whether we are exceeding the stack limit on the backtrack stack.
void CheckStackLimit();
// Generate a call to CheckStackGuardState.
void CallCheckStackGuardState(Register scratch);
void CallIsCharacterInRangeArray(const ZoneList<CharacterRange>* ranges);
// The ebp-relative location of a regexp register.
MemOperand register_location(int register_index);
......
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