Cédric Marchand
email: cedric.marchand@univ-ubs.fr

Emmanuel Boutillon
email: emmanuel.boutillon@univ-ubs.fr

Rate-adaptive Inner Code for Non-Binary Decoders

Keywords: Low SNR, Rate-adaptive, Non-Binary decoder, CCSK, CSK, truncated, sequence

In most communication systems, the coding rate of the error control code adapts to the channel condition. In this paper, we propose a new approach. A fixed coding rate GF(q) Non-binary code is used as an outer code, and a cardinal q nonlinear inner code is truncated to match the channel condition. The inner code is a Truncated Cyclic Code Shift Keying code. Simulation results for a payload of 120 bits show state-of-the-art performances in a wide range of SNR from -13.5 to 7 dB.

I. INTRODUCTION

Non-Binary (NB) LDPC codes [START_REF] Voicila | Low complexity decoding for non-binary LDPC codes in high order fields[END_REF], designed over Galois Field GF(q) have recently been adopted in satellite standards [START_REF]BeiDou Navigation Satellite System[END_REF]. They benefit from better error-correcting performance than their binary counterpart, especially when targeting short to moderate frame length [START_REF] Davey | Low density parity check codes over GF(q)[END_REF]. Recent standards define a rateadaptive scheme to adapt to channel conditions [START_REF] Etsi | Digital Video Broadcasting (DVB); Second generation framing structure, channel coding and modulation systems for Broadcasting,Interactive Services, News Gathering and other broadband satellite applications (DVB-S2)[END_REF] or available resources [START_REF]5G; NR; Multiplexixing and channel coding[END_REF]. However, designing a rate-adaptive NB-decoder along with NB codes is still a complex task. In fact, most NB decoder implementations are optimized for a single code rate [START_REF] Marchand | Hybrid Check Node Architectures for NB-LDPC Decoders[END_REF] [START_REF] Park | A Fully Parallel Nonbinary LDPC Decoder With Fine-Grained Dynamic Clock Gating[END_REF] [START_REF] Lin | An Efficient Decoder Architecture for Nonbinary LDPC Codes With Extended Min-Sum Algorithm[END_REF]. One way to get around the problem is by giving the rate-adaptive task to an inner code.

Code shift keying (CSK) or Cyclic CSK (CCSK) modulation [START_REF] Wong | Code-phase-shift keying: a power and bandwidth efficient spread spectrum signalling technique for wireless local area network applications[END_REF] [10] is a 2 m -ary Direct-Sequence Spread Spectrum (DSSS) technique that associates m-bits symbols to 2 m -chips sequences. The CCSK sequences are defined by a circular shift of the initial Pseudo-random Noise (PN) root sequence. An example of application is the Quasi-Zenith Satellite System (QZSS) [START_REF]Quasi-Zenith Satellite System Interface Specification -Centimeter Level Augmented Service (IS-QZSS-L6-003)[END_REF], where the encoded 8-bit symbols of a Reed-Solomon (255,223) code are mapped on CCSK sequences. An example of encoded symbols (first step) mapped on CCSK sequences (second step) is shown in Fig. 1. Without loss of generality, the NB-encoder is in this article an NB-LDPC encoder. This concatenation allows to target efficiently very low SNRs and gives advantages in both modulation and synchronization [START_REF] Abassi | Nonbinary coded CCSK and Frequency-Domain Equalization with simplified LLR generation[END_REF]. The Truncated CCSK (TCCSK) described in [START_REF] Dillard | Cyclic code shift keying: a low probability of intercept communication technique[END_REF] consists of not transmitting consecutive bits of the CCSK sequence to obtain code rate flexibility. Fig. 1 also highlights, in a third step, the truncation applied to the CCSK symbols. Thus, the combination of an NB decoder with a TCCSK code allows obtaining flexible rate while keeping the NB decoder optimized for a single rate.

Another simple process to obtain a flexible code is to use a repetition scheme as in 5G [START_REF]5G; NR; Multiplexixing and channel coding[END_REF] for the polar codes. In [START_REF] Kasai | Multiplicatively Repeated Nonbinary LDPC Codes[END_REF], an NB-LDPC code is concatenated with a repetition scheme where repeated GF symbols are multiplied by a predefined GF coefficient, giving better performance than best low-rate Fig. 1. Inner Truncated CCSK concatenated with outer NB encoder binary codes. In [START_REF] Savin | Multi-relay cooperative NB-LDPC coding with non-binary repetition codes over block-fading channels[END_REF], the non-binary multiplicative coefficients are optimized with the Hamming distance of the binary image of the component code. Similarly, the CCSK code is chosen for its good Hamming distance.

In this paper, the concatenated code is further enhanced to obtain fine-grained code rates and higher code rates than the outer NB code. An example of CCSK coding scheme for k = 20 information symbols on GF(64) and FER = 10 -3 shows a spectral efficiency within 2 dB from achievable capacity at finite blocklength regime [START_REF] Polyanskiy | Channel Coding Rate in the Finite Blocklength Regime[END_REF] at SNR from -13.5 dB to 7 dB.

The paper is organized as follows: Section II introduces NBcodes, the CCSK modulation, and the concatenation of an NB encoder with a CCSK modulation. Section III presents the truncation process applied to the CCSK modulation. Section IV presents simulation results. Finally, Section VI concludes the paper.

II. NB-LDPC CODES AND CCSK MODULATION

A. NB-LDPC codes

In this article, a NB-LDPC code is used as NB-code without loss of generality. Throughout this article, NB-LDPC codes are defined over GF(q) where q = 2 m . A NB-LDPC encoder encodes k symbols into n symbols as shows in Fig. 1. The outer code rate is given by r o = k/n.

Since the output of a NB encoder are NB symbols that can be directly mapped to modulation of the same order, both the NB-LDPC encoder and decoder do not need modification to be concatenated with the CCSK modulation.

B. Pseudo Noise sequence construction

CCSK uses a Pseudo-Noise (PN) binary sequence of length p 0 ≥ q defined as B 0 = (B 0 (0), B 0 (1), ..., B 0 (p 0 -1)), where B 0 (i) ∈ {0, 1}, ∀i = 0, ..., p 0 -1. The PN sequence can be generated using an m-sequence, an extended m-sequence [START_REF] Fiebig | Correlation properties of extended msequences[END_REF], or a balanced sequence with good auto-correlation properties. An m-sequence has a length of 2 m -1 bits and is generated using a Linear Feedback Shift Register (LFSR) of m bits.

Considering an example of 4-bit LFSR with a feedback polynomial g(x) defined as g 4 (x) = x 4 + x + 1 and an initialization state with the first flip-flop set at 1 and others set at 0, the obtained m-sequence of 15 chips is

B 0 = [000111101011001]. (1)
The m-sequence is a Maximum-Length Sequence (MLS), i.e., during a period of 2 m -1 cycles, the m LFSR registers take all possible 2 m -1 states (2 m states minus the all-zero state). In [START_REF] Fiebig | Correlation properties of extended msequences[END_REF], for practical reasons, the MLS is extended to 2 m chips by adding the all-zero state. The all-zero state is obtained by inserting a zero to the longest run of 0 in the MLS. Due to the periodicity of MLS, B 0 (0) = B 0 (q -1) = 0, the MLS of ( 1) is extended by one bit as follows

B 0 = [0001111010110010]. (2)
By applying one right circular shift to B 0 , one can check that a run of m zeros is obtained. Also, the sequence is balanced with the same number of occurrences of 0 and 1. This result is valid for all Extended MLS (EMLS) with all m values, provided that the first LFSR flip-flop is initialized with a 1 and others are initialized with zeros.

