LCOV - code coverage report
Current view: top level - src/interpreter - bytecode-array-builder.h (source / functions) Hit Total Coverage
Test: app.info Lines: 16 16 100.0 %
Date: 2019-02-19 Functions: 3 3 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_BYTECODE_ARRAY_BUILDER_H_
       6             : #define V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_
       7             : 
       8             : #include "src/ast/ast.h"
       9             : #include "src/base/compiler-specific.h"
      10             : #include "src/globals.h"
      11             : #include "src/interpreter/bytecode-array-writer.h"
      12             : #include "src/interpreter/bytecode-flags.h"
      13             : #include "src/interpreter/bytecode-register-allocator.h"
      14             : #include "src/interpreter/bytecode-register.h"
      15             : #include "src/interpreter/bytecode-source-info.h"
      16             : #include "src/interpreter/bytecodes.h"
      17             : #include "src/interpreter/constant-array-builder.h"
      18             : #include "src/interpreter/handler-table-builder.h"
      19             : #include "src/zone/zone-containers.h"
      20             : 
      21             : namespace v8 {
      22             : namespace internal {
      23             : 
      24             : class FeedbackVectorSpec;
      25             : class Isolate;
      26             : 
      27             : namespace interpreter {
      28             : 
      29             : class BytecodeLabel;
      30             : class BytecodeNode;
      31             : class BytecodeRegisterOptimizer;
      32             : class BytecodeJumpTable;
      33             : class Register;
      34             : 
      35     4214604 : class V8_EXPORT_PRIVATE BytecodeArrayBuilder final {
      36             :  public:
      37             :   BytecodeArrayBuilder(
      38             :       Zone* zone, int parameter_count, int locals_count,
      39             :       FeedbackVectorSpec* feedback_vector_spec = nullptr,
      40             :       SourcePositionTableBuilder::RecordingMode source_position_mode =
      41             :           SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS);
      42             : 
      43             :   Handle<BytecodeArray> ToBytecodeArray(Isolate* isolate);
      44             : 
      45             :   // Get the number of parameters expected by function.
      46             :   int parameter_count() const {
      47             :     DCHECK_GE(parameter_count_, 0);
      48             :     return parameter_count_;
      49             :   }
      50             : 
      51             :   // Get the number of locals required for bytecode array.
      52             :   int locals_count() const {
      53             :     DCHECK_GE(local_register_count_, 0);
      54             :     return local_register_count_;
      55             :   }
      56             : 
      57             :   // Returns the number of fixed (non-temporary) registers.
      58     2106750 :   int fixed_register_count() const { return locals_count(); }
      59             : 
      60             :   // Returns the number of fixed and temporary registers.
      61             :   int total_register_count() const {
      62             :     DCHECK_LE(fixed_register_count(),
      63             :               register_allocator()->maximum_register_count());
      64     2082966 :     return register_allocator()->maximum_register_count();
      65             :   }
      66             : 
      67             :   Register Local(int index) const;
      68             :   Register Parameter(int parameter_index) const;
      69             :   Register Receiver() const;
      70             : 
      71             :   // Constant loads to accumulator.
      72             :   BytecodeArrayBuilder& LoadConstantPoolEntry(size_t entry);
      73             :   BytecodeArrayBuilder& LoadLiteral(Smi value);
      74             :   BytecodeArrayBuilder& LoadLiteral(double value);
      75             :   BytecodeArrayBuilder& LoadLiteral(const AstRawString* raw_string);
      76             :   BytecodeArrayBuilder& LoadLiteral(const Scope* scope);
      77             :   BytecodeArrayBuilder& LoadLiteral(AstBigInt bigint);
      78             :   BytecodeArrayBuilder& LoadLiteral(AstSymbol symbol);
      79             :   BytecodeArrayBuilder& LoadUndefined();
      80             :   BytecodeArrayBuilder& LoadNull();
      81             :   BytecodeArrayBuilder& LoadTheHole();
      82             :   BytecodeArrayBuilder& LoadTrue();
      83             :   BytecodeArrayBuilder& LoadFalse();
      84             :   BytecodeArrayBuilder& LoadBoolean(bool value);
      85             : 
      86             :   // Global loads to the accumulator and stores from the accumulator.
      87             :   BytecodeArrayBuilder& LoadGlobal(const AstRawString* name, int feedback_slot,
      88             :                                    TypeofMode typeof_mode);
      89             :   BytecodeArrayBuilder& StoreGlobal(const AstRawString* name,
      90             :                                     int feedback_slot);
      91             : 
      92             :   // Load the object at |slot_index| at |depth| in the context chain starting
      93             :   // with |context| into the accumulator.
      94             :   enum ContextSlotMutability { kImmutableSlot, kMutableSlot };
      95             :   BytecodeArrayBuilder& LoadContextSlot(Register context, int slot_index,
      96             :                                         int depth,
      97             :                                         ContextSlotMutability immutable);
      98             : 
      99             :   // Stores the object in the accumulator into |slot_index| at |depth| in the
     100             :   // context chain starting with |context|.
     101             :   BytecodeArrayBuilder& StoreContextSlot(Register context, int slot_index,
     102             :                                          int depth);
     103             : 
     104             :   // Load from a module variable into the accumulator. |depth| is the depth of
     105             :   // the current context relative to the module context.
     106             :   BytecodeArrayBuilder& LoadModuleVariable(int cell_index, int depth);
     107             : 
     108             :   // Store from the accumulator into a module variable. |depth| is the depth of
     109             :   // the current context relative to the module context.
     110             :   BytecodeArrayBuilder& StoreModuleVariable(int cell_index, int depth);
     111             : 
     112             :   // Register-accumulator transfers.
     113             :   BytecodeArrayBuilder& LoadAccumulatorWithRegister(Register reg);
     114             :   BytecodeArrayBuilder& StoreAccumulatorInRegister(Register reg);
     115             : 
     116             :   // Register-register transfer.
     117             :   BytecodeArrayBuilder& MoveRegister(Register from, Register to);
     118             : 
     119             :   // Named load property.
     120             :   BytecodeArrayBuilder& LoadNamedProperty(Register object,
     121             :                                           const AstRawString* name,
     122             :                                           int feedback_slot);
     123             :   // Named load property without feedback
     124             :   BytecodeArrayBuilder& LoadNamedPropertyNoFeedback(Register object,
     125             :                                                     const AstRawString* name);
     126             : 
     127             :   // Keyed load property. The key should be in the accumulator.
     128             :   BytecodeArrayBuilder& LoadKeyedProperty(Register object, int feedback_slot);
     129             :   // Named load property of the @@iterator symbol.
     130             :   BytecodeArrayBuilder& LoadIteratorProperty(Register object,
     131             :                                              int feedback_slot);
     132             :   // Named load property of the @@asyncIterator symbol.
     133             :   BytecodeArrayBuilder& LoadAsyncIteratorProperty(Register object,
     134             :                                                   int feedback_slot);
     135             : 
     136             :   // Store properties. Flag for NeedsSetFunctionName() should
     137             :   // be in the accumulator.
     138             :   BytecodeArrayBuilder& StoreDataPropertyInLiteral(
     139             :       Register object, Register name, DataPropertyInLiteralFlags flags,
     140             :       int feedback_slot);
     141             : 
     142             :   // Collect type information for developer tools. The value for which we
     143             :   // record the type is stored in the accumulator.
     144             :   BytecodeArrayBuilder& CollectTypeProfile(int position);
     145             : 
     146             :   // Store a property named by a property name. The value to be stored should be
     147             :   // in the accumulator.
     148             :   BytecodeArrayBuilder& StoreNamedProperty(Register object,
     149             :                                            const AstRawString* name,
     150             :                                            int feedback_slot,
     151             :                                            LanguageMode language_mode);
     152             : 
     153             :   // Store a property named by a property name without feedback slot. The value
     154             :   // to be stored should be in the accumulator.
     155             :   BytecodeArrayBuilder& StoreNamedPropertyNoFeedback(
     156             :       Register object, const AstRawString* name, LanguageMode language_mode);
     157             : 
     158             :   // Store a property named by a constant from the constant pool. The value to
     159             :   // be stored should be in the accumulator.
     160             :   BytecodeArrayBuilder& StoreNamedProperty(Register object,
     161             :                                            size_t constant_pool_entry,
     162             :                                            int feedback_slot,
     163             :                                            LanguageMode language_mode);
     164             :   // Store an own property named by a constant from the constant pool. The
     165             :   // value to be stored should be in the accumulator.
     166             :   BytecodeArrayBuilder& StoreNamedOwnProperty(Register object,
     167             :                                               const AstRawString* name,
     168             :                                               int feedback_slot);
     169             :   // Store a property keyed by a value in a register. The value to be stored
     170             :   // should be in the accumulator.
     171             :   BytecodeArrayBuilder& StoreKeyedProperty(Register object, Register key,
     172             :                                            int feedback_slot,
     173             :                                            LanguageMode language_mode);
     174             :   // Store an own element in an array literal. The value to be stored should be
     175             :   // in the accumulator.
     176             :   BytecodeArrayBuilder& StoreInArrayLiteral(Register array, Register index,
     177             :                                             int feedback_slot);
     178             :   // Store the home object property. The value to be stored should be in the
     179             :   // accumulator.
     180             :   BytecodeArrayBuilder& StoreHomeObjectProperty(Register object,
     181             :                                                 int feedback_slot,
     182             :                                                 LanguageMode language_mode);
     183             : 
     184             :   // Store the class fields property. The initializer to be stored should
     185             :   // be in the accumulator.
     186             :   BytecodeArrayBuilder& StoreClassFieldsInitializer(Register constructor,
     187             :                                                     int feedback_slot);
     188             : 
     189             :   // Load class fields property.
     190             :   BytecodeArrayBuilder& LoadClassFieldsInitializer(Register constructor,
     191             :                                                    int feedback_slot);
     192             : 
     193             :   // Lookup the variable with |name|.
     194             :   BytecodeArrayBuilder& LoadLookupSlot(const AstRawString* name,
     195             :                                        TypeofMode typeof_mode);
     196             : 
     197             :   // Lookup the variable with |name|, which is known to be at |slot_index| at
     198             :   // |depth| in the context chain if not shadowed by a context extension
     199             :   // somewhere in that context chain.
     200             :   BytecodeArrayBuilder& LoadLookupContextSlot(const AstRawString* name,
     201             :                                               TypeofMode typeof_mode,
     202             :                                               int slot_index, int depth);
     203             : 
     204             :   // Lookup the variable with |name|, which has its feedback in |feedback_slot|
     205             :   // and is known to be global if not shadowed by a context extension somewhere
     206             :   // up to |depth| in that context chain.
     207             :   BytecodeArrayBuilder& LoadLookupGlobalSlot(const AstRawString* name,
     208             :                                              TypeofMode typeof_mode,
     209             :                                              int feedback_slot, int depth);
     210             : 
     211             :   // Store value in the accumulator into the variable with |name|.
     212             :   BytecodeArrayBuilder& StoreLookupSlot(
     213             :       const AstRawString* name, LanguageMode language_mode,
     214             :       LookupHoistingMode lookup_hoisting_mode);
     215             : 
     216             :   // Create a new closure for a SharedFunctionInfo which will be inserted at
     217             :   // constant pool index |shared_function_info_entry|.
     218             :   BytecodeArrayBuilder& CreateClosure(size_t shared_function_info_entry,
     219             :                                       int slot, int flags);
     220             : 
     221             :   // Create a new local context for a |scope|.
     222             :   BytecodeArrayBuilder& CreateBlockContext(const Scope* scope);
     223             : 
     224             :   // Create a new context for a catch block with |exception| and |scope|.
     225             :   BytecodeArrayBuilder& CreateCatchContext(Register exception,
     226             :                                            const Scope* scope);
     227             : 
     228             :   // Create a new context with the given |scope| and size |slots|.
     229             :   BytecodeArrayBuilder& CreateFunctionContext(const Scope* scope, int slots);
     230             : 
     231             :   // Create a new eval context with the given |scope| and size |slots|.
     232             :   BytecodeArrayBuilder& CreateEvalContext(const Scope* scope, int slots);
     233             : 
     234             :   // Creates a new context with the given |scope| for a with-statement
     235             :   // with the |object| in a register.
     236             :   BytecodeArrayBuilder& CreateWithContext(Register object, const Scope* scope);
     237             : 
     238             :   // Create a new arguments object in the accumulator.
     239             :   BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type);
     240             : 
     241             :   // Literals creation.  Constant elements should be in the accumulator.
     242             :   BytecodeArrayBuilder& CreateRegExpLiteral(const AstRawString* pattern,
     243             :                                             int literal_index, int flags);
     244             :   BytecodeArrayBuilder& CreateArrayLiteral(size_t constant_elements_entry,
     245             :                                            int literal_index, int flags);
     246             :   BytecodeArrayBuilder& CreateEmptyArrayLiteral(int literal_index);
     247             :   BytecodeArrayBuilder& CreateArrayFromIterable();
     248             :   BytecodeArrayBuilder& CreateObjectLiteral(size_t constant_properties_entry,
     249             :                                             int literal_index, int flags);
     250             :   BytecodeArrayBuilder& CreateEmptyObjectLiteral();
     251             :   BytecodeArrayBuilder& CloneObject(Register source, int flags,
     252             :                                     int feedback_slot);
     253             : 
     254             :   // Gets or creates the template for a TemplateObjectDescription which will
     255             :   // be inserted at constant pool index |template_object_description_entry|.
     256             :   BytecodeArrayBuilder& GetTemplateObject(
     257             :       size_t template_object_description_entry, int feedback_slot);
     258             : 
     259             :   // Push the context in accumulator as the new context, and store in register
     260             :   // |context|.
     261             :   BytecodeArrayBuilder& PushContext(Register context);
     262             : 
     263             :   // Pop the current context and replace with |context|.
     264             :   BytecodeArrayBuilder& PopContext(Register context);
     265             : 
     266             :   // Call a JS function which is known to be a property of a JS object. The
     267             :   // JSFunction or Callable to be called should be in |callable|. The arguments
     268             :   // should be in |args|, with the receiver in |args[0]|. The call type of the
     269             :   // expression is in |call_type|. Type feedback is recorded in the
     270             :   // |feedback_slot| in the type feedback vector.
     271             :   BytecodeArrayBuilder& CallProperty(Register callable, RegisterList args,
     272             :                                      int feedback_slot);
     273             : 
     274             :   // Call a JS function with an known undefined receiver. The JSFunction or
     275             :   // Callable to be called should be in |callable|. The arguments should be in
     276             :   // |args|, with no receiver as it is implicitly set to undefined. Type
     277             :   // feedback is recorded in the |feedback_slot| in the type feedback vector.
     278             :   BytecodeArrayBuilder& CallUndefinedReceiver(Register callable,
     279             :                                               RegisterList args,
     280             :                                               int feedback_slot);
     281             : 
     282             :   // Call a JS function with an any receiver, possibly (but not necessarily)
     283             :   // undefined. The JSFunction or Callable to be called should be in |callable|.
     284             :   // The arguments should be in |args|, with the receiver in |args[0]|. Type
     285             :   // feedback is recorded in the |feedback_slot| in the type feedback vector.
     286             :   BytecodeArrayBuilder& CallAnyReceiver(Register callable, RegisterList args,
     287             :                                         int feedback_slot);
     288             : 
     289             :   // Call a JS function with an any receiver, possibly (but not necessarily)
     290             :   // undefined. The JSFunction or Callable to be called should be in |callable|.
     291             :   // The arguments should be in |args|, with the receiver in |args[0]|.
     292             :   BytecodeArrayBuilder& CallNoFeedback(Register callable, RegisterList args);
     293             : 
     294             :   // Tail call into a JS function. The JSFunction or Callable to be called
     295             :   // should be in |callable|. The arguments should be in |args|, with the
     296             :   // receiver in |args[0]|. Type feedback is recorded in the |feedback_slot| in
     297             :   // the type feedback vector.
     298             :   BytecodeArrayBuilder& TailCall(Register callable, RegisterList args,
     299             :                                  int feedback_slot);
     300             : 
     301             :   // Call a JS function. The JSFunction or Callable to be called should be in
     302             :   // |callable|, the receiver in |args[0]| and the arguments in |args[1]|
     303             :   // onwards. The final argument must be a spread.
     304             :   BytecodeArrayBuilder& CallWithSpread(Register callable, RegisterList args,
     305             :                                        int feedback_slot);
     306             : 
     307             :   // Call the Construct operator. The accumulator holds the |new_target|.
     308             :   // The |constructor| is in a register and arguments are in |args|.
     309             :   BytecodeArrayBuilder& Construct(Register constructor, RegisterList args,
     310             :                                   int feedback_slot);
     311             : 
     312             :   // Call the Construct operator for use with a spread. The accumulator holds
     313             :   // the |new_target|. The |constructor| is in a register and arguments are in
     314             :   // |args|. The final argument must be a spread.
     315             :   BytecodeArrayBuilder& ConstructWithSpread(Register constructor,
     316             :                                             RegisterList args,
     317             :                                             int feedback_slot);
     318             : 
     319             :   // Call the runtime function with |function_id| and arguments |args|.
     320             :   BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id,
     321             :                                     RegisterList args);
     322             :   // Call the runtime function with |function_id| with single argument |arg|.
     323             :   BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id,
     324             :                                     Register arg);
     325             :   // Call the runtime function with |function_id| with no arguments.
     326             :   BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id);
     327             : 
     328             :   // Call the runtime function with |function_id| and arguments |args|, that
     329             :   // returns a pair of values. The return values will be returned in
     330             :   // |return_pair|.
     331             :   BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id,
     332             :                                            RegisterList args,
     333             :                                            RegisterList return_pair);
     334             :   // Call the runtime function with |function_id| with single argument |arg|
     335             :   // that returns a pair of values. The return values will be returned in
     336             :   // |return_pair|.
     337             :   BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id,
     338             :                                            Register arg,
     339             :                                            RegisterList return_pair);
     340             : 
     341             :   // Call the JS runtime function with |context_index| and arguments |args|,
     342             :   // with no receiver as it is implicitly set to undefined.
     343             :   BytecodeArrayBuilder& CallJSRuntime(int context_index, RegisterList args);
     344             : 
     345             :   // Operators (register holds the lhs value, accumulator holds the rhs value).
     346             :   // Type feedback will be recorded in the |feedback_slot|
     347             :   BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg,
     348             :                                         int feedback_slot);
     349             :   // Same as above, but lhs in the accumulator and rhs in |literal|.
     350             :   BytecodeArrayBuilder& BinaryOperationSmiLiteral(Token::Value binop,
     351             :                                                   Smi literal,
     352             :                                                   int feedback_slot);
     353             : 
     354             :   // Unary and Count Operators (value stored in accumulator).
     355             :   // Type feedback will be recorded in the |feedback_slot|
     356             :   BytecodeArrayBuilder& UnaryOperation(Token::Value op, int feedback_slot);
     357             : 
     358             :   enum class ToBooleanMode {
     359             :     kConvertToBoolean,  // Perform ToBoolean conversion on accumulator.
     360             :     kAlreadyBoolean,    // Accumulator is already a Boolean.
     361             :   };
     362             : 
     363             :   // Unary Operators.
     364             :   BytecodeArrayBuilder& LogicalNot(ToBooleanMode mode);
     365             :   BytecodeArrayBuilder& TypeOf();
     366             : 
     367             :   // Expects a heap object in the accumulator. Returns its super constructor in
     368             :   // the register |out| if it passes the IsConstructor test. Otherwise, it
     369             :   // throws a TypeError exception.
     370             :   BytecodeArrayBuilder& GetSuperConstructor(Register out);
     371             : 
     372             :   // Deletes property from an object. This expects that accumulator contains
     373             :   // the key to be deleted and the register contains a reference to the object.
     374             :   BytecodeArrayBuilder& Delete(Register object, LanguageMode language_mode);
     375             : 
     376             :   // JavaScript defines two kinds of 'nil'.
     377             :   enum NilValue { kNullValue, kUndefinedValue };
     378             : 
     379             :   // Tests.
     380             :   BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg,
     381             :                                          int feedback_slot);
     382             :   BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg);
     383             :   BytecodeArrayBuilder& CompareReference(Register reg);
     384             :   BytecodeArrayBuilder& CompareUndetectable();
     385             :   BytecodeArrayBuilder& CompareUndefined();
     386             :   BytecodeArrayBuilder& CompareNull();
     387             :   BytecodeArrayBuilder& CompareNil(Token::Value op, NilValue nil);
     388             :   BytecodeArrayBuilder& CompareTypeOf(
     389             :       TestTypeOfFlags::LiteralFlag literal_flag);
     390             : 
     391             :   // Converts accumulator and stores result in register |out|.
     392             :   BytecodeArrayBuilder& ToObject(Register out);
     393             :   BytecodeArrayBuilder& ToName(Register out);
     394             :   BytecodeArrayBuilder& ToString();
     395             : 
     396             :   // Converts accumulator and stores result back in accumulator.
     397             :   BytecodeArrayBuilder& ToNumber(int feedback_slot);
     398             :   BytecodeArrayBuilder& ToNumeric(int feedback_slot);
     399             : 
     400             :   // Flow Control.
     401             :   BytecodeArrayBuilder& Bind(BytecodeLabel* label);
     402             :   BytecodeArrayBuilder& Bind(const BytecodeLabel& target, BytecodeLabel* label);
     403             :   BytecodeArrayBuilder& Bind(BytecodeJumpTable* jump_table, int case_value);
     404             : 
     405             :   BytecodeArrayBuilder& Jump(BytecodeLabel* label);
     406             :   BytecodeArrayBuilder& JumpLoop(BytecodeLabel* label, int loop_depth);
     407             : 
     408             :   BytecodeArrayBuilder& JumpIfTrue(ToBooleanMode mode, BytecodeLabel* label);
     409             :   BytecodeArrayBuilder& JumpIfFalse(ToBooleanMode mode, BytecodeLabel* label);
     410             :   BytecodeArrayBuilder& JumpIfJSReceiver(BytecodeLabel* label);
     411             :   BytecodeArrayBuilder& JumpIfNull(BytecodeLabel* label);
     412             :   BytecodeArrayBuilder& JumpIfNotNull(BytecodeLabel* label);
     413             :   BytecodeArrayBuilder& JumpIfUndefined(BytecodeLabel* label);
     414             :   BytecodeArrayBuilder& JumpIfNotUndefined(BytecodeLabel* label);
     415             :   BytecodeArrayBuilder& JumpIfNil(BytecodeLabel* label, Token::Value op,
     416             :                                   NilValue nil);
     417             :   BytecodeArrayBuilder& JumpIfNotNil(BytecodeLabel* label, Token::Value op,
     418             :                                      NilValue nil);
     419             : 
     420             :   BytecodeArrayBuilder& SwitchOnSmiNoFeedback(BytecodeJumpTable* jump_table);
     421             : 
     422             :   BytecodeArrayBuilder& StackCheck(int position);
     423             : 
     424             :   // Sets the pending message to the value in the accumulator, and returns the
     425             :   // previous pending message in the accumulator.
     426             :   BytecodeArrayBuilder& SetPendingMessage();
     427             : 
     428             :   BytecodeArrayBuilder& Throw();
     429             :   BytecodeArrayBuilder& ReThrow();
     430             :   BytecodeArrayBuilder& Abort(AbortReason reason);
     431             :   BytecodeArrayBuilder& Return();
     432             :   BytecodeArrayBuilder& ThrowReferenceErrorIfHole(const AstRawString* name);
     433             :   BytecodeArrayBuilder& ThrowSuperNotCalledIfHole();
     434             :   BytecodeArrayBuilder& ThrowSuperAlreadyCalledIfNotHole();
     435             : 
     436             :   // Debugger.
     437             :   BytecodeArrayBuilder& Debugger();
     438             : 
     439             :   // Increment the block counter at the given slot (block code coverage).
     440             :   BytecodeArrayBuilder& IncBlockCounter(int slot);
     441             : 
     442             :   // Complex flow control.
     443             :   BytecodeArrayBuilder& ForInEnumerate(Register receiver);
     444             :   BytecodeArrayBuilder& ForInPrepare(RegisterList cache_info_triple,
     445             :                                      int feedback_slot);
     446             :   BytecodeArrayBuilder& ForInContinue(Register index, Register cache_length);
     447             :   BytecodeArrayBuilder& ForInNext(Register receiver, Register index,
     448             :                                   RegisterList cache_type_array_pair,
     449             :                                   int feedback_slot);
     450             :   BytecodeArrayBuilder& ForInStep(Register index);
     451             : 
     452             :   // Generators.
     453             :   BytecodeArrayBuilder& SuspendGenerator(Register generator,
     454             :                                          RegisterList registers,
     455             :                                          int suspend_id);
     456             :   BytecodeArrayBuilder& SwitchOnGeneratorState(Register generator,
     457             :                                                BytecodeJumpTable* jump_table);
     458             :   BytecodeArrayBuilder& ResumeGenerator(Register generator,
     459             :                                         RegisterList registers);
     460             : 
     461             :   // Exception handling.
     462             :   BytecodeArrayBuilder& MarkHandler(int handler_id,
     463             :                                     HandlerTable::CatchPrediction will_catch);
     464             :   BytecodeArrayBuilder& MarkTryBegin(int handler_id, Register context);
     465             :   BytecodeArrayBuilder& MarkTryEnd(int handler_id);
     466             : 
     467             :   // Creates a new handler table entry and returns a {hander_id} identifying the
     468             :   // entry, so that it can be referenced by above exception handling support.
     469      148674 :   int NewHandlerEntry() { return handler_table_builder()->NewHandlerEntry(); }
     470             : 
     471             :   // Allocates a new jump table of given |size| and |case_value_base| in the
     472             :   // constant pool.
     473             :   BytecodeJumpTable* AllocateJumpTable(int size, int case_value_base);
     474             : 
     475             :   // Gets a constant pool entry.
     476             :   size_t GetConstantPoolEntry(const AstRawString* raw_string);
     477             :   size_t GetConstantPoolEntry(AstBigInt bigint);
     478             :   size_t GetConstantPoolEntry(const Scope* scope);
     479             :   size_t GetConstantPoolEntry(double number);
     480             : #define ENTRY_GETTER(NAME, ...) size_t NAME##ConstantPoolEntry();
     481             :   SINGLETON_CONSTANT_ENTRY_TYPES(ENTRY_GETTER)
     482             : #undef ENTRY_GETTER
     483             : 
     484             :   // Allocates a slot in the constant pool which can later be set.
     485             :   size_t AllocateDeferredConstantPoolEntry();
     486             :   // Sets the deferred value into an allocated constant pool entry.
     487             :   void SetDeferredConstantPoolEntry(size_t entry, Handle<Object> object);
     488             : 
     489             :   void InitializeReturnPosition(FunctionLiteral* literal);
     490             : 
     491             :   void SetStatementPosition(Statement* stmt) {
     492    12863818 :     if (stmt->position() == kNoSourcePosition) return;
     493             :     latest_source_info_.MakeStatementPosition(stmt->position());
     494             :   }
     495             : 
     496             :   void SetExpressionPosition(Expression* expr) {
     497    23679283 :     SetExpressionPosition(expr->position());
     498             :   }
     499             : 
     500             :   void SetExpressionPosition(int position) {
     501    24033217 :     if (position == kNoSourcePosition) return;
     502    21855570 :     if (!latest_source_info_.is_statement()) {
     503             :       // Ensure the current expression position is overwritten with the
     504             :       // latest value.
     505             :       latest_source_info_.MakeExpressionPosition(position);
     506             :     }
     507             :   }
     508             : 
     509             :   void SetExpressionAsStatementPosition(Expression* expr) {
     510      310872 :     if (expr->position() == kNoSourcePosition) return;
     511             :     latest_source_info_.MakeStatementPosition(expr->position());
     512             :   }
     513             : 
     514     2439467 :   void SetReturnPosition(int source_position, FunctionLiteral* literal) {
     515     2439467 :     if (source_position != kNoSourcePosition) {
     516             :       latest_source_info_.MakeStatementPosition(source_position);
     517     1520262 :     } else if (literal->return_position() != kNoSourcePosition) {
     518     1520363 :       latest_source_info_.MakeStatementPosition(literal->return_position());
     519             :     }
     520     2439621 :   }
     521             : 
     522             :   bool RequiresImplicitReturn() const { return !return_seen_in_block_; }
     523             :   bool RemainderOfBlockIsDead() const {
     524    16886416 :     return bytecode_array_writer_.RemainderOfBlockIsDead();
     525             :   }
     526             : 
     527             :   // Returns the raw operand value for the given register or register list.
     528             :   uint32_t GetInputRegisterOperand(Register reg);
     529             :   uint32_t GetOutputRegisterOperand(Register reg);
     530             :   uint32_t GetInputRegisterListOperand(RegisterList reg_list);
     531             :   uint32_t GetOutputRegisterListOperand(RegisterList reg_list);
     532             : 
     533             :   // Outputs raw register transfer bytecodes without going through the register
     534             :   // optimizer.
     535             :   void OutputLdarRaw(Register reg);
     536             :   void OutputStarRaw(Register reg);
     537             :   void OutputMovRaw(Register src, Register dest);
     538             : 
     539             :   // Accessors
     540             :   BytecodeRegisterAllocator* register_allocator() {
     541             :     return &register_allocator_;
     542             :   }
     543             :   const BytecodeRegisterAllocator* register_allocator() const {
     544             :     return &register_allocator_;
     545             :   }
     546             :   Zone* zone() const { return zone_; }
     547             : 
     548             :  private:
     549             :   friend class BytecodeRegisterAllocator;
     550             :   template <Bytecode bytecode, AccumulatorUse accumulator_use,
     551             :             OperandType... operand_types>
     552             :   friend class BytecodeNodeBuilder;
     553             : 
     554             :   const FeedbackVectorSpec* feedback_vector_spec() const {
     555             :     return feedback_vector_spec_;
     556             :   }
     557             : 
     558             :   // Returns the current source position for the given |bytecode|.
     559             :   V8_INLINE BytecodeSourceInfo CurrentSourcePosition(Bytecode bytecode);
     560             : 
     561             : #define DECLARE_BYTECODE_OUTPUT(Name, ...)                         \
     562             :   template <typename... Operands>                                  \
     563             :   V8_INLINE BytecodeNode Create##Name##Node(Operands... operands); \
     564             :   template <typename... Operands>                                  \
     565             :   V8_INLINE void Output##Name(Operands... operands);               \
     566             :   template <typename... Operands>                                  \
     567             :   V8_INLINE void Output##Name(BytecodeLabel* label, Operands... operands);
     568             :   BYTECODE_LIST(DECLARE_BYTECODE_OUTPUT)
     569             : #undef DECLARE_OPERAND_TYPE_INFO
     570             : 
     571             :   V8_INLINE void OutputSwitchOnSmiNoFeedback(BytecodeJumpTable* jump_table);
     572             : 
     573             :   bool RegisterIsValid(Register reg) const;
     574             :   bool RegisterListIsValid(RegisterList reg_list) const;
     575             : 
     576             :   // Sets a deferred source info which should be emitted before any future
     577             :   // source info (either attached to a following bytecode or as a nop).
     578             :   void SetDeferredSourceInfo(BytecodeSourceInfo source_info);
     579             :   // Either attach deferred source info to node, or emit it as a nop bytecode
     580             :   // if node already have valid source info.
     581             :   void AttachOrEmitDeferredSourceInfo(BytecodeNode* node);
     582             : 
     583             :   // Write bytecode to bytecode array.
     584             :   void Write(BytecodeNode* node);
     585             :   void WriteJump(BytecodeNode* node, BytecodeLabel* label);
     586             :   void WriteSwitch(BytecodeNode* node, BytecodeJumpTable* label);
     587             : 
     588             :   // Not implemented as the illegal bytecode is used inside internally
     589             :   // to indicate a bytecode field is not valid or an error has occurred
     590             :   // during bytecode generation.
     591             :   BytecodeArrayBuilder& Illegal();
     592             : 
     593             :   template <Bytecode bytecode, AccumulatorUse accumulator_use>
     594             :   void PrepareToOutputBytecode();
     595             : 
     596     4802875 :   void LeaveBasicBlock() { return_seen_in_block_ = false; }
     597             : 
     598             :   BytecodeArrayWriter* bytecode_array_writer() {
     599             :     return &bytecode_array_writer_;
     600             :   }
     601             :   ConstantArrayBuilder* constant_array_builder() {
     602             :     return &constant_array_builder_;
     603             :   }
     604             :   const ConstantArrayBuilder* constant_array_builder() const {
     605             :     return &constant_array_builder_;
     606             :   }
     607             :   HandlerTableBuilder* handler_table_builder() {
     608             :     return &handler_table_builder_;
     609             :   }
     610             : 
     611             :   Zone* zone_;
     612             :   FeedbackVectorSpec* feedback_vector_spec_;
     613             :   bool bytecode_generated_;
     614             :   ConstantArrayBuilder constant_array_builder_;
     615             :   HandlerTableBuilder handler_table_builder_;
     616             :   bool return_seen_in_block_;
     617             :   int parameter_count_;
     618             :   int local_register_count_;
     619             :   BytecodeRegisterAllocator register_allocator_;
     620             :   BytecodeArrayWriter bytecode_array_writer_;
     621             :   BytecodeRegisterOptimizer* register_optimizer_;
     622             :   BytecodeSourceInfo latest_source_info_;
     623             :   BytecodeSourceInfo deferred_source_info_;
     624             : 
     625             :   DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBuilder);
     626             : };
     627             : 
     628             : V8_EXPORT_PRIVATE std::ostream& operator<<(
     629             :     std::ostream& os, const BytecodeArrayBuilder::ToBooleanMode& mode);
     630             : 
     631             : }  // namespace interpreter
     632             : }  // namespace internal
     633             : }  // namespace v8
     634             : 
     635             : #endif  // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_

Generated by: LCOV version 1.10