Skip to content

Commit 8d27b51

Browse files
committed
[GR-17610] Improve performance of native module imports.
PullRequest: graalpython/609
2 parents 6d81775 + 9e3f268 commit 8d27b51

File tree

12 files changed

+209
-32
lines changed

12 files changed

+209
-32
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ public enum PythonBuiltinClassType implements LazyPythonClass {
203203
this(name, null);
204204
}
205205

206+
@Override
206207
public String getName() {
207208
return name;
208209
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PythonCextBuiltins.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
import com.oracle.graal.python.nodes.attributes.HasInheritedAttributeNode;
142142
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
143143
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
144+
import com.oracle.graal.python.nodes.attributes.WriteAttributeToDynamicObjectNode;
144145
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
145146
import com.oracle.graal.python.nodes.call.InvokeNode;
146147
import com.oracle.graal.python.nodes.call.PythonCallNode;
@@ -590,25 +591,25 @@ Object op5(VirtualFrame frame, Object a, Object b, @SuppressWarnings("unused") i
590591

591592
@Builtin(name = "PyTruffle_SetAttr", minNumOfPositionalArgs = 3)
592593
@GenerateNodeFactory
593-
abstract static class PyObject_Setattr extends PythonBuiltinNode {
594+
abstract static class PyObject_Setattr extends PythonTernaryBuiltinNode {
594595
@Specialization
595-
@TruffleBoundary
596-
Object setattr(PythonBuiltinClass object, String key, Object value) {
597-
object.setAttributeUnsafe(key, value);
596+
Object doBuiltinClass(PythonBuiltinClass object, String key, Object value,
597+
@Exclusive @Cached("createForceType()") WriteAttributeToObjectNode writeAttrNode) {
598+
writeAttrNode.execute(object, key, value);
598599
return PNone.NONE;
599600
}
600601

601-
@Specialization(guards = {"!isPythonBuiltinClass(object)"})
602-
@TruffleBoundary
603-
Object setattr(PythonObject object, String key, Object value) {
604-
object.getStorage().define(key, value);
602+
@Specialization
603+
Object doNativeClass(PythonNativeClass object, String key, Object value,
604+
@Exclusive @Cached("createForceType()") WriteAttributeToObjectNode writeAttrNode) {
605+
writeAttrNode.execute(object, key, value);
605606
return PNone.NONE;
606607
}
607608

608-
@Specialization
609-
Object setattr(PythonNativeClass object, String key, Object value,
610-
@Cached("createForceType()") WriteAttributeToObjectNode writeAttrNode) {
611-
writeAttrNode.execute(object, key, value);
609+
@Specialization(guards = {"!isPythonBuiltinClass(object)"})
610+
Object doObject(PythonObject object, String key, Object value,
611+
@Exclusive @Cached WriteAttributeToDynamicObjectNode writeAttrToDynamicObjectNode) {
612+
writeAttrToDynamicObjectNode.execute(object.getStorage(), key, value);
612613
return PNone.NONE;
613614
}
614615
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/CExtNodes.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_PTR_COMPARE;
4646
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_PY_FLOAT_AS_DOUBLE;
4747
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_PY_TRUFFLE_BYTE_ARRAY_TO_NATIVE;
48-
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_PY_TRUFFLE_CSTR_TO_STRING;
4948
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_PY_TRUFFLE_STRING_TO_CSTR;
5049
import static com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols.FUN_WHCAR_SIZE;
5150
import static com.oracle.graal.python.nodes.SpecialMethodNames.__FLOAT__;
@@ -76,6 +75,7 @@
7675
import com.oracle.graal.python.builtins.objects.function.PKeyword;
7776
import com.oracle.graal.python.builtins.objects.ints.PInt;
7877
import com.oracle.graal.python.builtins.objects.module.PythonModule;
78+
import com.oracle.graal.python.builtins.objects.str.NativeCharSequence;
7979
import com.oracle.graal.python.builtins.objects.str.PString;
8080
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
8181
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
@@ -891,13 +891,12 @@ public static AsCharPointerNode getUncached() {
891891
// -----------------------------------------------------------------------------------------------------------------
892892
@GenerateUncached
893893
public abstract static class FromCharPointerNode extends CExtBaseNode {
894-
public abstract String execute(Object charPtr);
894+
public abstract Object execute(Object charPtr);
895895

896896
@Specialization
897-
public String execute(Object charPtr,
898-
@Cached PCallCapiFunction callCstrToStringNode) {
899-
900-
return (String) callCstrToStringNode.call(FUN_PY_TRUFFLE_CSTR_TO_STRING, charPtr);
897+
PString execute(Object charPtr,
898+
@Cached PythonObjectFactory factory) {
899+
return factory.createString(new NativeCharSequence(charPtr));
901900
}
902901
}
903902

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/PythonNativeClass.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ public interface PythonNativeClass extends PythonAbstractClass {
5353

5454
TruffleObject getPtr();
5555

56+
@Override
57+
default String getName() {
58+
return String.format("PythonNativeClass(%s)", getPtr());
59+
}
60+
5661
static boolean isInstance(Object object) {
5762
return object instanceof PythonAbstractNativeObject;
5863
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public String toString() {
118118
if (enclosingType == null) {
119119
return String.format("PBuiltinFunction %s at 0x%x", name, hashCode());
120120
} else {
121-
return String.format("PBuiltinFunction %s.%s at 0x%x", GetNameNode.doSlowPath(enclosingType), name, hashCode());
121+
return String.format("PBuiltinFunction %s.%s at 0x%x", enclosingType.getName(), name, hashCode());
122122
}
123123
}
124124

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/LazyString.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4949
import com.oracle.truffle.api.profiles.ConditionProfile;
5050

51-
public class LazyString implements CharSequence {
51+
public class LazyString implements PCharSequence {
5252

5353
protected static final int MinLazyStringLength;
5454
protected static final boolean UseLazyStrings;
@@ -157,22 +157,26 @@ public int length() {
157157

158158
@Override
159159
public String toString() {
160-
if (!isFlat()) {
161-
flatten();
160+
if (!isMaterialized()) {
161+
return materialize();
162162
}
163163
return (String) left;
164164
}
165165

166-
private boolean isFlat() {
166+
@Override
167+
public boolean isMaterialized() {
167168
return right == null;
168169
}
169170

171+
@Override
170172
@TruffleBoundary
171-
private void flatten() {
173+
public String materialize() {
172174
char[] dst = new char[len];
173-
flatten(this, 0, len, dst, 0);
174-
left = new String(dst);
175+
LazyString.flatten(this, 0, len, dst, 0);
176+
String flattened = new String(dst);
177+
left = flattened;
175178
right = null;
179+
return flattened;
176180
}
177181

178182
private static void flatten(CharSequence src, int srcBegin, int srcEnd, char[] dst, int dstBegin) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.builtins.objects.str;
42+
43+
import java.util.Objects;
44+
45+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.PCallCapiFunction;
46+
import com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols;
47+
import com.oracle.truffle.api.CompilerAsserts;
48+
49+
public class NativeCharSequence implements PCharSequence {
50+
51+
private final Object ptr;
52+
private String materialized;
53+
54+
public NativeCharSequence(Object ptr) {
55+
this.ptr = ptr;
56+
}
57+
58+
@Override
59+
public int length() {
60+
return materialize().length();
61+
}
62+
63+
@Override
64+
public char charAt(int index) {
65+
return materialize().charAt(index);
66+
}
67+
68+
@Override
69+
public CharSequence subSequence(int start, int end) {
70+
return materialize().subSequence(start, end);
71+
}
72+
73+
@Override
74+
public boolean isMaterialized() {
75+
return materialized != null;
76+
}
77+
78+
@Override
79+
public String materialize() {
80+
if (!isMaterialized()) {
81+
materialized = (String) PCallCapiFunction.getUncached().call(NativeCAPISymbols.FUN_PY_TRUFFLE_CSTR_TO_STRING, ptr);
82+
}
83+
return materialized;
84+
}
85+
86+
@Override
87+
public String toString() {
88+
CompilerAsserts.neverPartOfCompilation();
89+
if (isMaterialized()) {
90+
return materialized;
91+
}
92+
return Objects.toString(ptr);
93+
}
94+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.builtins.objects.str;
42+
43+
public interface PCharSequence extends CharSequence {
44+
45+
boolean isMaterialized();
46+
47+
String materialize();
48+
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/PString.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ public PString(LazyPythonClass clazz, CharSequence value) {
4444
}
4545

4646
public String getValue() {
47+
if (value instanceof PCharSequence) {
48+
PCharSequence s = (PCharSequence) value;
49+
if (!s.isMaterialized()) {
50+
return s.materialize();
51+
}
52+
return s.toString();
53+
}
4754
return value.toString();
4855
}
4956

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/LazyPythonClass.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,10 @@
4343
import com.oracle.truffle.api.interop.TruffleObject;
4444

4545
public interface LazyPythonClass extends TruffleObject {
46+
47+
/**
48+
* Returns the name of the class for debugging purposes. This method must assume that no context
49+
* is available.
50+
*/
51+
String getName();
4652
}

0 commit comments

Comments
 (0)