C. CCSK mapping

The CCSK modulation maps an element b ∈ {0, 1, ..., q-1} to the sequence B b defined as the circular left shift of B 0 by b positions, that is

B b (i) = B 0 (i + b mod p 0 ), ∀i = 0, ..., p 0 -1. (3)
where p 0 ≥ q. Then, a BPSK modulation (0 → 1, 1 → -1) maps the B b sequence to the P b sequence.

Let us define the injective function π that gives b the value of the circular shift of B 0 by b positions as a function of the GF symbol a. Table I gives an example where B 0 is given by ( 2) and q = 8. The PN sequence B 0 is shifted circularly by π(a) = b positions to transmit a symbol a ∈ GF [START_REF] Lin | An Efficient Decoder Architecture for Nonbinary LDPC Codes With Extended Min-Sum Algorithm[END_REF].

Since binary representation of GF(q) symbols are on log 2 (q) = m bits and the m bits are mapped on p 0 chips, we define the inner code rate as

r i = m p 0 . (4)
Considering both the inner CCSK code and the outer NB code, we define the effective code rate as

r = r o × r i . ( 5
) TABLE I SEQUENCE AS A FUNCTION OF a WITH p 0 > q a b = π(a) B b 0 0 0001111010110010 α 0 1 0011110101100100 α 1 2 0111101011001000 α 2
3 1111010110010000 α 3 4 1110101100100001 α 4 5 1101011001000011 α 5 6 1010110010000111 α 6 7 0101100100001111

Considering an example with GF(64), r o = 1 3 and p 0 = q, then r = 1 3 × 6 64 = 1 32 . With p 0 > q, one can target a much lower effective coding rate. e.g., with p 0 = 1024 then r = 1 512 .

III. TRUNCATED CCSK

A. Principle

The TCCSK sends the first p bits p ≤ p 0 of the CCSK sequence as shown in Fig. 1. The TCCSK mapping is defined as

B p b (i) = B 0 (i + b mod p 0 ), ∀i = 0, ..., p -1. (6)
The truncation rate is r T = p0 p and the inner code rate is updated to

r i = m p . (7)
To avoid r i greater than 1, p is lower bounded to p ≥ m. Thus, r i can take p 0 -m + 1 different values between m p0 and 1, i.e., m p0 ≤ r i ≤ 1. Let us apply a truncation such that p = m = 3 to the CCSK mapping shown in Table I One can see in Table II that B 3 3 = B 3 4 . When applying truncation to natural CCSK mapping, two different symbols can map the same truncated sequence, which will lead to significant performance degradation. The optimized injective function π makes sure that all symbols in GF(q) are mapping a different truncated sequence. Hence, π must validate

When p 0 > q, the mapping optimization can be done by an update of π such that (8) is true. In Table II, π is optimized to π where π (4) is updated to meet the requirement in [START_REF] Lin | An Efficient Decoder Architecture for Nonbinary LDPC Codes With Extended Min-Sum Algorithm[END_REF]. Thus, when p 0 > q, a specific mapping π is precomputed.

B. Construction of optimized sequence for truncation

By construction, an MLS will produce q -1 different truncated sequences of size p = m, i.e., all possible different truncated sequences except the all-zero sequence. The EMLS provides the missing truncated sequence, i.e, B T 16 of (2) gives [0000]. Thus, the EMLS validates (8) by definition. For p 0 > q, many sequences and π options validate (8) but the challenge is to find out the sequence that provides the best performances.

First, a cost criterion has to be defined to select a root sequence rather than another. The CCSK modulation is considered as a code and its minimum Hamming distance is computed. Each sequence B b of the CCSK modulation is studied as a codeword and the CCSK modulation with the highest hamming distance is selected. When p 0 = q, an EMLS of degree m can be used as a reference, and the exploration of the best possible solutions can be limited to the selection of the MLS primitive that gives the best Hamming distance. When p 0 > q, the exploration space is huge. One solution to obtain a good Hamming distance for (l+1)×q > p 0 > l×q is to use an MLS of degree m + l + 1, then truncate the obtained root sequence to p 0 and update π to meet the requirements in [START_REF] Lin | An Efficient Decoder Architecture for Nonbinary LDPC Codes With Extended Min-Sum Algorithm[END_REF]. Fig. 2 shows the average Hamming distance per chip as a function of p for a CCSK constructed from an EMLS, an MLS, or a repetition code. The EMLS is of size p = 64 and is generated from polynomial g 6 (x) = x 6 + x + 1. The MLS is of size p 0 = 127 and is generated from polynomial g 7 (x) = x 7 + x + 1. The min distance of the repetition code is given by p/m . The MLS shows a Hamming distance 3 times better than the repetition code for p = p 0 = 127.

The EMLS also has the property to have a uniform distribution of 0s and 1s, assuming a uniform distribution of a ∈ GF(q), for all p values. The MLS does not have the same property but can be optimized with π to obtain uniform distribution with less than 1% deviation.

C. Per symbol truncation

The highest truncation also gives the highest code rate gap between two code rates. The two highest truncations for q = 64 are p = 6 and p = 7 which gives according to ( 5) and ( 7), r = 1/3 and r = 2 7 . The percentage difference between the two r is 15%. When targeting a fine-grained rateadaptive decoder, a finer code rate adaptation can be obtained by considering per symbol truncation. This technique applies a different truncation value as a function of the j th encoded symbol. The average truncation p is given by

p = 1 n n-1 j=0 p(j), (9)
where p(j) is the truncation applied to the j th CCSK sequence associated with the j th symbol. The average inner code rate r i with per symbol truncation is given by

r i = m p . (10)
To obtain fine-grained values between p and p + 1, we can use CCSK mapping on p + 1 chips for the first x symbols and CCSK mapping on p chips for the last n -x other symbols. The average p value is updated to

p = p + x n . ( 11
)
Thanks to this process, the code rate gap can be as fine as required. With n = 10, the maximum gap is less than 2% and with n = 100, the maximum gap is less than 0.2%.

D. CCSK over-truncation

CCSK over truncation consists of sending only p < m bits. This truncation process is called over-truncation since the TCCSK code rate becomes greater than one, i.e., r i = m/p > 1. However, the effective code rate r can not be greater than 1, giving a lower bound to p such that p > r o × m. With r o =1/3, it is possible to target r equals 2/3, 1/2, or 2/5 respectively with p equals 3, 4, or 5 bits.

Over-truncation leads to loss of information since (8) constraint can not be found. The NB decoder is in charge of recovering this loss. Over-truncation is applied more on redundant symbols than on information symbols to obtain good performance. Let us consider p I , the truncation applied to information symbols, and p R the truncation applied to the redundant symbols. Table III gives the p I , p R , and obtained r used for simulations.

IV. SIMULATION RESULTS OF TCCSK

In this section, the CCSK demodulation used in simulations and the TCCSK capacity shown in simulations are first described.

A. CCSK demodulation

The intrinsic associated with each symbol a is obtained from the CCSK demodulation. Let us consider a symbol a ∈ GF(q) transmitted using CCSK modulation with X = P a . Assuming Binary Additive White Gaussian Noise (Bi-AWGN), the received CCSK signal is

Y (i) = X(i) + Z(i), (12)
where Z(i) are real-valued, mutually independent samples of the N (0, σ 2 ) normal distribution.

The a priori information associated with the received symbol is given by the Log-Likelihood Ratio (LLR) value defined by

Γ(a) = log Pr(X = P â|Y ) Pr(X = P a |Y ) , (13)
where â = arg max Pr(X = P a |Y ), a ∈ GF(q). Hence, we have

