/*
 * 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_ALIGNED(reinterpret_cast<uintptr_t>(obj), 8);
  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 Find(Object* direct_pointer, int bottomIndex, int topIndex, const Object** table) {
  for (int i = bottomIndex; i < topIndex; ++i) {
    if (table[i] == direct_pointer) {
      return i;
    }
  }
  return -1;
}

bool IndirectReferenceTable::ContainsDirectPointer(Object* direct_pointer) const {
  return Find(direct_pointer, 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) {
    Object* direct_pointer = reinterpret_cast<Object*>(iref);
    idx = Find(direct_pointer, 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
