[pypy-svn] r77530 - in pypy/branch/larger-writebarrier/pypy: jit/backend/llgraph jit/backend/llsupport jit/backend/llsupport/test jit/backend/test jit/backend/x86 jit/metainterp rpython/memory rpython/memory/gc rpython/memory/gc/test rpython/memory/gctransform
arigo at codespeak.net
arigo at codespeak.net
Fri Oct 1 16:55:32 CEST 2010
Author: arigo
Date: Fri Oct 1 16:55:30 2010
New Revision: 77530
Modified:
pypy/branch/larger-writebarrier/pypy/jit/backend/llgraph/llimpl.py
pypy/branch/larger-writebarrier/pypy/jit/backend/llsupport/gc.py
pypy/branch/larger-writebarrier/pypy/jit/backend/llsupport/test/test_gc.py
pypy/branch/larger-writebarrier/pypy/jit/backend/test/runner_test.py
pypy/branch/larger-writebarrier/pypy/jit/backend/x86/assembler.py
pypy/branch/larger-writebarrier/pypy/jit/backend/x86/regalloc.py
pypy/branch/larger-writebarrier/pypy/jit/metainterp/resoperation.py
pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/base.py
pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/generation.py
pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/minimark.py
pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/test/test_direct.py
pypy/branch/larger-writebarrier/pypy/rpython/memory/gctransform/framework.py
pypy/branch/larger-writebarrier/pypy/rpython/memory/gcwrapper.py
Log:
In-progress: partial revert of the merge of branch/smaller-writebarrier
(revision 77403).
Modified: pypy/branch/larger-writebarrier/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/jit/backend/llgraph/llimpl.py (original)
+++ pypy/branch/larger-writebarrier/pypy/jit/backend/llgraph/llimpl.py Fri Oct 1 16:55:30 2010
@@ -129,7 +129,7 @@
'arraylen_gc' : (('ref',), 'int'),
'call' : (('ref', 'varargs'), 'intorptr'),
'call_assembler' : (('varargs',), 'intorptr'),
- 'cond_call_gc_wb' : (('ptr',), None),
+ 'cond_call_gc_wb' : (('ptr', 'ptr'), None),
'oosend' : (('varargs',), 'intorptr'),
'oosend_pure' : (('varargs',), 'intorptr'),
'guard_true' : (('bool',), None),
@@ -810,7 +810,7 @@
FLOAT: 0.0}
return d[calldescr.typeinfo]
- def op_cond_call_gc_wb(self, descr, a):
+ def op_cond_call_gc_wb(self, descr, a, b):
py.test.skip("cond_call_gc_wb not supported")
def op_oosend(self, descr, obj, *args):
Modified: pypy/branch/larger-writebarrier/pypy/jit/backend/llsupport/gc.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/jit/backend/llsupport/gc.py (original)
+++ pypy/branch/larger-writebarrier/pypy/jit/backend/llsupport/gc.py Fri Oct 1 16:55:30 2010
@@ -404,7 +404,7 @@
self.GC_MALLOC_BASIC = lltype.Ptr(lltype.FuncType(
[lltype.Signed, lltype.Signed], llmemory.GCREF))
self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
- [llmemory.Address], lltype.Void))
+ [llmemory.Address, llmemory.Address], lltype.Void))
self.write_barrier_descr = WriteBarrierDescr(self)
#
def malloc_array(itemsize, tid, num_elem):
@@ -550,7 +550,8 @@
# the GC, and call it immediately
llop1 = self.llop1
funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR)
- funcptr(llmemory.cast_ptr_to_adr(gcref_struct))
+ funcptr(llmemory.cast_ptr_to_adr(gcref_struct),
+ llmemory.cast_ptr_to_adr(gcref_newptr))
def rewrite_assembler(self, cpu, operations):
# Perform two kinds of rewrites in parallel:
@@ -589,7 +590,7 @@
v = op.getarg(1)
if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
bool(v.value)): # store a non-NULL
- self._gen_write_barrier(newops, op.getarg(0))
+ self._gen_write_barrier(newops, op.getarg(0), v)
op = op.copy_and_change(rop.SETFIELD_RAW)
# ---------- write barrier for SETARRAYITEM_GC ----------
if op.getopnum() == rop.SETARRAYITEM_GC:
@@ -598,15 +599,15 @@
bool(v.value)): # store a non-NULL
# XXX detect when we should produce a
# write_barrier_from_array
- self._gen_write_barrier(newops, op.getarg(0))
+ self._gen_write_barrier(newops, op.getarg(0), v)
op = op.copy_and_change(rop.SETARRAYITEM_RAW)
# ----------
newops.append(op)
del operations[:]
operations.extend(newops)
- def _gen_write_barrier(self, newops, v_base):
- args = [v_base]
+ def _gen_write_barrier(self, newops, v_base, v_value):
+ args = [v_base, v_value]
newops.append(ResOperation(rop.COND_CALL_GC_WB, args, None,
descr=self.write_barrier_descr))
Modified: pypy/branch/larger-writebarrier/pypy/jit/backend/llsupport/test/test_gc.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/jit/backend/llsupport/test/test_gc.py (original)
+++ pypy/branch/larger-writebarrier/pypy/jit/backend/llsupport/test/test_gc.py Fri Oct 1 16:55:30 2010
@@ -141,8 +141,8 @@
repr(offset_to_length), p))
return p
- def _write_barrier_failing_case(self, adr_struct):
- self.record.append(('barrier', adr_struct))
+ def _write_barrier_failing_case(self, adr_struct, adr_newptr):
+ self.record.append(('barrier', adr_struct, adr_newptr))
def get_write_barrier_failing_case(self, FPTRTYPE):
return llhelper(FPTRTYPE, self._write_barrier_failing_case)
@@ -239,6 +239,7 @@
s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s)
r_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, r)
s_adr = llmemory.cast_ptr_to_adr(s)
+ r_adr = llmemory.cast_ptr_to_adr(r)
#
s_hdr.tid &= ~gc_ll_descr.GCClass.JIT_WB_IF_FLAG
gc_ll_descr.do_write_barrier(s_gcref, r_gcref)
@@ -246,7 +247,7 @@
#
s_hdr.tid |= gc_ll_descr.GCClass.JIT_WB_IF_FLAG
gc_ll_descr.do_write_barrier(s_gcref, r_gcref)
- assert self.llop1.record == [('barrier', s_adr)]
+ assert self.llop1.record == [('barrier', s_adr, r_adr)]
def test_gen_write_barrier(self):
gc_ll_descr = self.gc_ll_descr
@@ -254,11 +255,13 @@
#
newops = []
v_base = BoxPtr()
- gc_ll_descr._gen_write_barrier(newops, v_base)
+ v_value = BoxPtr()
+ gc_ll_descr._gen_write_barrier(newops, v_base, v_value)
assert llop1.record == []
assert len(newops) == 1
assert newops[0].getopnum() == rop.COND_CALL_GC_WB
assert newops[0].getarg(0) == v_base
+ assert newops[0].getarg(1) == v_value
assert newops[0].result is None
wbdescr = newops[0].getdescr()
assert isinstance(wbdescr.jit_wb_if_flag, int)
@@ -358,6 +361,7 @@
#
assert operations[0].getopnum() == rop.COND_CALL_GC_WB
assert operations[0].getarg(0) == v_base
+ assert operations[0].getarg(1) == v_value
assert operations[0].result is None
#
assert operations[1].getopnum() == rop.SETFIELD_RAW
@@ -381,6 +385,7 @@
#
assert operations[0].getopnum() == rop.COND_CALL_GC_WB
assert operations[0].getarg(0) == v_base
+ assert operations[0].getarg(1) == v_value
assert operations[0].result is None
#
assert operations[1].getopnum() == rop.SETARRAYITEM_RAW
Modified: pypy/branch/larger-writebarrier/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/jit/backend/test/runner_test.py (original)
+++ pypy/branch/larger-writebarrier/pypy/jit/backend/test/runner_test.py Fri Oct 1 16:55:30 2010
@@ -1427,12 +1427,12 @@
assert not excvalue
def test_cond_call_gc_wb(self):
- def func_void(a):
- record.append(a)
+ def func_void(a, b):
+ record.append((a, b))
record = []
#
S = lltype.GcStruct('S', ('tid', lltype.Signed))
- FUNC = self.FuncType([lltype.Ptr(S)], lltype.Void)
+ FUNC = self.FuncType([lltype.Ptr(S), lltype.Signed], lltype.Void)
func_ptr = llhelper(lltype.Ptr(FUNC), func_void)
funcbox = self.get_funcbox(self.cpu, func_ptr)
class WriteBarrierDescr(AbstractDescr):
@@ -1453,10 +1453,10 @@
sgcref = lltype.cast_opaque_ptr(llmemory.GCREF, s)
del record[:]
self.execute_operation(rop.COND_CALL_GC_WB,
- [BoxPtr(sgcref)],
+ [BoxPtr(sgcref), ConstInt(-2121)],
'void', descr=WriteBarrierDescr())
if cond:
- assert record == [s]
+ assert record == [(s, -2121)]
else:
assert record == []
Modified: pypy/branch/larger-writebarrier/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/larger-writebarrier/pypy/jit/backend/x86/assembler.py Fri Oct 1 16:55:30 2010
@@ -1780,11 +1780,12 @@
self.mc.PUSH_i32(loc.getint())
if IS_X86_64:
- # We clobber this register to pass the arguments, but that's
+ # We clobber these registers to pass the arguments, but that's
# okay, because consider_cond_call_gc_wb makes sure that any
# caller-save registers with values in them are present in arglocs,
# so they are saved on the stack above and restored below
self.mc.MOV_rs(edi.value, 0)
+ self.mc.MOV_rs(esi.value, 8)
# misaligned stack in the call, but it's ok because the write barrier
# is not going to call anything more. Also, this assumes that the
Modified: pypy/branch/larger-writebarrier/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/jit/backend/x86/regalloc.py (original)
+++ pypy/branch/larger-writebarrier/pypy/jit/backend/x86/regalloc.py Fri Oct 1 16:55:30 2010
@@ -696,9 +696,13 @@
def consider_cond_call_gc_wb(self, op):
assert op.result is None
args = op.getarglist()
+ loc_newvalue = self.rm.make_sure_var_in_reg(op.getarg(1), args)
+ # ^^^ we force loc_newvalue in a reg (unless it's a Const),
+ # because it will be needed anyway by the following setfield_gc.
+ # It avoids loading it twice from the memory.
loc_base = self.rm.make_sure_var_in_reg(op.getarg(0), args,
imm_fine=False)
- arglocs = [loc_base]
+ arglocs = [loc_base, loc_newvalue]
# add eax, ecx and edx as extra "arguments" to ensure they are
# saved and restored. Fish in self.rm to know which of these
# registers really need to be saved (a bit of a hack). Moreover,
Modified: pypy/branch/larger-writebarrier/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/jit/metainterp/resoperation.py (original)
+++ pypy/branch/larger-writebarrier/pypy/jit/metainterp/resoperation.py Fri Oct 1 16:55:30 2010
@@ -455,7 +455,7 @@
'UNICODESETITEM/3',
'NEWUNICODE/1',
#'RUNTIMENEW/1', # ootype operation
- 'COND_CALL_GC_WB/1d', # [objptr] (for the write barrier)
+ 'COND_CALL_GC_WB/2d', # [objptr, newvalue] (for the write barrier)
'DEBUG_MERGE_POINT/1', # debugging only
'VIRTUAL_REF_FINISH/2', # removed before it's passed to the backend
'COPYSTRCONTENT/5', # src, dst, srcstart, dststart, length
Modified: pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/base.py (original)
+++ pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/base.py Fri Oct 1 16:55:30 2010
@@ -79,7 +79,7 @@
def set_root_walker(self, root_walker):
self.root_walker = root_walker
- def write_barrier(self, addr_struct):
+ def write_barrier(self, newvalue, addr_struct):
pass
def statistics(self, index):
Modified: pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/generation.py (original)
+++ pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/generation.py Fri Oct 1 16:55:30 2010
@@ -157,6 +157,11 @@
"odd-valued (i.e. tagged) pointer unexpected here")
return self.nursery <= addr < self.nursery_top
+ def appears_to_be_in_nursery(self, addr):
+ # same as is_in_nursery(), but may return True accidentally if
+ # 'addr' is a tagged pointer with just the wrong value.
+ return self.nursery <= addr < self.nursery_top
+
def malloc_fixedsize_clear(self, typeid, size, can_collect,
has_finalizer=False, contains_weakptr=False):
if (has_finalizer or not can_collect or
@@ -326,7 +331,7 @@
addr = pointer.address[0]
newaddr = self.copy(addr)
pointer.address[0] = newaddr
- self.write_into_last_generation_obj(obj)
+ self.write_into_last_generation_obj(obj, newaddr)
# ____________________________________________________________
# Implementation of nursery-only collections
@@ -457,9 +462,9 @@
# "if addr_struct.int0 & JIT_WB_IF_FLAG: remember_young_pointer()")
JIT_WB_IF_FLAG = GCFLAG_NO_YOUNG_PTRS
- def write_barrier(self, addr_struct):
- if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
- self.remember_young_pointer(addr_struct)
+ def write_barrier(self, newvalue, addr_struct):
+ if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
+ self.remember_young_pointer(addr_struct, newvalue)
def _setup_wb(self):
DEBUG = self.DEBUG
@@ -470,23 +475,33 @@
# For x86, there is also an extra requirement: when the JIT calls
# remember_young_pointer(), it assumes that it will not touch the SSE
# registers, so it does not save and restore them (that's a *hack*!).
- def remember_young_pointer(addr_struct):
+ def remember_young_pointer(addr_struct, addr):
#llop.debug_print(lltype.Void, "\tremember_young_pointer",
# addr_struct, "<-", addr)
if DEBUG:
ll_assert(not self.is_in_nursery(addr_struct),
"nursery object with GCFLAG_NO_YOUNG_PTRS")
- self.old_objects_pointing_to_young.append(addr_struct)
- self.header(addr_struct).tid &= ~GCFLAG_NO_YOUNG_PTRS
- self.write_into_last_generation_obj(addr_struct)
+ #
+ # What is important in this function is that it *must*
+ # clear the flag GCFLAG_NO_YOUNG_PTRS from 'addr_struct'
+ # if 'addr' is in the nursery. It is ok if, accidentally,
+ # it also clears the flag in some more rare cases, like
+ # 'addr' being a tagged pointer whose value happens to be
+ # a large integer that fools is_in_nursery().
+ if self.appears_to_be_in_nursery(addr):
+ self.old_objects_pointing_to_young.append(addr_struct)
+ self.header(addr_struct).tid &= ~GCFLAG_NO_YOUNG_PTRS
+ self.write_into_last_generation_obj(addr_struct, addr)
remember_young_pointer._dont_inline_ = True
self.remember_young_pointer = remember_young_pointer
- def write_into_last_generation_obj(self, addr_struct):
+ def write_into_last_generation_obj(self, addr_struct, addr):
objhdr = self.header(addr_struct)
if objhdr.tid & GCFLAG_NO_HEAP_PTRS:
- objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
- self.last_generation_root_objects.append(addr_struct)
+ if (self.is_valid_gc_object(addr) and
+ not self.is_last_generation(addr)):
+ objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
+ self.last_generation_root_objects.append(addr_struct)
write_into_last_generation_obj._always_inline_ = True
def assume_young_pointers(self, addr_struct):
Modified: pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/minimark.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/minimark.py (original)
+++ pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/minimark.py Fri Oct 1 16:55:30 2010
@@ -726,16 +726,16 @@
def JIT_max_size_of_young_obj(cls):
return cls.TRANSLATION_PARAMS['large_object']
- def write_barrier(self, addr_struct):
+ def write_barrier(self, newvalue, addr_struct):
if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
- self.remember_young_pointer(addr_struct)
+ self.remember_young_pointer(addr_struct, newvalue)
- def write_barrier_from_array(self, addr_array, index):
+ def write_barrier_from_array(self, newvalue, addr_array, index):
if self.header(addr_array).tid & GCFLAG_NO_YOUNG_PTRS:
if self.card_page_indices > 0: # <- constant-folded
self.remember_young_pointer_from_array(addr_array, index)
else:
- self.remember_young_pointer(addr_array)
+ self.remember_young_pointer(addr_array, newvalue)
def _init_writebarrier_logic(self):
DEBUG = self.DEBUG
@@ -746,7 +746,7 @@
# For x86, there is also an extra requirement: when the JIT calls
# remember_young_pointer(), it assumes that it will not touch the SSE
# registers, so it does not save and restore them (that's a *hack*!).
- def remember_young_pointer(addr_struct):
+ def remember_young_pointer(addr_struct, newvalue):
# 'addr_struct' is the address of the object in which we write.
if DEBUG:
ll_assert(not self.is_in_nursery(addr_struct),
@@ -754,7 +754,9 @@
#
# We assume that what we are writing is a pointer to the nursery
# (and don't care for the fact that this new pointer may not
- # actually point to the nursery, which seems ok). What we need is
+ # actually point to the nursery, which seems ok
+ # XXXXXX XXX wrong !! fix me
+ # ). What we need is
# to remove the flag GCFLAG_NO_YOUNG_PTRS and add the old object
# to the list 'old_objects_pointing_to_young'. We know that
# 'addr_struct' cannot be in the nursery, because nursery objects
@@ -784,12 +786,19 @@
# 'addr_array' is the address of the object in which we write,
# which must have an array part; 'index' is the index of the
# item that is (or contains) the pointer that we write.
+ if DEBUG:
+ ll_assert(not self.is_in_nursery(addr_array),
+ "nursery array with GCFLAG_NO_YOUNG_PTRS")
objhdr = self.header(addr_array)
if objhdr.tid & GCFLAG_HAS_CARDS == 0:
#
- # no cards, use default logic. The 'nocard_logic()' is just
- # 'remember_young_pointer()', but forced to be inlined here.
- nocard_logic(addr_array)
+ # no cards, use default logic. Mostly copied from above.
+ self.old_objects_pointing_to_young.append(addr_array)
+ objhdr = self.header(addr_array)
+ objhdr.tid &= ~GCFLAG_NO_YOUNG_PTRS
+ if objhdr.tid & GCFLAG_NO_HEAP_PTRS:
+ objhdr.tid &= ~GCFLAG_NO_HEAP_PTRS
+ self.prebuilt_root_objects.append(addr_array)
return
#
# 'addr_array' is a raw_malloc'ed array with card markers
@@ -807,17 +816,15 @@
return
#
# We set the flag (even if the newly written address does not
- # actually point to the nursery -- like remember_young_pointer()).
+ # actually point to the nursery, which seems to be ok -- actually
+ # it seems more important that remember_young_pointer_from_array()
+ # does not take 3 arguments).
addr_byte.char[0] = chr(byte | bitmask)
#
if objhdr.tid & GCFLAG_CARDS_SET == 0:
self.old_objects_with_cards_set.append(addr_array)
objhdr.tid |= GCFLAG_CARDS_SET
- nocard_logic = func_with_new_name(self.remember_young_pointer,
- 'remember_young_pointer_nocard')
- del nocard_logic._dont_inline_
- nocard_logic._always_inline_ = True
remember_young_pointer_from_array._dont_inline_ = True
self.remember_young_pointer_from_array = (
remember_young_pointer_from_array)
Modified: pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/test/test_direct.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/test/test_direct.py (original)
+++ pypy/branch/larger-writebarrier/pypy/rpython/memory/gc/test/test_direct.py Fri Oct 1 16:55:30 2010
@@ -86,17 +86,19 @@
def write(self, p, fieldname, newvalue):
if self.gc.needs_write_barrier:
+ newaddr = llmemory.cast_ptr_to_adr(newvalue)
addr_struct = llmemory.cast_ptr_to_adr(p)
- self.gc.write_barrier(addr_struct)
+ self.gc.write_barrier(newaddr, addr_struct)
setattr(p, fieldname, newvalue)
def writearray(self, p, index, newvalue):
if self.gc.needs_write_barrier:
+ newaddr = llmemory.cast_ptr_to_adr(newvalue)
addr_struct = llmemory.cast_ptr_to_adr(p)
if hasattr(self.gc, 'write_barrier_from_array'):
- self.gc.write_barrier_from_array(addr_struct, index)
+ self.gc.write_barrier_from_array(newvalue, addr_struct, index)
else:
- self.gc.write_barrier(addr_struct)
+ self.gc.write_barrier(newaddr, addr_struct)
p[index] = newvalue
def malloc(self, TYPE, n=None):
Modified: pypy/branch/larger-writebarrier/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/rpython/memory/gctransform/framework.py (original)
+++ pypy/branch/larger-writebarrier/pypy/rpython/memory/gctransform/framework.py Fri Oct 1 16:55:30 2010
@@ -426,6 +426,7 @@
if GCClass.needs_write_barrier:
self.write_barrier_ptr = getfn(GCClass.write_barrier.im_func,
[s_gc,
+ annmodel.SomeAddress(),
annmodel.SomeAddress()],
annmodel.s_None,
inline=True)
@@ -434,7 +435,8 @@
# func should not be a bound method, but a real function
assert isinstance(func, types.FunctionType)
self.write_barrier_failing_case_ptr = getfn(func,
- [annmodel.SomeAddress()],
+ [annmodel.SomeAddress(),
+ annmodel.SomeAddress()],
annmodel.s_None)
func = getattr(GCClass, 'write_barrier_from_array', None)
if func is not None:
@@ -1034,8 +1036,11 @@
v_index])
else:
self.write_barrier_calls += 1
+ v_newvalue = hop.genop("cast_ptr_to_adr", [v_newvalue],
+ resulttype = llmemory.Address)
hop.genop("direct_call", [self.write_barrier_ptr,
self.c_const_gc,
+ v_newvalue,
v_structaddr])
hop.rename('bare_' + opname)
Modified: pypy/branch/larger-writebarrier/pypy/rpython/memory/gcwrapper.py
==============================================================================
--- pypy/branch/larger-writebarrier/pypy/rpython/memory/gcwrapper.py (original)
+++ pypy/branch/larger-writebarrier/pypy/rpython/memory/gcwrapper.py Fri Oct 1 16:55:30 2010
@@ -94,6 +94,7 @@
assert (type(index) is int # <- fast path
or lltype.typeOf(index) == lltype.Signed)
self.gc.write_barrier_from_array(
+ llmemory.cast_ptr_to_adr(newvalue),
llmemory.cast_ptr_to_adr(toplevelcontainer),
index)
wb = False
@@ -101,6 +102,7 @@
#
if wb:
self.gc.write_barrier(
+ llmemory.cast_ptr_to_adr(newvalue),
llmemory.cast_ptr_to_adr(toplevelcontainer))
llheap.setinterior(toplevelcontainer, inneraddr, INNERTYPE, newvalue)
More information about the Pypy-commit
mailing list