Java2C - Requirements and features

Java2C - Requirements and features

Inhalt


1 Features

Topic:.Java2C.Features.

pStyle=std tableStyle=stdTable

You find a german documentation and discussion above this topic at http://www.vishia.org/Java2C. If you have questions or notes, please mail to hartmut.schorrig@vishia.de.

Why C and not C++?

In the table below the features of the Java2C translator and the CRuntimeJavalike are visualized.

Java-feature

Implementation in C

Remarks

 class MyClass
 { int a;
   MyOther other;
   final int myMethod(...)
   {
   }
 typedef struct MyClass_t
 { ObjectJc object;
   int a;
   struct MyOther_t* other;
   ...
 }MyClass;
 int myMethod_MyClass(...)

ready, basic feature!

 class MyClass extends BaseClass
 { ...
 typedef struct MyClass_t
 { BaseClass super;
   ...

ready, inheritance concept is interestedly but not essentially for embedded control. But it is no large expenditure of implementation.

 class MyClass
   implements MyInterface
 { ...
 struct Mtbl_MyClass_t
 { Mtbl_ObjectJc mtblObjectJc;
   { MT_method_MyInterface*
       implMethod;
     ...
 }mtblMyClass
   ...

ready, The inheritance concept is interestedly but not essentially for embedded control. It is solved as a matter of principle. An interface is represented by a ObjectJc* reference and a Mtbl-struct (method address table) as part of reflection informations. Searching the appropriate table regards the inheritance tree (base class and interfaces). The reflection of the instance type and the Type of interface/baseclass are used as inputs. No reference to jmp addresses is stored in a data area. It is a concept of safety: A data area may be attacked by a software bug of another module. In such cases no influence to program flow should be exert. To optimize accesses inside a method, the reference to the mtbl is stored in the stack.

 obj.getClass();
 getClass_ObjectJc(obj)

Prio2, The reflection concept is interestedly but not essentially for embedded control. The reflection tables are used to search method tables for the interface concept.

The reflection concept helps inspecting an embedded control system: Using reflections an access to all internal fields and invoking of internal methods can be done from outside without any additional special programming. At example the access can be done via a network interface (UDP).

 class MyClass
 { void myNotFinalMethod(...)
 struct Mtbl_MyClass_t
 { ...

ready, It's the same like interface concept, but more simple because a enhanced reference is not need.

 class MyClass
 { ...
   MyClass(...)
   { ref = new OtherClass(args);
 ref = ctor_MyClass
 ( alloc_MemC(sizeof(MyClass))
 , args
 );

ready. The using of dynamic memory is supported both in the construction phase in embedded real-time software and really dynamically at run time. A garbage collector is implemented.

 class MyClass
 { final OtherClass ref
   = new OtherClass(args);
 struct MyStruct
 { ...
   OtherClass ref;
 }
 ...
 ctor_MyClass()
 { ctor_OtherClass
   (&ythis->ref, args
   );

ready. If the reference at class level is final and assigned at class level with the same Class, it is a fix instance. Therefore a embedded struct is realized in C. It is a important basic feature because in C embedded struct are an opportune implementation for nested data.

 class X{ class Inner{...}
 struct Inner_X_t
 { ... X* outer;
 

ready. Inner classes may be static or not. Non-static classes got a pointer outer which is initialized in ctor. The direct access to elements of the outer class use ythis->outer->....

 final Ifc ref = new Ifc(){...}
 struct ref_Ifc_t
 { ...}
 ref = ctor_ref_Ifc(...)
 

ready. Anonymous classes are translated to a struct with the name of the reference or with a generated name for the typical case of the shown final initialization. A more seldom construct is the usage of ... (new Type(param){...}).method()... inside any expression. Than a generated name is assigned to the struct. Any anonymous class is mapped to a named struct in C.

 ref = new MyClass(args);
 ref = ctor_MyClass
 ( alloc_MemC(sizeof(MyClass))
 , args
 );

ready. In the runtime phase in embedded real-time software no extensively using of dynamic memory should be done. But for special requests like events or temporary Strings, dynamic instances are necessary. To support such, a BlockHeap concept with equals blocks is slated. The dynamic objects should have a limited size. It may be opportune in embedded control.

 Type[] array;
 Type_AY array;

ready. Arrays can be used at C level as referenced arrays. An array pointer type is defined for any type. It contains head information and the data. Such arrays should instanciated dynamically with any length. The head information contains the length of the array.

prio2: Only one-dimensional arrays are implemented yet. More as one dimensions are TODO.

 final Type[] array = new Type[123];
 struct{ ObjectJc object;
         int32 length, ...
         Type data[123]
       } array;

ready. If an Array is fix, it is implemented as embedded instance. The elements of the array may be embedded or referenced. If also the elements are embedded, the array occupies only one memory area inside another struct. It is the commonly used opportune memory model of C programming.

prio2: Only one-dimensional arrays are implemented yet. More as one dimensions are TODO.

 /**@Java2C=simpleArray;*/
 Type[] array = new Type[123];
 Type array[123];

ready. Arrays without any head informations are common used in C. If an algorithm is tested well in Java, and the array itself isn't use as Object in container classes, it can be implemented pure directly like C-programmers knows it. The array.length is translated to a macro ARRAYLEN(array) using sizeof mechanism.

 try{...} catch throw
 STACKTRC_ENTRY("name");
 TRY{...}_TRY
 CATCH(...){...}
 FINALLY{...}
 END_TRY

ready. The try-catch-throw concept is essentially in Java, found in C++ and a convenient and necessary feature in C. The implementation of throw in C is done using the longjmp-concept, known since 1970 and available for all processors. For C++ environments also the try/throw of C++ is useable. See german description at http://www.vishia.org/Jc/html/Exception_Jc.html. There are use some macros to produce a better readable C code. The macros contains simple tests and sets, see ExceptionJc.h.

 String ss = "a" + 5;
 StringJc ss;
 ss = toString_StringBufferJc
      ( iXJc( ...s0BXJc(
      "a"), 5));

ready. Strings are necessary in embedded control to assembly error messages or such ones. The concatenation of Strings is done with a StringBuilder. The Buffer can be allocated in Heap, in Stack or in a ThreadContext-range. The necessity persistence of the String are controlled by annotations in the Java-Code. If a String doesn't need to be persistent, it doesn't need dynamic memory. Therefore working without dynamic memory is possible. The basic features of java.lang.StringBuilder is implemented.

java.lang.String, java.lang.Thread

ThreadJc, RunnableJc

ready. Multithreading is a basic needfull feature of embedded control. Not all features, especially not ThreadGroup etc. are supported.

java.util.List, LinkedList, ArrayList, TreeMap, Container

ListJc, LinkedListJc, ArrayListJc

Prio1. This features are interestedly and supports the reason to work with java. C don't know a good concept of container. All this features are implemented in C level in CRuntimeJavalike. It should be work together with the Garbage-Collector - BlockHeap- concept, because the Nodes of Lists are managed with them.

java.awt, javax.swing

nothing

not supported. If graphical features should be used with Java style, the using of Virtual Machines for Java for embedded controller should be considered. There are some offers, like Jamaica-VM. It is possible to connect C routines with Java at the same processor using JNI or localhost-InterProcessComm or at a second processor. It is a good decision using embedded control in connection with PC based software.

java.net.Socket

InterProcessComm

ready. The InterProcessComm implementations in C and Java are adapted together. The socket communication should use this wrapper. It is a concept using Socket communication or other communication ways like serial or DualPortRam, above the java.net.Socket-classes. The InterProcessComm may be the basic concept to connect processors with several programming concepts.

java.io

FileIOJc.h, FileOutputStream, os_file.h

ready. The accesses to the file system are a basic feature in C since anno 1970, but they are lightweightly different. Therefore an OSAL-layer is used to adapt it. The layer above is defined with routines in FileIOJc.h. Basicly requirements of file-handling are complied with them. It is opportune with requirements of embedded control-software.


2 Changes from..to revision

2.1 Changes from 0.91 to 0.93

Topic:.Java2C.changes091_093.

pStyle=std tableStyle=stdTable

. Date: 2010-12-31


2.1.1 Java2C - core

Topic:.Java2C.changes091_093.Java2C.

pStyle=std tableStyle=stdTable

There was done a lot of work in detail in the last year.


2.1.2 Documentation

Topic:.Java2C.changes091_093.docu.

pStyle=std tableStyle=stdTable

Some things added.


2.1.3 CRuntimeJavalike

Topic:.Java2C.changes091_093.Jc.

pStyle=std tableStyle=stdTable


2.1.4 Examples

Topic:.Java2C.changes091_093.examples.

pStyle=std tableStyle=stdTable

The PositionControl-Example is completed with a graphical output now. You can see how the calculation works. The graphic representation is a Java-program, working with SWT-Graphic with an own concept of building the GUI-application. This concept is used only here. It is not described extensively here.

The data-communication between the PositionControl-programm and the GUI based on a Socket communication using the InterProcessComm-Interface, which is provided in C as in Java.

The testAllConcepts-examples are completed especially with String checks.


2.2 Detect bugs and requirements

Topic:.Java2C.TODO.

pStyle=std tableStyle=stdTable

.


2.2.1 Detect bugs and requirements of the translation process

Topic:.Java2C.TODO.bugsTranslator.

pStyle=std tableStyle=stdTable


2.2.2 Detect bugs and requirements in the appearance of generated C-Code

Topic:.Java2C.TODO.genCCode.

pStyle=std tableStyle=stdTable

This part describes, which changes should be done in the form of generated C-Code


2.2.3 Detect bugs and requirements of CRuntimeJavalike

Topic:.Java2C.TODO.bugsCRJ.

pStyle=std tableStyle=stdTable


2.2.4 Detect bugs and requirements of the whole presentation

Topic:.Java2C.TODO.bugsDownload.

pStyle=std tableStyle=stdTable


2.2.5 View to the near future

Topic:.Java2C.TODO.future.

pStyle=std tableStyle=stdTable


3 JcLib or CRuntimeJavalike

The CRuntimeJavalike is the runtime system of the C-translated Java sources. It contains some classes, which are part of java.lang or java.util. Some of implementations are made regarding C-typically things.


The JcLib based on a OSAL-interface (Operation System Adapting Layer). That OSAL should be adapted to the given RTOS. The download contains an adaption to MS-Windows using API-calls. It may be worked under typically Windows-Versions, started with Win-NT. It is tested under XP.


The CRuntimeJavalike is documented in German language yet only. See CRuntimeJavalike.


4 Examples

Topic:.Java2C.Examples.

pStyle=std tableStyle=stdTable

examplePositionControl.html: A praxis-oriented example. Translated Java-sources to C up to now with a Visual-Studio-6-Project (running under windows). In the future: Eclipse-project for Linux too. See local folder Java2C-download:examples/positionControl

javasrc:_org/vishia/java2C/test/TestAllConcepts: Java classes translated to C. See local folder Java2C-download:examples/testAllConcepts


5 Documentation

Topic:.Java2C.Documentation.

pStyle=std tableStyle=stdTable


6 Concepts

See org/vishia/Java2C/Docu.java. This file contains detaild descriptions.


6.1 Programming concepts

Topic:.Java2C.swConceptsInCentury.

pStyle=std tableStyle=stdTable

All programming language are still in use.


6.2 Differences from C, C++, Java, Solution in Java2C

Topic:.Java2C.CvsJavaImplinJava2C.

pStyle=std tableStyle=stdTable

topic

C

C++

Java

Solution in Java2C

classes

manually with struct and associated C-routines

basic concept

basic concept

struct and associated C-routines with a fix schema

packages

no, unified global names.

namespaces as possibility of solution (?)

basic concept

definition of alternative C-names of classes (prefix, postfix) to keep unified names.

extension of classes

struct in struct, manually

basic concept

basic concept

struct in struct with a fix schema

interfaces, dynamic call

manually, function-pointer

using class with abstract methods

basic concept

dynamic call tables with a fix schema

common base class for common features of all classes

unknown, manual solutions

unknown, manual solutions

basic concept: Object

basic concept ObjectJc, but it is shrinking useable.

inner classes

manually possible

only classes like static in Java, elsewhere manually

access to outer class without programming effort. Is it a ObjectOriented Conecpt? It is a visibleness concept of nested structures! It is well useable.

implented with outer->

Container

No standard solution, some reuseable libs

The Standard Template Library, but extensively using of dynamical memory, therefore often improperly for embedded solutions.

java.util

LinkedListJc, ArrayListJc, etc. using BlockHeapJc-Concept for fast realtime memory management.

String-processing

zero-terminated strings as basicly idea, sprintf(...), but unsafely because length of strings are unpredictably.

std::string, but extensively using of dynamical memory, therefore often improperly for embedded solutions. Often using of C-concepts with there unsafetyness.

basic concept String, extensively using of dynamical memory while concatenating strings. Therefore safe! Dynamic memory handling fast!

StringJc, 2 Solutions: a) Without dynamic memory using StringBuilder-Buffer, but safe! Checks the persistence. b) Problem of temorary memory soluted with block heap concept.

dynamic memory

malloc(), but often using static memory because memory leak problem. Problem of management of usage of instances - dangling pointer and memory-glutton.

new(), memory leak problem is the same like C. Who calls delete()?

Garbage Collection, managed also the memory segmentation, therefore no memory leaks. But often not for hard realtime.

BlockHeapJc-concept with blocks with same size, only for small data portions (temporary strings, event-data, nodes for LinkedList). Interrupt-able Garbage Collector for the BlockHeap.

static memory

baisc concept, either malloc() at startup-time or static variables. embedded structs.

same like C

no concept, possible new at startup-time, but not vulgarizes, JTRES: new concept of immortal memory.

same like C, especially support of building of embedded struct on

 Type ref = new Type();

if Type is final.

Orientation of new at startup-time or static memory in C-sources outside Java2C-translated code.

Multi-Threading

No concept, special operation system support necessary

same like C, some special libraries

basic concept, java.lang.Thread, synchronized, Object.wait, java.util.concurrent etc.

basic concept, ThreadJc, ConcurrentLinkedListJc etc., fix os-interface to adapt to any operation system: OSAL-layer.


6.3 The block heap concept and garbage collection

Topic:.Java2C.BlockHeapConcept.

pStyle=std tableStyle=stdTable

In hard realtime long-running systems the using of dynamic allocated memory isn't allowed often. The reason is the hazard of appearance of memory leaks. Memory is allocated and freed to any times in any allocated sizes. An algorithm to sort the allocated areas can't be run because it need non interrupted CPU time to work.

But in more complexly algorithms a usage of dynamic memory is desirable. Using Java it is more suggesting to do so. At example:

Another topic regarding Java-usage is the garbage collector. A typical C or C++ implementation uses malloc or new and the opposite call of free or delete. But if data are interchanged between modules, one module allocated the memory spaces and another module or more as one another module use it. Which module should delete it?

The answer for Java-like programming with hard realtime long running systems is the BlockHeap-Concept. It combines both requirements, the prevention of memory leaks and the garbage collection.

A base idea is, that a dynamically required memory is not a large memory. All main data should be instantiated statically. Dynamically required data are only small pieces of data: A buffer for textual assembling, a buffer for new event data, or such ones.


6.3.1 Blocks of equal sizes

Topic:.Java2C.BlockHeapConcept..

pStyle=std tableStyle=stdTable

Therefore the BlockHeap works with blocks with equal size. If any dynamically memory is required, a whole block is occupied. It is not so effective in memory using, but the kilobytes of available memory are not the first problem. In fine tuning there are supported two block sizes: also small blocks inside a normal block, and third a blocksize for nodes of LinkedList, TreeMap etc.

The BlockHeap management are able to instantiate more as one time. Therewith a independent using of blocks is possible. A outreaching usage of blocks from one BlockHeap management instance don't block the other functionality.


6.3.2 The garbage collector

Topic:.Java2C.BlockHeapConcept..

pStyle=std tableStyle=stdTable

The garbage collector is a basic concept in Java and it should be worked also in C-translated parts. The garbage collector is based on the BlockHeap-Concept.


6.3.2.1 Concept of back references

Topic:.Java2C.BlockHeapConcept...

pStyle=std tableStyle=stdTable

To detect whether a block of the BlockHeap is used, it should be known if references to it are existing. The Blockheap works with backward references:

From all references to blocks of a BlockHeap backward references are noted inside the appropriate Block of the BlockHeap. By storing a reference the appropriated back reference from the block to the using reference should be set. This work is done by calling

 bool setBackRefJc(ObjectRefValuesJc* refbase, void const* src);

where refbase is the memory address of the reference, from member refbase, and src is the object which is referenced and which is located in any block of any blockheap. The memory address of src needn't be the start of the block, it may an address inside a block. At example it may be a reference to an embedded struct or to a part of a string.

The algorithm of setBackRefJc() detects first, to which heap and to which block in the heap the src is appendant. This is a simple address comparing with all known heaps (there are about 1..10 in a users application) and a simple mask of the address, because each block has a size of power of two. It is possible, that src isn't a reference to a block. Than no action is done.

With knowledge of the correct BlockHeap manager and the block, the back reference to the reference can be set into the block. The setting of back-refs needs a few instruction time, but not much one. In the block there is a array of back references. Typically 1..10 back references can be stored. If there are more, the effort is little more, because the back references need an own block in the Blockheap. But this is not typical. The index of the back reference array element is stored in the enhanced reference, inside the element refbase. So a reference knows, whether and where it has a back reference. It may be also of note in test or debug situations.

If a reference is changed, set to null or removed, the back reference have to be deleted. This work is done by calling

 bool clearBackRefJc(ObjectRefValuesJc* refbase);

Because the index to the back reference is known, this is a fast access.


6.3.2.2 Using the back reference info for garbage collection

Topic:.Java2C.BlockHeapConcept...

pStyle=std tableStyle=stdTable

The back reference contains the memory address of the reference to the block. The reference may be located in another block of a BlockHeap, or it is a reference from outside. Outside means, it is from static allocated memory, or possible from a reference in the stack. All references are so named enhanced references, containing the reference (pointer in C) and the additional info refbase.

If a reference comes from outside, the block is used!

If a reference comes from another block of a BlockHeap, it comes from inside. That is a dynamically allocated memory location, also to treat by GC. Thereby it is possible that this block is not referenced from anywhere. The garbage collector assembles all blocks that are referencing together, and test them. It is a cluster of blocks. If no outside references to any block of the cluster are found, there are only internal dangling references. The blocks are not in use. This blocks should be freed. In normally, there are a less number of blocks per cluster, 2 or 3... but it is possible it's more.

Abort GC if the referencing situation is changed

But a thread timing effect maybe: At example A and B references it together. B is referenced from outside. The GC recognizes, A is not used from outside, B will be attempted to test.

                  A <----> B <---outside

Now a higher prior thread interrupts the GC, and changes the reference situation to

   outside -----> A <----> B

This is a simple example, but it describes the common situation. If the GC is continued after this operation, the GC thinks, that A is not be used from outside, and recognized yet, that B is also not be referenced from outside. But this is false.

Therefore the garbage collector is aborted in its work if a block is reused with a new or other reference while it is in the testing cluster. The GC should test the blocks of this cluster again, it should forgot the found now assessment. But second, if the same block is tested again, and a fast algorithm switches the references between this blocks again and again, the GC is aborted again and again and it doesn't step forward. Thats why the aborted GC doesn't start with test of the same (aborted) block, it starts in generally with the next block in the BlockHeap.

All tested blocks of a cluster are queued. The queue uses the element nextBlock in the head data of any block. The queue is used and drained, if the whole cluster of blocks is detect as used or free. To implement the behavior of aborting GC, the nextBlock-reference of a new referenced block is tested. If it is not null, the block is member of the current tested cluster. If a setBackref() handle such a block, it set a bit (signal) to the GC to dismiss its work with the cluster.

References from freed blocks: The backward references have to be deleted

A Cluster spans only the block they have references one another. References from internal data of outside blocks are not tested from GC because they are unknown. But backward references may exist from outside to the freeing-candidate blocks. The next figure show it: X and Y are referenced from A and B. X and Y are not tested yet. A is tested first.

       X <--- Y <--- A <---- B

A is referenced from B, but no references from outside are detected furthermore. Therefore A and B builds a cluster and are freed. The result is:

       X <--- Y <--- ?

The question mark symbols a reference to Y inside the old, now freed A.

The backward references in outside blocks to the freeing-candidate blocks should be purged. It is done to set null to inside references. But the user doesn't should be done it at Java level. This action is done in the finalize()-routine of any class. The finalize() is called from garbage collector before freeing the block using dynamic call concept. The finalize_UserType() is generated from Java2C, regarding all references of the UserType. finalize_UserType() contains this generated part of code, plus the part of a possible finalize()-routine from Java level.


6.3.2.3 Optimizations of back-ref-using

Topic:.Java2C.BlockHeapConcept...

pStyle=std tableStyle=stdTable

Enhanced references with the necessity of call setBackRefJc() are not used

If a reference to a block is only stored in a stack variable without back-reference, it should not be considered by garbage collector to prevent a free of this block while using. Therefore the first (single) using of a block is marked with a bit. If the first back-ref is stored, the block is marked to consider by GC. If no back-reference is stored, the block may be only used locally in a thread. But after its using it should be freed. Therefore on end of the statement block, in which the block is allocated, a call of activateGarbageCollectorAccess_BlockHeapJc() is done to commit it to the GC. After this block either the reference is stored with notation of back-ref, if it is used later again or in another thread, or it is not used furthermore.

But there is a second situation, at example with following Java code:

 void example()
 { Type ref1 = this->ref;
   this->ref = null;
   return ref1;
 }

called by

 Type ref1 = example();
 ref1.dosomething;
 this->ref2 = ref1;

In the 3. line of example() the reference is set to null. It means, the object is not referenced by this->ref. But because the ref1 is not registered as back reference, because it is a stack variable, the GC may free this block, though it is in use. To prevent this situation, there are two solutions:

The second algorithm is implementable in Java2C-translated sources because the translator knowns all situations. But it needs additional calculation time and it is not optimal for fast control.

There is a third solution:

At this time the first solution is focused. If it is necessary, the third solution can be used. The effort of the second solution should be estimated.


6.3.2.4 Advantage of auto generation

Topic:.Java2C.BlockHeapConcept...

pStyle=std tableStyle=stdTable

If an concept of garbage collection is used, it don't care which, some special operations should be done. Using C++, automatic generated destructors or overloaded operators can be used. But in C it should be programmed manually. Therefore the automatic code generation from Java to C helps to do this things. The Java2C translator produces the right code without any slips.