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
	
	 Iain Ireland
						Iain Ireland