trace.h revision 0791adc2249366c50684935a4c42ba5e58bc3746
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 17e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#ifndef ART_SRC_TRACE_H_ 18e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#define ART_SRC_TRACE_H_ 19e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 20e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include <map> 21a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <ostream> 22a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <set> 23a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <string> 24e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 25a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include "file.h" 26e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "globals.h" 27e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "macros.h" 282692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao#include "UniquePtr.h" 29e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 30e343b76af81a005ef64f5e75a555389fd9147dabjeffhaonamespace art { 31e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 32e343b76af81a005ef64f5e75a555389fd9147dabjeffhaoclass Method; 33a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhaoclass Thread; 34e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 3557b86d47b66322693a070185fadfb43cb9c12eabIan Rogersuint32_t TraceMethodUnwindFromCode(Thread* self); 3657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers 37e343b76af81a005ef64f5e75a555389fd9147dabjeffhaostruct TraceStackFrame { 38e343b76af81a005ef64f5e75a555389fd9147dabjeffhao TraceStackFrame(Method* method, uintptr_t return_pc) 39e343b76af81a005ef64f5e75a555389fd9147dabjeffhao : method_(method), return_pc_(return_pc) { 40e343b76af81a005ef64f5e75a555389fd9147dabjeffhao } 41e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 42e343b76af81a005ef64f5e75a555389fd9147dabjeffhao Method* method_; 43e343b76af81a005ef64f5e75a555389fd9147dabjeffhao uintptr_t return_pc_; 44e343b76af81a005ef64f5e75a555389fd9147dabjeffhao}; 45e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 46e343b76af81a005ef64f5e75a555389fd9147dabjeffhaoclass Trace { 47e343b76af81a005ef64f5e75a555389fd9147dabjeffhao public: 48a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 49a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao enum TraceEvent { 50a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao kMethodTraceEnter = 0, 51a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao kMethodTraceExit = 1, 52a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao kMethodTraceUnwind = 2, 53a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao }; 54a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 550791adc2249366c50684935a4c42ba5e58bc3746jeffhao enum TraceFlag { 560791adc2249366c50684935a4c42ba5e58bc3746jeffhao kTraceCountAllocs = 1, 570791adc2249366c50684935a4c42ba5e58bc3746jeffhao }; 580791adc2249366c50684935a4c42ba5e58bc3746jeffhao 59e343b76af81a005ef64f5e75a555389fd9147dabjeffhao static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags, bool direct_to_ddms); 60e343b76af81a005ef64f5e75a555389fd9147dabjeffhao static void Stop(); 61b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao static void Shutdown(); 62e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 632692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao void LogMethodTraceEvent(Thread* self, const Method* method, TraceEvent event); 64a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 652692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao void AddSavedCodeToMap(const Method* method, const void* code); 662692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao void RemoveSavedCodeFromMap(const Method* method); 672692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao const void* GetSavedCodeFromMap(const Method* method); 68e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 69b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao void SaveAndUpdateCode(Method* method); 702692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao void ResetSavedCode(Method* method); 71e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 72e343b76af81a005ef64f5e75a555389fd9147dabjeffhao private: 730791adc2249366c50684935a4c42ba5e58bc3746jeffhao explicit Trace(File* trace_file, int buffer_size, int flags) 740791adc2249366c50684935a4c42ba5e58bc3746jeffhao : trace_file_(trace_file), buf_(new uint8_t[buffer_size]()), flags_(flags), overflow_(false), 750791adc2249366c50684935a4c42ba5e58bc3746jeffhao buffer_size_(buffer_size), start_time_(0), trace_version_(0), record_size_(0), cur_offset_(0) { 762692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao } 772692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 782692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao void BeginTracing(); 792692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao void FinishTracing(); 802692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 81e343b76af81a005ef64f5e75a555389fd9147dabjeffhao // Replaces code of each method with a pointer to a stub for method tracing. 822692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao void InstallStubs(); 83e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 84e343b76af81a005ef64f5e75a555389fd9147dabjeffhao // Restores original code for each method and fixes the return values of each thread's stack. 852692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao void UninstallStubs(); 86e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 87a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // Methods to output traced methods and threads. 882692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao void GetVisitedMethods(size_t end_offset); 892692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao void DumpMethodList(std::ostream& os); 902692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao void DumpThreadList(std::ostream& os); 912692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 922692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao // Maps a method to its original code pointer. 932692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao std::map<const Method*, const void*> saved_code_map_; 942692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 952692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao // Set of methods visited by the profiler. 962692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao std::set<const Method*> visited_methods_; 972692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 982692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao // Maps a thread to its clock base. 992692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao std::map<Thread*, uint64_t> thread_clock_base_map_; 1002692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1012692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao // File to write trace data out to, NULL if direct to ddms. 1022692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao UniquePtr<File> trace_file_; 1032692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1042692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao // Buffer to store trace data. 1052692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao UniquePtr<uint8_t> buf_; 1062692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1070791adc2249366c50684935a4c42ba5e58bc3746jeffhao // Flags enabling extra tracing of things such as alloc counts. 1080791adc2249366c50684935a4c42ba5e58bc3746jeffhao int flags_; 1090791adc2249366c50684935a4c42ba5e58bc3746jeffhao 1102692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao bool overflow_; 1112692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao int buffer_size_; 1122692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao uint64_t start_time_; 1132692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao uint16_t trace_version_; 1142692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao uint16_t record_size_; 1152692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1162692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao volatile int32_t cur_offset_; 117a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 118e343b76af81a005ef64f5e75a555389fd9147dabjeffhao DISALLOW_COPY_AND_ASSIGN(Trace); 119e343b76af81a005ef64f5e75a555389fd9147dabjeffhao}; 120e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 121e343b76af81a005ef64f5e75a555389fd9147dabjeffhao} // namespace art 122e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 123e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#endif // ART_SRC_TRACE_H_ 124