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