change layout to type

This commit is contained in:
Torsten Ruger 2016-02-25 19:10:56 -08:00
parent ed94806e36
commit 48e4c8a27d
5 changed files with 29 additions and 28 deletions

View File

@ -42,7 +42,7 @@ a reference tags the class for when that is known at compile time. If so i can d
inline the get's implementation. If not i could cache, but that's for later.
As a furhter example on this, when one function has two calls on the same object, the layout must only be retrieved once.
ie in the sequences getLayout, determine method, call, the first step can be ommitted for the second call as a layout is
ie in the sequences getType, determine method, call, the first step can be ommitted for the second call as a layout is
constant.
And as a final bonus of all this clarity, i immediately spotted the inconcistency in my own design: The frame i designed
@ -70,7 +70,7 @@ smalltalk (like ruby and...) all objects have a class. But some of the smalltalk
objects. This was supposed to make things easier and faster. Slots were a bit like instance variables, but there were no
classes to rule them.
Now in ruby, any object can have any variables anyway, but they incur a dynamic lookup. Layouts on the other hand are like
slots, and keeping each Layout constant (while an object can change layouts) makes it possible to have completely
Now in ruby, any object can have any variables anyway, but they incur a dynamic lookup. Types on the other hand are like
slots, and keeping each Type constant (while an object can change layouts) makes it possible to have completely
dynamic behaviour (smalltalk/ruby) **and** use a slot-like (self) system with constant lookup speed. Admittatley the
constantcy only affects cache hits, but as most systems are not dynamic most of the time, that is almost always.

View File

@ -1,9 +1,9 @@
---
layout: salama
title: Memory layout and management
title: Types, memory layout and management
---
Memory management must be one of the main horrors of computing. That's why garbage collected languages like ruby are so great. Even simple malloc implementations tend to be quite complicated. Unneccessay so, if one used object oriented principles of data hiding.
Memory management must be one of the main horrors of computing. That's why garbage collected languages like ruby are so great. Even simple malloc implementations tend to be quite complicated. Unnecessary so, if one used object oriented principles of data hiding.
### Object and values
@ -19,29 +19,30 @@ If integers were normal objects, the first would mean they would be singletons.
Instead of trying to make this difference go away (like MRI) I think it should be explicit and indeed be expanded to all Objects that have these properties. Words for examples (ruby calls them Symbols), are the same. A Table is a Table, and Toble is not. Floats (all numbers) and Times are the same.
### Object Layout
### Object Type
So if we're not tagging we must pass and keep the type information around seperately. For passing it has been mentioned that a seperate register is used.
So if we're not tagging we must pass and keep the type information around separately. For passing it has been mentioned that a separate register is used.
For keeping track of the type data we need to make a descision of how many we support. The register for passing gives the upper limit of 4 bits, and this fits well with the idea of cache lines. So if we use cahce lines, for every 8 words, we take one for the type.
For keeping track of the type data we need to make a decision of how many we support. The register for passing gives the upper limit of 4 bits, and this fits well with the idea of cache lines. So if we use cache lines, for every 8 words, we take one for the type.
Traditionally the class of the object is stored in the object. But this forces the dynamic lookup that is a good part of the performance problem. Instead we store the Object's Layout. The Layout then stores the Class, but it is the layout that describes the memory layout of the object (and all objects with the same layout).
Traditionally the class of the object is stored in the object. But this forces the dynamic lookup that is a good part of the performance problem. Instead we store the Object's Type. The Type then stores the Class, but it is the type that describes the memory layout of the object (and all objects with the same type).
This is is in essence a level of indirection that gives us the space to have several Layouts for one class, and so we can eveolve the class without having to hange the Layout (we just create new ones for every change)
This is is in essence a level of indirection that gives us the space to have several Types for one class, and so we can evolve the class without having to change the Type (we just create new ones for every change)
The memory layout of **every** object is type word, layout reference and "data".
The memory layout of **every** object is type word followed by "data".
That leaves the length open and we can use the 8th 4bits to store it. That gives a maximum of 16 Lines.
#### Continuations
But (i hear), ruby is dynamic, we must be able to add variables and methods to an object at any time. So the layout can't
be fixed. Ok, we can change the Layout every time, but when any empty slots have been used up, what then.
But (i hear), ruby is dynamic, we must be able to add variables and methods to an object at any time.
So the type can't be fixed. Ok, we can change the Type every time, but when any empty slots have
been used up, what then.
Then we use Continuations, so instead of adding a new variable to the end of the object, we use a new object and store it
in the original object. Thus extending the object.
Then we use Continuations, so instead of adding a new variable to the end of the object, we use a
new object and store it in the original object. Thus extending the object.
Continuations are pretty normal objects and it is just up to the layout to manage the redirection.
Continuations are pretty normal objects and it is just up to the object to manage the redirection.
Off course this may splatter objects a little, but in running application this does not really happen much. Most instance variables are added quite soon after startup, just as functions are usually parsed in the beginning.
The good side of continuation is also that we can be quite tight on initial allocation, and even minimal with continuations. Continuations can be completely changed out after all.

