// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/platform/bindings/parkable_string.h"

#include <string>

#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/timer/elapsed_timer.h"
#include "base/trace_event/trace_event.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/bindings/parkable_string_manager.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/wtf/address_sanitizer.h"
#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/zlib/google/compression_utils.h"

namespace blink {

namespace {

void RecordParkingAction(ParkableStringImpl::ParkingAction action) {
  UMA_HISTOGRAM_ENUMERATION("Memory.MovableStringParkingAction", action);
}

void RecordStatistics(size_t size,
                      base::TimeDelta duration,
                      ParkableStringImpl::ParkingAction action) {
  size_t throughput_mb_s =
      static_cast<size_t>(size / duration.InSecondsF()) / 1000000;
  size_t size_kb = size / 1000;
  if (action == ParkableStringImpl::ParkingAction::kParkedInBackground) {
    UMA_HISTOGRAM_COUNTS_10000("Memory.ParkableString.Compression.SizeKb",
                               size_kb);
    // Size is at least 10kB, and at most ~1MB, and compression throughput
    // ranges from single-digit MB/s to ~40MB/s depending on the CPU, hence
    // the range.
    UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
        "Memory.ParkableString.Compression.Latency", duration,
        base::TimeDelta::FromMicroseconds(500), base::TimeDelta::FromSeconds(1),
        100);
    UMA_HISTOGRAM_COUNTS_1000(
        "Memory.ParkableString.Compression.ThroughputMBps", throughput_mb_s);
  } else {
    UMA_HISTOGRAM_COUNTS_10000("Memory.ParkableString.Decompression.SizeKb",
                               size_kb);
    UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
        "Memory.ParkableString.Decompression.Latency", duration,
        base::TimeDelta::FromMicroseconds(500), base::TimeDelta::FromSeconds(1),
        100);
    // Decompression speed can go up to >500MB/s.
    UMA_HISTOGRAM_COUNTS_1000(
        "Memory.ParkableString.Decompression.ThroughputMBps", throughput_mb_s);
  }
}

void AsanPoisonString(const String& string) {
#if defined(ADDRESS_SANITIZER)
  if (string.IsNull())
    return;
  // Since |string| is not deallocated, it remains in the per-thread
  // AtomicStringTable, where its content can be accessed for equality
  // comparison for instance, triggering a poisoned memory access.
  // See crbug.com/883344 for an example.
  if (string.Impl()->IsAtomic())
    return;

  ASAN_POISON_MEMORY_REGION(string.Bytes(), string.CharactersSizeInBytes());
#endif  // defined(ADDRESS_SANITIZER)
}

void AsanUnpoisonString(const String& string) {
#if defined(ADDRESS_SANITIZER)
  if (string.IsNull())
    return;

  ASAN_UNPOISON_MEMORY_REGION(string.Bytes(), string.CharactersSizeInBytes());
#endif  // defined(ADDRESS_SANITIZER)
}

}  // namespace

// Created and destroyed on the same thread, accessed on a background thread as
// well. |string|'s reference counting is *not* thread-safe, hence |string|'s
// reference count must *not* change on the background thread.
struct CompressionTaskParams final {
  CompressionTaskParams(
      scoped_refptr<ParkableStringImpl> string,
      const void* data,
      size_t size,
      scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner)
      : string(string),
        data(data),
        size(size),
        callback_task_runner(std::move(callback_task_runner)) {
    DCHECK(IsMainThread());
  }

  ~CompressionTaskParams() { DCHECK(IsMainThread()); }

  const scoped_refptr<ParkableStringImpl> string;
  const void* data;
  const size_t size;
  const scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner;

  CompressionTaskParams(CompressionTaskParams&&) = delete;
  DISALLOW_COPY_AND_ASSIGN(CompressionTaskParams);
};

// Valid transitions are:
// 1. kUnparked -> kParkingInProgress: Parking started asynchronously
// 2. kParkingInProgress -> kUnparked: Parking did not complete
// 3. kParkingInProgress -> kParked: Parking completed normally
// 4. kParked -> kUnparked: String has been unparked.
//
// See |Park()| for (1), |OnParkingCompleteOnMainThread()| for 2-3, and
// |Unpark()| for (4).
enum class ParkableStringImpl::State { kUnparked, kParkingInProgress, kParked };

ParkableStringImpl::ParkableStringImpl(scoped_refptr<StringImpl>&& impl,
                                       ParkableState parkable)
    : mutex_(),
      lock_depth_(0),
      state_(State::kUnparked),
      string_(std::move(impl)),
      compressed_(nullptr),
      may_be_parked_(parkable == ParkableState::kParkable),
      is_8bit_(string_.Is8Bit()),
      length_(string_.length())
#if DCHECK_IS_ON()
      ,
      owning_thread_(CurrentThread())
#endif
{
  DCHECK(!string_.IsNull());
}

