summaryrefslogtreecommitdiff
path: root/include/ruby
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-10-30 21:53:56 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-10-30 21:53:56 +0000
commit312b105d0e263a36c129a14f2681fe16905c0244 (patch)
tree00bf11825e6f8a8cb12ba1f2c02c722f35090e0c /include/ruby
parent69b8ffcd5b8b28c56212368a3fe66f076b90e4c4 (diff)
introduce TransientHeap. [Bug #14858]
* transient_heap.c, transient_heap.h: implement TransientHeap (theap). theap is designed for Ruby's object system. theap is like Eden heap on generational GC terminology. theap allocation is very fast because it only needs to bump up pointer and deallocation is also fast because we don't do anything. However we need to evacuate (Copy GC terminology) if theap memory is long-lived. Evacuation logic is needed for each type. See [Bug #14858] for details. * array.c: Now, theap for T_ARRAY is supported. ary_heap_alloc() tries to allocate memory area from theap. If this trial sccesses, this array has theap ptr and RARRAY_TRANSIENT_FLAG is turned on. We don't need to free theap ptr. * ruby.h: RARRAY_CONST_PTR() returns malloc'ed memory area. It menas that if ary is allocated at theap, force evacuation to malloc'ed memory. It makes programs slow, but very compatible with current code because theap memory can be evacuated (theap memory will be recycled). If you want to get transient heap ptr, use RARRAY_CONST_PTR_TRANSIENT() instead of RARRAY_CONST_PTR(). If you can't understand when evacuation will occur, use RARRAY_CONST_PTR(). (re-commit of r65444) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65449 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'include/ruby')
-rw-r--r--include/ruby/ruby.h30
1 files changed, 25 insertions, 5 deletions
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index a05651ac3b..1512e78179 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -1020,12 +1020,15 @@ enum ruby_rarray_flags {
RARRAY_EMBED_LEN_MASK = (RUBY_FL_USER4|RUBY_FL_USER3),
RARRAY_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+3),
+ RARRAY_TRANSIENT_FLAG = RUBY_FL_USER13,
+
RARRAY_ENUM_END
};
#define RARRAY_EMBED_FLAG (VALUE)RARRAY_EMBED_FLAG
#define RARRAY_EMBED_LEN_MASK (VALUE)RARRAY_EMBED_LEN_MASK
#define RARRAY_EMBED_LEN_MAX RARRAY_EMBED_LEN_MAX
#define RARRAY_EMBED_LEN_SHIFT RARRAY_EMBED_LEN_SHIFT
+#define RARRAY_TRANSIENT_FLAG RARRAY_TRANSIENT_FLAG
struct RArray {
struct RBasic basic;
union {
@@ -1046,9 +1049,14 @@ struct RArray {
#define RARRAY_LEN(a) rb_array_len(a)
#define RARRAY_LENINT(ary) rb_long2int(RARRAY_LEN(ary))
#define RARRAY_CONST_PTR(a) rb_array_const_ptr(a)
+#define RARRAY_CONST_PTR_TRANSIENT(a) rb_array_const_ptr_transient(a)
+#define RARRAY_TRANSIENT_P(ary) FL_TEST_RAW((ary), RARRAY_TRANSIENT_FLAG)
+
+VALUE *rb_ary_ptr_use_start(VALUE ary);
+void rb_ary_ptr_use_end(VALUE ary);
-#define RARRAY_PTR_USE_START(a) ((VALUE *)RARRAY_CONST_PTR(a))
-#define RARRAY_PTR_USE_END(a) /* */
+#define RARRAY_PTR_USE_START(a) rb_ary_ptr_use_start(a)
+#define RARRAY_PTR_USE_END(a) rb_ary_ptr_use_end(a)
#define RARRAY_PTR_USE(ary, ptr_name, expr) do { \
const VALUE _ary = (ary); \
@@ -1057,11 +1065,12 @@ struct RArray {
RARRAY_PTR_USE_END(_ary); \
} while (0)
-#define RARRAY_AREF(a, i) (RARRAY_CONST_PTR(a)[i])
+#define RARRAY_AREF(a, i) (RARRAY_CONST_PTR_TRANSIENT(a)[i])
#define RARRAY_ASET(a, i, v) do { \
const VALUE _ary = (a); \
+ const VALUE _v = (v); \
VALUE *ptr = (VALUE *)RARRAY_PTR_USE_START(_ary); \
- RB_OBJ_WRITE(_ary, &ptr[i], (v)); \
+ RB_OBJ_WRITE(_ary, &ptr[i], _v); \
RARRAY_PTR_USE_END(_ary); \
} while (0)
@@ -2110,12 +2119,23 @@ rb_array_len(VALUE a)
#endif
static inline const VALUE *
-rb_array_const_ptr(VALUE a)
+rb_array_const_ptr_transient(VALUE a)
{
return FIX_CONST_VALUE_PTR((RBASIC(a)->flags & RARRAY_EMBED_FLAG) ?
RARRAY(a)->as.ary : RARRAY(a)->as.heap.ptr);
}
+void rb_ary_detransient(VALUE a);
+
+static inline const VALUE *
+rb_array_const_ptr(VALUE a)
+{
+ if (RARRAY_TRANSIENT_P(a)) {
+ rb_ary_detransient(a);
+ }
+ return rb_array_const_ptr_transient(a);
+}
+
#if defined(EXTLIB) && defined(USE_DLN_A_OUT)
/* hook for external modules */
static char *dln_libs_to_be_linked[] = { EXTLIB, 0 };