View File

@ -17,10 +17,10 @@ But this can easily lead to a dictionary/hash type of implementation. As variabl
common thing an OO system does, that leads to bad performance (unneccessarily).
So instead we keep variables layed out c++ style, continous, array style, at the address of the object. Then we have
to manage that in a dynamic manner. This (as i mentioned [here](memory.html)) is done by the indirection of the Layout. A Layout is
to manage that in a dynamic manner. This (as i mentioned [here](memory.html)) is done by the indirection of the Type. A Type is
a dynamic structure mapping names to indexes (actually implemented as an array too, but the api is hash-like).
When a new variable is added, we create a *new* Layout and change the Layout of the object. We can do this as the Layout will
When a new variable is added, we create a *new* Type and change the Type of the object. We can do this as the Type will
determine the Class of the object, which stays the same. The memory page mentions how this works with constant sized objects.
So, Problem one fixed: instance variable access at O(1)
@ -44,11 +44,11 @@ The Plock can store those cache hits inside the code. So then we "just" need to
Initializing the cached values is by normal lazy initialization. Ie we check for nil and if so we do the dynamic lookup, and store the result.
Remember, we cache Layout against function address. Since Layouts never change, we're done. We could (as hinted above)
Remember, we cache Type against function address. Since Types never change, we're done. We could (as hinted above)
do things with counters or robins, but that is for later.
Alas: While Layouts are constant, darn the ruby, method implementations can actually change! And while it is tempting to
just create a new Layout for that too, that would mean going through existing objects and changing the Layout, nischt gut.
Alas: While Types are constant, darn the ruby, method implementations can actually change! And while it is tempting to
just create a new Type for that too, that would mean going through existing objects and changing the Type, nischt gut.
So we need change notifications, so when we cache, we must register a change listener and update the generated function,
or at least nullify it.

View File

@ -19,14 +19,14 @@ In soml object is not the root of the class hierarchy, but Value is. Integer, Fl
derived from Value. So an integer is *not* an object, but still has a class and methods, just no
instance variables.
### Layout and Class
### Type and Class
Each object has a layout that describes the instance variables and types of the object. It also
reference the class of the object. Layout objects are constant, may not be changed over their
lifetime. When a field is added to a class, a new layout is created.
Each object has a type that describes the instance variables and types of the object. It also
reference the class of the object. Type objects are constant, may not be changed over their
lifetime. When a field is added to a class, a new Type is created.
A Class describes a set of objects that respond to the same methods (methods are store in the class).
A Layout describes a set of objects that have the same instance variables.
A Type describes a set of objects that have the same instance variables.
### Method, Message and Frame

View File

@ -48,7 +48,7 @@ field definitions, and are basically instance variables, but not hidden (see bel
The example below shows how to define local variables at the same time. Notice chaining, both for
field access and call, is not allowed.
Layout l = self.layout
Type l = self.type
Class c = l.object_class
Word n = c.name
@ -109,7 +109,7 @@ field, must be in class (not method) scope and may not be assigned to.
class Class < Object
field List instance_methods
field Layout object_layout
field Type object_type
field Word name
...
end