// Copyright (c) 2017, 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/compilation_trace.h"

#include "vm/closure_functions_cache.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/globals.h"
#include "vm/log.h"
#include "vm/longjump.h"
#include "vm/object_store.h"
#include "vm/resolver.h"
#include "vm/symbols.h"
#include "vm/version.h"

namespace dart {

#if !defined(DART_PRECOMPILED_RUNTIME)

DEFINE_FLAG(bool, trace_compilation_trace, false, "Trace compilation trace.");

CompilationTraceSaver::CompilationTraceSaver(Zone* zone)
    : buf_(zone, 1 * MB),
      func_name_(String::Handle(zone)),
      cls_(Class::Handle(zone)),
      cls_name_(String::Handle(zone)),
      lib_(Library::Handle(zone)),
      uri_(String::Handle(zone)) {}

void CompilationTraceSaver::VisitFunction(const Function& function) {
  if (!function.HasCode()) {
    return;  // Not compiled.
  }
  if (function.parent_function() != Function::null()) {
    // Lookup works poorly for local functions. We compile all local functions
    // in a compiled function instead.
    return;
  }

  func_name_ = function.name();
  func_name_ = String::RemovePrivateKey(func_name_);
  cls_ = function.Owner();
  cls_name_ = cls_.Name();
  cls_name_ = String::RemovePrivateKey(cls_name_);
  lib_ = cls_.library();
  uri_ = lib_.url();
  buf_.Printf("%s,%s,%s\n", uri_.ToCString(), cls_name_.ToCString(),
              func_name_.ToCString());
}

CompilationTraceLoader::CompilationTraceLoader(Thread* thread)
    : thread_(thread),
      zone_(thread->zone()),
      uri_(String::Handle(zone_)),
      class_name_(String::Handle(zone_)),
      function_name_(String::Handle(zone_)),
      function_name2_(String::Handle(zone_)),
      lib_(Library::Handle(zone_)),
      cls_(Class::Handle(zone_)),
      function_(Function::Handle(zone_)),
      function2_(Function::Handle(zone_)),
      field_(Field::Handle(zone_)),
      sites_(Array::Handle(zone_)),
      site_(ICData::Handle(zone_)),
      static_type_(AbstractType::Handle(zone_)),
      receiver_cls_(Class::Handle(zone_)),
      target_(Function::Handle(zone_)),
      selector_(String::Handle(zone_)),
      args_desc_(Array::Handle(zone_)),
      error_(Object::Handle(zone_)) {}

static char* FindCharacter(char* str, char goal, char* limit) {
  while (str < limit) {
    if (*str == goal) {
      return str;
    }
    str++;
  }
  return NULL;
}

ObjectPtr CompilationTraceLoader::CompileTrace(uint8_t* buffer, intptr_t size) {
  // First compile functions named in the trace.
  char* cursor = reinterpret_cast<char*>(buffer);
  char* limit = cursor + size;
  while (cursor < limit) {
    char* uri = cursor;
    char* comma1 = FindCharacter(uri, ',', limit);
    if (comma1 == NULL) {
      break;
    }
    *comma1 = 0;
    char* cls_name = comma1 + 1;
    char* comma2 = FindCharacter(cls_name, ',', limit);
    if (comma2 == NULL) {
      break;
    }
    *comma2 = 0;
    char* func_name = comma2 + 1;
    char* newline = FindCharacter(func_name, '\n', limit);
    if (newline == NULL) {
      break;
    }
    *newline = 0;
    error_ = CompileTriple(uri, cls_name, func_name);
    if (error_.IsError()) {
      return error_.raw();
    }
    cursor = newline + 1;
  }

  // Next, compile common dispatchers. These aren't found with the normal
  // lookup above because they have irregular lookup that depends on the
  // arguments descriptor (e.g. call() versus call(x)).
  const Class& closure_class = Class::Handle(
      zone_, thread_->isolate_group()->object_store()->closure_class());
  Array& arguments_descriptor = Array::Handle(zone_);
  Function& dispatcher = Function::Handle(zone_);
  for (intptr_t argc = 1; argc <= 4; argc++) {
    const intptr_t kTypeArgsLen = 0;

    // TODO(dartbug.com/33549): Update this code to use the size of the
    // parameters when supporting calls to closures with unboxed parameters.
    arguments_descriptor = ArgumentsDescriptor::NewBoxed(kTypeArgsLen, argc);
    dispatcher = closure_class.GetInvocationDispatcher(
        Symbols::Call(), arguments_descriptor,
        FunctionLayout::kInvokeFieldDispatcher, true /* create_if_absent */);
    error_ = CompileFunction(dispatcher);
    if (error_.IsError()) {
      return error_.raw();
    }
  }

  // Finally, compile closures in all compiled functions. Note: We rely on the
  // fact that parent functions are visited before children.
  error_ = Object::null();
  auto& result = Object::Handle(zone_);
  ClosureFunctionsCache::ForAllClosureFunctions([&](const Function& func) {
    function2_ = func.parent_function();
    if (function2_.HasCode()) {
      result = CompileFunction(function_);
      if (result.IsError()) {
        error_ = result.raw();
        return false;  // Stop iteration.
      }
    }
    return true;
  });

  return Object::null();
}

// Use a fuzzy match to find the right function to compile. This allows a
// compilation trace to remain mostly valid in the face of program changes, and
// deals with implicit/dispatcher functions that don't have proper names.
//  - Ignore private name mangling
//  - If looking for a getter and we only have the corresponding regular method,
//    compile the regular method, create its implicit closure and compile that.
//  - If looking for a regular method and we only have the corresponding getter,
//    compile the getter, create its method extractor and compile that.
//  - If looking for a getter and we only have a const field, evaluate the const
//    field.
ObjectPtr CompilationTraceLoader::CompileTriple(const char* uri_cstr,
                                                const char* cls_cstr,
                                                const char* func_cstr) {
  uri_ = Symbols::New(thread_, uri_cstr);
  class_name_ = Symbols::New(thread_, cls_cstr);
  function_name_ = Symbols::New(thread_, func_cstr);

  if (function_name_.Equals("_getMainClosure")) {
    // The scheme for invoking main relies on compiling _getMainClosure after
    // synthetically importing the root library.
    if (FLAG_trace_compilation_trace) {
      THR_Print("Compilation trace: skip %s,%s,%s\n", uri_.ToCString(),
                class_name_.ToCString(), function_name_.ToCString());
    }
    return Object::null();
  }

  lib_ = Library::LookupLibrary(thread_, uri_);
  if (lib_.IsNull()) {
    // Missing library.
    if (FLAG_trace_compilation_trace) {
      THR_Print("Compilation trace: missing library %s,%s,%s\n",
                uri_.ToCString(), class_name_.ToCString(),
                function_name_.ToCString());
    }
    return Object::null();
  }

  bool is_dyn = Function::IsDynamicInvocationForwarderName(function_name_);
  if (is_dyn) {
    function_name_ =
        Function::DemangleDynamicInvocationForwarderName(function_name_);
  }

  bool is_getter = Field::IsGetterName(function_name_);
  bool is_init = Field::IsInitName(function_name_);
  bool add_closure = false;
  bool processed = false;

  if (class_name_.Equals(Symbols::TopLevel())) {
    function_ = lib_.LookupFunctionAllowPrivate(function_name_);
    field_ = lib_.LookupFieldAllowPrivate(function_name_);
    if (function_.IsNull() && is_getter) {
      // Maybe this was a tear off.
      add_closure = true;
      function_name2_ = Field::NameFromGetter(function_name_);
      function_ = lib_.LookupFunctionAllowPrivate(function_name2_);
      field_ = lib_.LookupFieldAllowPrivate(function_name2_);
    }
    if (field_.IsNull() && is_getter) {
      function_name2_ = Field::NameFromGetter(function_name_);
      field_ = lib_.LookupFieldAllowPrivate(function_name2_);
    }
    if (field_.IsNull() && is_init) {
      function_name2_ = Field::NameFromInit(function_name_);
      field_ = lib_.LookupFieldAllowPrivate(function_name2_);
    }
  } else {
    cls_ = lib_.SlowLookupClassAllowMultiPartPrivate(class_name_);
    if (cls_.IsNull()) {
      // Missing class.
      if (FLAG_trace_compilation_trace) {
        THR_Print("Compilation trace: missing class %s,%s,%s\n",
                  uri_.ToCString(), class_name_.ToCString(),
                  function_name_.ToCString());
      }
      return Object::null();
    }

    error_ = cls_.EnsureIsFinalized(thread_);
    if (error_.IsError()) {
      // Non-finalized class.
      if (FLAG_trace_compilation_trace) {
        THR_Print("Compilation trace: non-finalized class %s,%s,%s (%s)\n",
                  uri_.ToCString(), class_name_.ToCString(),
                  function_name_.ToCString(),
                  Error::Cast(error_).ToErrorCString());
      }
      return error_.raw();
    }

    function_ = cls_.LookupFunctionAllowPrivate(function_name_);
    field_ = cls_.LookupFieldAllowPrivate(function_name_);
    if (function_.IsNull() && is_getter) {
      // Maybe this was a tear off.
      add_closure = true;
      function_name2_ = Field::NameFromGetter(function_name_);
      function_ = cls_.LookupFunctionAllowPrivate(function_name2_);
      field_ = cls_.LookupFieldAllowPrivate(function_name2_);
      if (!function_.IsNull() && !function_.is_static()) {
        // Maybe this was a method extractor.
        function2_ =
            Resolver::ResolveDynamicAnyArgs(zone_, cls_, function_name_);
        if (!function2_.IsNull()) {
          error_ = CompileFunction(function2_);
          if (error_.IsError()) {
            if (FLAG_trace_compilation_trace) {
              THR_Print(
                  "Compilation trace: error compiling extractor %s for "
                  "%s,%s,%s (%s)\n",
                  function2_.ToCString(), uri_.ToCString(),
                  class_name_.ToCString(), function_name_.ToCString(),
                  Error::Cast(error_).ToErrorCString());
            }
            return error_.raw();
          }
        }
      }
    }
    if (field_.IsNull() && is_getter) {
      function_name2_ = Field::NameFromGetter(function_name_);
      field_ = cls_.LookupFieldAllowPrivate(function_name2_);
    }
    if (field_.IsNull() && is_init) {
      function_name2_ = Field::NameFromInit(function_name_);
      field_ = cls_.LookupFieldAllowPrivate(function_name2_);
    }
  }

  if (!field_.IsNull() && field_.is_const() && field_.is_static() &&
      (field_.StaticValue() == Object::sentinel().raw())) {
    processed = true;
    error_ = field_.InitializeStatic();
    if (error_.IsError()) {
      if (FLAG_trace_compilation_trace) {
        THR_Print(
            "Compilation trace: error initializing field %s for %s,%s,%s "
            "(%s)\n",
            field_.ToCString(), uri_.ToCString(), class_name_.ToCString(),
            function_name_.ToCString(), Error::Cast(error_).ToErrorCString());
      }
      return error_.raw();
    }
  }

  if (!function_.IsNull()) {
    processed = true;
    error_ = CompileFunction(function_);
    if (error_.IsError()) {
      if (FLAG_trace_compilation_trace) {
        THR_Print("Compilation trace: error compiling %s,%s,%s (%s)\n",
                  uri_.ToCString(), class_name_.ToCString(),
                  function_name_.ToCString(),
                  Error::Cast(error_).ToErrorCString());
      }
      return error_.raw();
    }
    if (add_closure) {
      function_ = function_.ImplicitClosureFunction();
      error_ = CompileFunction(function_);
      if (error_.IsError()) {
        if (FLAG_trace_compilation_trace) {
          THR_Print(
              "Compilation trace: error compiling closure %s,%s,%s (%s)\n",
              uri_.ToCString(), class_name_.ToCString(),
              function_name_.ToCString(), Error::Cast(error_).ToErrorCString());
        }
        return error_.raw();
      }
    } else if (is_dyn) {
      function_name_ = function_.name();  // With private mangling.
      function_name_ =
          Function::CreateDynamicInvocationForwarderName(function_name_);
      function_ = function_.GetDynamicInvocationForwarder(function_name_);
      error_ = CompileFunction(function_);
      if (error_.IsError()) {
        if (FLAG_trace_compilation_trace) {
          THR_Print(
              "Compilation trace: error compiling dynamic forwarder %s,%s,%s "
              "(%s)\n",
              uri_.ToCString(), class_name_.ToCString(),
              function_name_.ToCString(), Error::Cast(error_).ToErrorCString());
        }
        return error_.raw();
      }
    }
  }

  if (!field_.IsNull() && field_.is_static() && !field_.is_const() &&
      field_.has_nontrivial_initializer()) {
    processed = true;
    function_ = field_.EnsureInitializerFunction();
    error_ = CompileFunction(function_);
    if (error_.IsError()) {
      if (FLAG_trace_compilation_trace) {
        THR_Print(
            "Compilation trace: error compiling initializer %s,%s,%s (%s)\n",
            uri_.ToCString(), class_name_.ToCString(),
            function_name_.ToCString(), Error::Cast(error_).ToErrorCString());
      }
      return error_.raw();
    }
  }

  if (FLAG_trace_compilation_trace) {
    if (!processed) {
      THR_Print("Compilation trace: ignored %s,%s,%s\n", uri_.ToCString(),
                class_name_.ToCString(), function_name_.ToCString());
    }
  }
  return Object::null();
}

ObjectPtr CompilationTraceLoader::CompileFunction(const Function& function) {
  if (function.is_abstract() || function.HasCode()) {
    return Object::null();
  }

  error_ = Compiler::CompileFunction(thread_, function);
  if (error_.IsError()) {
    return error_.raw();
  }

  SpeculateInstanceCallTargets(function);

  return error_.raw();
}

// For instance calls, if the receiver's static type has one concrete
// implementation, lookup the target for that implementation and add it
// to the ICData's entries.
// For some well-known interfaces, do the same for the most common concrete
// implementation (e.g., int -> _Smi).
void CompilationTraceLoader::SpeculateInstanceCallTargets(
    const Function& function) {
  sites_ = function.ic_data_array();
  if (sites_.IsNull()) {
    return;
  }
  for (intptr_t i = 1; i < sites_.Length(); i++) {
    site_ ^= sites_.At(i);
    if (site_.rebind_rule() != ICData::kInstance) {
      continue;
    }
    if (site_.NumArgsTested() != 1) {
      continue;
    }

    static_type_ = site_.receivers_static_type();
    if (static_type_.IsNull()) {
      continue;
    } else if (static_type_.IsDoubleType()) {
      receiver_cls_ = IsolateGroup::Current()->class_table()->At(kDoubleCid);
    } else if (static_type_.IsIntType()) {
      receiver_cls_ = IsolateGroup::Current()->class_table()->At(kSmiCid);
    } else if (static_type_.IsStringType()) {
      receiver_cls_ =
          IsolateGroup::Current()->class_table()->At(kOneByteStringCid);
    } else if (static_type_.IsDartFunctionType() ||
               static_type_.IsDartClosureType()) {
      receiver_cls_ = IsolateGroup::Current()->class_table()->At(kClosureCid);
    } else if (static_type_.HasTypeClass()) {
      receiver_cls_ = static_type_.type_class();
      if (receiver_cls_.is_implemented() || receiver_cls_.is_abstract()) {
        continue;
      }
    } else {
      continue;
    }

    selector_ = site_.target_name();
    args_desc_ = site_.arguments_descriptor();
    target_ = Resolver::ResolveDynamicForReceiverClass(
        receiver_cls_, selector_, ArgumentsDescriptor(args_desc_));
    if (!target_.IsNull() && !site_.HasReceiverClassId(receiver_cls_.id())) {
      intptr_t count = 0;  // Don't pollute type feedback and coverage data.
      site_.AddReceiverCheck(receiver_cls_.id(), target_, count);
    }
  }
}

TypeFeedbackSaver::TypeFeedbackSaver(BaseWriteStream* stream)
    : stream_(stream),
      cls_(Class::Handle()),
      lib_(Library::Handle()),
      str_(String::Handle()),
      fields_(Array::Handle()),
      field_(Field::Handle()),
      code_(Code::Handle()),
      call_sites_(Array::Handle()),
      call_site_(ICData::Handle()) {}

// These flags affect deopt ids.
static char* CompilerFlags() {
  TextBuffer buffer(64);

#define ADD_FLAG(flag) buffer.AddString(FLAG_##flag ? " " #flag : " no-" #flag)
  ADD_FLAG(enable_asserts);
  ADD_FLAG(use_field_guards);
  ADD_FLAG(use_osr);
  ADD_FLAG(fields_may_be_reset);
#undef ADD_FLAG

  return buffer.Steal();
}

void TypeFeedbackSaver::WriteHeader() {
  const char* expected_version = Version::SnapshotString();
  ASSERT(expected_version != NULL);
  const intptr_t version_len = strlen(expected_version);
  stream_->WriteBytes(reinterpret_cast<const uint8_t*>(expected_version),
                      version_len);

  char* expected_features = CompilerFlags();
  ASSERT(expected_features != NULL);
  const intptr_t features_len = strlen(expected_features);
  stream_->WriteBytes(reinterpret_cast<const uint8_t*>(expected_features),
                      features_len + 1);
  free(expected_features);
}

void TypeFeedbackSaver::SaveClasses() {
  ClassTable* table = IsolateGroup::Current()->class_table();

  intptr_t num_cids = table->NumCids();
  WriteInt(num_cids);

  for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
    cls_ = table->At(cid);
    WriteClassByName(cls_);
  }
}

