/*
 * Copyright (C) 2009 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 "indirect_reference_table.h"
#include "jni_internal.h"
#include "reference_table.h"
#include "runtime.h"
#include "thread.h"
#include "utils.h"

#include <cstdlib>

namespace art {

static void AbortMaybe() {
  // If -Xcheck:jni is on, it'll give a more detailed error before aborting.
  if (!Runtime::Current()->GetJavaVM()->check_jni) {
    // Otherwise, we want to abort rather than hand back a bad reference.
    LOG(FATAL) << "JNI ERROR (app bug): see above.";
  }
}

IndirectReferenceTable::IndirectReferenceTable(size_t initialCount,
    size_t maxCount, IndirectRefKind desiredKind)
{
  CHECK_GT(initialCount, 0U);
  CHECK_LE(initialCount, maxCount);
  CHECK_NE(desiredKind, kSirtOrInvalid);

  table_ = reinterpret_cast<const Object**>(malloc(initialCount * sizeof(const Object*)));
  CHECK(table_ != NULL);
#ifndef NDEBUG
  memset(table_, 0xd1, initialCount * sizeof(const Object*));
#endif

  slot_data_ = reinterpret_cast<IndirectRefSlot*>(calloc(initialCount, sizeof(IndirectRefSlot)));
  CHECK(slot_data_ != NULL);

  segment_state_.all = IRT_FIRST_SEGMENT;
  alloc_entries_ = initialCount;
  max_entries_ = maxCount;
  kind_ = desiredKind;
}

IndirectReferenceTable::~IndirectReferenceTable() {
  free(table_);
  free(slot_data_);
  table_ = NULL;
  slot_data_ = NULL;
  alloc_entries_ = max_entries_ = -1;
}

/*
 * Make sure that the entry at "idx" is correctly paired with "iref".
 */
bool IndirectReferenceTable::CheckEntry(const char* what, IndirectRef iref, int idx) const {
  const Object* obj = table_[idx];
  IndirectRef checkRef = ToIndirectRef(obj, idx);
  if (checkRef != iref) {
    LOG(ERROR) << "JNI ERROR (app bug): attempt to " << what
               << " stale " << kind_ << " " << iref
               << " (should be " << checkRef << ")";
    AbortMaybe();
    return false;
  }
  return true;
}

IndirectRef IndirectReferenceTable::Add(uint32_t cookie, const Object* obj) {
  IRTSegmentState prevState;
  prevState.all = cookie;
  size_t topIndex = segment_state_.parts.topIndex;

  DCHECK(obj != NULL);
  // TODO: stronger sanity check on the object (such as in heap)
  DCHECK(IsAligned(reinterpret_cast<intptr_t>(obj), 8)) << reinterpret_cast<const void*>(obj);
  DCHECK(table_ != NULL);
  DCHECK_LE(alloc_entries_, max_entries_);
  DCHECK_GE(segment_state_.parts.numHoles, prevState.parts.numHoles);

  if (topIndex == alloc_entries_) {
    /* reached end of allocated space; did we hit buffer max? */
    if (topIndex == max_entries_) {
      LOG(ERROR) << "JNI ERROR (app bug): " << kind_ << " table overflow "
                 << "(max=" << max_entries_ << ")";
      Dump();
      LOG(FATAL); // TODO: operator<< for IndirectReferenceTable
    }

    size_t newSize = alloc_entries_ * 2;
    if (newSize > max_entries_) {
      newSize = max_entries_;
    }
    DCHECK_GT(newSize, alloc_entries_);

    table_ = (const Object**) realloc(table_, newSize * sizeof(const Object*));
    slot_data_ = (IndirectRefSlot*) realloc(slot_data_, newSize * sizeof(IndirectRefSlot));
    if (table_ == NULL || slot_data_ == NULL) {
      LOG(ERROR) << "JNI ERROR (app bug): unable to expand "
                 << kind_ << " table (from "
                 << alloc_entries_ << " to " << newSize
                 << ", max=" << max_entries_ << ")";
      Dump();
      LOG(FATAL); // TODO: operator<< for IndirectReferenceTable
    }

    // Clear the newly-allocated slot_data_ elements.
    memset(slot_data_ + alloc_entries_, 0, (newSize - alloc_entries_) * sizeof(IndirectRefSlot));

    alloc_entries_ = newSize;
  }

  /*
   * We know there's enough room in the table.  Now we just need to find
   * the right spot.  If there's a hole, find it and fill it; otherwise,
   * add to the end of the list.
   */
  IndirectRef result;
  int numHoles = segment_state_.parts.numHoles - prevState.parts.numHoles;
  if (numHoles > 0) {
    DCHECK_GT(topIndex, 1U);
    /* find the first hole; likely to be near the end of the list */
    const Object** pScan = &table_[topIndex - 1];
    DCHECK(*pScan != NULL);
    while (*--pScan != NULL) {
      DCHECK_GE(pScan, table_ + prevState.parts.topIndex);
    }
    UpdateSlotAdd(obj, pScan - table_);
    result = ToIndirectRef(obj, pScan - table_);
    *pScan = obj;
    segment_state_.parts.numHoles--;
  } else {
    /* add to the end */
    UpdateSlotAdd(obj, topIndex);
    result = ToIndirectRef(obj, topIndex);
    table_[topIndex++] = obj;
    segment_state_.parts.topIndex = topIndex;
  }
  if (false) {
    LOG(INFO) << "+++ added at " << ExtractIndex(result) << " top=" << segment_state_.parts.topIndex
              << " holes=" << segment_state_.parts.numHoles;
  }

  DCHECK(result != NULL);
  return result;
}

