Skip to content

Commit 40f0035

Browse files
committed
[GR-31962] Support directly passing arrays to NFI arguments without host object wrappers.
PullRequest: graal/10784
2 parents c0e077b + 4a328bc commit 40f0035

File tree

7 files changed

+192
-234
lines changed

7 files changed

+192
-234
lines changed

truffle/src/com.oracle.truffle.nfi.backend.libffi/src/com/oracle/truffle/nfi/backend/libffi/LibFFIType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
import com.oracle.truffle.nfi.backend.libffi.ClosureArgumentNodeFactory.BufferClosureArgumentNodeGen;
4949
import com.oracle.truffle.nfi.backend.libffi.ClosureArgumentNodeFactory.ObjectClosureArgumentNodeGen;
5050
import com.oracle.truffle.nfi.backend.libffi.ClosureArgumentNodeFactory.StringClosureArgumentNodeGen;
51-
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNode.SerializeArrayNode;
5251
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNode.SerializeDoubleNode;
5352
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNode.SerializeEnvNode;
5453
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNode.SerializeFloatNode;
@@ -57,6 +56,7 @@
5756
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNode.SerializeInt64Node;
5857
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNode.SerializeInt8Node;
5958
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNode.SerializeObjectNode;
59+
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.SerializeArrayNodeGen;
6060
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.SerializeNullableNodeGen;
6161
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.SerializePointerNodeGen;
6262
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.SerializeStringNodeGen;
@@ -473,7 +473,7 @@ static final class ArrayType extends BasePointerType {
473473

474474
@Override
475475
public SerializeArgumentNode createSerializeArgumentNode() {
476-
return SerializeArrayNode.create(this);
476+
return SerializeArrayNodeGen.create(this);
477477
}
478478

479479
@Override

truffle/src/com.oracle.truffle.nfi.backend.libffi/src/com/oracle/truffle/nfi/backend/libffi/SerializeArgumentNode.java

Lines changed: 75 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@
4141
package com.oracle.truffle.nfi.backend.libffi;
4242

4343
import com.oracle.truffle.api.CompilerDirectives;
44+
import com.oracle.truffle.api.dsl.Bind;
4445
import com.oracle.truffle.api.dsl.Cached;
4546
import com.oracle.truffle.api.dsl.Fallback;
46-
import com.oracle.truffle.api.dsl.NodeChild;
4747
import com.oracle.truffle.api.dsl.Specialization;
4848
import com.oracle.truffle.api.interop.InteropLibrary;
4949
import com.oracle.truffle.api.interop.UnsupportedMessageException;
@@ -59,12 +59,12 @@
5959
import com.oracle.truffle.nfi.backend.libffi.LibFFIType.ObjectType;
6060
import com.oracle.truffle.nfi.backend.libffi.LibFFIType.StringType;
6161
import com.oracle.truffle.nfi.backend.libffi.NativeArgumentBuffer.TypeTag;
62-
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.SerializeByteArrayNodeGen;
63-
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.SerializeDoubleArrayNodeGen;
64-
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.SerializeFloatArrayNodeGen;
65-
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.SerializeIntArrayNodeGen;
66-
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.SerializeLongArrayNodeGen;
67-
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.SerializeShortArrayNodeGen;
62+
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.GetByteArrayTagNodeGen;
63+
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.GetDoubleArrayTagNodeGen;
64+
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.GetFloatArrayTagNodeGen;
65+
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.GetIntArrayTagNodeGen;
66+
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.GetLongArrayTagNodeGen;
67+
import com.oracle.truffle.nfi.backend.libffi.SerializeArgumentNodeFactory.GetShortArrayTagNodeGen;
6868

6969
abstract class SerializeArgumentNode extends Node {
7070

@@ -347,207 +347,141 @@ public boolean isAdoptable() {
347347
}
348348
}
349349

350-
abstract static class UnwrapHostObjectNode extends Node {
350+
abstract static class GetTypeTagNode extends Node {
351351

352-
abstract Object execute(Object value);
353-
354-
final boolean isHostObject(Object value) {
355-
LibFFIContext ctx = LibFFIContext.get(this);
356-
return ctx.env.isHostObject(value);
357-
}
358-
359-
@Specialization(guards = "isHostObject(value)")
360-
Object doHostObject(Object value) {
361-
return LibFFIContext.get(this).env.asHostObject(value);
362-
}
352+
abstract TypeTag execute(Object value);
363353

364354
@Fallback
365-
Object doOther(@SuppressWarnings("unused") Object value) {
366-
return null;
367-
}
368-
}
369-
370-
abstract static class ObjectDummy extends Node {
371-
372-
static ObjectDummy create() {
355+
TypeTag doOther(@SuppressWarnings("unused") Object value) {
373356
return null;
374357
}
375-
376-
abstract Object execute();
377358
}
378359

379-
abstract static class BufferDummy extends Node {
380-
381-
static BufferDummy create() {
382-
return null;
383-
}
384-
385-
abstract NativeArgumentBuffer execute();
386-
}
387-
388-
@NodeChild(value = "value", type = ObjectDummy.class, implicit = true)
389-
@NodeChild(value = "buffer", type = BufferDummy.class, implicit = true)
390-
@NodeChild(value = "hostObject", type = UnwrapHostObjectNode.class, executeWith = "value", implicit = true)
391360
abstract static class SerializeArrayNode extends SerializeArgumentNode {
392361

393-
SerializeArrayNode(CachedTypeInfo type) {
394-
super(type);
395-
}
362+
@Child GetTypeTagNode getTypeTag;
396363

397-
static SerializeArrayNode create(ArrayType type) {
364+
SerializeArrayNode(ArrayType type) {
365+
super(type);
398366
switch (type.elementType) {
399367
case UINT8:
400368
case SINT8:
401-
return SerializeByteArrayNodeGen.create(type);
369+
getTypeTag = GetByteArrayTagNodeGen.create();
370+
break;
402371
case UINT16:
403372
case SINT16:
404-
return SerializeShortArrayNodeGen.create(type);
373+
getTypeTag = GetShortArrayTagNodeGen.create();
374+
break;
405375
case UINT32:
406376
case SINT32:
407-
return SerializeIntArrayNodeGen.create(type);
377+
getTypeTag = GetIntArrayTagNodeGen.create();
378+
break;
408379
case UINT64:
409380
case SINT64:
410-
return SerializeLongArrayNodeGen.create(type);
381+
getTypeTag = GetLongArrayTagNodeGen.create();
382+
break;
411383
case FLOAT:
412-
return SerializeFloatArrayNodeGen.create(type);
384+
getTypeTag = GetFloatArrayTagNodeGen.create();
385+
break;
413386
case DOUBLE:
414-
return SerializeDoubleArrayNodeGen.create(type);
387+
getTypeTag = GetDoubleArrayTagNodeGen.create();
388+
break;
415389
default:
416390
throw CompilerDirectives.shouldNotReachHere(type.elementType.name());
417391
}
418392
}
419393

420-
@Specialization(guards = "hostObject == null")
421-
void doInteropObject(Object value, NativeArgumentBuffer buffer, Object hostObject,
422-
@Cached(parameters = "type") SerializePointerNode serialize) throws UnsupportedTypeException {
423-
assert hostObject == null;
424-
serialize.execute(value, buffer);
394+
final boolean isHostObject(Object value) {
395+
return LibFFIContext.get(this).env.isHostObject(value);
425396
}
426-
}
427-
428-
abstract static class SerializeByteArrayNode extends SerializeArrayNode {
429397

430-
SerializeByteArrayNode(ArrayType type) {
431-
super(type);
398+
final Object asHostObject(Object value) {
399+
return LibFFIContext.get(this).env.asHostObject(value);
432400
}
433401

434-
@Specialization
435-
void putBooleanArray(Object value, NativeArgumentBuffer buffer, boolean[] array) {
436-
assert LibFFIContext.get(this).env.asHostObject(value) == array;
437-
buffer.putObject(TypeTag.BOOLEAN_ARRAY, array, type.size);
402+
@Specialization(guards = {"isHostObject(value)", "tag != null"})
403+
void doHostObject(@SuppressWarnings("unused") Object value, NativeArgumentBuffer buffer,
404+
@Bind("asHostObject(value)") Object hostObject,
405+
@Bind("getTypeTag.execute(hostObject)") TypeTag tag) {
406+
buffer.putObject(tag, hostObject, type.size);
438407
}
439408

440-
@Specialization
441-
void putByteArray(Object value, NativeArgumentBuffer buffer, byte[] array) {
442-
assert LibFFIContext.get(this).env.asHostObject(value) == array;
443-
buffer.putObject(TypeTag.BYTE_ARRAY, array, type.size);
409+
@Specialization(guards = "tag != null")
410+
void doArray(Object value, NativeArgumentBuffer buffer,
411+
@Bind("getTypeTag.execute(value)") TypeTag tag) {
412+
buffer.putObject(tag, value, type.size);
444413
}
445414

446415
@Fallback
447-
@SuppressWarnings("unused")
448-
void doError(Object value, NativeArgumentBuffer buffer, Object array) throws UnsupportedTypeException {
449-
throw UnsupportedTypeException.create(new Object[]{value});
416+
void doInteropObject(Object value, NativeArgumentBuffer buffer,
417+
@Cached(parameters = "type") SerializePointerNode serialize) throws UnsupportedTypeException {
418+
serialize.execute(value, buffer);
450419
}
451420
}
452421

453-
abstract static class SerializeShortArrayNode extends SerializeArrayNode {
454-
455-
SerializeShortArrayNode(ArrayType type) {
456-
super(type);
457-
}
422+
abstract static class GetByteArrayTagNode extends GetTypeTagNode {
458423

459424
@Specialization
460-
void putShortArray(Object value, NativeArgumentBuffer buffer, short[] array) {
461-
assert LibFFIContext.get(this).env.asHostObject(value) == array;
462-
buffer.putObject(TypeTag.SHORT_ARRAY, array, type.size);
425+
TypeTag doBooleanArray(boolean[] array) {
426+
assert array != null;
427+
return TypeTag.BOOLEAN_ARRAY;
463428
}
464429

465430
@Specialization
466-
void putCharArray(Object value, NativeArgumentBuffer buffer, char[] array) {
467-
assert LibFFIContext.get(this).env.asHostObject(value) == array;
468-
buffer.putObject(TypeTag.CHAR_ARRAY, array, type.size);
469-
}
470-
471-
@Fallback
472-
@SuppressWarnings("unused")
473-
void doError(Object value, NativeArgumentBuffer buffer, Object array) throws UnsupportedTypeException {
474-
throw UnsupportedTypeException.create(new Object[]{value});
431+
TypeTag doByteArray(byte[] array) {
432+
assert array != null;
433+
return TypeTag.BYTE_ARRAY;
475434
}
476435
}
477436

478-
abstract static class SerializeIntArrayNode extends SerializeArrayNode {
479-
480-
SerializeIntArrayNode(ArrayType type) {
481-
super(type);
482-
}
437+
abstract static class GetShortArrayTagNode extends GetTypeTagNode {
483438

484439
@Specialization
485-
void putIntArray(Object value, NativeArgumentBuffer buffer, int[] array) {
486-
assert LibFFIContext.get(this).env.asHostObject(value) == array;
487-
buffer.putObject(TypeTag.INT_ARRAY, array, type.size);
440+
TypeTag doShortArray(short[] array) {
441+
assert array != null;
442+
return TypeTag.SHORT_ARRAY;
488443
}
489444

490-
@Fallback
491-
@SuppressWarnings("unused")
492-
void doError(Object value, NativeArgumentBuffer buffer, Object array) throws UnsupportedTypeException {
493-
throw UnsupportedTypeException.create(new Object[]{value});
445+
@Specialization
446+
TypeTag doCharArray(char[] array) {
447+
assert array != null;
448+
return TypeTag.CHAR_ARRAY;
494449
}
495450
}
496451

497-
abstract static class SerializeLongArrayNode extends SerializeArrayNode {
498-
499-
SerializeLongArrayNode(ArrayType type) {
500-
super(type);
501-
}
452+
abstract static class GetIntArrayTagNode extends GetTypeTagNode {
502453

503454
@Specialization
504-
void putLongArray(Object value, NativeArgumentBuffer buffer, long[] array) {
505-
assert LibFFIContext.get(this).env.asHostObject(value) == array;
506-
buffer.putObject(TypeTag.LONG_ARRAY, array, type.size);
507-
}
508-
509-
@Fallback
510-
@SuppressWarnings("unused")
511-
void doError(Object value, NativeArgumentBuffer buffer, Object array) throws UnsupportedTypeException {
512-
throw UnsupportedTypeException.create(new Object[]{value});
455+
TypeTag doIntArray(int[] array) {
456+
assert array != null;
457+
return TypeTag.INT_ARRAY;
513458
}
514459
}
515460

516-
abstract static class SerializeFloatArrayNode extends SerializeArrayNode {
517-
518-
SerializeFloatArrayNode(ArrayType type) {
519-
super(type);
520-
}
461+
abstract static class GetLongArrayTagNode extends GetTypeTagNode {
521462

522463
@Specialization
523-
void putFloatArray(Object value, NativeArgumentBuffer buffer, float[] array) {
524-
assert LibFFIContext.get(this).env.asHostObject(value) == array;
525-
buffer.putObject(TypeTag.FLOAT_ARRAY, array, type.size);
526-
}
527-
528-
@Fallback
529-
@SuppressWarnings("unused")
530-
void doError(Object value, NativeArgumentBuffer buffer, Object array) throws UnsupportedTypeException {
531-
throw UnsupportedTypeException.create(new Object[]{value});
464+
TypeTag doLongArray(long[] array) {
465+
assert array != null;
466+
return TypeTag.LONG_ARRAY;
532467
}
533468
}
534469

535-
abstract static class SerializeDoubleArrayNode extends SerializeArrayNode {
536-
537-
SerializeDoubleArrayNode(ArrayType type) {
538-
super(type);
539-
}
470+
abstract static class GetFloatArrayTagNode extends GetTypeTagNode {
540471

541472
@Specialization
542-
void putDoubleArray(Object value, NativeArgumentBuffer buffer, double[] array) {
543-
assert LibFFIContext.get(this).env.asHostObject(value) == array;
544-
buffer.putObject(TypeTag.DOUBLE_ARRAY, array, type.size);
473+
TypeTag doFloatArray(float[] array) {
474+
assert array != null;
475+
return TypeTag.FLOAT_ARRAY;
545476
}
477+
}
546478

547-
@Fallback
548-
@SuppressWarnings("unused")
549-
void doError(Object value, NativeArgumentBuffer buffer, Object array) throws UnsupportedTypeException {
550-
throw UnsupportedTypeException.create(new Object[]{value});
479+
abstract static class GetDoubleArrayTagNode extends GetTypeTagNode {
480+
481+
@Specialization
482+
TypeTag doDoubleArray(double[] array) {
483+
assert array != null;
484+
return TypeTag.DOUBLE_ARRAY;
551485
}
552486
}
553487
}

0 commit comments

Comments
 (0)