void TypeFeedbackSaver::SaveFields() {
  ClassTable* table = IsolateGroup::Current()->class_table();
  intptr_t num_cids = table->NumCids();
  for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
    cls_ = table->At(cid);
    WriteClassByName(cls_);

    fields_ = cls_.fields();
    WriteInt(fields_.Length());
    for (intptr_t i = 0; i < fields_.Length(); i++) {
      field_ ^= fields_.At(i);

      str_ = field_.name();
      str_ = String::RemovePrivateKey(str_);
      WriteString(str_);

      WriteInt(field_.guarded_cid());
      WriteInt(static_cast<intptr_t>(field_.is_nullable()));
    }
  }
}

void TypeFeedbackSaver::VisitFunction(const Function& function) {
  if (!function.HasCode()) {
    return;  // Not compiled.
  }

  cls_ = function.Owner();
  WriteClassByName(cls_);

  str_ = function.name();
  str_ = String::RemovePrivateKey(str_);
  WriteString(str_);

  WriteInt(function.kind());
  WriteInt(function.token_pos().Serialize());

  code_ = function.CurrentCode();
  intptr_t usage = function.usage_counter();
  if (usage < 0) {
    // Usage is set to INT32_MIN while in the background compilation queue ...
    usage = (usage - INT32_MIN) + FLAG_optimization_counter_threshold;
  } else if (code_.is_optimized()) {
    // ... and set to 0 when an optimizing compile completes.
    usage = usage + FLAG_optimization_counter_threshold;
  }
  WriteInt(usage);

  WriteInt(function.inlining_depth());

  call_sites_ = function.ic_data_array();
  if (call_sites_.IsNull()) {
    call_sites_ = Object::empty_array().raw();  // Remove edge case.
  }

  // First element is edge counters.
  WriteInt(call_sites_.Length() - 1);
  for (intptr_t i = 1; i < call_sites_.Length(); i++) {
    call_site_ ^= call_sites_.At(i);

    WriteInt(call_site_.deopt_id());
    WriteInt(call_site_.rebind_rule());

    str_ = call_site_.target_name();
    str_ = String::RemovePrivateKey(str_);
    WriteString(str_);

    intptr_t num_checked_arguments = call_site_.NumArgsTested();
    WriteInt(num_checked_arguments);

    intptr_t num_entries = call_site_.NumberOfChecks();
    WriteInt(num_entries);

    for (intptr_t entry_index = 0; entry_index < num_entries; entry_index++) {
      WriteInt(call_site_.GetCountAt(entry_index));

      for (intptr_t argument_index = 0; argument_index < num_checked_arguments;
           argument_index++) {
        WriteInt(call_site_.GetClassIdAt(entry_index, argument_index));
      }
    }
  }
}