void IndirectReferenceTable::AssertEmpty() {
  if (begin() != end()) {
    Dump();
    LOG(FATAL) << "Internal Error: non-empty local reference table";
  }
}

/*
 * Verify that the indirect table lookup is valid.
 *
 * Returns "false" if something looks bad.
 */
bool IndirectReferenceTable::GetChecked(IndirectRef iref) const {
  if (iref == NULL) {
    LOG(WARNING) << "Attempt to look up NULL " << kind_;
    return false;
  }
  if (GetIndirectRefKind(iref) == kSirtOrInvalid) {
    LOG(ERROR) << "JNI ERROR (app bug): invalid " << kind_ << " " << iref;
    AbortMaybe();
    return false;
  }

  int topIndex = segment_state_.parts.topIndex;
  int idx = ExtractIndex(iref);
  if (idx >= topIndex) {
    /* bad -- stale reference? */
    LOG(ERROR) << "JNI ERROR (app bug): accessed stale " << kind_ << " "
               << iref << " (index " << idx << " in a table of size " << topIndex << ")";
    AbortMaybe();
    return false;
  }

  if (table_[idx] == NULL) {
    LOG(ERROR) << "JNI ERROR (app bug): accessed deleted " << kind_ << " " << iref;
    AbortMaybe();
    return false;
  }

  if (!CheckEntry("use", iref, idx)) {
    return false;
  }

  return true;
}

static int LinearScan(IndirectRef iref, int bottomIndex, int topIndex, const Object** table) {
  for (int i = bottomIndex; i < topIndex; ++i) {
    if (table[i] == reinterpret_cast<const Object*>(iref)) {
      return i;
    }
  }
  return -1;
}

bool IndirectReferenceTable::Contains(IndirectRef iref) const {
  return LinearScan(iref, 0, segment_state_.parts.topIndex, table_) != -1;
}

/*
 * Remove "obj" from "pRef".  We extract the table offset bits from "iref"
 * and zap the corresponding entry, leaving a hole if it's not at the top.
 *
 * If the entry is not between the current top index and the bottom index
 * specified by the cookie, we don't remove anything.  This is the behavior
 * required by JNI's DeleteLocalRef function.
 *
 * Note this is NOT called when a local frame is popped.  This is only used
 * for explicit single removals.
 *
 * Returns "false" if nothing was removed.
 */
