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) { ...@@ -219,6 +219,55 @@ void RegExpMacroAssemblerRISCV::CheckGreedyLoop(Label* on_equal) {
BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0)); 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( void RegExpMacroAssemblerRISCV::CheckNotBackReferenceIgnoreCase(
int start_reg, bool read_backward, bool unicode, Label* on_no_match) { int start_reg, bool read_backward, bool unicode, Label* on_no_match) {
Label fallthrough; Label fallthrough;
...@@ -299,11 +348,7 @@ void RegExpMacroAssemblerRISCV::CheckNotBackReferenceIgnoreCase( ...@@ -299,11 +348,7 @@ void RegExpMacroAssemblerRISCV::CheckNotBackReferenceIgnoreCase(
} }
} else { } else {
DCHECK(mode_ == UC16); DCHECK(mode_ == UC16);
// Put regexp engine registers on stack. PushCallerSavedRegisters();
RegList regexp_registers_to_retain = current_input_offset().bit() |
current_character().bit() |
backtrack_stackpointer().bit();
__ MultiPush(regexp_registers_to_retain);
int argument_count = 4; int argument_count = 4;
__ PrepareCallCFunction(argument_count, a2); __ PrepareCallCFunction(argument_count, a2);
...@@ -342,7 +387,7 @@ void RegExpMacroAssemblerRISCV::CheckNotBackReferenceIgnoreCase( ...@@ -342,7 +387,7 @@ void RegExpMacroAssemblerRISCV::CheckNotBackReferenceIgnoreCase(
} }
// Restore regexp engine registers. // Restore regexp engine registers.
__ MultiPop(regexp_registers_to_retain); PopCallerSavedRegisters();
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
__ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); __ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
...@@ -900,12 +945,9 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) { ...@@ -900,12 +945,9 @@ Handle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(Handle<String> source) {
SafeCallTarget(&check_preempt_label_); SafeCallTarget(&check_preempt_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1); StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
// Put regexp engine registers on stack. // Put regexp engine registers on stack.
RegList regexp_registers_to_retain = current_input_offset().bit() | PushCallerSavedRegisters();
current_character().bit() |
backtrack_stackpointer().bit();
__ MultiPush(regexp_registers_to_retain);
CallCheckStackGuardState(a0); CallCheckStackGuardState(a0);
__ MultiPop(regexp_registers_to_retain); PopCallerSavedRegisters();
// If returning non-zero, we should end execution with the given // If returning non-zero, we should end execution with the given
// result as return value. // result as return value.
__ Branch(&return_a0, ne, a0, Operand(zero_reg)); __ Branch(&return_a0, ne, a0, Operand(zero_reg));
......
...@@ -18,68 +18,72 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerRISCV ...@@ -18,68 +18,72 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerRISCV
public: public:
RegExpMacroAssemblerRISCV(Isolate* isolate, Zone* zone, Mode mode, RegExpMacroAssemblerRISCV(Isolate* isolate, Zone* zone, Mode mode,
int registers_to_save); int registers_to_save);
virtual ~RegExpMacroAssemblerRISCV(); ~RegExpMacroAssemblerRISCV() override;
virtual int stack_limit_slack(); int stack_limit_slack() override;
virtual void AdvanceCurrentPosition(int by); void AdvanceCurrentPosition(int by) override;
virtual void AdvanceRegister(int reg, int by); void AdvanceRegister(int reg, int by) override;
virtual void Backtrack(); void Backtrack() override;
virtual void Bind(Label* label); void Bind(Label* label) override;
virtual void CheckAtStart(int cp_offset, Label* on_at_start); void CheckAtStart(int cp_offset, Label* on_at_start) override;
virtual void CheckCharacter(uint32_t c, Label* on_equal); void CheckCharacter(uint32_t c, Label* on_equal) override;
virtual void CheckCharacterAfterAnd(uint32_t c, uint32_t mask, void CheckCharacterAfterAnd(uint32_t c, uint32_t mask,
Label* on_equal); Label* on_equal) override;
virtual void CheckCharacterGT(base::uc16 limit, Label* on_greater); void CheckCharacterGT(base::uc16 limit, Label* on_greater) override;
virtual void CheckCharacterLT(base::uc16 limit, Label* on_less); void CheckCharacterLT(base::uc16 limit, Label* on_less) override;
// A "greedy loop" is a loop that is both greedy and with a simple // A "greedy loop" is a loop that is both greedy and with a simple
// body. It has a particularly simple implementation. // body. It has a particularly simple implementation.
virtual void CheckGreedyLoop(Label* on_tos_equals_current_position); void CheckGreedyLoop(Label* on_tos_equals_current_position) override;
virtual void CheckNotAtStart(int cp_offset, Label* on_not_at_start); void CheckNotAtStart(int cp_offset, Label* on_not_at_start) override;
virtual void CheckNotBackReference(int start_reg, bool read_backward, void CheckNotBackReference(int start_reg, bool read_backward,
Label* on_no_match); Label* on_no_match) override;
virtual void CheckNotBackReferenceIgnoreCase(int start_reg, void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
bool read_backward, bool unicode, bool unicode,
Label* on_no_match); Label* on_no_match) override;
virtual void CheckNotCharacter(uint32_t c, Label* on_not_equal); void CheckNotCharacter(uint32_t c, Label* on_not_equal) override;
virtual void CheckNotCharacterAfterAnd(uint32_t c, uint32_t mask, void CheckNotCharacterAfterAnd(uint32_t c, uint32_t mask,
Label* on_not_equal); Label* on_not_equal) override;
virtual void CheckNotCharacterAfterMinusAnd(base::uc16 c, base::uc16 minus, void CheckNotCharacterAfterMinusAnd(base::uc16 c, base::uc16 minus,
base::uc16 mask, base::uc16 mask,
Label* on_not_equal); Label* on_not_equal) override;
virtual void CheckCharacterInRange(base::uc16 from, base::uc16 to, void CheckCharacterInRange(base::uc16 from, base::uc16 to,
Label* on_in_range); Label* on_in_range) override;
virtual void CheckCharacterNotInRange(base::uc16 from, base::uc16 to, void CheckCharacterNotInRange(base::uc16 from, base::uc16 to,
Label* on_not_in_range); Label* on_not_in_range) override;
virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set); 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 // Checks whether the given offset from the current position is before
// the end of the string. // the end of the string.
virtual void CheckPosition(int cp_offset, Label* on_outside_input); void CheckPosition(int cp_offset, Label* on_outside_input) override;
virtual bool CheckSpecialCharacterClass(StandardCharacterSet type, bool CheckSpecialCharacterClass(StandardCharacterSet type,
Label* on_no_match); Label* on_no_match) override;
virtual void Fail(); void Fail() override;
virtual Handle<HeapObject> GetCode(Handle<String> source); Handle<HeapObject> GetCode(Handle<String> source) override;
virtual void GoTo(Label* label); void GoTo(Label* label) override;
virtual void IfRegisterGE(int reg, int comparand, Label* if_ge); void IfRegisterGE(int reg, int comparand, Label* if_ge) override;
virtual void IfRegisterLT(int reg, int comparand, Label* if_lt); void IfRegisterLT(int reg, int comparand, Label* if_lt) override;
virtual void IfRegisterEqPos(int reg, Label* if_eq); void IfRegisterEqPos(int reg, Label* if_eq) override;
virtual IrregexpImplementation Implementation(); IrregexpImplementation Implementation() override;
virtual void LoadCurrentCharacterUnchecked(int cp_offset, void LoadCurrentCharacterUnchecked(int cp_offset,
int character_count); int character_count) override;
virtual void PopCurrentPosition(); void PopCurrentPosition() override;
virtual void PopRegister(int register_index); void PopRegister(int register_index) override;
virtual void PushBacktrack(Label* label); void PushBacktrack(Label* label) override;
virtual void PushCurrentPosition(); void PushCurrentPosition() override;
virtual void PushRegister(int register_index, void PushRegister(int register_index,
StackCheckFlag check_stack_limit); StackCheckFlag check_stack_limit) override;
virtual void ReadCurrentPositionFromRegister(int reg); void ReadCurrentPositionFromRegister(int reg) override;
virtual void ReadStackPointerFromRegister(int reg); void ReadStackPointerFromRegister(int reg) override;
virtual void SetCurrentPositionFromEnd(int by); void SetCurrentPositionFromEnd(int by) override;
virtual void SetRegister(int register_index, int to); void SetRegister(int register_index, int to) override;
virtual bool Succeed(); bool Succeed() override;
virtual void WriteCurrentPositionToRegister(int reg, int cp_offset); void WriteCurrentPositionToRegister(int reg, int cp_offset) override;
virtual void ClearRegisters(int reg_from, int reg_to); void ClearRegisters(int reg_from, int reg_to) override;
virtual void WriteStackPointerToRegister(int reg); void WriteStackPointerToRegister(int reg) override;
virtual bool CanReadUnaligned() const; bool CanReadUnaligned() const override;
// Called from RegExp if the stack-guard is triggered. // Called from RegExp if the stack-guard is triggered.
// If the code object is relocated, the return address is fixed before // If the code object is relocated, the return address is fixed before
...@@ -134,14 +138,17 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerRISCV ...@@ -134,14 +138,17 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerRISCV
// Initial size of code buffer. // Initial size of code buffer.
static const int kRegExpCodeSize = 1024; static const int kRegExpCodeSize = 1024;
void PushCallerSavedRegisters();
void PopCallerSavedRegisters();
// Check whether preemption has been requested. // Check whether preemption has been requested.
void CheckPreemption(); void CheckPreemption();
// Check whether we are exceeding the stack limit on the backtrack stack. // Check whether we are exceeding the stack limit on the backtrack stack.
void CheckStackLimit(); void CheckStackLimit();
// Generate a call to CheckStackGuardState.
void CallCheckStackGuardState(Register scratch); void CallCheckStackGuardState(Register scratch);
void CallIsCharacterInRangeArray(const ZoneList<CharacterRange>* ranges);
// The ebp-relative location of a regexp register. // The ebp-relative location of a regexp register.
MemOperand register_location(int register_index); 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