| 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 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 ASSERT(is_near_linked()); | 203 ASSERT(is_near_linked()); |
| 204 } else { | 204 } else { |
| 205 pos_ = pos + 1; | 205 pos_ = pos + 1; |
| 206 ASSERT(is_linked()); | 206 ASSERT(is_linked()); |
| 207 } | 207 } |
| 208 } | 208 } |
| 209 | 209 |
| 210 friend class Assembler; | 210 friend class Assembler; |
| 211 friend class Displacement; | 211 friend class Displacement; |
| 212 friend class RegExpMacroAssemblerIrregexp; | 212 friend class RegExpMacroAssemblerIrregexp; |
| 213 |
| 214 #if V8_TARGET_ARCH_A64 |
| 215 // On A64, the Assembler keeps track of pointers to Labels to resolve branches |
| 216 // to distant targets. Copying labels would confuse the Assembler. |
| 217 DISALLOW_COPY_AND_ASSIGN(Label); // NOLINT |
| 218 #endif |
| 213 }; | 219 }; |
| 214 | 220 |
| 215 | 221 |
| 216 enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs }; | 222 enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs }; |
| 217 | 223 |
| 218 | 224 |
| 219 // ----------------------------------------------------------------------------- | 225 // ----------------------------------------------------------------------------- |
| 220 // Relocation information | 226 // Relocation information |
| 221 | 227 |
| 222 | 228 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 // Everything after runtime_entry (inclusive) is not GC'ed. | 275 // Everything after runtime_entry (inclusive) is not GC'ed. |
| 270 RUNTIME_ENTRY, | 276 RUNTIME_ENTRY, |
| 271 JS_RETURN, // Marks start of the ExitJSFrame code. | 277 JS_RETURN, // Marks start of the ExitJSFrame code. |
| 272 COMMENT, | 278 COMMENT, |
| 273 POSITION, // See comment for kNoPosition above. | 279 POSITION, // See comment for kNoPosition above. |
| 274 STATEMENT_POSITION, // See comment for kNoPosition above. | 280 STATEMENT_POSITION, // See comment for kNoPosition above. |
| 275 DEBUG_BREAK_SLOT, // Additional code inserted for debug break slot. | 281 DEBUG_BREAK_SLOT, // Additional code inserted for debug break slot. |
| 276 EXTERNAL_REFERENCE, // The address of an external C++ function. | 282 EXTERNAL_REFERENCE, // The address of an external C++ function. |
| 277 INTERNAL_REFERENCE, // An address inside the same function. | 283 INTERNAL_REFERENCE, // An address inside the same function. |
| 278 | 284 |
| 279 // Marks a constant pool. Only used on ARM. | 285 // Marks constant and veneer pools. Only used on ARM and A64. |
| 280 // It uses a custom noncompact encoding. | 286 // They use a custom noncompact encoding. |
| 281 CONST_POOL, | 287 CONST_POOL, |
| 288 VENEER_POOL, |
| 282 | 289 |
| 283 // add more as needed | 290 // add more as needed |
| 284 // Pseudo-types | 291 // Pseudo-types |
| 285 NUMBER_OF_MODES, // There are at most 15 modes with noncompact encoding. | 292 NUMBER_OF_MODES, // There are at most 15 modes with noncompact encoding. |
| 286 NONE32, // never recorded 32-bit value | 293 NONE32, // never recorded 32-bit value |
| 287 NONE64, // never recorded 64-bit value | 294 NONE64, // never recorded 64-bit value |
| 288 CODE_AGE_SEQUENCE, // Not stored in RelocInfo array, used explictly by | 295 CODE_AGE_SEQUENCE, // Not stored in RelocInfo array, used explictly by |
| 289 // code aging. | 296 // code aging. |
| 290 FIRST_REAL_RELOC_MODE = CODE_TARGET, | 297 FIRST_REAL_RELOC_MODE = CODE_TARGET, |
| 291 LAST_REAL_RELOC_MODE = CONST_POOL, | 298 LAST_REAL_RELOC_MODE = VENEER_POOL, |
| 292 FIRST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE, | 299 FIRST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE, |
| 293 LAST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE, | 300 LAST_PSEUDO_RELOC_MODE = CODE_AGE_SEQUENCE, |
| 294 LAST_CODE_ENUM = DEBUG_BREAK, | 301 LAST_CODE_ENUM = DEBUG_BREAK, |
| 295 LAST_GCED_ENUM = CELL, | 302 LAST_GCED_ENUM = CELL, |
| 296 // Modes <= LAST_COMPACT_ENUM are guaranteed to have compact encoding. | 303 // Modes <= LAST_COMPACT_ENUM are guaranteed to have compact encoding. |
| 297 LAST_COMPACT_ENUM = CODE_TARGET_WITH_ID, | 304 LAST_COMPACT_ENUM = CODE_TARGET_WITH_ID, |
| 298 LAST_STANDARD_NONCOMPACT_ENUM = INTERNAL_REFERENCE | 305 LAST_STANDARD_NONCOMPACT_ENUM = INTERNAL_REFERENCE |
| 299 }; | 306 }; |
| 300 | 307 |
| 301 | 308 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 } | 342 } |
| 336 static inline bool IsJSReturn(Mode mode) { | 343 static inline bool IsJSReturn(Mode mode) { |
| 337 return mode == JS_RETURN; | 344 return mode == JS_RETURN; |
| 338 } | 345 } |
| 339 static inline bool IsComment(Mode mode) { | 346 static inline bool IsComment(Mode mode) { |
| 340 return mode == COMMENT; | 347 return mode == COMMENT; |
| 341 } | 348 } |
| 342 static inline bool IsConstPool(Mode mode) { | 349 static inline bool IsConstPool(Mode mode) { |
| 343 return mode == CONST_POOL; | 350 return mode == CONST_POOL; |
| 344 } | 351 } |
| 352 static inline bool IsVeneerPool(Mode mode) { |
| 353 return mode == VENEER_POOL; |
| 354 } |
| 345 static inline bool IsPosition(Mode mode) { | 355 static inline bool IsPosition(Mode mode) { |
| 346 return mode == POSITION || mode == STATEMENT_POSITION; | 356 return mode == POSITION || mode == STATEMENT_POSITION; |
| 347 } | 357 } |
| 348 static inline bool IsStatementPosition(Mode mode) { | 358 static inline bool IsStatementPosition(Mode mode) { |
| 349 return mode == STATEMENT_POSITION; | 359 return mode == STATEMENT_POSITION; |
| 350 } | 360 } |
| 351 static inline bool IsExternalReference(Mode mode) { | 361 static inline bool IsExternalReference(Mode mode) { |
| 352 return mode == EXTERNAL_REFERENCE; | 362 return mode == EXTERNAL_REFERENCE; |
| 353 } | 363 } |
| 354 static inline bool IsInternalReference(Mode mode) { | 364 static inline bool IsInternalReference(Mode mode) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 368 // Accessors | 378 // Accessors |
| 369 byte* pc() const { return pc_; } | 379 byte* pc() const { return pc_; } |
| 370 void set_pc(byte* pc) { pc_ = pc; } | 380 void set_pc(byte* pc) { pc_ = pc; } |
| 371 Mode rmode() const { return rmode_; } | 381 Mode rmode() const { return rmode_; } |
| 372 intptr_t data() const { return data_; } | 382 intptr_t data() const { return data_; } |
| 373 double data64() const { return data64_; } | 383 double data64() const { return data64_; } |
| 374 uint64_t raw_data64() { | 384 uint64_t raw_data64() { |
| 375 return BitCast<uint64_t>(data64_); | 385 return BitCast<uint64_t>(data64_); |
| 376 } | 386 } |
| 377 Code* host() const { return host_; } | 387 Code* host() const { return host_; } |
| 388 void set_host(Code* host) { host_ = host; } |
| 378 | 389 |
| 379 // Apply a relocation by delta bytes | 390 // Apply a relocation by delta bytes |
| 380 INLINE(void apply(intptr_t delta)); | 391 INLINE(void apply(intptr_t delta)); |
| 381 | 392 |
| 382 // Is the pointer this relocation info refers to coded like a plain pointer | 393 // Is the pointer this relocation info refers to coded like a plain pointer |
| 383 // or is it strange in some way (e.g. relative or patched into a series of | 394 // or is it strange in some way (e.g. relative or patched into a series of |
| 384 // instructions). | 395 // instructions). |
| 385 bool IsCodedSpecially(); | 396 bool IsCodedSpecially(); |
| 386 | 397 |
| 398 // If true, the pointer this relocation info refers to is an entry in the |
| 399 // constant pool, otherwise the pointer is embedded in the instruction stream. |
| 400 bool IsInConstantPool(); |
| 401 |
| 387 // Read/modify the code target in the branch/call instruction | 402 // Read/modify the code target in the branch/call instruction |
| 388 // this relocation applies to; | 403 // this relocation applies to; |
| 389 // can only be called if IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) | 404 // can only be called if IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) |
| 390 INLINE(Address target_address()); | 405 INLINE(Address target_address()); |
| 391 INLINE(void set_target_address(Address target, | 406 INLINE(void set_target_address(Address target, |
| 392 WriteBarrierMode mode = UPDATE_WRITE_BARRIER)); | 407 WriteBarrierMode mode = UPDATE_WRITE_BARRIER)); |
| 393 INLINE(Object* target_object()); | 408 INLINE(Object* target_object()); |
| 394 INLINE(Handle<Object> target_object_handle(Assembler* origin)); | 409 INLINE(Handle<Object> target_object_handle(Assembler* origin)); |
| 395 INLINE(void set_target_object(Object* target, | 410 INLINE(void set_target_object(Object* target, |
| 396 WriteBarrierMode mode = UPDATE_WRITE_BARRIER)); | 411 WriteBarrierMode mode = UPDATE_WRITE_BARRIER)); |
| 397 INLINE(Address target_runtime_entry(Assembler* origin)); | 412 INLINE(Address target_runtime_entry(Assembler* origin)); |
| 398 INLINE(void set_target_runtime_entry(Address target, | 413 INLINE(void set_target_runtime_entry(Address target, |
| 399 WriteBarrierMode mode = | 414 WriteBarrierMode mode = |
| 400 UPDATE_WRITE_BARRIER)); | 415 UPDATE_WRITE_BARRIER)); |
| 401 INLINE(Cell* target_cell()); | 416 INLINE(Cell* target_cell()); |
| 402 INLINE(Handle<Cell> target_cell_handle()); | 417 INLINE(Handle<Cell> target_cell_handle()); |
| 403 INLINE(void set_target_cell(Cell* cell, | 418 INLINE(void set_target_cell(Cell* cell, |
| 404 WriteBarrierMode mode = UPDATE_WRITE_BARRIER)); | 419 WriteBarrierMode mode = UPDATE_WRITE_BARRIER)); |
| 405 INLINE(Handle<Object> code_age_stub_handle(Assembler* origin)); | 420 INLINE(Handle<Object> code_age_stub_handle(Assembler* origin)); |
| 406 INLINE(Code* code_age_stub()); | 421 INLINE(Code* code_age_stub()); |
| 407 INLINE(void set_code_age_stub(Code* stub)); | 422 INLINE(void set_code_age_stub(Code* stub)); |
| 408 | 423 |
| 424 // Returns the address of the constant pool entry where the target address |
| 425 // is held. This should only be called if IsInConstantPool returns true. |
| 426 INLINE(Address constant_pool_entry_address()); |
| 427 |
| 409 // Read the address of the word containing the target_address in an | 428 // Read the address of the word containing the target_address in an |
| 410 // instruction stream. What this means exactly is architecture-independent. | 429 // instruction stream. What this means exactly is architecture-independent. |
| 411 // The only architecture-independent user of this function is the serializer. | 430 // The only architecture-independent user of this function is the serializer. |
| 412 // The serializer uses it to find out how many raw bytes of instruction to | 431 // The serializer uses it to find out how many raw bytes of instruction to |
| 413 // output before the next target. Architecture-independent code shouldn't | 432 // output before the next target. Architecture-independent code shouldn't |
| 414 // dereference the pointer it gets back from this. | 433 // dereference the pointer it gets back from this. |
| 415 INLINE(Address target_address_address()); | 434 INLINE(Address target_address_address()); |
| 435 |
| 416 // This indicates how much space a target takes up when deserializing a code | 436 // This indicates how much space a target takes up when deserializing a code |
| 417 // stream. For most architectures this is just the size of a pointer. For | 437 // stream. For most architectures this is just the size of a pointer. For |
| 418 // an instruction like movw/movt where the target bits are mixed into the | 438 // an instruction like movw/movt where the target bits are mixed into the |
| 419 // instruction bits the size of the target will be zero, indicating that the | 439 // instruction bits the size of the target will be zero, indicating that the |
| 420 // serializer should not step forwards in memory after a target is resolved | 440 // serializer should not step forwards in memory after a target is resolved |
| 421 // and written. In this case the target_address_address function above | 441 // and written. In this case the target_address_address function above |
| 422 // should return the end of the instructions to be patched, allowing the | 442 // should return the end of the instructions to be patched, allowing the |
| 423 // deserializer to deserialize the instructions as raw bytes and put them in | 443 // deserializer to deserialize the instructions as raw bytes and put them in |
| 424 // place, ready to be patched with the target. | 444 // place, ready to be patched with the target. |
| 425 INLINE(int target_address_size()); | 445 INLINE(int target_address_size()); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 // On ia32 and arm this is 1 + 4 + 1 + 1 + 1 + 4 = 12. | 550 // On ia32 and arm this is 1 + 4 + 1 + 1 + 1 + 4 = 12. |
| 531 // On x64 this is 1 + 4 + 1 + 1 + 1 + 8 == 16; | 551 // On x64 this is 1 + 4 + 1 + 1 + 1 + 8 == 16; |
| 532 // Here we use the maximum of the two. | 552 // Here we use the maximum of the two. |
| 533 static const int kMaxSize = 16; | 553 static const int kMaxSize = 16; |
| 534 | 554 |
| 535 private: | 555 private: |
| 536 inline uint32_t WriteVariableLengthPCJump(uint32_t pc_delta); | 556 inline uint32_t WriteVariableLengthPCJump(uint32_t pc_delta); |
| 537 inline void WriteTaggedPC(uint32_t pc_delta, int tag); | 557 inline void WriteTaggedPC(uint32_t pc_delta, int tag); |
| 538 inline void WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag); | 558 inline void WriteExtraTaggedPC(uint32_t pc_delta, int extra_tag); |
| 539 inline void WriteExtraTaggedIntData(int data_delta, int top_tag); | 559 inline void WriteExtraTaggedIntData(int data_delta, int top_tag); |
| 540 inline void WriteExtraTaggedConstPoolData(int data); | 560 inline void WriteExtraTaggedPoolData(int data, int pool_type); |
| 541 inline void WriteExtraTaggedData(intptr_t data_delta, int top_tag); | 561 inline void WriteExtraTaggedData(intptr_t data_delta, int top_tag); |
| 542 inline void WriteTaggedData(intptr_t data_delta, int tag); | 562 inline void WriteTaggedData(intptr_t data_delta, int tag); |
| 543 inline void WriteExtraTag(int extra_tag, int top_tag); | 563 inline void WriteExtraTag(int extra_tag, int top_tag); |
| 544 | 564 |
| 545 byte* pos_; | 565 byte* pos_; |
| 546 byte* last_pc_; | 566 byte* last_pc_; |
| 547 int last_id_; | 567 int last_id_; |
| 548 int last_position_; | 568 int last_position_; |
| 549 DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter); | 569 DISALLOW_COPY_AND_ASSIGN(RelocInfoWriter); |
| 550 }; | 570 }; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 581 // Advance* moves the position before/after reading. | 601 // Advance* moves the position before/after reading. |
| 582 // *Read* reads from current byte(s) into rinfo_. | 602 // *Read* reads from current byte(s) into rinfo_. |
| 583 // *Get* just reads and returns info on current byte. | 603 // *Get* just reads and returns info on current byte. |
| 584 void Advance(int bytes = 1) { pos_ -= bytes; } | 604 void Advance(int bytes = 1) { pos_ -= bytes; } |
| 585 int AdvanceGetTag(); | 605 int AdvanceGetTag(); |
| 586 int GetExtraTag(); | 606 int GetExtraTag(); |
| 587 int GetTopTag(); | 607 int GetTopTag(); |
| 588 void ReadTaggedPC(); | 608 void ReadTaggedPC(); |
| 589 void AdvanceReadPC(); | 609 void AdvanceReadPC(); |
| 590 void AdvanceReadId(); | 610 void AdvanceReadId(); |
| 591 void AdvanceReadConstPoolData(); | 611 void AdvanceReadPoolData(); |
| 592 void AdvanceReadPosition(); | 612 void AdvanceReadPosition(); |
| 593 void AdvanceReadData(); | 613 void AdvanceReadData(); |
| 594 void AdvanceReadVariableLengthPCJump(); | 614 void AdvanceReadVariableLengthPCJump(); |
| 595 int GetLocatableTypeTag(); | 615 int GetLocatableTypeTag(); |
| 596 void ReadTaggedId(); | 616 void ReadTaggedId(); |
| 597 void ReadTaggedPosition(); | 617 void ReadTaggedPosition(); |
| 598 | 618 |
| 599 // If the given mode is wanted, set it in rinfo_ and return true. | 619 // If the given mode is wanted, set it in rinfo_ and return true. |
| 600 // Else return false. Used for efficiently skipping unwanted modes. | 620 // Else return false. Used for efficiently skipping unwanted modes. |
| 601 bool SetMode(RelocInfo::Mode mode) { | 621 bool SetMode(RelocInfo::Mode mode) { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 | 724 |
| 705 // Isolate as an external reference. | 725 // Isolate as an external reference. |
| 706 static ExternalReference isolate_address(Isolate* isolate); | 726 static ExternalReference isolate_address(Isolate* isolate); |
| 707 | 727 |
| 708 // One-of-a-kind references. These references are not part of a general | 728 // One-of-a-kind references. These references are not part of a general |
| 709 // pattern. This means that they have to be added to the | 729 // pattern. This means that they have to be added to the |
| 710 // ExternalReferenceTable in serialize.cc manually. | 730 // ExternalReferenceTable in serialize.cc manually. |
| 711 | 731 |
| 712 static ExternalReference incremental_marking_record_write_function( | 732 static ExternalReference incremental_marking_record_write_function( |
| 713 Isolate* isolate); | 733 Isolate* isolate); |
| 714 static ExternalReference incremental_evacuation_record_write_function( | |
| 715 Isolate* isolate); | |
| 716 static ExternalReference store_buffer_overflow_function( | 734 static ExternalReference store_buffer_overflow_function( |
| 717 Isolate* isolate); | 735 Isolate* isolate); |
| 718 static ExternalReference flush_icache_function(Isolate* isolate); | 736 static ExternalReference flush_icache_function(Isolate* isolate); |
| 719 static ExternalReference perform_gc_function(Isolate* isolate); | 737 static ExternalReference perform_gc_function(Isolate* isolate); |
| 720 static ExternalReference delete_handle_scope_extensions(Isolate* isolate); | 738 static ExternalReference delete_handle_scope_extensions(Isolate* isolate); |
| 721 | 739 |
| 722 static ExternalReference get_date_field_function(Isolate* isolate); | 740 static ExternalReference get_date_field_function(Isolate* isolate); |
| 723 static ExternalReference date_cache_stamp(Isolate* isolate); | 741 static ExternalReference date_cache_stamp(Isolate* isolate); |
| 724 | 742 |
| 725 static ExternalReference get_make_code_young_function(Isolate* isolate); | 743 static ExternalReference get_make_code_young_function(Isolate* isolate); |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1032 }; | 1050 }; |
| 1033 | 1051 |
| 1034 class NullCallWrapper : public CallWrapper { | 1052 class NullCallWrapper : public CallWrapper { |
| 1035 public: | 1053 public: |
| 1036 NullCallWrapper() { } | 1054 NullCallWrapper() { } |
| 1037 virtual ~NullCallWrapper() { } | 1055 virtual ~NullCallWrapper() { } |
| 1038 virtual void BeforeCall(int call_size) const { } | 1056 virtual void BeforeCall(int call_size) const { } |
| 1039 virtual void AfterCall() const { } | 1057 virtual void AfterCall() const { } |
| 1040 }; | 1058 }; |
| 1041 | 1059 |
| 1060 |
| 1061 // The multiplier and shift for signed division via multiplication, see Warren's |
| 1062 // "Hacker's Delight", chapter 10. |
| 1063 class MultiplierAndShift { |
| 1064 public: |
| 1065 explicit MultiplierAndShift(int32_t d); |
| 1066 int32_t multiplier() const { return multiplier_; } |
| 1067 int32_t shift() const { return shift_; } |
| 1068 |
| 1069 private: |
| 1070 int32_t multiplier_; |
| 1071 int32_t shift_; |
| 1072 }; |
| 1073 |
| 1074 |
| 1042 } } // namespace v8::internal | 1075 } } // namespace v8::internal |
| 1043 | 1076 |
| 1044 #endif // V8_ASSEMBLER_H_ | 1077 #endif // V8_ASSEMBLER_H_ |
| OLD | NEW |