Skip to content

'maximum recursion depth exceeded' while finalizing a large function #74

@eliben

Description

@eliben

I'm generating a fairly large function using PeachPy (compiling from another language). When the function has a large number of labels it seems that the finalization invoked when RETURN is called is blowing the Python style.

Part of the stack trace:

  File "function.py", line 549, in analyze_reachability
    output_block.analyze_reachability()
  File "function.py", line 549, in analyze_reachability
    output_block.analyze_reachability()
  File "function.py", line 549, in analyze_reachability
    output_block.analyze_reachability()
  File "function.py", line 549, in analyze_reachability
    output_block.analyze_reachability()

FWIW I'm not even using the register allocation features, all my registers are managed manually. A silly reproducer below:

import peachpy
import peachpy.x86_64

x = peachpy.Argument(peachpy.int64_t)
y = peachpy.Argument(peachpy.int64_t)

with peachpy.x86_64.Function("Times", (x, y), peachpy.int64_t) as asm_function:
    reg_x = peachpy.x86_64.rax
    reg_y = peachpy.x86_64.rbx
    reg_accum = peachpy.x86_64.rcx

    peachpy.x86_64.LOAD.ARGUMENT(reg_x, x)
    peachpy.x86_64.LOAD.ARGUMENT(reg_y, y)
    peachpy.x86_64.MOV(reg_accum, 0)

    for i in range(1000):
      loop_start_label = peachpy.x86_64.Label('loop_start{}'.format(i))
      loop_end_label = peachpy.x86_64.Label('loop_end{}'.format(i))

      peachpy.x86_64.CMP(reg_y, 0)
      peachpy.x86_64.JE(loop_end_label)
      peachpy.x86_64.LABEL(loop_start_label)      # bind the label
      peachpy.x86_64.ADD(reg_accum, reg_x)
      peachpy.x86_64.SUB(reg_y, 1)
      peachpy.x86_64.JG(loop_start_label)
      peachpy.x86_64.LABEL(loop_end_label)        # bind the label

    peachpy.x86_64.RETURN(reg_accum)

abi = peachpy.x86_64.abi.detect()
encoded_function = asm_function.finalize(abi).encode()
python_function = encoded_function.load()

print(encoded_function.format())
code = python_function.code_segment

fname = '/tmp/ppout.bin'
with open(fname, 'wb') as f:
    f.write(code)

print('Wrote code to file [{0}]: {1}'.format(fname, code))

# The JIT call
print(python_function(3, 4))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions