RSS

(root)/ildjit/libiljitirprofiler : 1 : src/irspecializer.c

« back to all changes in this revision

Viewing changes to src/irspecializer.c

Speziale Ettore
2009-11-18 09:55:46
Revision ID: ettore@mars-20091118095546-yfnbhnvbiw32txil
Initial import into Bazaar.

Show diffs side-by-side

added added

removed removed

 
1
/*
 
2
 * Copyright (C) 2007, 2008  Campanoni Simone, Anelli Stefano
 
3
 *
 
4
 * iljit - This is a Just-in-time for the CIL language specified with the ECMA-335
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 */
 
20
/***************************************** HEADERS */
 
21
#include <stdio.h>
 
22
#include <stdlib.h>
 
23
#include <string.h>
 
24
#include <xanlib.h>
 
25
#include <pthread.h>
 
26
#include <ir_method.h>
 
27
#include <jitsystem.h>
 
28
#include <decoding_tools.h>
 
29
#include <ir_language.h>
 
30
#include <ecma_constant.h>
 
31
#include <compiler_memory_manager.h>
 
32
 
 
33
// My headers
 
34
#include <irprofiler_system.h>
 
35
#include <ir_optimization_interface.h>
 
36
#include "irprofiler.h"
 
37
#include "irspecializer.h"
 
38
#include "irspecializer_util.h"
 
39
#include "irspecializer_perform.h"
 
40
// End
 
41
 
 
42
/***************************************** INTERFACES */
 
43
 
 
44
/*----------------------------------------- ir_specializer_t ----------------------------------------*/
 
45
void ir_specializer_manageCallSitesBeforeCompile(ir_specializer_t* specializer,
 
46
                        void* ilMethod, JITUINT32 recompileStateValue,
 
47
                        ir_method_t* (*getIRMethod)(void* ilMethod),
 
48
                        void (*setState)(void* ilMethod, JITUINT32 state), JITUINT32 (*getState)(void* ilMethod),
 
49
                        void (*setJITFunction) (void *ilMethod, void* jitFunction), void* (*getJITFunction)(void *ilMethod),
 
50
                        JITBOOLEAN (*isCctor)(void* ilMethod));
 
51
void ir_specializer_shutdown(struct ir_specializer_t* specializer);
 
52
 
 
53
void ir_specializer_loadHintsFromFile(ir_specializer_t* specializer, char* programName);
 
54
void ir_specializer_printHintsForMethod(ir_specializer_t *specializer, FILE* out);
 
55
 
 
56
void* ir_specializer_recompile_request_thread(void* parameters);
 
57
 
 
58
/* ----------------------------------------- specializer_expression_hint_t -----------------------------------------*/
 
59
void specializer_expression_hint_init(struct specializer_expression_hint_t* expression, JITUINT32 position, JITUINT32 action, JITINT64 ivalue, JITFLOAT64 fvalue,  struct specializer_expression_hint_t* prev, struct specializer_expression_hint_t* next);
 
60
void specializer_expression_hint_printSingle(struct specializer_expression_hint_t* expression, FILE *out);
 
61
void specializer_expression_hint_printChain(struct specializer_expression_hint_t* expression, FILE *out);
 
62
void specializer_expression_hint_clean(struct specializer_expression_hint_t* expression, ir_specializer_t* specializer);
 
63
 
 
64
/* ----------------------------------------- specializer_hintsForMethod_t -----------------------------------------*/
 
65
void specializer_hintsForMethod_init(specializer_hintsForMethod_t *hints, char* methodCompleteName, char* methodSignature, JITFLOAT32 zeroProfilerTypeThreshold, JITUINT32 zeroProfilerMemorySize, JITUINT32 zeroDispatcherRemoveThreshold, JITUINT32 firstProfilerThreshold, JITUINT32 secondProfilerMemorySize, JITFLOAT32 secondProfilerStaticThreshold, JITUINT32 dispatcherRemoveThreshold, ir_specializer_t* specializer);
 
66
void specializer_hintsForMethod_print(specializer_hintsForMethod_t *hints, FILE* out);
 
67
void specializer_hintsForMethod_clean(specializer_hintsForMethod_t *hints, ir_specializer_t* specializer);
 
68
JITBOOLEAN specializer_hintsForMethod_equals(specializer_hintsForMethod_t *hints, char *methodCompleteName, char *methodSignature);
 
69
void specializer_hintsForMethod_addExpression(specializer_hintsForMethod_t *hints, specializer_expression_hint_t* expression);
 
70
specializer_expression_hint_t* specializer_hintsForMethod_getExpression(specializer_hintsForMethod_t *hints, JITUINT32 index);
 
71
JITUINT32 specializer_hintsForMethod_getExpressionsNumber(specializer_hintsForMethod_t *hints);
 
72
 
 
73
/* ----------------------------------------- specializer_method_wrapper_t -----------------------------------------*/
 
74
void specializer_method_wrapper_init(specializer_method_wrapper_t* methodWrapper,
 
75
                        void* ilMethod, JITUINT32 recompileStateValue,
 
76
                        ir_method_t* (*getIRMethod)(void* ilMethod),
 
77
                        void (*setState)(void* ilMethod, JITUINT32 state), JITUINT32 (*getState)(void* ilMethod),
 
78
                        void (*setJITFunction) (void *ilMethod, void* jitFunction), void* (*getJITFunction)(void *ilMethod),
 
79
                        JITBOOLEAN (*isCctor)(void* ilMethod));
 
80
void specializer_method_wrapper_print (ir_specializer_t *specializer, specializer_method_wrapper_t* methodWrapper, FILE* out);
 
81
void specializer_method_wrapper_clean(specializer_method_wrapper_t* methodWrapper, ir_specializer_t* specializer);
 
82
ir_method_t* specializer_method_wrapper_getIRMethod(specializer_method_wrapper_t* methodWrapper);
 
83
void specializer_method_wrapper_setState(specializer_method_wrapper_t* methodWrapper, JITUINT32 state);
 
84
JITUINT32 specializer_method_wrapper_getState(specializer_method_wrapper_t* methodWrapper);
 
85
void specializer_method_wrapper_setToRecompileState(specializer_method_wrapper_t* methodWrapper);
 
86
void specializer_method_wrapper_setJITFunction(specializer_method_wrapper_t* methodWrapper, void* jitFunction);
 
87
void* specializer_method_wrapper_getJITFunction(specializer_method_wrapper_t* methodWrapper);
 
88
JITBOOLEAN specializer_method_wrapper_isCctor(specializer_method_wrapper_t* methodWrapper);
 
89
 
 
90
/* ----------------------------------------- specializer_method_callSite_t -----------------------------------------*/
 
91
void specializer_method_callSite_init(specializer_method_callSite_t* callSite, specializer_method_wrapper_t *methodWrapper, t_ir_instruction* call, specializer_hintsForMethod_t *hints, ir_specializer_t* specializer);
 
92
void specializer_method_callSite_print (specializer_method_callSite_t* callSite, FILE* out, ir_specializer_t *specializer);
 
93
void specializer_method_callSite_clean(specializer_method_callSite_t* callSite, ir_specializer_t* specializer);
 
94
void specializer_method_callSite_addInstruction(specializer_method_callSite_t* callSite, t_ir_instruction* instruction);
 
95
JITINT32 specializer_method_callSite_hasVariableParameters (specializer_method_callSite_t* callSite);
 
96
void specializer_method_callSite_removeInstructionsFromMethod(specializer_method_callSite_t* callSite, ir_method_t* irMethod);
 
97
void specializer_method_callSite_performAction(specializer_method_callSite_t* callSite, specializer_method_wrapper_t* callerWrapper, ir_specializer_t* specializer);
 
98
 
 
99
 
 
100
/* ----------------------------------------- specializer_callSitesForMethod_t -----------------------------------------*/
 
101
void specializer_callSitesForMethod_init(specializer_callSitesForMethod_t* callSitesForMethod, specializer_method_wrapper_t* wrapper, ir_specializer_t* specializer);
 
102
void specializer_callSitesForMethod_print (specializer_callSitesForMethod_t* callSitesForMethod, FILE* out, ir_specializer_t *specializer);
 
103
void specializer_callSitesForMethod_clean(specializer_callSitesForMethod_t* callSitesForMethod, ir_specializer_t* specializer);
 
104
specializer_method_callSite_t*  specializer_callSitesForMethod_getCallSiteForInstruction(specializer_callSitesForMethod_t* callSitesForMethod, specializer_method_wrapper_t *methodWrapper, t_ir_instruction* call, specializer_hintsForMethod_t *hints, ir_specializer_t* specializer);
 
105
JITBOOLEAN      specializer_callSitesForMethod_isInjectedInstruction(specializer_callSitesForMethod_t* callSitesForMethod, t_ir_instruction* instruction);
 
106
 
 
107
/* ----------------------------------------- specializer_method_callSite_firstProfiler_t -----------------------------------------*/
 
108
void specializer_method_callSite_firstProfiler_init(specializer_method_callSite_firstProfiler_t* profiler, void* callSiteContext, ir_specializer_t* specializer);
 
109
void specializer_method_callSite_firstProfiler_print(specializer_method_callSite_firstProfiler_t* profiler, FILE* out);
 
110
void specializer_method_callSite_firstProfiler_clean(specializer_method_callSite_firstProfiler_t* profiler, ir_specializer_t* specializer);
 
111
JITUINT32* specializer_method_callSite_firstProfiler_getCounterPointer(specializer_method_callSite_firstProfiler_t* profiler);
 
112
JITUINT32 specializer_method_callSite_firstProfiler_getCounterValue(struct specializer_method_callSite_firstProfiler_t* profiler);
 
113
JITUINT32* specializer_method_callSite_firstProfiler_getThresholdReachedPointer(specializer_method_callSite_firstProfiler_t* profiler);
 
114
JITUINT32 specializer_method_callSite_firstProfiler_isThresholdReached(specializer_method_callSite_firstProfiler_t* profiler);
 
115
 
 
116
/* ----------------------------------------- specializer_callSite_secondProfiler_param_t -----------------------------------------*/
 
117
void specializer_callSite_secondProfiler_param_init(specializer_callSite_secondProfiler_param_t* secondProfilerParam, ir_item_t* item, JITUINT32 offset, JITUINT32 position, JITBOOLEAN isVector);
 
118
void specializer_callSite_secondProfiler_param_print(specializer_callSite_secondProfiler_param_t* secondProfilerParam, FILE* out);
 
119
void specializer_callSite_secondProfiler_param_clean(specializer_callSite_secondProfiler_param_t* secondProfilerParam, ir_specializer_t* specializer);
 
120
JITUINT32 specializer_callSite_secondProfiler_param_getParamType(specializer_callSite_secondProfiler_param_t* secondProfilerParam);
 
121
JITUINT32 specializer_callSite_secondProfiler_param_getParamInternalType(specializer_callSite_secondProfiler_param_t* secondProfilerParam);
 
122
size_t specializer_callSite_secondProfiler_param_getParameterSize(specializer_callSite_secondProfiler_param_t* secondProfilerParam);
 
123
JITBOOLEAN specializer_callSite_secondProfiler_param_isVariable(specializer_callSite_secondProfiler_param_t* secondProfilerParam);
 
124
JITBOOLEAN specializer_callSite_secondProfiler_param_isConstant(specializer_callSite_secondProfiler_param_t* secondProfilerParam);
 
125
JITBOOLEAN specializer_callSite_secondProfiler_param_isVector(specializer_callSite_secondProfiler_param_t* secondProfilerParam);
 
126
IR_ITEM_VALUE specializer_callSite_secondProfiler_param_getValue(specializer_callSite_secondProfiler_param_t* secondProfilerParam);
 
127
IR_ITEM_FVALUE specializer_callSite_secondProfiler_param_getFValue(specializer_callSite_secondProfiler_param_t* secondProfilerParam);
 
128
JITUINT32 specializer_callSite_secondProfiler_param_getType(specializer_callSite_secondProfiler_param_t* secondProfilerParam);
 
129
 
 
130
/* ----------------------------------------- specializer_method_callSite_secondProfiler_t -----------------------------------------*/
 
131
void specializer_method_callSite_secondProfiler_init(specializer_method_callSite_secondProfiler_t* profiler, void *callSiteContext, ir_specializer_t* specializer);
 
132
void specializer_method_callSite_secondProfiler_print(specializer_method_callSite_secondProfiler_t* profiler, FILE* out);
 
133
void specializer_method_callSite_secondProfiler_clean(specializer_method_callSite_secondProfiler_t* profiler, ir_specializer_t* specializer);
 
134
JITUINT32* specializer_method_callSite_secondProfiler_getCounterPointer(specializer_method_callSite_secondProfiler_t* profiler);
 
135
JITUINT32 specializer_method_callSite_secondProfiler_getCounterValue(specializer_method_callSite_secondProfiler_t* profiler);
 
136
JITUINT32* specializer_method_callSite_secondProfiler_getThresholdReachedPointer(specializer_method_callSite_secondProfiler_t* profiler);
 
137
JITUINT32 specializer_method_callSite_secondProfiler_isThresholdReached(specializer_method_callSite_secondProfiler_t* profiler);
 
138
JITUINT32 specializer_method_callSite_secondProfiler_getThreshold(specializer_method_callSite_secondProfiler_t* profiler);
 
139
JITUINT32 specializer_method_callSite_secondProfiler_getBlockSize(specializer_method_callSite_secondProfiler_t* profiler);
 
140
XanList* specializer_method_callSite_secondProfiler_getStaticExpressions(specializer_method_callSite_secondProfiler_t* profiler, ir_specializer_t* specializer);
 
141
 
 
142
/* ----------------------------------------- specializer_valueWithFrequency_t -----------------------------------------*/
 
143
void specializer_valueWithFrequency_init(specializer_valueWithFrequency_t* valueWithFrequency, specializer_multiValueContainer valueContainer, JITFLOAT32 frequency);
 
144
void specializer_valueWithFrequency_print(specializer_valueWithFrequency_t* valueWithFrequency, FILE* out);
 
145
void specializer_valueWithFrequency_clean(specializer_valueWithFrequency_t* valueWithFrequency, ir_specializer_t* specializer);
 
146
 
 
147
/* ----------------------------------------- specializer_callSite_secondProfiler_param_values_t -----------------------------------------*/
 
148
void specializer_callSite_secondProfiler_param_values_init(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, JITUINT32 position, ir_specializer_t* specializer);
 
149
void specializer_callSite_secondProfiler_param_values_print(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, FILE* out);
 
150
void specializer_callSite_secondProfiler_param_values_clean(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, ir_specializer_t* specializer);
 
151
void specializer_callSite_secondProfiler_param_values_addValue(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, specializer_valueWithFrequency_t* valueWithFrequency);
 
152
specializer_valueWithFrequency_t* specializer_callSite_secondProfiler_param_values_getValue(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, JITUINT32 index);
 
153
JITUINT32 specializer_callSite_secondProfiler_param_values_getValuesNumber(specializer_callSite_secondProfiler_param_values_t* valuesForPosition);
 
154
 
 
155
/* ----------------------------------------- specializer_staticExpression_hint_t -----------------------------------------*/
 
156
void specializer_staticExpression_hint_init(specializer_staticExpression_hint_t* staticExpression, specializer_expression_hint_t *expression, specializer_multiValueContainer *values);
 
157
void specializer_staticExpression_hint_print(specializer_staticExpression_hint_t* staticExpression, FILE* out);
 
158
void specializer_staticExpression_hint_clean(specializer_staticExpression_hint_t* staticExpression, ir_specializer_t* specializer);
 
159
JITBOOLEAN specializer_staticExpression_hint_equals(specializer_staticExpression_hint_t* staticExpression, specializer_staticExpression_hint_t* otherExpression);
 
160
 
 
161
/* ----------------------------------------- specializer_method_callSite_dispatcher_t -----------------------------------------*/
 
162
void specializer_method_callSite_dispatcher_init(specializer_method_callSite_dispatcher_t* dispatcher, void *callSiteContext);
 
163
void specializer_method_callSite_dispatcher_print(specializer_method_callSite_dispatcher_t* dispatcher, FILE* out);
 
164
void specializer_method_callSite_dispatcher_clean(specializer_method_callSite_dispatcher_t* dispatcher, ir_specializer_t* specializer);
 
165
JITINT32* specializer_method_callSite_dispatcher_getCounterPointer(specializer_method_callSite_dispatcher_t* dispatcher);
 
166
JITINT32 specializer_method_callSite_dispatcher_getCounterValue(specializer_method_callSite_dispatcher_t* dispatcher);
 
167
 
 
168
/* ----------------------------------------- specializer_specialized_method_wrapper_t -----------------------------------------*/
 
169
void specializer_specialized_method_wrapper_init(specializer_specialized_method_wrapper_t* specializedMethod,
 
170
                                                specializer_staticExpression_hint_t *staticExpression,
 
171
                                                specializer_method_wrapper_t *originalMethodWrapper,
 
172
                                                specializer_method_wrapper_t *specializedMethodWrapper);
 
173
void specializer_specialized_method_wrapper_print (specializer_specialized_method_wrapper_t* specializedMethod, FILE* out, ir_specializer_t *specializer);
 
174
void specializer_specialized_method_wrapper_clean(specializer_specialized_method_wrapper_t* specializedMethod, ir_specializer_t* specializer);
 
175
JITBOOLEAN specializer_specialized_method_wrapper_equals(specializer_specialized_method_wrapper_t* specializedMethod,
 
176
                                                        specializer_method_wrapper_t *originalMethodWrapper,
 
177
                                                        specializer_staticExpression_hint_t *staticExpression);
 
178
 
 
179
/* ----------------------------------------- specializer_method_callSite_type_dispatcher_t -----------------------------------------*/
 
180
void specializer_method_callSite_type_dispatcher_init(specializer_method_callSite_type_dispatcher_t* dispatcher, void *callSiteContext);
 
181
void specializer_method_callSite_type_dispatcher_print(specializer_method_callSite_type_dispatcher_t* dispatcher, FILE* out);
 
182
void specializer_method_callSite_type_dispatcher_clean(specializer_method_callSite_type_dispatcher_t* dispatcher, ir_specializer_t* specializer);
 
183
JITINT32* specializer_method_callSite_type_dispatcher_getCounterPointer(specializer_method_callSite_type_dispatcher_t* dispatcher);
 
184
JITINT32 specializer_method_callSite_type_dispatcher_getCounterValue(specializer_method_callSite_type_dispatcher_t* dispatcher);
 
185
 
 
186
 
 
187
/* ------------------------------------------ Internal functions                        */
 
188
static inline void internal_action_to_second_or_dispatch_state (specializer_method_callSite_t* callSite, specializer_method_wrapper_t* callerWrapper, ir_specializer_t* specializer);
 
189
 
 
190
/***************************************** IMPLEMENTATION */
 
191
 
 
192
/*----------------------------------------- ir_specializer_t ----------------------------------------*/
 
193
void newSpecializer(ir_specializer_t* specializer, void* system, ir_lib_t *irlib, ir_optimizer_t *optimizer, char* programName,
 
194
                        JITINT32 arrayLengthOffset, JITINT32 objectLayoutOffset,
 
195
                        void (*forceRecompile)(void* ilMethod),
 
196
                        void (*compileToIR) (void* ilMethod),
 
197
                        void*(*newApplicationMethod)(), void* (*newJITFunction)(void* ilMethod),
 
198
                        void (*decode_jit_signature)(void *system, void* method),
 
199
                        void*(*getMethodFromVirtualMethodAndType)(void* virtualCalledMethod, void* layout),
 
200
                        void*(*decode_ir_signature)(void* system, void* ilMethod), JITBOOLEAN(*isInternalCall)(void* ilMethod)){
 
201
 
 
202
        /* Assertions */
 
203
        assert(specializer != NULL);
 
204
        assert(programName != NULL);
 
205
        assert(forceRecompile != NULL);
 
206
        assert(compileToIR != NULL);
 
207
        assert(newApplicationMethod != NULL);
 
208
        assert(newJITFunction != NULL);
 
209
        assert(system != NULL);
 
210
        assert(decode_jit_signature != NULL);
 
211
        assert(isInternalCall != NULL);
 
212
        assert(system != NULL);
 
213
        assert(irlib != NULL);
 
214
        assert(optimizer != NULL);
 
215
        PDEBUG("\n______________________________________________________________________________________________\n");
 
216
 
 
217
        /* Assign variables */
 
218
        specializer->arrayLengthOffset = arrayLengthOffset;
 
219
        specializer->objectLayoutOffset = objectLayoutOffset;
 
220
 
 
221
        /* Assign recompile function */
 
222
        specializer->forceRecompile                     = forceRecompile;
 
223
        specializer->compileToIR                        = compileToIR;
 
224
 
 
225
        /* Assign the system */
 
226
        specializer->system                             = system;
 
227
        specializer->irlib                              = irlib;
 
228
        specializer->optimizer                          = optimizer;
 
229
 
 
230
        /* The system has not been shutted down */
 
231
        specializer->shuttedDown                        = JITFALSE;
 
232
 
 
233
        /* Assign new method creation function */
 
234
        specializer->newApplicationMethod               = newApplicationMethod;
 
235
        specializer->newJITFunction                     = newJITFunction;
 
236
        specializer->decode_jit_signature               = decode_jit_signature;
 
237
        specializer->getMethodFromVirtualMethodAndType  = getMethodFromVirtualMethodAndType;
 
238
        specializer->decode_ir_signature                = decode_ir_signature;
 
239
        specializer->isInternalCall                     = isInternalCall;
 
240
 
 
241
        /* Assign internal calls */
 
242
        specializer->shutdown                           = ir_specializer_shutdown;
 
243
        specializer->manageCallSitesBeforeCompile       = ir_specializer_manageCallSitesBeforeCompile;
 
244
 
 
245
        /* Generate the list */
 
246
        specializer->callSitesForMethods                = xanListNew(allocFunction, freeFunction, NULL);
 
247
        specializer->hintsForMethods                    = xanListNew(allocFunction, freeFunction, NULL);
 
248
        specializer->wrapperForMethods                  = xanListNew(allocFunction, freeFunction, NULL);
 
249
        specializer->specializedMethods                 = xanListNew(allocFunction, freeFunction, NULL);
 
250
 
 
251
        /* Generate the recompile request pipe */
 
252
        specializer->recompileRequestPipe = xanPipeNew(allocFunction, freeFunction);
 
253
 
 
254
        /* Generate the recompile request thread */
 
255
        if(pthread_create(&specializer->recompileRequestThread, NULL,  ir_specializer_recompile_request_thread, specializer) != 0){
 
256
                fprintf(stderr, "SPECIALIZER : New :\n\t\tERROR = Unable to create the recompile thread\n");
 
257
                abort();
 
258
        }
 
259
 
 
260
        /* Load hints from file                 */
 
261
        ir_specializer_loadHintsFromFile(specializer, programName);
 
262
        PDEBUG("______________________________________________________________________________________________\n");
 
263
}
 
