Limitation of number os literals in a method?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Limitation of number os literals in a method?

gerard alis
I get that error when I try save a CLView builded with the UIBuilder

More than 256 literals referenced.
You must split or otherwise simplify this method.
The 257th literal is: 128

Select Proceed to continue, or close this window to cancel the operation.



How I can solve that problem? The method than I try save is generated programmatically...

Thanks
Reply | Threaded
Open this post in threaded view
|

Re: Limitation of number os literals in a method?

Eliot Miranda-2

On Sat, Jul 31, 2010 at 1:57 AM, nullPointer <[hidden email]> wrote:

I get that error when I try save a CLView builded with the UIBuilder

More than 256 literals referenced.
You must split or otherwise simplify this method.
The 257th literal is: 128

Select Proceed to continue, or close this window to cancel the operation.



How I can solve that problem? The method than I try save is generated
programmatically...

A proper fix requires new bytecodes, but if your method contains lots of explicit literal references, not just lots of message selectors or global varaiables, then there is a workaround.  The problem is due to encoding ranges in message send and literal reference bytecodes which are limited to a 0 to 255 single byte range.  There is no way around this limitation for message selectors or global variables without defining as bytecode with an extended range, but for explicit references if you put your literals in multiple arrays and access them by index you can pool the indices.  This can be done either at the compiler level or at the generation level, but you should start working at the generation level.  e.g.

myMethod
    | litPool0 litPool1 litPool2 litPool3 |
    litPool0 := #( a literal array with up to 128 elements).
    litPool1 := #( a literal array with up to 128 elements).
    litPool2 := #( a literal array with up to 128 elements).
    litPool3 := #( a literal array with up to 128 elements).
    ....
    self doSomethingWith: (litPool2 at: 127)
    ...

