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_H_
6 #define V8_INTERPRETER_INTERPRETER_H_
7 
8 #include <memory>
9 
10 // Clients of this interface shouldn't depend on lots of interpreter internals.
11 // Do not include anything from src/interpreter other than
12 // src/interpreter/bytecodes.h here!
13 #include "src/base/macros.h"
14 #include "src/builtins/builtins.h"
15 #include "src/interpreter/bytecodes.h"
16 #include "src/runtime/runtime.h"
17 
18 namespace v8 {
19 namespace internal {
20 
21 class BytecodeArray;
22 class Callable;
23 class UnoptimizedCompilationJob;
24 class FunctionLiteral;
25 class IgnitionStatisticsTester;
26 class Isolate;
27 class LocalIsolate;
28 class ParseInfo;
29 class RootVisitor;
30 class SetupIsolateDelegate;
31 template <typename>
32 class ZoneVector;
33 
34 namespace interpreter {
35 
36 class InterpreterAssembler;
37 
38 class Interpreter {
39  public:
40   explicit Interpreter(Isolate* isolate);
41   virtual ~Interpreter() = default;
42   Interpreter(const Interpreter&) = delete;
43   Interpreter& operator=(const Interpreter&) = delete;
44 
45   // Creates a compilation job which will generate bytecode for |literal|.
46   // Additionally, if |eager_inner_literals| is not null, adds any eagerly
47   // compilable inner FunctionLiterals to this list.
48   static std::unique_ptr<UnoptimizedCompilationJob> NewCompilationJob(
49       ParseInfo* parse_info, FunctionLiteral* literal, Handle<Script> script,
50       AccountingAllocator* allocator,
51       std::vector<FunctionLiteral*>* eager_inner_literals,
52       LocalIsolate* local_isolate);
53 
54   // Creates a compilation job which will generate source positions for
55   // |literal| and when finalized, store the result into |existing_bytecode|.
56   static std::unique_ptr<UnoptimizedCompilationJob>
57   NewSourcePositionCollectionJob(ParseInfo* parse_info,
58                                  FunctionLiteral* literal,
59                                  Handle<BytecodeArray> existing_bytecode,
60                                  AccountingAllocator* allocator,
61                                  LocalIsolate* local_isolate);
62 
63   // If the bytecode handler for |bytecode| and |operand_scale| has not yet
64   // been loaded, deserialize it. Then return the handler.
65   V8_EXPORT_PRIVATE CodeT GetBytecodeHandler(Bytecode bytecode,
66                                              OperandScale operand_scale);
67 
68   // Set the bytecode handler for |bytecode| and |operand_scale|.
69   void SetBytecodeHandler(Bytecode bytecode, OperandScale operand_scale,
70                           CodeT handler);
71 
72   // Disassembler support.
73   V8_EXPORT_PRIVATE const char* LookupNameOfBytecodeHandler(const Code code);
74 
75   V8_EXPORT_PRIVATE Handle<JSObject> GetDispatchCountersObject();
76 
77   void ForEachBytecode(const std::function<void(Bytecode, OperandScale)>& f);
78 
79   void Initialize();
80 
81   bool IsDispatchTableInitialized() const;
82 
dispatch_table_address()83   Address dispatch_table_address() {
84     return reinterpret_cast<Address>(&dispatch_table_[0]);
85   }
86 
bytecode_dispatch_counters_table()87   Address bytecode_dispatch_counters_table() {
88     return reinterpret_cast<Address>(bytecode_dispatch_counters_table_.get());
89   }
90 
address_of_interpreter_entry_trampoline_instruction_start() const91   Address address_of_interpreter_entry_trampoline_instruction_start() const {
92     return reinterpret_cast<Address>(
93         &interpreter_entry_trampoline_instruction_start_);
94   }
95 
96  private:
97   friend class SetupInterpreter;
98   friend class v8::internal::SetupIsolateDelegate;
99   friend class v8::internal::IgnitionStatisticsTester;
100 
101   V8_EXPORT_PRIVATE void InitDispatchCounters();
102   V8_EXPORT_PRIVATE uintptr_t GetDispatchCounter(Bytecode from,
103                                                  Bytecode to) const;
104 
105   // Get dispatch table index of bytecode.
106   static size_t GetDispatchTableIndex(Bytecode bytecode,
107                                       OperandScale operand_scale);
108 
109   static const int kNumberOfWideVariants = BytecodeOperands::kOperandScaleCount;
110   static const int kDispatchTableSize = kNumberOfWideVariants * (kMaxUInt8 + 1);
111   static const int kNumberOfBytecodes = static_cast<int>(Bytecode::kLast) + 1;
112 
113   Isolate* isolate_;
114   Address dispatch_table_[kDispatchTableSize];
115   std::unique_ptr<uintptr_t[]> bytecode_dispatch_counters_table_;
116   Address interpreter_entry_trampoline_instruction_start_;
117 };
118 
119 #ifdef V8_IGNITION_DISPATCH_COUNTING
120 #define V8_IGNITION_DISPATCH_COUNTING_BOOL true
121 #else
122 #define V8_IGNITION_DISPATCH_COUNTING_BOOL false
123 #endif
124 
125 }  // namespace interpreter
126 }  // namespace internal
127 }  // namespace v8
128 
129 #endif  // V8_INTERPRETER_INTERPRETER_H_
130