264
void ir_specializer_manageCallSitesBeforeCompile(ir_specializer_t* specializer,
 
265
                        void* ilMethod, JITUINT32 recompileStateValue,
 
266
                        ir_method_t* (*getIRMethod)(void* ilMethod),
 
267
                        void (*setState)(void* ilMethod, JITUINT32 state), JITUINT32 (*getState)(void* ilMethod),
 
268
                        void (*setJITFunction) (void *ilMethod, void* jitFunction), void* (*getJITFunction)(void *ilMethod),
 
269
                        JITBOOLEAN (*isCctor)(void*ilMethod)){
 
270
        specializer_method_wrapper_t            *callerWrapper;                 /* The caller method wrapper */
 
271
        ir_method_t                             *irMethod;                      /* The caller IR Method */
 
272
        t_ir_instruction                        *currentInstruction;            /* The current IR Instruction */
 
273
        specializer_method_wrapper_t            *calleeWrapper;                 /* The callee method wrapper */
 
274
        void                                    *calleeMethod;                  /* Pointer to callee method */
 
275
        specializer_hintsForMethod_t            *calleeHints;                   /* The hints for the callee method */
 
276
        specializer_callSitesForMethod_t        *callerCallSites;               /* The call sited*/
 
277
        specializer_method_callSite_t           *callSite;                      /* The current call site */
 
278
        JITBOOLEAN                              changed;                        /* Detect if the method has possibly changed */
 
279
        XanListItem                             *item;                          /* The first parameter in the call parameters list */
 
280
        ir_item_t                               *parameter;                     /* Generic parameter */
 
281
 
 
282
        /* Assertions */
 
283
        assert(ilMethod != NULL);
 
284
        assert(getIRMethod != NULL);
 
285
        assert(setState != NULL);
 
286
        assert(getState != NULL);
 
287
        assert(isCctor != NULL);
 
288
        assert(getJITFunction != NULL);
 
289
        assert(setJITFunction != NULL);
 
290
 
 
291
        /* Check if the system has been shutted down; if so don't do anything */
 
292
        if(specializer->shuttedDown){
 
293
                PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : The specializer has already been shut down!\n");
 
294
                return;
 
295
        }
 
296
 
 
297
        /* Variable Initialization */
 
298
        irMethod        = getIRMethod(ilMethod);        
 
299
        callerWrapper   = NULL;
 
300
        calleeWrapper   = NULL;
 
301
        callerCallSites = NULL;
 
302
        changed         = JITFALSE;
 
303
 
 
304
        /* Print the before any change on stdout */
 
305
#ifdef PRINTDEBUG
 
306
        fprintf(stdout, "{BEFORE} METHOD %s [%s]\n", getFullName(ilMethod),getSignature(ilMethod));
 
307
        printIrMethod(irMethod, stdout, getFullName, getSignature);
 
308
        fprintf(stdout, "END\n\n");
 
309
#endif
 
310
 
 
311
        /* Print informations about the caller */
 
312
        PDEBUG("\n______________________________________________________________________________________________\n");
 
313
        PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Caller Name  = %s\n", getFullName(ilMethod));
 
314
        PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Caller Signature =  %s\n", getSignature(ilMethod));
 
315
        PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Caller Instructions Number = %d\n", irMethod->getInstructionsNumber(irMethod));
 
316
 
 
317
        /* For each instruction                 */
 
318
        for(currentInstruction = irMethod->getNextInstruction(irMethod, NULL); currentInstruction != NULL; currentInstruction = irMethod->getNextInstruction(irMethod, currentInstruction)){
 
319
 
 
320
                assert(currentInstruction != NULL);
 
321
 
 
322
                /* Check if its a call instruction */
 
323
                //if(currentInstruction->type == IRCALL || currentInstruction->type == IRVCALL){
 
324
                if(currentInstruction->type == IRCALL){
 
325
 
 
326
                        /* Take the method                              */
 
327
                        PDEBUG("SPECIALIZER : manageCallSitesbeforeCompilation : Retrieve callee pointer from instruction\n");
 
328
                        calleeMethod    = (void*)(JITNUINT)((currentInstruction->param_1).value);
 
329
                        assert(calleeMethod != NULL);
 
330
 
 
331
                        /* Print the founded call site                  */
 
332
                        PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Found a new call site; Name = %s [%s]; Method Callee Pointer = %p; Call Pointer = %p\n", getFullName(calleeMethod), getSignature(calleeMethod), calleeMethod, currentInstruction);
 
333
 
 
334
                        /* Check that the method is not a native one    */
 
335
                        if(specializer->isInternalCall(calleeMethod)){
 
336
                                PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Found a call to a native internal method.... Skip it!!\n");
 
337
                                continue;
 
338
                        }
 
339
 
 
340
                        /* If it is a virtual call check that the first parameter is a variable
 
341
                         * (i.e. that currentIntruction->callParameter[0].type == IROFFSET) */
 
342
                        if(currentInstruction->type == IRVCALL){
 
343
                                assert(currentInstruction->callParameters != NULL);
 
344
                                assert(currentInstruction->callParameters->length(currentInstruction->callParameters) > 0);
 
345
                                item = currentInstruction->callParameters->getElementFromPositionNumber(currentInstruction->callParameters, 0);
 
346
                                assert(item != NULL);
 
347
                                parameter = (ir_item_t*) currentInstruction->callParameters->data(currentInstruction->callParameters, item);
 
348
                                assert(parameter != NULL);
 
349
                                if(parameter->type != IROFFSET){
 
350
                                        PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation: Found a virtual call that cannot be managed because the caller object is not a variable\n");
 
351
                                        continue;
 
352
                                }
 
353
                        }
 
354
 
 
355
                        /* Retrieve the callee wrapper */
 
356
                        PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Retrieve callee wrapper\n");
 
357
                        calleeWrapper   = ir_specializer_getMethodWrapper(specializer, calleeMethod, recompileStateValue, getIRMethod, setState, getState, setJITFunction, getJITFunction, isCctor);
 
358
                        assert(calleeWrapper != NULL);
 
359
 
 
360
                        /* Check if specializable */
 
361
                        calleeHints     = ir_specializer_getHintsForMethodForMethod(specializer, calleeWrapper);
 
362
                        if(calleeHints == NULL){
 
363
                                continue;
 
364
                        }
 
365
        
 
366
                        /* Found a specializable call site */
 
367
                        PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Loaded hints for method %s [%s]\n", getFullName(calleeMethod), getSignature(calleeMethod));
 
368
 
 
369
                        /* Retrieve the caller wrapper */
 
370
                        if(callerWrapper == NULL){
 
371
                                PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Retrieve caller wrapper\n");
 
372
                                callerWrapper = ir_specializer_getMethodWrapper(specializer, ilMethod,recompileStateValue, getIRMethod, setState, getState, setJITFunction, getJITFunction, isCctor);
 
373
                        }
 
374
                        assert(callerWrapper != NULL);
 
375
 
 
376
                        /* Retrieve the call sites list for the current method */
 
377
                        if(callerCallSites == NULL){
 
378
                                PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Retrieve caller call sites list\n");
 
379
                                callerCallSites = ir_specializer_getCallSitesFormMethod(specializer, callerWrapper);
 
380
                        }
 
381
                        assert(callerCallSites != NULL);
 
382
 
 
383
                        /* Retrieve the call site for this call */
 
384
                        PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Retrieve call site\n");
 
385
                        callSite = callerCallSites->getCallSiteForInstruction(callerCallSites, calleeWrapper, currentInstruction, calleeHints, specializer);
 
386
                        assert(callSite != NULL);
 
387
 
 
388
                        /* Perform action based on call status */
 
389
                        PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Perform actions on the call site\n");
 
390
                        callSite->performAction(callSite, callerWrapper, specializer);
 
391
 
 
392
                        /* The method has changed */
 
393
                        changed = JITTRUE;
 
394
                }
 
395
        }
 
396
        PDEBUG("______________________________________________________________________________________________\n");
 
397
 
 
398
        /* Print the changed method on stdout   */
 
399
#ifdef PRINTDEBUG
 
400
        if(changed){
 
401
                fprintf(stdout, "{AFTER} METHOD %s [%s]\n", getFullName(ilMethod),getSignature(ilMethod));
 
402
                printIrMethod(irMethod, stdout, getFullName, getSignature);
 
403
                fprintf(stdout, "END\n\n");
 
404
        }
 
405
#endif
 
406
 
 
407
        /* Return                               */
 
408
        return ;
 
409
}
 
410
void ir_specializer_shutdown(struct ir_specializer_t* specializer){
 
411
        XanListItem                             *item;  /* Generic item */
 
412
        JITUINT32                               index;
 
413
        specializer_method_wrapper_t            *methodWrapper; /* The method wrapper to delete */
 
414
        specializer_hintsForMethod_t            *hintsForMethod;        /* The hints for method to delete */
 
415
        specializer_callSitesForMethod_t        *callSitesForMethod;    /* The call sites for a method to delete */
 
416
        specializer_specialized_method_wrapper_t* specializedMethod;    /* The specialized method to delete */
 
417
 
 
418
        /* Assertions */
 
419
        assert(specializer != NULL);
 
420
        PDEBUG("SPECIALIZER : shutdown : Shutting down the specializer system\n");
 
421
 
 
422
        #ifdef FULLMODE_PRINTDEBUG
 
423
        FMODEPRINT("SPECIALIZER : Shutdown\n");
 
424
        #endif
 
425
 
 
426
        /* Set the method as shutted down */
 
427
        specializer->shuttedDown = JITTRUE;
 
428
 
 
429
        /* Stop the recompile thread */
 
430
        specializer->recompileRequestPipe->synchPut(specializer->recompileRequestPipe, NULL);
 
431
        pthread_join(specializer->recompileRequestThread, NULL);
 
432
        #ifdef FULLMODE_PRINTDEBUG
 
433
        FMODEPRINT("SPECIALIZER : Shutdown: The compiler thread has been deleted\n");
 
434
        #endif
 
435
 
 
436
        /* Destroy the pipeline */
 
437
        specializer->recompileRequestPipe->destroyPipe(specializer->recompileRequestPipe);
 
438
        
 
439
        /* Destroy the hints inside the list */
 
440
        for(index = 0; index < specializer->hintsForMethods->length(specializer->hintsForMethods); index++){
 
441
                item = specializer->hintsForMethods->getElementFromPositionNumber(specializer->hintsForMethods, index);
 
442
                hintsForMethod = (specializer_hintsForMethod_t*) specializer->hintsForMethods->data(specializer->hintsForMethods, item);
 
443
                hintsForMethod->clean(hintsForMethod, specializer);
 
444
        }
 
445
 
 
446
        /* Destroy the hints list */
 
447
        specializer->hintsForMethods->destroyList(specializer->hintsForMethods);
 
448
 
 
449
        /* Destroy the call sites inside the list */
 
450
        for(index = 0; index < specializer->callSitesForMethods->length(specializer->callSitesForMethods); index++){
 
451
                item = specializer->callSitesForMethods->getElementFromPositionNumber(specializer->callSitesForMethods, index);
 
452
                callSitesForMethod = (specializer_callSitesForMethod_t*) specializer->callSitesForMethods->data(specializer->callSitesForMethods, item);
 
453
                callSitesForMethod->clean(callSitesForMethod, specializer);
 
454
        }
 
455
 
 
456
        /* Destroy the call site list */
 
457
        specializer->callSitesForMethods->destroyList(specializer->callSitesForMethods);
 
458
 
 
459
        /* Destroy the wrappers in the list */
 
460
        for(index = 0; index < specializer->wrapperForMethods->length(specializer->wrapperForMethods); index++){
 
461
                item = specializer->wrapperForMethods->getElementFromPositionNumber(specializer->wrapperForMethods, index);
 
462
                methodWrapper = (specializer_method_wrapper_t*) specializer->wrapperForMethods->data(specializer->wrapperForMethods, item);
 
463
                methodWrapper->clean(methodWrapper, specializer);
 
464
        }
 
465
 
 
466
        /* Destroy the wrapper list */
 
467
        specializer->wrapperForMethods->destroyList(specializer->wrapperForMethods);
 
468
 
 
469
        /* Destroy all specialized methods in the list */
 
470
        for(index = 0; index < specializer->specializedMethods->length(specializer->specializedMethods); index++){
 
471
                item = specializer->specializedMethods->getElementFromPositionNumber(specializer->specializedMethods, index);
 
472
                specializedMethod = (specializer_specialized_method_wrapper_t*) specializer->specializedMethods->data(specializer->specializedMethods, item);
 
473
                specializedMethod->clean(specializedMethod, specializer);
 
474
        }
 
475
 
 
476
        /* Destroy the list of specialized methods */
 
477
        specializer->specializedMethods->destroyList(specializer->specializedMethods);
 
478
}
 
479
 
 
480
void ir_specializer_loadHintsFromFile(ir_specializer_t* specializer, char* programName){
 
481
        /* Variables */
 
482
        char* fileName;                         /* Name of the file to read*/
 
483
        FILE* inputFile;                        /* Input file */
 
484
        JITUINT32 programNameSize;      /* Size of the program name */
 
485
        specializer_hintsForMethod_t* hints;    /* Next hint read from file */
 
486
 
 
487
        /* Assertions */
 
488
        assert(specializer != NULL);
 
489
        assert(programName != NULL);
 
490
 
 
491
        PDEBUG("SPECIALIZER : loadHintsFromFile : Start loading hints for program %s\n",programName);
 
492
 
 
493
        /* Generate file name of the file that contains specialization informations */
 
494
        programNameSize = strlen(programName);
 
495
        fileName = allocFunction(sizeof(char)*(programNameSize + 5));
 
496
        fileName = strcpy(fileName, programName);
 
497
        fileName = strncat(fileName, ".spc", 5);
 
498
 
 
499
        /* Open file */
 
500
        PDEBUG("SPECIALIZER : loadHintsFromFile : Open file %s\n", fileName);
 
501
        inputFile = fopen(fileName, "r");
 
502
 
 
503
        /* Check file exists */
 
504
        if(inputFile == NULL){
 
505
                PDEBUG("SPECIALIZER : loadHintsFromFile : No specialization file named %s\n", fileName);
 
506
                return;
 
507
        }
 
508
 
 
509
        /* Lock the list */
 
510
        specializer->hintsForMethods->lock(specializer->hintsForMethods);
 
511
 
 
512
        /* Read new hints form file */
 
513
        while((hints = readHintsForMethodFromFile(inputFile, specializer)) !=NULL )
 
514
                specializer->hintsForMethods->append(specializer->hintsForMethods, hints);
 
515
 
 
516
        /* Unlock the list */
 
517
        specializer->hintsForMethods->unlock(specializer->hintsForMethods);
 
518
 
 
519
        /* Print all specialization */
 
520
#ifdef PRINTDEBUG
 
521
        PDEBUG("\nSPECIALIZER : loadHintsFromFile : Specialization read from file are: \n");
 
522
        ir_specializer_printHintsForMethod(specializer, stderr);
 
523
#endif
 
524
 
 
525
#ifdef FULLMODE_PRINTDEBUG
 
526
        FMODEPRINT("SPECIALIZER : Loaded hints from file are: \n");
 
527
        ir_specializer_printHintsForMethod(specializer, stderr);
 
528
#endif
 
529
 
 
530
        /* Close file */
 
531
        fclose(inputFile);
 
532
 
 
533
        /* Terminate and free space */
 
534
        PDEBUG("SPECIALIZER : loadHintsFromFile : Specialization loaded %s\n", fileName);
 
535
        freeFunction(fileName);
 
536
}
 
537
void ir_specializer_printHintsForMethod(ir_specializer_t *specializer, FILE* out){
 
538
        /* Variables */
 
539
        JITUINT32 index;        /* Index used to scan list */
 
540
        XanListItem* item;
 
541
        specializer_hintsForMethod_t* hintsForMethod;   /* The hints for method to print on out */
 
542
 
 
543
        /* Assertions */
 
544
        assert(specializer != NULL);
 
545
        assert(out != NULL);
 
546
 
 
547
        /* Lock the list */
 
548
        specializer->hintsForMethods->lock(specializer->hintsForMethods);
 
549
 
 
550
        /* For each hints for method */
 
551
        for(index=0;index < specializer->hintsForMethods->length(specializer->hintsForMethods); index++){
 
552
                fprintf(out, "Expression At Position %d :\n", index);
 
553
                /* Load the item */
 
554
                item = specializer->hintsForMethods->getElementFromPositionNumber(specializer->hintsForMethods, index);
 
555
                assert(item != NULL);
 
556
 
 
557
                /* Read next hint in the list */
 
558
                hintsForMethod = (specializer_hintsForMethod_t*) specializer->hintsForMethods->data(specializer->hintsForMethods, item);
 
559
                assert(hintsForMethod != NULL);
 
560
 
 
561
                hintsForMethod->print(hintsForMethod, out);
 
562
        }
 
563
 
 
564
        /* Unlock the list */
 
565
        specializer->hintsForMethods->unlock(specializer->hintsForMethods);
 
566
}
 
567
 
 
568
specializer_hintsForMethod_t* ir_specializer_getHintsForMethodForMethod(ir_specializer_t *specializer, specializer_method_wrapper_t* wrapper){
 
569
        JITUINT32 index;        /* Index used to scan hints list */
 
570
        XanListItem* item;      /* Generic list Item */
 
571
        specializer_hintsForMethod_t* hintsForMethod;   /* Hints loaded */
 
572
        specializer_hintsForMethod_t* result;   /* The result of this operation (i.e. the specializaiton info for the required method)*/
 
573
        char* methodName;               /* The name of the method */
 
574
        char* methodSignature;  /* The method signature*/
 
575
        ir_method_t     *irMethod;
 
576
 
 
577
        /* Assertions */
 
578
        assert(specializer != NULL);
 
579
        assert(wrapper != NULL);
 
580
 
 
581
        /* Initialize Variables */
 
582
        result          = NULL;
 
583
 
 
584
        /* Fetch the IR method  */
 
585
        irMethod        = wrapper->getIRMethod(wrapper);
 
586
        assert(irMethod != NULL);
 
587
        
 
588
        /* Fetch the signature  */
 
589
        methodSignature = irMethod->getSignatureInString(irMethod, specializer->irlib->typeChecker);
 
590
        assert(methodSignature != NULL);
 
591
        
 
592
        /* Fetch the name       */
 
593
        methodName      = irMethod->getCompleteName(irMethod);
 
594
        assert(methodName != NULL);
 
595
 
 
596
        /* Lock the list */
 
597
        PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Lock the hints for methods list list\n");
 
598
        specializer->hintsForMethods->lock(specializer->hintsForMethods);
 
599
 
 
600
        /* For each hints for method */
 
601
        PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Search for method %s [%s]\n", methodName, methodSignature);
 
602
        for(index=0; (index < specializer->hintsForMethods->length(specializer->hintsForMethods)) && (result == NULL); index++){
 
603
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Read item at position %d\n", index);
 
604
                item = specializer->hintsForMethods->getElementFromPositionNumber(specializer->hintsForMethods, index);
 
605
                assert(item != NULL);
 
606
 
 
607
                /* Read next hint in the list */
 
608
                hintsForMethod = (specializer_hintsForMethod_t*) specializer->hintsForMethods->data(specializer->hintsForMethods, item);
 
609
                assert(hintsForMethod != NULL);
 
610
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Comparing with : %s [%s]\n", hintsForMethod->methodCompleteName, hintsForMethod->methodSignature);
 
611
 
 
612
                /* Check if it satisfy the required conditions */
 
613
                if(hintsForMethod->equals(hintsForMethod, methodName, methodSignature)){
 
614
                        PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Hints found!\n");
 
615
                        result = hintsForMethod;
 
616
                }
 
617
        }
 
618
 
 
619
        //TODO: Search for hints for method inside method meta-data
 
620
 
 
621
        #ifdef SPECIALIZE_EVERY_METHOD
 
622
        if(result == NULL){ /* Create a new simple hint from the signature */
 
623
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : FULL SPECIALIZATION MODE has been actived... create the hint for the given method since no one already found!\n");
 
624
                ir_method_t* method;                    /* The IR method */
 
625
                ILMethod_signature cilSignature;        /* The il signature */
 
626
                JITBOOLEAN hasThis;     /* Check if there is the object */
 
627
                specializer_expression_hint_t* expression;      /* New expression that needs to be created */
 
628
                FILE* inputFile;
 
629
                char inputString[1024];
 
630
                JITUINT32 type;
 
631
 
 
632
                if(specializer_fullspecialization_counter == -1){
 
633
                        PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Loading from file the full specialization counter threshold\n");
 
634
                        inputFile = fopen("specializer.spc","r");
 
635
                        if(inputFile == NULL){
 
636
                                FMODEPRINT("SPECIALIZER - getHintsForMethodForMethod\n\t\tWARNING : No such file specializer.spc... set the fullSpecializationCounter to 1\n");
 
637
                                specializer_fullspecialization_counter = 1;
 
638
                        } else {
 
639
                                fgets(inputString, 1023, inputFile);
 
640
                                specializer_fullspecialization_counter = atoi(inputString);
 
641
                                fclose(inputFile);
 
642
                        }
 
643
                        #ifdef FULLMODE_PRINTDEBUG
 
644
                        FMODEPRINT("SPECIALIZER : Multiply Constant : %d\n", specializer_fullspecialization_counter);
 
645
                        #endif
 
646
                }
 
647
 
 
648
                /* Generate, for each parameter that can be specialized an expression hint */
 
649
                method          = wrapper->getIRMethod(wrapper);
 
650
                assert(method != NULL);
 
651
                cilSignature    = method->CIL_method_signature;
 
652
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Original IR Signature Parameter size = %d\n", (method->signature).parameters_number);
 
653
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Original CIL Signature Param size = %d\n", cilSignature.param_count);
 
654
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod: Types for IR signature = ");
 
655
                #ifdef PRINTDEBUG
 
656
                for(index = 0; index < (method->signature).parameters_number; index++){
 
657
                        PDEBUG("%s, ", getTypeName((method->signature).parameter_internal_types[index]));
 
658
                }
 
659
                #endif
 
660
                PDEBUG("\n");
 
661
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : signature hasThis = %s\n", cilSignature.hasThis?"TRUE":"FALSE");
 
662
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : isCctor = %s\n", (wrapper->isCctor(wrapper))?"TRUE":"FALSE");
 
663
                hasThis = cilSignature.hasThis && /*!wrapper->isCctor(wrapper) && */ ( cilSignature.param_count != (method->signature).parameters_number);      /* Used to always skip the this pointer */
 
664
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : hasThis = %s\n", hasThis?"TRUE":"FALSE");
 
665
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : hasSentinel = %s (%d)\n", (cilSignature.sentinel)?"True":"False", cilSignature.sentinel);
 
666
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Sentinel Param Index = %u\n", cilSignature.sentinel_param_index);
 
667
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : hasVarargcalling type = %s (%u) -%s [%s]\n", (cilSignature.calling_convention==VARARG)?"True":"False", cilSignature.calling_convention, wrapper->getFullName(wrapper), wrapper->getSignature(wrapper));
 
668
                expression = NULL;
 
669
 
 
670
                if(cilSignature.calling_convention==VARARG){
 
671
                        PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Method with VARARG found but this feature is not supported: method not specializable \n");
 
672
                }else if(cilSignature.param_count != 0){ /* If the method has no parameters it is no worhwhile specializing */
 
673
 
 
674
                        PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Create a new hints for method with signature size %d\n", cilSignature.param_count);
 
675
                        for(index = 0; index < cilSignature.param_count; index++){
 
676
                                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Read element of signature at position %d: ", index);
 
677
 
 
678
                                if(cilSignature.sentinel && (index >= cilSignature.sentinel_param_index)){
 
679
                                        PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Found VARARGS argument... nothing more to specialize for the method\n");
 
680
                                        break;
 
681
                                }
 
682
 
 
683
 
 
684
                                //currentType = irSignature.parameter_internal_types[index];
 
685
                                /* Search if it is a scalar */
 
686
                                type = (method->signature).parameter_internal_types[index+hasThis];
 
687
//                              if((cilSignature.params[index].type != NULL) &&
 
688
//                                              (((cilSignature.params[index].type)->type == ELEMENT_TYPE_I1)
 
689
//                                              || ((cilSignature.params[index].type)->type == ELEMENT_TYPE_U1)
 
690
//                                              || ((cilSignature.params[index].type)->type == ELEMENT_TYPE_I2)
 
691
//                                              || ((cilSignature.params[index].type)->type == ELEMENT_TYPE_U2)
 
692
//                                              || ((cilSignature.params[index].type)->type == ELEMENT_TYPE_I4)
 
693
//                                              || ((cilSignature.params[index].type)->type == ELEMENT_TYPE_U4)
 
694
//                                              || ((cilSignature.params[index].type)->type == ELEMENT_TYPE_I8)
 
695
//                                              || ((cilSignature.params[index].type)->type == ELEMENT_TYPE_U8)
 
696
//                                              || ((cilSignature.params[index].type)->type == ELEMENT_TYPE_R4)
 
697
//                                              || ((cilSignature.params[index].type)->type == ELEMENT_TYPE_R8)
 
698
//                                              )){
 
699
                                if((cilSignature.params[index].type != NULL) && (
 
700
                                        (type == IRINT8) || (type == IRINT16) || (type == IRINT32) || (type == IRINT64) || (type == IRNINT) ||
 
701
                                        (type == IRUINT8) || (type == IRUINT16) || (type == IRUINT32) || (type == IRUINT64) || (type == IRNUINT) ||
 
702
                                        (type == IRFLOAT32) || (type == IRFLOAT64) || (type == IRNFLOAT))){
 
703
                                        PDEBUG("SCALAR VALUE\n");
 
704
 
 
705
                                        /* Create a new hint structure if needed */
 
706
                                        if(result == NULL){
 
707
                                                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Create a new hints for method\n");
 
708
                                                result = newSpecializerHintsForMethod(specializer);
 
709
                                                result->init(result, methodName, methodSignature,
 
710
                                                                SEPCIALIZER_ZERO_PROFILER_THRESHOLD, SPECIALIZER_ZERO_PROFILER_MEMORY_SIZE, SEPCIALIZER_ZERO_DISPATCHER_REMOVE_THRESHOLD,
 
711
                                                                SPECIALIZER_FIRST_PROFILER_THRESHOLD, SPECIALIZER_SECOND_PROFILER_MEMORY_SIZE*(method->signature).parameters_number, SPECIALIZER_SECOND_PROFILER_STATIC_THRESHOLD,
 
712
                                                                SPECIALIZER_DISPATCHER_REMOVE_THRESHOLD, specializer);
 
713
                                        }
 
714
 
 
715
                                        /* Create a new single STATIC expression for this parameter */
 
716
                                        expression              = newSpecializerExpressionHint(specializer);
 
717
                                        expression->init(expression, index+hasThis, SPECIALIZER_ACTION_STATIC, 0, 0, NULL, NULL);
 
718
                                        expression->depth       = 1;
 
719
 
 
720
                                        /* Add the expression to the list */
 
721
                                        result->addExpression(result, expression);
 
722
 
 
723
                                /* Search if it is a vector     */
 
724
                                } else if(      (cilSignature.params[index].type != NULL)                               &&
 
725
                                                ((cilSignature.params[index].type)->type == ELEMENT_TYPE_SZARRAY)       ){
 
726
                                                PDEBUG("ARRAY VALUE\n");
 
727
 
 
728
                                                /* Create a new hint structure if needed */
 
729
                                                if(result == NULL){
 
730
                                                        PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Create a new hints for method\n");
 
731
                                                        result = newSpecializerHintsForMethod(specializer);
 
732
                                                        result->init(result, methodName, methodSignature,
 
733
                                                                        SEPCIALIZER_ZERO_PROFILER_THRESHOLD, SPECIALIZER_ZERO_PROFILER_MEMORY_SIZE, SEPCIALIZER_ZERO_DISPATCHER_REMOVE_THRESHOLD,
 
734
                                                                        SPECIALIZER_FIRST_PROFILER_THRESHOLD, SPECIALIZER_SECOND_PROFILER_MEMORY_SIZE*(method->signature).parameters_number, SPECIALIZER_SECOND_PROFILER_STATIC_THRESHOLD,
 
735
                                                                        SPECIALIZER_DISPATCHER_REMOVE_THRESHOLD, specializer);
 
736
                                                }
 
737
 
 
738
                                                /* Create a new single STATIC LENGTH expression for this parameter */
 
739
                                                expression = newSpecializerExpressionHint(specializer);
 
740
                                                expression->init(expression, index+hasThis, SPECIALIZER_ACTION_STATIC_LENGTH, 0, 0, NULL, NULL);
 
741
                                                expression->depth = 1;
 
742
 
 
743
                                                /* Add the expression to the list */
 
744
                                                result->addExpression(result, expression);
 
745
                                } else {
 
746
                                        #ifdef DEBUG
 
747
                                        PDEBUG("UNSPECIALIZABLE because ");
 
748
                                        if(cilSignature.params[index].type == NULL){
 
749
                                                PDEBUG("type is NULL\n");
 
750
                                        } else {
 
751
                                                PDEBUG("type is %d\n",(cilSignature.params[index].type)->type);
 
752
                                        }
 
753
                                        #endif
 
754
                                }
 
755
                        }
 
756
 
 
757
                        /* Append to the list */
 
758
                        if(result != NULL){
 
759
                                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Append the hints for the method to the hintsForMethodList\n");
 
760
                                specializer->hintsForMethods->append(specializer->hintsForMethods, result);
 
761
                        }
 
762
 
 
763
                        #ifdef PRINTDEBUG
 
764
                        if(result != NULL){
 
765
                                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Generated a new hints for method :\n");
 
766
                                result->print(result, stderr);
 
767
                        }
 
768
                        #endif
 
769
 
 
770
                        #ifdef FULLMODE_PRINTDEBUG
 
771
                        if(result != NULL){
 
772
                           FMODEPRINT("SPECIALIZER : Hints for %s [%s] (hasThis = %s)\n", methodName, methodSignature, hasThis?"TRUE":"FALSE");
 
773
                           result->print(result, stderr);
 
774
                        }
 
775
                        #endif
 
776
                } else {
 
777
                        PDEBUG("SPECIALIZER : getHintsForMethodForMethod : The method has no incoming parameters!\n");
 
778
                }
 
779
        }
 
780
#endif
 
781
 
 
782
        #ifdef PRINTDEBUG
 
783
        if(result == NULL){
 
784
                PDEBUG("SPECIALIZER : getHintsForMethodForMethod : No hints have been found since here!\n");
 
785
        }
 
786
        #endif
 
787
 
 
788
        /* Unlock the list */
 
789
        PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Unlock the hints for methods list list\n");
 
790
        specializer->hintsForMethods->unlock(specializer->hintsForMethods);
 
791
 
 
792
        /* Return the required hints or NULL if such hints doesn't exists */
 
793
        return result;
 
794
}
 