void TypeFeedbackSaver::WriteClassByName(const Class& cls) {
  lib_ = cls.library();

  str_ = lib_.url();
  WriteString(str_);

  str_ = cls_.Name();
  str_ = String::RemovePrivateKey(str_);
  WriteString(str_);
}

void TypeFeedbackSaver::WriteString(const String& value) {
  const char* cstr = value.ToCString();
  intptr_t len = strlen(cstr);
  stream_->WriteUnsigned(len);
  stream_->WriteBytes(cstr, len);
}

TypeFeedbackLoader::TypeFeedbackLoader(Thread* thread)
    : thread_(thread),
      zone_(thread->zone()),
      stream_(nullptr),
      cid_map_(nullptr),
      uri_(String::Handle(zone_)),
      lib_(Library::Handle(zone_)),
      cls_name_(String::Handle(zone_)),
      cls_(Class::Handle(zone_)),
      field_name_(String::Handle(zone_)),
      fields_(Array::Handle(zone_)),
      field_(Field::Handle(zone_)),
      func_name_(String::Handle(zone_)),
      func_(Function::Handle(zone_)),
      call_sites_(Array::Handle(zone_)),
      call_site_(ICData::Handle(zone_)),
      target_name_(String::Handle(zone_)),
      target_(Function::Handle(zone_)),
      args_desc_(Array::Handle(zone_)),
      functions_to_compile_(
          GrowableObjectArray::Handle(zone_, GrowableObjectArray::New())),
      error_(Error::Handle(zone_)) {}

