Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 194 TYPE_STRTAB = 3, | 194 TYPE_STRTAB = 3, |
| 195 TYPE_RELA = 4, | 195 TYPE_RELA = 4, |
| 196 TYPE_HASH = 5, | 196 TYPE_HASH = 5, |
| 197 TYPE_DYNAMIC = 6, | 197 TYPE_DYNAMIC = 6, |
| 198 TYPE_NOTE = 7, | 198 TYPE_NOTE = 7, |
| 199 TYPE_NOBITS = 8, | 199 TYPE_NOBITS = 8, |
| 200 TYPE_REL = 9, | 200 TYPE_REL = 9, |
| 201 TYPE_SHLIB = 10, | 201 TYPE_SHLIB = 10, |
| 202 TYPE_DYNSYM = 11, | 202 TYPE_DYNSYM = 11, |
| 203 TYPE_LOPROC = 0x70000000, | 203 TYPE_LOPROC = 0x70000000, |
| 204 TYPE_X86_64_UNWIND = 0x70000001, | |
| 204 TYPE_HIPROC = 0x7fffffff, | 205 TYPE_HIPROC = 0x7fffffff, |
| 205 TYPE_LOUSER = 0x80000000, | 206 TYPE_LOUSER = 0x80000000, |
| 206 TYPE_HIUSER = 0xffffffff | 207 TYPE_HIUSER = 0xffffffff |
| 207 }; | 208 }; |
| 208 | 209 |
| 209 enum Flags { | 210 enum Flags { |
| 210 FLAG_WRITE = 1, | 211 FLAG_WRITE = 1, |
| 211 FLAG_ALLOC = 2, | 212 FLAG_ALLOC = 2, |
| 212 FLAG_EXEC = 4 | 213 FLAG_EXEC = 4 |
| 213 }; | 214 }; |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 632 } | 633 } |
| 633 } | 634 } |
| 634 | 635 |
| 635 ZoneList<ELFSymbol> locals_; | 636 ZoneList<ELFSymbol> locals_; |
| 636 ZoneList<ELFSymbol> globals_; | 637 ZoneList<ELFSymbol> globals_; |
| 637 }; | 638 }; |
| 638 | 639 |
| 639 | 640 |
| 640 class CodeDescription BASE_EMBEDDED { | 641 class CodeDescription BASE_EMBEDDED { |
| 641 public: | 642 public: |
| 643 | |
| 644 enum OffsetType { | |
| 645 #ifdef V8_TARGET_ARCH_X64 | |
| 646 POST_RBP_PUSH, | |
| 647 POST_RBP_SET, | |
| 648 POST_RBP_POP, | |
| 649 OFFSET_TYPE_MAX | |
| 650 #endif | |
| 651 }; | |
| 652 | |
| 642 CodeDescription(const char* name, | 653 CodeDescription(const char* name, |
| 643 Code* code, | 654 Code* code, |
| 644 Handle<Script> script, | 655 Handle<Script> script, |
| 645 GDBJITLineInfo* lineinfo) | 656 GDBJITLineInfo* lineinfo, |
| 646 : name_(name), code_(code), script_(script), lineinfo_(lineinfo) | 657 GDBJITInterface::CodeTag type) |
|
Vyacheslav Egorov (Chromium)
2011/02/01 13:17:25
nitpick: type -> tag
| |
| 658 : name_(name), | |
| 659 code_(code), | |
| 660 script_(script), | |
| 661 lineinfo_(lineinfo), | |
| 662 type_(type) | |
|
Vyacheslav Egorov (Chromium)
2011/02/01 13:17:25
nitpick: type -> tag
| |
| 647 { } | 663 { } |
| 648 | 664 |
| 649 const char* code_name() const { | 665 const char* code_name() const { |
| 650 return name_; | 666 return name_; |
| 651 } | 667 } |
| 652 | 668 |
| 653 uintptr_t code_size() const { | 669 uintptr_t code_size() const { |
| 654 return code_->instruction_end() - code_->instruction_start(); | 670 return code_->instruction_end() - code_->instruction_start(); |
| 655 } | 671 } |
| 656 | 672 |
| 673 uintptr_t code_end() const { | |
| 674 return (uintptr_t)code_->instruction_end(); | |
| 675 } | |
| 676 | |
| 657 uintptr_t code_start() const { | 677 uintptr_t code_start() const { |
| 658 return (uintptr_t)code_->instruction_start(); | 678 return (uintptr_t)code_->instruction_start(); |
| 659 } | 679 } |
| 660 | 680 |
| 661 bool is_line_info_available() { | 681 bool is_line_info_available() { |
| 662 return !script_.is_null() && | 682 return !script_.is_null() && |
| 663 script_->source()->IsString() && | 683 script_->source()->IsString() && |
| 664 script_->HasValidSource() && | 684 script_->HasValidSource() && |
| 665 script_->name()->IsString() && | 685 script_->name()->IsString() && |
| 666 lineinfo_ != NULL; | 686 lineinfo_ != NULL; |
| 667 } | 687 } |
| 668 | 688 |
| 689 uintptr_t get_location(OffsetType ofs) const { | |
| 690 ASSERT(ofs < OFFSET_TYPE_MAX); | |
|
Vyacheslav Egorov (Chromium)
2011/02/01 13:17:25
will not compile on ia32
| |
| 691 return offsets_[ofs]; | |
| 692 } | |
| 693 | |
| 694 void set_location(OffsetType ofs, uintptr_t value) { | |
| 695 ASSERT(ofs < OFFSET_TYPE_MAX); | |
|
Vyacheslav Egorov (Chromium)
2011/02/01 13:17:25
will not compile on ia32
| |
| 696 offsets_[ofs] = value; | |
| 697 } | |
| 698 | |
| 669 GDBJITLineInfo* lineinfo() const { return lineinfo_; } | 699 GDBJITLineInfo* lineinfo() const { return lineinfo_; } |
| 670 | 700 |
| 671 SmartPointer<char> filename() { | 701 SmartPointer<char> filename() { |
| 672 return String::cast(script_->name())->ToCString(); | 702 return String::cast(script_->name())->ToCString(); |
| 673 } | 703 } |
| 674 | 704 |
| 675 int GetScriptLineNumber(int pos) { | 705 int GetScriptLineNumber(int pos) { |
| 676 return GetScriptLineNumberSafe(script_, pos) + 1; | 706 return GetScriptLineNumberSafe(script_, pos) + 1; |
| 677 } | 707 } |
| 678 | 708 |
| 709 GDBJITInterface::CodeTag get_type() const { | |
|
Vyacheslav Egorov (Chromium)
2011/02/01 13:17:25
nitpick: type -> tag
| |
| 710 return type_; | |
|
Vyacheslav Egorov (Chromium)
2011/02/01 13:17:25
nitpick: type -> tag
| |
| 711 } | |
| 712 | |
| 679 private: | 713 private: |
| 680 const char* name_; | 714 const char* name_; |
| 681 Code* code_; | 715 Code* code_; |
| 682 Handle<Script> script_; | 716 Handle<Script> script_; |
| 683 GDBJITLineInfo* lineinfo_; | 717 GDBJITLineInfo* lineinfo_; |
| 718 GDBJITInterface::CodeTag type_; | |
|
Vyacheslav Egorov (Chromium)
2011/02/01 13:17:25
nitpick: type -> tag
| |
| 719 #ifdef V8_TARGET_ARCH_X64 | |
| 720 uintptr_t offsets_[OFFSET_TYPE_MAX]; | |
| 721 #endif | |
| 684 }; | 722 }; |
| 685 | 723 |
| 686 | 724 |
| 687 static void CreateSymbolsTable(CodeDescription* desc, | 725 static void CreateSymbolsTable(CodeDescription* desc, |
| 688 ELF* elf, | 726 ELF* elf, |
| 689 int text_section_index) { | 727 int text_section_index) { |
| 690 ELFSymbolTable* symtab = new ELFSymbolTable(".symtab"); | 728 ELFSymbolTable* symtab = new ELFSymbolTable(".symtab"); |
| 691 StringTable* strtab = new StringTable(".strtab"); | 729 StringTable* strtab = new StringTable(".strtab"); |
| 692 | 730 |
| 693 // Symbol table should be followed by the linked string table. | 731 // Symbol table should be followed by the linked string table. |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 893 return +1; | 931 return +1; |
| 894 } else { | 932 } else { |
| 895 return -1; | 933 return -1; |
| 896 } | 934 } |
| 897 } | 935 } |
| 898 | 936 |
| 899 CodeDescription* desc_; | 937 CodeDescription* desc_; |
| 900 }; | 938 }; |
| 901 | 939 |
| 902 | 940 |
| 941 #ifdef V8_TARGET_ARCH_X64 | |
| 942 | |
| 943 | |
| 944 class UnwindInfoSection : public ELFSection { | |
| 945 public: | |
| 946 explicit UnwindInfoSection(CodeDescription *desc); | |
| 947 virtual bool WriteBody(Writer *w); | |
| 948 | |
| 949 int WriteCIE(Writer *w); | |
| 950 void WriteFDE(Writer *w, int); | |
| 951 | |
| 952 void WriteFDEStateOne(Writer *w); | |
| 953 void WriteFDEStateTwo(Writer *w); | |
| 954 void WriteFDEStateThree(Writer *w); | |
| 955 void WriteFDEStateFour(Writer *w); | |
| 956 | |
| 957 void WriteLength(Writer *w, Writer::Slot<uint32_t> &, int); | |
| 958 | |
| 959 private: | |
| 960 CodeDescription *desc_; | |
| 961 | |
| 962 // DWARF3 Specification, Table 7.23 | |
| 963 enum CFIInstructions { | |
| 964 DW_CFA_ADVANCE_LOC = 0X40, | |
| 965 DW_CFA_OFFSET = 0X80, | |
| 966 DW_CFA_RESTORE = 0XC0, | |
| 967 DW_CFA_NOP = 0X00, | |
| 968 DW_CFA_SET_LOC = 0X01, | |
| 969 DW_CFA_ADVANCE_LOC1 = 0X02, | |
| 970 DW_CFA_ADVANCE_LOC2 = 0X03, | |
| 971 DW_CFA_ADVANCE_LOC4 = 0X04, | |
| 972 DW_CFA_OFFSET_EXTENDED = 0X05, | |
| 973 DW_CFA_RESTORE_EXTENDED = 0X06, | |
| 974 DW_CFA_UNDEFINED = 0X07, | |
| 975 DW_CFA_SAME_VALUE = 0X08, | |
| 976 DW_CFA_REGISTER = 0X09, | |
| 977 DW_CFA_REMEMBER_STATE = 0X0A, | |
| 978 DW_CFA_RESTORE_STATE = 0X0B, | |
| 979 DW_CFA_DEF_CFA = 0X0C, | |
| 980 DW_CFA_DEF_CFA_REGISTER = 0X0D, | |
| 981 DW_CFA_DEF_CFA_OFFSET = 0X0E, | |
| 982 | |
| 983 DW_CFA_DEF_CFA_EXPRESSION = 0X0F, | |
| 984 DW_CFA_EXPRESSION = 0X10, | |
| 985 DW_CFA_OFFSET_EXTENDED_SF = 0X11, | |
| 986 DW_CFA_DEF_CFA_SF = 0X12, | |
| 987 DW_CFA_DEF_CFA_OFFSET_SF = 0X13, | |
| 988 DW_CFA_VAL_OFFSET = 0X14, | |
| 989 DW_CFA_VAL_OFFSET_SF = 0X15, | |
| 990 DW_CFA_VAL_EXPRESSION = 0X16 | |
| 991 }; | |
| 992 | |
| 993 // System V ABI, AMD64 Supplement, Version 0.99.5, Figure 3.36 | |
| 994 enum RegisterMapping { | |
| 995 // Only the relevant ones have been added to reduce clutter. | |
| 996 AMD64_RBP = 6, | |
| 997 AMD64_RSP = 7, | |
| 998 AMD64_RA = 16 | |
| 999 }; | |
| 1000 | |
| 1001 enum CFIConstants { | |
| 1002 CIE_ID = 0, | |
| 1003 CIE_VERSION = 1, | |
| 1004 CODE_ALIGN_FACTOR = 1, | |
| 1005 DATA_ALIGN_FACTOR = 1, | |
| 1006 RETURN_ADDRESS_REGISTER = AMD64_RA | |
| 1007 }; | |
| 1008 }; | |
| 1009 | |
| 1010 | |
| 1011 void UnwindInfoSection::WriteLength(Writer *w, | |
| 1012 Writer::Slot<uint32_t> &length_slot, | |
| 1013 int initial_position) { | |
| 1014 uint32_t align = (w->position() - initial_position) % kPointerSize; | |
| 1015 | |
| 1016 if (align != 0) { | |
| 1017 for (uint32_t i = 0; i < (kPointerSize - align); i++) | |
| 1018 w->Write<uint8_t>(DW_CFA_NOP); | |
| 1019 } | |
| 1020 | |
| 1021 ASSERT((w->position() - initial_position) % kPointerSize == 0); | |
| 1022 length_slot.set(w->position() - initial_position); | |
| 1023 } | |
| 1024 | |
| 1025 | |
| 1026 UnwindInfoSection::UnwindInfoSection(CodeDescription *desc) | |
| 1027 : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), desc_(desc) | |
| 1028 { } | |
| 1029 | |
| 1030 int UnwindInfoSection::WriteCIE(Writer *w) { | |
| 1031 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>(); | |
| 1032 uint32_t cie_position = w->position(); | |
| 1033 | |
| 1034 // Write out the CIE header. Currently no 'common instructions' are | |
| 1035 // emitted onto the CIE; every FDE has its own set of instructions. | |
| 1036 | |
| 1037 w->Write<uint32_t>(CIE_ID); | |
| 1038 w->Write<uint8_t>(CIE_VERSION); | |
| 1039 w->Write<uint8_t>(0); // Null augmentation string. | |
| 1040 w->WriteSLEB128(CODE_ALIGN_FACTOR); | |
| 1041 w->WriteSLEB128(DATA_ALIGN_FACTOR); | |
| 1042 w->Write<uint8_t>(RETURN_ADDRESS_REGISTER); | |
| 1043 | |
| 1044 WriteLength(w, cie_length_slot, cie_position); | |
| 1045 | |
| 1046 return cie_position; | |
| 1047 } | |
| 1048 | |
| 1049 | |
| 1050 void UnwindInfoSection::WriteFDE(Writer *w, int cie_position) { | |
| 1051 // The only FDE for this function. The CFA is the current RBP. | |
| 1052 Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>(); | |
| 1053 int fde_position = w->position(); | |
| 1054 w->Write<int32_t>(fde_position - cie_position + 4); | |
| 1055 | |
| 1056 w->Write<uintptr_t>(desc_->code_start()); | |
| 1057 w->Write<uintptr_t>(desc_->code_size()); | |
| 1058 | |
| 1059 WriteFDEStateOne(w); | |
| 1060 WriteFDEStateTwo(w); | |
| 1061 WriteFDEStateThree(w); | |
| 1062 WriteFDEStateFour(w); | |
| 1063 | |
| 1064 WriteLength(w, fde_length_slot, fde_position); | |
| 1065 } | |
| 1066 | |
| 1067 | |
| 1068 void UnwindInfoSection::WriteFDEStateOne(Writer *w) { | |
| 1069 // The first state, just after the control has been transferred to the the | |
| 1070 // function. | |
| 1071 | |
| 1072 // RBP for this function will be the value of RSP after pushing the RBP | |
| 1073 // for the previous function. The previous RBP has not been pushed yet. | |
| 1074 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); | |
| 1075 w->WriteULEB128(AMD64_RSP); | |
| 1076 w->WriteSLEB128(-kPointerSize); | |
| 1077 | |
| 1078 // The RA is stored at location CFA + kCallerPCOffset. This is an invariant, | |
| 1079 // and hence omitted from the next states. | |
| 1080 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); | |
| 1081 w->WriteULEB128(AMD64_RA); | |
| 1082 w->WriteSLEB128(StandardFrameConstants::kCallerPCOffset); | |
| 1083 | |
| 1084 // The RBP of the previous function is still in RBP. | |
| 1085 w->Write<uint8_t>(DW_CFA_SAME_VALUE); | |
| 1086 w->WriteULEB128(AMD64_RBP); | |
| 1087 | |
| 1088 // Last location described by this entry. | |
| 1089 w->Write<uint8_t>(DW_CFA_SET_LOC); | |
| 1090 w->Write<uint64_t>(desc_->get_location(CodeDescription::POST_RBP_PUSH)); | |
| 1091 } | |
| 1092 | |
| 1093 | |
| 1094 void UnwindInfoSection::WriteFDEStateTwo(Writer *w) { | |
| 1095 // The second state, just after RBP has been pushed. | |
| 1096 | |
| 1097 // RBP / CFA for this function is now the current RSP, so just set the | |
| 1098 // offset from the previous rule (from -8) to 0. | |
| 1099 w->Write<uint8_t>(DW_CFA_DEF_CFA_OFFSET); | |
| 1100 w->WriteULEB128(0); | |
| 1101 | |
| 1102 // The previous RBP is stored at CFA + kCallerFPOffset. This is an invariant | |
| 1103 // in this and the next state, and hence omitted in the next state. | |
| 1104 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); | |
| 1105 w->WriteULEB128(AMD64_RBP); | |
| 1106 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); | |
| 1107 | |
| 1108 // Last location described by this entry. | |
| 1109 w->Write<uint8_t>(DW_CFA_SET_LOC); | |
| 1110 w->Write<uint64_t>(desc_->get_location(CodeDescription::POST_RBP_SET)); | |
| 1111 } | |
| 1112 | |
| 1113 | |
| 1114 void UnwindInfoSection::WriteFDEStateThree(Writer *w) { | |
| 1115 // The third state, after the RBP has been set. | |
| 1116 | |
| 1117 // The CFA can now directly be set to RBP. | |
| 1118 w->Write<uint8_t>(DW_CFA_DEF_CFA); | |
| 1119 w->WriteULEB128(AMD64_RBP); | |
| 1120 w->WriteULEB128(0); | |
| 1121 | |
| 1122 // Last location described by this entry. | |
| 1123 w->Write<uint8_t>(DW_CFA_SET_LOC); | |
| 1124 w->Write<uint64_t>(desc_->get_location(CodeDescription::POST_RBP_POP)); | |
| 1125 } | |
| 1126 | |
| 1127 | |
| 1128 void UnwindInfoSection::WriteFDEStateFour(Writer *w) { | |
| 1129 // The fourth (final) state. The RBP has been popped (just before issuing a | |
| 1130 // return). | |
| 1131 | |
| 1132 // The CFA can is now calculated in the same way as in the first state. | |
| 1133 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); | |
| 1134 w->WriteULEB128(AMD64_RSP); | |
| 1135 w->WriteSLEB128(-kPointerSize); | |
| 1136 | |
| 1137 // The RBP | |
| 1138 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); | |
| 1139 w->WriteULEB128(AMD64_RBP); | |
| 1140 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); | |
| 1141 | |
| 1142 // Last location described by this entry. | |
| 1143 w->Write<uint8_t>(DW_CFA_SET_LOC); | |
| 1144 w->Write<uint64_t>(desc_->code_end()); | |
| 1145 } | |
| 1146 | |
| 1147 | |
| 1148 bool UnwindInfoSection::WriteBody(Writer *w) { | |
| 1149 uint32_t cie_position = WriteCIE(w); | |
| 1150 WriteFDE(w, cie_position); | |
| 1151 return true; | |
| 1152 } | |
| 1153 | |
| 1154 | |
| 1155 #endif // V8_TARGET_ARCH_X64 | |
| 1156 | |
| 1157 | |
| 903 static void CreateDWARFSections(CodeDescription* desc, ELF* elf) { | 1158 static void CreateDWARFSections(CodeDescription* desc, ELF* elf) { |
| 904 if (desc->is_line_info_available()) { | 1159 if (desc->is_line_info_available()) { |
| 905 elf->AddSection(new DebugInfoSection(desc)); | 1160 elf->AddSection(new DebugInfoSection(desc)); |
| 906 elf->AddSection(new DebugAbbrevSection); | 1161 elf->AddSection(new DebugAbbrevSection); |
| 907 elf->AddSection(new DebugLineSection(desc)); | 1162 elf->AddSection(new DebugLineSection(desc)); |
| 908 } | 1163 } |
| 909 } | 1164 elf->AddSection(new UnwindInfoSection(desc)); |
|
Vyacheslav Egorov (Chromium)
2011/02/01 13:17:25
I don't think it will compile on ia32
| |
| 910 | 1165 } |
| 911 | 1166 |
| 1167 | |
| 912 // ------------------------------------------------------------------- | 1168 // ------------------------------------------------------------------- |
| 913 // Binary GDB JIT Interface as described in | 1169 // Binary GDB JIT Interface as described in |
| 914 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html | 1170 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html |
| 915 extern "C" { | 1171 extern "C" { |
| 916 typedef enum { | 1172 typedef enum { |
| 917 JIT_NOACTION = 0, | 1173 JIT_NOACTION = 0, |
| 918 JIT_REGISTER_FN, | 1174 JIT_REGISTER_FN, |
| 919 JIT_UNREGISTER_FN | 1175 JIT_UNREGISTER_FN |
| 920 } JITAction; | 1176 } JITAction; |
| 921 | 1177 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1058 void GDBJITInterface::AddCode(Handle<String> name, | 1314 void GDBJITInterface::AddCode(Handle<String> name, |
| 1059 Handle<Script> script, | 1315 Handle<Script> script, |
| 1060 Handle<Code> code) { | 1316 Handle<Code> code) { |
| 1061 if (!FLAG_gdbjit) return; | 1317 if (!FLAG_gdbjit) return; |
| 1062 | 1318 |
| 1063 // Force initialization of line_ends array. | 1319 // Force initialization of line_ends array. |
| 1064 GetScriptLineNumber(script, 0); | 1320 GetScriptLineNumber(script, 0); |
| 1065 | 1321 |
| 1066 if (!name.is_null()) { | 1322 if (!name.is_null()) { |
| 1067 SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS); | 1323 SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS); |
| 1068 AddCode(*name_cstring, *code, *script); | 1324 AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script); |
| 1069 } else { | 1325 } else { |
| 1070 AddCode("", *code, *script); | 1326 AddCode("", *code, GDBJITInterface::FUNCTION, *script); |
| 1071 } | 1327 } |
| 1072 } | 1328 } |
| 1073 | 1329 |
| 1330 #ifdef V8_TARGET_ARCH_X64 | |
| 1331 | |
| 1332 #define RBP_PUSH_OFFSET 1 | |
|
Vyacheslav Egorov (Chromium)
2011/02/01 13:17:25
We prefer constants to macroses:
static const int
| |
| 1333 #define RBP_SET_OFFSET 4 | |
| 1334 #define RBP_POP_OFFSET -3 | |
| 1335 | |
| 1336 static void AddUnwindInfo(CodeDescription *cd) { | |
| 1337 if (cd->get_type() == GDBJITInterface::FUNCTION) { | |
| 1338 cd->set_location(CodeDescription::POST_RBP_PUSH, | |
| 1339 cd->code_start() + RBP_PUSH_OFFSET); | |
| 1340 cd->set_location(CodeDescription::POST_RBP_SET, | |
| 1341 cd->code_start() + RBP_SET_OFFSET); | |
| 1342 cd->set_location(CodeDescription::POST_RBP_POP, | |
| 1343 cd->code_end() + RBP_POP_OFFSET); | |
| 1344 } else { | |
| 1345 cd->set_location(CodeDescription::POST_RBP_PUSH, cd->code_start()); | |
| 1346 cd->set_location(CodeDescription::POST_RBP_SET, cd->code_start()); | |
| 1347 cd->set_location(CodeDescription::POST_RBP_POP, cd->code_end()); | |
| 1348 } | |
| 1349 } | |
| 1350 #else | |
| 1351 #define AddUnwindInfo(x) ((void) x) | |
|
Vyacheslav Egorov (Chromium)
2011/02/01 13:17:25
Move #ifdef into function body to avoid defining m
| |
| 1352 #endif // V8_TARGET_ARCH_X64 | |
| 1353 | |
| 1074 | 1354 |
| 1075 void GDBJITInterface::AddCode(const char* name, | 1355 void GDBJITInterface::AddCode(const char* name, |
| 1076 Code* code, | 1356 Code* code, |
| 1357 GDBJITInterface::CodeTag type, | |
| 1077 Script* script) { | 1358 Script* script) { |
| 1078 if (!FLAG_gdbjit) return; | 1359 if (!FLAG_gdbjit) return; |
| 1079 AssertNoAllocation no_gc; | 1360 AssertNoAllocation no_gc; |
| 1080 | 1361 |
| 1081 HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), true); | 1362 HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), true); |
| 1082 if (e->value != NULL && !IsLineInfoTagged(e->value)) return; | 1363 GDBJITLineInfo* lineinfo; |
| 1083 | 1364 |
| 1084 GDBJITLineInfo* lineinfo = UntagLineInfo(e->value); | 1365 if (e->value != NULL && !IsLineInfoTagged(e->value)) |
|
Vyacheslav Egorov (Chromium)
2011/02/01 13:17:25
Is there a reason for this change?
If we are regi
| |
| 1366 lineinfo = NULL; | |
| 1367 else | |
| 1368 lineinfo = UntagLineInfo(e->value); | |
| 1369 | |
| 1085 CodeDescription code_desc(name, | 1370 CodeDescription code_desc(name, |
| 1086 code, | 1371 code, |
| 1087 script != NULL ? Handle<Script>(script) | 1372 script != NULL ? Handle<Script>(script) |
| 1088 : Handle<Script>(), | 1373 : Handle<Script>(), |
| 1089 lineinfo); | 1374 lineinfo, |
| 1375 type); | |
| 1090 | 1376 |
| 1091 if (!FLAG_gdbjit_full && !code_desc.is_line_info_available()) { | 1377 AddUnwindInfo(&code_desc); |
|
Vyacheslav Egorov (Chromium)
2011/02/01 13:17:25
Why did you kill FLAG_gdbjit_full support?
It is
| |
| 1092 delete lineinfo; | |
| 1093 entries.Remove(code, HashForCodeObject(code)); | |
| 1094 return; | |
| 1095 } | |
| 1096 | 1378 |
| 1097 JITCodeEntry* entry = CreateELFObject(&code_desc); | 1379 JITCodeEntry* entry = CreateELFObject(&code_desc); |
| 1098 ASSERT(!IsLineInfoTagged(entry)); | 1380 ASSERT(!IsLineInfoTagged(entry)); |
| 1099 | |
| 1100 delete lineinfo; | 1381 delete lineinfo; |
| 1101 e->value = entry; | 1382 e->value = entry; |
| 1102 | |
| 1103 RegisterCodeEntry(entry); | 1383 RegisterCodeEntry(entry); |
| 1104 } | 1384 } |
| 1105 | 1385 |
| 1106 | 1386 |
| 1107 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, | 1387 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, |
| 1108 const char* name, | 1388 const char* name, |
| 1109 Code* code) { | 1389 Code* code) { |
| 1110 if (!FLAG_gdbjit) return; | 1390 if (!FLAG_gdbjit) return; |
| 1111 | 1391 |
| 1112 EmbeddedVector<char, 256> buffer; | 1392 EmbeddedVector<char, 256> buffer; |
| 1113 StringBuilder builder(buffer.start(), buffer.length()); | 1393 StringBuilder builder(buffer.start(), buffer.length()); |
| 1114 | 1394 |
| 1115 builder.AddString(Tag2String(tag)); | 1395 builder.AddString(Tag2String(tag)); |
| 1116 if ((name != NULL) && (*name != '\0')) { | 1396 if ((name != NULL) && (*name != '\0')) { |
| 1117 builder.AddString(": "); | 1397 builder.AddString(": "); |
| 1118 builder.AddString(name); | 1398 builder.AddString(name); |
| 1119 } else { | 1399 } else { |
| 1120 builder.AddFormatted(": code object %p", static_cast<void*>(code)); | 1400 builder.AddFormatted(": code object %p", static_cast<void*>(code)); |
| 1121 } | 1401 } |
| 1122 | 1402 |
| 1123 AddCode(builder.Finalize(), code); | 1403 AddCode(builder.Finalize(), code, tag); |
| 1124 } | 1404 } |
| 1125 | 1405 |
| 1126 | 1406 |
| 1127 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, | 1407 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, |
| 1128 String* name, | 1408 String* name, |
| 1129 Code* code) { | 1409 Code* code) { |
| 1130 if (!FLAG_gdbjit) return; | 1410 if (!FLAG_gdbjit) return; |
| 1131 AddCode(tag, name != NULL ? *name->ToCString(DISALLOW_NULLS) : NULL, code); | 1411 AddCode(tag, name != NULL ? *name->ToCString(DISALLOW_NULLS) : NULL, code); |
| 1132 } | 1412 } |
| 1133 | 1413 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 1161 GDBJITLineInfo* line_info) { | 1441 GDBJITLineInfo* line_info) { |
| 1162 ASSERT(!IsLineInfoTagged(line_info)); | 1442 ASSERT(!IsLineInfoTagged(line_info)); |
| 1163 HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), true); | 1443 HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), true); |
| 1164 ASSERT(e->value == NULL); | 1444 ASSERT(e->value == NULL); |
| 1165 e->value = TagLineInfo(line_info); | 1445 e->value = TagLineInfo(line_info); |
| 1166 } | 1446 } |
| 1167 | 1447 |
| 1168 | 1448 |
| 1169 } } // namespace v8::internal | 1449 } } // namespace v8::internal |
| 1170 #endif | 1450 #endif |
| OLD | NEW |