Skip to content
This repository
Browse code

Working on refactoring memory allocation for dynamic function calls

  • Loading branch information...
commit d6abdbbb2570a66871a68c310b7df610b9fbefb6 1 parent 37945e3
John Harrison authored

Showing 1 changed file with 90 additions and 87 deletions. Show diff stats Hide diff stats

  1. +90 87 src/pmc/nci.pmc
177 src/pmc/nci.pmc
@@ -124,7 +124,10 @@ find_matching(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length,
124 124
125 125 typedef struct pmc_holder_t {
126 126 PMC* p;
127   - INTVAL* val;
  127 + union {
  128 + INTVAL* ival;
  129 + void** pval;
  130 + };
128 131 } pmc_holder_t;
129 132
130 133 /*
@@ -155,7 +158,7 @@ parse_sig(PARROT_INTERP, STRING *sig, size_t sig_length, Parrot_NCI_attributes *
155 158 arg_types = mem_internal_allocate_n_zeroed_typed(1, ffi_type*);
156 159 arg_types[0] = &ffi_type_void;
157 160 nci_info->pcc_params_signature = string_make(interp, "", 1, NULL, 0);
158   - nci_info->arg_translation = "";
  161 + nci_info->arg_translation = NULL;
159 162 nci_info->arity = 0;
160 163 }
161 164 }
@@ -164,7 +167,7 @@ parse_sig(PARROT_INTERP, STRING *sig, size_t sig_length, Parrot_NCI_attributes *
164 167 arg_types[0] = &ffi_type_void;
165 168 return_type = &ffi_type_void;
166 169 nci_info->pcc_params_signature = string_make(interp, "", 1, NULL, 0);
167   - nci_info->arg_translation = "";
  170 + nci_info->arg_translation = NULL;
168 171 nci_info->arity = 0;
169 172 }
170 173
@@ -335,18 +338,6 @@ parse_identifier(PARROT_INTERP,
335 338 *type_obj = &ffi_type_schar;
336 339 }
337 340 break;
338   - /*
339   - case (INTVAL)'b':
340   - translation[(*translation_count) - 1] = 'b';
341   - type[(*pmc_count)++] = 'I';
342   - if (prefix & PREFIX_UNSIGNED) {
343   - *type_obj = &ffi_type_uint8;
344   - }
345   - else {
346   - *type_obj = &ffi_type_sint8;
347   - }
348   - break;
349   - */
350 341 case (INTVAL)'B':
351 342 translation[(*translation_count) - 1] = 'B';
352 343 type[(*pmc_count)++] = 'S';
@@ -460,7 +451,7 @@ parse_identifier(PARROT_INTERP,
460 451 type[(*pmc_count)++] = 'N';
461 452 *type_obj = &ffi_type_double;
462 453 break;
463   -#if (DOUBEL_SIZE > 8) /* FLOATVAL is a long double */
  454 +#if (DOUBLE_SIZE > 8) /* FLOATVAL is a long double */
464 455 case (INTVAL)'N':
465 456 #endif
466 457 case (INTVAL)'D':
@@ -478,7 +469,7 @@ parse_identifier(PARROT_INTERP,
478 469 type[(*pmc_count)++] = 'P';
479 470 type[(*pmc_count)++] = 's';
480 471 break;
481   - defualt:
  472 + default:
482 473 Parrot_ex_throw_from_c_args(interp, NULL,
483 474 EXCEPTION_JIT_ERROR,
484 475 "Unknown param Signature %c\n", (char)c);
@@ -1021,7 +1012,7 @@ class, the PMC arguments are shifted down.
1021 1012 INTVAL return_size = sizeof (void*);
1022 1013 PMC *ctx = CURRENT_CONTEXT(interp);
1023 1014 PMC *call_object = Parrot_pcc_get_signature(interp, ctx);
1024   - void* (*func)(); /* a function pointer for our function to call */
  1015 + void (*func)(void*,void*,void*); /* a function pointer for our function to call */
1025 1016
1026 1017 if (PObj_flag_TEST(private2, SELF)) {
1027 1018 void *orig_func;
@@ -1029,11 +1020,11 @@ class, the PMC arguments are shifted down.
1029 1020 GET_ATTR_orig_func(INTERP, SELF, orig_func);
1030 1021 GET_ATTR_fb_info(INTERP, SELF, fb_info);
1031 1022
1032   - func = FFI_FN(orig_func);
  1023 + func = (void (*)(void*, void*, void*))orig_func;
1033 1024
1034 1025 if (!func) {
1035 1026 /* build the thunk only when necessary */
1036   - func = FFI_FN(build_func(interp, nci_info));
  1027 + func = (void (*)(void*, void*, void*))build_func(interp, nci_info);
1037 1028
1038 1029 if (!func)
1039 1030 Parrot_ex_throw_from_c_args(INTERP, NULL,
@@ -1041,23 +1032,21 @@ class, the PMC arguments are shifted down.
1041 1032 "attempt to call NULL function");
1042 1033 }
1043 1034
1044   - func = FFI_FN(D2FPTR(orig_func));
  1035 + func = (void (*)(void*, void*, void*))(orig_func);
1045 1036 func(INTERP, SELF, fb_info);
1046 1037 }
1047 1038 else {
1048 1039 PMC *positional, *arg_iter;
1049 1040 STRING *void_return;
1050   - void **values, **middle_man, **pcc_values, **translation_pointers;
  1041 + void **values, **middle_man, **pcc_ptr, **pcc_value, **translation_pointers;
1051 1042 void *return_data;
1052 1043 size_t count, i, j_offset;
1053 1044 char *tmp_sig;
1054 1045 ffi_cif *cif, pcc_cif;
1055 1046 ffi_type **pcc_args;
1056 1047
1057   - PMC * pmc_3;
1058   -
1059   - cif = nci_info->cif;
1060   - GET_ATTR_func(INTERP, SELF, func);
  1048 + cif = (ffi_cif*)nci_info->cif;
  1049 + func = (void (*)(void*, void*, void*))nci_info->func;
1061 1050
1062 1051 if (!cif) {
1063 1052 /* build the thunk only when necessary */
@@ -1070,62 +1059,67 @@ class, the PMC arguments are shifted down.
1070 1059 }
1071 1060
1072 1061 if (nci_info->arity > 0) {
1073   - size_t pcc_values_offset, pcc_values_size;
1074   - /* Function has arguments */
1075   - values = mem_internal_allocate_n_zeroed_typed(nci_info->arity + 1, void*);
  1062 + size_t pcc_argc, pcc_values_offset, pcc_values_size, values_size;
  1063 + /* Function has arguments */
1076 1064 pcc_args = mem_internal_allocate_n_zeroed_typed(nci_info->arity + 4, ffi_type*);
1077   -
1078   - if (nci_info->pcc_params_signature)
1079   - tmp_sig = Parrot_str_to_cstring(interp, nci_info->pcc_params_signature);
  1065 +
  1066 + tmp_sig = Parrot_str_to_cstring(interp, nci_info->pcc_params_signature);
1080 1067
1081 1068 pcc_args[0] = &ffi_type_pointer;
1082 1069 pcc_args[1] = &ffi_type_pointer;
1083 1070 pcc_args[2] = &ffi_type_pointer;
1084   - pcc_values_size = 0;
1085   - for (i = 0; i < nci_info->arity; i++) {
  1071 + pcc_values_size = 0;
  1072 + values_size = 0;
  1073 + pcc_argc = Parrot_str_length(interp, nci_info->pcc_params_signature);
  1074 + /* Add up the size of the pcc arguments */
  1075 + for (i = 0; i < pcc_argc; i++) {
1086 1076 pcc_args[i + 3] = &ffi_type_pointer;
1087   - if (tmp_sig[i] == 'N')
1088   - pcc_values_size += sizeof(FLOATVAL);
1089   - else if (tmp_sig[i] == 'I')
1090   - pcc_values_size += sizeof(INTVAL);
1091   - else if (tmp_sig[i] == 'P' || tmp_sig[i] == 'S')
1092   - pcc_values_size += sizeof(void*);
  1077 + if (tmp_sig[i] == 'N')
  1078 + pcc_values_size += sizeof(FLOATVAL);
  1079 + else if (tmp_sig[i] == 'I')
  1080 + pcc_values_size += sizeof(INTVAL);
  1081 + else if (tmp_sig[i] == 'P' || tmp_sig[i] == 'S')
  1082 + pcc_values_size += sizeof(void*);
  1083 + }
  1084 +
  1085 + /* Add up the size of memory needed for the actual call */
  1086 + for (i = 0; i < (size_t)nci_info->arity; i++) {
  1087 + values_size += cif->arg_types[i]->size;
1093 1088 }
1094 1089
1095   - if (ffi_prep_cif(&pcc_cif, FFI_DEFAULT_ABI, 3 + nci_info->arity,
  1090 + if (ffi_prep_cif(&pcc_cif, FFI_DEFAULT_ABI, 3 + pcc_argc,
1096 1091 &ffi_type_void, pcc_args) != FFI_OK) {
1097 1092 Parrot_ex_throw_from_c_args(INTERP, NULL,
1098 1093 EXCEPTION_INVALID_OPERATION,
1099 1094 "Bad signature generated for Parrot_pcc_fill_params_from_c_args in NCI");
1100 1095 }
1101 1096
1102   - fprintf(stderr, "Allocating... %d\n", pcc_values_size);
  1097 + fprintf(stderr, "Allocating... %s %d %d\n", tmp_sig, values_size, pcc_values_size + sizeof(void*));
1103 1098
1104   - pcc_values = mem_internal_allocate_zeroed(pcc_values_size + sizeof(void*) * 4);
  1099 + pcc_ptr = (void**)mem_internal_allocate_n_zeroed_typed(pcc_argc, void*);
  1100 + pcc_value = (void**)mem_internal_allocate_zeroed(pcc_values_size + sizeof(void*));
1105 1101
1106 1102 /* Setup Parrot_pcc_fill_params_from_c_args required arguments */
1107   - pcc_values[0] = &interp;
1108   - pcc_values[1] = &call_object;
1109   - pcc_values[2] = &tmp_sig;
  1103 + pcc_ptr[0] = &interp;
  1104 + pcc_ptr[1] = &call_object;
  1105 + pcc_ptr[2] = &tmp_sig;
1110 1106
1111   - middle_man = mem_internal_allocate_n_zeroed_typed(nci_info->arity + 1, void*);
  1107 + values = (void**)mem_internal_allocate_zeroed(values_size + sizeof(void*));
  1108 + /* Middle man is used to contain */
  1109 + middle_man = mem_internal_allocate_n_zeroed_typed(nci_info->arity, void*);
1112 1110
1113 1111 /* Fill in arg references, J is magically inserted, so we need
1114 1112 * to offset the other variables if a J is supposed to be used
1115 1113 */
1116   - j_offset = 0;
1117   - pcc_values_offset = 0;
1118   - for (i = 0; i < nci_info->arity; i++) {
1119   - if (((char*)nci_info->arg_translation)[i] == 'J')
1120   - j_offset++;
1121   - middle_man[i] = &values[i + j_offset];
1122   - pcc_values[i + 3 + pcc_values_offset] = &middle_man[i];
1123   - if (tmp_sig[i] == 'N') {
1124   - pcc_values_offset += 1;
1125   - }
  1114 + pcc_values_offset = 0;
  1115 + for (i = 0; i < (size_t)nci_info->arity; i++) {
  1116 + pcc_ptr[i + 3] = &pcc_value[i + pcc_values_offset];
  1117 + if (tmp_sig[i] == 'N') {
  1118 + pcc_values_offset += 1;
  1119 + }
1126 1120 }
1127 1121
1128   - ffi_call(&pcc_cif, FFI_FN(Parrot_pcc_fill_params_from_c_args), NULL, pcc_values);
  1122 + ffi_call(&pcc_cif, FFI_FN(Parrot_pcc_fill_params_from_c_args), NULL, pcc_value);
1129 1123 Parrot_str_free_cstring(tmp_sig);
1130 1124
1131 1125 /*
@@ -1135,45 +1129,47 @@ class, the PMC arguments are shifted down.
1135 1129 * but other transformations might apply later, like packing an
1136 1130 * object into a ManagedStruct
1137 1131 */
  1132 + j_offset = 0;
1138 1133 translation_pointers = mem_internal_allocate_n_zeroed_typed(nci_info->arity, void*);
1139   - for (i = 0; i < nci_info->arity; i++) {
  1134 + for (i = 0; i < (size_t)nci_info->arity; i++) {
1140 1135 switch ((INTVAL)((char*)nci_info->arg_translation)[i]) {
1141 1136 case 'J':
1142 1137 values[i] = &interp;
  1138 + j_offset++;
1143 1139 break;
1144 1140 case 't':
1145   - if (STRING_IS_NULL((STRING*)values[i])) {
  1141 + if (STRING_IS_NULL((STRING*)pcc_value[i - j_offset])) {
1146 1142 translation_pointers[i] = (char*) NULL;
1147 1143 }
1148 1144 else {
1149   - translation_pointers[i] = Parrot_str_to_cstring(interp, (STRING*)values[i]);
  1145 + translation_pointers[i] = Parrot_str_to_cstring(interp, (STRING*)pcc_value[i - j_offset]);
1150 1146 }
1151 1147 values[i] = &translation_pointers[i];
1152 1148 break;
1153 1149 case 'B':
1154   - if (STRING_IS_NULL((STRING*)values[i])) {
  1150 + if (STRING_IS_NULL((STRING*)pcc_value[i - j_offset])) {
1155 1151 translation_pointers[i] = (char*) NULL;
1156 1152 }
1157 1153 else {
1158   - translation_pointers[i] = Parrot_str_to_cstring(interp, (STRING*)values[i]);
  1154 + translation_pointers[i] = Parrot_str_to_cstring(interp, (STRING*)pcc_value[i - j_offset]);
1159 1155 }
1160 1156 middle_man[i] = &translation_pointers[i];
1161 1157 values[i] = &middle_man[i];
1162 1158 break;
1163 1159 case 'b':
1164   - values[i] = &Buffer_bufstart((STRING*)values[i]);
  1160 + values[i] = &Buffer_bufstart((STRING*)pcc_value[i - j_offset]);
1165 1161 break;
1166 1162 case 'c':
1167 1163 translation_pointers[i] = mem_internal_allocate_zeroed_typed(char);
1168   - *((char**)translation_pointers)[i] = (char)*(INTVAL*)middle_man[i];
  1164 + *((char**)translation_pointers)[i] = (char)*(*INTVAL)pcc_ptr[i + 3 - j_offset];
1169 1165 values[i] = translation_pointers[i];
1170 1166 break;
1171 1167 case '2':
1172 1168 translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
1173 1169 ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)middle_man[i];
1174   - ((pmc_holder_t*)translation_pointers[i])->val = mem_internal_allocate_zeroed_typed(short);
1175   - *((pmc_holder_t*)translation_pointers[i])->val = (short)VTABLE_get_integer(interp, *(PMC**)middle_man[i]);
1176   - values[i] = &((pmc_holder_t*)translation_pointers[i])->val;
  1170 + ((pmc_holder_t*)translation_pointers[i])->ival = (INTVAL*)mem_internal_allocate_zeroed_typed(short);
  1171 + *((pmc_holder_t*)translation_pointers[i])->ival = (short)VTABLE_get_integer(interp, *(PMC**)middle_man[i]);
  1172 + values[i] = &((pmc_holder_t*)translation_pointers[i])->ival;
1177 1173 break;
1178 1174 case 's':
1179 1175 translation_pointers[i] = mem_internal_allocate_zeroed_typed(short);
@@ -1183,9 +1179,9 @@ class, the PMC arguments are shifted down.
1183 1179 case '3':
1184 1180 translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
1185 1181 ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)middle_man[i];
1186   - ((pmc_holder_t*)translation_pointers[i])->val = mem_internal_allocate_zeroed_typed(int);
1187   - *((pmc_holder_t*)translation_pointers[i])->val = (int)VTABLE_get_integer(interp, *(PMC**)middle_man[i]);
1188   - values[i] = &((pmc_holder_t*)translation_pointers[i])->val;
  1182 + ((pmc_holder_t*)translation_pointers[i])->ival = (INTVAL*)mem_internal_allocate_zeroed_typed(int);
  1183 + *((pmc_holder_t*)translation_pointers[i])->ival = (int)VTABLE_get_integer(interp, *(PMC**)middle_man[i]);
  1184 + values[i] = &((pmc_holder_t*)translation_pointers[i])->ival;
1189 1185 break;
1190 1186 case 'i':
1191 1187 translation_pointers[i] = mem_internal_allocate_zeroed_typed(int);
@@ -1195,9 +1191,9 @@ class, the PMC arguments are shifted down.
1195 1191 case '4':
1196 1192 translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
1197 1193 ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)middle_man[i];
1198   - ((pmc_holder_t*)translation_pointers[i])->val = mem_internal_allocate_zeroed_typed(long);
1199   - *((pmc_holder_t*)translation_pointers[i])->val = (long)VTABLE_get_integer(interp, *(PMC**)middle_man[i]);
1200   - values[i] = &((pmc_holder_t*)translation_pointers[i])->val;
  1194 + ((pmc_holder_t*)translation_pointers[i])->ival = (INTVAL*)mem_internal_allocate_zeroed_typed(long);
  1195 + *((pmc_holder_t*)translation_pointers[i])->ival = (long)VTABLE_get_integer(interp, *(PMC**)middle_man[i]);
  1196 + values[i] = &((pmc_holder_t*)translation_pointers[i])->ival;
1201 1197 break;
1202 1198 case 'l':
1203 1199 translation_pointers[i] = mem_internal_allocate_zeroed_typed(long);
@@ -1212,9 +1208,9 @@ class, the PMC arguments are shifted down.
1212 1208 case 'V':
1213 1209 translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
1214 1210 ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)middle_man[i];
1215   - ((pmc_holder_t*)translation_pointers[i])->val = mem_internal_allocate_zeroed_typed(void*);
1216   - *((pmc_holder_t*)translation_pointers[i])->val = (void*)VTABLE_get_pointer(interp, *(PMC**)middle_man[i]);
1217   - values[i] = &((pmc_holder_t*)translation_pointers[i])->val;
  1211 + ((pmc_holder_t*)translation_pointers[i])->pval = (void**)mem_internal_allocate_zeroed_typed(void*);
  1212 + *((pmc_holder_t*)translation_pointers[i])->pval = (void*)VTABLE_get_pointer(interp, *(PMC**)middle_man[i]);
  1213 + values[i] = &((pmc_holder_t*)translation_pointers[i])->pval;
1218 1214 break;
1219 1215 case 'P':
1220 1216 translation_pointers[i] = values[i];
@@ -1244,7 +1240,7 @@ class, the PMC arguments are shifted down.
1244 1240 mem_sys_free(pcc_args);
1245 1241 }
1246 1242 if (pcc_values) {
1247   - mem_sys_free(pcc_values);
  1243 + /* mem_sys_free(pcc_values); */
1248 1244 }
1249 1245 }
1250 1246 else {
@@ -1268,11 +1264,10 @@ class, the PMC arguments are shifted down.
1268 1264 case 'p':
1269 1265 {
1270 1266 PMC *final_destination = PMCNULL;
1271   -
  1267 +
1272 1268 if (*(void**)return_data != NULL) {
1273 1269 final_destination = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
1274 1270 VTABLE_set_pointer(interp, final_destination, *(void**)return_data);
1275   -
1276 1271 }
1277 1272 ret_object = Parrot_pcc_build_call_from_c_args(interp,
1278 1273 call_object,
@@ -1323,38 +1318,46 @@ class, the PMC arguments are shifted down.
1323 1318 * Free memory used for cstrings,
1324 1319 * and any other translations that use temporary memory
1325 1320 */
1326   - for (i = 0; i < nci_info->arity; i++) {
  1321 + for (i = 0; i < (size_t)nci_info->arity; i++) {
1327 1322 switch ((INTVAL)((char*)nci_info->arg_translation)[i]) {
1328 1323 case (INTVAL)'B':
1329 1324 if (translation_pointers[i]) {
1330   - Parrot_str_free_cstring(translation_pointers[i]);
  1325 + Parrot_str_free_cstring((char*)translation_pointers[i]);
1331 1326 }
1332 1327 break;
1333 1328 case (INTVAL)'t':
1334 1329 if (translation_pointers[i]) {
1335   - Parrot_str_free_cstring(translation_pointers[i]);
  1330 + Parrot_str_free_cstring((char*)translation_pointers[i]);
1336 1331 }
1337 1332 break;
1338 1333 case (INTVAL)'2':
1339   - VTABLE_set_integer_native(interp, ((pmc_holder_t*)translation_pointers[i])->p, (INTVAL)*(short*)((pmc_holder_t*)translation_pointers[i])->val);
  1334 + VTABLE_set_integer_native(interp,
  1335 + ((pmc_holder_t*)translation_pointers[i])->p,
  1336 + (INTVAL)*(short*)((pmc_holder_t*)translation_pointers[i])->ival);
1340 1337 if (translation_pointers[i]) {
1341 1338 mem_sys_free(translation_pointers[i]);
1342 1339 }
1343 1340 break;
1344 1341 case (INTVAL)'3':
1345   - VTABLE_set_integer_native(interp, ((pmc_holder_t*)translation_pointers[i])->p, (INTVAL)*(int*)((pmc_holder_t*)translation_pointers[i])->val);
  1342 + VTABLE_set_integer_native(interp,
  1343 + ((pmc_holder_t*)translation_pointers[i])->p,
  1344 + (INTVAL)*(int*)((pmc_holder_t*)translation_pointers[i])->ival);
1346 1345 if (translation_pointers[i]) {
1347 1346 mem_sys_free(translation_pointers[i]);
1348 1347 }
1349 1348 break;
1350 1349 case (INTVAL)'4':
1351   - VTABLE_set_integer_native(interp, ((pmc_holder_t*)translation_pointers[i])->p, (INTVAL)*(long*)((pmc_holder_t*)translation_pointers[i])->val);
  1350 + VTABLE_set_integer_native(interp,
  1351 + ((pmc_holder_t*)translation_pointers[i])->p,
  1352 + (INTVAL)*(long*)((pmc_holder_t*)translation_pointers[i])->ival);
1352 1353 if (translation_pointers[i]) {
1353 1354 mem_sys_free(translation_pointers[i]);
1354 1355 }
1355 1356 break;
1356 1357 case (INTVAL)'V':
1357   - VTABLE_set_pointer(interp, ((pmc_holder_t*)translation_pointers[i])->p, (void*)*(void**)((pmc_holder_t*)translation_pointers[i])->val);
  1358 + VTABLE_set_pointer(interp,
  1359 + ((pmc_holder_t*)translation_pointers[i])->p,
  1360 + (PMC*)*((pmc_holder_t*)translation_pointers[i])->pval);
1358 1361 if (translation_pointers[i]) {
1359 1362 mem_sys_free(translation_pointers[i]);
1360 1363 }

0 comments on commit d6abdbb

Please sign in to comment.
Something went wrong with that request. Please try again.