Skip to content

Commit 209d2db

Browse files
zengdageV8 LUCI CQ
authored andcommitted
[riscv] Fix compilation error and disassembling error when enabling the RISC-V C extension
Change-Id: I34a930f7bcda514698ce64d132cbe05fa32b323c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6934163 Reviewed-by: Yahan Lu (LuYahan) <yahan@iscas.ac.cn> Reviewed-by: Kasper Lund <kasperl@rivosinc.com> Commit-Queue: Yahan Lu (LuYahan) <yahan@iscas.ac.cn> Cr-Commit-Position: refs/heads/main@{#102431}
1 parent 401e80c commit 209d2db

2 files changed

Lines changed: 38 additions & 12 deletions

File tree

src/codegen/constant-pool.cc

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -554,11 +554,22 @@ void ConstantPool::EmitAndClear(Jump require_jump) {
554554
EmitPrologue(require_alignment);
555555
if (require_alignment == Alignment::kRequired) assm_->DataAlign(kInt64Size);
556556
EmitEntries();
557+
// Emit padding data to ensure the constant pool size matches the expected
558+
// constant count during disassembly.
559+
if (v8_flags.riscv_c_extension) {
560+
int code_size = assm_->SizeOfCodeGeneratedSince(&size_check);
561+
DCHECK_LE(code_size, size);
562+
563+
while (code_size < size) {
564+
assm_->db(0xcc);
565+
code_size++;
566+
}
567+
}
557568
assm_->RecordComment("]");
558569
assm_->bind(&after_pool);
559570
DEBUG_PRINTF("\tConstant Pool end\n")
560571

561-
DCHECK_LE(assm_->SizeOfCodeGeneratedSince(&size_check) - size, 3);
572+
DCHECK_EQ(size, assm_->SizeOfCodeGeneratedSince(&size_check));
562573
Clear();
563574
}
564575

@@ -666,17 +677,30 @@ bool ConstantPool::ShouldEmitNow(Jump require_jump, size_t margin) const {
666677
int ConstantPool::ComputeSize(Jump require_jump,
667678
Alignment require_alignment) const {
668679
int size_up_to_marker = PrologueSize(require_jump);
669-
int alignment = require_alignment == Alignment::kRequired ? kInstrSize : 0;
680+
// With RVC enabled, constant pool alignment must use kInt64Size to ensure
681+
// sufficient padding space for 8-byte alignment; otherwise, alignment may
682+
// fail.
683+
//
684+
// Example:
685+
// pc_offset = 0x22
686+
// Aligned(0x22, kInt64Size) = 0x28 → 6 bytes of padding needed.
687+
int alignment = require_alignment == Alignment::kRequired
688+
? (v8_flags.riscv_c_extension ? kInt64Size : kInstrSize)
689+
: 0;
670690
size_t size_after_marker =
671691
Entry32Count() * kInt32Size + alignment + Entry64Count() * kInt64Size;
672692
return size_up_to_marker + static_cast<int>(size_after_marker);
673693
}
674694

675695
Alignment ConstantPool::IsAlignmentRequiredIfEmittedAt(Jump require_jump,
676696
int pc_offset) const {
697+
// When the RVC extension is enabled, constant pool entries must be aligned to
698+
// kInstrSize to prevent unaligned 32-bit memory accesses.
677699
int size_up_to_marker = PrologueSize(require_jump);
678-
if (Entry64Count() != 0 &&
679-
!IsAligned(pc_offset + size_up_to_marker, kInt64Size)) {
700+
if ((Entry64Count() != 0 &&
701+
!IsAligned(pc_offset + size_up_to_marker, kInt64Size)) ||
702+
(Entry32Count() != 0 && v8_flags.riscv_c_extension &&
703+
!IsAligned(pc_offset + size_up_to_marker, kInstrSize))) {
680704
return Alignment::kRequired;
681705
}
682706
return Alignment::kOmitted;

src/codegen/riscv/macro-assembler-riscv.cc

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5470,24 +5470,22 @@ void MacroAssembler::StoreReturnAddressAndCall(Register target) {
54705470
// trigger GC, since the callee function will return to it.
54715471

54725472
Assembler::BlockTrampolinePoolScope block_trampoline_pool(this);
5473-
int kNumInstructions = v8_flags.riscv_c_extension ? 5 : 6;
5474-
Label start;
5473+
Label start, end;
54755474

54765475
// Make 'ra' point to the correct return location, just after the 'jalr t6'
54775476
// instruction that does the call, and store 'ra' at the top of the stack.
54785477
bind(&start);
5479-
auipc(ra, 0); // Set 'ra' the current 'pc'.
5480-
AddWord(ra, ra, kNumInstructions * kInstrSize);
5478+
LoadAddress(ra, &end);
54815479
StoreWord(ra, MemOperand(sp)); // Reserved in EnterExitFrame.
54825480
AddWord(sp, sp, -kCArgsSlotsSize); // Preserves stack alignment.
54835481

54845482
// Call the C routine.
54855483
Mv(t6, target); // Function pointer in 't6' to conform to ABI for PIC.
54865484
jalr(t6);
54875485

5488-
// Make sure the stored 'ra' points to this position. This way, the 'ra'
5489-
// value we stored on the stack matches the value of 'ra' during the call.
5490-
DCHECK_EQ(kNumInstructions, InstructionsGeneratedSince(&start));
5486+
// The 'ra' value we stored on the stack matches the value of 'ra' during the
5487+
// call.
5488+
bind(&end);
54915489
}
54925490

54935491
void MacroAssembler::Ret(Condition cond, Register rs, const Operand& rt) {
@@ -7458,7 +7456,11 @@ int MacroAssembler::CallCFunctionHelper(
74587456
AddWord(sp, sp, Operand(stack_passed_arguments * kSystemPointerSize));
74597457
}
74607458
if (kMaxSizeOfMoveAfterFastCall > pc_offset() - before_offset) {
7461-
nop();
7459+
// If the RCV extension is enabled, we may have to emit multiple NOPs to
7460+
// have enough space for patching in the deopt trampoline.
7461+
do {
7462+
NOP();
7463+
} while (pc_offset() - before_offset != kMaxSizeOfMoveAfterFastCall);
74627464
}
74637465
// We assume that with the nop padding, the move instruction uses
74647466
// kMaxSizeOfMoveAfterFastCall bytes. When we patch in the deopt trampoline,

0 commit comments

Comments
 (0)