Γ(a) = p-1 i=0 log Pr(P â(i)|Y (i)) Pr(P a (i)|Y (i)) = p-1 i=0 P â(i) -P a (i) 2 log Pr(X(i) = +1|Y (i)) Pr(X(i) = -1|Y (i)) . (14)
With BI-AWGN channel, we have log Pr(X(i)=+1|Y (i))

Pr(X(i)=-1|Y (i)) = 2 σ 2 Y (i) and therefore Γ(a) = 1 σ 2 p-1 i=0 Y (i)P â(i) -Y (i)P a (i). (15)
Note that by construction, Γ(â) = 0 and Γ(a) ≥ 0.

B. TCCSK capacity

The mutual information between the input U of the TCCSK modulation and the output Y of the channel give the maximal achievable rate r of the TCCSK modulation. I.e.,

r = I(U ; Y ) = H(U ) -H(U |Y ), (16)
where U denotes the channel input, H(U ) denotes the entropy of U , and H(U |Y ) denotes the conditional entropy of U given Y . For BPSK modulation, H(U ) = 1 and the conditional entropy H(U |Y ) can be estimated numerically by Monte-Carlo simulation by averaging over the channel output Y ,

H(U |Y ) = E Y   - k∈Zq Π(k) log q Π(k)   , (17)
where Π(k) = Pr(U = k|Y ) denotes the conditional probability distribution of U given Y .

Let us define the Monte-Carlo simulation that provides I(U ; Y ) = f (SNR,p). To compute the curve showing capacity r as a function of SNR, one must find the SNR that validates I(U ; Y ) = r for a given p value.

In [START_REF] Polyanskiy | Channel Coding Rate in the Finite Blocklength Regime[END_REF], Polyanskiy et al. show that the maximal rate achievable with error probability and block length N is closely approximate by

C * = C - V N Q -1 ( ), (18)
where V is a characteristic of the channel referred to as channel dispersion, and Q is the complementary Gaussian cumulative distribution function.

C. Simulation results

The NB decoder is an NB-LDPC decoder on GF(64) using the Extended Min-Sum algorithm [START_REF] Voicila | Low complexity decoding for non-binary LDPC codes in high order fields[END_REF], a forward-backward check node implementation [START_REF] Boutillon | Bubble check: a simplified algorithm for elementary check node processing in extended min-sum non-binary LDPC decoders[END_REF], a maximum of 30 iterations, n m = 20, and n op = 25. The NB-LDPC code is a k = 20 and r o = 1/3 code. The Signal-to-Noise Ratio is defined as SNR=-10 log 10 (σ 2 ) (dB).

Fig. 3 shows simulation results of an NB decoder combined with TCCSK. The CCSK sequence is an MLS of length p 0 = 127. The simulation of the NB-decoder alone (without TCCSK) with BPSK modulation provides a reference curve for r = 1/3. The TCCSK with p = 6, 7, 8, and 9 provide simulation results for r = 1/3, 2/7, 1/4, 2/9 respectively. The TCCSK with over truncation at p = 5 and p = 4 provide simulation results for r = 1/2 and 2/5 respectively. One can check that the NB decoder alone with BPSK gives the same simulation result as the NB-decoder concatenated with TCCSK with p = 6 (r o = 1/3 and r i = 1). Simulation results of 5G are also shown for comparison with state-of-the-art. 5G results are obtained using flooding BP, a maximum of 50 iterations, LDPC code base 1, 120 information bits, code rates 1/3, 2/5, 1/2 and BPSK modulation.

Fig. 4 shows r as a function of the SNR required to obtain FER= 0.001. The simulation result of the TCCSK concatenated with the NB-LDPC is shown on its full code rate range. The circle on the TCCSK range represent the simulation result of the NB decoder with BPSK modulation. The maximal achievable coding rate of a BPSK modulation is shown as a reference. The TCCSK's capacity is obtained from ( 16) and ( 17) by simulation. The achievable coding rate of TCCSK modulation for a given FER and frame length [START_REF] Polyanskiy | Channel Coding Rate in the Finite Blocklength Regime[END_REF] is computed from (18). Furthermore, the simulation result of a repetition process concatenated with the NB decoder is also shown. At SNR lower than -5 dB, repetition shows 0.75 dB performance loss compared with the TCCSK solution.

V. CONCLUSION

In this paper, we show that a low SNR fine-grained rateadaptive NB decoder can be obtained by combining an NB decoder with a Truncated CCSK modulation. The truncation process shows achievable capacity close to the Shannon capacity.

Fig. 2 .

 2 Fig. 2. Average Hamming distance per chip of inner code as a function of p

1 FERFig. 3 .

 13 Fig. 3. FER Simulation results with TCCSK.

Fig. 4 .

 4 Fig. 4. Full code rate range simulation results with TCCSK.

  , i.e., to transmit a symbol a ∈ GF[START_REF] Lin | An Efficient Decoder Architecture for Nonbinary LDPC Codes With Extended Min-Sum Algorithm[END_REF], only the first 3 chips of the B b sequence are transmitted instead of 16 chips. TableIIgives the truncated sequence B m b associated to each symbol a.

TABLE III r

 III AS A FUNCTION OF p I AND p R VALUES

	p I	p R	p	r i	r	r
	6	1	8/3	9/4	3/4	0.75
	5	2	3	2	2/3	0.667
	6	2	10/3	9/5	3/5	0.6
	6	3	4	3/2	1/2	0.5
	5	5	5	6/5	2/5	0.4
	. . .	. . .	. . .	. . .	. . .	. . .
	64	64	64	6/64	2/64	0.031

ACKNOWLEDGEMENT

