| // Copyright (c) 2020, 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. |
| |
| #ifndef RUNTIME_VM_COMPILER_AOT_PRECOMPILER_TRACER_H_ |
| #define RUNTIME_VM_COMPILER_AOT_PRECOMPILER_TRACER_H_ |
| |
| #if defined(DART_PRECOMPILED_RUNTIME) |
| #error "AOT runtime should not use compiler sources (including header files)" |
| #endif // defined(DART_PRECOMPILED_RUNTIME) |
| |
| #include "vm/allocation.h" |
| #include "vm/hash_table.h" |
| #include "vm/symbols.h" |
| |
| namespace dart { |
| |
| // Forward declarations. |
| class Precompiler; |
| |
| #if defined(DART_PRECOMPILER) |
| // Tracer which produces machine readable precompiler tracer, which captures |
| // information about all compiled functions and dependencies between them. |
| // See pkg/vm_snapshot_analysis/README.md for the definition of the |
| // format. |
| class PrecompilerTracer : public ZoneAllocated { |
| public: |
| static PrecompilerTracer* StartTracingIfRequested(Precompiler* precompiler); |
| |
| void Finalize(); |
| |
| void WriteEntityRef(const Object& field) { |
| Write("%" Pd ",", InternEntity(field)); |
| } |
| |
| void WriteFieldRef(const Field& field) { WriteEntityRef(field); } |
| |
| void WriteFunctionRef(const Function& function) { WriteEntityRef(function); } |
| |
| void WriteSelectorRef(const String& selector) { |
| Write("\"S\",%" Pd ",", InternString(selector)); |
| } |
| |
| void WriteTableSelectorRef(intptr_t id) { Write("\"T\",%" Pd ",", id); } |
| |
| void WriteClassInstantiationRef(const Class& cls) { WriteEntityRef(cls); } |
| |
| void WriteCompileFunctionEvent(const Function& function) { |
| Write("\"C\","); |
| WriteEntityRef(function); |
| } |
| |
| private: |
| struct CString { |
| const char* str; |
| const intptr_t length; |
| uword hash; |
| }; |
| |
| struct StringTableTraits { |
| static bool ReportStats() { return false; } |
| static const char* Name() { return "StringTableTraits"; } |
| |
| static bool IsMatch(const Object& a, const Object& b) { |
| return String::Cast(a).Equals(String::Cast(b)); |
| } |
| |
| static bool IsMatch(const CString& cstr, const Object& other) { |
| const String& other_str = String::Cast(other); |
| if (other_str.Hash() != cstr.hash) { |
| return false; |
| } |
| |
| if (other_str.Length() != cstr.length) { |
| return false; |
| } |
| |
| return other_str.Equals(cstr.str); |
| } |
| |
| static uword Hash(const CString& cstr) { return cstr.hash; } |
| |
| static uword Hash(const Object& obj) { return String::Cast(obj).Hash(); } |
| |
| static ObjectPtr NewKey(const CString& cstr) { |
| return Symbols::New(Thread::Current(), cstr.str); |
| } |
| }; |
| |
| struct EntityTableTraits { |
| static bool ReportStats() { return false; } |
| static const char* Name() { return "EntityTableTraits"; } |
| |
| static bool IsMatch(const Object& a, const Object& b) { |
| return a.ptr() == b.ptr(); |
| } |
| |
| static uword Hash(const Object& obj) { |
| if (obj.IsFunction()) { |
| return Function::Cast(obj).Hash(); |
| } else if (obj.IsClass()) { |
| return String::HashRawSymbol(Class::Cast(obj).Name()); |
| } else if (obj.IsField()) { |
| return String::HashRawSymbol(Field::Cast(obj).name()); |
| } |
| return obj.GetClassId(); |
| } |
| }; |
| |
| using StringTable = UnorderedHashMap<StringTableTraits>; |
| using EntityTable = UnorderedHashMap<EntityTableTraits>; |
| |
| PrecompilerTracer(Precompiler* precompiler, void* stream); |
| |
| intptr_t InternString(const CString& cstr); |
| intptr_t InternString(const String& str); |
| intptr_t InternEntity(const Object& obj); |
| |
| void Write(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) { |
| va_list va; |
| va_start(va, format); |
| buffer_.VPrintf(format, va); |
| va_end(va); |
| } |
| |
| CString NameForTrace(const Function& f); |
| |
| void WriteEntityTable(); |
| void WriteStringTable(); |
| |
| Zone* zone_; |
| Precompiler* precompiler_; |
| TextBuffer buffer_; |
| void* stream_; |
| StringTable strings_; |
| EntityTable entities_; |
| |
| Object& object_; |
| Class& cls_; |
| }; |
| #endif // defined(DART_PRECOMPILER) |
| |
| } // namespace dart |
| |
| #endif // RUNTIME_VM_COMPILER_AOT_PRECOMPILER_TRACER_H_ |