Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: src/assembler.cc

Issue 6793016: Record AST ids in relocation info at spots where we collect dynamic type feedback. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add ARM port Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 12 matching lines...) Expand all
23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 // The original source code covered by the above license above has been 31 // The original source code covered by the above license above has been
32 // modified significantly by Google Inc. 32 // modified significantly by Google Inc.
33 // Copyright 2006-2009 the V8 project authors. All rights reserved. 33 // Copyright 2011 the V8 project authors. All rights reserved.
34 34
35 #include "v8.h" 35 #include "v8.h"
36 36
37 #include "arguments.h" 37 #include "arguments.h"
38 #include "deoptimizer.h" 38 #include "deoptimizer.h"
39 #include "execution.h" 39 #include "execution.h"
40 #include "ic-inl.h" 40 #include "ic-inl.h"
41 #include "factory.h" 41 #include "factory.h"
42 #include "runtime.h" 42 #include "runtime.h"
43 #include "runtime-profiler.h" 43 #include "runtime-profiler.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // Implementation of RelocInfoWriter and RelocIterator 88 // Implementation of RelocInfoWriter and RelocIterator
89 // 89 //
90 // Encoding 90 // Encoding
91 // 91 //
92 // The most common modes are given single-byte encodings. Also, it is 92 // The most common modes are given single-byte encodings. Also, it is
93 // easy to identify the type of reloc info and skip unwanted modes in 93 // easy to identify the type of reloc info and skip unwanted modes in
94 // an iteration. 94 // an iteration.
95 // 95 //
96 // The encoding relies on the fact that there are less than 14 96 // The encoding relies on the fact that there are less than 14
97 // different relocation modes. 97 // different relocation modes.
98 // 98 //
Vitaly Repeshko 2011/04/15 01:24:43 It'd be nice to describe the tag structure, i.e. t
William Hesse 2011/04/15 11:51:27 I have a rewrite of this, that I forgot to copy in
99 // embedded_object: [6 bits pc delta] 00 99 // Written by WriteTaggedPC:
100 // embedded_object: [6 bits pc delta] 00
100 // 101 //
101 // code_taget: [6 bits pc delta] 01 102 // code_target: [6 bits pc delta] 01
102 // 103 //
103 // position: [6 bits pc delta] 10, 104 // Written by WriteTaggedPC, WriteTaggedData sequence:
104 // [7 bits signed data delta] 0 105 // code_target_with_id: [6 bits pc delta] 10,
106 // [6 bits signed data delta] 00
105 // 107 //
106 // statement_position: [6 bits pc delta] 10, 108 // position: [6 bits pc delta] 10,
107 // [7 bits signed data delta] 1 109 // [6 bits signed data delta] 01
108 // 110 //
109 // any nondata mode: 00 [4 bits rmode] 11, // rmode: 0..13 only 111 // statement_position: [6 bits pc delta] 10,
110 // 00 [6 bits pc delta] 112 // [6 bits signed data delta] 10
111 // 113 //
112 // pc-jump: 00 1111 11, 114 // Written by WriteExtraTag:
113 // 00 [6 bits pc delta] 115 // any nondata mode: 00 [4 bit rmode_field] 11,
116 // 00 [6 bits pc delta]
117 // (The rmode_field encodes rmode - RelocInfo::LAST_COMPACT_ENUM,
118 // and is between 0000 and 1101)
114 // 119 //
115 // pc-jump: 01 1111 11, 120 // pc-jump: 00 1111 11,
116 // (variable length) 7 - 26 bit pc delta, written in chunks of 7 121 // 00 [6 bits pc delta]
117 // bits, the lowest 7 bits written first.
118 // 122 //
119 // data-jump + pos: 00 1110 11, 123 // Written by WriteVariableLengthPCJump, implicitly called by WriteTaggedPC.
120 // signed intptr_t, lowest byte written first 124 // pc-jump (variable length):
125 // 01 1111 11,
126 // [7 bits data] 0
127 // ...
128 // [7 bits data] 1
129 // (Bits 6..31 of pc delta, with leading zeroes
130 // dropped, and last non-zero chunk tagged with 1.)
121 // 131 //
122 // data-jump + st.pos: 01 1110 11, 132 // data-jump + position : 00 1110 11,
Vitaly Repeshko 2011/04/15 01:24:43 We need a similar "Written by" comment here.
123 // signed intptr_t, lowest byte written first 133 // signed intptr_t, lowest byte written first
124 // 134 //
125 // data-jump + comm.: 10 1110 11, 135 // data-jump + statement position:
126 // signed intptr_t, lowest byte written first 136 // 01 1110 11,
137 // signed intptr_t, lowest byte written first
138 //
139 // data-jump + comment: 10 1110 11,
140 // signed intptr_t, lowest byte written first
127 // 141 //
128 const int kMaxRelocModes = 14; 142 const int kMaxRelocModes = 14;
129 143
130 const int kTagBits = 2; 144 const int kTagBits = 2;
131 const int kTagMask = (1 << kTagBits) - 1; 145 const int kTagMask = (1 << kTagBits) - 1;
132 const int kExtraTagBits = 4; 146 const int kExtraTagBits = 4;
133 const int kPositionTypeTagBits = 1; 147 const int kLocatableTypeTagBits = 2;
134 const int kSmallDataBits = kBitsPerByte - kPositionTypeTagBits; 148 const int kSmallDataBits = kBitsPerByte - kLocatableTypeTagBits;
135 149
136 const int kEmbeddedObjectTag = 0; 150 const int kEmbeddedObjectTag = 0;
137 const int kCodeTargetTag = 1; 151 const int kCodeTargetTag = 1;
138 const int kPositionTag = 2; 152 const int kLocatableTag = 2;
139 const int kDefaultTag = 3; 153 const int kDefaultTag = 3;
140 154
141 const int kPCJumpTag = (1 << kExtraTagBits) - 1; 155 const int kPCJumpTag = (1 << kExtraTagBits) - 1;
Vitaly Repeshko 2011/04/15 01:24:43 Let's rename this to kPCJumpExtraTag.
William Hesse 2011/04/15 11:51:27 Done.
142 156
143 const int kSmallPCDeltaBits = kBitsPerByte - kTagBits; 157 const int kSmallPCDeltaBits = kBitsPerByte - kTagBits;
144 const int kSmallPCDeltaMask = (1 << kSmallPCDeltaBits) - 1; 158 const int kSmallPCDeltaMask = (1 << kSmallPCDeltaBits) - 1;
145 const int RelocInfo::kMaxSmallPCDelta = kSmallPCDeltaMask; 159 const int RelocInfo::kMaxSmallPCDelta = kSmallPCDeltaMask;
146 160
147 const int kVariableLengthPCJumpTopTag = 1; 161 const int kVariableLengthPCJumpTopTag = 1;
148 const int kChunkBits = 7; 162 const int kChunkBits = 7;
149 const int kChunkMask = (1 << kChunkBits) - 1; 163 const int kChunkMask = (1 << kChunkBits) - 1;
150 const int kLastChunkTagBits = 1; 164 const int kLastChunkTagBits = 1;
151 const int kLastChunkTagMask = 1; 165 const int kLastChunkTagMask = 1;
152 const int kLastChunkTag = 1; 166 const int kLastChunkTag = 1;
153 167
154 168
155 const int kDataJumpTag = kPCJumpTag - 1; 169 const int kDataJumpTag = kPCJumpTag - 1;
Vitaly Repeshko 2011/04/15 01:24:43 kDataJumpExtraTag
William Hesse 2011/04/15 11:51:27 Done.
156 170
157 const int kNonstatementPositionTag = 0; 171 const int kCodeWithIdTag = 0;
158 const int kStatementPositionTag = 1; 172 const int kNonstatementPositionTag = 1;
159 const int kCommentTag = 2; 173 const int kStatementPositionTag = 2;
174 const int kCommentTag = 3;
160 175
161 176
162 uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) { 177 uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) {
163 // Return if the pc_delta can fit in kSmallPCDeltaBits bits. 178 // Return if the pc_delta can fit in kSmallPCDeltaBits bits.
164 // Otherwise write a variable length PC jump for the bits that do 179 // Otherwise write a variable length PC jump for the bits that do
165 // not fit in the kSmallPCDeltaBits bits. 180 // not fit in the kSmallPCDeltaBits bits.
166 if (is_uintn(pc_delta, kSmallPCDeltaBits)) return pc_delta; 181 if (is_uintn(pc_delta, kSmallPCDeltaBits)) return pc_delta;
167 WriteExtraTag(kPCJumpTag, kVariableLengthPCJumpTopTag); 182 WriteExtraTag(kPCJumpTag, kVariableLengthPCJumpTopTag);
168 uint32_t pc_jump = pc_delta >> kSmallPCDeltaBits; 183 uint32_t pc_jump = pc_delta >> kSmallPCDeltaBits;
169 ASSERT(pc_jump > 0); 184 ASSERT(pc_jump > 0);
(...skipping 10 matching lines...) Expand all
180 195
181 196
182 void RelocInfoWriter::WriteTaggedPC(uint32_t pc_delta, int tag) { 197 void RelocInfoWriter::WriteTaggedPC(uint32_t pc_delta, int tag) {
183 // Write a byte of tagged pc-delta, possibly preceded by var. length pc-jump. 198 // Write a byte of tagged pc-delta, possibly preceded by var. length pc-jump.
184 pc_delta = WriteVariableLengthPCJump(pc_delta); 199 pc_delta = WriteVariableLengthPCJump(pc_delta);
185 *--pos_ = pc_delta << kTagBits | tag; 200 *--pos_ = pc_delta << kTagBits | tag;
186 } 201 }
187 202
188 203
189 void RelocInfoWriter::WriteTaggedData(intptr_t data_delta, int tag) { 204 void RelocInfoWriter::WriteTaggedData(intptr_t data_delta, int tag) {
190 *--pos_ = static_cast<byte>(data_delta << kPositionTypeTagBits | tag); 205 *--pos_ = static_cast<byte>(data_delta << kLocatableTypeTagBits | tag);
191 } 206 }
192 207
193 208
194 void RelocInfoWriter::WriteExtraTag(int extra_tag, int top_tag) { 209 void RelocInfoWriter::WriteExtraTag(int extra_tag, int top_tag) {
195 *--pos_ = static_cast<int>(top_tag << (kTagBits + kExtraTagBits) | 210 *--pos_ = static_cast<int>(top_tag << (kTagBits + kExtraTagBits) |
196 extra_tag << kTagBits | 211 extra_tag << kTagBits |
197 kDefaultTag); 212 kDefaultTag);
198 } 213 }
199 214
200 215
201 void RelocInfoWriter::WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag) { 216 void RelocInfoWriter::WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag) {
202 // Write two-byte tagged pc-delta, possibly preceded by var. length pc-jump. 217 // Write two-byte tagged pc-delta, possibly preceded by var. length pc-jump.
203 pc_delta = WriteVariableLengthPCJump(pc_delta); 218 pc_delta = WriteVariableLengthPCJump(pc_delta);
204 WriteExtraTag(extra_tag, 0); 219 WriteExtraTag(extra_tag, 0);
205 *--pos_ = pc_delta; 220 *--pos_ = pc_delta;
206 } 221 }
207 222
208 223
224 void RelocInfoWriter::WriteExtraTaggedIntData(int data_delta, int top_tag)
225 {
Vitaly Repeshko 2011/04/15 01:24:43 nit: Put '{' on the previous line.
William Hesse 2011/04/15 11:51:27 Done.
226 WriteExtraTag(kDataJumpTag, top_tag);
227 for (int i = 0; i < kIntSize; i++) {
228 *--pos_ = static_cast<byte>(data_delta);
229 // Signed right shift is arithmetic shift. Tested in test-utils.cc.
230 data_delta = data_delta >> kBitsPerByte;
231 }
232 }
233
209 void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) { 234 void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) {
210 WriteExtraTag(kDataJumpTag, top_tag); 235 WriteExtraTag(kDataJumpTag, top_tag);
211 for (int i = 0; i < kIntptrSize; i++) { 236 for (int i = 0; i < kIntptrSize; i++) {
212 *--pos_ = static_cast<byte>(data_delta); 237 *--pos_ = static_cast<byte>(data_delta);
213 // Signed right shift is arithmetic shift. Tested in test-utils.cc. 238 // Signed right shift is arithmetic shift. Tested in test-utils.cc.
214 data_delta = data_delta >> kBitsPerByte; 239 data_delta = data_delta >> kBitsPerByte;
215 } 240 }
216 } 241 }
217 242
218 243
219 void RelocInfoWriter::Write(const RelocInfo* rinfo) { 244 void RelocInfoWriter::Write(const RelocInfo* rinfo) {
220 #ifdef DEBUG 245 #ifdef DEBUG
221 byte* begin_pos = pos_; 246 byte* begin_pos = pos_;
222 #endif 247 #endif
223 ASSERT(rinfo->pc() - last_pc_ >= 0); 248 ASSERT(rinfo->pc() - last_pc_ >= 0);
224 ASSERT(RelocInfo::NUMBER_OF_MODES <= kMaxRelocModes); 249 ASSERT(RelocInfo::NUMBER_OF_MODES - RelocInfo::LAST_CODE_ENUM <=
Vitaly Repeshko 2011/04/15 01:24:43 LAST_COMPACT_ENUM?
William Hesse 2011/04/15 11:51:27 Done.
250 kMaxRelocModes);
225 // Use unsigned delta-encoding for pc. 251 // Use unsigned delta-encoding for pc.
226 uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_); 252 uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_);
227 RelocInfo::Mode rmode = rinfo->rmode(); 253 RelocInfo::Mode rmode = rinfo->rmode();
228 254
229 // The two most common modes are given small tags, and usually fit in a byte. 255 // The two most common modes are given small tags, and usually fit in a byte.
230 if (rmode == RelocInfo::EMBEDDED_OBJECT) { 256 if (rmode == RelocInfo::EMBEDDED_OBJECT) {
231 WriteTaggedPC(pc_delta, kEmbeddedObjectTag); 257 WriteTaggedPC(pc_delta, kEmbeddedObjectTag);
232 } else if (rmode == RelocInfo::CODE_TARGET) { 258 } else if (rmode == RelocInfo::CODE_TARGET) {
233 WriteTaggedPC(pc_delta, kCodeTargetTag); 259 WriteTaggedPC(pc_delta, kCodeTargetTag);
234 ASSERT(begin_pos - pos_ <= RelocInfo::kMaxCallSize); 260 ASSERT(begin_pos - pos_ <= RelocInfo::kMaxCallSize);
235 } else if (RelocInfo::IsPosition(rmode)) { 261 } else if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
236 // Use signed delta-encoding for data. 262 // Use signed delta-encoding for id.
237 intptr_t data_delta = rinfo->data() - last_data_; 263 ASSERT(static_cast<int>(rinfo->data()) == rinfo->data());
238 int pos_type_tag = rmode == RelocInfo::POSITION ? kNonstatementPositionTag 264 int id_delta = static_cast<int>(rinfo->data()) - last_id_;
239 : kStatementPositionTag; 265 // Check if delta is small enough to fit in a tagged byte.
240 // Check if data is small enough to fit in a tagged byte. 266 if (is_intn(id_delta, kSmallDataBits)) {
241 // We cannot use is_intn because data_delta is not an int32_t. 267 WriteTaggedPC(pc_delta, kLocatableTag);
242 if (data_delta >= -(1 << (kSmallDataBits-1)) && 268 WriteTaggedData(id_delta, kCodeWithIdTag);
243 data_delta < 1 << (kSmallDataBits-1)) {
244 WriteTaggedPC(pc_delta, kPositionTag);
245 WriteTaggedData(data_delta, pos_type_tag);
246 last_data_ = rinfo->data();
247 } else { 269 } else {
248 // Otherwise, use costly encoding. 270 // Otherwise, use costly encoding.
249 WriteExtraTaggedPC(pc_delta, kPCJumpTag); 271 WriteExtraTaggedPC(pc_delta, kPCJumpTag);
250 WriteExtraTaggedData(data_delta, pos_type_tag); 272 WriteExtraTaggedIntData(id_delta, kCodeWithIdTag);
251 last_data_ = rinfo->data();
252 } 273 }
274 last_id_ = static_cast<int>(rinfo->data());
275 } else if (RelocInfo::IsPosition(rmode)) {
276 // Use signed delta-encoding for position.
277 ASSERT(static_cast<int>(rinfo->data()) == rinfo->data());
278 int pos_delta = static_cast<int>(rinfo->data()) - last_position_;
279 int pos_type_tag = (rmode == RelocInfo::POSITION) ? kNonstatementPositionTag
280 : kStatementPositionTag;
281 // Check if delta is small enough to fit in a tagged byte.
282 if (is_intn(pos_delta, kSmallDataBits)) {
283 WriteTaggedPC(pc_delta, kLocatableTag);
284 WriteTaggedData(pos_delta, pos_type_tag);
285 } else {
286 // Otherwise, use costly encoding.
287 WriteExtraTaggedPC(pc_delta, kPCJumpTag);
288 WriteExtraTaggedIntData(pos_delta, pos_type_tag);
289 }
290 last_position_ = static_cast<int>(rinfo->data());
253 } else if (RelocInfo::IsComment(rmode)) { 291 } else if (RelocInfo::IsComment(rmode)) {
254 // Comments are normally not generated, so we use the costly encoding. 292 // Comments are normally not generated, so we use the costly encoding.
255 WriteExtraTaggedPC(pc_delta, kPCJumpTag); 293 WriteExtraTaggedPC(pc_delta, kPCJumpTag);
256 WriteExtraTaggedData(rinfo->data() - last_data_, kCommentTag); 294 WriteExtraTaggedData(rinfo->data(), kCommentTag);
257 last_data_ = rinfo->data();
258 ASSERT(begin_pos - pos_ >= RelocInfo::kMinRelocCommentSize); 295 ASSERT(begin_pos - pos_ >= RelocInfo::kMinRelocCommentSize);
259 } else { 296 } else {
297 ASSERT(rmode > RelocInfo::LAST_COMPACT_ENUM);
298 int saved_mode = rmode - RelocInfo::LAST_COMPACT_ENUM;
260 // For all other modes we simply use the mode as the extra tag. 299 // For all other modes we simply use the mode as the extra tag.
261 // None of these modes need a data component. 300 // None of these modes need a data component.
262 ASSERT(rmode < kPCJumpTag && rmode < kDataJumpTag); 301 ASSERT(saved_mode < kPCJumpTag && saved_mode < kDataJumpTag);
263 WriteExtraTaggedPC(pc_delta, rmode); 302 WriteExtraTaggedPC(pc_delta, saved_mode);
264 } 303 }
265 last_pc_ = rinfo->pc(); 304 last_pc_ = rinfo->pc();
266 #ifdef DEBUG 305 #ifdef DEBUG
267 ASSERT(begin_pos - pos_ <= kMaxSize); 306 ASSERT(begin_pos - pos_ <= kMaxSize);
268 #endif 307 #endif
269 } 308 }
270 309
271 310
272 inline int RelocIterator::AdvanceGetTag() { 311 inline int RelocIterator::AdvanceGetTag() {
273 return *--pos_ & kTagMask; 312 return *--pos_ & kTagMask;
(...skipping 13 matching lines...) Expand all
287 inline void RelocIterator::ReadTaggedPC() { 326 inline void RelocIterator::ReadTaggedPC() {
288 rinfo_.pc_ += *pos_ >> kTagBits; 327 rinfo_.pc_ += *pos_ >> kTagBits;
289 } 328 }
290 329
291 330
292 inline void RelocIterator::AdvanceReadPC() { 331 inline void RelocIterator::AdvanceReadPC() {
293 rinfo_.pc_ += *--pos_; 332 rinfo_.pc_ += *--pos_;
294 } 333 }
295 334
296 335
336 void RelocIterator::AdvanceReadId() {
337 int x = 0;
338 for (int i = 0; i < kIntSize; i++) {
339 x |= static_cast<int>(*--pos_) << i * kBitsPerByte;
340 }
341 last_id_ += x;
342 rinfo_.data_ = last_id_;
343 }
344
345
346 void RelocIterator::AdvanceReadPosition() {
347 int x = 0;
348 for (int i = 0; i < kIntSize; i++) {
349 x |= static_cast<int>(*--pos_) << i * kBitsPerByte;
350 }
351 last_position_ += x;
352 rinfo_.data_ = last_position_;
353 }
354
355
297 void RelocIterator::AdvanceReadData() { 356 void RelocIterator::AdvanceReadData() {
298 intptr_t x = 0; 357 intptr_t x = 0;
299 for (int i = 0; i < kIntptrSize; i++) { 358 for (int i = 0; i < kIntptrSize; i++) {
300 x |= static_cast<intptr_t>(*--pos_) << i * kBitsPerByte; 359 x |= static_cast<intptr_t>(*--pos_) << i * kBitsPerByte;
301 } 360 }
302 rinfo_.data_ += x; 361 rinfo_.data_ = x;
303 } 362 }
304 363
305 364
306 void RelocIterator::AdvanceReadVariableLengthPCJump() { 365 void RelocIterator::AdvanceReadVariableLengthPCJump() {
307 // Read the 32-kSmallPCDeltaBits most significant bits of the 366 // Read the 32-kSmallPCDeltaBits most significant bits of the
308 // pc jump in kChunkBits bit chunks and shift them into place. 367 // pc jump in kChunkBits bit chunks and shift them into place.
309 // Stop when the last chunk is encountered. 368 // Stop when the last chunk is encountered.
310 uint32_t pc_jump = 0; 369 uint32_t pc_jump = 0;
311 for (int i = 0; i < kIntSize; i++) { 370 for (int i = 0; i < kIntSize; i++) {
312 byte pc_jump_part = *--pos_; 371 byte pc_jump_part = *--pos_;
313 pc_jump |= (pc_jump_part >> kLastChunkTagBits) << i * kChunkBits; 372 pc_jump |= (pc_jump_part >> kLastChunkTagBits) << i * kChunkBits;
314 if ((pc_jump_part & kLastChunkTagMask) == 1) break; 373 if ((pc_jump_part & kLastChunkTagMask) == 1) break;
315 } 374 }
316 // The least significant kSmallPCDeltaBits bits will be added 375 // The least significant kSmallPCDeltaBits bits will be added
317 // later. 376 // later.
318 rinfo_.pc_ += pc_jump << kSmallPCDeltaBits; 377 rinfo_.pc_ += pc_jump << kSmallPCDeltaBits;
319 } 378 }
320 379
321 380
322 inline int RelocIterator::GetPositionTypeTag() { 381 inline int RelocIterator::GetLocatableTypeTag() {
323 return *pos_ & ((1 << kPositionTypeTagBits) - 1); 382 return *pos_ & ((1 << kLocatableTypeTagBits) - 1);
324 } 383 }
325 384
326 385
327 inline void RelocIterator::ReadTaggedData() { 386 inline void RelocIterator::ReadTaggedId() {
328 int8_t signed_b = *pos_; 387 int8_t signed_b = *pos_;
329 // Signed right shift is arithmetic shift. Tested in test-utils.cc. 388 // Signed right shift is arithmetic shift. Tested in test-utils.cc.
330 rinfo_.data_ += signed_b >> kPositionTypeTagBits; 389 last_id_ += signed_b >> kLocatableTypeTagBits;
390 rinfo_.data_ = last_id_;
331 } 391 }
332 392
333 393
334 inline RelocInfo::Mode RelocIterator::DebugInfoModeFromTag(int tag) { 394 inline void RelocIterator::ReadTaggedPosition() {
335 if (tag == kStatementPositionTag) { 395 int8_t signed_b = *pos_;
336 return RelocInfo::STATEMENT_POSITION; 396 // Signed right shift is arithmetic shift. Tested in test-utils.cc.
337 } else if (tag == kNonstatementPositionTag) { 397 last_position_ += signed_b >> kLocatableTypeTagBits;
338 return RelocInfo::POSITION; 398 rinfo_.data_ = last_position_;
339 } else {
340 ASSERT(tag == kCommentTag);
341 return RelocInfo::COMMENT;
342 }
343 } 399 }
344 400
345 401
402 static inline RelocInfo::Mode GetPositionModeFromTag(int tag) {
403 ASSERT(tag == kNonstatementPositionTag ||
404 tag == kStatementPositionTag);
405 return (tag == kNonstatementPositionTag) ?
406 RelocInfo::POSITION :
407 RelocInfo::STATEMENT_POSITION;
408 }
409
410
346 void RelocIterator::next() { 411 void RelocIterator::next() {
347 ASSERT(!done()); 412 ASSERT(!done());
348 // Basically, do the opposite of RelocInfoWriter::Write. 413 // Basically, do the opposite of RelocInfoWriter::Write.
349 // Reading of data is as far as possible avoided for unwanted modes, 414 // Reading of data is as far as possible avoided for unwanted modes,
350 // but we must always update the pc. 415 // but we must always update the pc.
351 // 416 //
352 // We exit this loop by returning when we find a mode we want. 417 // We exit this loop by returning when we find a mode we want.
353 while (pos_ > end_) { 418 while (pos_ > end_) {
354 int tag = AdvanceGetTag(); 419 int tag = AdvanceGetTag();
355 if (tag == kEmbeddedObjectTag) { 420 if (tag == kEmbeddedObjectTag) {
356 ReadTaggedPC(); 421 ReadTaggedPC();
357 if (SetMode(RelocInfo::EMBEDDED_OBJECT)) return; 422 if (SetMode(RelocInfo::EMBEDDED_OBJECT)) return;
358 } else if (tag == kCodeTargetTag) { 423 } else if (tag == kCodeTargetTag) {
359 ReadTaggedPC(); 424 ReadTaggedPC();
360 if (SetMode(RelocInfo::CODE_TARGET)) return; 425 if (SetMode(RelocInfo::CODE_TARGET)) return;
361 } else if (tag == kPositionTag) { 426 } else if (tag == kLocatableTag) {
362 ReadTaggedPC(); 427 ReadTaggedPC();
363 Advance(); 428 Advance();
364 // Check if we want source positions. 429 int locatable_tag = GetLocatableTypeTag();
365 if (mode_mask_ & RelocInfo::kPositionMask) { 430 if (locatable_tag == kCodeWithIdTag) {
366 ReadTaggedData(); 431 if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) {
367 if (SetMode(DebugInfoModeFromTag(GetPositionTypeTag()))) return; 432 ReadTaggedId();
433 return;
434 }
435 } else {
436 // Compact encoding is never used for comments,
437 // so it must be a position.
438 ASSERT(locatable_tag == kNonstatementPositionTag ||
439 locatable_tag == kStatementPositionTag);
440 if (mode_mask_ & RelocInfo::kPositionMask) {
441 ReadTaggedPosition();
442 if (SetMode(GetPositionModeFromTag(locatable_tag))) return;
443 }
368 } 444 }
369 } else { 445 } else {
370 ASSERT(tag == kDefaultTag); 446 ASSERT(tag == kDefaultTag);
371 int extra_tag = GetExtraTag(); 447 int extra_tag = GetExtraTag();
372 if (extra_tag == kPCJumpTag) { 448 if (extra_tag == kPCJumpTag) {
373 int top_tag = GetTopTag(); 449 int top_tag = GetTopTag();
374 if (top_tag == kVariableLengthPCJumpTopTag) { 450 if (top_tag == kVariableLengthPCJumpTopTag) {
375 AdvanceReadVariableLengthPCJump(); 451 AdvanceReadVariableLengthPCJump();
376 } else { 452 } else {
377 AdvanceReadPC(); 453 AdvanceReadPC();
378 } 454 }
379 } else if (extra_tag == kDataJumpTag) { 455 } else if (extra_tag == kDataJumpTag) {
380 // Check if we want debug modes (the only ones with data). 456 int locatable_tag = GetTopTag();
381 if (mode_mask_ & RelocInfo::kDebugMask) { 457 if (locatable_tag == kCodeWithIdTag) {
382 int top_tag = GetTopTag(); 458 if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) {
383 AdvanceReadData(); 459 AdvanceReadId();
384 if (SetMode(DebugInfoModeFromTag(top_tag))) return; 460 return;
461 }
462 Advance(kIntSize);
463 } else if (locatable_tag != kCommentTag) {
464 ASSERT(locatable_tag == kNonstatementPositionTag ||
465 locatable_tag == kStatementPositionTag);
466 if (mode_mask_ & RelocInfo::kPositionMask) {
467 AdvanceReadPosition();
468 if (SetMode(GetPositionModeFromTag(locatable_tag))) return;
469 } else {
470 Advance(kIntSize);
471 }
385 } else { 472 } else {
386 // Otherwise, just skip over the data. 473 ASSERT(locatable_tag == kCommentTag);
474 if (SetMode(RelocInfo::COMMENT)) {
475 AdvanceReadData();
476 return;
477 }
387 Advance(kIntptrSize); 478 Advance(kIntptrSize);
388 } 479 }
389 } else { 480 } else {
390 AdvanceReadPC(); 481 AdvanceReadPC();
391 if (SetMode(static_cast<RelocInfo::Mode>(extra_tag))) return; 482 int rmode = extra_tag + RelocInfo::LAST_COMPACT_ENUM;
483 if (SetMode(static_cast<RelocInfo::Mode>(rmode))) return;
392 } 484 }
393 } 485 }
394 } 486 }
395 done_ = true; 487 done_ = true;
396 } 488 }
397 489
398 490
399 RelocIterator::RelocIterator(Code* code, int mode_mask) { 491 RelocIterator::RelocIterator(Code* code, int mode_mask) {
400 rinfo_.pc_ = code->instruction_start(); 492 rinfo_.pc_ = code->instruction_start();
401 rinfo_.data_ = 0; 493 rinfo_.data_ = 0;
402 // Relocation info is read backwards. 494 // Relocation info is read backwards.
403 pos_ = code->relocation_start() + code->relocation_size(); 495 pos_ = code->relocation_start() + code->relocation_size();
404 end_ = code->relocation_start(); 496 end_ = code->relocation_start();
405 done_ = false; 497 done_ = false;
406 mode_mask_ = mode_mask; 498 mode_mask_ = mode_mask;
499 last_id_ = 0;
500 last_position_ = 0;
407 if (mode_mask_ == 0) pos_ = end_; 501 if (mode_mask_ == 0) pos_ = end_;
408 next(); 502 next();
409 } 503 }
410 504
411 505
412 RelocIterator::RelocIterator(const CodeDesc& desc, int mode_mask) { 506 RelocIterator::RelocIterator(const CodeDesc& desc, int mode_mask) {
413 rinfo_.pc_ = desc.buffer; 507 rinfo_.pc_ = desc.buffer;
414 rinfo_.data_ = 0; 508 rinfo_.data_ = 0;
415 // Relocation info is read backwards. 509 // Relocation info is read backwards.
416 pos_ = desc.buffer + desc.buffer_size; 510 pos_ = desc.buffer + desc.buffer_size;
417 end_ = pos_ - desc.reloc_size; 511 end_ = pos_ - desc.reloc_size;
418 done_ = false; 512 done_ = false;
419 mode_mask_ = mode_mask; 513 mode_mask_ = mode_mask;
514 last_id_ = 0;
515 last_position_ = 0;
420 if (mode_mask_ == 0) pos_ = end_; 516 if (mode_mask_ == 0) pos_ = end_;
421 next(); 517 next();
422 } 518 }
423 519
424 520
425 // ----------------------------------------------------------------------------- 521 // -----------------------------------------------------------------------------
426 // Implementation of RelocInfo 522 // Implementation of RelocInfo
427 523
428 524
429 #ifdef ENABLE_DISASSEMBLER 525 #ifdef ENABLE_DISASSEMBLER
430 const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) { 526 const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
431 switch (rmode) { 527 switch (rmode) {
432 case RelocInfo::NONE: 528 case RelocInfo::NONE:
433 return "no reloc"; 529 return "no reloc";
434 case RelocInfo::EMBEDDED_OBJECT: 530 case RelocInfo::EMBEDDED_OBJECT:
435 return "embedded object"; 531 return "embedded object";
436 case RelocInfo::CONSTRUCT_CALL: 532 case RelocInfo::CONSTRUCT_CALL:
437 return "code target (js construct call)"; 533 return "code target (js construct call)";
438 case RelocInfo::CODE_TARGET_CONTEXT: 534 case RelocInfo::CODE_TARGET_CONTEXT:
439 return "code target (context)"; 535 return "code target (context)";
440 case RelocInfo::DEBUG_BREAK: 536 case RelocInfo::DEBUG_BREAK:
441 #ifndef ENABLE_DEBUGGER_SUPPORT 537 #ifndef ENABLE_DEBUGGER_SUPPORT
442 UNREACHABLE(); 538 UNREACHABLE();
443 #endif 539 #endif
444 return "debug break"; 540 return "debug break";
445 case RelocInfo::CODE_TARGET: 541 case RelocInfo::CODE_TARGET:
446 return "code target"; 542 return "code target";
543 case RelocInfo::CODE_TARGET_WITH_ID:
544 return "code target with id";
447 case RelocInfo::GLOBAL_PROPERTY_CELL: 545 case RelocInfo::GLOBAL_PROPERTY_CELL:
448 return "global property cell"; 546 return "global property cell";
449 case RelocInfo::RUNTIME_ENTRY: 547 case RelocInfo::RUNTIME_ENTRY:
450 return "runtime entry"; 548 return "runtime entry";
451 case RelocInfo::JS_RETURN: 549 case RelocInfo::JS_RETURN:
452 return "js return"; 550 return "js return";
453 case RelocInfo::COMMENT: 551 case RelocInfo::COMMENT:
454 return "comment"; 552 return "comment";
455 case RelocInfo::POSITION: 553 case RelocInfo::POSITION:
456 return "position"; 554 return "position";
(...skipping 26 matching lines...) Expand all
483 PrintF(out, ")"); 581 PrintF(out, ")");
484 } else if (rmode_ == EXTERNAL_REFERENCE) { 582 } else if (rmode_ == EXTERNAL_REFERENCE) {
485 ExternalReferenceEncoder ref_encoder; 583 ExternalReferenceEncoder ref_encoder;
486 PrintF(out, " (%s) (%p)", 584 PrintF(out, " (%s) (%p)",
487 ref_encoder.NameOfAddress(*target_reference_address()), 585 ref_encoder.NameOfAddress(*target_reference_address()),
488 *target_reference_address()); 586 *target_reference_address());
489 } else if (IsCodeTarget(rmode_)) { 587 } else if (IsCodeTarget(rmode_)) {
490 Code* code = Code::GetCodeFromTargetAddress(target_address()); 588 Code* code = Code::GetCodeFromTargetAddress(target_address());
491 PrintF(out, " (%s) (%p)", Code::Kind2String(code->kind()), 589 PrintF(out, " (%s) (%p)", Code::Kind2String(code->kind()),
492 target_address()); 590 target_address());
591 if (rmode_ == CODE_TARGET_WITH_ID) {
592 PrintF(" (id=%d)", static_cast<int>(data_));
593 }
493 } else if (IsPosition(rmode_)) { 594 } else if (IsPosition(rmode_)) {
494 PrintF(out, " (%" V8_PTR_PREFIX "d)", data()); 595 PrintF(out, " (%" V8_PTR_PREFIX "d)", data());
495 } else if (rmode_ == RelocInfo::RUNTIME_ENTRY && 596 } else if (rmode_ == RelocInfo::RUNTIME_ENTRY &&
496 Isolate::Current()->deoptimizer_data() != NULL) { 597 Isolate::Current()->deoptimizer_data() != NULL) {
497 // Depotimization bailouts are stored as runtime entries. 598 // Depotimization bailouts are stored as runtime entries.
498 int id = Deoptimizer::GetDeoptimizationId( 599 int id = Deoptimizer::GetDeoptimizationId(
499 target_address(), Deoptimizer::EAGER); 600 target_address(), Deoptimizer::EAGER);
500 if (id != Deoptimizer::kNotDeoptimizationEntry) { 601 if (id != Deoptimizer::kNotDeoptimizationEntry) {
501 PrintF(out, " (deoptimization bailout %d)", id); 602 PrintF(out, " (deoptimization bailout %d)", id);
502 } 603 }
(...skipping 13 matching lines...) Expand all
516 case GLOBAL_PROPERTY_CELL: 617 case GLOBAL_PROPERTY_CELL:
517 Object::VerifyPointer(target_cell()); 618 Object::VerifyPointer(target_cell());
518 break; 619 break;
519 case DEBUG_BREAK: 620 case DEBUG_BREAK:
520 #ifndef ENABLE_DEBUGGER_SUPPORT 621 #ifndef ENABLE_DEBUGGER_SUPPORT
521 UNREACHABLE(); 622 UNREACHABLE();
522 break; 623 break;
523 #endif 624 #endif
524 case CONSTRUCT_CALL: 625 case CONSTRUCT_CALL:
525 case CODE_TARGET_CONTEXT: 626 case CODE_TARGET_CONTEXT:
627 case CODE_TARGET_WITH_ID:
526 case CODE_TARGET: { 628 case CODE_TARGET: {
527 // convert inline target address to code object 629 // convert inline target address to code object
528 Address addr = target_address(); 630 Address addr = target_address();
529 ASSERT(addr != NULL); 631 ASSERT(addr != NULL);
530 // Check that we can find the right code object. 632 // Check that we can find the right code object.
531 Code* code = Code::GetCodeFromTargetAddress(addr); 633 Code* code = Code::GetCodeFromTargetAddress(addr);
532 Object* found = HEAP->FindCodeObject(addr); 634 Object* found = HEAP->FindCodeObject(addr);
533 ASSERT(found->IsCode()); 635 ASSERT(found->IsCode());
534 ASSERT(code->address() == HeapObject::cast(found)->address()); 636 ASSERT(code->address() == HeapObject::cast(found)->address());
535 break; 637 break;
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position); 1161 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position);
1060 state_.written_position = state_.current_position; 1162 state_.written_position = state_.current_position;
1061 written = true; 1163 written = true;
1062 } 1164 }
1063 1165
1064 // Return whether something was written. 1166 // Return whether something was written.
1065 return written; 1167 return written;
1066 } 1168 }
1067 1169
1068 } } // namespace v8::internal 1170 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698