Mercurial > hg > truffle
changeset 22318:a016a0239ad9
Optimize argument access for foreign access functions.
author | Christian Humer <christian.humer@oracle.com> |
---|---|
date | Tue, 20 Oct 2015 18:21:19 +0200 |
parents | 7005216255fa |
children | d0c672a6e632 |
files | truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CachedObjectAccessNode.java truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccessArguments.java truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/GenericObjectAccessNode.java |
diffstat | 3 files changed, 36 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CachedObjectAccessNode.java Tue Oct 20 18:21:19 2015 +0200 +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/CachedObjectAccessNode.java Tue Oct 20 18:21:19 2015 +0200 @@ -32,6 +32,8 @@ @Child private ObjectAccessNode next; private final ForeignAccess languageCheck; + @Child private ForeignAccessArguments accessArguments = new ForeignAccessArguments(); + protected CachedObjectAccessNode(DirectCallNode callTarget, ObjectAccessNode next, ForeignAccess languageCheck) { this.callTarget = callTarget; this.next = next; @@ -50,7 +52,7 @@ private Object doAccess(VirtualFrame frame, TruffleObject receiver, Object[] arguments) { if (languageCheck.canHandle(receiver)) { - return callTarget.call(frame, ForeignAccessArguments.create(receiver, arguments)); + return callTarget.call(frame, accessArguments.executeCreate(receiver, arguments)); } else { return doNext(frame, receiver, arguments); }
--- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccessArguments.java Tue Oct 20 18:21:19 2015 +0200 +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccessArguments.java Tue Oct 20 18:21:19 2015 +0200 @@ -24,19 +24,41 @@ */ package com.oracle.truffle.api.interop; -final class ForeignAccessArguments { +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.nodes.Node; + +final class ForeignAccessArguments extends Node { + static final Object[] EMPTY_ARGUMENTS_ARRAY = new Object[0]; static final int RECEIVER_INDEX = 0; static final int RUNTIME_ARGUMENT_COUNT = 1; - static Object[] create(Object receiver, Object... arguments) { - if (arguments.length == 0) { - return new Object[]{receiver}; + @CompilationFinal private int previousLength = -2; + + public Object[] executeCreate(Object receiver, Object... arguments) { + int length = profileLength(arguments.length); + Object[] objectArguments = new Object[RUNTIME_ARGUMENT_COUNT + length]; + objectArguments[RECEIVER_INDEX] = receiver; + arraycopy(arguments, 0, objectArguments, RUNTIME_ARGUMENT_COUNT, length); + return objectArguments; + } + + private int profileLength(int length) { + int returnLength = length; + if (previousLength != -1) { + if (previousLength == length) { + returnLength = previousLength; + } else { + CompilerDirectives.transferToInterpreterAndInvalidate(); + if (previousLength == -2) { + previousLength = length; + } else { + previousLength = -1; + } + } } - Object[] objectArguments = new Object[RUNTIME_ARGUMENT_COUNT + arguments.length]; - objectArguments[RECEIVER_INDEX] = receiver; - arraycopy(arguments, 0, objectArguments, RUNTIME_ARGUMENT_COUNT, arguments.length); - return objectArguments; + return returnLength; } private static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) {
--- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/GenericObjectAccessNode.java Tue Oct 20 18:21:19 2015 +0200 +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/GenericObjectAccessNode.java Tue Oct 20 18:21:19 2015 +0200 @@ -34,6 +34,8 @@ private final Message access; @Child private IndirectCallNode indirectCallNode; + @Child private ForeignAccessArguments accessArguments = new ForeignAccessArguments(); + public GenericObjectAccessNode(Message access) { this.access = access; indirectCallNode = Truffle.getRuntime().createIndirectCallNode(); @@ -50,7 +52,7 @@ if (ct == null) { throw messageNotRecognizedException(fa); } - return indirectCallNode.call(frame, ct, ForeignAccessArguments.create(truffleObject, arguments)); + return indirectCallNode.call(frame, ct, accessArguments.executeCreate(truffleObject, arguments)); } @CompilerDirectives.TruffleBoundary