Inhalt
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++?
C is nearer to machine code as C++ and therefore better appropriate, if the execution code should be known. It is frequently in embedded control.
C is supported for all embedded controller, C++ not in any case.
In C the functionality of inheritance and dynamic calls (interface concept) is implementable. Because the translator produces the necessary code, it should not be manually written, the necessary extensive complex statements don't be a problem.
In C++ a dynamical call (virtual method call) is unsafe, if any bug had destroyed user data. Because: The reference to the virtual table is a part of user data. In C this problem is better able to control: The informations about a derivated instance type is only able to store in user data. But some additional tests are possible if safety software is required. This tests need some, but not to much calculation time (some nanoseconds on fast processors). Dynamical calls are used often only in slower threads (milliseconds). Therefore C++ will be a inappropriate choice for safety software, C is appropriate.
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 |
final Ifc ref = new Ifc(){...} |
struct ref_Ifc_t { ...} ref = ctor_ref_Ifc(...) |
ready. Anonymous classes are translated to a |
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 |
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 |
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.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. |
Topic:.Java2C.changes091_093.
pStyle=std tableStyle=stdTable
. Date: 2010-12-31
Topic:.Java2C.changes091_093.Java2C.
pStyle=std tableStyle=stdTable
There was done a lot of work in detail in the last year.
bugfix: 2009-10-25 Hartmut: A description of statements were written three times, now fixed. Only short description is got from Java code and transported to the C-code.
bugfix: 2010-01-24 Hartmut: On super.call() the reference was written with ythis
, now (&ythis->base.super)
. Source: SecondPass.java.gen_reference(...)
chg: 2010-05-14 If a file is to translate because the Java-src is newer, but the file exists, it will be renamed to "...bak". The other choice may be: It have to be deleted! In other way an error while translating left the file unchanged, the error isn't detected and changes are not applied.
chg: 2010-04-04 The String processing is changed again: Now the calling of toString()
or any other routine which returns a String is optimal respectively fast realtime and works without dynamically memory: The
String is not copied in a independend buffer, but it is referenced where it is (other than in Java!). The String is copied
later when necessary. The behaviour is able to determine with some new annotations in comment, so working without dynamic
memory and with restricted usage possibilities but hard realtime is able to establish, in responsibility to the user. The
String processing is documented out of the view of the CRumtimeJavalike-library (basics of C-Programming) in german language,
see Jc/String_Jc. In that work the behaviour of the Java2C-translator is checked and improved too.
new/bugfix: 2010-04-11 Hartmut: If an inner type of a class is need calling LocalIdents.getType()
, and the environment class was not translated yet, the getLocalIdents()
of the environment type was returned null
. Now the method JavaSrcTreeFile.getLocalIdents()
tests whether the file is translated. It translate it if necessary and returns the correct data.
new: 2010-04-25 A new idea: If an instance is designated with @java2c=embeddedType:Name
than an instance is implemented as embedded instance, also if it is not intitialized, and also, the reference type is a base
type. The translator reserves the memory for the given instance type, and handle the reference adequate to the annotaion @java2c=instanceType
. It means, in Java a base class or interface may be used, but in C the given type is used without dynamically call of methods.
The constructor may be called later, at that moment, where in Java new Type(...)
is called. Than a init_ObjectJc(...)
and before that a finalize_ObjectJc()
is called. A new Type(...)
can be called more as one time, the instance were initialized newly. Thats why the finalize
is called before. If the instance is referenced, the reference refers the new instance after them. This behaviour is other
than in Java. The Java2C-translator may control, whether a reference is used, and it may warn on that (later, TODO). In a
embedded software it should be easily comprehansible. This feature were necessary because the instance of a java.IO.FileOutputStream
is only possible with given Filename with opened file. Without this feature either a dynamic memory management were obligated
or a special wrapper with an open-method were necessary. With this feature the originally Java src-style for such constructs
is able to use.
new: 2010-02-09: If a method returns a non-primitive type, it is a reference. That reference is excluded from the activategGarbageCollection(...)
-call before return. It means, the block is not activated for garbage collection. That is important, because the block is
footloose just now, not staticly referenced. Its reference is returned in stack, and the block may be used footloose yet.
But the calling routine have to call activategGarbageCollection(...)
for that block. This is determined by setting the annotation @java2c=return-new
for that method. Than the caller stores the reference and activates the block for garbage collection, also if it doesn't
use itself. This is the decisive step to enable the working of garbage collection in a higher priority as other threads. Elsewhere
if a block war activated for garbage collection, and it was found as 'non-used', but it is used as stack-referenced, it would
be freed wrongly.
new: 2010-05-15: The check of parameter in the routine ClassData.searchMethod() uses a score. The method, which uses less conversion of parameter, wins. It is important to select the appropriate method. A method whith variable arguments have the lowest score. The problem is found while testing LogMessage.
new: 2010-0612: Initial values were written as initial values in C too. Changed in GenerateClass.gen_variableDefinition(...). The problem is: Java accepts definition of variable inside the block, C only at begin. If the value is const, it is set on begin of the block. If it is non-const, the order of execution have to be regarded. Therefore a initializing at begin of block may be fault, it isn't done, instead the setting of the value at the correct position in the thread of code.
new: 2010-0612: Methods with variable argument list are stored with keyname#*
only one time instead more as one for all imaginable number of parameters. Therewith the usage of stc-file for example for
LogMessageFW.sendMsg(...)
is possible. In the stc-file it is written with ... name
as the last parameter.
new:2010-0725: The stc-File-parsing is redesigned. See java2c:ReadStructure. The content is parsed firstly, and then evaluate. It is important for inner classes. They should be known first before evaluate
the content of other elements which uses it. A second output of structure of a java2c:ClassData-Definition is written if a sub-directory stcCmp
exists at level of source directory of a read stc-file. It is to compare, for test, whether the parsed content is equal to
originally written one. Only for test. If this directory doesn't exist, no second output will be written. The older version
wrote a .sec..file any time, but in the last versions without content.
new:2010-0807: The package replacement and the creation of java2c:JavaSrcTreeFile is changed respectively corrected. The older variant assumes, that all Java-files should be found as Java-files, though they
are not scheduled to translate. For example, if a org/vishia/util/StringPart
is used, it have to be found in the Java-sourcepath of the configuration of Java2C-translation, though it is present in the
translated form (J1c/StringPartJc.c
). Now, if a Java-Type is used and its package-replacement is given, the associated stc-file is found, though a affiliated
Java-file is not existing in the current translation focus. That is better and more practical.
new:2010-0807: The package path and the package replacement are corrected:
In java2c:CRuntimeJavalikeClassData, all standard packages are created. It is for example java/io
, java/util
, but org/vishia/bridgeC
and org/vishia/util
too.
The package- and javafile-replacement for all files, which are contained in the CRuntimeJavalike, were set there too.
But the concretely contents of the java-files respectively there representation in the CRuntimeJavalike in C are contained in stc-files. The stc-files should be parsed, if the types are used. It need a piece of calculation time. But the parsing needs less time (milliseconds). The advantage is, the content is adjustable at text-level. If a method is changed in the CRuntimeJavalike-C-library, the translator shouldn't be changed. Only the stc-file should be adapted. The stc-file is a mapping of structure in relation to the header-files.
The standard types and simple structures are definded in the java2c:CRuntimeJavalikeClassData still.
new:2010-0826: Anonymous inner classes are implemented now. It was complex to do so, but anonymous classes are interesting for a good design of Java-sources. In C automatically named classes are build. The constructor is derived from the called constructor of the base class. Hint: Anonymous classes are built in Java with the syntax 'new Type(param){ derived content of class };'
new: 2010-0826: All methods should be found now. Previously, a non-found-method are created and marked as "/*unknown method*/". It means, now the stc-files have to be completely. If a method isn't found, a detailed error message is given.
new: 2010-0826: ClassData contains the information 'sourceOfClassData' to evaluate, where and when the ClassData are created. It contains either the path of the stc-file or of the Java-file. Or "CRuntimeJavalike-std" is contained there, if the ClassData are created in java2c:CRuntimeJavalike.
new: 2010-12-05: embedded types are handled more correctly, see java2c:Docu.G_Instantiation#g7_embeddedTypes(). Embedded types should be defined as final in Java. Because-they have its mem-space in C. There are not referenced in C.
new: 2010-12-01: The 2. pass of the translation is running after the first pass of the file, not only after all first passes. It has an advantage if some errors of translation occurs. If a second pass war run successfully, it is finished.
new: 2010-12: Some error messages are improved. For example if a method is missed in an stc-file, the signature of the method is shown in the error messages. It may be a hand written stc-file, which can be completed with this informations. The source of the gotten ClassData in the translation process is stored in the ClassData therefore.
new: 2010-12: const as attribute of a class in an stc-file: The class-pointer is designated as Type const* this then. A const instance is built-able in C (read-only methods). ClassData.isConstant as attribute.
new: 2010-12: Persistence of referenced instances, especially used for Strings: The modeStatic in FieldData is used now to designate non-persistent fields using a 'r' as char. It is set if @java2c=nonPersistent is annotated.
new: 2010-12: A new class org/vishia/util/Java4C was created. It contains annotation-interfaces. There are not used yet, but in preparation. It is better to use annotation classes than annotations in the description/comment. It helps for example in Eclipse using word-completion. That annotation classes should be established in the next version.
new: 2010-12-31: abstract classes don't produce now method tables. The first class where it was detected was ByteDataAccess. An abstract method hasn't an implementation, therefore the pointer to the method doesn't exist. The method table of an abstract class is never used because it is never the type of an instance.
Topic:.Java2C.changes091_093.docu.
pStyle=std tableStyle=stdTable
Some things added.
Topic:.Java2C.changes091_093.Jc.
pStyle=std tableStyle=stdTable
chg: 2010-01-25 Hartmut: ReflectionJc.c: An access to a remote memory (at example via FPGA to DSP) was established. Not necessary yet for Java2C.
bugfix: 2010-04-09 Hartmut: BlockHeapJc_GarbageCol.c:testBlockCluster_GarbageCollectorJc(...) and BlockHeapJc_GarbageCol.c:allocObject_IIs_BlockHeapJc(...):
If the heap is overflowed (empty), the ythis->lastFreeBlock
should set to null too. If any block is freed, and ythis->firstFreeBlock == null
, than this is the first now available block. The bug was, if the heap was overflowed, after them freed blocks are not available
any time. The situation was noticeable especially if the garbage collector was running because no block are available calling
alloc_ObjectJc(...)
.
bugfix: 2010-04-09 Hartmut: BlockHeapJc_GarbageCol.c, runUserCalledGc_BlockHeapJc(...)
: A running garbage collection was aborted setting bAbortTestBecauseUserCall
to true
. But this setting had effect also to the current call, it was aborted too. Now the method garbageCollection_BlockHeapJc(bool bUserCall)
knows, whether it is a user call or a normal call.
new: 2010-05-23 Hartmut: Fwc/LogMessage_FW is enhanced with 2 virtual methods: MT_sendMsg_LogMessageFW and MT_sendMsg_time_LogMessageFW. Though a direct virtual call using the method table can be used instead a call of sendMsg_Szv_LogMessageFW(...) which is implemented in LogMessage_FW and calls Jc/getMtbl_ObjectJc(...). The new possibility is faster!
chg: 2010-07-03 Hartmut: The size of blocks in the BlockHeap is defined now as a constant SIZEBLOCK_BlockHeapJc in the file fw_platform_conventions.h. A variable size of blocks in several instances of Blockheap isn't supported anymore. It was a too complex concept, which handicaps a fast calculation from an address inside a block to the start of block. Mostly, the memory is not a strong limited ressource, so fine tunings of block size to save memory is less times necessary as the save of calculation time.
bugfix: 2010-08-16 Hartmut: The Macro SETREFJc has used the argument OBJP twice, so the code is called twice, with side effect of double allocation of memory.
new: 2010-08-15 Hartmut: Some corrections on messages of garbageCollection_BlockHeapJc().
new: 2010-12: Improvement of String processing. The String processing is able to use especially without garbage collection, the necessity of persistence of String can be designated in Java2C via annotations or in C direct with usage of the proper methods.
new: 2010-12: New type ByteStringJc. It is adequat to StringJc, but a ByteStringJc is a byte-container in any case. A StringJc may be a container of UTF-16 chars too (if it is need).
new: 2010-10: The OSAL-adaption is done for Linux. It is not ready yet and not tested in all features, but it is started to do.
new: 2011-01-01: The order of elements in OS_ValuePtr
is changed, now it is renamed to OS_PtrValue
. It needs an adaption in some files, maybe also in user-spaces, and for all os-specific os_types_def.h
-files. The reason for this change: There is not a difference between access to the pointer for enhanced references. It simplifies
the handling in an inspector tool, which works with symbolic access to all variables of a controller software. The pointer
is the first element now.
new: 2010-12: Some checks and improvements are done.
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.
Topic:.Java2C.TODO.
pStyle=std tableStyle=stdTable
.
Topic:.Java2C.TODO.bugsTranslator.
pStyle=std tableStyle=stdTable
calling of methods from super-superclasses or from interfaces of superclasses were wrong anyway. In access to method table
the nested method table is absent: at ex. mtthis->Ifc_Test.processIfcMethod(...)
is produced, correct is mtthis->ImplIfc_Test.Ifc_Test.processIfcMethod(...)
It should be able to fix with small effort! - 2011-01-02: It may be fixed now- to test.
apppend_L_StringBuffer(..., ObjectJc*)
is not implemented yet, the call of toString(...)
from any Object is not tested.
for-loop-variant using iterator isn't implemented yet.
The [] for array type should be arranged also after the indentifier, not only after the type. Support 'long array[]', not only 'long[] array'. This bug isn't fixed yet.
If StringJc is generated in the reflection, it isn't an enhanced reference!
bug100514a: (new TestgarbageCollector()).test(); doesn't work
unnamed inner classes (anonymous) - only one class is admissibile - because algorithm to build the name.
Topic:.Java2C.TODO.genCCode.
pStyle=std tableStyle=stdTable
This part describes, which changes should be done in the form of generated C-Code
bug_genCC912_01 If StringJc is generated in the reflection, it isn't an enhanced reference! ?check whether is fixed?
Topic:.Java2C.TODO.bugsCRJ.
pStyle=std tableStyle=stdTable
The Linux implementation for the OSAL-Layer is not ready yet.
Topic:.Java2C.TODO.bugsDownload.
pStyle=std tableStyle=stdTable
Some Linux-shell-scripts to translated are present, but they are not tested in the current version.
Topic:.Java2C.TODO.future.
pStyle=std tableStyle=stdTable
LinkedList etc. (Container) should be implemented in the near future. Some basics for that are done. A ConcurrentLinkedQueue is present in the CRuntimeJavalike, it works since 2007. But it isn't full integrated in Java2C.
The garbage collector should be tested explicitely, still to do. I assume, it works.
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.
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
Topic:.Java2C.Documentation.
pStyle=std tableStyle=stdTable
See org/vishia/Java2C/Docu.java. This file contains detaild descriptions.
Topic:.Java2C.swConceptsInCentury.
pStyle=std tableStyle=stdTable
1955: COBOL, Fortran: High level Language Programming
1975: C (Algol, Pascal): Structural Programming
1995: Java (UML): Object Oriented Programming (C++ is not a new concept, only the application of OOP to C with some additional ideas)
2015: commonly using of dynamic programming languages? Functional Programming as new concept after OOP?
All programming language are still in use.
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. |
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:
The assembling of a textual output with some informations need a buffer. In C the using of sprintf
is a decision. But the buffer should be supplied or existing.
Events in a statemachine- or event driven system often needs dynamic allocated memory for itself or for there data.
In C or C++ without using dynamic memory a self-made memory management for special cases is implemented often. But this implementations are user specific though it is a system requirement. It is an effort in the users software.
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.
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.
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.
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.
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.
Topic:.Java2C.BlockHeapConcept...
pStyle=std tableStyle=stdTable
Enhanced references with the necessity of call setBackRefJc() are not used
for local (stack-) -variables and method arguments,
for classes there are not slated for using in dynamically memory, that classes should be marked with @staticInstance
in the description of class.
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:
first: The GC should only run, if no other thread is running. It means, it don't interrupt any algorithm. This solution is possible, if a realtime system have only fast threads, there are limited in calculation time. It is typically for time cyclic control algorithms. A system which uses a real Java Virtual Machine for longer processing algorithms, and implements only the fast cyclic parts in C, are a matching example. The GC should run in the lowest thread priority or in a background loop.
second: All accesses to the value of a references should be implement the setting of the same bit mConsideredInGarbage_Type_Object
in the head data of the block like after a new-statement. All in this manner used blocks should be stored in a list, and should
be processed with activateGarbageCollectorAccess_BlockHeapJc()
at the end of the visibility of the stack reference. But exclusive that value, which is returned. But this value of block
reference should be handled in the stack level above.
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:
A reference stored as class member should never used only locally, it should be set to null in class member only if the usage of it is excluded. - But this is a request to the programming style.
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.
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.