Skip to content

Commit a6f11f1

Browse files
committed
profile the channel class for file access
1 parent e64e4a3 commit a6f11f1

File tree

2 files changed

+76
-52
lines changed

2 files changed

+76
-52
lines changed

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

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -294,18 +294,19 @@ Object fstatStd(@SuppressWarnings("unused") int fd) {
294294
@Specialization(guards = "fd > 2")
295295
@TruffleBoundary
296296
Object fstat(int fd,
297-
@Cached("create()") BranchProfile fstatForNonFile) {
297+
@Cached("create()") BranchProfile fstatForNonFile,
298+
@Cached("createClassProfile()") ValueProfile channelClassProfile) {
298299
PosixResources resources = getResources();
299300
String filePath = resources.getFilePath(fd);
300301
if (filePath != null) {
301302
if (statNode == null) {
302303
CompilerDirectives.transferToInterpreterAndInvalidate();
303304
statNode = insert(StatNode.create());
304305
}
305-
return statNode.executeWith(getResources().getFilePath(fd), PNone.NO_VALUE);
306+
return statNode.executeWith(resources.getFilePath(fd), PNone.NO_VALUE);
306307
} else {
307308
fstatForNonFile.enter();
308-
Channel fileChannel = resources.getFileChannel(fd);
309+
Channel fileChannel = resources.getFileChannel(fd, channelClassProfile);
309310
int mode = 0;
310311
if (fileChannel instanceof ReadableByteChannel) {
311312
mode |= 0444;
@@ -623,8 +624,9 @@ Object open(String pathname, int flags, int fileMode, @SuppressWarnings("unused"
623624
public abstract static class LseekNode extends PythonFileNode {
624625
@Specialization
625626
@TruffleBoundary
626-
Object lseek(int fd, long pos, int how) {
627-
Channel channel = getResources().getFileChannel(fd);
627+
Object lseek(int fd, long pos, int how,
628+
@Cached("createClassProfile()") ValueProfile channelClassProfile) {
629+
Channel channel = getResources().getFileChannel(fd, channelClassProfile);
628630
if (channel == null || !(channel instanceof SeekableByteChannel)) {
629631
throw raise(OSError, "Illegal seek");
630632
}
@@ -653,12 +655,14 @@ Object lseek(int fd, long pos, int how) {
653655
public abstract static class CloseNode extends PythonFileNode {
654656
@Specialization
655657
@TruffleBoundary
656-
Object close(int fd) {
657-
Channel channel = getResources().getFileChannel(fd);
658+
Object close(int fd,
659+
@Cached("createClassProfile()") ValueProfile channelClassProfile) {
660+
PosixResources resources = getResources();
661+
Channel channel = resources.getFileChannel(fd, channelClassProfile);
658662
if (channel == null) {
659663
throw raise(OSError, "invalid fd");
660664
} else {
661-
getResources().close(fd);
665+
resources.close(fd);
662666
try {
663667
channel.close();
664668
} catch (IOException e) {
@@ -726,8 +730,9 @@ public abstract static class WriteNode extends PythonFileNode {
726730

727731
@Specialization
728732
@TruffleBoundary
729-
Object write(int fd, byte[] data) {
730-
Channel channel = getResources().getFileChannel(fd);
733+
Object write(int fd, byte[] data,
734+
@Cached("createClassProfile()") ValueProfile channelClassProfile) {
735+
Channel channel = getResources().getFileChannel(fd, channelClassProfile);
731736
if (channel instanceof WritableByteChannel) {
732737
try {
733738
return ((WritableByteChannel) channel).write(ByteBuffer.wrap(data));
@@ -741,20 +746,23 @@ Object write(int fd, byte[] data) {
741746

742747
@Specialization
743748
@TruffleBoundary
744-
Object write(int fd, String data) {
745-
return write(fd, data.getBytes());
749+
Object write(int fd, String data,
750+
@Cached("createClassProfile()") ValueProfile channelClassProfile) {
751+
return write(fd, data.getBytes(), channelClassProfile);
746752
}
747753

748754
@Specialization
749755
@TruffleBoundary
750-
Object write(int fd, PBytes data) {
751-
return write(fd, getByteArray(data));
756+
Object write(int fd, PBytes data,
757+
@Cached("createClassProfile()") ValueProfile channelClassProfile) {
758+
return write(fd, getByteArray(data), channelClassProfile);
752759
}
753760

754761
@Specialization
755762
@TruffleBoundary
756-
Object write(int fd, PByteArray data) {
757-
return write(fd, getByteArray(data));
763+
Object write(int fd, PByteArray data,
764+
@Cached("createClassProfile()") ValueProfile channelClassProfile) {
765+
return write(fd, getByteArray(data), channelClassProfile);
758766
}
759767

760768
@Specialization
@@ -782,8 +790,9 @@ public static WriteNode create() {
782790
@TypeSystemReference(PythonArithmeticTypes.class)
783791
public abstract static class ReadNode extends PythonFileNode {
784792
@Specialization(guards = "readOpaque(frame)")
785-
Object readOpaque(@SuppressWarnings("unused") VirtualFrame frame, int fd, @SuppressWarnings("unused") Object requestedSize) {
786-
Channel channel = getResources().getFileChannel(fd);
793+
Object readOpaque(@SuppressWarnings("unused") VirtualFrame frame, int fd, @SuppressWarnings("unused") Object requestedSize,
794+
@Cached("createClassProfile()") ValueProfile channelClassProfile) {
795+
Channel channel = getResources().getFileChannel(fd, channelClassProfile);
787796
try {
788797
return new OpaqueBytes(doRead(channel, Integer.MAX_VALUE));
789798
} catch (IOException e) {
@@ -792,8 +801,9 @@ Object readOpaque(@SuppressWarnings("unused") VirtualFrame frame, int fd, @Suppr
792801
}
793802

794803
@Specialization(guards = "!readOpaque(frame)")
795-
Object read(@SuppressWarnings("unused") VirtualFrame frame, int fd, long requestedSize) {
796-
Channel channel = getResources().getFileChannel(fd);
804+
Object read(@SuppressWarnings("unused") VirtualFrame frame, int fd, long requestedSize,
805+
@Cached("createClassProfile()") ValueProfile channelClassProfile) {
806+
Channel channel = getResources().getFileChannel(fd, channelClassProfile);
797807
try {
798808
byte[] array = doRead(channel, (int) requestedSize);
799809
return factory().createBytes(array);
@@ -1171,18 +1181,19 @@ Object rename(Object src, Object dst, @SuppressWarnings("unused") Object[] args,
11711181

11721182
Object effectiveSrc = src;
11731183
Object effectiveDst = dst;
1184+
PosixResources resources = getResources();
11741185
for (int i = 0; i < kwargs.length; i++) {
11751186
Object value = kwargs[i].getValue();
11761187
if ("src_dir_fd".equals(kwargs[i].getName())) {
11771188
if (!(value instanceof Integer)) {
11781189
throw raise(OSError, "invalid file descriptor provided");
11791190
}
1180-
effectiveSrc = getResources().getFilePath((int) value);
1191+
effectiveSrc = resources.getFilePath((int) value);
11811192
} else if ("dst_dir_fd".equals(kwargs[i].getName())) {
11821193
if (!(value instanceof Integer)) {
11831194
throw raise(OSError, "invalid file descriptor provided");
11841195
}
1185-
effectiveDst = getResources().getFilePath((int) value);
1196+
effectiveDst = resources.getFilePath((int) value);
11861197
}
11871198
}
11881199
return rename(convertSrcNode.execute(effectiveSrc), convertDstNode.execute(effectiveDst));

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PosixResources.java

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@
4848
import java.util.Collections;
4949
import java.util.List;
5050

51-
import com.oracle.truffle.api.TruffleFile;
5251
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
52+
import com.oracle.truffle.api.TruffleFile;
5353
import com.oracle.truffle.api.TruffleLanguage.Env;
54+
import com.oracle.truffle.api.profiles.ValueProfile;
5455

5556
/**
5657
* This class manages the set of file descriptors and child PIDs of a context. File descriptors are
@@ -83,52 +84,60 @@ public PosixResources() {
8384
files.add(null);
8485
}
8586

86-
@TruffleBoundary
87-
public Channel getFileChannel(int fd) {
87+
@TruffleBoundary(allowInlining = true)
88+
public Channel getFileChannel(int fd, ValueProfile classProfile) {
89+
if (files.size() > fd) {
90+
return classProfile.profile(files.get(fd));
91+
}
92+
return null;
93+
}
94+
95+
@TruffleBoundary(allowInlining = true)
96+
private Channel getFileChannel(int fd) {
8897
if (files.size() > fd) {
8998
return files.get(fd);
9099
}
91100
return null;
92101
}
93102

94-
@TruffleBoundary
103+
@TruffleBoundary(allowInlining = true)
95104
public String getFilePath(int fd) {
96105
if (filePaths.size() > fd) {
97106
return filePaths.get(fd);
98107
}
99108
return null;
100109
}
101110

102-
@TruffleBoundary
111+
@TruffleBoundary(allowInlining = true)
103112
public void close(int fd) {
104113
if (filePaths.size() > fd) {
105114
files.set(fd, null);
106115
filePaths.set(fd, null);
107116
}
108117
}
109118

110-
@TruffleBoundary
119+
@TruffleBoundary(allowInlining = true)
111120
public void fdopen(int fd, Channel fc) {
112121
files.set(fd, fc);
113122
}
114123

115-
@TruffleBoundary
124+
@TruffleBoundary(allowInlining = true)
116125
public int open(TruffleFile path, Channel fc) {
117126
int fd = nextFreeFd();
118127
files.set(fd, fc);
119128
filePaths.set(fd, path.getAbsoluteFile().getPath());
120129
return fd;
121130
}
122131

123-
@TruffleBoundary
132+
@TruffleBoundary(allowInlining = true)
124133
public int dup(int fd) {
125134
int dupFd = nextFreeFd();
126135
files.set(dupFd, getFileChannel(fd));
127136
filePaths.set(dupFd, getFilePath(fd));
128137
return dupFd;
129138
}
130139

131-
@TruffleBoundary
140+
@TruffleBoundary(allowInlining = true)
132141
public int[] pipe() throws IOException {
133142
Pipe pipe = Pipe.open();
134143
int read = nextFreeFd();
@@ -138,47 +147,51 @@ public int[] pipe() throws IOException {
138147
return new int[]{read, write};
139148
}
140149

141-
@TruffleBoundary
142-
synchronized private int nextFreeFd() {
143-
for (int i = 0; i < filePaths.size(); i++) {
144-
String openPath = filePaths.get(i);
145-
Channel openChannel = files.get(i);
146-
if (openPath == null && openChannel == null) {
147-
return i;
150+
@TruffleBoundary(allowInlining = true)
151+
private int nextFreeFd() {
152+
synchronized (filePaths) {
153+
for (int i = 0; i < filePaths.size(); i++) {
154+
String openPath = filePaths.get(i);
155+
Channel openChannel = files.get(i);
156+
if (openPath == null && openChannel == null) {
157+
return i;
158+
}
148159
}
160+
files.add(null);
161+
filePaths.add(null);
162+
return filePaths.size() - 1;
149163
}
150-
files.add(null);
151-
filePaths.add(null);
152-
return filePaths.size() - 1;
153164
}
154165

155-
@TruffleBoundary
166+
@TruffleBoundary(allowInlining = true)
156167
public void setEnv(Env env) {
157168
files.set(0, Channels.newChannel(env.in()));
158169
files.set(1, Channels.newChannel(env.out()));
159170
files.set(2, Channels.newChannel(env.err()));
160171
}
161172

162-
@TruffleBoundary
173+
@TruffleBoundary(allowInlining = true)
163174
public int registerChild(Process child) {
164175
int pid = nextFreePid();
165176
children.set(pid, child);
166177
return pid;
167178
}
168179

169-
@TruffleBoundary
170-
synchronized private int nextFreePid() {
171-
for (int i = 0; i < children.size(); i++) {
172-
Process openPath = children.get(i);
173-
if (openPath == null) {
174-
return i;
180+
@TruffleBoundary(allowInlining = true)
181+
private int nextFreePid() {
182+
synchronized (children) {
183+
for (int i = 0; i < children.size(); i++) {
184+
Process openPath = children.get(i);
185+
if (openPath == null) {
186+
return i;
187+
}
175188
}
189+
children.add(null);
190+
return children.size() - 1;
176191
}
177-
children.add(null);
178-
return children.size() - 1;
179192
}
180193

181-
@TruffleBoundary
194+
@TruffleBoundary(allowInlining = true)
182195
public int waitpid(int pid) throws ArrayIndexOutOfBoundsException, InterruptedException {
183196
Process process = children.get(pid);
184197
int exitStatus = process.waitFor();

0 commit comments

Comments
 (0)