This work has been funded by the french ANR under grant number ANR-19-CE25-0013-01 (QCSP Project: https://qcsp.univ-ubs.fr/).


MUSCLE WASTING IN HEAD AND NECK CARCINOMAS: INVESTIGATIONS ON THE UNDERLING TRANSCRIPTIONAL REPROGRAMMATION j

Héla Hachicha¹, Iryna Pirozhkova², Aurore Gelin², François Bidault², Valérie Rouffiac², Thibault Dayris², Thierry Ragot², Ingrid Breuskin², Caroline Even², Philippe Gorphe², Pierre Busson².

¹ Henri Becquerel Cancer Center, Rouen, France, ² Gustave Roussy institute, Villejuif, France.

RESULTS: INTRODUCTION:

Cancer cachexia:  Is a multifactorial syndrome often including skeletal muscle atrophy .  Affects at least 55% of patients bearing Head and Neck Squamous Cell Carcinomas (HNSCCs) 

To our knowledge, molecular mechanisms of muscle alterations have never been investigated on clinical muscle specimens from HNSCC patients. The aim of this study was to perform transcriptome profiling by bulk RNAseq on human immortalized myoblasts co-cultivated with malignant HNSCC cells in vitro, muscle fragments collected from HNSCC patients with or without cachexia, and finally from nude mice bearing human HNSCC xenografts.

METHODS:

Our study was made in three parts:

 In Vitro investigations on human myoblasts co-cultivated with HNSCC cells (FADU et SQ20B):

 Indirect co-culture system (without cell-cell contact), using Transwell inserts .  Proliferation setting: MyoN cells were seeded in 6 well plates (5000 cells/well) and expanded using a specific "proliferation" or "growth" medium.  Differentiation setting: MyoN cells were seeded in 6 well plates at high density (250 000 cells/well), incubated in rich medium for 24h to have cells reaching confluence and then subjected to a change of culture medium with substitution by a less rich one called "differentiation" medium. MitoTracker™ Orange (fluorescent mitochondrial dye) and Hoechst 33342 (fluorescent DNA dye), were added into the culture media : Differentiating cells were distinguished according to their mitochondrial reactivity.

 In Situ investigations on muscles collected from nude mice xenografted with HNSSCs cells (FADU):

 Exploration of clinical muscle samples collected from HNSCC patients.

12 patients with a diagnosis of HNSCC (Department of Head and Neck surgery of Gustave Roussy Institute). 3 control skeletal muscle fragments from patients free of malignant tumors, age and sex matched.

 RNA sequencing was used to assess gene expression changes and gene function enrichment in myoblasts co-cultivated with malignant cells as well as skeletal muscle samples collected from mice xenografted with HNSCC cells (FADU) or HNSCC patients.



  on human myoblasts co-cultivated in vitro with HNSCC cells Control MyoN cells MyoN co-cultivated with FADU cells MyoN co-cultivated with SQ20B Effect of HNSCCs cells on human proliferating myoblast cell number Influence of HNSCC cells on human differentiating myoblasts in vitro  Impact on the number and morphology of MyoN cells proportional to the amount of malignant HNSCC cells.  Mitotracker fluorescence much weaker for cells co-Two genes are upregulated in sarcopenic muscles in situ as well as in co-cultivated myoblasts in vitro CONCLUSIONS: Up-regulation of BIRC 3 is a transcriptional modification shared by sarcopenic muscles in ENT patients and in xenografted mice as well as by myoblasts co-cultivated in vitro with malignant cells. Although the mechanism of BIRC3 up-regulation in cachectic muscle cells is not yet known, this finding is likely to be important for the management of HNSCC patients in a context of promising therapeutic results obtained using Smac mimetics. Because these compounds are inhibitors of the c-IAP protein family, it will be important in the future to monitor their positive or negative effects on muscle alterations in cachectic HNSCC patients. of IL-32 and BIRC3 transcripts upregulated in sarcopenic muscle in situ and myoblasts co-cutivated with malignant cells in vitro Mann-Whitney test was performed to define significant difference. *p<0.05 **p<0.01; ***p<0.001. and skeletal muscle mass: Body weight Skeletal muscle mass by micro-computed tomography  L (Length of the tibia)  T (Thickness of the muscle)  IMM: T/L Gastrocnemius muscle weight RT qPCR of genes coding for factors involved in muscle growth and differentiation. RNA was extracted from gastrocnemius muscles of mice. Mann-Whitney test was performed to define significant difference. *p<0.05 **p<0.01; ***p<0.001. component analysis (PCA) → Distinction between different muscle location → Major transcriptome variations are observed depending on muscle anatomic location. However, transcriptome alterations related to tumor bearing conditions are observed regardless of muscle anatomic locations, including up-regulation of BIRC3 transcription. Part 2: Transcriptionnal alterations in human sarcopenic muscle in vitro and in situ Part 3: Investigations of muscle wasting in nude mice xenografted with HNSCC cells Volcano plot of the distribution of all DEGs Heatmap comparing cervical muscle to hind leg muscles RNA extracted from 16 muscles specimen collected from 3 control mice and 3 mice xenografted with FADU cells)


Guillermo Polito
email: guillermo.polito@univ-lille.fr

Pablo Tesone

Stéphane Ducasse

Luc Fabresse
email: luc.fabresse@imt-lille-douai.fr

Théo Rogliano

Pierre Misse-Chanabier

Carolina Hernandez Phillips

Cross-ISA Testing of the Pharo VM: Lessons Learned While Porting to ARMv8

Keywords: Software and its engineering → Runtime environments just-in-time compilers, virtual machines, ARM, testing, ports, Cross-ISA

Testing and debugging a Virtual Machine is a laborious task without the proper tooling. This is particularly true for VMs with JIT compilation and dynamic code patching for techniques such as inline caching. In addition, this situation is getting worse when the VM builds and runs on multiple target architectures.

In this paper, we report on several lessons we learned while testing the Pharo VM, particularly during the port of its Cogit JIT compiler to the AArch64 architecture. The Pharo VM presented already a simulation environment that is very handy to simulate full executions and live-develop the VM. However, this full simulation environment makes it difficult to reproduce short and simple testing scenarios. We extended the pre-existing simulation environment with a testing infrastructure and a methodology that allow us to have fine-grained control of testing scenarios, making tests small, fast, reproducible, and cross-ISA.

We report on how this testing infrastructure allowed us to cope with two different development scenarios: (1) porting the Cogit JIT compiler to AArch64 without early access to real hardware and (2) debugging memory corruptions due to GC bugs.

Introduction

Testing and debugging a Virtual Machine is a laborious task without the proper tooling. This is particularly true for VMs that support code generation for JIT compilation and dynamic code patching for techniques such as inline caching. This complexity is aggravated when the VM builds and runs on multiple target architectures [START_REF] Bowen Alpern | Experiences Porting the Jikes RVM to Linux/IA32[END_REF].

Several solutions have been proposed to aid in VM debugging tasks. Traditionally, VM simulation environments have appeared in Self [START_REF] Ungar | Constructing a metacircular Virtual machine in an exploratory programming environment[END_REF], Smalltalk [START_REF] Ingalls | Back to the Future: The Story of Squeak, a Practical Smalltalk Written in Itself[END_REF][START_REF] Miranda | Two decades of smalltalk VM development: live VM development through simulation tools[END_REF] and Metacircular VMs such as Maxine [START_REF] Wimmer | Maxine: An approachable virtual machine for, and in, java[END_REF]. Complementary to simulation environments, multi-level debuggers [START_REF] Kruck | Multi-Level Debugging for Interpreter Developers[END_REF][START_REF] Thomas "würthinger | Multi-level Virtual Machine Debugging Using the Java Platform Debugger Architecture[END_REF] aid VM developers to switch views between the program-level and the implementation (VM)-level. These solutions are indeed beneficial to identify and track problems once an issue has been spotted and reproduced. However, reproducing bugs still remains an expensive and long task because millions of instructions may need to be executed before hitting the actual problem. For example, it has been reported that debugging memory corruption bugs in a simulation could take several hours of execution 1 . Recently, the team of Maxine recently reported a test-based infrastructure for cross-ISA debugging [START_REF] Kotselidis | Cross-ISA debugging in meta-circular VMs[END_REF]. They report that still debugging happens in gdb in a different abstraction level than the original source code and that they are not able to cover many parts of their codebase.

In this paper, we report on several lessons we learned while testing the Pharo VM, particularly while porting its Cogit JIT compiler to the AArch64 architecture. The Pharo VM presented already a high-level simulation environment that is very handy to simulate full executions and live program the VM [START_REF] Miranda | Two decades of smalltalk VM development: live VM development through simulation tools[END_REF] (See Section 2). We extended the preexisting simulation environment with a testing infrastructure that allows us to have fine-grained control of testing scenarios, making tests small, fast, reproducible, and cross-ISA (See Section 3). We defined a hybrid testing methodology that takes advantage of the strengths of unit-testing, full-system simulation, and real-hardware execution where they perform better. In Section 5, we describe how this testing infrastructure allowed us to cope with two different development scenarios: [START_REF] Bowen Alpern | Experiences Porting the Jikes RVM to Linux/IA32[END_REF] porting the Cogit JIT compiler to AArch64 without early access to real hardware and (2) debugging memory corruptions due to GC bugs.

Context: The Pharo VM

