Skip to content

Commit adf6312

Browse files
committed
Explode loop when filling defaults.
1 parent 40fc4ea commit adf6312

File tree

1 file changed

+58
-13
lines changed

1 file changed

+58
-13
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/CreateArgumentsNode.java

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import com.oracle.graal.python.nodes.PNodeWithContext;
5757
import com.oracle.graal.python.nodes.argument.CreateArgumentsNodeGen.ApplyPositionalArgumentsNodeGen;
5858
import com.oracle.graal.python.nodes.argument.CreateArgumentsNodeGen.CreateAndCheckArgumentsNodeGen;
59+
import com.oracle.graal.python.nodes.argument.CreateArgumentsNodeGen.FillDefaultsNodeGen;
5960
import com.oracle.graal.python.nodes.argument.CreateArgumentsNodeGen.HandleTooManyArgumentsNodeGen;
6061
import com.oracle.graal.python.runtime.PythonOptions;
6162
import com.oracle.graal.python.runtime.exception.PException;
@@ -139,6 +140,7 @@ protected abstract static class CreateAndCheckArgumentsNode extends PNodeWithCon
139140
@Child private ApplyKeywordsNode applyKeywords;
140141
@Child private HandleTooManyArgumentsNode handleTooManyArgumentsNode;
141142
@Child private ApplyPositionalArguments applyPositional = ApplyPositionalArguments.create();
143+
@Child private FillDefaultsNode fillDefaultsNode;
142144

143145
public static CreateAndCheckArgumentsNode create() {
144146
return CreateAndCheckArgumentsNodeGen.create();
@@ -230,24 +232,15 @@ private Object[] createAndCheckArguments(PythonObject callable, Object[] args_w,
230232

231233
boolean more_filling = input_argcount < co_argcount + co_kwonlyargcount;
232234
if (more_filling) {
233-
int firstDefaultArgIdx = co_argcount - defaults.length;
234235

235-
int missingCnt = 0;
236236
String[] missingNames = new String[co_argcount + co_kwonlyargcount];
237237

238238
// then, fill the normal arguments with defaults_w (if needed)
239-
for (int i = input_argcount; i < co_argcount; i++) {
240-
if (PArguments.getArgument(scope_w, i) != null) {
241-
continue;
242-
}
243-
int defnum = i - firstDefaultArgIdx;
244-
if (defnum >= 0) {
245-
PArguments.setArgument(scope_w, i, defaults[defnum]);
246-
} else {
247-
missingNames[missingCnt++] = arity.getParameterIds()[i];
248-
}
239+
if (fillDefaultsNode == null) {
240+
CompilerDirectives.transferToInterpreterAndInvalidate();
241+
fillDefaultsNode = insert(FillDefaultsNode.create());
249242
}
250-
243+
int missingCnt = fillDefaultsNode.execute(arity, scope_w, defaults, input_argcount, co_argcount, missingNames);
251244
if (missingCnt > 0) {
252245
throw raise(PythonBuiltinClassType.TypeError, "%s() missing %d required positional argument%s: %s",
253246
getName(callable),
@@ -408,6 +401,58 @@ public static ApplyPositionalArguments create() {
408401
}
409402
}
410403

404+
protected abstract static class FillDefaultsNode extends Node {
405+
406+
public abstract int execute(Arity arity, Object[] scope_w, Object[] defaults, int input_argcount, int co_argcount, String[] missingNames);
407+
408+
@Specialization(guards = {"input_argcount == cachedInputArgcount", "co_argcount == cachedArgcount", "checkIterations(input_argcount, co_argcount)"})
409+
@ExplodeLoop
410+
int doCached(Arity arity, Object[] scope_w, Object[] defaults, @SuppressWarnings("unused") int input_argcount, @SuppressWarnings("unused") int co_argcount, String[] missingNames,
411+
@Cached("input_argcount") int cachedInputArgcount,
412+
@Cached("co_argcount") int cachedArgcount) {
413+
int firstDefaultArgIdx = cachedArgcount - defaults.length;
414+
int missingCnt = 0;
415+
for (int i = cachedInputArgcount; i < cachedArgcount; i++) {
416+
if (PArguments.getArgument(scope_w, i) != null) {
417+
continue;
418+
}
419+
int defnum = i - firstDefaultArgIdx;
420+
if (defnum >= 0) {
421+
PArguments.setArgument(scope_w, i, defaults[defnum]);
422+
} else {
423+
missingNames[missingCnt++] = arity.getParameterIds()[i];
424+
}
425+
}
426+
return missingCnt;
427+
}
428+
429+
@Specialization(replaces = "doCached")
430+
int doUncached(Arity arity, Object[] scope_w, Object[] defaults, int input_argcount, int co_argcount, String[] missingNames) {
431+
int firstDefaultArgIdx = co_argcount - defaults.length;
432+
int missingCnt = 0;
433+
for (int i = input_argcount; i < co_argcount; i++) {
434+
if (PArguments.getArgument(scope_w, i) != null) {
435+
continue;
436+
}
437+
int defnum = i - firstDefaultArgIdx;
438+
if (defnum >= 0) {
439+
PArguments.setArgument(scope_w, i, defaults[defnum]);
440+
} else {
441+
missingNames[missingCnt++] = arity.getParameterIds()[i];
442+
}
443+
}
444+
return missingCnt;
445+
}
446+
447+
protected static boolean checkIterations(int input_argcount, int co_argcount) {
448+
return co_argcount - input_argcount < 32;
449+
}
450+
451+
public static FillDefaultsNode create() {
452+
return FillDefaultsNodeGen.create();
453+
}
454+
}
455+
411456
protected static Arity getArity(Object callable) {
412457
return getProperty(callable, ArityGetter.INSTANCE);
413458
}

0 commit comments

Comments
 (0)