OLD | NEW |
1 //=- ThreadedStreamingCache.cpp - Cache for StreamingMemoryObject -*- C++ -*-=// | 1 //=- ThreadedStreamingCache.cpp - Cache for StreamingMemoryObject -*- C++ -*-=// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 | 9 |
10 #include "ThreadedStreamingCache.h" | 10 #include "ThreadedStreamingCache.h" |
11 #include "llvm/Support/Compiler.h" | 11 #include "llvm/Support/Compiler.h" |
12 #include "llvm/Support/Mutex.h" | 12 #include "llvm/Support/Mutex.h" |
13 #include <cstring> | 13 #include <cstring> |
14 | 14 |
15 using llvm::sys::ScopedLock; | 15 using llvm::sys::ScopedLock; |
16 | 16 |
17 ThreadedStreamingCache::ThreadedStreamingCache( | 17 ThreadedStreamingCache::ThreadedStreamingCache( |
18 llvm::StreamingMemoryObject *S) : Streamer(S), | 18 llvm::StreamingMemoryObject *S) : Streamer(S), |
19 Cache(kCacheSize), | 19 Cache(kCacheSize), |
20 MinObjectSize(0), | 20 MinObjectSize(0), |
21 CacheBase(-1) { | 21 CacheBase(-1) { |
22 LLVM_STATIC_ASSERT((kCacheSize & (kCacheSize - 1)) == 0, | 22 LLVM_STATIC_ASSERT((kCacheSize & (kCacheSize - 1)) == 0, |
23 "kCacheSize must be a power of 2") | 23 "kCacheSize must be a power of 2") |
24 } | 24 } |
25 | 25 |
26 int ThreadedStreamingCache::fetchCacheLine(uint64_t address) const { | 26 int ThreadedStreamingCache::fetchCacheLine(uint64_t address) const { |
27 uint64_t Base = address & kCacheSizeMask; | 27 uint64_t Base = address & kCacheSizeMask; |
28 uint64_t Copied; | |
29 int Ret; | 28 int Ret; |
30 ScopedLock L(StreamerLock); | 29 ScopedLock L(StreamerLock); |
31 if (Streamer->isValidAddress(Base + kCacheSize - 1)) { | 30 if (Streamer->isValidAddress(Base + kCacheSize - 1)) { |
32 Ret = Streamer->readBytes(Base, kCacheSize, &Cache[0], &Copied); | 31 Ret = Streamer->readBytes(Base, kCacheSize, &Cache[0]); |
33 assert(Copied == kCacheSize); | |
34 assert(Ret == 0); | 32 assert(Ret == 0); |
35 MinObjectSize = Base + kCacheSize; | 33 MinObjectSize = Base + kCacheSize; |
36 } else { | 34 } else { |
37 uint64_t End = Streamer->getExtent(); | 35 uint64_t End = Streamer->getExtent(); |
38 assert(End > address && End <= Base + kCacheSize); | 36 assert(End > address && End <= Base + kCacheSize); |
39 Ret = Streamer->readBytes(Base, End - Base, &Cache[0], &Copied); | 37 Ret = Streamer->readBytes(Base, End - Base, &Cache[0]); |
40 assert(Copied == End - Base); | |
41 assert(Ret == 0); | 38 assert(Ret == 0); |
42 MinObjectSize = End; | 39 MinObjectSize = End; |
43 } | 40 } |
44 CacheBase = Base; | 41 CacheBase = Base; |
45 return Ret; | 42 return Ret; |
46 } | 43 } |
47 | 44 |
48 int ThreadedStreamingCache::readByte( | 45 int ThreadedStreamingCache::readByte( |
49 uint64_t address, uint8_t* ptr) const { | 46 uint64_t address, uint8_t* ptr) const { |
50 if (address < CacheBase || address >= CacheBase + kCacheSize) { | 47 if (address < CacheBase || address >= CacheBase + kCacheSize) { |
51 if(fetchCacheLine(address)) | 48 if(fetchCacheLine(address)) |
52 return -1; | 49 return -1; |
53 } | 50 } |
54 *ptr = Cache[address - CacheBase]; | 51 *ptr = Cache[address - CacheBase]; |
55 return 0; | 52 return 0; |
56 } | 53 } |
57 | 54 |
58 int ThreadedStreamingCache::readBytes( | 55 int ThreadedStreamingCache::readBytes( |
59 uint64_t address, uint64_t size, uint8_t* buf, uint64_t* copied) const { | 56 uint64_t address, uint64_t size, uint8_t* buf) const { |
60 // To keep the cache fetch simple, we currently require that no request cross | 57 // To keep the cache fetch simple, we currently require that no request cross |
61 // the cache line. This isn't a problem for the bitcode reader because it only | 58 // the cache line. This isn't a problem for the bitcode reader because it only |
62 // fetches a byte or a word at a time. | 59 // fetches a byte or a word at a time. |
63 if (address < CacheBase || (address + size) > CacheBase + kCacheSize) { | 60 if (address < CacheBase || (address + size) > CacheBase + kCacheSize) { |
64 if ((address & kCacheSizeMask) != ((address + size - 1) & kCacheSizeMask)) | 61 if ((address & kCacheSizeMask) != ((address + size - 1) & kCacheSizeMask)) |
65 llvm::report_fatal_error("readBytes request spans cache lines"); | 62 llvm::report_fatal_error("readBytes request spans cache lines"); |
66 if(fetchCacheLine(address)) | 63 if(fetchCacheLine(address)) |
67 return -1; | 64 return -1; |
68 } | 65 } |
69 if (copied) *copied = size; | |
70 memcpy(buf, &Cache[address - CacheBase], size); | 66 memcpy(buf, &Cache[address - CacheBase], size); |
71 return 0; | 67 return 0; |
72 } | 68 } |
73 | 69 |
74 uint64_t ThreadedStreamingCache::getExtent() const { | 70 uint64_t ThreadedStreamingCache::getExtent() const { |
75 llvm::report_fatal_error( | 71 llvm::report_fatal_error( |
76 "getExtent should not be called for pnacl streaming bitcode"); | 72 "getExtent should not be called for pnacl streaming bitcode"); |
77 return 0; | 73 return 0; |
78 } | 74 } |
79 | 75 |
(...skipping 25 matching lines...) Expand all Loading... |
105 | 101 |
106 void ThreadedStreamingCache::setKnownObjectSize(size_t size) { | 102 void ThreadedStreamingCache::setKnownObjectSize(size_t size) { |
107 MinObjectSize = size; | 103 MinObjectSize = size; |
108 ScopedLock L(StreamerLock); | 104 ScopedLock L(StreamerLock); |
109 Streamer->setKnownObjectSize(size); | 105 Streamer->setKnownObjectSize(size); |
110 } | 106 } |
111 | 107 |
112 const uint64_t ThreadedStreamingCache::kCacheSize; | 108 const uint64_t ThreadedStreamingCache::kCacheSize; |
113 const uint64_t ThreadedStreamingCache::kCacheSizeMask; | 109 const uint64_t ThreadedStreamingCache::kCacheSizeMask; |
114 llvm::sys::SmartMutex<false> ThreadedStreamingCache::StreamerLock; | 110 llvm::sys::SmartMutex<false> ThreadedStreamingCache::StreamerLock; |
OLD | NEW |