Skip to content

Commit

Permalink
[GR-17457] Avoid streams
Browse files Browse the repository at this point in the history
PullRequest: truffleruby/4029
  • Loading branch information
eregon committed Oct 12, 2023
2 parents 21ad763 + 2e8c6c4 commit 3875f52
Show file tree
Hide file tree
Showing 14 changed files with 120 additions and 148 deletions.
55 changes: 4 additions & 51 deletions src/main/.checkstyle_checks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,10 @@
<property name="format" value="@Exclusive @Cached"/>
<property name="message" value="Wrong order of annotations. The correct order is @Cached @Exclusive."/>
</module>
<module name="RegexpSinglelineJava">
<property name="format" value="Stream\.of\(|Arrays\.stream\(|\.stream\(\)|import java\.util\.stream\."/>
<property name="message" value="Avoid using Java Streams, they cause lots of allocations and are slow for startup and in interpreter."/>
</module>
<module name="IllegalType">
<!-- Use PrintStream instead of PrintWriter, PrintWriter does not consistently flush, even when writing \n.-->
<property name="illegalClassNames" value="PrintWriter"/>
Expand All @@ -287,62 +291,11 @@
<property name="tokens" value="ANNOTATION_FIELD_DEF,INTERFACE_DEF,METHOD_CALL,METHOD_DEF,METHOD_REF,PARAMETER_DEF,VARIABLE_DEF,PATTERN_VARIABLE_DEF,RECORD_DEF,RECORD_COMPONENT_DEF"/>
</module>

<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="Checkstyle: stop constant name check"/>
<property name="onCommentFormat" value="Checkstyle: resume constant name check"/>
<property name="checkFormat" value="ConstantNameCheck"/>
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Allow non-conforming constant names"/>
</module>
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="Checkstyle: stop method name check"/>
<property name="onCommentFormat" value="Checkstyle: resume method name check"/>
<property name="checkFormat" value="MethodName"/>
<property name="checkC" value="false"/>
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable method name checks"/>
</module>
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CheckStyle: stop parameter assignment check"/>
<property name="onCommentFormat" value="CheckStyle: resume parameter assignment check"/>
<property name="checkFormat" value="ParameterAssignment"/>
<property name="checkC" value="false"/>
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable Parameter Assignment"/>
</module>
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="Checkstyle: stop final variable check"/>
<property name="onCommentFormat" value="Checkstyle: resume final variable check"/>
<property name="checkFormat" value="FinalLocalVariable"/>
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable final variable checks"/>
</module>
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="Checkstyle: stop"/>
<property name="onCommentFormat" value="Checkstyle: resume"/>
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable all checks"/>
</module>
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CheckStyle: stop inner assignment check"/>
<property name="onCommentFormat" value="CheckStyle: resume inner assignment check"/>
<property name="checkFormat" value="InnerAssignment"/>
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable inner assignment checks"/>
</module>
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="Checkstyle: stop field name check"/>
<property name="onCommentFormat" value="Checkstyle: resume field name check"/>
<property name="checkFormat" value="MemberName"/>
<property name="checkC" value="false"/>
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable field name checks"/>
</module>
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CheckStyle: stop system..print check"/>
<property name="onCommentFormat" value="CheckStyle: resume system..print check"/>
<property name="checkFormat" value="RegexpSingleline"/>
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable System.(out|err).print checks"/>
</module>
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CheckStyle: stop header check"/>
<property name="onCommentFormat" value="CheckStyle: resume header check"/>
<property name="checkFormat" value=".*Header"/>
<metadata name="com.atlassw.tools.eclipse.checkstyle.comment" value="Disable header checks"/>
</module>
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CheckStyle: start generated"/>
<property name="onCommentFormat" value="CheckStyle: stop generated"/>
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/org/truffleruby/aot/ParserCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.source.Source;
import org.truffleruby.core.CoreLibrary;
import org.truffleruby.core.array.ArrayUtils;
import org.truffleruby.core.string.StringUtils;
import org.truffleruby.language.loader.ResourceLoader;
import org.truffleruby.parser.RubyDeferredWarnings;
import org.truffleruby.parser.RubyDeferredWarnings.WarningMessage;
import org.truffleruby.parser.RubySource;
import org.truffleruby.parser.TranslatorDriver;
import org.truffleruby.parser.ast.RootParseNode;
Expand Down Expand Up @@ -64,12 +66,11 @@ private static RootParseNode parse(RubySource source) {
final StaticScope staticScope = new StaticScope(StaticScope.Type.LOCAL, null);
final ParserConfiguration parserConfiguration = new ParserConfiguration(null, false, true, false);
RubyDeferredWarnings rubyWarnings = new RubyDeferredWarnings();
RootParseNode rootParseNode = TranslatorDriver
.parseToJRubyAST(null, source, staticScope, parserConfiguration, rubyWarnings);
var rootParseNode = TranslatorDriver.parseToJRubyAST(null, source, staticScope, parserConfiguration,
rubyWarnings);
if (!rubyWarnings.warnings.isEmpty()) {
throw new RuntimeException("Core files should not emit warnings: " + String.join(
"\n",
rubyWarnings.warnings.stream().map(w -> w.getWarningMessage()).collect(Collectors.toList())));
throw new RuntimeException("Core files should not emit warnings: " +
StringUtils.join(ArrayUtils.map(rubyWarnings.warnings, WarningMessage::getWarningMessage), "\n"));
}
return rootParseNode;
}
Expand Down
17 changes: 8 additions & 9 deletions src/main/java/org/truffleruby/core/VMPrimitiveNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@
*/
package org.truffleruby.core;

