Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Memory Allocation & Self Modifying Code

From: robbo1mark:aol at: 2-Aug-2001 8:52

Memory Allocation & Self Modifying Code This mailing will discuss some predictive theories on REBOL Block! memory allocation and also how it effects the result of performing some self modifying code expressions. DISCLAIMER: I only had REBOL/Core 2.5 running on Windows 95 available whilst performing these tests / enquiries so I can only make statements about results I found in relation to this REBOL version and platform combination, I do not know how this compares to other REBOL versions & platforms etc. REBOL Block! Memory Allocation. In relation to an earlier thread this week What Kind of Bug is This? I was intrigued as to why a self modifying REBOL expression always appeared to make errors at the same places but not at others. Ladislav Mecir mentioned that this was probably due to the REBOL implementation issues and Brian Hawley reckoned it was most likely due to the way memory is allocated for REBOL Block! values. This guided my thinking & enquiries, and if you wish you can repeat my tests with the following code.
>> Echo %test.txt >> a: [ append a [+ 1] 1] >> loop 1000 [ print [ do a newline ] print [ "Block length: " length? a
Bytes used: ((length? a) * 16) ] ] I ran this code until REBOL crashed at the following stage 254 Block Length: 510 Bytes Used 8160 Careful examination of Test.txt file reveals the following positions where REBOL makes errors. Block Length: 14 Bytes Used 224 6 Block Length: 16 Bytes Used 256 8 ..... Block Length: 28 Bytes Used 448 14 Block Length: 30 Bytes Used 480 14 Block Length: 32 Bytes Used 512 16 ..... Block Length: 28 Bytes Used 448 14 Block Length: 30 Bytes Used 480 14 Block Length: 32 Bytes Used 512 16 ..... Block length: 60 Bytes used: 960 30 Block length: 62 Bytes used: 992 30 Block length: 64 Bytes used: 1024 32 ..... Block Length: 124 Bytes Used 1984 62 Block Length: 126 Bytes Used 2016 62 Block Length: 128 Bytes Used 2048 64 ..... Block Length: 252 Bytes Used 4032 126 Block Length: 254 Bytes Used 4064 126 Block Length: 256 Bytes Used 4096 128 ..... Block Length: 380 Bytes Used 6080 190 Block Length: 382 Bytes Used 6112 190 Block Length: 384 Bytes Used 6144 ..... 254 Block Length: 510 Bytes Used 8160 ###### REBOL CRASHES HERE ########## Now it was earlier postulated on this list that in BLOCK! values REBOL allocates approximately 16 bytes per value. ( Or to put it another way all REBOL values / datatypes could be contained within a 16 byte value with pointers used to areas of memory storage for series! type values like block! and string! data. ) REBOL Tech staff also pointed out that users shouldn't speculate on such things because it can be highly platform dependant and also subject to change, which is fair enough and true, but specualting on inner secrets of REBOL is interesting ( well to me anyway ; ) so I'll continue. The following code would appear to validate the theory of approximately 16 bytes per value for Block! types.
>> a: system/stats
== 1463472
>> make block! 100000
== []
>> b: system/stats
== 3065008
>> ( b - a ) / 100000
== 16.01536
>>
So assuming that each value is ~16 bytes we can return to the results of Test.txt and we see an interesting pattern emerging. REBOL Block! it would seem automatically allocates sufficient memory to hold 16 values or 256 bytes. The first error occurs as the evaluted block encroaches on this limit of 16 values. The next error occurs as the evaluated block encroaches upon 32 values, so we can infer that REBOL allocated another 256 bytes block space in addition to the original 256 bytes. The next errors occur at encroaching 64 , 128, 256, 384 & 512 values.
>From this I deduce that REBOL Block!'s allocate memory thus...
STAGE 1. 256 bytes or 16 values initial allocation STAGE 2. 256 bytes or 16 values additional allocation STAGE 3. 512 bytes or 32 values additonal allocation STAGE 4. 1024 bytes or 64 values additional allocation STAGE 5. 2048 bytes or 128 values each additional allocation thereafter. If we think in terms of THE LANGUAGE THAT MUST NOT BE MENTIONED and do our own memory allocation in a new REBOL session we see that the self modifying block expression runs correctly without any glitches at least until it reaches our set block! allocation limit. Try this....
>> echo %test2.txt >> a: make block! 1024
== []
>> insert a [append a [+ 1] 1]
== []
>> a
== [append a [+ 1] 1]
>> loop 1000 [ print [ do a newline ] print [ "Block length: " length? a
Bytes used: ((length? a) * 16) ] ] Examining Test2.txt we see that REBOL happily & correctly evaluates away until we get to my Block! set upper limit of 1024 values. Block length: 1018 Bytes used: 16288 509 Block length: 1020 Bytes used: 16320 510 Block length: 1022 Bytes used: 16352 ###### REBOL CRASHES HERE ############# So we can see that by utilising Memory Allocation techniques just as one would in THE LANGUAGE WE DARE NOT MENTION IT'S NAME we can happily use self modifying code in this manner. Does anybody have any comments or obtain differeing results on their appropriate REBOL version / platform combination, as I'm interested to see how REBOL performs in those instances. Feel free to comment here. Cheers everybody, Mark Dickson