Skip to content

Conversation

@luke-li-2003
Copy link
Contributor

Supports the inlining of multianewArray on P when a new 2D array is created with the second dimension having a length of zero.

@luke-li-2003
Copy link
Contributor Author

Related issue: #2424

@luke-li-2003
Copy link
Contributor Author

@zl-wang FYI

@luke-li-2003
Copy link
Contributor Author

The code is working and as far as I can tell without error for arr[0][0], arr[n][0], and arr[n][n] (where it should correctly engage the out of line code).

@luke-li-2003
Copy link
Contributor Author

luke-li-2003 commented May 13, 2025

Performance: where the load is basically me allocating a bunch of 2D arrays:

arr[n][0]

length-n default accelerated
0 2.837 233.8
1 1.974 134.1
10 0.517 28.93
128 0.05 1.35

The throughput unit is 1e6.

@luke-li-2003
Copy link
Contributor Author

The offheap implementation is not done yet, but shouldn't be hard.

@zl-wang
Copy link
Contributor

zl-wang commented May 13, 2025

i supposed the "length" above is the 1st dimension size (i.e. n). the 2nd dimension size is also n? or it varied in your tests?

@luke-li-2003
Copy link
Contributor Author

The 2nd dimension is zero as outlined in the problem statement. When the 2nd dimension is not zero, the performance of default and accelerated code are pretty much the same (since the accelerated code just call anyway).

@luke-li-2003
Copy link
Contributor Author

luke-li-2003 commented May 14, 2025

In what is the weirdest bug I have seen, the evaluator wouldn't work if I set -Xnoaot or -Xshareclasses:none. All other options (like -Xshareclasses:reset) have no effect on it.

Update: resolved, I was not handling the case where the shiftAmount for compressed pointers is zero correctly, which happens to be the case when AOT was disabled.

@luke-li-2003
Copy link
Contributor Author

luke-li-2003 commented May 20, 2025

A sanity.functional test revealed one failure, which should be caused by #21844 and not related to my code.

I will rebase the code and try again.

https://hyc-runtimes-jenkins.swg-devops.com/job/Pipeline-Build-Test-Personal/28072/console

Update: test passed https://hyc-runtimes-jenkins.swg-devops.com/job/Pipeline-Build-Test-Personal/28154/

@luke-li-2003
Copy link
Contributor Author

luke-li-2003 commented May 21, 2025