ParkableStringImpl::~ParkableStringImpl() {
  AssertOnValidThread();
#if DCHECK_IS_ON()
  {
    MutexLocker locker(mutex_);
    DCHECK_EQ(0, lock_depth_);
  }
#endif
  AsanUnpoisonString(string_);
  DCHECK(state_ == State::kParked || state_ == State::kUnparked);

  if (may_be_parked_)
    ParkableStringManager::Instance().Remove(this, string_.Impl());
}

void ParkableStringImpl::Lock() {
  MutexLocker locker(mutex_);
  lock_depth_ += 1;
}

void ParkableStringImpl::Unlock() {
  MutexLocker locker(mutex_);
  DCHECK_GT(lock_depth_, 0);
  lock_depth_ -= 1;

#if defined(ADDRESS_SANITIZER) && DCHECK_IS_ON()
  // There are no external references to the data, nobody should touch the data.
  //
  // Note: Only poison the memory if this is on the owning thread, as this is
  // otherwise racy. Indeed |Unlock()| may be called on any thread, and
  // the owning thread may concurrently call |ToString()|. It is then allowed
  // to use the string until the end of the current owning thread task.
  // Requires DCHECK_IS_ON() for the |owning_thread_| check.
  //
  // Checking the owning thread first as CanParkNow() can only be called from
  // the owning thread.
  if (owning_thread_ == CurrentThread() && CanParkNow()) {
    AsanPoisonString(string_);
  }
#endif  // defined(ADDRESS_SANITIZER) && DCHECK_IS_ON()
}

void ParkableStringImpl::PurgeMemory() {
  AssertOnValidThread();
  if (state_ == State::kUnparked)
    compressed_ = nullptr;
}

const String& ParkableStringImpl::ToString() {
  AssertOnValidThread();
  MutexLocker locker(mutex_);
  AsanUnpoisonString(string_);

  Unpark();
  return string_;
}

unsigned ParkableStringImpl::CharactersSizeInBytes() const {
  AssertOnValidThread();
  return length_ * (is_8bit() ? sizeof(LChar) : sizeof(UChar));
}

bool ParkableStringImpl::Park(ParkingMode mode) {
  AssertOnValidThread();
  MutexLocker locker(mutex_);
  DCHECK(may_be_parked_);
  if (state_ == State::kUnparked && CanParkNow()) {
    // Parking can proceed synchronously.
    if (has_compressed_data()) {
      RecordParkingAction(ParkingAction::kParkedInBackground);
      state_ = State::kParked;
      ParkableStringManager::Instance().OnParked(this, string_.Impl());

      // Must unpoison the memory before releasing it.
      AsanUnpoisonString(string_);
      string_ = String();
    } else if (mode == ParkingMode::kAlways) {
      // |string_|'s data should not be touched except in the compression task.
      AsanPoisonString(string_);
      // |params| keeps |this| alive until |OnParkingCompleteOnMainThread()|.
      auto params = std::make_unique<CompressionTaskParams>(
          this, string_.Bytes(), string_.CharactersSizeInBytes(),
          Thread::Current()->GetTaskRunner());
      background_scheduler::PostOnBackgroundThread(
          FROM_HERE, CrossThreadBind(&ParkableStringImpl::CompressInBackground,
                                     WTF::Passed(std::move(params))));
      state_ = State::kParkingInProgress;
    }
  }

  return state_ == State::kParked || state_ == State::kParkingInProgress;
}

bool ParkableStringImpl::is_parked() const {
  return state_ == State::kParked;
}

bool ParkableStringImpl::CanParkNow() const {
  mutex_.AssertAcquired();
  // Can park iff:
  // - the string is eligible to parking
  // - There are no external reference to |string_|. Since |this| holds a
  //   reference to it, then we are the only one.
  // - |this| is not locked.
  return may_be_parked_ && string_.Impl()->HasOneRef() && lock_depth_ == 0;
}

void ParkableStringImpl::Unpark() {
  AssertOnValidThread();
  mutex_.AssertAcquired();
  if (state_ != State::kParked)
    return;

  TRACE_EVENT1("blink", "ParkableStringImpl::Unpark", "size",
               CharactersSizeInBytes());
  DCHECK(compressed_);
  base::ElapsedTimer timer;

  base::StringPiece compressed_string_piece(
      reinterpret_cast<const char*>(compressed_->data()),
      compressed_->size() * sizeof(uint8_t));
  String uncompressed;
  base::StringPiece uncompressed_string_piece;
  size_t size = CharactersSizeInBytes();
  if (is_8bit()) {
    LChar* data;
    uncompressed = String::CreateUninitialized(length(), data);
    uncompressed_string_piece =
        base::StringPiece(reinterpret_cast<const char*>(data), size);
  } else {
    UChar* data;
    uncompressed = String::CreateUninitialized(length(), data);
    uncompressed_string_piece =
        base::StringPiece(reinterpret_cast<const char*>(data), size);
  }

  // If decompression fails, this is either because:
  // 1. The output buffer is too small
  // 2. Compressed data is corrupted
  // 3. Cannot allocate memory in zlib
  //
  // (1-2) are data corruption, and (3) is OOM. In all cases, we cannot recover
  // the string we need, nothing else to do than to abort.
  CHECK(compression::GzipUncompress(compressed_string_piece,
                                    uncompressed_string_piece));
  string_ = uncompressed;
  state_ = State::kUnparked;
  ParkableStringManager::Instance().OnUnparked(this, string_.Impl());

  bool backgrounded =
      ParkableStringManager::Instance().IsRendererBackgrounded();
  auto action = backgrounded ? ParkingAction::kUnparkedInBackground
                             : ParkingAction::kUnparkedInForeground;
  RecordParkingAction(action);
  RecordStatistics(CharactersSizeInBytes(), timer.Elapsed(), action);
}

