Skip to content

Commit

Permalink
Directly allocate warnings asVectorEnsoObjects (#10143)
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach authored Jun 1, 2024
1 parent af4177e commit 9632f04
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 86 deletions.
8 changes: 4 additions & 4 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Data/Array.enso
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ type Array
`Map_Error`.
- No_Wrap: The first error is thrown, and is not wrapped in
`Map_Error`.
- Report_Warning: The result for that element is `Nothing`,
- Report_Warning: The result for that element is `Nothing`,
the error is attached as a warning. Currently unimplemented.
- Ignore: The result is `Nothing`, and the error is
ignored.
Expand Down Expand Up @@ -421,7 +421,7 @@ type Array
`Map_Error`.
- No_Wrap: The first error is thrown, and is not wrapped in
`Map_Error`.
- Report_Warning: The result for that element is `Nothing`,
- Report_Warning: The result for that element is `Nothing`,
the error is attached as a warning. Currently unimplemented.
- Ignore: The result is `Nothing`, and the error is
ignored.
Expand Down Expand Up @@ -668,7 +668,7 @@ type Array
`Map_Error`.
- No_Wrap: The first error is thrown, and is not wrapped in
`Map_Error`.
- Report_Warning: The result for that element is `Nothing`,
- Report_Warning: The result for that element is `Nothing`,
the error is attached as a warning. Currently unimplemented.
- Ignore: The result is `Nothing`, and the error is
ignored.
Expand Down Expand Up @@ -891,7 +891,7 @@ type Array
`Map_Error`.
- No_Wrap: The first error is thrown, and is not wrapped in
`Map_Error`.
- Report_Warning: The result for that element is `Nothing`,
- Report_Warning: The result for that element is `Nothing`,
the error is attached as a warning. Currently unimplemented.
- Ignore: The result is `Nothing`, and the error is
ignored.
Expand Down
15 changes: 7 additions & 8 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Data/Vector.enso
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ type Vector a
`Map_Error`.
- No_Wrap: The first error is thrown, and is not wrapped in
`Map_Error`.
- Report_Warning: The result for that element is `Nothing`,
- Report_Warning: The result for that element is `Nothing`,
the error is attached as a warning. Currently unimplemented.
- Ignore: The result is `Nothing`, and the error is
ignored.
Expand Down Expand Up @@ -718,7 +718,7 @@ type Vector a
`Map_Error`.
- No_Wrap: The first error is thrown, and is not wrapped in
`Map_Error`.
- Report_Warning: The result for that element is `Nothing`,
- Report_Warning: The result for that element is `Nothing`,
the error is attached as a warning. Currently unimplemented.
- Ignore: The result is `Nothing`, and the error is
ignored.
Expand Down Expand Up @@ -772,7 +772,7 @@ type Vector a
`Map_Error`.
- No_Wrap: The first error is thrown, and is not wrapped in
`Map_Error`.
- Report_Warning: The result for that element is `Nothing`,
- Report_Warning: The result for that element is `Nothing`,
the error is attached as a warning. Currently unimplemented.
- Ignore: The result is `Nothing`, and the error is
ignored.
Expand Down Expand Up @@ -1014,7 +1014,7 @@ type Vector a
`Map_Error`.
- No_Wrap: The first error is thrown, and is not wrapped in
`Map_Error`.
- Report_Warning: The result for that element is `Nothing`,
- Report_Warning: The result for that element is `Nothing`,
the error is attached as a warning. Currently unimplemented.
- Ignore: The result is `Nothing`, and the error is
ignored.
Expand Down Expand Up @@ -1507,17 +1507,16 @@ type Builder
## GROUP Conversions
ICON convert
Clones the builder into a Vector.
to_vector : Vector Any
to_vector self =
to_vector self -> Vector =
## This creates a fresh copy of the builders storage, so any future
changes to the builder will not affect the returned vector.

This also reattaches any warnings that were attached to the added
values. It attaches them to the whole array, not the individual
values.
warnings_vector = Vector.from_polyglot_array self.warnings_java_builder.toArray
warnings_vector = self.warnings_java_builder.toArray
Warning.attach_multiple warnings_vector <|
Vector.from_polyglot_array self.elements_java_builder.toArray
self.elements_java_builder.toArray

## PRIVATE
Describes an error attached to a value within a `Vector`. The `index` field
Expand Down
6 changes: 3 additions & 3 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Warning.enso
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ type Warning
- wrap_errors: If true, warnings attached to elements in array-likes are
wrapped in Map_Error.
get_all : Any -> Boolean -> Vector Warning
get_all value wrap_errors:Boolean=False = Vector.from_polyglot_array (get_all_array value wrap_errors)
get_all value wrap_errors:Boolean=False = get_all_vector value wrap_errors

## PRIVATE
ADVANCED
Expand Down Expand Up @@ -306,8 +306,8 @@ attach_with_stacktrace value warning origin = @Builtin_Method "Warning.attach_wi
## PRIVATE

Builtin function that gets all the warnings attached to the given value.
get_all_array : Any -> Boolean -> Array Warning
get_all_array value should_wrap = @Builtin_Method "Warning.get_all_array"
get_all_vector : Any -> Boolean -> Vector Warning
get_all_vector value should_wrap = @Builtin_Method "Warning.get_all_vector"

## PRIVATE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,15 @@ public void initializeBenchmark(BenchmarkParams params) throws Exception {
import Standard.Base.Data.Vector.Builder
import Standard.Base.Data.Vector.Vector
import Standard.Base.Data.Array_Proxy.Array_Proxy
from Standard.Base.Data.Boolean import False
avg arr =
sum acc i = if i == arr.length then acc else
@Tail_Call sum (acc + arr.at i) i+1
sum acc i =
stop = i == arr.length
if stop then acc else
value = arr.at i
both = acc + value
@Tail_Call sum both i+1
(sum 0 0) / arr.length
fibarr size modulo =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,11 @@ public Optional<BuiltinFunction> getBuiltinFunction(
if (atomNodes == null) {
return Optional.empty();
}
LoadedBuiltinMethod builtin = atomNodes.get(methodName).get();
var supply = atomNodes.get(methodName);
if (supply == null) {
return Optional.empty();
}
LoadedBuiltinMethod builtin = supply.get();
if (builtin == null) {
return Optional.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@
import com.oracle.truffle.api.nodes.Node;
import java.util.Arrays;
import org.enso.interpreter.runtime.data.EnsoObject;
import org.enso.interpreter.runtime.error.WarningsLibrary;

@ExportLibrary(InteropLibrary.class)
final class ArrayBuilder implements EnsoObject {
private static final String[] MEMBERS =
new String[] {"isEmpty", "add", "appendTo", "get", "getSize", "toArray"};
private static final Object[] EMPTY_ARRAY = new Object[0];
private final int initialCapacity;
private int size;
private Object primitiveArray;
private Object[] objectArray;

/** becomes {@code true} when a non trivial value is being added to the builder */
private boolean nonTrivialEnsoValue;

private ArrayBuilder(int initialCapacity) {
this.initialCapacity = Math.max(1, initialCapacity);
}
Expand All @@ -41,14 +44,21 @@ boolean isEmpty() {
* Adds an element to the builder
*
* @param e the element to add
* @param warnings library to check for values with warnings
*/
void add(Object e) {
if (objectArray != null) {
if (size == objectArray.length) {
CompilerDirectives.transferToInterpreter();
objectArray = Arrays.copyOf(objectArray, size * 2);
void add(Object e, WarningsLibrary warnings) {
if (!nonTrivialEnsoValue) {
if (warnings.hasWarnings(e)) {
nonTrivialEnsoValue = true;
} else {
var isEnsoValue = e instanceof EnsoObject || e instanceof Long || e instanceof Double;
if (!isEnsoValue) {
nonTrivialEnsoValue = true;
}
}
objectArray[size++] = e;
}
if (objectArray != null) {
addToObjectArray(e);
} else if (primitiveArray instanceof long[] longArray) {
if (e instanceof Long l) {
if (size == longArray.length) {
Expand All @@ -63,7 +73,7 @@ void add(Object e) {
objectArray[i] = longArray[i];
}
primitiveArray = null;
add(e);
addToObjectArray(e);
}
} else if (primitiveArray instanceof double[] doubleArray) {
if (e instanceof Double d) {
Expand All @@ -79,29 +89,41 @@ void add(Object e) {
objectArray[i] = doubleArray[i];
}
primitiveArray = null;
add(e);
addToObjectArray(e);
}
} else {
assert objectArray == null;
assert primitiveArray == null;
assert size == 0;
if (e instanceof Long l) {
var arr = new long[initialCapacity];
arr[0] = l;
primitiveArray = arr;
} else if (e instanceof Double d) {
var arr = new double[initialCapacity];
arr[0] = d;
primitiveArray = arr;
} else {
var arr = new Object[initialCapacity];
arr[0] = e;
objectArray = arr;
switch (e) {
case Long l -> {
var arr = new long[initialCapacity];
arr[0] = l;
primitiveArray = arr;
}
case Double d -> {
var arr = new double[initialCapacity];
arr[0] = d;
primitiveArray = arr;
}
default -> {
var arr = new Object[initialCapacity];
arr[0] = e;
objectArray = arr;
}
}
size = 1;
}
}

private void addToObjectArray(Object e) {
if (size == objectArray.length) {
CompilerDirectives.transferToInterpreter();
objectArray = Arrays.copyOf(objectArray, size * 2);
}
objectArray[size++] = e;
}

/** Obtains an element from the builder */
private Object get(int index, Node node) {
try {
Expand All @@ -121,15 +143,15 @@ private Object get(int index, Node node) {
}

/** Returns the current array of the builder. */
Object toArray() {
private Object toArray() {
if (objectArray != null) {
return objectArray.length == size ? objectArray : Arrays.copyOf(objectArray, size);
} else if (primitiveArray instanceof long[] longArray) {
return longArray.length == size ? longArray : Arrays.copyOf(longArray, size);
} else if (primitiveArray instanceof double[] doubleArray) {
return doubleArray.length == size ? doubleArray : Arrays.copyOf(doubleArray, size);
} else {
return EMPTY_ARRAY;
return null;
}
}

Expand All @@ -138,20 +160,24 @@ int getSize() {
}

@ExportMessage
Object invokeMember(String name, Object[] args, @CachedLibrary(limit = "3") InteropLibrary iop)
Object invokeMember(
String name,
Object[] args,
@CachedLibrary(limit = "3") InteropLibrary iop,
@CachedLibrary(limit = "3") WarningsLibrary warnings)
throws UnknownIdentifierException, UnsupportedTypeException, UnsupportedMessageException {
return switch (name) {
case "isEmpty" -> isEmpty();
case "add" -> {
add(args[0]);
add(args[0], warnings);
yield this;
}
case "appendTo" -> {
long len = iop.getArraySize(args[0]);
for (var i = 0; i < len; i++) {
try {
var e = iop.readArrayElement(args[0], i);
add(e);
add(e, warnings);
} catch (InvalidArrayIndexException ex) {
throw UnsupportedTypeException.create(args);
}
Expand All @@ -169,16 +195,7 @@ Object invokeMember(String name, Object[] args, @CachedLibrary(limit = "3") Inte
yield get(index, iop);
}
case "getSize" -> getSize();
case "toArray" -> {
var arr = toArray();
if (arr instanceof long[] longs) {
yield Vector.fromLongArray(longs);
}
if (arr instanceof double[] doubles) {
yield Vector.fromDoubleArray(doubles);
}
yield Vector.fromInteropArray(Array.wrap((Object[]) arr));
}
case "toArray" -> asVector();
default -> throw UnknownIdentifierException.create(name);
};
}
Expand Down Expand Up @@ -207,4 +224,19 @@ EnsoObject getMembers(boolean includeInternal) {
String toDisplayString(boolean ignore) {
return "Array_Builder";
}

Object asVector() {
var res = toArray();
if (res instanceof long[] longs) {
return Vector.fromLongArray(longs);
}
if (res instanceof double[] doubles) {
return Vector.fromDoubleArray(doubles);
}
if (nonTrivialEnsoValue) {
return Vector.fromInteropArray(Array.wrap((Object[]) res));
} else {
return Vector.fromEnsoOnlyArray((Object[]) res);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,35 +90,14 @@ public static Object vectorFromFunction(
@CachedLibrary(limit = "3") WarningsLibrary warnings) {
var len = Math.toIntExact(length);
var target = ArrayBuilder.newBuilder(len);
boolean nonTrivialEnsoValue = false;
for (int i = 0; i < len; i++) {
var value = invokeFunctionNode.execute(fun, frame, state, new Long[] {(long) i});
if (value instanceof DataflowError) {
return value;
}
if (warnings.hasWarnings(value)) {
nonTrivialEnsoValue = true;
} else {
var isEnsoValue =
value instanceof EnsoObject || value instanceof Long || value instanceof Double;
if (!isEnsoValue) {
nonTrivialEnsoValue = true;
}
}
target.add(value);
}
var res = target.toArray();
if (res instanceof long[] longs) {
return Vector.fromLongArray(longs);
}
if (res instanceof double[] doubles) {
return Vector.fromDoubleArray(doubles);
}
if (nonTrivialEnsoValue) {
return Vector.fromInteropArray(Array.wrap((Object[]) res));
} else {
return Vector.fromEnsoOnlyArray((Object[]) res);
target.add(value, warnings);
}
return target.asVector();
}

@Builtin.Method(
Expand Down Expand Up @@ -166,4 +145,12 @@ public static EnsoObject asVectorWithCheckAt(Object... arr) {
public static EnsoObject asVectorFromArray(Object storage) {
return Vector.fromInteropArray(storage);
}

public static EnsoObject asVectorEnsoObjects(EnsoObject... arr) {
return Vector.fromEnsoOnlyArray(arr);
}

public static EnsoObject asVectorEmpty() {
return Vector.fromEnsoOnlyArray(null);
}
}
Loading

0 comments on commit 9632f04

Please sign in to comment.