2016/06/24

11:39

Based on the URI specification, the scheme specific part is always the path.

11:48

Actually a class path system based on URIs could be complex although rather future proofed. java.net.URI has really non-conforming URI layouts and some of the constructors are very simple and just paste strings together rather than encoding them as they should.

11:57

Actually the JVM could be backed using the standard MEEP interfaces. Instead of having class-path, I just instead have an implementation of the SuiteManager and TaskManager. The base would act as a kind of kernel of sorts.

12:00

So there would be basically two levels. A JVM would run as the kernel which then manages sub-JVMs running at lower ends.

12:15

Perhaps the JVM can be final. Then it can either be constructor or an implementation specific factory be used. At least with an implementation specific factory there can be fallbacks in the event new features are added to the JVM. If something is missing then there would be a fallback.

12:32

So the first thing to do for the ability factory is provide an interface that would be used with the Suite manager to find the launcher JAR. Then once the JAR is located a task should be created and then switched to.

12:38

The JVM's suite manager should have only a single implementation managed by the JVM itself. However, due to some of the varying needs that might not exist (such as a filesystem), suites should still be installable by passing the raw JAR bytes for example (after a download or other unpack).

12:46

I will need to implement the classes used in the suite manager since they do not exist and I have no templates to base from.

14:31

I wonder why SuiteInstaller and stuff such as Suite are classes instead of interfaces. I suppose the intention that despite there being many managers that there will just be a set few when it comes to suites? Regardless, the suite managers and such will instead be an artifact that is used in the user space process and not the kernel. Otherwise when it comes to suite management the kernel can get confused if it is running a virtual enviroment on SquirrelJME or another Java ME implementation.

14:48

Especially since Task is final that means it cannot be used at all. So SWM is completely client side. However after manually typing out the classes I have a feel of how it would work.

14:58

Unless the Suite and Task have package private or private constructors that do not exist in the documentation. JavaDoc really should have included information if a class can even be constructed at all. I am going to guess that the constructors are private or package private. The classes that exist are just stubs which even lack constructors.

15:29

And with that the entire MEEP SWM has been implemented. That took about 3 hours or so to complete.

15:29

So what I need to do when it comes to the JVM since SWM is application side (and not JVM side) is just provide access to the available suites via the unsafe classes. So the suite code and such will just call into the system code and such. However the JVM itself can still use some of the MEEP flags and states such as the enumerations. So there will essentially just be a JVM side of the MEEP code that unsafe bridges to.

15:37

Ok so since including all of the verification details and class transformation would be difficult in the JVM, perhaps the launcher can perform all the details. When an application requests to download a JAR from the internet it can instead forward the request through to the launcher. So basically the installation system of a JAR is purely handled by the launcher. The JVM would have a full permissions mode which is used by the launcher. When it comes to the JVM's set of suites, there will just be a basic install output stream of sorts. This would assume that the launcher verified all the details and such. So the JVM's default suite (to replace the class path stuff) will just contain a simple interface means of accessing built-in suites that are pre-installed. In the event of native code, these JAR suites would be completely built into the executable (and not be in other JARs). However in the case of the JVM based one, it will just treat all JARs in the current directory as preinstalled. Then with it done this way, this would mean that native binaries just come alone with precompiled code and suite setups. The access to preinstalled suites will just basically be getResourceAsStream and likely another interface such as an executable class context.

20:26

One thing I can do is potential native integration of sorts. Have the SquirrelJME executable. For each installed program a new binary appears. This binary is just a wrapper which then calls SquirrelJME with the program that it represents. The program would just launch and provide an icon for the most part. So for example on Palm OS native applications can be created and placed on the list of applications to quickly switch to JARs which are available. There could still be a single SquirrelJME process running with the VM however.

20:40

Well actually the JVM has the native compiler and not the launcher, however when it comes to native execution of code the JVM could recompile any classes that need to be recompiled if they have not be cached or similar.

20:45

Due to my goal of supporting very limited systems, perhaps my handling of the classes is completely wrong. Right now when it comes to compilation I will basically load everything about the class into memory. Then that gets natively compiled. If I can make it so a Java class file can be put into an input stream which is passed to compiler. It performs some basic verifications that it can perform at the given stage along with basic stack map details and such. It will basically just fly through the code attribute as is and perform compilation in a single pass, perhaps without even loading the exception table and stack map table attribute. Then the code can pass through the micro operations execution-like system for each operation. Then that would be output to the JIT which produces native code for a method. Once all of the native code has been compiled it will then package it in an executable blob that will be loaded into memory or become part of global blob in an executable. If the blob route is taken then executables can just be made out of a bunch of executable blobs with some initialization code (so the JVM can load). Having a JIT on systems with as small as 64KiB could potentially be done using this method. It would also be very fast. The ZIP code requires a sliding window however, so as long as the classes remain small they should work on a multitude of systems. So classes need to have not many methods and be within a given size. I would suppose in the build system I can warn if a class exceeds a given size (so I can trim it). I would suppose that the lowest of lower limits I can go for is 4KiB. If a class exceeds that size then it is way too large. The larger a class, the more difficult it is to handle as the more memory it consumes.

20:59

4KiB might be a little too low, especially if there is debug information in the JARs. However, debugging information is rather useful to have at least for now. So I suppose the current limit I can impose is 12KiB. When writing the JARs for a distribution I can strip the debugging information anyway since SquirrelJME would likely not be capable of line based debugging.

21:08

So I need the JIT to be as small and as fast as possible while using the least amount of memory. This would then equal faster than interpretation on limited systems. Due to the lack of reflection and invokedynamic I do need to perform some checks. I would suppose that the code generated in a class should be together as one. At the end of a class chunk there can be symbol information which contains information on any classes which are referenced along with methods. Then with this, blobs can be independent. The only major concern are that symbol references can be quite long. So I suppose a UTF-8 form is used so that characters take up a byte instead of a char in the file. I can have special String handling for UTF-8 strings with non ASCII characters in it. However in the general case this will never be the situation because when it comes to class names and such, there will generally never be characters beyond the basic ASCII range.

21:15

Another consideration is that there can be symbolic special names which use a preset dictionary to refer to classes. There can even be prefixed forms of these too. So if I limit strings to be 32768 bytes then that means I can use the upper bit for a string prefix. The String class can handle these special prefixed data. I would also have to memory map the class constant data area also by using byte[] which write to actual addresses. Using handles as I plan to do means I need not worry about it. When it comes to a prefix I can support 127 of them, then 255 bytes can be used for remaining UTF-8 data.