ByteCodeCompiler.st
changeset 1810 977902a043fe
parent 1799 121a51d444a6
child 1813 b6662812c373
equal deleted inserted replaced
1809:007cb2a08623 1810:977902a043fe
    13 "{ Package: 'stx:libcomp' }"
    13 "{ Package: 'stx:libcomp' }"
    14 
    14 
    15 Parser subclass:#ByteCodeCompiler
    15 Parser subclass:#ByteCodeCompiler
    16 	instanceVariableNames:'codeBytes codeIndex litArray stackDelta extra lineno extraLiteral
    16 	instanceVariableNames:'codeBytes codeIndex litArray stackDelta extra lineno extraLiteral
    17 		maxStackDepth relocList methodTempVars numTemp maxNumTemp
    17 		maxStackDepth relocList methodTempVars numTemp maxNumTemp
    18 		methodClass extraOP allLiterals'
    18 		methodClass extraOP allLiterals allIdenticalLiterals'
    19 	classVariableNames:'JumpToAbsJump ShareCode ListCompiledMethods NewCodeSet
    19 	classVariableNames:'JumpToAbsJump ShareCode ListCompiledMethods NewCodeSet
    20 		NewPrimitives'
    20 		NewPrimitives'
    21 	poolDictionaries:''
    21 	poolDictionaries:''
    22 	category:'System-Compiler'
    22 	category:'System-Compiler'
    23 !
    23 !
  2496 
  2496 
  2497 addLiteral:anObject
  2497 addLiteral:anObject
  2498     "add a literal to the literalArray - watch for and eliminate
  2498     "add a literal to the literalArray - watch for and eliminate
  2499      duplicates. return the index of the literal in the Array"
  2499      duplicates. return the index of the literal in the Array"
  2500 
  2500 
  2501     |index "{ Class: SmallInteger }" oldLit class|
  2501     |index "{ Class: SmallInteger }" oldLit class sharable sharableValue|
  2502 
  2502 
  2503     litArray isNil ifTrue:[
  2503     litArray isNil ifTrue:[
  2504         litArray := OrderedCollection with:anObject.
  2504         litArray := OrderedCollection with:anObject.
  2505         ^ 1
  2505         ^ 1
  2506     ].
  2506     ].
  2507 
  2507 
  2508     "/ searching a set is *much* faster; the code below starts to
  2508     sharable := sharableValue := false.
       
  2509     class := anObject class.
       
  2510     class == Symbol 
       
  2511         ifTrue:[ sharable := true ]
       
  2512         ifFalse:[
       
  2513             ((class == String) or:[class == Array or:[class == ByteArray]]) ifTrue:[
       
  2514                 anObject size == 0 ifTrue:[
       
  2515                     sharable := true
       
  2516                 ]
       
  2517             ] ifFalse:[
       
  2518                 ((class == Float) or:[class == Fraction or:[class == LargeInteger]]) ifTrue:[
       
  2519                     sharableValue := true
       
  2520                 ]
       
  2521             ]
       
  2522         ].
       
  2523 
       
  2524     (sharable not and:[sharableValue not]) ifTrue:[
       
  2525         litArray add:anObject.
       
  2526         index := litArray size.
       
  2527         ^ index.
       
  2528     ].
       
  2529 
       
  2530     "/ searching a dictionary is *much* faster; the code below starts to
  2509     "/ keep track of literals whenever we have collected more than a threshold
  2531     "/ keep track of literals whenever we have collected more than a threshold
  2510     allLiterals notNil ifTrue:[
  2532     allLiterals notNil ifTrue:[
  2511         (allLiterals includes:anObject) ifFalse:[
  2533         sharable ifTrue:[
  2512             litArray add:anObject.
  2534             index := allLiterals at:anObject ifAbsent:nil.
  2513             allLiterals add:anObject.
  2535             index isNil ifTrue:[
  2514             ^ litArray size.
  2536                 litArray add:anObject.
       
  2537                 index := litArray size.
       
  2538                 allLiterals at:anObject put:index.
       
  2539                 ^ index.
       
  2540             ].
       
  2541             (litArray at:index) class ~~ anObject class ifTrue:[
       
  2542                 index := nil.
       
  2543             ].
  2515         ].
  2544         ].
  2516     ].
  2545     ].
  2517 
  2546     index isNil ifTrue:[
  2518     index := litArray identityIndexOf:anObject.
  2547         index := litArray identityIndexOf:anObject.
       
  2548     ].
  2519     (index == 0) ifTrue:[
  2549     (index == 0) ifTrue:[
  2520         "
  2550         "
  2521          reuse constants if same value and same class
  2551          reuse constants if same value and same class
  2522         "
  2552         "
  2523         class := anObject class.
       
  2524         ((class == Float) 
  2553         ((class == Float) 
  2525         or:[class == Fraction
  2554         or:[class == Fraction
  2526         or:[class == LargeInteger
  2555         or:[class == LargeInteger
  2527         "or:[class == String] --only if literalString option has been added---" ]]) ifTrue:[
  2556         "or:[class == String] --only if literalString option has been added---" ]]) ifTrue:[
  2528             index := litArray indexOf:anObject.
  2557             index := litArray indexOf:anObject.
  2553         (index == 0) ifTrue:[
  2582         (index == 0) ifTrue:[
  2554             litArray add:anObject.
  2583             litArray add:anObject.
  2555             index := litArray size.
  2584             index := litArray size.
  2556             index > 30 ifTrue:[
  2585             index > 30 ifTrue:[
  2557                 allLiterals isNil ifTrue:[    
  2586                 allLiterals isNil ifTrue:[    
  2558                     allLiterals := litArray asSet.
  2587                     allLiterals := Dictionary new.
       
  2588                     litArray keysAndValuesDo:[:idx :lit | allLiterals at:lit put:idx].
  2559                 ].
  2589                 ].
  2560                 allLiterals add:anObject.
  2590                 allLiterals at:anObject put:index.
  2561             ].
  2591             ].
  2562         ].
  2592         ].
  2563     ].
  2593     ].
  2564 
  2594 
  2565     ^ index
  2595     ^ index
  3199     (sel == #isNil) ifTrue:[^ false].
  3229     (sel == #isNil) ifTrue:[^ false].
  3200     (sel == #notNil) ifTrue:[^ false].
  3230     (sel == #notNil) ifTrue:[^ false].
  3201     ^ true
  3231     ^ true
  3202 !
  3232 !
  3203 
  3233 
  3204 isBuiltIn1ArgSelector:sel forReceiver:receiver
  3234 isBuiltInSelector:sel forReceiver:receiver
  3205     "return true, if selector sel is built-in.
  3235     "return true, if selector sel is built-in. 
  3206      (i.e. there is a single bytecode for it)"
  3236      (i.e. there is a single bytecode for it)"
  3207 
  3237 
  3208     (sel == #at:)     ifTrue:[^ true].
  3238     (sel == #value)  ifTrue:[^ true].
  3209     (sel == #value:)  ifTrue:[^ true].
  3239     (sel == #value:) ifTrue:[^ true].
  3210     (sel == #bitAnd:) ifTrue:[^ true].
  3240     (sel == #class)  ifTrue:[^ true].
  3211     (sel == #bitOr:)  ifTrue:[^ true].
  3241     (sel == #size)   ifTrue:[^ true].
  3212     (sel == #new:)    ifTrue:[^ true].
  3242     (sel == #isNil)  ifTrue:[^ true].
       
  3243     (sel == #notNil) ifTrue:[^ true].
       
  3244     (sel == #not)    ifTrue:[^ true].
       
  3245 
       
  3246     (sel == #new)    ifTrue:[^ true].
       
  3247     (sel == #basicNew) ifTrue:[
       
  3248         "/ this one is critical - some redefine it
       
  3249         receiver isGlobal ifTrue:[
       
  3250             (#('String' 'ByteArray' 'Array'
       
  3251                'Point' 'Rectangle' 'Object')
       
  3252             includes:receiver name) ifTrue:[^ true].
       
  3253         ].
       
  3254     ].
  3213     (sel == #basicNew:) ifTrue:[
  3255     (sel == #basicNew:) ifTrue:[
  3214 	"/ this one is critical - some redefine it
  3256         "/ this one is critical - some redefine it
  3215 	receiver isGlobal ifTrue:[
  3257         receiver isGlobal ifTrue:[
  3216 	    (#('String' 'ByteArray' 'Array'
  3258             (#('String' 'ByteArray' 'Array'
  3217 	      'Point' 'Rectangle' 'Object')
  3259               'Point' 'Rectangle' 'Object')
  3218 	    includes:receiver name) ifTrue:[^ true].
  3260             includes:receiver name) ifTrue:[^ true].
  3219 	].
  3261         ].
  3220     ].
  3262     ].
  3221     ^ false
       
  3222 
       
  3223     "Created: 17.4.1996 / 22:33:13 / cg"
       
  3224     "Modified: 4.6.1997 / 12:24:18 / cg"
       
  3225 !
       
  3226 
       
  3227 isBuiltIn2ArgSelector:sel forReceiver:receiver
       
  3228     "return true, if selector sel is built-in.
       
  3229      (i.e. there is a single bytecode for it)"
       
  3230 
       
  3231     (sel == #at:put:) ifTrue:[^ true].
       
  3232     ^ false
       
  3233 
       
  3234     "Created: 17.4.1996 / 22:33:16 / cg"
       
  3235 !
       
  3236 
       
  3237 isBuiltInBinarySelector:sel forReceiver:receiver
       
  3238     "return true, if binary selector sel is built-in. 
       
  3239      (i.e. there is a single bytecode for it)"
       
  3240 
  3263 
  3241     sel == #== ifTrue:[^ true].
  3264     sel == #== ifTrue:[^ true].
  3242     sel == #~~ ifTrue:[^ true].
  3265     sel == #~~ ifTrue:[^ true].
  3243     sel == #=  ifTrue:[^ true].
  3266     sel == #=  ifTrue:[^ true].
  3244     sel == #~= ifTrue:[^ true].
  3267     sel == #~= ifTrue:[^ true].
  3249     sel == #>  ifTrue:[^ true].
  3272     sel == #>  ifTrue:[^ true].
  3250     sel == #>= ifTrue:[^ true].
  3273     sel == #>= ifTrue:[^ true].
  3251     sel == #*  ifTrue:[^ true].
  3274     sel == #*  ifTrue:[^ true].
  3252     sel == #&  ifTrue:[^ true].
  3275     sel == #&  ifTrue:[^ true].
  3253     sel == #|  ifTrue:[^ true].
  3276     sel == #|  ifTrue:[^ true].
  3254     ^ false
  3277 
  3255 
  3278     (sel == #at:)     ifTrue:[^ true].
  3256     "Created: 17.4.1996 / 22:34:27 / cg"
  3279     (sel == #at:put:) ifTrue:[^ true].
  3257     "Modified: 4.6.1997 / 12:24:00 / cg"
  3280     (sel == #bitAnd:) ifTrue:[^ true].
  3258 !
  3281     (sel == #bitOr:)  ifTrue:[^ true].
  3259 
  3282     (sel == #new:)    ifTrue:[^ true].
  3260 isBuiltInUnarySelector:sel forReceiver:receiver
  3283 
  3261     "return true, if unary selector sel is built-in. 
       
  3262      (i.e. there is a single bytecode for it)"
       
  3263 
       
  3264     (sel == #value)  ifTrue:[^ true].
       
  3265     (sel == #class)  ifTrue:[^ true].
       
  3266     (sel == #size)   ifTrue:[^ true].
       
  3267     (sel == #isNil)  ifTrue:[^ true].
       
  3268     (sel == #notNil) ifTrue:[^ true].
       
  3269     (sel == #not)    ifTrue:[^ true].
       
  3270 
       
  3271     (sel == #new)    ifTrue:[^ true].
       
  3272     (sel == #basicNew) ifTrue:[
       
  3273 	"/ this one is critical - some redefine it
       
  3274 	receiver isGlobal ifTrue:[
       
  3275 	    (#('String' 'ByteArray' 'Array'
       
  3276 	       'Point' 'Rectangle' 'Object')
       
  3277 	    includes:receiver name) ifTrue:[^ true].
       
  3278 	].
       
  3279     ].
       
  3280     ^ false
  3284     ^ false
  3281 
  3285 
  3282     "Created: 17.4.1996 / 22:32:16 / cg"
  3286     "Created: 17.4.1996 / 22:32:16 / cg"
  3283     "Modified: 4.6.1997 / 12:23:30 / cg"
  3287     "Modified: 4.6.1997 / 12:23:30 / cg"
  3284 !
  3288 !
  3374 ! !
  3378 ! !
  3375 
  3379 
  3376 !ByteCodeCompiler class methodsFor:'documentation'!
  3380 !ByteCodeCompiler class methodsFor:'documentation'!
  3377 
  3381 
  3378 version
  3382 version
  3379     ^ '$Header: /cvs/stx/stx/libcomp/ByteCodeCompiler.st,v 1.241 2006-08-08 21:37:08 cg Exp $'
  3383     ^ '$Header: /cvs/stx/stx/libcomp/ByteCodeCompiler.st,v 1.242 2006-08-09 12:00:53 cg Exp $'
  3380 ! !
  3384 ! !
  3381 
  3385 
  3382 ByteCodeCompiler initialize!
  3386 ByteCodeCompiler initialize!