1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
import py
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from rpython.rlib.jit_hooks import LOOP_RUN_CONTAINER
from rpython.rlib import rgc
from rpython.jit.backend.x86.assembler import Assembler386
from rpython.jit.backend.x86.regalloc import gpr_reg_mgr_cls, xmm_reg_mgr_cls
from rpython.jit.backend.x86.profagent import ProfileAgent
from rpython.jit.backend.llsupport.llmodel import AbstractLLCPU
from rpython.jit.backend.x86 import regloc
import sys
from rpython.tool.ansi_print import ansi_log
log = py.log.Producer('jitbackend')
py.log.setconsumer('jitbackend', ansi_log)
class AbstractX86CPU(AbstractLLCPU):
debug = True
supports_floats = True
supports_singlefloats = True
dont_keepalive_stuff = False # for tests
with_threads = False
frame_reg = regloc.ebp
from rpython.jit.backend.x86.arch import JITFRAME_FIXED_SIZE
all_reg_indexes = gpr_reg_mgr_cls.all_reg_indexes
gen_regs = gpr_reg_mgr_cls.all_regs
float_regs = xmm_reg_mgr_cls.all_regs
def __init__(self, rtyper, stats, opts=None, translate_support_code=False,
gcdescr=None):
AbstractLLCPU.__init__(self, rtyper, stats, opts,
translate_support_code, gcdescr)
profile_agent = ProfileAgent()
if rtyper is not None:
config = rtyper.annotator.translator.config
if config.translation.jit_profiler == "oprofile":
from rpython.jit.backend.x86 import oprofile
if not oprofile.OPROFILE_AVAILABLE:
log.WARNING('oprofile support was explicitly enabled, but oprofile headers seem not to be available')
profile_agent = oprofile.OProfileAgent()
self.with_threads = config.translation.thread
self.profile_agent = profile_agent
def set_debug(self, flag):
return self.assembler.set_debug(flag)
def get_failargs_limit(self):
if self.opts is not None:
return self.opts.failargs_limit
else:
return 1000
def setup(self):
self.assembler = Assembler386(self, self.translate_support_code)
def build_regalloc(self):
''' for tests'''
from rpython.jit.backend.x86.regalloc import RegAlloc
assert self.assembler is not None
return RegAlloc(self.assembler, False)
@rgc.no_release_gil
def setup_once(self):
self.profile_agent.startup()
self.assembler.setup_once()
@rgc.no_release_gil
def finish_once(self):
self.assembler.finish_once()
self.profile_agent.shutdown()
def dump_loop_token(self, looptoken):
"""
NOT_RPYTHON
"""
from rpython.jit.backend.x86.tool.viewcode import machine_code_dump
data = []
label_list = [(offset, name) for name, offset in
looptoken._x86_ops_offset.iteritems()]
label_list.sort()
addr = looptoken._x86_rawstart
src = rffi.cast(rffi.CCHARP, addr)
for p in range(looptoken._x86_fullsize):
data.append(src[p])
data = ''.join(data)
lines = machine_code_dump(data, addr, self.backend_name, label_list)
print ''.join(lines)
def compile_loop(self, inputargs, operations, looptoken, log=True,
name='', logger=None):
return self.assembler.assemble_loop(inputargs, operations, looptoken, log,
name, logger)
def compile_bridge(self, faildescr, inputargs, operations,
original_loop_token, log=True, logger=None):
clt = original_loop_token.compiled_loop_token
clt.compiling_a_bridge()
return self.assembler.assemble_bridge(faildescr, inputargs, operations,
original_loop_token, log, logger)
def clear_latest_values(self, count):
setitem = self.assembler.fail_boxes_ptr.setitem
null = lltype.nullptr(llmemory.GCREF.TO)
for index in range(count):
setitem(index, null)
def cast_ptr_to_int(x):
adr = llmemory.cast_ptr_to_adr(x)
return CPU386.cast_adr_to_int(adr)
cast_ptr_to_int._annspecialcase_ = 'specialize:arglltype(0)'
cast_ptr_to_int = staticmethod(cast_ptr_to_int)
def redirect_call_assembler(self, oldlooptoken, newlooptoken):
self.assembler.redirect_call_assembler(oldlooptoken, newlooptoken)
def invalidate_loop(self, looptoken):
from rpython.jit.backend.x86 import codebuf
for addr, tgt in looptoken.compiled_loop_token.invalidate_positions:
mc = codebuf.MachineCodeBlockWrapper()
mc.JMP_l(tgt)
assert mc.get_relative_pos() == 5 # [JMP] [tgt 4 bytes]
mc.copy_to_raw_memory(addr - 1)
# positions invalidated
looptoken.compiled_loop_token.invalidate_positions = []
def get_all_loop_runs(self):
l = lltype.malloc(LOOP_RUN_CONTAINER,
len(self.assembler.loop_run_counters))
for i, ll_s in enumerate(self.assembler.loop_run_counters):
l[i].type = ll_s.type
l[i].number = ll_s.number
l[i].counter = ll_s.i
return l
class CPU386(AbstractX86CPU):
backend_name = 'x86'
NUM_REGS = 8
CALLEE_SAVE_REGISTERS = [regloc.ebx, regloc.esi, regloc.edi]
supports_longlong = True
IS_64_BIT = False
def __init__(self, *args, **kwargs):
assert sys.maxint == (2**31 - 1)
super(CPU386, self).__init__(*args, **kwargs)
class CPU386_NO_SSE2(CPU386):
supports_floats = False
supports_longlong = False
class CPU_X86_64(AbstractX86CPU):
backend_name = 'x86_64'
NUM_REGS = 16
CALLEE_SAVE_REGISTERS = [regloc.ebx, regloc.r12, regloc.r13, regloc.r14, regloc.r15]
IS_64_BIT = True
CPU = CPU386
|