/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "immune_spaces.h"

#include "gc/space/space-inl.h"
#include "mirror/object.h"
#include "oat_file.h"

namespace art {
namespace gc {
namespace collector {

void ImmuneSpaces::Reset() {
  spaces_.clear();
  largest_immune_region_.Reset();
}

void ImmuneSpaces::CreateLargestImmuneRegion() {
  uintptr_t best_begin = 0u;
  uintptr_t best_end = 0u;
  uintptr_t cur_begin = 0u;
  uintptr_t cur_end = 0u;
  // TODO: If the last space is an image space, we may include its oat file in the immune region.
  // This could potentially hide heap corruption bugs if there is invalid pointers that point into
  // the boot oat code
  for (space::ContinuousSpace* space : GetSpaces()) {
    uintptr_t space_begin = reinterpret_cast<uintptr_t>(space->Begin());
    uintptr_t space_end = reinterpret_cast<uintptr_t>(space->Limit());
    if (space->IsImageSpace()) {
      // For the boot image, the boot oat file is always directly after. For app images it may not
      // be if the app image was mapped at a random address.
      space::ImageSpace* image_space = space->AsImageSpace();
      // Update the end to include the other non-heap sections.
      space_end = RoundUp(reinterpret_cast<uintptr_t>(image_space->GetImageEnd()), kPageSize);
      // For the app image case, GetOatFileBegin is where the oat file was mapped during image
      // creation, the actual oat file could be somewhere else.
      const OatFile* const image_oat_file = image_space->GetOatFile();
      if (image_oat_file != nullptr) {
        uintptr_t oat_begin = reinterpret_cast<uintptr_t>(image_oat_file->Begin());
        uintptr_t oat_end = reinterpret_cast<uintptr_t>(image_oat_file->End());
        if (space_end == oat_begin) {
          DCHECK_GE(oat_end, oat_begin);
          space_end = oat_end;
        }
      }
    }
    if (cur_begin == 0u) {
      cur_begin = space_begin;
      cur_end = space_end;
    } else if (cur_end == space_begin) {
      // Extend current region.
      cur_end = space_end;
    } else {
      // Reset.
      cur_begin = 0;
      cur_end = 0;
    }
    if (cur_end - cur_begin > best_end - best_begin) {
      // Improvement, update the best range.
      best_begin = cur_begin;
      best_end = cur_end;
    }
  }
  largest_immune_region_.SetBegin(reinterpret_cast<mirror::Object*>(best_begin));
  largest_immune_region_.SetEnd(reinterpret_cast<mirror::Object*>(best_end));
  VLOG(collector) << "Immune region " << largest_immune_region_.Begin() << "-"
                  << largest_immune_region_.End();
}

void ImmuneSpaces::AddSpace(space::ContinuousSpace* space) {
  DCHECK(spaces_.find(space) == spaces_.end()) << *space;
  // Bind live to mark bitmap if necessary.
  if (space->GetLiveBitmap() != space->GetMarkBitmap()) {
    CHECK(space->IsContinuousMemMapAllocSpace());
    space->AsContinuousMemMapAllocSpace()->BindLiveToMarkBitmap();
  }
  spaces_.insert(space);
  CreateLargestImmuneRegion();
}

bool ImmuneSpaces::CompareByBegin::operator()(space::ContinuousSpace* a, space::ContinuousSpace* b)
    const {
  return a->Begin() < b->Begin();
}

bool ImmuneSpaces::ContainsSpace(space::ContinuousSpace* space) const {
  return spaces_.find(space) != spaces_.end();
}

}  // namespace collector
}  // namespace gc
}  // namespace art
