Bug 1594545: Part 2: Push, Pop, register allocation r=jandem

This patch defines our register usage, and implements a few simple ops that don't rely on anything else.

Depends on D68412

Differential Revision: https://phabricator.services.mozilla.com/D68414

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Iain Ireland 2020-03-27 07:16:43 +00:00
parent 144dea2809
commit 1850525f8f
2 changed files with 111 additions and 1 deletions

View file

@ -31,14 +31,68 @@ class SMRegExpMacroAssembler final : public NativeRegExpMacroAssembler {
virtual int stack_limit_slack();
virtual IrregexpImplementation Implementation();
virtual bool Succeed();
virtual void Fail();
virtual void AdvanceCurrentPosition(int by);
virtual void PopCurrentPosition();
virtual void PushCurrentPosition();
private:
// Push a register on the backtrack stack.
void Push(js::jit::Register value);
// Pop a value from the backtrack stack.
void Pop(js::jit::Register target);
inline int char_size() { return static_cast<int>(mode_); }
inline js::jit::Scale factor() {
return mode_ == UC16 ? js::jit::TimesTwo : js::jit::TimesOne;
}
private:
JSContext* cx_;
js::jit::StackMacroAssembler& masm_;
/*
* This assembler uses the following registers:
*
* - current_character_:
* Contains the character (or characters) currently being examined.
* Must be loaded using LoadCurrentCharacter before using any of the
* dispatch methods. After a matching pass for a global regexp,
* temporarily stores the index of capture start.
* - current_position_:
* Current position in input *as negative byte offset from end of string*.
* - input_end_pointer_:
* Points to byte after last character in the input. current_position_ is
* relative to this.
* - backtrack_stack_pointer_:
* Points to tip of the (heap-allocated) backtrack stack. The stack grows
* downward (like the native stack).
* - temp0_, temp1_, temp2_:
* Scratch registers.
*
* The native stack pointer is used to access arguments (InputOutputData),
* local variables (FrameData), and irregexp's internal virtual registers
* (see register_location).
*/
js::jit::Register current_character_;
js::jit::Register current_position_;
js::jit::Register input_end_pointer_;
js::jit::Register backtrack_stack_pointer_;
js::jit::Register temp0_, temp1_, temp2_;
js::jit::Label entry_label_;
js::jit::Label start_label_;
js::jit::Label success_label_;
js::jit::Label exit_label_;
Mode mode_;
int num_registers_;
int num_capture_registers_;
js::jit::LiveGeneralRegisterSet savedRegisters_;
};
} // namespace internal

View file

@ -16,6 +16,12 @@
namespace v8 {
namespace internal {
using js::jit::Address;
using js::jit::AllocatableGeneralRegisterSet;
using js::jit::GeneralRegisterSet;
using js::jit::Imm32;
using js::jit::ImmWord;
using js::jit::Register;
using js::jit::StackMacroAssembler;
SMRegExpMacroAssembler::SMRegExpMacroAssembler(JSContext* cx, Isolate* isolate,
@ -30,12 +36,62 @@ SMRegExpMacroAssembler::SMRegExpMacroAssembler(JSContext* cx, Isolate* isolate,
num_capture_registers_(num_capture_registers) {
// Each capture has a start and an end register
MOZ_ASSERT(num_capture_registers_ % 2 == 0);
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
temp0_ = regs.takeAny();
temp1_ = regs.takeAny();
temp2_ = regs.takeAny();
input_end_pointer_ = regs.takeAny();
current_character_ = regs.takeAny();
current_position_ = regs.takeAny();
backtrack_stack_pointer_ = regs.takeAny();
savedRegisters_ = js::jit::SavedNonVolatileRegisters(regs);
masm_.jump(&entry_label_); // We'll generate the entry code later
masm_.bind(&start_label_); // and continue from here.
}
int SMRegExpMacroAssembler::stack_limit_slack() {
return RegExpStack::kStackLimitSlack;
}
void SMRegExpMacroAssembler::AdvanceCurrentPosition(int by) {
if (by != 0) {
masm_.addPtr(Imm32(by * char_size()), current_position_);
}
}
void SMRegExpMacroAssembler::Fail() {
masm_.movePtr(ImmWord(js::RegExpRunStatus_Success_NotFound), temp0_);
masm_.jump(&exit_label_);
}
void SMRegExpMacroAssembler::PopCurrentPosition() { Pop(current_position_); }
void SMRegExpMacroAssembler::PushCurrentPosition() { Push(current_position_); }
// Returns true if a regexp match can be restarted (aka the regexp is global).
// The return value is not used anywhere, but we implement it to be safe.
bool SMRegExpMacroAssembler::Succeed() {
masm_.jump(&success_label_);
return global();
}
void SMRegExpMacroAssembler::Push(Register source) {
MOZ_ASSERT(source != backtrack_stack_pointer_);
masm_.subPtr(Imm32(sizeof(void*)), backtrack_stack_pointer_);
masm_.storePtr(source, Address(backtrack_stack_pointer_, 0));
}
void SMRegExpMacroAssembler::Pop(Register target) {
MOZ_ASSERT(target != backtrack_stack_pointer_);
masm_.loadPtr(Address(backtrack_stack_pointer_, 0), target);
masm_.addPtr(Imm32(sizeof(void*)), backtrack_stack_pointer_);
}
// This is only used by tracing code.
// The return value doesn't matter.
RegExpMacroAssembler::IrregexpImplementation