| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 #ifndef V8_SAFEPOINT_TABLE_H_ | 5 #ifndef V8_SAFEPOINT_TABLE_H_ |
| 6 #define V8_SAFEPOINT_TABLE_H_ | 6 #define V8_SAFEPOINT_TABLE_H_ |
| 7 | 7 |
| 8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
| 9 #include "src/heap/heap.h" | 9 #include "src/heap/heap.h" |
| 10 #include "src/v8memory.h" | 10 #include "src/v8memory.h" |
| 11 #include "src/zone.h" | 11 #include "src/zone.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 | 15 |
| 16 struct Register; | 16 struct Register; |
| 17 | 17 |
| 18 class SafepointEntry BASE_EMBEDDED { | 18 class SafepointEntry BASE_EMBEDDED { |
| 19 public: | 19 public: |
| 20 SafepointEntry() : info_(0), deoptimization_pc_(0), bits_(NULL) {} | 20 SafepointEntry() : info_(0), bits_(NULL) {} |
| 21 | 21 |
| 22 SafepointEntry(unsigned info, unsigned deoptimization_pc, uint8_t* bits) | 22 SafepointEntry(unsigned info, uint8_t* bits) : info_(info), bits_(bits) { |
| 23 : info_(info), deoptimization_pc_(deoptimization_pc), bits_(bits) { | |
| 24 DCHECK(is_valid()); | 23 DCHECK(is_valid()); |
| 25 } | 24 } |
| 26 | 25 |
| 27 bool is_valid() const { return bits_ != NULL; } | 26 bool is_valid() const { return bits_ != NULL; } |
| 28 | 27 |
| 29 bool Equals(const SafepointEntry& other) const { | 28 bool Equals(const SafepointEntry& other) const { |
| 30 return info_ == other.info_ && bits_ == other.bits_; | 29 return info_ == other.info_ && bits_ == other.bits_; |
| 31 } | 30 } |
| 32 | 31 |
| 33 void Reset() { | 32 void Reset() { |
| 34 info_ = 0; | 33 info_ = 0; |
| 35 bits_ = NULL; | 34 bits_ = NULL; |
| 36 } | 35 } |
| 37 | 36 |
| 38 int deoptimization_index() const { | 37 int deoptimization_index() const { |
| 39 DCHECK(is_valid()); | 38 DCHECK(is_valid()); |
| 40 return DeoptimizationIndexField::decode(info_); | 39 return DeoptimizationIndexField::decode(info_); |
| 41 } | 40 } |
| 42 | 41 |
| 43 unsigned deoptimization_pc() const { | |
| 44 DCHECK(is_valid()); | |
| 45 return deoptimization_pc_; | |
| 46 } | |
| 47 | |
| 48 static const int kArgumentsFieldBits = 3; | 42 static const int kArgumentsFieldBits = 3; |
| 49 static const int kSaveDoublesFieldBits = 1; | 43 static const int kSaveDoublesFieldBits = 1; |
| 50 static const int kDeoptIndexBits = | 44 static const int kDeoptIndexBits = |
| 51 32 - kArgumentsFieldBits - kSaveDoublesFieldBits; | 45 32 - kArgumentsFieldBits - kSaveDoublesFieldBits; |
| 52 class DeoptimizationIndexField: | 46 class DeoptimizationIndexField: |
| 53 public BitField<int, 0, kDeoptIndexBits> {}; // NOLINT | 47 public BitField<int, 0, kDeoptIndexBits> {}; // NOLINT |
| 54 class ArgumentsField: | 48 class ArgumentsField: |
| 55 public BitField<unsigned, | 49 public BitField<unsigned, |
| 56 kDeoptIndexBits, | 50 kDeoptIndexBits, |
| 57 kArgumentsFieldBits> {}; // NOLINT | 51 kArgumentsFieldBits> {}; // NOLINT |
| (...skipping 15 matching lines...) Expand all Loading... |
| 73 uint8_t* bits() { | 67 uint8_t* bits() { |
| 74 DCHECK(is_valid()); | 68 DCHECK(is_valid()); |
| 75 return bits_; | 69 return bits_; |
| 76 } | 70 } |
| 77 | 71 |
| 78 bool HasRegisters() const; | 72 bool HasRegisters() const; |
| 79 bool HasRegisterAt(int reg_index) const; | 73 bool HasRegisterAt(int reg_index) const; |
| 80 | 74 |
| 81 private: | 75 private: |
| 82 unsigned info_; | 76 unsigned info_; |
| 83 unsigned deoptimization_pc_; | |
| 84 uint8_t* bits_; | 77 uint8_t* bits_; |
| 85 }; | 78 }; |
| 86 | 79 |
| 87 | 80 |
| 88 class SafepointTable BASE_EMBEDDED { | 81 class SafepointTable BASE_EMBEDDED { |
| 89 public: | 82 public: |
| 90 explicit SafepointTable(Code* code); | 83 explicit SafepointTable(Code* code); |
| 91 | 84 |
| 92 int size() const { | 85 int size() const { |
| 93 return kHeaderSize + | 86 return kHeaderSize + |
| 94 (length_ * (kPcAndDeoptimizationInfoSize + entry_size_)); | 87 (length_ * (kPcAndDeoptimizationIndexSize + entry_size_)); |
| 95 } | 88 } |
| 96 unsigned length() const { return length_; } | 89 unsigned length() const { return length_; } |
| 97 unsigned entry_size() const { return entry_size_; } | 90 unsigned entry_size() const { return entry_size_; } |
| 98 | 91 |
| 99 unsigned GetPcOffset(unsigned index) const { | 92 unsigned GetPcOffset(unsigned index) const { |
| 100 DCHECK(index < length_); | 93 DCHECK(index < length_); |
| 101 return Memory::uint32_at(GetPcOffsetLocation(index)); | 94 return Memory::uint32_at(GetPcOffsetLocation(index)); |
| 102 } | 95 } |
| 103 | 96 |
| 104 unsigned GetDeoptimizationPcOffset(unsigned index) const { | |
| 105 DCHECK(index < length_); | |
| 106 return Memory::uint32_at(GetDeoptimizationPcLocation(index)); | |
| 107 } | |
| 108 | |
| 109 SafepointEntry GetEntry(unsigned index) const { | 97 SafepointEntry GetEntry(unsigned index) const { |
| 110 DCHECK(index < length_); | 98 DCHECK(index < length_); |
| 111 unsigned info = Memory::uint32_at(GetInfoLocation(index)); | 99 unsigned info = Memory::uint32_at(GetInfoLocation(index)); |
| 112 unsigned deopt_pc = Memory::uint32_at(GetDeoptimizationPcLocation(index)); | |
| 113 uint8_t* bits = &Memory::uint8_at(entries_ + (index * entry_size_)); | 100 uint8_t* bits = &Memory::uint8_at(entries_ + (index * entry_size_)); |
| 114 return SafepointEntry(info, deopt_pc, bits); | 101 return SafepointEntry(info, bits); |
| 115 } | 102 } |
| 116 | 103 |
| 117 // Returns the entry for the given pc. | 104 // Returns the entry for the given pc. |
| 118 SafepointEntry FindEntry(Address pc) const; | 105 SafepointEntry FindEntry(Address pc) const; |
| 119 | 106 |
| 120 void PrintEntry(unsigned index, OStream& os) const; // NOLINT | 107 void PrintEntry(unsigned index, OStream& os) const; // NOLINT |
| 121 | 108 |
| 122 private: | 109 private: |
| 123 static const uint8_t kNoRegisters = 0xFF; | 110 static const uint8_t kNoRegisters = 0xFF; |
| 124 | 111 |
| 125 static const int kLengthOffset = 0; | 112 static const int kLengthOffset = 0; |
| 126 static const int kEntrySizeOffset = kLengthOffset + kIntSize; | 113 static const int kEntrySizeOffset = kLengthOffset + kIntSize; |
| 127 static const int kHeaderSize = kEntrySizeOffset + kIntSize; | 114 static const int kHeaderSize = kEntrySizeOffset + kIntSize; |
| 128 | 115 |
| 129 static const int kPcSize = kIntSize; | 116 static const int kPcSize = kIntSize; |
| 130 static const int kDeoptimizationIndexSize = kIntSize; | 117 static const int kDeoptimizationIndexSize = kIntSize; |
| 131 static const int kDeoptimizationPcSize = kIntSize; | 118 static const int kPcAndDeoptimizationIndexSize = |
| 132 static const int kPcAndDeoptimizationInfoSize = | 119 kPcSize + kDeoptimizationIndexSize; |
| 133 kPcSize + kDeoptimizationIndexSize + kDeoptimizationPcSize; | |
| 134 | 120 |
| 135 Address GetPcOffsetLocation(unsigned index) const { | 121 Address GetPcOffsetLocation(unsigned index) const { |
| 136 return pc_and_deoptimization_indexes_ + | 122 return pc_and_deoptimization_indexes_ + |
| 137 (index * kPcAndDeoptimizationInfoSize); | 123 (index * kPcAndDeoptimizationIndexSize); |
| 138 } | 124 } |
| 139 | 125 |
| 140 Address GetInfoLocation(unsigned index) const { | 126 Address GetInfoLocation(unsigned index) const { |
| 141 return GetPcOffsetLocation(index) + kPcSize; | 127 return GetPcOffsetLocation(index) + kPcSize; |
| 142 } | 128 } |
| 143 | 129 |
| 144 Address GetDeoptimizationPcLocation(unsigned index) const { | |
| 145 return GetInfoLocation(index) + kDeoptimizationIndexSize; | |
| 146 } | |
| 147 | |
| 148 static void PrintBits(OStream& os, // NOLINT | 130 static void PrintBits(OStream& os, // NOLINT |
| 149 uint8_t byte, int digits); | 131 uint8_t byte, int digits); |
| 150 | 132 |
| 151 DisallowHeapAllocation no_allocation_; | 133 DisallowHeapAllocation no_allocation_; |
| 152 Code* code_; | 134 Code* code_; |
| 153 unsigned length_; | 135 unsigned length_; |
| 154 unsigned entry_size_; | 136 unsigned entry_size_; |
| 155 | 137 |
| 156 Address pc_and_deoptimization_indexes_; | 138 Address pc_and_deoptimization_indexes_; |
| 157 Address entries_; | 139 Address entries_; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 170 kWithRegisters = 1 << 0, | 152 kWithRegisters = 1 << 0, |
| 171 kWithDoubles = 1 << 1, | 153 kWithDoubles = 1 << 1, |
| 172 kWithRegistersAndDoubles = kWithRegisters | kWithDoubles | 154 kWithRegistersAndDoubles = kWithRegisters | kWithDoubles |
| 173 } Kind; | 155 } Kind; |
| 174 | 156 |
| 175 enum DeoptMode { | 157 enum DeoptMode { |
| 176 kNoLazyDeopt, | 158 kNoLazyDeopt, |
| 177 kLazyDeopt | 159 kLazyDeopt |
| 178 }; | 160 }; |
| 179 | 161 |
| 180 class Id { | |
| 181 private: | |
| 182 explicit Id(int id) : id_(id) {} | |
| 183 | |
| 184 int id_; | |
| 185 | |
| 186 friend class SafepointTableBuilder; | |
| 187 friend class Safepoint; | |
| 188 }; | |
| 189 | |
| 190 static const int kNoDeoptimizationIndex = | 162 static const int kNoDeoptimizationIndex = |
| 191 (1 << (SafepointEntry::kDeoptIndexBits)) - 1; | 163 (1 << (SafepointEntry::kDeoptIndexBits)) - 1; |
| 192 | 164 |
| 193 static const unsigned kNoDeoptimizationPc = ~0U; | |
| 194 | |
| 195 void DefinePointerSlot(int index, Zone* zone) { indexes_->Add(index, zone); } | 165 void DefinePointerSlot(int index, Zone* zone) { indexes_->Add(index, zone); } |
| 196 void DefinePointerRegister(Register reg, Zone* zone); | 166 void DefinePointerRegister(Register reg, Zone* zone); |
| 197 | 167 |
| 198 Id id() const { return Id(id_); } | |
| 199 | |
| 200 private: | 168 private: |
| 201 Safepoint(int id, ZoneList<int>* indexes, ZoneList<int>* registers) | 169 Safepoint(ZoneList<int>* indexes, ZoneList<int>* registers) |
| 202 : id_(id), indexes_(indexes), registers_(registers) {} | 170 : indexes_(indexes), registers_(registers) {} |
| 203 int id_; | |
| 204 ZoneList<int>* indexes_; | 171 ZoneList<int>* indexes_; |
| 205 ZoneList<int>* registers_; | 172 ZoneList<int>* registers_; |
| 206 | 173 |
| 207 friend class SafepointTableBuilder; | 174 friend class SafepointTableBuilder; |
| 208 }; | 175 }; |
| 209 | 176 |
| 210 | 177 |
| 211 class SafepointTableBuilder BASE_EMBEDDED { | 178 class SafepointTableBuilder BASE_EMBEDDED { |
| 212 public: | 179 public: |
| 213 explicit SafepointTableBuilder(Zone* zone) | 180 explicit SafepointTableBuilder(Zone* zone) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 227 Safepoint::Kind kind, | 194 Safepoint::Kind kind, |
| 228 int arguments, | 195 int arguments, |
| 229 Safepoint::DeoptMode mode); | 196 Safepoint::DeoptMode mode); |
| 230 | 197 |
| 231 // Record deoptimization index for lazy deoptimization for the last | 198 // Record deoptimization index for lazy deoptimization for the last |
| 232 // outstanding safepoints. | 199 // outstanding safepoints. |
| 233 void RecordLazyDeoptimizationIndex(int index); | 200 void RecordLazyDeoptimizationIndex(int index); |
| 234 void BumpLastLazySafepointIndex() { | 201 void BumpLastLazySafepointIndex() { |
| 235 last_lazy_safepoint_ = deopt_index_list_.length(); | 202 last_lazy_safepoint_ = deopt_index_list_.length(); |
| 236 } | 203 } |
| 237 void SetDeoptimizationPc(Safepoint::Id safepoint_id, | |
| 238 unsigned deoptimization_pc) { | |
| 239 deoptimization_info_[safepoint_id.id_].deoptimization_pc = | |
| 240 deoptimization_pc; | |
| 241 } | |
| 242 | 204 |
| 243 // Emit the safepoint table after the body. The number of bits per | 205 // Emit the safepoint table after the body. The number of bits per |
| 244 // entry must be enough to hold all the pointer indexes. | 206 // entry must be enough to hold all the pointer indexes. |
| 245 void Emit(Assembler* assembler, int bits_per_entry); | 207 void Emit(Assembler* assembler, int bits_per_entry); |
| 246 | 208 |
| 247 | 209 |
| 248 private: | 210 private: |
| 249 struct DeoptimizationInfo { | 211 struct DeoptimizationInfo { |
| 250 unsigned pc; | 212 unsigned pc; |
| 251 unsigned arguments; | 213 unsigned arguments; |
| 252 bool has_doubles; | 214 bool has_doubles; |
| 253 unsigned deoptimization_pc; | |
| 254 }; | 215 }; |
| 255 | 216 |
| 256 uint32_t EncodeExceptPC(const DeoptimizationInfo& info, unsigned index); | 217 uint32_t EncodeExceptPC(const DeoptimizationInfo& info, unsigned index); |
| 257 | 218 |
| 258 ZoneList<DeoptimizationInfo> deoptimization_info_; | 219 ZoneList<DeoptimizationInfo> deoptimization_info_; |
| 259 ZoneList<unsigned> deopt_index_list_; | 220 ZoneList<unsigned> deopt_index_list_; |
| 260 ZoneList<ZoneList<int>*> indexes_; | 221 ZoneList<ZoneList<int>*> indexes_; |
| 261 ZoneList<ZoneList<int>*> registers_; | 222 ZoneList<ZoneList<int>*> registers_; |
| 262 | 223 |
| 263 unsigned offset_; | 224 unsigned offset_; |
| 264 bool emitted_; | 225 bool emitted_; |
| 265 int last_lazy_safepoint_; | 226 int last_lazy_safepoint_; |
| 266 | 227 |
| 267 Zone* zone_; | 228 Zone* zone_; |
| 268 | 229 |
| 269 DISALLOW_COPY_AND_ASSIGN(SafepointTableBuilder); | 230 DISALLOW_COPY_AND_ASSIGN(SafepointTableBuilder); |
| 270 }; | 231 }; |
| 271 | 232 |
| 272 } } // namespace v8::internal | 233 } } // namespace v8::internal |
| 273 | 234 |
| 274 #endif // V8_SAFEPOINT_TABLE_H_ | 235 #endif // V8_SAFEPOINT_TABLE_H_ |
| OLD | NEW |