forked from mirrors/gecko-dev
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:
parent
144dea2809
commit
1850525f8f
2 changed files with 111 additions and 1 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue