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 |