Tuesday, August 25, 2020

Object and array inlining continued

Objects and array inlining operate on a group of objects and arrays in the heap that are in a parent-child relationship. These nest levels allow the reference of a child to be directly in the parent even if a parent has multiple children. There can be a hierarchy of such levels but the difference is only between object fields and array fields. 

The bytecode is the same between array and object fields but the inlining is different between the two. The size of the object is known beforehand. The size of an array is not known until allocation. Hot fields are worth more for optimizing. The Just-in-time compiler is leveraged for this purpose which inserts read barriers that increment field access counters per field and class. 


The inlining works when the following two conditions are met. First, the parent and child objects must be allocated together and the field store that places the reference of the parent in the child must happen immediately afterwards so that it remains true for the lifetime of the data structures that are collocated this way. Second, the field stores must not overwrite the field with a new value. 


The improvement can be seen this way. Let us say Parent and Child are two nested objects. Parent has a member c that points to a child and the child has a member f. Then the access p.c.f would cause the following instructions traditionally: 


eax: p 

mov ebx, [eax+8 

mov ecx, [ebx+8] 

ecxp.c.f 

Instead, the optimized machine code is now: 

eax: p 

mov ecx[eax + 24] 

ecxp.c.f  


The object and array inlining are different. When arrays are used as inlining children, the size of arrays is not clear as a compile time constant. The Java bytecodes for accessing array elements have no static type information. The preconditions can be made similar to that of object inlining if the following three instructions are combined into a single instruction for collocation-  the object allocation of parent, the array allocation of the child, and the field store of the array field.

There are three types of inlining: fixed array inlining, variable array inlining, and dynamic array inlining

Fixed array inlining is one where the array fields can be handled the same way as object fields because the length is constant.

Variable array inlining is one where the array fields have different but fixed lengths.

Dynamic array inlining is one where the array field is assigned multiple times.



Monday, August 24, 2020

Enhancements to introspection events.

 


The introspection stream in a stream store system gathers runtime information in the form of events from all the system components that produce it. The system itself becomes a reader and writer of events. All the events are raw data from the components that may or may not have any aggregation performed over time. These events from the introspection store is helpful for the system diagnostics when call home events are raised. The convenience of logs and metrics to be searched via grep or influxdb sql can also be emulated with stream store events. A stock Flink Application that reads all the events in the introspection store can be included in the utility belt of the troubleshooter. All introspection events may be wrapped in a standard manner so that they appear the same across all publishers within the stream store. The Flink Application may also be savvy to include not just one query but any number of ready-made queries that would provide useful query results to the troubleshooter. The type and format of contents in an introspection store is already known before-hand. This would make the queries also predictable and the library of queries for introspection store can also be kept up to date as and when new publishers are added.

There are still a few enhancements that can be made. 

First, the events themselves can have augmented fields that work with the data from the system. These fields can be automatically injected at the time of write such that they are controlled by policies such as time of day or day of week independent of the system. Just like ‘IPSEC’ rules can be authored based on a number of factors. This automatic injection of fields in placeholders can be done independent of the data published from the system components. An administrator then has the ability to color code certain events based on his policies which can useful for inclusion in the query later.

Second, the queries can be improved if there are field extractors that can process the events of the stream to come up with a set of key-value attributes that can be found in some or all of the events in the introspection store. Consider the injection of arbitrary key values as enhancements to the introspection events by a third party aside from the publishers of the introspection events. These arbitrary key-values can be parsed for field extractions that would provide additional leverage in introspection queries. 

Both injection of fields in introspection events and the extraction of fields for introspection queries are additional enhancements that do not disturb the operations of the system and allow for customizations from administrators and policy-based monitoring software.

Further reading: https://1drv.ms/w/s!Ashlm-Nw-wnWvBx94AZEWepNG5P5?e=IWNHMb 


Sunday, August 23, 2020

Object and Array Inlining continued

 Objects and array inlining operate on a group of objects and arrays in the heap that are in a parent-child relationship. These nest levels allow the reference of a child to be directly in the parent even if a parent has multiple children. There can be a hierarchy of such levels but the difference is only between object fields and array fields. 

The bytecode is the same between array and object fields but the inlining is different between the two. The size of the object is known beforehand. The size of an array is not known until allocation. Hot fields are worth more for optimizing. The Just-in-time compiler is leveraged for this purpose which inserts read barriers that increment field access counters per field and class. 


The inlining works when the following two conditions are met. First, the parent and child objects must be allocated together and the field store that places the reference of the parent in the child must happen immediately afterwards so that it remains true for the lifetime of the data structures that are collocated this way. Second, the field stores must not overwrite the field with a new value. 


The improvement can be seen this way. Let us say Parent and Child are two nested objects. Parent has a member c that points to a child and the child has a member f. Then the access p.c.f would cause the following instructions traditionally: 


eax: p 

mov ebx, [eax+8 

mov ecx, [ebx+8] 

ecxp.c.f 

Instead, the optimized machine code is now: 

eax: p 

mov ecx[eax + 24] 

ecxp.c.f