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

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 fixes in response to comments. 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 //
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,
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 kPCJumpExtraTag = (1 << kExtraTagBits) - 1;
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 kDataJumpExtraTag = kPCJumpExtraTag - 1;
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(kPCJumpExtraTag, 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);
170 // Write kChunkBits size chunks of the pc_jump. 185 // Write kChunkBits size chunks of the pc_jump.
171 for (; pc_jump > 0; pc_jump = pc_jump >> kChunkBits) { 186 for (; pc_jump > 0; pc_jump = pc_jump >> kChunkBits) {
172 byte b = pc_jump & kChunkMask; 187 byte b = pc_jump & kChunkMask;
173 *--pos_ = b << kLastChunkTagBits; 188 *--pos_ = b << kLastChunkTagBits;
174 } 189 }
175 // Tag the last chunk so it can be identified. 190 // Tag the last chunk so it can be identified.
176 *pos_ = *pos_ | kLastChunkTag; 191 *pos_ = *pos_ | kLastChunkTag;
177 // Return the remaining kSmallPCDeltaBits of the pc_delta. 192 // Return the remaining kSmallPCDeltaBits of the pc_delta.
178 return pc_delta & kSmallPCDeltaMask; 193 return pc_delta & kSmallPCDeltaMask;
179 } 194 }
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
209 void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) { 224 void RelocInfoWriter::WriteExtraTaggedIntData(int data_delta, int top_tag) {
210 WriteExtraTag(kDataJumpTag, top_tag); 225 WriteExtraTag(kDataJumpExtraTag, top_tag);
211 for (int i = 0; i < kIntptrSize; i++) { 226 for (int i = 0; i < kIntSize; i++) {
212 *--pos_ = static_cast<byte>(data_delta); 227 *--pos_ = static_cast<byte>(data_delta);
213 // Signed right shift is arithmetic shift. Tested in test-utils.cc. 228 // Signed right shift is arithmetic shift. Tested in test-utils.cc.
214 data_delta = data_delta >> kBitsPerByte; 229 data_delta = data_delta >> kBitsPerByte;
215 } 230 }
216 } 231 }
232
233 void RelocInfoWriter::WriteExtraTaggedData(intptr_t data_delta, int top_tag) {
234 WriteExtraTag(kDataJumpExtraTag, top_tag);
235 for (int i = 0; i < kIntptrSize; i++) {
236 *--pos_ = static_cast<byte>(data_delta);
237 // Signed right shift is arithmetic shift. Tested in test-utils.cc.
238 data_delta = data_delta >> kBitsPerByte;
239 }
240 }
217 241
218 242
219 void RelocInfoWriter::Write(const RelocInfo* rinfo) { 243 void RelocInfoWriter::Write(const RelocInfo* rinfo) {
220 #ifdef DEBUG 244 #ifdef DEBUG
221 byte* begin_pos = pos_; 245 byte* begin_pos = pos_;
222 #endif 246 #endif
223 ASSERT(rinfo->pc() - last_pc_ >= 0); 247 ASSERT(rinfo->pc() - last_pc_ >= 0);
224 ASSERT(RelocInfo::NUMBER_OF_MODES <= kMaxRelocModes); 248 ASSERT(RelocInfo::NUMBER_OF_MODES - RelocInfo::LAST_COMPACT_ENUM <=
249 kMaxRelocModes);
225 // Use unsigned delta-encoding for pc. 250 // Use unsigned delta-encoding for pc.
226 uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_); 251 uint32_t pc_delta = static_cast<uint32_t>(rinfo->pc() - last_pc_);
227 RelocInfo::Mode rmode = rinfo->rmode(); 252 RelocInfo::Mode rmode = rinfo->rmode();
228 253
229 // The two most common modes are given small tags, and usually fit in a byte. 254 // The two most common modes are given small tags, and usually fit in a byte.
230 if (rmode == RelocInfo::EMBEDDED_OBJECT) { 255 if (rmode == RelocInfo::EMBEDDED_OBJECT) {
231 WriteTaggedPC(pc_delta, kEmbeddedObjectTag); 256 WriteTaggedPC(pc_delta, kEmbeddedObjectTag);
232 } else if (rmode == RelocInfo::CODE_TARGET) { 257 } else if (rmode == RelocInfo::CODE_TARGET) {
233 WriteTaggedPC(pc_delta, kCodeTargetTag); 258 WriteTaggedPC(pc_delta, kCodeTargetTag);
234 ASSERT(begin_pos - pos_ <= RelocInfo::kMaxCallSize); 259 ASSERT(begin_pos - pos_ <= RelocInfo::kMaxCallSize);
235 } else if (RelocInfo::IsPosition(rmode)) { 260 } else if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
236 // Use signed delta-encoding for data. 261 // Use signed delta-encoding for id.
237 intptr_t data_delta = rinfo->data() - last_data_; 262 ASSERT(static_cast<int>(rinfo->data()) == rinfo->data());
238 int pos_type_tag = rmode == RelocInfo::POSITION ? kNonstatementPositionTag 263 int id_delta = static_cast<int>(rinfo->data()) - last_id_;
239 : kStatementPositionTag; 264 // 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. 265 if (is_intn(id_delta, kSmallDataBits)) {
241 // We cannot use is_intn because data_delta is not an int32_t. 266 WriteTaggedPC(pc_delta, kLocatableTag);
242 if (data_delta >= -(1 << (kSmallDataBits-1)) && 267 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 { 268 } else {
248 // Otherwise, use costly encoding. 269 // Otherwise, use costly encoding.
249 WriteExtraTaggedPC(pc_delta, kPCJumpTag); 270 WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
250 WriteExtraTaggedData(data_delta, pos_type_tag); 271 WriteExtraTaggedIntData(id_delta, kCodeWithIdTag);
251 last_data_ = rinfo->data();
252 } 272 }
273 last_id_ = static_cast<int>(rinfo->data());
274 } else if (RelocInfo::IsPosition(rmode)) {
275 // Use signed delta-encoding for position.
276 ASSERT(static_cast<int>(rinfo->data()) == rinfo->data());
277 int pos_delta = static_cast<int>(rinfo->data()) - last_position_;
278 int pos_type_tag = (rmode == RelocInfo::POSITION) ? kNonstatementPositionTag
279 : kStatementPositionTag;
280 // Check if delta is small enough to fit in a tagged byte.
281 if (is_intn(pos_delta, kSmallDataBits)) {
282 WriteTaggedPC(pc_delta, kLocatableTag);
283 WriteTaggedData(pos_delta, pos_type_tag);
284 } else {
285 // Otherwise, use costly encoding.
286 WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
287 WriteExtraTaggedIntData(pos_delta, pos_type_tag);
288 }
289 last_position_ = static_cast<int>(rinfo->data());
253 } else if (RelocInfo::IsComment(rmode)) { 290 } else if (RelocInfo::IsComment(rmode)) {
254 // Comments are normally not generated, so we use the costly encoding. 291 // Comments are normally not generated, so we use the costly encoding.
255 WriteExtraTaggedPC(pc_delta, kPCJumpTag); 292 WriteExtraTaggedPC(pc_delta, kPCJumpExtraTag);
256 WriteExtraTaggedData(rinfo->data() - last_data_, kCommentTag); 293 WriteExtraTaggedData(rinfo->data(), kCommentTag);
257 last_data_ = rinfo->data();
258 ASSERT(begin_pos - pos_ >= RelocInfo::kMinRelocCommentSize); 294 ASSERT(begin_pos - pos_ >= RelocInfo::kMinRelocCommentSize);
259 } else { 295 } else {
296 ASSERT(rmode > RelocInfo::LAST_COMPACT_ENUM);
297 int saved_mode = rmode - RelocInfo::LAST_COMPACT_ENUM;
260 // For all other modes we simply use the mode as the extra tag. 298 // For all other modes we simply use the mode as the extra tag.
261 // None of these modes need a data component. 299 // None of these modes need a data component.
262 ASSERT(rmode < kPCJumpTag && rmode < kDataJumpTag); 300 ASSERT(saved_mode < kPCJumpExtraTag && saved_mode < kDataJumpExtraTag);
263 WriteExtraTaggedPC(pc_delta, rmode); 301 WriteExtraTaggedPC(pc_delta, saved_mode);
264 } 302 }
265 last_pc_ = rinfo->pc(); 303 last_pc_ = rinfo->pc();
266 #ifdef DEBUG 304 #ifdef DEBUG
267 ASSERT(begin_pos - pos_ <= kMaxSize); 305 ASSERT(begin_pos - pos_ <= kMaxSize);
268 #endif 306 #endif
269 } 307 }
270 308
271 309
272 inline int RelocIterator::AdvanceGetTag() { 310 inline int RelocIterator::AdvanceGetTag() {
273 return *--pos_ & kTagMask; 311 return *--pos_ & kTagMask;
(...skipping 13 matching lines...) Expand all
287 inline void RelocIterator::ReadTaggedPC() { 325 inline void RelocIterator::ReadTaggedPC() {
288 rinfo_.pc_ += *pos_ >> kTagBits; 326 rinfo_.pc_ += *pos_ >> kTagBits;
289 } 327 }
290 328
291 329
292 inline void RelocIterator::AdvanceReadPC() { 330 inline void RelocIterator::AdvanceReadPC() {
293 rinfo_.pc_ += *--pos_; 331 rinfo_.pc_ += *--pos_;
294 } 332 }
295 333
296 334
335 void RelocIterator::AdvanceReadId() {
336 int x = 0;
337 for (int i = 0; i < kIntSize; i++) {
338 x |= static_cast<int>(*--pos_) << i * kBitsPerByte;
339 }
340 last_id_ += x;
341 rinfo_.data_ = last_id_;
342 }
343
344
345 void RelocIterator::AdvanceReadPosition() {
346 int x = 0;
347 for (int i = 0; i < kIntSize; i++) {
348 x |= static_cast<int>(*--pos_) << i * kBitsPerByte;
349 }
350 last_position_ += x;
351 rinfo_.data_ = last_position_;
352 }
353
354
297 void RelocIterator::AdvanceReadData() { 355 void RelocIterator::AdvanceReadData() {
298 intptr_t x = 0; 356 intptr_t x = 0;
299 for (int i = 0; i < kIntptrSize; i++) { 357 for (int i = 0; i < kIntptrSize; i++) {
300 x |= static_cast<intptr_t>(*--pos_) << i * kBitsPerByte; 358 x |= static_cast<intptr_t>(*--pos_) << i * kBitsPerByte;
301 } 359 }
302 rinfo_.data_ += x; 360 rinfo_.data_ = x;
303 } 361 }
304 362
305 363
306 void RelocIterator::AdvanceReadVariableLengthPCJump() { 364 void RelocIterator::AdvanceReadVariableLengthPCJump() {
307 // Read the 32-kSmallPCDeltaBits most significant bits of the 365 // Read the 32-kSmallPCDeltaBits most significant bits of the
308 // pc jump in kChunkBits bit chunks and shift them into place. 366 // pc jump in kChunkBits bit chunks and shift them into place.
309 // Stop when the last chunk is encountered. 367 // Stop when the last chunk is encountered.
310 uint32_t pc_jump = 0; 368 uint32_t pc_jump = 0;
311 for (int i = 0; i < kIntSize; i++) { 369 for (int i = 0; i < kIntSize; i++) {
312 byte pc_jump_part = *--pos_; 370 byte pc_jump_part = *--pos_;
313 pc_jump |= (pc_jump_part >> kLastChunkTagBits) << i * kChunkBits; 371 pc_jump |= (pc_jump_part >> kLastChunkTagBits) << i * kChunkBits;
314 if ((pc_jump_part & kLastChunkTagMask) == 1) break; 372 if ((pc_jump_part & kLastChunkTagMask) == 1) break;
315 } 373 }
316 // The least significant kSmallPCDeltaBits bits will be added 374 // The least significant kSmallPCDeltaBits bits will be added
317 // later. 375 // later.
318 rinfo_.pc_ += pc_jump << kSmallPCDeltaBits; 376 rinfo_.pc_ += pc_jump << kSmallPCDeltaBits;
319 } 377 }
320 378
321 379
322 inline int RelocIterator::GetPositionTypeTag() { 380 inline int RelocIterator::GetLocatableTypeTag() {
323 return *pos_ & ((1 << kPositionTypeTagBits) - 1); 381 return *pos_ & ((1 << kLocatableTypeTagBits) - 1);
324 } 382 }
325 383
326 384
327 inline void RelocIterator::ReadTaggedData() { 385 inline void RelocIterator::ReadTaggedId() {
328 int8_t signed_b = *pos_; 386 int8_t signed_b = *pos_;
329 // Signed right shift is arithmetic shift. Tested in test-utils.cc. 387 // Signed right shift is arithmetic shift. Tested in test-utils.cc.
330 rinfo_.data_ += signed_b >> kPositionTypeTagBits; 388 last_id_ += signed_b >> kLocatableTypeTagBits;
389 rinfo_.data_ = last_id_;
331 } 390 }
332 391
333 392
334 inline RelocInfo::Mode RelocIterator::DebugInfoModeFromTag(int tag) { 393 inline void RelocIterator::ReadTaggedPosition() {
335 if (tag == kStatementPositionTag) { 394 int8_t signed_b = *pos_;
336 return RelocInfo::STATEMENT_POSITION; 395 // Signed right shift is arithmetic shift. Tested in test-utils.cc.
337 } else if (tag == kNonstatementPositionTag) { 396 last_position_ += signed_b >> kLocatableTypeTagBits;
338 return RelocInfo::POSITION; 397 rinfo_.data_ = last_position_;
339 } else {
340 ASSERT(tag == kCommentTag);
341 return RelocInfo::COMMENT;
342 }
343 } 398 }
344 399
345 400
401 static inline RelocInfo::Mode GetPositionModeFromTag(int tag) {
402 ASSERT(tag == kNonstatementPositionTag ||
403 tag == kStatementPositionTag);
404 return (tag == kNonstatementPositionTag) ?
405 RelocInfo::POSITION :
406 RelocInfo::STATEMENT_POSITION;
407 }
408
409
346 void RelocIterator::next() { 410 void RelocIterator::next() {
347 ASSERT(!done()); 411 ASSERT(!done());
348 // Basically, do the opposite of RelocInfoWriter::Write. 412 // Basically, do the opposite of RelocInfoWriter::Write.
349 // Reading of data is as far as possible avoided for unwanted modes, 413 // Reading of data is as far as possible avoided for unwanted modes,
350 // but we must always update the pc. 414 // but we must always update the pc.
351 // 415 //
352 // We exit this loop by returning when we find a mode we want. 416 // We exit this loop by returning when we find a mode we want.
353 while (pos_ > end_) { 417 while (pos_ > end_) {
354 int tag = AdvanceGetTag(); 418 int tag = AdvanceGetTag();
355 if (tag == kEmbeddedObjectTag) { 419 if (tag == kEmbeddedObjectTag) {
356 ReadTaggedPC(); 420 ReadTaggedPC();
357 if (SetMode(RelocInfo::EMBEDDED_OBJECT)) return; 421 if (SetMode(RelocInfo::EMBEDDED_OBJECT)) return;
358 } else if (tag == kCodeTargetTag) { 422 } else if (tag == kCodeTargetTag) {
359 ReadTaggedPC(); 423 ReadTaggedPC();
360 if (SetMode(RelocInfo::CODE_TARGET)) return; 424 if (SetMode(RelocInfo::CODE_TARGET)) return;
361 } else if (tag == kPositionTag) { 425 } else if (tag == kLocatableTag) {
362 ReadTaggedPC(); 426 ReadTaggedPC();
363 Advance(); 427 Advance();
364 // Check if we want source positions. 428 int locatable_tag = GetLocatableTypeTag();
365 if (mode_mask_ & RelocInfo::kPositionMask) { 429 if (locatable_tag == kCodeWithIdTag) {
366 ReadTaggedData(); 430 if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) {
367 if (SetMode(DebugInfoModeFromTag(GetPositionTypeTag()))) return; 431 ReadTaggedId();
432 return;
433 }
434 } else {
435 // Compact encoding is never used for comments,
436 // so it must be a position.
437 ASSERT(locatable_tag == kNonstatementPositionTag ||
438 locatable_tag == kStatementPositionTag);
439 if (mode_mask_ & RelocInfo::kPositionMask) {
440 ReadTaggedPosition();
441 if (SetMode(GetPositionModeFromTag(locatable_tag))) return;
442 }
368 } 443 }
369 } else { 444 } else {
370 ASSERT(tag == kDefaultTag); 445 ASSERT(tag == kDefaultTag);
371 int extra_tag = GetExtraTag(); 446 int extra_tag = GetExtraTag();
372 if (extra_tag == kPCJumpTag) { 447 if (extra_tag == kPCJumpExtraTag) {
373 int top_tag = GetTopTag(); 448 int top_tag = GetTopTag();
374 if (top_tag == kVariableLengthPCJumpTopTag) { 449 if (top_tag == kVariableLengthPCJumpTopTag) {
375 AdvanceReadVariableLengthPCJump(); 450 AdvanceReadVariableLengthPCJump();
376 } else { 451 } else {
377 AdvanceReadPC(); 452 AdvanceReadPC();
378 } 453 }
379 } else if (extra_tag == kDataJumpTag) { 454 } else if (extra_tag == kDataJumpExtraTag) {
380 // Check if we want debug modes (the only ones with data). 455 int locatable_tag = GetTopTag();
381 if (mode_mask_ & RelocInfo::kDebugMask) { 456 if (locatable_tag == kCodeWithIdTag) {
382 int top_tag = GetTopTag(); 457 if (SetMode(RelocInfo::CODE_TARGET_WITH_ID)) {
383 AdvanceReadData(); 458 AdvanceReadId();
384 if (SetMode(DebugInfoModeFromTag(top_tag))) return; 459 return;
460 }
461 Advance(kIntSize);
462 } else if (locatable_tag != kCommentTag) {
463 ASSERT(locatable_tag == kNonstatementPositionTag ||
464 locatable_tag == kStatementPositionTag);
465 if (mode_mask_ & RelocInfo::kPositionMask) {
466 AdvanceReadPosition();
467 if (SetMode(GetPositionModeFromTag(locatable_tag))) return;
468 } else {
469 Advance(kIntSize);
470 }
385 } else { 471 } else {
386 // Otherwise, just skip over the data. 472 ASSERT(locatable_tag == kCommentTag);
473 if (SetMode(RelocInfo::COMMENT)) {
474 AdvanceReadData();
475 return;
476 }
387 Advance(kIntptrSize); 477 Advance(kIntptrSize);
388 } 478 }
389 } else { 479 } else {
390 AdvanceReadPC(); 480 AdvanceReadPC();
391 if (SetMode(static_cast<RelocInfo::Mode>(extra_tag))) return; 481 int rmode = extra_tag + RelocInfo::LAST_COMPACT_ENUM;
482 if (SetMode(static_cast<RelocInfo::Mode>(rmode))) return;
392 } 483 }
393 } 484 }
394 } 485 }
395 done_ = true; 486 done_ = true;
396 } 487 }
397 488
398 489
399 RelocIterator::RelocIterator(Code* code, int mode_mask) { 490 RelocIterator::RelocIterator(Code* code, int mode_mask) {
400 rinfo_.pc_ = code->instruction_start(); 491 rinfo_.pc_ = code->instruction_start();
401 rinfo_.data_ = 0; 492 rinfo_.data_ = 0;
402 // Relocation info is read backwards. 493 // Relocation info is read backwards.
403 pos_ = code->relocation_start() + code->relocation_size(); 494 pos_ = code->relocation_start() + code->relocation_size();
404 end_ = code->relocation_start(); 495 end_ = code->relocation_start();
405 done_ = false; 496 done_ = false;
406 mode_mask_ = mode_mask; 497 mode_mask_ = mode_mask;
498 last_id_ = 0;
499 last_position_ = 0;
407 if (mode_mask_ == 0) pos_ = end_; 500 if (mode_mask_ == 0) pos_ = end_;
408 next(); 501 next();
409 } 502 }
410 503
411 504
412 RelocIterator::RelocIterator(const CodeDesc& desc, int mode_mask) { 505 RelocIterator::RelocIterator(const CodeDesc& desc, int mode_mask) {
413 rinfo_.pc_ = desc.buffer; 506 rinfo_.pc_ = desc.buffer;
414 rinfo_.data_ = 0; 507 rinfo_.data_ = 0;
415 // Relocation info is read backwards. 508 // Relocation info is read backwards.
416 pos_ = desc.buffer + desc.buffer_size; 509 pos_ = desc.buffer + desc.buffer_size;
417 end_ = pos_ - desc.reloc_size; 510 end_ = pos_ - desc.reloc_size;
418 done_ = false; 511 done_ = false;
419 mode_mask_ = mode_mask; 512 mode_mask_ = mode_mask;
513 last_id_ = 0;
514 last_position_ = 0;
420 if (mode_mask_ == 0) pos_ = end_; 515 if (mode_mask_ == 0) pos_ = end_;
421 next(); 516 next();
422 } 517 }
423 518
424 519
425 // ----------------------------------------------------------------------------- 520 // -----------------------------------------------------------------------------
426 // Implementation of RelocInfo 521 // Implementation of RelocInfo
427 522
428 523
429 #ifdef ENABLE_DISASSEMBLER 524 #ifdef ENABLE_DISASSEMBLER
430 const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) { 525 const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
431 switch (rmode) { 526 switch (rmode) {
432 case RelocInfo::NONE: 527 case RelocInfo::NONE:
433 return "no reloc"; 528 return "no reloc";
434 case RelocInfo::EMBEDDED_OBJECT: 529 case RelocInfo::EMBEDDED_OBJECT:
435 return "embedded object"; 530 return "embedded object";
436 case RelocInfo::CONSTRUCT_CALL: 531 case RelocInfo::CONSTRUCT_CALL:
437 return "code target (js construct call)"; 532 return "code target (js construct call)";
438 case RelocInfo::CODE_TARGET_CONTEXT: 533 case RelocInfo::CODE_TARGET_CONTEXT:
439 return "code target (context)"; 534 return "code target (context)";
440 case RelocInfo::DEBUG_BREAK: 535 case RelocInfo::DEBUG_BREAK:
441 #ifndef ENABLE_DEBUGGER_SUPPORT 536 #ifndef ENABLE_DEBUGGER_SUPPORT
442 UNREACHABLE(); 537 UNREACHABLE();
443 #endif 538 #endif
444 return "debug break"; 539 return "debug break";
445 case RelocInfo::CODE_TARGET: 540 case RelocInfo::CODE_TARGET:
446 return "code target"; 541 return "code target";
542 case RelocInfo::CODE_TARGET_WITH_ID:
543 return "code target with id";
447 case RelocInfo::GLOBAL_PROPERTY_CELL: 544 case RelocInfo::GLOBAL_PROPERTY_CELL:
448 return "global property cell"; 545 return "global property cell";
449 case RelocInfo::RUNTIME_ENTRY: 546 case RelocInfo::RUNTIME_ENTRY:
450 return "runtime entry"; 547 return "runtime entry";
451 case RelocInfo::JS_RETURN: 548 case RelocInfo::JS_RETURN:
452 return "js return"; 549 return "js return";
453 case RelocInfo::COMMENT: 550 case RelocInfo::COMMENT:
454 return "comment"; 551 return "comment";
455 case RelocInfo::POSITION: 552 case RelocInfo::POSITION:
456 return "position"; 553 return "position";
(...skipping 26 matching lines...) Expand all
483 PrintF(out, ")"); 580 PrintF(out, ")");
484 } else if (rmode_ == EXTERNAL_REFERENCE) { 581 } else if (rmode_ == EXTERNAL_REFERENCE) {
485 ExternalReferenceEncoder ref_encoder; 582 ExternalReferenceEncoder ref_encoder;
486 PrintF(out, " (%s) (%p)", 583 PrintF(out, " (%s) (%p)",
487 ref_encoder.NameOfAddress(*target_reference_address()), 584 ref_encoder.NameOfAddress(*target_reference_address()),
488 *target_reference_address()); 585 *target_reference_address());
489 } else if (IsCodeTarget(rmode_)) { 586 } else if (IsCodeTarget(rmode_)) {
490 Code* code = Code::GetCodeFromTargetAddress(target_address()); 587 Code* code = Code::GetCodeFromTargetAddress(target_address());
491 PrintF(out, " (%s) (%p)", Code::Kind2String(code->kind()), 588 PrintF(out, " (%s) (%p)", Code::Kind2String(code->kind()),
492 target_address()); 589 target_address());
590 if (rmode_ == CODE_TARGET_WITH_ID) {
591 PrintF(" (id=%d)", static_cast<int>(data_));
592 }
493 } else if (IsPosition(rmode_)) { 593 } else if (IsPosition(rmode_)) {
494 PrintF(out, " (%" V8_PTR_PREFIX "d)", data()); 594 PrintF(out, " (%" V8_PTR_PREFIX "d)", data());
495 } else if (rmode_ == RelocInfo::RUNTIME_ENTRY && 595 } else if (rmode_ == RelocInfo::RUNTIME_ENTRY &&
496 Isolate::Current()->deoptimizer_data() != NULL) { 596 Isolate::Current()->deoptimizer_data() != NULL) {
497 // Depotimization bailouts are stored as runtime entries. 597 // Depotimization bailouts are stored as runtime entries.
498 int id = Deoptimizer::GetDeoptimizationId( 598 int id = Deoptimizer::GetDeoptimizationId(
499 target_address(), Deoptimizer::EAGER); 599 target_address(), Deoptimizer::EAGER);
500 if (id != Deoptimizer::kNotDeoptimizationEntry) { 600 if (id != Deoptimizer::kNotDeoptimizationEntry) {
501 PrintF(out, " (deoptimization bailout %d)", id); 601 PrintF(out, " (deoptimization bailout %d)", id);
502 } 602 }
(...skipping 13 matching lines...) Expand all
516 case GLOBAL_PROPERTY_CELL: 616 case GLOBAL_PROPERTY_CELL:
517 Object::VerifyPointer(target_cell()); 617 Object::VerifyPointer(target_cell());
518 break; 618 break;
519 case DEBUG_BREAK: 619 case DEBUG_BREAK:
520 #ifndef ENABLE_DEBUGGER_SUPPORT 620 #ifndef ENABLE_DEBUGGER_SUPPORT
521 UNREACHABLE(); 621 UNREACHABLE();
522 break; 622 break;
523 #endif 623 #endif
524 case CONSTRUCT_CALL: 624 case CONSTRUCT_CALL:
525 case CODE_TARGET_CONTEXT: 625 case CODE_TARGET_CONTEXT:
626 case CODE_TARGET_WITH_ID:
526 case CODE_TARGET: { 627 case CODE_TARGET: {
527 // convert inline target address to code object 628 // convert inline target address to code object
528 Address addr = target_address(); 629 Address addr = target_address();
529 ASSERT(addr != NULL); 630 ASSERT(addr != NULL);
530 // Check that we can find the right code object. 631 // Check that we can find the right code object.
531 Code* code = Code::GetCodeFromTargetAddress(addr); 632 Code* code = Code::GetCodeFromTargetAddress(addr);
532 Object* found = HEAP->FindCodeObject(addr); 633 Object* found = HEAP->FindCodeObject(addr);
533 ASSERT(found->IsCode()); 634 ASSERT(found->IsCode());
534 ASSERT(code->address() == HeapObject::cast(found)->address()); 635 ASSERT(code->address() == HeapObject::cast(found)->address());
535 break; 636 break;
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position); 1160 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position);
1060 state_.written_position = state_.current_position; 1161 state_.written_position = state_.current_position;
1061 written = true; 1162 written = true;
1062 } 1163 }
1063 1164
1064 // Return whether something was written. 1165 // Return whether something was written.
1065 return written; 1166 return written;
1066 } 1167 }
1067 1168
1068 } } // namespace v8::internal 1169 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698