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 16 matching lines...) Expand all Loading... | |
| 27 | 27 |
| 28 #ifdef ENABLE_GDB_JIT_INTERFACE | 28 #ifdef ENABLE_GDB_JIT_INTERFACE |
| 29 #include "v8.h" | 29 #include "v8.h" |
| 30 #include "gdb-jit.h" | 30 #include "gdb-jit.h" |
| 31 | 31 |
| 32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 33 #include "compiler.h" | 33 #include "compiler.h" |
| 34 #include "global-handles.h" | 34 #include "global-handles.h" |
| 35 #include "messages.h" | 35 #include "messages.h" |
| 36 #include "natives.h" | 36 #include "natives.h" |
| 37 #include "scopeinfo.h" | |
| 38 | |
| 39 #ifdef __APPLE__ | |
| 40 #define __MACH_O | |
| 41 #define SECTION_BASE MachOSection | |
| 42 #define OBJ_FORMAT MachO | |
| 43 #else | |
| 44 #define __ELF | |
| 45 #define SECTION_BASE ELFSection | |
| 46 #define OBJ_FORMAT ELF | |
| 47 #endif | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:14:47
I don't think we are using macros for anything lik
zarko
2011/06/27 22:24:29
Done (though I have kept the __MACH_O/__ELF define
| |
| 37 | 48 |
| 38 namespace v8 { | 49 namespace v8 { |
| 39 namespace internal { | 50 namespace internal { |
| 40 | 51 |
| 41 class ELF; | 52 class ELF; |
| 53 class MachO; | |
| 42 | 54 |
| 43 class Writer BASE_EMBEDDED { | 55 class Writer BASE_EMBEDDED { |
| 44 public: | 56 public: |
| 45 explicit Writer(ELF* elf) | 57 explicit Writer(ELF* elf) |
| 46 : elf_(elf), | 58 : elf_(elf), |
| 59 mach_o_(0), | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:14:47
Instead of duplicating code and members replace el
zarko
2011/06/27 22:24:29
Done.
| |
| 47 position_(0), | 60 position_(0), |
| 48 capacity_(1024), | 61 capacity_(1024), |
| 49 buffer_(reinterpret_cast<byte*>(malloc(capacity_))) { | 62 buffer_(reinterpret_cast<byte*>(malloc(capacity_))) { |
| 63 } | |
| 64 | |
| 65 explicit Writer(MachO* mach_o) | |
| 66 : elf_(0), | |
| 67 mach_o_(mach_o), | |
| 68 position_(0), | |
| 69 capacity_(1024), | |
| 70 buffer_(reinterpret_cast<byte*>(malloc(capacity_))) { | |
| 50 } | 71 } |
| 51 | 72 |
| 52 ~Writer() { | 73 ~Writer() { |
| 53 free(buffer_); | 74 free(buffer_); |
| 54 } | 75 } |
| 55 | 76 |
| 56 uintptr_t position() const { | 77 uintptr_t position() const { |
| 57 return position_; | 78 return position_; |
| 58 } | 79 } |
| 59 | 80 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 return SlotAt<T>(slot_position); | 126 return SlotAt<T>(slot_position); |
| 106 } | 127 } |
| 107 | 128 |
| 108 void Ensure(uintptr_t pos) { | 129 void Ensure(uintptr_t pos) { |
| 109 if (capacity_ < pos) { | 130 if (capacity_ < pos) { |
| 110 while (capacity_ < pos) capacity_ *= 2; | 131 while (capacity_ < pos) capacity_ *= 2; |
| 111 buffer_ = reinterpret_cast<byte*>(realloc(buffer_, capacity_)); | 132 buffer_ = reinterpret_cast<byte*>(realloc(buffer_, capacity_)); |
| 112 } | 133 } |
| 113 } | 134 } |
| 114 | 135 |
| 115 ELF* elf() { return elf_; } | 136 ELF* elf() { ASSERT(elf_ != 0); return elf_; } |
| 137 | |
| 138 MachO* mach_o() { ASSERT(mach_o_ != 0); return mach_o_; } | |
| 116 | 139 |
| 117 byte* buffer() { return buffer_; } | 140 byte* buffer() { return buffer_; } |
| 118 | 141 |
| 119 void Align(uintptr_t align) { | 142 void Align(uintptr_t align) { |
| 120 uintptr_t delta = position_ % align; | 143 uintptr_t delta = position_ % align; |
| 121 if (delta == 0) return; | 144 if (delta == 0) return; |
| 122 uintptr_t padding = align - delta; | 145 uintptr_t padding = align - delta; |
| 123 Ensure(position_ += padding); | 146 Ensure(position_ += padding); |
| 124 ASSERT((position_ % align) == 0); | 147 ASSERT((position_ % align) == 0); |
| 125 } | 148 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 private: | 182 private: |
| 160 template<typename T> friend class Slot; | 183 template<typename T> friend class Slot; |
| 161 | 184 |
| 162 template<typename T> | 185 template<typename T> |
| 163 T* RawSlotAt(uintptr_t offset) { | 186 T* RawSlotAt(uintptr_t offset) { |
| 164 ASSERT(offset < capacity_ && offset + sizeof(T) <= capacity_); | 187 ASSERT(offset < capacity_ && offset + sizeof(T) <= capacity_); |
| 165 return reinterpret_cast<T*>(&buffer_[offset]); | 188 return reinterpret_cast<T*>(&buffer_[offset]); |
| 166 } | 189 } |
| 167 | 190 |
| 168 ELF* elf_; | 191 ELF* elf_; |
| 192 MachO* mach_o_; | |
| 169 uintptr_t position_; | 193 uintptr_t position_; |
| 170 uintptr_t capacity_; | 194 uintptr_t capacity_; |
| 171 byte* buffer_; | 195 byte* buffer_; |
| 172 }; | 196 }; |
| 173 | 197 |
| 174 class StringTable; | 198 class StringTable; |
| 175 | 199 |
| 200 class MachOSection : public ZoneObject { | |
| 201 public: | |
| 202 struct Header { | |
| 203 char sectname[16]; | |
| 204 char segname[16]; | |
| 205 #if defined(V8_TARGET_ARCH_IA32) | |
| 206 uint32_t addr; | |
| 207 uint32_t size; | |
| 208 #else | |
| 209 uint64_t addr; | |
| 210 uint64_t size; | |
| 211 #endif | |
| 212 uint32_t offset; | |
| 213 uint32_t align; | |
| 214 uint32_t reloff; | |
| 215 uint32_t nreloc; | |
| 216 uint32_t flags; | |
| 217 uint32_t reserved1; | |
| 218 uint32_t reserved2; | |
| 219 }; | |
| 220 | |
| 221 enum Type { | |
| 222 S_REGULAR = 0x0u, | |
| 223 S_ATTR_COALESCED = 0xbu, | |
| 224 S_ATTR_SOME_INSTRUCTIONS = 0x400u, | |
| 225 S_ATTR_DEBUG = 0x02000000u, | |
| 226 S_ATTR_PURE_INSTRUCTIONS = 0x80000000u | |
| 227 }; | |
| 228 | |
| 229 MachOSection(const char* name, | |
| 230 const char* segment, | |
| 231 uintptr_t align, | |
| 232 uint32_t flags) | |
| 233 : name_(name), | |
| 234 segment_(segment), | |
| 235 align_(align), | |
| 236 flags_(flags) { | |
| 237 ASSERT(IsPowerOf2(align)); | |
| 238 if (align_ != 0) { | |
| 239 align_ = WhichPowerOf2(align_); | |
| 240 } | |
| 241 } | |
| 242 | |
| 243 virtual ~MachOSection() { } | |
| 244 | |
| 245 virtual void PopulateHeader(Writer::Slot<Header> header) { | |
| 246 header->addr = 0; | |
| 247 header->size = 0; | |
| 248 header->offset = 0; | |
| 249 header->align = align_; | |
| 250 header->reloff = 0; | |
| 251 header->nreloc = 0; | |
| 252 header->flags = flags_; | |
| 253 header->reserved1 = 0; | |
| 254 header->reserved2 = 0; | |
| 255 memset(header->sectname, 0, 16); | |
| 256 memset(header->segname, 0, 16); | |
| 257 ASSERT(strlen(name_) < 16); | |
| 258 ASSERT(strlen(segment_) < 16); | |
| 259 strcpy(header->sectname, name_); | |
| 260 strcpy(header->segname, segment_); | |
| 261 } | |
| 262 | |
| 263 virtual void WriteBody(Writer::Slot<Header> header, Writer* writer) { | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:14:47
Seems to be shared between ELFSection and MachOSec
zarko
2011/06/27 22:24:29
Done.
| |
| 264 uintptr_t start = writer->position(); | |
| 265 if (WriteBody(writer)) { | |
| 266 uintptr_t end = writer->position(); | |
| 267 header->offset = start; | |
| 268 header->addr = 0; | |
| 269 header->size = end - start; | |
| 270 } | |
| 271 } | |
| 272 | |
| 273 virtual bool WriteBody(Writer* writer) { | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:14:47
Ditto.
zarko
2011/06/27 22:24:29
Done.
| |
| 274 return false; | |
| 275 } | |
| 276 | |
| 277 private: | |
| 278 const char* name_; | |
| 279 const char* segment_; | |
| 280 uintptr_t align_; | |
| 281 uint32_t flags_; | |
| 282 }; | |
| 283 | |
| 284 | |
| 176 class ELFSection : public ZoneObject { | 285 class ELFSection : public ZoneObject { |
| 177 public: | 286 public: |
| 178 struct Header { | 287 struct Header { |
| 179 uint32_t name; | 288 uint32_t name; |
| 180 uint32_t type; | 289 uint32_t type; |
| 181 uintptr_t flags; | 290 uintptr_t flags; |
| 182 uintptr_t address; | 291 uintptr_t address; |
| 183 uintptr_t offset; | 292 uintptr_t offset; |
| 184 uintptr_t size; | 293 uintptr_t size; |
| 185 uint32_t link; | 294 uint32_t link; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 virtual void PopulateHeader(Writer::Slot<Header> header) { | 354 virtual void PopulateHeader(Writer::Slot<Header> header) { |
| 246 header->flags = 0; | 355 header->flags = 0; |
| 247 header->address = 0; | 356 header->address = 0; |
| 248 header->offset = 0; | 357 header->offset = 0; |
| 249 header->size = 0; | 358 header->size = 0; |
| 250 header->link = 0; | 359 header->link = 0; |
| 251 header->info = 0; | 360 header->info = 0; |
| 252 header->entry_size = 0; | 361 header->entry_size = 0; |
| 253 } | 362 } |
| 254 | 363 |
| 255 | |
| 256 private: | 364 private: |
| 257 const char* name_; | 365 const char* name_; |
| 258 Type type_; | 366 Type type_; |
| 259 uintptr_t align_; | 367 uintptr_t align_; |
| 260 uint16_t index_; | 368 uint16_t index_; |
| 261 }; | 369 }; |
| 262 | 370 |
| 263 | 371 |
| 372 class MachOTextSection : public MachOSection { | |
| 373 public: | |
| 374 MachOTextSection(uintptr_t align, | |
| 375 uintptr_t addr, | |
| 376 uintptr_t size) | |
| 377 : MachOSection("__text", | |
| 378 "__TEXT", | |
| 379 align, | |
| 380 MachOSection::S_REGULAR | | |
| 381 MachOSection::S_ATTR_SOME_INSTRUCTIONS | | |
| 382 MachOSection::S_ATTR_PURE_INSTRUCTIONS), | |
| 383 addr_(addr), | |
| 384 size_(size) { } | |
| 385 | |
| 386 protected: | |
| 387 virtual void PopulateHeader(Writer::Slot<Header> header) { | |
| 388 MachOSection::PopulateHeader(header); | |
| 389 header->addr = addr_; | |
| 390 header->size = size_; | |
| 391 } | |
| 392 | |
| 393 private: | |
| 394 uintptr_t addr_; | |
| 395 uintptr_t size_; | |
| 396 }; | |
| 397 | |
| 398 | |
| 264 class FullHeaderELFSection : public ELFSection { | 399 class FullHeaderELFSection : public ELFSection { |
| 265 public: | 400 public: |
| 266 FullHeaderELFSection(const char* name, | 401 FullHeaderELFSection(const char* name, |
| 267 Type type, | 402 Type type, |
| 268 uintptr_t align, | 403 uintptr_t align, |
| 269 uintptr_t addr, | 404 uintptr_t addr, |
| 270 uintptr_t offset, | 405 uintptr_t offset, |
| 271 uintptr_t size, | 406 uintptr_t size, |
| 272 uintptr_t flags) | 407 uintptr_t flags) |
| 273 : ELFSection(name, type, align), | 408 : ELFSection(name, type, align), |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 344 | 479 |
| 345 void ELFSection::PopulateHeader(Writer::Slot<ELFSection::Header> header, | 480 void ELFSection::PopulateHeader(Writer::Slot<ELFSection::Header> header, |
| 346 StringTable* strtab) { | 481 StringTable* strtab) { |
| 347 header->name = strtab->Add(name_); | 482 header->name = strtab->Add(name_); |
| 348 header->type = type_; | 483 header->type = type_; |
| 349 header->alignment = align_; | 484 header->alignment = align_; |
| 350 PopulateHeader(header); | 485 PopulateHeader(header); |
| 351 } | 486 } |
| 352 | 487 |
| 353 | 488 |
| 489 class MachO BASE_EMBEDDED { | |
| 490 public: | |
| 491 MachO() : sections_(6) { } | |
| 492 | |
| 493 uint32_t AddSection(MachOSection* section) { | |
| 494 sections_.Add(section); | |
| 495 return sections_.length() - 1; | |
| 496 } | |
| 497 | |
| 498 void Write(Writer* w, uintptr_t code_start, uintptr_t code_size); | |
| 499 | |
| 500 private: | |
| 501 struct MachOHeader { | |
| 502 uint32_t magic; | |
| 503 uint32_t cputype; | |
| 504 uint32_t cpusubtype; | |
| 505 uint32_t filetype; | |
| 506 uint32_t ncmds; | |
| 507 uint32_t sizeofcmds; | |
| 508 uint32_t flags; | |
| 509 #if defined(V8_TARGET_ARCH_X64) | |
| 510 uint32_t reserved; | |
| 511 #endif | |
| 512 }; | |
| 513 | |
| 514 struct MachOSegmentCommand { | |
| 515 uint32_t cmd; | |
| 516 uint32_t cmdsize; | |
| 517 char segname[16]; | |
| 518 #if defined(V8_TARGET_ARCH_IA32) | |
| 519 uint32_t vmaddr; | |
| 520 uint32_t vmsize; | |
| 521 uint32_t fileoff; | |
| 522 uint32_t filesize; | |
| 523 #else | |
| 524 uint64_t vmaddr; | |
| 525 uint64_t vmsize; | |
| 526 uint64_t fileoff; | |
| 527 uint64_t filesize; | |
| 528 #endif | |
| 529 uint32_t maxprot; | |
| 530 uint32_t initprot; | |
| 531 uint32_t nsects; | |
| 532 uint32_t flags; | |
| 533 }; | |
| 534 | |
| 535 enum MachOLoadCommandCmd { | |
| 536 LC_SEGMENT_32 = 0x00000001u, | |
| 537 LC_SEGMENT_64 = 0x00000019u | |
| 538 }; | |
| 539 | |
| 540 ZoneList<MachOSection*> sections_; | |
| 541 }; | |
| 542 | |
| 543 | |
| 544 void MachO::Write(Writer* w, | |
| 545 uintptr_t code_start, | |
| 546 uintptr_t code_size) { | |
| 547 ASSERT(w->position() == 0); | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:14:47
Can you split this method into several like it is
zarko
2011/06/27 22:24:29
Done.
| |
| 548 Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>(); | |
| 549 #if defined(V8_TARGET_ARCH_IA32) | |
| 550 header->magic = 0xFEEDFACEu; | |
| 551 header->cputype = 7; // i386 | |
| 552 header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL | |
| 553 #elif defined(V8_TARGET_ARCH_X64) | |
| 554 header->magic = 0xFEEDFACFu; | |
| 555 header->cputype = 7 | 0x01000000; // i386 | 64-bit ABI | |
| 556 header->cpusubtype = 3; // CPU_SUBTYPE_I386_ALL | |
| 557 header->reserved = 0; | |
| 558 #else | |
| 559 #error Unsupported target architecture. | |
| 560 #endif | |
| 561 header->filetype = 0x1; // MH_OBJECT | |
| 562 header->ncmds = 1; | |
| 563 header->sizeofcmds = 0; | |
| 564 header->flags = 0; | |
| 565 uintptr_t load_command_start = w->position(); | |
| 566 Writer::Slot<MachOSegmentCommand> cmd = | |
| 567 w->CreateSlotHere<MachOSegmentCommand>(); | |
| 568 #if defined(V8_TARGET_ARCH_IA32) | |
| 569 cmd->cmd = LC_SEGMENT_32; | |
| 570 #else | |
| 571 cmd->cmd = LC_SEGMENT_64; | |
| 572 #endif | |
| 573 cmd->vmaddr = code_start; | |
| 574 cmd->vmsize = code_size; | |
| 575 cmd->fileoff = 0; | |
| 576 cmd->filesize = 0; | |
| 577 cmd->maxprot = 7; | |
| 578 cmd->initprot = 7; | |
| 579 cmd->flags = 0; | |
| 580 cmd->nsects = sections_.length(); | |
| 581 memset(cmd->segname, 0, 16); | |
| 582 cmd->cmdsize = sizeof(MachOSegmentCommand) + sizeof(MachOSection::Header) * | |
| 583 cmd->nsects; | |
| 584 Writer::Slot<MachOSection::Header> headers = | |
| 585 w->CreateSlotsHere<MachOSection::Header>(sections_.length()); | |
| 586 cmd->fileoff = w->position(); | |
| 587 header->sizeofcmds = w->position() - load_command_start; | |
| 588 for (int section = 0; section < sections_.length(); ++section) { | |
| 589 sections_[section]->PopulateHeader(headers.at(section)); | |
| 590 sections_[section]->WriteBody(headers.at(section), w); | |
| 591 } | |
| 592 cmd->filesize = w->position() - (uintptr_t)cmd->fileoff; | |
| 593 } | |
| 594 | |
| 595 | |
| 354 class ELF BASE_EMBEDDED { | 596 class ELF BASE_EMBEDDED { |
| 355 public: | 597 public: |
| 356 ELF() : sections_(6) { | 598 ELF() : sections_(6) { |
| 357 sections_.Add(new ELFSection("", ELFSection::TYPE_NULL, 0)); | 599 sections_.Add(new ELFSection("", ELFSection::TYPE_NULL, 0)); |
| 358 sections_.Add(new StringTable(".shstrtab")); | 600 sections_.Add(new StringTable(".shstrtab")); |
| 359 } | 601 } |
| 360 | 602 |
| 361 void Write(Writer* w) { | 603 void Write(Writer* w) { |
| 362 WriteHeader(w); | 604 WriteHeader(w); |
| 363 WriteSectionTable(w); | 605 WriteSectionTable(w); |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 650 POST_RBP_SET, | 892 POST_RBP_SET, |
| 651 POST_RBP_POP, | 893 POST_RBP_POP, |
| 652 STACK_STATE_MAX | 894 STACK_STATE_MAX |
| 653 }; | 895 }; |
| 654 #endif | 896 #endif |
| 655 | 897 |
| 656 CodeDescription(const char* name, | 898 CodeDescription(const char* name, |
| 657 Code* code, | 899 Code* code, |
| 658 Handle<Script> script, | 900 Handle<Script> script, |
| 659 GDBJITLineInfo* lineinfo, | 901 GDBJITLineInfo* lineinfo, |
| 660 GDBJITInterface::CodeTag tag) | 902 GDBJITInterface::CodeTag tag, |
| 903 CompilationInfo* info) | |
| 661 : name_(name), | 904 : name_(name), |
| 662 code_(code), | 905 code_(code), |
| 663 script_(script), | 906 script_(script), |
| 664 lineinfo_(lineinfo), | 907 lineinfo_(lineinfo), |
| 665 tag_(tag) { | 908 tag_(tag), |
| 909 info_(info) { | |
| 666 } | 910 } |
| 667 | 911 |
| 668 const char* name() const { | 912 const char* name() const { |
| 669 return name_; | 913 return name_; |
| 670 } | 914 } |
| 671 | 915 |
| 672 GDBJITLineInfo* lineinfo() const { | 916 GDBJITLineInfo* lineinfo() const { |
| 673 return lineinfo_; | 917 return lineinfo_; |
| 674 } | 918 } |
| 675 | 919 |
| 676 GDBJITInterface::CodeTag tag() const { | 920 GDBJITInterface::CodeTag tag() const { |
| 677 return tag_; | 921 return tag_; |
| 678 } | 922 } |
| 679 | 923 |
| 924 CompilationInfo* info() const { | |
| 925 return info_; | |
| 926 } | |
| 927 | |
| 928 bool IsInfoAvailable() const { | |
| 929 return info_ != NULL; | |
| 930 } | |
| 931 | |
| 680 uintptr_t CodeStart() const { | 932 uintptr_t CodeStart() const { |
| 681 return reinterpret_cast<uintptr_t>(code_->instruction_start()); | 933 return reinterpret_cast<uintptr_t>(code_->instruction_start()); |
| 682 } | 934 } |
| 683 | 935 |
| 684 uintptr_t CodeEnd() const { | 936 uintptr_t CodeEnd() const { |
| 685 return reinterpret_cast<uintptr_t>(code_->instruction_end()); | 937 return reinterpret_cast<uintptr_t>(code_->instruction_end()); |
| 686 } | 938 } |
| 687 | 939 |
| 688 uintptr_t CodeSize() const { | 940 uintptr_t CodeSize() const { |
| 689 return CodeEnd() - CodeStart(); | 941 return CodeEnd() - CodeStart(); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 717 return GetScriptLineNumberSafe(script_, pos) + 1; | 969 return GetScriptLineNumberSafe(script_, pos) + 1; |
| 718 } | 970 } |
| 719 | 971 |
| 720 | 972 |
| 721 private: | 973 private: |
| 722 const char* name_; | 974 const char* name_; |
| 723 Code* code_; | 975 Code* code_; |
| 724 Handle<Script> script_; | 976 Handle<Script> script_; |
| 725 GDBJITLineInfo* lineinfo_; | 977 GDBJITLineInfo* lineinfo_; |
| 726 GDBJITInterface::CodeTag tag_; | 978 GDBJITInterface::CodeTag tag_; |
| 979 CompilationInfo* info_; | |
| 727 #ifdef V8_TARGET_ARCH_X64 | 980 #ifdef V8_TARGET_ARCH_X64 |
| 728 uintptr_t stack_state_start_addresses_[STACK_STATE_MAX]; | 981 uintptr_t stack_state_start_addresses_[STACK_STATE_MAX]; |
| 729 #endif | 982 #endif |
| 730 }; | 983 }; |
| 731 | 984 |
| 732 | 985 #ifdef __ELF |
| 733 static void CreateSymbolsTable(CodeDescription* desc, | 986 static void CreateSymbolsTable(CodeDescription* desc, |
| 734 ELF* elf, | 987 ELF* elf, |
| 735 int text_section_index) { | 988 int text_section_index) { |
| 736 ELFSymbolTable* symtab = new ELFSymbolTable(".symtab"); | 989 ELFSymbolTable* symtab = new ELFSymbolTable(".symtab"); |
| 737 StringTable* strtab = new StringTable(".strtab"); | 990 StringTable* strtab = new StringTable(".strtab"); |
| 738 | 991 |
| 739 // Symbol table should be followed by the linked string table. | 992 // Symbol table should be followed by the linked string table. |
| 740 elf->AddSection(symtab); | 993 elf->AddSection(symtab); |
| 741 elf->AddSection(strtab); | 994 elf->AddSection(strtab); |
| 742 | 995 |
| 743 symtab->Add(ELFSymbol("V8 Code", | 996 symtab->Add(ELFSymbol("V8 Code", |
| 744 0, | 997 0, |
| 745 0, | 998 0, |
| 746 ELFSymbol::BIND_LOCAL, | 999 ELFSymbol::BIND_LOCAL, |
| 747 ELFSymbol::TYPE_FILE, | 1000 ELFSymbol::TYPE_FILE, |
| 748 ELFSection::INDEX_ABSOLUTE)); | 1001 ELFSection::INDEX_ABSOLUTE)); |
| 749 | 1002 |
| 750 symtab->Add(ELFSymbol(desc->name(), | 1003 symtab->Add(ELFSymbol(desc->name(), |
| 751 0, | 1004 0, |
| 752 desc->CodeSize(), | 1005 desc->CodeSize(), |
| 753 ELFSymbol::BIND_GLOBAL, | 1006 ELFSymbol::BIND_GLOBAL, |
| 754 ELFSymbol::TYPE_FUNC, | 1007 ELFSymbol::TYPE_FUNC, |
| 755 text_section_index)); | 1008 text_section_index)); |
| 756 } | 1009 } |
| 1010 #endif | |
| 757 | 1011 |
| 758 | 1012 |
| 759 class DebugInfoSection : public ELFSection { | 1013 class DebugInfoSection : public SECTION_BASE { |
| 760 public: | 1014 public: |
| 761 explicit DebugInfoSection(CodeDescription* desc) | 1015 explicit DebugInfoSection(CodeDescription* desc) |
| 762 : ELFSection(".debug_info", TYPE_PROGBITS, 1), desc_(desc) { } | 1016 #ifdef __ELF |
| 1017 : ELFSection(".debug_info", TYPE_PROGBITS, 1), | |
| 1018 #else | |
| 1019 : MachOSection("__debug_info", "__DWARF", 1, | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:14:47
one argument per line.
zarko
2011/06/27 22:24:29
Done.
| |
| 1020 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG), | |
| 1021 #endif | |
| 1022 desc_(desc) { } | |
| 1023 | |
| 1024 // DWARF2 standard | |
| 1025 enum DWARF2LocationOp { | |
| 1026 DW_OP_reg0 = 0x50, | |
| 1027 DW_OP_reg1 = 0x51, | |
| 1028 DW_OP_reg2 = 0x52, | |
| 1029 DW_OP_reg3 = 0x53, | |
| 1030 DW_OP_reg4 = 0x54, | |
| 1031 DW_OP_reg5 = 0x55, | |
| 1032 DW_OP_reg6 = 0x56, | |
| 1033 DW_OP_reg7 = 0x57, | |
| 1034 DW_OP_fbreg = 0x91 // 1 param: SLEB128 offset | |
| 1035 }; | |
| 1036 | |
| 1037 enum DWARF2Encoding { | |
| 1038 DW_ATE_ADDRESS = 0x1, | |
| 1039 DW_ATE_SIGNED = 0x5 | |
| 1040 }; | |
| 763 | 1041 |
| 764 bool WriteBody(Writer* w) { | 1042 bool WriteBody(Writer* w) { |
| 1043 uintptr_t cu_start = w->position(); | |
| 765 Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>(); | 1044 Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>(); |
| 766 uintptr_t start = w->position(); | 1045 uintptr_t start = w->position(); |
| 767 w->Write<uint16_t>(2); // DWARF version. | 1046 w->Write<uint16_t>(2); // DWARF version. |
| 768 w->Write<uint32_t>(0); // Abbreviation table offset. | 1047 w->Write<uint32_t>(0); // Abbreviation table offset. |
| 769 w->Write<uint8_t>(sizeof(intptr_t)); | 1048 w->Write<uint8_t>(sizeof(intptr_t)); |
| 770 | 1049 |
| 771 w->WriteULEB128(1); // Abbreviation code. | 1050 w->WriteULEB128(1); // Abbreviation code. |
| 772 w->WriteString(*desc_->GetFilename()); | 1051 w->WriteString(*desc_->GetFilename()); |
| 773 w->Write<intptr_t>(desc_->CodeStart()); | 1052 w->Write<intptr_t>(desc_->CodeStart()); |
| 774 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); | 1053 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); |
| 775 w->Write<uint32_t>(0); | 1054 w->Write<uint32_t>(0); |
| 1055 | |
| 1056 uint32_t ty_offset = static_cast<uint32_t>(w->position() - cu_start); | |
| 1057 w->WriteULEB128(3); | |
| 1058 w->Write<uint8_t>(kPointerSize); | |
| 1059 w->WriteString("v8value"); | |
| 1060 | |
| 1061 if (desc_->IsInfoAvailable()) { | |
| 1062 CompilationInfo* info = desc_->info(); | |
| 1063 ScopeInfo<FreeStoreAllocationPolicy> scope_info(info->scope()); | |
| 1064 w->WriteULEB128(2); | |
| 1065 w->WriteString(desc_->name()); | |
| 1066 w->Write<intptr_t>(desc_->CodeStart()); | |
| 1067 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize()); | |
| 1068 Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>(); | |
| 1069 uintptr_t fb_block_start = w->position(); | |
| 1070 #if defined(V8_TARGET_ARCH_IA32) | |
| 1071 w->Write<uint8_t>(DW_OP_reg5); // The frame pointer's here on ia32 | |
| 1072 #elif defined(V8_TARGET_ARCH_X64) | |
| 1073 w->Write<uint8_t>(DW_OP_reg6); // and here on x64. | |
| 1074 #else | |
| 1075 #error Unsupported target architecture. | |
| 1076 #endif | |
| 1077 fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start)); | |
| 1078 | |
| 1079 int params = scope_info.number_of_parameters(); | |
| 1080 int slots = scope_info.number_of_stack_slots(); | |
| 1081 int context_slots = scope_info.number_of_context_slots(); | |
| 1082 // The real slot ID is internal_slots + context_slot_id. | |
| 1083 int internal_slots = Context::MIN_CONTEXT_SLOTS; | |
| 1084 int locals = scope_info.NumberOfLocals(); | |
| 1085 int current_abbreviation = 4; | |
| 1086 | |
| 1087 for (int param = 0; param < params; ++param) { | |
| 1088 w->WriteULEB128(current_abbreviation++); | |
| 1089 w->WriteString( | |
| 1090 *scope_info.parameter_name(param)->ToCString(DISALLOW_NULLS)); | |
| 1091 w->Write<uint32_t>(ty_offset); | |
| 1092 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); | |
| 1093 uintptr_t block_start = w->position(); | |
| 1094 w->Write<uint8_t>(DW_OP_fbreg); | |
| 1095 w->WriteSLEB128( | |
| 1096 JavaScriptFrameConstants::kLastParameterOffset + | |
| 1097 kPointerSize * (params - param - 1)); | |
| 1098 block_size.set(static_cast<uint32_t>(w->position() - block_start)); | |
| 1099 } | |
| 1100 | |
| 1101 EmbeddedVector<char, 256> buffer; | |
| 1102 StringBuilder builder(buffer.start(), buffer.length()); | |
| 1103 | |
| 1104 for (int slot = 0; slot < slots; ++slot) { | |
| 1105 w->WriteULEB128(current_abbreviation++); | |
| 1106 builder.Reset(); | |
| 1107 builder.AddFormatted("slot%d", slot); | |
| 1108 w->WriteString(builder.Finalize()); | |
| 1109 } | |
| 1110 | |
| 1111 // See contexts.h for more information. | |
| 1112 ASSERT(Context::MIN_CONTEXT_SLOTS == 5); | |
| 1113 ASSERT(Context::CLOSURE_INDEX == 0); | |
| 1114 ASSERT(Context::FCONTEXT_INDEX == 1); | |
| 1115 ASSERT(Context::PREVIOUS_INDEX == 2); | |
| 1116 ASSERT(Context::EXTENSION_INDEX == 3); | |
| 1117 ASSERT(Context::GLOBAL_INDEX == 4); | |
| 1118 w->WriteULEB128(current_abbreviation++); | |
| 1119 w->WriteString(".closure"); | |
| 1120 w->WriteULEB128(current_abbreviation++); | |
| 1121 w->WriteString(".fcontext"); | |
| 1122 w->WriteULEB128(current_abbreviation++); | |
| 1123 w->WriteString(".previous"); | |
| 1124 w->WriteULEB128(current_abbreviation++); | |
| 1125 w->WriteString(".extension"); | |
| 1126 w->WriteULEB128(current_abbreviation++); | |
| 1127 w->WriteString(".global"); | |
| 1128 | |
| 1129 for (int context_slot = 0; context_slot < context_slots; | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:14:47
for(x;
y;
z)
zarko
2011/06/27 22:24:29
Done.
| |
| 1130 ++context_slot) { | |
| 1131 w->WriteULEB128(current_abbreviation++); | |
| 1132 builder.Reset(); | |
| 1133 builder.AddFormatted("context_slot%d", context_slot + internal_slots); | |
| 1134 w->WriteString(builder.Finalize()); | |
| 1135 } | |
| 1136 | |
| 1137 for (int local = 0; local < locals; ++local) { | |
| 1138 w->WriteULEB128(current_abbreviation++); | |
| 1139 w->WriteString( | |
| 1140 *scope_info.LocalName(local)->ToCString(DISALLOW_NULLS)); | |
| 1141 w->Write<uint32_t>(ty_offset); | |
| 1142 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); | |
| 1143 uintptr_t block_start = w->position(); | |
| 1144 w->Write<uint8_t>(DW_OP_fbreg); | |
| 1145 w->WriteSLEB128( | |
| 1146 JavaScriptFrameConstants::kLocal0Offset - | |
| 1147 kPointerSize * local); | |
| 1148 block_size.set(static_cast<uint32_t>(w->position() - block_start)); | |
| 1149 } | |
| 1150 | |
| 1151 { | |
| 1152 w->WriteULEB128(current_abbreviation++); | |
| 1153 w->WriteString("__function"); | |
| 1154 w->Write<uint32_t>(ty_offset); | |
| 1155 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); | |
| 1156 uintptr_t block_start = w->position(); | |
| 1157 w->Write<uint8_t>(DW_OP_fbreg); | |
| 1158 w->WriteSLEB128(JavaScriptFrameConstants::kFunctionOffset); | |
| 1159 block_size.set(static_cast<uint32_t>(w->position() - block_start)); | |
| 1160 } | |
| 1161 | |
| 1162 { | |
| 1163 w->WriteULEB128(current_abbreviation++); | |
| 1164 w->WriteString("__context"); | |
| 1165 w->Write<uint32_t>(ty_offset); | |
| 1166 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>(); | |
| 1167 uintptr_t block_start = w->position(); | |
| 1168 w->Write<uint8_t>(DW_OP_fbreg); | |
| 1169 w->WriteSLEB128(StandardFrameConstants::kContextOffset); | |
| 1170 block_size.set(static_cast<uint32_t>(w->position() - block_start)); | |
| 1171 } | |
| 1172 } | |
| 1173 | |
| 776 size.set(static_cast<uint32_t>(w->position() - start)); | 1174 size.set(static_cast<uint32_t>(w->position() - start)); |
| 777 return true; | 1175 return true; |
| 778 } | 1176 } |
| 779 | 1177 |
| 780 private: | 1178 private: |
| 781 CodeDescription* desc_; | 1179 CodeDescription* desc_; |
| 782 }; | 1180 }; |
| 783 | 1181 |
| 784 | 1182 |
| 785 class DebugAbbrevSection : public ELFSection { | 1183 class DebugAbbrevSection : public SECTION_BASE { |
| 786 public: | 1184 public: |
| 787 DebugAbbrevSection() : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1) { } | 1185 explicit DebugAbbrevSection(CodeDescription* desc) |
| 1186 #ifdef __ELF | |
| 1187 : ELFSection(".debug_abbrev", TYPE_PROGBITS, 1), | |
| 1188 #else | |
| 1189 : MachOSection("__debug_abbrev", "__DWARF", 1, | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:14:47
Argument per line
zarko
2011/06/27 22:24:29
Done.
| |
| 1190 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG), | |
| 1191 #endif | |
| 1192 desc_(desc) { } | |
| 788 | 1193 |
| 789 // DWARF2 standard, figure 14. | 1194 // DWARF2 standard, figure 14. |
| 790 enum DWARF2Tags { | 1195 enum DWARF2Tags { |
| 791 DW_TAG_COMPILE_UNIT = 0x11 | 1196 DW_TAG_FORMAL_PARAMETER = 0x05, |
| 1197 DW_TAG_POINTER_TYPE = 0xf, | |
| 1198 DW_TAG_COMPILE_UNIT = 0x11, | |
| 1199 DW_TAG_STRUCTURE_TYPE = 0x13, | |
| 1200 DW_TAG_BASE_TYPE = 0x24, | |
| 1201 DW_TAG_SUBPROGRAM = 0x2e, | |
| 1202 DW_TAG_VARIABLE = 0x34 | |
| 792 }; | 1203 }; |
| 793 | 1204 |
| 794 // DWARF2 standard, figure 16. | 1205 // DWARF2 standard, figure 16. |
| 795 enum DWARF2ChildrenDetermination { | 1206 enum DWARF2ChildrenDetermination { |
| 796 DW_CHILDREN_NO = 0, | 1207 DW_CHILDREN_NO = 0, |
| 797 DW_CHILDREN_YES = 1 | 1208 DW_CHILDREN_YES = 1 |
| 798 }; | 1209 }; |
| 799 | 1210 |
| 800 // DWARF standard, figure 17. | 1211 // DWARF standard, figure 17. |
| 801 enum DWARF2Attribute { | 1212 enum DWARF2Attribute { |
| 1213 DW_AT_LOCATION = 0x2, | |
| 802 DW_AT_NAME = 0x3, | 1214 DW_AT_NAME = 0x3, |
| 1215 DW_AT_BYTE_SIZE = 0xb, | |
| 803 DW_AT_STMT_LIST = 0x10, | 1216 DW_AT_STMT_LIST = 0x10, |
| 804 DW_AT_LOW_PC = 0x11, | 1217 DW_AT_LOW_PC = 0x11, |
| 805 DW_AT_HIGH_PC = 0x12 | 1218 DW_AT_HIGH_PC = 0x12, |
| 1219 DW_AT_ENCODING = 0x3e, | |
| 1220 DW_AT_FRAME_BASE = 0x40, | |
| 1221 DW_AT_TYPE = 0x49 | |
| 806 }; | 1222 }; |
| 807 | 1223 |
| 808 // DWARF2 standard, figure 19. | 1224 // DWARF2 standard, figure 19. |
| 809 enum DWARF2AttributeForm { | 1225 enum DWARF2AttributeForm { |
| 810 DW_FORM_ADDR = 0x1, | 1226 DW_FORM_ADDR = 0x1, |
| 1227 DW_FORM_BLOCK4 = 0x4, | |
| 811 DW_FORM_STRING = 0x8, | 1228 DW_FORM_STRING = 0x8, |
| 812 DW_FORM_DATA4 = 0x6 | 1229 DW_FORM_DATA4 = 0x6, |
| 1230 DW_FORM_BLOCK = 0x9, | |
| 1231 DW_FORM_DATA1 = 0xb, | |
| 1232 DW_FORM_FLAG = 0xc, | |
| 1233 DW_FORM_REF4 = 0x13 | |
| 813 }; | 1234 }; |
| 814 | 1235 |
| 815 bool WriteBody(Writer* w) { | 1236 bool WriteBody(Writer* w) { |
| 1237 bool extra_info = desc_->IsInfoAvailable(); | |
| 1238 ASSERT(desc_->IsLineInfoAvailable()); | |
| 816 w->WriteULEB128(1); | 1239 w->WriteULEB128(1); |
| 817 w->WriteULEB128(DW_TAG_COMPILE_UNIT); | 1240 w->WriteULEB128(DW_TAG_COMPILE_UNIT); |
| 818 w->Write<uint8_t>(DW_CHILDREN_NO); | 1241 w->Write<uint8_t>(extra_info ? DW_CHILDREN_YES : DW_CHILDREN_NO); |
| 819 w->WriteULEB128(DW_AT_NAME); | 1242 w->WriteULEB128(DW_AT_NAME); |
| 820 w->WriteULEB128(DW_FORM_STRING); | 1243 w->WriteULEB128(DW_FORM_STRING); |
| 821 w->WriteULEB128(DW_AT_LOW_PC); | 1244 w->WriteULEB128(DW_AT_LOW_PC); |
| 822 w->WriteULEB128(DW_FORM_ADDR); | 1245 w->WriteULEB128(DW_FORM_ADDR); |
| 823 w->WriteULEB128(DW_AT_HIGH_PC); | 1246 w->WriteULEB128(DW_AT_HIGH_PC); |
| 824 w->WriteULEB128(DW_FORM_ADDR); | 1247 w->WriteULEB128(DW_FORM_ADDR); |
| 825 w->WriteULEB128(DW_AT_STMT_LIST); | 1248 w->WriteULEB128(DW_AT_STMT_LIST); |
| 826 w->WriteULEB128(DW_FORM_DATA4); | 1249 w->WriteULEB128(DW_FORM_DATA4); |
| 827 w->WriteULEB128(0); | 1250 w->WriteULEB128(0); |
| 828 w->WriteULEB128(0); | 1251 w->WriteULEB128(0); |
| 829 w->WriteULEB128(0); | 1252 |
| 1253 if (extra_info) { | |
| 1254 CompilationInfo* info = desc_->info(); | |
| 1255 ScopeInfo<FreeStoreAllocationPolicy> scope_info(info->scope()); | |
| 1256 int params = scope_info.number_of_parameters(); | |
| 1257 int slots = scope_info.number_of_stack_slots(); | |
| 1258 int context_slots = scope_info.number_of_context_slots(); | |
| 1259 // The real slot ID is internal_slots + context_slot_id. | |
| 1260 int internal_slots = Context::MIN_CONTEXT_SLOTS; | |
| 1261 int locals = scope_info.NumberOfLocals(); | |
| 1262 int total_children = | |
| 1263 params + slots + context_slots + internal_slots + locals + 2; | |
| 1264 | |
| 1265 // The extra duplication below seems to be necessary to keep | |
| 1266 // gdb from getting upset on OSX. | |
| 1267 | |
| 1268 w->WriteULEB128(2); // Abbreviation code. | |
| 1269 w->WriteULEB128(DW_TAG_SUBPROGRAM); | |
| 1270 w->Write<uint8_t>( | |
| 1271 total_children != 0 ? DW_CHILDREN_YES : DW_CHILDREN_NO); | |
| 1272 w->WriteULEB128(DW_AT_NAME); | |
| 1273 w->WriteULEB128(DW_FORM_STRING); | |
| 1274 w->WriteULEB128(DW_AT_LOW_PC); | |
| 1275 w->WriteULEB128(DW_FORM_ADDR); | |
| 1276 w->WriteULEB128(DW_AT_HIGH_PC); | |
| 1277 w->WriteULEB128(DW_FORM_ADDR); | |
| 1278 w->WriteULEB128(DW_AT_FRAME_BASE); | |
| 1279 w->WriteULEB128(DW_FORM_BLOCK4); | |
| 1280 w->WriteULEB128(0); | |
| 1281 w->WriteULEB128(0); | |
| 1282 | |
| 1283 w->WriteULEB128(3); | |
| 1284 w->WriteULEB128(DW_TAG_STRUCTURE_TYPE); | |
| 1285 w->Write<uint8_t>(DW_CHILDREN_NO); | |
| 1286 w->WriteULEB128(DW_AT_BYTE_SIZE); | |
| 1287 w->WriteULEB128(DW_FORM_DATA1); | |
| 1288 w->WriteULEB128(DW_AT_NAME); | |
| 1289 w->WriteULEB128(DW_FORM_STRING); | |
| 1290 w->WriteULEB128(0); | |
| 1291 w->WriteULEB128(0); | |
| 1292 | |
| 1293 int current_abbreviation = 4; | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:28:37
Move it to the beginning of the function and use i
zarko
2011/06/27 22:24:29
Done.
| |
| 1294 for (int param = 0; param < params; ++param) { | |
| 1295 w->WriteULEB128(current_abbreviation++); | |
| 1296 w->WriteULEB128(DW_TAG_FORMAL_PARAMETER); | |
| 1297 w->Write<uint8_t>(DW_CHILDREN_NO); | |
| 1298 w->WriteULEB128(DW_AT_NAME); | |
| 1299 w->WriteULEB128(DW_FORM_STRING); | |
| 1300 w->WriteULEB128(DW_AT_TYPE); | |
| 1301 w->WriteULEB128(DW_FORM_REF4); | |
| 1302 w->WriteULEB128(DW_AT_LOCATION); | |
| 1303 w->WriteULEB128(DW_FORM_BLOCK4); | |
| 1304 w->WriteULEB128(0); | |
| 1305 w->WriteULEB128(0); | |
| 1306 } | |
| 1307 | |
| 1308 for (int slot = 0; slot < slots; ++slot) { | |
| 1309 w->WriteULEB128(current_abbreviation++); | |
| 1310 w->WriteULEB128(DW_TAG_VARIABLE); | |
| 1311 w->Write<uint8_t>(DW_CHILDREN_NO); | |
| 1312 w->WriteULEB128(DW_AT_NAME); | |
| 1313 w->WriteULEB128(DW_FORM_STRING); | |
| 1314 w->WriteULEB128(0); | |
| 1315 w->WriteULEB128(0); | |
| 1316 } | |
| 1317 | |
| 1318 for (int context_slot = 0; context_slot < context_slots; | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:28:37
for(x;
y;
z)
zarko
2011/06/27 22:24:29
Done.
| |
| 1319 ++context_slot) { | |
| 1320 w->WriteULEB128(current_abbreviation++); | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:28:37
Seems to be duplicated. Extract to a method?
| |
| 1321 w->WriteULEB128(DW_TAG_VARIABLE); | |
| 1322 w->Write<uint8_t>(DW_CHILDREN_NO); | |
| 1323 w->WriteULEB128(DW_AT_NAME); | |
| 1324 w->WriteULEB128(DW_FORM_STRING); | |
| 1325 w->WriteULEB128(0); | |
| 1326 w->WriteULEB128(0); | |
| 1327 } | |
| 1328 | |
| 1329 for (int internal_slot = 0; internal_slot < internal_slots; | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:28:37
for(x;
y;
z)
zarko
2011/06/27 22:24:29
Done.
| |
| 1330 ++internal_slot) { | |
| 1331 w->WriteULEB128(current_abbreviation++); | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:28:37
Seems to be duplicated. Extract to a method?
Mayb
| |
| 1332 w->WriteULEB128(DW_TAG_VARIABLE); | |
| 1333 w->Write<uint8_t>(DW_CHILDREN_NO); | |
| 1334 w->WriteULEB128(DW_AT_NAME); | |
| 1335 w->WriteULEB128(DW_FORM_STRING); | |
| 1336 w->WriteULEB128(0); | |
| 1337 w->WriteULEB128(0); | |
| 1338 } | |
| 1339 | |
| 1340 for (int local = 0; local < locals; ++local) { | |
| 1341 w->WriteULEB128(current_abbreviation++); | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:28:37
Partially duplicated. If possible try to unify wit
| |
| 1342 w->WriteULEB128(DW_TAG_VARIABLE); | |
| 1343 w->Write<uint8_t>(DW_CHILDREN_NO); | |
| 1344 w->WriteULEB128(DW_AT_NAME); | |
| 1345 w->WriteULEB128(DW_FORM_STRING); | |
| 1346 w->WriteULEB128(DW_AT_TYPE); | |
| 1347 w->WriteULEB128(DW_FORM_REF4); | |
| 1348 w->WriteULEB128(DW_AT_LOCATION); | |
| 1349 w->WriteULEB128(DW_FORM_BLOCK4); | |
| 1350 w->WriteULEB128(0); | |
| 1351 w->WriteULEB128(0); | |
| 1352 } | |
| 1353 | |
| 1354 // The function. | |
| 1355 w->WriteULEB128(current_abbreviation++); | |
| 1356 w->WriteULEB128(DW_TAG_VARIABLE); | |
| 1357 w->Write<uint8_t>(DW_CHILDREN_NO); | |
| 1358 w->WriteULEB128(DW_AT_NAME); | |
| 1359 w->WriteULEB128(DW_FORM_STRING); | |
| 1360 w->WriteULEB128(DW_AT_TYPE); | |
| 1361 w->WriteULEB128(DW_FORM_REF4); | |
| 1362 w->WriteULEB128(DW_AT_LOCATION); | |
| 1363 w->WriteULEB128(DW_FORM_BLOCK4); | |
| 1364 w->WriteULEB128(0); | |
| 1365 w->WriteULEB128(0); | |
| 1366 | |
| 1367 // The context. | |
| 1368 w->WriteULEB128(current_abbreviation++); | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:28:37
Duplicated?
| |
| 1369 w->WriteULEB128(DW_TAG_VARIABLE); | |
| 1370 w->Write<uint8_t>(DW_CHILDREN_NO); | |
| 1371 w->WriteULEB128(DW_AT_NAME); | |
| 1372 w->WriteULEB128(DW_FORM_STRING); | |
| 1373 w->WriteULEB128(DW_AT_TYPE); | |
| 1374 w->WriteULEB128(DW_FORM_REF4); | |
| 1375 w->WriteULEB128(DW_AT_LOCATION); | |
| 1376 w->WriteULEB128(DW_FORM_BLOCK4); | |
| 1377 w->WriteULEB128(0); | |
| 1378 w->WriteULEB128(0); | |
| 1379 | |
| 1380 if (total_children != 0) { | |
| 1381 w->WriteULEB128(0); // Terminate the sibling list. | |
| 1382 } | |
| 1383 } | |
| 1384 | |
| 1385 w->WriteULEB128(0); // Terminate the table. | |
| 830 return true; | 1386 return true; |
| 831 } | 1387 } |
| 1388 | |
| 1389 private: | |
| 1390 CodeDescription* desc_; | |
| 832 }; | 1391 }; |
| 833 | 1392 |
| 834 | 1393 |
| 835 class DebugLineSection : public ELFSection { | 1394 class DebugLineSection : public SECTION_BASE { |
| 836 public: | 1395 public: |
| 837 explicit DebugLineSection(CodeDescription* desc) | 1396 explicit DebugLineSection(CodeDescription* desc) |
| 1397 #ifdef __ELF | |
| 838 : ELFSection(".debug_line", TYPE_PROGBITS, 1), | 1398 : ELFSection(".debug_line", TYPE_PROGBITS, 1), |
| 1399 #else | |
| 1400 : MachOSection("__debug_line", "__DWARF", 1, | |
| 1401 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG), | |
| 1402 #endif | |
| 839 desc_(desc) { } | 1403 desc_(desc) { } |
| 840 | 1404 |
| 841 // DWARF2 standard, figure 34. | 1405 // DWARF2 standard, figure 34. |
| 842 enum DWARF2Opcodes { | 1406 enum DWARF2Opcodes { |
| 843 DW_LNS_COPY = 1, | 1407 DW_LNS_COPY = 1, |
| 844 DW_LNS_ADVANCE_PC = 2, | 1408 DW_LNS_ADVANCE_PC = 2, |
| 845 DW_LNS_ADVANCE_LINE = 3, | 1409 DW_LNS_ADVANCE_LINE = 3, |
| 846 DW_LNS_SET_FILE = 4, | 1410 DW_LNS_SET_FILE = 4, |
| 847 DW_LNS_SET_COLUMN = 5, | 1411 DW_LNS_SET_COLUMN = 5, |
| 848 DW_LNS_NEGATE_STMT = 6 | 1412 DW_LNS_NEGATE_STMT = 6 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 985 return -1; | 1549 return -1; |
| 986 } | 1550 } |
| 987 } | 1551 } |
| 988 | 1552 |
| 989 CodeDescription* desc_; | 1553 CodeDescription* desc_; |
| 990 }; | 1554 }; |
| 991 | 1555 |
| 992 | 1556 |
| 993 #ifdef V8_TARGET_ARCH_X64 | 1557 #ifdef V8_TARGET_ARCH_X64 |
| 994 | 1558 |
| 995 | 1559 class UnwindInfoSection : public SECTION_BASE { |
| 996 class UnwindInfoSection : public ELFSection { | |
| 997 public: | 1560 public: |
| 998 explicit UnwindInfoSection(CodeDescription *desc); | 1561 explicit UnwindInfoSection(CodeDescription *desc); |
| 999 virtual bool WriteBody(Writer *w); | 1562 virtual bool WriteBody(Writer *w); |
| 1000 | 1563 |
| 1001 int WriteCIE(Writer *w); | 1564 int WriteCIE(Writer *w); |
| 1002 void WriteFDE(Writer *w, int); | 1565 void WriteFDE(Writer *w, int); |
| 1003 | 1566 |
| 1004 void WriteFDEStateOnEntry(Writer *w); | 1567 void WriteFDEStateOnEntry(Writer *w); |
| 1005 void WriteFDEStateAfterRBPPush(Writer *w); | 1568 void WriteFDEStateAfterRBPPush(Writer *w); |
| 1006 void WriteFDEStateAfterRBPSet(Writer *w); | 1569 void WriteFDEStateAfterRBPSet(Writer *w); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1072 w->Write<uint8_t>(DW_CFA_NOP); | 1635 w->Write<uint8_t>(DW_CFA_NOP); |
| 1073 } | 1636 } |
| 1074 } | 1637 } |
| 1075 | 1638 |
| 1076 ASSERT((w->position() - initial_position) % kPointerSize == 0); | 1639 ASSERT((w->position() - initial_position) % kPointerSize == 0); |
| 1077 length_slot->set(w->position() - initial_position); | 1640 length_slot->set(w->position() - initial_position); |
| 1078 } | 1641 } |
| 1079 | 1642 |
| 1080 | 1643 |
| 1081 UnwindInfoSection::UnwindInfoSection(CodeDescription *desc) | 1644 UnwindInfoSection::UnwindInfoSection(CodeDescription *desc) |
| 1082 : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), desc_(desc) | 1645 #ifdef __ELF |
| 1083 { } | 1646 : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), |
| 1647 #else | |
| 1648 : MachOSection("__eh_frame", "__TEXT", sizeof(uintptr_t), | |
| 1649 MachOSection::S_REGULAR), | |
| 1650 #endif | |
| 1651 desc_(desc) { } | |
| 1084 | 1652 |
| 1085 int UnwindInfoSection::WriteCIE(Writer *w) { | 1653 int UnwindInfoSection::WriteCIE(Writer *w) { |
| 1086 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>(); | 1654 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>(); |
| 1087 uint32_t cie_position = w->position(); | 1655 uint32_t cie_position = w->position(); |
| 1088 | 1656 |
| 1089 // Write out the CIE header. Currently no 'common instructions' are | 1657 // Write out the CIE header. Currently no 'common instructions' are |
| 1090 // emitted onto the CIE; every FDE has its own set of instructions. | 1658 // emitted onto the CIE; every FDE has its own set of instructions. |
| 1091 | 1659 |
| 1092 w->Write<uint32_t>(CIE_ID); | 1660 w->Write<uint32_t>(CIE_ID); |
| 1093 w->Write<uint8_t>(CIE_VERSION); | 1661 w->Write<uint8_t>(CIE_VERSION); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1205 | 1773 |
| 1206 bool UnwindInfoSection::WriteBody(Writer *w) { | 1774 bool UnwindInfoSection::WriteBody(Writer *w) { |
| 1207 uint32_t cie_position = WriteCIE(w); | 1775 uint32_t cie_position = WriteCIE(w); |
| 1208 WriteFDE(w, cie_position); | 1776 WriteFDE(w, cie_position); |
| 1209 return true; | 1777 return true; |
| 1210 } | 1778 } |
| 1211 | 1779 |
| 1212 | 1780 |
| 1213 #endif // V8_TARGET_ARCH_X64 | 1781 #endif // V8_TARGET_ARCH_X64 |
| 1214 | 1782 |
| 1215 | 1783 static void CreateDWARFSections(CodeDescription* desc, OBJ_FORMAT* obj) { |
| 1216 static void CreateDWARFSections(CodeDescription* desc, ELF* elf) { | |
| 1217 if (desc->IsLineInfoAvailable()) { | 1784 if (desc->IsLineInfoAvailable()) { |
| 1218 elf->AddSection(new DebugInfoSection(desc)); | 1785 obj->AddSection(new DebugInfoSection(desc)); |
| 1219 elf->AddSection(new DebugAbbrevSection); | 1786 obj->AddSection(new DebugAbbrevSection(desc)); |
| 1220 elf->AddSection(new DebugLineSection(desc)); | 1787 obj->AddSection(new DebugLineSection(desc)); |
| 1221 } | 1788 } |
| 1222 #ifdef V8_TARGET_ARCH_X64 | 1789 #ifdef V8_TARGET_ARCH_X64 |
| 1223 elf->AddSection(new UnwindInfoSection(desc)); | 1790 obj->AddSection(new UnwindInfoSection(desc)); |
| 1224 #endif | 1791 #endif |
| 1225 } | 1792 } |
| 1226 | 1793 |
| 1227 | 1794 |
| 1228 // ------------------------------------------------------------------- | 1795 // ------------------------------------------------------------------- |
| 1229 // Binary GDB JIT Interface as described in | 1796 // Binary GDB JIT Interface as described in |
| 1230 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html | 1797 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html |
| 1231 extern "C" { | 1798 extern "C" { |
| 1232 typedef enum { | 1799 typedef enum { |
| 1233 JIT_NOACTION = 0, | 1800 JIT_NOACTION = 0, |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1253 // To prevent GCC from inlining or removing it we place noinline attribute | 1820 // To prevent GCC from inlining or removing it we place noinline attribute |
| 1254 // and inline assembler statement inside. | 1821 // and inline assembler statement inside. |
| 1255 void __attribute__((noinline)) __jit_debug_register_code() { | 1822 void __attribute__((noinline)) __jit_debug_register_code() { |
| 1256 __asm__(""); | 1823 __asm__(""); |
| 1257 } | 1824 } |
| 1258 | 1825 |
| 1259 // GDB will inspect contents of this descriptor. | 1826 // GDB will inspect contents of this descriptor. |
| 1260 // Static initialization is necessary to prevent GDB from seeing | 1827 // Static initialization is necessary to prevent GDB from seeing |
| 1261 // uninitialized descriptor. | 1828 // uninitialized descriptor. |
| 1262 JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; | 1829 JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; |
| 1830 | |
| 1831 #ifdef OBJECT_PRINT | |
| 1832 void __gdb_print_v8_object(MaybeObject* object) { | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:14:47
Frankly speaking I don't see any reason to add thi
zarko
2011/06/27 22:24:29
gdb was having some trouble finding the symbol for
| |
| 1833 object->Print(); | |
| 1834 fprintf(stdout, "\n"); | |
| 1835 } | |
| 1836 #endif | |
| 1263 } | 1837 } |
| 1264 | 1838 |
| 1265 | 1839 |
| 1266 static JITCodeEntry* CreateCodeEntry(Address symfile_addr, | 1840 static JITCodeEntry* CreateCodeEntry(Address symfile_addr, |
| 1267 uintptr_t symfile_size) { | 1841 uintptr_t symfile_size) { |
| 1268 JITCodeEntry* entry = static_cast<JITCodeEntry*>( | 1842 JITCodeEntry* entry = static_cast<JITCodeEntry*>( |
| 1269 malloc(sizeof(JITCodeEntry) + symfile_size)); | 1843 malloc(sizeof(JITCodeEntry) + symfile_size)); |
| 1270 | 1844 |
| 1271 entry->symfile_addr_ = reinterpret_cast<Address>(entry + 1); | 1845 entry->symfile_addr_ = reinterpret_cast<Address>(entry + 1); |
| 1272 entry->symfile_size_ = symfile_size; | 1846 entry->symfile_size_ = symfile_size; |
| 1273 memcpy(entry->symfile_addr_, symfile_addr, symfile_size); | 1847 memcpy(entry->symfile_addr_, symfile_addr, symfile_size); |
| 1274 | 1848 |
| 1275 entry->prev_ = entry->next_ = NULL; | 1849 entry->prev_ = entry->next_ = NULL; |
| 1276 | 1850 |
| 1277 return entry; | 1851 return entry; |
| 1278 } | 1852 } |
| 1279 | 1853 |
| 1280 | 1854 |
| 1281 static void DestroyCodeEntry(JITCodeEntry* entry) { | 1855 static void DestroyCodeEntry(JITCodeEntry* entry) { |
| 1282 free(entry); | 1856 free(entry); |
| 1283 } | 1857 } |
| 1284 | 1858 |
| 1285 | 1859 |
| 1286 static void RegisterCodeEntry(JITCodeEntry* entry) { | 1860 static void RegisterCodeEntry(JITCodeEntry* entry, |
| 1861 bool dump_if_enabled, | |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:14:47
something with indentation.
zarko
2011/06/27 22:24:29
Done.
| |
| 1862 const char* name_hint) { | |
| 1287 #if defined(DEBUG) && !defined(WIN32) | 1863 #if defined(DEBUG) && !defined(WIN32) |
| 1288 static int file_num = 0; | 1864 static int file_num = 0; |
| 1289 if (FLAG_gdbjit_dump) { | 1865 if (FLAG_gdbjit_dump && dump_if_enabled) { |
| 1290 static const int kMaxFileNameSize = 64; | 1866 static const int kMaxFileNameSize = 64; |
| 1291 static const char* kElfFilePrefix = "/tmp/elfdump"; | 1867 static const char* kElfFilePrefix = "/tmp/elfdump"; |
| 1292 static const char* kObjFileExt = ".o"; | 1868 static const char* kObjFileExt = ".o"; |
| 1293 char file_name[64]; | 1869 char file_name[64]; |
| 1294 | 1870 |
| 1295 OS::SNPrintF(Vector<char>(file_name, kMaxFileNameSize), "%s%d%s", | 1871 OS::SNPrintF(Vector<char>(file_name, kMaxFileNameSize), "%s%s%d%s", |
|
Vyacheslav Egorov (Chromium)
2011/06/23 11:14:47
One argument per line.
(somehow I missed this pla
zarko
2011/06/27 22:24:29
Done.
| |
| 1296 kElfFilePrefix, file_num++, kObjFileExt); | 1872 kElfFilePrefix, (name_hint != NULL) ? name_hint : "", |
| 1873 file_num++, kObjFileExt); | |
| 1297 WriteBytes(file_name, entry->symfile_addr_, entry->symfile_size_); | 1874 WriteBytes(file_name, entry->symfile_addr_, entry->symfile_size_); |
| 1298 } | 1875 } |
| 1299 #endif | 1876 #endif |
| 1300 | 1877 |
| 1301 entry->next_ = __jit_debug_descriptor.first_entry_; | 1878 entry->next_ = __jit_debug_descriptor.first_entry_; |
| 1302 if (entry->next_ != NULL) entry->next_->prev_ = entry; | 1879 if (entry->next_ != NULL) entry->next_->prev_ = entry; |
| 1303 __jit_debug_descriptor.first_entry_ = | 1880 __jit_debug_descriptor.first_entry_ = |
| 1304 __jit_debug_descriptor.relevant_entry_ = entry; | 1881 __jit_debug_descriptor.relevant_entry_ = entry; |
| 1305 | 1882 |
| 1306 __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN; | 1883 __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1320 } | 1897 } |
| 1321 | 1898 |
| 1322 __jit_debug_descriptor.relevant_entry_ = entry; | 1899 __jit_debug_descriptor.relevant_entry_ = entry; |
| 1323 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN; | 1900 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN; |
| 1324 __jit_debug_register_code(); | 1901 __jit_debug_register_code(); |
| 1325 } | 1902 } |
| 1326 | 1903 |
| 1327 | 1904 |
| 1328 static JITCodeEntry* CreateELFObject(CodeDescription* desc) { | 1905 static JITCodeEntry* CreateELFObject(CodeDescription* desc) { |
| 1329 ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); | 1906 ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); |
| 1907 #ifdef __MACH_O | |
| 1908 MachO mach_o; | |
| 1909 Writer w(&mach_o); | |
| 1330 | 1910 |
| 1911 mach_o.AddSection(new MachOTextSection(kCodeAlignment, | |
| 1912 desc->CodeStart(), | |
| 1913 desc->CodeSize())); | |
| 1914 | |
| 1915 CreateDWARFSections(desc, &mach_o); | |
| 1916 | |
| 1917 mach_o.Write(&w, desc->CodeStart(), desc->CodeSize()); | |
| 1918 #else | |
| 1331 ELF elf; | 1919 ELF elf; |
| 1332 Writer w(&elf); | 1920 Writer w(&elf); |
| 1333 | 1921 |
| 1334 int text_section_index = elf.AddSection( | 1922 int text_section_index = elf.AddSection( |
| 1335 new FullHeaderELFSection(".text", | 1923 new FullHeaderELFSection(".text", |
| 1336 ELFSection::TYPE_NOBITS, | 1924 ELFSection::TYPE_NOBITS, |
| 1337 kCodeAlignment, | 1925 kCodeAlignment, |
| 1338 desc->CodeStart(), | 1926 desc->CodeStart(), |
| 1339 0, | 1927 0, |
| 1340 desc->CodeSize(), | 1928 desc->CodeSize(), |
| 1341 ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC)); | 1929 ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC)); |
| 1342 | 1930 |
| 1343 CreateSymbolsTable(desc, &elf, text_section_index); | 1931 CreateSymbolsTable(desc, &elf, text_section_index); |
| 1344 | 1932 |
| 1345 CreateDWARFSections(desc, &elf); | 1933 CreateDWARFSections(desc, &elf); |
| 1346 | 1934 |
| 1347 elf.Write(&w); | 1935 elf.Write(&w); |
| 1936 #endif | |
| 1348 | 1937 |
| 1349 return CreateCodeEntry(w.buffer(), w.position()); | 1938 return CreateCodeEntry(w.buffer(), w.position()); |
| 1350 } | 1939 } |
| 1351 | 1940 |
| 1352 | 1941 |
| 1353 static bool SameCodeObjects(void* key1, void* key2) { | 1942 static bool SameCodeObjects(void* key1, void* key2) { |
| 1354 return key1 == key2; | 1943 return key1 == key2; |
| 1355 } | 1944 } |
| 1356 | 1945 |
| 1357 | 1946 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1386 | 1975 |
| 1387 | 1976 |
| 1388 static GDBJITLineInfo* UntagLineInfo(void* ptr) { | 1977 static GDBJITLineInfo* UntagLineInfo(void* ptr) { |
| 1389 return reinterpret_cast<GDBJITLineInfo*>( | 1978 return reinterpret_cast<GDBJITLineInfo*>( |
| 1390 reinterpret_cast<intptr_t>(ptr) & ~kLineInfoTag); | 1979 reinterpret_cast<intptr_t>(ptr) & ~kLineInfoTag); |
| 1391 } | 1980 } |
| 1392 | 1981 |
| 1393 | 1982 |
| 1394 void GDBJITInterface::AddCode(Handle<String> name, | 1983 void GDBJITInterface::AddCode(Handle<String> name, |
| 1395 Handle<Script> script, | 1984 Handle<Script> script, |
| 1396 Handle<Code> code) { | 1985 Handle<Code> code, |
| 1986 CompilationInfo* info) { | |
| 1397 if (!FLAG_gdbjit) return; | 1987 if (!FLAG_gdbjit) return; |
| 1398 | 1988 |
| 1399 // Force initialization of line_ends array. | 1989 // Force initialization of line_ends array. |
| 1400 GetScriptLineNumber(script, 0); | 1990 GetScriptLineNumber(script, 0); |
| 1401 | 1991 |
| 1402 if (!name.is_null()) { | 1992 if (!name.is_null()) { |
| 1403 SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS); | 1993 SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS); |
| 1404 AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script); | 1994 AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info); |
| 1405 } else { | 1995 } else { |
| 1406 AddCode("", *code, GDBJITInterface::FUNCTION, *script); | 1996 AddCode("", *code, GDBJITInterface::FUNCTION, *script, info); |
| 1407 } | 1997 } |
| 1408 } | 1998 } |
| 1409 | 1999 |
| 1410 static void AddUnwindInfo(CodeDescription *desc) { | 2000 static void AddUnwindInfo(CodeDescription *desc) { |
| 1411 #ifdef V8_TARGET_ARCH_X64 | 2001 #ifdef V8_TARGET_ARCH_X64 |
| 1412 if (desc->tag() == GDBJITInterface::FUNCTION) { | 2002 if (desc->tag() == GDBJITInterface::FUNCTION) { |
| 1413 // To avoid propagating unwinding information through | 2003 // To avoid propagating unwinding information through |
| 1414 // compilation pipeline we use an approximation. | 2004 // compilation pipeline we use an approximation. |
| 1415 // For most use cases this should not affect usability. | 2005 // For most use cases this should not affect usability. |
| 1416 static const int kFramePointerPushOffset = 1; | 2006 static const int kFramePointerPushOffset = 1; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1443 #endif // V8_TARGET_ARCH_X64 | 2033 #endif // V8_TARGET_ARCH_X64 |
| 1444 } | 2034 } |
| 1445 | 2035 |
| 1446 | 2036 |
| 1447 Mutex* GDBJITInterface::mutex_ = OS::CreateMutex(); | 2037 Mutex* GDBJITInterface::mutex_ = OS::CreateMutex(); |
| 1448 | 2038 |
| 1449 | 2039 |
| 1450 void GDBJITInterface::AddCode(const char* name, | 2040 void GDBJITInterface::AddCode(const char* name, |
| 1451 Code* code, | 2041 Code* code, |
| 1452 GDBJITInterface::CodeTag tag, | 2042 GDBJITInterface::CodeTag tag, |
| 1453 Script* script) { | 2043 Script* script, |
| 2044 CompilationInfo* info) { | |
| 1454 if (!FLAG_gdbjit) return; | 2045 if (!FLAG_gdbjit) return; |
| 1455 | 2046 |
| 1456 ScopedLock lock(mutex_); | 2047 ScopedLock lock(mutex_); |
| 1457 AssertNoAllocation no_gc; | 2048 AssertNoAllocation no_gc; |
| 1458 | 2049 |
| 1459 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); | 2050 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); |
| 1460 if (e->value != NULL && !IsLineInfoTagged(e->value)) return; | 2051 if (e->value != NULL && !IsLineInfoTagged(e->value)) return; |
| 1461 | 2052 |
| 1462 GDBJITLineInfo* lineinfo = UntagLineInfo(e->value); | 2053 GDBJITLineInfo* lineinfo = UntagLineInfo(e->value); |
| 1463 CodeDescription code_desc(name, | 2054 CodeDescription code_desc(name, |
| 1464 code, | 2055 code, |
| 1465 script != NULL ? Handle<Script>(script) | 2056 script != NULL ? Handle<Script>(script) |
| 1466 : Handle<Script>(), | 2057 : Handle<Script>(), |
| 1467 lineinfo, | 2058 lineinfo, |
| 1468 tag); | 2059 tag, |
| 2060 info); | |
| 1469 | 2061 |
| 1470 if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) { | 2062 if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) { |
| 1471 delete lineinfo; | 2063 delete lineinfo; |
| 1472 GetEntries()->Remove(code, HashForCodeObject(code)); | 2064 GetEntries()->Remove(code, HashForCodeObject(code)); |
| 1473 return; | 2065 return; |
| 1474 } | 2066 } |
| 1475 | 2067 |
| 1476 AddUnwindInfo(&code_desc); | 2068 AddUnwindInfo(&code_desc); |
| 1477 JITCodeEntry* entry = CreateELFObject(&code_desc); | 2069 JITCodeEntry* entry = CreateELFObject(&code_desc); |
| 1478 ASSERT(!IsLineInfoTagged(entry)); | 2070 ASSERT(!IsLineInfoTagged(entry)); |
| 1479 | 2071 |
| 1480 delete lineinfo; | 2072 delete lineinfo; |
| 1481 e->value = entry; | 2073 e->value = entry; |
| 1482 | 2074 |
| 1483 RegisterCodeEntry(entry); | 2075 const char* name_hint = NULL; |
| 2076 bool should_dump = false; | |
| 2077 if (FLAG_gdbjit_dump) { | |
| 2078 if (strlen(FLAG_gdbjit_dump_filter) == 0) { | |
| 2079 name_hint = name; | |
| 2080 should_dump = true; | |
| 2081 } else if (name != NULL) { | |
| 2082 name_hint = strstr(name, FLAG_gdbjit_dump_filter); | |
| 2083 should_dump = (name_hint != NULL); | |
| 2084 } | |
| 2085 } | |
| 2086 RegisterCodeEntry(entry, should_dump, name_hint); | |
| 1484 } | 2087 } |
| 1485 | 2088 |
| 1486 | 2089 |
| 1487 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, | 2090 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, |
| 1488 const char* name, | 2091 const char* name, |
| 1489 Code* code) { | 2092 Code* code) { |
| 1490 if (!FLAG_gdbjit) return; | 2093 if (!FLAG_gdbjit) return; |
| 1491 | 2094 |
| 1492 EmbeddedVector<char, 256> buffer; | 2095 EmbeddedVector<char, 256> buffer; |
| 1493 StringBuilder builder(buffer.start(), buffer.length()); | 2096 StringBuilder builder(buffer.start(), buffer.length()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1545 ScopedLock lock(mutex_); | 2148 ScopedLock lock(mutex_); |
| 1546 ASSERT(!IsLineInfoTagged(line_info)); | 2149 ASSERT(!IsLineInfoTagged(line_info)); |
| 1547 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); | 2150 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); |
| 1548 ASSERT(e->value == NULL); | 2151 ASSERT(e->value == NULL); |
| 1549 e->value = TagLineInfo(line_info); | 2152 e->value = TagLineInfo(line_info); |
| 1550 } | 2153 } |
| 1551 | 2154 |
| 1552 | 2155 |
| 1553 } } // namespace v8::internal | 2156 } } // namespace v8::internal |
| 1554 #endif | 2157 #endif |
| OLD | NEW |