// 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/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()->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. Don't cache the
  // length since compiling may append to this list.
  const GrowableObjectArray& closure_functions = GrowableObjectArray::Handle(
      zone_, thread_->isolate()->object_store()->closure_functions());
  for (intptr_t i = 0; i < closure_functions.Length(); i++) {
    function_ ^= closure_functions.At(i);
    function2_ = function_.parent_function();
    if (function2_.HasCode()) {
      error_ = CompileFunction(function_);
      if (error_.IsError()) {
        return error_.raw();
      }
    }
  }

  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_ = Isolate::Current()->class_table()->At(kDoubleCid);
    } else if (static_type_.IsIntType()) {
      receiver_cls_ = Isolate::Current()->class_table()->At(kSmiCid);
    } else if (static_type_.IsStringType()) {
      receiver_cls_ = Isolate::Current()->class_table()->At(kOneByteStringCid);
    } else if (static_type_.IsDartFunctionType() ||
               static_type_.IsDartClosureType()) {
      receiver_cls_ = Isolate::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(WriteStream* 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(causal_async_stacks);
  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 = Isolate::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 = Isolate::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().value());

  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();
    }

    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());
  intptr_t token_pos = 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()->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,
                                             intptr_t 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_.
    const GrowableObjectArray& closure_functions = GrowableObjectArray::Handle(
        zone_, thread_->isolate()->object_store()->closure_functions());
    bool found = false;
    for (intptr_t i = 0; i < closure_functions.Length(); i++) {
      func_ ^= closure_functions.At(i);
      if ((func_.Owner() == cls_.raw()) &&
          (func_.token_pos().value() == token_pos)) {
        found = true;
        break;
      }
    }
    if (!found) {
      func_ = Function::null();
    }
  } 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
