| 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 |