795
specializer_method_wrapper_t* ir_specializer_getMethodWrapper(ir_specializer_t* specializer,
 
796
                void* ilMethod, JITUINT32 recompileStateValue,
 
797
                ir_method_t* (*getIRMethod)(void* ilMethod),
 
798
                void (*setState)(void* ilMethod, JITUINT32 state), JITUINT32 (*getState)(void* ilMethod),
 
799
                void (*setJITFunction) (void *ilMethod, void* jitFunction), void* (*getJITFunction)(void *ilMethod),
 
800
                JITBOOLEAN (*isCctor)(void*ilMethod)){
 
801
        specializer_method_wrapper_t    *result;        /* The result method wrapper */
 
802
        specializer_method_wrapper_t    *methodWrapper; /* A generic method wrapper */
 
803
        JITUINT32                       index;
 
804
        XanListItem                     *item;
 
805
 
 
806
        /* Assertions */
 
807
        assert(specializer != NULL);
 
808
        assert(ilMethod != NULL);
 
809
        assert(getIRMethod != NULL);
 
810
        assert(setState != NULL);
 
811
        assert(getState != NULL);
 
812
        assert(setJITFunction != NULL);
 
813
        assert(getJITFunction != NULL);
 
814
        assert(isCctor != NULL);
 
815
 
 
816
        /* Initialize the variables */
 
817
        result = methodWrapper = NULL;
 
818
        item = NULL;
 
819
        index = 0;
 
820
 
 
821
        /* Lock the list */
 
822
        specializer->wrapperForMethods->lock(specializer->wrapperForMethods);
 
823
 
 
824
        /* For each element */
 
825
        PDEBUG("SPECIALIZER : ir_specializer_getMethodWrapper : Search for %p\n", ilMethod);
 
826
        for(index = 0; (index < specializer->wrapperForMethods->length(specializer->wrapperForMethods)) && (result == NULL); index++){
 
827
                /* Load item at given position */
 
828
                item = specializer->wrapperForMethods->getElementFromPositionNumber(specializer->wrapperForMethods, index);
 
829
                assert(item != NULL);
 
830
 
 
831
                /* Load methodWrapper */
 
832
                methodWrapper = (specializer_method_wrapper_t*) specializer->wrapperForMethods->data(specializer->wrapperForMethods, item);
 
833
                assert(methodWrapper != NULL);
 
834
 
 
835
                /* Check if it's the required one*/
 
836
                if(methodWrapper->ilMethod == ilMethod){
 
837
                        result = methodWrapper;
 
838
                }
 
839
        }
 
840
 
 
841
        if(result == NULL){ 
 
842
                /* No element found */
 
843
                /* Create a new one */
 
844
                result = newSpecializerMethodWrapper(specializer);
 
845
                result->init(result, ilMethod, recompileStateValue, getIRMethod, setState, getState, setJITFunction, getJITFunction, isCctor);
 
846
                specializer->wrapperForMethods->append(specializer->wrapperForMethods, result);
 
847
        }
 
848
 
 
849
        /* Unlock the list */
 
850
        specializer->wrapperForMethods->unlock(specializer->wrapperForMethods);
 
851
 
 
852
        /* return the result */
 
853
        return result;
 
854
}
 
855
 
 
856
specializer_callSitesForMethod_t* ir_specializer_getCallSitesFormMethod(ir_specializer_t* specializer, specializer_method_wrapper_t* wrapper){
 
857
        specializer_callSitesForMethod_t* callSitesForMethod, *result;
 
858
        XanListItem* item;
 
859
        JITUINT32 index;
 
860
 
 
861
        /* Assertions */
 
862
        assert(specializer != NULL);
 
863
        assert(wrapper != NULL);
 
864
 
 
865
        /* Initialize variables */
 
866
        result = NULL;
 
867
 
 
868
        /* Lock the list */
 
869
        specializer->callSitesForMethods->lock(specializer->callSitesForMethods);
 
870
 
 
871
        /* Search in the list */
 
872
        for(index  = 0; (index < specializer->callSitesForMethods->length(specializer->callSitesForMethods)) && (result == NULL); index++){
 
873
                /* Load the item */
 
874
                item = specializer->callSitesForMethods->getElementFromPositionNumber(specializer->callSitesForMethods, index);
 
875
 
 
876
                /* Load the callSitesForMethod */
 
877
                callSitesForMethod = (specializer_callSitesForMethod_t*) specializer->callSitesForMethods->data(specializer->callSitesForMethods, item);
 
878
 
 
879
                /* Check for equality */
 
880
                if(callSitesForMethod->methodWrapper == wrapper)
 
881
                        result = callSitesForMethod;
 
882
 
 
883
        }
 
884
 
 
885
        if(result == NULL){ /* If not found create it */
 
886
                /* Create a new call sites for methdod */
 
887
                result = newSpecializerCallSitesForMethod(specializer);
 
888
                result->init(result, wrapper, specializer);
 
889
                /* Append the the new call sites for methods */
 
890
                specializer->callSitesForMethods->append(specializer->callSitesForMethods, result);
 
891
        }
 
892
 
 
893
        /* Lock the list */
 
894
        specializer->callSitesForMethods->unlock(specializer->callSitesForMethods);
 
895
 
 
896
        /* Return the call sites for method */
 
897
        return result;
 
898
}
 
899
 
 
900
specializer_method_wrapper_t* ir_specializer_getSpecializedMethod(ir_specializer_t *specializer, specializer_method_wrapper_t* originalMethodWrapper, specializer_staticExpression_hint_t* staticExpression){
 
901
        specializer_specialized_method_wrapper_t* specializedMethod = NULL;
 
902
        specializer_specialized_method_wrapper_t* result = NULL;
 
903
        void* newMethod;
 
904
        JITUINT32 index;
 
905
        XanListItem* item;
 
906
 
 
907
        /* Assertions */
 
908
        assert(specializer != NULL);
 
909
        assert(originalMethodWrapper != NULL);
 
910
        assert(staticExpression != NULL);
 
911
 
 
912
#ifdef PRINTDEBUG
 
913
        PDEBUG("SPECIALIZER : getSpecializedMethod : Required original method %s [%s]\n", originalMethodWrapper->getFullName(originalMethodWrapper), originalMethodWrapper->getSignature(originalMethodWrapper));
 
914
        PDEBUG("SPECIALIZER : getSpecializedMethod : Static expression required: ");
 
915
        staticExpression->print(staticExpression, stderr);
 
916
        PDEBUG("\n");
 
917
#endif
 
918
 
 
919
        /* Lock the list */
 
920
        PDEBUG("SPECIALIZER : getSpecializedMethod : Try to lock specialized methods list...\n");
 
921
        specializer->specializedMethods->lock(specializer->specializedMethods);
 
922
        PDEBUG("SPECIALIZER : getSpecializedMethod : Lock specialized methods list\n");
 
923
        PDEBUG("SPECIALIZER : getSpecializedMethod : The list contains %d elements\n", specializer->specializedMethods->length(specializer->specializedMethods));
 
924
 
 
925
        /* Search for the specialized method wrapper inside the list */
 
926
        PDEBUG("SPECIALIZER : getSpecializedMethod : Search inside the list for required method and expression\n");
 
927
        result = NULL;
 
928
        for(index = 0; (index < specializer->specializedMethods->length(specializer->specializedMethods)) && (result == NULL); index++){
 
929
                item = specializer->specializedMethods->getElementFromPositionNumber(specializer->specializedMethods, index);
 
930
                assert(item != NULL);
 
931
 
 
932
                specializedMethod = (specializer_specialized_method_wrapper_t*) specializer->specializedMethods->data(specializer->specializedMethods, item);
 
933
                assert(specializedMethod != NULL);
 
934
 
 
935
                if((specializedMethod->originalMethodWrapper == originalMethodWrapper) &&
 
936
                                staticExpression->equals(staticExpression, specializedMethod->staticExpression)){
 
937
                        PDEBUG("SPECIALIZER : getSpecializedMethod : Found a method for the given static expression!\n");
 
938
                        result = specializedMethod;
 
939
                }
 
940
        }
 
941
 
 
942
        /* If not found create a new specialized method */
 
943
        if(result == NULL){
 
944
                void    *newJitFunction;
 
945
                PDEBUG("SPECIALIZER : getSpecializedMethod : Specialized method not found\n");
 
946
 
 
947
                /* Clone the static expression                  */
 
948
                staticExpression        = specializer_cloneStaticExpression(staticExpression, specializer);
 
949
 
 
950
                /* Create a new application method              */
 
951
                newMethod               = specializer->newApplicationMethod();
 
952
                assert(newMethod != NULL);
 
953
 
 
954
                /* Create a wrapper for the application method  */
 
955
                PDEBUG("SPECIALIZER : getSpecializedMethod : Create a new specialized wrapper (irPointer = %p)\n", originalMethodWrapper->_getIRMethod(newMethod));
 
956
                result          = getSpecializerSpecializedMethodWrapper(specializer);
 
957
                assert(result != NULL);
 
958
                result->init(result, staticExpression, originalMethodWrapper, ir_specializer_getMethodWrapper(specializer, newMethod, originalMethodWrapper->recompileStateValue, originalMethodWrapper->_getIRMethod, originalMethodWrapper->_setState, originalMethodWrapper->_getState, originalMethodWrapper->_setJITFunction, originalMethodWrapper->_getJITFunction, originalMethodWrapper->_isCctor));
 
959
                
 
960
                /* Create the specialized method                */
 
961
                PDEBUG("SPECIALIZER : getSpecializedMethod : Create a new specialized IR method (irPointer = %p)\n", result->specializedMethodWrapper->getIRMethod(result->specializedMethodWrapper));
 
962
                specializer_clone_makeSpecializedIRMethod(result->specializedMethodWrapper->ilMethod, originalMethodWrapper, result->specializedMethodWrapper, staticExpression, ir_specializer_getCallSitesFormMethod(specializer, originalMethodWrapper), specializer);
 
963
                PDEBUG("SPECIALIZER : getSpecializedMethod : Result CIL SIgnature : %s\n", result->specializedMethodWrapper->getSignature(result->specializedMethodWrapper));
 
964
 
 
965
                /* Create the JIT signature                     */
 
966
                PDEBUG("SPECIALIZER : getSpecializedMethod : Decode JIT signature\n");
 
967
                specializer->decode_jit_signature(specializer->system, result->specializedMethodWrapper->ilMethod);
 
968
 
 
969
                /* Create a new JIT Function for the specialized method */
 
970
                PDEBUG("SPECIALIZER : getSpecializedMethod : Create the JIT function\n");
 
971
                assert(result->specializedMethodWrapper->setJITFunction != NULL);
 
972
                assert(specializer->newJITFunction != NULL);
 
973
                assert(result->specializedMethodWrapper->ilMethod != NULL);
 
974
                newJitFunction  = specializer->newJITFunction(result->specializedMethodWrapper->ilMethod);
 
975
                assert(newJitFunction != NULL);
 
976
 
 
977
                /* Change the state to IR_STATE                                 */
 
978
                PDEBUG("SPECIALIZER : getSpecializedMethod : Require method for recompile\n");
 
979
                result->specializedMethodWrapper->setState(result->specializedMethodWrapper, 4);
 
980
 
 
981
                /* Append the specializer method to specialized method list     */
 
982
                PDEBUG("SPECIALIZER : getSpecializedMethod : Append the specialized method to specialized method list\n");
 
983
                specializer->specializedMethods->append(specializer->specializedMethods, result);
 
984
 
 
985
                /* Print the IRMethod for DEBUG */
 
986
#ifdef PRINTDEBUG
 
987
                fprintf(stdout, "\nSPECIALIZER : NEW SPECIALIZED METHOD OF %s [%s]\n",originalMethodWrapper->getFullName(originalMethodWrapper),originalMethodWrapper->getSignature(originalMethodWrapper));
 
988
                fprintf(stdout, "[SPECIALIZED] Method %s [%s] [%s]; Var Num = %d; Pointer = %p\n", result->specializedMethodWrapper->getFullName(result->specializedMethodWrapper), result->specializedMethodWrapper->getSignature(result->specializedMethodWrapper), result->specializedMethodWrapper->getIRMethod(result->specializedMethodWrapper)->signatureInString, result->specializedMethodWrapper->getIRMethod(result->specializedMethodWrapper)->getMaxVariables(result->specializedMethodWrapper->getIRMethod(result->specializedMethodWrapper)),result->specializedMethodWrapper->getIRMethod(result->specializedMethodWrapper));
 
989
                printIrMethod(result->specializedMethodWrapper->getIRMethod(result->specializedMethodWrapper), stdout, result->specializedMethodWrapper->_getFullName, result->specializedMethodWrapper->_getSignature);
 
990
                fprintf(stdout, "End [SPECIALIZED] Method %s [%s]\n", result->specializedMethodWrapper->getFullName(result->specializedMethodWrapper), result->specializedMethodWrapper->getSignature(result->specializedMethodWrapper));
 
991
#endif
 
992
        }
 
993
 
 
994
        /* Unlock the list */
 
995
        specializer->specializedMethods->unlock(specializer->specializedMethods);
 
996
 
 
997
        /* Return the value */
 
998
        return result->specializedMethodWrapper;
 
999
}
 
1000
 
 
1001
void* ir_specializer_recompile_request_thread(void* parameters){
 
1002
        /* Variables */
 
1003
        ir_specializer_t* specializer;
 
1004
        specializer_method_wrapper_t* callerWrapper;    /* Wrapper of the method to recompile */
 
1005
 
 
1006
        /* Assertions */
 
1007
        assert(parameters != NULL);
 
1008
 
 
1009
        /* Set thread cancel state */
 
1010
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
 
1011
        pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
 
1012
 
 
1013
        /* Set the specializer */
 
1014
        specializer = (ir_specializer_t*) parameters;
 
1015
 
 
1016
        while(1){
 
1017
 
 
1018
                /* Read next wrapper */
 
1019
                callerWrapper = (specializer_method_wrapper_t*) specializer->recompileRequestPipe->synchGet(specializer->recompileRequestPipe);
 
1020
 
 
1021
                /* Check if I have to exit      */
 
1022
                if (callerWrapper == NULL) break;
 
1023
                assert(callerWrapper != NULL);
 
1024
 
 
1025
                PDEBUG("\n//////////////////////////////////////////////////////////////////////////////////\n");
 
1026
                PDEBUG("SPECIALIZER : RECOMPILE REQUEST THREAD : Found a new method wrapper\n");
 
1027
                PDEBUG("SPECIALIZER : RECOMPILE REQUEST THREAD : Method Name = %s\n", callerWrapper->getFullName(callerWrapper));
 
1028
                PDEBUG("SPECIALIZER : RECOMPILE REQUEST THREAD : Method Signature = %s\n", callerWrapper->getSignature(callerWrapper));
 
1029
                PDEBUG("SPECIALIZER : RECOMPILE REQUEST THREAD : Method has %d variables\n", callerWrapper->getIRMethod(callerWrapper)->getMaxVariables(callerWrapper->getIRMethod(callerWrapper)));
 
1030
                PDEBUG("//////////////////////////////////////////////////////////////////////////////////\n");
 
1031
#ifdef PRINTDEBUG
 
1032
                fflush(stderr);
 
1033
#endif
 
1034
 
 
1035
                /* Change to recompile state */
 
1036
                callerWrapper->setToRecompileState(callerWrapper);
 
1037
 
 
1038
                /* Place it in the pipeline */
 
1039
                if(!specializer->shuttedDown){
 
1040
                        specializer->forceRecompile(callerWrapper->ilMethod);
 
1041
                } else {
 
1042
                        return NULL;
 
1043
                }
 
1044
        }
 
1045
 
 
1046
        return NULL;
 
1047
}
 
1048
 
 
1049
/* ----------------------------------------- specializer_expression_hint_t -----------------------------------------*/
 
1050
specializer_expression_hint_t* newSpecializerExpressionHint(ir_specializer_t* specializer){
 
1051
        /* Variables */
 
1052
        specializer_expression_hint_t* expression;
 
1053
 
 
1054
        /* Assertions */
 
1055
        assert(specializer != NULL);
 
1056
 
 
1057
        /* Allocate new space */
 
1058
        expression = (specializer_expression_hint_t*) allocFunction((size_t)sizeof(specializer_expression_hint_t));
 
1059
        assert(expression != NULL);
 
1060
 
 
1061
        /* Initialize calls */
 
1062
        expression->init                = specializer_expression_hint_init;
 
1063
        expression->printSingle = specializer_expression_hint_printSingle;
 
1064
        expression->printChain  = specializer_expression_hint_printChain;
 
1065
        expression->clean               = specializer_expression_hint_clean;
 
1066
 
 
1067
        /* Return hints For Method */
 
1068
        return expression;
 
1069
}
 
1070
void specializer_expression_hint_init(specializer_expression_hint_t* expression, JITUINT32 position, JITUINT32 action, JITINT64 ivalue, JITFLOAT64 fvalue, specializer_expression_hint_t* prev, specializer_expression_hint_t* next){
 
1071
        /* Assertions */
 
1072
        assert(expression != NULL);
 
1073
        assert(action == SPECIALIZER_ACTION_STATIC_EQ || action == SPECIALIZER_ACTION_STATIC_EQF || action == SPECIALIZER_ACTION_STATIC || action == SPECIALIZER_ACTION_STATIC_LENGTH);
 
1074
 
 
1075
        /* Assign values */
 
1076
        expression->position            = position;
 
1077
        expression->action                      = action;
 
1078
        if(expression->action == SPECIALIZER_ACTION_STATIC_EQ)
 
1079
                expression->value.ivalue = ivalue;
 
1080
        else if(expression->action == SPECIALIZER_ACTION_STATIC_EQ)
 
1081
                expression->value.fvalue = fvalue;
 
1082
        expression->depth = 0;
 
1083
        expression->next = next;
 
1084
        expression->prev = prev;
 
1085
}
 
