Ticket #18: summary.patch.txt

File summary.patch.txt, 15.3 KB (added by Infinoid, 5 years ago)

Summary patch (contains 01, 02, 03) for easier testing.

Line 
1diff --git a/config/gen/makefiles/root.in b/config/gen/makefiles/root.in
2index 29e2c6f..7042889 100644
3--- a/config/gen/makefiles/root.in
4+++ b/config/gen/makefiles/root.in
5@@ -1054,7 +1054,7 @@ $(SRC_DIR)/jit_cpu$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/jit_emit.h
6 
7 $(SRC_DIR)/exec$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h
8 
9-$(SRC_DIR)/exec_dep$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h
10+$(SRC_DIR)/exec_dep$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h $(SRC_DIR)/pmc/managedstruct.c
11 
12 $(SRC_DIR)/exec_cpu$(O) : $(GENERAL_H_FILES) @TEMP_exec_h@ $(SRC_DIR)/jit_emit.h
13 
14@@ -1187,7 +1187,7 @@ $(SRC_DIR)/dataypes$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/dataypes.c
15 
16 $(SRC_DIR)/exit$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/exit.c
17 
18-$(SRC_DIR)/nci$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/nci.c $(SRC_DIR)/nci.str
19+$(SRC_DIR)/nci$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/nci.c $(SRC_DIR)/nci.str $(SRC_DIR)/pmc/pmc_managedstruct.h
20 
21 $(SRC_DIR)/vtables$(O) : $(GENERAL_H_FILES) $(SRC_DIR)/vtables.c
22 
23diff --git a/config/gen/platform/generic/memexec.c b/config/gen/platform/generic/memexec.c
24index 813673c..aa82081 100644
25--- a/config/gen/platform/generic/memexec.c
26+++ b/config/gen/platform/generic/memexec.c
27@@ -22,6 +22,9 @@ Memory protection stuff
28 */
29 
30 #ifdef PARROT_HAS_EXEC_PROTECT
31+
32+#define PARROT_EXEC_PERMS PROT_READ|PROT_WRITE|PROT_EXEC
33+
34 /*
35 
36 =item C<void * mem_alloc_executable(size_t size)>
37@@ -39,24 +42,36 @@ mem_alloc_executable(size_t size)
38     void *p;
39     size_t pagesize = sysconf(_SC_PAGESIZE);
40     size = (size + pagesize - 1) & ~(pagesize-1);
41+#ifdef WIN32
42     if (posix_memalign(&p, pagesize, size))
43         return NULL;
44-    mprotect(p, size, PROT_READ|PROT_WRITE|PROT_EXEC);
45+    mprotect(p, size, PARROT_EXEC_PERMS);
46+#else /* !WIN32 */
47+    p = mmap(NULL, size, PARROT_EXEC_PERMS, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
48+    if (!p)
49+        return NULL;
50+#endif /* WIN32 */
51     return p;
52 }
53 
54 /*
55 
56-=item C<void mem_free_executable(void *p)>
57+=item C<void mem_free_executable(void *p, size_t)>
58+
59+Free a buffer allocated with mem_alloc_executable().
60 
61 =cut
62 
63 */
64 
65 void
66-mem_free_executable(void *p)
67+mem_free_executable(void *p, size_t size)
68 {
69+#ifdef WIN32
70     free(p);
71+#else /* !WIN32 */
72+    munmap(p, size);
73+#endif /* WIN32 */
74 }
75 
76 /*
77@@ -72,12 +87,13 @@ The intermediate temp is required because we don't know the old size
78 */
79 
80 void *
81-mem_realloc_executable(void* oldp, size_t newsize)
82+mem_realloc_executable(void* oldp, size_t oldsize, size_t newsize)
83 {
84     void *temp;
85     void *newp;
86     size_t pagesize = sysconf(_SC_PAGESIZE);
87     size_t roundup;
88+#ifdef WIN32
89     temp = realloc(oldp, newsize);
90     if (temp == NULL)
91         return NULL;
92@@ -86,10 +102,13 @@ mem_realloc_executable(void* oldp, size_t newsize)
93     if (posix_memalign(&newp, pagesize, roundup))
94         newp = NULL;
95     if (newp) {
96-        mprotect(newp, roundup, PROT_READ|PROT_WRITE|PROT_EXEC);
97+        mprotect(newp, roundup, PARROT_EXEC_PERMS);
98         memcpy(newp, temp, newsize);
99     }
100     free(temp);
101+#else /* !WIN32 */
102+    temp = mremap(oldp, oldsize, newsize, PARROT_EXEC_PERMS);
103+#endif /* WIN32 */
104     return newp;
105 }
106 #endif
107diff --git a/config/gen/platform/openbsd/memexec.c b/config/gen/platform/openbsd/memexec.c
108index 8488bc2..95bfd3e 100644
109--- a/config/gen/platform/openbsd/memexec.c
110+++ b/config/gen/platform/openbsd/memexec.c
111@@ -49,14 +49,16 @@ mem_alloc_executable(size_t size)
112 
113 /*
114 
115-=item C<void mem_free_executable(void *p)>
116+=item C<void mem_free_executable(void *p, size_t size)>
117+
118+Free a buffer allocated with mem_alloc_executable().
119 
120 =cut
121 
122 */
123 
124 void
125-mem_free_executable(void *p)
126+mem_free_executable(void *p, size_t size)
127 {
128     free(p);
129 }
130diff --git a/config/gen/platform/platform_interface.h b/config/gen/platform/platform_interface.h
131index 9985244..7712ea8 100644
132--- a/config/gen/platform/platform_interface.h
133+++ b/config/gen/platform/platform_interface.h
134@@ -40,12 +40,12 @@ void Parrot_free_memalign(void *);
135 
136 #ifdef PARROT_HAS_EXEC_PROTECT
137 void *mem_alloc_executable(size_t);
138-void mem_free_executable(void *);
139-void *mem_realloc_executable(void *, size_t);
140+void mem_free_executable(void *, size_t);
141+void *mem_realloc_executable(void *, size_t, size_t);
142 #else
143 #  define mem_alloc_executable mem_sys_allocate
144-#  define mem_free_executable mem_sys_free
145-#  define mem_realloc_executable mem_sys_realloc
146+#  define mem_free_executable(a, b) mem_sys_free(a)
147+#  define mem_realloc_executable(a, b, c) mem_sys_realloc((a), (c))
148 #endif
149 
150 void* Parrot_memcpy_aligned(void*, void*, size_t);
151diff --git a/src/jit.c b/src/jit.c
152index 956ba5c..70756d8 100644
153--- a/src/jit.c
154+++ b/src/jit.c
155@@ -1257,7 +1257,7 @@ Parrot_destroy_jit(void *ptr)
156     }
157     /* arena stuff */
158     mem_sys_free(jit_info->arena.op_map);
159-    mem_free_executable(jit_info->arena.start);
160+    mem_free_executable(jit_info->arena.start, jit_info->arena.size);
161     fixup = jit_info->arena.fixups;
162     while (fixup) {
163         next_f = fixup->next;
164@@ -1525,7 +1525,7 @@ parrot_build_asm(PARROT_INTERP, ARGIN(opcode_t *code_start), ARGIN(opcode_t *cod
165                 Parrot_jit_extend_arena(jit_info);
166 #else
167                 new_arena = (char *)mem_realloc_executable(jit_info->arena.start,
168-                        (size_t)jit_info->arena.size * 2);
169+                        jit_info->arena.size, (size_t)jit_info->arena.size * 2);
170                 jit_info->arena.size *= 2;
171                 jit_info->native_ptr  = new_arena +
172                     (jit_info->native_ptr - jit_info->arena.start);
173diff --git a/src/jit.h b/src/jit.h
174index 39b444c..27fe7ac 100644
175--- a/src/jit.h
176+++ b/src/jit.h
177@@ -321,7 +321,13 @@ parrot_build_asm(PARROT_INTERP,
178 /*
179  * NCI interface
180  */
181-void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *);
182+void *Parrot_jit_build_call_func(Interp *, PMC *, STRING *, int *);
183+/* custom pmc callback functions */
184+void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv);
185+PMC* Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv);
186+struct jit_buffer_private_data {
187+    int size;
188+};
189 
190 #endif /* PARROT_JIT_H_GUARD */
191 
192diff --git a/src/jit/i386/exec_dep.c b/src/jit/i386/exec_dep.c
193index 0756ac3..d62dec8 100644
194--- a/src/jit/i386/exec_dep.c
195+++ b/src/jit/i386/exec_dep.c
196@@ -16,6 +16,7 @@
197  */
198 
199 #include "parrot/parrot.h"
200+#include "pmc/pmc_managedstruct.h"
201 #include "jit.h"
202 #define JIT_EMIT 1
203 #include "jit_emit.h"
204@@ -186,6 +187,49 @@ offset_fixup(Parrot_exec_objfile_t *obj)
205     }
206 }
207 
208+void
209+Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv) {
210+    struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv;
211+    mem_free_executable(ptr, jit->size);
212+    free(priv);
213+}
214+
215+PMC *
216+Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv) {
217+    struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv;
218+    PMC *rv = pmc_new(interp, pmc->vtable->base_type);
219+    void *tmp, *tmp2;
220+
221+    VTABLE_init(interp, rv);
222+    /* copy the attributes */
223+    GETATTR_ManagedStruct_custom_free_func(interp, pmc, tmp);
224+    SETATTR_ManagedStruct_custom_free_func(interp, rv , tmp);
225+    GETATTR_ManagedStruct_custom_clone_func(interp, pmc, tmp);
226+    SETATTR_ManagedStruct_custom_clone_func(interp, rv , tmp);
227+    GETATTR_ManagedStruct_custom_free_priv(interp, pmc, tmp);
228+    if(tmp) {
229+        tmp2 = mem_sys_allocate(sizeof(struct jit_buffer_private_data));
230+        memcpy(tmp2, tmp, sizeof(struct jit_buffer_private_data));
231+        SETATTR_ManagedStruct_custom_free_priv(interp, rv , tmp2);
232+    }
233+    GETATTR_ManagedStruct_custom_clone_priv(interp, pmc, tmp);
234+    if(tmp) {
235+        tmp2 = mem_sys_allocate(sizeof(struct jit_buffer_private_data));
236+        memcpy(tmp2, tmp, sizeof(struct jit_buffer_private_data));
237+        SETATTR_ManagedStruct_custom_clone_priv(interp, rv , tmp2);
238+    }
239+
240+    /* copy the execmem buffer */
241+    if (PARROT_MANAGEDSTRUCT(pmc)->ptr) {
242+        void *newptr, *ptr = PARROT_MANAGEDSTRUCT(pmc)->ptr;
243+        newptr = mem_alloc_executable(jit->size);
244+        memcpy(newptr, ptr, jit->size);
245+        PARROT_MANAGEDSTRUCT(rv)->ptr = newptr;
246+    }
247+
248+    return rv;
249+}
250+
251 /*
252  * Local variables:
253  *   c-file-style: "parrot"
254diff --git a/src/jit/i386/exec_dep.h b/src/jit/i386/exec_dep.h
255index d8a7d92..b081f1c 100644
256--- a/src/jit/i386/exec_dep.h
257+++ b/src/jit/i386/exec_dep.h
258@@ -33,6 +33,9 @@ void Parrot_exec_normal_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
259 void Parrot_exec_restart_op(Parrot_jit_info_t *jit_info, PARROT_INTERP)
260         __attribute__nonnull__(2);
261 
262+void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv);
263+PMC* Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv);
264+
265 #define ASSERT_ARGS_offset_fixup __attribute__unused__ int _ASSERT_ARGS_CHECK = 0
266 #define ASSERT_ARGS_Parrot_exec_cpcf_op __attribute__unused__ int _ASSERT_ARGS_CHECK = \
267        PARROT_ASSERT_ARG(interp)
268diff --git a/src/jit/i386/jit_defs.c b/src/jit/i386/jit_defs.c
269index dac55fa..5d60a97 100644
270--- a/src/jit/i386/jit_defs.c
271+++ b/src/jit/i386/jit_defs.c
272@@ -2116,10 +2116,13 @@ calc_signature_needs(const char *sig, int *strings)
273  * The generate function for a specific signature looks quite similar to
274  * an optimized compile of src/nci.c:pcf_x_yy(). In case of any troubles
275  * just compare the disassembly.
276+ *
277+ * If a non-NULL sizeptr is passed, the integer it points to will be written
278+ * with the size of the allocated execmem buffer.
279  */
280 
281 void *
282-Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature)
283+Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature, int *sizeptr)
284 {
285     Parrot_jit_info_t jit_info;
286     char     *pc;
287@@ -2289,7 +2292,7 @@ Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature)
288             case '2':
289             case '3':
290             case '4':
291-                mem_free_executable(jit_info.native_ptr);
292+                mem_free_executable(jit_info.native_ptr, JIT_ALLOC_SIZE);
293                 return NULL;
294                 break;
295                 /* This might be right. Or not... */
296@@ -2306,7 +2309,7 @@ Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature)
297                  * oops unknown signature:
298                  * cleanup and try nci.c
299                  */
300-                mem_free_executable(jit_info.native_ptr);
301+                mem_free_executable(jit_info.native_ptr, JIT_ALLOC_SIZE);
302                 return NULL;
303         }
304         args_offset +=4;
305@@ -2435,7 +2438,7 @@ Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature)
306              * oops unknown signature:
307              * cleanup and try nci.c
308              */
309-            mem_free_executable(jit_info.native_ptr);
310+            mem_free_executable(jit_info.native_ptr, JIT_ALLOC_SIZE);
311             return NULL;
312     }
313 
314@@ -2453,6 +2456,8 @@ Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci, STRING *signature)
315     PARROT_ASSERT(pc - jit_info.arena.start <= JIT_ALLOC_SIZE);
316     /* could shrink arena.start here to used size */
317     PObj_active_destroy_SET(pmc_nci);
318+    if (sizeptr)
319+        *sizeptr = JIT_ALLOC_SIZE;
320     return (void *)D2FPTR(jit_info.arena.start);
321 }
322 
323diff --git a/src/jit/i386/jit_emit.h b/src/jit/i386/jit_emit.h
324index f6f29fe..4ea814e 100644
325--- a/src/jit/i386/jit_emit.h
326+++ b/src/jit/i386/jit_emit.h
327@@ -1879,7 +1879,7 @@ int count_regs(PARROT_INTERP, char *sig, char *sig_start);
328 size_t calc_signature_needs(const char *sig, int *strings);
329 
330 void * Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc_nci,
331-    STRING *signature);
332+    STRING *signature, int *sizeptr);
333 
334 /*
335  * register usage
336diff --git a/src/pmc/managedstruct.pmc b/src/pmc/managedstruct.pmc
337index 36fe392..5221ea7 100644
338--- a/src/pmc/managedstruct.pmc
339+++ b/src/pmc/managedstruct.pmc
340@@ -21,8 +21,21 @@ C<struct> values that Parrot is responsible for disposing of.
341 
342 #include "parrot/parrot.h"
343 
344+typedef void (*custom_free_func_t)(PARROT_INTERP, void *ptr, void *priv);
345+typedef PMC * (*custom_clone_func_t)(PARROT_INTERP, PMC *ptr, void *priv);
346 
347 pmclass ManagedStruct extends UnManagedStruct need_ext {
348+    /* if custom_free_func and ptr (inherited from UnManagedStruct) are both set,
349+     * custom_free_func is called before the normal destroy() function does any
350+     * work.
351+     */
352+    ATTR void *custom_free_func;
353+    ATTR void *custom_free_priv;
354+    /* if custom_clone_func is set, it will be called *instead* of the normal
355+     * clone() function logic.
356+     */
357+    ATTR void *custom_clone_func;
358+    ATTR void *custom_clone_priv;
359 
360 /*
361 
362@@ -68,8 +81,16 @@ Destroys the struct, freeing the allocated memory.
363 */
364 
365     VTABLE void destroy() {
366-        if (PARROT_MANAGEDSTRUCT(SELF)->ptr)
367-            mem_sys_free(PARROT_MANAGEDSTRUCT(SELF)->ptr);
368+        void *ptr = PARROT_MANAGEDSTRUCT(SELF)->ptr;
369+        if (ptr) {
370+            custom_free_func_t free_func =
371+                (custom_free_func_t)PARROT_MANAGEDSTRUCT(SELF)->custom_free_func;
372+            if (free_func) {
373+                void *free_data = PARROT_MANAGEDSTRUCT(SELF)->custom_free_priv;
374+                free_func(interp, ptr, free_data);
375+            } else
376+                mem_sys_free(ptr);
377+        }
378         mem_sys_free(PMC_data(SELF));
379     }
380 
381@@ -118,7 +139,14 @@ how to clone I<that> data.
382 */
383 
384     VTABLE PMC *clone() {
385-        PMC *dest = pmc_new_init(interp, SELF->vtable->base_type,
386+        custom_clone_func_t clone_func =
387+            (custom_clone_func_t)PARROT_MANAGEDSTRUCT(SELF)->custom_clone_func;
388+        PMC *dest;
389+        if (clone_func) {
390+            void *clone_data = PARROT_MANAGEDSTRUCT(SELF)->custom_clone_priv;
391+            return clone_func(interp, SELF, clone_data);
392+        }
393+        dest = pmc_new_init(interp, SELF->vtable->base_type,
394             PARROT_MANAGEDSTRUCT(SELF)->init);
395 
396         if (PARROT_MANAGEDSTRUCT(SELF)->ptr)
397diff --git a/tools/build/nativecall.pl b/tools/build/nativecall.pl
398index 5d878d5..4c542f8 100644
399--- a/tools/build/nativecall.pl
400+++ b/tools/build/nativecall.pl
401@@ -195,8 +195,10 @@ sub print_head {
402 #include "parrot/parrot.h"
403 #include "parrot/hash.h"
404 #include "parrot/oplib/ops.h"
405+#include "pmc/pmc_managedstruct.h"
406 #include "pmc/pmc_nci.h"
407 #include "nci.str"
408+#include "jit.h"
409 
410 /* HEADERIZER HFILE: none */
411 /* HEADERIZER STOP */
412@@ -554,11 +556,22 @@ $put_pointer
413         return F2DPTR(VTABLE_get_pointer(interp, b));
414     }
415     else {
416-        void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature);
417+        int jit_size;
418+        void * const result = Parrot_jit_build_call_func(interp, pmc_nci, signature, &jit_size);
419         if (result) {
420+            struct jit_buffer_private_data *priv;
421             *jitted = 1;
422             temp_pmc = pmc_new(interp, enum_class_ManagedStruct);
423             VTABLE_set_pointer(interp, temp_pmc, (void *)result);
424+#ifdef PARROT_HAS_EXEC_PROTECT
425+            priv = (struct jit_buffer_private_data *)
426+                mem_sys_allocate(sizeof(struct jit_buffer_private_data));
427+            priv->size = jit_size;
428+            SETATTR_ManagedStruct_custom_free_func(interp, temp_pmc, Parrot_jit_free_buffer);
429+            SETATTR_ManagedStruct_custom_free_priv(interp, temp_pmc, priv);
430+            SETATTR_ManagedStruct_custom_clone_func(interp, temp_pmc, Parrot_jit_clone_buffer);
431+            SETATTR_ManagedStruct_custom_clone_priv(interp, temp_pmc, priv);
432+#endif /* PARROT_HAS_EXEC_PROTECT */
433             VTABLE_set_pmc_keyed_str(interp, HashPointer, jit_key_name, temp_pmc);
434             return result;
435         }