Your method now uses 1 literal for each pool and 1 literal for each array index other than 1 & 2 (1 & 2 have special bytecodes for them, as does the selector #at:).  So, assuming every index is used, the above method uses 4 + 126 = 130 literals, leaving 126 literals for selectors and globals, while providing access to 512 explicit literals in the pool literal arrays.  If you were to make the literal pools 256 elements large you'd loose because you'd need as many literals for the indices 3 to 256 as you saved from making the literal pool indirect.  So using more smaller pools increases the total number of  literals, e.g. with 8 64-element pools the above example uses 8 + 62 = 70 literals.

When we can get to it we need to redefine the bytecode set to extend these ranges.  Take a look at the VisualWorks bytecodes for a better encoding scheme.

HTH
Eliot
 

Thanks
--
View this message in context: http://forum.world.st/Limitation-of-number-os-literals-in-a-method-tp2308740p2308740.html
Sent from the Pharo Smalltalk mailing list archive at Nabble.com.

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Limitation of number os literals in a method?

gerard alis
In reply to this post by gerard alis
That is the method with the problems:

         http://paste.lisp.org/display/113020
Reply | Threaded
Open this post in threaded view
|

Re: Limitation of number os literals in a method?

Randal L. Schwartz
>>>>> "nullPointer" == nullPointer  <[hidden email]> writes:

nullPointer> That is the method with the problems:

nullPointer>          http://paste.lisp.org/display/113020

Eww.  I hope that method was generated automatically, and that humans
can maintain something that *generates* that method.

Otherwise, it's a strong candidate for being broken up into sane smaller
methods.

Lots of repetition too.  Could use a good refactoring, to invoke that
code driven from some sort of data structure.

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[hidden email]> <URL:http://www.stonehenge.com/merlyn/>
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Limitation of number os literals in a method?

gerard alis
XD
Reply | Threaded
Open this post in threaded view
|

Re: Limitation of number os literals in a method?

Stéphane Ducasse
In reply to this post by Eliot Miranda-2
eliot

in VW did windows spec faced such a limit and relied on such bytecodes?
I imagine that this is the case but...

Stef

On Jul 31, 2010, at 6:10 PM, Eliot Miranda wrote:

>
> On Sat, Jul 31, 2010 at 1:57 AM, nullPointer <[hidden email]> wrote:
>
> I get that error when I try save a CLView builded with the UIBuilder
>
> More than 256 literals referenced.
> You must split or otherwise simplify this method.
> The 257th literal is: 128
>
> Select Proceed to continue, or close this window to cancel the operation.
>
>
>
> How I can solve that problem? The method than I try save is generated
> programmatically...
>
> A proper fix requires new bytecodes, but if your method contains lots of explicit literal references, not just lots of message selectors or global varaiables, then there is a workaround.  The problem is due to encoding ranges in message send and literal reference bytecodes which are limited to a 0 to 255 single byte range.  There is no way around this limitation for message selectors or global variables without defining as bytecode with an extended range, but for explicit references if you put your literals in multiple arrays and access them by index you can pool the indices.  This can be done either at the compiler level or at the generation level, but you should start working at the generation level.  e.g.
>
> myMethod
>     | litPool0 litPool1 litPool2 litPool3 |
>     litPool0 := #( a literal array with up to 128 elements).
>     litPool1 := #( a literal array with up to 128 elements).
>     litPool2 := #( a literal array with up to 128 elements).
>     litPool3 := #( a literal array with up to 128 elements).
>     ....
>     self doSomethingWith: (litPool2 at: 127)
>     ...
>
> Your method now uses 1 literal for each pool and 1 literal for each array index other than 1 & 2 (1 & 2 have special bytecodes for them, as does the selector #at:).  So, assuming every index is used, the above method uses 4 + 126 = 130 literals, leaving 126 literals for selectors and globals, while providing access to 512 explicit literals in the pool literal arrays.  If you were to make the literal pools 256 elements large you'd loose because you'd need as many literals for the indices 3 to 256 as you saved from making the literal pool indirect.  So using more smaller pools increases the total number of  literals, e.g. with 8 64-element pools the above example uses 8 + 62 = 70 literals.
>
> When we can get to it we need to redefine the bytecode set to extend these ranges.  Take a look at the VisualWorks bytecodes for a better encoding scheme.
>
> HTH
> Eliot
>  
>
> Thanks
> --
> View this message in context: http://forum.world.st/Limitation-of-number-os-literals-in-a-method-tp2308740p2308740.html
> Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Limitation of number os literals in a method?

Stéphane Ducasse
In reply to this post by gerard alis
did you try to generate a string (I know this is not the same)

container := CLPanel new.
        container name: 'container'.
        container text: ''.
        container usePolymorphStyleMechanism: true.
        container balloonText: nil.
        container enabled: true.
        container location: 8@10.
        container extent: 653@460.
        container anchors: {false .false .false .false .}.
        container imageResource: nil.
        container style: {
(BorderStyle width: 0 color: Color transparent) .(Color r: 0.972 g: 0.972 b: 0.944) .(Color r: 0.972 g: 0.972 b: 0.944)
 .false .false .}.
        container minWidth: 2.
        container minHeight: 2.
        container layout: {ProportionalLayout .#rigid .#rigid .0 .#center .#none .0 .#topLeft .#topToBottom .#none .false .#topLeft .#none .0 .1073741823 .}.
        container visible = false.
        container openInWorld.

=>

        'Panel
                name: ''container''
                usePolymorphStyleMechanism: true.
                enabled: true.
                location: 8@10.
                extent: 653@460.
                anchors: {false .false .false .false .}.
                ...
                 minWidth: 2.
                 minHeight: 2.
                layout: #(ProportionalLayout .#rigid .#rigid .0 .#center .#none .0 .#topLeft .#topToBottom .#none .false .#topLeft .#none .0 .1073741823 ) .
                visible: false.'
       
then you parse only subexpressions delimited by #( )
and do a big perform: loop


what you could do is also to decouple the description from its interpretation using a Builder Design Pattern.
This way you do not bind the spec to your specific widgets and you could customize your build with different
widgets.

PS: Apparently you have a problem also

        container visible = false.
        =>
        container visible: false.

Stef

On Jul 31, 2010, at 10:57 AM, nullPointer wrote:

>
> I get that error when I try save a CLView builded with the UIBuilder
>
> More than 256 literals referenced.
> You must split or otherwise simplify this method.
> The 257th literal is: 128
>
> Select Proceed to continue, or close this window to cancel the operation.
>
>
>
> How I can solve that problem? The method than I try save is generated
> programmatically...
>
> Thanks
> --
> View this message in context: http://forum.world.st/Limitation-of-number-os-literals-in-a-method-tp2308740p2308740.html
> Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Limitation of number os literals in a method?

gerard alis
I´m looking for use of strings. That could be a solution...


        "container"
        container := CLPanel new.
        Compiler new evaluate: 'container name: ''container''.
        container text: ''''.
        container usePolymorphStyleMechanism: true.
        container balloonText: nil.
        container enabled: true.
        container location: 8@10.
        container extent: 653@460.
        container anchors: {false .false .false .false .}.
        container imageResource: nil.
        container style: {(BorderStyle width: 0 color: Color transparent) .(Color r: 0.972 g: 0.972 b: 0.944) .(Color r: 0.972 g: 0.972 b: 0.944) .false .false .}.
        container minWidth: 2.
        container minHeight: 2.
        container layout: {ProportionalLayout .#rigid .#rigid .0 .#center .#none .0 .#topLeft .#topToBottom .#none .false .#topLeft .#none .0 .1073741823 .}.
        container visible = false.
        container openInWorld.' in: thisContext to: nil.


I did the probe and works.
Reply | Threaded
Open this post in threaded view
|

Re: Limitation of number os literals in a method?

gerard alis
Finnally I call for each widget another method spec for configure it. Is possible now reproduce the same error, but is much more difficult.

http://paste.lisp.org/display/113020#1

I wait that version it seems less revolting to Randal  xD

I will upload that fix in SqueakSource UIBuilder project.

Anyway I don´t understant really the problem of limitation at 256 literals. Is for VM?

Regards
Reply | Threaded
Open this post in threaded view
|

Re: Limitation of number os literals in a method?

Stéphane Ducasse
a suggestion

lblImage does not read well in Smalltalk

labelImage is way better and you only need two extra characters.
Favor readibility.

Stef


On Aug 2, 2010, at 2:53 PM, nullPointer wrote:

>
> Finnally I call for each widget another method spec for configure it. Is
> possible now reproduce the same error, but is much more difficult.
>
> http://paste.lisp.org/display/113020#1
>
> I wait that version it seems less revolting to Randal  xD
>
> I will upload that fix in SqueakSource UIBuilder project.
>
> Anyway I don´t understant really the problem of limitation at 256 literals.
> Is for VM?

yes.
The problem is where do you store literals (nil, 'mystring' #asymbol #+) that are in a method.
The solution is that a method is composed on bytecode (stack language) and its store its literal in
a literal frame. So far nothing special.
Now the problem is that there are byte code to access literal objects and this bytecode is limited.
so you cannot store too many literals in a method.


>
> Regards
> --
> View this message in context: http://forum.world.st/Limitation-of-number-os-literals-in-a-method-tp2308740p2310239.html
> Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Limitation of number os literals in a method?

Igor Stasenko
If performance is not a problem , then you could wrap things in one array, like:

array := #(

( #selector1 arg1 arg2 arg3)
( #selector2 arg1 arg2 arg3)
( #selector3 arg1 arg2 arg3)
( #selector4 arg1 arg2 arg3)
...
)

then in compiled method you'll have only a single literal - and outer
array, and everything else will sit within it:

array do: [:msg |
  container perform: msg first withArguments: msg allButFirst ]

--
Best regards,
Igor Stasenko AKA sig.

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Limitation of number os literals in a method?

Stéphane Ducasse
ok so now this is exactly the VW windowspec and I understand why they did it like that.
They have a declarative expression with multiple possible interpretations

I was not sure that literal inside arrays where in the literal frame but I was stupid.

Stef

> If performance is not a problem , then you could wrap things in one array, like:
>
> array := #(
>
> ( #selector1 arg1 arg2 arg3)
> ( #selector2 arg1 arg2 arg3)
> ( #selector3 arg1 arg2 arg3)
> ( #selector4 arg1 arg2 arg3)
> ...
> )
>
> then in compiled method you'll have only a single literal - and outer
> array, and everything else will sit within it:
>
> array do: [:msg |
>  container perform: msg first withArguments: msg allButFirst ]
>
> --
> Best regards,
> Igor Stasenko AKA sig.
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project