Skip to content

Commit 2d54d73

Browse files
committed
Merge branch 'perf/avoid-location-revalidation' into perf/avoid-dis-location-overhead
2 parents 483c683 + 7b483f5 commit 2d54d73

2 files changed

Lines changed: 45 additions & 5 deletions

File tree

src/bytecode/concrete.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,9 @@ def _assemble_locations(
577577

578578
_, size, lineno, old_location = next(iter_in)
579579
# Infer the line if location is None
580-
old_location = old_location or InstrLocation(lineno, None, None, None)
580+
old_location = old_location or InstrLocation._from_tuple(
581+
lineno, None, None, None
582+
)
581583
lineno = first_lineno
582584

583585
# We track the last set lineno to be able to compute deltas
@@ -932,14 +934,18 @@ def to_bytecode(
932934
else:
933935
arg = c_arg
934936

935-
location = c_instr.location or InstrLocation(lineno, None, None, None)
937+
location = c_instr.location or InstrLocation._from_tuple(
938+
lineno, None, None, None
939+
)
936940

937941
if jump_target is not None:
938942
arg = PLACEHOLDER_LABEL
939943
instr_index = len(instructions)
940944
jumps.append((instr_index, jump_target))
941945

942-
instructions.append(Instr(c_instr.name, arg, location=location))
946+
instructions.append(
947+
Instr._from_trusted(c_instr._name, c_instr._opcode, arg, location)
948+
)
943949

944950
# We now insert the TryEnd entries
945951
if current_instr_offset in ex_end:
@@ -1032,7 +1038,9 @@ def add(names: list[str], name: str) -> int:
10321038
return index
10331039

10341040
def concrete_instructions(self) -> None:
1035-
location = InstrLocation(self.bytecode.first_lineno, None, None, None)
1041+
location = InstrLocation._from_tuple(
1042+
self.bytecode.first_lineno, None, None, None
1043+
)
10361044
# Track instruction (index) using cell vars and free vars to be able to update
10371045
# the index used once all the names are known.
10381046
cell_instrs: list[int] = []
@@ -1088,7 +1096,7 @@ def concrete_instructions(self) -> None:
10881096
continue
10891097

10901098
if isinstance(instr, SetLineno):
1091-
location = InstrLocation(instr.lineno, None, None, None)
1099+
location = InstrLocation._from_tuple(instr.lineno, None, None, None)
10921100
continue
10931101

10941102
if isinstance(instr, TryBegin):

src/bytecode/instr.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,22 @@ def from_positions(cls, position: dis.Positions) -> InstrLocation: # type: igno
621621
position.end_col_offset,
622622
)
623623

624+
@classmethod
625+
def _from_tuple(
626+
cls,
627+
lineno: Optional[int],
628+
end_lineno: Optional[int],
629+
col_offset: Optional[int],
630+
end_col_offset: Optional[int],
631+
) -> InstrLocation:
632+
"""Fast path for trusted position data (e.g. from co_positions())."""
633+
new = object.__new__(cls)
634+
object.__setattr__(new, "lineno", lineno)
635+
object.__setattr__(new, "end_lineno", end_lineno)
636+
object.__setattr__(new, "col_offset", col_offset)
637+
object.__setattr__(new, "end_col_offset", end_col_offset)
638+
return new
639+
624640

625641
class SetLineno:
626642
__slots__ = ("_lineno",)
@@ -819,6 +835,22 @@ def copy(self: T) -> T:
819835
new._location = self._location
820836
return new
821837

838+
@classmethod
839+
def _from_trusted(
840+
cls: type[T],
841+
name: str,
842+
opcode: int,
843+
arg: A,
844+
location: Optional[InstrLocation],
845+
) -> T:
846+
"""Fast path for internal construction from already-validated data."""
847+
new = object.__new__(cls)
848+
new._name = name
849+
new._opcode = opcode
850+
new._arg = arg
851+
new._location = location
852+
return new
853+
822854
def has_jump(self) -> bool:
823855
return self._has_jump(self._opcode)
824856

0 commit comments

Comments
 (0)