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