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 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
473 // | 473 // |
474 // Label L; // unbound label | 474 // Label L; // unbound label |
475 // j(cc, &L); // forward branch to unbound label | 475 // j(cc, &L); // forward branch to unbound label |
476 // bind(&L); // bind label to the current pc | 476 // bind(&L); // bind label to the current pc |
477 // j(cc, &L); // backward branch to bound label | 477 // j(cc, &L); // backward branch to bound label |
478 // bind(&L); // illegal: a label may be bound only once | 478 // bind(&L); // illegal: a label may be bound only once |
479 // | 479 // |
480 // Note: The same Label can be used for forward and backward branches | 480 // Note: The same Label can be used for forward and backward branches |
481 // but it may be bound only once. | 481 // but it may be bound only once. |
482 void bind(Label* L); // Binds an unbound label L to current code position. | 482 void bind(Label* L); // Binds an unbound label L to current code position. |
483 // Determines if Label is bound and near enough so that branch instruction | |
484 // can be used to reach it, instead of jump instruction. | |
485 bool is_near(Label* L); | |
483 | 486 |
484 // Returns the branch offset to the given label from the current code | 487 // Returns the branch offset to the given label from the current code |
485 // position. Links the label to the current position if it is still unbound. | 488 // position. Links the label to the current position if it is still unbound. |
486 // Manages the jump elimination optimization if the second parameter is true. | 489 // Manages the jump elimination optimization if the second parameter is true. |
487 int32_t branch_offset(Label* L, bool jump_elimination_allowed); | 490 int32_t branch_offset(Label* L, bool jump_elimination_allowed); |
488 int32_t shifted_branch_offset(Label* L, bool jump_elimination_allowed) { | 491 int32_t shifted_branch_offset(Label* L, bool jump_elimination_allowed) { |
489 int32_t o = branch_offset(L, jump_elimination_allowed); | 492 int32_t o = branch_offset(L, jump_elimination_allowed); |
490 ASSERT((o & 3) == 0); // Assert the offset is aligned. | 493 ASSERT((o & 3) == 0); // Assert the offset is aligned. |
491 return o >> 2; | 494 return o >> 2; |
492 } | 495 } |
496 uint32_t jump_address(Label* L); | |
493 | 497 |
494 // Puts a labels target address at the given position. | 498 // Puts a labels target address at the given position. |
495 // The high 8 bits are set to zero. | 499 // The high 8 bits are set to zero. |
496 void label_at_put(Label* L, int at_offset); | 500 void label_at_put(Label* L, int at_offset); |
497 | 501 |
498 // Read/Modify the code target address in the branch/call instruction at pc. | 502 // Read/Modify the code target address in the branch/call instruction at pc. |
499 static Address target_address_at(Address pc); | 503 static Address target_address_at(Address pc); |
500 static void set_target_address_at(Address pc, Address target); | 504 static void set_target_address_at(Address pc, Address target); |
501 | 505 |
502 // This sets the branch destination (which gets loaded at the call address). | 506 // This sets the branch destination (which gets loaded at the call address). |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
633 | 637 |
634 void addiu(Register rd, Register rs, int32_t j); | 638 void addiu(Register rd, Register rs, int32_t j); |
635 | 639 |
636 // Logical. | 640 // Logical. |
637 void and_(Register rd, Register rs, Register rt); | 641 void and_(Register rd, Register rs, Register rt); |
638 void or_(Register rd, Register rs, Register rt); | 642 void or_(Register rd, Register rs, Register rt); |
639 void xor_(Register rd, Register rs, Register rt); | 643 void xor_(Register rd, Register rs, Register rt); |
640 void nor(Register rd, Register rs, Register rt); | 644 void nor(Register rd, Register rs, Register rt); |
641 | 645 |
642 void andi(Register rd, Register rs, int32_t j); | 646 void andi(Register rd, Register rs, int32_t j); |
643 void ori(Register rd, Register rs, int32_t j); | 647 void ori(Register rd, Register rs, int32_t j, bool check_buffer = true); |
Søren Thygesen Gjesse
2011/06/24 13:05:15
This boolean flag seems rather obscure - when shou
Paul Lind
2011/06/28 06:53:14
Agree that it was confusing. I have removed the fl
| |
644 void xori(Register rd, Register rs, int32_t j); | 648 void xori(Register rd, Register rs, int32_t j); |
645 void lui(Register rd, int32_t j); | 649 void lui(Register rd, int32_t j, bool check_buffer = true); |
646 | 650 |
647 // Shifts. | 651 // Shifts. |
648 // Please note: sll(zero_reg, zero_reg, x) instructions are reserved as nop | 652 // Please note: sll(zero_reg, zero_reg, x) instructions are reserved as nop |
649 // and may cause problems in normal code. coming_from_nop makes sure this | 653 // and may cause problems in normal code. coming_from_nop makes sure this |
650 // doesn't happen. | 654 // doesn't happen. |
651 void sll(Register rd, Register rt, uint16_t sa, bool coming_from_nop = false); | 655 void sll(Register rd, Register rt, uint16_t sa, bool coming_from_nop = false); |
652 void sllv(Register rd, Register rt, Register rs); | 656 void sllv(Register rd, Register rt, Register rs); |
653 void srl(Register rd, Register rt, uint16_t sa); | 657 void srl(Register rd, Register rt, uint16_t sa); |
654 void srlv(Register rd, Register rt, Register rs); | 658 void srlv(Register rd, Register rt, Register rs); |
655 void sra(Register rt, Register rd, uint16_t sa); | 659 void sra(Register rt, Register rd, uint16_t sa); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
803 void RecordDebugBreakSlot(); | 807 void RecordDebugBreakSlot(); |
804 | 808 |
805 // Record the AST id of the CallIC being compiled, so that it can be placed | 809 // Record the AST id of the CallIC being compiled, so that it can be placed |
806 // in the relocation information. | 810 // in the relocation information. |
807 void RecordAstId(unsigned ast_id) { ast_id_for_reloc_info_ = ast_id; } | 811 void RecordAstId(unsigned ast_id) { ast_id_for_reloc_info_ = ast_id; } |
808 | 812 |
809 // Record a comment relocation entry that can be used by a disassembler. | 813 // Record a comment relocation entry that can be used by a disassembler. |
810 // Use --code-comments to enable. | 814 // Use --code-comments to enable. |
811 void RecordComment(const char* msg); | 815 void RecordComment(const char* msg); |
812 | 816 |
817 static void RelocateInternalReference(byte* pc, intptr_t pc_delta); | |
818 | |
813 // Writes a single byte or word of data in the code stream. Used for | 819 // Writes a single byte or word of data in the code stream. Used for |
814 // inline tables, e.g., jump-tables. | 820 // inline tables, e.g., jump-tables. |
815 void db(uint8_t data); | 821 void db(uint8_t data); |
816 void dd(uint32_t data); | 822 void dd(uint32_t data); |
817 | 823 |
818 int32_t pc_offset() const { return pc_ - buffer_; } | 824 int32_t pc_offset() const { return pc_ - buffer_; } |
819 | 825 |
820 PositionsRecorder* positions_recorder() { return &positions_recorder_; } | 826 PositionsRecorder* positions_recorder() { return &positions_recorder_; } |
821 | 827 |
822 // Postpone the generation of the trampoline pool for the specified number of | 828 // Postpone the generation of the trampoline pool for the specified number of |
(...skipping 16 matching lines...) Expand all Loading... | |
839 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } | 845 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } |
840 void instr_at_put(int pos, Instr instr) { | 846 void instr_at_put(int pos, Instr instr) { |
841 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; | 847 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; |
842 } | 848 } |
843 | 849 |
844 // Check if an instruction is a branch of some kind. | 850 // Check if an instruction is a branch of some kind. |
845 static bool IsBranch(Instr instr); | 851 static bool IsBranch(Instr instr); |
846 static bool IsBeq(Instr instr); | 852 static bool IsBeq(Instr instr); |
847 static bool IsBne(Instr instr); | 853 static bool IsBne(Instr instr); |
848 | 854 |
855 static bool IsJump(Instr instr); | |
856 static bool IsJ(Instr instr); | |
857 static bool IsLui(Instr instr); | |
858 static bool IsOri(Instr instr); | |
859 | |
849 static bool IsNop(Instr instr, unsigned int type); | 860 static bool IsNop(Instr instr, unsigned int type); |
850 static bool IsPop(Instr instr); | 861 static bool IsPop(Instr instr); |
851 static bool IsPush(Instr instr); | 862 static bool IsPush(Instr instr); |
852 static bool IsLwRegFpOffset(Instr instr); | 863 static bool IsLwRegFpOffset(Instr instr); |
853 static bool IsSwRegFpOffset(Instr instr); | 864 static bool IsSwRegFpOffset(Instr instr); |
854 static bool IsLwRegFpNegOffset(Instr instr); | 865 static bool IsLwRegFpNegOffset(Instr instr); |
855 static bool IsSwRegFpNegOffset(Instr instr); | 866 static bool IsSwRegFpNegOffset(Instr instr); |
856 | 867 |
857 static Register GetRtReg(Instr instr); | 868 static Register GetRtReg(Instr instr); |
858 static Register GetRsReg(Instr instr); | 869 static Register GetRsReg(Instr instr); |
859 static Register GetRdReg(Instr instr); | 870 static Register GetRdReg(Instr instr); |
860 | 871 |
861 static uint32_t GetRt(Instr instr); | 872 static uint32_t GetRt(Instr instr); |
862 static uint32_t GetRtField(Instr instr); | 873 static uint32_t GetRtField(Instr instr); |
863 static uint32_t GetRs(Instr instr); | 874 static uint32_t GetRs(Instr instr); |
864 static uint32_t GetRsField(Instr instr); | 875 static uint32_t GetRsField(Instr instr); |
865 static uint32_t GetRd(Instr instr); | 876 static uint32_t GetRd(Instr instr); |
866 static uint32_t GetRdField(Instr instr); | 877 static uint32_t GetRdField(Instr instr); |
867 static uint32_t GetSa(Instr instr); | 878 static uint32_t GetSa(Instr instr); |
868 static uint32_t GetSaField(Instr instr); | 879 static uint32_t GetSaField(Instr instr); |
869 static uint32_t GetOpcodeField(Instr instr); | 880 static uint32_t GetOpcodeField(Instr instr); |
881 static uint32_t GetFunction(Instr instr); | |
882 static uint32_t GetFunctionField(Instr instr); | |
870 static uint32_t GetImmediate16(Instr instr); | 883 static uint32_t GetImmediate16(Instr instr); |
871 static uint32_t GetLabelConst(Instr instr); | 884 static uint32_t GetLabelConst(Instr instr); |
872 | 885 |
873 static int32_t GetBranchOffset(Instr instr); | 886 static int32_t GetBranchOffset(Instr instr); |
874 static bool IsLw(Instr instr); | 887 static bool IsLw(Instr instr); |
875 static int16_t GetLwOffset(Instr instr); | 888 static int16_t GetLwOffset(Instr instr); |
876 static Instr SetLwOffset(Instr instr, int16_t offset); | 889 static Instr SetLwOffset(Instr instr, int16_t offset); |
877 | 890 |
878 static bool IsSw(Instr instr); | 891 static bool IsSw(Instr instr); |
879 static Instr SetSwOffset(Instr instr, int16_t offset); | 892 static Instr SetSwOffset(Instr instr, int16_t offset); |
880 static bool IsAddImmediate(Instr instr); | 893 static bool IsAddImmediate(Instr instr); |
881 static Instr SetAddImmediateOffset(Instr instr, int16_t offset); | 894 static Instr SetAddImmediateOffset(Instr instr, int16_t offset); |
882 | 895 |
883 static bool IsAndImmediate(Instr instr); | 896 static bool IsAndImmediate(Instr instr); |
884 | 897 |
885 void CheckTrampolinePool(bool force_emit = false); | 898 void CheckTrampolinePool(); |
886 | 899 |
887 protected: | 900 protected: |
888 // Relocation for a type-recording IC has the AST id added to it. This | 901 // Relocation for a type-recording IC has the AST id added to it. This |
889 // member variable is a way to pass the information from the call site to | 902 // member variable is a way to pass the information from the call site to |
890 // the relocation info. | 903 // the relocation info. |
891 unsigned ast_id_for_reloc_info_; | 904 unsigned ast_id_for_reloc_info_; |
892 | 905 |
893 bool emit_debug_code() const { return emit_debug_code_; } | 906 bool emit_debug_code() const { return emit_debug_code_; } |
894 | 907 |
895 int32_t buffer_space() const { return reloc_info_writer.pos() - pc_; } | 908 int32_t buffer_space() const { return reloc_info_writer.pos() - pc_; } |
(...skipping 24 matching lines...) Expand all Loading... | |
920 } | 933 } |
921 | 934 |
922 bool is_trampoline_pool_blocked() const { | 935 bool is_trampoline_pool_blocked() const { |
923 return trampoline_pool_blocked_nesting_ > 0; | 936 return trampoline_pool_blocked_nesting_ > 0; |
924 } | 937 } |
925 | 938 |
926 bool has_exception() const { | 939 bool has_exception() const { |
927 return internal_trampoline_exception_; | 940 return internal_trampoline_exception_; |
928 } | 941 } |
929 | 942 |
943 bool is_trampoline_emitted() const { | |
944 return trampoline_emitted_; | |
945 } | |
946 | |
930 private: | 947 private: |
931 // Code buffer: | 948 // Code buffer: |
932 // The buffer into which code and relocation info are generated. | 949 // The buffer into which code and relocation info are generated. |
933 byte* buffer_; | 950 byte* buffer_; |
934 int buffer_size_; | 951 int buffer_size_; |
935 // True if the assembler owns the buffer, false if buffer is external. | 952 // True if the assembler owns the buffer, false if buffer is external. |
936 bool own_buffer_; | 953 bool own_buffer_; |
937 | 954 |
938 // Buffer size and constant pool distance are checked together at regular | 955 // Buffer size and constant pool distance are checked together at regular |
939 // intervals of kBufferCheckInterval emitted bytes. | 956 // intervals of kBufferCheckInterval emitted bytes. |
940 static const int kBufferCheckInterval = 1*KB/2; | 957 static const int kBufferCheckInterval = 1*KB/2; |
941 | 958 |
942 // Code generation. | 959 // Code generation. |
943 // The relocation writer's position is at least kGap bytes below the end of | 960 // The relocation writer's position is at least kGap bytes below the end of |
944 // the generated instructions. This is so that multi-instruction sequences do | 961 // the generated instructions. This is so that multi-instruction sequences do |
945 // not have to check for overflow. The same is true for writes of large | 962 // not have to check for overflow. The same is true for writes of large |
946 // relocation info entries. | 963 // relocation info entries. MIPS uses 8 bytes more than other architectures, |
947 static const int kGap = 32; | 964 // because it does not check for this gap when instructions with internal |
965 // reference relocation info are emitted. | |
966 static const int kGap = 40; | |
948 byte* pc_; // The program counter - moves forward. | 967 byte* pc_; // The program counter - moves forward. |
949 | 968 |
950 | 969 |
951 // Repeated checking whether the trampoline pool should be emitted is rather | 970 // Repeated checking whether the trampoline pool should be emitted is rather |
952 // expensive. By default we only check again once a number of instructions | 971 // expensive. By default we only check again once a number of instructions |
953 // has been generated. | 972 // has been generated. |
954 static const int kCheckConstIntervalInst = 32; | 973 static const int kCheckConstIntervalInst = 32; |
955 static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize; | 974 static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize; |
956 | 975 |
957 int next_buffer_check_; // pc offset of next buffer check. | 976 int next_buffer_check_; // pc offset of next buffer check. |
958 | 977 |
959 // Emission of the trampoline pool may be blocked in some code sequences. | 978 // Emission of the trampoline pool may be blocked in some code sequences. |
960 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. | 979 int trampoline_pool_blocked_nesting_; // Block emission if this is not zero. |
961 int no_trampoline_pool_before_; // Block emission before this pc offset. | 980 int no_trampoline_pool_before_; // Block emission before this pc offset. |
962 | 981 |
963 // Keep track of the last emitted pool to guarantee a maximal distance. | 982 // Keep track of the last emitted pool to guarantee a maximal distance. |
964 int last_trampoline_pool_end_; // pc offset of the end of the last pool. | 983 int last_trampoline_pool_end_; // pc offset of the end of the last pool. |
965 | 984 |
966 // Relocation information generation. | 985 // Relocation information generation. |
967 // Each relocation is encoded as a variable size value. | 986 // Each relocation is encoded as a variable size value. |
968 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; | 987 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; |
969 RelocInfoWriter reloc_info_writer; | 988 RelocInfoWriter reloc_info_writer; |
970 | 989 |
971 // The bound position, before this we cannot do instruction elimination. | 990 // The bound position, before this we cannot do instruction elimination. |
972 int last_bound_pos_; | 991 int last_bound_pos_; |
973 | 992 |
974 // Code emission. | 993 // Code emission. |
975 inline void CheckBuffer(); | 994 inline void CheckBuffer(); |
976 void GrowBuffer(); | 995 void GrowBuffer(); |
977 inline void emit(Instr x); | 996 inline void emit(Instr x, bool check_buffer = true); |
978 inline void CheckTrampolinePoolQuick(); | 997 inline void CheckTrampolinePoolQuick(); |
979 | 998 |
980 // Instruction generation. | 999 // Instruction generation. |
981 // We have 3 different kind of encoding layout on MIPS. | 1000 // We have 3 different kind of encoding layout on MIPS. |
982 // However due to many different types of objects encoded in the same fields | 1001 // However due to many different types of objects encoded in the same fields |
983 // we have quite a few aliases for each mode. | 1002 // we have quite a few aliases for each mode. |
984 // Using the same structure to refer to Register and FPURegister would spare a | 1003 // Using the same structure to refer to Register and FPURegister would spare a |
985 // few aliases, but mixing both does not look clean to me. | 1004 // few aliases, but mixing both does not look clean to me. |
986 // Anyway we could surely implement this differently. | 1005 // Anyway we could surely implement this differently. |
987 | 1006 |
(...skipping 28 matching lines...) Expand all Loading... | |
1016 void GenInstrRegister(Opcode opcode, | 1035 void GenInstrRegister(Opcode opcode, |
1017 SecondaryField fmt, | 1036 SecondaryField fmt, |
1018 Register rt, | 1037 Register rt, |
1019 FPUControlRegister fs, | 1038 FPUControlRegister fs, |
1020 SecondaryField func = NULLSF); | 1039 SecondaryField func = NULLSF); |
1021 | 1040 |
1022 | 1041 |
1023 void GenInstrImmediate(Opcode opcode, | 1042 void GenInstrImmediate(Opcode opcode, |
1024 Register rs, | 1043 Register rs, |
1025 Register rt, | 1044 Register rt, |
1026 int32_t j); | 1045 int32_t j, |
1046 bool check_buffer = true); | |
1027 void GenInstrImmediate(Opcode opcode, | 1047 void GenInstrImmediate(Opcode opcode, |
1028 Register rs, | 1048 Register rs, |
1029 SecondaryField SF, | 1049 SecondaryField SF, |
1030 int32_t j); | 1050 int32_t j); |
1031 void GenInstrImmediate(Opcode opcode, | 1051 void GenInstrImmediate(Opcode opcode, |
1032 Register r1, | 1052 Register r1, |
1033 FPURegister r2, | 1053 FPURegister r2, |
1034 int32_t j); | 1054 int32_t j); |
1035 | 1055 |
1036 | 1056 |
1037 void GenInstrJump(Opcode opcode, | 1057 void GenInstrJump(Opcode opcode, |
1038 uint32_t address); | 1058 uint32_t address); |
1039 | 1059 |
1040 // Helpers. | 1060 // Helpers. |
1041 void LoadRegPlusOffsetToAt(const MemOperand& src); | 1061 void LoadRegPlusOffsetToAt(const MemOperand& src); |
1042 | 1062 |
1043 // Labels. | 1063 // Labels. |
1044 void print(Label* L); | 1064 void print(Label* L); |
1045 void bind_to(Label* L, int pos); | 1065 void bind_to(Label* L, int pos); |
1046 void link_to(Label* L, Label* appendix); | |
1047 void next(Label* L); | 1066 void next(Label* L); |
1048 | 1067 |
1049 // One trampoline consists of: | 1068 // One trampoline consists of: |
1050 // - space for trampoline slots, | 1069 // - space for trampoline slots, |
1051 // - space for labels. | 1070 // - space for labels. |
1052 // | 1071 // |
1053 // Space for trampoline slots is equal to slot_count * 2 * kInstrSize. | 1072 // Space for trampoline slots is equal to slot_count * 2 * kInstrSize. |
1054 // Space for trampoline slots preceeds space for labels. Each label is of one | 1073 // Space for trampoline slots preceeds space for labels. Each label is of one |
1055 // instruction size, so total amount for labels is equal to | 1074 // instruction size, so total amount for labels is equal to |
1056 // label_count * kInstrSize. | 1075 // label_count * kInstrSize. |
1057 class Trampoline { | 1076 class Trampoline { |
1058 public: | 1077 public: |
1059 Trampoline(int start, int slot_count, int label_count) { | 1078 Trampoline() { |
1079 start_ = 0; | |
1080 next_slot_ = 0; | |
1081 free_slot_count_ = 0; | |
1082 end_ = 0; | |
1083 } | |
1084 Trampoline(int start, int slot_count) { | |
1060 start_ = start; | 1085 start_ = start; |
1061 next_slot_ = start; | 1086 next_slot_ = start; |
1062 free_slot_count_ = slot_count; | 1087 free_slot_count_ = slot_count; |
1063 next_label_ = start + slot_count * 2 * kInstrSize; | 1088 end_ = start + slot_count * kTrampolineSlotsSize; |
1064 free_label_count_ = label_count; | |
1065 end_ = next_label_ + (label_count - 1) * kInstrSize; | |
1066 } | 1089 } |
1067 int start() { | 1090 int start() { |
1068 return start_; | 1091 return start_; |
1069 } | 1092 } |
1070 int end() { | 1093 int end() { |
1071 return end_; | 1094 return end_; |
1072 } | 1095 } |
1073 int take_slot() { | 1096 int take_slot() { |
1074 int trampoline_slot = kInvalidSlotPos; | 1097 int trampoline_slot = kInvalidSlotPos; |
1075 if (free_slot_count_ <= 0) { | 1098 if (free_slot_count_ <= 0) { |
1076 // We have run out of space on trampolines. | 1099 // We have run out of space on trampolines. |
1077 // Make sure we fail in debug mode, so we become aware of each case | 1100 // Make sure we fail in debug mode, so we become aware of each case |
1078 // when this happens. | 1101 // when this happens. |
1079 ASSERT(0); | 1102 ASSERT(0); |
1080 // Internal exception will be caught. | 1103 // Internal exception will be caught. |
1081 } else { | 1104 } else { |
1082 trampoline_slot = next_slot_; | 1105 trampoline_slot = next_slot_; |
1083 free_slot_count_--; | 1106 free_slot_count_--; |
1084 next_slot_ += 2*kInstrSize; | 1107 next_slot_ += kTrampolineSlotsSize; |
1085 } | 1108 } |
1086 return trampoline_slot; | 1109 return trampoline_slot; |
1087 } | 1110 } |
1088 int take_label() { | |
1089 int label_pos = next_label_; | |
1090 ASSERT(free_label_count_ > 0); | |
1091 free_label_count_--; | |
1092 next_label_ += kInstrSize; | |
1093 return label_pos; | |
1094 } | |
1095 | |
1096 private: | 1111 private: |
1097 int start_; | 1112 int start_; |
1098 int end_; | 1113 int end_; |
1099 int next_slot_; | 1114 int next_slot_; |
1100 int free_slot_count_; | 1115 int free_slot_count_; |
1101 int next_label_; | |
1102 int free_label_count_; | |
1103 }; | 1116 }; |
1104 | 1117 |
1105 int32_t get_label_entry(int32_t pos, bool next_pool = true); | 1118 int32_t get_trampoline_entry(int32_t pos); |
1106 int32_t get_trampoline_entry(int32_t pos, bool next_pool = true); | 1119 int unbound_labels_count; |
1107 | 1120 // If trampoline is emitted, generated code is becoming large. As this is |
1108 static const int kSlotsPerTrampoline = 2304; | 1121 // already a slow case which can possibly break our code generation for |
Søren Thygesen Gjesse
2011/06/24 13:05:15
for -> for the / in the
Paul Lind
2011/06/28 06:53:14
Done.
| |
1109 static const int kLabelsPerTrampoline = 8; | 1122 // extreme case, we use this information to trigger different mode for |
Søren Thygesen Gjesse
2011/06/24 13:05:15
for -> of
Paul Lind
2011/06/28 06:53:14
Done.
| |
1110 static const int kTrampolineInst = | 1123 // branch instruction generation, where we use jump instructions rather |
1111 2 * kSlotsPerTrampoline + kLabelsPerTrampoline; | 1124 // than regular branch instructions. |
1112 static const int kTrampolineSize = kTrampolineInst * kInstrSize; | 1125 bool trampoline_emitted_; |
1126 static const int kTrampolineSlotsSize = 4 * kInstrSize; | |
1113 static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; | 1127 static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; |
1114 static const int kMaxDistBetweenPools = | |
1115 kMaxBranchOffset - 2 * kTrampolineSize; | |
1116 static const int kInvalidSlotPos = -1; | 1128 static const int kInvalidSlotPos = -1; |
1117 | 1129 |
1118 List<Trampoline> trampolines_; | 1130 Trampoline trampoline_; |
1119 bool internal_trampoline_exception_; | 1131 bool internal_trampoline_exception_; |
1120 | 1132 |
1121 friend class RegExpMacroAssemblerMIPS; | 1133 friend class RegExpMacroAssemblerMIPS; |
1122 friend class RelocInfo; | 1134 friend class RelocInfo; |
1123 friend class CodePatcher; | 1135 friend class CodePatcher; |
1124 friend class BlockTrampolinePoolScope; | 1136 friend class BlockTrampolinePoolScope; |
1125 | 1137 |
1126 PositionsRecorder positions_recorder_; | 1138 PositionsRecorder positions_recorder_; |
1127 bool emit_debug_code_; | 1139 bool emit_debug_code_; |
1128 friend class PositionsRecorder; | 1140 friend class PositionsRecorder; |
1129 friend class EnsureSpace; | 1141 friend class EnsureSpace; |
1130 }; | 1142 }; |
1131 | 1143 |
1132 | 1144 |
1133 class EnsureSpace BASE_EMBEDDED { | 1145 class EnsureSpace BASE_EMBEDDED { |
1134 public: | 1146 public: |
1135 explicit EnsureSpace(Assembler* assembler) { | 1147 explicit EnsureSpace(Assembler* assembler) { |
1136 assembler->CheckBuffer(); | 1148 assembler->CheckBuffer(); |
1137 } | 1149 } |
1138 }; | 1150 }; |
1139 | 1151 |
1140 } } // namespace v8::internal | 1152 } } // namespace v8::internal |
1141 | 1153 |
1142 #endif // V8_ARM_ASSEMBLER_MIPS_H_ | 1154 #endif // V8_ARM_ASSEMBLER_MIPS_H_ |
OLD | NEW |