Compact libraries by source set rather than by target.
[SquirrelJME.git] / design.mkd
blob58ebbf53d9bd40f0491be50300051d7edabc6c43
1 # Design Document
3 This document outlines several decisions and design considerations for the
4 SquirrelJME Virtual Machine. This document should reflect the most recent
5 path that SquirrelJME will be taking in its design. Note that the design may
6 change and this is not forever concrete (that would be foolish).
8 For day to day notes on my current thought process you may look within the
9 [developer notes](assets/developer-notes/index.mkd).
11 For the current route of development see the [release route](route.mkd)
12 document.
14 Because Java ME is different from Java SE, there are some considerations,
15 advantages, and disadvantages to consider when reading this document. Note that
16 this document is mostly within the scope of Java ME and not Java SE.
18  * Reduced library subset.
19    * The main library is much smaller which means it will load faster and
20      use less memory. Less memory means it can run on smaller/weaker systems.
21  * No reflection.
22    * There is `Class.forName()` and `Class.newInstance()`, however they are
23      trivial to support.
24    * More secure because access checks do not have to be performed at run-time
25      to determine if it is permissible to access an object.
26    * Random object fields (and finals) can be cached because their reference
27      or primitive values will never change.
28    * More secure because for example changing `Boolean.TRUE` to be `false` may
29      cause security exploits with code that relies on it being `true`.
30    * The resulting virtual machine is smaller because information such as
31      the types of fields and methods that exist and their type information does
32      not have to be included within the virtual machine. This reduces the bloat
33      within the virtual machine.
34    * Produces faster code because `final` variable and especially
35      `static final` values can directly be accessed rather than requiring a
36      read of a field pointer value.
37  * No finalizers (the `finalize()` method).
38    * Finalizers are very integrated with how the garbage collector works.
39    * It is never known when they will actually be called (if ever).
40    * Timing attacks could be performed when finalizers are called between
41      garbage collection runs.
42  * No serialization.
43    * No objects are `Serializable`.
44    * Serialization uses virtual machine magic to access internal details, since
45      there is no reflection the information that would be used for
46      serialization does not exist.
47    * The `transient` keyword becomes obsolete.
48    * Simplifies implementation.
49  * No `invokedynamic` instruction.
50    * Simplifies virtual machine operation, at the cost of lambdas (which could
51      be smartly wrapped in anonymous classes by a compiler).
53 There are also disadvantages however:
55  * Without reflection, one cannot include plugins dynamically from the program.
56    * However, Java ME 3 (or so) added LIBlets which may be optional and provide
57      a slight alternative to plugins. These however are fixed to the JAR/JAD
58      which means that the difficulty is increased.
59    * Alternatively, Java ME 8 has `ServiceLoader` which enables JARs to
60      potentially be merged to provide services. Also using `Class.forName()`
61      and `Class.newInstance()`, plugins using a common interface can be
62      initialized when they are not directly known.
64 For specific APIs, one should read the [Project Scope](scope.mkd) document
65 which outlines the APIs which exist for Java ME and whether they would be
66 implemented in SquirrelJME or third party vendors.
68 # Java SE vs SquirrelJME
70 This section is more a bit in depth of the differences between SquirrelJME and
71 Java SE.
73 ## Memory
75 Java SE has a standard garbage collector which in general will free objects
76 when they are no longer referenced using a mark and sweep algorithm. In most
77 cases it will try to avoid freeing memory in the event that it could be used
78 again, also doing major garbage collection sweeps can be computationally
79 expensive. Despite being very virtual machine specific, this gives Java the
80 appearance of using quite the amount of memory (it has historically and
81 currently is seen as a memory and resource hog) especially if code running on
82 it has not be designed in an optimal way (which is usually the case). The
83 garbage collector in large instances may take awhile to execute and can take
84 considerable resources. The garbage collector generally is designed to run in
85 another thread and hopefully can concurrently garbage collect objects making
86 use of extra CPUs to decrease cleanup time. In general this garbage collector
87 is made for speed where it only affects program execution speed when needed.
88 Recent JVM advancements do have stack allocations which do not operate with the
89 heap at all, which makes cleanup much easier if these optimizations can be
90 used.
92 SquirrelJME on the other hand will try to use the lowest amount of memory it
93 can by freeing objects from memory as soon as possible (in well designed code,
94 one that does not use circular references). Once it is known that a given
95 object can be freed from memory it will be freed to make up space for other
96 programs and objects (within SquirrelJME). So virtually in most cases
97 SquirrelJME will use the minimum memory footprint needed to run it. Although
98 the lowest amount of memory will be used, a reference counted garbage collector
99 has some slight overhead in that it needs to count objects and be able to
100 free the objects when they are no longer counted. Parts of code which heavily
101 use objects will run a bit slower due to the counting required. This is
102 definitely a trade-off as it gives memory a more important consideration than
103 speed. Since SquirrelJME targets low end systems, this extra memory can be
104 very important. However, unlike Java SE all allocations are on the heap since
105 the size of the stack may be very small.
107 # Programming Language
109 SquirrelJME is written entirely in Java. This means that it only requires a
110 Java virtual machine and a Java compiler to be built. There are also no other
111 dependencies apart from what is within SquirrelJME itself, it is entirely
112 standalone and self contained.
114 One may ask why Java and not another language such as C? Well, Java is a much
115 simpler language compared to C when it comes to syntax (C has the preprocessor,
116 structures, pointers, typedefs, function pointers, etc.). One main advantage
117 of Java is the consistency of the code.
119 One misconception about using Java is that it is impossible to use native code
120 or one will require and assembler to assemble assembly code for things which
121 Java cannot do. This is not the case for SquirrelJME. The major and most
122 important part of SquirrelJME is the compiler which can turn Java byte code
123 into native machine code. Since the compiler is very much integrated into
124 SquirrelJME this means that certain aspects of interacting with the host
125 environment can be accessed by changing compilation for certain aspects in a
126 way where it remains compatible with Java but also provides native access when
127 needed. Native access is provided by replacing method calls to special static
128 methods within a special class by the appropriate machine code rather than
129 invoking a method call. These special rewrites affect everything within a
130 special package. This is used to provide
131 support for multiple operating systems and environments without causing name
132 collisions (since you cannot have classes with the same name in multiple
133 projects when they are merged together).
135 ## Portability
137 I intend for SquirrelJME to be very portable so that it can be built for and
138 built on a large number of systems.
140 ## Self Hosting
142 I intend SquirrelJME to be self hosting in that it can build itself.
144 In the future a Java compiler will be written which can run on SquirrelJME
145 itself and allow building and compiling itself from source. This would also
146 allow other programs to be built from source and can be used as a self
147 contained Java development environment.
149 # Environment
151 This details the environment in which SquirrelJME operates within the host
152 operating system.
154 ## APIs
156 This describes the design of standard implementations.
158 ### `javax.microedition.lcdui.*`
160 The LCDUI API is used by a large number of older J2ME applications to display
161 widgets and graphics on the screen. On SquirrelJME everything is done by
162 SquirrelJME itself on its own framebuffer which it draws into, this makes
163 portability easier.
165 #### `javax.microedition.lcdui.Image`
167 Since many systems may have varying image formats and supported native pixel
168 formats, instances of this class may be specific to the given hardware and may
169 have the screen display limitations. Images generally may use 32-bits to
170 store their pixel data, but some implementations may use images with a lower
171 bit density (such as 256 color images).
173 ## Pathname Handling
175 Instances of the `Path` class will be strictly limited to the limitations of
176 the host system and will not provide support for allowing limitations to be
177 skirted as that complicates compatibility.
179 As an example for DOS, there are severe filename limitations such as a
180 maximum of 8 characters for a file name and 3 characters for an extension along
181 with other naming restrictions. As such getting a path which does not produce
182 a valid DOS pathname will result in an exception being thrown.
184 # Compilation Time
186 This section contains information related to the operation of the Ahead-Of-Time
187 Compiler and the Just-In-Time Compiler.
189 # Virtual Machine
191 This section contains information related to the target independent virtual
192 machine at run-time.
194 ## Garbage Collection
196 For simplicity the garbage collector is a reference counter with sweeping when
197 no more memory is available (or GC is called manually). As such, cyclic
198 object references will not be freed unless one or both directions are
199 weakly referenced (using `WeakReference`). This means that the following
200 situations would permit both objects to be potentially collected:
202  * A has a strong reference to B, B does not reference A.
203  * A has a weak reference to B, B does not reference A.
204  * A has a strong reference to B, B has a weak reference to A.
205  * A has a weak reference to B, B has a strong reference to A.
206  * A and B both have weak references to each other.
208 Although reference counting may increase lock contention on the CPU and memory
209 buses it simplifies the design greatly by not requiring complex garbage
210 collection algorithms. In most cases with reference counting, SquirrelJME is
211 capable of using always a minimum footprint of memory depending on whether that
212 memory should be freed to the operating system or within SquirrelJME's own
213 memory for other programs running in it.
215 Objects will have two counts: The number of strong references pointed to this
216 object and the number of weak references pointed to this object. These two
217 counts determine if an object can be garbage collected. If any object has a
218 strong reference count that is non-zero then it will be garbage collected as
219 long as it has zero weak count also. Thus, an object which is never referenced
220 at all will be garbage collected. In a standard Java VM, a `WeakReference` in
221 most cases will only give an object if it has at least one strong reference.
223 ### Strongly reached, weakly reached (`WeakReference`)
225 In Java ME with Java being garbage collected, there are two types of
226 references to objects which affects how garbage collection is performed.
227 Similar to other languages this can be seen as a smart pointer or a special
228 kind of reference counting pointer.
230 A strong reference is a normal reference to an object, like a value which is
231 placed within a field (a static field or an instance field) or a local
232 variable in a method. Any objects that are strongly referenced cannot be
233 garbage collected because they are used.
235 A weak reference is another kind of reference to an object which is provided
236 by the `WeakReference` class. Essentially it does not have a strong bond to
237 the object it points to and that object may be garbage collected and
238 return `null` as long as no strong references point to it. Weak references
239 cannot really be used as a cache due to the way the garbage collector works,
240 for a cache a `SoftReference` should be used by Java ME does not have such a
241 class. At least with weak references, the virtual machine will in the most
242 average case always use the least amount of memory. In short, weak references
243 are garbage collected as soon as possible. If used for memoization it will
244 not have the best intended effect of reducing calculations but it would reduce
245 the memory footprint.
247 ### Strong Count of Zero, Non-Zero Weak Count
249 When an object has no strong references and only weak references, that means
250 that it can soon be garbage collected. For simplicity when `WeakReference`
251 detects that a target object has no strong references to it, it will detach
252 itself from that object, reduce the weak reference count, and return `null`.
253 If a `WeakReference` is no longer strongly referenced it will also cause a
254 detach to occur.
256 If the system is out of memory then all objects will be iterated and any
257 objects which only have weak references to them will be removed.
259 ### Strong Count of Zero, Zero Weak Count
261 This object can be garbage collected, it will be removed and that memory will
262 be made available for other allocations.
264 ## Tasks
266 MIDP 3 allows multiple programs to be ran at the same time (provided they
267 are actual different MIDlets). One thing to simplify the design of SquirrelJME
268 without needing much work.
270 ## Synchronization and Locks
272 Java naturally provides synchronization which is used for writing code which
273 is thread safe. Since synchronization and monitors are very intertwined, the
274 design will reference future information. Since there are a number of different
275 ways different CPUs and targets could have thread safety, those details have
276 been removed and replaced with easy to determine common means.
278 ### Loop Threading for Multi-Threading
280 Since Java is multi-threaded and SquirrelJME may run on top of a number of
281 system which may have different threading models, the following differences
282 determine what happens when a loop needs to be repeated due to a failed
283 operation.
285 #### Preemptive
287 The loop should perform a given number of checks, then once a certain
288 threshold is reached a longer duration sleep should be entered so that CPU
289 cycles are not spent deadlocking. Essentially it waits upon a signal where
290 possible.
292 #### Cooperative
294 The loop should yield and not attempt another try (because only a single thread
295 can run at one time) that way another thread which is able to be ran can
296 executed, potentially one which controls the monitor for the given object.
298 It is possible that an internal threading manager can determine the best
299 thread to choose for consecutive execution.