fastruby 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +2 -2
- data/ext/fastruby_base/fastruby_base.inl +222 -0
- data/lib/fastruby.rb +1 -1
- metadata +4 -3
data/Rakefile
CHANGED
@@ -7,7 +7,7 @@ require "rspec/core/rake_task"
|
|
7
7
|
|
8
8
|
spec = Gem::Specification.new do |s|
|
9
9
|
s.name = 'fastruby'
|
10
|
-
s.version = '0.0.
|
10
|
+
s.version = '0.0.11'
|
11
11
|
s.author = 'Dario Seminara'
|
12
12
|
s.email = 'robertodarioseminara@gmail.com'
|
13
13
|
s.platform = Gem::Platform::RUBY
|
@@ -19,7 +19,7 @@ spec = Gem::Specification.new do |s|
|
|
19
19
|
s.extra_rdoc_files = [ 'README' ]
|
20
20
|
s.extensions = FileList["ext/**/extconf.rb"].to_a
|
21
21
|
# s.rdoc_options << '--main' << 'README'
|
22
|
-
s.files = Dir.glob("{benchmarks,examples,lib,spec}/**/*") + Dir.glob("ext/**/*.c") + Dir.glob("ext/**/*.h") + Dir.glob("ext/**/extconf.rb") +
|
22
|
+
s.files = Dir.glob("{benchmarks,examples,lib,spec}/**/*") + Dir.glob("ext/**/*.inl")+ Dir.glob("ext/**/*.c") + Dir.glob("ext/**/*.h") + Dir.glob("ext/**/extconf.rb") +
|
23
23
|
[ 'LICENSE', 'AUTHORS', 'README', 'Rakefile', 'TODO', 'CHANGELOG' ]
|
24
24
|
end
|
25
25
|
|
@@ -0,0 +1,222 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "node.h"
|
3
|
+
#include "env.h"
|
4
|
+
|
5
|
+
VALUE rb_cStackChunk;
|
6
|
+
VALUE rb_cFastRubyThreadData;
|
7
|
+
VALUE rb_cStackChunkReference;
|
8
|
+
VALUE rb_mFastRuby;
|
9
|
+
|
10
|
+
ID id_fastruby_thread_data;
|
11
|
+
|
12
|
+
#define PAGE_SIZE 0x1000
|
13
|
+
#define NUM_PAGES 0x1000
|
14
|
+
#define PAGE_MASK 0xFFF
|
15
|
+
|
16
|
+
struct STACKCHUNK {
|
17
|
+
VALUE* pages[NUM_PAGES];
|
18
|
+
int current_position;
|
19
|
+
int frozen;
|
20
|
+
};
|
21
|
+
|
22
|
+
struct FASTRUBYTHREADDATA {
|
23
|
+
VALUE exception;
|
24
|
+
VALUE accumulator;
|
25
|
+
VALUE rb_stack_chunk;
|
26
|
+
};
|
27
|
+
|
28
|
+
|
29
|
+
static inline void stack_chunk_initialize(struct STACKCHUNK* sc) {
|
30
|
+
// initialize pointers with zeros
|
31
|
+
memset(sc->pages, 0, sizeof(sc->pages));
|
32
|
+
|
33
|
+
sc->current_position = 0;
|
34
|
+
sc->frozen = 0;
|
35
|
+
}
|
36
|
+
|
37
|
+
static inline int stack_chunk_frozen(struct STACKCHUNK* sc) {
|
38
|
+
return sc->frozen;
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
static inline void stack_chunk_freeze(struct STACKCHUNK* sc) {
|
43
|
+
sc->frozen = 1;
|
44
|
+
}
|
45
|
+
|
46
|
+
static inline int stack_chunk_get_current_position(struct STACKCHUNK* sc) {
|
47
|
+
return sc->current_position;
|
48
|
+
}
|
49
|
+
|
50
|
+
static inline void stack_chunk_set_current_position(struct STACKCHUNK* sc, int position) {
|
51
|
+
if (sc->frozen == 0) {
|
52
|
+
sc->current_position = position;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
|
57
|
+
static inline void* stack_chunk_alloc(struct STACKCHUNK* sc, int size){
|
58
|
+
|
59
|
+
if (sc->frozen) {
|
60
|
+
rb_raise(rb_eSysStackError,"Trying to alloc frozen object");
|
61
|
+
}
|
62
|
+
|
63
|
+
void *address = 0;
|
64
|
+
int position_in_page = sc->current_position & PAGE_MASK;
|
65
|
+
int page = sc->current_position / PAGE_SIZE;
|
66
|
+
|
67
|
+
if (position_in_page+size >= PAGE_SIZE) {
|
68
|
+
|
69
|
+
int new_page = page+1;
|
70
|
+
|
71
|
+
if (new_page >= NUM_PAGES) {
|
72
|
+
rb_raise(rb_eSysStackError,"stack level too deep");
|
73
|
+
}
|
74
|
+
|
75
|
+
if (sc->pages[new_page ] == 0) {
|
76
|
+
// alloc the page corresponding for the new stack position
|
77
|
+
sc->pages[new_page] = malloc(PAGE_SIZE*sizeof(VALUE));
|
78
|
+
}
|
79
|
+
// alloc new page
|
80
|
+
int i;
|
81
|
+
|
82
|
+
for (i=position_in_page; i<PAGE_SIZE; i++) {
|
83
|
+
sc->pages[page][i] = Qfalse;
|
84
|
+
}
|
85
|
+
|
86
|
+
for (i=0; i<size; i++) {
|
87
|
+
sc->pages[new_page][i] = Qfalse;
|
88
|
+
}
|
89
|
+
|
90
|
+
sc->current_position = new_page*PAGE_SIZE + size;
|
91
|
+
|
92
|
+
address = sc->pages[new_page];
|
93
|
+
|
94
|
+
} else {
|
95
|
+
|
96
|
+
if (sc->pages[page ] == 0) {
|
97
|
+
// alloc the page corresponding to current stack position
|
98
|
+
sc->pages[page] = malloc(PAGE_SIZE*sizeof(VALUE));
|
99
|
+
}
|
100
|
+
|
101
|
+
int i;
|
102
|
+
for (i=position_in_page; i<position_in_page+size; i++) {
|
103
|
+
sc->pages[page][i] = Qfalse;
|
104
|
+
}
|
105
|
+
|
106
|
+
sc->current_position += size;
|
107
|
+
int new_page = sc->current_position / PAGE_SIZE;
|
108
|
+
|
109
|
+
if (new_page >= NUM_PAGES) {
|
110
|
+
rb_raise(rb_eSysStackError,"stack level too deep");
|
111
|
+
}
|
112
|
+
|
113
|
+
if (sc->pages[new_page ] == 0) {
|
114
|
+
// alloc the page corresponding for the new stack position
|
115
|
+
sc->pages[new_page] = malloc(PAGE_SIZE*sizeof(VALUE));
|
116
|
+
}
|
117
|
+
|
118
|
+
address = sc->pages[page]+position_in_page;
|
119
|
+
}
|
120
|
+
|
121
|
+
return address;
|
122
|
+
}
|
123
|
+
|
124
|
+
static inline void stack_chunk_mark(struct STACKCHUNK* sc) {
|
125
|
+
// Mark local variables on each allocated page up to current_position
|
126
|
+
int i;
|
127
|
+
|
128
|
+
for (i=0; i<sc->current_position; i++) {
|
129
|
+
int position_in_page = i & PAGE_MASK;
|
130
|
+
int page = i / PAGE_SIZE;
|
131
|
+
|
132
|
+
rb_gc_mark(sc->pages[page][position_in_page]);
|
133
|
+
}
|
134
|
+
}
|
135
|
+
|
136
|
+
static inline void stack_chunk_free(struct STACKCHUNK* sc) {
|
137
|
+
|
138
|
+
int i;
|
139
|
+
for (i=0; i<NUM_PAGES;i++) {
|
140
|
+
if (sc->pages[i] != 0) {
|
141
|
+
free(sc->pages[i]);
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
free(sc);
|
146
|
+
}
|
147
|
+
|
148
|
+
static inline VALUE rb_stack_chunk_create(VALUE self) {
|
149
|
+
// alloc memory for struct
|
150
|
+
struct STACKCHUNK* sc;
|
151
|
+
|
152
|
+
// make ruby object to wrap the stack and let the ruby GC do his work
|
153
|
+
VALUE ret = Data_Make_Struct(rb_cStackChunk,struct STACKCHUNK,stack_chunk_mark,stack_chunk_free,sc);
|
154
|
+
|
155
|
+
stack_chunk_initialize(sc);
|
156
|
+
|
157
|
+
return ret;
|
158
|
+
}
|
159
|
+
|
160
|
+
static inline struct STACKCHUNK* stack_chunk_get_struct(VALUE self) {
|
161
|
+
struct STACKCHUNK* data;
|
162
|
+
Data_Get_Struct(self,struct STACKCHUNK,data);
|
163
|
+
|
164
|
+
return data;
|
165
|
+
}
|
166
|
+
|
167
|
+
|
168
|
+
static inline VALUE rb_stack_chunk_alloc(VALUE self, VALUE rb_size) {
|
169
|
+
|
170
|
+
struct STACKCHUNK* data;
|
171
|
+
Data_Get_Struct(self,struct STACKCHUNK,data);
|
172
|
+
|
173
|
+
stack_chunk_alloc(data,FIX2INT(rb_size));
|
174
|
+
return self;
|
175
|
+
}
|
176
|
+
|
177
|
+
|
178
|
+
static inline void fastruby_thread_data_mark(struct FASTRUBYTHREADDATA* thread_data) {
|
179
|
+
rb_gc_mark(thread_data->exception);
|
180
|
+
rb_gc_mark(thread_data->accumulator);
|
181
|
+
rb_gc_mark(thread_data->rb_stack_chunk);
|
182
|
+
}
|
183
|
+
|
184
|
+
static inline VALUE rb_thread_data_create() {
|
185
|
+
struct FASTRUBYTHREADDATA* thread_data;
|
186
|
+
|
187
|
+
VALUE ret = Data_Make_Struct(rb_cFastRubyThreadData,struct FASTRUBYTHREADDATA,fastruby_thread_data_mark,0,thread_data);
|
188
|
+
|
189
|
+
thread_data->exception = Qnil;
|
190
|
+
thread_data->accumulator = Qnil;
|
191
|
+
thread_data->rb_stack_chunk = Qnil;
|
192
|
+
|
193
|
+
return ret;
|
194
|
+
}
|
195
|
+
|
196
|
+
static inline struct FASTRUBYTHREADDATA* rb_current_thread_data() {
|
197
|
+
VALUE rb_thread = rb_thread_current();
|
198
|
+
VALUE rb_thread_data = rb_thread_local_aref(rb_thread,id_fastruby_thread_data);
|
199
|
+
|
200
|
+
struct FASTRUBYTHREADDATA* thread_data = 0;
|
201
|
+
|
202
|
+
if (rb_thread_data == Qnil) {
|
203
|
+
rb_thread_data = rb_thread_data_create();
|
204
|
+
rb_thread_local_aset(rb_thread,id_fastruby_thread_data,rb_thread_data);
|
205
|
+
}
|
206
|
+
|
207
|
+
Data_Get_Struct(rb_thread_data,struct FASTRUBYTHREADDATA,thread_data);
|
208
|
+
return thread_data;
|
209
|
+
}
|
210
|
+
|
211
|
+
static void init_stack_chunk() {
|
212
|
+
|
213
|
+
rb_mFastRuby = rb_define_module("FastRuby");
|
214
|
+
rb_cStackChunk = rb_define_class_under(rb_mFastRuby, "StackChunk", rb_cObject);
|
215
|
+
rb_cFastRubyThreadData = rb_define_class_under(rb_mFastRuby, "ThreadData", rb_cObject);
|
216
|
+
|
217
|
+
id_fastruby_thread_data = rb_intern("fastruby_thread_data");
|
218
|
+
|
219
|
+
rb_define_singleton_method(rb_cStackChunk, "create", rb_stack_chunk_create,0);
|
220
|
+
rb_define_method(rb_cStackChunk, "alloc", rb_stack_chunk_alloc,1);
|
221
|
+
}
|
222
|
+
|
data/lib/fastruby.rb
CHANGED
@@ -33,6 +33,6 @@ module FastRuby
|
|
33
33
|
FastRuby.fastruby_script_path = File.expand_path(__FILE__)
|
34
34
|
FastRuby.fastruby_load_path = File.expand_path(File.dirname(__FILE__))
|
35
35
|
|
36
|
-
VERSION = "0.0.
|
36
|
+
VERSION = "0.0.11" unless defined? FastRuby::VERSION
|
37
37
|
end
|
38
38
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 9
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 11
|
10
|
+
version: 0.0.11
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dario Seminara
|
@@ -107,6 +107,7 @@ files:
|
|
107
107
|
- spec/literal_spec.rb
|
108
108
|
- spec/singleton_spec.rb
|
109
109
|
- spec/integrity_spec.rb
|
110
|
+
- ext/fastruby_base/fastruby_base.inl
|
110
111
|
- ext/fastruby_base/fastruby_base.c
|
111
112
|
- ext/fastruby_base/extconf.rb
|
112
113
|
- LICENSE
|