TypeFeedbackLoader::~TypeFeedbackLoader() {
  delete[] cid_map_;
}

ObjectPtr TypeFeedbackLoader::LoadFeedback(ReadStream* stream) {
  stream_ = stream;

  error_ = CheckHeader();
  if (error_.IsError()) {
    return error_.raw();
  }

  error_ = LoadClasses();
  if (error_.IsError()) {
    return error_.raw();
  }

  error_ = LoadFields();
  if (error_.IsError()) {
    return error_.raw();
  }

  while (stream_->PendingBytes() > 0) {
    error_ = LoadFunction();
    if (error_.IsError()) {
      return error_.raw();
    }
  }

  while (functions_to_compile_.Length() > 0) {
    func_ ^= functions_to_compile_.RemoveLast();

    if (Compiler::CanOptimizeFunction(thread_, func_) &&
        (func_.usage_counter() >= FLAG_optimization_counter_threshold)) {
      error_ = Compiler::CompileOptimizedFunction(thread_, func_);
      if (error_.IsError()) {
        return error_.raw();
      }
    }
  }

  if (FLAG_trace_compilation_trace) {
    THR_Print("Done loading feedback\n");
  }

  return Error::null();
}

ObjectPtr TypeFeedbackLoader::CheckHeader() {
  const char* expected_version = Version::SnapshotString();
  ASSERT(expected_version != NULL);
  const intptr_t version_len = strlen(expected_version);
  if (stream_->PendingBytes() < version_len) {
    const intptr_t kMessageBufferSize = 128;
    char message_buffer[kMessageBufferSize];
    Utils::SNPrint(message_buffer, kMessageBufferSize,
                   "No snapshot version found, expected '%s'",
                   expected_version);
    const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
    return ApiError::New(msg, Heap::kOld);
  }

  const char* version =
      reinterpret_cast<const char*>(stream_->AddressOfCurrentPosition());
  ASSERT(version != NULL);
  if (strncmp(version, expected_version, version_len) != 0) {
    const intptr_t kMessageBufferSize = 256;
    char message_buffer[kMessageBufferSize];
    char* actual_version = Utils::StrNDup(version, version_len);
    Utils::SNPrint(message_buffer, kMessageBufferSize,
                   "Wrong snapshot version, expected '%s' found '%s'",
                   expected_version, actual_version);
    free(actual_version);
    const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
    return ApiError::New(msg, Heap::kOld);
  }
  stream_->Advance(version_len);

  char* expected_features = CompilerFlags();
  ASSERT(expected_features != NULL);
  const intptr_t expected_len = strlen(expected_features);

  const char* features =
      reinterpret_cast<const char*>(stream_->AddressOfCurrentPosition());
  ASSERT(features != NULL);
  intptr_t buffer_len = Utils::StrNLen(features, stream_->PendingBytes());
  if ((buffer_len != expected_len) ||
      (strncmp(features, expected_features, expected_len) != 0)) {
    const String& msg = String::Handle(String::NewFormatted(
        Heap::kOld,
        "Feedback not compatible with the current VM configuration: "
        "the feedback requires '%.*s' but the VM has '%s'",
        static_cast<int>(buffer_len > 1024 ? 1024 : buffer_len), features,
        expected_features));
    free(expected_features);
    return ApiError::New(msg, Heap::kOld);
  }
  free(expected_features);
  stream_->Advance(expected_len + 1);
  return Error::null();
}