1086
void specializer_expression_hint_printSingle(specializer_expression_hint_t* expression, FILE *out){
 
1087
        /* Assertions */
 
1088
        assert(expression != NULL);
 
1089
        assert(out != NULL);
 
1090
 
 
1091
        /* Print position */
 
1092
        fprintf(out, "#%d ", expression->position+1);
 
1093
        /* Print action */
 
1094
        switch(expression->action){
 
1095
                case SPECIALIZER_ACTION_STATIC:
 
1096
                        fprintf(out, "STATIC");
 
1097
                        break;
 
1098
                case SPECIALIZER_ACTION_STATIC_LENGTH:
 
1099
                        fprintf(out, "STATIC LENGTH");
 
1100
                        break;
 
1101
                case SPECIALIZER_ACTION_STATIC_EQ:
 
1102
                        fprintf(out, "EQUALS");
 
1103
                        break;
 
1104
                case SPECIALIZER_ACTION_STATIC_EQF:
 
1105
                        fprintf(out, "EQUALS FLOAT");
 
1106
                        break;
 
1107
                default:
 
1108
                        fprintf(stderr, "SPECIALIZER ERROR\n\t\tUnknown action value %u for expression\n", expression->action);
 
1109
                        abort();
 
1110
        }
 
1111
        /* Print value for equals */
 
1112
        if(expression->action == SPECIALIZER_ACTION_STATIC_EQ)
 
1113
                fprintf(out, " %lld", expression->value.ivalue);
 
1114
        else if(expression->action == SPECIALIZER_ACTION_STATIC_EQ)
 
1115
                fprintf(out, " %e", expression->value.fvalue);
 
1116
 
 
1117
}
 
1118
void specializer_expression_hint_printChain(specializer_expression_hint_t* expression, FILE *out){
 
1119
        /* Assertions */
 
1120
        assert(expression != NULL);
 
1121
        assert(out != NULL);
 
1122
 
 
1123
        /* Print this expression */
 
1124
        specializer_expression_hint_printSingle(expression, out);
 
1125
 
 
1126
        /* Print next expression if exists */
 
1127
        if(expression->next != NULL){
 
1128
                fprintf(out, " AND ");
 
1129
                specializer_expression_hint_printChain(expression->next, out);
 
1130
        }
 
1131
 
 
1132
        /* Print the depth */
 
1133
        if(expression->prev == NULL)
 
1134
                fprintf(out, " (Depth = %u) ", expression->depth);
 
1135
 
 
1136
}
 
1137
void specializer_expression_hint_clean(specializer_expression_hint_t* expression, ir_specializer_t* specializer){
 
1138
        /* Assertions */
 
1139
        assert(expression != NULL);
 
1140
        assert(specializer != NULL);
 
1141
 
 
1142
        /* Free next expression if exists */
 
1143
        if(expression->next != NULL)
 
1144
                specializer_expression_hint_clean(expression->next, specializer);
 
1145
 
 
1146
        /* Free expression itself */
 
1147
        freeFunction(expression);
 
1148
}
 
1149
/* ----------------------------------------- specializer_hintsForMethod_t -----------------------------------------*/
 
1150
specializer_hintsForMethod_t* newSpecializerHintsForMethod(ir_specializer_t* specializer){
 
1151
        /* Variables */
 
1152
        specializer_hintsForMethod_t* hints = NULL;
 
1153
 
 
1154
        /* Assertions */
 
1155
        assert(specializer != NULL);
 
1156
 
 
1157
        /* Allocate space */
 
1158
        hints = (specializer_hintsForMethod_t*) allocFunction((size_t)sizeof(specializer_hintsForMethod_t));
 
1159
        assert(hints != NULL);
 
1160
 
 
1161
        /* Initialize calls */
 
1162
        hints->init = specializer_hintsForMethod_init;
 
1163
        hints->print = specializer_hintsForMethod_print;
 
1164
        hints->clean = specializer_hintsForMethod_clean;
 
1165
        hints->equals = specializer_hintsForMethod_equals;
 
1166
        hints->addExpression = specializer_hintsForMethod_addExpression;
 
1167
        hints->getExpression = specializer_hintsForMethod_getExpression;
 
1168
        hints->getExpressionsNumber = specializer_hintsForMethod_getExpressionsNumber;
 
1169
 
 
1170
        /* Return hintsForMethod */
 
1171
        return hints;
 
1172
}
 
1173
void specializer_hintsForMethod_init(specializer_hintsForMethod_t *hints,
 
1174
                char* methodCompleteName, char* methodSignature,
 
1175
                JITFLOAT32 zeroProfilerTypeThreshold, JITUINT32 zeroProfilerMemorySize,
 
1176
                JITUINT32 zeroDispatcherRemoveThreshold, JITUINT32 firstProfilerThreshold,
 
1177
                JITUINT32 secondProfilerMemorySize, JITFLOAT32 secondProfilerStaticThreshold,
 
1178
                JITUINT32 dispatcherRemoveThreshold, ir_specializer_t* specializer){
 
1179
        /* Assertions */
 
1180
        assert(hints != NULL);
 
1181
        assert(methodCompleteName != NULL);
 
1182
        assert(methodSignature != NULL);
 
1183
        assert(secondProfilerStaticThreshold > 0 && secondProfilerStaticThreshold <= 1);
 
1184
        assert(zeroProfilerTypeThreshold > 0 && zeroProfilerTypeThreshold <= 1);
 
1185
 
 
1186
        /* Values assignment */
 
1187
        hints->methodCompleteName = methodCompleteName;
 
1188
        hints->methodSignature = methodSignature;
 
1189
        hints->zeroProfilerMemorySize = zeroProfilerMemorySize;
 
1190
        hints->zeroProfilerTypeThreshold = zeroProfilerTypeThreshold;
 
1191
        hints->zeroDispatcherRemoveThreshold = zeroDispatcherRemoveThreshold;
 
1192
        hints->firstProfilerThreshold = firstProfilerThreshold;
 
1193
        hints->secondProfilerMemorySize = secondProfilerMemorySize;
 
1194
        hints->secondProfilerStaticThreshold = secondProfilerStaticThreshold;
 
1195
        hints->dispatcherRemoveThreshold = dispatcherRemoveThreshold;
 
1196
 
 
1197
        /* Create the list of hints */
 
1198
        hints->expressions = xanListNew(allocFunction, freeFunction, NULL);
 
1199
        assert(hints->expressions != NULL);
 
1200
}
 
1201
void specializer_hintsForMethod_print(specializer_hintsForMethod_t *hints, FILE* out){
 
1202
        /* Variables */
 
1203
        JITUINT32 index = 0;    //Index for expressions
 
1204
        specializer_expression_hint_t* expression = NULL;       // Expression to print
 
1205
 
 
1206
        /* Assertions */
 
1207
        assert(hints != NULL);
 
1208
        assert(out != NULL);
 
1209
 
 
1210
        /* Print name and signature */
 
1211
        fprintf(out, "\tMethod Complete Name: %s\n", hints->methodCompleteName);
 
1212
        fprintf(out, "\tMethod Signature: %s\n", hints->methodSignature);
 
1213
        fprintf(out, "\tZero Profiler Type Threshold: %5.2e\n", hints->zeroProfilerTypeThreshold);
 
1214
        fprintf(out, "\tZero Profiler Memory Size: %u\n",hints->zeroProfilerMemorySize);
 
1215
        fprintf(out, "\tFirst Profiler Threshold: %u\n", hints->firstProfilerThreshold);
 
1216
        fprintf(out, "\tSecond Profiler Memory Size: %u bytes\n", hints->secondProfilerMemorySize);
 
1217
        fprintf(out, "\tSecond Profiler Static Threshold: %5.2e\n", hints->secondProfilerStaticThreshold);
 
1218
        fprintf(out, "\tDispatcher Remove Threshold: %u\n", hints->dispatcherRemoveThreshold);
 
1219
 
 
1220
        /* Print expressions */
 
1221
        fprintf(out, "\tExpressions:\n");
 
1222
        for(index=0;index<hints->expressions->length(hints->expressions);index++){
 
1223
                fprintf(out, "\t\t");
 
1224
                expression = hints->getExpression(hints, index);
 
1225
                expression->printChain(expression, out);
 
1226
                fprintf(out, "\n");
 
1227
        }
 
1228
 
 
1229
}
 
1230
void specializer_hintsForMethod_clean(specializer_hintsForMethod_t *hints, ir_specializer_t* specializer){
 
1231
        /* Variables */
 
1232
        JITUINT32 index = 0;    //Index for expressions
 
1233
        specializer_expression_hint_t* expression = NULL;       // Expression to clean
 
1234
 
 
1235
        /* Assertions */
 
1236
        assert(hints != NULL);
 
1237
        assert(specializer != NULL);
 
1238
 
 
1239
        /* Free name and signature */
 
1240
        freeFunction(hints->methodCompleteName);
 
1241
        freeFunction(hints->methodSignature);
 
1242
 
 
1243
        /* Clean each expression */
 
1244
        for(index = 0;index< hints->getExpressionsNumber(hints); index++){
 
1245
                expression = specializer_hintsForMethod_getExpression(hints, index);
 
1246
                expression->clean(expression, specializer);
 
1247
        }
 
1248
 
 
1249
        /* Destroy the expression list */
 
1250
        hints->expressions->destroyList(hints->expressions);
 
1251
 
 
1252
        /* Free itself */
 
1253
        freeFunction(hints);
 
1254
}
 
1255
JITBOOLEAN specializer_hintsForMethod_equals(specializer_hintsForMethod_t *hints, char *methodCompleteName, char *methodSignature){
 
1256
        /* Assertions */
 
1257
        assert(hints != NULL);
 
1258
        assert(methodCompleteName != NULL);
 
1259
        assert(methodSignature != NULL);
 
1260
 
 
1261
        /* String comparison of values */
 
1262
        return (strcmp(hints->methodCompleteName,methodCompleteName)==0) && (strcmp(hints->methodSignature, methodSignature)==0);
 
1263
}
 
1264
void specializer_hintsForMethod_addExpression(specializer_hintsForMethod_t *hints, specializer_expression_hint_t* expression){
 
1265
        /* Assertions */
 
1266
        assert(hints != NULL);
 
1267
        assert(expression != NULL);
 
1268
        assert(hints->expressions != NULL);
 
1269
 
 
1270
        /* Append the expression to the list of expressions */
 
1271
        hints->expressions->append(hints->expressions, expression);
 
1272
}
 
1273
specializer_expression_hint_t* specializer_hintsForMethod_getExpression(specializer_hintsForMethod_t *hints, JITUINT32 index){
 
1274
        /* Variables */
 
1275
        XanListItem* item;      // Item of the list
 
1276
        specializer_expression_hint_t* expression; // Read expression
 
1277
 
 
1278
        /* Assertions */
 
1279
        assert(hints != NULL);
 
1280
        assert(index < specializer_hintsForMethod_getExpressionsNumber(hints));
 
1281
 
 
1282
        /* Read the item */
 
1283
        item = hints->expressions->getElementFromPositionNumber(hints->expressions, index);
 
1284
        assert(item != NULL);
 
1285
 
 
1286
        /* Read the expression */
 
1287
        expression = (specializer_expression_hint_t*) hints->expressions->data(hints->expressions, item);
 
1288
        assert(expression != NULL);
 
1289
 
 
1290
        /* Return the expression */
 
1291
        return expression;
 
1292
}
 
1293
JITUINT32 specializer_hintsForMethod_getExpressionsNumber(specializer_hintsForMethod_t *hints){
 
1294
        /* Assertions */
 
1295
        assert(hints != NULL);
 
1296
        assert(hints->expressions != NULL);
 
1297
 
 
1298
        /* Return the length of the array element */
 
1299
        return hints->expressions->length(hints->expressions);
 
1300
}
 
1301
 
 
1302
/* ----------------------------------------- specializer_method_wrapper_t -----------------------------------------*/
 
1303
specializer_method_wrapper_t* newSpecializerMethodWrapper(ir_specializer_t* specializer){
 
1304
        /* Variables */
 
1305
        specializer_method_wrapper_t* methodWrapper = NULL;
 
1306
 
 
1307
        /* Assertions */
 
1308
        assert(specializer != NULL);
 
1309
 
 
1310
        /* Allocate space */
 
1311
        methodWrapper = (specializer_method_wrapper_t*) allocFunction((size_t)sizeof(specializer_method_wrapper_t));
 
1312
        assert(methodWrapper != NULL);
 
1313
 
 
1314
        /* Initialize calls */
 
1315
        methodWrapper->setState = specializer_method_wrapper_setState;
 
1316
        methodWrapper->getState = specializer_method_wrapper_getState;
 
1317
        methodWrapper->getIRMethod = specializer_method_wrapper_getIRMethod;
 
1318
        methodWrapper->setJITFunction = specializer_method_wrapper_setJITFunction;
 
1319
        methodWrapper->getJITFunction = specializer_method_wrapper_getJITFunction;
 
1320
        methodWrapper->isCctor = specializer_method_wrapper_isCctor;
 
1321
 
 
1322
        methodWrapper->init = specializer_method_wrapper_init;
 
1323
        methodWrapper->print = specializer_method_wrapper_print;
 
1324
        methodWrapper->clean = specializer_method_wrapper_clean;
 
1325
        methodWrapper->setToRecompileState = specializer_method_wrapper_setToRecompileState;
 
1326
 
 
1327
        /* Return the method */
 
1328
        return methodWrapper;
 
1329
 
 
1330
}
 
1331
void specializer_method_wrapper_init(specializer_method_wrapper_t* methodWrapper,
 
1332
                void* ilMethod, JITUINT32 recompileStateValue,
 
1333
                ir_method_t* (*getIRMethod)(void* ilMethod),
 
1334
                void (*setState)(void* ilMethod, JITUINT32 state), JITUINT32 (*getState)(void* ilMethod),
 
1335
                void (*setJITFunction) (void *ilMethod, void* jitFunction), void* (*getJITFunction)(void *ilMethod),
 
1336
                JITBOOLEAN (*isCctor)(void* ilMethod)){
 
1337
 
 
1338
        /* Assertion */
 
1339
        assert(methodWrapper != NULL);
 
1340
        assert(ilMethod != NULL);
 
1341
        assert(getIRMethod != NULL);
 
1342
        assert(setState != NULL);
 
1343
        assert(getState != NULL);
 
1344
        assert(getJITFunction != NULL);
 
1345
        assert(setJITFunction != NULL);
 
1346
        assert(isCctor != NULL);
 
1347
 
 
1348
        /* Assign variables */
 
1349
        methodWrapper->ilMethod = ilMethod;
 
1350
        methodWrapper->recompileStateValue = recompileStateValue;
 
1351
        methodWrapper->_getIRMethod = getIRMethod;
 
1352
        methodWrapper->_setState = setState;
 
1353
        methodWrapper->_getState = getState;
 
1354
        methodWrapper->_setJITFunction = setJITFunction;
 
1355
        methodWrapper->_getJITFunction = getJITFunction;
 
1356
        methodWrapper->_isCctor = isCctor;
 
1357
 
 
1358
}
 
1359
void specializer_method_wrapper_print (ir_specializer_t *specializer, specializer_method_wrapper_t* methodWrapper, FILE* out){
 
1360
        ir_method_t     *method;
 
1361
 
 
1362
        /* Assertions                                           */
 
1363
        assert(methodWrapper != NULL);
 
1364
        assert(out != NULL);
 
1365
        assert(specializer != NULL);
 
1366
 
 
1367
        /* Fetch the IR method                                  */
 
1368
        method          = methodWrapper->getIRMethod(methodWrapper);
 
1369
        assert(method != NULL);
 
1370
 
 
1371
        /* Just print out the full name and the signature       */
 
1372
        fprintf(out, "%s [%s]", method->getCompleteName(method), method->getSignatureInString(method, specializer->irlib->typeChecker));
 
1373
 
 
1374
        /* Return                                               */
 
1375
        return;
 
1376
}
 
1377
 
 
1378
void specializer_method_wrapper_clean(specializer_method_wrapper_t* methodWrapper, ir_specializer_t* specializer){
 
1379
        /* Assertions */
 
1380
        assert(specializer != NULL);
 
1381
        assert(methodWrapper != NULL);
 
1382
 
 
1383
        /* Hust clean itself */
 
1384
        freeFunction(methodWrapper);
 
1385
 
 
1386
}
 
1387
 
 
1388
ir_method_t* specializer_method_wrapper_getIRMethod(specializer_method_wrapper_t* methodWrapper){
 
1389
        /* Assertions */
 
1390
        assert(methodWrapper != NULL);
 
1391
 
 
1392
        /* Execute */
 
1393
        return methodWrapper->_getIRMethod(methodWrapper->ilMethod);
 
1394
}
 
1395
void specializer_method_wrapper_setState(specializer_method_wrapper_t* methodWrapper, JITUINT32 state){
 
1396
        /* Assertions */
 
1397
        assert(methodWrapper != NULL);
 
1398
 
 
1399
        /* Execute */
 
1400
        methodWrapper->_setState(methodWrapper->ilMethod, state);
 
1401
}
 
1402
JITUINT32 specializer_method_wrapper_getState(specializer_method_wrapper_t* methodWrapper){
 
1403
        /* Assertions */
 
1404
        assert(methodWrapper != NULL);
 
1405
 
 
1406
        /* Execute */
 
1407
        return methodWrapper->_getState(methodWrapper->ilMethod);
 
1408
}
 
1409
void specializer_method_wrapper_setToRecompileState(specializer_method_wrapper_t* methodWrapper){
 
1410
        /* Assertions */
 
1411
        assert(methodWrapper != NULL);
 
1412
 
 
1413
        /* Change the method state */
 
1414
        methodWrapper->_setState(methodWrapper->ilMethod, methodWrapper->recompileStateValue);
 
1415
}
 
1416
void specializer_method_wrapper_setJITFunction(specializer_method_wrapper_t* methodWrapper, void* jitFunction){
 
1417
        /* Assertions */
 
1418
        assert(methodWrapper != NULL);
 
1419
        assert(jitFunction != NULL);
 
1420
 
 
1421
        /* Assign the JIT function */
 
1422
        methodWrapper->_setJITFunction(methodWrapper->ilMethod, jitFunction);
 
1423
}
 
1424
void* specializer_method_wrapper_getJITFunction(specializer_method_wrapper_t* methodWrapper){
 
1425
        /* Assertions */
 
1426
        assert(methodWrapper !=  NULL);
 
1427
 
 
1428
        /* Return the jit function */
 
1429
        return methodWrapper->_getJITFunction(methodWrapper->ilMethod);
 
1430
}
 
1431
JITBOOLEAN specializer_method_wrapper_isCctor(specializer_method_wrapper_t* methodWrapper){
 
1432
        /* Assertions */
 
1433
        assert(methodWrapper != NULL);
 
1434
 
 
1435
        /* Return the required value */
 
1436
        return methodWrapper->_isCctor(methodWrapper->ilMethod);
 
1437
}
 
1438
 
 
1439
/* ----------------------------------------- specializer_method_callSite_t -----------------------------------------*/
 
1440
specializer_method_callSite_t* newSpecializerCallSite(ir_specializer_t* specializer){
 
1441
        /* Variables */
 
1442
        specializer_method_callSite_t* callSite = NULL;
 
1443
 
 
1444
        /* Assertions */
 
1445
        assert(specializer != NULL);
 
1446
 
 
1447
        /* Allocate space */
 
1448
        callSite = (specializer_method_callSite_t*) allocFunction((size_t)sizeof(specializer_method_callSite_t));
 
1449
        assert(callSite != NULL);
 
1450
 
 
1451
        /* Assign calls */
 
1452
        callSite->init                          = specializer_method_callSite_init;
 
1453
        callSite->print                         = specializer_method_callSite_print;
 
1454
        callSite->clean                         = specializer_method_callSite_clean;
 
1455
        callSite->addInstruction                = specializer_method_callSite_addInstruction;
 
1456
        callSite->removeInstructionsFromMethod  = specializer_method_callSite_removeInstructionsFromMethod;
 
1457
        callSite->performAction                 = specializer_method_callSite_performAction;
 
1458
        callSite->hasVariableParameters         = specializer_method_callSite_hasVariableParameters;
 
1459
 
 
1460
        /* return the call site */
 
1461
        return callSite;
 
1462
}
 
1463
 
 
1464
void specializer_method_callSite_init(specializer_method_callSite_t* callSite, specializer_method_wrapper_t *methodWrapper, t_ir_instruction* call, specializer_hintsForMethod_t *hints, ir_specializer_t* specializer){
 
1465
        /* Assertions */
 
1466
        assert(callSite != NULL);
 
1467
        assert(methodWrapper != NULL);
 
1468
        assert(call != NULL);
 
1469
        //assert(hints != NULL);
 
1470
        assert(specializer != NULL);
 
1471
 
 
1472
        /* Assign variables */
 
1473
        callSite->methodWrapper = methodWrapper;
 
1474
        callSite->call = call;
 
1475
        callSite->hints = hints;
 
1476
 
 
1477
        /* Initialize variables */
 
1478
        callSite->status = SPECIALIZER_CALLSITE_STATUS_CLEAN;
 
1479
        callSite->addedInstructions = xanListNew(allocFunction, freeFunction, NULL);
 
1480
 
 
1481
        /* Initialize profilers and dispatcher */
 
1482
        callSite->firstProfiler = NULL;
 
1483
        callSite->secondProfiler = NULL;
 
1484
        callSite->dispatcher = NULL;
 
1485
        callSite->typeDispatcher = NULL;
 
1486
}
 
1487
 
 
1488
void specializer_method_callSite_print (specializer_method_callSite_t* callSite, FILE* out, ir_specializer_t *specializer){
 
1489
        ir_method_t     *method;
 
1490
 
 
1491
        /* Assertions */
 
1492
        assert(callSite != NULL);
 
1493
        assert(out != NULL);
 
1494
        assert(specializer != NULL);
 
1495
 
 
1496
        /* Fetch the method             */
 
1497
        method          = callSite->methodWrapper->getIRMethod(callSite->methodWrapper);
 
1498
        assert(method != NULL);
 
1499
 
 
1500
        /* Print common informations */
 
1501
        fprintf(out, "\tCallee Method Full Name : %s [%s]\n", method->getCompleteName(method), method->getSignatureInString(method, specializer->irlib->typeChecker));
 
1502
        fprintf(out, "\tCall Instruction Pointer: %p\n", callSite->call);
 
1503
        fprintf(out, "\tNumber of instructions injected: %d\n", callSite->addedInstructions->length(callSite->addedInstructions));
 
1504
        /* Print status information */
 
1505
        switch(callSite->status){
 
1506
                case SPECIALIZER_CALLSITE_STATUS_CLEAN:
 
1507
                        fprintf(out, "\tStatus: CLEAN\n");
 
1508
                        break;
 
1509
                case SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED:
 
1510
                        fprintf(out, "\tStatus: FIRST PROFILER INJECTED\n");
 
1511
                        callSite->firstProfiler->print(callSite->firstProfiler, out);
 
1512
                        break;
 
1513
                case SPECIALIZER_CALLSITE_STATUS_SECOND_PROFILER_REQUEST:
 
1514
                        fprintf(out, "\tStatus: SECOND PROFILER REQUEST\n");
 
1515
                        if(callSite->firstProfiler != NULL)
 
1516
                                callSite->firstProfiler->print(callSite->firstProfiler, out);
 
1517
                        else
 
1518
                                fprintf(out, "\t\tNo such information about the first profiler!\n");
 
1519
                        break;
 
1520
                case SPECIALIZER_CALLSITE_STATUS_SECOND_PROFILER_INJECTED:
 
1521
                        fprintf(out, "\tStatus: SECOND PROFILER INJECTED\n");
 
1522
                        callSite->secondProfiler->print(callSite->secondProfiler, out);
 
1523
                        break;
 
1524
                case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_REQUEST:
 
1525
                        fprintf(out, "\tStatus: DISPATCHER REQUEST\n");
 
1526
                        callSite->secondProfiler->print(callSite->secondProfiler, out);
 
1527
                        break;
 
1528
                case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_INJECTED:
 
1529
                        fprintf(out, "\tStatus: DISPATCHER INJECTED\n");
 
1530
                        callSite->dispatcher->print(callSite->dispatcher, out);
 
1531
                        break;
 
1532
                case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_REMOVE:
 
1533
                        fprintf(out, "\tStatus: DISPATCHER REMOVE REQUEST\n");
 
1534
                        callSite->dispatcher->print(callSite->dispatcher, out);
 
1535
                        break;
 
1536
                case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_UNSPECIALIZABLE:
 
1537
                        fprintf(out, "\tStatus: UNSPECIALIZABLE\n");
 
1538
                        break;
 
1539
                case SPECIALIZER_CALLSITE_STATUS_TYPE_DISPATCHER_REQUEST:
 
1540
                        fprintf(out, "\tStatus: TYPE DISPATCHER REQUEST\n");
 
1541
                        callSite->firstProfiler->print(callSite->firstProfiler, out);
 
1542
                        break;
 
1543
                case SPECIALIZER_CALLSITE_STATUS_TYPE_DISPATCHER_INJECTED:
 
1544
                        fprintf(out, "\tStatus: TYPE DISPATCHER INJECTED\n");
 
1545
                        callSite->typeDispatcher->print(callSite->typeDispatcher, out);
 
1546
                        break;
 
1547
                case SPECIALIZER_CALLSITE_STATUS_TYPE_DISPATCHER_REMOVE:
 
1548
                        fprintf(out, "\tStatus: TYPE DISPATCHER REMOVE REQUEST\n");
 
1549
                        callSite->typeDispatcher->print(callSite->typeDispatcher, out);
 
1550
                        break;
 
1551
                default:
 
1552
                        fprintf(out, "\tStatus: Unknown (%u)\n", callSite->status);
 
1553
                        fprintf(stderr, "SPECIALIZER : specializer_method_callSite_print\n\t\tERROR = Unknown call site status\n");
 
1554
                        abort();
 
1555
        }
 
1556
}
 
