blob: 0b7c44e2d984a50eb8169af7daba6ce8af096854 [file] [log] [blame]
Ben Murdoch097c5b22016-05-18 11:27:45 +01001// 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#include "src/interpreter/source-position-table.h"
6
7#include "src/assembler.h"
8#include "src/objects-inl.h"
9#include "src/objects.h"
10
11namespace v8 {
12namespace internal {
13namespace interpreter {
14
15class IsStatementField : public BitField<bool, 0, 1> {};
16class SourcePositionField : public BitField<int, 1, 30> {};
17
18void SourcePositionTableBuilder::AddStatementPosition(size_t bytecode_offset,
19 int source_position) {
20 int offset = static_cast<int>(bytecode_offset);
21 // If a position has already been assigned to this bytecode offset,
22 // do not reassign a new statement position.
23 if (CodeOffsetHasPosition(offset)) return;
24 uint32_t encoded = IsStatementField::encode(true) |
25 SourcePositionField::encode(source_position);
26 entries_.push_back({offset, encoded});
27}
28
29void SourcePositionTableBuilder::AddExpressionPosition(size_t bytecode_offset,
30 int source_position) {
31 int offset = static_cast<int>(bytecode_offset);
32 // If a position has already been assigned to this bytecode offset,
33 // do not reassign a new statement position.
34 if (CodeOffsetHasPosition(offset)) return;
35 uint32_t encoded = IsStatementField::encode(false) |
36 SourcePositionField::encode(source_position);
37 entries_.push_back({offset, encoded});
38}
39
40void SourcePositionTableBuilder::RevertPosition(size_t bytecode_offset) {
41 int offset = static_cast<int>(bytecode_offset);
42 // If we already added a source position table entry, but the bytecode array
43 // builder ended up not outputting a bytecode for the corresponding bytecode
44 // offset, we have to remove that entry.
45 if (CodeOffsetHasPosition(offset)) entries_.pop_back();
46}
47
48Handle<FixedArray> SourcePositionTableBuilder::ToFixedArray() {
49 int length = static_cast<int>(entries_.size());
50 Handle<FixedArray> table =
51 isolate_->factory()->NewFixedArray(length * 2, TENURED);
52 for (int i = 0; i < length; i++) {
53 table->set(i * 2, Smi::FromInt(entries_[i].bytecode_offset));
54 table->set(i * 2 + 1, Smi::FromInt(entries_[i].source_position_and_type));
55 }
56 return table;
57}
58
59SourcePositionTableIterator::SourcePositionTableIterator(
60 BytecodeArray* bytecode_array)
61 : table_(bytecode_array->source_position_table()),
62 index_(0),
63 length_(table_->length()) {
64 DCHECK(table_->length() % 2 == 0);
65 Advance();
66}
67
68void SourcePositionTableIterator::Advance() {
69 if (index_ < length_) {
70 int new_bytecode_offset = Smi::cast(table_->get(index_))->value();
71 // Bytecode offsets are in ascending order.
72 DCHECK(bytecode_offset_ < new_bytecode_offset || index_ == 0);
73 bytecode_offset_ = new_bytecode_offset;
74 uint32_t source_position_and_type =
75 static_cast<uint32_t>(Smi::cast(table_->get(index_ + 1))->value());
76 is_statement_ = IsStatementField::decode(source_position_and_type);
77 source_position_ = SourcePositionField::decode(source_position_and_type);
78 }
79 index_ += 2;
80}
81
82} // namespace interpreter
83} // namespace internal
84} // namespace v8