import java.util.Arrays;
import java.util.Map.Entry;
import java.util.stream.Stream;

import com.oracle.truffle.api.TruffleStackTrace;
import com.oracle.truffle.api.dsl.Bind;
Expand Down Expand Up @@ -621,15 +619,16 @@ RubyArray argumentsDescriptor(VirtualFrame frame) {
private RubyArray descriptorToArray(ArgumentsDescriptor descriptor) {
if (descriptor == EmptyArgumentsDescriptor.INSTANCE) {
return createEmptyArray();
} else if (descriptor instanceof KeywordArgumentsDescriptor) {
final KeywordArgumentsDescriptor keywordArgumentsDescriptor = (KeywordArgumentsDescriptor) descriptor;
} else if (descriptor instanceof KeywordArgumentsDescriptor keywordArgumentsDescriptor) {
var keywords = keywordArgumentsDescriptor.getKeywords();

final Stream<RubySymbol> keywords = Stream.concat(
Stream.of("keywords"),
Arrays.stream(keywordArgumentsDescriptor.getKeywords()))
.map(getLanguage()::getSymbol);
Object[] array = new Object[1 + keywords.length];
array[0] = getSymbol("keywords");
for (int i = 0; i < keywords.length; i++) {
array[i + 1] = getSymbol(keywords[i]);
}

return createArray(keywords.toArray());
return createArray(array);
} else {
throw CompilerDirectives.shouldNotReachHere();
}
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/org/truffleruby/core/array/ArrayUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
package org.truffleruby.core.array;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.TruffleSafepoint;
Expand Down Expand Up @@ -278,4 +281,35 @@ public static List<Object> asList(Object[] array) {
return Arrays.asList(array);
}

/** Compares by identity using Java {@code ==} */
@TruffleBoundary
public static Object[] subtract(Object[] a, Object[] b) {
var result = new ArrayList<>();
for (Object element : a) {
if (!contains(b, element)) {
result.add(element);
}
}
return result.toArray();
}

@TruffleBoundary
public static <T, R> Object[] map(T[] array, Function<? super T, ? extends R> mapper) {
var result = new Object[array.length];
for (int i = 0; i < array.length; i++) {
result[i] = mapper.apply(array[i]);
}
return result;
}

@TruffleBoundary
public static <T, R> Object[] map(Collection<T> list, Function<? super T, ? extends R> mapper) {
var result = new Object[list.size()];
var iterator = list.iterator();
for (int i = 0; i < list.size(); i++) {
result[i] = mapper.apply(iterator.next());
}
return result;
}

}
24 changes: 7 additions & 17 deletions src/main/java/org/truffleruby/core/regexp/TruffleRegexpNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.TruffleSafepoint;
Expand Down Expand Up @@ -458,32 +457,23 @@ protected <T> RubyArray fillinInstrumentData(Set<T> map, ArrayBuilderNode arrayB
@TruffleBoundary
protected static Set<RubyRegexp> allCompiledRegexps() {
final Set<RubyRegexp> ret = new HashSet<>();

ret.addAll(DYNAMIC_REGEXPS);
ret.addAll(LITERAL_REGEXPS);

return ret;
}

@TruffleBoundary
protected static Set<RubyRegexp> allMatchedRegexps() {
final Set<RubyRegexp> ret = new HashSet<>();

ret.addAll(
MATCHED_REGEXPS_JONI
.keySet()
.stream()
.map(matchInfo -> matchInfo.regex)
.collect(Collectors.toSet()));
ret.addAll(
MATCHED_REGEXPS_TREGEX
.keySet()
.stream()
.map(matchInfo -> matchInfo.regex)
.collect(Collectors.toSet()));

for (var matchInfo : MATCHED_REGEXPS_JONI.keySet()) {
ret.add(matchInfo.regex);
}
for (var matchInfo : MATCHED_REGEXPS_TREGEX.keySet()) {
ret.add(matchInfo.regex);
}
return ret;
}

}

@CoreMethod(names = "regexp_compilation_stats_array", onSingleton = true, required = 1)
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/org/truffleruby/core/string/StringUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,22 @@ public static String toUpperCase(String string) {
return string.toUpperCase(Locale.ENGLISH);
}

@TruffleBoundary
public static String join(Object[] elements, String separator) {
return join(elements, separator, "", "");
}

@TruffleBoundary
public static String join(Object[] elements, String separator, String prefix, String suffix) {
var builder = new StringBuilder(prefix);
for (int i = 0; i < elements.length; i++) {
builder.append(elements[i]);
if (i != elements.length - 1) {
builder.append(separator);
}
}
builder.append(suffix);
return builder.toString();
}

}
47 changes: 22 additions & 25 deletions src/main/java/org/truffleruby/debug/TruffleASTPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.oracle.truffle.api.profiles.Profile;
import org.graalvm.collections.Pair;
import org.truffleruby.core.proc.ProcCallTargets;
import org.truffleruby.core.string.StringUtils;
import org.truffleruby.core.support.DetailedInspectingSupport;
import org.truffleruby.language.RubyRootNode;
import org.truffleruby.language.methods.CachedLazyCallTargetSupplier;
Expand Down Expand Up @@ -121,23 +120,21 @@ private static List<Pair<String, Object>> getNodeAttributes(Node node) {
}