1557
void specializer_method_callSite_clean(specializer_method_callSite_t* callSite, ir_specializer_t* specializer){
 
1558
        /* Assertions */
 
1559
        assert(callSite != NULL);
 
1560
        assert(specializer != NULL);
 
1561
 
 
1562
        /* Destroy the first profiler if needed */
 
1563
        if(callSite->firstProfiler != NULL){
 
1564
                callSite->firstProfiler->clean(callSite->firstProfiler, specializer);
 
1565
                callSite->firstProfiler = NULL;
 
1566
        }
 
1567
 
 
1568
        /* Destroy the dispatcher if needed */
 
1569
        if(callSite->secondProfiler != NULL){
 
1570
                callSite->secondProfiler->clean(callSite->secondProfiler, specializer);
 
1571
                callSite->secondProfiler = NULL;
 
1572
        }
 
1573
 
 
1574
        /* Destroy the dispatcher if needed */
 
1575
        if(callSite->dispatcher != NULL){
 
1576
                callSite->dispatcher->clean(callSite->dispatcher, specializer);
 
1577
                callSite->dispatcher = NULL;
 
1578
        }
 
1579
 
 
1580
        /* Clean the type dispatcher */
 
1581
        if(callSite->typeDispatcher != NULL){
 
1582
                callSite->typeDispatcher->clean(callSite->typeDispatcher, specializer);
 
1583
                callSite->typeDispatcher = NULL;
 
1584
        }
 
1585
 
 
1586
        /* Destroy instructions list */
 
1587
        callSite->addedInstructions->destroyList(callSite->addedInstructions);
 
1588
        callSite->addedInstructions = NULL;
 
1589
 
 
1590
        /* Free itself */
 
1591
        freeFunction(callSite);
 
1592
}
 
1593
 
 
1594
JITINT32 specializer_method_callSite_hasVariableParameters (specializer_method_callSite_t* callSite){
 
1595
        XanListItem     *item;
 
1596
 
 
1597
        /* Assertions                           */
 
1598
        assert(callSite != NULL);
 
1599
        assert(callSite->call != NULL);
 
1600
 
 
1601
        /* Check the existance of parameters    */
 
1602
        if (    (callSite->call->callParameters == NULL)                                        ||
 
1603
                (callSite->call->callParameters->length(callSite->call->callParameters) == 0)   ){
 
1604
                return JITFALSE;
 
1605
        }
 
1606
        
 
1607
        /* Check the parameters                 */
 
1608
        item    = callSite->call->callParameters->first(callSite->call->callParameters);
 
1609
        assert(item != NULL);
 
1610
        while (item != NULL){
 
1611
                ir_item_t       *param;
 
1612
                param   = (ir_item_t *) callSite->call->callParameters->data(callSite->call->callParameters, item);
 
1613
                assert(param != NULL);
 
1614
                if (param->type == IROFFSET) return JITTRUE;
 
1615
                item    = callSite->call->callParameters->next(callSite->call->callParameters, item);
 
1616
        }
 
1617
 
 
1618
        /* Return                               */
 
1619
        return JITFALSE;
 
1620
}
 
1621
 
 
1622
void specializer_method_callSite_addInstruction(specializer_method_callSite_t* callSite, t_ir_instruction* instruction){
 
1623
        /* Assertions */
 
1624
        assert(callSite != NULL);
 
1625
        assert(instruction != NULL);
 
1626
 
 
1627
        /* Add the instruction */
 
1628
        callSite->addedInstructions->append(callSite->addedInstructions, instruction);
 
1629
}
 
1630
void specializer_method_callSite_removeInstructionsFromMethod(specializer_method_callSite_t* callSite, ir_method_t* irMethod){
 
1631
        /* Variables */
 
1632
        t_ir_instruction* instruction;  /* Instruction to remove */
 
1633
//      JITUINT32 index;
 
1634
        XanListItem* item;
 
1635
 
 
1636
        /* Assertions */
 
1637
        assert(callSite != NULL);
 
1638
        assert(irMethod != NULL);
 
1639
 
 
1640
        /* While there are instructions added */
 
1641
        while(callSite->addedInstructions->length(callSite->addedInstructions) > 0){
 
1642
                //PDEBUG("X");
 
1643
                /* Load the next instruction */
 
1644
                item =  callSite->addedInstructions->getElementFromPositionNumber(callSite->addedInstructions, 0);
 
1645
                instruction = (t_ir_instruction*) callSite->addedInstructions->data(callSite->addedInstructions, item);
 
1646
 
 
1647
                /* Delete the instruction from the method */
 
1648
                irMethod->deleteInstruction(irMethod, instruction);
 
1649
 
 
1650
                /* Remove the instruction */
 
1651
                callSite->addedInstructions->deleteItem(callSite->addedInstructions, item);
 
1652
        }
 
1653
        //PDEBUG("\n");
 
1654
 
 
1655
//      /* Remove all instructions from irMehtod */
 
1656
//      for(index = 0; index < callSite->addedInstructions->length(callSite->addedInstructions); index++){
 
1657
//              /* Read the item */
 
1658
//              item =  callSite->addedInstructions->getElementFromPositionNumber(callSite->addedInstructions, index);
 
1659
//
 
1660
//              /* Read the instruction*/
 
1661
//              instruction = (t_ir_instruction*) callSite->addedInstructions->data(callSite->addedInstructions, item);
 
1662
//
 
1663
//              /* If it is a IRCALL instruction remove it from the call site list! */
 
1664
//              //TODO:
 
1665
//
 
1666
//              /* Remove the instruction from the method */
 
1667
//              irMethod->deleteInstruction(irMethod, instruction);
 
1668
//      }
 
1669
//
 
1670
//      /* Remove each instruction from the list */
 
1671
//      callSite->addedInstructions->emptyOutList(callSite->addedInstructions);
 
1672
}
 
1673
 
 
1674
void specializer_method_callSite_performAction (specializer_method_callSite_t* callSite, specializer_method_wrapper_t* callerWrapper, ir_specializer_t* specializer){
 
1675
        XanList         *staticExpressions;
 
1676
        #ifdef DEBUG
 
1677
        ir_method_t     *callerMethod;
 
1678
        ir_method_t     *calleeMethod;
 
1679
        #endif
 
1680
 
 
1681
        /* Assertions */
 
1682
        assert(callSite != NULL);
 
1683
        assert(specializer != NULL);
 
1684
        assert(callerWrapper != NULL);
 
1685
 
 
1686
#ifdef FULLMODE_PRINTDEBUG
 
1687
        ir_method_t     *irMethod;
 
1688
        ir_method_t     *irMethod2;
 
1689
        irMethod        = callerWrapper->getIRMethod(callerWrapper);
 
1690
        irMethod2       = callSite->methodWrapper->getIRMethod(callSite->methodWrapper);
 
1691
        FMODEPRINT("SPECIALIZER : performAction : Caller %s \tCallee %s\t", irMethod->getSignatureInString(irMethod, specializer->irlib->typeChecker), irMethod2->getSignatureInString(irMethod2, specializer->irlib->typeChecker));
 
1692
        FMODEPRINT("Enter State: %s\t", getStateName(callSite->status));
 
1693
#endif
 
1694
 
 
1695
        /* Fetch the methods    */
 
1696
        #ifdef DEBUG
 
1697
        callerMethod    = callerWrapper->getIRMethod(callerWrapper);
 
1698
        calleeMethod    = callSite->methodWrapper->getIRMethod(callSite->methodWrapper);
 
1699
        #endif
 
1700
        /* Print start informations */
 
1701
        PDEBUG("######################################################################################################\n");
 
1702
        PDEBUG("SPECIALIZER : CALL SITE : performAction : Start performing action\n");
 
1703
        PDEBUG("SPECIALIZER : CALL SITE : Caller full name  is \"%s\"\n", callerWrapper->getFullName(callerWrapper));
 
1704
        PDEBUG("SPECIALIZER : CALL SITE : Caller signature  is \"%s\"\n", callerWrapper->getSignature(callerWrapper));
 
1705
        PDEBUG("SPECIALIZER : CALL SITE : Caller pointer  is %p\n", callerWrapper->ilMethod);
 
1706
        PDEBUG("SPECIALIZER : CALL SITE : Call site informations at perform action START : \n");
 
1707
#ifdef PRINTDEBUG
 
1708
        callSite->print(callSite, stderr);
 
1709
#endif
 
1710
 
 
1711
        /* Execute action depending on the call site */
 
1712
        switch(callSite->status){
 
1713
                case SPECIALIZER_CALLSITE_STATUS_CLEAN:
 
1714
 
 
1715
                        /* Check if the call site has   *
 
1716
                         * only constants               */
 
1717
                        if (!(callSite->hasVariableParameters(callSite))){
 
1718
                                internal_action_to_second_or_dispatch_state(callSite, callerWrapper, specializer);
 
1719
                                break;
 
1720
                        }
 
1721
 
 
1722
                        /* Create the first profiler    */
 
1723
                        if(callSite->firstProfiler == NULL){
 
1724
                                callSite->firstProfiler = newSpecializerFirstProfiler(specializer);
 
1725
                                callSite->firstProfiler->init(callSite->firstProfiler, callSite, specializer);
 
1726
                        } else { 
 
1727
 
 
1728
                                /* Just clean it        */
 
1729
                                callSite->firstProfiler->counter                = 0;
 
1730
                                callSite->firstProfiler->thresholdReached       = JITFALSE;
 
1731
                        }
 
1732
 
 
1733
                        /* Inject the first profiler profiler */
 
1734
                        callSite->firstProfiler->inject(callSite->firstProfiler, callerWrapper, specializer);
 
1735
 
 
1736
                        /* Change the status */
 
1737
                        callSite->status        = SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED;
 
1738
                        break;
 
1739
                case SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED:
 
1740
                        /* Clean the type dispatcher if required */
 
1741
//                      if(callSite->typeDispatcher != NULL){
 
1742
//                              callSite->typeDispatcher->clean(callSite->typeDispatcher, specializer);
 
1743
//                              callSite->typeDispatcher = NULL;
 
1744
//                      }
 
1745
                        /* Clean the dispatcher if required */
 
1746
//                      if(callSite->dispatcher != NULL){
 
1747
//                              callSite->dispatcher->clean(callSite->dispatcher, specializer);
 
1748
//                              callSite->dispatcher = NULL;
 
1749
//                      }
 
1750
                        /* Clean the second profiler if requires */
 
1751
//                      if(callSite->secondProfiler != NULL){
 
1752
//                              callSite->secondProfiler->clean(callSite->secondProfiler, specializer);
 
1753
//                              callSite->secondProfiler = NULL;
 
1754
//                      }
 
1755
                        break;
 
1756
                case SPECIALIZER_CALLSITE_STATUS_SECOND_PROFILER_REQUEST:
 
1757
                        internal_action_to_second_or_dispatch_state(callSite, callerWrapper, specializer);
 
1758
                        break;
 
1759
                case SPECIALIZER_CALLSITE_STATUS_SECOND_PROFILER_INJECTED:
 
1760
                        /* Just remove the second profiler if present because it is necessary no more */
 
1761
//                      if(callSite->firstProfiler != NULL){
 
1762
//                              callSite->firstProfiler->clean(callSite->firstProfiler, specializer);
 
1763
//                              callSite->firstProfiler = NULL;
 
1764
//                      }
 
1765
                        break;
 
1766
                case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_REQUEST:
 
1767
                        /*
 
1768
                         * NOTE: Don't clear here the second profiler!!!!
 
1769
                         * It could be used by the execution thread even if changed the IR method!!
 
1770
                         *
 
1771
                         * So here we can just remove the second profiler
 
1772
                         * */
 
1773
 
 
1774
                        /* Remove the second profiler */
 
1775
                        callSite->secondProfiler->remove(callSite->secondProfiler, callerWrapper);
 
1776
 
 
1777
                        staticExpressions = callSite->secondProfiler->getStaticExpressions(callSite->secondProfiler, specializer);
 
1778
 
 
1779
                        if(staticExpressions != NULL){  /* If there are static expressions */
 
1780
                                /* Create the new dispatcher */
 
1781
                                if(callSite->dispatcher == NULL){
 
1782
                                        callSite->dispatcher = newSpecializerDispatcher(specializer);
 
1783
                                        callSite->dispatcher->init(callSite->dispatcher, callSite);
 
1784
                                } else {
 
1785
                                        callSite->dispatcher->counter = 0;
 
1786
                                        callSite->dispatcher->thresholdReached = JITFALSE;
 
1787
                                }
 
1788
 
 
1789
                                /* Inject the dispatcher */
 
1790
                                callSite->dispatcher->inject(callSite->dispatcher, callerWrapper, staticExpressions, specializer);
 
1791
 
 
1792
                                /* Change the status */
 
1793
                                callSite->status = SPECIALIZER_CALLSITE_STATUS_DISPATCHER_INJECTED;
 
1794
                        } else { /* If there are no static expressions */
 
1795
 
 
1796
                                /* Re-inject first profiler */
 
1797
                                if(callSite->firstProfiler == NULL){
 
1798
                                        callSite->firstProfiler = newSpecializerFirstProfiler(specializer);
 
1799
                                        callSite->firstProfiler->init(callSite->firstProfiler, callSite, specializer);
 
1800
                                } else { /* Just clean it*/
 
1801
                                        callSite->firstProfiler->counter = 0;
 
1802
                                        callSite->firstProfiler->thresholdReached = JITFALSE;
 
1803
                                }
 
1804
 
 
1805
                                /* Change the status to clean to enable the first profiler inject */
 
1806
                                callSite->status = SPECIALIZER_CALLSITE_STATUS_CLEAN;
 
1807
                                //callSite->firstProfiler->counter = 0;
 
1808
                                //callSite->firstProfiler->thresholdReached = JITFALSE;
 
1809
                                callSite->firstProfiler->inject(callSite->firstProfiler, callerWrapper, specializer);
 
1810
 
 
1811
                                /* Change the status to first profiler injected */
 
1812
                                callSite->status = SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED;
 
1813
 
 
1814
                        }
 
1815
                        break;
 
1816
                case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_INJECTED:
 
1817
                        /* Just clean the second profiler */
 
1818
//                      if(callSite->secondProfiler != NULL){
 
1819
//                              callSite->secondProfiler->clean(callSite->secondProfiler, specializer);
 
1820
//                              callSite->secondProfiler = NULL;
 
1821
//                      }
 
1822
                        break;
 
1823
                case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_REMOVE:
 
1824
                        /*
 
1825
                         * NOTE: Don't clear here the dispatcher!!!!
 
1826
                         * It could be used by the execution thread even if changed the IR method!!
 
1827
                         *
 
1828
                         * So here we can just remove the dispatcher
 
1829
                         * */
 
1830
 
 
1831
                        /* Remove the dispatcher */
 
1832
                        callSite->dispatcher->remove(callSite->dispatcher, callerWrapper);
 
1833
 
 
1834
                        /* Re-inject first profiler */
 
1835
                        if(callSite->firstProfiler == NULL){
 
1836
                                callSite->firstProfiler = newSpecializerFirstProfiler(specializer);
 
1837
                                callSite->firstProfiler->init(callSite->firstProfiler, callSite, specializer);
 
1838
                        } else { /* Just clean it*/
 
1839
                                callSite->firstProfiler->counter = 0;
 
1840
                                callSite->firstProfiler->thresholdReached = JITFALSE;
 
1841
                        }
 
1842
 
 
1843
                        /* Change the status to clean */
 
1844
                        callSite->status = SPECIALIZER_CALLSITE_STATUS_CLEAN;
 
1845
                        //callSite->firstProfiler->counter = 0;
 
1846
                        //callSite->firstProfiler->thresholdReached = JITFALSE;
 
1847
                        callSite->firstProfiler->inject(callSite->firstProfiler, callerWrapper, specializer);
 
1848
 
 
1849
                        /* Change the status to first profiler injected */
 
1850
                        callSite->status = SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED;
 
1851
                        break;
 
1852
                case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_UNSPECIALIZABLE:
 
1853
                        // Nothing to do
 
1854
                        break;
 
1855
                case SPECIALIZER_CALLSITE_STATUS_TYPE_DISPATCHER_REQUEST:
 
1856
 
 
1857
                        /* Remove the first profiler */
 
1858
                         callSite->firstProfiler->remove(callSite->firstProfiler, callerWrapper);
 
1859
 
 
1860
                        /* Create the type dispatcher */
 
1861
                        if(callSite->typeDispatcher == NULL){
 
1862
                                callSite->typeDispatcher = newSpecializerTypeDispatcher(specializer);
 
1863
                                callSite->typeDispatcher->init(callSite->typeDispatcher, callSite);
 
1864
                        } else {
 
1865
                                callSite->typeDispatcher->counter = 0;
 
1866
                                callSite->typeDispatcher->thresholdReached = JITFALSE;
 
1867
                        }
 
1868
 
 
1869
                        /* Inject the type dispatcher */
 
1870
                        if(callSite->typeDispatcher->inject(callSite->typeDispatcher, callerWrapper,callSite->firstProfiler->memory, callSite->firstProfiler->counter, specializer)){
 
1871
                                /* Change the status of this call site */
 
1872
                                callSite->status = SPECIALIZER_CALLSITE_STATUS_TYPE_DISPATCHER_INJECTED;
 
1873
                        } else {
 
1874
 
 
1875
                                /* Clean the specializer */
 
1876
                                callSite->typeDispatcher->clean(callSite->typeDispatcher, specializer);
 
1877
                                callSite->typeDispatcher = NULL;
 
1878
 
 
1879
                                /* Change the status of this call site */
 
1880
                                callSite->status = SPECIALIZER_CALLSITE_STATUS_CLEAN;
 
1881
 
 
1882
                                /* Reinject first profiler */
 
1883
                                callSite->firstProfiler->counter = 0;
 
1884
                                callSite->firstProfiler->thresholdReached = JITFALSE;
 
1885
                                callSite->firstProfiler->inject(callSite->firstProfiler, callerWrapper, specializer);
 
1886
 
 
1887
                                /* Change the status to first profiler injected */
 
1888
                                callSite->status = SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED;
 
1889
                        }
 
1890
                        break;
 
1891
                case SPECIALIZER_CALLSITE_STATUS_TYPE_DISPATCHER_INJECTED:
 
1892
                        // Just clean the first profiler
 
1893
//                      if(callSite->firstProfiler != NULL){
 
1894
//                              callSite->firstProfiler->clean(callSite->firstProfiler, specializer);
 
1895
//                              callSite->firstProfiler = NULL;
 
1896
//                      }
 
1897
                        break;
 
1898
                case SPECIALIZER_CALLSITE_STATUS_TYPE_DISPATCHER_REMOVE:
 
1899
                        /* Remove the type dispatcher */
 
1900
                        callSite->typeDispatcher->remove(callSite->typeDispatcher, callerWrapper);
 
1901
 
 
1902
                        /* Re-inject first profiler */
 
1903
                        if(callSite->firstProfiler == NULL){
 
1904
                                callSite->firstProfiler = newSpecializerFirstProfiler(specializer);
 
1905
                                callSite->firstProfiler->init(callSite->firstProfiler, callSite, specializer);
 
1906
                        } else {
 
1907
                                callSite->firstProfiler->counter = 0;
 
1908
                                callSite->firstProfiler->thresholdReached = JITFALSE;
 
1909
                        }
 
1910
 
 
1911
                        /* Change the status to clean */
 
1912
                        callSite->status = SPECIALIZER_CALLSITE_STATUS_CLEAN;
 
1913
                        //callSite->firstProfiler->counter = 0;
 
1914
                        //callSite->firstProfiler->thresholdReached = JITFALSE;
 
1915
                        callSite->firstProfiler->inject(callSite->firstProfiler, callerWrapper, specializer);
 
1916
 
 
1917
                        /* Change the status of this call site */
 
1918
                        callSite->status = SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED;
 
1919
                        break;
 
1920
                default:
 
1921
                        fprintf(stderr, "SPECIALIZER : specializer_method_callSite_performAction\n\t\tERROR = Unknown call site status\n");
 
1922
                        abort();
 
1923
        }
 
1924
 
 
1925
#ifdef FULLMODE_PRINTDEBUG
 
1926
        FMODEPRINT("Exit State: %s\n", getStateName(callSite->status));
 
1927
#endif
 
1928
 
 
1929
        /* Print informations at method exit */
 
1930
        PDEBUG("SPECIALIZER : CALL SITE : Call site informations at perform action at END : \n");
 
1931
#ifdef PRINTDEBUG
 
1932
        callSite->print(callSite, stderr);
 
1933
#endif
 
1934
        PDEBUG("######################################################################################################\n\n");
 
1935
}
 
1936
 
 
1937
/* ----------------------------------------- specializer_callSitesForMethod_t -----------------------------------------*/
 
1938
specializer_callSitesForMethod_t* newSpecializerCallSitesForMethod(ir_specializer_t* specializer){
 
1939
        /* Variables */
 
1940
        specializer_callSitesForMethod_t* callSitesForMethod = NULL;
 
1941
 
 
1942
        /* Assertions */
 
1943
        assert(specializer != NULL);
 
1944
 
 
1945
        /* Allocate space */
 
1946
        callSitesForMethod = (specializer_callSitesForMethod_t*) allocFunction((size_t)sizeof(specializer_callSitesForMethod_t));
 
1947
        assert(callSitesForMethod != NULL);
 
1948
 
 
1949
        /* Initialize calls */
 
1950
        callSitesForMethod->init = specializer_callSitesForMethod_init;
 
1951
        callSitesForMethod->print = specializer_callSitesForMethod_print;
 
1952
        callSitesForMethod->clean = specializer_callSitesForMethod_clean;
 
1953
        callSitesForMethod->getCallSiteForInstruction = specializer_callSitesForMethod_getCallSiteForInstruction;
 
1954
        callSitesForMethod->isInjectedInstruction = specializer_callSitesForMethod_isInjectedInstruction;
 
1955
 
 
1956
        /* Return the callSites */
 
1957
        return callSitesForMethod;
 
1958
}
 
