Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Unified Diff: src/gdb-jit.cc

Issue 6287015: Added gdb-jit interface support for ARM. Compressed .debug_line table by 1)... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/flag-definitions.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gdb-jit.cc
===================================================================
--- src/gdb-jit.cc (revision 6529)
+++ src/gdb-jit.cc (working copy)
@@ -394,7 +394,7 @@
void WriteHeader(Writer* w) {
ASSERT(w->position() == 0);
Writer::Slot<ELFHeader> header = w->CreateSlotHere<ELFHeader>();
-#if defined(V8_TARGET_ARCH_IA32)
+#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM)
Vyacheslav Egorov (Chromium) 2011/02/01 12:49:51 I think that you need to change SConstruct to enab
const uint8_t ident[16] =
{ 0x7f, 'E', 'L', 'F', 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
#elif defined(V8_TARGET_ARCH_X64)
@@ -412,6 +412,10 @@
// System V ABI, AMD64 Supplement
// http://www.x86-64.org/documentation/abi.pdf
header->machine = 62;
+#elif defined(V8_TARGET_ARCH_ARM)
+ // Set to EM_ARM, defined as 40, in "ARM ELF File Format" at
+ // infocenter.arm.com/help/topic/com.arm.doc.dui0101a/DUI0101A_Elf.pdf
+ header->machine = 40;
#else
#error Unsupported target architecture.
#endif
@@ -503,7 +507,7 @@
return static_cast<Binding>(info >> 4);
}
-#if defined(V8_TARGET_ARCH_IA32)
+#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM)
struct SerializedLayout {
SerializedLayout(uint32_t name,
uintptr_t value,
@@ -814,14 +818,20 @@
Writer::Slot<uint32_t> total_length = w->CreateSlotHere<uint32_t>();
uintptr_t start = w->position();
+ // Used for special opcodes
+ const int8_t line_base = 1;
+ const uint8_t line_range = 7;
+ const int8_t max_line_incr = (line_base + line_range - 1);
+ const uint8_t opcode_base = DW_LNS_NEGATE_STMT + 1;
+
w->Write<uint16_t>(2); // Field version.
Writer::Slot<uint32_t> prologue_length = w->CreateSlotHere<uint32_t>();
uintptr_t prologue_start = w->position();
w->Write<uint8_t>(1); // Field minimum_instruction_length.
w->Write<uint8_t>(1); // Field default_is_stmt.
- w->Write<int8_t>(0); // Field line_base.
- w->Write<uint8_t>(2); // Field line_range.
- w->Write<uint8_t>(DW_LNS_NEGATE_STMT + 1); // Field opcode_base.
+ w->Write<int8_t>(line_base); // Field line_base.
+ w->Write<uint8_t>(line_range); // Field line_range.
+ w->Write<uint8_t>(opcode_base); // Field opcode_base.
w->Write<uint8_t>(0); // DW_LNS_COPY operands count.
w->Write<uint8_t>(1); // DW_LNS_ADVANCE_PC operands count.
w->Write<uint8_t>(1); // DW_LNS_ADVANCE_LINE operands count.
@@ -838,6 +848,7 @@
WriteExtendedOpcode(w, DW_LNE_SET_ADDRESS, sizeof(intptr_t));
w->Write<intptr_t>(desc_->code_start());
+ w->Write<uint8_t>(DW_LNS_COPY);
intptr_t pc = 0;
intptr_t line = 1;
@@ -845,29 +856,81 @@
List<GDBJITLineInfo::PCInfo>* pc_info = desc_->lineinfo()->pc_info();
pc_info->Sort(&ComparePCInfo);
- for (int i = 0; i < pc_info->length(); i++) {
+
+ int pc_info_length = pc_info->length();
+ for (int i = 0; i < pc_info_length; i++) {
GDBJITLineInfo::PCInfo* info = &pc_info->at(i);
- uintptr_t pc_diff = info->pc_ - pc;
ASSERT(info->pc_ >= pc);
- if (pc_diff != 0) {
- w->Write<uint8_t>(DW_LNS_ADVANCE_PC);
- w->WriteSLEB128(pc_diff);
- pc += pc_diff;
+
+ // Reduce bloating in the debug line table by removing duplicate
+ // <file, line, column> entries (per dwarf 2.0 standard).
Vyacheslav Egorov (Chromium) 2011/02/01 12:49:51 Comment is slightly confusing as we do not track c
+ intptr_t new_line = desc_->GetScriptLineNumber(info->pos_);
+ if (new_line == line) {
+ continue;
}
- intptr_t line_diff = desc_->GetScriptLineNumber(info->pos_) - line;
- if (line_diff != 0) {
- w->Write<uint8_t>(DW_LNS_ADVANCE_LINE);
- w->WriteSLEB128(line_diff);
- line += line_diff;
- }
- if (is_statement != info->is_statement_) {
+
+ // Mark statement boundaries. For a better debugging experience, mark
+ // the last pc address in the function as a statement (e.g. "}"), so that
+ // a user can see the result of the last line executed in the function,
+ // should control reach the end.
+ if ((i+1) == pc_info_length) {
+ if (!is_statement) {
+ w->Write<uint8_t>(DW_LNS_NEGATE_STMT);
+ }
+ } else if (is_statement != info->is_statement_) {
w->Write<uint8_t>(DW_LNS_NEGATE_STMT);
is_statement = !is_statement;
}
- if (pc_diff != 0 || i == 0) {
+
+ // Generate special opcodes, if possible. This results in more compact
+ // debug line tables. See the DWARF 2.0 standard to learn more about
+ // special opcodes.
+ bool special_opcode_used = false;
+ uintptr_t pc_diff = info->pc_ - pc;
+ intptr_t line_diff = desc_->GetScriptLineNumber(info->pos_) - line;
Vyacheslav Egorov (Chromium) 2011/02/01 12:49:51 I think desc_->GetScriptLineNumber(info->pos_) is
+
+ // Compute special opcode (see DWARF 2.0 standard)
+ intptr_t special_opcode = (line_diff - line_base) +
+ (line_range * pc_diff) + opcode_base;
+
+ // If the special opcode is < 255, it can be used as a special opcode.
Vyacheslav Egorov (Chromium) 2011/02/01 12:49:51 I prefer to write "less than" instead of "<". BT
+ // If line_diff is larger than the max line increment allowed for a
+ // special opcode, or if line_diff is less than the minimum line that can
+ // be added to the line register (i.e. line_base), then special opcode
+ // can't be used.
+ if ((special_opcode >= opcode_base) && (special_opcode <= 255) &&
+ (line_diff <= max_line_incr) && (line_diff >= line_base)) {
+ w->Write<uint8_t>(special_opcode);
+ special_opcode_used = true;
+ } else {
+ if (pc_diff != 0) {
+ w->Write<uint8_t>(DW_LNS_ADVANCE_PC);
+ w->WriteSLEB128(pc_diff);
+ }
+ if (line_diff != 0) {
Vyacheslav Egorov (Chromium) 2011/02/01 12:49:51 line_diff is guaranteed to be non-zero now.
+ w->Write<uint8_t>(DW_LNS_ADVANCE_LINE);
+ w->WriteSLEB128(line_diff);
+ }
+ }
+
+ // Increment the pc and line operands.
+ pc += pc_diff;
+ line += line_diff;
+
+ // Copy state machine registers if there is a line number difference.
+ // A copy operation is not needed if a special opcode was emitted.
+ if (!special_opcode_used && (line_diff != 0)) {
Vyacheslav Egorov (Chromium) 2011/02/01 12:49:51 line_diff is guaranteed to be non-zero now. So y
w->Write<uint8_t>(DW_LNS_COPY);
}
}
+ // Need to advance the pc to the end of the routine before an end sequence
Vyacheslav Egorov (Chromium) 2011/02/01 12:49:51 Empty line before comment.
+ // can be generated (otherwise the wrong pc address gets associated with
+ // the last line).
+
+ // Advance the pc to the end of the routine, since the end sequence opcode
+ // requires this.
+ w->Write<uint8_t>(DW_LNS_ADVANCE_PC);
+ w->WriteSLEB128(desc_->code_size() - pc);
WriteExtendedOpcode(w, DW_LNE_END_SEQUENCE, 0);
total_length.set(static_cast<uint32_t>(w->position() - start));
return true;
@@ -968,6 +1031,22 @@
static void RegisterCodeEntry(JITCodeEntry* entry) {
+#if defined(DEBUG) && !defined(WIN32)
+ static int fileNum = 0;
+ FILE* file;
+ if (FLAG_gdbjit_dump) {
+ static const int kBufferSize = 64;
+ static const char* kElfFilePre = "/tmp/elfdump";
+ static const char* kObjFileExt = ".o";
+ char buffer[64];
+
+ OS::SNPrintF(Vector<char>(buffer, kBufferSize), "%s%d%s",
+ kElfFilePre, fileNum, kObjFileExt);
+ file = OS::FOpen(buffer, "w");
+ fwrite(entry->symfile_addr_, entry->symfile_size_, 1, file);
Vyacheslav Egorov (Chromium) 2011/02/01 12:49:51 I think you can use WriteBytes() utility function
+ }
+#endif
+
entry->next_ = __jit_debug_descriptor.first_entry_;
if (entry->next_ != NULL) entry->next_->prev_ = entry;
__jit_debug_descriptor.first_entry_ =
@@ -975,6 +1054,13 @@
__jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN;
__jit_debug_register_code();
+
+#if defined(DEBUG) && !defined(WIN32)
+ if (FLAG_gdbjit_dump) {
+ fileNum++;
Vyacheslav Egorov (Chromium) 2011/02/01 12:49:51 it's not clear why you close the file after callin
+ fclose(file);
+ }
+#endif
}
@@ -1025,7 +1111,10 @@
}
-static HashMap entries(&SameCodeObjects);
+static HashMap* GetEntries() {
+ static HashMap entries(&SameCodeObjects);
Vyacheslav Egorov (Chromium) 2011/02/01 12:49:51 Google C++ Style Guide explicitly forbid non POD s
+ return &entries;
+}
static uint32_t HashForCodeObject(Code* code) {
@@ -1078,7 +1167,7 @@
if (!FLAG_gdbjit) return;
AssertNoAllocation no_gc;
- HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), true);
+ HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true);
if (e->value != NULL && !IsLineInfoTagged(e->value)) return;
GDBJITLineInfo* lineinfo = UntagLineInfo(e->value);
@@ -1090,7 +1179,7 @@
if (!FLAG_gdbjit_full && !code_desc.is_line_info_available()) {
delete lineinfo;
- entries.Remove(code, HashForCodeObject(code));
+ GetEntries()->Remove(code, HashForCodeObject(code));
return;
}
@@ -1142,7 +1231,7 @@
void GDBJITInterface::RemoveCode(Code* code) {
if (!FLAG_gdbjit) return;
- HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), false);
+ HashMap::Entry* e =GetEntries()->Lookup(code, HashForCodeObject(code), false);
Vyacheslav Egorov (Chromium) 2011/02/01 12:49:51 after = add space
if (e == NULL) return;
if (IsLineInfoTagged(e->value)) {
@@ -1153,14 +1242,14 @@
DestroyCodeEntry(entry);
}
e->value = NULL;
- entries.Remove(code, HashForCodeObject(code));
+ GetEntries()->Remove(code, HashForCodeObject(code));
}
void GDBJITInterface::RegisterDetailedLineInfo(Code* code,
GDBJITLineInfo* line_info) {
ASSERT(!IsLineInfoTagged(line_info));
- HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), true);
+ HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true);
ASSERT(e->value == NULL);
e->value = TagLineInfo(line_info);
}
« no previous file with comments | « src/flag-definitions.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698