Generated machine code, for reference:

    0x7fff8ecec238 00000040 [    0x7fff8c21a2a0]                   2    Label L0018:    ; (Start of internal control flow)
    0x7fff8ecec238 00000040 [    0x7fff8c21c5e0] 80020004          2    lwz     gr0, [gr2, 4]
    0x7fff8ecec23c 00000044 [    0x7fff8c21c730] 80e20000          2    lwz     gr7, [gr2, 0]
    0x7fff8ecec240 00000048 [    0x7fff8c21c7d0] 2c070000          2    cmpwi   cr0, gr7, 0
    0x7fff8ecec244 0000004c [    0x7fff8c21c870] 408200b4          2    bne     cr0, Label L0023
    0x7fff8ecec248 00000050 [    0x7fff8c21c910] 2c000000          2    cmpwi   cr0, gr0, 0
    0x7fff8ecec24c 00000054 [    0x7fff8c21c9b0] 40820030          2    bne     cr0, Label L0019
    0x7fff8ecec250 00000058 [    0x7fff8c21cb00] e86f0060          2    ld      gr3, [gr15, 96]
    0x7fff8ecec254 0000005c [    0x7fff8c21cba0] 38a30010          2    addi    gr5, gr3, 16
    0x7fff8ecec258 00000060 [    0x7fff8c21ccf0] e8cf0068          2    ld      gr6, [gr15, 104]
    0x7fff8ecec25c 00000064 [    0x7fff8c21cd90] 7c253000          2    cmpd    cr0, gr5, gr6
    0x7fff8ecec260 00000068 [    0x7fff8c21ce30] 41810098          2    bgt     cr0, Label L0023
    0x7fff8ecec264 0000006c [    0x7fff8c21cf80] f8af0060          2    std     [gr15, 96], gr5
    0x7fff8ecec268 00000070 [    0x7fff8c21d0d0] 90830000          2    stw     [gr3, 0], gr4
    0x7fff8ecec26c 00000074 [    0x7fff8c21d170] 38a00000          2    li      gr5, 0000000000000000
    0x7fff8ecec270 00000078 [    0x7fff8c21d2c0] 90a30004          2    stw     [gr3, 4], gr5
    0x7fff8ecec274 0000007c [    0x7fff8c21d410] 90a30008          2    stw     [gr3, 8], gr5
    0x7fff8ecec278 00000080 [    0x7fff8c21d4b0] 48000084          2    b       Label L0021     
    0x7fff8ecec27c 00000084 [    0x7fff8c21d540]                   2    Label L0019:    
    0x7fff8ecec27c 00000084 [    0x7fff8c21d5d0] 3ca03fff          2    lis     gr5, 0000000000003FFF
    0x7fff8ecec280 00000088 [    0x7fff8c21d670] 60a5ffff          2    ori     gr5, gr5, 65535
    0x7fff8ecec284 0000008c [    0x7fff8c21d710] 7c002840          2    cmplw   cr0, gr0, gr5
    0x7fff8ecec288 00000090 [    0x7fff8c21d7b0] 41810070          2    bgt     cr0, Label L0023
    0x7fff8ecec28c 00000094 [    0x7fff8c21d850] 5405103a          2    rlwinm  gr5, gr0, 0000000000000002, 00000000FFFFFFFC
    0x7fff8ecec290 00000098 [    0x7fff8c21d900] 38a5000f          2    addi    gr5, gr5, 15
    0x7fff8ecec294 0000009c [    0x7fff8c21d9a0] 54a50038          2    rlwinm  gr5, gr5, 0000000000000000, FFFFFFFFFFFFFFF8
    0x7fff8ecec298 000000a0 [    0x7fff8c21da50] 1cc00010          2    mulli   gr6, gr0, 16
    0x7fff8ecec29c 000000a4 [    0x7fff8c21daf0] 7cc62a14          2    add     gr6, gr6, gr5
    0x7fff8ecec2a0 000000a8 [    0x7fff8c21dc40] e86f0060          2    ld      gr3, [gr15, 96]
    0x7fff8ecec2a4 000000ac [    0x7fff8c21dce0] 7cc61a14          2    add     gr6, gr6, gr3
    0x7fff8ecec2a8 000000b0 [    0x7fff8c21de30] e8ef0068          2    ld      gr7, [gr15, 104]
    0x7fff8ecec2ac 000000b4 [    0x7fff8c21ded0] 7c263800          2    cmpd    cr0, gr6, gr7
    0x7fff8ecec2b0 000000b8 [    0x7fff8c21df70] 41810048          2    bgt     cr0, Label L0023
    0x7fff8ecec2b4 000000bc [    0x7fff8c21e0c0] f8cf0060          2    std     [gr15, 96], gr6
    0x7fff8ecec2b8 000000c0 [    0x7fff8c21e210] 90830000          2    stw     [gr3, 0], gr4
    0x7fff8ecec2bc 000000c4 [    0x7fff8c21e360] 90030004          2    stw     [gr3, 4], gr0
    0x7fff8ecec2c0 000000c8 [    0x7fff8c21e4b0] e8840058          2    ld      gr4, [gr4, 88]
    0x7fff8ecec2c4 000000cc [    0x7fff8c21e550] 7cc51a14          2    add     gr6, gr5, gr3
    0x7fff8ecec2c8 000000d0 [    0x7fff8c21e5f0] 38a30008          2    addi    gr5, gr3, 8
    0x7fff8ecec2cc 000000d4 [    0x7fff8c21e690] 7c0903a6          2    mtctr   gr0
    0x7fff8ecec2d0 000000d8 [    0x7fff8c21e730] 38e00000          2    li      gr7, 0000000000000000
    0x7fff8ecec2d4 000000dc [    0x7fff8c21e7d0]                   2    Label L0020:
    0x7fff8ecec2d4 000000dc [    0x7fff8c21e910] 90860000          2    stw     [gr6, 0], gr4
    0x7fff8ecec2d8 000000e0 [    0x7fff8c21ea60] 90e60004          2    stw     [gr6, 4], gr7
    0x7fff8ecec2dc 000000e4 [    0x7fff8c21ebb0] 90e60008          2    stw     [gr6, 8], gr7
    0x7fff8ecec2e0 000000e8 [    0x7fff8c21ec50] 78c0e8c2          2    rldicl  gr0, gr6, 000000000000003D, 1FFFFFFFFFFFFFFF
    0x7fff8ecec2e4 000000ec [    0x7fff8c21edb0] 90050000          2    stw     [gr5, 0], gr0
    0x7fff8ecec2e8 000000f0 [    0x7fff8c21ee50] 38a50004          2    addi    gr5, gr5, 4
    0x7fff8ecec2ec 000000f4 [    0x7fff8c21eef0] 38c60010          2    addi    gr6, gr6, 16
    0x7fff8ecec2f0 000000f8 [    0x7fff8c21ef90] 4200ffe4          2    bdnz    cr0, Label L0020
    0x7fff8ecec2f4 000000fc [    0x7fff8c21f030] 48000008          2    b       Label L0021
    0x7fff8ecec2f8 00000100 [    0x7fff8c21f0c0]                   2    Label L0023:
    0x7fff8ecec2f8 00000100 [    0x7fff8c21f150] 4800001c          2    b       Outlined Label L0022
    0x7fff8ecec2fc 00000104 [    0x7fff8c21f340]                   2    Label L0021:    ; (End of internal control flow)

