summaryrefslogtreecommitdiff
path: root/sv.h
Commit message (Collapse)AuthorAgeFilesLines
* reduce cost of SvVALID()David Mitchell2016-11-131-1/+2
| | | | | | | | Now that SvVALID() no longer just checks an SV flag, but instead checks for the existence of a certain type of magic, avoid using this more expensive macro when its not really needed. Also, and an extra flag test to SvVALID() to make it fail quicker.
* eliminate SVpbm_VALID flagDavid Mitchell2016-11-121-41/+14
| | | | | | | | This flag is set on an SV to indicate that it has PERL_MAGIC_bm (fast Boyer-Moore) magic attached. Instead just directly check whether it has such magic. This frees up the 0x40000000 bit for anything except AVs and HVs
* eliminate SVpbm_TAIL/SvTAIL_on()/SvTAIL_off()David Mitchell2016-11-121-10/+6
| | | | | | | | | | | | (but keep SvTAIL()) This flag is only set on SVs that have Boyer-Moore magic attached. Such SVs already re-purpose the unused IVX slot of that SV to store BmUSEFUL. This commit repurposes the unused NVX slot to store this boolean value instead. Now that flag bit (0x80000000) is only used with AVs, HVs, RVs and scalar SVs with IOK.
* Only test SvTAIL when SvVALIDDavid Mitchell2016-11-121-0/+1
| | | | | | Only use the SvTAIL() macro when we've already confirmed that the SV is SvVALID() - this is in preparation for removing the SVpbm_TAIL flag in the next commit
* Eliminate SVrepl_EVAL and SvEVALED()David Mitchell2016-11-121-6/+1
| | | | | | | | | | | This flag is only used to indicate that the SV holding the text of the replacement part of a s/// has seen at least one /e. Instead, set the IVX field in the SV to a true value. (We already set the NVX field on that SV to indicate a multi-src-line substitution). This is to reduce the number of odd special cases for the SVpbm_VALID flag.
* remove DOES's usage of SvSCREAMDavid Mitchell2016-11-121-2/+1
| | | | | | | | | | | | | | | | Currently the SvSCREAM flag is set on a temporary SV whose string value is "isa", but where for the purposes of printing Can't call method "XXX" its name is treated as "DOES" rather than "isa". Instead, set the temp SV's PVX buffer to point to a special static string (PL_isa_DOES) whose value is "isa", but the where the error reporting code can compare the address with PL_isa_DOES and if so, print "DOES" instead. This is to reduce the number of odd special cases for the SvSCREAM flag.
* remove eval's usage of SvSCREAMDavid Mitchell2016-11-121-1/+0
| | | | | | | | Currently the SvSCREAM flag is set on the sv pointed to by cx->blk_eval.cur_text, to indicate that it is ref counted. Instead, use a spare bit in the blk_u16 field of the eval context. This is to reduce the number of odd special cases for the SvSCREAM flag.
* sv.c: add sv_setpv_bufsize() and SvPVCLEAR()Yves Orton2016-10-191-0/+5
| | | | | | | | | | The first can be used to wrap several SVPV steps into a single sub, and a wrapper macro which is the equivalent of $s= ""; but is optimized in various ways.
* Eliminate xpad_cop_seq from _xnvu unionDavid Mitchell2016-09-271-4/+1
| | | | | | | | | | | | | PVNV's used to be used to hold pad names (like '$lex'), but aren't used for this purpose any more. So eliminate the xpad_cop_seq part of the union. Since S_scan_subst() was using xnv_u.xpad_cop_seq.xlow to store a temporary line count, add a new union member for that. The main usage of this field on CPAN is to define COP_SEQ_RANGE_LOW()-style macros, so if the module is still using xpad_cop_seq for that purpose, it's already broken.
* first step to documenting the Internals namespaceYves Orton2016-08-141-1/+18
| | | | | | | | | | | After discussion, we have decided to document Internals. This is a first step doing so, with lib/Internals.pod. At the same time I updated sv.h that there were equivalents for SvREFCNT and SvREADONLY in the Internals namespace, this required adding docs for SvREADONLY. I also tweaked the test name in Porting/Maintainers.pm so that it pointed at Porting/Maintainers.pl to make it more obvious how to specify a maintainer for a new file.
* New bug numbers in *.[ch]Father Chrysostomos2016-07-291-1/+1
| | | | perl -pi -e 'BEGIN { %map = split " ", join "", `cat pb2rt.txt` } s/(?<!\d)\d{8}\.\d{3}(?!\d)/$& (#$map{$&})/g' *.[ch]
* Revert "More generalized fix for #127855"David Mitchell2016-05-031-7/+4
| | | | | | | | This reverts commit bcc9f606509ad2fad50e16f081103451b7dc49e1. This and the next commit revert the two commits that were an original fix for RT #127855, but which is fixed in a different way in a following commit. See the ticket for more details.
* More generalized fix for #127855, overallocate in SvGROW and not just sv_grow()Yves Orton2016-04-081-4/+7
| | | | | | If we overallocate in SvGROW() and not just sv_grow() we can ensure we have more cases where we can COW. We need to ensure we always have room for a null and a reference count.
* move SET_SVANY_FOR_BODYLESS_IV() from sv.c to sv.hDavid Mitchell2016-02-031-0/+34
| | | | | | | | Ditto for SET_SVANY_FOR_BODYLESS_NV. The IV variant will shortly be needed in pp_hot.c, so make it available outside sv.c. For now, protect with #ifdef PERL_CORE, so as little as possible is changed by this commit.
* fix the API description of SvLEN_set()David Mitchell2015-12-031-1/+1
| | | | | | | | | | RT #126245 Make it clearer that is the buffer length being specified, not the string length. Also, change the 'See "SvIV_set"' to SvLEN. That appears to be a cut and paste error. Based on suggested wording from jazzkutya@gmail.com
* avoid (TAINTING_get && TAINT_get)David Mitchell2015-11-101-4/+3
| | | | | | | | | | In various places we test for both (PL_tainting && PL_tainted). Since if tainting isn't enabled PL_tainted should never get set, it's more efficient to just test for (TAINT_get). We ensure that PL_tainted doesn't actually get set when !PL_tainting by changing some "setting" macros from PL_tainted = TRUE to PL_tainted = PL_tainting.
* fbm_instr(): tweak docs and formattingDavid Mitchell2015-10-131-1/+1
| | | | | Expand the commentary at the start of this function; add more blank lines to separate chunks of code, and document what SVpbm_TAIL is for.
* make sv_backoff tailcall friendlyDaniel Dragan2015-10-081-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Reorder the body of Perl_sv_backoff slightly to make it more tail-call friendly, and change its signature from returning an int (always 0) to void. sv_backoff has only 1.5 function calls in it, there is a memcpy of a U32 * for alignment reasons (I wont discuss U32_ALIGNMENT_REQUIRED) inside of SvOOK_offset, and the explicit Move()/memmove. GCC and clang often inline memcpy/memmove when the length is a constant and is small. Sometimes a CC might also do unaligned memory reads if OS/CPU allows it http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20130513/174807.html so I'll assume memcpy by short constant isn't a func call for discussion. By moving SvFLAGS modification before the one and only func call, and changing the return type to void, there is no code to execute after the Move func call so the CC, if it wants (OS/ABI/CPU, specifically I am thinking about x86-64) can tailcall jump to memmove. Also var sv can be stored in a cheaper vol reg since it is not saved around any func calls (SvFLAGS set was moved) assuming the memcpy by short constant was inlined. The before machine code size of Perl_sv_backoff with VC 2003 -O1 was 0x6d bytes. After size is 0x61. .text section size of perl523.dll was after was 0xD2733 bytes long, before was 0xD2743 bytes long. VC perl does not inline memcpys by default. In commit a0d0e21ea6 "perl 5.000" the return 0 was added. The int ret type is from day 1 of sv_backoff function existing/day 1 of SV *s from commit 79072805bf "perl 5.0 alpha 2". str_backoff didn't exist AFAIK, only str_grow would retake the memory at the start of the block. Since sv_backoff is usually used in a "&& func()" macro (SvOOK_off), it needed a non void ret type, a simple ", 0" in the macro fixes that. All CCs optimize and remove "if(0)" machine instructions so the ", 0" is optimized away in the perl binary.
* POD fix in the documentation for SvTHINKFIRSTRafael Garcia-Suarez2015-09-251-1/+1
|
* perlapi use 'UTF-8' instead of variants of thatKarl Williamson2015-09-031-5/+5
|
* Various pods: Add C<> around many typed-as-is thingsKarl Williamson2015-09-031-91/+91
| | | | Removes 'the' in front of parameter names in some instances.
* perlapi, perlintern: Add L<> links to podKarl Williamson2015-09-031-23/+23
|
* re-implement OPpASSIGN_COMMON mechanismDavid Mitchell2015-08-171-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit almost completely replaces the current mechanism for detecting and handing common vars in list assignment, e.g. ($a,$b) = ($b,$a); In general outline: it creates more false positives at compile-time than before, but also no longer misses some false negatives. In compensation, it considerably reduces the run-time cost of handling potential and real commonality. It does this firstly by splitting the OPpASSIGN_COMMON flag into 3 separate flags: OPpASSIGN_COMMON_AGG OPpASSIGN_COMMON_RC1 OPpASSIGN_COMMON_SCALAR which indicate different classes of commonality that can be handled in different ways at runtime. Most importantly, it distinguishes between two basic cases. Firstly, common scalars (OPpASSIGN_COMMON_SCALAR), e.g. ($x,....) = (....,$x,...) where $x is modified and then sometime later its value is used again, but that value has changed in the meantime. In this case, we need replace such vars on the RHS with mortal copies before processing the assign. The second case is an aggregate on the LHS (OPpASSIGN_COMMON_AGG), e.g. (...,@a) = (...., $a[0],...) In this case, the issue is instead that when @a is cleared, it may free items on the RHS (due to the stack not being ref counted). What is required here is that rather than making of a copy of each RHS element and storing it in the array as we progress, we make *all* the copies *before* clearing the array, but mortalise them in case we die in the meantime. We can further distinguish two scalar cases; sometimes it's possible to confirm non-commonality at run-time merely by checking that all the LHS scalars have a reference count of 1. If this is possible, we set the OPpASSIGN_COMMON_RC1 flag rather than the OPpASSIGN_COMMON_SCALAR flag. The major improvement in the run-time performance in the OPpASSIGN_COMMON_SCALAR case (or OPpASSIGN_COMMON_RC1 if rc>1 scalars are detected), is to use a mark-and-sweep scan of the two lists using the SVf_BREAK flag, to determine which elements are common, and only make mortal copies of those elements. This has a very big effect on run-time performance; for example in the classic ($a,$b) = ($b,$a); it would formerly make temp copies of both $a and $b; now it only copies $a. In more detail, the mark and sweep mechanism in pp_aassign works by looping through each LHS and RHS SV pair in parallel. It temporarily marks each LHS SV with the SVf_BREAK flag, then makes a copy of each RHS element only if it has the SVf_BREAK flag set. When the scan is finished, the flag is unset on all LHS elements. One major change in compile-time flagging is that package scalar vars are now treated as if they could always be aliased. So we don't bother any more to do the compile-time PL_generation checking on package vars (we still do it on lexical vars). We also no longer make use of the run-time PL_sawalias mechanism for detecting aliased package vars (and indeed the next commit but one will remove that mechanism). This means that more list assignment expressions which feature package vars will now need to do a runtime mark-and-sweep (or where appropriate, RC1) test. In compensation, we no longer need to test for aliasing and set PL_sawalias in pp_gvsv and pp_gv, nor reset PL_sawalias in every pp_nextstate. Part of the reasoning behind this is that it's nearly impossible to detect all possible package var aliasing; for example PL_sawalias would fail to detect XS code doing GvSV(gv) = sv. Note that we now scan the two children of the OP_AASSIGN separately, and in particular we mark lexicals with PL_generation only on the LHS and test only on the RHS. So something like ($x,$y) = ($default, $default) will no longer be regarded as having common vars. In terms of performance, running Porting/perlbench.pl on the new expr::aassign:: tests in t/perf/benchmarks show that the biggest slowdown is around 13% more instruction reads and 20% more conditional branches in this: setup => 'my ($v1,$v2,$v3) = 1..3; ($x,$y,$z) = 1..3;', code => '($x,$y,$z) = ($v1,$v2,$v3)', where this is now a false positive due to the presence of package variables. The biggest speedup is 50% less instruction reads and conditional branches in this: setup => '@_ = 1..3; my ($x,$y,$z)', code => '($x,$y,$z) = @_', because formerly the presence of @_ pessimised things if the LHS wasn't a my declaration (it's still pessimised, but the runtime's faster now). Conversely, we pessimise the 'my' variant too now: setup => '@_ = 1..3;', code => 'my ($x,$y,$z) = @_', this gives 5% more instruction reads and 11% more conditional branches now. But see the next commit, which will cheat for that particular construct.
* perlapi: Use F<> around file namesKarl Williamson2015-08-011-1/+1
|
* perlapi: Use C<> instead of I<> for parameter names, etcKarl Williamson2015-08-011-9/+9
| | | | | The majority of perlapi uses C<> to specify these things, but a few things used I<> instead. Standardize to C<>.
* all SV inheriter types have DEBUG_LEAKING_SCALARS data, so always show itDaniel Dragan2015-07-081-9/+13
| | | | | | | | I noticed AV *s in my C debugger didn't the sv_debug_* members, but if I casted the AV * to a SV * in my C debugger using a expession in my watch tab, all the info was there. Put the DEBUG_LEAKING_SCALARS in _SV_HEAD_UNION so the sv_debug_* members appear everywhere (CV/HV/AV/etc), not just for SVs.
* Remove NEW_ from PERL_NEW_COPY_ON_WRITEFather Chrysostomos2015-06-291-1/+1
|
* Remove SvRELEASE_IVXFather Chrysostomos2015-06-291-8/+2
| | | | Now that PERL_OLD_COPY_ON_WRITE is gone, it no longer does anything.
* Remove PERL_OLD_COPY_ON_WRITEFather Chrysostomos2015-06-291-18/+7
|
* sv.h: document additional use of SVp_SCREAM flagDavid Mitchell2015-06-121-0/+1
|
* perlapi: Add 2 links to other parts of the podKarl Williamson2015-05-081-0/+3
|
* Replace common Emacs file-local variables with dir-localsDagfinn Ilmari Mannsåker2015-03-221-6/+0
| | | | | | | | | | | | | | | | An empty cpan/.dir-locals.el stops Emacs using the core defaults for code imported from CPAN. Committer's work: To keep t/porting/cmp_version.t and t/porting/utils.t happy, $VERSION needed to be incremented in many files, including throughout dist/PathTools. perldelta entry for module updates. Add two Emacs control files to MANIFEST; re-sort MANIFEST. For: RT #124119.
* improve SvPV_set's docs, it really shouldn't be public APIDaniel Dragan2015-01-191-3/+8
| | | | | | | Someone else in the perl community wrote XS code using SvPV_set instead of sv_setpvn and couldn't figure out why he was getting heap corruption/failed asserts/SEGVs/etc. Improve the docs to basically say never use this.
* More branch prediction hints for sv_setsv_flagsSteffen Mueller2014-12-011-1/+1
| | | | | | | | | | | | | | | Dave's cachegrind benchmark says "small win": REF THIS ------ ------ Ir 105.35 105.91 Dr 104.45 105.42 Dw 105.42 105.17 COND 104.33 104.58 IND 107.04 106.76 COND_m 98.55 110.11 IND_m 110.09 111.08
* [perl #123223] Make PADNAME a separate typeFather Chrysostomos2014-11-301-63/+7
| | | | | | | | | | | distinct from SV. This should fix the CPAN modules that were failing when the PadnameLVALUE flag was added, because it shared the same bit as SVs_OBJECT and pad names were going through code paths not designed to handle pad names. Unfortunately, it will probably break other CPAN modules, but I think this change is for the better, as it makes both pad names and SVs sim- pler and makes pad names take less memory.
* Make PADNAMELIST a separate typeFather Chrysostomos2014-11-301-2/+1
| | | | This is in preparation for making PADNAME a separate type.
* Use PADNAME rather than SV in the sourceFather Chrysostomos2014-11-301-1/+1
| | | | | | | | | This is in preparation for making PADNAME a separate type. This commit is not perfect. What I did was temporarily make PADNAME a separate struct identical to struct sv and make whatever changes were necessary to avoid compiler warnings. In some cases I had to add tem- porary SV casts.
* remove a branch in SvIV_please_nomgDaniel Dragan2014-11-241-3/+3
| | | | | | | | | | | | | | | | On VC 2003 and GCC 4.6.3, this patch decreases from 3 branches to 2 branches that machine code that makes up SvIV_please_nomg. Functionality should be identical as before. This is intended to make math functions like pp_add faster. Due to complexity/my time, SvIV_please wasn't optimized. "(SvNOK(sv) || SvPOK(sv)" was optimized to "(SvFLAGS(sv) & (SVf_NOK|SVf_POK))" on GCC and VC 2003 before this patch, so that change reenforces what the optimizer already did before. .text section of miniperl.exe size in bytes gcc 32b 4.6.3 -O2 before 0x10d154 gcc 32b 4.6.3 -O2 after 0x10d064 vc2003 before 0xa4odf vc2003 after 0xa406f
* Add new LVALUE flag for pad namesFather Chrysostomos2014-11-131-0/+2
| | | | | This will be used to record whether a pad entry is used as an lvalue multiple times. If so, it cannot be used as a constant.
* add xs_handshake APIDaniel Dragan2014-11-071-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This API elevates the amount of ABI compatibility protection between XS modules and the interp. It also makes each boot XSUB smaller in machine code by removing function calls and factoring out code into the new Perl_xs_handshake and Perl_xs_epilog functions. sv.c : - revise padlist duping code to reduce code bloat/asserts on DEBUGGING ext/DynaLoader/dlutils.c : - disable version checking so interp startup is faster, ABI mismatches are impossible because DynaLoader is never available as a shared library ext/XS-APItest/XSUB-redefined-macros.xs : - "" means dont check the version, so switch to " " to make the test in xsub_h.t pass, see ML thread "XS_APIVERSION_BOOTCHECK and XS_VERSION is CPP defined but "", mow what?" ext/re/re.xs : - disable API version checking until #123007 is resolved ParseXS/Utilities.pm : 109-standard_XS_defs.t : - remove context from S_croak_xs_usage similar to core commit cb077ed296 . CvGV doesn't need a context until 5.21.4 and commit ae77754ae2 and by then core's croak_xs_uage API has been long available and this backport doesn't need to account for newer perls - fix test where lack of having PERL_IMPLICIT_CONTEXT caused it to fail
* free up CvPADLIST slot for XSUBs for future useDaniel Dragan2014-10-311-1/+4
| | | | | | | | | | | | | | | | | | | CvRESERVED is a placeholder, it will be replaced with a sentinal value from future revised BOOTCHECK API. CvPADLIST_set was helpful during development of this patch, so keep it around for now. PoisonPADLIST's magic value is from PERL_POISON 0xEF pattern. Some PoisonPADLIST locations will get code from future BOOTCHECK API. Make padlist_dup a NN function to avoid overhead of calling it for XSUBs during closing. Perl_cv_undef_flags's else if (CvISXSUB(&cvbody)) is to avoid whitespace changes. Filed as perl [#123059].
* Apify SV_CATBYTES and SV_CATUTF8Father Chrysostomos2014-10-181-6/+2
| | | | | | | When I added them I was not sure at the time whether they would be stable or whether they might need to be changed. They seem pretty stable now, and they are extremely useful, so make them part of the API.
* optimize SV creation funcs in sv.cDaniel Dragan2014-10-041-0/+3
| | | | | | | | | | | | | | | | | | | | In Perl_newSV, the sv_upgrade is redundant, except to protect against a segv in blindly SV body derefing SvGROW (but not in sv_grow). sv_grow has always upgraded a non-PV SV to PV. So don't it here. Since a new SV will never have be a COW, have a SvLEN or a body, all of which SvGROW uses, just call sv_grow. Less branching, and smaller code that way. In Perl_newSV_type, give a hint to compiler that if a platform's symbol visibility allows inlining, and newSV_type's arg is the base type (currently SVt_NULL, maybe SVt_IV in future (see ML)), to possibly inline new_SV into the caller and remove the sv_upgrade call. Also don't call sv_upgrade if it isn't needed (SVt_NULL) in the public symbol version. The redundant sv_upgrade then sv_grow goes to commit 79072805bf "perl 5.0 alpha 2". VC 2003 -01 32 bit threaded machine code size in bytes of 2 functions Perl_newSV_type before 0x2f after 0x29 Perl_newSV before 0x48 after 0x28
* for storage of NVs, use "IV in sv_u in head no-body trick" where possibleDaniel Dragan2014-09-281-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | This completes the goal of commit 7b2c381cf3 from 5.9.2/2005. 8 bytes are saved on arena and 8 byte double is NV builds, and usually 32 bytes on PURIFY/malloced bodies builds. (2 void *s/16 bytes for header+16 bytes minimum malloc size on typical malloc schemes). long doubles can't use this optimization. Also a hypothetical NV is 32 bit float on 32 bit pointer OS Perl build would use this optimization. 64 bit IVs on 32 bit pointer OS use this optimization. Also fixed was a bad solution from ML post "[PATCH] Free old_body in sv_upgrade, also with -DPURIFY" commit bc78644842 which made the old body freeing code in sv_upgrade not obey the body_details table. By checking allocation size instead whether there is an arena better determins if there there is a body to free, PURIFY or not. Note the upper SV types that are malloced/no arena are not upgradable so this code wont be reached due to earlier croak, so there is no danger of an arena ptr getting a free() done on it. This author doesnt have access to PURIFY. Also remove padding from body_details struct. On Win64, this struct was 16 bytes, in format of U8 U8 U8 PAD1BYTE U32 U64. On Win32 it was 12 bytes long, in format of U8 U8 U8 PAD1BYTE U32 U32. Now on compilers (such as VC) that allow 1 byte C bitfields (non-standard extension to C), the struct is always 8 bytes long. I can't imagine an arena being >4GB on 64 bit perl.
* Remove most uses of PADMYFather Chrysostomos2014-09-241-3/+5
| | | | SVs_PADMY is now 0, and SvPADMY means !SvPADTMP.
* Stop setting PADMY; renumber PADSTALEFather Chrysostomos2014-09-241-11/+8
| | | | | | | | | | | | | | | | | | | | The PADMY flag was originally used on values stored in pads as a way to mark those slots ase being in use already during pad allocation. That changed for the most part all the way back in bbce6d6978 (perl5.003_09), but vestiges still remained, because some ops used PADMY for their targets. I removed the last one yesterday in 14d91147. So the PADMY flag now serves no purpose. At run time, the sole purpose of PADMY is to determine the meaning of the flag bit shared by PADTMP and PADSTALE. If PADMY is set, the flag means the latter. Instead of that more complicated check, we can just renumber PADSTALE to use the PADMY bit and assume that anything not PADTMP is PADMY. This commit changes the flags and does just enough to get tests passing (except Peek.t). fixup for padmy flag renumbering
* SvFLAGS: informally reserve a bitDavid Mitchell2014-09-221-2/+4
| | | | | | | SvFAKE is currently unused on HVs, so I'm marking it as mine. Hopefully it will eventually get used for vtables on HVs. I've also improved the description of SVs_TEMP.
* Consistent spaces after dots in perlapiFather Chrysostomos2014-09-211-1/+1
|
* Implement the bipolar read-only systemFather Chrysostomos2014-09-201-6/+12
| | | | | | | | | | | | | | | | | | | | | This fixes bugs related to Hash::Util::unlock accidentally unlocking internal scalars (e.g., that returned by undef()) and allowing them to be modified. Internal read-only values are now marked by two flags, the regular read-only flag, and the new ‘protected’ flag. Before this SvREADONLY served two purposes: 1) The code would use it to protect things that must not be modi- fied, ever (except when the core sees fit to do so). 2) Hash::Util and everybody else would use it to make this unmodifia- ble temporarily when requested by the user. Internals::SvREADONLY serves the latter purpose and only flips the read-only flag, so things that need to stay read-only will remain so, because of the ‘other’ read-only flag, that CPAN doesn’t know about. (If you are a CPAN author, do not read this.)
* Add SVf_PROTECTFather Chrysostomos2014-09-201-0/+1
|