LCOV - code coverage report
Current view: top level - src/interpreter - interpreter-assembler.h (source / functions) Hit Total Coverage
Test: app.info Lines: 2 2 100.0 %
Date: 2017-04-26 Functions: 1 1 100.0 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_INTERPRETER_INTERPRETER_ASSEMBLER_H_
       6             : #define V8_INTERPRETER_INTERPRETER_ASSEMBLER_H_
       7             : 
       8             : #include "src/allocation.h"
       9             : #include "src/builtins/builtins.h"
      10             : #include "src/code-stub-assembler.h"
      11             : #include "src/frames.h"
      12             : #include "src/globals.h"
      13             : #include "src/interpreter/bytecode-register.h"
      14             : #include "src/interpreter/bytecodes.h"
      15             : #include "src/runtime/runtime.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : namespace interpreter {
      20             : 
      21             : class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
      22             :  public:
      23             :   InterpreterAssembler(compiler::CodeAssemblerState* state, Bytecode bytecode,
      24             :                        OperandScale operand_scale);
      25             :   ~InterpreterAssembler();
      26             : 
      27             :   // Returns the 32-bit unsigned count immediate for bytecode operand
      28             :   // |operand_index| in the current bytecode.
      29             :   compiler::Node* BytecodeOperandCount(int operand_index);
      30             :   // Returns the 32-bit unsigned flag for bytecode operand |operand_index|
      31             :   // in the current bytecode.
      32             :   compiler::Node* BytecodeOperandFlag(int operand_index);
      33             :   // Returns the 32-bit zero-extended index immediate for bytecode operand
      34             :   // |operand_index| in the current bytecode.
      35             :   compiler::Node* BytecodeOperandIdxInt32(int operand_index);
      36             :   // Returns the word zero-extended index immediate for bytecode operand
      37             :   // |operand_index| in the current bytecode.
      38             :   compiler::Node* BytecodeOperandIdx(int operand_index);
      39             :   // Returns the smi index immediate for bytecode operand |operand_index|
      40             :   // in the current bytecode.
      41             :   compiler::Node* BytecodeOperandIdxSmi(int operand_index);
      42             :   // Returns the 32-bit unsigned immediate for bytecode operand |operand_index|
      43             :   // in the current bytecode.
      44             :   compiler::Node* BytecodeOperandUImm(int operand_index);
      45             :   // Returns the word-size unsigned immediate for bytecode operand
      46             :   // |operand_index| in the current bytecode.
      47             :   compiler::Node* BytecodeOperandUImmWord(int operand_index);
      48             :   // Returns the 32-bit signed immediate for bytecode operand |operand_index|
      49             :   // in the current bytecode.
      50             :   compiler::Node* BytecodeOperandImm(int operand_index);
      51             :   // Returns the word-size signed immediate for bytecode operand |operand_index|
      52             :   // in the current bytecode.
      53             :   compiler::Node* BytecodeOperandImmIntPtr(int operand_index);
      54             :   // Returns the smi immediate for bytecode operand |operand_index| in the
      55             :   // current bytecode.
      56             :   compiler::Node* BytecodeOperandImmSmi(int operand_index);
      57             :   // Returns the word-size sign-extended register index for bytecode operand
      58             :   // |operand_index| in the current bytecode.
      59             :   compiler::Node* BytecodeOperandReg(int operand_index);
      60             :   // Returns the 32-bit unsigned runtime id immediate for bytecode operand
      61             :   // |operand_index| in the current bytecode.
      62             :   compiler::Node* BytecodeOperandRuntimeId(int operand_index);
      63             :   // Returns the 32-bit unsigned intrinsic id immediate for bytecode operand
      64             :   // |operand_index| in the current bytecode.
      65             :   compiler::Node* BytecodeOperandIntrinsicId(int operand_index);
      66             : 
      67             :   // Accumulator.
      68             :   compiler::Node* GetAccumulator();
      69             :   void SetAccumulator(compiler::Node* value);
      70             : 
      71             :   // Context.
      72             :   compiler::Node* GetContext();
      73             :   void SetContext(compiler::Node* value);
      74             : 
      75             :   // Context at |depth| in the context chain starting at |context|.
      76             :   compiler::Node* GetContextAtDepth(compiler::Node* context,
      77             :                                     compiler::Node* depth);
      78             : 
      79             :   // Goto the given |target| if the context chain starting at |context| has any
      80             :   // extensions up to the given |depth|.
      81             :   void GotoIfHasContextExtensionUpToDepth(compiler::Node* context,
      82             :                                           compiler::Node* depth, Label* target);
      83             : 
      84             :   // Number of registers.
      85             :   compiler::Node* RegisterCount();
      86             : 
      87             :   // Backup/restore register file to/from a fixed array of the correct length.
      88             :   compiler::Node* ExportRegisterFile(compiler::Node* array);
      89             :   compiler::Node* ImportRegisterFile(compiler::Node* array);
      90             : 
      91             :   // Loads from and stores to the interpreter register file.
      92             :   compiler::Node* LoadRegister(Register reg);
      93             :   compiler::Node* LoadRegister(compiler::Node* reg_index);
      94             :   compiler::Node* LoadAndUntagRegister(Register reg);
      95             :   compiler::Node* StoreRegister(compiler::Node* value, Register reg);
      96             :   compiler::Node* StoreRegister(compiler::Node* value,
      97             :                                 compiler::Node* reg_index);
      98             :   compiler::Node* StoreAndTagRegister(compiler::Node* value, Register reg);
      99             : 
     100             :   // Returns the next consecutive register.
     101             :   compiler::Node* NextRegister(compiler::Node* reg_index);
     102             : 
     103             :   // Returns the location in memory of the register |reg_index| in the
     104             :   // interpreter register file.
     105             :   compiler::Node* RegisterLocation(compiler::Node* reg_index);
     106             : 
     107             :   // Load constant at |index| in the constant pool.
     108             :   compiler::Node* LoadConstantPoolEntry(compiler::Node* index);
     109             : 
     110             :   // Load and untag constant at |index| in the constant pool.
     111             :   compiler::Node* LoadAndUntagConstantPoolEntry(compiler::Node* index);
     112             : 
     113             :   // Load the FeedbackVector for the current function.
     114             :   compiler::Node* LoadFeedbackVector();
     115             : 
     116             :   // Increment the call count for a CALL_IC or construct call.
     117             :   // The call count is located at feedback_vector[slot_id + 1].
     118             :   compiler::Node* IncrementCallCount(compiler::Node* feedback_vector,
     119             :                                      compiler::Node* slot_id);
     120             : 
     121             :   // Call JSFunction or Callable |function| with |arg_count| arguments (not
     122             :   // including receiver) and the first argument located at |first_arg|. Type
     123             :   // feedback is collected in the slot at index |slot_id|.
     124             :   //
     125             :   // If the |receiver_mode| is kNullOrUndefined, then the receiver is implicitly
     126             :   // undefined and |first_arg| is the first parameter. Otherwise, |first_arg| is
     127             :   // the receiver and it is converted according to |receiver_mode|.
     128             :   compiler::Node* CallJSWithFeedback(
     129             :       compiler::Node* function, compiler::Node* context,
     130             :       compiler::Node* first_arg, compiler::Node* arg_count,
     131             :       compiler::Node* slot_id, compiler::Node* feedback_vector,
     132             :       ConvertReceiverMode receiver_mode, TailCallMode tail_call_mode);
     133             : 
     134             :   // Call JSFunction or Callable |function| with |arg_count| arguments (not
     135             :   // including receiver) and the first argument located at |first_arg|, possibly
     136             :   // including the receiver depending on |receiver_mode|.
     137             :   compiler::Node* CallJS(compiler::Node* function, compiler::Node* context,
     138             :                          compiler::Node* first_arg, compiler::Node* arg_count,
     139             :                          ConvertReceiverMode receiver_mode,
     140             :                          TailCallMode tail_call_mode);
     141             : 
     142             :   // Call JSFunction or Callable |function| with |arg_count|
     143             :   // arguments (not including receiver) and the first argument
     144             :   // located at |first_arg|.
     145             :   compiler::Node* CallJSWithSpread(compiler::Node* function,
     146             :                                    compiler::Node* context,
     147             :                                    compiler::Node* first_arg,
     148             :                                    compiler::Node* arg_count);
     149             : 
     150             :   // Call constructor |constructor| with |arg_count| arguments (not
     151             :   // including receiver) and the first argument located at
     152             :   // |first_arg|. The |new_target| is the same as the
     153             :   // |constructor| for the new keyword, but differs for the super
     154             :   // keyword.
     155             :   compiler::Node* Construct(compiler::Node* constructor,
     156             :                             compiler::Node* context, compiler::Node* new_target,
     157             :                             compiler::Node* first_arg,
     158             :                             compiler::Node* arg_count, compiler::Node* slot_id,
     159             :                             compiler::Node* feedback_vector);
     160             : 
     161             :   // Call constructor |constructor| with |arg_count| arguments (not including
     162             :   // receiver) and the first argument located at |first_arg|. The last argument
     163             :   // is always a spread. The |new_target| is the same as the |constructor| for
     164             :   // the new keyword, but differs for the super keyword.
     165             :   compiler::Node* ConstructWithSpread(compiler::Node* constructor,
     166             :                                       compiler::Node* context,
     167             :                                       compiler::Node* new_target,
     168             :                                       compiler::Node* first_arg,
     169             :                                       compiler::Node* arg_count);
     170             : 
     171             :   // Call runtime function with |arg_count| arguments and the first argument
     172             :   // located at |first_arg|.
     173             :   compiler::Node* CallRuntimeN(compiler::Node* function_id,
     174             :                                compiler::Node* context,
     175             :                                compiler::Node* first_arg,
     176             :                                compiler::Node* arg_count, int return_size = 1);
     177             : 
     178             :   // Jump forward relative to the current bytecode by the |jump_offset|.
     179             :   compiler::Node* Jump(compiler::Node* jump_offset);
     180             : 
     181             :   // Jump backward relative to the current bytecode by the |jump_offset|.
     182             :   compiler::Node* JumpBackward(compiler::Node* jump_offset);
     183             : 
     184             :   // Jump forward relative to the current bytecode by |jump_offset| if the
     185             :   // word values |lhs| and |rhs| are equal.
     186             :   void JumpIfWordEqual(compiler::Node* lhs, compiler::Node* rhs,
     187             :                        compiler::Node* jump_offset);
     188             : 
     189             :   // Jump forward relative to the current bytecode by |jump_offset| if the
     190             :   // word values |lhs| and |rhs| are not equal.
     191             :   void JumpIfWordNotEqual(compiler::Node* lhs, compiler::Node* rhs,
     192             :                           compiler::Node* jump_offset);
     193             : 
     194             :   // Returns true if the stack guard check triggers an interrupt.
     195             :   compiler::Node* StackCheckTriggeredInterrupt();
     196             : 
     197             :   // Updates the profiler interrupt budget for a return.
     198             :   void UpdateInterruptBudgetOnReturn();
     199             : 
     200             :   // Returns the OSR nesting level from the bytecode header.
     201             :   compiler::Node* LoadOSRNestingLevel();
     202             : 
     203             :   // Dispatch to the bytecode.
     204             :   compiler::Node* Dispatch();
     205             : 
     206             :   // Dispatch to bytecode handler.
     207         903 :   compiler::Node* DispatchToBytecodeHandler(compiler::Node* handler) {
     208         903 :     return DispatchToBytecodeHandler(handler, BytecodeOffset());
     209             :   }
     210             : 
     211             :   // Dispatch bytecode as wide operand variant.
     212             :   void DispatchWide(OperandScale operand_scale);
     213             : 
     214             :   // Truncate tagged |value| to word32 and store the type feedback in
     215             :   // |var_type_feedback|.
     216             :   compiler::Node* TruncateTaggedToWord32WithFeedback(
     217             :       compiler::Node* context, compiler::Node* value,
     218             :       Variable* var_type_feedback);
     219             : 
     220             :   // Abort with the given bailout reason.
     221             :   void Abort(BailoutReason bailout_reason);
     222             :   void AbortIfWordNotEqual(compiler::Node* lhs, compiler::Node* rhs,
     223             :                            BailoutReason bailout_reason);
     224             : 
     225             :   // Dispatch to frame dropper trampoline if necessary.
     226             :   void MaybeDropFrames(compiler::Node* context);
     227             : 
     228             :   // Returns the offset from the BytecodeArrayPointer of the current bytecode.
     229             :   compiler::Node* BytecodeOffset();
     230             : 
     231             :  protected:
     232             :   Bytecode bytecode() const { return bytecode_; }
     233             :   static bool TargetSupportsUnalignedAccess();
     234             : 
     235             :  private:
     236             :   // Returns a tagged pointer to the current function's BytecodeArray object.
     237             :   compiler::Node* BytecodeArrayTaggedPointer();
     238             : 
     239             :   // Returns a raw pointer to first entry in the interpreter dispatch table.
     240             :   compiler::Node* DispatchTableRawPointer();
     241             : 
     242             :   // Returns the accumulator value without checking whether bytecode
     243             :   // uses it. This is intended to be used only in dispatch and in
     244             :   // tracing as these need to bypass accumulator use validity checks.
     245             :   compiler::Node* GetAccumulatorUnchecked();
     246             : 
     247             :   // Returns the frame pointer for the interpreted frame of the function being
     248             :   // interpreted.
     249             :   compiler::Node* GetInterpretedFramePointer();
     250             : 
     251             :   // Saves and restores interpreter bytecode offset to the interpreter stack
     252             :   // frame when performing a call.
     253             :   void CallPrologue();
     254             :   void CallEpilogue();
     255             : 
     256             :   // Increment the dispatch counter for the (current, next) bytecode pair.
     257             :   void TraceBytecodeDispatch(compiler::Node* target_index);
     258             : 
     259             :   // Traces the current bytecode by calling |function_id|.
     260             :   void TraceBytecode(Runtime::FunctionId function_id);
     261             : 
     262             :   // Updates the bytecode array's interrupt budget by a 32-bit unsigned |weight|
     263             :   // and calls Runtime::kInterrupt if counter reaches zero. If |backward|, then
     264             :   // the interrupt budget is decremented, otherwise it is incremented.
     265             :   void UpdateInterruptBudget(compiler::Node* weight, bool backward);
     266             : 
     267             :   // Returns the offset of register |index| relative to RegisterFilePointer().
     268             :   compiler::Node* RegisterFrameOffset(compiler::Node* index);
     269             : 
     270             :   // Returns the offset of an operand relative to the current bytecode offset.
     271             :   compiler::Node* OperandOffset(int operand_index);
     272             : 
     273             :   // Returns a value built from an sequence of bytes in the bytecode
     274             :   // array starting at |relative_offset| from the current bytecode.
     275             :   // The |result_type| determines the size and signedness.  of the
     276             :   // value read. This method should only be used on architectures that
     277             :   // do not support unaligned memory accesses.
     278             :   compiler::Node* BytecodeOperandReadUnaligned(int relative_offset,
     279             :                                                MachineType result_type);
     280             : 
     281             :   // Returns zero- or sign-extended to word32 value of the operand.
     282             :   compiler::Node* BytecodeOperandUnsignedByte(int operand_index);
     283             :   compiler::Node* BytecodeOperandSignedByte(int operand_index);
     284             :   compiler::Node* BytecodeOperandUnsignedShort(int operand_index);
     285             :   compiler::Node* BytecodeOperandSignedShort(int operand_index);
     286             :   compiler::Node* BytecodeOperandUnsignedQuad(int operand_index);
     287             :   compiler::Node* BytecodeOperandSignedQuad(int operand_index);
     288             : 
     289             :   // Returns zero- or sign-extended to word32 value of the operand of
     290             :   // given size.
     291             :   compiler::Node* BytecodeSignedOperand(int operand_index,
     292             :                                         OperandSize operand_size);
     293             :   compiler::Node* BytecodeUnsignedOperand(int operand_index,
     294             :                                           OperandSize operand_size);
     295             : 
     296             :   // Jump relative to the current bytecode by the |jump_offset|. If |backward|,
     297             :   // then jump backward (subtract the offset), otherwise jump forward (add the
     298             :   // offset). Helper function for Jump and JumpBackward.
     299             :   compiler::Node* Jump(compiler::Node* jump_offset, bool backward);
     300             : 
     301             :   // Jump forward relative to the current bytecode by |jump_offset| if the
     302             :   // |condition| is true. Helper function for JumpIfWordEqual and
     303             :   // JumpIfWordNotEqual.
     304             :   void JumpConditional(compiler::Node* condition, compiler::Node* jump_offset);
     305             : 
     306             :   // Save the bytecode offset to the interpreter frame.
     307             :   void SaveBytecodeOffset();
     308             : 
     309             :   // Updates and returns BytecodeOffset() advanced by the current bytecode's
     310             :   // size. Traces the exit of the current bytecode.
     311             :   compiler::Node* Advance();
     312             : 
     313             :   // Updates and returns BytecodeOffset() advanced by delta bytecodes.
     314             :   // Traces the exit of the current bytecode.
     315             :   compiler::Node* Advance(int delta);
     316             :   compiler::Node* Advance(compiler::Node* delta, bool backward = false);
     317             : 
     318             :   // Load the bytecode at |bytecode_offset|.
     319             :   compiler::Node* LoadBytecode(compiler::Node* bytecode_offset);
     320             : 
     321             :   // Look ahead for Star and inline it in a branch. Returns a new target
     322             :   // bytecode node for dispatch.
     323             :   compiler::Node* StarDispatchLookahead(compiler::Node* target_bytecode);
     324             : 
     325             :   // Build code for Star at the current BytecodeOffset() and Advance() to the
     326             :   // next dispatch offset.
     327             :   void InlineStar();
     328             : 
     329             :   // Dispatch to |target_bytecode| at |new_bytecode_offset|.
     330             :   // |target_bytecode| should be equivalent to loading from the offset.
     331             :   compiler::Node* DispatchToBytecode(compiler::Node* target_bytecode,
     332             :                                      compiler::Node* new_bytecode_offset);
     333             : 
     334             :   // Dispatch to the bytecode handler with code offset |handler|.
     335             :   compiler::Node* DispatchToBytecodeHandler(compiler::Node* handler,
     336             :                                             compiler::Node* bytecode_offset);
     337             : 
     338             :   // Dispatch to the bytecode handler with code entry point |handler_entry|.
     339             :   compiler::Node* DispatchToBytecodeHandlerEntry(
     340             :       compiler::Node* handler_entry, compiler::Node* bytecode_offset);
     341             : 
     342             :   int CurrentBytecodeSize() const;
     343             : 
     344             :   OperandScale operand_scale() const { return operand_scale_; }
     345             : 
     346             :   Bytecode bytecode_;
     347             :   OperandScale operand_scale_;
     348             :   CodeStubAssembler::Variable bytecode_offset_;
     349             :   CodeStubAssembler::Variable interpreted_frame_pointer_;
     350             :   CodeStubAssembler::Variable bytecode_array_;
     351             :   CodeStubAssembler::Variable dispatch_table_;
     352             :   CodeStubAssembler::Variable accumulator_;
     353             :   AccumulatorUse accumulator_use_;
     354             :   bool made_call_;
     355             :   bool reloaded_frame_ptr_;
     356             :   bool saved_bytecode_offset_;
     357             : 
     358             :   bool disable_stack_check_across_call_;
     359             :   compiler::Node* stack_pointer_before_call_;
     360             : 
     361             :   DISALLOW_COPY_AND_ASSIGN(InterpreterAssembler);
     362             : };
     363             : 
     364             : }  // namespace interpreter
     365             : }  // namespace internal
     366             : }  // namespace v8
     367             : 
     368             : #endif  // V8_INTERPRETER_INTERPRETER_ASSEMBLER_H_

Generated by: LCOV version 1.10