@@ -4728,8 +4728,9 @@ void MacroAssembler::LoadAddressPCRelative(Register dst, Label* target) {
47284728 // daddiu could handle 16-bit pc offset.
47294729 int32_t offset = branch_offset_helper (target, OffsetSize::kOffset16 );
47304730 DCHECK (is_int16 (offset));
4731- mov (t8, ra);
4732- daddiu (dst, ra, offset);
4731+ mov (t8, ra); // Delay slot and pc base address
4732+ daddiu (dst, ra, offset); // Address that ra really points to
4733+ daddiu (dst, dst, -kInstrSize ); // Fix offset computed based on ra
47334734 mov (ra, t8);
47344735}
47354736
@@ -6265,27 +6266,40 @@ int MacroAssembler::CallCFunctionHelper(
62656266 Sd (fp, ExternalReferenceAsOperand (IsolateFieldId::kFastCCallCallerFP ));
62666267 }
62676268
6268- Call (function);
6269- int call_pc_offset = pc_offset ();
6270- bind (&get_pc);
6269+ int call_pc_offset;
6270+ {
6271+ BlockTrampolinePoolScope block_trampoline_pool (this );
6272+ Call (function);
6273+ call_pc_offset = pc_offset ();
6274+ bind (&get_pc);
6275+ if (return_location) bind (return_location);
6276+
6277+ int before_offset = pc_offset ();
6278+ int stack_passed_arguments =
6279+ CalculateStackPassedWords (num_reg_arguments, num_double_arguments);
6280+
6281+ if (base::OS::ActivationFrameAlignment () > kSystemPointerSize ) {
6282+ Ld (sp, MemOperand (sp, stack_passed_arguments * kSystemPointerSize ));
6283+ } else {
6284+ Daddu (sp, sp, Operand (stack_passed_arguments * kSystemPointerSize ));
6285+ }
62716286
6272- if (return_location) bind (return_location);
6287+ if (kMaxSizeOfMoveAfterFastCall > pc_offset () - before_offset) {
6288+ nop ();
6289+ }
6290+ // We assume that with the nop padding, the move instruction uses
6291+ // kMaxSizeOfMoveAfterFastCall bytes. When we patch in the deopt
6292+ // trampoline, we patch it in after the move instruction, so that the
6293+ // stack has been restored correctly.
6294+ CHECK_EQ (kMaxSizeOfMoveAfterFastCall , pc_offset () - before_offset);
6295+ }
62736296
62746297 if (set_isolate_data_slots == SetIsolateDataSlots::kYes ) {
62756298 // We don't unset the PC; the FP is the source of truth.
62766299 Sd (zero_reg,
62776300 ExternalReferenceAsOperand (IsolateFieldId::kFastCCallCallerFP ));
62786301 }
62796302
6280- int stack_passed_arguments =
6281- CalculateStackPassedWords (num_reg_arguments, num_double_arguments);
6282-
6283- if (base::OS::ActivationFrameAlignment () > kPointerSize ) {
6284- Ld (sp, MemOperand (sp, stack_passed_arguments * kPointerSize ));
6285- } else {
6286- Daddu (sp, sp, Operand (stack_passed_arguments * kPointerSize ));
6287- }
6288-
62896303 set_pc_for_safepoint ();
62906304
62916305 return call_pc_offset;
0 commit comments