MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / handle_fixup

Method handle_fixup

cranelift/codegen/src/machinst/buffer.rs:1496–1559  ·  view source on GitHub ↗
(
        &mut self,
        fixup: MachLabelFixup<I>,
        force_veneers: ForceVeneers,
        forced_threshold: CodeOffset,
    )

Source from the content-addressed store, hash-verified

1494 }
1495
1496 fn handle_fixup(
1497 &mut self,
1498 fixup: MachLabelFixup<I>,
1499 force_veneers: ForceVeneers,
1500 forced_threshold: CodeOffset,
1501 ) {
1502 let MachLabelFixup {
1503 label,
1504 offset,
1505 kind,
1506 } = fixup;
1507 let start = offset as usize;
1508 let end = (offset + kind.patch_size()) as usize;
1509 let label_offset = self.resolve_label_offset(label);
1510
1511 if label_offset != UNKNOWN_LABEL_OFFSET {
1512 // If the offset of the label for this fixup is known then
1513 // we're going to do something here-and-now. We're either going
1514 // to patch the original offset because it's an in-bounds jump,
1515 // or we're going to generate a veneer, patch the fixup to jump
1516 // to the veneer, and then keep going.
1517 //
1518 // If the label comes after the original fixup, then we should
1519 // be guaranteed that the jump is in-bounds. Otherwise there's
1520 // a bug somewhere because this method wasn't called soon
1521 // enough. All forward-jumps are tracked and should get veneers
1522 // before their deadline comes and they're unable to jump
1523 // further.
1524 //
1525 // Otherwise if the label is before the fixup, then that's a
1526 // backwards jump. If it's past the maximum negative range
1527 // then we'll emit a veneer that to jump forward to which can
1528 // then jump backwards.
1529 let veneer_required = if label_offset >= offset {
1530 assert!((label_offset - offset) <= kind.max_pos_range());
1531 false
1532 } else {
1533 (offset - label_offset) > kind.max_neg_range()
1534 };
1535 trace!(
1536 " -> label_offset = {}, known, required = {} (pos {} neg {})",
1537 label_offset,
1538 veneer_required,
1539 kind.max_pos_range(),
1540 kind.max_neg_range()
1541 );
1542
1543 if (force_veneers == ForceVeneers::Yes && kind.supports_veneer()) || veneer_required {
1544 self.emit_veneer(label, offset, kind);
1545 } else {
1546 let slice = &mut self.data[start..end];
1547 trace!(
1548 "patching in-range! slice = {slice:?}; offset = {offset:#x}; label_offset = {label_offset:#x}"
1549 );
1550 kind.patch(slice, offset, label_offset);
1551 }
1552 } else {
1553 // If the offset of this label is not known at this time then

Callers 1

Calls 6

resolve_label_offsetMethod · 0.80
emit_veneerMethod · 0.80
patch_sizeMethod · 0.45
max_neg_rangeMethod · 0.45
supports_veneerMethod · 0.45
patchMethod · 0.45

Tested by

no test coverage detected