Author: Maciej Fijalkowski <[email protected]>
Branch: jitframe-on-heap
Changeset: r60105:0722c7563762
Date: 2013-01-16 00:54 +0200
http://bitbucket.org/pypy/pypy/changeset/0722c7563762/
Log: die in fire!!!!
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -228,196 +228,6 @@
# All code below is for the hybrid or minimark GC
-class GcRootMap_asmgcc(object):
- """Handles locating the stack roots in the assembler.
- This is the class supporting --gcrootfinder=asmgcc.
- """
- is_shadow_stack = False
- is_64_bit = (WORD == 8)
-
- LOC_REG = 0
- LOC_ESP_PLUS = 1
- LOC_EBP_PLUS = 2
- LOC_EBP_MINUS = 3
-
- GCMAP_ARRAY = rffi.CArray(lltype.Signed)
- CALLSHAPE_ARRAY_PTR = rffi.CArrayPtr(rffi.UCHAR)
-
- def __init__(self, gcdescr=None):
- # '_gcmap' is an array of length '_gcmap_maxlength' of addresses.
- # '_gcmap_curlength' tells how full the array really is.
- # The addresses are actually grouped in pairs:
- # (addr-after-the-CALL-in-assembler, addr-of-the-call-shape).
- # '_gcmap_deadentries' counts pairs marked dead (2nd item is NULL).
- # '_gcmap_sorted' is True only if we know the array is sorted.
- self._gcmap = lltype.nullptr(self.GCMAP_ARRAY)
- self._gcmap_curlength = 0
- self._gcmap_maxlength = 0
- self._gcmap_deadentries = 0
- self._gcmap_sorted = True
-
- def add_jit2gc_hooks(self, jit2gc):
- jit2gc.update({
- 'gcmapstart': lambda: self.gcmapstart(),
- 'gcmapend': lambda: self.gcmapend(),
- 'gcmarksorted': lambda: self.gcmarksorted(),
- })
-
- def initialize(self):
- # hack hack hack. Remove these lines and see MissingRTypeAttribute
- # when the rtyper tries to annotate these methods only when GC-ing...
- self.gcmapstart()
- self.gcmapend()
- self.gcmarksorted()
-
- def gcmapstart(self):
- return rffi.cast(llmemory.Address, self._gcmap)
-
- def gcmapend(self):
- addr = self.gcmapstart()
- if self._gcmap_curlength:
- addr += rffi.sizeof(lltype.Signed) * self._gcmap_curlength
- if not we_are_translated() and type(addr) is long:
- from pypy.rpython.lltypesystem import ll2ctypes
- addr = ll2ctypes._lladdress(addr) # XXX workaround
- return addr
-
- def gcmarksorted(self):
- # Called by the GC when it is about to sort [gcmapstart():gcmapend()].
- # Returns the previous sortedness flag -- i.e. returns True if it
- # is already sorted, False if sorting is needed.
- sorted = self._gcmap_sorted
- self._gcmap_sorted = True
- return sorted
-
- def put(self, retaddr, callshapeaddr):
- """'retaddr' is the address just after the CALL.
- 'callshapeaddr' is the address of the raw 'shape' marker.
- Both addresses are actually integers here."""
- index = self._gcmap_curlength
- if index + 2 > self._gcmap_maxlength:
- index = self._enlarge_gcmap()
- self._gcmap[index] = retaddr
- self._gcmap[index+1] = callshapeaddr
- self._gcmap_curlength = index + 2
- self._gcmap_sorted = False
-
- @rgc.no_collect
- def _enlarge_gcmap(self):
- oldgcmap = self._gcmap
- if self._gcmap_deadentries * 3 * 2 > self._gcmap_maxlength:
- # More than 1/3rd of the entries are dead. Don't actually
- # enlarge the gcmap table, but just clean up the dead entries.
- newgcmap = oldgcmap
- else:
- # Normal path: enlarge the array.
- newlength = 250 + (self._gcmap_maxlength // 3) * 4
- newgcmap = lltype.malloc(self.GCMAP_ARRAY, newlength, flavor='raw',
- track_allocation=False)
- self._gcmap_maxlength = newlength
- #
- j = 0
- i = 0
- end = self._gcmap_curlength
- while i < end:
- if oldgcmap[i + 1]:
- newgcmap[j] = oldgcmap[i]
- newgcmap[j + 1] = oldgcmap[i + 1]
- j += 2
- i += 2
- self._gcmap_curlength = j
- self._gcmap_deadentries = 0
- if oldgcmap != newgcmap:
- self._gcmap = newgcmap
- if oldgcmap:
- lltype.free(oldgcmap, flavor='raw', track_allocation=False)
- return j
-
- @rgc.no_collect
- def freeing_block(self, start, stop):
- # if [start:stop] is a raw block of assembler, then look up the
- # corresponding gcroot markers, and mark them as freed now in
- # self._gcmap by setting the 2nd address of every entry to NULL.
- gcmapstart = self.gcmapstart()
- gcmapend = self.gcmapend()
- if gcmapstart == gcmapend:
- return
- if not self.gcmarksorted():
- asmgcroot.sort_gcmap(gcmapstart, gcmapend)
- # A note about gcmarksorted(): the deletion we do here keeps the
- # array sorted. This avoids needing too many sort_gcmap()s.
- # Indeed, freeing_block() is typically called many times in a row,
- # so it will call sort_gcmap() at most the first time.
- startaddr = rffi.cast(llmemory.Address, start)
- stopaddr = rffi.cast(llmemory.Address, stop)
- item = asmgcroot.binary_search(gcmapstart, gcmapend, startaddr)
- # 'item' points to one of the entries. Because the whole array
- # is sorted, we know that it points either to the first entry we
- # want to kill, or to the previous entry.
- if item.address[0] < startaddr:
- item += asmgcroot.arrayitemsize # go forward one entry
- assert item == gcmapend or item.address[0] >= startaddr
- while item != gcmapend and item.address[0] < stopaddr:
- item.address[1] = llmemory.NULL
- self._gcmap_deadentries += 1
- item += asmgcroot.arrayitemsize
-
- def get_basic_shape(self):
- # XXX: Should this code even really know about stack frame layout of
- # the JIT?
- if self.is_64_bit:
- return [chr(self.LOC_EBP_PLUS | 4), # return addr: at 8(%rbp)
- chr(self.LOC_EBP_MINUS | 4), # saved %rbx: at -8(%rbp)
- chr(self.LOC_EBP_MINUS | 8), # saved %r12: at -16(%rbp)
- chr(self.LOC_EBP_MINUS | 12), # saved %r13: at -24(%rbp)
- chr(self.LOC_EBP_MINUS | 16), # saved %r14: at -32(%rbp)
- chr(self.LOC_EBP_MINUS | 20), # saved %r15: at -40(%rbp)
- chr(self.LOC_EBP_PLUS | 0), # saved %rbp: at (%rbp)
- chr(0)]
- else:
- return [chr(self.LOC_EBP_PLUS | 4), # return addr: at 4(%ebp)
- chr(self.LOC_EBP_MINUS | 4), # saved %ebx: at -4(%ebp)
- chr(self.LOC_EBP_MINUS | 8), # saved %esi: at -8(%ebp)
- chr(self.LOC_EBP_MINUS | 12), # saved %edi: at -12(%ebp)
- chr(self.LOC_EBP_PLUS | 0), # saved %ebp: at (%ebp)
- chr(0)]
-
- def _encode_num(self, shape, number):
- assert number >= 0
- flag = 0
- while number >= 0x80:
- shape.append(chr((number & 0x7F) | flag))
- flag = 0x80
- number >>= 7
- shape.append(chr(number | flag))
-
- def add_frame_offset(self, shape, offset):
- if self.is_64_bit:
- assert (offset & 7) == 0
- offset >>= 1
- else:
- assert (offset & 3) == 0
- if offset >= 0:
- num = self.LOC_EBP_PLUS | offset
- else:
- num = self.LOC_EBP_MINUS | (-offset)
- self._encode_num(shape, num)
-
- def add_callee_save_reg(self, shape, reg_index):
- assert reg_index > 0
- shape.append(chr(self.LOC_REG | (reg_index << 2)))
-
- def compress_callshape(self, shape, datablockwrapper):
- # Similar to compress_callshape() in trackgcroot.py.
- # Returns an address to raw memory (as an integer).
- length = len(shape)
- rawaddr = datablockwrapper.malloc_aligned(length, 1)
- p = rffi.cast(self.CALLSHAPE_ARRAY_PTR, rawaddr)
- for i in range(length):
- p[length-1-i] = rffi.cast(rffi.UCHAR, shape[i])
- return rawaddr
-
-
class GcRootMap_shadowstack(object):
"""Handles locating the stack roots in the assembler.
This is the class supporting --gcrootfinder=shadowstack.
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit