Spaces:
Running
Running
| inlining | |
| collectInlineList | |
| "Make a list of methods that should be inlined." | |
| "Details: The method must not include any inline C, since the translator cannot | |
| currently map variable names in inlined C code. The #inline: directive may be | |
| used to override this for cases in which the C code or declarations are harmless. | |
| Methods to be inlined must be small or called from only one place." | |
| | methodsNotToInline callsOf inlineIt hasCCode nodeCount senderCount | |
| sel | | |
| methodsNotToInline := Set new: methods size. | |
| "build dictionary to record the number of calls to each method" | |
| callsOf := Dictionary new: methods size * 2. | |
| methods keys do: [ :s | callsOf at: s put: 0 ]. | |
| "For each method, scan its parse tree once to: | |
| 1. determine if the method contains C code or declarations | |
| 2. determine how many nodes it has | |
| 3. increment the sender counts of the methods it calls | |
| 4. determine if it includes any C declarations or code" | |
| inlineList := Set new: methods size * 2. | |
| methods do: [ :m | | |
| inlineIt := #dontCare. | |
| (translationDict includesKey: m selector) ifTrue: [ | |
| hasCCode := true. | |
| ] ifFalse: [ | |
| hasCCode := m declarations size > 0. | |
| nodeCount := 0. | |
| m parseTree nodesDo: [ :node | | |
| node isSend ifTrue: [ | |
| sel := node selector. | |
| (sel = #cCode: or: [sel = #cCode:inSmalltalk:]) | |
| ifTrue: [ hasCCode := true ]. | |
| senderCount := callsOf at: sel ifAbsent: [ nil ]. | |
| nil = senderCount ifFalse: [ | |
| callsOf at: sel put: senderCount + 1. | |
| ]. | |
| ]. | |
| nodeCount := nodeCount + 1. | |
| ]. | |
| inlineIt := m extractInlineDirective. "may be true, false, or | |
| #dontCare" | |
| ]. | |
| (inlineIt ~= true and: [hasCCode or: [inlineIt = false]]) ifTrue: [ | |
| "Don't inline if method has C code or if it contains a negative inline | |
| directive. If it contains a positive inline directive, permit inlining even | |
| if C code is present." | |
| methodsNotToInline add: m selector. | |
| ] ifFalse: [ | |
| ((nodeCount < 40) or: [inlineIt = true]) ifTrue: [ | |
| "inline if method has no C code and is either small or contains | |
| inline directive" | |
| inlineList add: m selector. | |
| ]. | |
| ]. | |
| ]. | |
| callsOf associationsDo: [ :assoc | | |
| ((assoc value = 1) and: [(methodsNotToInline includes: assoc key) | |
| not]) ifTrue: [ | |
| inlineList add: assoc key. | |
| ]. | |
| ]. |