bool IndirectReferenceTable::Remove(uint32_t cookie, IndirectRef iref) {
  IRTSegmentState prevState;
  prevState.all = cookie;
  int topIndex = segment_state_.parts.topIndex;
  int bottomIndex = prevState.parts.topIndex;

  DCHECK(table_ != NULL);
  DCHECK_LE(alloc_entries_, max_entries_);
  DCHECK_GE(segment_state_.parts.numHoles, prevState.parts.numHoles);

  int idx = ExtractIndex(iref);

  JavaVMExt* vm = Runtime::Current()->GetJavaVM();
  if (GetIndirectRefKind(iref) == kSirtOrInvalid &&
      Thread::Current()->SirtContains(reinterpret_cast<jobject>(iref))) {
    LOG(WARNING) << "Attempt to remove local SIRT entry from IRT, ignoring";
    return true;
  }
  if (GetIndirectRefKind(iref) == kSirtOrInvalid || vm->work_around_app_jni_bugs) {
    idx = LinearScan(iref, bottomIndex, topIndex, table_);
    if (idx == -1) {
      LOG(WARNING) << "trying to work around app JNI bugs, but didn't find " << iref << " in table!";
      return false;
    }
  }

  if (idx < bottomIndex) {
    // Wrong segment.
    LOG(WARNING) << "Attempt to remove index outside index area (" << idx
                 << " vs " << bottomIndex << "-" << topIndex << ")";
    return false;
  }
  if (idx >= topIndex) {
    // Bad --- stale reference?
    LOG(WARNING) << "Attempt to remove invalid index " << idx
                 << " (bottom=" << bottomIndex << " top=" << topIndex << ")";
    return false;
  }

  if (idx == topIndex-1) {
    // Top-most entry.  Scan up and consume holes.

    if (!vm->work_around_app_jni_bugs && !CheckEntry("remove", iref, idx)) {
      return false;
    }

    table_[idx] = NULL;
    int numHoles = segment_state_.parts.numHoles - prevState.parts.numHoles;
    if (numHoles != 0) {
      while (--topIndex > bottomIndex && numHoles != 0) {
        if (false) {
          LOG(INFO) << "+++ checking for hole at " << topIndex-1
                    << " (cookie=" << cookie << ") val=" << table_[topIndex - 1];
        }
        if (table_[topIndex-1] != NULL) {
          break;
        }
        if (false) {
          LOG(INFO) << "+++ ate hole at " << (topIndex - 1);
        }
        numHoles--;
      }
      segment_state_.parts.numHoles = numHoles + prevState.parts.numHoles;
      segment_state_.parts.topIndex = topIndex;
    } else {
      segment_state_.parts.topIndex = topIndex-1;
      if (false) {
        LOG(INFO) << "+++ ate last entry " << topIndex - 1;
      }
    }
  } else {
    /*
     * Not the top-most entry.  This creates a hole.  We NULL out the
     * entry to prevent somebody from deleting it twice and screwing up
     * the hole count.
     */
    if (table_[idx] == NULL) {
      LOG(INFO) << "--- WEIRD: removing null entry " << idx;
      return false;
    }
    if (!vm->work_around_app_jni_bugs && !CheckEntry("remove", iref, idx)) {
      return false;
    }

    table_[idx] = NULL;
    segment_state_.parts.numHoles++;
    if (false) {
      LOG(INFO) << "+++ left hole at " << idx << ", holes=" << segment_state_.parts.numHoles;
    }
  }

  return true;
}

void IndirectReferenceTable::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
  typedef IndirectReferenceTable::iterator It; // TODO: C++0x auto
  for (It it = begin(), end = this->end(); it != end; ++it) {
    visitor(**it, arg);
  }
}

std::ostream& operator<<(std::ostream& os, IndirectRefKind rhs) {
  switch (rhs) {
  case kSirtOrInvalid:
    os << "stack indirect reference table or invalid reference";
    break;
  case kLocal:
    os << "local reference";
    break;
  case kGlobal:
    os << "global reference";
    break;
  case kWeakGlobal:
    os << "weak global reference";
    break;
  default:
    os << "IndirectRefKind[" << static_cast<int>(rhs) << "]";
    break;
  }
  return os;
}

void IndirectReferenceTable::Dump() const {
  LOG(WARNING) << kind_ << " table dump:";
  std::vector<const Object*> entries(table_, table_ + Capacity());
  ReferenceTable::Dump(entries);
}

}  // namespace art