void ParkableStringImpl::OnParkingCompleteOnMainThread(
    std::unique_ptr<CompressionTaskParams> params,
    std::unique_ptr<Vector<uint8_t>> compressed) {
  MutexLocker locker(mutex_);
  DCHECK_EQ(State::kParkingInProgress, state_);
  // Between |Park()| and now, things may have happened:
  // 1. |ToString()| or
  // 2. |Lock()| may have been called.
  //
  // We only care about "surviving" calls, that is iff the string returned by
  // |ToString()| is still alive, or whether we are still locked. Since this
  // function is protected by the lock, no concurrent modifications can occur.
  //
  // Finally, since this is a distinct task from any one that can call
  // |ToString()|, the invariant that the pointer stays valid until the next
  // task is preserved.
  if (CanParkNow() && compressed) {
    RecordParkingAction(ParkingAction::kParkedInBackground);
    state_ = State::kParked;
    compressed_ = std::move(compressed);
    ParkableStringManager::Instance().OnParked(this, string_.Impl());

    // Must unpoison the memory before releasing it.
    AsanUnpoisonString(string_);
    string_ = String();
  } else {
    state_ = State::kUnparked;
  }
}

// static
void ParkableStringImpl::CompressInBackground(
    std::unique_ptr<CompressionTaskParams> params) {
  TRACE_EVENT1("blink", "ParkableStringImpl::CompressInBackground", "size",
               params->size);

  base::ElapsedTimer timer;
#if defined(ADDRESS_SANITIZER)
  // Lock the string to prevent a concurrent |Unlock()| on the main thread from
  // poisoning the string in the meantime.
  params->string->Lock();
#endif  // defined(ADDRESS_SANITIZER)
  // Compression touches the string.
  AsanUnpoisonString(params->string->string_);
  base::StringPiece data(reinterpret_cast<const char*>(params->data),
                         params->size);
  std::string compressed_string;
  bool ok = compression::GzipCompress(data, &compressed_string);

  std::unique_ptr<Vector<uint8_t>> compressed = nullptr;
  if (ok && compressed_string.size() < params->size) {
    compressed = std::make_unique<Vector<uint8_t>>();
    compressed->Append(
        reinterpret_cast<const uint8_t*>(compressed_string.c_str()),
        compressed_string.size());
  }
#if defined(ADDRESS_SANITIZER)
  params->string->Unlock();
#endif  // defined(ADDRESS_SANITIZER)

  auto* task_runner = params->callback_task_runner.get();
  size_t size = params->size;
  PostCrossThreadTask(
      *task_runner, FROM_HERE,
      CrossThreadBind(
          [](std::unique_ptr<CompressionTaskParams> params,
             std::unique_ptr<Vector<uint8_t>> compressed) {
            auto* string = params->string.get();
            string->OnParkingCompleteOnMainThread(std::move(params),
                                                  std::move(compressed));
          },
          WTF::Passed(std::move(params)), WTF::Passed(std::move(compressed))));
  RecordStatistics(size, timer.Elapsed(), ParkingAction::kParkedInBackground);
}

ParkableString::ParkableString(scoped_refptr<StringImpl>&& impl) {
  if (!impl) {
    impl_ = nullptr;
    return;
  }

  bool is_parkable = ParkableStringManager::ShouldPark(*impl);
  if (is_parkable) {
    impl_ = ParkableStringManager::Instance().Add(std::move(impl));
  } else {
    impl_ = base::MakeRefCounted<ParkableStringImpl>(
        std::move(impl), ParkableStringImpl::ParkableState::kNotParkable);
  }
}

ParkableString::~ParkableString() = default;

void ParkableString::Lock() const {
  if (impl_)
    impl_->Lock();
}

void ParkableString::Unlock() const {
  if (impl_)
    impl_->Unlock();
}

bool ParkableString::Is8Bit() const {
  return impl_->is_8bit();
}

String ParkableString::ToString() const {
  return impl_ ? impl_->ToString() : String();
}

wtf_size_t ParkableString::CharactersSizeInBytes() const {
  return impl_ ? impl_->CharactersSizeInBytes() : 0;
}

}  // namespace blink