1959
void specializer_callSitesForMethod_init(specializer_callSitesForMethod_t* callSitesForMethod, specializer_method_wrapper_t* wrapper, ir_specializer_t* specializer){
 
1960
        /* Assertions */
 
1961
        assert(callSitesForMethod != NULL);
 
1962
        assert(wrapper != NULL);
 
1963
        assert(specializer != NULL);
 
1964
 
 
1965
        /* Assign variables */
 
1966
        callSitesForMethod->methodWrapper = wrapper;
 
1967
 
 
1968
        /* initialize call site list */
 
1969
        callSitesForMethod->callSites = xanListNew(allocFunction, freeFunction, NULL);
 
1970
}
 
1971
 
 
1972
void specializer_callSitesForMethod_print (specializer_callSitesForMethod_t* callSitesForMethod, FILE* out, ir_specializer_t *specializer){
 
1973
        JITUINT32                       index;
 
1974
        XanListItem                     *item;
 
1975
        specializer_method_callSite_t   *callSite;
 
1976
        ir_method_t                     *method;
 
1977
 
 
1978
        /* Assertions                   */
 
1979
        assert(callSitesForMethod != NULL);
 
1980
        assert(out != NULL);
 
1981
        assert(specializer != NULL);
 
1982
 
 
1983
        /* Fetch the IR Method          */
 
1984
        method          = callSitesForMethod->methodWrapper->getIRMethod(callSitesForMethod->methodWrapper);
 
1985
        assert(method != NULL);
 
1986
 
 
1987
        /* Print caller information */
 
1988
        fprintf(out, "Caller: %s [%s]\n", method->getCompleteName(method), method->getSignatureInString(method, specializer->irlib->typeChecker));
 
1989
        
 
1990
        /* Print each call site */
 
1991
        callSitesForMethod->callSites->lock(callSitesForMethod->callSites);
 
1992
        fprintf(out, "There are %d call sites", callSitesForMethod->callSites->length(callSitesForMethod->callSites));
 
1993
        for(index=0;index < callSitesForMethod->callSites->length(callSitesForMethod->callSites); index++){
 
1994
                /* Load the item */
 
1995
                item = callSitesForMethod->callSites->getElementFromPositionNumber(callSitesForMethod->callSites, index);
 
1996
 
 
1997
                /* Load the call site */
 
1998
                callSite = (specializer_method_callSite_t*)callSitesForMethod->callSites->data(callSitesForMethod->callSites, item);
 
1999
 
 
2000
                /* Print the call site */
 
2001
                callSite->print(callSite, out, specializer);
 
2002
        }
 
2003
        callSitesForMethod->callSites->unlock(callSitesForMethod->callSites);
 
2004
}
 
2005
 
 
2006
void specializer_callSitesForMethod_clean(specializer_callSitesForMethod_t* callSitesForMethod, ir_specializer_t* specializer){
 
2007
        /* Variables */
 
2008
        JITUINT32 index;
 
2009
        XanListItem* item;
 
2010
        specializer_method_callSite_t* callSite;
 
2011
 
 
2012
        /* Assertions */
 
2013
        assert(callSitesForMethod != NULL);
 
2014
        assert(specializer != NULL);
 
2015
 
 
2016
        /* Destroy the each call site */
 
2017
        for(index=0;index < callSitesForMethod->callSites->length(callSitesForMethod->callSites); index++){
 
2018
                /* Load the item */
 
2019
                item = callSitesForMethod->callSites->getElementFromPositionNumber(callSitesForMethod->callSites, index);
 
2020
 
 
2021
                /* Load the call site */
 
2022
                callSite = (specializer_method_callSite_t*)callSitesForMethod->callSites->data(callSitesForMethod->callSites, item);
 
2023
 
 
2024
                /* Clean the call site */
 
2025
                callSite->clean(callSite, specializer);
 
2026
        }
 
2027
 
 
2028
        /* Destroy the list */
 
2029
        callSitesForMethod->callSites->destroyList(callSitesForMethod->callSites);
 
2030
 
 
2031
        /* Clean it self */
 
2032
        freeFunction(callSitesForMethod);
 
2033
}
 
2034
specializer_method_callSite_t*  specializer_callSitesForMethod_getCallSiteForInstruction(specializer_callSitesForMethod_t* callSitesForMethod, specializer_method_wrapper_t *calleeWrapper, t_ir_instruction* call, specializer_hintsForMethod_t *hints, ir_specializer_t* specializer){
 
2035
        /* Variables */
 
2036
        JITUINT32 index;
 
2037
        XanListItem* item;
 
2038
        specializer_method_callSite_t *callSite, *result;
 
2039
 
 
2040
        /* Assertions */
 
2041
        assert(callSitesForMethod != NULL);
 
2042
        assert(call != NULL);
 
2043
        assert(specializer != NULL);
 
2044
        assert(calleeWrapper != NULL);
 
2045
 
 
2046
        /* Lock the list */
 
2047
        callSitesForMethod->callSites->lock(callSitesForMethod->callSites);
 
2048
 
 
2049
        /* Search in the list */
 
2050
        result = NULL;
 
2051
        for(index=0;(index < callSitesForMethod->callSites->length(callSitesForMethod->callSites)) && (result == NULL); index++){
 
2052
                /* Load the item */
 
2053
                item = callSitesForMethod->callSites->getElementFromPositionNumber(callSitesForMethod->callSites, index);
 
2054
 
 
2055
                /* Load the call site */
 
2056
                callSite = (specializer_method_callSite_t*)callSitesForMethod->callSites->data(callSitesForMethod->callSites, item);
 
2057
 
 
2058
                /* Print the call site */
 
2059
                if(callSite->call == call)
 
2060
                        result = callSite;
 
2061
        }
 
2062
 
 
2063
 
 
2064
        if(result == NULL){     /* If not found create and add it */
 
2065
                result = newSpecializerCallSite(specializer);
 
2066
                result->init(result, calleeWrapper, call, hints, specializer);
 
2067
                callSitesForMethod->callSites->append(callSitesForMethod->callSites, result);
 
2068
        }
 
2069
 
 
2070
        /* Unlock the list */
 
2071
        callSitesForMethod->callSites->unlock(callSitesForMethod->callSites);
 
2072
 
 
2073
        return result;
 
2074
}
 
2075
JITBOOLEAN      specializer_callSitesForMethod_isInjectedInstruction(specializer_callSitesForMethod_t* callSitesForMethod, t_ir_instruction* instruction){
 
2076
        /* Variables */
 
2077
        JITUINT32 index;
 
2078
        XanListItem* item;
 
2079
        specializer_method_callSite_t *callSite;
 
2080
        JITBOOLEAN found;
 
2081
 
 
2082
        /* Assertions */
 
2083
        assert(callSitesForMethod != NULL);
 
2084
        assert(instruction != NULL);
 
2085
 
 
2086
        /* Lock the list */
 
2087
        callSitesForMethod->callSites->lock(callSitesForMethod->callSites);
 
2088
 
 
2089
        /* Search in the list */
 
2090
        found = JITFALSE;
 
2091
        for(index=0;(index < callSitesForMethod->callSites->length(callSitesForMethod->callSites)) && !found; index++){
 
2092
                /* Load the item */
 
2093
                item = callSitesForMethod->callSites->getElementFromPositionNumber(callSitesForMethod->callSites, index);
 
2094
 
 
2095
                /* Load the call site */
 
2096
                callSite = (specializer_method_callSite_t*)callSitesForMethod->callSites->data(callSitesForMethod->callSites, item);
 
2097
 
 
2098
                /* Have found? */
 
2099
                found = callSite->addedInstructions->find(callSite->addedInstructions, instruction) != NULL;
 
2100
        }
 
2101
 
 
2102
        /* Unlock the list */
 
2103
        callSitesForMethod->callSites->unlock(callSitesForMethod->callSites);
 
2104
 
 
2105
        return found;
 
2106
}
 
2107
 
 
2108
/* ----------------------------------------- specializer_method_callSite_firstProfiler_t -----------------------------------------*/
 
2109
specializer_method_callSite_firstProfiler_t* newSpecializerFirstProfiler(ir_specializer_t* specializer){
 
2110
        /* Variables */
 
2111
        specializer_method_callSite_firstProfiler_t* profiler = NULL;
 
2112
 
 
2113
        /* Assertions */
 
2114
        assert(specializer != NULL);
 
2115
 
 
2116
        /* Allocate space */
 
2117
        profiler = (specializer_method_callSite_firstProfiler_t*) allocFunction((size_t)sizeof(specializer_method_callSite_firstProfiler_t));
 
2118
        assert(profiler);
 
2119
 
 
2120
        /* Assign functions */
 
2121
        profiler->init = specializer_method_callSite_firstProfiler_init;
 
2122
        profiler->print = specializer_method_callSite_firstProfiler_print;
 
2123
        profiler->clean = specializer_method_callSite_firstProfiler_clean;
 
2124
        profiler->getCounterPointer = specializer_method_callSite_firstProfiler_getCounterPointer;
 
2125
        profiler->getCounterValue = specializer_method_callSite_firstProfiler_getCounterValue;
 
2126
        profiler->getThresholdReachedPointer = specializer_method_callSite_firstProfiler_getThresholdReachedPointer;
 
2127
        profiler->isThresholdReached = specializer_method_callSite_firstProfiler_isThresholdReached;
 
2128
        profiler->inject = specializer_method_callSite_firstProfiler_inject;
 
2129
        profiler->remove = specializer_method_callSite_firstProfiler_remove;
 
2130
 
 
2131
        /* Return the profiler */
 
2132
        return profiler;
 
2133
}
 
2134
void specializer_method_callSite_firstProfiler_init(specializer_method_callSite_firstProfiler_t* profiler, void* callSiteContext, ir_specializer_t* specializer){
 
2135
        /* Variables */
 
2136
        specializer_method_callSite_t* callSite;
 
2137
 
 
2138
        /* Assertions */
 
2139
        assert(profiler != NULL);
 
2140
        assert(callSiteContext != NULL);
 
2141
        assert(specializer != NULL);
 
2142
 
 
2143
        /* Assign variables */
 
2144
        profiler->callSiteContext = callSiteContext;
 
2145
 
 
2146
        /* Initialize variables */
 
2147
        profiler->counter = 0;
 
2148
        profiler->thresholdReached = JITFALSE;
 
2149
 
 
2150
        /* Initialize the memory for the IRVCALL if required */
 
2151
        callSite = callSiteContext;
 
2152
        if(callSite->call->type == IRVCALL){
 
2153
                PDEBUG("SPECIALIZER : FIRST PROFILER : init : Allocate space for zero type profiler memory");
 
2154
                profiler->memory = (JITUINT32*) allocFunction((size_t)sizeof(JITUINT32)*callSite->hints->zeroProfilerMemorySize);
 
2155
                assert(profiler->memory != NULL);
 
2156
                memset(profiler->memory, 0xFF, (size_t)sizeof(JITUINT32)*callSite->hints->zeroProfilerMemorySize);
 
2157
                PDEBUG(" (%p)//(%u)\n", profiler->memory, (JITUINT32) profiler->memory);
 
2158
        }
 
2159
}
 
2160
void specializer_method_callSite_firstProfiler_print(specializer_method_callSite_firstProfiler_t* profiler, FILE* out){
 
2161
        /* Assertions */
 
2162
        assert(profiler != NULL);
 
2163
        assert(out != NULL);
 
2164
 
 
2165
        /* Print the profiler */
 
2166
        fprintf(out,"\t\t(1st) Counter Value: %u\n", specializer_method_callSite_firstProfiler_getCounterValue(profiler));
 
2167
        fprintf(out,"\t\t(1st) Counter Pointer: %p\n", specializer_method_callSite_firstProfiler_getCounterPointer(profiler));
 
2168
        fprintf(out,"\t\t(1st) Threshold Reached: %s\n", specializer_method_callSite_firstProfiler_isThresholdReached(profiler)?"TRUE":"FALSE");
 
2169
        fprintf(out,"\t\t(1st) Threshold Reached Pointer: %p\n", specializer_method_callSite_firstProfiler_getThresholdReachedPointer(profiler));
 
2170
}
 
2171
void specializer_method_callSite_firstProfiler_clean(specializer_method_callSite_firstProfiler_t* profiler, ir_specializer_t* specializer){
 
2172
        /* Variables */
 
2173
        specializer_method_callSite_t* callSite;
 
2174
 
 
2175
        /* Assertions */
 
2176
        assert(profiler != NULL);
 
2177
 
 
2178
        /* Free the memory allocated for the type profiler */
 
2179
        callSite = profiler->callSiteContext;
 
2180
        if(callSite->call->type == IRVCALL){
 
2181
                freeFunction(profiler->memory);
 
2182
        }
 
2183
 
 
2184
        /*Just clean itself */
 
2185
        freeFunction(profiler);
 
2186
}
 
2187
JITUINT32* specializer_method_callSite_firstProfiler_getCounterPointer(specializer_method_callSite_firstProfiler_t* profiler){
 
2188
        /* Assertions */
 
2189
        assert(profiler != NULL);
 
2190
 
 
2191
        /* Return the pointer to the counter */
 
2192
        return &(profiler->counter);
 
2193
}
 
2194
JITUINT32 specializer_method_callSite_firstProfiler_getCounterValue(struct specializer_method_callSite_firstProfiler_t* profiler){
 
2195
        /* Assertions */
 
2196
        assert(profiler != NULL);
 
2197
 
 
2198
        /* Return the value of the counter */
 
2199
        return profiler->counter;
 
2200
 
 
2201
}
 
2202
JITUINT32* specializer_method_callSite_firstProfiler_getThresholdReachedPointer(specializer_method_callSite_firstProfiler_t* profiler){
 
2203
        /* Assertions */
 
2204
        assert(profiler != NULL);
 
2205
 
 
2206
        /* Return the pointer to the threshold reached variable */
 
2207
        return &(profiler->thresholdReached);
 
2208
}
 
2209
JITUINT32 specializer_method_callSite_firstProfiler_isThresholdReached(specializer_method_callSite_firstProfiler_t* profiler){
 
2210
        /* Assertions */
 
2211
        assert(profiler != NULL);
 
2212
 
 
2213
        /* Return the value of the threshold reached variable  */
 
2214
        return profiler->thresholdReached;
 
2215
}
 
2216
 
 
2217
/* ----------------------------------------- specializer_callSite_secondProfiler_param_t -----------------------------------------*/
 
2218
specializer_callSite_secondProfiler_param_t* newSpecializerSecondProfileParameter(ir_specializer_t* specializer){
 
2219
        /* Variables */
 
2220
        specializer_callSite_secondProfiler_param_t* parameter = NULL;
 
2221
 
 
2222
        /* Assertions */
 
2223
        assert(specializer != NULL);
 
2224
 
 
2225
        /* Allocate space */
 
2226
        parameter = (specializer_callSite_secondProfiler_param_t*) allocFunction((size_t)sizeof(specializer_callSite_secondProfiler_param_t));
 
2227
 
 
2228
        /* Assign instruction call */
 
2229
        parameter->init = specializer_callSite_secondProfiler_param_init;
 
2230
        parameter->print = specializer_callSite_secondProfiler_param_print;
 
2231
        parameter->clean = specializer_callSite_secondProfiler_param_clean;
 
2232
        parameter->getParamType = specializer_callSite_secondProfiler_param_getParamType;
 
2233
        parameter->getParamInternalType = specializer_callSite_secondProfiler_param_getParamInternalType;
 
2234
        parameter->getParameterSize = specializer_callSite_secondProfiler_param_getParameterSize;
 
2235
        parameter->isVariable = specializer_callSite_secondProfiler_param_isVariable;
 
2236
        parameter->isConstant = specializer_callSite_secondProfiler_param_isConstant;
 
2237
        parameter->isVector = specializer_callSite_secondProfiler_param_isVector;
 
2238
        parameter->getValue = specializer_callSite_secondProfiler_param_getValue;
 
2239
        parameter->getFValue = specializer_callSite_secondProfiler_param_getFValue;
 
2240
        parameter->getType = specializer_callSite_secondProfiler_param_getType;
 
2241
 
 
2242
        /* return the parameter */
 
2243
        return parameter;
 
2244
}
 
2245
void specializer_callSite_secondProfiler_param_init(specializer_callSite_secondProfiler_param_t* secondProfilerParam, ir_item_t* item, JITUINT32 offset, JITUINT32 position, JITBOOLEAN isVector){
 
2246
        /* Assertion */
 
2247
        assert(secondProfilerParam != NULL);
 
2248
        assert(item != NULL);
 
2249
 
 
2250
        /* Clone the item variable */
 
2251
        secondProfilerParam->item.value = item->value;
 
2252
        secondProfilerParam->item.fvalue = item->fvalue;
 
2253
        secondProfilerParam->item.type = item->type;
 
2254
        secondProfilerParam->item.internal_type = item->internal_type;
 
2255
        secondProfilerParam->item.value_type_infos = item->value_type_infos;
 
2256
 
 
2257
        /* Assign offset and position */
 
2258
        secondProfilerParam->offset = offset;
 
2259
        secondProfilerParam->position = position;
 
2260
        secondProfilerParam->_isVector = isVector;
 
2261
}
 
2262
void specializer_callSite_secondProfiler_param_print(specializer_callSite_secondProfiler_param_t* secondProfilerParam, FILE* out){
 
2263
        /* Assertions */
 
2264
        assert(secondProfilerParam != NULL);
 
2265
        assert(out != NULL);
 
2266
 
 
2267
        /* Print the parameter */
 
2268
        if(secondProfilerParam->_isVector)
 
2269
                fprintf(out,"Variable = %lld, Type = VECTOR, (Position = %d, Offset = %d, Size = %d)",  secondProfilerParam->item.value, secondProfilerParam->position, secondProfilerParam->offset, specializer_callSite_secondProfiler_param_getParameterSize(secondProfilerParam));
 
2270
        else if(secondProfilerParam->item.type != IROFFSET)
 
2271
                fprintf(out,"Type = CONSTANT, Value = (%lld, %5.2e),  (Position = %d, Offset = %d, Size = %d)", secondProfilerParam->item.value, secondProfilerParam->item.fvalue, secondProfilerParam->position, secondProfilerParam->offset, specializer_callSite_secondProfiler_param_getParameterSize(secondProfilerParam));
 
2272
        else if(secondProfilerParam->item.type == IROFFSET)
 
2273
                fprintf(out,"Variable = %lld, Type = %s, (Position = %d, Offset = %d, Size = %d)",  secondProfilerParam->item.value, getTypeName(secondProfilerParam->item.internal_type), secondProfilerParam->position, secondProfilerParam->offset, specializer_callSite_secondProfiler_param_getParameterSize(secondProfilerParam));
 
2274
        else
 
2275
                fprintf(out,"Type = UNKNOWN!!!");
 
2276
}
 
2277
void specializer_callSite_secondProfiler_param_clean(specializer_callSite_secondProfiler_param_t* secondProfilerParam, ir_specializer_t* specializer){
 
2278
        /* Assertions */
 
2279
        assert(secondProfilerParam != NULL);
 
2280
        assert(specializer != NULL);
 
2281
 
 
2282
        /* Just clean itself */
 
2283
        freeFunction(secondProfilerParam);
 
2284
 
 
2285
}
 
2286
JITUINT32 specializer_callSite_secondProfiler_param_getParamType(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
 
2287
        /* Assertions */
 
2288
        assert(secondProfilerParam != NULL);
 
2289
 
 
2290
        /* Return the required value */
 
2291
        return secondProfilerParam->item.type;
 
2292
}
 
2293
JITUINT32 specializer_callSite_secondProfiler_param_getParamInternalType(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
 
2294
        /* Assertions */
 
2295
        assert(secondProfilerParam != NULL);
 
2296
 
 
2297
        /* Return the required value */
 
2298
        return secondProfilerParam->item.internal_type;
 
2299
}
 
2300
size_t specializer_callSite_secondProfiler_param_getParameterSize(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
 
2301
        /* Assertions */
 
2302
        assert(secondProfilerParam != NULL);
 
2303
 
 
2304
        /* Return the required value */
 
2305
        if(secondProfilerParam->_isVector)
 
2306
                return getSizeByType(IRUINT32);
 
2307
        else if(secondProfilerParam->item.type == IROFFSET)
 
2308
                return getSizeByType(secondProfilerParam->item.internal_type);
 
2309
        return getSizeByType(secondProfilerParam->item.type);
 
2310
}
 
2311
JITUINT32 specializer_callSite_secondProfiler_param_getType(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
 
2312
        /* Assertions */
 
2313
        assert(secondProfilerParam != NULL);
 
2314
 
 
2315
        /* Return the required value */
 
2316
        if(secondProfilerParam->_isVector)
 
2317
                return IRUINT32;
 
2318
        else if(secondProfilerParam->item.type == IROFFSET)
 
2319
                return secondProfilerParam->item.internal_type;
 
2320
        return secondProfilerParam->item.type;
 
2321
 
 
2322
}
 
2323
JITBOOLEAN specializer_callSite_secondProfiler_param_isVariable(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
 
2324
        /* Assertions */
 
2325
        assert(secondProfilerParam != NULL);
 
2326
 
 
2327
        /* Return the required value */
 
2328
        return (secondProfilerParam->item.type == IROFFSET) /*&& !secondProfilerParam->_isVector*/;
 
2329
}
 
2330
JITBOOLEAN specializer_callSite_secondProfiler_param_isConstant(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
 
2331
        /* Assertions */
 
2332
        assert(secondProfilerParam != NULL);
 
2333
 
 
2334
        /* Return the required value */
 
2335
        return (secondProfilerParam->item.type != IROFFSET) /*&& !secondProfilerParam->_isVector*/;
 
2336
}
 
2337
JITBOOLEAN specializer_callSite_secondProfiler_param_isVector(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
 
2338
        /* Assertions */
 
2339
        assert(secondProfilerParam != NULL);
 
2340
 
 
2341
        /* Return the required value */
 
2342
        return secondProfilerParam->_isVector;
 
2343
}
 
2344
IR_ITEM_VALUE specializer_callSite_secondProfiler_param_getValue(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
 
2345
        /* Assertions */
 
2346
        assert(secondProfilerParam != NULL);
 
2347
 
 
2348
        /* Return the required value */
 
2349
        return secondProfilerParam->item.value;
 
2350
}
 
2351
IR_ITEM_FVALUE specializer_callSite_secondProfiler_param_getFValue(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
 
2352
        /* Assertions */
 
2353
        assert(secondProfilerParam != NULL);
 
2354
 
 
2355
        /* Return the required value */
 
2356
        return secondProfilerParam->item.fvalue;
 
2357
}
 
2358
 
 
2359
/* ----------------------------------------- specializer_method_callSite_secondProfiler_t -----------------------------------------*/
 