var attributesMap = NodeUtil.collectNodeProperties(node);
var attributes = new ArrayList<>(attributesMap.entrySet())
.stream()
.map(entry -> Pair.create(entry.getKey(), entry.getValue()))
.map(pair -> {
if (pair.getLeft().startsWith("field.")) {
String name = pair.getLeft().substring("field.".length());
return Pair.create(name, pair.getRight());
} else {
return pair;
}
})
.filter(pair -> pair.getRight() != null) // hide numerous attributes that aren't initialized yet
.filter(pair -> !attributesToIgnore.contains(pair.getLeft())) // ignore some noisy attributes
.filter(pair -> !generatedFieldNames.contains(pair.getLeft())) // ignore attributes of generated -Gen classes
.filter(pair -> !(pair.getRight() instanceof Profile)) // ignore ...Profile as far as they might be disabled/enabled that affects string representation
.collect(Collectors.toList());
var attributes = new ArrayList<Pair<String, Object>>();
for (var entry : attributesMap.entrySet()) {
String name = entry.getKey();
Object value = entry.getValue();
if (name.startsWith("field.")) {
name = name.substring("field.".length());
}

if (value != null && // hide numerous attributes that aren't initialized yet
!attributesToIgnore.contains(name) && // ignore some noisy attributes
!generatedFieldNames.contains(name) && // ignore attributes of generated -Gen classes
!(value instanceof Profile)) { // ignore ...Profile as far as they might be disabled/enabled that affects string representation
attributes.add(Pair.create(name, value));
}
}
return attributes;
}

