• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 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_CODEGEN_SOURCE_POSITION_TABLE_H_
6 #define V8_CODEGEN_SOURCE_POSITION_TABLE_H_
7 
8 #include "src/base/export-template.h"
9 #include "src/codegen/source-position.h"
10 #include "src/common/assert-scope.h"
11 #include "src/common/checks.h"
12 #include "src/common/globals.h"
13 #include "src/utils/vector.h"
14 #include "src/zone/zone-containers.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 class ByteArray;
20 template <typename T>
21 class Handle;
22 class Isolate;
23 class Zone;
24 
25 struct PositionTableEntry {
PositionTableEntryPositionTableEntry26   PositionTableEntry()
27       : code_offset(kFunctionEntryBytecodeOffset),
28         source_position(0),
29         is_statement(false) {}
PositionTableEntryPositionTableEntry30   PositionTableEntry(int offset, int64_t source, bool statement)
31       : code_offset(offset), source_position(source), is_statement(statement) {}
32 
33   int code_offset;
34   int64_t source_position;
35   bool is_statement;
36 };
37 
38 class V8_EXPORT_PRIVATE SourcePositionTableBuilder {
39  public:
40   enum RecordingMode {
41     // Indicates that source positions are never to be generated. (Resulting in
42     // an empty table).
43     OMIT_SOURCE_POSITIONS,
44     // Indicates that source positions are not currently required, but may be
45     // generated later.
46     LAZY_SOURCE_POSITIONS,
47     // Indicates that source positions should be immediately generated.
48     RECORD_SOURCE_POSITIONS
49   };
50 
51   explicit SourcePositionTableBuilder(
52       Zone* zone, RecordingMode mode = RECORD_SOURCE_POSITIONS);
53 
54   void AddPosition(size_t code_offset, SourcePosition source_position,
55                    bool is_statement);
56 
57   template <typename LocalIsolate>
58   EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
59   Handle<ByteArray> ToSourcePositionTable(LocalIsolate* isolate);
60   OwnedVector<byte> ToSourcePositionTableVector();
61 
Omit()62   inline bool Omit() const { return mode_ != RECORD_SOURCE_POSITIONS; }
Lazy()63   inline bool Lazy() const { return mode_ == LAZY_SOURCE_POSITIONS; }
64 
65  private:
66   void AddEntry(const PositionTableEntry& entry);
67 
68   RecordingMode mode_;
69   ZoneVector<byte> bytes_;
70 #ifdef ENABLE_SLOW_DCHECKS
71   ZoneVector<PositionTableEntry> raw_entries_;
72 #endif
73   PositionTableEntry previous_;  // Previously written entry, to compute delta.
74 };
75 
76 class V8_EXPORT_PRIVATE SourcePositionTableIterator {
77  public:
78   // Filter that applies when advancing the iterator. If the filter isn't
79   // satisfied, we advance the iterator again.
80   enum IterationFilter { kJavaScriptOnly = 0, kExternalOnly = 1, kAll = 2 };
81   // Filter that applies only to the first entry of the source position table.
82   // If it is kSkipFunctionEntry, it will skip the FunctionEntry entry if it
83   // exists.
84   enum FunctionEntryFilter {
85     kSkipFunctionEntry = 0,
86     kDontSkipFunctionEntry = 1
87   };
88 
89   // Used for saving/restoring the iterator.
90   struct IndexAndPositionState {
91     int index_;
92     PositionTableEntry position_;
93     IterationFilter iteration_filter_;
94     FunctionEntryFilter function_entry_filter_;
95   };
96 
97   // We expose three flavours of the iterator, depending on the argument passed
98   // to the constructor:
99 
100   // Handlified iterator allows allocation, but it needs a handle (and thus
101   // a handle scope). This is the preferred version.
102   explicit SourcePositionTableIterator(
103       Handle<ByteArray> byte_array,
104       IterationFilter iteration_filter = kJavaScriptOnly,
105       FunctionEntryFilter function_entry_filter = kSkipFunctionEntry);
106 
107   // Non-handlified iterator does not need a handle scope, but it disallows
108   // allocation during its lifetime. This is useful if there is no handle
109   // scope around.
110   explicit SourcePositionTableIterator(
111       ByteArray byte_array, IterationFilter iteration_filter = kJavaScriptOnly,
112       FunctionEntryFilter function_entry_filter = kSkipFunctionEntry);
113 
114   // Handle-safe iterator based on an a vector located outside the garbage
115   // collected heap, allows allocation during its lifetime.
116   explicit SourcePositionTableIterator(
117       Vector<const byte> bytes,
118       IterationFilter iteration_filter = kJavaScriptOnly,
119       FunctionEntryFilter function_entry_filter = kSkipFunctionEntry);
120 
121   void Advance();
122 
code_offset()123   int code_offset() const {
124     DCHECK(!done());
125     return current_.code_offset;
126   }
source_position()127   SourcePosition source_position() const {
128     DCHECK(!done());
129     return SourcePosition::FromRaw(current_.source_position);
130   }
is_statement()131   bool is_statement() const {
132     DCHECK(!done());
133     return current_.is_statement;
134   }
done()135   bool done() const { return index_ == kDone; }
136 
GetState()137   IndexAndPositionState GetState() const {
138     return {index_, current_, iteration_filter_, function_entry_filter_};
139   }
140 
RestoreState(const IndexAndPositionState & saved_state)141   void RestoreState(const IndexAndPositionState& saved_state) {
142     index_ = saved_state.index_;
143     current_ = saved_state.position_;
144     iteration_filter_ = saved_state.iteration_filter_;
145     function_entry_filter_ = saved_state.function_entry_filter_;
146   }
147 
148  private:
149   // Initializes the source position interator with the first valid bytecode.
150   // Also sets the FunctionEntry SourcePosition if it exists.
151   void Initialize();
152 
153   static const int kDone = -1;
154 
155   Vector<const byte> raw_table_;
156   Handle<ByteArray> table_;
157   int index_ = 0;
158   PositionTableEntry current_;
159   IterationFilter iteration_filter_;
160   FunctionEntryFilter function_entry_filter_;
161   DISALLOW_HEAP_ALLOCATION(no_gc)
162 };
163 
164 }  // namespace internal
165 }  // namespace v8
166 
167 #endif  // V8_CODEGEN_SOURCE_POSITION_TABLE_H_
168