| 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 auto encoded = static_cast<typename std::make_unsigned<T>::type>(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 |