Expand All @@ -163,12 +160,12 @@ private static List<Pair<String, Object>> getNodeChildren(Node node) {
}
}

var children = new ArrayList<>(childrenMap.entrySet())
.stream()
.map(entry -> Pair.create(entry.getKey(), entry.getValue()))
.filter(pair -> pair.getRight() != null) // hide child nodes that aren't initialized yet
.collect(Collectors.toList());

var children = new ArrayList<Pair<String, Object>>();
for (var entry : childrenMap.entrySet()) {
if (entry.getValue() != null) { // hide child nodes that aren't initialized yet
children.add(Pair.create(entry.getKey(), entry.getValue()));
}
}
return children;
}

Expand Down Expand Up @@ -316,7 +313,7 @@ private static String valueOrArrayToString(Object value) {
strings[i] = valueToString(element);
}

valueString = Stream.of(strings).collect(Collectors.joining(", ", "[", "]"));
valueString = StringUtils.join(strings, ", ", "[", "]");
} else {
valueString = valueToString(value);
}
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/org/truffleruby/debug/TruffleDebugNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.truffleruby.core.RubyHandle;
import org.truffleruby.core.array.ArrayGuards;
import org.truffleruby.core.array.ArrayHelpers;
import org.truffleruby.core.array.ArrayUtils;
import org.truffleruby.core.array.RubyArray;
import org.truffleruby.core.array.library.ArrayStoreLibrary;
import org.truffleruby.core.binding.BindingNodes;
Expand Down Expand Up @@ -1403,10 +1404,9 @@ public abstract static class PrimitiveNamesNode extends CoreMethodArrayArguments
@TruffleBoundary
@Specialization
RubyArray primitiveNames() {
var primitiveNames = getLanguage().primitiveManager.getPrimitiveNames().stream()
.map(FromJavaStringNode::executeUncached);

return createArray(primitiveNames.toArray());
var primitives = getLanguage().primitiveManager.getPrimitiveNames();
var primitiveNames = ArrayUtils.map(primitives, FromJavaStringNode::executeUncached);
return createArray(primitiveNames);
}
}

Expand Down
7 changes: 2 additions & 5 deletions src/main/java/org/truffleruby/language/TruffleBootNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.nodes.NodeUtil;
Expand All @@ -29,6 +28,7 @@
import org.truffleruby.core.array.RubyArray;
import org.truffleruby.core.encoding.Encodings;
import org.truffleruby.core.string.RubyString;
import org.truffleruby.core.string.StringUtils;
import org.truffleruby.core.symbol.RubySymbol;
import org.truffleruby.language.control.RaiseException;
import org.truffleruby.language.dispatch.DispatchNode;
Expand Down Expand Up @@ -409,10 +409,7 @@ Object toolchainPaths(RubySymbol pathName,
final Toolchain toolchain = getToolchain(getContext(), this);
final List<TruffleFile> paths = toolchain.getPaths(name);
if (paths != null) {
String path = paths
.stream()
.map(file -> file.getPath())
.collect(Collectors.joining(File.pathSeparator));
String path = StringUtils.join(paths.toArray(), File.pathSeparator);
return createString(fromJavaStringNode, path, Encodings.UTF_8);
} else {
throw new RaiseException(
Expand Down
Loading

0 comments on commit 3875f52

Please sign in to comment.