2
* Copyright (C) 2006 - 2009 Campanoni Simone, AndreA Ciancone
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
#include <ir_method.h>
21
#include <ir_method_rpc.h>
22
#include <ir_language.h>
23
#include <compiler_memory_manager.h>
26
#include <ir_internal_functions.h>
29
static inline ir_method_t * ir_lib_iface_getIRMethod(ir_method_t * method, JITNUINT irMethodID) {
30
return ((ir_lib_t *) method->sys)->getIRMethod(((ir_lib_t *) method->sys)->context, irMethodID);
33
void ir_rpc_instr_par_create(ir_method_t * method, t_ir_instruction * inst, ir_item_t * param, ir_item_rpc_t * par_rpc) {
36
t_row_type_def_table *classID;
38
ir_method_t *methodToCall;
42
assert(method != NULL);
44
assert(param != NULL);
45
assert(par_rpc != NULL);
47
if (param->type == IRCLASSID){
48
assert(inst->binary != NULL);
49
classID = (t_row_type_def_table *) (JITNUINT) param->value;
50
assert(classID != NULL);
51
typeName = get_string(&((inst->binary->metadata).streams_metadata.string_stream), classID->type_name);
52
assert(typeName != NULL);
53
typeNameSpace = get_string(&((inst->binary->metadata).streams_metadata.string_stream), classID->type_name_space);
54
assert(typeNameSpace != NULL);
55
strLength = strlen(typeName) + strlen(typeNameSpace) + 2;
56
(par_rpc->name).name_val = (char *) allocFunction( sizeof(char) * strLength);
57
(par_rpc->name).name_len = strLength;
58
snprintf((par_rpc->name).name_val, strLength * sizeof(char), "%s.%s", typeNameSpace, typeName);
59
} else if (param->type == IRMETHODID){
60
methodID = (ILMethodID) (JITNUINT) param->value;
61
assert(methodID != NULL);
62
methodToCall = ir_lib_iface_getIRMethod(method, methodID);
63
assert(methodToCall != NULL);
64
strLength = strlen(methodToCall->getName(methodToCall)) + 1;
65
(par_rpc->name).name_val = (char *) allocFunction( sizeof(char) * strLength);
66
(par_rpc->name).name_len = strLength;
67
snprintf((par_rpc->name).name_val, strLength * sizeof(char), "%s", methodToCall->getName(methodToCall));
69
(par_rpc->name).name_len = 0;
70
(par_rpc->name).name_val = NULL;
72
par_rpc->value = param->value;
73
par_rpc->fvalue = param->fvalue;
74
par_rpc->type = param->type;
75
par_rpc->internal_type = param->internal_type;
76
if ((param->value_type_infos).type_infos == NULL){
77
(par_rpc->infos).type_infos = 0;
80
assert((param->value_type_infos).type_infos != NULL);
81
//* FIXME why segfault? find reason
82
//* assert((param->value_type_infos).type_infos->ID != NULL);
83
//* assert((param->value_type_infos).type_infos->binary != NULL);
84
(par_rpc->infos).isByref = (param->value_type_infos).isByref;
85
(par_rpc->infos).type_infos = (JITNINT) (param->value_type_infos).type_infos;
90
void ir_rpc_instr_call_params_create(ir_method_t * method, t_ir_instruction *inst, ir_instr_rpc_t *rpc_inst) {
98
assert(rpc_inst != NULL);
100
/* Initialize the variables */
106
/* Check if the IR instruction is a call */
107
if ( (inst->callParameters == NULL) ||
108
(inst->callParameters->length(inst->callParameters) == 0) ){
109
(rpc_inst->call_parameters).call_parameters_len = 0;
110
(rpc_inst->call_parameters).call_parameters_val = NULL;
114
/* Fetch the number of the parameters */
115
count = inst->callParameters->length(inst->callParameters);
116
(rpc_inst->call_parameters).call_parameters_len = count;
120
(rpc_inst->call_parameters).call_parameters_val = (ir_item_rpc_t *) allocFunction( sizeof(ir_item_rpc_t) * count);
122
/* Make the parameters */
123
item = inst->callParameters->first(inst->callParameters);
125
assert(item != NULL);
126
param = (ir_item_t *) item->data;
127
assert(param != NULL);
128
ir_rpc_instr_par_create(method, inst, param, &((rpc_inst->call_parameters).call_parameters_val[count2]));
131
item = inst->callParameters->next(inst->callParameters, item);
135
JITINT16 ir_rpc_method_init(ir_method_t * method, ir_method_rpc_t *method_rpc) {
136
JITUINT32 instructionsIRNumber;
138
t_ir_instruction *inst;
141
assert(method != NULL);
142
assert(method_rpc != NULL);
144
/* Initialize the variables */
145
instructionsIRNumber = 0;
149
/* Fetch the IR instructions number */
150
method->lock(method);
151
instructionsIRNumber = method->getInstructionsNumber(method);
152
assert(instructionsIRNumber > 0);
154
/* Fill up the method informations */
155
method_rpc->max_variables = method->getMaxVariables(method);
156
(method_rpc->instructions).instructions_val = (ir_instr_rpc_t *) allocFunction( sizeof(ir_instr_rpc_t) * instructionsIRNumber);
157
(method_rpc->instructions).instructions_len = instructionsIRNumber;
158
method_rpc->optimize_flags = CONTINUOUS_OPTIMIZATION;
159
(method_rpc->name).name_len = strlen(method->getName(method)) + 1;
160
assert(method->getName(method)!=NULL);
161
(method_rpc->name).name_val = (char *) allocFunction( sizeof(char) * (strlen(method->getName(method)) + 1));
162
snprintf((method_rpc->name).name_val, sizeof(char) * (strlen(method->getName(method)) + 1), "%s", method->getName(method));
164
(method_rpc->local_internal_types).local_internal_types_len = method->getLocalsNumber(method);
165
if((method_rpc->local_internal_types).local_internal_types_len > 0) {
166
(method_rpc->local_internal_types).local_internal_types_val = (JITUINT32 *) allocFunction( sizeof(JITUINT32) * (method_rpc->local_internal_types).local_internal_types_len);
168
(method_rpc->local_internal_types).local_internal_types_val = NULL;
171
JITUINT32 * param = NULL;
172
for(i=0; i < (method_rpc->local_internal_types).local_internal_types_len; i++) {
173
param = method->getNextLocal(method, param);
174
assert(param != NULL);
175
(method_rpc->local_internal_types).local_internal_types_val[i] = *param;
178
/* Fill up the method's signature informations */
179
(method_rpc->signature).result_type = (method->signature).result_type;
180
(method_rpc->signature).parameter_types.parameter_types_len = (method->signature).parameters_number;
181
(method_rpc->signature).parameter_types.parameter_types_val = (method->signature).parameter_internal_types;
182
//* (method_rpc->signature).parameter_types.parameter_types_val = (unsigned int *) allocFunction( sizeof(unsigned int) * (method_rpc->signature).parameter_types.parameter_types_len);
184
/* Fill up the method's basic block informations */
185
(method_rpc->basicBlock).basicBlock_len = method->getBasicBlocksNumber(method);
186
(method_rpc->basicBlock).basicBlock_val = method->basicBlocks;
187
method_rpc->liveness_block_numbers = method->livenessBlockNumbers;
188
method_rpc->available_expressions_block_numbers = method->availableExpressionsBlockNumbers;
189
method_rpc->reaching_expressions_block_numbers = method->reachingExpressionsBlockNumbers;
190
method_rpc->reaching_definitions_block_numbers = method->reachingDefinitionsBlockNumbers;
192
/* Fill up the root set informations */
193
(method_rpc->rootSet).rootSet_len = method->getRootSetTop(method);
194
if ((method_rpc->rootSet).rootSet_len > 0){
195
(method_rpc->rootSet).rootSet_val = (JITUINT32 *) allocFunction( sizeof(JITUINT32) * (method_rpc->rootSet).rootSet_len);
197
(method_rpc->rootSet).rootSet_val = NULL;
199
for (count=0; count < method->getRootSetTop(method); count++){
200
(method_rpc->rootSet).rootSet_val[count] = method->getRootSetSlot(method, count);
203
/* Fill up the IR instructions informations */
204
for (count=0; count < instructionsIRNumber; count++){
205
inst = method->getNextInstruction(method, inst);
206
assert(inst != NULL);
207
((method_rpc->instructions).instructions_val[count]).parameters.parameters_val = (ir_item_rpc_t *) allocFunction( sizeof(ir_item_rpc_t) * 4);
208
((method_rpc->instructions).instructions_val[count]).ID = count;
209
((method_rpc->instructions).instructions_val[count]).type = inst->type;
210
((method_rpc->instructions).instructions_val[count]).byte_offset = inst->byte_offset;
211
((method_rpc->instructions).instructions_val[count]).parameters.parameters_len = 4;
212
((method_rpc->instructions).instructions_val[count]).binary = inst->binary;
213
((method_rpc->instructions).instructions_val[count]).nfunc = inst->nfunc;
215
/* Store the parameters */
216
ir_rpc_instr_par_create(method, inst, method->getInstrPar1(inst), &((method_rpc->instructions).instructions_val[count].parameters.parameters_val[0]));
217
ir_rpc_instr_par_create(method, inst, method->getInstrPar2(inst), &((method_rpc->instructions).instructions_val[count].parameters.parameters_val[1]));
218
ir_rpc_instr_par_create(method, inst, method->getInstrPar3(inst), &((method_rpc->instructions).instructions_val[count].parameters.parameters_val[2]));
219
ir_rpc_instr_par_create(method, inst, method->getInstrPar4(inst), &((method_rpc->instructions).instructions_val[count].parameters.parameters_val[3]));
220
ir_rpc_instr_par_create(method, inst, method->getInstrResult(inst), &((method_rpc->instructions).instructions_val[count].result));
222
/* Store the result */
223
ir_rpc_instr_call_params_create(method, inst, &((method_rpc->instructions).instructions_val[count]));
225
method->unlock(method);
230
void ir_instr_par_set_from_rpc(ir_item_rpc_t *param_rpc, ir_item_t * param) {
232
assert(param_rpc != NULL);
233
assert(param != NULL);
235
param->value = param_rpc->value;
236
param->fvalue = param_rpc->fvalue;
237
param->type = param_rpc->type;
238
param->internal_type = param_rpc->internal_type;
239
if ((param_rpc->infos).type_infos == 0) {
242
//* FIXME why segfault? find reason
243
//* assert(((ILType *)(param_rpc->infos).type_infos)->ID != NULL);
244
//* assert(((ILType *)(param_rpc->infos).type_infos)->binary != NULL);
245
(param->value_type_infos).isByref = (param_rpc->infos).isByref;
246
(param->value_type_infos).type_infos = (ILType *) (param_rpc->infos).type_infos;
247
assert(((param->value_type_infos).type_infos) != NULL);
248
//* FIXME why segfault? find reason
249
//* assert(((param->value_type_infos).type_infos)->ID != NULL);
250
//* assert(((param->value_type_infos).type_infos)->binary != NULL);
254
XanList * ir_intr_all_new_from_rpc(ir_method_t * method, ir_method_rpc_t *method_rpc) {
256
JITUINT32 callParamsLength;
257
XanList *instructions;
258
t_ir_instruction *inst;
260
assert(method != NULL);
261
assert(method_rpc != NULL);
263
/* Initialize the variables */
267
callParamsLength = 0;
269
/* Make the new instructions */
270
for (count=0; count < (method_rpc->instructions).instructions_len; count++){
271
assert((method_rpc->instructions).instructions_val != NULL);
272
assert((method_rpc->instructions).instructions_val[count].parameters.parameters_val != NULL);
274
/* Alloc a new instruction */
275
// inst = ir_instr_make(method);
277
assert(inst != NULL);
279
/* Insert the new instruction into the list */
280
instructions = instructions->append(instructions, inst);
281
assert(instructions != NULL);
283
/* Store the byte offset */
284
inst->byte_offset = (method_rpc->instructions).instructions_val[count].byte_offset;
286
/* Store the instruction type */
287
inst->type = (method_rpc->instructions).instructions_val[count].type;
289
/* Store the parameters */
290
ir_instr_par_set_from_rpc(&((method_rpc->instructions).instructions_val[count].parameters.parameters_val[0]), &(inst->param_1));
291
ir_instr_par_set_from_rpc(&((method_rpc->instructions).instructions_val[count].parameters.parameters_val[1]), &(inst->param_2));
292
ir_instr_par_set_from_rpc(&((method_rpc->instructions).instructions_val[count].parameters.parameters_val[2]), &(inst->param_3));
293
ir_instr_par_set_from_rpc(&((method_rpc->instructions).instructions_val[count].parameters.parameters_val[3]), &(inst->param_4));
295
/* Store the result */
296
ir_instr_par_set_from_rpc(&((method_rpc->instructions).instructions_val[count].result), &(inst->result));
298
/* Store the call parameters */
299
callParamsLength = (method_rpc->instructions).instructions_val[count].call_parameters.call_parameters_len;
300
if (callParamsLength <= 0){
301
inst->callParameters = xanListNew(allocFunction, freeFunction, NULL);
302
assert(inst->callParameters != NULL);
305
XanList *call_par_rpc;
306
call_par_rpc = xanListNew(allocFunction, freeFunction, NULL);
307
assert(call_par_rpc != NULL);
308
for (par_count=0; par_count < callParamsLength; par_count++){
310
call_par = (ir_item_t *) allocFunction( sizeof(ir_item_t));
311
call_par->type = (method_rpc->instructions).instructions_val[count].call_parameters.call_parameters_val[par_count].type;
312
call_par->internal_type = (method_rpc->instructions).instructions_val[count].call_parameters.call_parameters_val[par_count].internal_type;
313
call_par->value = (method_rpc->instructions).instructions_val[count].call_parameters.call_parameters_val[par_count].value;
314
call_par->fvalue = (method_rpc->instructions).instructions_val[count].call_parameters.call_parameters_val[par_count].fvalue;
315
call_par_rpc->append(call_par_rpc, call_par);
317
assert(callParamsLength == call_par_rpc->length(call_par_rpc));
318
inst->callParameters = call_par_rpc;
321
inst->binary = (method_rpc->instructions).instructions_val[count].binary;
322
inst->nfunc = (method_rpc->instructions).instructions_val[count].nfunc;
323
//* /* Store the instruction informations */
324
//* if ((method_rpc->instructions).instructions_val[count].ID == -1){
325
//* inst->nfunc = NULL;
326
//* inst->binary = NULL;
328
//* t_ir_instruction *old_inst;
329
//* old_inst = method->getInstructionAt(method, (JITUINT32) (method_rpc->instructions).instructions_val[count].ID);
330
//* assert(old_inst != NULL);
331
//* inst->binary = old_inst->binary;
332
//* inst->nfunc = old_inst->nfunc;
338
JITINT16 ir_method_set_from_rpc(ir_method_t * method, ir_method_rpc_t *method_rpc){
339
XanList *new_instructions;
344
assert(method != NULL);
345
assert(method_rpc != NULL);
347
/* Fill up the method informations */
348
method->lock(method);
349
method->setMaxVariables(method, method_rpc->max_variables);
350
name = (char *) allocFunction( sizeof(char) * (method_rpc->name).name_len);
351
snprintf(name, sizeof(char) * (method_rpc->name).name_len, "%s", method->getName(method));
352
method->setName(method, name);
354
method->setLocalsNumber(method, (method_rpc->local_internal_types).local_internal_types_len);
356
JITUINT32 * param = (JITUINT32 *) allocFunction( sizeof(JITUINT32) * (method_rpc->local_internal_types).local_internal_types_len);
357
for(i=0; i < (method_rpc->local_internal_types).local_internal_types_len; i++) {
358
param[i] = (method_rpc->local_internal_types).local_internal_types_val[i];
359
method->insertLocal(method, &(param[i]) );
362
/* Fill up the method's signature informations */
365
(method_rpc->signature).result_type = (method->signature).result_type;
366
(method_rpc->signature).parameter_types.parameter_types_len = (method->signature).parameters_number;
367
(method_rpc->signature).parameter_types.parameter_types_val = (method->signature).parameter_internal_types;
368
// (method_rpc->signature).parameter_types.parameter_types_val = (unsigned int *) allocFunction( sizeof(unsigned int) * (method_rpc->signature).parameter_types.parameter_types_len);
370
/* Make the new instructions */
371
new_instructions = ir_intr_all_new_from_rpc(method, method_rpc);
372
assert(new_instructions != NULL);
374
/* Insert all the new instructions */
375
method->instructions = new_instructions;
377
/* Fill up the method's basic block informations */
378
(method->root_set).top = (method_rpc->basicBlock).basicBlock_len;
379
(method->root_set).allocated = (method_rpc->basicBlock).basicBlock_len;
380
(method->root_set).rootSet = (method_rpc->basicBlock).basicBlock_val;
382
method->livenessAllocBlocks(method, method_rpc->liveness_block_numbers);
383
method->reachingDefinitionsAllocBlocks(method, method_rpc->reaching_definitions_block_numbers);
384
method->reachingExpressionsAllocBlocks(method, method_rpc->reaching_expressions_block_numbers);
385
method->availableExpressionsAllocBlocks(method, method_rpc->available_expressions_block_numbers);
387
/* Fill up the root set informations */
388
assert((method_rpc->rootSet).rootSet_len == 0 || (method_rpc->rootSet).rootSet_val != NULL);
389
for (count=0; count < (method_rpc->rootSet).rootSet_len; count++){
390
method->addVariableToRootSet(method, (method_rpc->rootSet).rootSet_val[count]);
392
assert((method_rpc->rootSet).rootSet_val == method->getRootSetTop(method));
394
/* Store the new method optimized */
395
method->setMaxVariables(method, method_rpc->max_variables);
396
method->unlock(method);
401
JITINT16 ir_method_update_from_rpc(ir_method_t * method, ir_method_rpc_t *method_rpc){
402
XanList *new_instructions;
406
assert(method != NULL);
408
/* Check if there was no error durin the transmission with the optimizer */
409
if (method_rpc == NULL) return -1;
411
method->lock(method);
412
method->destroy(method);
413
/* Free the memory of the previous instructions */
414
method->deleteInstructions(method);
416
ir_method_set_from_rpc(method, method_rpc);
417
method->unlock(method);
422
void ir_rpc_method_delete(struct ir_method_t *method, ir_method_rpc_t * method_rpc) {
426
assert(method_rpc != NULL);
428
/* Free the call paremeters for *
429
* each IR instruction */
430
method->lock(method);
431
for (count=0; count < (method_rpc->instructions).instructions_len; count++){
433
if((method_rpc->instructions).instructions_val[count].call_parameters.call_parameters_len > 0){
434
freeFunction( (method_rpc->instructions).instructions_val[count].call_parameters.call_parameters_val);
436
freeFunction( ((method_rpc->instructions).instructions_val[count]).parameters.parameters_val);
439
/* Free the IR instructions */
440
freeFunction( (method_rpc->instructions).instructions_val);
442
/* Free the method informations */
443
freeFunction( (method_rpc->name).name_val);
444
method->unlock(method);