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

Side by Side Diff: src/assembler.cc

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