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

#include "vm/isolate.h"
#include "vm/json_stream.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/runtime_entry.h"

namespace dart {

MallocGrowableArray<const char*> UserTags::subscribed_tags_(4);
Mutex* UserTags::subscribed_tags_lock_ = nullptr;

const char* VMTag::TagName(uword tag) {
  if (IsNativeEntryTag(tag)) {
    const uint8_t* native_reverse_lookup = NativeEntry::ResolveSymbol(tag);
    if (native_reverse_lookup != NULL) {
      return reinterpret_cast<const char*>(native_reverse_lookup);
    }
    return "Unknown native entry";
  } else if (IsRuntimeEntryTag(tag)) {
    const char* runtime_entry_name = RuntimeEntryTagName(tag);
    ASSERT(runtime_entry_name != NULL);
    return runtime_entry_name;
  }
  ASSERT(tag != kInvalidTagId);
  ASSERT(tag < kNumVMTags);
  const TagEntry& entry = entries_[tag];
  ASSERT(entry.id == tag);
  return entry.name;
}

bool VMTag::IsNativeEntryTag(uword tag) {
  return (tag > kLastTagId) && !IsRuntimeEntryTag(tag);
}

bool VMTag::IsDartTag(uword id) {
  return (id == kDartTagId);
}

bool VMTag::IsExitFrameTag(uword id) {
  return (id != 0) && !IsDartTag(id) && (id != kIdleTagId) &&
         (id != kVMTagId) && (id != kEmbedderTagId);
}

bool VMTag::IsRuntimeEntryTag(uword id) {
  return RuntimeEntryTagName(id) != nullptr;
}

const char* VMTag::RuntimeEntryTagName(uword id) {
  void* address = reinterpret_cast<void*>(id);

#define CHECK_RUNTIME_ADDRESS(n)                                               \
  if (address == k##n##RuntimeEntry.function())                                \
    return k##n##RuntimeEntry.name();
  RUNTIME_ENTRY_LIST(CHECK_RUNTIME_ADDRESS)
#undef CHECK_RUNTIME_ADDRESS

#define CHECK_LEAF_RUNTIME_ADDRESS(type, n, ...)                               \
  if (address == k##n##RuntimeEntry.function())                                \
    return k##n##RuntimeEntry.name();
  LEAF_RUNTIME_ENTRY_LIST(CHECK_LEAF_RUNTIME_ADDRESS)
#undef CHECK_LEAF_RUNTIME_ADDRESS

  return nullptr;
}

const VMTag::TagEntry VMTag::entries_[] = {
    {
        "InvalidTag",
        kInvalidTagId,
    },
#define DEFINE_VM_TAG_ENTRY(tag) {"" #tag, k##tag##TagId},
    VM_TAG_LIST(DEFINE_VM_TAG_ENTRY)
#undef DEFINE_VM_TAG_ENTRY
        {"kNumVMTags", kNumVMTags},
};

VMTagScope::VMTagScope(Thread* thread, uword tag, bool conditional_set)
    : ThreadStackResource(thread) {
  if (thread != NULL) {
    ASSERT(isolate_group() != NULL);
    previous_tag_ = thread->vm_tag();
    if (conditional_set) {
      thread->set_vm_tag(tag);
    }
  }
}

VMTagScope::~VMTagScope() {
  if (thread() != NULL) {
    ASSERT(isolate_group() != NULL);
    thread()->set_vm_tag(previous_tag_);
  }
}

VMTagCounters::VMTagCounters() {
  for (intptr_t i = 0; i < VMTag::kNumVMTags; i++) {
    counters_[i] = 0;
  }
}

void VMTagCounters::Increment(uword tag) {
  if (VMTag::IsRuntimeEntryTag(tag)) {
    counters_[VMTag::kRuntimeTagId]++;
    return;
  } else if (tag > VMTag::kNumVMTags) {
    // Assume native entry.
    counters_[VMTag::kNativeTagId]++;
    return;
  }
  ASSERT(tag != VMTag::kInvalidTagId);
  ASSERT(tag < VMTag::kNumVMTags);
  counters_[tag]++;
}

int64_t VMTagCounters::count(uword tag) {
  ASSERT(tag != VMTag::kInvalidTagId);
  ASSERT(tag < VMTag::kNumVMTags);
  return counters_[tag];
}

#ifndef PRODUCT
void VMTagCounters::PrintToJSONObject(JSONObject* obj) {
  {
    JSONArray arr(obj, "names");
    for (intptr_t i = 1; i < VMTag::kNumVMTags; i++) {
      arr.AddValue(VMTag::TagName(i));
    }
  }
  {
    JSONArray arr(obj, "counters");
    for (intptr_t i = 1; i < VMTag::kNumVMTags; i++) {
      arr.AddValue64(counters_[i]);
    }
  }
}
#endif  // !PRODUCT

const char* UserTags::TagName(uword tag_id) {
  ASSERT(tag_id >= kUserTagIdOffset);
  ASSERT(tag_id < kUserTagIdOffset + kMaxUserTags);
  Zone* zone = Thread::Current()->zone();
  const UserTag& tag = UserTag::Handle(zone, UserTag::FindTagById(tag_id));
  ASSERT(!tag.IsNull());
  const String& label = String::Handle(zone, tag.label());
  return label.ToCString();
}

void UserTags::AddStreamableTagName(const char* tag) {
  MutexLocker ml(subscribed_tags_lock_);
  // Check this tag isn't already in the subscription list.
  for (intptr_t i = 0; i < subscribed_tags_.length(); ++i) {
    if (strcmp(tag, subscribed_tags_.At(i)) == 0) {
      return;
    }
  }
  subscribed_tags_.Add(strdup(tag));
}

void UserTags::RemoveStreamableTagName(const char* tag) {
  MutexLocker ml(subscribed_tags_lock_);
  bool found = false;
  for (intptr_t i = 0; i < subscribed_tags_.length(); ++i) {
    if (strcmp(tag, subscribed_tags_.At(i)) == 0) {
      free(const_cast<char*>(subscribed_tags_.At(i)));
      subscribed_tags_.RemoveAt(i);
      found = true;
      break;
    }
  }
  ASSERT(found);
}

bool UserTags::IsTagNameStreamable(const char* tag) {
  MutexLocker ml(subscribed_tags_lock_);
  for (intptr_t i = 0; i < subscribed_tags_.length(); ++i) {
    if (strcmp(tag, subscribed_tags_.At(i)) == 0) {
      return true;
    }
  }
  return false;
}

void UserTags::Init() {
  subscribed_tags_lock_ = new Mutex();
}

void UserTags::Cleanup() {
  {
    MutexLocker ml(subscribed_tags_lock_);
    for (intptr_t i = 0; i < subscribed_tags_.length(); ++i) {
      free(const_cast<char*>(subscribed_tags_.At(i)));
    }
    subscribed_tags_.Clear();
  }
  delete subscribed_tags_lock_;
  subscribed_tags_lock_ = nullptr;
}

}  // namespace dart
