OLD | NEW |
---|---|
(Empty) | |
1 //===---- llvm/Bitcode/Reader/BitcodeStream.cpp - ----*- C++ -*-===// | |
nlewycky
2011/11/05 00:45:06
Missing description, needs to be exactly 80 column
(google.com) Derek Schuff
2011/11/07 17:59:35
Done.
| |
2 // | |
3 // The LLVM Compiler Infrastructure | |
4 // | |
5 // This file is distributed under the University of Illinois Open Source | |
6 // License. See LICENSE.TXT for details. | |
7 // | |
8 //===----------------------------------------------------------------------===// | |
9 // | |
10 // Support for streaming (lazy reading) of bitcode files on disk | |
nlewycky
2011/11/05 00:45:06
Full sentence.
(google.com) Derek Schuff
2011/11/07 17:59:35
Done.
| |
11 // | |
12 //===----------------------------------------------------------------------===// | |
13 | |
14 #define DEBUG_TYPE "bitcode-stream" | |
15 #include "llvm/ADT/Statistic.h" | |
16 #include "llvm/Bitcode/BitcodeStream.h" | |
17 #include "llvm/Support/MemoryBuffer.h" | |
18 #include "llvm/Support/system_error.h" | |
19 #include <string> | |
20 #include <cerrno> | |
21 #include <cstdio> | |
22 #if !defined(_MSC_VER) && !defined(__MINGW32__) | |
23 #include <unistd.h> | |
24 #else | |
25 #include <io.h> | |
26 #endif | |
27 #include <fcntl.h> | |
28 using namespace llvm; | |
29 | |
30 // Goals: | |
31 // * BitstreamVector doesn't care about complexities like using | |
32 // threads/async callbacks to overlap download+compile | |
33 // * Don't want to duplicate bitcode | |
34 // * Don't need to know total bitcode len in advance | |
35 | |
36 // BSV already has random access so this interface is only for in-order | |
37 // streaming (no arbitrary seeking, else we'd have to buffer all the bitcode | |
38 // here in addition to BSV). this also means that if we want the option | |
39 // to free bitcode, BSV/BitcodeReader will implement it. | |
40 | |
41 STATISTIC(NumStreamFetches, "Number of calls to bitcode stream fetch"); | |
42 | |
43 namespace { | |
44 | |
45 const static error_code success; | |
46 // Very simple stream backed by a file. Mostly useful for stdin; | |
47 // actual file access is probably still best done with mmap | |
48 class BitcodeFileStreamer : public BitcodeStreamer { | |
49 int Fd; | |
50 public: | |
51 BitcodeFileStreamer() : Fd(0) {} | |
52 virtual ~BitcodeFileStreamer() { | |
53 close(Fd); | |
54 } | |
55 virtual size_t GetBytes(unsigned char *buf, size_t len) { | |
56 NumStreamFetches++; | |
57 return read(Fd, buf, len); | |
58 } | |
59 | |
60 error_code OpenFile(const std::string &Filename) { | |
61 int OpenFlags = O_RDONLY; | |
62 #ifdef O_BINARY | |
nlewycky
2011/11/05 00:45:06
Sorry, code which does this sort of platform-speci
(google.com) Derek Schuff
2011/11/07 17:59:35
Actually in that case, probably this whole file sh
| |
63 OpenFlags |= O_BINARY; // Open input file in binary mode on win32. | |
64 #endif | |
65 if (Filename == "-") | |
66 Fd = 0; | |
67 else | |
68 Fd = ::open(Filename.c_str(), OpenFlags); | |
69 if (Fd == -1) return error_code(errno, posix_category()); | |
70 return success; | |
71 } | |
72 }; | |
73 | |
74 // Streams backed by memory. not used right now because it means the bitcode | |
75 // is duplicated (one copy on the backing store here, and one in BSV) | |
76 class MemoryStreamer : public BitcodeStreamer { | |
77 const char* Start; | |
78 const char* End; | |
79 const char* Cur; | |
80 public: | |
81 MemoryStreamer(const char* start, size_t len) : Start(start), | |
82 End(start + len), Cur(start) {} | |
83 virtual size_t GetBytes(unsigned char *buf, size_t len) { | |
84 size_t CopyLen = std::min(len, static_cast<size_t>(End - Cur)); | |
85 memcpy(buf, Cur, CopyLen); | |
86 Cur += CopyLen; | |
87 return CopyLen; | |
88 } | |
89 }; | |
90 | |
91 class MemoryBufferStreamer : public MemoryStreamer { | |
92 MemoryBuffer *Buffer; | |
93 bool IsBufferOwned; | |
94 public: | |
95 MemoryBufferStreamer(MemoryBuffer *Buf) : | |
96 MemoryStreamer(Buffer->getBufferStart(), Buffer->getBufferSize()), | |
97 Buffer(Buf), IsBufferOwned(false) { } | |
98 void setBufferOwned(bool owned) { IsBufferOwned = owned; } | |
99 ~MemoryBufferStreamer() { | |
100 if (IsBufferOwned) delete Buffer; | |
101 } | |
102 }; | |
103 | |
104 } | |
105 | |
106 namespace llvm { | |
107 BitcodeStreamer* getBitcodeFileStreamer(const std::string &Filename, | |
108 std::string *StrError) { | |
109 BitcodeFileStreamer* s = new BitcodeFileStreamer(); | |
110 error_code e = s->OpenFile(Filename); | |
111 if (e != success) { | |
112 *StrError = std::string() + "Could not open " + Filename + ": " | |
113 + e.message() + "\n"; | |
114 return NULL; | |
115 } | |
116 return s; | |
117 } | |
118 | |
119 BitcodeStreamer* getBitcodeMemoryStreamer(const char *Start, size_t Len) { | |
120 if (!Start) return NULL; | |
121 return new MemoryStreamer(Start, Len); | |
122 } | |
123 } | |
OLD | NEW |