The Pharo Virtual Machine is an industrial level Virtual Machine written in Pharo itself and transpiled to C using a VM-specific translator called Slang [START_REF] Ingalls | Back to the Future: The Story of Squeak, a Practical Smalltalk Written in Itself[END_REF]. The VM implements at the core of its execution engine a threaded bytecode interpreter, a linear non-optimising JIT compiler named Cogit [START_REF] Miranda | The Cog Smalltalk Virtual Machine[END_REF] that includes polymorphic inline caches [START_REF] Hölzle | Optimizing Dynamically-Typed Object-Oriented Languages With Polymorphic Inline Caches[END_REF] and a generational scavenger garbage collector that uses a copy collector for young objects and a mark-compact collector for older objects [START_REF] Ungar | Generation Scavenging: A Non-Disruptive High Performance Storage Reclamation Algorithm[END_REF]. The following numbers illustrate the complexity of this Virtual Machine:

• It implements 255 bytecodes, organized in a total of 77 different families [START_REF] Béra | A bytecode set for adaptive optimizations[END_REF].

• It implements about 340 primitive methods, with a number of them both duplicated in the interpreter and in the JIT compiler.

• The compiler defines about 150 different IR instructions.

Slang

The Pharo Virtual Machine is written in a subset of Pharo that is easily transpilable to efficient C. As Pharo is a Smalltalk inspired language, the Pharo to C translation is done using Slang, a Smalltalk-to-C VM-specific transpiler [START_REF] Ingalls | Back to the Future: The Story of Squeak, a Practical Smalltalk Written in Itself[END_REF]. Slang operates by translating a group of classes into a single C file. Methods are translated into functions, message-sends are translated as function calls. While the Pharo source program presents dynamic behaviour such as polymorphism, exceptions, or runtime reflection, Slang does not allow many of those: it either forbids them at translation-time or generates invalid C code. Using Slang to develop the Pharo VM has two key advantages. First, Slang automatically introduces interpreter optimisations such as (a) the localisation of critical variables (frame pointer, instruction pointer) [START_REF] Miranda | BrouHaHa -A Portable Smalltalk Interpreter[END_REF], (b) the inlining of bytecode cases inside the interpretation loop, or (c) threaded code [START_REF] Ertl | The Structure and Performance of Efficient Interpreters[END_REF]. Second, it allows us to simulate the Pharo VM just by executing it as normal Pharo code, avoiding expensive change-compile-test development cycles [START_REF] Miranda | Two decades of smalltalk VM development: live VM development through simulation tools[END_REF].

The Cogit JIT Compiler

The Cogit JIT compiler is a non-optimising method-based linear JIT compiler originally implemented by Miranda [START_REF] Miranda | The Cog Smalltalk Virtual Machine[END_REF]. It uses a linear 2-address-code intermediate representation that does not explicitly model a control flow graph (CFG). The compiler implements monomorphic inline caches as linked sends, and polymorphic inline caches as stubs. The compiler's entry point for compilation is a single method where bytecodes are translated in linear fashion into machine code: the code layout of the generated machine code almost entirely mirrors the code layout of the bytecode. Compiling a method includes three main phases:

• 1. Bytecode scan phase iterates the bytecodes of a method to extract meta-data from them. For example, it decides whether the method requires to be frame-less or not based on the presence of interruption points (message sends and backjumps).

• 2. Bytecode parsing phase does an abstract interpretation of the bytecodes performing a stack bytecode to register IR transformation.

• 3. Code generation phase computes IR instruction offsets and assembles the final machine code for the current platform.

CogRTL Intermediate Representation

