[#20189] [Bug #805] Ruby 1.9.1 preview 2 : build failure on OpenSolaris — Dae San Hwang <redmine@...>
Bug #805: Ruby 1.9.1 preview 2 : build failure on OpenSolaris
Hi,
[#20190] Behavior: autoload calls rb_require() directly — Evan Phoenix <evan@...>
Hi everyone,
Hi,
However, that is *not* currently the implementation, and it could introduce
Hi,
Yukihiro Matsumoto wrote:
On Fri, Dec 05, 2008 at 03:25:42AM +0900, Charles Oliver Nutter wrote:
Dave Thomas wrote:
Hi --
2008/12/4 Charles Oliver Nutter <charles.nutter@sun.com>:
Hi,
Yukihiro Matsumoto wrote:
Floats are 64-bits wide, and need at least 1 bit to indicate that the
On Sat, Dec 06, 2008 at 04:46:36AM +0900, Brent Roman wrote:
Hi,
On Mon, 08 Dec 2008 18:21:39 +0900, SASADA Koichi wrote:
Ken Bloom wrote::
On Fri, Dec 05, 2008 at 06:25:08AM +0900, Dave Thomas wrote:
Charles Oliver Nutter wrote:
daz wrote:
On Fri, 05 Dec 2008 09:58:02 +1100, Charles Oliver Nutter
Michael Selig wrote:
On Fri, Dec 05, 2008 at 09:56:19AM +0900, Charles Oliver Nutter wrote:
Except for the frames that are already on stack... that's not so easy.
On Thu, 04 Dec 2008 16:51:10 +0900, Yukihiro Matsumoto wrote:
Evan Phoenix wrote:
On Wed, Dec 03, 2008 at 01:50:42PM +0900, Charles Oliver Nutter wrote:
Paul Brannan wrote:
On Wed, Dec 03, 2008 at 11:49:49PM +0900, Charles Oliver Nutter wrote:
[#20201] Language list in unicode.org — Yukihiro Matsumoto <matz@...>
Hi,
[#20214] Proposal: deferred blocks — "Yehuda Katz" <wycats@...>
Several people have played around with solutions that use ParseTree or
Yehuda Katz wrote:
[#20226] \b and \B with Unicode — Dave Thomas <dave@...>
#encoding: utf-8
[#20235] autoload and concurrency — "Yehuda Katz" <wycats@...>
Merb uses autoload rather extensively. We have lately observed some
This seems like a strong argument in favor of Ruby-core:20225.
Jim Deville wrote:
Charles Oliver Nutter wrote:
Also, this just illustrates that it's possible. In the case of Merb, we
I think it has already been concluded that autoload and require are inheren=
Require could be made safe if only one thread were allowed to execute
SSBtZWFudCB0aGF0IGV2ZW4gaWYgYXV0b2xvYWQgaXMgImZpeGVkIiBieSBhZGRpbmcgc29tZSBr
Except that my proposed fix for autoload would have all secondary
Yehuda Katz wrote:
Charles Oliver Nutter wrote:
Because of this problem, we *will* be removing the use of autoload in 1.1.
On Thu, Dec 4, 2008 at 1:14 AM, Yehuda Katz <wycats@gmail.com> wrote:
[#20241] [Bug #814] NoMethodError: undefined method `read_nonblock' for #<OpenSSL::SSL::SSLSocket:0x1a64f9a0> — Aaron Patterson <redmine@...>
Bug #814: NoMethodError: undefined method `read_nonblock' for #<OpenSSL::SSL::SSLSocket:0x1a64f9a0>
In article <4936125f7242c_8817a7829234b3@redmine.ruby-lang.org>,
Issue #814 has been updated by Aaron Patterson.
Issue #814 has been updated by Tony Arcieri.
In article <49a642ba6184_852787888e668d@redmine.ruby-lang.org>,
On Thu, Feb 26, 2009 at 2:14 AM, Tanaka Akira <akr@fsij.org> wrote:
In article <c7e6b2b00903100000n30f71021ve44c823b0812e163@mail.gmail.com>,
On Tue, Mar 10, 2009 at 2:29 AM, Tanaka Akira <akr@fsij.org> wrote:
[#20273] Tail recursion? — "Robert Dober" <robert.dober@...>
Hi list
Hi,
[#20310] [Bug #822] gets blocks when it shouldn't — Ahmed Saeed <redmine@...>
Bug #822: gets blocks when it shouldn't
[#20345] Achieving C-like performance with more indirection? — Jan Wedekind <jan@...>
I am working on a Ruby-extension for doing real-time computer vision
[#20363] RDoc can't generate documentation of Ruby — hemant <gethemant@...>
Hi,
[#20400] More powerful method arguments — "=?ISO-8859-2?Q?Rados=B3aw_Bu=B3at?=" <radek.bulat@...>
(I'm thinking very loudly, don't get it to seriously)
[#20416] [Feature #839] Add code on each line of a backtrace output to the screen — Roger Pack <redmine@...>
Feature #839: Add code on each line of a backtrace output to the screen
[#20418] Array#to_proc — "Eust痃uio Rangel" <eustaquiorangel@...>
Some months ago I sent a patch to Rails proposing an Array#to_proc the
[#20434] Another Patch for curses extension. — "Giancarlo F Bellido" <support@...>
Hello,
[#20446] [Bug #844] Interpreter wide IO deadlock — "coderrr ." <redmine@...>
Bug #844: Interpreter wide IO deadlock
[#20483] encoding of symbols — Dave Thomas <dave@...>
If I have a source file like this:
Dave Thomas wrote:
Hi,
Hi,
Yukihiro Matsumoto wrote:
On Sat, Dec 13, 2008 at 08:33:13PM +0900, Charles Oliver Nutter wrote:
On Sun, 14 Dec 2008 01:01:44 +1100, Brian Candler <B.Candler@pobox.com>
On Sat, Dec 13, 2008 at 22:57, Michael Selig <michael.selig@fs.com.au> wrot=
On Sun, 14 Dec 2008 11:57:55 +1100, Michael Selig
Hi,
Hi,
> I don't mean to shoot you down in flames, but a lot of thought and effort
> You're right. When we have two strings with identical byte sequence
Hi,
> I am against trancoding before comparison. The applications models
On Thu, Dec 18, 2008 at 06:22:28PM +0900, Daniel Cavanagh wrote:
On Thu, Dec 18, 2008 at 08:43:45AM +0900, danielcavanagh@aanet.com.au wrote:
On 18/12/2008, at 7:24 PM, Brian Candler wrote:
On Sun, Dec 14, 2008 at 09:57:55AM +0900, Michael Selig wrote:
[#20502] [Bug #863] Openssl issues with fresh compile on Ubuntu — Brian Takita <redmine@...>
Bug #863: Openssl issues with fresh compile on Ubuntu
[#20519] [Fwd: [ruby-dev:37282] [Bug #827] Fix document for Gem::Installer#write_spec] — "Yugui (Yuki Sonoda)" <yugui@...>
okkez sent a patch for RubyGems to ruby-dev. He said that rdoc does not
[#20553] [Bug #873] compilation failure — Oleg Puchinin <redmine@...>
Bug #873: compilation failure
[#20564] [Bug #883] Failure: test_handle_special_CROSSREF_no_underscore(TestRDocMarkupToHtmlCrossref) — Kazuhiro NISHIYAMA <redmine@...>
Bug #883: Failure: test_handle_special_CROSSREF_no_underscore(TestRDocMarkupToHtmlCrossref)
[#20576] [Bug #888] zlib 1.2.3 does not work with Rubygems 1.3.1 (in Ruby 1.9.1) on Windows — Chauk-Mean PROUM <redmine@...>
Bug #888: zlib 1.2.3 does not work with Rubygems 1.3.1 (in Ruby 1.9.1) on Windows
Issue #888 has been updated by Yasuhiro MISE.
[#20578] [Feature #889] erb.rb should use Array and << for eoutvar and not String and concat — Thomas Enebo <redmine@...>
Feature #889: erb.rb should use Array and << for eoutvar and not String and concat
Issue #889 has been updated by Kurt Stephens.
[#20601] ruby-mode.el has moved — Phil Hagelberg <phil@...>
[#20606] system() issues on Windows — "James M. Lawrence" <quixoticsycophant@...>
I put together a spec of my grievances with system() on Windows and
[#20620] Proposal: Proc#bind — "Paweł Kondzior" <kondzior.p@...>
SXQgd291bGQgYmUgZ29vZCB0byBoYXZlIFByb2MjYmluZChyZWNlaXZlcikgbWV0aG9kIHRoYXQg
[#20626] ruby take non .rb files? — "Roger Pack" <rogerpack2005@...>
I'm pretty sure this has been discussed before, but what would the
[#20665] best way to handle $: when embedding ruby — Rolando Abarca <funkaster@...>
Hi all,
[#20668] [Feature #905] Add String.new(fixnum) to preallocate large buffer — Charles Nutter <redmine@...>
Feature #905: Add String.new(fixnum) to preallocate large buffer
Issue #905 has been updated by Brian Ford.
Hi
Yukihiro Matsumoto wrote:
Jim Weirich wrote:
Dave Thomas wrote:
Dave Thomas wrote:
Dave Thomas wrote:
Issue #905 has been updated by caleb clausen.
Hi,
Doesn't Ruby allocate already using a "double memory if you run out"
On Fri, 5 Mar 2010, Kornelius Kalnbach wrote:
Issue #905 has been updated by caleb clausen.
On 04.03.10 21:08, caleb clausen wrote:
Hi,
Issue #905 has been updated by Kurt Stephens.
On 05.03.10 01:13, Kurt Stephens wrote:
Hi,
On 3/5/10, Yusuke ENDOH <mame@tsg.ne.jp> wrote:
On Fri, Mar 5, 2010 at 17:25, Caleb Clausen <vikkous@gmail.com> wrote:
Issue #905 has been updated by Kornelius Kalnbach.
[#20669] [Bug #906] File.close not working good in Windows — Yong Lu <redmine@...>
Bug #906: File.close not working good in Windows
[#20695] [Bug #907] Various system() and backticks problems on Windows — "James M. Lawrence" <redmine@...>
Bug #907: Various system() and backticks problems on Windows
[#20699] how is 1.9 able to handle > 1024 sockets? — "Roger Pack" <rogerpack2005@...>
I noticed that select in 1.9 seems to be able to handle more than
[#20706] [Feature #908] Should be an easy way of reading N characters from am I/O stream — Michael Selig <redmine@...>
Feature #908: Should be an easy way of reading N characters from am I/O stream
Issue #908 has been updated by Michael Selig.
In article <4988d2fa997f8_8527a9e32018e7@redmine.ruby-lang.org>,
Hi,
In article <op.uotab6oa9245dp@kool>,
2009/2/14 Tanaka Akira <akr@fsij.org>:
In article <a5d587fb0902141711q780f0d24jef9be9b8bbe69b2a@mail.gmail.com>,
2009/2/15 Tanaka Akira <akr@fsij.org>:
In article <a5d587fb0902160252u56b50cfdv8e0fd36bb4f0b1b3@mail.gmail.com>,
2009/2/18 Tanaka Akira <akr@fsij.org>:
On Thu, 19 Feb 2009 02:21:21 +1100, Michal Suchanek <hramrach@centrum.cz>
In article <op.upklh9q19245dp@kool>,
At 19:00 09/02/19, Tanaka Akira wrote:
In article <6.0.0.20.2.20090220134502.0823ee98@localhost>,
On Mon, 23 Feb 2009 03:00:41 +1100, Tanaka Akira <akr@fsij.org> wrote:
2009/2/22 Michael Selig <michael.selig@fs.com.au>:
2009/2/23 Michal Suchanek <hramrach@centrum.cz>:
On Mon, 23 Feb 2009 21:35:30 +1100, Michal Suchanek <hramrach@centrum.cz>
2009/2/24 Michael Selig <michael.selig@fs.com.au>:
On Thu, 19 Feb 2009 21:00:52 +1100, Tanaka Akira <akr@fsij.org> wrote:
[#20720] Current status of 1.9.1 RC1's issues — "Yugui (Yuki Sonoda)" <yugui@...>
Hi, folks
[#20723] [Bug #911] ArgumentError in Resolv#getaddress — Federico Builes <redmine@...>
Bug #911: ArgumentError in Resolv#getaddress
In article <494d365145bcf_881769c31c84a0@redmine.ruby-lang.org>,
Issue #911 has been updated by Federico Builes.
[#20724] Working with binary strings in Ruby 1.9? — Hadmut Danisch <hadmut@...>
Hi,
On Dec 20, 2008, at 12:49 PM, Hadmut Danisch wrote:
On Sun, 21 Dec 2008 06:43:32 +1100, James Gray <james@grayproductions.net>
[#20734] irb prompt question — "Roger Pack" <rogerpack2005@...>
I'm used to irb giving me indication of continued statements:
[#20754] Array#map and #select overrides — "David A. Black" <dblack@...>
Hi --
[#20794] [Bug #920] require is not thread-safe — Charles Nutter <redmine@...>
Bug #920: require is not thread-safe
[#20797] [Bug #921] autoload is not thread-safe — Charles Nutter <redmine@...>
Bug #921: autoload is not thread-safe
Hi,
Dave Thomas wrote:
[#20874] [Feature #928] RDoc encoding conversion — Yuki Sonoda <redmine@...>
Feature #928: RDoc encoding conversion
[#20877] [ANN] Updated status of the releasing 1.9.1 RC — "Yugui (Yuki Sonoda)" <yugui@...>
Hi, folks
[#20879] [Feature #929] Array#shuffle does not initialize random seed — Justin Collins <redmine@...>
Feature #929: Array#shuffle does not initialize random seed
[#20893] [Bug #932] incorrect case statement in "ext/dl/test/test_base.rb" causes library problems on openSUSE 11.1 64-bit — Ed Borasky <redmine@...>
Bug #932: incorrect case statement in "ext/dl/test/test_base.rb" causes library problems on openSUSE 11.1 64-bit
[#20894] [Bug #933] Fiber class documentation — Muhammad Ali <redmine@...>
Bug #933: Fiber class documentation
[#20938] [Bug #940] ruby/config.h:1:1: warning: "PACKAGE_NAME" redefined — bugmenot bugmenot <redmine@...>
Bug #940: ruby/config.h:1:1: warning: "PACKAGE_NAME" redefined
[#20944] [Bug #942] Build fails on IA-32 Linux with gcc 4.3.2 — Michael Klishin <redmine@...>
Bug #942: Build fails on IA-32 Linux with gcc 4.3.2
[#20978] Definable != is a Bad Thing™ — Ryan Davis <ryand-ruby@...>
> >> class X; def == o; :great; end; def != o; :horrible; end; end
Hi,
Ryan Davis <ryand-ruby@zenspider.com> wrote:
On Fri, Jan 2, 2009 at 01:37, Ken Bloom <kbloom@gmail.com> wrote:
Daniel Luz wrote:
On Fri, Jan 2, 2009 at 12:42 PM, Kornelius Kalnbach <murphy@rubychan.de> wrote:
[#20990] [Bug #951] "make DESTDIR=... install" creates dirs outside DESTDIR — Sven Schwyn <redmine@...>
Bug #951: "make DESTDIR=... install" creates dirs outside DESTDIR
[#20994] [Bug #956] Encoding: nl_langinfo(CODESET) on cygwin 1.5 always returns US-ASCII — Tom Link <redmine@...>
Bug #956: Encoding: nl_langinfo(CODESET) on cygwin 1.5 always returns US-ASCII
Issue #956 has been updated by Tom Link.
Hi,
[#20999] Supporting Thread.critical=with native threads — Shri Borde <Shri.Borde@...>
Hi,
Shri Borde wrote:
WWVzLCBUaHJlYWQja2lsbCBhbmQgVGhyZWFkI3JhaXNlIGNhbiBiZSBpbXBsZW1lbnRlZCBpbiBJ
Shri Borde wrote:
On Dec 30, 2008, at 15:00 PM, Shri Borde wrote:
http://www.ruby-doc.org/core/classes/Thread.html#M000461 says:
I'm starting come around to Shri's idea of critical= being represented
SXMgb3BlbmluZyBhIGJ1ZyB0aGUgcmVjb21tZW5kZWQgd2F5IHRvIGdldCB0aGUgc3BlYyBjaGFu
Brent, we are looking for Ruby to officially allow Thread.critical=3D to be=
Brent Roman wrote:
I disagree on most points, since 1.8 is going to remain the most
[ruby-core:20497] Re: Status of copy-on-write friendly garbage collector
Hi,
In message "Re: [ruby-core:20481] Re: Status of copy-on-write friendly garbage collector"
on Fri, 12 Dec 2008 00:11:52 +0900, "Roger Pack" <rogerpack2005@gmail.com> writes:
|I assume that it works now, and was merged into trunk?
It works now, but have not yet been merged it since it still slows
down non-forking programs. I attach the diff from trunk for those who
want to try and inspect the idea.
matz.
Attachments (1)
diff --git a/debug.c b/debug.c
index bfce7ad..384fbb2 100644
--- a/debug.c
+++ b/debug.c
@@ -31,7 +31,7 @@ static const union {
RUBY_ENC_CODERANGE_7BIT = ENC_CODERANGE_7BIT,
RUBY_ENC_CODERANGE_VALID = ENC_CODERANGE_VALID,
RUBY_ENC_CODERANGE_BROKEN = ENC_CODERANGE_BROKEN,
- RUBY_FL_MARK = FL_MARK,
+ RUBY_FL_ALIGNOFF = FL_ALIGNOFF,
RUBY_FL_RESERVED = FL_RESERVED,
RUBY_FL_FINALIZE = FL_FINALIZE,
RUBY_FL_TAINT = FL_TAINT,
diff --git a/gc.c b/gc.c
index d2ef85f..864143a 100644
--- a/gc.c
+++ b/gc.c
@@ -22,6 +22,7 @@
#include <stdio.h>
#include <setjmp.h>
#include <sys/types.h>
+#include <math.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
@@ -248,6 +249,13 @@ typedef struct RVALUE {
VALUE flags; /* always 0 for freed obj */
struct RVALUE *next;
} free;
+ struct {
+ VALUE flags;
+ struct RVALUE *next;
+ int *map;
+ VALUE slot;
+ int limit;
+ } bitmap;
struct RBasic basic;
struct RObject object;
struct RClass klass;
@@ -279,6 +287,7 @@ struct heaps_slot {
void *membase;
RVALUE *slot;
int limit;
+ RVALUE *bitmap;
};
#define HEAP_MIN_SLOTS 10000
@@ -308,6 +317,7 @@ typedef struct rb_objspace {
RVALUE *freelist;
RVALUE *range[2];
RVALUE *freed;
+ RVALUE *freed_bitmap;
} heap;
struct {
int dont_gc;
@@ -379,22 +389,12 @@ rb_objspace_alloc(void)
#endif
/* tiny heap size */
-/* 32KB */
-/*#define HEAP_SIZE 0x8000 */
-/* 128KB */
-/*#define HEAP_SIZE 0x20000 */
-/* 64KB */
-/*#define HEAP_SIZE 0x10000 */
-/* 16KB */
-#define HEAP_SIZE 0x4000
-/* 8KB */
-/*#define HEAP_SIZE 0x2000 */
-/* 4KB */
-/*#define HEAP_SIZE 0x1000 */
-/* 2KB */
-/*#define HEAP_SIZE 0x800 */
-
-#define HEAP_OBJ_LIMIT (HEAP_SIZE / sizeof(struct RVALUE))
+#define BITMAP_ALIGN 0x4000
+
+/* (16KB/sizeof(RVALUE) + 2) * sizeof(RVALUE) */
+#define HEAP_SIZE 0x4024
+#define BITMAP_MASK 0xFFFFc000
+#define HEAP_OBJ_LIMIT (HEAP_SIZE / sizeof(struct RVALUE) - 1)
extern VALUE rb_cMutex;
extern st_table *rb_class_tbl;
@@ -783,6 +783,149 @@ allocate_heaps(rb_objspace_t *objspace, size_t next_heaps_length)
heaps_length = next_heaps_length;
}
+
+#define FIND_BITMAP(res, p) do {\
+ if (((RVALUE *)p)->as.free.flags & FL_ALIGNOFF) {\
+ res = (RVALUE *)((((VALUE)p & BITMAP_MASK) + BITMAP_ALIGN) / sizeof(RVALUE) * sizeof(RVALUE)); \
+ }\
+ else {\
+ res = (RVALUE *)(((VALUE)p & BITMAP_MASK) / sizeof(RVALUE) * sizeof(RVALUE));\
+ }\
+} while(0)
+
+#define NUM_IN_SLOT(p, slot) (((VALUE)p - (VALUE)slot)/sizeof(RVALUE))
+#define BITMAP_INDEX(bmap, p) (NUM_IN_SLOT(p, bmap->as.bitmap.slot) / (sizeof(int) * 8))
+// #define BITMAP_INDEX(bmap, p) (NUM_IN_SLOT(p, bmap->as.bitmap.slot) >> 5)
+#define BITMAP_OFFSET(bmap, p) (NUM_IN_SLOT(p, bmap->as.bitmap.slot) & ((sizeof(int) * 8)-1))
+#define MARKED_IN_BITMAP(bmap, p) (bmap->as.bitmap.map[BITMAP_INDEX(bmap, p)] & 1 << BITMAP_OFFSET(bmap, p))
+#define MARK_IN_BITMAP(bmap, p) (bmap->as.bitmap.map[BITMAP_INDEX(bmap, p)] |= 1 << BITMAP_OFFSET(bmap, p))
+#define CLEAR_IN_BITMAP(bmap, p) (bmap->as.bitmap.map[BITMAP_INDEX(bmap, p)] &= ~(1 << BITMAP_OFFSET(bmap, p)))
+#define MARKED_IN_BITMAP_DIRECT(map, index, offset) (map[index] & 1 << offset)
+#define MARK_IN_BITMAP_DIRECT(map, index, offset) (map[index] |= 1 << offset)
+
+//for debug
+void
+bitmap_p(RVALUE *p)
+{
+ RVALUE *bmap;
+ int index, offset, marked;
+
+ FIND_BITMAP(bmap, p);
+ index = BITMAP_INDEX(bmap, p);
+ offset = BITMAP_OFFSET(bmap, p);
+ marked = MARKED_IN_BITMAP(bmap, p);
+ printf("bitmap : ((RVALUE *)%p)\n", bmap);
+ printf("map_index : %d | offset : %d\n", index, offset);
+ printf("is mark ? %s\n", marked? "true" : "false");
+}
+
+VALUE
+find_bitmap(RVALUE *p) {
+ RVALUE *res;
+
+ FIND_BITMAP(res, p);
+ return (VALUE)res;
+}
+
+void
+dump_bitmap(RVALUE *bmap) {
+ int i;
+
+ for (i = 0; i < 26; i++) {
+ printf("dump %p map %d : %d %s\n", bmap, i, bmap->as.bitmap.map[i], bmap->as.bitmap.map[i]? "remain" : "clean");
+ }
+}
+
+void
+bitmap2obj(RVALUE *bmap, int index, int offset)
+{
+ printf("(RVALUE *)%p\n", (RVALUE *)(bmap->as.bitmap.slot + (index * sizeof(int) * 8 + offset) * sizeof(RVALUE)));
+}
+
+
+static void
+make_bitmap(struct heaps_slot *slot)
+{
+ RVALUE *p, *pend, *bitmap, *last, *border;
+ int *map = 0;
+ int size;
+
+ p = slot->slot;
+ pend = p + slot->limit;
+ last = pend - 1;
+ RBASIC(last)->flags = 0;
+ FIND_BITMAP(bitmap, last);
+ if (bitmap < p || pend <= bitmap) {
+ rb_bug("not include in heap slot: result bitmap(%p), find (%p), p (%p), pend(%p)", bitmap, last, p, pend);
+ }
+ border = bitmap;
+ if (!((VALUE)border % BITMAP_ALIGN)) {
+ border--;
+ }
+ while (p < pend) {
+ if (p <= border) {
+ RBASIC(p)->flags = FL_ALIGNOFF;
+ }
+ else {
+ RBASIC(p)->flags = 0;
+ }
+ p++;
+ }
+
+ size = sizeof(int) * (HEAP_OBJ_LIMIT / (sizeof(int) * 8)+1);
+ map = (int *)malloc(size);
+ if (map == 0) {
+ rb_memerror();
+ }
+ MEMZERO(map, int, (size/sizeof(int)));
+ bitmap->as.bitmap.flags |= T_BITMAP;
+ bitmap->as.bitmap.map = map;
+ bitmap->as.bitmap.slot = (VALUE)slot->slot;
+ bitmap->as.bitmap.limit = slot->limit;
+ slot->bitmap = bitmap;
+}
+
+void
+test_bitmap(RVALUE *p, RVALUE *pend)
+{
+ RVALUE *first, *bmap = 0, *bmap_tmp;
+ int i;
+
+ first = p;
+ FIND_BITMAP(bmap_tmp, p);
+ while (p < pend) {
+ if (MARKED_IN_BITMAP(bmap, p)) printf("already marking! %p\n", p);
+ if (bmap_tmp != p) {
+ FIND_BITMAP(bmap, p);
+ if (bmap_tmp != bmap) printf("diffrence bmap %p : %p\n", bmap_tmp, bmap);
+ MARK_IN_BITMAP(bmap, p);
+ }
+ else {
+ MARK_IN_BITMAP(bmap, p);
+ }
+ if (!MARKED_IN_BITMAP(bmap, p)) printf("not marking! %p\n", p);
+ p++;
+ }
+ for (i =0; i < 26; i++) {
+ printf("bitmap[%d] : %x\n", i, bmap->as.bitmap.map[i]);
+ }
+ p = first;
+ while (p < pend) {
+ if (bmap_tmp != p) {
+ FIND_BITMAP(bmap, p);
+ CLEAR_IN_BITMAP(bmap, p);
+ }
+ else {
+ CLEAR_IN_BITMAP(bmap, p);
+ }
+ if (MARKED_IN_BITMAP(bmap, p)) printf("not clear! %p\n", p);
+ p++;
+ }
+ for (i =0; i < 26; i++) {
+ printf("bitmap[%d] : %x\n", i, bmap->as.bitmap.map[i]);
+ }
+}
+
static void
assign_heap_slot(rb_objspace_t *objspace)
{
@@ -801,9 +944,6 @@ assign_heap_slot(rb_objspace_t *objspace)
membase = p;
if ((VALUE)p % sizeof(RVALUE) != 0) {
p = (RVALUE*)((VALUE)p + sizeof(RVALUE) - ((VALUE)p % sizeof(RVALUE)));
- if ((HEAP_SIZE - HEAP_OBJ_LIMIT * sizeof(RVALUE)) < ((char*)p - (char*)membase)) {
- objs--;
- }
}
lo = 0;
@@ -825,6 +965,7 @@ assign_heap_slot(rb_objspace_t *objspace)
if (hi < heaps_used) {
MEMMOVE(&heaps[hi+1], &heaps[hi], struct heaps_slot, heaps_used - hi);
}
+
heaps[hi].membase = membase;
heaps[hi].slot = p;
heaps[hi].limit = objs;
@@ -833,10 +974,12 @@ assign_heap_slot(rb_objspace_t *objspace)
if (himem < pend) himem = pend;
heaps_used++;
+ make_bitmap(&heaps[hi]);
while (p < pend) {
- p->as.free.flags = 0;
- p->as.free.next = freelist;
- freelist = p;
+ if (BUILTIN_TYPE(p) != T_BITMAP) {
+ p->as.free.next = freelist;
+ freelist = p;
+ }
p++;
}
}
@@ -888,6 +1031,7 @@ static VALUE
rb_newobj_from_heap(rb_objspace_t *objspace)
{
VALUE obj;
+ int bmap_left = 0;
if ((ruby_gc_stress && !ruby_disable_gc_stress) || !freelist) {
if (!heaps_increment(objspace) && !garbage_collect(objspace)) {
@@ -899,7 +1043,13 @@ rb_newobj_from_heap(rb_objspace_t *objspace)
obj = (VALUE)freelist;
freelist = freelist->as.free.next;
+ if (RANY(obj)->as.free.flags & FL_ALIGNOFF) {
+ bmap_left = Qtrue;
+ }
MEMZERO((void*)obj, RVALUE, 1);
+ if (bmap_left) {
+ RANY(obj)->as.free.flags = FL_ALIGNOFF;
+ }
#ifdef GC_DEBUG
RANY(obj)->file = rb_sourcefile();
RANY(obj)->line = rb_sourceline();
@@ -915,13 +1065,15 @@ rb_fill_value_cache(rb_thread_t *th)
rb_objspace_t *objspace = &rb_objspace;
int i;
VALUE rv;
+ RVALUE *bmap;
/* LOCK */
for (i=0; i<RUBY_VM_VALUE_CACHE_SIZE; i++) {
VALUE v = rb_newobj_from_heap(objspace);
th->value_cache[i] = v;
- RBASIC(v)->flags = FL_MARK;
+ FIND_BITMAP(bmap, v);
+ MARK_IN_BITMAP(bmap, v);
}
th->value_cache_ptr = &th->value_cache[0];
rv = rb_newobj_from_heap(objspace);
@@ -960,7 +1112,7 @@ rb_newobj(void)
#if USE_VALUE_CACHE
if (v) {
- RBASIC(v)->flags = 0;
+ FL_FORCE_SET(p, 0);
th->value_cache_ptr++;
}
else {
@@ -1085,18 +1237,21 @@ init_mark_stack(rb_objspace_t *objspace)
static void gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev);
static void gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev);
+#define IS_FREE_CELL(obj) ((obj->as.basic.flags & ~(FL_ALIGNOFF)) == 0)
+
static void
gc_mark_all(rb_objspace_t *objspace)
{
- RVALUE *p, *pend;
+ RVALUE *p, *pend, *bmap;
size_t i;
init_mark_stack(objspace);
for (i = 0; i < heaps_used; i++) {
p = heaps[i].slot; pend = p + heaps[i].limit;
+ bmap = heaps[i].bitmap;
while (p < pend) {
- if ((p->as.basic.flags & FL_MARK) &&
- (p->as.basic.flags != FL_MARK)) {
+ if (MARKED_IN_BITMAP(bmap, p) &&
+ !(IS_FREE_CELL(p))) {
gc_mark_children(objspace, (VALUE)p, 0);
}
p++;
@@ -1271,13 +1426,15 @@ rb_gc_mark_maybe(VALUE obj)
static void
gc_mark(rb_objspace_t *objspace, VALUE ptr, int lev)
{
- register RVALUE *obj;
+ register RVALUE *obj, *bmap;
obj = RANY(ptr);
if (rb_special_const_p(ptr)) return; /* special const not marked */
- if (obj->as.basic.flags == 0) return; /* free cell */
- if (obj->as.basic.flags & FL_MARK) return; /* already marked */
- obj->as.basic.flags |= FL_MARK;
+ if (IS_FREE_CELL(obj)) return; /* free cell */
+ if (BUILTIN_TYPE(obj) == T_BITMAP) return;
+ FIND_BITMAP(bmap, obj);
+ if (MARKED_IN_BITMAP(bmap, obj)) return; /* already marked */
+ MARK_IN_BITMAP(bmap, obj);
if (lev > GC_LEVEL_MAX || (lev == 0 && stack_check())) {
if (!mark_stack_overflow) {
@@ -1303,16 +1460,17 @@ rb_gc_mark(VALUE ptr)
static void
gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
{
- register RVALUE *obj = RANY(ptr);
+ register RVALUE *obj = RANY(ptr), *bmap;
goto marking; /* skip */
again:
obj = RANY(ptr);
if (rb_special_const_p(ptr)) return; /* special const not marked */
- if (obj->as.basic.flags == 0) return; /* free cell */
- if (obj->as.basic.flags & FL_MARK) return; /* already marked */
- obj->as.basic.flags |= FL_MARK;
+ if (IS_FREE_CELL(obj)) return; /* free cell */
+ FIND_BITMAP(bmap, obj);
+ if (MARKED_IN_BITMAP(bmap, obj)) return; /* already marked */
+ MARK_IN_BITMAP(bmap, obj);
marking:
if (FL_TEST(obj, FL_EXIVAR)) {
@@ -1573,8 +1731,12 @@ static int obj_free(rb_objspace_t *, VALUE);
static inline void
add_freelist(rb_objspace_t *objspace, RVALUE *p)
{
+ RVALUE *bmap;
+
VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
- p->as.free.flags = 0;
+ FL_FORCE_SET(p, 0);
+ FIND_BITMAP(bmap, p);
+ CLEAR_IN_BITMAP(bmap, p);
p->as.free.next = freelist;
freelist = p;
}
@@ -1600,15 +1762,17 @@ static void
free_unused_heaps(rb_objspace_t *objspace)
{
size_t i, j;
- RVALUE *last = 0;
+ RVALUE *last = 0, *bmap = 0;
for (i = j = 1; j < heaps_used; i++) {
if (heaps[i].limit == 0) {
if (!last) {
last = heaps[i].membase;
+ bmap = heaps[i].bitmap;
}
else {
free(heaps[i].membase);
+ free(heaps[i].bitmap->as.bitmap.map);
}
heaps_used--;
}
@@ -1622,10 +1786,13 @@ free_unused_heaps(rb_objspace_t *objspace)
if (last) {
if (last < heaps_freed) {
free(heaps_freed);
+ free(objspace->heap.freed_bitmap->as.bitmap.map);
heaps_freed = last;
+ heaps_freed = bmap;
}
else {
free(last);
+ free(bmap->as.bitmap.map);
}
}
}
@@ -1653,25 +1820,35 @@ gc_sweep(rb_objspace_t *objspace)
int free_num = 0, final_num = 0;
RVALUE *free = freelist;
RVALUE *final = final_list;
- int deferred;
+ int *map = heaps[i].bitmap->as.bitmap.map;
+ int deferred, bmap_index = 0, bmap_offset = 0;
p = heaps[i].slot; pend = p + heaps[i].limit;
while (p < pend) {
- if (!(p->as.basic.flags & FL_MARK)) {
- if (p->as.basic.flags &&
+ if (BUILTIN_TYPE(p) == T_BITMAP) {
+ free_num++;
+ }
+ else if(!(MARKED_IN_BITMAP_DIRECT(map, bmap_index, bmap_offset))) {
+ if (!(IS_FREE_CELL(p)) &&
((deferred = obj_free(objspace, (VALUE)p)) ||
((FL_TEST(p, FL_FINALIZE)) && need_call_final))) {
if (!deferred) {
- p->as.free.flags = T_ZOMBIE;
+ FL_FORCE_SET(p, T_ZOMBIE);
RDATA(p)->dfree = 0;
}
- p->as.free.flags |= FL_MARK;
p->as.free.next = final_list;
final_list = p;
final_num++;
}
else {
- add_freelist(objspace, p);
+ /* Do not touch the fields if they don't have to be modified.
+ * This is in order to preserve copy-on-write semantics.
+ */
+ if (!IS_FREE_CELL(p))
+ FL_FORCE_SET(p, 0);
+ if (p->as.free.next != freelist)
+ p->as.free.next = freelist;
+ freelist = p;
free_num++;
}
}
@@ -1680,11 +1857,16 @@ gc_sweep(rb_objspace_t *objspace)
/* do nothing remain marked */
}
else {
- RBASIC(p)->flags &= ~FL_MARK;
live++;
}
p++;
+ bmap_offset++;
+ if (bmap_offset >= (sizeof(int) * 8)) {
+ bmap_index++;
+ bmap_offset = 0;
+ }
}
+ MEMZERO(heaps[i].bitmap->as.bitmap.map, int, bmap_index+1);
if (final_num + free_num == heaps[i].limit && freed > do_heap_free) {
RVALUE *pp;
@@ -1714,11 +1896,16 @@ gc_sweep(rb_objspace_t *objspace)
/* clear finalization list */
if (final_list) {
+ RVALUE *bmap, *pp;
+ for (pp = final_list; pp != 0; pp = pp->as.free.next) {
+ FIND_BITMAP(bmap, pp);
+ MARK_IN_BITMAP(bmap, pp);
+ }
GC_PROF_SET_HEAP_INFO;
deferred_final_list = final_list;
RUBY_VM_SET_FINALIZER_INTERRUPT(GET_THREAD());
}
- else{
+ else {
free_unused_heaps(objspace);
GC_PROF_SET_HEAP_INFO;
}
@@ -1734,7 +1921,7 @@ rb_gc_force_recycle(VALUE p)
static inline void
make_deferred(RVALUE *p)
{
- p->as.basic.flags = (p->as.basic.flags & ~T_MASK) | T_ZOMBIE;
+ FL_FORCE_SET(p, ((p->as.basic.flags & ~T_MASK) | T_ZOMBIE));
}
static inline void
@@ -2102,12 +2289,13 @@ os_obj_of(rb_objspace_t *objspace, VALUE of)
p = heaps[i].slot; pend = p + heaps[i].limit;
for (;p < pend; p++) {
- if (p->as.basic.flags) {
+ if (!IS_FREE_CELL(p)) {
switch (BUILTIN_TYPE(p)) {
case T_NONE:
case T_ICLASS:
case T_NODE:
case T_ZOMBIE:
+ case T_BITMAP:
continue;
case T_CLASS:
if (FL_TEST(p, FL_SINGLETON)) continue;
@@ -2311,10 +2499,12 @@ rb_gc_finalize_deferred(void)
static int
chain_finalized_object(st_data_t key, st_data_t val, st_data_t arg)
{
- RVALUE *p = (RVALUE *)key, **final_list = (RVALUE **)arg;
+ RVALUE *p = (RVALUE *)key, **final_list = (RVALUE **)arg, *bmap;
if (p->as.basic.flags & FL_FINALIZE) {
if (BUILTIN_TYPE(p) != T_ZOMBIE) {
- p->as.free.flags = FL_MARK | T_ZOMBIE; /* remain marked */
+ FL_FORCE_SET(p, T_ZOMBIE);
+ FIND_BITMAP(bmap, p);
+ MARK_IN_BITMAP(bmap, p);
RDATA(p)->dfree = 0;
}
p->as.free.next = *final_list;
@@ -2358,7 +2548,7 @@ rb_gc_call_finalizer_at_exit(void)
if (BUILTIN_TYPE(p) == T_DATA &&
DATA_PTR(p) && RANY(p)->as.data.dfree &&
RANY(p)->as.basic.klass != rb_cThread && RANY(p)->as.basic.klass != rb_cMutex) {
- p->as.free.flags = 0;
+ FL_FORCE_SET(p, 0);
if ((long)RANY(p)->as.data.dfree == -1) {
xfree(DATA_PTR(p));
}
@@ -2372,6 +2562,7 @@ rb_gc_call_finalizer_at_exit(void)
if (RANY(p)->as.file.fptr) {
make_io_deferred(RANY(p));
RANY(p)->as.free.next = final_list;
+ FL_FORCE_SET(p, 0);
final_list = p;
}
}
@@ -2564,7 +2755,7 @@ count_objects(int argc, VALUE *argv, VALUE os)
p = heaps[i].slot; pend = p + heaps[i].limit;
for (;p < pend; p++) {
- if (p->as.basic.flags) {
+ if (!IS_FREE_CELL(p)) {
counts[BUILTIN_TYPE(p)]++;
}
else {
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index b1fe650..40eca5f 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -310,6 +310,7 @@ enum ruby_value_type {
RUBY_T_FALSE = 0x13,
RUBY_T_SYMBOL = 0x14,
RUBY_T_FIXNUM = 0x15,
+ RUBY_T_BITMAP = 0x19,
RUBY_T_UNDEF = 0x1b,
RUBY_T_NODE = 0x1c,
@@ -334,6 +335,7 @@ enum ruby_value_type {
#define T_BIGNUM RUBY_T_BIGNUM
#define T_FILE RUBY_T_FILE
#define T_FIXNUM RUBY_T_FIXNUM
+#define T_BITMAP RUBY_T_BITMAP
#define T_TRUE RUBY_T_TRUE
#define T_FALSE RUBY_T_FALSE
#define T_DATA RUBY_T_DATA
@@ -499,9 +501,17 @@ char *rb_str2cstr(VALUE,long*);
#define CHR2FIX(x) INT2FIX((long)((x)&0xff))
VALUE rb_newobj(void);
+#define FL_FORCE_SET(obj,t) do {\
+ if (RBASIC(obj)->flags & FL_ALIGNOFF) {\
+ RBASIC(obj)->flags = FL_ALIGNOFF | t;\
+ }\
+ else {\
+ RBASIC(obj)->flags = t;\
+ }\
+} while(0)
#define NEWOBJ(obj,type) type *obj = (type*)rb_newobj()
#define OBJSETUP(obj,c,t) do {\
- RBASIC(obj)->flags = (t);\
+ FL_FORCE_SET(obj, t);\
RBASIC(obj)->klass = (c);\
if (rb_safe_level() >= 3) FL_SET(obj, FL_TAINT | FL_UNTRUSTED);\
} while (0)
@@ -777,7 +787,7 @@ struct RBignum {
#define RCOMPLEX(obj) (R_CAST(RComplex)(obj))
#define FL_SINGLETON FL_USER0
-#define FL_MARK (((VALUE)1)<<5)
+#define FL_ALIGNOFF (((VALUE)1)<<5)
#define FL_RESERVED (((VALUE)1)<<6) /* will be used in the future GC */
#define FL_FINALIZE (((VALUE)1)<<7)
#define FL_TAINT (((VALUE)1)<<8)
diff --git a/object.c b/object.c
index be99de6..7cc9f32 100644
--- a/object.c
+++ b/object.c
@@ -233,7 +233,8 @@ rb_obj_clone(VALUE obj)
}
clone = rb_obj_alloc(rb_obj_class(obj));
RBASIC(clone)->klass = rb_singleton_class_clone(obj);
- RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT) | FL_TEST(clone, FL_UNTRUSTED)) & ~(FL_FREEZE|FL_FINALIZE);
+ RBASIC(clone)->flags = ((RBASIC(obj)->flags & ~(FL_ALIGNOFF|FL_FREEZE|FL_FINALIZE)) |
+ FL_TEST(clone, FL_ALIGNOFF|FL_TAINT|FL_UNTRUSTED));
init_copy(clone, obj);
RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE;
diff --git a/vm.c b/vm.c
index 782fc99..11d0ebe 100644
--- a/vm.c
+++ b/vm.c
@@ -1479,7 +1479,7 @@ thread_free(void *ptr)
VALUE *ptr = th->value_cache_ptr;
while (*ptr) {
VALUE v = *ptr;
- RBASIC(v)->flags = 0;
+ FL_FORCE_SET(v, 0);
RBASIC(v)->klass = 0;
ptr++;
}
@@ -1789,7 +1789,7 @@ Init_VM(void)
/* ::VM::FrozenCore */
fcore = rb_class_new(rb_cBasicObject);
- RBASIC(fcore)->flags = T_ICLASS;
+ FL_FORCE_SET(fcore, T_ICLASS);
klass = rb_singleton_class(fcore);
rb_define_method_id(klass, id_core_set_method_alias, m_core_set_method_alias, 3);
rb_define_method_id(klass, id_core_set_variable_alias, m_core_set_variable_alias, 2);