ObjectPtr TypeFeedbackLoader::LoadClasses() {
  num_cids_ = ReadInt();

  cid_map_ = new intptr_t[num_cids_];
  for (intptr_t cid = 0; cid < num_cids_; cid++) {
    cid_map_[cid] = kIllegalCid;
  }
  for (intptr_t cid = kInstanceCid; cid < kNumPredefinedCids; cid++) {
    cid_map_[cid] = cid;
  }

  for (intptr_t cid = kNumPredefinedCids; cid < num_cids_; cid++) {
    cls_ = ReadClassByName();
    if (!cls_.IsNull()) {
      cid_map_[cid] = cls_.id();
    }
  }

  return Error::null();
}

ObjectPtr TypeFeedbackLoader::LoadFields() {
  for (intptr_t cid = kNumPredefinedCids; cid < num_cids_; cid++) {
    cls_ = ReadClassByName();
    bool skip = cls_.IsNull();

    intptr_t num_fields = ReadInt();
    if (!skip && (num_fields > 0)) {
      error_ = cls_.EnsureIsFinalized(thread_);
      if (error_.IsError()) {
        return error_.raw();
      }
      fields_ = cls_.fields();
    }

    SafepointWriteRwLocker ml(thread_,
                              thread_->isolate_group()->program_lock());
    for (intptr_t i = 0; i < num_fields; i++) {
      field_name_ = ReadString();
      intptr_t guarded_cid = cid_map_[ReadInt()];
      intptr_t is_nullable = ReadInt();

      if (skip) {
        continue;
      }

      if (i >= fields_.Length()) {
        if (FLAG_trace_compilation_trace) {
          THR_Print("Missing field %s\n", field_name_.ToCString());
        }
        continue;
      }

      field_ ^= fields_.At(i);
      if (!String::EqualsIgnoringPrivateKey(String::Handle(field_.name()),
                                            field_name_)) {
        if (FLAG_trace_compilation_trace) {
          THR_Print("Missing field %s\n", field_name_.ToCString());
        }
        continue;
      }

      if (guarded_cid == kIllegalCid) {
        // Guarded CID from feedback is not in current program: assume the field
        // will become polymorphic.
        field_.set_guarded_cid(kDynamicCid);
        field_.set_is_nullable(true);
      } else if ((field_.guarded_cid() != kIllegalCid) &&
                 (field_.guarded_cid() == guarded_cid)) {
        // Guarded CID from feedback is different from initialized guarded CID
        // in the current program: assume the field will become polymorphic.
        field_.set_guarded_cid(kDynamicCid);
        field_.set_is_nullable(true);
      } else {
        field_.set_guarded_cid(guarded_cid);
        field_.set_is_nullable((is_nullable != 0) || field_.is_nullable());
      }

      // TODO(rmacnak): Merge other field type feedback.
      field_.set_guarded_list_length(Field::kNoFixedLength);
      field_.set_guarded_list_length_in_object_offset(
          Field::kUnknownLengthOffset);
      field_.set_static_type_exactness_state(
          StaticTypeExactnessState::NotTracking());
      field_.DeoptimizeDependentCode();
    }
  }

  return Error::null();
}

ObjectPtr TypeFeedbackLoader::LoadFunction() {
  bool skip = false;

  cls_ = ReadClassByName();
  if (!cls_.IsNull()) {
    error_ = cls_.EnsureIsFinalized(thread_);
    if (error_.IsError()) {
      return error_.raw();
    }
  } else {
    skip = true;
  }

  func_name_ = ReadString();  // Without private mangling.
  FunctionLayout::Kind kind = static_cast<FunctionLayout::Kind>(ReadInt());
  const TokenPosition& token_pos = TokenPosition::Deserialize(ReadInt());
  intptr_t usage = ReadInt();
  intptr_t inlining_depth = ReadInt();
  intptr_t num_call_sites = ReadInt();

  if (!skip) {
    func_ = FindFunction(kind, token_pos);
    if (func_.IsNull()) {
      skip = true;
      if (FLAG_trace_compilation_trace) {
        THR_Print("Missing function %s %s\n", func_name_.ToCString(),
                  Function::KindToCString(kind));
      }
    }
  }

  if (!skip) {
    error_ = Compiler::CompileFunction(thread_, func_);
    if (error_.IsError()) {
      return error_.raw();
    }
    call_sites_ = func_.ic_data_array();
    if (call_sites_.IsNull()) {
      call_sites_ = Object::empty_array().raw();  // Remove edge case.
    }
    if (call_sites_.Length() != num_call_sites + 1) {
      skip = true;
      if (FLAG_trace_compilation_trace) {
        THR_Print("Mismatched call site count %s %" Pd " %" Pd "\n",
                  func_name_.ToCString(), call_sites_.Length(), num_call_sites);
      }
    }
  }

  // First element is edge counters.
  for (intptr_t i = 1; i <= num_call_sites; i++) {
    intptr_t deopt_id = ReadInt();
    intptr_t rebind_rule = ReadInt();
    target_name_ = ReadString();
    intptr_t num_checked_arguments = ReadInt();
    intptr_t num_entries = ReadInt();

    if (!skip) {
      call_site_ ^= call_sites_.At(i);
      if ((call_site_.deopt_id() != deopt_id) ||
          (call_site_.rebind_rule() != rebind_rule) ||
          (call_site_.NumArgsTested() != num_checked_arguments)) {
        skip = true;
        if (FLAG_trace_compilation_trace) {
          THR_Print("Mismatched call site %s\n", call_site_.ToCString());
        }
      }
    }

    for (intptr_t entry_index = 0; entry_index < num_entries; entry_index++) {
      intptr_t entry_usage = ReadInt();
      bool skip_entry = skip;
      GrowableArray<intptr_t> cids(num_checked_arguments);

      for (intptr_t argument_index = 0; argument_index < num_checked_arguments;
           argument_index++) {
        intptr_t cid = cid_map_[ReadInt()];
        cids.Add(cid);
        if (cid == kIllegalCid) {
          // Alternative: switch to a sentinel value such as kDynamicCid and
          // have the optimizer generate a megamorphic call.
          skip_entry = true;
        }
      }

      if (skip_entry) {
        continue;
      }

      intptr_t reuse_index = call_site_.FindCheck(cids);
      if (reuse_index == -1) {
        cls_ = thread_->isolate_group()->class_table()->At(cids[0]);
        // Use target name and args descriptor from the current program
        // instead of saved feedback to get the correct private mangling and
        // ensure no arity mismatch crashes.
        target_name_ = call_site_.target_name();
        args_desc_ = call_site_.arguments_descriptor();
        if (cls_.EnsureIsFinalized(thread_) == Error::null()) {
          target_ = Resolver::ResolveDynamicForReceiverClass(
              cls_, target_name_, ArgumentsDescriptor(args_desc_));
        }
        if (!target_.IsNull()) {
          if (num_checked_arguments == 1) {
            call_site_.AddReceiverCheck(cids[0], target_, entry_usage);
          } else {
            call_site_.AddCheck(cids, target_, entry_usage);
          }
        }
      } else {
        call_site_.IncrementCountAt(reuse_index, entry_usage);
      }
    }
  }

  if (!skip) {
    func_.set_usage_counter(usage);
    func_.set_inlining_depth(inlining_depth);

    // Delay compilation until all feedback is loaded so feedback is available
    // for inlined functions.
    functions_to_compile_.Add(func_);
  }

  return Error::null();
}

