138 |
138 |
139 blockInvocationInfo isNil ifTrue:[ |
139 blockInvocationInfo isNil ifTrue:[ |
140 blockInvocationInfo := OrderedCollection new. |
140 blockInvocationInfo := OrderedCollection new. |
141 ]. |
141 ]. |
142 blockEntryInfo := BlockExecutionInfo new cleanInfo. |
142 blockEntryInfo := BlockExecutionInfo new cleanInfo. |
|
143 blockEntryInfo startPosition:aBlockNode startPosition endPosition:aBlockNode endPosition. |
143 blockInvocationInfo add:blockEntryInfo. |
144 blockInvocationInfo add:blockEntryInfo. |
144 |
145 |
145 countCode := |
146 countCode := |
146 StatementNode |
147 StatementNode |
147 expression:(MessageNode |
148 expression:(MessageNode |
155 ] ifFalse:[ |
156 ] ifFalse:[ |
156 countCode nextStatement:aBlockNode statements. |
157 countCode nextStatement:aBlockNode statements. |
157 aBlockNode statements:countCode. |
158 aBlockNode statements:countCode. |
158 ]. |
159 ]. |
159 |
160 |
160 "Modified: / 27-04-2010 / 14:52:38 / cg" |
161 "Modified: / 28-04-2010 / 15:55:30 / cg" |
161 ! |
162 ! |
162 |
163 |
163 addBlockCountersToEachBlockIn:aCollection |
164 addBlockCountersToEachBlockIn:aCollection |
164 aCollection do:[:eachNode | |
165 aCollection do:[:eachNode | |
165 eachNode isBlockNode ifTrue:[ |
166 eachNode isBlockNode ifTrue:[ |
191 "Created: / 27-04-2010 / 12:17:22 / cg" |
192 "Created: / 27-04-2010 / 12:17:22 / cg" |
192 ! ! |
193 ! ! |
193 |
194 |
194 !InstrumentingCompiler methodsFor:'code generation-hooks'! |
195 !InstrumentingCompiler methodsFor:'code generation-hooks'! |
195 |
196 |
|
197 blockNodeRewriteHookFor:aBlockNode |
|
198 "/ add a counter for the block |
|
199 self addBlockCounterTo:aBlockNode. |
|
200 ^ aBlockNode |
|
201 |
|
202 "Created: / 28-04-2010 / 14:21:27 / cg" |
|
203 ! |
|
204 |
196 messageNodeRewriteHookFor:aMessageNode |
205 messageNodeRewriteHookFor:aMessageNode |
197 "/ argument could be a constantNode (due to contant-folding optimization) |
206 "/ see blockNodeRewriter... |
198 aMessageNode isConstant ifTrue:[^ aMessageNode]. |
207 |
199 ( |
208 "/ "/ argument could be a constantNode (due to contant-folding optimization) |
200 #( |
209 "/ aMessageNode isConstant ifTrue:[^ aMessageNode]. |
201 ifTrue: |
210 "/ ( |
202 ifFalse: |
211 "/ #( |
203 ifTrue:ifFalse: |
212 "/ ifTrue: |
204 ifFalse:ifTrue: |
213 "/ ifFalse: |
205 ) |
214 "/ ifTrue:ifFalse: |
206 includes:aMessageNode selector |
215 "/ ifFalse:ifTrue: |
207 ) ifTrue:[ |
216 "/ ) |
208 "/ add a counter for the block |
217 "/ includes:aMessageNode selector |
209 self addBlockCountersToEachBlockIn:(aMessageNode arguments) |
218 "/ ) ifTrue:[ |
210 ]. |
219 "/ "/ add a counter for the block |
|
220 "/ self addBlockCountersToEachBlockIn:(aMessageNode arguments) |
|
221 "/ ]. |
211 ^ aMessageNode |
222 ^ aMessageNode |
212 |
223 |
213 "Created: / 27-04-2010 / 11:43:22 / cg" |
224 "Created: / 27-04-2010 / 11:43:22 / cg" |
214 "Modified: / 27-04-2010 / 12:45:27 / cg" |
225 "Modified: / 28-04-2010 / 14:22:05 / cg" |
215 ! |
226 ! |
216 |
227 |
217 startCodeGenerationHookOn:codeStream |
228 startCodeGenerationHookOn:codeStream |
218 methodEntryInfo := MethodInvocationInfo new. |
229 methodEntryInfo := MethodInvocationInfo new. |
219 |
230 |
275 |
286 |
276 "Created: / 27-04-2010 / 13:45:15 / cg" |
287 "Created: / 27-04-2010 / 13:45:15 / cg" |
277 ! |
288 ! |
278 |
289 |
279 characterPosition |
290 characterPosition |
280 ^ characterPosition |
291 ^ startPosition |
281 |
292 |
282 "Created: / 23-06-2006 / 13:31:19 / cg" |
293 "Created: / 23-06-2006 / 13:31:19 / cg" |
|
294 "Modified: / 28-04-2010 / 15:54:24 / cg" |
283 ! |
295 ! |
284 |
296 |
285 characterPosition:something |
297 characterPosition:something |
286 characterPosition := something. |
298 startPosition := something. |
287 |
299 |
288 "Created: / 23-06-2006 / 13:31:19 / cg" |
300 "Created: / 23-06-2006 / 13:31:19 / cg" |
|
301 "Modified: / 28-04-2010 / 15:54:30 / cg" |
289 ! |
302 ! |
290 |
303 |
291 count |
304 count |
292 ^ count |
305 ^ count |
293 |
306 |
294 "Created: / 23-06-2006 / 13:31:28 / cg" |
307 "Created: / 23-06-2006 / 13:31:28 / cg" |
|
308 ! |
|
309 |
|
310 endPosition |
|
311 ^ endPosition |
|
312 |
|
313 "Created: / 28-04-2010 / 15:57:14 / cg" |
|
314 ! |
|
315 |
|
316 startPosition |
|
317 ^ startPosition |
|
318 |
|
319 "Created: / 28-04-2010 / 15:54:26 / cg" |
|
320 ! |
|
321 |
|
322 startPosition:startArg endPosition:endArg |
|
323 startPosition := startArg. |
|
324 endPosition := endArg. |
|
325 |
|
326 "Created: / 28-04-2010 / 15:54:47 / cg" |
295 ! ! |
327 ! ! |
296 |
328 |
297 !InstrumentingCompiler::BlockExecutionInfo methodsFor:'cleanup'! |
329 !InstrumentingCompiler::BlockExecutionInfo methodsFor:'cleanup'! |
298 |
330 |
299 cleanInfo |
331 cleanInfo |
312 owningMethod changed:#methodInfo |
344 owningMethod changed:#methodInfo |
313 ]. |
345 ]. |
314 |
346 |
315 "Created: / 23-06-2006 / 13:31:16 / cg" |
347 "Created: / 23-06-2006 / 13:31:16 / cg" |
316 "Modified: / 27-04-2010 / 14:03:29 / cg" |
348 "Modified: / 27-04-2010 / 14:03:29 / cg" |
|
349 ! ! |
|
350 |
|
351 !InstrumentingCompiler::BlockExecutionInfo methodsFor:'queries'! |
|
352 |
|
353 hasBeenExecuted |
|
354 ^ count > 0 |
|
355 |
|
356 "Created: / 28-04-2010 / 14:39:46 / cg" |
317 ! ! |
357 ! ! |
318 |
358 |
319 !InstrumentingCompiler::MethodInvocationInfo methodsFor:'accessing'! |
359 !InstrumentingCompiler::MethodInvocationInfo methodsFor:'accessing'! |
320 |
360 |
321 callingMethodsDo:aBlock |
361 callingMethodsDo:aBlock |
473 "invoked by instrumented compiled code, upon method entry" |
513 "invoked by instrumented compiled code, upon method entry" |
474 |
514 |
475 |sender sendingMethod infoPerMethod viaPerform| |
515 |sender sendingMethod infoPerMethod viaPerform| |
476 |
516 |
477 sender := aContext sender methodHome. |
517 sender := aContext sender methodHome. |
478 sendingMethod := sender method. |
518 sender isNil ifTrue:[ |
479 viaPerform := false. |
519 ^ self. |
480 |
520 ] ifFalse:[ |
481 (sendingMethod mclass == Object |
|
482 and:[ sendingMethod selector startsWith:'perform:'] ) ifTrue:[ |
|
483 "/ Transcript showCR:('%1 [info]: skipping #perform' bindWith:self class nameWithoutPrefix). |
|
484 sender := sender sender methodHome. |
|
485 sendingMethod := sender method. |
521 sendingMethod := sender method. |
486 viaPerform := true. |
522 viaPerform := false. |
|
523 |
|
524 (sendingMethod mclass == Object |
|
525 and:[ sendingMethod selector startsWith:'perform:'] ) ifTrue:[ |
|
526 "/ Transcript showCR:('%1 [info]: skipping #perform' bindWith:self class nameWithoutPrefix). |
|
527 sender := sender sender methodHome. |
|
528 sendingMethod := sender method. |
|
529 viaPerform := true. |
|
530 ]. |
487 ]. |
531 ]. |
488 |
532 |
489 infoPerSendingMethod isNil ifTrue:[ |
533 infoPerSendingMethod isNil ifTrue:[ |
490 infoPerSendingMethod := IdentityDictionary new. |
534 infoPerSendingMethod := IdentityDictionary new. |
491 ]. |
535 ]. |
493 at:sendingMethod |
537 at:sendingMethod |
494 ifAbsentPut:[ MethodInvocationInfoPerSendingMethod new ]. |
538 ifAbsentPut:[ MethodInvocationInfoPerSendingMethod new ]. |
495 |
539 |
496 infoPerMethod entry:aContext viaPerform:viaPerform |
540 infoPerMethod entry:aContext viaPerform:viaPerform |
497 |
541 |
498 "Modified: / 27-04-2010 / 18:19:04 / cg" |
542 "Modified: / 28-04-2010 / 16:09:04 / cg" |
499 ! ! |
543 ! ! |
500 |
544 |
501 !InstrumentingCompiler::MethodInvocationInfo::MethodInvocationInfoPerReceiverClass::MethodInvocationInfoPerSendingMethod methodsFor:'accessing'! |
545 !InstrumentingCompiler::MethodInvocationInfo::MethodInvocationInfoPerReceiverClass::MethodInvocationInfoPerSendingMethod methodsFor:'accessing'! |
502 |
546 |
503 invokedViaPerform |
547 invokedViaPerform |