Changeset 180894 in webkit
- Timestamp:
- Mar 2, 2015 1:51:13 PM (9 years ago)
- Location:
- trunk/Source
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r180891 r180894 1 2015-03-02 Antti Koivisto <antti@apple.com> 2 3 Add way to dump cache meta data to file 4 https://bugs.webkit.org/show_bug.cgi?id=142183 5 6 Reviewed by Andreas Kling. 7 8 Export appendQuotedJSONStringToBuilder. 9 10 * bytecompiler/NodesCodegen.cpp: 11 (JSC::ObjectPatternNode::toString): 12 * runtime/JSONObject.cpp: 13 (JSC::appendQuotedJSONStringToBuilder): 14 (JSC::Stringifier::appendQuotedString): 15 (JSC::escapeStringToBuilder): Deleted. 16 * runtime/JSONObject.h: 17 1 18 2015-03-02 Joseph Pecoraro <pecoraro@apple.com> 2 19 -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r180875 r180894 2928 2928 builder.append('{'); 2929 2929 for (size_t i = 0; i < m_targetPatterns.size(); i++) { 2930 if (m_targetPatterns[i].wasString) { 2931 builder.append('"'); 2932 escapeStringToBuilder(builder, m_targetPatterns[i].propertyName.string()); 2933 builder.append('"'); 2934 } else 2930 if (m_targetPatterns[i].wasString) 2931 appendQuotedJSONStringToBuilder(builder, m_targetPatterns[i].propertyName.string()); 2932 else 2935 2933 builder.append(m_targetPatterns[i].propertyName.string()); 2936 2934 builder.append(':'); -
trunk/Source/JavaScriptCore/runtime/JSONObject.cpp
r179429 r180894 305 305 } 306 306 307 void escapeStringToBuilder(StringBuilder& builder, const String& message) 308 { 307 void appendQuotedJSONStringToBuilder(StringBuilder& builder, const String& message) 308 { 309 builder.append('"'); 310 309 311 if (message.is8Bit()) 310 312 appendStringToStringBuilder(builder, message.characters8(), message.length()); 311 313 else 312 314 appendStringToStringBuilder(builder, message.characters16(), message.length()); 315 316 builder.append('"'); 313 317 } 314 318 315 319 void Stringifier::appendQuotedString(StringBuilder& builder, const String& value) 316 320 { 317 int length = value.length(); 318 319 builder.append('"'); 320 321 if (value.is8Bit()) 322 appendStringToStringBuilder<LChar>(builder, value.characters8(), length); 323 else 324 appendStringToStringBuilder<UChar>(builder, value.characters16(), length); 325 326 builder.append('"'); 321 appendQuotedJSONStringToBuilder(builder, value); 327 322 } 328 323 -
trunk/Source/JavaScriptCore/runtime/JSONObject.h
r173269 r180894 63 63 JS_EXPORT_PRIVATE String JSONStringify(ExecState*, JSValue, unsigned indent); 64 64 65 void escapeStringToBuilder(StringBuilder&, const String&); 65 JS_EXPORT_PRIVATE void appendQuotedJSONStringToBuilder(StringBuilder&, const String&); 66 66 67 67 68 } // namespace JSC -
trunk/Source/WebKit2/ChangeLog
r180892 r180894 1 2015-03-02 Antti Koivisto <antti@apple.com> 2 3 Add way to dump cache meta data to file 4 https://bugs.webkit.org/show_bug.cgi?id=142183 5 6 Reviewed by Andreas Kling. 7 8 Dump goes to WebKitCache/dump.json. On OSX it can be triggered with 9 10 notifyutil -p com.apple.WebKit.Cache.dump 11 12 * NetworkProcess/cache/NetworkCache.cpp: 13 (WebKit::NetworkCache::initialize): 14 (WebKit::NetworkCache::dumpFilePath): 15 (WebKit::entryAsJSON): 16 (WebKit::NetworkCache::dumpContentsToFile): 17 (WebKit::NetworkCache::clear): 18 19 Also clear any dumps. 20 21 * NetworkProcess/cache/NetworkCache.h: 22 * NetworkProcess/cache/NetworkCacheStorage.h: 23 (WebKit::NetworkCacheStorage::baseDirectoryPath): 24 * NetworkProcess/cache/NetworkCacheStorageCocoa.mm: 25 (WebKit::fileNameForKey): 26 (WebKit::filePathForKey): 27 (WebKit::openFile): 28 (WebKit::openFileForKey): 29 (WebKit::decodeEntryHeader): 30 31 Separate header decoding. 32 33 (WebKit::decodeEntry): 34 (WebKit::NetworkCacheStorage::traverse): 35 36 Add asynchronous cache traversal inteface. 37 1 38 2015-03-02 Anders Carlsson <andersca@apple.com> 2 39 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp
r180456 r180894 35 35 #include "NetworkResourceLoader.h" 36 36 #include "WebCoreArgumentCoders.h" 37 #include <JavaScriptCore/JSONObject.h> 37 38 #include <WebCore/CacheValidation.h> 39 #include <WebCore/FileSystem.h> 38 40 #include <WebCore/HTTPHeaderNames.h> 39 41 #include <WebCore/ResourceResponse.h> … … 43 45 #include <wtf/text/StringBuilder.h> 44 46 47 #if PLATFORM(COCOA) 48 #include <notify.h> 49 #endif 50 45 51 namespace WebKit { 46 52 … … 57 63 if (enableEfficacyLogging) 58 64 m_statistics = NetworkCacheStatistics::open(cachePath); 65 66 #if PLATFORM(COCOA) 67 // Triggers with "notifyutil -p com.apple.WebKit.Cache.dump". 68 if (m_storage) { 69 int token; 70 notify_register_dispatch("com.apple.WebKit.Cache.dump", &token, dispatch_get_main_queue(), ^(int) { 71 dumpContentsToFile(); 72 }); 73 } 74 #endif 59 75 60 76 LOG(NetworkCache, "(NetworkProcess) opened cache storage, success %d", !!m_storage); … … 355 371 } 356 372 373 String NetworkCache::dumpFilePath() const 374 { 375 return WebCore::pathByAppendingComponent(m_storage->baseDirectoryPath(), "dump.json"); 376 } 377 378 static bool entryAsJSON(StringBuilder& json, const NetworkCacheKey& key, const NetworkCacheStorage::Entry& entry) 379 { 380 NetworkCacheDecoder decoder(entry.header.data(), entry.header.size()); 381 WebCore::ResourceResponse cachedResponse; 382 if (!decoder.decode(cachedResponse)) 383 return false; 384 json.append("{\n"); 385 json.append("\"hash\": "); 386 JSC::appendQuotedJSONStringToBuilder(json, key.hashAsString()); 387 json.append(",\n"); 388 json.append("\"partition\": "); 389 JSC::appendQuotedJSONStringToBuilder(json, key.partition()); 390 json.append(",\n"); 391 json.append("\"timestamp\": "); 392 json.appendNumber(entry.timeStamp.count()); 393 json.append(",\n"); 394 json.append("\"URL\": "); 395 JSC::appendQuotedJSONStringToBuilder(json, cachedResponse.url().string()); 396 json.append(",\n"); 397 json.append("\"headers\": {\n"); 398 bool firstHeader = true; 399 for (auto& header : cachedResponse.httpHeaderFields()) { 400 if (!firstHeader) 401 json.append(",\n"); 402 firstHeader = false; 403 json.append(" "); 404 JSC::appendQuotedJSONStringToBuilder(json, header.key); 405 json.append(": "); 406 JSC::appendQuotedJSONStringToBuilder(json, header.value); 407 } 408 json.append("\n}\n"); 409 json.append("}"); 410 return true; 411 } 412 413 void NetworkCache::dumpContentsToFile() 414 { 415 if (!m_storage) 416 return; 417 auto dumpFileHandle = WebCore::openFile(dumpFilePath(), WebCore::OpenForWrite); 418 if (!dumpFileHandle) 419 return; 420 WebCore::writeToFile(dumpFileHandle, "[\n", 2); 421 m_storage->traverse([dumpFileHandle](const NetworkCacheKey& key, const NetworkCacheStorage::Entry* entry) { 422 if (!entry) { 423 WebCore::writeToFile(dumpFileHandle, "{}\n]\n", 5); 424 auto handle = dumpFileHandle; 425 WebCore::closeFile(handle); 426 } 427 StringBuilder json; 428 if (!entryAsJSON(json, key, *entry)) 429 return; 430 json.append(",\n"); 431 auto writeData = json.toString().utf8(); 432 WebCore::writeToFile(dumpFileHandle, writeData.data(), writeData.length()); 433 }); 434 } 435 357 436 void NetworkCache::clear() 358 437 { 359 438 LOG(NetworkCache, "(NetworkProcess) clearing cache"); 360 if (m_storage) 439 if (m_storage) { 361 440 m_storage->clear(); 441 442 auto queue = WorkQueue::create("com.apple.WebKit.Cache.delete"); 443 StringCapture dumpFilePathCapture(dumpFilePath()); 444 queue->dispatch([dumpFilePathCapture] { 445 WebCore::deleteFile(dumpFilePathCapture.string()); 446 }); 447 } 362 448 if (m_statistics) 363 449 m_statistics->clear(); -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h
r180456 r180894 102 102 void clear(); 103 103 104 void dumpContentsToFile(); 105 104 106 String storagePath() const; 105 107 … … 107 109 NetworkCache() = default; 108 110 ~NetworkCache() = delete; 111 112 String dumpFilePath() const; 109 113 110 114 std::unique_ptr<NetworkCacheStorage> m_storage; -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h
r180008 r180894 149 149 void update(const NetworkCacheKey&, const Entry& updateEntry, const Entry& existingEntry, StoreCompletionHandler&&); 150 150 151 // Null entry signals end. 152 void traverse(std::function<void (const NetworkCacheKey&, const Entry*)>&&); 153 151 154 void setMaximumSize(size_t); 152 155 void clear(); … … 154 157 static const unsigned version = 2; 155 158 159 const String& baseDirectoryPath() const { return m_baseDirectoryPath; } 156 160 const String& directoryPath() const { return m_directoryPath; } 157 161 -
trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorageCocoa.mm
r180869 r180894 141 141 } 142 142 143 static String fileNameForKey(const NetworkCacheKey& key) 144 { 145 return key.hashAsString(); 146 } 147 143 148 static String filePathForKey(const NetworkCacheKey& key, const String& cachePath) 144 149 { 145 return WebCore::pathByAppendingComponent(directoryPathForKey(key, cachePath), key.hashAsString());150 return WebCore::pathByAppendingComponent(directoryPathForKey(key, cachePath), fileNameForKey(key)); 146 151 } 147 152 148 153 enum class FileOpenType { Read, Write, Create }; 149 static DispatchPtr<dispatch_io_t> openFile ForKey(const NetworkCacheKey& key, FileOpenType type, const String& cachePath, int& fd)154 static DispatchPtr<dispatch_io_t> openFile(const String& fileName, const String& directoryPath, FileOpenType type, int& fd) 150 155 { 151 156 int oflag; … … 156 161 oflag = O_RDWR | O_CREAT | O_TRUNC | O_NONBLOCK; 157 162 mode = S_IRUSR | S_IWUSR; 158 WebCore::makeAllDirectories(directoryPath ForKey(key, cachePath));163 WebCore::makeAllDirectories(directoryPath); 159 164 break; 160 165 case FileOpenType::Write: … … 167 172 } 168 173 169 CString path = WebCore::fileSystemRepresentation( filePathForKey(key, cachePath));174 CString path = WebCore::fileSystemRepresentation(WebCore::pathByAppendingComponent(directoryPath, fileName)); 170 175 fd = ::open(path.data(), oflag, mode); 171 176 … … 182 187 183 188 return channel; 189 } 190 191 static DispatchPtr<dispatch_io_t> openFileForKey(const NetworkCacheKey& key, FileOpenType type, const String& cachePath, int& fd) 192 { 193 return openFile(fileNameForKey(key), directoryPathForKey(key, cachePath), type, fd); 184 194 } 185 195 … … 251 261 } 252 262 263 static bool decodeEntryHeader(dispatch_data_t fileData, EntryMetaData& metaData, NetworkCacheStorage::Data& data) 264 { 265 if (!decodeEntryMetaData(metaData, fileData)) 266 return false; 267 if (metaData.cacheStorageVersion != NetworkCacheStorage::version) 268 return false; 269 if (metaData.headerOffset + metaData.headerSize > metaData.bodyOffset) 270 return false; 271 272 auto headerData = adoptDispatch(dispatch_data_create_subrange(fileData, metaData.headerOffset, metaData.headerSize)); 273 if (metaData.headerChecksum != hashData(headerData.get())) { 274 LOG(NetworkCacheStorage, "(NetworkProcess) header checksum mismatch"); 275 return false; 276 } 277 data = NetworkCacheStorage::Data { headerData }; 278 return true; 279 } 280 253 281 static std::unique_ptr<NetworkCacheStorage::Entry> decodeEntry(dispatch_data_t fileData, int fd, const NetworkCacheKey& key) 254 282 { 255 283 EntryMetaData metaData; 256 if (!decodeEntryMetaData(metaData, fileData)) 284 NetworkCacheStorage::Data headerData; 285 if (!decodeEntryHeader(fileData, metaData, headerData)) 257 286 return nullptr; 258 287 259 if (metaData.cacheStorageVersion != NetworkCacheStorage::version)260 return nullptr;261 288 if (metaData.key != key) 262 return nullptr;263 if (metaData.headerOffset + metaData.headerSize > metaData.bodyOffset)264 289 return nullptr; 265 290 if (metaData.bodyOffset + metaData.bodySize != dispatch_data_get_size(fileData)) 266 291 return nullptr; 267 268 auto headerData = adoptDispatch(dispatch_data_create_subrange(fileData, metaData.headerOffset, metaData.headerSize));269 if (metaData.headerChecksum != hashData(headerData.get())) {270 LOG(NetworkCacheStorage, "(NetworkProcess) header checksum mismatch");271 return nullptr;272 }273 292 274 293 auto bodyData = mapFile(fd, metaData.bodyOffset, metaData.bodySize); … … 285 304 return std::make_unique<NetworkCacheStorage::Entry>(NetworkCacheStorage::Entry { 286 305 metaData.timeStamp, 287 NetworkCacheStorage::Data { headerData },306 headerData, 288 307 NetworkCacheStorage::Data { bodyData, NetworkCacheStorage::Data::Backing::Map } 289 308 }); … … 472 491 } 473 492 493 void NetworkCacheStorage::traverse(std::function<void (const NetworkCacheKey&, const Entry*)>&& traverseHandler) 494 { 495 StringCapture cachePathCapture(m_directoryPath); 496 dispatch_async(m_ioQueue.get(), [this, cachePathCapture, traverseHandler] { 497 String cachePath = cachePathCapture.string(); 498 auto semaphore = adoptDispatch(dispatch_semaphore_create(0)); 499 traverseCacheFiles(cachePath, [this, &semaphore, &traverseHandler](const String& fileName, const String& partitionPath) { 500 int fd; 501 auto channel = openFile(fileName, partitionPath, FileOpenType::Read, fd); 502 const size_t headerReadSize = 16 << 10; 503 dispatch_io_read(channel.get(), 0, headerReadSize, dispatch_get_main_queue(), [this, fd, &semaphore, &traverseHandler](bool done, dispatch_data_t fileData, int) { 504 EntryMetaData metaData; 505 NetworkCacheStorage::Data headerData; 506 if (decodeEntryHeader(fileData, metaData, headerData)) { 507 Entry entry { metaData.timeStamp, headerData, Data() }; 508 traverseHandler(metaData.key, &entry); 509 } 510 if (done) 511 dispatch_semaphore_signal(semaphore.get()); 512 }); 513 dispatch_semaphore_wait(semaphore.get(), DISPATCH_TIME_FOREVER); 514 }); 515 dispatch_async(dispatch_get_main_queue(), [this, traverseHandler] { 516 traverseHandler({ }, nullptr); 517 }); 518 }); 519 } 520 474 521 void NetworkCacheStorage::dispatchPendingWriteOperations() 475 522 {
Note: See TracChangeset
for help on using the changeset viewer.