OLD | NEW |
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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 int shadowed_pos_; | 123 int shadowed_pos_; |
124 #ifdef DEBUG | 124 #ifdef DEBUG |
125 bool is_shadowing_; | 125 bool is_shadowing_; |
126 #endif | 126 #endif |
127 }; | 127 }; |
128 | 128 |
129 | 129 |
130 // ----------------------------------------------------------------------------- | 130 // ----------------------------------------------------------------------------- |
131 // Relocation information | 131 // Relocation information |
132 | 132 |
133 // The constant kNoPosition is used with the collecting of source positions | |
134 // in the relocation information. Two types of source positions are collected | |
135 // "position" (RelocMode position) and "statement position" (RelocMode | |
136 // statement_position). The "position" is collected at places in the source | |
137 // code which are of interest when making stack traces to pin-point the source | |
138 // location of a stack frame as close as possible. The "statement position" is | |
139 // collected at the beginning at each statement, and is used to indicate | |
140 // possible break locations. kNoPosition is used to indicate an | |
141 // invalid/uninitialized position value. | |
142 static const int kNoPosition = -1; | |
143 | |
144 | |
145 enum RelocMode { | |
146 // Please note the order is important (see is_code_target, is_gc_reloc_mode). | |
147 js_construct_call, // code target that is an exit JavaScript frame stub. | |
148 exit_js_frame, // code target that is an exit JavaScript frame stub. | |
149 code_target_context, // code target used for contextual loads. | |
150 code_target, // code target which is not any of the above. | |
151 embedded_object, | |
152 embedded_string, | |
153 | |
154 // Everything after runtime_entry (inclusive) is not GC'ed. | |
155 runtime_entry, | |
156 js_return, // Marks start of the ExitJSFrame code. | |
157 comment, | |
158 position, // See comment for kNoPosition above. | |
159 statement_position, // See comment for kNoPosition above. | |
160 external_reference, // The address of an external C++ function. | |
161 internal_reference, // An address inside the same function. | |
162 | |
163 // add more as needed | |
164 // Pseudo-types | |
165 reloc_mode_count, // must be no greater than 14 - see RelocInfoWriter | |
166 no_reloc, // never recorded | |
167 last_code_enum = code_target, | |
168 last_gced_enum = embedded_string | |
169 }; | |
170 | |
171 | |
172 inline int RelocMask(RelocMode mode) { | |
173 return 1 << mode; | |
174 } | |
175 | |
176 | |
177 inline bool is_js_construct_call(RelocMode mode) { | |
178 return mode == js_construct_call; | |
179 } | |
180 | |
181 | |
182 inline bool is_exit_js_frame(RelocMode mode) { | |
183 return mode == exit_js_frame; | |
184 } | |
185 | |
186 | |
187 inline bool is_code_target(RelocMode mode) { | |
188 return mode <= last_code_enum; | |
189 } | |
190 | |
191 | |
192 // Is the relocation mode affected by GC? | |
193 inline bool is_gc_reloc_mode(RelocMode mode) { | |
194 return mode <= last_gced_enum; | |
195 } | |
196 | |
197 | |
198 inline bool is_js_return(RelocMode mode) { | |
199 return mode == js_return; | |
200 } | |
201 | |
202 | |
203 inline bool is_comment(RelocMode mode) { | |
204 return mode == comment; | |
205 } | |
206 | |
207 | |
208 inline bool is_position(RelocMode mode) { | |
209 return mode == position || mode == statement_position; | |
210 } | |
211 | |
212 | |
213 inline bool is_statement_position(RelocMode mode) { | |
214 return mode == statement_position; | |
215 } | |
216 | |
217 | |
218 inline bool is_external_reference(RelocMode mode) { | |
219 return mode == external_reference; | |
220 } | |
221 | |
222 | |
223 inline bool is_internal_reference(RelocMode mode) { | |
224 return mode == internal_reference; | |
225 } | |
226 | |
227 | 133 |
228 // Relocation information consists of the address (pc) of the datum | 134 // Relocation information consists of the address (pc) of the datum |
229 // to which the relocation information applies, the relocation mode | 135 // to which the relocation information applies, the relocation mode |
230 // (rmode), and an optional data field. The relocation mode may be | 136 // (rmode), and an optional data field. The relocation mode may be |
231 // "descriptive" and not indicate a need for relocation, but simply | 137 // "descriptive" and not indicate a need for relocation, but simply |
232 // describe a property of the datum. Such rmodes are useful for GC | 138 // describe a property of the datum. Such rmodes are useful for GC |
233 // and nice disassembly output. | 139 // and nice disassembly output. |
234 | 140 |
235 class RelocInfo BASE_EMBEDDED { | 141 class RelocInfo BASE_EMBEDDED { |
236 public: | 142 public: |
| 143 // The constant kNoPosition is used with the collecting of source positions |
| 144 // in the relocation information. Two types of source positions are collected |
| 145 // "position" (RelocMode position) and "statement position" (RelocMode |
| 146 // statement_position). The "position" is collected at places in the source |
| 147 // code which are of interest when making stack traces to pin-point the source |
| 148 // location of a stack frame as close as possible. The "statement position" is |
| 149 // collected at the beginning at each statement, and is used to indicate |
| 150 // possible break locations. kNoPosition is used to indicate an |
| 151 // invalid/uninitialized position value. |
| 152 static const int kNoPosition = -1; |
| 153 |
| 154 enum Mode { |
| 155 // Please note the order is important (see IsCodeTarget, IsGCRelocMode). |
| 156 CONSTRUCT_CALL, // code target that is a call to a JavaScript constructor. |
| 157 CODE_TARGET_CONTEXT, // code target used for contextual loads. |
| 158 CODE_TARGET, // code target which is not any of the above. |
| 159 EMBEDDED_OBJECT, |
| 160 EMBEDDED_STRING, |
| 161 |
| 162 // Everything after runtime_entry (inclusive) is not GC'ed. |
| 163 RUNTIME_ENTRY, |
| 164 JS_RETURN, // Marks start of the ExitJSFrame code. |
| 165 COMMENT, |
| 166 POSITION, // See comment for kNoPosition above. |
| 167 STATEMENT_POSITION, // See comment for kNoPosition above. |
| 168 EXTERNAL_REFERENCE, // The address of an external C++ function. |
| 169 INTERNAL_REFERENCE, // An address inside the same function. |
| 170 |
| 171 // add more as needed |
| 172 // Pseudo-types |
| 173 NUMBER_OF_MODES, // must be no greater than 14 - see RelocInfoWriter |
| 174 NONE, // never recorded |
| 175 LAST_CODE_ENUM = CODE_TARGET, |
| 176 LAST_GCED_ENUM = EMBEDDED_STRING |
| 177 }; |
| 178 |
| 179 |
237 RelocInfo() {} | 180 RelocInfo() {} |
238 RelocInfo(byte* pc, RelocMode rmode, intptr_t data) | 181 RelocInfo(byte* pc, Mode rmode, intptr_t data) |
239 : pc_(pc), rmode_(rmode), data_(data) { | 182 : pc_(pc), rmode_(rmode), data_(data) { |
240 } | 183 } |
241 | 184 |
| 185 static inline bool IsConstructCall(Mode mode) { |
| 186 return mode == CONSTRUCT_CALL; |
| 187 } |
| 188 static inline bool IsCodeTarget(Mode mode) { |
| 189 return mode <= LAST_CODE_ENUM; |
| 190 } |
| 191 // Is the relocation mode affected by GC? |
| 192 static inline bool IsGCRelocMode(Mode mode) { |
| 193 return mode <= LAST_GCED_ENUM; |
| 194 } |
| 195 static inline bool IsJSReturn(Mode mode) { |
| 196 return mode == JS_RETURN; |
| 197 } |
| 198 static inline bool IsComment(Mode mode) { |
| 199 return mode == COMMENT; |
| 200 } |
| 201 static inline bool IsPosition(Mode mode) { |
| 202 return mode == POSITION || mode == STATEMENT_POSITION; |
| 203 } |
| 204 static inline bool IsStatementPosition(Mode mode) { |
| 205 return mode == STATEMENT_POSITION; |
| 206 } |
| 207 static inline bool IsExternalReference(Mode mode) { |
| 208 return mode == EXTERNAL_REFERENCE; |
| 209 } |
| 210 static inline bool IsInternalReference(Mode mode) { |
| 211 return mode == INTERNAL_REFERENCE; |
| 212 } |
| 213 static inline int ModeMask(Mode mode) { return 1 << mode; } |
| 214 |
242 // Accessors | 215 // Accessors |
243 byte* pc() const { return pc_; } | 216 byte* pc() const { return pc_; } |
244 void set_pc(byte* pc) { pc_ = pc; } | 217 void set_pc(byte* pc) { pc_ = pc; } |
245 RelocMode rmode() const { return rmode_; } | 218 Mode rmode() const { return rmode_; } |
246 intptr_t data() const { return data_; } | 219 intptr_t data() const { return data_; } |
247 | 220 |
248 // Apply a relocation by delta bytes | 221 // Apply a relocation by delta bytes |
249 INLINE(void apply(int delta)); | 222 INLINE(void apply(int delta)); |
250 | 223 |
251 // Read/modify the code target in the branch/call instruction this relocation | 224 // Read/modify the code target in the branch/call instruction this relocation |
252 // applies to; can only be called if this->is_code_target(rmode_) | 225 // applies to; can only be called if IsCodeTarget(rmode_) |
253 INLINE(Address target_address()); | 226 INLINE(Address target_address()); |
254 INLINE(void set_target_address(Address target)); | 227 INLINE(void set_target_address(Address target)); |
255 INLINE(Object* target_object()); | 228 INLINE(Object* target_object()); |
256 INLINE(Object** target_object_address()); | 229 INLINE(Object** target_object_address()); |
257 INLINE(void set_target_object(Object* target)); | 230 INLINE(void set_target_object(Object* target)); |
258 | 231 |
259 // Read/modify the reference in the instruction this relocation | 232 // Read/modify the reference in the instruction this relocation |
260 // applies to; can only be called if rmode_ is external_reference | 233 // applies to; can only be called if rmode_ is external_reference |
261 INLINE(Address* target_reference_address()); | 234 INLINE(Address* target_reference_address()); |
262 | 235 |
263 // Read/modify the address of a call instruction. This is used to relocate | 236 // Read/modify the address of a call instruction. This is used to relocate |
264 // the break points where straight-line code is patched with a call | 237 // the break points where straight-line code is patched with a call |
265 // instruction. | 238 // instruction. |
266 INLINE(Address call_address()); | 239 INLINE(Address call_address()); |
267 INLINE(void set_call_address(Address target)); | 240 INLINE(void set_call_address(Address target)); |
268 INLINE(Object* call_object()); | 241 INLINE(Object* call_object()); |
269 INLINE(Object** call_object_address()); | 242 INLINE(Object** call_object_address()); |
270 INLINE(void set_call_object(Object* target)); | 243 INLINE(void set_call_object(Object* target)); |
271 | 244 |
272 // Patch the code with some other code. | 245 // Patch the code with some other code. |
273 void patch_code(byte* instructions, int instruction_count); | 246 void patch_code(byte* instructions, int instruction_count); |
274 | 247 |
275 // Patch the code with a call. | 248 // Patch the code with a call. |
276 void patch_code_with_call(Address target, int guard_bytes); | 249 void patch_code_with_call(Address target, int guard_bytes); |
277 INLINE(bool is_call_instruction()); | 250 INLINE(bool is_call_instruction()); |
278 | 251 |
279 #ifdef ENABLE_DISASSEMBLER | 252 #ifdef ENABLE_DISASSEMBLER |
280 // Printing | 253 // Printing |
281 static const char* RelocModeName(RelocMode rmode); | 254 static const char* RelocModeName(Mode rmode); |
282 void Print(); | 255 void Print(); |
283 #endif // ENABLE_DISASSEMBLER | 256 #endif // ENABLE_DISASSEMBLER |
284 #ifdef DEBUG | 257 #ifdef DEBUG |
285 // Debugging | 258 // Debugging |
286 void Verify(); | 259 void Verify(); |
287 #endif | 260 #endif |
288 | 261 |
289 static const int kCodeTargetMask = (1 << (last_code_enum + 1)) - 1; | 262 static const int kCodeTargetMask = (1 << (LAST_CODE_ENUM + 1)) - 1; |
290 static const int kPositionMask = 1 << position | 1 << statement_position; | 263 static const int kPositionMask = 1 << POSITION | 1 << STATEMENT_POSITION; |
291 static const int kDebugMask = kPositionMask | 1 << comment; | 264 static const int kDebugMask = kPositionMask | 1 << COMMENT; |
292 static const int kApplyMask; // Modes affected by apply. Depends on arch. | 265 static const int kApplyMask; // Modes affected by apply. Depends on arch. |
293 | 266 |
294 private: | 267 private: |
295 // On ARM, note that pc_ is the address of the constant pool entry | 268 // On ARM, note that pc_ is the address of the constant pool entry |
296 // to be relocated and not the address of the instruction | 269 // to be relocated and not the address of the instruction |
297 // referencing the constant pool entry (except when rmode_ == | 270 // referencing the constant pool entry (except when rmode_ == |
298 // comment). | 271 // comment). |
299 byte* pc_; | 272 byte* pc_; |
300 RelocMode rmode_; | 273 Mode rmode_; |
301 intptr_t data_; | 274 intptr_t data_; |
302 friend class RelocIterator; | 275 friend class RelocIterator; |
303 }; | 276 }; |
304 | 277 |
305 | 278 |
306 // RelocInfoWriter serializes a stream of relocation info. It writes towards | 279 // RelocInfoWriter serializes a stream of relocation info. It writes towards |
307 // lower addresses. | 280 // lower addresses. |
308 class RelocInfoWriter BASE_EMBEDDED { | 281 class RelocInfoWriter BASE_EMBEDDED { |
309 public: | 282 public: |
310 RelocInfoWriter() : pos_(NULL), last_pc_(NULL), last_data_(0) {} | 283 RelocInfoWriter() : pos_(NULL), last_pc_(NULL), last_data_(0) {} |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 int AdvanceGetTag(); | 349 int AdvanceGetTag(); |
377 int GetExtraTag(); | 350 int GetExtraTag(); |
378 int GetTopTag(); | 351 int GetTopTag(); |
379 void ReadTaggedPC(); | 352 void ReadTaggedPC(); |
380 void AdvanceReadPC(); | 353 void AdvanceReadPC(); |
381 void AdvanceReadData(); | 354 void AdvanceReadData(); |
382 void AdvanceReadVariableLengthPCJump(); | 355 void AdvanceReadVariableLengthPCJump(); |
383 int GetPositionTypeTag(); | 356 int GetPositionTypeTag(); |
384 void ReadTaggedData(); | 357 void ReadTaggedData(); |
385 | 358 |
386 static RelocMode DebugInfoModeFromTag(int tag); | 359 static RelocInfo::Mode DebugInfoModeFromTag(int tag); |
387 | 360 |
388 // If the given mode is wanted, set it in rinfo_ and return true. | 361 // If the given mode is wanted, set it in rinfo_ and return true. |
389 // Else return false. Used for efficiently skipping unwanted modes. | 362 // Else return false. Used for efficiently skipping unwanted modes. |
390 bool SetMode(RelocMode mode) { | 363 bool SetMode(RelocInfo::Mode mode) { |
391 return (mode_mask_ & 1 << mode) ? (rinfo_.rmode_ = mode, true) : false; | 364 return (mode_mask_ & 1 << mode) ? (rinfo_.rmode_ = mode, true) : false; |
392 } | 365 } |
393 | 366 |
394 byte* pos_; | 367 byte* pos_; |
395 byte* end_; | 368 byte* end_; |
396 RelocInfo rinfo_; | 369 RelocInfo rinfo_; |
397 bool done_; | 370 bool done_; |
398 int mode_mask_; | 371 int mode_mask_; |
399 DISALLOW_COPY_AND_ASSIGN(RelocIterator); | 372 DISALLOW_COPY_AND_ASSIGN(RelocIterator); |
400 }; | 373 }; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 static inline bool is_uint4(int x) { return is_uintn(x, 4); } | 460 static inline bool is_uint4(int x) { return is_uintn(x, 4); } |
488 static inline bool is_uint5(int x) { return is_uintn(x, 5); } | 461 static inline bool is_uint5(int x) { return is_uintn(x, 5); } |
489 static inline bool is_uint8(int x) { return is_uintn(x, 8); } | 462 static inline bool is_uint8(int x) { return is_uintn(x, 8); } |
490 static inline bool is_uint12(int x) { return is_uintn(x, 12); } | 463 static inline bool is_uint12(int x) { return is_uintn(x, 12); } |
491 static inline bool is_uint16(int x) { return is_uintn(x, 16); } | 464 static inline bool is_uint16(int x) { return is_uintn(x, 16); } |
492 static inline bool is_uint24(int x) { return is_uintn(x, 24); } | 465 static inline bool is_uint24(int x) { return is_uintn(x, 24); } |
493 | 466 |
494 } } // namespace v8::internal | 467 } } // namespace v8::internal |
495 | 468 |
496 #endif // V8_ASSEMBLER_H_ | 469 #endif // V8_ASSEMBLER_H_ |
OLD | NEW |