2360
specializer_method_callSite_secondProfiler_t* newSpecializerSecondProfiler(ir_specializer_t* specializer){
 
2361
        /* Variables */
 
2362
        specializer_method_callSite_secondProfiler_t* profiler;
 
2363
 
 
2364
        /* Assertions */
 
2365
        assert(specializer != NULL);
 
2366
 
 
2367
        /* Allocate space */
 
2368
        profiler = (specializer_method_callSite_secondProfiler_t*) allocFunction((size_t)sizeof(specializer_method_callSite_secondProfiler_t));
 
2369
        assert(profiler != NULL);
 
2370
 
 
2371
        /* Initialize Calls */
 
2372
        profiler->init = specializer_method_callSite_secondProfiler_init;
 
2373
        profiler->print = specializer_method_callSite_secondProfiler_print;
 
2374
        profiler->clean = specializer_method_callSite_secondProfiler_clean;
 
2375
        profiler->inject = specializer_method_callSite_secondProfiler_inject;
 
2376
        profiler->remove = specializer_method_callSite_secondProfiler_remove;
 
2377
 
 
2378
        profiler->getCounterPointer = specializer_method_callSite_secondProfiler_getCounterPointer;
 
2379
        profiler->getCounterValue = specializer_method_callSite_secondProfiler_getCounterValue;
 
2380
        profiler->getThresholdReachedPointer = specializer_method_callSite_secondProfiler_getThresholdReachedPointer;
 
2381
        profiler->isThresholdReached = specializer_method_callSite_secondProfiler_isThresholdReached;
 
2382
        profiler->getThreshold = specializer_method_callSite_secondProfiler_getThreshold;
 
2383
        profiler->getBlockSize = specializer_method_callSite_secondProfiler_getBlockSize;
 
2384
 
 
2385
        profiler->getStaticExpressions = specializer_method_callSite_secondProfiler_getStaticExpressions;
 
2386
 
 
2387
        /* Return the profiler */
 
2388
        return profiler;
 
2389
}
 
2390
 
 
2391
void specializer_method_callSite_secondProfiler_init(specializer_method_callSite_secondProfiler_t* profiler, void *callSiteContext, ir_specializer_t* specializer){
 
2392
        specializer_method_callSite_t* callSite;        /* The call site */
 
2393
        XanListItem* listItem;  /* The item for the list  */
 
2394
        ir_item_t* parameter;   /* A generic parameter */
 
2395
        JITBOOLEAN* requiredParameters; /* Vector of required parameters */
 
2396
        specializer_expression_hint_t* expression;      /* An expression to manipulate */
 
2397
        specializer_callSite_secondProfiler_param_t* secondProfilerParameter;
 
2398
        JITUINT32 index;
 
2399
 
 
2400
        /* Assertions */
 
2401
        assert(profiler != NULL);
 
2402
        assert(specializer !=  NULL);
 
2403
        assert(callSiteContext != NULL);
 
2404
 
 
2405
        /* Initialize variables */
 
2406
        profiler->callSiteContext = callSiteContext;
 
2407
        profiler->threshold = 0;
 
2408
        profiler->blockSize = 0;
 
2409
        profiler->counter = 0;
 
2410
        profiler->thresholdReached = JITFALSE;
 
2411
 
 
2412
        /* Create parameters list */
 
2413
        profiler->parameters    = xanListNew(allocFunction, freeFunction, NULL);
 
2414
 
 
2415
        /* Initialize the call site */
 
2416
        callSite                = (specializer_method_callSite_t*) callSiteContext;
 
2417
 
 
2418
        /* Allocate memory where parameters values must be stored */
 
2419
        profiler->memory        = allocFunction(callSite->hints->secondProfilerMemorySize);
 
2420
 
 
2421
        /* Create the vector to detect which parameters have been used */
 
2422
        requiredParameters      = (JITBOOLEAN*) allocFunction(sizeof(JITBOOLEAN)*callSite->call->callParameters->length(callSite->call->callParameters));
 
2423
        memset(requiredParameters, JITFALSE, sizeof(JITBOOLEAN)*callSite->call->callParameters->length(callSite->call->callParameters));
 
2424
 
 
2425
        /* Find offset for each parameter */
 
2426
        PDEBUG("SPECIALIZER: CALL SITE : SECOND PROFIELR : Required parameters : ");
 
2427
        PDEBUG("\t\tExpression hints for\n");
 
2428
        #ifdef PRINTDEBUG
 
2429
        callSite->hints->print(callSite->hints, stderr);
 
2430
        #endif
 
2431
        for(index = 0; index < callSite->hints->getExpressionsNumber(callSite->hints); index++){
 
2432
                /* Load expression */
 
2433
                expression = callSite->hints->getExpression(callSite->hints, index);
 
2434
                PDEBUG("{Expression:");
 
2435
                #ifdef PRINTDEBUG
 
2436
                expression->printChain(expression, stderr);
 
2437
                #endif
 
2438
                PDEBUG("}");
 
2439
                do{
 
2440
                        /* If the parameter hasn't already been created */
 
2441
                        if(!requiredParameters[expression->position]){
 
2442
                                PDEBUG("%u ", expression->position);
 
2443
 
 
2444
                                /* Load parameter at required position */
 
2445
                                listItem = callSite->call->callParameters->getElementFromPositionNumber(callSite->call->callParameters, expression->position);
 
2446
                                assert(listItem != NULL);
 
2447
                                parameter = (ir_item_t*) callSite->call->callParameters->data(callSite->call->callParameters, listItem);
 
2448
 
 
2449
                                /* Create a new second profiler Parameter */
 
2450
                                secondProfilerParameter = newSpecializerSecondProfileParameter(specializer);
 
2451
                                secondProfilerParameter->init(secondProfilerParameter, parameter, profiler->blockSize, expression->position, expression->action == SPECIALIZER_ACTION_STATIC_LENGTH);
 
2452
 
 
2453
                                /* Ass the new profiler parameter to parameters list */
 
2454
                                profiler->parameters->append(profiler->parameters, secondProfilerParameter);
 
2455
 
 
2456
                                /* Change the parameter block size */
 
2457
                                if(!secondProfilerParameter->isConstant(secondProfilerParameter)){
 
2458
                                        #ifdef PRINTDEBUG
 
2459
                                        if(secondProfilerParameter->isVector(secondProfilerParameter)) PDEBUG("[VECTOR], ");
 
2460
                                        else PDEBUG("[VARIABLE], ");
 
2461
                                        #endif
 
2462
                                        profiler->blockSize += secondProfilerParameter->getParameterSize(secondProfilerParameter);
 
2463
                                } else {
 
2464
                                        PDEBUG("[CONSTANT], ");
 
2465
                                }
 
2466
 
 
2467
                                /* Set the parameter as already required */
 
2468
                                requiredParameters[expression->position] = JITTRUE;
 
2469
                        } else {
 
2470
                                PDEBUG("{Skip %u}, ", expression->position);
 
2471
                        }
 
2472
 
 
2473
                        /* Go to next subexpression */
 
2474
                        expression = expression->next;
 
2475
                }while(expression != NULL);
 
2476
        }
 
2477
        PDEBUG("\n");
 
2478
 
 
2479
        /* Free memory no long used */
 
2480
        freeFunction(requiredParameters);
 
2481
 
 
2482
        /* Calculate the threshold value */
 
2483
        if(profiler->blockSize > 0) {
 
2484
                profiler->threshold = callSite->hints->secondProfilerMemorySize / profiler->blockSize;
 
2485
        } else {
 
2486
                profiler->threshold = 0;
 
2487
        }
 
2488
 
 
2489
        /* Return                       */
 
2490
        return;
 
2491
}
 
2492
 
 
2493
void specializer_method_callSite_secondProfiler_print(specializer_method_callSite_secondProfiler_t* profiler, FILE* out){
 
2494
        /* Variables */
 
2495
        specializer_callSite_secondProfiler_param_t* parameter; /* Parameter to clean */
 
2496
        XanListItem* item;
 
2497
        JITUINT32 index;
 
2498
 
 
2499
        /* Assertions */
 
2500
        assert(profiler != NULL);
 
2501
        assert(out != NULL);
 
2502
 
 
2503
        /* Print informations about the profile data */
 
2504
        fprintf(out, "\t\t(2nd) Counter Value : %u\n", profiler->getCounterValue(profiler));
 
2505
        fprintf(out, "\t\t(2nd) Counter Pointer : %p\n", profiler->getCounterPointer(profiler));
 
2506
        fprintf(out, "\t\t(2nd) Threshold Reached Values : %u\n", profiler->thresholdReached);
 
2507
        fprintf(out, "\t\t(2nd) Threshold Reached Pointer : %p\n", &(profiler->thresholdReached));
 
2508
        fprintf(out, "\t\t(2nd) Threshold Reached : %s\n", profiler->thresholdReached?"TRUE":"FALSE");
 
2509
        fprintf(out, "\t\t(2nd) Threshold : %u\n", profiler->threshold);
 
2510
        fprintf(out, "\t\t(2nd) Block size : %u\n", profiler->blockSize);
 
2511
        fprintf(out, "\t\t(2nd) Parameters Number : %u\n", profiler->parameters->length(profiler->parameters));
 
2512
 
 
2513
        /* Print each parameter in the list */
 
2514
        for(index=0;index< profiler->parameters->length(profiler->parameters); index++){
 
2515
                fprintf(out, "\t\t\t%u) ", index+1);
 
2516
                item = profiler->parameters->getElementFromPositionNumber(profiler->parameters, index);
 
2517
                parameter = (specializer_callSite_secondProfiler_param_t*) profiler->parameters->data(profiler->parameters, item);
 
2518
                parameter->print(parameter, out);
 
2519
                fprintf(out, "\n");
 
2520
        }
 
2521
 
 
2522
}
 
2523
void specializer_method_callSite_secondProfiler_clean(specializer_method_callSite_secondProfiler_t* profiler, ir_specializer_t* specializer){
 
2524
        /* Variables */
 
2525
        specializer_callSite_secondProfiler_param_t* parameter; /* Parameter to clean */
 
2526
        XanListItem* item;
 
2527
        JITUINT32 index;
 
2528
 
 
2529
        /* Assertions */
 
2530
        assert(profiler != NULL);
 
2531
        assert(specializer != NULL);
 
2532
 
 
2533
        /* Free memory space for parameters informations store */
 
2534
        freeFunction(profiler->memory);
 
2535
 
 
2536
        /* Clean each parameter in the list */
 
2537
        for(index=0;index< profiler->parameters->length(profiler->parameters); index++){
 
2538
                item = profiler->parameters->getElementFromPositionNumber(profiler->parameters, index);
 
2539
                parameter = (specializer_callSite_secondProfiler_param_t*) profiler->parameters->data(profiler->parameters, item);
 
2540
                parameter->clean(parameter, specializer);
 
2541
        }
 
2542
 
 
2543
        /* Destroy the parameters list */
 
2544
        profiler->parameters->destroyList(profiler->parameters);
 
2545
 
 
2546
        /* Free profiler space */
 
2547
        freeFunction(profiler);
 
2548
}
 
2549
JITUINT32* specializer_method_callSite_secondProfiler_getCounterPointer(specializer_method_callSite_secondProfiler_t* profiler){
 
2550
        /* Assertions */
 
2551
        assert(profiler != NULL);
 
2552
 
 
2553
        /* Return the required value */
 
2554
        return &(profiler->counter);
 
2555
}
 
2556
JITUINT32 specializer_method_callSite_secondProfiler_getCounterValue(specializer_method_callSite_secondProfiler_t* profiler){
 
2557
        /* Assertions */
 
2558
        assert(profiler != NULL);
 
2559
 
 
2560
        /* Return the required value */
 
2561
        return profiler->counter;
 
2562
}
 
2563
JITUINT32* specializer_method_callSite_secondProfiler_getThresholdReachedPointer(specializer_method_callSite_secondProfiler_t* profiler){
 
2564
        /* Assertions */
 
2565
        assert(profiler != NULL);
 
2566
 
 
2567
        /* Return the required value */
 
2568
        return &(profiler->thresholdReached);
 
2569
}
 
2570
JITUINT32 specializer_method_callSite_secondProfiler_isThresholdReached(specializer_method_callSite_secondProfiler_t* profiler){
 
2571
        /* Assertions */
 
2572
        assert(profiler != NULL);
 
2573
 
 
2574
        /* Return the required value */
 
2575
        return profiler->thresholdReached;
 
2576
}
 
2577
JITUINT32 specializer_method_callSite_secondProfiler_getThreshold(specializer_method_callSite_secondProfiler_t* profiler){
 
2578
        /* Assertions */
 
2579
        assert(profiler != NULL);
 
2580
 
 
2581
        /* Return the required value */
 
2582
        return profiler->threshold;
 
2583
}
 
2584
JITUINT32 specializer_method_callSite_secondProfiler_getBlockSize(specializer_method_callSite_secondProfiler_t* profiler){
 
2585
        /* Assertions */
 
2586
        assert(profiler != NULL);
 
2587
 
 
2588
        /* Return the required value */
 
2589
        return profiler->blockSize;
 
2590
}
 
2591
XanList* specializer_method_callSite_secondProfiler_getStaticExpressions(specializer_method_callSite_secondProfiler_t* profiler, ir_specializer_t* specializer){
 
2592
        /* Variables */
 
2593
        specializer_method_callSite_t* callSite = NULL; /* The call site */
 
2594
        XanList* parametersValuesAndFrequency = NULL;   /* Vector for parameter frequency values */
 
2595
        XanList* staticExpressions = NULL; /* Vector for static expression */
 
2596
        JITUINT32 index;        /* Generic index */
 
2597
        specializer_callSite_secondProfiler_param_t* parameter; /* The specializable parameter */
 
2598
        specializer_callSite_secondProfiler_param_values_t* parameterValues;    /* Values for a parameter */
 
2599
        XanListItem* item;
 
2600
 
 
2601
        /* Assertions */
 
2602
        assert(profiler != NULL);
 
2603
        assert(specializer != NULL);
 
2604
 
 
2605
        /* Load the call site */
 
2606
        callSite = (specializer_method_callSite_t*) profiler->callSiteContext;
 
2607
        assert(callSite != NULL);
 
2608
 
 
2609
 
 
2610
        /* Print the memory content */
 
2611
#ifdef PRINTDEBUG
 
2612
        PDEBUG("SPECIALIZER : Memory Content: \n");
 
2613
        printVoidVector(profiler->memory, callSite->hints->secondProfilerMemorySize, stderr, 8, 4);
 
2614
        PDEBUG("\n");
 
2615
#endif
 
2616
 
 
2617
        /* Create a new parameters with values list */
 
2618
        parametersValuesAndFrequency = xanListNew(allocFunction, freeFunction, NULL);
 
2619
 
 
2620
        /* Compute for each parameter the values ober the threshold */
 
2621
        for(index = 0; index < profiler->parameters->length(profiler->parameters); index++){
 
2622
                /* Read the parameter */
 
2623
                item = profiler->parameters->getElementFromPositionNumber(profiler->parameters, index);
 
2624
                parameter = (specializer_callSite_secondProfiler_param_t*) profiler->parameters->data(profiler->parameters, item);
 
2625
 
 
2626
                parameterValues = specializer_computeValuesWithFrequency(profiler, parameter, specializer);
 
2627
                if(parameterValues != NULL)
 
2628
                        parametersValuesAndFrequency->append(parametersValuesAndFrequency, parameterValues);
 
2629
        }
 
2630
 
 
2631
        /* Detect the static expression */
 
2632
        staticExpressions = specializer_makeStaticExpressions(callSite->hints, parametersValuesAndFrequency, specializer);
 
2633
 
 
2634
        /* Free all elements inside the list */
 
2635
        for(index = 0; index < parametersValuesAndFrequency->length(parametersValuesAndFrequency); index++){
 
2636
                /* Read the parameterValues */
 
2637
                item = parametersValuesAndFrequency->getElementFromPositionNumber(parametersValuesAndFrequency, index);
 
2638
                parameterValues = (specializer_callSite_secondProfiler_param_values_t*) parametersValuesAndFrequency->data(parametersValuesAndFrequency, item);
 
2639
 
 
2640
                /* Clean the parameter values */
 
2641
                parameterValues->clean(parameterValues, specializer);
 
2642
        }
 
2643
 
 
2644
        /* Destroy the parameters values and frequency list */
 
2645
        parametersValuesAndFrequency->destroyList(parametersValuesAndFrequency);
 
2646
 
 
2647
        /* If there are no static expression destroy the list... so much work for nothing  */
 
2648
        if(staticExpressions->length(staticExpressions) == 0){
 
2649
                staticExpressions->destroyList(staticExpressions);
 
2650
                staticExpressions = NULL;
 
2651
        }
 
2652
 
 
2653
        /* Return the active expression */
 
2654
        return staticExpressions;
 
2655
}
 
2656
 
 
2657
/* ----------------------------------------- specializer_valueWithFrequency_t -----------------------------------------*/
 
2658
specializer_valueWithFrequency_t* newSpecializerValueWithFrequency(ir_specializer_t* specializer){
 
2659
        /* Variables */
 
2660
        specializer_valueWithFrequency_t* valueWithFrequency;
 
2661
 
 
2662
        /* Assertions */
 
2663
        assert(specializer != NULL);
 
2664
 
 
2665
        /* Allocate space */
 
2666
        valueWithFrequency = (specializer_valueWithFrequency_t*) allocFunction((size_t)sizeof(specializer_valueWithFrequency_t));
 
2667
        assert(valueWithFrequency != NULL);
 
2668
 
 
2669
        /* Initialize calls */
 
2670
        valueWithFrequency->init = specializer_valueWithFrequency_init;
 
2671
        valueWithFrequency->print = specializer_valueWithFrequency_print;
 
2672
        valueWithFrequency->clean = specializer_valueWithFrequency_clean;
 
2673
 
 
2674
        /* Return the value with frequency */
 
2675
        return valueWithFrequency;
 
2676
}
 
2677
void specializer_valueWithFrequency_init(specializer_valueWithFrequency_t* valueWithFrequency, specializer_multiValueContainer valueContainer, JITFLOAT32 frequency){
 
2678
        /* Assertions */
 
2679
        assert(valueWithFrequency != NULL);
 
2680
 
 
2681
        /* Assign Values */
 
2682
        valueWithFrequency->valueContainer = valueContainer;
 
2683
        valueWithFrequency->frequency = frequency;
 
2684
}
 
2685
void specializer_valueWithFrequency_print(specializer_valueWithFrequency_t* valueWithFrequency, FILE* out){
 
2686
        /* Assertions */
 
2687
        assert(valueWithFrequency != NULL);
 
2688
        assert(out != NULL);
 
2689
 
 
2690
        /* Print the value with the frequency */
 
2691
        printMultiValueContainer(valueWithFrequency->valueContainer, out);
 
2692
        fprintf(out," [%5.2f%%]", valueWithFrequency->frequency*100);
 
2693
}
 
2694
void specializer_valueWithFrequency_clean(specializer_valueWithFrequency_t* valueWithFrequency, ir_specializer_t* specializer){
 
2695
        /* Assertions */
 
2696
        assert(valueWithFrequency != NULL);
 
2697
        assert(specializer != NULL);
 
2698
 
 
2699
        /* Just clean itself */
 
2700
        freeFunction(valueWithFrequency);
 
2701
}
 
2702
 
 
2703
/* ----------------------------------------- specializer_callSite_secondProfiler_param_values_t -----------------------------------------*/
 
2704
specializer_callSite_secondProfiler_param_values_t* newSpecializerValuesForParamPosition(ir_specializer_t* specializer){
 
2705
        /* Variables */
 
2706
        specializer_callSite_secondProfiler_param_values_t* values;
 
2707
 
 
2708
        /* Assertions */
 
2709
        assert(specializer != NULL);
 
2710
 
 
2711
        /* Allocate Space */
 
2712
        values = (specializer_callSite_secondProfiler_param_values_t*) allocFunction((size_t)sizeof(specializer_callSite_secondProfiler_param_values_t));
 
2713
        assert(values != NULL);
 
2714
 
 
2715
        /* Assign calls */
 
2716
        values->init = specializer_callSite_secondProfiler_param_values_init;
 
2717
        values->print = specializer_callSite_secondProfiler_param_values_print;
 
2718
        values->clean = specializer_callSite_secondProfiler_param_values_clean;
 
2719
        values->addValue = specializer_callSite_secondProfiler_param_values_addValue;
 
2720
        values->getValue = specializer_callSite_secondProfiler_param_values_getValue;
 
2721
        values->getValuesNumber = specializer_callSite_secondProfiler_param_values_getValuesNumber;
 
2722
 
 
2723
        /* Return the variable*/
 
2724
        return values;
 
2725
}
 
2726
void specializer_callSite_secondProfiler_param_values_init(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, JITUINT32 position, ir_specializer_t* specializer){
 
2727
        /* Assertions */
 
2728
        assert(valuesForPosition != NULL);
 
2729
        assert(specializer != NULL);
 
2730
 
 
2731
        /* Initialize the position */
 
2732
        valuesForPosition->position = position;
 
2733
 
 
2734
        /* Initialize the vector of values */
 
2735
        valuesForPosition->values = xanListNew(allocFunction, freeFunction, NULL);
 
2736
        assert(valuesForPosition->values != NULL);
 
2737
}
 
2738
void specializer_callSite_secondProfiler_param_values_print(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, FILE* out){
 
2739
        /* Variables */
 
2740
        specializer_valueWithFrequency_t* valueWithFrequency;
 
2741
        JITUINT32 index;
 
2742
 
 
2743
        /* Assertions */
 
2744
        assert(valuesForPosition != NULL);
 
2745
 
 
2746
        /* Print the position */
 
2747
        fprintf(out, "%u : ", valuesForPosition->position);
 
2748
        /* Print the values */
 
2749
        if(valuesForPosition->getValuesNumber(valuesForPosition) == 0)
 
2750
                fprintf(out, "//");
 
2751
        else
 
2752
                for(index = 0; index < valuesForPosition->getValuesNumber(valuesForPosition); index++){
 
2753
                        valueWithFrequency = valuesForPosition->getValue(valuesForPosition, index);
 
2754
                        valueWithFrequency->print(valueWithFrequency, out);
 
2755
                        if(index != (valuesForPosition->getValuesNumber(valuesForPosition)-1))
 
2756
                                fprintf(out, ", ");
 
2757
                }
 
2758
}
 
2759
void specializer_callSite_secondProfiler_param_values_clean(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, ir_specializer_t* specializer){
 
2760
        /* Variables */
 
2761
        specializer_valueWithFrequency_t* valueWithFrequency;
 
2762
        JITUINT32 index;
 
2763
 
 
2764
        /* Assertions */
 
2765
        assert(valuesForPosition != NULL);
 
2766
 
 
2767
        /* Clean the single values */
 
2768
        for(index = 0; index < valuesForPosition->getValuesNumber(valuesForPosition); index++){
 
2769
                valueWithFrequency = valuesForPosition->getValue(valuesForPosition, index);
 
2770
                valueWithFrequency->clean(valueWithFrequency, specializer);
 
2771
        }
 
2772
 
 
2773
        /* Destroy the values list */
 
2774
        valuesForPosition->values->destroyList(valuesForPosition->values);
 
2775
 
 
2776
        /* Destroy itself */
 
2777
        freeFunction(valuesForPosition);
 
2778
}
 
2779
void specializer_callSite_secondProfiler_param_values_addValue(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, specializer_valueWithFrequency_t* valueWithFrequency){
 
2780
        /* Assertions */
 
2781
        assert(valuesForPosition != NULL);
 
2782
        assert(valueWithFrequency != NULL);
 
2783
 
 
2784
        /* Inject the value */
 
2785
        valuesForPosition->values->append(valuesForPosition->values, valueWithFrequency);
 
2786
}
 
2787
specializer_valueWithFrequency_t* specializer_callSite_secondProfiler_param_values_getValue(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, JITUINT32 index){
 
2788
        /* Variable */
 
2789
        XanListItem* item;
 
2790
        specializer_valueWithFrequency_t* valueWithFrequency;
 
2791
 
 
2792
        /* Assertions */
 
2793
        assert(valuesForPosition != NULL);
 
2794
        assert(index < specializer_callSite_secondProfiler_param_values_getValuesNumber(valuesForPosition));
 
2795
 
 
2796
        /* Load the item */
 
2797
        item = valuesForPosition->values->getElementFromPositionNumber(valuesForPosition->values, index);
 
2798
        assert(item != NULL);
 
2799
 
 
2800
        /* Load the element */
 
2801
        valueWithFrequency = (specializer_valueWithFrequency_t*) valuesForPosition->values->data(valuesForPosition->values, item);
 
2802
        assert(valueWithFrequency != NULL);
 
2803
 
 
2804
        /* Return the value */
 
2805
        return valueWithFrequency;
 
2806
}
 
