11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_CODEGEN_SOURCE_POSITION_TABLE_H_
61cb0ef41Sopenharmony_ci#define V8_CODEGEN_SOURCE_POSITION_TABLE_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/base/export-template.h"
91cb0ef41Sopenharmony_ci#include "src/base/vector.h"
101cb0ef41Sopenharmony_ci#include "src/codegen/source-position.h"
111cb0ef41Sopenharmony_ci#include "src/common/assert-scope.h"
121cb0ef41Sopenharmony_ci#include "src/common/checks.h"
131cb0ef41Sopenharmony_ci#include "src/common/globals.h"
141cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h"
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_cinamespace v8 {
171cb0ef41Sopenharmony_cinamespace internal {
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciclass ByteArray;
201cb0ef41Sopenharmony_citemplate <typename T>
211cb0ef41Sopenharmony_ciclass Handle;
221cb0ef41Sopenharmony_ciclass Isolate;
231cb0ef41Sopenharmony_ciclass Zone;
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_cistruct PositionTableEntry {
261cb0ef41Sopenharmony_ci  PositionTableEntry()
271cb0ef41Sopenharmony_ci      : code_offset(kFunctionEntryBytecodeOffset),
281cb0ef41Sopenharmony_ci        source_position(0),
291cb0ef41Sopenharmony_ci        is_statement(false) {}
301cb0ef41Sopenharmony_ci  PositionTableEntry(int offset, int64_t source, bool statement)
311cb0ef41Sopenharmony_ci      : code_offset(offset), source_position(source), is_statement(statement) {}
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci  int code_offset;
341cb0ef41Sopenharmony_ci  int64_t source_position;
351cb0ef41Sopenharmony_ci  bool is_statement;
361cb0ef41Sopenharmony_ci};
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE SourcePositionTableBuilder {
391cb0ef41Sopenharmony_ci public:
401cb0ef41Sopenharmony_ci  enum RecordingMode {
411cb0ef41Sopenharmony_ci    // Indicates that source positions are never to be generated. (Resulting in
421cb0ef41Sopenharmony_ci    // an empty table).
431cb0ef41Sopenharmony_ci    OMIT_SOURCE_POSITIONS,
441cb0ef41Sopenharmony_ci    // Indicates that source positions are not currently required, but may be
451cb0ef41Sopenharmony_ci    // generated later.
461cb0ef41Sopenharmony_ci    LAZY_SOURCE_POSITIONS,
471cb0ef41Sopenharmony_ci    // Indicates that source positions should be immediately generated.
481cb0ef41Sopenharmony_ci    RECORD_SOURCE_POSITIONS
491cb0ef41Sopenharmony_ci  };
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  explicit SourcePositionTableBuilder(
521cb0ef41Sopenharmony_ci      Zone* zone, RecordingMode mode = RECORD_SOURCE_POSITIONS);
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  void AddPosition(size_t code_offset, SourcePosition source_position,
551cb0ef41Sopenharmony_ci                   bool is_statement);
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  template <typename IsolateT>
581cb0ef41Sopenharmony_ci  EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
591cb0ef41Sopenharmony_ci  Handle<ByteArray> ToSourcePositionTable(IsolateT* isolate);
601cb0ef41Sopenharmony_ci  base::OwnedVector<byte> ToSourcePositionTableVector();
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  inline bool Omit() const { return mode_ != RECORD_SOURCE_POSITIONS; }
631cb0ef41Sopenharmony_ci  inline bool Lazy() const { return mode_ == LAZY_SOURCE_POSITIONS; }
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci private:
661cb0ef41Sopenharmony_ci  void AddEntry(const PositionTableEntry& entry);
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci  RecordingMode mode_;
691cb0ef41Sopenharmony_ci  ZoneVector<byte> bytes_;
701cb0ef41Sopenharmony_ci#ifdef ENABLE_SLOW_DCHECKS
711cb0ef41Sopenharmony_ci  ZoneVector<PositionTableEntry> raw_entries_;
721cb0ef41Sopenharmony_ci#endif
731cb0ef41Sopenharmony_ci  PositionTableEntry previous_;  // Previously written entry, to compute delta.
741cb0ef41Sopenharmony_ci};
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE SourcePositionTableIterator {
771cb0ef41Sopenharmony_ci public:
781cb0ef41Sopenharmony_ci  // Filter that applies when advancing the iterator. If the filter isn't
791cb0ef41Sopenharmony_ci  // satisfied, we advance the iterator again.
801cb0ef41Sopenharmony_ci  enum IterationFilter { kJavaScriptOnly = 0, kExternalOnly = 1, kAll = 2 };
811cb0ef41Sopenharmony_ci  // Filter that applies only to the first entry of the source position table.
821cb0ef41Sopenharmony_ci  // If it is kSkipFunctionEntry, it will skip the FunctionEntry entry if it
831cb0ef41Sopenharmony_ci  // exists.
841cb0ef41Sopenharmony_ci  enum FunctionEntryFilter {
851cb0ef41Sopenharmony_ci    kSkipFunctionEntry = 0,
861cb0ef41Sopenharmony_ci    kDontSkipFunctionEntry = 1
871cb0ef41Sopenharmony_ci  };
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci  // Used for saving/restoring the iterator.
901cb0ef41Sopenharmony_ci  struct IndexAndPositionState {
911cb0ef41Sopenharmony_ci    int index_;
921cb0ef41Sopenharmony_ci    PositionTableEntry position_;
931cb0ef41Sopenharmony_ci    IterationFilter iteration_filter_;
941cb0ef41Sopenharmony_ci    FunctionEntryFilter function_entry_filter_;
951cb0ef41Sopenharmony_ci  };
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci  // We expose three flavours of the iterator, depending on the argument passed
981cb0ef41Sopenharmony_ci  // to the constructor:
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  // Handlified iterator allows allocation, but it needs a handle (and thus
1011cb0ef41Sopenharmony_ci  // a handle scope). This is the preferred version.
1021cb0ef41Sopenharmony_ci  explicit SourcePositionTableIterator(
1031cb0ef41Sopenharmony_ci      Handle<ByteArray> byte_array,
1041cb0ef41Sopenharmony_ci      IterationFilter iteration_filter = kJavaScriptOnly,
1051cb0ef41Sopenharmony_ci      FunctionEntryFilter function_entry_filter = kSkipFunctionEntry);
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  // Non-handlified iterator does not need a handle scope, but it disallows
1081cb0ef41Sopenharmony_ci  // allocation during its lifetime. This is useful if there is no handle
1091cb0ef41Sopenharmony_ci  // scope around.
1101cb0ef41Sopenharmony_ci  explicit SourcePositionTableIterator(
1111cb0ef41Sopenharmony_ci      ByteArray byte_array, IterationFilter iteration_filter = kJavaScriptOnly,
1121cb0ef41Sopenharmony_ci      FunctionEntryFilter function_entry_filter = kSkipFunctionEntry);
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci  // Handle-safe iterator based on an a vector located outside the garbage
1151cb0ef41Sopenharmony_ci  // collected heap, allows allocation during its lifetime.
1161cb0ef41Sopenharmony_ci  explicit SourcePositionTableIterator(
1171cb0ef41Sopenharmony_ci      base::Vector<const byte> bytes,
1181cb0ef41Sopenharmony_ci      IterationFilter iteration_filter = kJavaScriptOnly,
1191cb0ef41Sopenharmony_ci      FunctionEntryFilter function_entry_filter = kSkipFunctionEntry);
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_ci  void Advance();
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci  int code_offset() const {
1241cb0ef41Sopenharmony_ci    DCHECK(!done());
1251cb0ef41Sopenharmony_ci    return current_.code_offset;
1261cb0ef41Sopenharmony_ci  }
1271cb0ef41Sopenharmony_ci  SourcePosition source_position() const {
1281cb0ef41Sopenharmony_ci    DCHECK(!done());
1291cb0ef41Sopenharmony_ci    return SourcePosition::FromRaw(current_.source_position);
1301cb0ef41Sopenharmony_ci  }
1311cb0ef41Sopenharmony_ci  bool is_statement() const {
1321cb0ef41Sopenharmony_ci    DCHECK(!done());
1331cb0ef41Sopenharmony_ci    return current_.is_statement;
1341cb0ef41Sopenharmony_ci  }
1351cb0ef41Sopenharmony_ci  bool done() const { return index_ == kDone; }
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  IndexAndPositionState GetState() const {
1381cb0ef41Sopenharmony_ci    return {index_, current_, iteration_filter_, function_entry_filter_};
1391cb0ef41Sopenharmony_ci  }
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci  void RestoreState(const IndexAndPositionState& saved_state) {
1421cb0ef41Sopenharmony_ci    index_ = saved_state.index_;
1431cb0ef41Sopenharmony_ci    current_ = saved_state.position_;
1441cb0ef41Sopenharmony_ci    iteration_filter_ = saved_state.iteration_filter_;
1451cb0ef41Sopenharmony_ci    function_entry_filter_ = saved_state.function_entry_filter_;
1461cb0ef41Sopenharmony_ci  }
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci private:
1491cb0ef41Sopenharmony_ci  // Initializes the source position interator with the first valid bytecode.
1501cb0ef41Sopenharmony_ci  // Also sets the FunctionEntry SourcePosition if it exists.
1511cb0ef41Sopenharmony_ci  void Initialize();
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci  static const int kDone = -1;
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci  base::Vector<const byte> raw_table_;
1561cb0ef41Sopenharmony_ci  Handle<ByteArray> table_;
1571cb0ef41Sopenharmony_ci  int index_ = 0;
1581cb0ef41Sopenharmony_ci  PositionTableEntry current_;
1591cb0ef41Sopenharmony_ci  IterationFilter iteration_filter_;
1601cb0ef41Sopenharmony_ci  FunctionEntryFilter function_entry_filter_;
1611cb0ef41Sopenharmony_ci  DISALLOW_GARBAGE_COLLECTION(no_gc)
1621cb0ef41Sopenharmony_ci};
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_ci}  // namespace internal
1651cb0ef41Sopenharmony_ci}  // namespace v8
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci#endif  // V8_CODEGEN_SOURCE_POSITION_TABLE_H_
168