Esempio n. 1
0
// NOTE: this will not find a new entry until it has been written to disk!
// Consumer should take ownership of the resulting buffer.
nsresult
StartupCache::GetBuffer(const char* id, char** outbuf, uint32_t* length) 
{
  NS_ASSERTION(NS_IsMainThread(), "Startup cache only available on main thread");
  WaitOnWriteThread();
  if (!mStartupWriteInitiated) {
    CacheEntry* entry; 
    nsDependentCString idStr(id);
    mTable.Get(idStr, &entry);
    if (entry) {
      *outbuf = new char[entry->size];
      memcpy(*outbuf, entry->data, entry->size);
      *length = entry->size;
      return NS_OK;
    }
  }

  nsresult rv = GetBufferFromZipArchive(mArchive, true, id, outbuf, length);
  if (NS_SUCCEEDED(rv))
    return rv;

  nsRefPtr<nsZipArchive> omnijar = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP);
  // no need to checksum omnijarred entries
  rv = GetBufferFromZipArchive(omnijar, false, id, outbuf, length);
  if (NS_SUCCEEDED(rv))
    return rv;

  omnijar = mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
  // no need to checksum omnijarred entries
  return GetBufferFromZipArchive(omnijar, false, id, outbuf, length);
}
Esempio n. 2
0
// Makes a copy of the buffer, client retains ownership of inbuf.
nsresult
StartupCache::PutBuffer(const char* id, const char* inbuf, uint32_t len) 
{
  NS_ASSERTION(NS_IsMainThread(), "Startup cache only available on main thread");
  WaitOnWriteThread();
  if (StartupCache::gShutdownInitiated) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  nsAutoArrayPtr<char> data(new char[len]);
  memcpy(data, inbuf, len);

  nsDependentCString idStr(id);
  // Cache it for now, we'll write all together later.
  CacheEntry* entry; 
  
#ifdef DEBUG
  mTable.Get(idStr, &entry);
  NS_ASSERTION(entry == nullptr, "Existing entry in StartupCache.");
  
  if (mArchive) {
    nsZipItem* zipItem = mArchive->GetItem(id);
    NS_ASSERTION(zipItem == nullptr, "Existing entry in disk StartupCache.");
  }
#endif
  
  entry = new CacheEntry(data.forget(), len);
  mTable.Put(idStr, entry);
  return ResetStartupWriteTimer();
}
Esempio n. 3
0
// Makes a copy of the buffer, client retains ownership of inbuf.
nsresult
StartupCache::PutBuffer(const char* id, const char* inbuf, uint32_t len) 
{
  NS_ASSERTION(NS_IsMainThread(), "Startup cache only available on main thread");
  WaitOnWriteThread();
  if (StartupCache::gShutdownInitiated) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  auto data = MakeUnique<char[]>(len);
  memcpy(data.get(), inbuf, len);

  nsCString idStr(id);
  // Cache it for now, we'll write all together later.
  CacheEntry* entry; 
  
  if (mTable.Get(idStr)) {
    NS_ASSERTION(false, "Existing entry in StartupCache.");
    // Double-caching is undesirable but not an error.
    return NS_OK;
  }

#ifdef DEBUG
  if (mArchive) {
    nsZipItem* zipItem = mArchive->GetItem(id);
    NS_ASSERTION(zipItem == nullptr, "Existing entry in disk StartupCache.");
  }
#endif

  entry = new CacheEntry(Move(data), len);
  mTable.Put(idStr, entry);
  mPendingWrites.AppendElement(idStr);
  return ResetStartupWriteTimer();
}
Esempio n. 4
0
// NOTE: this will not find a new entry until it has been written to disk!
// Consumer should take ownership of the resulting buffer.
nsresult
StartupCache::GetBuffer(const char* id, UniquePtr<char[]>* outbuf, uint32_t* length) 
{
  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::OTHER);

  NS_ASSERTION(NS_IsMainThread(), "Startup cache only available on main thread");

  WaitOnWriteThread();
  if (!mStartupWriteInitiated) {
    CacheEntry* entry; 
    nsDependentCString idStr(id);
    mTable.Get(idStr, &entry);
    if (entry) {
      *outbuf = MakeUnique<char[]>(entry->size);
      memcpy(outbuf->get(), entry->data.get(), entry->size);
      *length = entry->size;
      return NS_OK;
    }
  }

  nsresult rv = GetBufferFromZipArchive(mArchive, true, id, outbuf, length);
  if (NS_SUCCEEDED(rv))
    return rv;

  RefPtr<nsZipArchive> omnijar = mozilla::Omnijar::GetReader(mozilla::Omnijar::APP);
  // no need to checksum omnijarred entries
  rv = GetBufferFromZipArchive(omnijar, false, id, outbuf, length);
  if (NS_SUCCEEDED(rv))
    return rv;

  omnijar = mozilla::Omnijar::GetReader(mozilla::Omnijar::GRE);
  // no need to checksum omnijarred entries
  return GetBufferFromZipArchive(omnijar, false, id, outbuf, length);
}
StartupCache::~StartupCache() 
{
  if (mTimer) {
    mTimer->Cancel();
  }

  // Generally, the in-memory table should be empty here,
  // but an early shutdown means either mTimer didn't run 
  // or the write thread is still running.
  WaitOnWriteThread();

  // If we shutdown quickly timer wont have fired. Instead of writing
  // it on the main thread and block the shutdown we simply wont update
  // the startup cache. Always do this if the file doesn't exist since
  // we use it part of the packge step.
  if (!mArchive) {
    WriteToDisk();
  }

  gStartupCache = nullptr;
  (void)::NS_UnregisterMemoryReporter(mMappingMemoryReporter);
  (void)::NS_UnregisterMemoryReporter(mDataMemoryReporter);
  mMappingMemoryReporter = nullptr;
  mDataMemoryReporter = nullptr;
}
Esempio n. 6
0
void
StartupCache::InvalidateCache() 
{
  WaitOnWriteThread();
  mTable.Clear();
  mArchive = NULL;
  mFile->Remove(false);
  LoadArchive(gPostFlushAgeAction);
}
Esempio n. 7
0
void
StartupCache::InvalidateCache() 
{
  WaitOnWriteThread();
  mTable.Clear();
  mArchive = NULL;
  nsresult rv = mFile->Remove(false);
  if (NS_FAILED(rv) && rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST &&
      rv != NS_ERROR_FILE_NOT_FOUND) {
    gIgnoreDiskCache = true;
    return;
  }
  gIgnoreDiskCache = false;
  LoadArchive(gPostFlushAgeAction);
}
Esempio n. 8
0
void
StartupCache::InvalidateCache() 
{
  WaitOnWriteThread();
  mTable.Clear();
  mArchive = nullptr;
  nsresult rv = mFile->Remove(false);
  if (NS_FAILED(rv) && rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST &&
      rv != NS_ERROR_FILE_NOT_FOUND) {
    gIgnoreDiskCache = true;
    mozilla::Telemetry::Accumulate(Telemetry::STARTUP_CACHE_INVALID, true);
    return;
  }
  gIgnoreDiskCache = false;
  LoadArchive(gPostFlushAgeAction);
}
Esempio n. 9
0
StartupCache::~StartupCache() 
{
  if (mTimer) {
    mTimer->Cancel();
  }

  // Generally, the in-memory table should be empty here,
  // but an early shutdown means either mTimer didn't run 
  // or the write thread is still running.
  WaitOnWriteThread();
  WriteToDisk();
  gStartupCache = nullptr;
  (void)::NS_UnregisterMemoryReporter(mMappingMemoryReporter);
  (void)::NS_UnregisterMemoryReporter(mDataMemoryReporter);
  mMappingMemoryReporter = nullptr;
  mDataMemoryReporter = nullptr;
}
Esempio n. 10
0
bool
StartupCache::StartupWriteComplete()
{
  WaitOnWriteThread();
  return mStartupWriteInitiated && mTable.Count() == 0;
}