| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/tags.h" | 5 #include "vm/tags.h" |
| 6 | 6 |
| 7 #include "vm/isolate.h" | 7 #include "vm/isolate.h" |
| 8 #include "vm/json_stream.h" | 8 #include "vm/json_stream.h" |
| 9 #include "vm/native_entry.h" | 9 #include "vm/native_entry.h" |
| 10 #include "vm/object.h" |
| 10 #include "vm/runtime_entry.h" | 11 #include "vm/runtime_entry.h" |
| 11 #include "vm/object.h" | |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 const char* VMTag::TagName(uword tag) { | 15 const char* VMTag::TagName(uword tag) { |
| 16 if (IsNativeEntryTag(tag)) { | 16 if (IsNativeEntryTag(tag)) { |
| 17 const uint8_t* native_reverse_lookup = NativeEntry::ResolveSymbol(tag); | 17 const uint8_t* native_reverse_lookup = NativeEntry::ResolveSymbol(tag); |
| 18 if (native_reverse_lookup != NULL) { | 18 if (native_reverse_lookup != NULL) { |
| 19 return reinterpret_cast<const char*>(native_reverse_lookup); | 19 return reinterpret_cast<const char*>(native_reverse_lookup); |
| 20 } | 20 } |
| 21 return "Unknown native entry"; | 21 return "Unknown native entry"; |
| 22 } else if (IsRuntimeEntryTag(tag)) { | 22 } else if (IsRuntimeEntryTag(tag)) { |
| 23 const char* runtime_entry_name = RuntimeEntryTagName(tag); | 23 const char* runtime_entry_name = RuntimeEntryTagName(tag); |
| 24 ASSERT(runtime_entry_name != NULL); | 24 ASSERT(runtime_entry_name != NULL); |
| 25 return runtime_entry_name; | 25 return runtime_entry_name; |
| 26 } | 26 } |
| 27 ASSERT(tag != kInvalidTagId); | 27 ASSERT(tag != kInvalidTagId); |
| 28 ASSERT(tag < kNumVMTags); | 28 ASSERT(tag < kNumVMTags); |
| 29 const TagEntry& entry = entries_[tag]; | 29 const TagEntry& entry = entries_[tag]; |
| 30 ASSERT(entry.id == tag); | 30 ASSERT(entry.id == tag); |
| 31 return entry.name; | 31 return entry.name; |
| 32 } | 32 } |
| 33 | 33 |
| 34 | |
| 35 bool VMTag::IsNativeEntryTag(uword tag) { | 34 bool VMTag::IsNativeEntryTag(uword tag) { |
| 36 return (tag > kLastTagId) && !IsRuntimeEntryTag(tag); | 35 return (tag > kLastTagId) && !IsRuntimeEntryTag(tag); |
| 37 } | 36 } |
| 38 | 37 |
| 39 | |
| 40 bool VMTag::IsDartTag(uword id) { | 38 bool VMTag::IsDartTag(uword id) { |
| 41 return id == kDartTagId; | 39 return id == kDartTagId; |
| 42 } | 40 } |
| 43 | 41 |
| 44 | |
| 45 bool VMTag::IsExitFrameTag(uword id) { | 42 bool VMTag::IsExitFrameTag(uword id) { |
| 46 return (id != 0) && !IsDartTag(id) && (id != kIdleTagId) && | 43 return (id != 0) && !IsDartTag(id) && (id != kIdleTagId) && |
| 47 (id != kVMTagId) && (id != kEmbedderTagId); | 44 (id != kVMTagId) && (id != kEmbedderTagId); |
| 48 } | 45 } |
| 49 | 46 |
| 50 | |
| 51 static RuntimeEntry* runtime_entry_list = NULL; | 47 static RuntimeEntry* runtime_entry_list = NULL; |
| 52 | 48 |
| 53 | |
| 54 bool VMTag::IsRuntimeEntryTag(uword id) { | 49 bool VMTag::IsRuntimeEntryTag(uword id) { |
| 55 const RuntimeEntry* current = runtime_entry_list; | 50 const RuntimeEntry* current = runtime_entry_list; |
| 56 while (current != NULL) { | 51 while (current != NULL) { |
| 57 if (reinterpret_cast<uword>(current->function()) == id) { | 52 if (reinterpret_cast<uword>(current->function()) == id) { |
| 58 return true; | 53 return true; |
| 59 } | 54 } |
| 60 current = current->next(); | 55 current = current->next(); |
| 61 } | 56 } |
| 62 return false; | 57 return false; |
| 63 } | 58 } |
| 64 | 59 |
| 65 | |
| 66 const char* VMTag::RuntimeEntryTagName(uword id) { | 60 const char* VMTag::RuntimeEntryTagName(uword id) { |
| 67 const RuntimeEntry* current = runtime_entry_list; | 61 const RuntimeEntry* current = runtime_entry_list; |
| 68 while (current != NULL) { | 62 while (current != NULL) { |
| 69 if (reinterpret_cast<uword>(current->function()) == id) { | 63 if (reinterpret_cast<uword>(current->function()) == id) { |
| 70 return current->name(); | 64 return current->name(); |
| 71 } | 65 } |
| 72 current = current->next(); | 66 current = current->next(); |
| 73 } | 67 } |
| 74 return NULL; | 68 return NULL; |
| 75 } | 69 } |
| 76 | 70 |
| 77 | |
| 78 void VMTag::RegisterRuntimeEntry(RuntimeEntry* runtime_entry) { | 71 void VMTag::RegisterRuntimeEntry(RuntimeEntry* runtime_entry) { |
| 79 ASSERT(runtime_entry != NULL); | 72 ASSERT(runtime_entry != NULL); |
| 80 runtime_entry->set_next(runtime_entry_list); | 73 runtime_entry->set_next(runtime_entry_list); |
| 81 runtime_entry_list = runtime_entry; | 74 runtime_entry_list = runtime_entry; |
| 82 } | 75 } |
| 83 | 76 |
| 84 | |
| 85 VMTag::TagEntry VMTag::entries_[] = { | 77 VMTag::TagEntry VMTag::entries_[] = { |
| 86 { | 78 { |
| 87 "InvalidTag", kInvalidTagId, | 79 "InvalidTag", kInvalidTagId, |
| 88 }, | 80 }, |
| 89 #define DEFINE_VM_TAG_ENTRY(tag) {"" #tag, k##tag##TagId}, | 81 #define DEFINE_VM_TAG_ENTRY(tag) {"" #tag, k##tag##TagId}, |
| 90 VM_TAG_LIST(DEFINE_VM_TAG_ENTRY) | 82 VM_TAG_LIST(DEFINE_VM_TAG_ENTRY) |
| 91 #undef DEFINE_VM_TAG_ENTRY | 83 #undef DEFINE_VM_TAG_ENTRY |
| 92 {"kNumVMTags", kNumVMTags}, | 84 {"kNumVMTags", kNumVMTags}, |
| 93 }; | 85 }; |
| 94 | 86 |
| 95 | |
| 96 VMTagScope::VMTagScope(Thread* thread, uword tag, bool conditional_set) | 87 VMTagScope::VMTagScope(Thread* thread, uword tag, bool conditional_set) |
| 97 : StackResource(thread) { | 88 : StackResource(thread) { |
| 98 ASSERT(isolate() != NULL); | 89 ASSERT(isolate() != NULL); |
| 99 previous_tag_ = thread->vm_tag(); | 90 previous_tag_ = thread->vm_tag(); |
| 100 if (conditional_set) { | 91 if (conditional_set) { |
| 101 thread->set_vm_tag(tag); | 92 thread->set_vm_tag(tag); |
| 102 } | 93 } |
| 103 } | 94 } |
| 104 | 95 |
| 105 | |
| 106 VMTagScope::~VMTagScope() { | 96 VMTagScope::~VMTagScope() { |
| 107 ASSERT(isolate() != NULL); | 97 ASSERT(isolate() != NULL); |
| 108 thread()->set_vm_tag(previous_tag_); | 98 thread()->set_vm_tag(previous_tag_); |
| 109 } | 99 } |
| 110 | 100 |
| 111 | |
| 112 VMTagCounters::VMTagCounters() { | 101 VMTagCounters::VMTagCounters() { |
| 113 for (intptr_t i = 0; i < VMTag::kNumVMTags; i++) { | 102 for (intptr_t i = 0; i < VMTag::kNumVMTags; i++) { |
| 114 counters_[i] = 0; | 103 counters_[i] = 0; |
| 115 } | 104 } |
| 116 } | 105 } |
| 117 | 106 |
| 118 | |
| 119 void VMTagCounters::Increment(uword tag) { | 107 void VMTagCounters::Increment(uword tag) { |
| 120 if (VMTag::IsRuntimeEntryTag(tag)) { | 108 if (VMTag::IsRuntimeEntryTag(tag)) { |
| 121 counters_[VMTag::kRuntimeTagId]++; | 109 counters_[VMTag::kRuntimeTagId]++; |
| 122 return; | 110 return; |
| 123 } else if (tag > VMTag::kNumVMTags) { | 111 } else if (tag > VMTag::kNumVMTags) { |
| 124 // Assume native entry. | 112 // Assume native entry. |
| 125 counters_[VMTag::kNativeTagId]++; | 113 counters_[VMTag::kNativeTagId]++; |
| 126 return; | 114 return; |
| 127 } | 115 } |
| 128 ASSERT(tag != VMTag::kInvalidTagId); | 116 ASSERT(tag != VMTag::kInvalidTagId); |
| 129 ASSERT(tag < VMTag::kNumVMTags); | 117 ASSERT(tag < VMTag::kNumVMTags); |
| 130 counters_[tag]++; | 118 counters_[tag]++; |
| 131 } | 119 } |
| 132 | 120 |
| 133 | |
| 134 int64_t VMTagCounters::count(uword tag) { | 121 int64_t VMTagCounters::count(uword tag) { |
| 135 ASSERT(tag != VMTag::kInvalidTagId); | 122 ASSERT(tag != VMTag::kInvalidTagId); |
| 136 ASSERT(tag < VMTag::kNumVMTags); | 123 ASSERT(tag < VMTag::kNumVMTags); |
| 137 return counters_[tag]; | 124 return counters_[tag]; |
| 138 } | 125 } |
| 139 | 126 |
| 140 | |
| 141 #ifndef PRODUCT | 127 #ifndef PRODUCT |
| 142 void VMTagCounters::PrintToJSONObject(JSONObject* obj) { | 128 void VMTagCounters::PrintToJSONObject(JSONObject* obj) { |
| 143 if (!FLAG_support_service) { | 129 if (!FLAG_support_service) { |
| 144 return; | 130 return; |
| 145 } | 131 } |
| 146 { | 132 { |
| 147 JSONArray arr(obj, "names"); | 133 JSONArray arr(obj, "names"); |
| 148 for (intptr_t i = 1; i < VMTag::kNumVMTags; i++) { | 134 for (intptr_t i = 1; i < VMTag::kNumVMTags; i++) { |
| 149 arr.AddValue(VMTag::TagName(i)); | 135 arr.AddValue(VMTag::TagName(i)); |
| 150 } | 136 } |
| 151 } | 137 } |
| 152 { | 138 { |
| 153 JSONArray arr(obj, "counters"); | 139 JSONArray arr(obj, "counters"); |
| 154 for (intptr_t i = 1; i < VMTag::kNumVMTags; i++) { | 140 for (intptr_t i = 1; i < VMTag::kNumVMTags; i++) { |
| 155 arr.AddValue64(counters_[i]); | 141 arr.AddValue64(counters_[i]); |
| 156 } | 142 } |
| 157 } | 143 } |
| 158 } | 144 } |
| 159 #endif // !PRODUCT | 145 #endif // !PRODUCT |
| 160 | 146 |
| 161 | |
| 162 const char* UserTags::TagName(uword tag_id) { | 147 const char* UserTags::TagName(uword tag_id) { |
| 163 ASSERT(tag_id >= kUserTagIdOffset); | 148 ASSERT(tag_id >= kUserTagIdOffset); |
| 164 ASSERT(tag_id < kUserTagIdOffset + kMaxUserTags); | 149 ASSERT(tag_id < kUserTagIdOffset + kMaxUserTags); |
| 165 Zone* zone = Thread::Current()->zone(); | 150 Zone* zone = Thread::Current()->zone(); |
| 166 const UserTag& tag = UserTag::Handle(zone, UserTag::FindTagById(tag_id)); | 151 const UserTag& tag = UserTag::Handle(zone, UserTag::FindTagById(tag_id)); |
| 167 ASSERT(!tag.IsNull()); | 152 ASSERT(!tag.IsNull()); |
| 168 const String& label = String::Handle(zone, tag.label()); | 153 const String& label = String::Handle(zone, tag.label()); |
| 169 return label.ToCString(); | 154 return label.ToCString(); |
| 170 } | 155 } |
| 171 | 156 |
| 172 | |
| 173 } // namespace dart | 157 } // namespace dart |
| OLD | NEW |