28 #ifdef ENABLE_GDB_JIT_INTERFACE
47 typedef MachO DebugObject;
48 typedef MachOSection DebugSection;
53 typedef ELF DebugObject;
54 typedef ELFSection DebugSection;
59 explicit Writer(DebugObject* debug_object)
60 : debug_object_(debug_object),
63 buffer_(reinterpret_cast<
byte*>(malloc(capacity_))) {
70 uintptr_t position()
const {
77 Slot(Writer* w, uintptr_t offset) : w_(w), offset_(offset) { }
80 return w_->RawSlotAt<
T>(offset_);
83 void set(
const T& value) {
84 *w_->RawSlotAt<
T>(offset_) = value;
88 return Slot<T>(w_, offset_ +
sizeof(
T) * i);
97 void Write(
const T& val) {
98 Ensure(position_ +
sizeof(
T));
99 *RawSlotAt<T>(position_) = val;
100 position_ +=
sizeof(
T);
104 Slot<T> SlotAt(uintptr_t offset) {
105 Ensure(offset +
sizeof(
T));
106 return Slot<T>(
this, offset);
110 Slot<T> CreateSlotHere() {
111 return CreateSlotsHere<T>(1);
115 Slot<T> CreateSlotsHere(uint32_t count) {
116 uintptr_t slot_position = position_;
117 position_ +=
sizeof(
T) * count;
119 return SlotAt<T>(slot_position);
122 void Ensure(uintptr_t pos) {
123 if (capacity_ < pos) {
124 while (capacity_ < pos) capacity_ *= 2;
129 DebugObject* debug_object() {
return debug_object_; }
133 void Align(uintptr_t align) {
134 uintptr_t delta = position_ % align;
135 if (delta == 0)
return;
136 uintptr_t padding = align - delta;
137 Ensure(position_ += padding);
138 ASSERT((position_ % align) == 0);
141 void WriteULEB128(uintptr_t value) {
143 uint8_t
byte = value & 0x7F;
145 if (value != 0) byte |= 0x80;
146 Write<uint8_t>(
byte);
147 }
while (value != 0);
150 void WriteSLEB128(intptr_t value) {
153 int8_t byte = value & 0x7F;
154 bool byte_sign = byte & 0x40;
157 if ((value == 0 && !byte_sign) || (value == -1 && byte_sign)) {
167 void WriteString(
const char* str) {
174 template<
typename T>
friend class Slot;
177 T* RawSlotAt(uintptr_t offset) {
178 ASSERT(offset < capacity_ && offset +
sizeof(
T) <= capacity_);
179 return reinterpret_cast<T*
>(&
buffer_[offset]);
182 DebugObject* debug_object_;
190 template<
typename THeader>
191 class DebugSectionBase :
public ZoneObject {
193 virtual ~DebugSectionBase() { }
195 virtual void WriteBody(Writer::Slot<THeader> header, Writer* writer) {
196 uintptr_t start = writer->position();
197 if (WriteBody(writer)) {
198 uintptr_t end = writer->position();
199 header->offset = start;
200 #if defined(__MACH_O)
203 header->size = end - start;
207 virtual bool WriteBody(Writer* writer) {
211 typedef THeader Header;
215 struct MachOSectionHeader {
218 #if defined(V8_TARGET_ARCH_IA32)
235 class MachOSection :
public DebugSectionBase<MachOSectionHeader> {
239 S_ATTR_COALESCED = 0xbu,
240 S_ATTR_SOME_INSTRUCTIONS = 0x400u,
241 S_ATTR_DEBUG = 0x02000000u,
242 S_ATTR_PURE_INSTRUCTIONS = 0x80000000u
245 MachOSection(
const char*
name,
259 virtual ~MachOSection() { }
261 virtual void PopulateHeader(Writer::Slot<Header> header) {
265 header->align = align_;
268 header->flags = flags_;
269 header->reserved1 = 0;
270 header->reserved2 = 0;
271 memset(header->sectname, 0,
sizeof(header->sectname));
272 memset(header->segname, 0,
sizeof(header->segname));
274 ASSERT(strlen(segment_) <
sizeof(header->segname));
275 strncpy(header->sectname,
name_,
sizeof(header->sectname));
276 strncpy(header->segname, segment_,
sizeof(header->segname));
281 const char* segment_;
287 struct ELFSectionHeader {
297 uintptr_t entry_size;
302 class ELFSection :
public DebugSectionBase<ELFSectionHeader> {
317 TYPE_LOPROC = 0x70000000,
318 TYPE_X86_64_UNWIND = 0x70000001,
319 TYPE_HIPROC = 0x7fffffff,
320 TYPE_LOUSER = 0x80000000,
321 TYPE_HIUSER = 0xffffffff
330 enum SpecialIndexes {
331 INDEX_ABSOLUTE = 0xfff1
334 ELFSection(
const char* name, Type
type, uintptr_t align)
337 virtual ~ELFSection() { }
339 void PopulateHeader(Writer::Slot<Header> header, StringTable* strtab);
341 virtual void WriteBody(Writer::Slot<Header> header, Writer* w) {
342 uintptr_t start = w->position();
344 uintptr_t end = w->position();
345 header->offset = start;
346 header->size = end - start;
350 virtual bool WriteBody(Writer* w) {
354 uint16_t index()
const {
return index_; }
355 void set_index(
uint16_t index) { index_ = index; }
358 virtual void PopulateHeader(Writer::Slot<Header> header) {
365 header->entry_size = 0;
374 #endif // defined(__ELF)
377 #if defined(__MACH_O)
378 class MachOTextSection :
public MachOSection {
380 MachOTextSection(uintptr_t align,
383 : MachOSection(
"__text",
386 MachOSection::S_REGULAR |
387 MachOSection::S_ATTR_SOME_INSTRUCTIONS |
388 MachOSection::S_ATTR_PURE_INSTRUCTIONS),
393 virtual void PopulateHeader(Writer::Slot<Header> header) {
394 MachOSection::PopulateHeader(header);
395 header->addr = addr_;
396 header->size = size_;
403 #endif // defined(__MACH_O)
407 class FullHeaderELFSection :
public ELFSection {
409 FullHeaderELFSection(
const char* name,
416 : ELFSection(name, type, align),
423 virtual void PopulateHeader(Writer::Slot<Header> header) {
424 ELFSection::PopulateHeader(header);
425 header->address = addr_;
426 header->offset = offset_;
427 header->size = size_;
428 header->flags = flags_;
439 class StringTable :
public ELFSection {
441 explicit StringTable(
const char* name)
442 : ELFSection(name, TYPE_STRTAB, 1), writer_(
NULL), offset_(0), size_(0) {
445 uintptr_t Add(
const char* str) {
446 if (*str ==
'\0')
return 0;
448 uintptr_t offset = size_;
453 void AttachWriter(Writer* w) {
455 offset_ = writer_->position();
461 void DetachWriter() {
465 virtual void WriteBody(Writer::Slot<Header> header, Writer* w) {
467 header->offset = offset_;
468 header->size = size_;
472 void WriteString(
const char* str) {
473 uintptr_t written = 0;
475 writer_->Write(*str);
488 void ELFSection::PopulateHeader(Writer::Slot<ELFSection::Header> header,
489 StringTable* strtab) {
490 header->name = strtab->Add(
name_);
491 header->type =
type_;
492 header->alignment = align_;
493 PopulateHeader(header);
495 #endif // defined(__ELF)
498 #if defined(__MACH_O)
501 MachO() : sections_(6) { }
503 uint32_t AddSection(MachOSection* section) {
504 sections_.Add(section);
505 return sections_.length() - 1;
508 void Write(Writer* w, uintptr_t code_start, uintptr_t code_size) {
509 Writer::Slot<MachOHeader> header = WriteHeader(w);
510 uintptr_t load_command_start = w->position();
511 Writer::Slot<MachOSegmentCommand> cmd = WriteSegmentCommand(w,
514 WriteSections(w, cmd, header, load_command_start);
526 #if defined(V8_TARGET_ARCH_X64)
531 struct MachOSegmentCommand {
535 #if defined(V8_TARGET_ARCH_IA32)
552 enum MachOLoadCommandCmd {
553 LC_SEGMENT_32 = 0x00000001u,
554 LC_SEGMENT_64 = 0x00000019u
558 Writer::Slot<MachOHeader> WriteHeader(Writer* w) {
559 ASSERT(w->position() == 0);
560 Writer::Slot<MachOHeader> header = w->CreateSlotHere<MachOHeader>();
561 #if defined(V8_TARGET_ARCH_IA32)
562 header->magic = 0xFEEDFACEu;
564 header->cpusubtype = 3;
565 #elif defined(V8_TARGET_ARCH_X64)
566 header->magic = 0xFEEDFACFu;
567 header->cputype = 7 | 0x01000000;
568 header->cpusubtype = 3;
569 header->reserved = 0;
571 #error Unsupported target architecture.
573 header->filetype = 0x1;
575 header->sizeofcmds = 0;
581 Writer::Slot<MachOSegmentCommand> WriteSegmentCommand(Writer* w,
582 uintptr_t code_start,
583 uintptr_t code_size) {
584 Writer::Slot<MachOSegmentCommand> cmd =
585 w->CreateSlotHere<MachOSegmentCommand>();
586 #if defined(V8_TARGET_ARCH_IA32)
587 cmd->cmd = LC_SEGMENT_32;
589 cmd->cmd = LC_SEGMENT_64;
591 cmd->vmaddr = code_start;
592 cmd->vmsize = code_size;
598 cmd->nsects = sections_.length();
599 memset(cmd->segname, 0, 16);
600 cmd->cmdsize =
sizeof(MachOSegmentCommand) +
sizeof(MachOSection::Header) *
606 void WriteSections(Writer* w,
607 Writer::Slot<MachOSegmentCommand> cmd,
608 Writer::Slot<MachOHeader> header,
609 uintptr_t load_command_start) {
610 Writer::Slot<MachOSection::Header> headers =
611 w->CreateSlotsHere<MachOSection::Header>(sections_.length());
612 cmd->fileoff = w->position();
613 header->sizeofcmds = w->position() - load_command_start;
614 for (
int section = 0; section < sections_.length(); ++section) {
615 sections_[section]->PopulateHeader(headers.at(section));
616 sections_[section]->WriteBody(headers.at(section), w);
618 cmd->filesize = w->position() - (uintptr_t)cmd->fileoff;
622 ZoneList<MachOSection*> sections_;
624 #endif // defined(__MACH_O)
630 ELF() : sections_(6) {
631 sections_.Add(
new ELFSection(
"", ELFSection::TYPE_NULL, 0));
632 sections_.Add(
new StringTable(
".shstrtab"));
635 void Write(Writer* w) {
637 WriteSectionTable(w);
641 ELFSection* SectionAt(uint32_t index) {
642 return sections_[index];
645 uint32_t AddSection(ELFSection* section) {
646 sections_.Add(section);
647 section->set_index(sections_.length() - 1);
648 return sections_.length() - 1;
658 uintptr_t pht_offset;
659 uintptr_t sht_offset;
670 void WriteHeader(Writer* w) {
671 ASSERT(w->position() == 0);
672 Writer::Slot<ELFHeader> header = w->CreateSlotHere<ELFHeader>();
673 #if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM)
674 const uint8_t ident[16] =
675 { 0x7f,
'E',
'L',
'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
676 #elif defined(V8_TARGET_ARCH_X64)
677 const uint8_t ident[16] =
678 { 0x7f,
'E',
'L',
'F', 2, 1, 1, 0, 0, 0 , 0, 0, 0, 0, 0, 0};
680 #error Unsupported target architecture.
682 memcpy(header->ident, ident, 16);
684 #if defined(V8_TARGET_ARCH_IA32)
686 #elif defined(V8_TARGET_ARCH_X64)
690 header->machine = 62;
691 #elif defined(V8_TARGET_ARCH_ARM)
694 header->machine = 40;
696 #error Unsupported target architecture.
700 header->pht_offset = 0;
701 header->sht_offset =
sizeof(ELFHeader);
703 header->header_size =
sizeof(ELFHeader);
704 header->pht_entry_size = 0;
705 header->pht_entry_num = 0;
706 header->sht_entry_size =
sizeof(ELFSection::Header);
707 header->sht_entry_num = sections_.length();
708 header->sht_strtab_index = 1;
711 void WriteSectionTable(Writer* w) {
713 ASSERT(w->position() ==
sizeof(ELFHeader));
715 Writer::Slot<ELFSection::Header> headers =
716 w->CreateSlotsHere<ELFSection::Header>(sections_.length());
719 StringTable* strtab =
static_cast<StringTable*
>(SectionAt(1));
720 strtab->AttachWriter(w);
721 for (
int i = 0, length = sections_.length();
724 sections_[i]->PopulateHeader(headers.at(i), strtab);
726 strtab->DetachWriter();
729 int SectionHeaderPosition(uint32_t section_index) {
730 return sizeof(ELFHeader) +
sizeof(ELFSection::Header) * section_index;
733 void WriteSections(Writer* w) {
734 Writer::Slot<ELFSection::Header> headers =
735 w->SlotAt<ELFSection::Header>(
sizeof(ELFHeader));
737 for (
int i = 0, length = sections_.length();
740 sections_[i]->WriteBody(headers.at(i), w);
744 ZoneList<ELFSection*> sections_;
768 ELFSymbol(
const char* name,
777 info((binding << 4) | type),
782 Binding binding()
const {
783 return static_cast<Binding
>(info >> 4);
785 #if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM)
786 struct SerializedLayout {
787 SerializedLayout(uint32_t name,
796 info((binding << 4) | type),
808 #elif defined(V8_TARGET_ARCH_X64)
809 struct SerializedLayout {
810 SerializedLayout(uint32_t name,
817 info((binding << 4) | type),
833 void Write(Writer::Slot<SerializedLayout> s, StringTable* t) {
835 s->name = t->Add(name);
840 s->section = section;
853 class ELFSymbolTable :
public ELFSection {
855 explicit ELFSymbolTable(
const char* name)
856 : ELFSection(name, TYPE_SYMTAB, sizeof(uintptr_t)),
861 virtual void WriteBody(Writer::Slot<Header> header, Writer* w) {
862 w->Align(header->alignment);
863 int total_symbols = locals_.length() + globals_.length() + 1;
864 header->offset = w->position();
866 Writer::Slot<ELFSymbol::SerializedLayout> symbols =
867 w->CreateSlotsHere<ELFSymbol::SerializedLayout>(total_symbols);
869 header->size = w->position() - header->offset;
872 StringTable* strtab =
873 static_cast<StringTable*
>(w->debug_object()->SectionAt(index() + 1));
874 strtab->AttachWriter(w);
875 symbols.at(0).set(ELFSymbol::SerializedLayout(0,
878 ELFSymbol::BIND_LOCAL,
879 ELFSymbol::TYPE_NOTYPE,
881 WriteSymbolsList(&locals_, symbols.at(1), strtab);
882 WriteSymbolsList(&globals_, symbols.at(locals_.length() + 1), strtab);
883 strtab->DetachWriter();
886 void Add(
const ELFSymbol& symbol) {
887 if (symbol.binding() == ELFSymbol::BIND_LOCAL) {
890 globals_.Add(symbol);
895 virtual void PopulateHeader(Writer::Slot<Header> header) {
896 ELFSection::PopulateHeader(header);
898 header->link = index() + 1;
899 header->info = locals_.length() + 1;
900 header->entry_size =
sizeof(ELFSymbol::SerializedLayout);
904 void WriteSymbolsList(
const ZoneList<ELFSymbol>* src,
905 Writer::Slot<ELFSymbol::SerializedLayout> dst,
906 StringTable* strtab) {
907 for (
int i = 0, len = src->length();
910 src->at(i).Write(dst.at(i), strtab);
914 ZoneList<ELFSymbol> locals_;
915 ZoneList<ELFSymbol> globals_;
917 #endif // defined(__ELF)
922 #ifdef V8_TARGET_ARCH_X64
931 CodeDescription(
const char* name,
933 Handle<Script> script,
934 GDBJITLineInfo* lineinfo,
935 GDBJITInterface::CodeTag tag,
936 CompilationInfo* info)
945 const char*
name()
const {
949 GDBJITLineInfo* lineinfo()
const {
953 GDBJITInterface::CodeTag tag()
const {
957 CompilationInfo* info()
const {
961 bool IsInfoAvailable()
const {
962 return info_ !=
NULL;
965 uintptr_t CodeStart()
const {
966 return reinterpret_cast<uintptr_t
>(code_->instruction_start());
969 uintptr_t CodeEnd()
const {
970 return reinterpret_cast<uintptr_t
>(code_->instruction_end());
973 uintptr_t CodeSize()
const {
974 return CodeEnd() - CodeStart();
977 bool IsLineInfoAvailable() {
978 return !script_.is_null() &&
979 script_->source()->IsString() &&
980 script_->HasValidSource() &&
981 script_->name()->IsString() &&
985 #ifdef V8_TARGET_ARCH_X64
986 uintptr_t GetStackStateStartAddress(StackState state)
const {
987 ASSERT(state < STACK_STATE_MAX);
988 return stack_state_start_addresses_[state];
991 void SetStackStateStartAddress(StackState state, uintptr_t addr) {
992 ASSERT(state < STACK_STATE_MAX);
993 stack_state_start_addresses_[state] = addr;
997 SmartArrayPointer<char> GetFilename() {
1009 Handle<Script> script_;
1010 GDBJITLineInfo* lineinfo_;
1011 GDBJITInterface::CodeTag tag_;
1012 CompilationInfo* info_;
1013 #ifdef V8_TARGET_ARCH_X64
1014 uintptr_t stack_state_start_addresses_[STACK_STATE_MAX];
1019 static void CreateSymbolsTable(CodeDescription* desc,
1021 int text_section_index) {
1022 ELFSymbolTable* symtab =
new ELFSymbolTable(
".symtab");
1023 StringTable* strtab =
new StringTable(
".strtab");
1026 elf->AddSection(symtab);
1027 elf->AddSection(strtab);
1029 symtab->Add(ELFSymbol(
"V8 Code",
1032 ELFSymbol::BIND_LOCAL,
1033 ELFSymbol::TYPE_FILE,
1034 ELFSection::INDEX_ABSOLUTE));
1036 symtab->Add(ELFSymbol(desc->name(),
1039 ELFSymbol::BIND_GLOBAL,
1040 ELFSymbol::TYPE_FUNC,
1041 text_section_index));
1043 #endif // defined(__ELF)
1046 class DebugInfoSection :
public DebugSection {
1048 explicit DebugInfoSection(CodeDescription* desc)
1050 : ELFSection(
".debug_info", TYPE_PROGBITS, 1),
1052 : MachOSection(
"__debug_info",
1055 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
1060 enum DWARF2LocationOp {
1072 enum DWARF2Encoding {
1073 DW_ATE_ADDRESS = 0x1,
1077 bool WriteBody(Writer* w) {
1078 uintptr_t cu_start = w->position();
1079 Writer::Slot<uint32_t> size = w->CreateSlotHere<uint32_t>();
1080 uintptr_t start = w->position();
1082 w->Write<uint32_t>(0);
1083 w->Write<uint8_t>(
sizeof(intptr_t));
1086 w->WriteString(*desc_->GetFilename());
1087 w->Write<intptr_t>(desc_->CodeStart());
1088 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
1089 w->Write<uint32_t>(0);
1091 uint32_t ty_offset =
static_cast<uint32_t
>(w->position() - cu_start);
1094 w->WriteString(
"v8value");
1096 if (desc_->IsInfoAvailable()) {
1097 CompilationInfo* info = desc_->info();
1098 ScopeInfo<FreeStoreAllocationPolicy> scope_info(info->scope());
1100 w->WriteString(desc_->name());
1101 w->Write<intptr_t>(desc_->CodeStart());
1102 w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
1103 Writer::Slot<uint32_t> fb_block_size = w->CreateSlotHere<uint32_t>();
1104 uintptr_t fb_block_start = w->position();
1105 #if defined(V8_TARGET_ARCH_IA32)
1106 w->Write<uint8_t>(DW_OP_reg5);
1107 #elif defined(V8_TARGET_ARCH_X64)
1108 w->Write<uint8_t>(DW_OP_reg6);
1110 #error Unsupported target architecture.
1112 fb_block_size.set(static_cast<uint32_t>(w->position() - fb_block_start));
1114 int params = scope_info.number_of_parameters();
1115 int slots = scope_info.number_of_stack_slots();
1116 int context_slots = scope_info.number_of_context_slots();
1119 int locals = scope_info.LocalCount();
1120 int current_abbreviation = 4;
1122 for (
int param = 0; param < params; ++param) {
1123 w->WriteULEB128(current_abbreviation++);
1126 w->Write<uint32_t>(ty_offset);
1127 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1128 uintptr_t block_start = w->position();
1129 w->Write<uint8_t>(DW_OP_fbreg);
1133 block_size.set(static_cast<uint32_t>(w->position() - block_start));
1136 EmbeddedVector<char, 256> buffer;
1137 StringBuilder builder(buffer.start(), buffer.length());
1139 for (
int slot = 0; slot < slots; ++slot) {
1140 w->WriteULEB128(current_abbreviation++);
1142 builder.AddFormatted(
"slot%d", slot);
1143 w->WriteString(builder.Finalize());
1152 w->WriteULEB128(current_abbreviation++);
1153 w->WriteString(
".closure");
1154 w->WriteULEB128(current_abbreviation++);
1155 w->WriteString(
".previous");
1156 w->WriteULEB128(current_abbreviation++);
1157 w->WriteString(
".extension");
1158 w->WriteULEB128(current_abbreviation++);
1159 w->WriteString(
".global");
1161 for (
int context_slot = 0;
1162 context_slot < context_slots;
1164 w->WriteULEB128(current_abbreviation++);
1166 builder.AddFormatted(
"context_slot%d", context_slot + internal_slots);
1167 w->WriteString(builder.Finalize());
1170 for (
int local = 0; local < locals; ++local) {
1171 w->WriteULEB128(current_abbreviation++);
1174 w->Write<uint32_t>(ty_offset);
1175 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1176 uintptr_t block_start = w->position();
1177 w->Write<uint8_t>(DW_OP_fbreg);
1181 block_size.set(static_cast<uint32_t>(w->position() - block_start));
1185 w->WriteULEB128(current_abbreviation++);
1186 w->WriteString(
"__function");
1187 w->Write<uint32_t>(ty_offset);
1188 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1189 uintptr_t block_start = w->position();
1190 w->Write<uint8_t>(DW_OP_fbreg);
1192 block_size.set(static_cast<uint32_t>(w->position() - block_start));
1196 w->WriteULEB128(current_abbreviation++);
1197 w->WriteString(
"__context");
1198 w->Write<uint32_t>(ty_offset);
1199 Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
1200 uintptr_t block_start = w->position();
1201 w->Write<uint8_t>(DW_OP_fbreg);
1203 block_size.set(static_cast<uint32_t>(w->position() - block_start));
1207 size.set(static_cast<uint32_t>(w->position() - start));
1212 CodeDescription* desc_;
1216 class DebugAbbrevSection :
public DebugSection {
1218 explicit DebugAbbrevSection(CodeDescription* desc)
1220 : ELFSection(
".debug_abbrev", TYPE_PROGBITS, 1),
1222 : MachOSection(
"__debug_abbrev",
1225 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
1231 DW_TAG_FORMAL_PARAMETER = 0x05,
1232 DW_TAG_POINTER_TYPE = 0xf,
1233 DW_TAG_COMPILE_UNIT = 0x11,
1234 DW_TAG_STRUCTURE_TYPE = 0x13,
1235 DW_TAG_BASE_TYPE = 0x24,
1236 DW_TAG_SUBPROGRAM = 0x2e,
1237 DW_TAG_VARIABLE = 0x34
1241 enum DWARF2ChildrenDetermination {
1247 enum DWARF2Attribute {
1248 DW_AT_LOCATION = 0x2,
1250 DW_AT_BYTE_SIZE = 0xb,
1251 DW_AT_STMT_LIST = 0x10,
1252 DW_AT_LOW_PC = 0x11,
1253 DW_AT_HIGH_PC = 0x12,
1254 DW_AT_ENCODING = 0x3e,
1255 DW_AT_FRAME_BASE = 0x40,
1260 enum DWARF2AttributeForm {
1262 DW_FORM_BLOCK4 = 0x4,
1263 DW_FORM_STRING = 0x8,
1264 DW_FORM_DATA4 = 0x6,
1265 DW_FORM_BLOCK = 0x9,
1266 DW_FORM_DATA1 = 0xb,
1271 void WriteVariableAbbreviation(Writer* w,
1272 int abbreviation_code,
1274 bool is_parameter) {
1275 w->WriteULEB128(abbreviation_code);
1276 w->WriteULEB128(is_parameter ? DW_TAG_FORMAL_PARAMETER : DW_TAG_VARIABLE);
1277 w->Write<uint8_t>(DW_CHILDREN_NO);
1278 w->WriteULEB128(DW_AT_NAME);
1279 w->WriteULEB128(DW_FORM_STRING);
1281 w->WriteULEB128(DW_AT_TYPE);
1282 w->WriteULEB128(DW_FORM_REF4);
1283 w->WriteULEB128(DW_AT_LOCATION);
1284 w->WriteULEB128(DW_FORM_BLOCK4);
1290 bool WriteBody(Writer* w) {
1291 int current_abbreviation = 1;
1292 bool extra_info = desc_->IsInfoAvailable();
1293 ASSERT(desc_->IsLineInfoAvailable());
1294 w->WriteULEB128(current_abbreviation++);
1295 w->WriteULEB128(DW_TAG_COMPILE_UNIT);
1296 w->Write<uint8_t>(extra_info ? DW_CHILDREN_YES : DW_CHILDREN_NO);
1297 w->WriteULEB128(DW_AT_NAME);
1298 w->WriteULEB128(DW_FORM_STRING);
1299 w->WriteULEB128(DW_AT_LOW_PC);
1300 w->WriteULEB128(DW_FORM_ADDR);
1301 w->WriteULEB128(DW_AT_HIGH_PC);
1302 w->WriteULEB128(DW_FORM_ADDR);
1303 w->WriteULEB128(DW_AT_STMT_LIST);
1304 w->WriteULEB128(DW_FORM_DATA4);
1309 CompilationInfo* info = desc_->info();
1310 ScopeInfo<FreeStoreAllocationPolicy> scope_info(info->scope());
1311 int params = scope_info.number_of_parameters();
1312 int slots = scope_info.number_of_stack_slots();
1313 int context_slots = scope_info.number_of_context_slots();
1316 int locals = scope_info.LocalCount();
1317 int total_children =
1318 params + slots + context_slots + internal_slots + locals + 2;
1322 w->WriteULEB128(current_abbreviation++);
1323 w->WriteULEB128(DW_TAG_SUBPROGRAM);
1325 total_children != 0 ? DW_CHILDREN_YES : DW_CHILDREN_NO);
1326 w->WriteULEB128(DW_AT_NAME);
1327 w->WriteULEB128(DW_FORM_STRING);
1328 w->WriteULEB128(DW_AT_LOW_PC);
1329 w->WriteULEB128(DW_FORM_ADDR);
1330 w->WriteULEB128(DW_AT_HIGH_PC);
1331 w->WriteULEB128(DW_FORM_ADDR);
1332 w->WriteULEB128(DW_AT_FRAME_BASE);
1333 w->WriteULEB128(DW_FORM_BLOCK4);
1337 w->WriteULEB128(current_abbreviation++);
1338 w->WriteULEB128(DW_TAG_STRUCTURE_TYPE);
1339 w->Write<uint8_t>(DW_CHILDREN_NO);
1340 w->WriteULEB128(DW_AT_BYTE_SIZE);
1341 w->WriteULEB128(DW_FORM_DATA1);
1342 w->WriteULEB128(DW_AT_NAME);
1343 w->WriteULEB128(DW_FORM_STRING);
1347 for (
int param = 0; param < params; ++param) {
1348 WriteVariableAbbreviation(w, current_abbreviation++,
true,
true);
1351 for (
int slot = 0; slot < slots; ++slot) {
1352 WriteVariableAbbreviation(w, current_abbreviation++,
false,
false);
1355 for (
int internal_slot = 0;
1356 internal_slot < internal_slots;
1358 WriteVariableAbbreviation(w, current_abbreviation++,
false,
false);
1361 for (
int context_slot = 0;
1362 context_slot < context_slots;
1364 WriteVariableAbbreviation(w, current_abbreviation++,
false,
false);
1367 for (
int local = 0; local < locals; ++local) {
1368 WriteVariableAbbreviation(w, current_abbreviation++,
true,
false);
1372 WriteVariableAbbreviation(w, current_abbreviation++,
true,
false);
1375 WriteVariableAbbreviation(w, current_abbreviation++,
true,
false);
1377 if (total_children != 0) {
1387 CodeDescription* desc_;
1391 class DebugLineSection :
public DebugSection {
1393 explicit DebugLineSection(CodeDescription* desc)
1395 : ELFSection(
".debug_line", TYPE_PROGBITS, 1),
1397 : MachOSection(
"__debug_line",
1400 MachOSection::S_REGULAR | MachOSection::S_ATTR_DEBUG),
1405 enum DWARF2Opcodes {
1407 DW_LNS_ADVANCE_PC = 2,
1408 DW_LNS_ADVANCE_LINE = 3,
1409 DW_LNS_SET_FILE = 4,
1410 DW_LNS_SET_COLUMN = 5,
1411 DW_LNS_NEGATE_STMT = 6
1415 enum DWARF2ExtendedOpcode {
1416 DW_LNE_END_SEQUENCE = 1,
1417 DW_LNE_SET_ADDRESS = 2,
1418 DW_LNE_DEFINE_FILE = 3
1421 bool WriteBody(Writer* w) {
1423 Writer::Slot<uint32_t> total_length = w->CreateSlotHere<uint32_t>();
1424 uintptr_t start = w->position();
1427 const int8_t line_base = 1;
1428 const uint8_t line_range = 7;
1429 const int8_t max_line_incr = (line_base + line_range - 1);
1430 const uint8_t opcode_base = DW_LNS_NEGATE_STMT + 1;
1433 Writer::Slot<uint32_t> prologue_length = w->CreateSlotHere<uint32_t>();
1434 uintptr_t prologue_start = w->position();
1435 w->Write<uint8_t>(1);
1436 w->Write<uint8_t>(1);
1437 w->Write<int8_t>(line_base);
1438 w->Write<uint8_t>(line_range);
1439 w->Write<uint8_t>(opcode_base);
1440 w->Write<uint8_t>(0);
1441 w->Write<uint8_t>(1);
1442 w->Write<uint8_t>(1);
1443 w->Write<uint8_t>(1);
1444 w->Write<uint8_t>(1);
1445 w->Write<uint8_t>(0);
1446 w->Write<uint8_t>(0);
1447 w->WriteString(*desc_->GetFilename());
1451 w->Write<uint8_t>(0);
1452 prologue_length.set(static_cast<uint32_t>(w->position() - prologue_start));
1454 WriteExtendedOpcode(w, DW_LNE_SET_ADDRESS,
sizeof(intptr_t));
1455 w->Write<intptr_t>(desc_->CodeStart());
1456 w->Write<uint8_t>(DW_LNS_COPY);
1460 bool is_statement =
true;
1462 List<GDBJITLineInfo::PCInfo>* pc_info = desc_->lineinfo()->pc_info();
1463 pc_info->Sort(&ComparePCInfo);
1465 int pc_info_length = pc_info->length();
1466 for (
int i = 0; i < pc_info_length; i++) {
1467 GDBJITLineInfo::PCInfo* info = &pc_info->at(i);
1472 intptr_t new_line = desc_->GetScriptLineNumber(info->pos_);
1473 if (new_line == line) {
1481 if ((i+1) == pc_info_length) {
1482 if (!is_statement) {
1483 w->Write<uint8_t>(DW_LNS_NEGATE_STMT);
1485 }
else if (is_statement != info->is_statement_) {
1486 w->Write<uint8_t>(DW_LNS_NEGATE_STMT);
1487 is_statement = !is_statement;
1493 uintptr_t pc_diff = info->pc_ -
pc;
1494 intptr_t line_diff = new_line - line;
1497 intptr_t special_opcode = (line_diff - line_base) +
1498 (line_range * pc_diff) + opcode_base;
1505 if ((special_opcode >= opcode_base) && (special_opcode <= 255) &&
1506 (line_diff <= max_line_incr) && (line_diff >= line_base)) {
1507 w->Write<uint8_t>(special_opcode);
1509 w->Write<uint8_t>(DW_LNS_ADVANCE_PC);
1510 w->WriteSLEB128(pc_diff);
1511 w->Write<uint8_t>(DW_LNS_ADVANCE_LINE);
1512 w->WriteSLEB128(line_diff);
1513 w->Write<uint8_t>(DW_LNS_COPY);
1522 w->Write<uint8_t>(DW_LNS_ADVANCE_PC);
1523 w->WriteSLEB128(desc_->CodeSize() -
pc);
1524 WriteExtendedOpcode(w, DW_LNE_END_SEQUENCE, 0);
1525 total_length.set(static_cast<uint32_t>(w->position() - start));
1530 void WriteExtendedOpcode(Writer* w,
1531 DWARF2ExtendedOpcode op,
1532 size_t operands_size) {
1533 w->Write<uint8_t>(0);
1534 w->WriteULEB128(operands_size + 1);
1535 w->Write<uint8_t>(op);
1538 static int ComparePCInfo(
const GDBJITLineInfo::PCInfo* a,
1539 const GDBJITLineInfo::PCInfo* b) {
1540 if (a->pc_ == b->pc_) {
1541 if (a->is_statement_ != b->is_statement_) {
1542 return b->is_statement_ ? +1 : -1;
1545 }
else if (a->pc_ > b->pc_) {
1552 CodeDescription* desc_;
1556 #ifdef V8_TARGET_ARCH_X64
1558 class UnwindInfoSection :
public DebugSection {
1560 explicit UnwindInfoSection(CodeDescription* desc);
1561 virtual bool WriteBody(Writer* w);
1563 int WriteCIE(Writer* w);
1564 void WriteFDE(Writer* w,
int);
1566 void WriteFDEStateOnEntry(Writer* w);
1567 void WriteFDEStateAfterRBPPush(Writer* w);
1568 void WriteFDEStateAfterRBPSet(Writer* w);
1569 void WriteFDEStateAfterRBPPop(Writer* w);
1571 void WriteLength(Writer* w,
1572 Writer::Slot<uint32_t>* length_slot,
1573 int initial_position);
1576 CodeDescription* desc_;
1579 enum CFIInstructions {
1580 DW_CFA_ADVANCE_LOC = 0x40,
1581 DW_CFA_OFFSET = 0x80,
1582 DW_CFA_RESTORE = 0xC0,
1584 DW_CFA_SET_LOC = 0x01,
1585 DW_CFA_ADVANCE_LOC1 = 0x02,
1586 DW_CFA_ADVANCE_LOC2 = 0x03,
1587 DW_CFA_ADVANCE_LOC4 = 0x04,
1588 DW_CFA_OFFSET_EXTENDED = 0x05,
1589 DW_CFA_RESTORE_EXTENDED = 0x06,
1590 DW_CFA_UNDEFINED = 0x07,
1591 DW_CFA_SAME_VALUE = 0x08,
1592 DW_CFA_REGISTER = 0x09,
1593 DW_CFA_REMEMBER_STATE = 0x0A,
1594 DW_CFA_RESTORE_STATE = 0x0B,
1595 DW_CFA_DEF_CFA = 0x0C,
1596 DW_CFA_DEF_CFA_REGISTER = 0x0D,
1597 DW_CFA_DEF_CFA_OFFSET = 0x0E,
1599 DW_CFA_DEF_CFA_EXPRESSION = 0x0F,
1600 DW_CFA_EXPRESSION = 0x10,
1601 DW_CFA_OFFSET_EXTENDED_SF = 0x11,
1602 DW_CFA_DEF_CFA_SF = 0x12,
1603 DW_CFA_DEF_CFA_OFFSET_SF = 0x13,
1604 DW_CFA_VAL_OFFSET = 0x14,
1605 DW_CFA_VAL_OFFSET_SF = 0x15,
1606 DW_CFA_VAL_EXPRESSION = 0x16
1610 enum RegisterMapping {
1620 CODE_ALIGN_FACTOR = 1,
1621 DATA_ALIGN_FACTOR = 1,
1622 RETURN_ADDRESS_REGISTER = AMD64_RA
1627 void UnwindInfoSection::WriteLength(Writer* w,
1628 Writer::Slot<uint32_t>* length_slot,
1629 int initial_position) {
1630 uint32_t align = (w->position() - initial_position) %
kPointerSize;
1633 for (uint32_t i = 0; i < (
kPointerSize - align); i++) {
1634 w->Write<uint8_t>(DW_CFA_NOP);
1639 length_slot->set(w->position() - initial_position);
1643 UnwindInfoSection::UnwindInfoSection(CodeDescription* desc)
1645 : ELFSection(
".eh_frame", TYPE_X86_64_UNWIND, 1),
1647 : MachOSection(
"__eh_frame",
"__TEXT",
sizeof(uintptr_t),
1648 MachOSection::S_REGULAR),
1652 int UnwindInfoSection::WriteCIE(Writer* w) {
1653 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>();
1654 uint32_t cie_position = w->position();
1659 w->Write<uint32_t>(CIE_ID);
1660 w->Write<uint8_t>(CIE_VERSION);
1661 w->Write<uint8_t>(0);
1662 w->WriteSLEB128(CODE_ALIGN_FACTOR);
1663 w->WriteSLEB128(DATA_ALIGN_FACTOR);
1664 w->Write<uint8_t>(RETURN_ADDRESS_REGISTER);
1666 WriteLength(w, &cie_length_slot, cie_position);
1668 return cie_position;
1672 void UnwindInfoSection::WriteFDE(Writer* w,
int cie_position) {
1674 Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>();
1675 int fde_position = w->position();
1676 w->Write<
int32_t>(fde_position - cie_position + 4);
1678 w->Write<uintptr_t>(desc_->CodeStart());
1679 w->Write<uintptr_t>(desc_->CodeSize());
1681 WriteFDEStateOnEntry(w);
1682 WriteFDEStateAfterRBPPush(w);
1683 WriteFDEStateAfterRBPSet(w);
1684 WriteFDEStateAfterRBPPop(w);
1686 WriteLength(w, &fde_length_slot, fde_position);
1690 void UnwindInfoSection::WriteFDEStateOnEntry(Writer* w) {
1696 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF);
1697 w->WriteULEB128(AMD64_RSP);
1702 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1703 w->WriteULEB128(AMD64_RA);
1707 w->Write<uint8_t>(DW_CFA_SAME_VALUE);
1708 w->WriteULEB128(AMD64_RBP);
1711 w->Write<uint8_t>(DW_CFA_SET_LOC);
1713 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_PUSH));
1717 void UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer* w) {
1722 w->Write<uint8_t>(DW_CFA_DEF_CFA_OFFSET);
1727 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1728 w->WriteULEB128(AMD64_RBP);
1732 w->Write<uint8_t>(DW_CFA_SET_LOC);
1734 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_SET));
1738 void UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer* w) {
1742 w->Write<uint8_t>(DW_CFA_DEF_CFA);
1743 w->WriteULEB128(AMD64_RBP);
1747 w->Write<uint8_t>(DW_CFA_SET_LOC);
1749 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_POP));
1753 void UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer* w) {
1758 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF);
1759 w->WriteULEB128(AMD64_RSP);
1763 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1764 w->WriteULEB128(AMD64_RBP);
1768 w->Write<uint8_t>(DW_CFA_SET_LOC);
1769 w->Write<uint64_t>(desc_->CodeEnd());
1773 bool UnwindInfoSection::WriteBody(Writer* w) {
1774 uint32_t cie_position = WriteCIE(w);
1775 WriteFDE(w, cie_position);
1780 #endif // V8_TARGET_ARCH_X64
1782 static void CreateDWARFSections(CodeDescription* desc, DebugObject* obj) {
1783 if (desc->IsLineInfoAvailable()) {
1784 obj->AddSection(
new DebugInfoSection(desc));
1785 obj->AddSection(
new DebugAbbrevSection(desc));
1786 obj->AddSection(
new DebugLineSection(desc));
1788 #ifdef V8_TARGET_ARCH_X64
1789 obj->AddSection(
new UnwindInfoSection(desc));
1804 struct JITCodeEntry {
1805 JITCodeEntry* next_;
1806 JITCodeEntry* prev_;
1808 uint64_t symfile_size_;
1811 struct JITDescriptor {
1813 uint32_t action_flag_;
1814 JITCodeEntry* relevant_entry_;
1815 JITCodeEntry* first_entry_;
1821 void __attribute__((noinline)) __jit_debug_register_code() {
1828 JITDescriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
1831 void __gdb_print_v8_object(MaybeObject*
object) {
1833 fprintf(stdout,
"\n");
1839 static JITCodeEntry* CreateCodeEntry(
Address symfile_addr,
1840 uintptr_t symfile_size) {
1841 JITCodeEntry* entry =
static_cast<JITCodeEntry*
>(
1842 malloc(
sizeof(JITCodeEntry) + symfile_size));
1844 entry->symfile_addr_ =
reinterpret_cast<Address>(entry + 1);
1845 entry->symfile_size_ = symfile_size;
1846 memcpy(entry->symfile_addr_, symfile_addr, symfile_size);
1848 entry->prev_ = entry->next_ =
NULL;
1854 static void DestroyCodeEntry(JITCodeEntry* entry) {
1859 static void RegisterCodeEntry(JITCodeEntry* entry,
1860 bool dump_if_enabled,
1861 const char* name_hint) {
1862 #if defined(DEBUG) && !defined(WIN32)
1863 static int file_num = 0;
1864 if (FLAG_gdbjit_dump && dump_if_enabled) {
1865 static const int kMaxFileNameSize = 64;
1866 static const char* kElfFilePrefix =
"/tmp/elfdump";
1867 static const char* kObjFileExt =
".o";
1870 OS::SNPrintF(Vector<char>(file_name, kMaxFileNameSize),
1873 (name_hint !=
NULL) ? name_hint :
"",
1876 WriteBytes(file_name, entry->symfile_addr_, entry->symfile_size_);
1880 entry->next_ = __jit_debug_descriptor.first_entry_;
1881 if (entry->next_ !=
NULL) entry->next_->prev_ = entry;
1882 __jit_debug_descriptor.first_entry_ =
1883 __jit_debug_descriptor.relevant_entry_ = entry;
1885 __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN;
1886 __jit_debug_register_code();
1890 static void UnregisterCodeEntry(JITCodeEntry* entry) {
1891 if (entry->prev_ !=
NULL) {
1892 entry->prev_->next_ = entry->next_;
1894 __jit_debug_descriptor.first_entry_ = entry->next_;
1897 if (entry->next_ !=
NULL) {
1898 entry->next_->prev_ = entry->prev_;
1901 __jit_debug_descriptor.relevant_entry_ = entry;
1902 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN;
1903 __jit_debug_register_code();
1907 static JITCodeEntry* CreateELFObject(CodeDescription* desc) {
1917 CreateDWARFSections(desc, &mach_o);
1919 mach_o.Write(&w, desc->CodeStart(), desc->CodeSize());
1924 int text_section_index = elf.AddSection(
1925 new FullHeaderELFSection(
".text",
1926 ELFSection::TYPE_NOBITS,
1931 ELFSection::FLAG_ALLOC | ELFSection::FLAG_EXEC));
1933 CreateSymbolsTable(desc, &elf, text_section_index);
1935 CreateDWARFSections(desc, &elf);
1940 return CreateCodeEntry(w.buffer(), w.position());
1944 static bool SameCodeObjects(
void* key1,
void* key2) {
1945 return key1 == key2;
1949 static HashMap* GetEntries() {
1951 if (entries ==
NULL) {
1952 entries =
new HashMap(&SameCodeObjects);
1958 static uint32_t HashForCodeObject(Code* code) {
1959 static const uintptr_t kGoldenRatio = 2654435761u;
1960 uintptr_t hash =
reinterpret_cast<uintptr_t
>(code->address());
1965 static const intptr_t kLineInfoTag = 0x1;
1968 static bool IsLineInfoTagged(
void* ptr) {
1969 return 0 != (
reinterpret_cast<intptr_t
>(ptr) & kLineInfoTag);
1973 static void* TagLineInfo(GDBJITLineInfo* ptr) {
1974 return reinterpret_cast<void*
>(
1975 reinterpret_cast<intptr_t
>(ptr) | kLineInfoTag);
1979 static GDBJITLineInfo* UntagLineInfo(
void* ptr) {
1980 return reinterpret_cast<GDBJITLineInfo*
>(
1981 reinterpret_cast<intptr_t
>(ptr) & ~kLineInfoTag);
1985 void GDBJITInterface::AddCode(Handle<String> name,
1986 Handle<Script> script,
1988 CompilationInfo* info) {
1989 if (!FLAG_gdbjit)
return;
1994 if (!name.is_null()) {
1995 SmartArrayPointer<char> name_cstring = name->ToCString(
DISALLOW_NULLS);
1996 AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info);
1998 AddCode(
"", *code, GDBJITInterface::FUNCTION, *script, info);
2002 static void AddUnwindInfo(CodeDescription* desc) {
2003 #ifdef V8_TARGET_ARCH_X64
2004 if (desc->tag() == GDBJITInterface::FUNCTION) {
2008 static const int kFramePointerPushOffset = 1;
2009 static const int kFramePointerSetOffset = 4;
2010 static const int kFramePointerPopOffset = -3;
2012 uintptr_t frame_pointer_push_address =
2013 desc->CodeStart() + kFramePointerPushOffset;
2015 uintptr_t frame_pointer_set_address =
2016 desc->CodeStart() + kFramePointerSetOffset;
2018 uintptr_t frame_pointer_pop_address =
2019 desc->CodeEnd() + kFramePointerPopOffset;
2021 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH,
2022 frame_pointer_push_address);
2023 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET,
2024 frame_pointer_set_address);
2025 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP,
2026 frame_pointer_pop_address);
2028 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_PUSH,
2030 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_SET,
2032 desc->SetStackStateStartAddress(CodeDescription::POST_RBP_POP,
2035 #endif // V8_TARGET_ARCH_X64
2042 void GDBJITInterface::AddCode(
const char* name,
2044 GDBJITInterface::CodeTag tag,
2046 CompilationInfo* info) {
2047 if (!FLAG_gdbjit)
return;
2049 ScopedLock lock(mutex.Pointer());
2050 AssertNoAllocation no_gc;
2052 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code),
true);
2053 if (e->value !=
NULL && !IsLineInfoTagged(e->value))
return;
2055 GDBJITLineInfo* lineinfo = UntagLineInfo(e->value);
2056 CodeDescription code_desc(name,
2058 script !=
NULL ? Handle<Script>(script)
2064 if (!FLAG_gdbjit_full && !code_desc.IsLineInfoAvailable()) {
2066 GetEntries()->Remove(code, HashForCodeObject(code));
2070 AddUnwindInfo(&code_desc);
2071 JITCodeEntry* entry = CreateELFObject(&code_desc);
2072 ASSERT(!IsLineInfoTagged(entry));
2077 const char* name_hint =
NULL;
2078 bool should_dump =
false;
2079 if (FLAG_gdbjit_dump) {
2080 if (strlen(FLAG_gdbjit_dump_filter) == 0) {
2083 }
else if (name !=
NULL) {
2084 name_hint = strstr(name, FLAG_gdbjit_dump_filter);
2085 should_dump = (name_hint !=
NULL);
2088 RegisterCodeEntry(entry, should_dump, name_hint);
2092 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag,
2095 if (!FLAG_gdbjit)
return;
2097 EmbeddedVector<char, 256> buffer;
2098 StringBuilder builder(buffer.start(), buffer.length());
2100 builder.AddString(Tag2String(tag));
2101 if ((name !=
NULL) && (*name !=
'\0')) {
2102 builder.AddString(
": ");
2103 builder.AddString(name);
2105 builder.AddFormatted(
": code object %p", static_cast<void*>(code));
2108 AddCode(builder.Finalize(), code, tag,
NULL,
NULL);
2112 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag,
2115 if (!FLAG_gdbjit)
return;
2120 void GDBJITInterface::AddCode(GDBJITInterface::CodeTag tag, Code* code) {
2121 if (!FLAG_gdbjit)
return;
2123 AddCode(tag,
"", code);
2127 void GDBJITInterface::RemoveCode(Code* code) {
2128 if (!FLAG_gdbjit)
return;
2130 ScopedLock lock(mutex.Pointer());
2131 HashMap::Entry* e = GetEntries()->Lookup(code,
2132 HashForCodeObject(code),
2134 if (e ==
NULL)
return;
2136 if (IsLineInfoTagged(e->value)) {
2137 delete UntagLineInfo(e->value);
2139 JITCodeEntry* entry =
static_cast<JITCodeEntry*
>(e->value);
2140 UnregisterCodeEntry(entry);
2141 DestroyCodeEntry(entry);
2144 GetEntries()->Remove(code, HashForCodeObject(code));
2148 void GDBJITInterface::RegisterDetailedLineInfo(Code* code,
2149 GDBJITLineInfo* line_info) {
2150 ScopedLock lock(mutex.Pointer());
2151 ASSERT(!IsLineInfoTagged(line_info));
2152 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code),
true);
2154 e->value = TagLineInfo(line_info);
static const int kCallerFPOffset
static const int kLastParameterOffset
const char * ToCString(const v8::String::Utf8Value &value)
static String * cast(Object *obj)
value format" "after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false, "print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false, "print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false, "report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true, "garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true, "flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true, "use incremental marking") DEFINE_bool(incremental_marking_steps, true, "do incremental marking steps") DEFINE_bool(trace_incremental_marking, false, "trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true, "Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false, "Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true, "use inline caching") DEFINE_bool(native_code_counters, false, "generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false, "Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true, "Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false, "Never perform compaction on full GC-testing only") DEFINE_bool(compact_code_space, true, "Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true, "Flush inline caches prior to mark compact collection and" "flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0, "Default seed for initializing random generator" "(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true, "allows verbose printing") DEFINE_bool(allow_natives_syntax, false, "allow natives syntax") DEFINE_bool(trace_sim, false, "Trace simulator execution") DEFINE_bool(check_icache, false, "Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0, "Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8, "Stack alingment in bytes in simulator(4 or 8, 8 is default)") DEFINE_bool(trace_exception, false, "print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false, "preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true, "randomize hashes to avoid predictable hash collisions" "(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0, "Fixed seed to use to hash property keys(0 means random)" "(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false, "activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true, "generate optimized regexp code") DEFINE_bool(testing_bool_flag, true, "testing_bool_flag") DEFINE_int(testing_int_flag, 13, "testing_int_flag") DEFINE_float(testing_float_flag, 2.5, "float-flag") DEFINE_string(testing_string_flag, "Hello, world!", "string-flag") DEFINE_int(testing_prng_seed, 42, "Seed used for threading test randomness") DEFINE_string(testing_serialization_file, "/tmp/serdes", "file in which to serialize heap") DEFINE_bool(help, false, "Print usage message, including flags, on console") DEFINE_bool(dump_counters, false, "Dump counters on exit") DEFINE_string(map_counters, "", "Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT, "Pass all remaining arguments to the script.Alias for\"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#43"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2#define FLAG_MODE_DEFINE_DEFAULTS#1"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flag-definitions.h"1#define FLAG_FULL(ftype, ctype, nam, def, cmt)#define FLAG_READONLY(ftype, ctype, nam, def, cmt)#define DEFINE_implication(whenflag, thenflag)#define DEFINE_bool(nam, def, cmt)#define DEFINE_int(nam, def, cmt)#define DEFINE_float(nam, def, cmt)#define DEFINE_string(nam, def, cmt)#define DEFINE_args(nam, def, cmt)#define FLAG DEFINE_bool(use_strict, false,"enforce strict mode") DEFINE_bool(es5_readonly, false,"activate correct semantics for inheriting readonliness") DEFINE_bool(es52_globals, false,"activate new semantics for global var declarations") DEFINE_bool(harmony_typeof, false,"enable harmony semantics for typeof") DEFINE_bool(harmony_scoping, false,"enable harmony block scoping") DEFINE_bool(harmony_modules, false,"enable harmony modules (implies block scoping)") DEFINE_bool(harmony_proxies, false,"enable harmony proxies") DEFINE_bool(harmony_collections, false,"enable harmony collections (sets, maps, and weak maps)") DEFINE_bool(harmony, false,"enable all harmony features (except typeof)") DEFINE_implication(harmony, harmony_scoping) DEFINE_implication(harmony, harmony_modules) DEFINE_implication(harmony, harmony_proxies) DEFINE_implication(harmony, harmony_collections) DEFINE_implication(harmony_modules, harmony_scoping) DEFINE_bool(packed_arrays, false,"optimizes arrays that have no holes") DEFINE_bool(smi_only_arrays, true,"tracks arrays with only smi values") DEFINE_bool(clever_optimizations, true,"Optimize object size, Array shift, DOM strings and string +") DEFINE_bool(unbox_double_arrays, true,"automatically unbox arrays of doubles") DEFINE_bool(string_slices, true,"use string slices") DEFINE_bool(crankshaft, true,"use crankshaft") DEFINE_string(hydrogen_filter,"","optimization filter") DEFINE_bool(use_range, true,"use hydrogen range analysis") DEFINE_bool(eliminate_dead_phis, true,"eliminate dead phis") DEFINE_bool(use_gvn, true,"use hydrogen global value numbering") DEFINE_bool(use_canonicalizing, true,"use hydrogen instruction canonicalizing") DEFINE_bool(use_inlining, true,"use function inlining") DEFINE_int(max_inlined_source_size, 600,"maximum source size in bytes considered for a single inlining") DEFINE_int(max_inlined_nodes, 196,"maximum number of AST nodes considered for a single inlining") DEFINE_int(max_inlined_nodes_cumulative, 196,"maximum cumulative number of AST nodes considered for inlining") DEFINE_bool(loop_invariant_code_motion, true,"loop invariant code motion") DEFINE_bool(collect_megamorphic_maps_from_stub_cache, true,"crankshaft harvests type feedback from stub cache") DEFINE_bool(hydrogen_stats, false,"print statistics for hydrogen") DEFINE_bool(trace_hydrogen, false,"trace generated hydrogen to file") DEFINE_string(trace_phase,"Z","trace generated IR for specified phases") DEFINE_bool(trace_inlining, false,"trace inlining decisions") DEFINE_bool(trace_alloc, false,"trace register allocator") DEFINE_bool(trace_all_uses, false,"trace all use positions") DEFINE_bool(trace_range, false,"trace range analysis") DEFINE_bool(trace_gvn, false,"trace global value numbering") DEFINE_bool(trace_representation, false,"trace representation types") DEFINE_bool(stress_pointer_maps, false,"pointer map for every instruction") DEFINE_bool(stress_environments, false,"environment for every instruction") DEFINE_int(deopt_every_n_times, 0,"deoptimize every n times a deopt point is passed") DEFINE_bool(trap_on_deopt, false,"put a break point before deoptimizing") DEFINE_bool(deoptimize_uncommon_cases, true,"deoptimize uncommon cases") DEFINE_bool(polymorphic_inlining, true,"polymorphic inlining") DEFINE_bool(use_osr, true,"use on-stack replacement") DEFINE_bool(array_bounds_checks_elimination, false,"perform array bounds checks elimination") DEFINE_bool(array_index_dehoisting, false,"perform array index dehoisting") DEFINE_bool(trace_osr, false,"trace on-stack replacement") DEFINE_int(stress_runs, 0,"number of stress runs") DEFINE_bool(optimize_closures, true,"optimize closures") DEFINE_bool(inline_construct, true,"inline constructor calls") DEFINE_bool(inline_arguments, true,"inline functions with arguments object") DEFINE_int(loop_weight, 1,"loop weight for representation inference") DEFINE_bool(optimize_for_in, true,"optimize functions containing for-in loops") DEFINE_bool(experimental_profiler, true,"enable all profiler experiments") DEFINE_bool(watch_ic_patching, false,"profiler considers IC stability") DEFINE_int(frame_count, 1,"number of stack frames inspected by the profiler") DEFINE_bool(self_optimization, false,"primitive functions trigger their own optimization") DEFINE_bool(direct_self_opt, false,"call recompile stub directly when self-optimizing") DEFINE_bool(retry_self_opt, false,"re-try self-optimization if it failed") DEFINE_bool(count_based_interrupts, false,"trigger profiler ticks based on counting instead of timing") DEFINE_bool(interrupt_at_exit, false,"insert an interrupt check at function exit") DEFINE_bool(weighted_back_edges, false,"weight back edges by jump distance for interrupt triggering") DEFINE_int(interrupt_budget, 5900,"execution budget before interrupt is triggered") DEFINE_int(type_info_threshold, 15,"percentage of ICs that must have type info to allow optimization") DEFINE_int(self_opt_count, 130,"call count before self-optimization") DEFINE_implication(experimental_profiler, watch_ic_patching) DEFINE_implication(experimental_profiler, self_optimization) DEFINE_implication(experimental_profiler, retry_self_opt) DEFINE_implication(experimental_profiler, count_based_interrupts) DEFINE_implication(experimental_profiler, interrupt_at_exit) DEFINE_implication(experimental_profiler, weighted_back_edges) DEFINE_bool(trace_opt_verbose, false,"extra verbose compilation tracing") DEFINE_implication(trace_opt_verbose, trace_opt) DEFINE_bool(debug_code, false,"generate extra code (assertions) for debugging") DEFINE_bool(code_comments, false,"emit comments in code disassembly") DEFINE_bool(enable_sse2, true,"enable use of SSE2 instructions if available") DEFINE_bool(enable_sse3, true,"enable use of SSE3 instructions if available") DEFINE_bool(enable_sse4_1, true,"enable use of SSE4.1 instructions if available") DEFINE_bool(enable_cmov, true,"enable use of CMOV instruction if available") DEFINE_bool(enable_rdtsc, true,"enable use of RDTSC instruction if available") DEFINE_bool(enable_sahf, true,"enable use of SAHF instruction if available (X64 only)") DEFINE_bool(enable_vfp3, true,"enable use of VFP3 instructions if available - this implies ""enabling ARMv7 instructions (ARM only)") DEFINE_bool(enable_armv7, true,"enable use of ARMv7 instructions if available (ARM only)") DEFINE_bool(enable_fpu, true,"enable use of MIPS FPU instructions if available (MIPS only)") DEFINE_string(expose_natives_as, NULL,"expose natives in global object") DEFINE_string(expose_debug_as, NULL,"expose debug in global object") DEFINE_bool(expose_gc, false,"expose gc extension") DEFINE_bool(expose_externalize_string, false,"expose externalize string extension") DEFINE_int(stack_trace_limit, 10,"number of stack frames to capture") DEFINE_bool(builtins_in_stack_traces, false,"show built-in functions in stack traces") DEFINE_bool(disable_native_files, false,"disable builtin natives files") DEFINE_bool(inline_new, true,"use fast inline allocation") DEFINE_bool(stack_trace_on_abort, true,"print a stack trace if an assertion failure occurs") DEFINE_bool(trace, false,"trace function calls") DEFINE_bool(mask_constants_with_cookie, true,"use random jit cookie to mask large constants") DEFINE_bool(lazy, true,"use lazy compilation") DEFINE_bool(trace_opt, false,"trace lazy optimization") DEFINE_bool(trace_opt_stats, false,"trace lazy optimization statistics") DEFINE_bool(opt, true,"use adaptive optimizations") DEFINE_bool(always_opt, false,"always try to optimize functions") DEFINE_bool(prepare_always_opt, false,"prepare for turning on always opt") DEFINE_bool(trace_deopt, false,"trace deoptimization") DEFINE_int(min_preparse_length, 1024,"minimum length for automatic enable preparsing") DEFINE_bool(always_full_compiler, false,"try to use the dedicated run-once backend for all code") DEFINE_bool(trace_bailout, false,"print reasons for falling back to using the classic V8 backend") DEFINE_bool(compilation_cache, true,"enable compilation cache") DEFINE_bool(cache_prototype_transitions, true,"cache prototype transitions") DEFINE_bool(trace_debug_json, false,"trace debugging JSON request/response") DEFINE_bool(debugger_auto_break, true,"automatically set the debug break flag when debugger commands are ""in the queue") DEFINE_bool(enable_liveedit, true,"enable liveedit experimental feature") DEFINE_bool(break_on_abort, true,"always cause a debug break before aborting") DEFINE_int(stack_size, kPointerSize *123,"default size of stack region v8 is allowed to use (in kBytes)") DEFINE_int(max_stack_trace_source_length, 300,"maximum length of function source code printed in a stack trace.") DEFINE_bool(always_inline_smi_code, false,"always inline smi code in non-opt code") DEFINE_int(max_new_space_size, 0,"max size of the new generation (in kBytes)") DEFINE_int(max_old_space_size, 0,"max size of the old generation (in Mbytes)") DEFINE_int(max_executable_size, 0,"max size of executable memory (in Mbytes)") DEFINE_bool(gc_global, false,"always perform global GCs") DEFINE_int(gc_interval,-1,"garbage collect after <n> allocations") DEFINE_bool(trace_gc, false,"print one trace line following each garbage collection") DEFINE_bool(trace_gc_nvp, false,"print one detailed trace line in name=value format ""after each garbage collection") DEFINE_bool(print_cumulative_gc_stat, false,"print cumulative GC statistics in name=value format on exit") DEFINE_bool(trace_gc_verbose, false,"print more details following each garbage collection") DEFINE_bool(trace_fragmentation, false,"report fragmentation for old pointer and data pages") DEFINE_bool(collect_maps, true,"garbage collect maps from which no objects can be reached") DEFINE_bool(flush_code, true,"flush code that we expect not to use again before full gc") DEFINE_bool(incremental_marking, true,"use incremental marking") DEFINE_bool(incremental_marking_steps, true,"do incremental marking steps") DEFINE_bool(trace_incremental_marking, false,"trace progress of the incremental marking") DEFINE_bool(use_idle_notification, true,"Use idle notification to reduce memory footprint.") DEFINE_bool(send_idle_notification, false,"Send idle notifcation between stress runs.") DEFINE_bool(use_ic, true,"use inline caching") DEFINE_bool(native_code_counters, false,"generate extra code for manipulating stats counters") DEFINE_bool(always_compact, false,"Perform compaction on every full GC") DEFINE_bool(lazy_sweeping, true,"Use lazy sweeping for old pointer and data spaces") DEFINE_bool(never_compact, false,"Never perform compaction on full GC - testing only") DEFINE_bool(compact_code_space, true,"Compact code space on full non-incremental collections") DEFINE_bool(cleanup_code_caches_at_gc, true,"Flush inline caches prior to mark compact collection and ""flush code caches in maps during mark compact cycle.") DEFINE_int(random_seed, 0,"Default seed for initializing random generator ""(0, the default, means to use system random).") DEFINE_bool(use_verbose_printer, true,"allows verbose printing") DEFINE_bool(allow_natives_syntax, false,"allow natives syntax") DEFINE_bool(trace_sim, false,"Trace simulator execution") DEFINE_bool(check_icache, false,"Check icache flushes in ARM and MIPS simulator") DEFINE_int(stop_sim_at, 0,"Simulator stop after x number of instructions") DEFINE_int(sim_stack_alignment, 8,"Stack alingment in bytes in simulator (4 or 8, 8 is default)") DEFINE_bool(trace_exception, false,"print stack trace when throwing exceptions") DEFINE_bool(preallocate_message_memory, false,"preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true,"randomize hashes to avoid predictable hash collisions ""(with snapshots this option cannot override the baked-in seed)") DEFINE_int(hash_seed, 0,"Fixed seed to use to hash property keys (0 means random)""(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(preemption, false,"activate a 100ms timer that switches between V8 threads") DEFINE_bool(regexp_optimization, true,"generate optimized regexp code") DEFINE_bool(testing_bool_flag, true,"testing_bool_flag") DEFINE_int(testing_int_flag, 13,"testing_int_flag") DEFINE_float(testing_float_flag, 2.5,"float-flag") DEFINE_string(testing_string_flag,"Hello, world!","string-flag") DEFINE_int(testing_prng_seed, 42,"Seed used for threading test randomness") DEFINE_string(testing_serialization_file,"/tmp/serdes","file in which to serialize heap") DEFINE_bool(help, false,"Print usage message, including flags, on console") DEFINE_bool(dump_counters, false,"Dump counters on exit") DEFINE_string(map_counters,"","Map counters to a file") DEFINE_args(js_arguments, JSARGUMENTS_INIT,"Pass all remaining arguments to the script. Alias for \"--\".") DEFINE_bool(debug_compile_events, true,"Enable debugger compile events") DEFINE_bool(debug_script_collected_events, true,"Enable debugger script collected events") DEFINE_bool(gdbjit, false,"enable GDBJIT interface (disables compacting GC)") DEFINE_bool(gdbjit_full, false,"enable GDBJIT interface for all code objects") DEFINE_bool(gdbjit_dump, false,"dump elf objects with debug info to disk") DEFINE_string(gdbjit_dump_filter,"","dump only objects containing this substring") DEFINE_bool(force_marking_deque_overflows, false,"force overflows of marking deque by reducing it's size ""to 64 words") DEFINE_bool(stress_compaction, false,"stress the GC compactor to flush out bugs (implies ""--force_marking_deque_overflows)")#define FLAG DEFINE_bool(enable_slow_asserts, false,"enable asserts that are slow to execute") DEFINE_bool(trace_codegen, false,"print name of functions for which code is generated") DEFINE_bool(print_source, false,"pretty print source code") DEFINE_bool(print_builtin_source, false,"pretty print source code for builtins") DEFINE_bool(print_ast, false,"print source AST") DEFINE_bool(print_builtin_ast, false,"print source AST for builtins") DEFINE_string(stop_at,"","function name where to insert a breakpoint") DEFINE_bool(print_builtin_scopes, false,"print scopes for builtins") DEFINE_bool(print_scopes, false,"print scopes") DEFINE_bool(trace_contexts, false,"trace contexts operations") DEFINE_bool(gc_greedy, false,"perform GC prior to some allocations") DEFINE_bool(gc_verbose, false,"print stuff during garbage collection") DEFINE_bool(heap_stats, false,"report heap statistics before and after GC") DEFINE_bool(code_stats, false,"report code statistics after GC") DEFINE_bool(verify_heap, false,"verify heap pointers before and after GC") DEFINE_bool(print_handles, false,"report handles after GC") DEFINE_bool(print_global_handles, false,"report global handles after GC") DEFINE_bool(trace_ic, false,"trace inline cache state transitions") DEFINE_bool(print_interfaces, false,"print interfaces") DEFINE_bool(print_interface_details, false,"print interface inference details") DEFINE_int(print_interface_depth, 5,"depth for printing interfaces") DEFINE_bool(trace_normalization, false,"prints when objects are turned into dictionaries.") DEFINE_bool(trace_lazy, false,"trace lazy compilation") DEFINE_bool(collect_heap_spill_statistics, false,"report heap spill statistics along with heap_stats ""(requires heap_stats)") DEFINE_bool(trace_isolates, false,"trace isolate state changes") DEFINE_bool(log_state_changes, false,"Log state changes.") DEFINE_bool(regexp_possessive_quantifier, false,"enable possessive quantifier syntax for testing") DEFINE_bool(trace_regexp_bytecodes, false,"trace regexp bytecode execution") DEFINE_bool(trace_regexp_assembler, false,"trace regexp macro assembler calls.")#define FLAG DEFINE_bool(log, false,"Minimal logging (no API, code, GC, suspect, or handles samples).") DEFINE_bool(log_all, false,"Log all events to the log file.") DEFINE_bool(log_runtime, false,"Activate runtime system %Log call.") DEFINE_bool(log_api, false,"Log API events to the log file.") DEFINE_bool(log_code, false,"Log code events to the log file without profiling.") DEFINE_bool(log_gc, false,"Log heap samples on garbage collection for the hp2ps tool.") DEFINE_bool(log_handles, false,"Log global handle events.") DEFINE_bool(log_snapshot_positions, false,"log positions of (de)serialized objects in the snapshot.") DEFINE_bool(log_suspect, false,"Log suspect operations.") DEFINE_bool(prof, false,"Log statistical profiling information (implies --log-code).") DEFINE_bool(prof_auto, true,"Used with --prof, starts profiling automatically") DEFINE_bool(prof_lazy, false,"Used with --prof, only does sampling and logging"" when profiler is active (implies --noprof_auto).") DEFINE_bool(prof_browser_mode, true,"Used with --prof, turns on browser-compatible mode for profiling.") DEFINE_bool(log_regexp, false,"Log regular expression execution.") DEFINE_bool(sliding_state_window, false,"Update sliding state window counters.") DEFINE_string(logfile,"v8.log","Specify the name of the log file.") DEFINE_bool(ll_prof, false,"Enable low-level linux profiler.")#define FLAG DEFINE_bool(trace_elements_transitions, false,"trace elements transitions") DEFINE_bool(print_code_stubs, false,"print code stubs") DEFINE_bool(test_secondary_stub_cache, false,"test secondary stub cache by disabling the primary one") DEFINE_bool(test_primary_stub_cache, false,"test primary stub cache by disabling the secondary one") DEFINE_bool(print_code, false,"print generated code") DEFINE_bool(print_opt_code, false,"print optimized code") DEFINE_bool(print_unopt_code, false,"print unoptimized code before ""printing optimized code based on it") DEFINE_bool(print_code_verbose, false,"print more information for code") DEFINE_bool(print_builtin_code, false,"print generated code for builtins")#47"/Users/thlorenz/dev/dx/v8-perf/build/v8/src/flags.cc"2 namespace{struct Flag{enum FlagType{TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_ARGS} name
#define ASSERT(condition)
LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak))
const intptr_t kCodeAlignment
StringInputBuffer *const buffer_
int WhichPowerOf2(uint32_t x)
int GetScriptLineNumberSafe(Handle< Script > script, int code_pos)
LazyDynamicInstance< Mutex, CreateMutexTrait, ThreadSafeInitOnceTrait >::type LazyMutex
#define T(name, string, precedence)
static int SNPrintF(Vector< char > str, const char *format,...)
int GetScriptLineNumber(Handle< Script > script, int code_pos)
static const int kContextOffset
static const int kFunctionOffset
const int kCodeAlignmentBits
static const int kCallerPCOffset
TemplateHashMapImpl< FreeStoreAllocationPolicy > HashMap
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
int WriteBytes(const char *filename, const byte *bytes, int size, bool verbose)
static const int kLocal0Offset