5 Ok, so I have been thinking about my JIT. Essentially what I have is a
6 gigantic static compiler. Right now my plan is to build a link table and have
7 all these class bits in there linked in. But I have been thinking of changing
8 things. Basically the linker needs to have everything in memory anyway, from
9 the byte code to the generated machine code. The JIT requires a bunch of
10 memory to load the program code. But the program code has to go into memory.
11 So right now I have a tradeoff, do I want an easier JIT with more memory
12 required to use it or one which is a bit more complicated and requires a bit
13 less memory. Basically I can go both ways. But I could have a kind of hybrid
14 approach to the JIT. Basically there is the text and data sections. However I
15 am hitting feature creep as I have before for other odd targets. I was
16 thinking of a C language target again. But I definitely do not want to get
17 into that loop again. So I am purely just targetting traditional CPUs.
21 Basically most systems have a code and data section. I can have a best of
22 both worlds kind of thing. Having everything loaded in does give me the
23 benefit of having some optimizations. But I think for speed and simplicity of
24 the JIT I will only be performing the most basic optimizations. I think I want
25 to avoid having the basic block logic, but basically have it where I have it
26 now but it is just generated machine code with a given mutated state. That way
27 once the byte code is parsed, I can just get rid of it. So basically in the
28 text section there would be special markers that indicate areas that need to
29 be adjusted depending on a given condition. Basically, the hypothesized calls
30 for checking casting, instead of a flag they can just be a method call. Of
31 course I can just optimize some of those method calls to ones which always
32 return whether the check passes or fails. It is not the best but it is simple
33 and does not require any extra special handling. For things which are not
34 known it can just use the default handler which does that determination.
38 So basically `LinkTable` instead becomes the output binary stream class which
39 holds the direct object code. There also is an indexing table used to replace
40 some method calls accordingly.
44 Then that class being used by whatever executable output there is just
45 provides a raw byte array or output to an `OutputStream` (or both probably).
46 Then it performs the magical replacement stuff as needed by the native system.
50 So since access checks are purely done at compile time (excpet for
51 `Class.newInstance()`), this means that there just needs to be an access
52 table. This is filled up with information which is then just check when
53 everything is done to make sure accesses are valid. Also read of static fields
54 can be made constant pointers for the most part. So everything is moved into
55 the compiler. Then at run-time the only thing that needs to run are class
56 initializers and such. So this stuff is going to make a number of classes so
57 they should be placed in their own sub-package from the base of the JIT so it
58 remains clean. So this is the basic hierachy:
62 * Resources in clusters
63 * Resources just link to regions in the data section but have tables
64 which are used to find actual resources.
65 * Map of ClassName to Classes
67 * Dynamic Class.newInstance() support
68 * Pointer to default constructor, null means cannot be constructed
69 * A flag indicating the lowest visibility of the class and the
70 default constructor. So if the DC is `private` and the class is
71 `public` then this flag is `private`. This would mean that only
72 the current class can initialize.
73 It is unknown how `protected` goes into this, would need to
75 * A basic identifier of the package the class is in.
76 * All static access checks done by the code
77 * Class.newInstance() will just have special dynamic access checks.
78 The check would basically be, from Class A can this method create an
79 instance of Class B. This would mean that all classes have a package
80 identifier and default constructor availability. If there is no
81 default constructor then this method does not work.
83 * This is just used to that package identifiers are unique for quick
86 * text, all of the machine code that executes.
87 * data, everything else which is not executable.
89 * Basically these are special instruction modifier markers which are
90 used to generate some parts of the text/data sections later on as
91 required. For example a static call to a method is not known until
92 the compiler reaches it, as such that would have a special marker
93 in place to make sure it eventually does get replaced as needed
94 and the code pointing to it is generated.
95 * Static field reads use the linking table for most types so that it
96 is possible for a non-memory reading load to be performed and if not
97 then a memory reading load is done. So if there is a get of a static
98 int field, if the constant value is known at compile time then the
99 generated instruction will just be a load of that constant. However
100 if it is not known at compile time then it will be the actual read
105 For inheritence I need to make sure that all of the interfaces that a class
106 implements are visible and such.