From 5eca9ea2c1da0dcb59e71ae938ea836b2574d3ab Mon Sep 17 00:00:00 2001 From: Lukas Stadler <lukas.stadler@oracle.com> Date: Tue, 1 Dec 2015 15:14:34 +0100 Subject: [PATCH] create new environments earlier during deserialization --- .../truffle/r/nodes/RTruffleVisitor.java | 95 +++++++++++++++---- .../oracle/truffle/r/runtime/RSerialize.java | 20 ++-- .../truffle/r/runtime/data/RDataFactory.java | 13 ++- .../truffle/r/runtime/env/REnvironment.java | 29 +++--- 4 files changed, 111 insertions(+), 46 deletions(-) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java index 6454110614..23b8ef26b7 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java @@ -22,27 +22,84 @@ */ package com.oracle.truffle.r.nodes; -import java.util.*; -import java.util.function.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.r.nodes.access.*; -import com.oracle.truffle.r.nodes.access.variables.*; -import com.oracle.truffle.r.nodes.binary.*; -import com.oracle.truffle.r.nodes.control.*; -import com.oracle.truffle.r.nodes.function.*; -import com.oracle.truffle.r.parser.ast.*; +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; + +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.access.AccessArgumentNode; +import com.oracle.truffle.r.nodes.access.ConstantNode; +import com.oracle.truffle.r.nodes.access.ReadVariadicComponentNode; +import com.oracle.truffle.r.nodes.access.WriteLocalFrameVariableNode; +import com.oracle.truffle.r.nodes.access.WriteReplacementNode; +import com.oracle.truffle.r.nodes.access.WriteVariableNode; +import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; +import com.oracle.truffle.r.nodes.binary.ColonNode; +import com.oracle.truffle.r.nodes.control.BlockNode; +import com.oracle.truffle.r.nodes.control.BreakNode; +import com.oracle.truffle.r.nodes.control.ForNode; +import com.oracle.truffle.r.nodes.control.IfNode; +import com.oracle.truffle.r.nodes.control.NextNode; +import com.oracle.truffle.r.nodes.control.ReplacementNode; +import com.oracle.truffle.r.nodes.control.WhileNode; +import com.oracle.truffle.r.nodes.function.FormalArguments; +import com.oracle.truffle.r.nodes.function.FunctionBodyNode; +import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode; +import com.oracle.truffle.r.nodes.function.FunctionExpressionNode; +import com.oracle.truffle.r.nodes.function.FunctionStatementsNode; +import com.oracle.truffle.r.nodes.function.GroupDispatchNode; +import com.oracle.truffle.r.nodes.function.PostProcessArgumentsNode; +import com.oracle.truffle.r.nodes.function.RCallNode; +import com.oracle.truffle.r.nodes.function.SaveArgumentsNode; +import com.oracle.truffle.r.nodes.function.WrapDefaultArgumentNode; +import com.oracle.truffle.r.parser.ast.ASTNode; +import com.oracle.truffle.r.parser.ast.AccessVariable; +import com.oracle.truffle.r.parser.ast.AccessVector; +import com.oracle.truffle.r.parser.ast.ArgNode; +import com.oracle.truffle.r.parser.ast.BinaryOperation; +import com.oracle.truffle.r.parser.ast.Break; +import com.oracle.truffle.r.parser.ast.Constant; import com.oracle.truffle.r.parser.ast.Constant.ConstantType; -import com.oracle.truffle.r.parser.ast.Operation.ArithmeticOperator; -import com.oracle.truffle.r.parser.ast.Operation.Operator; +import com.oracle.truffle.r.parser.ast.FieldAccess; +import com.oracle.truffle.r.parser.ast.For; +import com.oracle.truffle.r.parser.ast.Formula; import com.oracle.truffle.r.parser.ast.Function; -import com.oracle.truffle.r.parser.tools.*; -import com.oracle.truffle.r.runtime.*; -import com.oracle.truffle.r.runtime.data.*; -import com.oracle.truffle.r.runtime.env.frame.*; -import com.oracle.truffle.r.runtime.nodes.*; +import com.oracle.truffle.r.parser.ast.FunctionCall; +import com.oracle.truffle.r.parser.ast.If; +import com.oracle.truffle.r.parser.ast.Missing; +import com.oracle.truffle.r.parser.ast.Next; +import com.oracle.truffle.r.parser.ast.Operation.ArithmeticOperator; +import com.oracle.truffle.r.parser.ast.Repeat; +import com.oracle.truffle.r.parser.ast.Replacement; +import com.oracle.truffle.r.parser.ast.Sequence; +import com.oracle.truffle.r.parser.ast.SimpleAccessTempVariable; +import com.oracle.truffle.r.parser.ast.SimpleAccessVariable; +import com.oracle.truffle.r.parser.ast.SimpleAccessVariadicComponent; +import com.oracle.truffle.r.parser.ast.SimpleAssignVariable; +import com.oracle.truffle.r.parser.ast.UnaryOperation; +import com.oracle.truffle.r.parser.ast.UpdateField; +import com.oracle.truffle.r.parser.ast.UpdateVector; +import com.oracle.truffle.r.parser.ast.While; +import com.oracle.truffle.r.parser.tools.BasicVisitor; +import com.oracle.truffle.r.parser.tools.EvaluatedArgumentsVisitor; +import com.oracle.truffle.r.runtime.ArgumentsSignature; +import com.oracle.truffle.r.runtime.FastROptions; +import com.oracle.truffle.r.runtime.RGroupGenerics; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.data.FastPathFactory; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.REmpty; +import com.oracle.truffle.r.runtime.data.RFunction; +import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; +import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; public final class RTruffleVisitor extends BasicVisitor<RSyntaxNode> { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java index 6a0941c5b4..425e5d847c 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java @@ -190,9 +190,7 @@ public class RSerialize { protected Object addReadRef(Object item) { assert item != null; if (refTableIndex >= refTable.length) { - Object[] newRefTable = new Object[2 * refTable.length]; - System.arraycopy(refTable, 0, newRefTable, 0, refTable.length); - refTable = newRefTable; + refTable = Arrays.copyOf(refTable, refTable.length * 2); } refTable[refTableIndex++] = item; return item; @@ -416,15 +414,19 @@ public class RSerialize { Object enclos = readItem(); REnvironment enclosing = enclos == RNull.instance ? REnvironment.baseEnv() : (REnvironment) enclos; + final REnvironment.NewEnv env = RDataFactory.createNewEnv(enclosing, null); + /* + * We update the env reference as soon as possible, in case the contents of an + * environment contain a reference to the env itself. + */ + updateEnvReadRef(envRefTableIndex, env); Object frame = readItem(); boolean hashed = frame == RNull.instance; - REnvironment env; Object hashtab = readItem(); if (hashed) { - if (hashtab == RNull.instance) { - env = RDataFactory.createNewEnv(enclosing, null); - } else { - env = RDataFactory.createNewEnv(enclosing, null, true, ((RList) hashtab).getLength()); + if (hashtab != RNull.instance) { + env.setHashed(true); + env.setInitialSize(((RList) hashtab).getLength()); RList hashList = (RList) hashtab; // GnuR sizes its hash tables, empty slots indicated by RNull for (int i = 0; i < hashList.getLength(); i++) { @@ -437,14 +439,12 @@ public class RSerialize { } } } else { - env = RDataFactory.createNewEnv(enclosing, null); while (frame != RNull.instance) { RPairList pl = (RPairList) frame; env.safePut(((RSymbol) pl.getTag()).getName(), pl.car()); frame = pl.cdr(); } } - updateEnvReadRef(envRefTableIndex, env); if (locked != 0) { env.lock(false); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java index 1014afa96b..1c26f18688 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java @@ -437,15 +437,18 @@ public final class RDataFactory { } public static REnvironment createInternalEnv() { - return traceDataCreated(new REnvironment.NewEnv(null, RRuntime.createNonFunctionFrame().materialize(), REnvironment.UNNAMED, false, 0)); + return traceDataCreated(new REnvironment.NewEnv(null, RRuntime.createNonFunctionFrame().materialize(), REnvironment.UNNAMED)); } - public static REnvironment createNewEnv(REnvironment parent, String name) { - return traceDataCreated(new REnvironment.NewEnv(parent, RRuntime.createNonFunctionFrame().materialize(), name, false, 0)); + public static REnvironment.NewEnv createNewEnv(REnvironment parent, String name) { + return traceDataCreated(new REnvironment.NewEnv(parent, RRuntime.createNonFunctionFrame().materialize(), name)); } - public static REnvironment createNewEnv(REnvironment parent, String name, boolean hash, int size) { - return traceDataCreated(new REnvironment.NewEnv(parent, RRuntime.createNonFunctionFrame().materialize(), name, hash, size)); + public static REnvironment createNewEnv(REnvironment parent, String name, boolean hashed, int initialSize) { + REnvironment.NewEnv env = new REnvironment.NewEnv(parent, RRuntime.createNonFunctionFrame().materialize(), name); + env.setHashed(hashed); + env.setInitialSize(initialSize); + return traceDataCreated(env); } public static RS4Object createS4Object() { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java index db9575fff2..f6b6f3d4b9 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java @@ -487,7 +487,7 @@ public abstract class REnvironment extends RAttributeStorage implements RTypedVa /** * Add name to namespace registry. - * + * * @param name namespace name * @param env namespace value * @return {@code null} if name is already registered else {@code env} @@ -504,7 +504,7 @@ public abstract class REnvironment extends RAttributeStorage implements RTypedVa /** * Remove name from namespace registry. - * + * * @param name namespace name * @return {@code null} if name is not registered else namespace value */ @@ -641,7 +641,7 @@ public abstract class REnvironment extends RAttributeStorage implements RTypedVa */ @TruffleBoundary public static REnvironment createFromList(RAttributeProfiles attrProfiles, RList list, REnvironment parent) { - REnvironment result = RDataFactory.createNewEnv(parent, null, false, 0); + REnvironment result = RDataFactory.createNewEnv(parent, null); RStringVector names = list.getNames(attrProfiles); for (int i = 0; i < list.getLength(); i++) { try { @@ -980,13 +980,11 @@ public abstract class REnvironment extends RAttributeStorage implements RTypedVa * */ public static final class NewEnv extends REnvironment { - private final boolean hash; - private final int size; + private boolean hashed; + private int initialSize; - public NewEnv(REnvironment parent, MaterializedFrame frame, String name, boolean hash, int size) { + public NewEnv(REnvironment parent, MaterializedFrame frame, String name) { super(parent, UNNAMED, frame); - this.hash = hash; - this.size = size; if (parent != null) { RArguments.setEnclosingFrame(frame, parent.getFrame()); } @@ -995,14 +993,21 @@ public abstract class REnvironment extends RAttributeStorage implements RTypedVa } } - public boolean hashed() { - return hash; + public boolean isHashed() { + return hashed; } - public int createdSize() { - return size; + public void setHashed(boolean hashed) { + this.hashed = hashed; } + public int getInitialSize() { + return initialSize; + } + + public void setInitialSize(int initialSize) { + this.initialSize = initialSize; + } } /** -- GitLab