| Index: src/debug.cc
|
| diff --git a/src/debug.cc b/src/debug.cc
|
| index e6365289fdec37e10afa0496054d73099dcaae9a..38d9f47f29d186a41e6d4d225fb1fd2369e6a4f6 100644
|
| --- a/src/debug.cc
|
| +++ b/src/debug.cc
|
| @@ -1311,13 +1311,10 @@ void Debug::ClearStepNext() {
|
| }
|
|
|
|
|
| -// We start counting call sites from the stack check because the declaration
|
| -// code at the start of the function may have changed on recompile.
|
| -static void SkipToStackCheck(Isolate* isolate, RelocIterator* it) {
|
| - while (Code::GetCodeFromTargetAddress(it->rinfo()->target_address()) !=
|
| - *isolate->builtins()->StackCheck()) {
|
| - it->next();
|
| - }
|
| +bool MatchingCodeTargets(Code* target1, Code* target2) {
|
| + if (target1 == target2) return true;
|
| + if (target1->kind() != target2->kind()) return false;
|
| + return target1->is_handler() || target1->is_inline_cache_stub();
|
| }
|
|
|
|
|
| @@ -1328,24 +1325,42 @@ static Address ComputeNewPcForRedirect(Code* new_code, Code* old_code,
|
| DCHECK_EQ(old_code->kind(), Code::FUNCTION);
|
| DCHECK_EQ(new_code->kind(), Code::FUNCTION);
|
| DCHECK(new_code->has_debug_break_slots());
|
| - int mask = RelocInfo::kCodeTargetMask;
|
| - int index = 0;
|
| + static const int mask = RelocInfo::kCodeTargetMask;
|
| +
|
| + // Find the target of the current call.
|
| + Code* target = NULL;
|
| intptr_t delta = 0;
|
| - Isolate* isolate = new_code->GetIsolate();
|
| - RelocIterator old_it(old_code, mask);
|
| - for (SkipToStackCheck(isolate, &old_it); !old_it.done(); old_it.next()) {
|
| - RelocInfo* rinfo = old_it.rinfo();
|
| + 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;
|
| + target = Code::GetCodeFromTargetAddress(rinfo->target_address());
|
| + }
|
| +
|
| + // Count the number of calls to the same target before the current call.
|
| + int index = 0;
|
| + for (RelocIterator it(old_code, mask); !it.done(); it.next()) {
|
| + RelocInfo* rinfo = it.rinfo();
|
| + Address current_pc = rinfo->pc();
|
| + if (current_pc > old_pc) break;
|
| + Code* current = Code::GetCodeFromTargetAddress(rinfo->target_address());
|
| + if (MatchingCodeTargets(target, current)) index++;
|
| + }
|
| +
|
| + DCHECK(index > 0);
|
| +
|
| + // Repeat the count on the new code to find corresponding call.
|
| + for (RelocIterator it(new_code, mask); !it.done(); it.next()) {
|
| + RelocInfo* rinfo = it.rinfo();
|
| + Code* current = Code::GetCodeFromTargetAddress(rinfo->target_address());
|
| + if (MatchingCodeTargets(target, current)) index--;
|
| + if (index == 0) return rinfo->pc() + delta;
|
| }
|
|
|
| - RelocIterator new_it(new_code, mask);
|
| - SkipToStackCheck(isolate, &new_it);
|
| - for (int i = 1; i < index; i++) new_it.next();
|
| - return new_it.rinfo()->pc() + delta;
|
| + UNREACHABLE();
|
| + return NULL;
|
| }
|
|
|
|
|
|
|