...

    0x7fff8ecec314 0000011c [    0x7fff8c21a380]                   2    Outlined Label L0022:

 \\ Main.foo(II)[[Ljava/lang/Integer;
 \\    2 JBmultianewarray 24 dims 2 [[Ljava/lang/Integer;

    0x7fff8ecec314 0000011c [    0x7fff8c1d2b60] 60aa0000          2    ori     gr10, gr5, 0x0
    0x7fff8ecec318 00000120 [    0x7fff8c1d2ac0] 60890000          2    ori     gr9, gr4, 0x0
    0x7fff8ecec31c 00000124 [    0x7fff8c1d2a20] 60680000          2    ori     gr8, gr3, 0x0
    0x7fff8ecec320 00000128 [    0x7fff8c21bc50] 60830000          2    ori     gr3, gr4, 0x0
    0x7fff8ecec324 0000012c [    0x7fff8c21be50] 38800002          2    li      gr4, 0000000000000002
    0x7fff8ecec328 00000130 [    0x7fff8c21bf60] 60450000          2    ori     gr5, gr2, 0x0
    0x7fff8ecec32c 00000134 [    0x7fff8c21c260] 481623d5          2    bl      00007FFF8EE4E700                ; Direct Call "jitAMultiANewArray"
 PRE: [GPR_0027 : gr3] [GPR_0029 : gr4] [GPR_0030 : gr5] [D_GPR_0031 : gr11] [D_GPR_0032 : gr12]
POST: [&GPR_0028 : gr3] [GPR_0029 : gr4] [GPR_0030 : gr5] [D_GPR_0031 : gr11] [D_GPR_0032 : gr12]
    0x7fff8ecec330 00000138 [    0x7fff8c1d2940] 61450000          2    ori     gr5, gr10, 0x0
    0x7fff8ecec334 0000013c [    0x7fff8c1d28a0] 61240000          2    ori     gr4, gr9, 0x0
    0x7fff8ecec338 00000140 [    0x7fff8c1d2800] 7c634278          2    xor     gr3, gr3, gr8
    0x7fff8ecec33c 00000144 [    0x7fff8c1d2760] 7c684278          2    xor     gr8, gr3, gr8
    0x7fff8ecec340 00000148 [    0x7fff8c21c310] 61030000          2    ori     gr3, gr8, 0x0
    0x7fff8ecec344 0000014c [    0x7fff8c21c3b0] 4bffffb8          2    b       Label L0021

Comment on lines 2232 to 2455
TR::Node *callNode = outlinedHelperCall->getCallNode();
TR::Register *reg;
if (callNode->getFirstChild() == node->getFirstChild())
{
reg = callNode->getFirstChild()->getRegister();
if (reg)
dependencies->addPostCondition(reg, TR::RealRegister::NoReg);
}
if (callNode->getSecondChild() == node->getSecondChild())
{
reg = callNode->getSecondChild()->getRegister();
if (reg)
dependencies->addPostCondition(reg, TR::RealRegister::NoReg);
}
if (callNode->getThirdChild() == node->getThirdChild())
{
reg = callNode->getThirdChild()->getRegister();
if (reg)
dependencies->addPostCondition(reg, TR::RealRegister::NoReg);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am pretty certain these chunk of code does nothing, since if a child is shared by the callNode and the node (first if block), then the register must have already been added to the post condition in the code block above.

However, the x evaluator included it, so I am leaving it here for now. Feedback appreciated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if what you mentioned is true, these blocks of code can only cause bugs, instead of nothing. you cannot add a register to a dep condition repeatedly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. I forgot that while on x there is union to handle repeated registers gracefully, there isn't on p.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a check so at least the same register won't be inserted twice. I'm still not sure if this is needed at all, though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to me, less code is always better

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just worry that there might be a case where this is required that I haven't thought about. After all the x evaluator should not just have a block of useless code.

@luke-li-2003
Copy link
Contributor Author

I have eliminated all the initialisation to zero to the heap since per our discussion offline they should already by 0.

@zl-wang
Copy link
Contributor

zl-wang commented Jun 25, 2025

give it a thorough test to confirm everything is right

@luke-li-2003
Copy link
Contributor Author

luke-li-2003 commented Jun 25, 2025

The functional test is still running; here's the result for the performance test:

a[n][0] baseline newest before
0 2.8M 243M 240M
1 2M 139M 134M
8 631K 39M 39M
128 51K 1.4M 1.37M
1024 6.4K 31.9K 31K

newest is the build after I removed the code to initialise the zero fields.

Functional test https://hyc-runtimes-jenkins.swg-devops.com/job/Build_JDK21_ppc64le_linux_Personal/1013/

@zl-wang
Copy link
Contributor

zl-wang commented Jul 15, 2025

please take a look at non-zero 2nd dimension or 3rd dimension here: https://github.ibm.com/runtimes/openj9-jit-z/issues/1010
let's see what you can add here

@luke-li-2003
Copy link
Contributor Author

I read through the issue and I agree that it doesn't seem compilcated, it's just going to be very large.

Should I start with the implementation?

@zl-wang
Copy link
Contributor

zl-wang commented Jul 15, 2025

yes, give it a try. we may be able to do it in one go ...

@luke-li-2003 luke-li-2003 force-pushed the MultianewArrayP branch 3 times, most recently from d31a119 to 0bf7e23 Compare July 16, 2025 17:47
@luke-li-2003
Copy link
Contributor Author

Newest performance numbers, including non-zero second dimensions

a[n][0] baseline accelerated
0 2.77 257
1 1.87 137
2 1.47 110
16 0.36 21.6
a[n][1] baseline accelerated
1 1.9 128
2 1.5 102
16 0.36 21.1
a[n][16] baseline accelerated
1 1.9 85
2 1.5 55
16 0.34 7.7

@luke-li-2003
Copy link
Contributor Author

luke-li-2003 commented Jul 17, 2025

@zl-wang
Copy link
Contributor

zl-wang commented Jul 17, 2025

nice results. at least, 20x improvement? the perf numbers' unit is unclear

@luke-li-2003
Copy link
Contributor Author

The unit is 1e6 iterations per cycle.

@luke-li-2003 luke-li-2003 changed the title Accelerate multianewArray on P for 2D arrays with 0 Second Dimension Accelerate multianewArray on P for 2D arrays Jul 30, 2025
// oolJumpLabel is a common point that all branches will jump to.
// From this label, we branch to OOL code.
// We do this instead of jumping directly to OOL code from mainline
// since according to the x and z implementation that is not possible
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the reason it isn't possible? any insights here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was no further elaboration in the x and z implementation, and during my tests the direct jump was not failing, but I can't be sure if any subtle failure occured.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be for arranging a single return-point for the rest of OOL and/or Snippet.

TR::Register *dimsPtrReg = cg->evaluate(node->getFirstChild());
// number of dimensions - compile time constant
uint32_t nDims = node->getSecondChild()->get32bitIntegralValue();
// class pointer of objects in the array - in the 2D case this is the class of the subarray
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this comment looks not right: you directly store classReg to firstDim array's clazz field. That means classReg is firstDim's array class, instead of subarray's class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are on the same page here, it's the class of the subarray, not the class of the component of the subarray.

Copy link
Contributor

@zl-wang zl-wang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

review complete. once comments are addressed, i can approve it.

// === jump point because according to the x and z implementation we can't jump straight to oolFail
generateLabelInstruction(cg, TR::InstOpCode::label, node, oolJumpLabel);
generateLabelInstruction(cg, TR::InstOpCode::b, node, oolFailLabel);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since dimsPtrReg and classReg (arguments for the call later) are never modified in this seq, i would agree these callUses* are not necessary. re the secondChild, it will need to be put in a register before the call, hopefully OOL adds the necessary dependency there. you can adjust the code below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed them now.

}

generateDepLabelInstruction(cg, TR::InstOpCode::label, node, endLabel, dependencies);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am wondering why a targetRegisterFinal is necessary. isn't targetReg good already (presumably OOL jumps back to endLabel if we went down to it)? this mr just makes the path-length longer without much purposes.

On a second thought, could it be due to: in OOL, dimsPtrReg and targetReg should be both dependent on gr3 (first arg and result respectively). Here, targetReg is not hard-dep on gr3 ... there might be unforeseen occasions without targetRegisterFinal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I'm not sure about it other than to say it's copied from the x/z implementation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not the most ideal situation, but acceptable for the time being. need to examine register dependency overall to come up with the ideal solution.


// the maximum number of reference fields in the outer array
uintptr_t maxObjectSizeInRefFields = cg->getMaxObjectSizeGuaranteedNotToOverflow() / referenceFieldSize;
// the maximum number of elements in the inner array
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want you to waste instructions on these kind of useless big constants. use the single constant of maxObjectSizeInRefFields as the guard is good enough to me. any reasonable constant will do actually. re-materializing different constants is a total waste. imagine a max TLH of 128KB or even 2MB, this guard testing never catch the overflow ... the overflow will be caught at heapTop comparison.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

@luke-li-2003
Copy link
Contributor Author

luke-li-2003 commented Aug 28, 2025

Performance on dacapo graphchi using the same long option from z: numactl -C 8-15 java -Djava.security.manager=allow -Xmx2g -Xms2g -Xmn1g -Xshareclasses:none "-Xjit:perfTool,disableEscapeAnalysis,disableLoopTransfer,disableLoopReplicator,disableLoopStrider,acceptHugeMethods" -Xtune:throughput -jar dacapo-23.11-MR2-chopin.jar -n 40 graphchi

Numbers are benchmark time in msecs; lower is better

Forty iterations:

image

Averages:

Build time percentage
baseline 10767 100%
inliner 9748 90.5%

@zl-wang
Copy link
Contributor

zl-wang commented Aug 28, 2025

wow ... really nice improvement. @vijaysun-omr @r30shah

@vijaysun-omr
Copy link
Contributor

Indeed, very good results. Thanks for sharing.

fyi @Spencer-Comin @hzongaro @0xdaryl @knn-k @ehsankianifar

// 1. the header of a contiguous array
// 2. (firstDimLen * referenceFieldSize)
// 3. alignment padding
// temp1Reg = firstDimLenReg * referenceFieldSize; referenceFieldSize can only be 4 or 8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't the previous codegen better with a single shiftLeft of trailingZero(refFieldSize)?

int32_t shiftAmount = TR::Compiler->om.compressedReferenceShift();
if (shiftAmount != 0)
{
// firstDimLenReg can be used as a temp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can do a single shift outside the loop. but [n][0] probably isn't common enough in reality, this is acceptable for the time being as it is.

@zl-wang
Copy link
Contributor

zl-wang commented Aug 28, 2025

Jenkins test sanity aix,plinux jdk8,jdk21

@luke-li-2003
Copy link
Contributor Author

The updated zero-second-dimension case had no discernable impact on throughput, but at least nothing broke.

@luke-li-2003
Copy link
Contributor Author

The last build will crash, should be fixed now

@luke-li-2003
Copy link
Contributor Author

It turns out the callUses* code in the register dependencies is doing something after all, for the build will crash without it. I rolled back the changes now and it should be good now.

Copy link
Contributor

@zl-wang zl-wang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

}

generateDepLabelInstruction(cg, TR::InstOpCode::label, node, endLabel, dependencies);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not the most ideal situation, but acceptable for the time being. need to examine register dependency overall to come up with the ideal solution.

@zl-wang
Copy link
Contributor

zl-wang commented Aug 29, 2025

Jenkins test sanity aix,plinux jdk8,jdk21

@luke-li-2003
Copy link
Contributor Author

luke-li-2003 commented Aug 29, 2025

The code is working, finally.

The problem was that the size of an array header is not the power of 2 as I assumed when using offheap, so I changed the shift instruction into a multiply instruction.

I also updated the final register to duplicate what was done on x, just in case that matters.

@zl-wang
Copy link
Contributor

zl-wang commented Aug 29, 2025

Jenkins test sanity aix,plinux jdk8,jdk21

@zl-wang zl-wang merged commit b407dd3 into eclipse-openj9:master Aug 30, 2025
15 checks passed
ehsankianifar added a commit to ehsankianifar/openj9 that referenced this pull request Sep 4, 2025
The procedure to calculate the size of 2D array component was implemented as part of eclipse-openj9#21870.
This part of code is usable on other platforms so I moved it to a cross platform area.

signed-off-by: Ehsan Kiani Far <ehsan.kianifar@gmail.com>
ehsankianifar added a commit to ehsankianifar/openj9 that referenced this pull request Sep 4, 2025
The procedure to calculate the size of 2D array component was implemented as part of eclipse-openj9#21870.
This part of code is usable on other platforms so I moved it to a cross platform area.

signed-off-by: Ehsan Kiani Far <ehsan.kianifar@gmail.com>
ehsankianifar added a commit to ehsankianifar/openj9 that referenced this pull request Sep 4, 2025
The procedure to calculate the size of 2D array component was implemented as part of eclipse-openj9#21870.
This part of code is usable on other platforms so I moved it to a cross platform area.

signed-off-by: Ehsan Kiani Far <ehsan.kianifar@gmail.com>
ehsankianifar added a commit to ehsankianifar/openj9 that referenced this pull request Sep 4, 2025
The procedure to calculate the size of 2D array component was implemented as part of eclipse-openj9#21870.
This part of code is usable on other platforms so I moved it to a cross platform area.

signed-off-by: Ehsan Kiani Far <ehsan.kianifar@gmail.com>
ehsankianifar added a commit to ehsankianifar/openj9 that referenced this pull request Sep 4, 2025
The procedure to calculate the size of 2D array component was implemented as part of eclipse-openj9#21870.
This part of code is usable on other platforms so I moved it to a cross platform area.

signed-off-by: Ehsan Kiani Far <ehsan.kianifar@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants