// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/reverse_pc_lookup_cache.h"

#include "vm/isolate.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/stub_code.h"

namespace dart {

CodePtr ReversePc::FindCodeInGroup(IsolateGroup* group,
                                   uword pc,
                                   bool is_return_address) {
#if defined(DART_PRECOMPILED_RUNTIME)
  // This can run in the middle of GC and must not allocate handles.
  NoSafepointScope no_safepoint;

  if (is_return_address) {
    pc--;
  }

  // This expected number of tables is low (one per loading unit), so we go
  // through them linearly. If this changes, would could sort the table list
  // during deserialization and binary search for the table.
  GrowableObjectArrayPtr tables = group->object_store()->instructions_tables();
  intptr_t tables_length = Smi::Value(tables->untag()->length());
  for (intptr_t i = 0; i < tables_length; i++) {
    InstructionsTablePtr table = static_cast<InstructionsTablePtr>(
        tables->untag()->data()->untag()->element(i));
    CodePtr code = InstructionsTable::FindCode(table, pc);
    if (code != Code::null()) {
      return code;
    }
  }
#endif  // defined(DART_PRECOMPILED_RUNTIME)
  return Code::null();
}

const UntaggedCompressedStackMaps::Payload* ReversePc::FindStackMapInGroup(
    IsolateGroup* group,
    uword pc,
    bool is_return_address,
    uword* code_start,
    const UntaggedCompressedStackMaps::Payload** global_table) {
#if defined(DART_PRECOMPILED_RUNTIME)
  // This can run in the middle of GC and must not allocate handles.
  NoSafepointScope no_safepoint;

  if (is_return_address) {
    pc--;
  }

  // This expected number of tables is low (one per loading unit), so we go
  // through them linearly. If this changes, would could sort the table list
  // during deserialization and binary search for the table.
  GrowableObjectArrayPtr tables = group->object_store()->instructions_tables();
  intptr_t tables_length = Smi::Value(tables->untag()->length());
  for (intptr_t i = 0; i < tables_length; i++) {
    InstructionsTablePtr table = static_cast<InstructionsTablePtr>(
        tables->untag()->data()->untag()->element(i));
    auto map = InstructionsTable::FindStackMap(table, pc, code_start);
    if (map != nullptr) {
      // Take global table from the first table.
      table = static_cast<InstructionsTablePtr>(
          tables->untag()->data()->untag()->element(0));
      *global_table = InstructionsTable::GetCanonicalStackMap(table);
      return map;
    }
  }
#endif  // defined(DART_PRECOMPILED_RUNTIME)

  *code_start = 0;
  return nullptr;
}

const UntaggedCompressedStackMaps::Payload* ReversePc::FindStackMap(
    IsolateGroup* group,
    uword pc,
    bool is_return_address,
    uword* code_start,
    const UntaggedCompressedStackMaps::Payload** global_table) {
  ASSERT(FLAG_precompiled_mode);
  NoSafepointScope no_safepoint;
  return FindStackMapInGroup(group, pc, is_return_address, code_start,
                             global_table);
}

CodePtr ReversePc::FindCode(IsolateGroup* group,
                            uword pc,
                            bool is_return_address) {
  ASSERT(FLAG_precompiled_mode);
  NoSafepointScope no_safepoint;
  return FindCodeInGroup(group, pc, is_return_address);
}

CodePtr ReversePc::Lookup(IsolateGroup* group,
                          uword pc,
                          bool is_return_address) {
  ASSERT(FLAG_precompiled_mode);
  NoSafepointScope no_safepoint;

  return FindCode(group, pc, is_return_address);
}

}  // namespace dart