2807
JITUINT32 specializer_callSite_secondProfiler_param_values_getValuesNumber(specializer_callSite_secondProfiler_param_values_t* valuesForPosition){
 
2808
        /* Assertions */
 
2809
        assert(valuesForPosition != NULL);
 
2810
 
 
2811
        /* return the length of the values array */
 
2812
        return valuesForPosition->values->length(valuesForPosition->values);
 
2813
}
 
2814
 
 
2815
/* ----------------------------------------- specializer_staticExpression_hint_t -----------------------------------------*/
 
2816
specializer_staticExpression_hint_t* newSpecializerStaticExpression(ir_specializer_t* specializer){
 
2817
        /* Variables */
 
2818
        specializer_staticExpression_hint_t* staticExpression = NULL;
 
2819
 
 
2820
        /* Assertions */
 
2821
        assert(specializer != NULL);
 
2822
 
 
2823
        /* Allocate space */
 
2824
        staticExpression = (specializer_staticExpression_hint_t*) allocFunction((size_t)sizeof(specializer_staticExpression_hint_t));
 
2825
        assert(staticExpression != NULL);
 
2826
 
 
2827
        /* Assign calls */
 
2828
        staticExpression->init = specializer_staticExpression_hint_init;
 
2829
        staticExpression->print = specializer_staticExpression_hint_print;
 
2830
        staticExpression->clean = specializer_staticExpression_hint_clean;
 
2831
        staticExpression->equals = specializer_staticExpression_hint_equals;
 
2832
 
 
2833
        /* Return the value */
 
2834
        return staticExpression;
 
2835
}
 
2836
void specializer_staticExpression_hint_init(specializer_staticExpression_hint_t* staticExpression, specializer_expression_hint_t *expression, specializer_multiValueContainer *values){
 
2837
        /* Assertions */
 
2838
        assert(staticExpression != NULL);
 
2839
        assert(expression != NULL);
 
2840
        assert(values != NULL);
 
2841
 
 
2842
        /* Assign the values to variables */
 
2843
        staticExpression->expression = expression;
 
2844
        staticExpression->values = values;
 
2845
}
 
2846
void specializer_staticExpression_hint_print(specializer_staticExpression_hint_t* staticExpression, FILE* out){
 
2847
        /* Variables */
 
2848
        JITUINT32 index;
 
2849
        JITUINT32 depth;
 
2850
        specializer_expression_hint_t *expression;
 
2851
 
 
2852
        /* Assertions */
 
2853
        assert(staticExpression != NULL);
 
2854
        assert(out != NULL);
 
2855
 
 
2856
        staticExpression->expression->printChain(staticExpression->expression, out);
 
2857
        depth = staticExpression->expression->depth;
 
2858
        expression = staticExpression->expression;
 
2859
        fprintf(out, "; Values = {");
 
2860
        for(index = 0; index < depth; index++){
 
2861
                fprintf(out, "#%u = ", expression->position+1);
 
2862
                assert(expression != NULL);
 
2863
                printMultiValueContainer(staticExpression->values[index], out);
 
2864
                expression = expression->next;
 
2865
                if(index != (depth-1))
 
2866
                        fprintf(out, ", ");
 
2867
        }
 
2868
        fprintf(out, "}");
 
2869
}
 
2870
void specializer_staticExpression_hint_clean(specializer_staticExpression_hint_t* staticExpression, ir_specializer_t* specializer){
 
2871
        /* Assertions */
 
2872
        assert(staticExpression != NULL);
 
2873
        assert(specializer != NULL);
 
2874
 
 
2875
        /* Clean the values */
 
2876
        freeFunction(staticExpression->values);
 
2877
 
 
2878
        /* Clean itself */
 
2879
        freeFunction(staticExpression);
 
2880
}
 
2881
JITBOOLEAN specializer_staticExpression_hint_equals(specializer_staticExpression_hint_t* staticExpression, specializer_staticExpression_hint_t* otherExpression){
 
2882
        /* Variables */
 
2883
        JITUINT32 index;
 
2884
        specializer_expression_hint_t *expression, *compareExpression;
 
2885
 
 
2886
        /* Assertions */
 
2887
        assert(staticExpression != NULL);
 
2888
        assert(otherExpression != NULL);
 
2889
 
 
2890
#ifdef PRINTDEBUG
 
2891
        PDEBUG("SPECIALIZER : staticExpression : equals : Compare \"");
 
2892
        staticExpression->print(staticExpression, stderr);
 
2893
        PDEBUG("\" with \"");
 
2894
        otherExpression->print(otherExpression, stderr);
 
2895
        PDEBUG("\"\n");
 
2896
#endif
 
2897
 
 
2898
        /* Check the values are equals */
 
2899
        expression = staticExpression->expression;
 
2900
        compareExpression = otherExpression->expression;
 
2901
        assert(expression != NULL);
 
2902
        assert(compareExpression != NULL);
 
2903
 
 
2904
        /* Check the expression depth */
 
2905
        if(staticExpression->expression->depth != otherExpression->expression->depth)
 
2906
                return JITFALSE;
 
2907
 
 
2908
        /* Search the expression */
 
2909
        for(index = 0; index < staticExpression->expression->depth; index++){
 
2910
                if(expression->position != compareExpression->position)
 
2911
                        return JITFALSE;
 
2912
                if(staticExpression->values[index].type != otherExpression->values[index].type)
 
2913
                        return JITFALSE;
 
2914
                if(specializer_multiValueContainer_compare(&staticExpression->values[index], &otherExpression->values[index]) != 0)
 
2915
                        return JITFALSE;
 
2916
                /* Go to next expression */
 
2917
                expression = expression->next;
 
2918
                compareExpression = compareExpression->next;
 
2919
        }
 
2920
 
 
2921
        return JITTRUE;
 
2922
}
 
2923
 
 
2924
/* ----------------------------------------- specializer_method_callSite_dispatcher_t -----------------------------------------*/
 
2925
specializer_method_callSite_dispatcher_t* newSpecializerDispatcher(ir_specializer_t* specializer){
 
2926
        /* Variables */
 
2927
        specializer_method_callSite_dispatcher_t* dispatcher;
 
2928
 
 
2929
        /* Assertions*/
 
2930
        assert(specializer != NULL);
 
2931
 
 
2932
        /* Allocate space */
 
2933
        dispatcher = (specializer_method_callSite_dispatcher_t*) allocFunction((size_t)sizeof(specializer_method_callSite_dispatcher_t));
 
2934
        assert(dispatcher != NULL);
 
2935
 
 
2936
        /* Initialize calls */
 
2937
        dispatcher->init = specializer_method_callSite_dispatcher_init;
 
2938
        dispatcher->print = specializer_method_callSite_dispatcher_print;
 
2939
        dispatcher->clean = specializer_method_callSite_dispatcher_clean;
 
2940
        dispatcher->getCounterPointer = specializer_method_callSite_dispatcher_getCounterPointer;
 
2941
        dispatcher->getCounterValue = specializer_method_callSite_dispatcher_getCounterValue;
 
2942
        dispatcher->inject = specializer_method_callSite_dispatcher_inject;
 
2943
        dispatcher->remove = specializer_method_callSite_dispatcher_remove;
 
2944
 
 
2945
        /* Return the dispatcher */
 
2946
        return dispatcher;
 
2947
 
 
2948
}
 
2949
void specializer_method_callSite_dispatcher_init(specializer_method_callSite_dispatcher_t* dispatcher, void *callSiteContext){
 
2950
        /* Assertions */
 
2951
        assert(dispatcher != NULL);
 
2952
        assert(callSiteContext != NULL);
 
2953
 
 
2954
        /* Assign variables */
 
2955
        dispatcher->callSiteContext = callSiteContext;
 
2956
 
 
2957
        /* Initialize variables */
 
2958
        dispatcher->counter = 0;
 
2959
        dispatcher->thresholdReached = JITFALSE;
 
2960
}
 
2961
void specializer_method_callSite_dispatcher_print(specializer_method_callSite_dispatcher_t* dispatcher, FILE* out){
 
2962
        /* Assertions */
 
2963
        assert(out != NULL);
 
2964
        assert(dispatcher != NULL);
 
2965
 
 
2966
        /* Print the value of the counter*/
 
2967
        fprintf(out, "\t\tDispatcher counter : %d\n", dispatcher->getCounterValue(dispatcher));
 
2968
        fprintf(out, "\t\tDispatcher Threshold Reached counter : %s\n", dispatcher->thresholdReached?"TRUE":"FALSE");
 
2969
}
 
2970
void specializer_method_callSite_dispatcher_clean(specializer_method_callSite_dispatcher_t* dispatcher, ir_specializer_t* specializer){
 
2971
        /* Assertions */
 
2972
        assert(dispatcher != NULL);
 
2973
        assert(specializer != NULL);
 
2974
 
 
2975
        /* From the caller call site list remove the UNSPECIALIZABLE CALL SITES */
 
2976
        //TODO:
 
2977
 
 
2978
        /* Just clean itself */
 
2979
        freeFunction(dispatcher);
 
2980
}
 
2981
JITINT32* specializer_method_callSite_dispatcher_getCounterPointer(specializer_method_callSite_dispatcher_t* dispatcher){
 
2982
        /* Assertions */
 
2983
        assert(dispatcher != NULL);
 
2984
 
 
2985
        /* Return the counter pointer */
 
2986
        return &(dispatcher->counter);
 
2987
}
 
2988
JITINT32 specializer_method_callSite_dispatcher_getCounterValue(specializer_method_callSite_dispatcher_t* dispatcher){
 
2989
        /* Assertions */
 
2990
        assert(dispatcher != NULL);
 
2991
 
 
2992
        /* Return the counter value */
 
2993
        return dispatcher->counter;
 
2994
}
 
2995
 
 
2996
/* ----------------------------------------- specializer_specialized_method_wrapper_t -----------------------------------------*/
 
2997
specializer_specialized_method_wrapper_t* getSpecializerSpecializedMethodWrapper(ir_specializer_t* specializer){
 
2998
        /* Variables */
 
2999
        specializer_specialized_method_wrapper_t* specializedMethodWrapper = NULL;
 
3000
 
 
3001
        /* Assertions */
 
3002
        assert(specializer != NULL);
 
3003
 
 
3004
        /* Allocate space */
 
3005
        specializedMethodWrapper = (specializer_specialized_method_wrapper_t*) allocFunction((size_t)sizeof(specializer_specialized_method_wrapper_t));
 
3006
        assert(specializedMethodWrapper != NULL);
 
3007
 
 
3008
        /* Initialize calls */
 
3009
        specializedMethodWrapper->init          = specializer_specialized_method_wrapper_init;
 
3010
        specializedMethodWrapper->print         = specializer_specialized_method_wrapper_print;
 
3011
        specializedMethodWrapper->clean         = specializer_specialized_method_wrapper_clean;
 
3012
        specializedMethodWrapper->equals        = specializer_specialized_method_wrapper_equals;
 
3013
 
 
3014
        /* Return the method */
 
3015
        return specializedMethodWrapper;
 
3016
}
 
3017
 
 
3018
void specializer_specialized_method_wrapper_init(specializer_specialized_method_wrapper_t* specializedMethod,
 
3019
                                                specializer_staticExpression_hint_t *staticExpression,
 
3020
                                                specializer_method_wrapper_t *originalMethodWrapper,
 
3021
                                                specializer_method_wrapper_t *specializedMethodWrapper){
 
3022
        /* Assertions */
 
3023
        assert(specializedMethod != NULL);
 
3024
        assert(specializedMethodWrapper != NULL);
 
3025
        assert(staticExpression != NULL);
 
3026
        assert(originalMethodWrapper != NULL);
 
3027
 
 
3028
        /* Assign Variables */
 
3029
        specializedMethod->staticExpression             = staticExpression;
 
3030
        specializedMethod->originalMethodWrapper        = originalMethodWrapper;
 
3031
        specializedMethod->specializedMethodWrapper     = specializedMethodWrapper;
 
3032
}
 
3033
 
 
3034
void specializer_specialized_method_wrapper_print (specializer_specialized_method_wrapper_t* specializedMethod, FILE* out, ir_specializer_t *specializer){
 
3035
        ir_method_t     *method;
 
3036
 
 
3037
        /* Assertions                   */
 
3038
        assert(specializedMethod != NULL);
 
3039
        assert(out != NULL);
 
3040
        assert(specializer != NULL);
 
3041
 
 
3042
        /* Fetch the method             */
 
3043
        method  = specializedMethod->specializedMethodWrapper->getIRMethod(specializedMethod->specializedMethodWrapper);
 
3044
        assert(method != NULL);
 
3045
 
 
3046
        /* Print the original method    */
 
3047
        fprintf(out, "\tOriginal Method: (%p) %s [%s]\n", specializedMethod->originalMethodWrapper->ilMethod,
 
3048
                        method->getCompleteName(method), 
 
3049
                        method->getSignatureInString(method, specializer->irlib->typeChecker));
 
3050
 
 
3051
        /* Print the specialized method */
 
3052
        fprintf(out, "\tSpecialized Method: (%p) %s [%s]\n", specializedMethod->specializedMethodWrapper->ilMethod,
 
3053
                        method->getCompleteName(method), 
 
3054
                        method->getSignatureInString(method, specializer->irlib->typeChecker));
 
3055
 
 
3056
        /* Print the static expression */
 
3057
        fprintf(out, "\tStatic Expression : ");
 
3058
        specializedMethod->staticExpression->print(specializedMethod->staticExpression, out);
 
3059
        fprintf(out, "\n");
 
3060
}
 
3061
 
 
3062
void specializer_specialized_method_wrapper_clean(specializer_specialized_method_wrapper_t* specializedMethod, ir_specializer_t* specializer){
 
3063
        /* Assertions */
 
3064
        assert(specializedMethod != NULL);
 
3065
        assert(specializer != NULL);
 
3066
 
 
3067
        /* Clean the static expression */
 
3068
        specializedMethod->staticExpression->clean(specializedMethod->staticExpression, specializer);
 
3069
 
 
3070
        /* Clean it self*/
 
3071
        freeFunction(specializedMethod);
 
3072
}
 
3073
JITBOOLEAN specializer_specialized_method_wrapper_equals(specializer_specialized_method_wrapper_t* specializedMethod,
 
3074
                                                        specializer_method_wrapper_t *originalMethodWrapper,
 
3075
                                                        specializer_staticExpression_hint_t *staticExpression){
 
3076
        /* Assertions */
 
3077
        assert(specializedMethod != NULL);
 
3078
        assert(originalMethodWrapper != NULL);
 
3079
        assert(staticExpression != NULL);
 
3080
 
 
3081
        /* Check the original wrapper */
 
3082
        if(specializedMethod->originalMethodWrapper == originalMethodWrapper)
 
3083
                return JITFALSE;
 
3084
 
 
3085
        /* Check the equity of the staticExpression */
 
3086
        return specializedMethod->staticExpression->equals(specializedMethod->staticExpression,staticExpression);
 
3087
}
 
3088
 
 
3089
/* ----------------------------------------- specializer_method_callSite_type_dispatcher_t -----------------------------------------*/
 
3090
specializer_method_callSite_type_dispatcher_t* newSpecializerTypeDispatcher(ir_specializer_t* specializer){
 
3091
        /* Variables */
 
3092
        specializer_method_callSite_type_dispatcher_t* typeDispatcher;
 
3093
 
 
3094
        /* Assertions */
 
3095
        assert(specializer != NULL);
 
3096
 
 
3097
        /* Allocate space */
 
3098
        typeDispatcher = (specializer_method_callSite_type_dispatcher_t*) allocFunction((size_t)sizeof(specializer_method_callSite_type_dispatcher_t));
 
3099
        assert(typeDispatcher != NULL);
 
3100
 
 
3101
        /* Assign methods */
 
3102
        typeDispatcher->init = specializer_method_callSite_type_dispatcher_init;
 
3103
        typeDispatcher->print = specializer_method_callSite_type_dispatcher_print;
 
3104
        typeDispatcher->clean = specializer_method_callSite_type_dispatcher_clean;
 
3105
        typeDispatcher->inject = specializer_method_callSite_type_dispatcher_inject;
 
3106
        typeDispatcher->remove = specializer_method_callSite_type_dispatcher_remove;
 
3107
        typeDispatcher->getCounterPointer = specializer_method_callSite_type_dispatcher_getCounterPointer;
 
3108
        typeDispatcher->getCounterValue = specializer_method_callSite_type_dispatcher_getCounterValue;
 
3109
 
 
3110
        /* Return the dispatcher */
 
3111
        return typeDispatcher;
 
3112
}
 
3113
void specializer_method_callSite_type_dispatcher_init(specializer_method_callSite_type_dispatcher_t* dispatcher, void *callSiteContext){
 
3114
        /* Assertions */
 
3115
        assert(dispatcher != NULL);
 
3116
        assert(callSiteContext != NULL);
 
3117
        assert(((specializer_method_callSite_t*)callSiteContext)->call->type == IRVCALL);
 
3118
 
 
3119
        /* Assign the variable */
 
3120
        dispatcher->callSiteContext = callSiteContext;
 
3121
 
 
3122
        /* Initialize the counter */
 
3123
        dispatcher->counter = 0;
 
3124
        dispatcher->thresholdReached = JITFALSE;
 
3125
 
 
3126
}
 
3127
void specializer_method_callSite_type_dispatcher_print(specializer_method_callSite_type_dispatcher_t* dispatcher, FILE* out){
 
3128
        /* Assertions */
 
3129
        assert(out != NULL);
 
3130
        assert(dispatcher != NULL);
 
3131
 
 
3132
        /* Print the value of the counter*/
 
3133
        fprintf(out, "\t\tType Dispatcher counter : %d\n", dispatcher->getCounterValue(dispatcher));
 
3134
        fprintf(out, "\t\tType Dispatcher Threshold Reached counter : %s\n", dispatcher->thresholdReached?"TRUE":"FALSE");
 
3135
}
 
3136
void specializer_method_callSite_type_dispatcher_clean(specializer_method_callSite_type_dispatcher_t* dispatcher, ir_specializer_t* specializer){
 
3137
        /* Assertions */
 
3138
        assert(dispatcher != NULL);
 
3139
        assert(specializer != NULL);
 
3140
 
 
3141
        /* From the caller call site list remove the generated new direct call sites */
 
3142
        //TODO:
 
3143
 
 
3144
        /* Just clean itself */
 
3145
        freeFunction(dispatcher);
 
3146
}
 
3147
JITINT32* specializer_method_callSite_type_dispatcher_getCounterPointer(specializer_method_callSite_type_dispatcher_t* dispatcher){
 
3148
        /* Assertions */
 
3149
        assert(dispatcher != NULL);
 
3150
 
 
3151
        /* Return the counter pointer */
 
3152
        return &(dispatcher->counter);
 
3153
}
 
3154
JITINT32 specializer_method_callSite_type_dispatcher_getCounterValue(specializer_method_callSite_type_dispatcher_t* dispatcher){
 
3155
        /* Assertions */
 
3156
        assert(dispatcher != NULL);
 
3157
 
 
3158
        /* Return the counter value */
 
3159
        return dispatcher->counter;
 
3160
}
 
3161
 
 
3162
static inline void internal_action_to_second_or_dispatch_state (specializer_method_callSite_t* callSite, specializer_method_wrapper_t* callerWrapper, ir_specializer_t* specializer){
 
3163
        XanList         *staticExpressions;
 
3164
 
 
3165
        /* Assertions                           */
 
3166
        assert(callSite != NULL);
 
3167
 
 
3168
        /*
 
3169
         * NOTE: Don't clear here the first profiler!!!!
 
3170
         * It could be used by the execution thread even if changed the IR method!!
 
3171
         *
 
3172
         * So here we can just remove the first profiler
 
3173
         * */
 
3174
 
 
3175
        /* Remove the first profiler if necessary */
 
3176
        if(callSite->firstProfiler != NULL){
 
3177
                callSite->firstProfiler->remove(callSite->firstProfiler, callerWrapper);
 
3178
        }
 
3179
 
 
3180
        /* Create the second profiler */
 
3181
        if(callSite->secondProfiler == NULL) {
 
3182
                callSite->secondProfiler = newSpecializerSecondProfiler(specializer);
 
3183
                callSite->secondProfiler->init(callSite->secondProfiler, callSite, specializer);
 
3184
        } else {
 
3185
                callSite->secondProfiler->counter = 0;
 
3186
                callSite->secondProfiler->thresholdReached = JITFALSE;
 
3187
        }
 
3188
 
 
3189
        /* If there is something useful to do for the dispatcher */
 
3190
        if(callSite->secondProfiler->threshold > 0){
 
3191
 
 
3192
                /* Inject the second profiler   */
 
3193
                callSite->secondProfiler->inject(callSite->secondProfiler, callerWrapper, specializer);
 
3194
 
 
3195
                /* Change the status            */
 
3196
                callSite->status = SPECIALIZER_CALLSITE_STATUS_SECOND_PROFILER_INJECTED;
 
3197
 
 
3198
                /* Return                       */
 
3199
                return ;
 
3200
        }
 
3201
 
 
3202
        /* We can inject the dispatcher since all possible parameters are constants */
 
3203
 
 
3204
        /* Detect the static expressions */
 
3205
        staticExpressions = callSite->secondProfiler->getStaticExpressions(callSite->secondProfiler, specializer);
 
3206
 
 
3207
        /* If there are static expressions      */
 
3208
        if(staticExpressions != NULL){  
 
3209
 
 
3210
                /* Create the new dispatcher            */
 
3211
                if(callSite->dispatcher == NULL){
 
3212
                        callSite->dispatcher = newSpecializerDispatcher(specializer);
 
3213
                        callSite->dispatcher->init(callSite->dispatcher, callSite);
 
3214
                } else {
 
3215
                        callSite->dispatcher->counter           = 0;
 
3216
                        callSite->dispatcher->thresholdReached  = JITFALSE;
 
3217
                }
 
3218
 
 
3219
                /* Change the state */
 
3220
                callSite->status = SPECIALIZER_CALLSITE_STATUS_DISPATCHER_REQUEST;
 
3221
 
 
3222
                /* Inject the dispatcher */
 
3223
                callSite->dispatcher->inject(callSite->dispatcher, callerWrapper, staticExpressions, specializer);
 
3224
                //specializer->optimizer->callMethodOptimization(specializer->optimizer, callerWrapper->getIRMethod(callerWrapper), specializer->irlib, METHOD_PRINTER);
 
3225
 
 
3226
                /* Change the status */
 
3227
                callSite->status = SPECIALIZER_CALLSITE_STATUS_DISPATCHER_INJECTED;
 
3228
                
 
3229
                /* Return                       */
 
3230
                return ;
 
3231
        }
 
3232
 
 
3233
        /* Reinject the first profiler */
 
3234
        if(callSite->firstProfiler == NULL){
 
3235
                callSite->firstProfiler = newSpecializerFirstProfiler(specializer);
 
3236
                callSite->firstProfiler->init(callSite->firstProfiler, callSite, specializer);
 
3237
        } else { /* Just clean it*/
 
3238
                callSite->firstProfiler->counter = 0;
 
3239
                callSite->firstProfiler->thresholdReached = JITFALSE;
 
3240
        }
 
3241
 
 
3242
        /* Change the status */
 
3243
        callSite->status = SPECIALIZER_CALLSITE_STATUS_CLEAN;
 
3244
 
 
3245
        /* Inject the second profiler */
 
3246
        callSite->firstProfiler->inject(callSite->firstProfiler, callerWrapper, specializer);
 
3247
 
 
3248
        /* Change the status */
 
3249
        callSite->status = SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED;
 
3250
 
 
3251
        /* Return                       */
 
3252
        return ;
 
3253
}

Loggerhead 1.17 is a web-based interface for Bazaar branches