ytljit 0.0.3 → 0.0.4
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/ext/code_alloc.c +6 -0
- data/ext/memory.c +82 -0
- data/ext/ytljit.c +9 -0
- data/ext/ytljit.h +18 -0
- data/lib/runtime/gc.rb +41 -0
- data/lib/runtime/object.rb +18 -0
- data/lib/ytljit.rb +9 -0
- data/lib/ytljit/arena.rb +63 -0
- data/lib/ytljit/asm.rb +5 -1
- data/lib/ytljit/asmext.rb +42 -6
- data/lib/ytljit/asmutil.rb +26 -0
- data/lib/ytljit/instruction_ia.rb +28 -2
- data/lib/ytljit/type.rb +11 -5
- data/lib/ytljit/vm.rb +620 -173
- data/lib/ytljit/vm_codegen.rb +123 -26
- data/lib/ytljit/vm_cruby_obj.rb +91 -0
- data/lib/ytljit/vm_inline_method.rb +27 -19
- data/lib/ytljit/vm_sendnode.rb +416 -136
- data/lib/ytljit/vm_trans.rb +79 -19
- data/lib/ytljit/vm_type.rb +25 -19
- data/lib/ytljit/vm_type_gen.rb +55 -2
- data/test/test_arena.rb +60 -0
- data/test/test_assemble2.rb +25 -2
- metadata +10 -3
data/ext/code_alloc.c
CHANGED
@@ -229,7 +229,13 @@ csfree(void *chunk)
|
|
229
229
|
rb_raise(rb_eArgError, "Maybe free illgal chunk");
|
230
230
|
}
|
231
231
|
bitpos = offset / alocsize;
|
232
|
+
|
233
|
+
#if 0
|
232
234
|
arena->bitmap[bitpos / 64] ^= (1 << (bitpos & (64 - 1)));
|
235
|
+
if (arena->bitmap[bitpos / 64] & (1 << (bitpos & (64 - 1))) == 0) {
|
236
|
+
rb_raise(rb_eArgError, "Maybe freeed chunk passed");
|
237
|
+
}
|
238
|
+
#endif
|
233
239
|
|
234
240
|
/* Update arena_search_tab */
|
235
241
|
for (tmpa = arena_tab[logsize], sarena = arena_search_tab[logsize];
|
data/ext/memory.c
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
#include <unistd.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include "ruby.h"
|
4
|
+
|
5
|
+
#include "ytljit.h"
|
6
|
+
|
7
|
+
VALUE ytl_mRuntime;
|
8
|
+
VALUE ytl_cArena;
|
9
|
+
|
10
|
+
VALUE
|
11
|
+
ytl_arena_allocate(VALUE klass)
|
12
|
+
{
|
13
|
+
struct Arena *arena;
|
14
|
+
|
15
|
+
arena = malloc(ARENA_SIZE);
|
16
|
+
arena->size = ARENA_SIZE - sizeof(struct Arena);
|
17
|
+
|
18
|
+
return Data_Wrap_Struct(klass, NULL, free, (void *)arena);
|
19
|
+
}
|
20
|
+
|
21
|
+
VALUE
|
22
|
+
ytl_arena_ref(VALUE self, VALUE offset)
|
23
|
+
{
|
24
|
+
struct Arena *raw_arena;
|
25
|
+
int raw_offset;
|
26
|
+
|
27
|
+
raw_arena = (struct Arena *)DATA_PTR(self);
|
28
|
+
raw_offset = FIX2INT(offset);
|
29
|
+
|
30
|
+
return INT2FIX(raw_arena->body[raw_offset]);
|
31
|
+
}
|
32
|
+
|
33
|
+
VALUE
|
34
|
+
ytl_arena_emit(VALUE self, VALUE offset, VALUE src)
|
35
|
+
{
|
36
|
+
struct Arena *raw_arena;
|
37
|
+
|
38
|
+
int raw_offset;
|
39
|
+
|
40
|
+
raw_arena = (struct Arena *)DATA_PTR(self);
|
41
|
+
raw_offset = FIX2INT(offset);
|
42
|
+
|
43
|
+
raw_arena->body[raw_offset] = FIX2INT(src);
|
44
|
+
|
45
|
+
return src;
|
46
|
+
}
|
47
|
+
|
48
|
+
VALUE
|
49
|
+
ytl_arena_size(VALUE self)
|
50
|
+
{
|
51
|
+
struct Arena *raw_arena;
|
52
|
+
|
53
|
+
int raw_offset;
|
54
|
+
|
55
|
+
raw_arena = (struct Arena *)DATA_PTR(self);
|
56
|
+
|
57
|
+
return INT2FIX(raw_arena->size);
|
58
|
+
}
|
59
|
+
|
60
|
+
VALUE
|
61
|
+
ytl_arena_address(VALUE self)
|
62
|
+
{
|
63
|
+
struct Arena *raw_arena;
|
64
|
+
|
65
|
+
raw_arena = (struct Arena *)DATA_PTR(self);
|
66
|
+
|
67
|
+
return INT2FIX(raw_arena->body);
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
VALUE
|
72
|
+
ytl_arena_to_s(VALUE self)
|
73
|
+
{
|
74
|
+
struct Arena *raw_arena;
|
75
|
+
|
76
|
+
raw_arena = (struct Arena *)DATA_PTR(self);
|
77
|
+
|
78
|
+
return rb_sprintf("#<Arena %p size=%d body=%p>",
|
79
|
+
(void *)self,
|
80
|
+
raw_arena->size,
|
81
|
+
(void *)raw_arena->body);
|
82
|
+
}
|
data/ext/ytljit.c
CHANGED
@@ -511,6 +511,15 @@ Init_ytljit_ext()
|
|
511
511
|
rb_define_alloc_func(ytl_cValueSpace, ytl_value_space_allocate);
|
512
512
|
rb_define_method(ytl_cValueSpace, "to_s", ytl_value_space_to_s, 0);
|
513
513
|
|
514
|
+
ytl_mRuntime = rb_define_module_under(ytl_mYTLJit, "Runtime");
|
515
|
+
ytl_cArena = rb_define_class_under(ytl_mRuntime, "Arena", rb_cObject);
|
516
|
+
rb_define_alloc_func(ytl_cArena, ytl_arena_allocate);
|
517
|
+
rb_define_method(ytl_cArena, "[]=", ytl_arena_emit, 2);
|
518
|
+
rb_define_method(ytl_cArena, "[]", ytl_arena_ref, 1);
|
519
|
+
rb_define_method(ytl_cArena, "size", ytl_arena_size, 0);
|
520
|
+
rb_define_method(ytl_cArena, "address", ytl_arena_address, 0);
|
521
|
+
rb_define_method(ytl_cArena, "to_s", ytl_arena_to_s, 0);
|
522
|
+
|
514
523
|
/* Open Handles */
|
515
524
|
#ifdef __CYGWIN__
|
516
525
|
OPEN_CHECK(dl_handles[used_dl_handles] = dlopen("cygwin1.dll", RTLD_LAZY));
|
data/ext/ytljit.h
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
#define INIT_CODE_SPACE_SIZE 64
|
3
3
|
#define VALUE_SPACE_SIZE (8 * 1024)
|
4
4
|
|
5
|
+
#define ARENA_SIZE 256 * 1024 /* 256 Kbytes */
|
6
|
+
|
5
7
|
#define OPEN_CHECK(COND) \
|
6
8
|
do { \
|
7
9
|
if ((COND) == NULL) { \
|
@@ -15,8 +17,21 @@ struct CodeSpace {
|
|
15
17
|
char body[1];
|
16
18
|
};
|
17
19
|
|
20
|
+
struct Arena {
|
21
|
+
size_t size;
|
22
|
+
VALUE body[1];
|
23
|
+
};
|
24
|
+
|
18
25
|
VALUE ytl_address_of(VALUE, VALUE);
|
19
26
|
VALUE ytl_code_space_allocate(VALUE);
|
27
|
+
VALUE ytl_code_value_allocate(VALUE);
|
28
|
+
|
29
|
+
VALUE ytl_arena_allocate(VALUE);
|
30
|
+
VALUE ytl_arena_emit(VALUE, VALUE, VALUE);
|
31
|
+
VALUE ytl_arena_ref(VALUE, VALUE);
|
32
|
+
VALUE ytl_arena_size(VALUE);
|
33
|
+
VALUE ytl_arena_address(VALUE);
|
34
|
+
VALUE ytl_arena_to_s(VALUE);
|
20
35
|
|
21
36
|
void init_csarena();
|
22
37
|
void *csalloc(int);
|
@@ -28,6 +43,9 @@ extern VALUE ytl_cValueSpace;
|
|
28
43
|
extern VALUE ytl_cStepHandler;
|
29
44
|
extern VALUE ytl_eStepHandler;
|
30
45
|
|
46
|
+
extern VALUE ytl_mRuntime;
|
47
|
+
extern VALUE ytl_cArena;
|
48
|
+
|
31
49
|
/* Copy from node.h */
|
32
50
|
typedef struct RNode {
|
33
51
|
unsigned long flags;
|
data/lib/runtime/gc.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module YTLJit
|
2
|
+
module Runtime
|
3
|
+
class GCBase
|
4
|
+
def gc(heap)
|
5
|
+
raise "#{heap} is overflow"
|
6
|
+
end
|
7
|
+
|
8
|
+
def malloc(type)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class GCCopy<GCBase
|
13
|
+
def initialize
|
14
|
+
@arena = []
|
15
|
+
@arena[0] = Arena.new
|
16
|
+
@arena[1] = Arena.new
|
17
|
+
@from_arena = 0
|
18
|
+
end
|
19
|
+
|
20
|
+
def gc
|
21
|
+
end
|
22
|
+
|
23
|
+
def malloc(type)
|
24
|
+
siz = type.size
|
25
|
+
siz += YTLObject.size
|
26
|
+
fromare = @arena[@from_arena]
|
27
|
+
if fromare.size < fromare.using + siz then
|
28
|
+
gc
|
29
|
+
end
|
30
|
+
|
31
|
+
res = TypedDataArena.new(YTLObject, fromare, fromare.using)
|
32
|
+
fromare.using += siz
|
33
|
+
|
34
|
+
# Initialize object header
|
35
|
+
yield res
|
36
|
+
|
37
|
+
res.cast(type)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module YTLJit
|
2
|
+
module Runtime
|
3
|
+
include InternalRubyType
|
4
|
+
# Format of header
|
5
|
+
#
|
6
|
+
# size of object
|
7
|
+
# xxxxxxxxxxxxxxxxxxxFEUTFRM
|
8
|
+
#
|
9
|
+
ADDRESS = AsmType::MACHINE_WORD
|
10
|
+
YTLObject = AsmType::Struct.new(
|
11
|
+
VALUE, :header,
|
12
|
+
ADDRESS, :traverse_func,
|
13
|
+
AsmType::Array.new(VALUE, 0), :body
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
data/lib/ytljit.rb
CHANGED
data/lib/ytljit/arena.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
module YTLJit
|
2
|
+
module Runtime
|
3
|
+
class Arena
|
4
|
+
def initialize
|
5
|
+
@using = 0
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_accessor :using
|
9
|
+
end
|
10
|
+
|
11
|
+
class TypedDataArena
|
12
|
+
def initialize(type, arena, origin)
|
13
|
+
@type = type
|
14
|
+
@arena = arena
|
15
|
+
@origin = origin
|
16
|
+
end
|
17
|
+
|
18
|
+
def [](*arg)
|
19
|
+
TypedDataArena.new(@type[*arg], @arena, @origin)
|
20
|
+
end
|
21
|
+
|
22
|
+
def cast(otype)
|
23
|
+
TypedDataArena.new(otype, @arena, @origin)
|
24
|
+
end
|
25
|
+
|
26
|
+
def address
|
27
|
+
case @type
|
28
|
+
when AsmType::Scalar,
|
29
|
+
AsmType::Pointer,
|
30
|
+
AsmType::Array,
|
31
|
+
AsmType::Struct
|
32
|
+
@arena.address + @origin
|
33
|
+
|
34
|
+
when AsmType::StructMember, AsmType::PointedData
|
35
|
+
@arena.address + @origin + @type.offset
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def ref
|
41
|
+
case @type
|
42
|
+
when AsmType::Scalar, AsmType::Pointer, AsmType::Array
|
43
|
+
@arena[@origin]
|
44
|
+
|
45
|
+
when AsmType::StructMember, AsmType::PointedData
|
46
|
+
@arena[@origin + @type.offset / AsmType::MACHINE_WORD.size]
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def ref=(val)
|
52
|
+
case @type
|
53
|
+
when AsmType::Scalar, AsmType::Pointer, AsmType::Array
|
54
|
+
@arena[@origin] = val
|
55
|
+
|
56
|
+
when AsmType::StructMember, AsmType::PointedData
|
57
|
+
@arena[@origin + @type.offset / AsmType::MACHINE_WORD.size] = val
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/ytljit/asm.rb
CHANGED
@@ -77,12 +77,15 @@ module YTLJit
|
|
77
77
|
# Instruction pach table for forwarding reference
|
78
78
|
# This is array of proc object.
|
79
79
|
@after_patch_tab = []
|
80
|
+
@patched_num = 0
|
81
|
+
|
80
82
|
reset
|
81
83
|
end
|
82
84
|
|
83
85
|
def reset
|
84
86
|
@current_address = @output_stream.base_address
|
85
87
|
@offset = 0
|
88
|
+
@patched_num = 0
|
86
89
|
end
|
87
90
|
|
88
91
|
attr_accessor :current_address
|
@@ -131,9 +134,10 @@ module YTLJit
|
|
131
134
|
@output_stream.update_refer
|
132
135
|
end
|
133
136
|
|
134
|
-
@after_patch_tab.each do |patproc|
|
137
|
+
@after_patch_tab[@patched_num..-1].each do |patproc|
|
135
138
|
patproc.call
|
136
139
|
end
|
140
|
+
@patched_num = @after_patch_tab.size
|
137
141
|
@retry_mode = org_retry_mode
|
138
142
|
end
|
139
143
|
|
data/lib/ytljit/asmext.rb
CHANGED
@@ -22,26 +22,48 @@ module YTLJit
|
|
22
22
|
base = @entity
|
23
23
|
case @type
|
24
24
|
when AsmType::Scalar, AsmType::Pointer, AsmType::Array
|
25
|
-
if
|
25
|
+
if @type == AsmType::DOUBLE then
|
26
26
|
code = ""
|
27
|
-
code += asm.update_state(gen.
|
27
|
+
code += asm.update_state(gen.movsd(XMM0, base))
|
28
28
|
[code, @type]
|
29
29
|
else
|
30
|
-
|
30
|
+
if base != TMPR then
|
31
|
+
code = ""
|
32
|
+
code += asm.update_state(gen.mov(TMPR, base))
|
33
|
+
[code, @type]
|
34
|
+
else
|
35
|
+
["", @type]
|
36
|
+
end
|
31
37
|
end
|
32
38
|
|
33
39
|
when AsmType::StructMember
|
34
40
|
code = ""
|
35
|
-
|
41
|
+
|
42
|
+
oi = nil
|
43
|
+
if base.is_a?(OpRegXMM) then
|
44
|
+
oi = base
|
45
|
+
|
46
|
+
elsif base != TMPR then
|
47
|
+
code += asm.update_state(gen.call_stephandler) if code != ""
|
36
48
|
code += asm.update_state(gen.mov(TMPR, base))
|
49
|
+
oi = OpIndirect.new(TMPR, @type.offset)
|
50
|
+
|
51
|
+
else
|
52
|
+
oi = OpIndirect.new(TMPR, @type.offset)
|
37
53
|
end
|
38
|
-
|
39
|
-
if @type.type
|
54
|
+
|
55
|
+
if @type.type == AsmType::DOUBLE then
|
56
|
+
code += asm.update_state(gen.call_stephandler) if code != ""
|
57
|
+
code += asm.update_state(gen.movsd(XMM0, oi))
|
58
|
+
|
59
|
+
elsif @type.type.is_a?(AsmType::Array) then
|
40
60
|
code += asm.update_state(gen.call_stephandler) if code != ""
|
41
61
|
code += asm.update_state(gen.lea(TMPR, oi))
|
62
|
+
|
42
63
|
else
|
43
64
|
code += asm.update_state(gen.call_stephandler) if code != ""
|
44
65
|
code += asm.update_state(gen.mov(TMPR, oi))
|
66
|
+
|
45
67
|
end
|
46
68
|
[code, @type.type]
|
47
69
|
|
@@ -136,6 +158,20 @@ module YTLJit
|
|
136
158
|
return [rcode, TypedData.new(rtype, dst)]
|
137
159
|
end
|
138
160
|
|
161
|
+
when :movsd
|
162
|
+
case src
|
163
|
+
when TypedData
|
164
|
+
orgaddress = @asm.current_address
|
165
|
+
rcode = ""
|
166
|
+
rcode, rtype = src.gen_access(self)
|
167
|
+
if dst != XMM0 then
|
168
|
+
rcode += @asm.update_state(call_stephandler) if rcode != ""
|
169
|
+
rcode += @asm.update_state(movsd(dst, XMM0))
|
170
|
+
end
|
171
|
+
@asm.current_address = orgaddress
|
172
|
+
return [rcode, TypedData.new(rtype, dst)]
|
173
|
+
end
|
174
|
+
|
139
175
|
when :push
|
140
176
|
case dst
|
141
177
|
when OpRegXMM
|
data/lib/ytljit/asmutil.rb
CHANGED
@@ -113,6 +113,7 @@ module YTLJit
|
|
113
113
|
end
|
114
114
|
INDIRECT_TMPR = OpIndirect.new(TMPR)
|
115
115
|
INDIRECT_TMPR2 = OpIndirect.new(TMPR2)
|
116
|
+
INDIRECT_TMPR3 = OpIndirect.new(TMPR3)
|
116
117
|
INDIRECT_RETR = OpIndirect.new(RETR)
|
117
118
|
INDIRECT_SPR = OpIndirect.new(SPR)
|
118
119
|
INDIRECT_BPR = OpIndirect.new(BPR)
|
@@ -133,6 +134,8 @@ module YTLJit
|
|
133
134
|
module InternalRubyType
|
134
135
|
include AbsArch
|
135
136
|
VALUE = AsmType::MACHINE_WORD
|
137
|
+
P_VOID = AsmType::Pointer.new(VALUE)
|
138
|
+
P_VALUE = AsmType::Pointer.new(VALUE)
|
136
139
|
P_CHAR = AsmType::Pointer.new(AsmType::INT8)
|
137
140
|
|
138
141
|
RBasic = AsmType::Struct.new(
|
@@ -162,6 +165,29 @@ module YTLJit
|
|
162
165
|
AsmType::DOUBLE, :float_value
|
163
166
|
)
|
164
167
|
|
168
|
+
Arena = AsmType::Struct.new(
|
169
|
+
AsmType::MACHINE_WORD, :size,
|
170
|
+
AsmType::Array.new(AsmType::INT8, 0), :body
|
171
|
+
)
|
172
|
+
|
173
|
+
RData = AsmType::Struct.new(
|
174
|
+
RBasic, :basic,
|
175
|
+
P_VOID, :dmark,
|
176
|
+
P_VOID, :dfree,
|
177
|
+
AsmType::Pointer.new(Arena), :data)
|
178
|
+
|
179
|
+
RObject = AsmType::Struct.new(
|
180
|
+
RBasic, :basic,
|
181
|
+
AsmType::Union.new(
|
182
|
+
AsmType::Struct.new(
|
183
|
+
AsmType::INT32, :numiv,
|
184
|
+
P_VALUE, :ivptr,
|
185
|
+
P_VOID, :iv_index_tbl
|
186
|
+
), :heap,
|
187
|
+
AsmType::Array.new(VALUE, 3), :ary
|
188
|
+
), :as
|
189
|
+
)
|
190
|
+
|
165
191
|
EMBEDER_FLAG = (1 << 13)
|
166
192
|
def self.rstring_ptr(str, csstart, cscont)
|
167
193
|
cs_embed = CodeSpace.new
|