ytljit 0.0.6 → 0.0.7
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 +39 -17
- data/ext/memory.c +170 -22
- data/ext/ytljit.c +57 -2
- data/ext/ytljit.h +15 -2
- data/lib/ytljit/asm.rb +21 -0
- data/lib/ytljit/asmext_x64.rb +1 -1
- data/lib/ytljit/asmutil.rb +1 -0
- data/lib/ytljit/instruction.rb +6 -0
- data/lib/ytljit/instruction_ia.rb +31 -2
- data/lib/ytljit/util.rb +5 -4
- data/lib/ytljit/vm.rb +771 -182
- data/lib/ytljit/vm_codegen.rb +76 -25
- data/lib/ytljit/vm_cruby_obj.rb +34 -13
- data/lib/ytljit/vm_inline_method.rb +154 -32
- data/lib/ytljit/vm_sendnode.rb +597 -112
- data/lib/ytljit/vm_trans.rb +148 -35
- data/lib/ytljit/vm_type.rb +5 -1
- data/lib/ytljit/vm_type_gen.rb +224 -51
- data/lib/ytljit.rb +5 -0
- data/test/test_assemble2.rb +35 -5
- metadata +3 -3
data/ext/code_alloc.c
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#include <sys/mman.h>
|
5
5
|
#include <stdlib.h>
|
6
6
|
#include "ruby.h"
|
7
|
+
#include "ytljit.h"
|
7
8
|
|
8
9
|
|
9
10
|
/* CodeSpaceArena is memory area for allocate codespace
|
@@ -34,11 +35,10 @@ typedef struct {
|
|
34
35
|
uint64_t bitmap[1];
|
35
36
|
} CodeSpaceArena;
|
36
37
|
|
37
|
-
#define ARENA_SIZE 16 * 1024
|
38
38
|
|
39
39
|
/* 2 * 64 means header and gatekeeper */
|
40
40
|
#define BITMAP_SIZE(ALOCSIZ) \
|
41
|
-
(((
|
41
|
+
(((CODE_SPACE_SIZE) * 8 - 2 * 64) / ((ALOCSIZ) * 8 + 1))
|
42
42
|
|
43
43
|
/* Last "+ 1" means gatekeeper */
|
44
44
|
#define HEADER_SIZE(ALOCSIZ) \
|
@@ -64,31 +64,40 @@ static CodeSpaceArena *arena_search_tab[ALOCSIZLOG_MAX];
|
|
64
64
|
|
65
65
|
static size_t page_size;
|
66
66
|
|
67
|
-
CodeSpaceArena *
|
68
|
-
|
67
|
+
static CodeSpaceArena *
|
68
|
+
raw_alloc_arena(size_t size)
|
69
69
|
{
|
70
|
-
uint64_t rbitmap;
|
71
70
|
CodeSpaceArena *arena;
|
72
71
|
void *newmem;
|
73
|
-
|
74
|
-
int bitmap_size;
|
75
|
-
int allff_size;
|
76
|
-
int rest_size;
|
77
|
-
|
72
|
+
|
78
73
|
#if !defined(__CYGWIN__)
|
79
|
-
if (posix_memalign(&newmem,
|
74
|
+
if (posix_memalign(&newmem, CODE_SPACE_SIZE, size)) {
|
80
75
|
rb_raise(rb_eNoMemError, "Can't allocate code space area");
|
81
76
|
}
|
82
|
-
if(mprotect(newmem,
|
77
|
+
if(mprotect(newmem, CODE_SPACE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC)) {
|
83
78
|
rb_raise(rb_eNoMemError, "mprotect failed");
|
84
79
|
}
|
85
80
|
arena = (CodeSpaceArena *)newmem;
|
86
81
|
#else
|
87
|
-
if (!(arena = memalign(
|
82
|
+
if (!(arena = memalign(CODE_SPACE_SIZE, size))) {
|
88
83
|
rb_raise(rb_eNoMemError, "Can't allocate code space area");
|
89
84
|
}
|
90
85
|
#endif
|
86
|
+
|
87
|
+
return arena;
|
88
|
+
}
|
89
|
+
|
90
|
+
static CodeSpaceArena *
|
91
|
+
alloc_arena(size_t aloclogsiz, CodeSpaceArena *prev_csa)
|
92
|
+
{
|
93
|
+
uint64_t rbitmap;
|
94
|
+
CodeSpaceArena *arena;
|
95
|
+
int allocsiz;
|
96
|
+
int bitmap_size;
|
97
|
+
int allff_size;
|
98
|
+
int rest_size;
|
91
99
|
|
100
|
+
arena = raw_alloc_arena(CODE_SPACE_SIZE);
|
92
101
|
arena->next_and_size = ((uintptr_t)prev_csa) | aloclogsiz;
|
93
102
|
|
94
103
|
/* fill bitmap: 1 means free */
|
@@ -202,8 +211,15 @@ csalloc(int size)
|
|
202
211
|
void *res;
|
203
212
|
|
204
213
|
logsize = bytes_to_bucket(size);
|
205
|
-
|
206
|
-
|
214
|
+
if (logsize < 10) {
|
215
|
+
/* Small code space (less than 8192 bytes) */
|
216
|
+
res = search_free_chunk(arena_search_tab[logsize]);
|
217
|
+
}
|
218
|
+
else {
|
219
|
+
res = raw_alloc_arena(16 << logsize);
|
220
|
+
((struct CodeSpace *)res)->next_and_size = 0xf;
|
221
|
+
}
|
222
|
+
|
207
223
|
return res;
|
208
224
|
}
|
209
225
|
|
@@ -219,8 +235,14 @@ csfree(void *chunk)
|
|
219
235
|
int logsize;
|
220
236
|
int alocsize;
|
221
237
|
|
222
|
-
arena = (CodeSpaceArena *)(((uintptr_t)chunk) & (~(
|
238
|
+
arena = (CodeSpaceArena *)(((uintptr_t)chunk) & (~(CODE_SPACE_SIZE - 1)));
|
223
239
|
logsize = arena->next_and_size & 0xf;
|
240
|
+
if (logsize == 0xf) {
|
241
|
+
/* Large area */
|
242
|
+
free(arena);
|
243
|
+
return;
|
244
|
+
}
|
245
|
+
|
224
246
|
alocsize = 16 << logsize;
|
225
247
|
|
226
248
|
alocoff = csarena_allocarea_tab[logsize];
|
@@ -262,7 +284,7 @@ init_csarena()
|
|
262
284
|
#endif
|
263
285
|
|
264
286
|
/* Check page_size is valid */
|
265
|
-
if ((
|
287
|
+
if ((CODE_SPACE_SIZE / page_size) * page_size != CODE_SPACE_SIZE) {
|
266
288
|
rb_raise(rb_eNoMemError, "Not support this architecture");
|
267
289
|
}
|
268
290
|
|
data/ext/memory.c
CHANGED
@@ -7,40 +7,173 @@
|
|
7
7
|
VALUE ytl_mRuntime;
|
8
8
|
VALUE ytl_cArena;
|
9
9
|
|
10
|
+
void
|
11
|
+
ytl_arena_mark(struct ArenaHeader *arenah)
|
12
|
+
{
|
13
|
+
VALUE *base;
|
14
|
+
VALUE *start;
|
15
|
+
struct ArenaBody *bodyptr;
|
16
|
+
struct ArenaBody *next_bodyptr;
|
17
|
+
struct ArenaBody *lastbodyptr;
|
18
|
+
VALUE *bodyeleptr;
|
19
|
+
int appear;
|
20
|
+
|
21
|
+
lastbodyptr = (struct ArenaBody *)(((uintptr_t)arenah->lastptr) & (~(ARENA_SIZE - 1)));
|
22
|
+
appear = 0;
|
23
|
+
|
24
|
+
for (bodyptr = arenah->body; bodyptr; bodyptr = next_bodyptr) {
|
25
|
+
if (bodyptr == lastbodyptr) {
|
26
|
+
start = arenah->lastptr;
|
27
|
+
appear = 1;
|
28
|
+
}
|
29
|
+
else if (appear) {
|
30
|
+
start = bodyptr->body;
|
31
|
+
}
|
32
|
+
else {
|
33
|
+
next_bodyptr = bodyptr->next;
|
34
|
+
arenah->body = next_bodyptr;
|
35
|
+
free(bodyptr);
|
36
|
+
continue;
|
37
|
+
}
|
38
|
+
|
39
|
+
base = bodyptr->body + (bodyptr->size / sizeof(VALUE));
|
40
|
+
for (bodyeleptr = start; bodyeleptr < base; bodyeleptr++) {
|
41
|
+
rb_gc_mark_maybe(*bodyeleptr);
|
42
|
+
}
|
43
|
+
next_bodyptr = bodyptr->next;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
void
|
48
|
+
ytl_arena_free(struct ArenaHeader *arenah)
|
49
|
+
{
|
50
|
+
VALUE *base;
|
51
|
+
VALUE *start;
|
52
|
+
struct ArenaBody *curptr;
|
53
|
+
struct ArenaBody *curptr_next;
|
54
|
+
|
55
|
+
for (curptr = arenah->body; curptr; curptr = curptr_next) {
|
56
|
+
curptr_next = curptr->next;
|
57
|
+
free(curptr);
|
58
|
+
}
|
59
|
+
|
60
|
+
free(arenah);
|
61
|
+
}
|
62
|
+
|
63
|
+
#define DO_RETRY \
|
64
|
+
do { \
|
65
|
+
if (retry_mode) { \
|
66
|
+
rb_raise(rb_eNoMemError, "Can't allocate arena area"); \
|
67
|
+
} \
|
68
|
+
else { \
|
69
|
+
retry_mode = 1; \
|
70
|
+
rb_gc(); \
|
71
|
+
goto retry; \
|
72
|
+
} \
|
73
|
+
} while(0)
|
74
|
+
|
75
|
+
|
76
|
+
struct ArenaBody *
|
77
|
+
ytl_arena_allocate_body()
|
78
|
+
{
|
79
|
+
void *newmem;
|
80
|
+
struct ArenaBody *abody;
|
81
|
+
int retry_mode = 0;
|
82
|
+
|
83
|
+
retry:
|
84
|
+
|
85
|
+
#if !defined(__CYGWIN__)
|
86
|
+
if (posix_memalign(&newmem, ARENA_SIZE, ARENA_SIZE)) {
|
87
|
+
DO_RETRY;
|
88
|
+
}
|
89
|
+
abody = (struct ArenaBody *)newmem;
|
90
|
+
#else
|
91
|
+
if (!(abody = memalign(ARENA_SIZE, ARENA_SIZE))) {
|
92
|
+
DO_RETRY;
|
93
|
+
}
|
94
|
+
#endif
|
95
|
+
|
96
|
+
abody->size = ARENA_SIZE - sizeof(struct ArenaBody);
|
97
|
+
abody->next = 0;
|
98
|
+
return abody;
|
99
|
+
}
|
100
|
+
|
10
101
|
VALUE
|
11
102
|
ytl_arena_allocate(VALUE klass)
|
12
103
|
{
|
13
|
-
struct
|
104
|
+
struct ArenaHeader *arenah;
|
105
|
+
struct ArenaBody *arenab;
|
14
106
|
|
15
|
-
|
16
|
-
|
107
|
+
arenah = malloc(sizeof(struct ArenaHeader));
|
108
|
+
arenah->body = ytl_arena_allocate_body();
|
109
|
+
arenab = arenah->body;
|
110
|
+
arenab->header = arenah;
|
111
|
+
arenah->lastptr = arenab->body + (arenab->size / sizeof(VALUE));
|
17
112
|
|
18
|
-
return Data_Wrap_Struct(klass,
|
113
|
+
return Data_Wrap_Struct(klass, ytl_arena_mark, ytl_arena_free,
|
114
|
+
(void *)arenah);
|
115
|
+
}
|
116
|
+
|
117
|
+
char *
|
118
|
+
ytl_arena_alloca(char *stptr, int size)
|
119
|
+
{
|
120
|
+
uintptr_t lsp;
|
121
|
+
struct ArenaHeader *arenah;
|
122
|
+
struct ArenaBody *oldbody;
|
123
|
+
struct ArenaBody *bodyptr;
|
124
|
+
struct ArenaBody *next_bodyptr;
|
125
|
+
|
126
|
+
lsp = (uintptr_t)stptr;
|
127
|
+
oldbody = (struct ArenaBody *)(lsp & (~(ARENA_SIZE -1)));
|
128
|
+
arenah = oldbody->header;
|
129
|
+
size = size * 8;
|
130
|
+
|
131
|
+
for (bodyptr = arenah->body; bodyptr != oldbody; bodyptr = next_bodyptr) {
|
132
|
+
next_bodyptr = bodyptr->next;
|
133
|
+
arenah->body = next_bodyptr;
|
134
|
+
free(bodyptr);
|
135
|
+
}
|
136
|
+
|
137
|
+
if ((lsp & (ARENA_SIZE - 1)) < ((lsp - size - 64) & (ARENA_SIZE - 1))) {
|
138
|
+
struct ArenaBody *arenab;
|
139
|
+
|
140
|
+
arenah->lastptr = (void *)stptr;
|
141
|
+
arenab = arenah->body = ytl_arena_allocate_body();
|
142
|
+
if (arenab != oldbody) {
|
143
|
+
arenab->next = oldbody;
|
144
|
+
}
|
145
|
+
arenab->header = arenah;
|
146
|
+
arenah->lastptr = arenab->body + (arenab->size / sizeof(VALUE));
|
147
|
+
stptr = (char *)arenah->lastptr;
|
148
|
+
}
|
149
|
+
stptr -= size;
|
150
|
+
|
151
|
+
return stptr;
|
19
152
|
}
|
20
153
|
|
21
154
|
VALUE
|
22
155
|
ytl_arena_ref(VALUE self, VALUE offset)
|
23
156
|
{
|
24
|
-
struct
|
157
|
+
struct ArenaHeader *arenah;
|
25
158
|
int raw_offset;
|
26
159
|
|
27
|
-
|
160
|
+
Data_Get_Struct(self, struct ArenaHeader, arenah);
|
28
161
|
raw_offset = FIX2INT(offset);
|
29
162
|
|
30
|
-
return ULONG2NUM(
|
163
|
+
return ULONG2NUM(arenah->body->body[raw_offset]);
|
31
164
|
}
|
32
165
|
|
33
166
|
VALUE
|
34
167
|
ytl_arena_emit(VALUE self, VALUE offset, VALUE src)
|
35
168
|
{
|
36
|
-
struct
|
169
|
+
struct ArenaHeader *arenah;
|
37
170
|
|
38
171
|
int raw_offset;
|
39
172
|
|
40
|
-
|
173
|
+
Data_Get_Struct(self, struct ArenaHeader, arenah);
|
41
174
|
raw_offset = NUM2ULONG(offset);
|
42
175
|
|
43
|
-
|
176
|
+
arenah->body->body[raw_offset] = FIX2INT(src);
|
44
177
|
|
45
178
|
return src;
|
46
179
|
}
|
@@ -48,35 +181,50 @@ ytl_arena_emit(VALUE self, VALUE offset, VALUE src)
|
|
48
181
|
VALUE
|
49
182
|
ytl_arena_size(VALUE self)
|
50
183
|
{
|
51
|
-
struct
|
184
|
+
struct ArenaHeader *arenah;
|
185
|
+
struct ArenaBody *arenab;
|
52
186
|
|
53
|
-
int
|
187
|
+
int totsize;
|
54
188
|
|
55
|
-
|
189
|
+
Data_Get_Struct(self, struct ArenaHeader, arenah);
|
190
|
+
totsize = 0;
|
191
|
+
for (arenab = arenah->body; arenab; arenab = arenab->next) {
|
192
|
+
totsize += arenab->size;
|
193
|
+
}
|
56
194
|
|
57
|
-
return INT2FIX(
|
195
|
+
return INT2FIX(totsize);
|
58
196
|
}
|
59
197
|
|
60
198
|
VALUE
|
61
199
|
ytl_arena_address(VALUE self)
|
62
200
|
{
|
63
|
-
struct
|
201
|
+
struct ArenaHeader *arenah;
|
64
202
|
|
65
|
-
|
203
|
+
Data_Get_Struct(self, struct ArenaHeader, arenah);
|
66
204
|
|
67
|
-
return ULONG2NUM((uintptr_t)
|
205
|
+
return ULONG2NUM((uintptr_t)arenah->body->body);
|
68
206
|
}
|
69
207
|
|
208
|
+
VALUE
|
209
|
+
ytl_arena_raw_address(VALUE self)
|
210
|
+
{
|
211
|
+
struct ArenaHeader *arenah;
|
212
|
+
|
213
|
+
Data_Get_Struct(self, struct ArenaHeader, arenah);
|
214
|
+
|
215
|
+
return ULONG2NUM((uintptr_t)arenah);
|
216
|
+
}
|
70
217
|
|
71
218
|
VALUE
|
72
219
|
ytl_arena_to_s(VALUE self)
|
73
220
|
{
|
74
|
-
struct
|
221
|
+
struct ArenaHeader *arenah;
|
75
222
|
|
76
|
-
|
223
|
+
Data_Get_Struct(self, struct ArenaHeader, arenah);
|
77
224
|
|
78
|
-
return rb_sprintf("#<Arena %p size=%d body=%p>",
|
225
|
+
return rb_sprintf("#<Arena %p size=%d body=%p last=%p>",
|
79
226
|
(void *)self,
|
80
|
-
|
81
|
-
(void *)
|
227
|
+
ytl_arena_size(self) / 2,
|
228
|
+
(void *)arenah->body->body,
|
229
|
+
(void *)arenah->lastptr);
|
82
230
|
}
|
data/ext/ytljit.c
CHANGED
@@ -262,7 +262,7 @@ ytl_code_space_emit(VALUE self, VALUE offset, VALUE src)
|
|
262
262
|
void *new_cs = csalloc(newsize);
|
263
263
|
|
264
264
|
//*(struct CodeSpace *)new_cs = *(struct CodeSpace *)raw_cs;
|
265
|
-
memcpy(new_cs, raw_cs, newsize / 2);
|
265
|
+
//memcpy(new_cs, raw_cs, newsize / 2);
|
266
266
|
csfree(raw_cs);
|
267
267
|
raw_cs = new_cs;
|
268
268
|
raw_cs->size = newsize - sizeof(struct CodeSpace);
|
@@ -524,6 +524,60 @@ ytl_step_handler()
|
|
524
524
|
#endif
|
525
525
|
}
|
526
526
|
|
527
|
+
VALUE
|
528
|
+
ytl_ivar_get_boxing(VALUE slf, int off)
|
529
|
+
{
|
530
|
+
VALUE *ivptr;
|
531
|
+
VALUE rval;
|
532
|
+
|
533
|
+
ivptr = ROBJECT_IVPTR(slf);
|
534
|
+
rval = ivptr[off];
|
535
|
+
if (rval != Qundef) {
|
536
|
+
return rval;
|
537
|
+
}
|
538
|
+
else {
|
539
|
+
return Qnil;
|
540
|
+
}
|
541
|
+
}
|
542
|
+
|
543
|
+
VALUE
|
544
|
+
ytl_ivar_set_boxing(VALUE slf, int off, VALUE val)
|
545
|
+
{
|
546
|
+
int len;
|
547
|
+
int i;
|
548
|
+
|
549
|
+
/* Copy from variable.c in ruby1.9 */
|
550
|
+
len = ROBJECT_NUMIV(slf);
|
551
|
+
if (len <= off) {
|
552
|
+
VALUE *ptr = ROBJECT_IVPTR(slf);
|
553
|
+
if (off < ROBJECT_EMBED_LEN_MAX) {
|
554
|
+
RBASIC(slf)->flags |= ROBJECT_EMBED;
|
555
|
+
ptr = ROBJECT(slf)->as.ary;
|
556
|
+
for (i = 0; i < ROBJECT_EMBED_LEN_MAX; i++) {
|
557
|
+
ptr[i] = Qundef;
|
558
|
+
}
|
559
|
+
}
|
560
|
+
else {
|
561
|
+
VALUE *newptr;
|
562
|
+
long newsize = (off+1) + (off+1)/4; /* (index+1)*1.25 */
|
563
|
+
if (RBASIC(slf)->flags & ROBJECT_EMBED) {
|
564
|
+
newptr = ALLOC_N(VALUE, newsize);
|
565
|
+
MEMCPY(newptr, ptr, VALUE, len);
|
566
|
+
RBASIC(slf)->flags &= ~ROBJECT_EMBED;
|
567
|
+
ROBJECT(slf)->as.heap.ivptr = newptr;
|
568
|
+
}
|
569
|
+
else {
|
570
|
+
REALLOC_N(ROBJECT(slf)->as.heap.ivptr, VALUE, newsize);
|
571
|
+
newptr = ROBJECT(slf)->as.heap.ivptr;
|
572
|
+
}
|
573
|
+
for (; len < newsize; len++)
|
574
|
+
newptr[len] = Qundef;
|
575
|
+
ROBJECT(slf)->as.heap.numiv = newsize;
|
576
|
+
}
|
577
|
+
}
|
578
|
+
ROBJECT_IVPTR(slf)[off] = val;
|
579
|
+
}
|
580
|
+
|
527
581
|
void
|
528
582
|
Init_ytljit_ext()
|
529
583
|
{
|
@@ -575,7 +629,8 @@ Init_ytljit_ext()
|
|
575
629
|
rb_define_method(ytl_cArena, "[]=", ytl_arena_emit, 2);
|
576
630
|
rb_define_method(ytl_cArena, "[]", ytl_arena_ref, 1);
|
577
631
|
rb_define_method(ytl_cArena, "size", ytl_arena_size, 0);
|
578
|
-
rb_define_method(ytl_cArena, "
|
632
|
+
rb_define_method(ytl_cArena, "body_address", ytl_arena_address, 0);
|
633
|
+
rb_define_method(ytl_cArena, "raw_address", ytl_arena_raw_address, 0);
|
579
634
|
rb_define_method(ytl_cArena, "to_s", ytl_arena_to_s, 0);
|
580
635
|
|
581
636
|
/* Open Handles */
|
data/ext/ytljit.h
CHANGED
@@ -2,7 +2,8 @@
|
|
2
2
|
#define INIT_CODE_SPACE_SIZE 64
|
3
3
|
#define VALUE_SPACE_SIZE (8 * 1024)
|
4
4
|
|
5
|
-
#define
|
5
|
+
#define CODE_SPACE_SIZE (16 * 1024) /* 16 Kbytes */
|
6
|
+
#define ARENA_SIZE (256 * 1024) /* 256 Kbytes */
|
6
7
|
|
7
8
|
#define OPEN_CHECK(COND) \
|
8
9
|
do { \
|
@@ -12,13 +13,21 @@ do { \
|
|
12
13
|
} while(0)
|
13
14
|
|
14
15
|
struct CodeSpace {
|
16
|
+
uintptr_t next_and_size;
|
15
17
|
size_t size;
|
16
18
|
size_t used;
|
17
19
|
char body[1];
|
18
20
|
};
|
19
21
|
|
20
|
-
struct
|
22
|
+
struct ArenaHeader {
|
23
|
+
VALUE *lastptr;
|
24
|
+
struct ArenaBody *body;
|
25
|
+
};
|
26
|
+
|
27
|
+
struct ArenaBody {
|
21
28
|
size_t size;
|
29
|
+
struct ArenaBody *next;
|
30
|
+
struct ArenaHeader *header;
|
22
31
|
VALUE body[1];
|
23
32
|
};
|
24
33
|
|
@@ -27,13 +36,17 @@ VALUE ytl_code_space_allocate(VALUE);
|
|
27
36
|
VALUE ytl_code_value_allocate(VALUE);
|
28
37
|
|
29
38
|
VALUE ytl_arena_allocate(VALUE);
|
39
|
+
char *ytl_arena_alloca(char *, int);
|
30
40
|
VALUE ytl_arena_emit(VALUE, VALUE, VALUE);
|
31
41
|
VALUE ytl_arena_ref(VALUE, VALUE);
|
32
42
|
VALUE ytl_arena_size(VALUE);
|
43
|
+
VALUE ytl_arena_raw_address(VALUE);
|
33
44
|
VALUE ytl_arena_address(VALUE);
|
34
45
|
VALUE ytl_arena_to_s(VALUE);
|
35
46
|
|
36
47
|
void ytl_step_handler(void);
|
48
|
+
VALUE ytl_ivar_get_boxing(VALUE, int);
|
49
|
+
VALUE ytl_ivar_set_boxing(VALUE, int, VALUE);
|
37
50
|
|
38
51
|
void init_csarena();
|
39
52
|
void *csalloc(int);
|
data/lib/ytljit/asm.rb
CHANGED
@@ -182,12 +182,33 @@ module YTLJit
|
|
182
182
|
unless off = @@value_table_cache[val] then
|
183
183
|
off = @@value_table_entity.current_pos
|
184
184
|
@@value_table_entity.emit([val.value].pack("Q"))
|
185
|
+
stfunc = lambda {
|
186
|
+
oldpos = @@value_table_entity.current_pos
|
187
|
+
@@value_table_entity.current_pos = off
|
188
|
+
@@value_table_entity.emit([val.value].pack("Q"))
|
189
|
+
@@value_table_entity.current_pos = oldpos
|
190
|
+
}
|
191
|
+
val.add_refer(stfunc)
|
185
192
|
@@value_table_cache[val] = off
|
186
193
|
end
|
187
194
|
|
188
195
|
@@value_table_entity.var_base_address(off)
|
189
196
|
end
|
190
197
|
|
198
|
+
def add_value_entry_no_cache(val)
|
199
|
+
off = @@value_table_entity.current_pos
|
200
|
+
@@value_table_entity.emit([val.value].pack("Q"))
|
201
|
+
stfunc = lambda {
|
202
|
+
oldpos = @@value_table_entity.current_pos
|
203
|
+
@@value_table_entity.current_pos = off
|
204
|
+
@@value_table_entity.emit([val.value].pack("Q"))
|
205
|
+
@@value_table_entity.current_pos = oldpos
|
206
|
+
}
|
207
|
+
val.add_refer(stfunc)
|
208
|
+
|
209
|
+
@@value_table_entity.var_base_address(off)
|
210
|
+
end
|
211
|
+
|
191
212
|
def add_var_value_retry_func(mn, args)
|
192
213
|
if args.any? {|e| e.is_a?(OpVarValueMixin) } and
|
193
214
|
@retry_mode == false then
|
data/lib/ytljit/asmext_x64.rb
CHANGED
@@ -171,7 +171,7 @@ module YTLJit
|
|
171
171
|
orgaddress = @asm.current_address
|
172
172
|
code = ""
|
173
173
|
# code += @asm.update_state(mov(RAX, OpImmidiate32.new(argnum)))
|
174
|
-
code += @asm.update_state(mov(RAX, OpImmidiate32.new(0)))
|
174
|
+
# code += @asm.update_state(mov(RAX, OpImmidiate32.new(0)))
|
175
175
|
code += @asm.update_state(call(addr))
|
176
176
|
callpos = @asm.current_address - @asm.output_stream.base_address
|
177
177
|
if @asm.retry_mode == :change_op then
|
data/lib/ytljit/asmutil.rb
CHANGED
data/lib/ytljit/instruction.rb
CHANGED
@@ -36,9 +36,11 @@ module YTLJit
|
|
36
36
|
end
|
37
37
|
|
38
38
|
module OpVarValueMixin
|
39
|
+
@@instances = []
|
39
40
|
def initialize(var)
|
40
41
|
@var = var
|
41
42
|
@refer = []
|
43
|
+
@@instances.push self
|
42
44
|
end
|
43
45
|
|
44
46
|
def refer
|
@@ -56,6 +58,10 @@ module YTLJit
|
|
56
58
|
def to_immidiate(klass = OpVarImmidiateAddress)
|
57
59
|
klass.new(@var)
|
58
60
|
end
|
61
|
+
|
62
|
+
def self.instances
|
63
|
+
@@instances
|
64
|
+
end
|
59
65
|
end
|
60
66
|
|
61
67
|
class OpVarImmidiate32<OpImmidiate32
|
@@ -780,6 +780,23 @@ module YTLJit
|
|
780
780
|
return nosupported_addressing_mode(inst, dst, src)
|
781
781
|
end
|
782
782
|
end
|
783
|
+
|
784
|
+
def common_cvt(dst, src, op0, op1, inst)
|
785
|
+
if dst.is_a?(OpRegXMM) and
|
786
|
+
(src.is_a?(OpIndirect) or
|
787
|
+
src.is_a?(OpReg32) or
|
788
|
+
src.is_a?(OpReg64)) then
|
789
|
+
rexseq, rexfmt = rex(dst, src)
|
790
|
+
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
791
|
+
if op0 then
|
792
|
+
([op0] + rexseq + [0x0F, op1] + modseq).pack("C#{rexfmt}C2#{modfmt}")
|
793
|
+
else
|
794
|
+
(rexseq + [0x0F, op1] + modseq).pack("#{rexfmt}C2#{modfmt}")
|
795
|
+
end
|
796
|
+
else
|
797
|
+
return nosupported_addressing_mode(inst, dst, src)
|
798
|
+
end
|
799
|
+
end
|
783
800
|
end
|
784
801
|
|
785
802
|
class GeneratorIABinary<Generator
|
@@ -1138,7 +1155,7 @@ module YTLJit
|
|
1138
1155
|
case addr2
|
1139
1156
|
when Integer
|
1140
1157
|
offset = addr2 - @asm.current_address - 2
|
1141
|
-
if offset > -128 and offset < 127 then
|
1158
|
+
if offset > -128 and offset < 127 and false then
|
1142
1159
|
[0xeb, offset].pack("C2")
|
1143
1160
|
else
|
1144
1161
|
offset = addr2 - @asm.current_address - 5
|
@@ -1223,7 +1240,7 @@ module YTLJit
|
|
1223
1240
|
case src
|
1224
1241
|
when nil
|
1225
1242
|
modseq, modfmt = modrm(:imul, 5, dst, dst, src)
|
1226
|
-
return (rexseq + [0xF7] + modseq).pack("#{rexfmt}C#
|
1243
|
+
return (rexseq + [0xF7] + modseq).pack("#{rexfmt}C#{modfmt}")
|
1227
1244
|
|
1228
1245
|
when OpReg32, OpMem32, OpIndirect, OpReg64
|
1229
1246
|
modseq, modfmt = modrm(:imul, dst, src, dst, src, src2)
|
@@ -1367,8 +1384,20 @@ module YTLJit
|
|
1367
1384
|
common_arithxmm(dst, src, 0x66, 0x2F, :comisd)
|
1368
1385
|
end
|
1369
1386
|
|
1387
|
+
def cvtsi2sd(dst, src)
|
1388
|
+
common_cvt(dst, src, 0xf2, 0x2a, :cvtsi2sd)
|
1389
|
+
end
|
1390
|
+
|
1391
|
+
def cvtsi2ss(dst, src)
|
1392
|
+
common_cvt(dst, src, 0xf3, 0x2a, :cvtsi2ss)
|
1393
|
+
end
|
1394
|
+
|
1370
1395
|
def int3
|
1371
1396
|
[0xcc].pack("C")
|
1372
1397
|
end
|
1398
|
+
|
1399
|
+
def ud2
|
1400
|
+
[0x0f, 0x0b].pack("CC")
|
1401
|
+
end
|
1373
1402
|
end
|
1374
1403
|
end
|
data/lib/ytljit/util.rb
CHANGED
@@ -55,9 +55,6 @@ module YTLJit
|
|
55
55
|
@@instance_tab = {}
|
56
56
|
|
57
57
|
def self.instance(clsobj)
|
58
|
-
if clsobj.is_a?(ClassClassWrapper)
|
59
|
-
clsobj = clsobj.value
|
60
|
-
end
|
61
58
|
ins = @@instance_tab[clsobj]
|
62
59
|
if ins == nil then
|
63
60
|
ins = ClassClassWrapper.new(clsobj)
|
@@ -67,6 +64,10 @@ module YTLJit
|
|
67
64
|
ins
|
68
65
|
end
|
69
66
|
|
67
|
+
def self.instance_tab
|
68
|
+
@@instance_tab
|
69
|
+
end
|
70
|
+
|
70
71
|
def initialize(clsobj)
|
71
72
|
@klass_object = clsobj
|
72
73
|
@value = nil
|
@@ -98,7 +99,7 @@ module YTLJit
|
|
98
99
|
end
|
99
100
|
|
100
101
|
def marshal_load(obj)
|
101
|
-
@klass_object = obj
|
102
|
+
@klass_object = obj[0]
|
102
103
|
@value = nil
|
103
104
|
end
|
104
105
|
|