[#5711] Lexic confusion: method/local variable distinction works strange — noreply@...
Bugs item #2371, was opened at 2005-09-04 00:40
Hi,
Mine is 1.8.2 and it does raise syntax error.
[#5732] Re: Ruby development issue tracking will go to basecamp — ville.mattila@...
[#5737] returning strings from methods/instance_methods — TRANS <transfire@...>
I was just wondering why with #methods and #instance_methods, it was
Hi,
On 9/8/05, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:
Yukihiro Matsumoto <matz@ruby-lang.org> writes:
On Fri, 9 Sep 2005, Christian Neukirchen wrote:
[#5750] File.split edge cases — "Berger, Daniel" <Daniel.Berger@...>
Hi all,
Hi,
nobuyoshi nakada wrote:
Hi,
Yukihiro Matsumoto wrote:
Hi,
Yukihiro Matsumoto wrote:
[#5781] array sharing — Eric Mahurin <eric_mahurin@...>
This is my first time poking around in the ruby source code, so
[#5786] Difference between class declarations — Peter Vanbroekhoven <calamitas@...>
Hi,
Hi,
On 9/15/05, nobu.nokada@softhome.net <nobu.nokada@softhome.net> wrote:
[#5796] proposed attr writer patch — Daniel Berger <Daniel.Berger@...>
Hi all,
Hi,
Daniel Berger wrote:
James Britt <ruby@jamesbritt.com> writes:
On Sun, 18 Sep 2005, Christian Neukirchen wrote:
[#5798] Makefile error in OpenSLL extension (on Windows) — noreply@...
Bugs item #2472, was opened at 2005-09-16 18:56
Hi,
This is the just released 1.8.3 preview2.
Hi,
No, win32/Makefile.sub doe not contain those two lines.
Hi,
On 9/18/05, nobu.nokada@softhome.net <nobu.nokada@softhome.net> wrote:
Hi,
On 9/18/05, nobu.nokada@softhome.net <nobu.nokada@softhome.net> wrote:
[#5844] Ruby 1.8.3 released — Yukihiro Matsumoto <matz@...>
Hello Rubyists,
[#5848] Re: RubyGems in Ruby HEAD — Hugh Sasse <hgs@...>
On Wed, 21 Sep 2005, Chad Fowler wrote:
[#5851] Re: RubyGems in Ruby HEAD — Paul van Tilburg <paul@...>
Hi all,
I don't know if I can post to all those lists, but I'll leave them
Paul van Tilburg wrote:
Marc Dequ竪nes (Duck) wrote:
On 9/22/05, mathew <meta@pobox.com> wrote:
On 9/23/05, Pascal Terjan <pterjan@gmail.com> wrote:
On 9/23/05, Austin Ziegler <halostatue@gmail.com> wrote:
[#5882] Re: RubyGems TODO — Austin Ziegler <halostatue@...>
Okay. I said in the main thread on ruby-core that I'm putting together a
On 9/22/05, Austin Ziegler <halostatue@gmail.com> wrote:
[#5888] Re: RubyGems TODO — Mauricio Fern疣dez <mfp@...>
On Thu, Sep 22, 2005 at 11:46:18AM +0900, Chad Fowler wrote:
[#5898] Delegate and Forwardable Documentation — James Edward Gray II <james@...>
I've tried to send these files through a couple of times now with
On Sep 22, 2005, at 9:02 AM, James Edward Gray II wrote:
On Sep 22, 2005, at 11:53 AM, James Edward Gray II wrote:
Hi,
On Sep 23, 2005, at 10:54 AM, Yukihiro Matsumoto wrote:
Hi,
On Sep 23, 2005, at 12:31 PM, Yukihiro Matsumoto wrote:
Hi,
[#5901] Re: RubyGems TODO — "Jim Weirich" <jim@...>
>> On 21-Sep-05, at 7:17 PM, why the lucky stiff wrote:
[#5902] Vulnerability fixed in 1.8.3 — Yukihiro Matsumoto <matz@...>
Hi,
See below for a few grammar edits. As a separate issue, I would like
>>>>> "D" == Dominique Brezinski <dominique.brezinski@gmail.com> writes:
Yes, I can read it. You know, there are these things called
On 22 Sep 2005, at 09:36, Dominique Brezinski wrote:
On 9/22/05, Eric Hodel <drbrain@segment7.net> wrote:
[#5921] Mutually dependent libs double loading. — TRANS <transfire@...>
I'm on Ruby 1.8.2.
TRANS wrote:
On 9/22/05, Florian Gro<florgro@gmail.com> wrote:
I'm very suprised I have not gotten an official answer about this. Is
On Sat, 24 Sep 2005, TRANS wrote:
[#5966] $SAFE=4 is still dangerous to use as a sandbox — URABE Shyouhei <s-urabe@...>
This issue has been discussed at security@ruby-lang.org, but matz told
[#5975] segmentation fault on require 'yaml' — Ralph Amissah <ralph.amissah@...>
Status: Open
[#5985] Finally an answer to my RubyGems question and some small suggestions — TRANS <transfire@...>
I appreciate those that attempted to offer me some info on this issue.
On 9/25/05, TRANS <transfire@gmail.com> wrote:
On 9/26/05, Austin Ziegler <halostatue@gmail.com> wrote:
On 9/26/05, TRANS <transfire@gmail.com> wrote:
On 9/26/05, Austin Ziegler <halostatue@gmail.com> wrote:
On 9/26/05, TRANS <transfire@gmail.com> wrote:
On 9/26/05, Austin Ziegler <halostatue@gmail.com> wrote:
[#6001] Require Namepaces and RubyGems' effect on LoadPath problem — TRANS <transfire@...>
I've added namespaces to require. Works like this:
On 9/26/05, TRANS <transfire@gmail.com> wrote:
On 9/26/05, Austin Ziegler <halostatue@gmail.com> wrote:
On 9/26/05, TRANS <transfire@gmail.com> wrote:
On 9/26/05, Austin Ziegler <halostatue@gmail.com> wrote:
TRANS wrote:
Sorry for the delay. I was working hard on an improved implementation.
On 9/29/05, TRANS <transfire@gmail.com> wrote:
On 9/29/05, Austin Ziegler <halostatue@gmail.com> wrote:
On 9/29/05, TRANS <transfire@gmail.com> wrote:
On 9/29/05, Austin Ziegler <halostatue@gmail.com> wrote:
Quoting halostatue@gmail.com, on Tue, Sep 27, 2005 at 06:02:07AM +0900:
On 9/26/05, Sam Roberts <sroberts@uniserve.com> wrote:
Quoting halostatue@gmail.com, on Tue, Sep 27, 2005 at 10:29:17AM +0900:
On Sep 26, 2005, at 8:54 PM, Sam Roberts wrote:
Quoting james@grayproductions.net, on Tue, Sep 27, 2005 at 11:06:01AM +0900:
On 9/26/05, Sam Roberts <sroberts@uniserve.com> wrote:
Quoting halostatue@gmail.com, on Tue, Sep 27, 2005 at 11:49:14AM +0900:
On 9/27/05, Sam Roberts <sroberts@uniserve.com> wrote:
> Right now, they're watching people who have pretty much sat on the side
On 9/27/05, Ralph Amissah <ralph.amissah@gmail.com> wrote:
I'll greatly weaken my post, and give everyone the opportunity to head me
On Wed, 28 Sep 2005, Ralph Amissah wrote:
Hello,
On Wednesday 28 September 2005 07:35 pm, Mauricio Fern疣dez wrote:
On Thu, Sep 29, 2005 at 09:46:45AM +0900, Jim Weirich wrote:
On Sat, Oct 01, 2005 at 12:22:33AM +0900, Jim Weirich wrote:
Hi --
On 9/26/05, Sam Roberts <sroberts@uniserve.com> wrote:
On Monday 26 September 2005 22:41, Austin Ziegler wrote:
On Wed, 28 Sep 2005, Sean E. Russell wrote:
On Wednesday 28 September 2005 08:54, Hugh Sasse wrote:
On Mon, 10 Oct 2005, Sean E. Russell wrote:
Ok, in an attempt to reduce clutter, I'm responding to several people in one
On Monday 26 September 2005 21:29, Austin Ziegler wrote:
On Wed, 2005-09-28 at 20:56 +0900, Sean E. Russell wrote:
Tom Copeland wrote:
On Wednesday 28 September 2005 12:02, James Britt wrote:
On 9/28/05, Sean E. Russell <ser@germane-software.com> wrote:
On 9/28/05, Austin Ziegler <halostatue@gmail.com> wrote:
On 9/28/05, Dominique Brezinski <dominique.brezinski@gmail.com> wrote:
For what it is worth, I live life behind an authenticated proxy, so I
I have got gems to work from behind an authenticated proxy.
On 9/28/05, Jim Freeze <jim@freeze.org> wrote:
Ah, yes, but many proxies require credentials for each new HTTP
On Wednesday 28 September 2005 08:43, Austin Ziegler wrote:
On Fri, 30 Sep 2005, Sean E. Russell wrote:
On 9/30/05, David A. Black <dblack@wobblini.net> wrote:
[#6004] Problem with 1.8.3, extensions — Daniel Berger <Daniel.Berger@...>
Hi all,
[#6009] Re: ruby 1.8.3 (2005-09-21) [i486-linux] sisu segfault — Ralph Amissah <ralph.amissah@...>
(i) correction, segfault is with official ruby 1.8.3 (2005-09-21), not
[sorry for duplicate post]
>>>>> "R" == Ralph Amissah <ralph.amissah@gmail.com> writes:
On 9/27/05, ts <decoux@moulon.inra.fr> wrote:
>>>>> "R" == Ralph Amissah <ralph.amissah@gmail.com> writes:
>>>>> "t" == ts <decoux@moulon.inra.fr> writes:
In article <200509291419.j8TEJYid015419@moulon.inra.fr>,
>>>>> "T" == Tanaka Akira <akr@m17n.org> writes:
ruby 1.8.3 (2005-09-29)
the segfault has returned with the latest ruby build
>>>>> "R" == Ralph Amissah <ralph.amissah@gmail.com> writes:
[#6038] make warning from 1.8.3 — Daniel Berger <Daniel.Berger@...>
Solaris 10
[#6057] YAML loading of quoted Symbols broken in 1.8.3 — noreply@...
Bugs item #2535, was opened at 2005-09-28 11:50
At 01:58 +0900 29 Sep 2005, noreply@rubyforge.org wrote:
[#6076] Question about cgi.rb's read_multipart method and possible fix — "Zev Blut" <rubyzbibd@...>
Hello,
patch for O(1) performance for Array#unshift and Array#shift
Before giving that patch, here are some performance numbers for
n=65536 (the benchmark code is attached):
old (v1.9 from CVS):
user system total real
shift 0.020000 0.000000 0.020000 ( 0.025219)
pop 0.020000 0.000000 0.020000 ( 0.024189)
unshift 3.970000 0.000000 3.970000 ( 5.810518)
push 0.040000 0.000000 0.040000 ( 0.035977)
shift/unshift 9.900000 5.400000 15.300000 ( 15.900842)
pop/push 0.010000 0.000000 0.010000 ( 0.025130)
shift/push 7.760000 5.570000 13.330000 ( 13.995335)
pop/unshift 1.960000 0.000000 1.960000 ( 2.056620)
shift/pop 0.010000 0.000000 0.010000 ( 0.018803)
ushift/push 2.010000 0.000000 2.010000 ( 2.243158)
shift2 0.020000 0.000000 0.020000 ( 0.018887)
pop2 0.010000 0.000000 0.010000 ( 0.018966)
unshift2 2.000000 0.000000 2.000000 ( 2.128590)
push2 0.020000 0.000000 0.020000 ( 0.070644)
shift2/pop2 0.020000 0.000000 0.020000 ( 0.016413)
ushift2/push2 1.000000 0.000000 1.000000 ( 1.007503)
new:
user system total real
shift 0.020000 0.000000 0.020000 ( 0.040953)
pop 0.030000 0.000000 0.030000 ( 0.040594)
unshift 0.030000 0.000000 0.030000 ( 0.052172)
push 0.030000 0.000000 0.030000 ( 0.053591)
shift/unshift 0.020000 0.000000 0.020000 ( 0.035353)
pop/push 0.020000 0.000000 0.020000 ( 0.035218)
shift/push 0.020000 0.000000 0.020000 ( 0.035056)
pop/unshift 0.020000 0.000000 0.020000 ( 0.034636)
shift/pop 0.020000 0.000000 0.020000 ( 0.032797)
ushift/push 0.020000 0.000000 0.020000 ( 0.040963)
shift2 0.020000 0.000000 0.020000 ( 0.032121)
pop2 0.020000 0.000000 0.020000 ( 0.033111)
unshift2 0.020000 0.000000 0.020000 ( 0.033722)
push2 0.020000 0.000000 0.020000 ( 0.033936)
shift2/pop2 0.010000 0.000000 0.010000 ( 0.029171)
ushift2/push2 0.010000 0.000000 0.010000 ( 0.029569)
I didn't solve these (n=8192) where element sharing causes
O(n**2) memory usage (memory blows up with larger n):
shift2/unshift2 0.690000 0.090000 0.780000 ( 0.799305)
pop2/push2 1.090000 0.070000 1.160000 ( 1.179294)
shift2/push2 1.160000 0.080000 1.240000 ( 1.265385)
pop2/unshift2 0.820000 0.090000 0.910000 ( 0.937219)
I accomplished this by using a flag bit (ELTS_LFREE=FL_USER3)
to designate that there is free space to the left of ptr and
ptr[-1] will hold how many elements are free. Just like push
will allocate space with excess space for the array to grow by
50% to the right, unshift now does something similar for growth
to the left of the array (actually preserves some space on both
sides if there was space to the right already).
I just used cvs diff -u to generate the patch attached
(unshift.diff). Not sure if this is the right way.
Matz, is this acceptable? I don't see any downsides and it
gives huge performance increases for Array#shift and
Array#unshift.
Other things that could be done along these same lines include:
- make random all inserts/deletes do the operation toward the
closest end of the array. On average this will double the
random insert/delete performance.
- redo element sharing to not copy the parent array when it is
modified and one or more slices are sharing data with it.
Instead cause the slices to get copies. This would result in
something no worse in terms of memory usage than if sharing
wasn't employed - not something that can be said now.
- when the array needs to be stretched and data needs to be
moved, don't realloc/move. This results in 2 moves typically
because realloc typically has to do a move. Instead alloc
new/move old->new/free old.
- do the same things for string
Eric
__________________________________
Yahoo! Mail - PC Magazine Editors' Choice 2005
http://mail.yahoo.com
Attachments (2)
require 'benchmark'
[1 << 13, 1 << 16].each { |n|
puts
puts("n = #{n}")
n2 = n/2;
n4 = n/4;
a0 = []
an2 = Array.new(n2) { |i| i }
an = Array.new(n) { |i| i }
Benchmark.bmbm { |b|
b.report("shift") {a=an.dup;n.times{a.shift}}
b.report("pop") {a=an.dup;n.times{a.pop}}
b.report("unshift") {a=a0.dup;n.times{|i|a.unshift(i)}}
b.report("push") {a=a0.dup;n.times{|i|a.push(i)}}
b.report("shift/unshift") {a=an2.dup;n2.times{a.unshift(a.shift)}}
b.report("pop/push") {a=an2.dup;n2.times{a.push(a.pop)}}
b.report("shift/push") {a=an2.dup;n2.times{a.push(a.shift)}}
b.report("pop/unshift") {a=an2.dup;n2.times{a.unshift(a.pop)}}
b.report("shift/pop") {a=an.dup;n2.times{a.shift;a.pop}}
b.report("ushift/push") {a=a0.dup;n2.times{|i|a.unshift(i);a.push(i)}}
b.report("shift2") {a=an.dup;n2.times{a.shift(2)}}
b.report("pop2") {a=an.dup;n2.times{a.pop(2)}}
b.report("unshift2") {a=a0.dup;n2.times{|i|a.unshift(i,i)}}
b.report("push2") {a=a0.dup;n2.times{|i|a.push(i,i)}}
b.report("shift2/pop2") {a=an.dup;n4.times{a.shift(2);a.pop(2)}}
b.report("ushift2/push2") {a=a0.dup;n4.times{|i|a.unshift(i,i);a.push(i,i)}}
if n <= (1 << 13)
# these will run out of memory because of element sharing - O(n**2)
b.report("shift2/unshift2") {a=an.dup;n4.times{a.unshift(x=a.shift(2),x)}}
b.report("pop2/push2") {a=an.dup;n4.times{a.push(x=a.pop(2),x)}}
b.report("shift2/push2") {a=an.dup;n4.times{a.push(x=a.shift(2),x)}}
b.report("pop2/unshift2") {a=an.dup;n4.times{a.unshift(x=a.pop(2),x)}}
end
}
}
Index: array.c
===================================================================
RCS file: /src/ruby/array.c,v
retrieving revision 1.179
diff -u -r1.179 array.c
--- array.c 12 Sep 2005 15:23:54 -0000 1.179
+++ array.c 18 Sep 2005 18:50:58 -0000
@@ -211,6 +211,10 @@
shared->len = RARRAY(ary)->len;
shared->ptr = RARRAY(ary)->ptr;
shared->aux.capa = RARRAY(ary)->aux.capa;
+ if (FL_TEST(ary,ELTS_LFREE)) {
+ FL_SET(shared,ELTS_LFREE);
+ FL_UNSET(ary,ELTS_LFREE);
+ }
RARRAY(ary)->aux.shared = (VALUE)shared;
FL_SET(ary, ELTS_SHARED);
OBJ_FREEZE(shared);
@@ -341,7 +345,10 @@
}
rb_ary_modify(ary);
if (len > RARRAY(ary)->aux.capa) {
- REALLOC_N(RARRAY(ary)->ptr, VALUE, len);
+ long lfree = FL_TEST(ary,ELTS_LFREE) ? RARRAY(ary)->ptr[-1] : 0;
+ RARRAY(ary)->ptr -= lfree;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, len + lfree);
+ RARRAY(ary)->ptr += lfree;
RARRAY(ary)->aux.capa = len;
}
if (rb_block_given_p()) {
@@ -400,6 +407,7 @@
rb_ary_modify(ary);
if (idx >= RARRAY(ary)->aux.capa) {
long new_capa = RARRAY(ary)->aux.capa / 2;
+ long lfree = FL_TEST(ary,ELTS_LFREE) ? RARRAY(ary)->ptr[-1] : 0;
if (new_capa < ARY_DEFAULT_SIZE) {
new_capa = ARY_DEFAULT_SIZE;
@@ -408,7 +416,9 @@
if (new_capa * (long)sizeof(VALUE) <= new_capa) {
rb_raise(rb_eArgError, "index too big");
}
- REALLOC_N(RARRAY(ary)->ptr, VALUE, new_capa);
+ RARRAY(ary)->ptr -= lfree;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, new_capa + lfree);
+ RARRAY(ary)->ptr += lfree;
RARRAY(ary)->aux.capa = new_capa;
}
if (idx > RARRAY(ary)->len) {
@@ -500,8 +510,11 @@
if (!FL_TEST(ary, ELTS_SHARED) &&
RARRAY(ary)->len * 2 < RARRAY(ary)->aux.capa &&
RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) {
+ long lfree = FL_TEST(ary,ELTS_LFREE) ? RARRAY(ary)->ptr[-1] : 0;
RARRAY(ary)->aux.capa = RARRAY(ary)->len * 2;
- REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
+ RARRAY(ary)->ptr -= lfree;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa + lfree);
+ RARRAY(ary)->ptr += lfree;
}
return RARRAY(ary)->ptr[--RARRAY(ary)->len];
}
@@ -543,7 +556,15 @@
rb_ary_modify_check(ary);
if (RARRAY(ary)->len == 0) return Qnil;
top = RARRAY(ary)->ptr[0];
- ary_make_shared(ary);
+ if (!FL_TEST(ary,ELTS_SHARED)) {
+ if (FL_TEST(ary,ELTS_LFREE)) {
+ RARRAY(ary)->ptr[0] = RARRAY(ary)->ptr[-1]+1;
+ } else {
+ FL_SET(ary, ELTS_LFREE);
+ RARRAY(ary)->ptr[0] = 1;
+ }
+ RARRAY(ary)->aux.capa--;
+ }
RARRAY(ary)->ptr++; /* shift ptr */
RARRAY(ary)->len--;
@@ -587,28 +608,6 @@
return result;
}
-VALUE
-rb_ary_unshift(VALUE ary, VALUE item)
-{
- rb_ary_modify(ary);
- if (RARRAY(ary)->len == RARRAY(ary)->aux.capa) {
- long capa_inc = RARRAY(ary)->aux.capa / 2;
- if (capa_inc < ARY_DEFAULT_SIZE) {
- capa_inc = ARY_DEFAULT_SIZE;
- }
- RARRAY(ary)->aux.capa += capa_inc;
- REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->aux.capa);
- }
-
- /* sliding items */
- MEMMOVE(RARRAY(ary)->ptr + 1, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
-
- RARRAY(ary)->len++;
- RARRAY(ary)->ptr[0] = item;
-
- return ary;
-}
-
/*
* call-seq:
* array.unshift(obj, ...) -> array
@@ -624,20 +623,52 @@
static VALUE
rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
{
- long len = RARRAY(ary)->len;
-
- if (argc == 0) return ary;
-
- /* make rooms by setting the last item */
- rb_ary_store(ary, len + argc - 1, Qnil);
+ long lfree = FL_TEST(ary,ELTS_LFREE) ? RARRAY(ary)->ptr[-1] : 0;
+
+ rb_ary_modify_check(ary);
- /* sliding items */
- MEMMOVE(RARRAY(ary)->ptr + argc, RARRAY(ary)->ptr, VALUE, len);
+ if (lfree<argc) {
+ int elts_shared = FL_TEST(ary, ELTS_SHARED);
+ long len = RARRAY(ary)->len;
+ long rfree = elts_shared ? 0 : (RARRAY(ary)->aux.capa-len)/2;
+ long free2 = argc+(RARRAY(ary)->len+argc)/2;
+ VALUE *ptr;
+ if (free2 < ARY_DEFAULT_SIZE) {
+ free2 = ARY_DEFAULT_SIZE;
+ }
+ ptr = ALLOC_N(VALUE,len+free2)+(free2-rfree);
+ MEMMOVE(ptr, RARRAY(ary)->ptr, VALUE, len);
+ if (elts_shared) {
+ FL_UNSET(ary, ELTS_SHARED);
+ } else {
+ free(RARRAY(ary)->ptr-lfree);
+ }
+ RARRAY(ary)->ptr = ptr;
+ RARRAY(ary)->aux.capa = len+rfree;
+ lfree = free2-rfree;
+ FL_SET(ary, ELTS_LFREE);
+ }
+
+ RARRAY(ary)->ptr -= argc;
+ RARRAY(ary)->len += argc;
+ RARRAY(ary)->aux.capa += argc;
+ lfree -= argc;
+ if (lfree) {
+ RARRAY(ary)->ptr[-1] = lfree;
+ } else {
+ FL_UNSET(ary, ELTS_LFREE);
+ }
MEMCPY(RARRAY(ary)->ptr, argv, VALUE, argc);
-
+
return ary;
}
+VALUE
+rb_ary_unshift(VALUE ary, VALUE item)
+{
+ return rb_ary_unshift_m(1,&item,ary);
+}
+
/* faster version - use this if you don't need to treat negative offset */
static inline VALUE
rb_ary_elt(VALUE ary, long offset)
@@ -993,7 +1024,10 @@
if (beg >= RARRAY(ary)->len) {
len = beg + rlen;
if (len >= RARRAY(ary)->aux.capa) {
- REALLOC_N(RARRAY(ary)->ptr, VALUE, len);
+ long lfree = FL_TEST(ary,ELTS_LFREE) ? RARRAY(ary)->ptr[-1] : 0;
+ RARRAY(ary)->ptr -= lfree;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, len + lfree);
+ RARRAY(ary)->ptr += lfree;
RARRAY(ary)->aux.capa = len;
}
rb_mem_clear(RARRAY(ary)->ptr + RARRAY(ary)->len, beg - RARRAY(ary)->len);
@@ -1011,7 +1045,10 @@
alen = RARRAY(ary)->len + rlen - len;
if (alen >= RARRAY(ary)->aux.capa) {
- REALLOC_N(RARRAY(ary)->ptr, VALUE, alen);
+ long lfree = FL_TEST(ary,ELTS_LFREE) ? RARRAY(ary)->ptr[-1] : 0;
+ RARRAY(ary)->ptr -= lfree;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, alen + lfree);
+ RARRAY(ary)->ptr += lfree;
RARRAY(ary)->aux.capa = alen;
}
@@ -1752,7 +1789,10 @@
RARRAY(ary)->len = i2;
if (i2 * 2 < RARRAY(ary)->aux.capa &&
RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) {
- REALLOC_N(RARRAY(ary)->ptr, VALUE, i2 * 2);
+ long lfree = FL_TEST(ary,ELTS_LFREE) ? RARRAY(ary)->ptr[-1] : 0;
+ RARRAY(ary)->ptr -= lfree;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, i2 * 2 + lfree);
+ RARRAY(ary)->ptr += lfree;
RARRAY(ary)->aux.capa = i2 * 2;
}
}
@@ -2037,8 +2077,10 @@
orig = to_ary(orig);
if (copy == orig) return copy;
shared = ary_make_shared(orig);
- if (RARRAY(copy)->ptr && !FL_TEST(copy, ELTS_SHARED))
- free(RARRAY(copy)->ptr);
+ if (RARRAY(copy)->ptr && !FL_TEST(copy, ELTS_SHARED)) {
+ long lfree = FL_TEST(copy,ELTS_LFREE) ? RARRAY(copy)->ptr[-1] : 0;
+ free(RARRAY(copy)->ptr-lfree);
+ }
RARRAY(copy)->ptr = RARRAY(orig)->ptr;
RARRAY(copy)->len = RARRAY(orig)->len;
RARRAY(copy)->aux.shared = shared;
@@ -2063,7 +2105,10 @@
rb_ary_modify(ary);
RARRAY(ary)->len = 0;
if (ARY_DEFAULT_SIZE * 2 < RARRAY(ary)->aux.capa) {
- REALLOC_N(RARRAY(ary)->ptr, VALUE, ARY_DEFAULT_SIZE * 2);
+ long lfree = FL_TEST(ary,ELTS_LFREE) ? RARRAY(ary)->ptr[-1] : 0;
+ RARRAY(ary)->ptr -= lfree;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, ARY_DEFAULT_SIZE * 2 + lfree);
+ RARRAY(ary)->ptr += lfree;
RARRAY(ary)->aux.capa = ARY_DEFAULT_SIZE * 2;
}
return ary;
@@ -2132,7 +2177,10 @@
end = beg + len;
if (end > RARRAY(ary)->len) {
if (end >= RARRAY(ary)->aux.capa) {
- REALLOC_N(RARRAY(ary)->ptr, VALUE, end);
+ long lfree = FL_TEST(ary,ELTS_LFREE) ? RARRAY(ary)->ptr[-1] : 0;
+ RARRAY(ary)->ptr -= lfree;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, end + lfree);
+ RARRAY(ary)->ptr += lfree;
RARRAY(ary)->aux.capa = end;
}
if (beg > RARRAY(ary)->len) {
@@ -2661,6 +2709,7 @@
rb_ary_compact_bang(VALUE ary)
{
VALUE *p, *t, *end;
+ long lfree;
rb_ary_modify(ary);
p = t = RARRAY(ary)->ptr;
@@ -2674,7 +2723,10 @@
return Qnil;
}
RARRAY(ary)->len = RARRAY(ary)->aux.capa = (p - RARRAY(ary)->ptr);
- REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
+ lfree = FL_TEST(ary,ELTS_LFREE) ? RARRAY(ary)->ptr[-1] : 0;
+ RARRAY(ary)->ptr -= lfree;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len + lfree);
+ RARRAY(ary)->ptr += lfree;
return ary;
}
Index: gc.c
===================================================================
RCS file: /src/ruby/gc.c,v
retrieving revision 1.209
diff -u -r1.209 gc.c
--- gc.c 14 Sep 2005 08:30:15 -0000 1.209
+++ gc.c 18 Sep 2005 18:50:59 -0000
@@ -1111,7 +1111,8 @@
break;
case T_ARRAY:
if (RANY(obj)->as.array.ptr && !FL_TEST(obj, ELTS_SHARED)) {
- RUBY_CRITICAL(free(RANY(obj)->as.array.ptr));
+ long lfree = FL_TEST(obj,ELTS_LFREE) ? RANY(obj)->as.array.ptr[-1] : 0;
+ RUBY_CRITICAL(free(RANY(obj)->as.array.ptr-lfree));
}
break;
case T_HASH:
Index: ruby.h
===================================================================
RCS file: /src/ruby/ruby.h,v
retrieving revision 1.122
diff -u -r1.122 ruby.h
--- ruby.h 14 Sep 2005 13:40:43 -0000 1.122
+++ ruby.h 18 Sep 2005 18:50:59 -0000
@@ -347,6 +347,7 @@
};
#define ELTS_SHARED FL_USER2
+#define ELTS_LFREE FL_USER3
struct RString {
struct RBasic basic;