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

Unified Diff: src/debug.cc

Issue 1235603002: Debugger: make debug code on-stack replacement more robust. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 5 years, 5 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/assembler.cc ('k') | src/ia32/assembler-ia32.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/debug.cc
diff --git a/src/debug.cc b/src/debug.cc
index 1098f608c4c227cc752b36900892191581062a53..c8240e084fe85126357aeed1863a829337536eba 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -1436,56 +1436,58 @@ static void CollectActiveFunctionsFromThread(
}
-// Figure out how many bytes of "pc_offset" correspond to actual code by
-// subtracting off the bytes that correspond to constant/veneer pools. See
-// Assembler::CheckConstPool() and Assembler::CheckVeneerPool(). Note that this
-// is only useful for architectures using constant pools or veneer pools.
-static int ComputeCodeOffsetFromPcOffset(Code *code, int pc_offset) {
+// Count the number of calls before the current frame PC to find the
+// corresponding PC in the newly recompiled code.
+static Address ComputeNewPcForRedirect(Code* new_code, Code* old_code,
+ Address old_pc) {
+ DCHECK_EQ(old_code->kind(), Code::FUNCTION);
+ DCHECK_EQ(new_code->kind(), Code::FUNCTION);
+ DCHECK(!old_code->has_debug_break_slots());
+ DCHECK(new_code->has_debug_break_slots());
+ int mask = RelocInfo::kCodeTargetMask;
+ int index = 0;
+ intptr_t delta = 0;
+ for (RelocIterator it(old_code, mask); !it.done(); it.next()) {
+ RelocInfo* rinfo = it.rinfo();
+ Address current_pc = rinfo->pc();
+ // The frame PC is behind the call instruction by the call instruction size.
+ if (current_pc > old_pc) break;
+ index++;
+ delta = old_pc - current_pc;
+ }
+
+ RelocIterator it(new_code, mask);
+ for (int i = 1; i < index; i++) it.next();
+ return it.rinfo()->pc() + delta;
+}
+
+
+// Count the number of continuations at which the current pc offset is at.
+static int ComputeContinuationIndexFromPcOffset(Code* code, int pc_offset) {
DCHECK_EQ(code->kind(), Code::FUNCTION);
DCHECK(!code->has_debug_break_slots());
- DCHECK_LE(0, pc_offset);
- DCHECK_LT(pc_offset, code->instruction_end() - code->instruction_start());
-
- int mask = RelocInfo::ModeMask(RelocInfo::CONST_POOL) |
- RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
- byte *pc = code->instruction_start() + pc_offset;
- int code_offset = pc_offset;
+ Address pc = code->instruction_start() + pc_offset;
+ int mask = RelocInfo::ModeMask(RelocInfo::GENERATOR_CONTINUATION);
+ int index = 0;
for (RelocIterator it(code, mask); !it.done(); it.next()) {
- RelocInfo* info = it.rinfo();
- if (info->pc() >= pc) break;
- DCHECK(RelocInfo::IsConstPool(info->rmode()));
- code_offset -= static_cast<int>(info->data());
- DCHECK_LE(0, code_offset);
+ index++;
+ RelocInfo* rinfo = it.rinfo();
+ Address current_pc = rinfo->pc();
+ if (current_pc == pc) break;
+ DCHECK(current_pc < pc);
}
-
- return code_offset;
+ return index;
}
-// The inverse of ComputeCodeOffsetFromPcOffset.
-static int ComputePcOffsetFromCodeOffset(Code *code, int code_offset) {
+// Find the pc offset for the given continuation index.
+static int ComputePcOffsetFromContinuationIndex(Code* code, int index) {
DCHECK_EQ(code->kind(), Code::FUNCTION);
-
- int mask = RelocInfo::kDebugBreakSlotMask |
- RelocInfo::ModeMask(RelocInfo::CONST_POOL) |
- RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
- int reloc = 0;
- for (RelocIterator it(code, mask); !it.done(); it.next()) {
- RelocInfo* info = it.rinfo();
- if (info->pc() - code->instruction_start() - reloc >= code_offset) break;
- if (RelocInfo::IsDebugBreakSlot(info->rmode())) {
- reloc += Assembler::kDebugBreakSlotLength;
- } else {
- DCHECK(RelocInfo::IsConstPool(info->rmode()));
- reloc += static_cast<int>(info->data());
- }
- }
-
- int pc_offset = code_offset + reloc;
-
- DCHECK_LT(code->instruction_start() + pc_offset, code->instruction_end());
-
- return pc_offset;
+ DCHECK(code->has_debug_break_slots());
+ int mask = RelocInfo::ModeMask(RelocInfo::GENERATOR_CONTINUATION);
+ RelocIterator it(code, mask);
+ for (int i = 1; i < index; i++) it.next();
+ return static_cast<int>(it.rinfo()->pc() - code->instruction_start());
}
@@ -1510,13 +1512,8 @@ static void RedirectActivationsToRecompiledCodeOnThread(
continue;
}
- int old_pc_offset =
- static_cast<int>(frame->pc() - frame_code->instruction_start());
- int code_offset = ComputeCodeOffsetFromPcOffset(*frame_code, old_pc_offset);
- int new_pc_offset = ComputePcOffsetFromCodeOffset(*new_code, code_offset);
-
- // Compute the equivalent pc in the new code.
- byte* new_pc = new_code->instruction_start() + new_pc_offset;
+ Address new_pc =
+ ComputeNewPcForRedirect(*new_code, *frame_code, frame->pc());
if (FLAG_trace_deopt) {
PrintF("Replacing code %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) "
@@ -1603,8 +1600,8 @@ static void RecompileAndRelocateSuspendedGenerators(
EnsureFunctionHasDebugBreakSlots(fun);
- int code_offset = generators[i]->continuation();
- int pc_offset = ComputePcOffsetFromCodeOffset(fun->code(), code_offset);
+ int index = generators[i]->continuation();
+ int pc_offset = ComputePcOffsetFromContinuationIndex(fun->code(), index);
generators[i]->set_continuation(pc_offset);
}
}
@@ -1726,11 +1723,11 @@ void Debug::PrepareForBreakPoints() {
int pc_offset = gen->continuation();
DCHECK_LT(0, pc_offset);
- int code_offset =
- ComputeCodeOffsetFromPcOffset(fun->code(), pc_offset);
+ int index =
+ ComputeContinuationIndexFromPcOffset(fun->code(), pc_offset);
// This will be fixed after we recompile the functions.
- gen->set_continuation(code_offset);
+ gen->set_continuation(index);
suspended_generators.Add(Handle<JSGeneratorObject>(gen, isolate_));
} else if (obj->IsSharedFunctionInfo()) {
« no previous file with comments | « src/assembler.cc ('k') | src/ia32/assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698