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

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: last change 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
« no previous file with comments | « src/assembler.h ('k') | src/disassembler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 if (pos_ < 0) return -pos_ - 1; 80 if (pos_ < 0) return -pos_ - 1;
81 if (pos_ > 0) return pos_ - 1; 81 if (pos_ > 0) return pos_ - 1;
82 UNREACHABLE(); 82 UNREACHABLE();
83 return 0; 83 return 0;
84 } 84 }
85 85
86 86
87 // ----------------------------------------------------------------------------- 87 // -----------------------------------------------------------------------------
88 // Implementation of RelocInfoWriter and RelocIterator 88 // Implementation of RelocInfoWriter and RelocIterator
89 // 89 //
90 // Relocation information is written backwards in memory, from high addresses
91 // towards low addresses, byte by byte. Therefore, in the encodings listed
92 // below, the first byte listed it at the highest address, and successive
93 // bytes in the record are at progressively lower addresses.
94 //
90 // Encoding 95 // Encoding
91 // 96 //
92 // The most common modes are given single-byte encodings. Also, it is 97 // 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 98 // easy to identify the type of reloc info and skip unwanted modes in
94 // an iteration. 99 // an iteration.
95 // 100 //
96 // The encoding relies on the fact that there are less than 14 101 // The encoding relies on the fact that there are fewer than 14
97 // different relocation modes. 102 // different non-compactly encoded relocation modes.
98 // 103 //
99 // embedded_object: [6 bits pc delta] 00 104 // The first byte of a relocation record has a tag in its low 2 bits:
105 // Here are the record schemes, depending on the low tag and optional higher
106 // tags.
100 // 107 //
101 // code_taget: [6 bits pc delta] 01 108 // Low tag:
109 // 00: embedded_object: [6-bit pc delta] 00
102 // 110 //
103 // position: [6 bits pc delta] 10, 111 // 01: code_target: [6-bit pc delta] 01
104 // [7 bits signed data delta] 0
105 // 112 //
106 // statement_position: [6 bits pc delta] 10, 113 // 10: short_data_record: [6-bit pc delta] 10 followed by
107 // [7 bits signed data delta] 1 114 // [6-bit data delta] [2-bit data type tag]
108 // 115 //
109 // any nondata mode: 00 [4 bits rmode] 11, // rmode: 0..13 only 116 // 11: long_record [2-bit high tag][4 bit middle_tag] 11
110 // 00 [6 bits pc delta] 117 // followed by variable data depending on type.
111 // 118 //
112 // pc-jump: 00 1111 11, 119 // 2-bit data type tags, used in short_data_record and data_jump long_record:
113 // 00 [6 bits pc delta] 120 // code_target_with_id: 00
121 // position: 01
122 // statement_position: 10
123 // comment: 11 (not used in short_data_record)
114 // 124 //
115 // pc-jump: 01 1111 11, 125 // Long record format:
116 // (variable length) 7 - 26 bit pc delta, written in chunks of 7 126 // 4-bit middle_tag:
117 // bits, the lowest 7 bits written first. 127 // 0000 - 1100 : Short record for RelocInfo::Mode middle_tag + 2
128 // (The middle_tag encodes rmode - RelocInfo::LAST_COMPACT_ENUM,
129 // and is between 0000 and 1100)
130 // The format is:
131 // 00 [4 bit middle_tag] 11 followed by
132 // 00 [6 bit pc delta]
118 // 133 //
119 // data-jump + pos: 00 1110 11, 134 // 1101: not used (would allow one more relocation mode to be added)
120 // signed intptr_t, lowest byte written first 135 // 1110: long_data_record
136 // The format is: [2-bit data_type_tag] 1110 11
137 // signed intptr_t, lowest byte written first
138 // (except data_type code_target_with_id, which
139 // is followed by a signed int, not intptr_t.)
121 // 140 //
122 // data-jump + st.pos: 01 1110 11, 141 // 1111: long_pc_jump
123 // signed intptr_t, lowest byte written first 142 // The format is:
124 // 143 // pc-jump: 00 1111 11,
125 // data-jump + comm.: 10 1110 11, 144 // 00 [6 bits pc delta]
126 // signed intptr_t, lowest byte written first 145 // or
127 // 146 // pc-jump (variable length):
147 // 01 1111 11,
148 // [7 bits data] 0
149 // ...
150 // [7 bits data] 1
151 // (Bits 6..31 of pc delta, with leading zeroes
152 // dropped, and last non-zero chunk tagged with 1.)
153
154
128 const int kMaxRelocModes = 14; 155 const int kMaxRelocModes = 14;
129 156
130 const int kTagBits = 2; 157 const int kTagBits = 2;
131 const int kTagMask = (1 << kTagBits) - 1; 158 const int kTagMask = (1 << kTagBits) - 1;
132 const int kExtraTagBits = 4; 159 const int kExtraTagBits = 4;
133 const int kPositionTypeTagBits = 1; 160 const int kLocatableTypeTagBits = 2;
134 const int kSmallDataBits = kBitsPerByte - kPositionTypeTagBits; 161 const int kSmallDataBits = kBitsPerByte - kLocatableTypeTagBits;
135 162
136 const int kEmbeddedObjectTag = 0; 163 const int kEmbeddedObjectTag = 0;
137 const int kCodeTargetTag = 1; 164 const int kCodeTargetTag = 1;
138 const int kPositionTag = 2; 165 const int kLocatableTag = 2;
139 const int kDefaultTag = 3; 166 const int kDefaultTag = 3;
140 167
141 const int kPCJumpTag = (1 << kExtraTagBits) - 1; 168 const int kPCJumpExtraTag = (1 << kExtraTagBits) - 1;
142 169
143 const int kSmallPCDeltaBits = kBitsPerByte - kTagBits; 170 const int kSmallPCDeltaBits = kBitsPerByte - kTagBits;
144 const int kSmallPCDeltaMask = (1 << kSmallPCDeltaBits) - 1; 171 const int kSmallPCDeltaMask = (1 << kSmallPCDeltaBits) - 1;
145 const int RelocInfo::kMaxSmallPCDelta = kSmallPCDeltaMask; 172 const int RelocInfo::kMaxSmallPCDelta = kSmallPCDeltaMask;
146 173
147 const int kVariableLengthPCJumpTopTag = 1; 174 const int kVariableLengthPCJumpTopTag = 1;
148 const int kChunkBits = 7; 175 const int kChunkBits = 7;
149 const int kChunkMask = (1 << kChunkBits) - 1; 176 const int kChunkMask = (1 << kChunkBits) - 1;
150 const int kLastChunkTagBits = 1; 177 const int kLastChunkTagBits = 1;
151 const int kLastChunkTagMask = 1; 178 const int kLastChunkTagMask = 1;
152 const int kLastChunkTag = 1; 179 const int kLastChunkTag = 1;
153 180
154 181
155 const int kDataJumpTag = kPCJumpTag - 1; 182 const int kDataJumpExtraTag = kPCJumpExtraTag - 1;
156 183
157 const int kNonstatementPositionTag = 0; 184 const int kCodeWithIdTag = 0;
158 const int kStatementPositionTag = 1; 185 const int kNonstatementPositionTag = 1;
159 const int kCommentTag = 2; 186 const int kStatementPositionTag = 2;
187 const int kCommentTag = 3;
160 188
161 189
162 uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) { 190 uint32_t RelocInfoWriter::WriteVariableLengthPCJump(uint32_t pc_delta) {
163 // Return if the pc_delta can fit in kSmallPCDeltaBits bits. 191 // Return if the pc_delta can fit in kSmallPCDeltaBits bits.
164 // Otherwise write a variable length PC jump for the bits that do 192 // Otherwise write a variable length PC jump for the bits that do
165 // not fit in the kSmallPCDeltaBits bits. 193 // not fit in the kSmallPCDeltaBits bits.
166 if (is_uintn(pc_delta, kSmallPCDeltaBits)) return pc_delta; 194 if (is_uintn(pc_delta, kSmallPCDeltaBits)) return pc_delta;
167 WriteExtraTag(kPCJumpTag, kVariableLengthPCJumpTopTag); 195 WriteExtraTag(kPCJumpExtraTag, kVariableLengthPCJumpTopTag);
168 uint32_t pc_jump = pc_delta >> kSmallPCDeltaBits; 196 uint32_t pc_jump = pc_delta >> kSmallPCDeltaBits;
169 ASSERT(pc_jump > 0); 197 ASSERT(pc_jump > 0);
170 // Write kChunkBits size chunks of the pc_jump. 198 // Write kChunkBits size chunks of the pc_jump.
171 for (; pc_jump > 0; pc_jump = pc_jump >> kChunkBits) { 199 for (; pc_jump > 0; pc_jump = pc_jump >> kChunkBits) {
172 byte b = pc_jump & kChunkMask; 200 byte b = pc_jump & kChunkMask;
173 *--pos_ = b << kLastChunkTagBits; 201 *--pos_ = b << kLastChunkTagBits;
174 } 202 }
175 // Tag the last chunk so it can be identified. 203 // Tag the last chunk so it can be identified.
176 *pos_ = *pos_ | kLastChunkTag; 204 *pos_ = *pos_ | kLastChunkTag;
177 // Return the remaining kSmallPCDeltaBits of the pc_delta. 205 // Return the remaining kSmallPCDeltaBits of the pc_delta.
178 return pc_delta & kSmallPCDeltaMask; 206 return pc_delta & kSmallPCDeltaMask;
179 } 207 }
180 208
181 209
182 void RelocInfoWriter::WriteTaggedPC(uint32_t pc_delta, int tag) { 210 void RelocInfoWriter::WriteTaggedPC(uint32_t pc_delta, int tag) {
183 // Write a byte of tagged pc-delta, possibly preceded by var. length pc-jump. 211 // Write a byte of tagged pc-delta, possibly preceded by var. length pc-jump.
184 pc_delta = WriteVariableLengthPCJump(pc_delta); 212 pc_delta = WriteVariableLengthPCJump(pc_delta);
185 *--pos_ = pc_delta << kTagBits | tag; 213 *--pos_ = pc_delta << kTagBits | tag;
186 } 214 }
187 215
188 216
189 void RelocInfoWriter::WriteTaggedData(intptr_t data_delta, int tag) { 217 void RelocInfoWriter::WriteTaggedData(intptr_t data_delta, int tag) {
190 *--pos_ = static_cast<byte>(data_delta << kPositionTypeTagBits | tag); 218 *--pos_ = static_cast<byte>(data_delta << kLocatableTypeTagBits | tag);
191 } 219 }
192 220
193 221
194 void RelocInfoWriter::WriteExtraTag(int extra_tag, int top_tag) { 222 void RelocInfoWriter::WriteExtraTag(int extra_tag, int top_tag) {
195 *--pos_ = static_cast<int>(top_tag << (kTagBits + kExtraTagBits) | 223 *--pos_ = static_cast<int>(top_tag << (kTagBits + kExtraTagBits) |
196 extra_tag << kTagBits | 224 extra_tag << kTagBits |
197 kDefaultTag); 225 kDefaultTag);
198 } 226 }
199 227
200 228
201 void RelocInfoWriter::WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag) { 229 void RelocInfoWriter::WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag) {
202 // Write two-byte tagged pc-delta, possibly preceded by var. length pc-jump. 230 // Write two-byte tagged pc-delta, possibly preceded by var. length pc-jump.
203 pc_delta = WriteVariableLengthPCJump(pc_delta); 231 pc_delta = WriteVariableLengthPCJump(pc_delta);
204 WriteExtraTag(extra_tag, 0); 232 WriteExtraTag(extra_tag, 0);
205 *--pos_ = pc_delta; 233 *--pos_ = pc_delta;
206 } 234 }
207 235
208 236
209 void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) { 237 void RelocInfoWriter::WriteExtraTaggedIntData(int data_delta, int top_tag) {
210 WriteExtraTag(kDataJumpTag, top_tag); 238 WriteExtraTag(kDataJumpExtraTag, top_tag);
211 for (int i = 0; i < kIntptrSize; i++) { 239 for (int i = 0; i < kIntSize; i++) {
212 *--pos_ = static_cast<byte>(data_delta); 240 *--pos_ = static_cast<byte>(data_delta);
213 // Signed right shift is arithmetic shift. Tested in test-utils.cc. 241 // Signed right shift is arithmetic shift. Tested in test-utils.cc.
214 data_delta = data_delta >> kBitsPerByte; 242 data_delta = data_delta >> kBitsPerByte;
215 } 243 }
216 } 244 }
245
246 void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) {
247 WriteExtraTag(kDataJumpExtraTag, top_tag);
248 for (int i = 0; i < kIntptrSize; i++) {
249 *--pos_ = static_cast<byte>(data_delta);
250 // Signed right shift is arithmetic shift. Tested in test-utils.cc.
251 data_delta = data_delta >> kBitsPerByte;
252 }
253 }
217 254
218 255
219 void RelocInfoWriter::Write(const RelocInfo* rinfo) { 256 void RelocInfoWriter::Write(const RelocInfo* rinfo) {
220 #ifdef DEBUG 257 #ifdef DEBUG
221 byte* begin_pos = pos_; 258 byte* begin_pos = pos_;
222 #endif 259 #endif
223 ASSERT(rinfo->pc() - last_pc_ >= 0); 260 ASSERT(rinfo->pc() - last_pc_ >= 0);
224 ASSERT(RelocInfo::NUMBER_OF_MODES <= kMaxRelocModes); 261 ASSERT(RelocInfo::NUMBER_OF_MODES - RelocInfo::LAST_COMPACT_ENUM <=
262 kMaxRelocModes);
225 // Use unsigned delta-encoding for pc. 263 // Use unsigned delta-encoding for pc.
226 uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_); 264 uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_);
227 RelocInfo::Mode rmode = rinfo->rmode(); 265 RelocInfo::Mode rmode = rinfo->rmode();
228 266
229 // The two most common modes are given small tags, and usually fit in a byte. 267 // The two most common modes are given small tags, and usually fit in a byte.
230 if (rmode == RelocInfo::EMBEDDED_OBJECT) { 268 if (rmode == RelocInfo::EMBEDDED_OBJECT) {
231 WriteTaggedPC(pc_delta, kEmbeddedObjectTag); 269 WriteTaggedPC(pc_delta, kEmbeddedObjectTag);
232 } else if (rmode == RelocInfo::CODE_TARGET) { 270 } else if (rmode == RelocInfo::CODE_TARGET) {
233 WriteTaggedPC(pc_delta, kCodeTargetTag); 271 WriteTaggedPC(pc_delta, kCodeTargetTag);
234 ASSERT(begin_pos - pos_ <= RelocInfo::kMaxCallSize); 272 ASSERT(begin_pos - pos_ <= RelocInfo::kMaxCallSize);
235 } else if (RelocInfo::IsPosition(rmode)) { 273 } else if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
236 // Use signed delta-encoding for data. 274 // Use signed delta-encoding for id.
237 intptr_t data_delta = rinfo->data() - last_data_; 275 ASSERT(static_cast<int>(rinfo->data()) == rinfo->data());
238 int pos_type_tag = rmode == RelocInfo::POSITION ? kNonstatementPositionTag 276 int id_delta = static_cast<int>(rinfo->data()) - last_id_;
239 : kStatementPositionTag; 277 // 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. 278 if (is_intn(id_delta, kSmallDataBits)) {
241 // We cannot use is_intn because data_delta is not an int32_t. 279 WriteTaggedPC(pc_delta, kLocatableTag);
242 if (data_delta >= -(1 << (kSmallDataBits-1)) && 280 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 { 281 } else {
248 // Otherwise, use costly encoding. 282 // Otherwise, use costly encoding.
249 WriteExtraTaggedPC(pc_delta, kPCJumpTag); 283 WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
250 WriteExtraTaggedData(data_delta, pos_type_tag); 284 WriteExtraTaggedIntData(id_delta, kCodeWithIdTag);
251 last_data_ = rinfo->data();
252 } 285 }
286 last_id_ = static_cast<int>(rinfo->data());
287 } else if (RelocInfo::IsPosition(rmode)) {
288 // Use signed delta-encoding for position.
289 ASSERT(static_cast<int>(rinfo->data()) == rinfo->data());
290 int pos_delta = static_cast<int>(rinfo->data()) - last_position_;
291 int pos_type_tag = (rmode == RelocInfo::POSITION) ? kNonstatementPositionTag
292 : kStatementPositionTag;
293 // Check if delta is small enough to fit in a tagged byte.
294 if (is_intn(pos_delta, kSmallDataBits)) {
295 WriteTaggedPC(pc_delta, kLocatableTag);
296 WriteTaggedData(pos_delta, pos_type_tag);
297 } else {
298 // Otherwise, use costly encoding.
299 WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
300 WriteExtraTaggedIntData(pos_delta, pos_type_tag);
301 }
302 last_position_ = static_cast<int>(rinfo->data());
253 } else if (RelocInfo::IsComment(rmode)) { 303 } else if (RelocInfo::IsComment(rmode)) {
254 // Comments are normally not generated, so we use the costly encoding. 304 // Comments are normally not generated, so we use the costly encoding.
255 WriteExtraTaggedPC(pc_delta, kPCJumpTag); 305 WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
256 WriteExtraTaggedData(rinfo->data() - last_data_, kCommentTag); 306 WriteExtraTaggedData(rinfo->data(), kCommentTag);
257 last_data_ = rinfo->data();
258 ASSERT(begin_pos - pos_ >= RelocInfo::kMinRelocCommentSize); 307 ASSERT(begin_pos - pos_ >= RelocInfo::kMinRelocCommentSize);
259 } else { 308 } else {
309 ASSERT(rmode > RelocInfo::LAST_COMPACT_ENUM);
310 int saved_mode = rmode - RelocInfo::LAST_COMPACT_ENUM;
260 // For all other modes we simply use the mode as the extra tag. 311 // For all other modes we simply use the mode as the extra tag.
261 // None of these modes need a data component. 312 // None of these modes need a data component.
262 ASSERT(rmode < kPCJumpTag && rmode < kDataJumpTag); 313 ASSERT(saved_mode < kPCJumpExtraTag && saved_mode < kDataJumpExtraTag);
263 WriteExtraTaggedPC(pc_delta, rmode); 314 WriteExtraTaggedPC(pc_delta, saved_mode);
264 } 315 }
265 last_pc_ = rinfo->pc(); 316 last_pc_ = rinfo->pc();
266 #ifdef DEBUG 317 #ifdef DEBUG
267 ASSERT(begin_pos - pos_ <= kMaxSize); 318 ASSERT(begin_pos - pos_ <= kMaxSize);
268 #endif 319 #endif
269 } 320 }
270 321
271 322
272 inline int RelocIterator::AdvanceGetTag() { 323 inline int RelocIterator::AdvanceGetTag() {
273 return *--pos_ & kTagMask; 324 return *--pos_ & kTagMask;
(...skipping 13 matching lines...) Expand all
287 inline void RelocIterator::ReadTaggedPC() { 338 inline void RelocIterator::ReadTaggedPC() {
288 rinfo_.pc_ += *pos_ >> kTagBits; 339 rinfo_.pc_ += *pos_ >> kTagBits;
289 } 340 }
290 341
291 342
292 inline void RelocIterator::AdvanceReadPC() { 343 inline void RelocIterator::AdvanceReadPC() {
293 rinfo_.pc_ += *--pos_; 344 rinfo_.pc_ += *--pos_;
294 } 345 }
295 346
296 347
348 void RelocIterator::AdvanceReadId() {
349 int x = 0;
350 for (int i = 0; i < kIntSize; i++) {
351 x |= static_cast<int>(*--pos_) << i * kBitsPerByte;
352 }
353 last_id_ += x;
354 rinfo_.data_ = last_id_;
355 }
356
357
358 void RelocIterator::AdvanceReadPosition() {
359 int x = 0;
360 for (int i = 0; i < kIntSize; i++) {
361 x |= static_cast<int>(*--pos_) << i * kBitsPerByte;
362 }
363 last_position_ += x;
364 rinfo_.data_ = last_position_;
365 }
366
367
297 void RelocIterator::AdvanceReadData() { 368 void RelocIterator::AdvanceReadData() {
298 intptr_t x = 0; 369 intptr_t x = 0;
299 for (int i = 0; i < kIntptrSize; i++) { 370 for (int i = 0; i < kIntptrSize; i++) {
300 x |= static_cast<intptr_t>(*--pos_) << i * kBitsPerByte; 371 x |= static_cast<intptr_t>(*--pos_) << i * kBitsPerByte;
301 } 372 }
302 rinfo_.data_ += x; 373 rinfo_.data_ = x;
303 } 374 }
304 375
305 376
306 void RelocIterator::AdvanceReadVariableLengthPCJump() { 377 void RelocIterator::AdvanceReadVariableLengthPCJump() {
307 // Read the 32-kSmallPCDeltaBits most significant bits of the 378 // Read the 32-kSmallPCDeltaBits most significant bits of the
308 // pc jump in kChunkBits bit chunks and shift them into place. 379 // pc jump in kChunkBits bit chunks and shift them into place.
309 // Stop when the last chunk is encountered. 380 // Stop when the last chunk is encountered.
310 uint32_t pc_jump = 0; 381 uint32_t pc_jump = 0;
311 for (int i = 0; i < kIntSize; i++) { 382 for (int i = 0; i < kIntSize; i++) {
312 byte pc_jump_part = *--pos_; 383 byte pc_jump_part = *--pos_;
313 pc_jump |= (pc_jump_part >> kLastChunkTagBits) << i * kChunkBits; 384 pc_jump |= (pc_jump_part >> kLastChunkTagBits) << i * kChunkBits;
314 if ((pc_jump_part & kLastChunkTagMask) == 1) break; 385 if ((pc_jump_part & kLastChunkTagMask) == 1) break;
315 } 386 }
316 // The least significant kSmallPCDeltaBits bits will be added 387 // The least significant kSmallPCDeltaBits bits will be added
317 // later. 388 // later.
318 rinfo_.pc_ += pc_jump << kSmallPCDeltaBits; 389 rinfo_.pc_ += pc_jump << kSmallPCDeltaBits;
319 } 390 }
320 391
321 392
322 inline int RelocIterator::GetPositionTypeTag() { 393 inline int RelocIterator::GetLocatableTypeTag() {
323 return *pos_ & ((1 << kPositionTypeTagBits) - 1); 394 return *pos_ & ((1 << kLocatableTypeTagBits) - 1);
324 } 395 }
325 396
326 397
327 inline void RelocIterator::ReadTaggedData() { 398 inline void RelocIterator::ReadTaggedId() {
328 int8_t signed_b = *pos_; 399 int8_t signed_b = *pos_;
329 // Signed right shift is arithmetic shift. Tested in test-utils.cc. 400 // Signed right shift is arithmetic shift. Tested in test-utils.cc.
330 rinfo_.data_ += signed_b >> kPositionTypeTagBits; 401 last_id_ += signed_b >> kLocatableTypeTagBits;
402 rinfo_.data_ = last_id_;
331 } 403 }
332 404
333 405
334 inline RelocInfo::Mode RelocIterator::DebugInfoModeFromTag(int tag) { 406 inline void RelocIterator::ReadTaggedPosition() {
335 if (tag == kStatementPositionTag) { 407 int8_t signed_b = *pos_;
336 return RelocInfo::STATEMENT_POSITION; 408 // Signed right shift is arithmetic shift. Tested in test-utils.cc.
337 } else if (tag == kNonstatementPositionTag) { 409 last_position_ += signed_b >> kLocatableTypeTagBits;
338 return RelocInfo::POSITION; 410 rinfo_.data_ = last_position_;
339 } else {
340 ASSERT(tag == kCommentTag);
341 return RelocInfo::COMMENT;
342 }
343 } 411 }
344 412
345 413
414 static inline RelocInfo::Mode GetPositionModeFromTag(int tag) {
415 ASSERT(tag == kNonstatementPositionTag ||
416 tag == kStatementPositionTag);
417 return (tag == kNonstatementPositionTag) ?
418 RelocInfo::POSITION :
419 RelocInfo::STATEMENT_POSITION;
420 }
421
422
346 void RelocIterator::next() { 423 void RelocIterator::next() {
347 ASSERT(!done()); 424 ASSERT(!done());
348 // Basically, do the opposite of RelocInfoWriter::Write. 425 // Basically, do the opposite of RelocInfoWriter::Write.
349 // Reading of data is as far as possible avoided for unwanted modes, 426 // Reading of data is as far as possible avoided for unwanted modes,
350 // but we must always update the pc. 427 // but we must always update the pc.
351 // 428 //
352 // We exit this loop by returning when we find a mode we want. 429 // We exit this loop by returning when we find a mode we want.
353 while (pos_ > end_) { 430 while (pos_ > end_) {
354 int tag = AdvanceGetTag(); 431 int tag = AdvanceGetTag();
355 if (tag == kEmbeddedObjectTag) { 432 if (tag == kEmbeddedObjectTag) {
356 ReadTaggedPC(); 433 ReadTaggedPC();
357 if (SetMode(RelocInfo::EMBEDDED_OBJECT)) return; 434 if (SetMode(RelocInfo::EMBEDDED_OBJECT)) return;
358 } else if (tag == kCodeTargetTag) { 435 } else if (tag == kCodeTargetTag) {
359 ReadTaggedPC(); 436 ReadTaggedPC();
360 if (SetMode(RelocInfo::CODE_TARGET)) return; 437 if (SetMode(RelocInfo::CODE_TARGET)) return;
361 } else if (tag == kPositionTag) { 438 } else if (tag == kLocatableTag) {
362 ReadTaggedPC(); 439 ReadTaggedPC();
363 Advance(); 440 Advance();
364 // Check if we want source positions. 441 int locatable_tag = GetLocatableTypeTag();
365 if (mode_mask_ & RelocInfo::kPositionMask) { 442 if (locatable_tag == kCodeWithIdTag) {
366 ReadTaggedData(); 443 if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) {
367 if (SetMode(DebugInfoModeFromTag(GetPositionTypeTag()))) return; 444 ReadTaggedId();
445 return;
446 }
447 } else {
448 // Compact encoding is never used for comments,
449 // so it must be a position.
450 ASSERT(locatable_tag == kNonstatementPositionTag ||
451 locatable_tag == kStatementPositionTag);
452 if (mode_mask_ & RelocInfo::kPositionMask) {
453 ReadTaggedPosition();
454 if (SetMode(GetPositionModeFromTag(locatable_tag))) return;
455 }
368 } 456 }
369 } else { 457 } else {
370 ASSERT(tag == kDefaultTag); 458 ASSERT(tag == kDefaultTag);
371 int extra_tag = GetExtraTag(); 459 int extra_tag = GetExtraTag();
372 if (extra_tag == kPCJumpTag) { 460 if (extra_tag == kPCJumpExtraTag) {
373 int top_tag = GetTopTag(); 461 int top_tag = GetTopTag();
374 if (top_tag == kVariableLengthPCJumpTopTag) { 462 if (top_tag == kVariableLengthPCJumpTopTag) {
375 AdvanceReadVariableLengthPCJump(); 463 AdvanceReadVariableLengthPCJump();
376 } else { 464 } else {
377 AdvanceReadPC(); 465 AdvanceReadPC();
378 } 466 }
379 } else if (extra_tag == kDataJumpTag) { 467 } else if (extra_tag == kDataJumpExtraTag) {
380 // Check if we want debug modes (the only ones with data). 468 int locatable_tag = GetTopTag();
381 if (mode_mask_ & RelocInfo::kDebugMask) { 469 if (locatable_tag == kCodeWithIdTag) {
382 int top_tag = GetTopTag(); 470 if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) {
383 AdvanceReadData(); 471 AdvanceReadId();
384 if (SetMode(DebugInfoModeFromTag(top_tag))) return; 472 return;
473 }
474 Advance(kIntSize);
475 } else if (locatable_tag != kCommentTag) {
476 ASSERT(locatable_tag == kNonstatementPositionTag ||
477 locatable_tag == kStatementPositionTag);
478 if (mode_mask_ & RelocInfo::kPositionMask) {
479 AdvanceReadPosition();
480 if (SetMode(GetPositionModeFromTag(locatable_tag))) return;
481 } else {
482 Advance(kIntSize);
483 }
385 } else { 484 } else {
386 // Otherwise, just skip over the data. 485 ASSERT(locatable_tag == kCommentTag);
486 if (SetMode(RelocInfo::COMMENT)) {
487 AdvanceReadData();
488 return;
489 }
387 Advance(kIntptrSize); 490 Advance(kIntptrSize);
388 } 491 }
389 } else { 492 } else {
390 AdvanceReadPC(); 493 AdvanceReadPC();
391 if (SetMode(static_cast<RelocInfo::Mode>(extra_tag))) return; 494 int rmode = extra_tag + RelocInfo::LAST_COMPACT_ENUM;
495 if (SetMode(static_cast<RelocInfo::Mode>(rmode))) return;
392 } 496 }
393 } 497 }
394 } 498 }
395 done_ = true; 499 done_ = true;
396 } 500 }
397 501
398 502
399 RelocIterator::RelocIterator(Code* code, int mode_mask) { 503 RelocIterator::RelocIterator(Code* code, int mode_mask) {
400 rinfo_.pc_ = code->instruction_start(); 504 rinfo_.pc_ = code->instruction_start();
401 rinfo_.data_ = 0; 505 rinfo_.data_ = 0;
402 // Relocation info is read backwards. 506 // Relocation info is read backwards.
403 pos_ = code->relocation_start() + code->relocation_size(); 507 pos_ = code->relocation_start() + code->relocation_size();
404 end_ = code->relocation_start(); 508 end_ = code->relocation_start();
405 done_ = false; 509 done_ = false;
406 mode_mask_ = mode_mask; 510 mode_mask_ = mode_mask;
511 last_id_ = 0;
512 last_position_ = 0;
407 if (mode_mask_ == 0) pos_ = end_; 513 if (mode_mask_ == 0) pos_ = end_;
408 next(); 514 next();
409 } 515 }
410 516
411 517
412 RelocIterator::RelocIterator(const CodeDesc& desc, int mode_mask) { 518 RelocIterator::RelocIterator(const CodeDesc& desc, int mode_mask) {
413 rinfo_.pc_ = desc.buffer; 519 rinfo_.pc_ = desc.buffer;
414 rinfo_.data_ = 0; 520 rinfo_.data_ = 0;
415 // Relocation info is read backwards. 521 // Relocation info is read backwards.
416 pos_ = desc.buffer + desc.buffer_size; 522 pos_ = desc.buffer + desc.buffer_size;
417 end_ = pos_ - desc.reloc_size; 523 end_ = pos_ - desc.reloc_size;
418 done_ = false; 524 done_ = false;
419 mode_mask_ = mode_mask; 525 mode_mask_ = mode_mask;
526 last_id_ = 0;
527 last_position_ = 0;
420 if (mode_mask_ == 0) pos_ = end_; 528 if (mode_mask_ == 0) pos_ = end_;
421 next(); 529 next();
422 } 530 }
423 531
424 532
425 // ----------------------------------------------------------------------------- 533 // -----------------------------------------------------------------------------
426 // Implementation of RelocInfo 534 // Implementation of RelocInfo
427 535
428 536
429 #ifdef ENABLE_DISASSEMBLER 537 #ifdef ENABLE_DISASSEMBLER
430 const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) { 538 const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
431 switch (rmode) { 539 switch (rmode) {
432 case RelocInfo::NONE: 540 case RelocInfo::NONE:
433 return "no reloc"; 541 return "no reloc";
434 case RelocInfo::EMBEDDED_OBJECT: 542 case RelocInfo::EMBEDDED_OBJECT:
435 return "embedded object"; 543 return "embedded object";
436 case RelocInfo::CONSTRUCT_CALL: 544 case RelocInfo::CONSTRUCT_CALL:
437 return "code target (js construct call)"; 545 return "code target (js construct call)";
438 case RelocInfo::CODE_TARGET_CONTEXT: 546 case RelocInfo::CODE_TARGET_CONTEXT:
439 return "code target (context)"; 547 return "code target (context)";
440 case RelocInfo::DEBUG_BREAK: 548 case RelocInfo::DEBUG_BREAK:
441 #ifndef ENABLE_DEBUGGER_SUPPORT 549 #ifndef ENABLE_DEBUGGER_SUPPORT
442 UNREACHABLE(); 550 UNREACHABLE();
443 #endif 551 #endif
444 return "debug break"; 552 return "debug break";
445 case RelocInfo::CODE_TARGET: 553 case RelocInfo::CODE_TARGET:
446 return "code target"; 554 return "code target";
555 case RelocInfo::CODE_TARGET_WITH_ID:
556 return "code target with id";
447 case RelocInfo::GLOBAL_PROPERTY_CELL: 557 case RelocInfo::GLOBAL_PROPERTY_CELL:
448 return "global property cell"; 558 return "global property cell";
449 case RelocInfo::RUNTIME_ENTRY: 559 case RelocInfo::RUNTIME_ENTRY:
450 return "runtime entry"; 560 return "runtime entry";
451 case RelocInfo::JS_RETURN: 561 case RelocInfo::JS_RETURN:
452 return "js return"; 562 return "js return";
453 case RelocInfo::COMMENT: 563 case RelocInfo::COMMENT:
454 return "comment"; 564 return "comment";
455 case RelocInfo::POSITION: 565 case RelocInfo::POSITION:
456 return "position"; 566 return "position";
(...skipping 26 matching lines...) Expand all
483 PrintF(out, ")"); 593 PrintF(out, ")");
484 } else if (rmode_ == EXTERNAL_REFERENCE) { 594 } else if (rmode_ == EXTERNAL_REFERENCE) {
485 ExternalReferenceEncoder ref_encoder; 595 ExternalReferenceEncoder ref_encoder;
486 PrintF(out, " (%s) (%p)", 596 PrintF(out, " (%s) (%p)",
487 ref_encoder.NameOfAddress(*target_reference_address()), 597 ref_encoder.NameOfAddress(*target_reference_address()),
488 *target_reference_address()); 598 *target_reference_address());
489 } else if (IsCodeTarget(rmode_)) { 599 } else if (IsCodeTarget(rmode_)) {
490 Code* code = Code::GetCodeFromTargetAddress(target_address()); 600 Code* code = Code::GetCodeFromTargetAddress(target_address());
491 PrintF(out, " (%s) (%p)", Code::Kind2String(code->kind()), 601 PrintF(out, " (%s) (%p)", Code::Kind2String(code->kind()),
492 target_address()); 602 target_address());
603 if (rmode_ == CODE_TARGET_WITH_ID) {
604 PrintF(" (id=%d)", static_cast<int>(data_));
605 }
493 } else if (IsPosition(rmode_)) { 606 } else if (IsPosition(rmode_)) {
494 PrintF(out, " (%" V8_PTR_PREFIX "d)", data()); 607 PrintF(out, " (%" V8_PTR_PREFIX "d)", data());
495 } else if (rmode_ == RelocInfo::RUNTIME_ENTRY && 608 } else if (rmode_ == RelocInfo::RUNTIME_ENTRY &&
496 Isolate::Current()->deoptimizer_data() != NULL) { 609 Isolate::Current()->deoptimizer_data() != NULL) {
497 // Depotimization bailouts are stored as runtime entries. 610 // Depotimization bailouts are stored as runtime entries.
498 int id = Deoptimizer::GetDeoptimizationId( 611 int id = Deoptimizer::GetDeoptimizationId(
499 target_address(), Deoptimizer::EAGER); 612 target_address(), Deoptimizer::EAGER);
500 if (id != Deoptimizer::kNotDeoptimizationEntry) { 613 if (id != Deoptimizer::kNotDeoptimizationEntry) {
501 PrintF(out, " (deoptimization bailout %d)", id); 614 PrintF(out, " (deoptimization bailout %d)", id);
502 } 615 }
(...skipping 13 matching lines...) Expand all
516 case GLOBAL_PROPERTY_CELL: 629 case GLOBAL_PROPERTY_CELL:
517 Object::VerifyPointer(target_cell()); 630 Object::VerifyPointer(target_cell());
518 break; 631 break;
519 case DEBUG_BREAK: 632 case DEBUG_BREAK:
520 #ifndef ENABLE_DEBUGGER_SUPPORT 633 #ifndef ENABLE_DEBUGGER_SUPPORT
521 UNREACHABLE(); 634 UNREACHABLE();
522 break; 635 break;
523 #endif 636 #endif
524 case CONSTRUCT_CALL: 637 case CONSTRUCT_CALL:
525 case CODE_TARGET_CONTEXT: 638 case CODE_TARGET_CONTEXT:
639 case CODE_TARGET_WITH_ID:
526 case CODE_TARGET: { 640 case CODE_TARGET: {
527 // convert inline target address to code object 641 // convert inline target address to code object
528 Address addr = target_address(); 642 Address addr = target_address();
529 ASSERT(addr != NULL); 643 ASSERT(addr != NULL);
530 // Check that we can find the right code object. 644 // Check that we can find the right code object.
531 Code* code = Code::GetCodeFromTargetAddress(addr); 645 Code* code = Code::GetCodeFromTargetAddress(addr);
532 Object* found = HEAP->FindCodeObject(addr); 646 Object* found = HEAP->FindCodeObject(addr);
533 ASSERT(found->IsCode()); 647 ASSERT(found->IsCode());
534 ASSERT(code->address() == HeapObject::cast(found)->address()); 648 ASSERT(code->address() == HeapObject::cast(found)->address());
535 break; 649 break;
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position); 1173 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position);
1060 state_.written_position = state_.current_position; 1174 state_.written_position = state_.current_position;
1061 written = true; 1175 written = true;
1062 } 1176 }
1063 1177
1064 // Return whether something was written. 1178 // Return whether something was written.
1065 return written; 1179 return written;
1066 } 1180 }
1067 1181
1068 } } // namespace v8::internal 1182 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/assembler.h ('k') | src/disassembler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698