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 int stack_limit_slack(); | ||||||
|   virtual IrregexpImplementation Implementation(); |   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_; |   JSContext* cx_; | ||||||
|   js::jit::StackMacroAssembler& masm_; |   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_; |   Mode mode_; | ||||||
|   int num_registers_; |   int num_registers_; | ||||||
|   int num_capture_registers_; |   int num_capture_registers_; | ||||||
|  |   js::jit::LiveGeneralRegisterSet savedRegisters_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| }  // namespace internal
 | }  // namespace internal
 | ||||||
|  |  | ||||||
|  | @ -16,6 +16,12 @@ | ||||||
| namespace v8 { | namespace v8 { | ||||||
| namespace internal { | 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; | using js::jit::StackMacroAssembler; | ||||||
| 
 | 
 | ||||||
| SMRegExpMacroAssembler::SMRegExpMacroAssembler(JSContext* cx, Isolate* isolate, | SMRegExpMacroAssembler::SMRegExpMacroAssembler(JSContext* cx, Isolate* isolate, | ||||||
|  | @ -30,12 +36,62 @@ SMRegExpMacroAssembler::SMRegExpMacroAssembler(JSContext* cx, Isolate* isolate, | ||||||
|       num_capture_registers_(num_capture_registers) { |       num_capture_registers_(num_capture_registers) { | ||||||
|   // Each capture has a start and an end register
 |   // Each capture has a start and an end register
 | ||||||
|   MOZ_ASSERT(num_capture_registers_ % 2 == 0); |   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() { | int SMRegExpMacroAssembler::stack_limit_slack() { | ||||||
|   return RegExpStack::kStackLimitSlack; |   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.
 | // This is only used by tracing code.
 | ||||||
| // The return value doesn't matter.
 | // The return value doesn't matter.
 | ||||||
| RegExpMacroAssembler::IrregexpImplementation | RegExpMacroAssembler::IrregexpImplementation | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Iain Ireland
						Iain Ireland