OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/source-position-table.h" | 5 #include "src/source-position-table.h" |
6 | 6 |
7 #include "src/log.h" | 7 #include "src/log.h" |
8 #include "src/objects-inl.h" | 8 #include "src/objects-inl.h" |
9 #include "src/objects.h" | 9 #include "src/objects.h" |
10 | 10 |
(...skipping 29 matching lines...) Expand all Loading... |
40 } | 40 } |
41 | 41 |
42 // Helper: Substract the offsets from 'other' from 'value'. | 42 // Helper: Substract the offsets from 'other' from 'value'. |
43 void SubtractFromEntry(PositionTableEntry& value, | 43 void SubtractFromEntry(PositionTableEntry& value, |
44 const PositionTableEntry& other) { | 44 const PositionTableEntry& other) { |
45 value.code_offset -= other.code_offset; | 45 value.code_offset -= other.code_offset; |
46 value.source_position -= other.source_position; | 46 value.source_position -= other.source_position; |
47 } | 47 } |
48 | 48 |
49 // Helper: Encode an integer. | 49 // Helper: Encode an integer. |
50 void EncodeInt(ZoneVector<byte>& bytes, int value) { | 50 template <typename T> |
| 51 void EncodeInt(ZoneVector<byte>& bytes, T value) { |
51 // Zig-zag encoding. | 52 // Zig-zag encoding. |
52 static const int kShift = kIntSize * kBitsPerByte - 1; | 53 static const int kShift = sizeof(T) * kBitsPerByte - 1; |
53 value = ((value << 1) ^ (value >> kShift)); | 54 value = ((value << 1) ^ (value >> kShift)); |
54 DCHECK_GE(value, 0); | 55 DCHECK_GE(value, 0); |
55 unsigned int encoded = static_cast<unsigned int>(value); | 56 typename std::make_unsigned<T>::type encoded{value}; |
56 bool more; | 57 bool more; |
57 do { | 58 do { |
58 more = encoded > ValueBits::kMax; | 59 more = encoded > ValueBits::kMax; |
59 bytes.push_back(MoreBit::encode(more) | | 60 byte current = |
60 ValueBits::encode(encoded & ValueBits::kMask)); | 61 MoreBit::encode(more) | ValueBits::encode(encoded & ValueBits::kMask); |
| 62 bytes.push_back(current); |
61 encoded >>= ValueBits::kSize; | 63 encoded >>= ValueBits::kSize; |
62 } while (more); | 64 } while (more); |
63 } | 65 } |
64 | 66 |
65 // Encode a PositionTableEntry. | 67 // Encode a PositionTableEntry. |
66 void EncodeEntry(ZoneVector<byte>& bytes, const PositionTableEntry& entry) { | 68 void EncodeEntry(ZoneVector<byte>& bytes, const PositionTableEntry& entry) { |
67 // We only accept ascending code offsets. | 69 // We only accept ascending code offsets. |
68 DCHECK(entry.code_offset >= 0); | 70 DCHECK(entry.code_offset >= 0); |
69 // Since code_offset is not negative, we use sign to encode is_statement. | 71 // Since code_offset is not negative, we use sign to encode is_statement. |
70 EncodeInt(bytes, | 72 EncodeInt(bytes, |
71 entry.is_statement ? entry.code_offset : -entry.code_offset - 1); | 73 entry.is_statement ? entry.code_offset : -entry.code_offset - 1); |
72 EncodeInt(bytes, entry.source_position); | 74 EncodeInt(bytes, entry.source_position); |
73 } | 75 } |
74 | 76 |
75 // Helper: Decode an integer. | 77 // Helper: Decode an integer. |
76 void DecodeInt(ByteArray* bytes, int* index, int* v) { | 78 template <typename T> |
| 79 T DecodeInt(ByteArray* bytes, int* index) { |
77 byte current; | 80 byte current; |
78 int shift = 0; | 81 int shift = 0; |
79 int decoded = 0; | 82 T decoded = 0; |
80 bool more; | 83 bool more; |
81 do { | 84 do { |
82 current = bytes->get((*index)++); | 85 current = bytes->get((*index)++); |
83 decoded |= ValueBits::decode(current) << shift; | 86 decoded |= static_cast<typename std::make_unsigned<T>::type>( |
| 87 ValueBits::decode(current)) |
| 88 << shift; |
84 more = MoreBit::decode(current); | 89 more = MoreBit::decode(current); |
85 shift += ValueBits::kSize; | 90 shift += ValueBits::kSize; |
86 } while (more); | 91 } while (more); |
87 DCHECK_GE(decoded, 0); | 92 DCHECK_GE(decoded, 0); |
88 decoded = (decoded >> 1) ^ (-(decoded & 1)); | 93 decoded = (decoded >> 1) ^ (-(decoded & 1)); |
89 *v = decoded; | 94 return decoded; |
90 } | 95 } |
91 | 96 |
92 void DecodeEntry(ByteArray* bytes, int* index, PositionTableEntry* entry) { | 97 void DecodeEntry(ByteArray* bytes, int* index, PositionTableEntry* entry) { |
93 int tmp; | 98 int tmp = DecodeInt<int>(bytes, index); |
94 DecodeInt(bytes, index, &tmp); | |
95 if (tmp >= 0) { | 99 if (tmp >= 0) { |
96 entry->is_statement = true; | 100 entry->is_statement = true; |
97 entry->code_offset = tmp; | 101 entry->code_offset = tmp; |
98 } else { | 102 } else { |
99 entry->is_statement = false; | 103 entry->is_statement = false; |
100 entry->code_offset = -(tmp + 1); | 104 entry->code_offset = -(tmp + 1); |
101 } | 105 } |
102 DecodeInt(bytes, index, &entry->source_position); | 106 entry->source_position = DecodeInt<int64_t>(bytes, index); |
103 } | 107 } |
104 | 108 |
105 } // namespace | 109 } // namespace |
106 | 110 |
107 SourcePositionTableBuilder::SourcePositionTableBuilder( | 111 SourcePositionTableBuilder::SourcePositionTableBuilder( |
108 Zone* zone, SourcePositionTableBuilder::RecordingMode mode) | 112 Zone* zone, SourcePositionTableBuilder::RecordingMode mode) |
109 : mode_(mode), | 113 : mode_(mode), |
110 bytes_(zone), | 114 bytes_(zone), |
111 #ifdef ENABLE_SLOW_DCHECKS | 115 #ifdef ENABLE_SLOW_DCHECKS |
112 raw_entries_(zone), | 116 raw_entries_(zone), |
113 #endif | 117 #endif |
114 previous_() { | 118 previous_() { |
115 } | 119 } |
116 | 120 |
117 void SourcePositionTableBuilder::AddPosition(size_t code_offset, | 121 void SourcePositionTableBuilder::AddPosition(size_t code_offset, |
118 int source_position, | 122 SourcePosition source_position, |
119 bool is_statement) { | 123 bool is_statement) { |
120 if (Omit()) return; | 124 if (Omit()) return; |
| 125 DCHECK(source_position.IsKnown()); |
121 int offset = static_cast<int>(code_offset); | 126 int offset = static_cast<int>(code_offset); |
122 AddEntry({offset, source_position, is_statement}); | 127 AddEntry({offset, source_position.raw(), is_statement}); |
123 } | 128 } |
124 | 129 |
125 void SourcePositionTableBuilder::AddEntry(const PositionTableEntry& entry) { | 130 void SourcePositionTableBuilder::AddEntry(const PositionTableEntry& entry) { |
126 PositionTableEntry tmp(entry); | 131 PositionTableEntry tmp(entry); |
127 SubtractFromEntry(tmp, previous_); | 132 SubtractFromEntry(tmp, previous_); |
128 EncodeEntry(bytes_, tmp); | 133 EncodeEntry(bytes_, tmp); |
129 previous_ = entry; | 134 previous_ = entry; |
130 #ifdef ENABLE_SLOW_DCHECKS | 135 #ifdef ENABLE_SLOW_DCHECKS |
131 raw_entries_.push_back(entry); | 136 raw_entries_.push_back(entry); |
132 #endif | 137 #endif |
(...skipping 12 matching lines...) Expand all Loading... |
145 LOG_CODE_EVENT(isolate, CodeLinePosInfoRecordEvent(*code, *table)); | 150 LOG_CODE_EVENT(isolate, CodeLinePosInfoRecordEvent(*code, *table)); |
146 | 151 |
147 #ifdef ENABLE_SLOW_DCHECKS | 152 #ifdef ENABLE_SLOW_DCHECKS |
148 // Brute force testing: Record all positions and decode | 153 // Brute force testing: Record all positions and decode |
149 // the entire table to verify they are identical. | 154 // the entire table to verify they are identical. |
150 auto raw = raw_entries_.begin(); | 155 auto raw = raw_entries_.begin(); |
151 for (SourcePositionTableIterator encoded(*table); !encoded.done(); | 156 for (SourcePositionTableIterator encoded(*table); !encoded.done(); |
152 encoded.Advance(), raw++) { | 157 encoded.Advance(), raw++) { |
153 DCHECK(raw != raw_entries_.end()); | 158 DCHECK(raw != raw_entries_.end()); |
154 DCHECK_EQ(encoded.code_offset(), raw->code_offset); | 159 DCHECK_EQ(encoded.code_offset(), raw->code_offset); |
155 DCHECK_EQ(encoded.source_position(), raw->source_position); | 160 DCHECK_EQ(encoded.source_position().raw(), raw->source_position); |
156 DCHECK_EQ(encoded.is_statement(), raw->is_statement); | 161 DCHECK_EQ(encoded.is_statement(), raw->is_statement); |
157 } | 162 } |
158 DCHECK(raw == raw_entries_.end()); | 163 DCHECK(raw == raw_entries_.end()); |
159 // No additional source positions after creating the table. | 164 // No additional source positions after creating the table. |
160 mode_ = OMIT_SOURCE_POSITIONS; | 165 mode_ = OMIT_SOURCE_POSITIONS; |
161 #endif | 166 #endif |
162 return table; | 167 return table; |
163 } | 168 } |
164 | 169 |
165 SourcePositionTableIterator::SourcePositionTableIterator(ByteArray* byte_array) | 170 SourcePositionTableIterator::SourcePositionTableIterator(ByteArray* byte_array) |
166 : table_(byte_array), index_(0), current_() { | 171 : table_(byte_array), index_(0), current_() { |
167 Advance(); | 172 Advance(); |
168 } | 173 } |
169 | 174 |
170 void SourcePositionTableIterator::Advance() { | 175 void SourcePositionTableIterator::Advance() { |
171 DCHECK(!done()); | 176 DCHECK(!done()); |
172 DCHECK(index_ >= 0 && index_ <= table_->length()); | 177 DCHECK(index_ >= 0 && index_ <= table_->length()); |
173 if (index_ == table_->length()) { | 178 if (index_ == table_->length()) { |
174 index_ = kDone; | 179 index_ = kDone; |
175 } else { | 180 } else { |
176 PositionTableEntry tmp; | 181 PositionTableEntry tmp; |
177 DecodeEntry(table_, &index_, &tmp); | 182 DecodeEntry(table_, &index_, &tmp); |
178 AddAndSetEntry(current_, tmp); | 183 AddAndSetEntry(current_, tmp); |
179 } | 184 } |
180 } | 185 } |
181 | 186 |
182 } // namespace internal | 187 } // namespace internal |
183 } // namespace v8 | 188 } // namespace v8 |
OLD | NEW |