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