ytljit 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|