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