Skip to content

Commit f53d667

Browse files
committed
[GR-14471] function builtins - improve access performance for argument defaults and keyword defaults
PullRequest: graalpython/439
2 parents 212dc6f + fea8b70 commit f53d667

File tree

10 files changed

+293
-283
lines changed

10 files changed

+293
-283
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@
4646
import com.oracle.graal.python.builtins.objects.code.PCode;
4747
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
4848
import com.oracle.graal.python.builtins.objects.dict.PDict;
49-
import com.oracle.graal.python.builtins.objects.function.FunctionBuiltinsFactory.GetFunctionDefaultsNodeFactory;
50-
import com.oracle.graal.python.builtins.objects.function.FunctionBuiltinsFactory.GetFunctionKeywordDefaultsNodeFactory;
5149
import com.oracle.graal.python.builtins.objects.method.PMethod;
5250
import com.oracle.graal.python.builtins.objects.str.PString;
5351
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
5452
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
5553
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
56-
import com.oracle.graal.python.nodes.code.GetFunctionCodeNode;
54+
import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetFunctionCodeNode;
55+
import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetFunctionDefaultsNode;
56+
import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetFunctionKeywordDefaultsNode;
5757
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
5858
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
5959
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
@@ -139,12 +139,13 @@ Object setName(@SuppressWarnings("unused") Object self, @SuppressWarnings("unuse
139139

140140
@Builtin(name = __DEFAULTS__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
141141
@GenerateNodeFactory
142-
public abstract static class GetFunctionDefaultsNode extends PythonBinaryBuiltinNode {
142+
public abstract static class GetDefaultsNode extends PythonBinaryBuiltinNode {
143143
@Specialization(guards = "isNoValue(defaults)")
144-
Object defaults(PFunction self, @SuppressWarnings("unused") PNone defaults) {
145-
Object[] d = self.getDefaults();
146-
assert d != null;
147-
return (d.length == 0) ? PNone.NONE : factory().createTuple(d);
144+
Object defaults(PFunction self, @SuppressWarnings("unused") PNone defaults,
145+
@Cached("create()") GetFunctionDefaultsNode getFunctionDefaultsNode) {
146+
Object[] argDefaults = getFunctionDefaultsNode.execute(self);
147+
assert argDefaults != null;
148+
return (argDefaults.length == 0) ? PNone.NONE : factory().createTuple(argDefaults);
148149
}
149150

150151
@Specialization
@@ -158,23 +159,16 @@ Object setDefaults(PFunction self, @SuppressWarnings("unused") PNone defaults) {
158159
self.setDefaults(new Object[0]);
159160
return PNone.NONE;
160161
}
161-
162-
public static GetFunctionDefaultsNode create() {
163-
return GetFunctionDefaultsNodeFactory.create();
164-
}
165162
}
166163

167164
@Builtin(name = __KWDEFAULTS__, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true)
168165
@GenerateNodeFactory
169-
public abstract static class GetFunctionKeywordDefaultsNode extends PythonBinaryBuiltinNode {
166+
public abstract static class GetKeywordDefaultsNode extends PythonBinaryBuiltinNode {
170167
@Specialization(guards = "isNoValue(arg)")
171-
Object get(PFunction self, @SuppressWarnings("unused") PNone arg) {
172-
PKeyword[] kwdefaults = self.getKwDefaults();
173-
if (kwdefaults.length > 0) {
174-
return factory().createDict(kwdefaults);
175-
} else {
176-
return PNone.NONE;
177-
}
168+
Object get(PFunction self, @SuppressWarnings("unused") PNone arg,
169+
@Cached("create()") GetFunctionKeywordDefaultsNode getFunctionKeywordDefaultsNode) {
170+
PKeyword[] kwdefaults = getFunctionKeywordDefaultsNode.execute(self);
171+
return (kwdefaults.length > 0) ? factory().createDict(kwdefaults) : PNone.NONE;
178172
}
179173

180174
@Specialization(guards = "!isNoValue(arg)")
@@ -197,10 +191,6 @@ Object set(PFunction self, PDict arg) {
197191
self.setKwDefaults(keywords.toArray(new PKeyword[keywords.size()]));
198192
return PNone.NONE;
199193
}
200-
201-
public static GetFunctionKeywordDefaultsNode create() {
202-
return GetFunctionKeywordDefaultsNodeFactory.create();
203-
}
204194
}
205195

206196
@Builtin(name = __REDUCE__, minNumOfPositionalArgs = 1)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import com.oracle.graal.python.nodes.generator.GeneratorFunctionRootNode;
3838
import com.oracle.truffle.api.Assumption;
3939
import com.oracle.truffle.api.CompilerAsserts;
40-
import com.oracle.truffle.api.CompilerDirectives;
4140
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
4241
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4342
import com.oracle.truffle.api.RootCallTarget;
@@ -57,9 +56,7 @@ public class PFunction extends PythonObject {
5756
private final boolean isStatic;
5857
@CompilationFinal private PCode code;
5958
@CompilationFinal(dimensions = 1) private Object[] defaultValues;
60-
private Object[] uncachedDefaultValues;
6159
@CompilationFinal(dimensions = 1) private PKeyword[] kwDefaultValues;
62-
private PKeyword[] uncachedKwDefaultValues;
6360

6461
public PFunction(LazyPythonClass clazz, String name, String enclosingClassName, RootCallTarget callTarget, PythonObject globals, PCell[] closure) {
6562
this(clazz, name, enclosingClassName, callTarget, globals, EMPTY_DEFAULTS, PKeyword.EMPTY_KEYWORDS, closure);
@@ -73,8 +70,8 @@ public PFunction(LazyPythonClass clazz, String name, String enclosingClassName,
7370
this.isStatic = name.equals(SpecialMethodNames.__NEW__);
7471
this.enclosingClassName = enclosingClassName;
7572
this.globals = globals;
76-
this.defaultValues = this.uncachedDefaultValues = defaultValues == null ? EMPTY_DEFAULTS : defaultValues;
77-
this.kwDefaultValues = this.uncachedKwDefaultValues = kwDefaultValues == null ? PKeyword.EMPTY_KEYWORDS : kwDefaultValues;
73+
this.defaultValues = defaultValues == null ? EMPTY_DEFAULTS : defaultValues;
74+
this.kwDefaultValues = kwDefaultValues == null ? PKeyword.EMPTY_KEYWORDS : kwDefaultValues;
7875
this.closure = closure;
7976
addDefaultConstants(this.getStorage(), name, enclosingClassName);
8077
}
@@ -157,41 +154,21 @@ public String getEnclosingClassName() {
157154
}
158155

159156
public Object[] getDefaults() {
160-
Assumption assumption = this.defaultsStableAssumption;
161-
if (CompilerDirectives.isCompilationConstant(this) && CompilerDirectives.isCompilationConstant(assumption)) {
162-
if (assumption.isValid()) {
163-
return defaultValues;
164-
}
165-
}
166-
return uncachedDefaultValues;
167-
}
168-
169-
public Object[] getUncachedDefaultValues() {
170-
return uncachedDefaultValues;
157+
return defaultValues;
171158
}
172159

173160
public void setDefaults(Object[] defaults) {
174161
this.defaultsStableAssumption.invalidate("defaults changed for function " + getName());
175-
this.defaultValues = this.uncachedDefaultValues = defaults;
162+
this.defaultValues = defaults;
176163
}
177164

178165
public PKeyword[] getKwDefaults() {
179-
Assumption assumption = this.defaultsStableAssumption;
180-
if (CompilerDirectives.isCompilationConstant(this) && CompilerDirectives.isCompilationConstant(assumption)) {
181-
if (assumption.isValid()) {
182-
return kwDefaultValues;
183-
}
184-
}
185-
return uncachedKwDefaultValues;
186-
}
187-
188-
public PKeyword[] getUncachedKwDefaults() {
189-
return uncachedKwDefaultValues;
166+
return kwDefaultValues;
190167
}
191168

192169
public void setKwDefaults(PKeyword[] defaults) {
193170
this.defaultsStableAssumption.invalidate("kw defaults changed for function " + getName());
194-
this.kwDefaultValues = this.uncachedKwDefaultValues = defaults;
171+
this.kwDefaultValues = defaults;
195172
}
196173

197174
@TruffleBoundary

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodBuiltins.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@
4242
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4343
import com.oracle.graal.python.builtins.PythonBuiltins;
4444
import com.oracle.graal.python.builtins.objects.PNone;
45-
import com.oracle.graal.python.builtins.objects.function.FunctionBuiltins;
45+
import com.oracle.graal.python.builtins.objects.function.PKeyword;
4646
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
4747
import com.oracle.graal.python.nodes.SpecialAttributeNames;
4848
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
49+
import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetDefaultsNode;
50+
import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetKeywordDefaultsNode;
4951
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
5052
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
5153
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
@@ -113,18 +115,21 @@ protected static GetAttributeNode createGetAttributeNode() {
113115
public abstract static class GetMethodDefaultsNode extends PythonUnaryBuiltinNode {
114116
@Specialization
115117
Object defaults(PMethod self,
116-
@Cached("create()") FunctionBuiltins.GetFunctionDefaultsNode getFunctionDefaultsNode) {
117-
return getFunctionDefaultsNode.execute(self.getFunction(), PNone.NO_VALUE);
118+
@Cached("create()") GetDefaultsNode getDefaultsNode) {
119+
Object[] argDefaults = getDefaultsNode.execute(self);
120+
assert argDefaults != null;
121+
return (argDefaults.length == 0) ? PNone.NONE : factory().createTuple(argDefaults);
118122
}
119123
}
120124

121125
@Builtin(name = __KWDEFAULTS__, minNumOfPositionalArgs = 1, isGetter = true)
122126
@GenerateNodeFactory
123127
public abstract static class GetMethodKwdefaultsNode extends PythonUnaryBuiltinNode {
124128
@Specialization
125-
Object defaults(PMethod self,
126-
@Cached("create()") FunctionBuiltins.GetFunctionKeywordDefaultsNode getFunctionKwdefaultsNode) {
127-
return getFunctionKwdefaultsNode.execute(self.getFunction(), PNone.NO_VALUE);
129+
Object kwDefaults(PMethod self,
130+
@Cached("create()") GetKeywordDefaultsNode getKeywordDefaultsNode) {
131+
PKeyword[] kwdefaults = getKeywordDefaultsNode.execute(self);
132+
return (kwdefaults.length > 0) ? factory().createDict(kwdefaults) : PNone.NONE;
128133
}
129134
}
130135

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ public abstract class PGuards {
8989
* Specialization guards.
9090
*/
9191

92+
public static boolean isSameObject(Object left, Object right) {
93+
return left == right;
94+
}
95+
9296
public static boolean isEmpty(Object[] array) {
9397
return array.length == 0;
9498
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PNodeWithContext.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
4747
import com.oracle.graal.python.builtins.objects.exception.PBaseException;
4848
import com.oracle.graal.python.builtins.objects.function.PKeyword;
49-
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
5049
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
50+
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
5151
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
5252
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
5353
import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode;
@@ -64,7 +64,6 @@
6464
import com.oracle.truffle.api.TruffleLanguage.ContextReference;
6565
import com.oracle.truffle.api.frame.VirtualFrame;
6666
import com.oracle.truffle.api.nodes.Node;
67-
import com.oracle.truffle.api.nodes.RootNode;
6867
import com.oracle.truffle.api.profiles.ConditionProfile;
6968

7069
public abstract class PNodeWithContext extends Node {
@@ -175,16 +174,6 @@ public final PythonContext getContext() {
175174

176175
protected Assumption singleContextAssumption() {
177176
CompilerAsserts.neverPartOfCompilation("the singleContextAssumption should only be retrieved in the interpreter");
178-
PythonLanguage language = null;
179-
RootNode rootNode = getRootNode();
180-
if (rootNode != null) {
181-
language = rootNode.getLanguage(PythonLanguage.class);
182-
} else {
183-
throw new IllegalStateException("a python node was executed without being adopted!");
184-
}
185-
if (language == null) {
186-
language = PythonLanguage.getCurrent();
187-
}
188-
return language.singleContextAssumption;
177+
return PythonLanguage.getCurrent().singleContextAssumption;
189178
}
190179
}

0 commit comments

Comments
 (0)