The Cogit JIT compiler uses a linear 2-address-code intermediate representation named CogRTL. An interesting design point of the CogRTL IR is that it uses a fixed number of virtual registers with names such as ReceiverRegister or ClassRegister. Such registers have concrete roles at some point during the compilation (e.g., they refer to the current receiver or the receiver's class at method entry point), and when those roles are already fulfilled or not required they are used as general purpose registers. An example of such behaviour are some compiler intrinsics and machine code versions of primitive methods. 2The fixed virtual register design avoids the need of a complex register allocator. Instead, virtual registers are allocated ahead of time to physical registers as a compiler configuration for each supported backend/platform. Notice that in the current architecture, a register allocator would have very short windows of code to improve because of three reasons: (1) the compiler does not implement inline substitution, (2) it spills all registers before any message-send, and (3) message sends are omni-present in Pharo's code [START_REF] Zaitsev | Characterizing Pharo Code: A Technical Report[END_REF].

As a final point on CogRTL's design: it aims to be as machine-independent as possible. There is a clear separation between the compiler's front end that parses bytecode and generates an IR, and the compiler's backend that generates machine code from the IR. Machine specific decisions such as the ahead-of-time register allocation are backend-specific. However, there are some machine-specific decisions that cripple into the frontend making that a single method can produce different IRs in different machines. For example, when the backend is a RISC machine the frontend produces IR instructions to push the link register on a method's preamble.

Code Patching and PICs

Besides method compilation, the Cogit JIT compiler makes use of machine code patching without using any of the support explained above. Instead, machine code patching is implemented in the compiler's backend, reusing most of the compiler's assembler, but it requires in addition to implement a partial disassembler to identify the instructions to patch. Machine code patching happens in two main cases during the execution: updating/linking of mono/poly/mega-morphic inline caches and updating object references in machine code when objects are moved by the garbage collector.

The Cogit JIT compiler implements inline caches [START_REF] Deutsch | Efficient Implementation of the Smalltalk-80 system[END_REF] and polymorphic inline caches [START_REF] Holzle | Adaptive Optimization for Self: Reconciling High Performance with Exploratory Programming[END_REF][START_REF] Hölzle | Optimizing Dynamically-Typed Object-Oriented Languages With Polymorphic Inline Caches[END_REF]. Briefly, code patching of the inline caches works as follows. Call-sites are initially compiled as calls to send trampoline routines. Send trampolines eventually perform the method lookup and link the call-site making it a monomorphic call-site: they rewrite the call to the trampoline to a call to a type-checked entry point of the found method. A monomorphic cache miss happens when the receiver is of a different type than what the linked method expects, thus upgrading the monomorphic inline cache to a polymorphic inline cache (PIC). Instead of recompiling a method with a PIC in place, PICs are implemented as machine code stubs. The so far monomorphic call-site is re-linked to the PIC stub in the same way it was done for the monomorphic case. PICs are patched with new cases at runtime when a (type, method) pairs cause PIC misses, up to a certain threshold. Finally, when a PIC surpasses the threshold it is upgraded to a megamorphic inline cache. Megamorphic caches are implemented as stubs shared by many call-sites and linked in the same way monomorphic and polymorphic caches were.

An Iterative Test-Based Methodology

The Pharo VM presents a high-level simulation environment that is very handy to simulate full executions and live-program the VM [START_REF] Miranda | Two decades of smalltalk VM development: live VM development through simulation tools[END_REF]. The simulation environment is a hybrid execution environment. The interpreter, JIT compiler and memory manager are written in a Pharo subset that is transpilable to C using Slang, and are executable as normal Pharo code. The generated runtime, i.e., the machine code compiled methods generated by the JIT compiler, is executed using a machine code simulator. In Pharo, we have extended the original machine code simulation infrastructure to use Unicorn 3 , a QEMU-based machine code simulation library. Unicorn provides a small yet powerful API to simulate machine code on multiple architectures.

We extended the pre-existing simulation environment with a testing infrastructure that allows us to have finegrained control of testing scenarios, making tests small, fast, reproducible, and cross-ISA. The VM development environment is illustrated in Figure 1. During simulation, the VM 3 https://www.unicorn-engine.org/ has a heap and a native code cache memory regions instantiated as Pharo ByteArrays and is configured to work on a particular ISA/architecture. When JIT'ted code is simulated, the simulation environment gives control to the Unicorn machine simulator and when this latter hits a trampoline, it gives control back to the Pharo-side of the simulation. Our testing infrastructure lies within the simulation environment and has access to the same infrastructure as the full-simulation. Eventually, the VM is transpiled to C and compiled for a given ISA/architecture.

Based on this infrastructure we defined a hybrid testing methodology that mixes three different execution modes: unit-testing, full-system simulation, and full-system realhardware execution. Our methodology takes advantage of the strengths of unit-testing, full-system simulation, and real-hardware execution where they perform better. The VM is executed as Pharo code in the simulation environment and transpiled to C to produce the production artefact. The simulation environment has its own heap and native code cache used during the simulated execution. The production VM will allocate similar regions on the real execution. This new testing infrastructure extends and makes use of the existing simulation environment.

VM Testing: An Agile Perspective

Each of these execution modes has different benefits and constraints, as shown in Table 1. Real-hardware is not always readily available or easy to debug, but its execution is the most precise in comparison with simulated hardware. At the same time, testing changes in real hardware is expensive to compile and run, leading to slow develop-compile-test feedback cycles. On the other side of the spectrum, unit tests are a handy way to express reproducible and representative scenarios and specially are capable of capturing regressions. However, since they are based on a simulation environment, they suffer from execution imprecisions because the simulation machinery is not 100% representative of real executions. Based on these observations, we characterise the three different execution modes as per Table 1, using the following criterion:

• Feedback-Cycle Speed. How fast is the develop-compile-test cycle for a single test scenario? Unit tests support fast development cycles because they work on small and precise scenarios and do not require a full system initialization. Full-System simulations have slower development cycles because they require a full-system initialization plus the time to arrive to the interesting execution spot. Full-system real hardware execution has even slower feedback cycles than the full-system simulation because they require also a full VM compilation, which in our case includes transpilation, interpreter postprocessing and C compilation.

• Availability. Is the testing scenario readily available to execute? On the one hand, simulation-based solutions (Unit tests, full-system simulations) are highly available although tied to the availability of a machine code simulator, which are in general software-based portable solutions. On the other hand, hardware-based solutions (real hardware) are much less available, as they require target hardware access.

• Reproducibility. What are the chances of reproducing a single test scenario? Full-System executions (simulation, real hardware) have low reproducibility by default because millions of instructions may need to be executed before hitting an actual problem, and non-determinism may worsen the problem. Contrastingly, unit-tests are by construction repeatable.

• Precision. How precise is the scenario execution? Simulation-based solutions (Unit tests, full-system simulations) have generally lower precision than real hardware, because a machine code simulator introduces a distance between both executions. For example, the versions of QEMU and the Unicorn machine simulator we use do not perform stack pointer alignment checks on AArch64 because of performance reasons.

• Debuggability. Is the testing scenario easy to debug? Simulation-based solutions (Unit tests, full-system simulations) are often built with debugging support in mind.

On the other hand, real hardware execution requires abandoning the abstractions of the simulation environment and often deal with abstractions closer to the machine.

A Single Methodology to Rule Them All

Based on these constraints, we developed the methodology illustrated in Figure 2: 1. Spend as much time as possible working on unit tests: they are cheap to write and execute. 2. Introduce full-system simulations when we consider coverage is good enough: it represents a full-system execution without access to real hardware. 3. Introduce testing on real hardware when we consider full-system simulation reliable enough: to obtain final precise and reliable feedback. The key of this methodology is to augment the team's velocity and to apply Test-Driven-Development (TDD) techniques from Software Engineering to JIT compiler development. In this schema, unit tests are the main development unit because of their fast feedback. In our experience, unittests have caught the vast majority of bugs without the need to validate it in real hardware. Really few problems seemed to remain untestable at first because of simulation imprecisions, but most of them became testable after introducing fixes in the simulation environment.

We then use full-system executions (either simulated or on real hardware) to get feedback on failing untested functionalities. As soon as a full-system execution fails, we use that as feedback for unit testing: we build one or more failing tests for the scenario, we manually do test reduction on them, and finally fix the actual problem to make them pass. Such a mixed mode methodology allowed us to port most of the JIT compiler to AArch64 before we had access to real hardware. As a nice side effect, we created a large set of tests that are small, fast to run, reproducible and cross-ISA, and even unveiled old bugs in the pre-existing backends.

The Pharo VM Testing Infrastructure

The most complex part of writing a VM-specific unit test is defining the test fixture/setUp. Indeed, executing a short method doing push a, push b, send +, return requires the initialization of the heap, the execution stack, internal VM data structures, among others... Because of these, the largest effort of our infrastructure was put on extending SUnit 4 with VM-specific initializations and testing primitives. The core of our infrastructure lies within four abstract Test classes that developers extend to define their new testing scenarios:

• Heap Initialized Test Case. The root of our testing hierarchy. All tests that inherit from this class run configured with a heap. This class also provides facilities to create/load classes and instantiate objects.

Unit Test x1000

Better Testing Infrastructure

Full-System Simulation x10

Full-System Real Execution x1

Figure 2. Illustrating the Methodology of the AArch64 Port. Our methodology was based mainly on developing mostly black-box unit tests. When the number of running unit tests gave us enough confidence we introduced fullsystem simulations, and when we were confident enough about the full system simulations we spent time on real hardware. At each step, the problems we found were reduced to be bare minimum reproducible, translated as unit tests and introduced as regression tests.

• Interpreter Test Case. All tests that inherit from this class run configured with a heap and an execution stack.

They have access to a call-stack builder to create wellformed stack frames.

• Compiler Test Case. All tests that inherit from this class run configured with a heap, an execution stack, and a code cache. They have access to a simplified compiler interface that compiles either entire methods, compiler intrinsics and individual bytecodes. Moreover, all tests extending this class are by default executed on all supported ISAs.

VM Testing Guidelines

In our journey of writing tests for the Pharo VM, we developed a large test suite that covers different VM concerns such as the interpreter, the compiler, the object format, and the garbage collector. In this section, we report on our experience designing VM-specific unit tests in the form of several guidelines. These VM-specific guidelines emerged from applying general well-known testing principles such as:

Fast. A

Cross-ISA Testing Using Test Parameterisation

Our test infrastructure makes use of parameterized tests to automatically run a single test on many configurations. We express such configurations as a matrix. Listing 2 shows an example configuration of our compilation testing matrix. Our root test classes already provide pre-configured configuration matrices for the most common cases. For example, the interpreter and memory manager tests automatically run in 32bits and 64bits configurations. Compiler tests are configured to run in all supported compiler backends. Listing 2 illustrates the compiler configuration matrix which at the moment of writing this paper includes cases for AArch64, AArch32, x86 and x86-64.

Grow Slowly in Complexity

A simple heuristic we use to develop tests is to always start by the simplest test we can write. If a test cannot be easily written with the testing infrastructure as-is this is an indicator that either the infrastructure is missing support for some feature, or that a simpler test needs to be developed before.

A second heuristic is to treat test code as any other code. In other words, test code can be subject to refactorings, cleaning, and the extraction of other reusable components.

Dealing with Platform Specific Constraints

The guidelines above make tests that are generic by default, but generic tests do not deal correctly with platform specific constraints. Platform specific constraints arise from different VM configurations, target operating systems or target processors. For example, AArch64 differs from Intel based processors in many ways: multiplication overflow does not set the overflow flag, subtraction present an inverted carry flag, the stack pointer has alignment restrictions. Some operating systems impose exclusive write-executable permissions. VM specific differences appear between 32bits and 64bits memory models.

In cases like the ones exemplified above, our testing infrastructure does not forbid testing, but requires more finegrained control and narrowing the scope of test. We achieve fine-grained control in platform specific tests by allowing tests to manually feed Intermediate Representation instructions to the compiler. Also, when narrowing test scenarios for a particular platform, we observed the appearance of two main cases in our test suite:

Generic tests with exceptions. Some tests are valid for all but one matrix configuration. In such cases, the specific configuration is explicitly skipped for that test. Platform Specific Tests. Some tests are valid only for a single platform. In such cases, a separate test class with a specialized test matrix is written to host them. An example of this are the ARM stack alignment tests, in class VMARMStackAlignmentTest, with a test matrix using a single case, as shown in Listing 3.

Case Studies

All unit tests and the testing infrastructure reported in this article are available in the package VMMakerTests, in the branch headless of our Git public repository 5 . Our testing suite defines as-per-today 1367 written unit tests 6 , representing a total of 3603 run tests when the different matrix configurations are taken into account. A full run of our unit test suite amounts to a total time of ~2.5 minutes in our continuous integration server to the day we wrote this article. Table 2 details the processor independent test cases, and Table 3 details the processor dependent test cases.

In the remaining of this section we report our experience with two concrete case studies where our testing infrastructure has been proven useful. We provide in appendix code examples of both scenarios.

Porting the Cogit JIT Compiler to AArch64

We used this approach to port the Cogit JIT compiler to AArch64. When we started the port, the JIT compiler had mainly assembler tests that did not follow the principles stated above. Following our guidelines above, we guided our port to AArch64 by writing unit tests in increasing complexity, specifically by translating and executing single bytecodes and working exclusively on our test suites: we performed no full-system execution of any kind. For example, the first tests we wrote covered the bytecodes for push and pop of constants, we later introduced tests for message-send bytecodes which required to add testing support for trampolines, and later we introduced tests for polymorphic inline caches and their patching. This approach helped us with introducing the assembler support gradually.

In addition, some testing scenarios required modifications in the compiler's intermediate representation e.g., to test multiplication overflow we introduced a new JumpMultiply-Overflow instruction because AArch64's multiply instruction does not set the overflow flag. The JumpMultiplyOverflow is defined by default on all platforms as a JumpOverflow and redefined for AArch64. Having a cross-ISA and fast test suite allowed us to easily refactor and verify the change not only in AArch64 but in all our supported platforms in a couple of minutes, making sure we did not introduce any regression in the compiler.

Once our test suite was large enough and gave us enough confidence on our implementation, we switched to run fullsystem simulations. During a full-system simulation, we run the Pharo VM as if it was run from the command line. This made the simulation environment exercise parts of the code that were not necessarily covered by tests. When the simulation reached a bug or an error, we investigated the problem and rolled-back to design unit tests for the failing scenario, incrementing our test coverage with concrete cases.

When the simulation was able to execute for long periods of time without failing, we had a strong confidence in our implementation. We switched to real-hardware execution, knowing that we were going to face at least the stack pointer

Marshalling of Single-precision Floats in FFI.

A bug in our assembler has been found: when reading/writing single-precision floats, we used the 64bits instruction variant. Our tests were not covering all possible scenarios and this caused memory corruptions. This problem was not unveiled by the full-system simulation because it takes a huge amount of time to reach this point. OSX W+X. When preparing the Pharo VM build for the new M1 Apple Silicon Machines, we had to adapt the entire JIT architecture to use the mmap JIT permissions suggested by Apple7 .

Debugging and Testing Memory Corruptions

We used this same approach recently when facing a bug in the prototype ephemeron [START_REF] Hayes | Ephemerons: A new finalization mechanism[END_REF] implementation reported by a member of the Pharo community 8 . We started by investigating the issue in real-hardware using gdb. This first exploratory step was to be able to identify more clearly the symptoms of the problem and making hypothesis about the potential causes. A quick analysis showed us a heap corruption where the crash manifested itself far away from its real cause. After some debugging iterations we could observe that the corrupted objects were effectively the ephemeron objects, and that the corruption happened during GC, and we proceeded to reproduce the same problem in a unit test and debug it in the simulation environment. During this debugging session in the simulation environment we found other related bugs. The fixes and associated tests were published in the following pull request: https://github.com/pharo-project/ opensmalltalk-vm/pull/183.

Related Work

Several solutions have been proposed in the past to aid in VM debugging tasks and programming language implementation validation.

many parts of their codebase. We believe that many of these limitations come from the fact that Maxine is a meta-circular VM that uses its JIT compiler to compile itself. Finally, some work report recently efforts to validate in an automatic or semi-automatic way optimising compilers [START_REF] Béra | Practical Validation of Bytecode to Bytecode JIT Compiler Dynamic Deoptimization[END_REF][START_REF] Flückiger | Correctness of Speculative Optimizations with Dynamic Deoptimization[END_REF]. Although this is not the focus of this paper, we plan to extend our infrastructure in the future to test our prototype optimising JIT.

Conclusion

Testing and debugging a Virtual Machine is a laborious task without the proper tooling. This is particularly true for VMs with JIT compilation and dynamic code patching. In this paper we present a testing infrastructure and a methodology that allows us to take advantage of the strengths of unittesting, full-system simulation, and real-hardware execution where they perform better, and have fine-grained control of testing scenarios, making tests small, fast, reproducible, and cross-ISA.

We report on how this testing infrastructure allowed us to cope with two different development scenarios: (1) porting the Cogit JIT compiler to AArch64 without early access to real hardware and (2) debugging memory corruptions due to GC bugs. In our experience, unit-tests have caught the vast majority of bugs without the need to validate them in real hardware. Really few problems seemed to remain untestable at first because of simulation imprecisions, but most of them became testable after introducing fixes in the simulation environment.

Figure 1 .

 1 Figure 1. Development environment of the Pharo VM.The VM is executed as Pharo code in the simulation environment and transpiled to C to produce the production artefact. The simulation environment has its own heap and native code cache used during the simulated execution. The production VM will allocate similar regions on the real execution. This new testing infrastructure extends and makes use of the existing simulation environment.

1 testPushConstantZeroBytecodePushesASmallIntegerZero 2

 12 self compile: [ compiler genPushConstantZeroBytecode ].

4Listing 1 .

 1 self assert: self popAddress equals: (memory integerObjectOf: 0) Test compilation of push constant zero.

7 yourself 2 .

 72 #ISA -> #'aarch64'. #wordSize -> 8}; 4 addCase: { #ISA -> #'x86'. #wordSize -> 4}; 5 addCase: { #ISA -> #'X64'. #wordSize -> 8}; 6 addCase: { #ISA -> #'ARMv5'. #wordSize -> 4};Listing Testing matrix for compiler tests.

4 yourself 3 .

 43 #ISA -> #'aarch64'. #wordSize -> 8};Listing Testing matrix for a platform specific test.

Table 1 .

 1 Characterisation of different execution modes.

		Unit	Full-System Real Hardware
		Testing Simulation	Execution
	Feedback-cycle	High	Low	Very Low
	Speed
	Availability	High	High	Low
	Reproducibility	High	Low	Low
	Precision	Low	Low	High
	Debuggability	High	High	Low

  test should be as instantaneous as possible to ensure we have a fast feedback cycle. Reproducible. Test executions should be deterministic. Repeatable. Several test runs should be independent from each other. Unitary. Each test should test a single concern. Particularly, if a functionality has many aspects to test such as several border-cases, a test exists for each of them. The test uses our compiler interface to compile a single bytecode, execute the generated machine code and test that the constant zero was pushed to the operand stack. This test is written once and runs automatically in all supported compiler backends (AArch64, AArch32, x86, and x86-64), both in 32bits and 64bits machines.

	Validating. A test must have at least one assertion, and
	ideally only one.
	4.1 Black Box Testing
	We use black-box testing in the vast majority of our tests: we
	test externally observable behaviour. For example, most of
	our memory management tests are word-size independent.
	Another example are compiler tests: we avoid as much as
	possible exposing internals of the compiler such as the IR
	or the generated machine code within the test code. Indeed,
	most of our compiler related tests work with the granularity
	of a single bytecode. This design gives our tests two main
	properties: (1) resistance to changes in the VM and compiler
	implementation, and (2) architecture/ISA independence.
	Listing 1 shows one of the simpler tests in our compiler
	test suite.

Table 2 .

 2 Processor Independent Tests (32bits / 64bits): These tests center in the memory representation. They are executed for 32 and 64 bits machines. They don't use Unicorn's machine simulator.

	VM Component Operation	Independent Tests	Variations	Total Executions
		Method Builder	10		20
	Test Infrastructure	Stack Builder	18	32 bits / 64 bits	36
		Total	28		56
		Stack Reification	7		14
		Context / Stack Mapping	13		26
		GC Data Structures	13		26
		Unmovable Objects	9		18
		Old Object Garbage Collection	63		126
	Object Memory	Young Objects Garbage Collection	38	32 bits / 64 bits	76
		Weak Object Garbage Collection	9		18
		Ephemeron Object Garbage Collec-	19		38
		tion
		Old Objects FreeSpace Management	85		170
		Memory Structure Preconditions	30		60
		Total	286		572
		Bytecode Tests	43		86
		Method Lookup	15		30
	Interpreter	Object Representation	17	32 bits / 64 bits	34
		Primitives	62		124
		Total	137		274
		Total	451		902
	alignment restrictions that were not simulated properly. Dur-
	ing real-hardware execution, we only found three missing
	features in our JIT port:
	Stack alignment restrictions. We faced it right away in
	the first execution. This problem lead us to design
	platform specific tests to check the alignment, extend
	the unicorn machine simulation with support for stack
	alignment check, and refactor the JIT to use a general
	purpose register (x28) as stack pointer register for the
	Pharo execution stack. Since the Pharo VM uses as
	stack a stack allocated memory region, the x28 register
	is guaranteed to be always above the real stack pointer.

Primitives are native methods in Smalltalk/Pharo's jargon.

https://github.com/pharo-project/opensmalltalk-vm

https://github.com/pharo-project/opensmalltalk-vm/commit/ 8f3028057c4f98afa38c5645223d19ecfbfb2bf3

https://developer.apple.com/documentation/apple-silicon/porting-justin-time-compilers-to-apple-silicon

https://github.com/pharo-project/pharo/issues/8153

VM Simulation and Meta-circular VMs. VM frameworks and Meta-circular VMs have offered for a long time simulation environments that helped in testing and debugging virtual machines. Such is the case of Self [START_REF] Ungar | Constructing a metacircular Virtual machine in an exploratory programming environment[END_REF], Smalltalk [START_REF] Ingalls | Back to the Future: The Story of Squeak, a Practical Smalltalk Written in Itself[END_REF][START_REF] Miranda | Two decades of smalltalk VM development: live VM development through simulation tools[END_REF] and Maxine [START_REF] Wimmer | Maxine: An approachable virtual machine for, and in, java[END_REF]. These solutions allow full-system simulations to ease debugging at the cost of slower and lessprecise executions. Our solution complements full-system simulations with a unit-testing infrastructure and methodology, that helped us in fixing complex bugs and porting the JIT compiler to AArch64.

Compiler and VM Testing. Several works exist on the area of compiler testing, particularly on the automatic generation of test programs and oracles for their validation [START_REF] Chen | A Survey of Compiler Testing[END_REF].

Chen et al., do not study test generation or validation: they study the infrastructure required to produce maintainable, fast, focused and cross-ISA tests. Moreover, our tests cover not only the JIT compiler but other VM concerns such as the memory manager, the interpreter and the GC. We plan in the future to work on VM-specific test generation.

Recently, the team of Maxine reported a QEMU test-based infrastructure for cross-ISA testing and debugging [START_REF] Kotselidis | Cross-ISA debugging in meta-circular VMs[END_REF]. They reported that this infrastructure helped them in porting their VM to AArch32 (ARMv7), similarly that what ours helped us in porting to AArch64. Still, their debugging happens in gdb in an abstraction level far-away from the original source code. Moreover, they reported they still cannot cover


Manon Connault

Jérémy Tournayre

Céline Boby

Muriel Bonnet

Nadia Goué

Talkmine

Talkmine, a workflow for the prediction of the interactions between secretome and surfaceome in the dialogue between cellular types

ou non, émanant des établissements d'enseignement et de recherche français ou étrangers, des laboratoires publics ou privés.

Talkmine, a workflow for the prediction of the interactions between secretome and surfaceome in the dialogue between cellular types

Manon CONNAULT [START_REF] Bonnet | Prediction of the Secretome and the Surfaceome: A Strategy to Decipher the Crosstalk between Adipose Tissue and Muscle during Fetal Growth[END_REF] , Jérémy TOURNAYRE 2 , Céline BOBY 2 , Muriel BONNET 2 and Nadia GOUÉ

France

Corresponding Authors: nadia.goue@uca.fr, muriel.bonnet@inrae.fr

Contexte

The prediction of the protein-protein interactions is studied in different domains, for example for their roles in the interplay between cellular types or tissues [START_REF] Bonnet | Prediction of the Secretome and the Surfaceome: A Strategy to Decipher the Crosstalk between Adipose Tissue and Muscle during Fetal Growth[END_REF] . In particular, the interactions between surfaceome and secretome may strongly improved the understanding of cellular crosstalk. This project aims to develop a Snakemake-based workflow [START_REF] Mölder | Sustainable data analysis with Snakemake[END_REF] named Talkmine for the identification of molecular dialogue between two biologic tissues resulting from protein-protein interactions.

Materials and Methods

First objective was to identify and test some opensource tools known to predict proteins that belong to secretome or surfaceome. Publically available tools were classified according to three classes, i.e. peptide signal, subcellular location or topology prediction, and have been tested with a dataset of 164 UniProt protein entries whose subcellular location are known.

Secondly, we developed a workflow to connect the selected tools. In brief, user sends a gene or protein identifiers list to a python tool, g:Convert [3] which converts identifiers to a same format, according to a defined database. Then, Entrez-Direct tool [START_REF] Kans | Entrez Direct: E-utilities on the Unix Command Line[END_REF] generates a multi-fasta file with all protein sequences listed in the NCBI database, injected to secretome and surfaceome tools. Finally, proteins tagged to secretome and surfaceome classes are send to PSICQUIC tool [START_REF] Aranda | PSICQUIC and PSISCORE: accessing and scoring molecular interactions[END_REF] , which determines the interactions between proteins from these two classes.

Results

The resulting protein-protein interactions prediction from Talkmine is available both in standard output and in flat file. The user has access to the list of protein-protein interactions between the two tissues but also to the intermediate results.

Conclusion and perspectives

The workflow Talkmine is developed to predict the interactions between the proteins from the secretome and the surfaceome. This work was initiated to be applied to Bos taurus to determine the interactions between muscle and fat tissue but it is possible to apply it to other tissues and to application fields such as biomedical or food research.

  [START_REF] Bonnet | Prediction of the Secretome and the Surfaceome: A Strategy to Decipher the Crosstalk between Adipose Tissue and Muscle during Fetal Growth[END_REF]