@@ -1436,56 +1436,58 @@ static void CollectActiveFunctionsFromThread(
14361436}
14371437
14381438
1439- // Figure out how many bytes of "pc_offset" correspond to actual code by
1440- // subtracting off the bytes that correspond to constant/veneer pools. See
1441- // Assembler::CheckConstPool() and Assembler::CheckVeneerPool(). Note that this
1442- // is only useful for architectures using constant pools or veneer pools.
1443- static int ComputeCodeOffsetFromPcOffset (Code *code, int pc_offset) {
1439+ // Count the number of calls before the current frame PC to find the
1440+ // corresponding PC in the newly recompiled code.
1441+ static Address ComputeNewPcForRedirect (Code* new_code, Code* old_code,
1442+ Address old_pc) {
1443+ DCHECK_EQ (old_code->kind (), Code::FUNCTION );
1444+ DCHECK_EQ (new_code->kind (), Code::FUNCTION );
1445+ DCHECK (!old_code->has_debug_break_slots ());
1446+ DCHECK (new_code->has_debug_break_slots ());
1447+ int mask = RelocInfo::kCodeTargetMask ;
1448+ int index = 0 ;
1449+ intptr_t delta = 0 ;
1450+ for (RelocIterator it (old_code, mask); !it.done (); it.next ()) {
1451+ RelocInfo* rinfo = it.rinfo ();
1452+ Address current_pc = rinfo->pc ();
1453+ // The frame PC is behind the call instruction by the call instruction size.
1454+ if (current_pc > old_pc) break ;
1455+ index++;
1456+ delta = old_pc - current_pc;
1457+ }
1458+
1459+ RelocIterator it (new_code, mask);
1460+ for (int i = 1 ; i < index; i++) it.next ();
1461+ return it.rinfo ()->pc () + delta;
1462+ }
1463+
1464+
1465+ // Count the number of continuations at which the current pc offset is at.
1466+ static int ComputeContinuationIndexFromPcOffset (Code* code, int pc_offset) {
14441467 DCHECK_EQ (code->kind (), Code::FUNCTION );
14451468 DCHECK (!code->has_debug_break_slots ());
1446- DCHECK_LE (0 , pc_offset);
1447- DCHECK_LT (pc_offset, code->instruction_end () - code->instruction_start ());
1448-
1449- int mask = RelocInfo::ModeMask (RelocInfo::CONST_POOL ) |
1450- RelocInfo::ModeMask (RelocInfo::VENEER_POOL );
1451- byte *pc = code->instruction_start () + pc_offset;
1452- int code_offset = pc_offset;
1469+ Address pc = code->instruction_start () + pc_offset;
1470+ int mask = RelocInfo::ModeMask (RelocInfo::GENERATOR_CONTINUATION );
1471+ int index = 0 ;
14531472 for (RelocIterator it (code, mask); !it.done (); it.next ()) {
1454- RelocInfo* info = it. rinfo () ;
1455- if (info-> pc () >= pc) break ;
1456- DCHECK ( RelocInfo::IsConstPool (info-> rmode ()) );
1457- code_offset -= static_cast < int >(info-> data ()) ;
1458- DCHECK_LE ( 0 , code_offset );
1473+ index++ ;
1474+ RelocInfo* rinfo = it. rinfo () ;
1475+ Address current_pc = rinfo-> pc ( );
1476+ if (current_pc == pc) break ;
1477+ DCHECK (current_pc < pc );
14591478 }
1460-
1461- return code_offset;
1479+ return index;
14621480}
14631481
14641482
1465- // The inverse of ComputeCodeOffsetFromPcOffset .
1466- static int ComputePcOffsetFromCodeOffset (Code * code, int code_offset ) {
1483+ // Find the pc offset for the given continuation index .
1484+ static int ComputePcOffsetFromContinuationIndex (Code* code, int index ) {
14671485 DCHECK_EQ (code->kind (), Code::FUNCTION );
1468-
1469- int mask = RelocInfo::kDebugBreakSlotMask |
1470- RelocInfo::ModeMask (RelocInfo::CONST_POOL ) |
1471- RelocInfo::ModeMask (RelocInfo::VENEER_POOL );
1472- int reloc = 0 ;
1473- for (RelocIterator it (code, mask); !it.done (); it.next ()) {
1474- RelocInfo* info = it.rinfo ();
1475- if (info->pc () - code->instruction_start () - reloc >= code_offset) break ;
1476- if (RelocInfo::IsDebugBreakSlot (info->rmode ())) {
1477- reloc += Assembler::kDebugBreakSlotLength ;
1478- } else {
1479- DCHECK (RelocInfo::IsConstPool (info->rmode ()));
1480- reloc += static_cast <int >(info->data ());
1481- }
1482- }
1483-
1484- int pc_offset = code_offset + reloc;
1485-
1486- DCHECK_LT (code->instruction_start () + pc_offset, code->instruction_end ());
1487-
1488- return pc_offset;
1486+ DCHECK (code->has_debug_break_slots ());
1487+ int mask = RelocInfo::ModeMask (RelocInfo::GENERATOR_CONTINUATION );
1488+ RelocIterator it (code, mask);
1489+ for (int i = 1 ; i < index; i++) it.next ();
1490+ return static_cast <int >(it.rinfo ()->pc () - code->instruction_start ());
14891491}
14901492
14911493
@@ -1510,13 +1512,8 @@ static void RedirectActivationsToRecompiledCodeOnThread(
15101512 continue ;
15111513 }
15121514
1513- int old_pc_offset =
1514- static_cast <int >(frame->pc () - frame_code->instruction_start ());
1515- int code_offset = ComputeCodeOffsetFromPcOffset (*frame_code, old_pc_offset);
1516- int new_pc_offset = ComputePcOffsetFromCodeOffset (*new_code, code_offset);
1517-
1518- // Compute the equivalent pc in the new code.
1519- byte* new_pc = new_code->instruction_start () + new_pc_offset;
1515+ Address new_pc =
1516+ ComputeNewPcForRedirect (*new_code, *frame_code, frame->pc ());
15201517
15211518 if (FLAG_trace_deopt) {
15221519 PrintF (" Replacing code %08" V8PRIxPTR " - %08" V8PRIxPTR " (%d) "
@@ -1603,8 +1600,8 @@ static void RecompileAndRelocateSuspendedGenerators(
16031600
16041601 EnsureFunctionHasDebugBreakSlots (fun);
16051602
1606- int code_offset = generators[i]->continuation ();
1607- int pc_offset = ComputePcOffsetFromCodeOffset (fun->code (), code_offset );
1603+ int index = generators[i]->continuation ();
1604+ int pc_offset = ComputePcOffsetFromContinuationIndex (fun->code (), index );
16081605 generators[i]->set_continuation (pc_offset);
16091606 }
16101607}
@@ -1726,11 +1723,11 @@ void Debug::PrepareForBreakPoints() {
17261723 int pc_offset = gen->continuation ();
17271724 DCHECK_LT (0 , pc_offset);
17281725
1729- int code_offset =
1730- ComputeCodeOffsetFromPcOffset (fun->code (), pc_offset);
1726+ int index =
1727+ ComputeContinuationIndexFromPcOffset (fun->code (), pc_offset);
17311728
17321729 // This will be fixed after we recompile the functions.
1733- gen->set_continuation (code_offset );
1730+ gen->set_continuation (index );
17341731
17351732 suspended_generators.Add (Handle<JSGeneratorObject>(gen, isolate_));
17361733 } else if (obj->IsSharedFunctionInfo ()) {
0 commit comments