2
* Copyright (C) 2007, 2008 Campanoni Simone, Anelli Stefano
4
* iljit - This is a Just-in-time for the CIL language specified with the ECMA-335
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.
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.
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
20
/***************************************** HEADERS */
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>
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"
42
/***************************************** INTERFACES */
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);
53
void ir_specializer_loadHintsFromFile(ir_specializer_t* specializer, char* programName);
54
void ir_specializer_printHintsForMethod(ir_specializer_t *specializer, FILE* out);
56
void* ir_specializer_recompile_request_thread(void* parameters);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
190
/***************************************** IMPLEMENTATION */
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)){
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");
217
/* Assign variables */
218
specializer->arrayLengthOffset = arrayLengthOffset;
219
specializer->objectLayoutOffset = objectLayoutOffset;
221
/* Assign recompile function */
222
specializer->forceRecompile = forceRecompile;
223
specializer->compileToIR = compileToIR;
225
/* Assign the system */
226
specializer->system = system;
227
specializer->irlib = irlib;
228
specializer->optimizer = optimizer;
230
/* The system has not been shutted down */
231
specializer->shuttedDown = JITFALSE;
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;
241
/* Assign internal calls */
242
specializer->shutdown = ir_specializer_shutdown;
243
specializer->manageCallSitesBeforeCompile = ir_specializer_manageCallSitesBeforeCompile;
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);
251
/* Generate the recompile request pipe */
252
specializer->recompileRequestPipe = xanPipeNew(allocFunction, freeFunction);
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");
260
/* Load hints from file */
261
ir_specializer_loadHintsFromFile(specializer, programName);
262
PDEBUG("______________________________________________________________________________________________\n");
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 */
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);
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");
297
/* Variable Initialization */
298
irMethod = getIRMethod(ilMethod);
299
callerWrapper = NULL;
300
calleeWrapper = NULL;
301
callerCallSites = NULL;
304
/* Print the before any change on stdout */
306
fprintf(stdout, "{BEFORE} METHOD %s [%s]\n", getFullName(ilMethod),getSignature(ilMethod));
307
printIrMethod(irMethod, stdout, getFullName, getSignature);
308
fprintf(stdout, "END\n\n");
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));
317
/* For each instruction */
318
for(currentInstruction = irMethod->getNextInstruction(irMethod, NULL); currentInstruction != NULL; currentInstruction = irMethod->getNextInstruction(irMethod, currentInstruction)){
320
assert(currentInstruction != NULL);
322
/* Check if its a call instruction */
323
//if(currentInstruction->type == IRCALL || currentInstruction->type == IRVCALL){
324
if(currentInstruction->type == IRCALL){
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);
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);
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");
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");
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);
360
/* Check if specializable */
361
calleeHints = ir_specializer_getHintsForMethodForMethod(specializer, calleeWrapper);
362
if(calleeHints == NULL){
366
/* Found a specializable call site */
367
PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Loaded hints for method %s [%s]\n", getFullName(calleeMethod), getSignature(calleeMethod));
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);
374
assert(callerWrapper != NULL);
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);
381
assert(callerCallSites != NULL);
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);
388
/* Perform action based on call status */
389
PDEBUG("SPECIALIZER : manageCallSitesBeforeCompilation : Perform actions on the call site\n");
390
callSite->performAction(callSite, callerWrapper, specializer);
392
/* The method has changed */
396
PDEBUG("______________________________________________________________________________________________\n");
398
/* Print the changed method on stdout */
401
fprintf(stdout, "{AFTER} METHOD %s [%s]\n", getFullName(ilMethod),getSignature(ilMethod));
402
printIrMethod(irMethod, stdout, getFullName, getSignature);
403
fprintf(stdout, "END\n\n");
410
void ir_specializer_shutdown(struct ir_specializer_t* specializer){
411
XanListItem *item; /* Generic item */
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 */
419
assert(specializer != NULL);
420
PDEBUG("SPECIALIZER : shutdown : Shutting down the specializer system\n");
422
#ifdef FULLMODE_PRINTDEBUG
423
FMODEPRINT("SPECIALIZER : Shutdown\n");
426
/* Set the method as shutted down */
427
specializer->shuttedDown = JITTRUE;
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");
436
/* Destroy the pipeline */
437
specializer->recompileRequestPipe->destroyPipe(specializer->recompileRequestPipe);
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);
446
/* Destroy the hints list */
447
specializer->hintsForMethods->destroyList(specializer->hintsForMethods);
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);
456
/* Destroy the call site list */
457
specializer->callSitesForMethods->destroyList(specializer->callSitesForMethods);
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);
466
/* Destroy the wrapper list */
467
specializer->wrapperForMethods->destroyList(specializer->wrapperForMethods);
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);
476
/* Destroy the list of specialized methods */
477
specializer->specializedMethods->destroyList(specializer->specializedMethods);
480
void ir_specializer_loadHintsFromFile(ir_specializer_t* specializer, char* programName){
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 */
488
assert(specializer != NULL);
489
assert(programName != NULL);
491
PDEBUG("SPECIALIZER : loadHintsFromFile : Start loading hints for program %s\n",programName);
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);
500
PDEBUG("SPECIALIZER : loadHintsFromFile : Open file %s\n", fileName);
501
inputFile = fopen(fileName, "r");
503
/* Check file exists */
504
if(inputFile == NULL){
505
PDEBUG("SPECIALIZER : loadHintsFromFile : No specialization file named %s\n", fileName);
510
specializer->hintsForMethods->lock(specializer->hintsForMethods);
512
/* Read new hints form file */
513
while((hints = readHintsForMethodFromFile(inputFile, specializer)) !=NULL )
514
specializer->hintsForMethods->append(specializer->hintsForMethods, hints);
516
/* Unlock the list */
517
specializer->hintsForMethods->unlock(specializer->hintsForMethods);
519
/* Print all specialization */
521
PDEBUG("\nSPECIALIZER : loadHintsFromFile : Specialization read from file are: \n");
522
ir_specializer_printHintsForMethod(specializer, stderr);
525
#ifdef FULLMODE_PRINTDEBUG
526
FMODEPRINT("SPECIALIZER : Loaded hints from file are: \n");
527
ir_specializer_printHintsForMethod(specializer, stderr);
533
/* Terminate and free space */
534
PDEBUG("SPECIALIZER : loadHintsFromFile : Specialization loaded %s\n", fileName);
535
freeFunction(fileName);
537
void ir_specializer_printHintsForMethod(ir_specializer_t *specializer, FILE* out){
539
JITUINT32 index; /* Index used to scan list */
541
specializer_hintsForMethod_t* hintsForMethod; /* The hints for method to print on out */
544
assert(specializer != NULL);
548
specializer->hintsForMethods->lock(specializer->hintsForMethods);
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);
554
item = specializer->hintsForMethods->getElementFromPositionNumber(specializer->hintsForMethods, index);
555
assert(item != NULL);
557
/* Read next hint in the list */
558
hintsForMethod = (specializer_hintsForMethod_t*) specializer->hintsForMethods->data(specializer->hintsForMethods, item);
559
assert(hintsForMethod != NULL);
561
hintsForMethod->print(hintsForMethod, out);
564
/* Unlock the list */
565
specializer->hintsForMethods->unlock(specializer->hintsForMethods);
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;
578
assert(specializer != NULL);
579
assert(wrapper != NULL);
581
/* Initialize Variables */
584
/* Fetch the IR method */
585
irMethod = wrapper->getIRMethod(wrapper);
586
assert(irMethod != NULL);
588
/* Fetch the signature */
589
methodSignature = irMethod->getSignatureInString(irMethod, specializer->irlib->typeChecker);
590
assert(methodSignature != NULL);
593
methodName = irMethod->getCompleteName(irMethod);
594
assert(methodName != NULL);
597
PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Lock the hints for methods list list\n");
598
specializer->hintsForMethods->lock(specializer->hintsForMethods);
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);
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);
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;
619
//TODO: Search for hints for method inside method meta-data
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 */
629
char inputString[1024];
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;
639
fgets(inputString, 1023, inputFile);
640
specializer_fullspecialization_counter = atoi(inputString);
643
#ifdef FULLMODE_PRINTDEBUG
644
FMODEPRINT("SPECIALIZER : Multiply Constant : %d\n", specializer_fullspecialization_counter);
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 = ");
656
for(index = 0; index < (method->signature).parameters_number; index++){
657
PDEBUG("%s, ", getTypeName((method->signature).parameter_internal_types[index]));
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));
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 */
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);
678
if(cilSignature.sentinel && (index >= cilSignature.sentinel_param_index)){
679
PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Found VARARGS argument... nothing more to specialize for the method\n");
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)
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");
705
/* Create a new hint structure if needed */
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);
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;
720
/* Add the expression to the list */
721
result->addExpression(result, expression);
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");
728
/* Create a new hint structure if needed */
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);
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;
743
/* Add the expression to the list */
744
result->addExpression(result, expression);
747
PDEBUG("UNSPECIALIZABLE because ");
748
if(cilSignature.params[index].type == NULL){
749
PDEBUG("type is NULL\n");
751
PDEBUG("type is %d\n",(cilSignature.params[index].type)->type);
757
/* Append to the list */
759
PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Append the hints for the method to the hintsForMethodList\n");
760
specializer->hintsForMethods->append(specializer->hintsForMethods, result);
765
PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Generated a new hints for method :\n");
766
result->print(result, stderr);
770
#ifdef FULLMODE_PRINTDEBUG
772
FMODEPRINT("SPECIALIZER : Hints for %s [%s] (hasThis = %s)\n", methodName, methodSignature, hasThis?"TRUE":"FALSE");
773
result->print(result, stderr);
777
PDEBUG("SPECIALIZER : getHintsForMethodForMethod : The method has no incoming parameters!\n");
784
PDEBUG("SPECIALIZER : getHintsForMethodForMethod : No hints have been found since here!\n");
788
/* Unlock the list */
789
PDEBUG("SPECIALIZER : getHintsForMethodForMethod : Unlock the hints for methods list list\n");
790
specializer->hintsForMethods->unlock(specializer->hintsForMethods);
792
/* Return the required hints or NULL if such hints doesn't exists */
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 */
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);
816
/* Initialize the variables */
817
result = methodWrapper = NULL;
822
specializer->wrapperForMethods->lock(specializer->wrapperForMethods);
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);
831
/* Load methodWrapper */
832
methodWrapper = (specializer_method_wrapper_t*) specializer->wrapperForMethods->data(specializer->wrapperForMethods, item);
833
assert(methodWrapper != NULL);
835
/* Check if it's the required one*/
836
if(methodWrapper->ilMethod == ilMethod){
837
result = methodWrapper;
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);
849
/* Unlock the list */
850
specializer->wrapperForMethods->unlock(specializer->wrapperForMethods);
852
/* return the result */
856
specializer_callSitesForMethod_t* ir_specializer_getCallSitesFormMethod(ir_specializer_t* specializer, specializer_method_wrapper_t* wrapper){
857
specializer_callSitesForMethod_t* callSitesForMethod, *result;
862
assert(specializer != NULL);
863
assert(wrapper != NULL);
865
/* Initialize variables */
869
specializer->callSitesForMethods->lock(specializer->callSitesForMethods);
871
/* Search in the list */
872
for(index = 0; (index < specializer->callSitesForMethods->length(specializer->callSitesForMethods)) && (result == NULL); index++){
874
item = specializer->callSitesForMethods->getElementFromPositionNumber(specializer->callSitesForMethods, index);
876
/* Load the callSitesForMethod */
877
callSitesForMethod = (specializer_callSitesForMethod_t*) specializer->callSitesForMethods->data(specializer->callSitesForMethods, item);
879
/* Check for equality */
880
if(callSitesForMethod->methodWrapper == wrapper)
881
result = callSitesForMethod;
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);
894
specializer->callSitesForMethods->unlock(specializer->callSitesForMethods);
896
/* Return the call sites for method */
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;
908
assert(specializer != NULL);
909
assert(originalMethodWrapper != NULL);
910
assert(staticExpression != NULL);
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);
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));
925
/* Search for the specialized method wrapper inside the list */
926
PDEBUG("SPECIALIZER : getSpecializedMethod : Search inside the list for required method and expression\n");
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);
932
specializedMethod = (specializer_specialized_method_wrapper_t*) specializer->specializedMethods->data(specializer->specializedMethods, item);
933
assert(specializedMethod != NULL);
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;
942
/* If not found create a new specialized method */
944
void *newJitFunction;
945
PDEBUG("SPECIALIZER : getSpecializedMethod : Specialized method not found\n");
947
/* Clone the static expression */
948
staticExpression = specializer_cloneStaticExpression(staticExpression, specializer);
950
/* Create a new application method */
951
newMethod = specializer->newApplicationMethod();
952
assert(newMethod != NULL);
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));
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));
965
/* Create the JIT signature */
966
PDEBUG("SPECIALIZER : getSpecializedMethod : Decode JIT signature\n");
967
specializer->decode_jit_signature(specializer->system, result->specializedMethodWrapper->ilMethod);
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);
977
/* Change the state to IR_STATE */
978
PDEBUG("SPECIALIZER : getSpecializedMethod : Require method for recompile\n");
979
result->specializedMethodWrapper->setState(result->specializedMethodWrapper, 4);
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);
985
/* Print the IRMethod for DEBUG */
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));
994
/* Unlock the list */
995
specializer->specializedMethods->unlock(specializer->specializedMethods);
997
/* Return the value */
998
return result->specializedMethodWrapper;
1001
void* ir_specializer_recompile_request_thread(void* parameters){
1003
ir_specializer_t* specializer;
1004
specializer_method_wrapper_t* callerWrapper; /* Wrapper of the method to recompile */
1007
assert(parameters != NULL);
1009
/* Set thread cancel state */
1010
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
1011
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
1013
/* Set the specializer */
1014
specializer = (ir_specializer_t*) parameters;
1018
/* Read next wrapper */
1019
callerWrapper = (specializer_method_wrapper_t*) specializer->recompileRequestPipe->synchGet(specializer->recompileRequestPipe);
1021
/* Check if I have to exit */
1022
if (callerWrapper == NULL) break;
1023
assert(callerWrapper != NULL);
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");
1035
/* Change to recompile state */
1036
callerWrapper->setToRecompileState(callerWrapper);
1038
/* Place it in the pipeline */
1039
if(!specializer->shuttedDown){
1040
specializer->forceRecompile(callerWrapper->ilMethod);
1049
/* ----------------------------------------- specializer_expression_hint_t -----------------------------------------*/
1050
specializer_expression_hint_t* newSpecializerExpressionHint(ir_specializer_t* specializer){
1052
specializer_expression_hint_t* expression;
1055
assert(specializer != NULL);
1057
/* Allocate new space */
1058
expression = (specializer_expression_hint_t*) allocFunction((size_t)sizeof(specializer_expression_hint_t));
1059
assert(expression != NULL);
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;
1067
/* Return hints For Method */
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){
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);
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;
1086
void specializer_expression_hint_printSingle(specializer_expression_hint_t* expression, FILE *out){
1088
assert(expression != NULL);
1089
assert(out != NULL);
1091
/* Print position */
1092
fprintf(out, "#%d ", expression->position+1);
1094
switch(expression->action){
1095
case SPECIALIZER_ACTION_STATIC:
1096
fprintf(out, "STATIC");
1098
case SPECIALIZER_ACTION_STATIC_LENGTH:
1099
fprintf(out, "STATIC LENGTH");
1101
case SPECIALIZER_ACTION_STATIC_EQ:
1102
fprintf(out, "EQUALS");
1104
case SPECIALIZER_ACTION_STATIC_EQF:
1105
fprintf(out, "EQUALS FLOAT");
1108
fprintf(stderr, "SPECIALIZER ERROR\n\t\tUnknown action value %u for expression\n", expression->action);
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);
1118
void specializer_expression_hint_printChain(specializer_expression_hint_t* expression, FILE *out){
1120
assert(expression != NULL);
1121
assert(out != NULL);
1123
/* Print this expression */
1124
specializer_expression_hint_printSingle(expression, out);
1126
/* Print next expression if exists */
1127
if(expression->next != NULL){
1128
fprintf(out, " AND ");
1129
specializer_expression_hint_printChain(expression->next, out);
1132
/* Print the depth */
1133
if(expression->prev == NULL)
1134
fprintf(out, " (Depth = %u) ", expression->depth);
1137
void specializer_expression_hint_clean(specializer_expression_hint_t* expression, ir_specializer_t* specializer){
1139
assert(expression != NULL);
1140
assert(specializer != NULL);
1142
/* Free next expression if exists */
1143
if(expression->next != NULL)
1144
specializer_expression_hint_clean(expression->next, specializer);
1146
/* Free expression itself */
1147
freeFunction(expression);
1149
/* ----------------------------------------- specializer_hintsForMethod_t -----------------------------------------*/
1150
specializer_hintsForMethod_t* newSpecializerHintsForMethod(ir_specializer_t* specializer){
1152
specializer_hintsForMethod_t* hints = NULL;
1155
assert(specializer != NULL);
1157
/* Allocate space */
1158
hints = (specializer_hintsForMethod_t*) allocFunction((size_t)sizeof(specializer_hintsForMethod_t));
1159
assert(hints != NULL);
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;
1170
/* Return hintsForMethod */
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){
1180
assert(hints != NULL);
1181
assert(methodCompleteName != NULL);
1182
assert(methodSignature != NULL);
1183
assert(secondProfilerStaticThreshold > 0 && secondProfilerStaticThreshold <= 1);
1184
assert(zeroProfilerTypeThreshold > 0 && zeroProfilerTypeThreshold <= 1);
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;
1197
/* Create the list of hints */
1198
hints->expressions = xanListNew(allocFunction, freeFunction, NULL);
1199
assert(hints->expressions != NULL);
1201
void specializer_hintsForMethod_print(specializer_hintsForMethod_t *hints, FILE* out){
1203
JITUINT32 index = 0; //Index for expressions
1204
specializer_expression_hint_t* expression = NULL; // Expression to print
1207
assert(hints != NULL);
1208
assert(out != NULL);
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);
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);
1230
void specializer_hintsForMethod_clean(specializer_hintsForMethod_t *hints, ir_specializer_t* specializer){
1232
JITUINT32 index = 0; //Index for expressions
1233
specializer_expression_hint_t* expression = NULL; // Expression to clean
1236
assert(hints != NULL);
1237
assert(specializer != NULL);
1239
/* Free name and signature */
1240
freeFunction(hints->methodCompleteName);
1241
freeFunction(hints->methodSignature);
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);
1249
/* Destroy the expression list */
1250
hints->expressions->destroyList(hints->expressions);
1253
freeFunction(hints);
1255
JITBOOLEAN specializer_hintsForMethod_equals(specializer_hintsForMethod_t *hints, char *methodCompleteName, char *methodSignature){
1257
assert(hints != NULL);
1258
assert(methodCompleteName != NULL);
1259
assert(methodSignature != NULL);
1261
/* String comparison of values */
1262
return (strcmp(hints->methodCompleteName,methodCompleteName)==0) && (strcmp(hints->methodSignature, methodSignature)==0);
1264
void specializer_hintsForMethod_addExpression(specializer_hintsForMethod_t *hints, specializer_expression_hint_t* expression){
1266
assert(hints != NULL);
1267
assert(expression != NULL);
1268
assert(hints->expressions != NULL);
1270
/* Append the expression to the list of expressions */
1271
hints->expressions->append(hints->expressions, expression);
1273
specializer_expression_hint_t* specializer_hintsForMethod_getExpression(specializer_hintsForMethod_t *hints, JITUINT32 index){
1275
XanListItem* item; // Item of the list
1276
specializer_expression_hint_t* expression; // Read expression
1279
assert(hints != NULL);
1280
assert(index < specializer_hintsForMethod_getExpressionsNumber(hints));
1283
item = hints->expressions->getElementFromPositionNumber(hints->expressions, index);
1284
assert(item != NULL);
1286
/* Read the expression */
1287
expression = (specializer_expression_hint_t*) hints->expressions->data(hints->expressions, item);
1288
assert(expression != NULL);
1290
/* Return the expression */
1293
JITUINT32 specializer_hintsForMethod_getExpressionsNumber(specializer_hintsForMethod_t *hints){
1295
assert(hints != NULL);
1296
assert(hints->expressions != NULL);
1298
/* Return the length of the array element */
1299
return hints->expressions->length(hints->expressions);
1302
/* ----------------------------------------- specializer_method_wrapper_t -----------------------------------------*/
1303
specializer_method_wrapper_t* newSpecializerMethodWrapper(ir_specializer_t* specializer){
1305
specializer_method_wrapper_t* methodWrapper = NULL;
1308
assert(specializer != NULL);
1310
/* Allocate space */
1311
methodWrapper = (specializer_method_wrapper_t*) allocFunction((size_t)sizeof(specializer_method_wrapper_t));
1312
assert(methodWrapper != NULL);
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;
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;
1327
/* Return the method */
1328
return methodWrapper;
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)){
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);
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;
1359
void specializer_method_wrapper_print (ir_specializer_t *specializer, specializer_method_wrapper_t* methodWrapper, FILE* out){
1360
ir_method_t *method;
1363
assert(methodWrapper != NULL);
1364
assert(out != NULL);
1365
assert(specializer != NULL);
1367
/* Fetch the IR method */
1368
method = methodWrapper->getIRMethod(methodWrapper);
1369
assert(method != NULL);
1371
/* Just print out the full name and the signature */
1372
fprintf(out, "%s [%s]", method->getCompleteName(method), method->getSignatureInString(method, specializer->irlib->typeChecker));
1378
void specializer_method_wrapper_clean(specializer_method_wrapper_t* methodWrapper, ir_specializer_t* specializer){
1380
assert(specializer != NULL);
1381
assert(methodWrapper != NULL);
1383
/* Hust clean itself */
1384
freeFunction(methodWrapper);
1388
ir_method_t* specializer_method_wrapper_getIRMethod(specializer_method_wrapper_t* methodWrapper){
1390
assert(methodWrapper != NULL);
1393
return methodWrapper->_getIRMethod(methodWrapper->ilMethod);
1395
void specializer_method_wrapper_setState(specializer_method_wrapper_t* methodWrapper, JITUINT32 state){
1397
assert(methodWrapper != NULL);
1400
methodWrapper->_setState(methodWrapper->ilMethod, state);
1402
JITUINT32 specializer_method_wrapper_getState(specializer_method_wrapper_t* methodWrapper){
1404
assert(methodWrapper != NULL);
1407
return methodWrapper->_getState(methodWrapper->ilMethod);
1409
void specializer_method_wrapper_setToRecompileState(specializer_method_wrapper_t* methodWrapper){
1411
assert(methodWrapper != NULL);
1413
/* Change the method state */
1414
methodWrapper->_setState(methodWrapper->ilMethod, methodWrapper->recompileStateValue);
1416
void specializer_method_wrapper_setJITFunction(specializer_method_wrapper_t* methodWrapper, void* jitFunction){
1418
assert(methodWrapper != NULL);
1419
assert(jitFunction != NULL);
1421
/* Assign the JIT function */
1422
methodWrapper->_setJITFunction(methodWrapper->ilMethod, jitFunction);
1424
void* specializer_method_wrapper_getJITFunction(specializer_method_wrapper_t* methodWrapper){
1426
assert(methodWrapper != NULL);
1428
/* Return the jit function */
1429
return methodWrapper->_getJITFunction(methodWrapper->ilMethod);
1431
JITBOOLEAN specializer_method_wrapper_isCctor(specializer_method_wrapper_t* methodWrapper){
1433
assert(methodWrapper != NULL);
1435
/* Return the required value */
1436
return methodWrapper->_isCctor(methodWrapper->ilMethod);
1439
/* ----------------------------------------- specializer_method_callSite_t -----------------------------------------*/
1440
specializer_method_callSite_t* newSpecializerCallSite(ir_specializer_t* specializer){
1442
specializer_method_callSite_t* callSite = NULL;
1445
assert(specializer != NULL);
1447
/* Allocate space */
1448
callSite = (specializer_method_callSite_t*) allocFunction((size_t)sizeof(specializer_method_callSite_t));
1449
assert(callSite != NULL);
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;
1460
/* return the call site */
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){
1466
assert(callSite != NULL);
1467
assert(methodWrapper != NULL);
1468
assert(call != NULL);
1469
//assert(hints != NULL);
1470
assert(specializer != NULL);
1472
/* Assign variables */
1473
callSite->methodWrapper = methodWrapper;
1474
callSite->call = call;
1475
callSite->hints = hints;
1477
/* Initialize variables */
1478
callSite->status = SPECIALIZER_CALLSITE_STATUS_CLEAN;
1479
callSite->addedInstructions = xanListNew(allocFunction, freeFunction, NULL);
1481
/* Initialize profilers and dispatcher */
1482
callSite->firstProfiler = NULL;
1483
callSite->secondProfiler = NULL;
1484
callSite->dispatcher = NULL;
1485
callSite->typeDispatcher = NULL;
1488
void specializer_method_callSite_print (specializer_method_callSite_t* callSite, FILE* out, ir_specializer_t *specializer){
1489
ir_method_t *method;
1492
assert(callSite != NULL);
1493
assert(out != NULL);
1494
assert(specializer != NULL);
1496
/* Fetch the method */
1497
method = callSite->methodWrapper->getIRMethod(callSite->methodWrapper);
1498
assert(method != NULL);
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");
1509
case SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED:
1510
fprintf(out, "\tStatus: FIRST PROFILER INJECTED\n");
1511
callSite->firstProfiler->print(callSite->firstProfiler, out);
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);
1518
fprintf(out, "\t\tNo such information about the first profiler!\n");
1520
case SPECIALIZER_CALLSITE_STATUS_SECOND_PROFILER_INJECTED:
1521
fprintf(out, "\tStatus: SECOND PROFILER INJECTED\n");
1522
callSite->secondProfiler->print(callSite->secondProfiler, out);
1524
case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_REQUEST:
1525
fprintf(out, "\tStatus: DISPATCHER REQUEST\n");
1526
callSite->secondProfiler->print(callSite->secondProfiler, out);
1528
case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_INJECTED:
1529
fprintf(out, "\tStatus: DISPATCHER INJECTED\n");
1530
callSite->dispatcher->print(callSite->dispatcher, out);
1532
case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_REMOVE:
1533
fprintf(out, "\tStatus: DISPATCHER REMOVE REQUEST\n");
1534
callSite->dispatcher->print(callSite->dispatcher, out);
1536
case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_UNSPECIALIZABLE:
1537
fprintf(out, "\tStatus: UNSPECIALIZABLE\n");
1539
case SPECIALIZER_CALLSITE_STATUS_TYPE_DISPATCHER_REQUEST:
1540
fprintf(out, "\tStatus: TYPE DISPATCHER REQUEST\n");
1541
callSite->firstProfiler->print(callSite->firstProfiler, out);
1543
case SPECIALIZER_CALLSITE_STATUS_TYPE_DISPATCHER_INJECTED:
1544
fprintf(out, "\tStatus: TYPE DISPATCHER INJECTED\n");
1545
callSite->typeDispatcher->print(callSite->typeDispatcher, out);
1547
case SPECIALIZER_CALLSITE_STATUS_TYPE_DISPATCHER_REMOVE:
1548
fprintf(out, "\tStatus: TYPE DISPATCHER REMOVE REQUEST\n");
1549
callSite->typeDispatcher->print(callSite->typeDispatcher, out);
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");
1557
void specializer_method_callSite_clean(specializer_method_callSite_t* callSite, ir_specializer_t* specializer){
1559
assert(callSite != NULL);
1560
assert(specializer != NULL);
1562
/* Destroy the first profiler if needed */
1563
if(callSite->firstProfiler != NULL){
1564
callSite->firstProfiler->clean(callSite->firstProfiler, specializer);
1565
callSite->firstProfiler = NULL;
1568
/* Destroy the dispatcher if needed */
1569
if(callSite->secondProfiler != NULL){
1570
callSite->secondProfiler->clean(callSite->secondProfiler, specializer);
1571
callSite->secondProfiler = NULL;
1574
/* Destroy the dispatcher if needed */
1575
if(callSite->dispatcher != NULL){
1576
callSite->dispatcher->clean(callSite->dispatcher, specializer);
1577
callSite->dispatcher = NULL;
1580
/* Clean the type dispatcher */
1581
if(callSite->typeDispatcher != NULL){
1582
callSite->typeDispatcher->clean(callSite->typeDispatcher, specializer);
1583
callSite->typeDispatcher = NULL;
1586
/* Destroy instructions list */
1587
callSite->addedInstructions->destroyList(callSite->addedInstructions);
1588
callSite->addedInstructions = NULL;
1591
freeFunction(callSite);
1594
JITINT32 specializer_method_callSite_hasVariableParameters (specializer_method_callSite_t* callSite){
1598
assert(callSite != NULL);
1599
assert(callSite->call != NULL);
1601
/* Check the existance of parameters */
1602
if ( (callSite->call->callParameters == NULL) ||
1603
(callSite->call->callParameters->length(callSite->call->callParameters) == 0) ){
1607
/* Check the parameters */
1608
item = callSite->call->callParameters->first(callSite->call->callParameters);
1609
assert(item != NULL);
1610
while (item != NULL){
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);
1622
void specializer_method_callSite_addInstruction(specializer_method_callSite_t* callSite, t_ir_instruction* instruction){
1624
assert(callSite != NULL);
1625
assert(instruction != NULL);
1627
/* Add the instruction */
1628
callSite->addedInstructions->append(callSite->addedInstructions, instruction);
1630
void specializer_method_callSite_removeInstructionsFromMethod(specializer_method_callSite_t* callSite, ir_method_t* irMethod){
1632
t_ir_instruction* instruction; /* Instruction to remove */
1637
assert(callSite != NULL);
1638
assert(irMethod != NULL);
1640
/* While there are instructions added */
1641
while(callSite->addedInstructions->length(callSite->addedInstructions) > 0){
1643
/* Load the next instruction */
1644
item = callSite->addedInstructions->getElementFromPositionNumber(callSite->addedInstructions, 0);
1645
instruction = (t_ir_instruction*) callSite->addedInstructions->data(callSite->addedInstructions, item);
1647
/* Delete the instruction from the method */
1648
irMethod->deleteInstruction(irMethod, instruction);
1650
/* Remove the instruction */
1651
callSite->addedInstructions->deleteItem(callSite->addedInstructions, item);
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);
1660
// /* Read the instruction*/
1661
// instruction = (t_ir_instruction*) callSite->addedInstructions->data(callSite->addedInstructions, item);
1663
// /* If it is a IRCALL instruction remove it from the call site list! */
1666
// /* Remove the instruction from the method */
1667
// irMethod->deleteInstruction(irMethod, instruction);
1670
// /* Remove each instruction from the list */
1671
// callSite->addedInstructions->emptyOutList(callSite->addedInstructions);
1674
void specializer_method_callSite_performAction (specializer_method_callSite_t* callSite, specializer_method_wrapper_t* callerWrapper, ir_specializer_t* specializer){
1675
XanList *staticExpressions;
1677
ir_method_t *callerMethod;
1678
ir_method_t *calleeMethod;
1682
assert(callSite != NULL);
1683
assert(specializer != NULL);
1684
assert(callerWrapper != NULL);
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));
1695
/* Fetch the methods */
1697
callerMethod = callerWrapper->getIRMethod(callerWrapper);
1698
calleeMethod = callSite->methodWrapper->getIRMethod(callSite->methodWrapper);
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");
1708
callSite->print(callSite, stderr);
1711
/* Execute action depending on the call site */
1712
switch(callSite->status){
1713
case SPECIALIZER_CALLSITE_STATUS_CLEAN:
1715
/* Check if the call site has *
1717
if (!(callSite->hasVariableParameters(callSite))){
1718
internal_action_to_second_or_dispatch_state(callSite, callerWrapper, specializer);
1722
/* Create the first profiler */
1723
if(callSite->firstProfiler == NULL){
1724
callSite->firstProfiler = newSpecializerFirstProfiler(specializer);
1725
callSite->firstProfiler->init(callSite->firstProfiler, callSite, specializer);
1729
callSite->firstProfiler->counter = 0;
1730
callSite->firstProfiler->thresholdReached = JITFALSE;
1733
/* Inject the first profiler profiler */
1734
callSite->firstProfiler->inject(callSite->firstProfiler, callerWrapper, specializer);
1736
/* Change the status */
1737
callSite->status = SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED;
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;
1745
/* Clean the dispatcher if required */
1746
// if(callSite->dispatcher != NULL){
1747
// callSite->dispatcher->clean(callSite->dispatcher, specializer);
1748
// callSite->dispatcher = NULL;
1750
/* Clean the second profiler if requires */
1751
// if(callSite->secondProfiler != NULL){
1752
// callSite->secondProfiler->clean(callSite->secondProfiler, specializer);
1753
// callSite->secondProfiler = NULL;
1756
case SPECIALIZER_CALLSITE_STATUS_SECOND_PROFILER_REQUEST:
1757
internal_action_to_second_or_dispatch_state(callSite, callerWrapper, specializer);
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;
1766
case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_REQUEST:
1768
* NOTE: Don't clear here the second profiler!!!!
1769
* It could be used by the execution thread even if changed the IR method!!
1771
* So here we can just remove the second profiler
1774
/* Remove the second profiler */
1775
callSite->secondProfiler->remove(callSite->secondProfiler, callerWrapper);
1777
staticExpressions = callSite->secondProfiler->getStaticExpressions(callSite->secondProfiler, specializer);
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);
1785
callSite->dispatcher->counter = 0;
1786
callSite->dispatcher->thresholdReached = JITFALSE;
1789
/* Inject the dispatcher */
1790
callSite->dispatcher->inject(callSite->dispatcher, callerWrapper, staticExpressions, specializer);
1792
/* Change the status */
1793
callSite->status = SPECIALIZER_CALLSITE_STATUS_DISPATCHER_INJECTED;
1794
} else { /* If there are no static expressions */
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;
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);
1811
/* Change the status to first profiler injected */
1812
callSite->status = SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED;
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;
1823
case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_REMOVE:
1825
* NOTE: Don't clear here the dispatcher!!!!
1826
* It could be used by the execution thread even if changed the IR method!!
1828
* So here we can just remove the dispatcher
1831
/* Remove the dispatcher */
1832
callSite->dispatcher->remove(callSite->dispatcher, callerWrapper);
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;
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);
1849
/* Change the status to first profiler injected */
1850
callSite->status = SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED;
1852
case SPECIALIZER_CALLSITE_STATUS_DISPATCHER_UNSPECIALIZABLE:
1855
case SPECIALIZER_CALLSITE_STATUS_TYPE_DISPATCHER_REQUEST:
1857
/* Remove the first profiler */
1858
callSite->firstProfiler->remove(callSite->firstProfiler, callerWrapper);
1860
/* Create the type dispatcher */
1861
if(callSite->typeDispatcher == NULL){
1862
callSite->typeDispatcher = newSpecializerTypeDispatcher(specializer);
1863
callSite->typeDispatcher->init(callSite->typeDispatcher, callSite);
1865
callSite->typeDispatcher->counter = 0;
1866
callSite->typeDispatcher->thresholdReached = JITFALSE;
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;
1875
/* Clean the specializer */
1876
callSite->typeDispatcher->clean(callSite->typeDispatcher, specializer);
1877
callSite->typeDispatcher = NULL;
1879
/* Change the status of this call site */
1880
callSite->status = SPECIALIZER_CALLSITE_STATUS_CLEAN;
1882
/* Reinject first profiler */
1883
callSite->firstProfiler->counter = 0;
1884
callSite->firstProfiler->thresholdReached = JITFALSE;
1885
callSite->firstProfiler->inject(callSite->firstProfiler, callerWrapper, specializer);
1887
/* Change the status to first profiler injected */
1888
callSite->status = SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED;
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;
1898
case SPECIALIZER_CALLSITE_STATUS_TYPE_DISPATCHER_REMOVE:
1899
/* Remove the type dispatcher */
1900
callSite->typeDispatcher->remove(callSite->typeDispatcher, callerWrapper);
1902
/* Re-inject first profiler */
1903
if(callSite->firstProfiler == NULL){
1904
callSite->firstProfiler = newSpecializerFirstProfiler(specializer);
1905
callSite->firstProfiler->init(callSite->firstProfiler, callSite, specializer);
1907
callSite->firstProfiler->counter = 0;
1908
callSite->firstProfiler->thresholdReached = JITFALSE;
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);
1917
/* Change the status of this call site */
1918
callSite->status = SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED;
1921
fprintf(stderr, "SPECIALIZER : specializer_method_callSite_performAction\n\t\tERROR = Unknown call site status\n");
1925
#ifdef FULLMODE_PRINTDEBUG
1926
FMODEPRINT("Exit State: %s\n", getStateName(callSite->status));
1929
/* Print informations at method exit */
1930
PDEBUG("SPECIALIZER : CALL SITE : Call site informations at perform action at END : \n");
1932
callSite->print(callSite, stderr);
1934
PDEBUG("######################################################################################################\n\n");
1937
/* ----------------------------------------- specializer_callSitesForMethod_t -----------------------------------------*/
1938
specializer_callSitesForMethod_t* newSpecializerCallSitesForMethod(ir_specializer_t* specializer){
1940
specializer_callSitesForMethod_t* callSitesForMethod = NULL;
1943
assert(specializer != NULL);
1945
/* Allocate space */
1946
callSitesForMethod = (specializer_callSitesForMethod_t*) allocFunction((size_t)sizeof(specializer_callSitesForMethod_t));
1947
assert(callSitesForMethod != NULL);
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;
1956
/* Return the callSites */
1957
return callSitesForMethod;
1959
void specializer_callSitesForMethod_init(specializer_callSitesForMethod_t* callSitesForMethod, specializer_method_wrapper_t* wrapper, ir_specializer_t* specializer){
1961
assert(callSitesForMethod != NULL);
1962
assert(wrapper != NULL);
1963
assert(specializer != NULL);
1965
/* Assign variables */
1966
callSitesForMethod->methodWrapper = wrapper;
1968
/* initialize call site list */
1969
callSitesForMethod->callSites = xanListNew(allocFunction, freeFunction, NULL);
1972
void specializer_callSitesForMethod_print (specializer_callSitesForMethod_t* callSitesForMethod, FILE* out, ir_specializer_t *specializer){
1975
specializer_method_callSite_t *callSite;
1976
ir_method_t *method;
1979
assert(callSitesForMethod != NULL);
1980
assert(out != NULL);
1981
assert(specializer != NULL);
1983
/* Fetch the IR Method */
1984
method = callSitesForMethod->methodWrapper->getIRMethod(callSitesForMethod->methodWrapper);
1985
assert(method != NULL);
1987
/* Print caller information */
1988
fprintf(out, "Caller: %s [%s]\n", method->getCompleteName(method), method->getSignatureInString(method, specializer->irlib->typeChecker));
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++){
1995
item = callSitesForMethod->callSites->getElementFromPositionNumber(callSitesForMethod->callSites, index);
1997
/* Load the call site */
1998
callSite = (specializer_method_callSite_t*)callSitesForMethod->callSites->data(callSitesForMethod->callSites, item);
2000
/* Print the call site */
2001
callSite->print(callSite, out, specializer);
2003
callSitesForMethod->callSites->unlock(callSitesForMethod->callSites);
2006
void specializer_callSitesForMethod_clean(specializer_callSitesForMethod_t* callSitesForMethod, ir_specializer_t* specializer){
2010
specializer_method_callSite_t* callSite;
2013
assert(callSitesForMethod != NULL);
2014
assert(specializer != NULL);
2016
/* Destroy the each call site */
2017
for(index=0;index < callSitesForMethod->callSites->length(callSitesForMethod->callSites); index++){
2019
item = callSitesForMethod->callSites->getElementFromPositionNumber(callSitesForMethod->callSites, index);
2021
/* Load the call site */
2022
callSite = (specializer_method_callSite_t*)callSitesForMethod->callSites->data(callSitesForMethod->callSites, item);
2024
/* Clean the call site */
2025
callSite->clean(callSite, specializer);
2028
/* Destroy the list */
2029
callSitesForMethod->callSites->destroyList(callSitesForMethod->callSites);
2032
freeFunction(callSitesForMethod);
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){
2038
specializer_method_callSite_t *callSite, *result;
2041
assert(callSitesForMethod != NULL);
2042
assert(call != NULL);
2043
assert(specializer != NULL);
2044
assert(calleeWrapper != NULL);
2047
callSitesForMethod->callSites->lock(callSitesForMethod->callSites);
2049
/* Search in the list */
2051
for(index=0;(index < callSitesForMethod->callSites->length(callSitesForMethod->callSites)) && (result == NULL); index++){
2053
item = callSitesForMethod->callSites->getElementFromPositionNumber(callSitesForMethod->callSites, index);
2055
/* Load the call site */
2056
callSite = (specializer_method_callSite_t*)callSitesForMethod->callSites->data(callSitesForMethod->callSites, item);
2058
/* Print the call site */
2059
if(callSite->call == call)
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);
2070
/* Unlock the list */
2071
callSitesForMethod->callSites->unlock(callSitesForMethod->callSites);
2075
JITBOOLEAN specializer_callSitesForMethod_isInjectedInstruction(specializer_callSitesForMethod_t* callSitesForMethod, t_ir_instruction* instruction){
2079
specializer_method_callSite_t *callSite;
2083
assert(callSitesForMethod != NULL);
2084
assert(instruction != NULL);
2087
callSitesForMethod->callSites->lock(callSitesForMethod->callSites);
2089
/* Search in the list */
2091
for(index=0;(index < callSitesForMethod->callSites->length(callSitesForMethod->callSites)) && !found; index++){
2093
item = callSitesForMethod->callSites->getElementFromPositionNumber(callSitesForMethod->callSites, index);
2095
/* Load the call site */
2096
callSite = (specializer_method_callSite_t*)callSitesForMethod->callSites->data(callSitesForMethod->callSites, item);
2099
found = callSite->addedInstructions->find(callSite->addedInstructions, instruction) != NULL;
2102
/* Unlock the list */
2103
callSitesForMethod->callSites->unlock(callSitesForMethod->callSites);
2108
/* ----------------------------------------- specializer_method_callSite_firstProfiler_t -----------------------------------------*/
2109
specializer_method_callSite_firstProfiler_t* newSpecializerFirstProfiler(ir_specializer_t* specializer){
2111
specializer_method_callSite_firstProfiler_t* profiler = NULL;
2114
assert(specializer != NULL);
2116
/* Allocate space */
2117
profiler = (specializer_method_callSite_firstProfiler_t*) allocFunction((size_t)sizeof(specializer_method_callSite_firstProfiler_t));
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;
2131
/* Return the profiler */
2134
void specializer_method_callSite_firstProfiler_init(specializer_method_callSite_firstProfiler_t* profiler, void* callSiteContext, ir_specializer_t* specializer){
2136
specializer_method_callSite_t* callSite;
2139
assert(profiler != NULL);
2140
assert(callSiteContext != NULL);
2141
assert(specializer != NULL);
2143
/* Assign variables */
2144
profiler->callSiteContext = callSiteContext;
2146
/* Initialize variables */
2147
profiler->counter = 0;
2148
profiler->thresholdReached = JITFALSE;
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);
2160
void specializer_method_callSite_firstProfiler_print(specializer_method_callSite_firstProfiler_t* profiler, FILE* out){
2162
assert(profiler != NULL);
2163
assert(out != NULL);
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));
2171
void specializer_method_callSite_firstProfiler_clean(specializer_method_callSite_firstProfiler_t* profiler, ir_specializer_t* specializer){
2173
specializer_method_callSite_t* callSite;
2176
assert(profiler != NULL);
2178
/* Free the memory allocated for the type profiler */
2179
callSite = profiler->callSiteContext;
2180
if(callSite->call->type == IRVCALL){
2181
freeFunction(profiler->memory);
2184
/*Just clean itself */
2185
freeFunction(profiler);
2187
JITUINT32* specializer_method_callSite_firstProfiler_getCounterPointer(specializer_method_callSite_firstProfiler_t* profiler){
2189
assert(profiler != NULL);
2191
/* Return the pointer to the counter */
2192
return &(profiler->counter);
2194
JITUINT32 specializer_method_callSite_firstProfiler_getCounterValue(struct specializer_method_callSite_firstProfiler_t* profiler){
2196
assert(profiler != NULL);
2198
/* Return the value of the counter */
2199
return profiler->counter;
2202
JITUINT32* specializer_method_callSite_firstProfiler_getThresholdReachedPointer(specializer_method_callSite_firstProfiler_t* profiler){
2204
assert(profiler != NULL);
2206
/* Return the pointer to the threshold reached variable */
2207
return &(profiler->thresholdReached);
2209
JITUINT32 specializer_method_callSite_firstProfiler_isThresholdReached(specializer_method_callSite_firstProfiler_t* profiler){
2211
assert(profiler != NULL);
2213
/* Return the value of the threshold reached variable */
2214
return profiler->thresholdReached;
2217
/* ----------------------------------------- specializer_callSite_secondProfiler_param_t -----------------------------------------*/
2218
specializer_callSite_secondProfiler_param_t* newSpecializerSecondProfileParameter(ir_specializer_t* specializer){
2220
specializer_callSite_secondProfiler_param_t* parameter = NULL;
2223
assert(specializer != NULL);
2225
/* Allocate space */
2226
parameter = (specializer_callSite_secondProfiler_param_t*) allocFunction((size_t)sizeof(specializer_callSite_secondProfiler_param_t));
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;
2242
/* return the parameter */
2245
void specializer_callSite_secondProfiler_param_init(specializer_callSite_secondProfiler_param_t* secondProfilerParam, ir_item_t* item, JITUINT32 offset, JITUINT32 position, JITBOOLEAN isVector){
2247
assert(secondProfilerParam != NULL);
2248
assert(item != NULL);
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;
2257
/* Assign offset and position */
2258
secondProfilerParam->offset = offset;
2259
secondProfilerParam->position = position;
2260
secondProfilerParam->_isVector = isVector;
2262
void specializer_callSite_secondProfiler_param_print(specializer_callSite_secondProfiler_param_t* secondProfilerParam, FILE* out){
2264
assert(secondProfilerParam != NULL);
2265
assert(out != NULL);
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));
2275
fprintf(out,"Type = UNKNOWN!!!");
2277
void specializer_callSite_secondProfiler_param_clean(specializer_callSite_secondProfiler_param_t* secondProfilerParam, ir_specializer_t* specializer){
2279
assert(secondProfilerParam != NULL);
2280
assert(specializer != NULL);
2282
/* Just clean itself */
2283
freeFunction(secondProfilerParam);
2286
JITUINT32 specializer_callSite_secondProfiler_param_getParamType(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
2288
assert(secondProfilerParam != NULL);
2290
/* Return the required value */
2291
return secondProfilerParam->item.type;
2293
JITUINT32 specializer_callSite_secondProfiler_param_getParamInternalType(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
2295
assert(secondProfilerParam != NULL);
2297
/* Return the required value */
2298
return secondProfilerParam->item.internal_type;
2300
size_t specializer_callSite_secondProfiler_param_getParameterSize(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
2302
assert(secondProfilerParam != NULL);
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);
2311
JITUINT32 specializer_callSite_secondProfiler_param_getType(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
2313
assert(secondProfilerParam != NULL);
2315
/* Return the required value */
2316
if(secondProfilerParam->_isVector)
2318
else if(secondProfilerParam->item.type == IROFFSET)
2319
return secondProfilerParam->item.internal_type;
2320
return secondProfilerParam->item.type;
2323
JITBOOLEAN specializer_callSite_secondProfiler_param_isVariable(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
2325
assert(secondProfilerParam != NULL);
2327
/* Return the required value */
2328
return (secondProfilerParam->item.type == IROFFSET) /*&& !secondProfilerParam->_isVector*/;
2330
JITBOOLEAN specializer_callSite_secondProfiler_param_isConstant(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
2332
assert(secondProfilerParam != NULL);
2334
/* Return the required value */
2335
return (secondProfilerParam->item.type != IROFFSET) /*&& !secondProfilerParam->_isVector*/;
2337
JITBOOLEAN specializer_callSite_secondProfiler_param_isVector(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
2339
assert(secondProfilerParam != NULL);
2341
/* Return the required value */
2342
return secondProfilerParam->_isVector;
2344
IR_ITEM_VALUE specializer_callSite_secondProfiler_param_getValue(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
2346
assert(secondProfilerParam != NULL);
2348
/* Return the required value */
2349
return secondProfilerParam->item.value;
2351
IR_ITEM_FVALUE specializer_callSite_secondProfiler_param_getFValue(specializer_callSite_secondProfiler_param_t* secondProfilerParam){
2353
assert(secondProfilerParam != NULL);
2355
/* Return the required value */
2356
return secondProfilerParam->item.fvalue;
2359
/* ----------------------------------------- specializer_method_callSite_secondProfiler_t -----------------------------------------*/
2360
specializer_method_callSite_secondProfiler_t* newSpecializerSecondProfiler(ir_specializer_t* specializer){
2362
specializer_method_callSite_secondProfiler_t* profiler;
2365
assert(specializer != NULL);
2367
/* Allocate space */
2368
profiler = (specializer_method_callSite_secondProfiler_t*) allocFunction((size_t)sizeof(specializer_method_callSite_secondProfiler_t));
2369
assert(profiler != NULL);
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;
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;
2385
profiler->getStaticExpressions = specializer_method_callSite_secondProfiler_getStaticExpressions;
2387
/* Return the profiler */
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;
2401
assert(profiler != NULL);
2402
assert(specializer != NULL);
2403
assert(callSiteContext != NULL);
2405
/* Initialize variables */
2406
profiler->callSiteContext = callSiteContext;
2407
profiler->threshold = 0;
2408
profiler->blockSize = 0;
2409
profiler->counter = 0;
2410
profiler->thresholdReached = JITFALSE;
2412
/* Create parameters list */
2413
profiler->parameters = xanListNew(allocFunction, freeFunction, NULL);
2415
/* Initialize the call site */
2416
callSite = (specializer_method_callSite_t*) callSiteContext;
2418
/* Allocate memory where parameters values must be stored */
2419
profiler->memory = allocFunction(callSite->hints->secondProfilerMemorySize);
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));
2425
/* Find offset for each parameter */
2426
PDEBUG("SPECIALIZER: CALL SITE : SECOND PROFIELR : Required parameters : ");
2427
PDEBUG("\t\tExpression hints for\n");
2429
callSite->hints->print(callSite->hints, stderr);
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:");
2436
expression->printChain(expression, stderr);
2440
/* If the parameter hasn't already been created */
2441
if(!requiredParameters[expression->position]){
2442
PDEBUG("%u ", expression->position);
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);
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);
2453
/* Ass the new profiler parameter to parameters list */
2454
profiler->parameters->append(profiler->parameters, secondProfilerParameter);
2456
/* Change the parameter block size */
2457
if(!secondProfilerParameter->isConstant(secondProfilerParameter)){
2459
if(secondProfilerParameter->isVector(secondProfilerParameter)) PDEBUG("[VECTOR], ");
2460
else PDEBUG("[VARIABLE], ");
2462
profiler->blockSize += secondProfilerParameter->getParameterSize(secondProfilerParameter);
2464
PDEBUG("[CONSTANT], ");
2467
/* Set the parameter as already required */
2468
requiredParameters[expression->position] = JITTRUE;
2470
PDEBUG("{Skip %u}, ", expression->position);
2473
/* Go to next subexpression */
2474
expression = expression->next;
2475
}while(expression != NULL);
2479
/* Free memory no long used */
2480
freeFunction(requiredParameters);
2482
/* Calculate the threshold value */
2483
if(profiler->blockSize > 0) {
2484
profiler->threshold = callSite->hints->secondProfilerMemorySize / profiler->blockSize;
2486
profiler->threshold = 0;
2493
void specializer_method_callSite_secondProfiler_print(specializer_method_callSite_secondProfiler_t* profiler, FILE* out){
2495
specializer_callSite_secondProfiler_param_t* parameter; /* Parameter to clean */
2500
assert(profiler != NULL);
2501
assert(out != NULL);
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));
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);
2523
void specializer_method_callSite_secondProfiler_clean(specializer_method_callSite_secondProfiler_t* profiler, ir_specializer_t* specializer){
2525
specializer_callSite_secondProfiler_param_t* parameter; /* Parameter to clean */
2530
assert(profiler != NULL);
2531
assert(specializer != NULL);
2533
/* Free memory space for parameters informations store */
2534
freeFunction(profiler->memory);
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);
2543
/* Destroy the parameters list */
2544
profiler->parameters->destroyList(profiler->parameters);
2546
/* Free profiler space */
2547
freeFunction(profiler);
2549
JITUINT32* specializer_method_callSite_secondProfiler_getCounterPointer(specializer_method_callSite_secondProfiler_t* profiler){
2551
assert(profiler != NULL);
2553
/* Return the required value */
2554
return &(profiler->counter);
2556
JITUINT32 specializer_method_callSite_secondProfiler_getCounterValue(specializer_method_callSite_secondProfiler_t* profiler){
2558
assert(profiler != NULL);
2560
/* Return the required value */
2561
return profiler->counter;
2563
JITUINT32* specializer_method_callSite_secondProfiler_getThresholdReachedPointer(specializer_method_callSite_secondProfiler_t* profiler){
2565
assert(profiler != NULL);
2567
/* Return the required value */
2568
return &(profiler->thresholdReached);
2570
JITUINT32 specializer_method_callSite_secondProfiler_isThresholdReached(specializer_method_callSite_secondProfiler_t* profiler){
2572
assert(profiler != NULL);
2574
/* Return the required value */
2575
return profiler->thresholdReached;
2577
JITUINT32 specializer_method_callSite_secondProfiler_getThreshold(specializer_method_callSite_secondProfiler_t* profiler){
2579
assert(profiler != NULL);
2581
/* Return the required value */
2582
return profiler->threshold;
2584
JITUINT32 specializer_method_callSite_secondProfiler_getBlockSize(specializer_method_callSite_secondProfiler_t* profiler){
2586
assert(profiler != NULL);
2588
/* Return the required value */
2589
return profiler->blockSize;
2591
XanList* specializer_method_callSite_secondProfiler_getStaticExpressions(specializer_method_callSite_secondProfiler_t* profiler, ir_specializer_t* specializer){
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 */
2602
assert(profiler != NULL);
2603
assert(specializer != NULL);
2605
/* Load the call site */
2606
callSite = (specializer_method_callSite_t*) profiler->callSiteContext;
2607
assert(callSite != NULL);
2610
/* Print the memory content */
2612
PDEBUG("SPECIALIZER : Memory Content: \n");
2613
printVoidVector(profiler->memory, callSite->hints->secondProfilerMemorySize, stderr, 8, 4);
2617
/* Create a new parameters with values list */
2618
parametersValuesAndFrequency = xanListNew(allocFunction, freeFunction, NULL);
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);
2626
parameterValues = specializer_computeValuesWithFrequency(profiler, parameter, specializer);
2627
if(parameterValues != NULL)
2628
parametersValuesAndFrequency->append(parametersValuesAndFrequency, parameterValues);
2631
/* Detect the static expression */
2632
staticExpressions = specializer_makeStaticExpressions(callSite->hints, parametersValuesAndFrequency, specializer);
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);
2640
/* Clean the parameter values */
2641
parameterValues->clean(parameterValues, specializer);
2644
/* Destroy the parameters values and frequency list */
2645
parametersValuesAndFrequency->destroyList(parametersValuesAndFrequency);
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;
2653
/* Return the active expression */
2654
return staticExpressions;
2657
/* ----------------------------------------- specializer_valueWithFrequency_t -----------------------------------------*/
2658
specializer_valueWithFrequency_t* newSpecializerValueWithFrequency(ir_specializer_t* specializer){
2660
specializer_valueWithFrequency_t* valueWithFrequency;
2663
assert(specializer != NULL);
2665
/* Allocate space */
2666
valueWithFrequency = (specializer_valueWithFrequency_t*) allocFunction((size_t)sizeof(specializer_valueWithFrequency_t));
2667
assert(valueWithFrequency != NULL);
2669
/* Initialize calls */
2670
valueWithFrequency->init = specializer_valueWithFrequency_init;
2671
valueWithFrequency->print = specializer_valueWithFrequency_print;
2672
valueWithFrequency->clean = specializer_valueWithFrequency_clean;
2674
/* Return the value with frequency */
2675
return valueWithFrequency;
2677
void specializer_valueWithFrequency_init(specializer_valueWithFrequency_t* valueWithFrequency, specializer_multiValueContainer valueContainer, JITFLOAT32 frequency){
2679
assert(valueWithFrequency != NULL);
2682
valueWithFrequency->valueContainer = valueContainer;
2683
valueWithFrequency->frequency = frequency;
2685
void specializer_valueWithFrequency_print(specializer_valueWithFrequency_t* valueWithFrequency, FILE* out){
2687
assert(valueWithFrequency != NULL);
2688
assert(out != NULL);
2690
/* Print the value with the frequency */
2691
printMultiValueContainer(valueWithFrequency->valueContainer, out);
2692
fprintf(out," [%5.2f%%]", valueWithFrequency->frequency*100);
2694
void specializer_valueWithFrequency_clean(specializer_valueWithFrequency_t* valueWithFrequency, ir_specializer_t* specializer){
2696
assert(valueWithFrequency != NULL);
2697
assert(specializer != NULL);
2699
/* Just clean itself */
2700
freeFunction(valueWithFrequency);
2703
/* ----------------------------------------- specializer_callSite_secondProfiler_param_values_t -----------------------------------------*/
2704
specializer_callSite_secondProfiler_param_values_t* newSpecializerValuesForParamPosition(ir_specializer_t* specializer){
2706
specializer_callSite_secondProfiler_param_values_t* values;
2709
assert(specializer != NULL);
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);
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;
2723
/* Return the variable*/
2726
void specializer_callSite_secondProfiler_param_values_init(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, JITUINT32 position, ir_specializer_t* specializer){
2728
assert(valuesForPosition != NULL);
2729
assert(specializer != NULL);
2731
/* Initialize the position */
2732
valuesForPosition->position = position;
2734
/* Initialize the vector of values */
2735
valuesForPosition->values = xanListNew(allocFunction, freeFunction, NULL);
2736
assert(valuesForPosition->values != NULL);
2738
void specializer_callSite_secondProfiler_param_values_print(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, FILE* out){
2740
specializer_valueWithFrequency_t* valueWithFrequency;
2744
assert(valuesForPosition != NULL);
2746
/* Print the position */
2747
fprintf(out, "%u : ", valuesForPosition->position);
2748
/* Print the values */
2749
if(valuesForPosition->getValuesNumber(valuesForPosition) == 0)
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))
2759
void specializer_callSite_secondProfiler_param_values_clean(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, ir_specializer_t* specializer){
2761
specializer_valueWithFrequency_t* valueWithFrequency;
2765
assert(valuesForPosition != NULL);
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);
2773
/* Destroy the values list */
2774
valuesForPosition->values->destroyList(valuesForPosition->values);
2776
/* Destroy itself */
2777
freeFunction(valuesForPosition);
2779
void specializer_callSite_secondProfiler_param_values_addValue(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, specializer_valueWithFrequency_t* valueWithFrequency){
2781
assert(valuesForPosition != NULL);
2782
assert(valueWithFrequency != NULL);
2784
/* Inject the value */
2785
valuesForPosition->values->append(valuesForPosition->values, valueWithFrequency);
2787
specializer_valueWithFrequency_t* specializer_callSite_secondProfiler_param_values_getValue(specializer_callSite_secondProfiler_param_values_t* valuesForPosition, JITUINT32 index){
2790
specializer_valueWithFrequency_t* valueWithFrequency;
2793
assert(valuesForPosition != NULL);
2794
assert(index < specializer_callSite_secondProfiler_param_values_getValuesNumber(valuesForPosition));
2797
item = valuesForPosition->values->getElementFromPositionNumber(valuesForPosition->values, index);
2798
assert(item != NULL);
2800
/* Load the element */
2801
valueWithFrequency = (specializer_valueWithFrequency_t*) valuesForPosition->values->data(valuesForPosition->values, item);
2802
assert(valueWithFrequency != NULL);
2804
/* Return the value */
2805
return valueWithFrequency;
2807
JITUINT32 specializer_callSite_secondProfiler_param_values_getValuesNumber(specializer_callSite_secondProfiler_param_values_t* valuesForPosition){
2809
assert(valuesForPosition != NULL);
2811
/* return the length of the values array */
2812
return valuesForPosition->values->length(valuesForPosition->values);
2815
/* ----------------------------------------- specializer_staticExpression_hint_t -----------------------------------------*/
2816
specializer_staticExpression_hint_t* newSpecializerStaticExpression(ir_specializer_t* specializer){
2818
specializer_staticExpression_hint_t* staticExpression = NULL;
2821
assert(specializer != NULL);
2823
/* Allocate space */
2824
staticExpression = (specializer_staticExpression_hint_t*) allocFunction((size_t)sizeof(specializer_staticExpression_hint_t));
2825
assert(staticExpression != NULL);
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;
2833
/* Return the value */
2834
return staticExpression;
2836
void specializer_staticExpression_hint_init(specializer_staticExpression_hint_t* staticExpression, specializer_expression_hint_t *expression, specializer_multiValueContainer *values){
2838
assert(staticExpression != NULL);
2839
assert(expression != NULL);
2840
assert(values != NULL);
2842
/* Assign the values to variables */
2843
staticExpression->expression = expression;
2844
staticExpression->values = values;
2846
void specializer_staticExpression_hint_print(specializer_staticExpression_hint_t* staticExpression, FILE* out){
2850
specializer_expression_hint_t *expression;
2853
assert(staticExpression != NULL);
2854
assert(out != NULL);
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))
2870
void specializer_staticExpression_hint_clean(specializer_staticExpression_hint_t* staticExpression, ir_specializer_t* specializer){
2872
assert(staticExpression != NULL);
2873
assert(specializer != NULL);
2875
/* Clean the values */
2876
freeFunction(staticExpression->values);
2879
freeFunction(staticExpression);
2881
JITBOOLEAN specializer_staticExpression_hint_equals(specializer_staticExpression_hint_t* staticExpression, specializer_staticExpression_hint_t* otherExpression){
2884
specializer_expression_hint_t *expression, *compareExpression;
2887
assert(staticExpression != NULL);
2888
assert(otherExpression != NULL);
2891
PDEBUG("SPECIALIZER : staticExpression : equals : Compare \"");
2892
staticExpression->print(staticExpression, stderr);
2893
PDEBUG("\" with \"");
2894
otherExpression->print(otherExpression, stderr);
2898
/* Check the values are equals */
2899
expression = staticExpression->expression;
2900
compareExpression = otherExpression->expression;
2901
assert(expression != NULL);
2902
assert(compareExpression != NULL);
2904
/* Check the expression depth */
2905
if(staticExpression->expression->depth != otherExpression->expression->depth)
2908
/* Search the expression */
2909
for(index = 0; index < staticExpression->expression->depth; index++){
2910
if(expression->position != compareExpression->position)
2912
if(staticExpression->values[index].type != otherExpression->values[index].type)
2914
if(specializer_multiValueContainer_compare(&staticExpression->values[index], &otherExpression->values[index]) != 0)
2916
/* Go to next expression */
2917
expression = expression->next;
2918
compareExpression = compareExpression->next;
2924
/* ----------------------------------------- specializer_method_callSite_dispatcher_t -----------------------------------------*/
2925
specializer_method_callSite_dispatcher_t* newSpecializerDispatcher(ir_specializer_t* specializer){
2927
specializer_method_callSite_dispatcher_t* dispatcher;
2930
assert(specializer != NULL);
2932
/* Allocate space */
2933
dispatcher = (specializer_method_callSite_dispatcher_t*) allocFunction((size_t)sizeof(specializer_method_callSite_dispatcher_t));
2934
assert(dispatcher != NULL);
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;
2945
/* Return the dispatcher */
2949
void specializer_method_callSite_dispatcher_init(specializer_method_callSite_dispatcher_t* dispatcher, void *callSiteContext){
2951
assert(dispatcher != NULL);
2952
assert(callSiteContext != NULL);
2954
/* Assign variables */
2955
dispatcher->callSiteContext = callSiteContext;
2957
/* Initialize variables */
2958
dispatcher->counter = 0;
2959
dispatcher->thresholdReached = JITFALSE;
2961
void specializer_method_callSite_dispatcher_print(specializer_method_callSite_dispatcher_t* dispatcher, FILE* out){
2963
assert(out != NULL);
2964
assert(dispatcher != NULL);
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");
2970
void specializer_method_callSite_dispatcher_clean(specializer_method_callSite_dispatcher_t* dispatcher, ir_specializer_t* specializer){
2972
assert(dispatcher != NULL);
2973
assert(specializer != NULL);
2975
/* From the caller call site list remove the UNSPECIALIZABLE CALL SITES */
2978
/* Just clean itself */
2979
freeFunction(dispatcher);
2981
JITINT32* specializer_method_callSite_dispatcher_getCounterPointer(specializer_method_callSite_dispatcher_t* dispatcher){
2983
assert(dispatcher != NULL);
2985
/* Return the counter pointer */
2986
return &(dispatcher->counter);
2988
JITINT32 specializer_method_callSite_dispatcher_getCounterValue(specializer_method_callSite_dispatcher_t* dispatcher){
2990
assert(dispatcher != NULL);
2992
/* Return the counter value */
2993
return dispatcher->counter;
2996
/* ----------------------------------------- specializer_specialized_method_wrapper_t -----------------------------------------*/
2997
specializer_specialized_method_wrapper_t* getSpecializerSpecializedMethodWrapper(ir_specializer_t* specializer){
2999
specializer_specialized_method_wrapper_t* specializedMethodWrapper = NULL;
3002
assert(specializer != NULL);
3004
/* Allocate space */
3005
specializedMethodWrapper = (specializer_specialized_method_wrapper_t*) allocFunction((size_t)sizeof(specializer_specialized_method_wrapper_t));
3006
assert(specializedMethodWrapper != NULL);
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;
3014
/* Return the method */
3015
return specializedMethodWrapper;
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){
3023
assert(specializedMethod != NULL);
3024
assert(specializedMethodWrapper != NULL);
3025
assert(staticExpression != NULL);
3026
assert(originalMethodWrapper != NULL);
3028
/* Assign Variables */
3029
specializedMethod->staticExpression = staticExpression;
3030
specializedMethod->originalMethodWrapper = originalMethodWrapper;
3031
specializedMethod->specializedMethodWrapper = specializedMethodWrapper;
3034
void specializer_specialized_method_wrapper_print (specializer_specialized_method_wrapper_t* specializedMethod, FILE* out, ir_specializer_t *specializer){
3035
ir_method_t *method;
3038
assert(specializedMethod != NULL);
3039
assert(out != NULL);
3040
assert(specializer != NULL);
3042
/* Fetch the method */
3043
method = specializedMethod->specializedMethodWrapper->getIRMethod(specializedMethod->specializedMethodWrapper);
3044
assert(method != NULL);
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));
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));
3056
/* Print the static expression */
3057
fprintf(out, "\tStatic Expression : ");
3058
specializedMethod->staticExpression->print(specializedMethod->staticExpression, out);
3062
void specializer_specialized_method_wrapper_clean(specializer_specialized_method_wrapper_t* specializedMethod, ir_specializer_t* specializer){
3064
assert(specializedMethod != NULL);
3065
assert(specializer != NULL);
3067
/* Clean the static expression */
3068
specializedMethod->staticExpression->clean(specializedMethod->staticExpression, specializer);
3071
freeFunction(specializedMethod);
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){
3077
assert(specializedMethod != NULL);
3078
assert(originalMethodWrapper != NULL);
3079
assert(staticExpression != NULL);
3081
/* Check the original wrapper */
3082
if(specializedMethod->originalMethodWrapper == originalMethodWrapper)
3085
/* Check the equity of the staticExpression */
3086
return specializedMethod->staticExpression->equals(specializedMethod->staticExpression,staticExpression);
3089
/* ----------------------------------------- specializer_method_callSite_type_dispatcher_t -----------------------------------------*/
3090
specializer_method_callSite_type_dispatcher_t* newSpecializerTypeDispatcher(ir_specializer_t* specializer){
3092
specializer_method_callSite_type_dispatcher_t* typeDispatcher;
3095
assert(specializer != NULL);
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);
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;
3110
/* Return the dispatcher */
3111
return typeDispatcher;
3113
void specializer_method_callSite_type_dispatcher_init(specializer_method_callSite_type_dispatcher_t* dispatcher, void *callSiteContext){
3115
assert(dispatcher != NULL);
3116
assert(callSiteContext != NULL);
3117
assert(((specializer_method_callSite_t*)callSiteContext)->call->type == IRVCALL);
3119
/* Assign the variable */
3120
dispatcher->callSiteContext = callSiteContext;
3122
/* Initialize the counter */
3123
dispatcher->counter = 0;
3124
dispatcher->thresholdReached = JITFALSE;
3127
void specializer_method_callSite_type_dispatcher_print(specializer_method_callSite_type_dispatcher_t* dispatcher, FILE* out){
3129
assert(out != NULL);
3130
assert(dispatcher != NULL);
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");
3136
void specializer_method_callSite_type_dispatcher_clean(specializer_method_callSite_type_dispatcher_t* dispatcher, ir_specializer_t* specializer){
3138
assert(dispatcher != NULL);
3139
assert(specializer != NULL);
3141
/* From the caller call site list remove the generated new direct call sites */
3144
/* Just clean itself */
3145
freeFunction(dispatcher);
3147
JITINT32* specializer_method_callSite_type_dispatcher_getCounterPointer(specializer_method_callSite_type_dispatcher_t* dispatcher){
3149
assert(dispatcher != NULL);
3151
/* Return the counter pointer */
3152
return &(dispatcher->counter);
3154
JITINT32 specializer_method_callSite_type_dispatcher_getCounterValue(specializer_method_callSite_type_dispatcher_t* dispatcher){
3156
assert(dispatcher != NULL);
3158
/* Return the counter value */
3159
return dispatcher->counter;
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;
3166
assert(callSite != NULL);
3169
* NOTE: Don't clear here the first profiler!!!!
3170
* It could be used by the execution thread even if changed the IR method!!
3172
* So here we can just remove the first profiler
3175
/* Remove the first profiler if necessary */
3176
if(callSite->firstProfiler != NULL){
3177
callSite->firstProfiler->remove(callSite->firstProfiler, callerWrapper);
3180
/* Create the second profiler */
3181
if(callSite->secondProfiler == NULL) {
3182
callSite->secondProfiler = newSpecializerSecondProfiler(specializer);
3183
callSite->secondProfiler->init(callSite->secondProfiler, callSite, specializer);
3185
callSite->secondProfiler->counter = 0;
3186
callSite->secondProfiler->thresholdReached = JITFALSE;
3189
/* If there is something useful to do for the dispatcher */
3190
if(callSite->secondProfiler->threshold > 0){
3192
/* Inject the second profiler */
3193
callSite->secondProfiler->inject(callSite->secondProfiler, callerWrapper, specializer);
3195
/* Change the status */
3196
callSite->status = SPECIALIZER_CALLSITE_STATUS_SECOND_PROFILER_INJECTED;
3202
/* We can inject the dispatcher since all possible parameters are constants */
3204
/* Detect the static expressions */
3205
staticExpressions = callSite->secondProfiler->getStaticExpressions(callSite->secondProfiler, specializer);
3207
/* If there are static expressions */
3208
if(staticExpressions != NULL){
3210
/* Create the new dispatcher */
3211
if(callSite->dispatcher == NULL){
3212
callSite->dispatcher = newSpecializerDispatcher(specializer);
3213
callSite->dispatcher->init(callSite->dispatcher, callSite);
3215
callSite->dispatcher->counter = 0;
3216
callSite->dispatcher->thresholdReached = JITFALSE;
3219
/* Change the state */
3220
callSite->status = SPECIALIZER_CALLSITE_STATUS_DISPATCHER_REQUEST;
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);
3226
/* Change the status */
3227
callSite->status = SPECIALIZER_CALLSITE_STATUS_DISPATCHER_INJECTED;
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;
3242
/* Change the status */
3243
callSite->status = SPECIALIZER_CALLSITE_STATUS_CLEAN;
3245
/* Inject the second profiler */
3246
callSite->firstProfiler->inject(callSite->firstProfiler, callerWrapper, specializer);
3248
/* Change the status */
3249
callSite->status = SPECIALIZER_CALLSITE_STATUS_FIRST_PROFILER_INJECTED;