FunctionPtr TypeFeedbackLoader::FindFunction(FunctionLayout::Kind kind,
                                             const TokenPosition& token_pos) {
  if (cls_name_.Equals(Symbols::TopLevel())) {
    func_ = lib_.LookupFunctionAllowPrivate(func_name_);
  } else {
    func_ = cls_.LookupFunctionAllowPrivate(func_name_);
  }

  if (!func_.IsNull()) {
    // Found regular method.
  } else if (kind == FunctionLayout::kMethodExtractor) {
    ASSERT(Field::IsGetterName(func_name_));
    // Without private mangling:
    String& name = String::Handle(zone_, Field::NameFromGetter(func_name_));
    func_ = cls_.LookupFunctionAllowPrivate(name);
    if (!func_.IsNull() && func_.IsDynamicFunction()) {
      name = func_.name();  // With private mangling.
      name = Field::GetterName(name);
      func_ = func_.GetMethodExtractor(name);
    } else {
      func_ = Function::null();
    }
  } else if (kind == FunctionLayout::kDynamicInvocationForwarder) {
    // Without private mangling:
    String& name = String::Handle(
        zone_, Function::DemangleDynamicInvocationForwarderName(func_name_));
    func_ = cls_.LookupFunctionAllowPrivate(name);
    if (!func_.IsNull() && func_.IsDynamicFunction()) {
      name = func_.name();  // With private mangling.
      name = Function::CreateDynamicInvocationForwarderName(name);
      func_ = func_.CreateDynamicInvocationForwarder(name);
    } else {
      func_ = Function::null();
    }
  } else if (kind == FunctionLayout::kClosureFunction) {
    // Note this lookup relies on parent functions appearing before child
    // functions in the serialized feedback, so the parent will have already
    // been unoptimized compilated and the child function created and added to
    // ObjectStore::closure_functions_.
    func_ = ClosureFunctionsCache::LookupClosureFunction(cls_, token_pos);
  } else {
    // This leaves unhandled:
    // - kInvokeFieldDispatcher (how to get a valid args descriptor?)
    // - static field getters
    // - static field initializers (not retained by the field object)
  }

  if (!func_.IsNull()) {
    if (kind == FunctionLayout::kImplicitClosureFunction) {
      func_ = func_.ImplicitClosureFunction();
    }
    if (func_.is_abstract() || (func_.kind() != kind)) {
      func_ = Function::null();
    }
  }

  return func_.raw();
}

ClassPtr TypeFeedbackLoader::ReadClassByName() {
  uri_ = ReadString();
  cls_name_ = ReadString();

  lib_ = Library::LookupLibrary(thread_, uri_);
  if (lib_.IsNull()) {
    if (FLAG_trace_compilation_trace) {
      THR_Print("Missing library %s\n", uri_.ToCString());
    }
    return Class::null();
  }

  if (cls_name_.Equals(Symbols::TopLevel())) {
    cls_ = lib_.toplevel_class();
  } else {
    cls_ = lib_.SlowLookupClassAllowMultiPartPrivate(cls_name_);
    if (cls_.IsNull()) {
      if (FLAG_trace_compilation_trace) {
        THR_Print("Missing class %s %s\n", uri_.ToCString(),
                  cls_name_.ToCString());
      }
    }
  }
  return cls_.raw();
}

StringPtr TypeFeedbackLoader::ReadString() {
  intptr_t len = stream_->ReadUnsigned();
  const char* cstr =
      reinterpret_cast<const char*>(stream_->AddressOfCurrentPosition());
  stream_->Advance(len);
  return Symbols::New(thread_, cstr, len);
}

#endif  // !defined(DART_PRECOMPILED_RUNTIME)

}  // namespace dart
