| Index: src/heap-snapshot-generator.h
|
| diff --git a/src/profile-generator.h b/src/heap-snapshot-generator.h
|
| similarity index 64%
|
| copy from src/profile-generator.h
|
| copy to src/heap-snapshot-generator.h
|
| index 43c737ea19a5e58c2dae8bcb606451aefcef417a..77c659a9959ad9ed6953aeabcae2083215e0edfe 100644
|
| --- a/src/profile-generator.h
|
| +++ b/src/heap-snapshot-generator.h
|
| @@ -1,4 +1,4 @@
|
| -// Copyright 2011 the V8 project authors. All rights reserved.
|
| +// Copyright 2013 the V8 project authors. All rights reserved.
|
| // Redistribution and use in source and binary forms, with or without
|
| // modification, are permitted provided that the following conditions are
|
| // met:
|
| @@ -25,428 +25,12 @@
|
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
| -#ifndef V8_PROFILE_GENERATOR_H_
|
| -#define V8_PROFILE_GENERATOR_H_
|
| -
|
| -#include "allocation.h"
|
| -#include "hashmap.h"
|
| -#include "../include/v8-profiler.h"
|
| +#ifndef V8_HEAP_SNAPSHOT_GENERATOR_H_
|
| +#define V8_HEAP_SNAPSHOT_GENERATOR_H_
|
|
|
| namespace v8 {
|
| namespace internal {
|
|
|
| -class TokenEnumerator {
|
| - public:
|
| - TokenEnumerator();
|
| - ~TokenEnumerator();
|
| - int GetTokenId(Object* token);
|
| -
|
| - static const int kNoSecurityToken = -1;
|
| - static const int kInheritsSecurityToken = -2;
|
| -
|
| - private:
|
| - static void TokenRemovedCallback(v8::Isolate* isolate,
|
| - v8::Persistent<v8::Value> handle,
|
| - void* parameter);
|
| - void TokenRemoved(Object** token_location);
|
| -
|
| - List<Object**> token_locations_;
|
| - List<bool> token_removed_;
|
| -
|
| - friend class TokenEnumeratorTester;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TokenEnumerator);
|
| -};
|
| -
|
| -
|
| -// Provides a storage of strings allocated in C++ heap, to hold them
|
| -// forever, even if they disappear from JS heap or external storage.
|
| -class StringsStorage {
|
| - public:
|
| - StringsStorage();
|
| - ~StringsStorage();
|
| -
|
| - const char* GetCopy(const char* src);
|
| - const char* GetFormatted(const char* format, ...);
|
| - const char* GetVFormatted(const char* format, va_list args);
|
| - const char* GetName(String* name);
|
| - const char* GetName(int index);
|
| - inline const char* GetFunctionName(String* name);
|
| - inline const char* GetFunctionName(const char* name);
|
| - size_t GetUsedMemorySize() const;
|
| -
|
| - private:
|
| - static const int kMaxNameSize = 1024;
|
| -
|
| - INLINE(static bool StringsMatch(void* key1, void* key2)) {
|
| - return strcmp(reinterpret_cast<char*>(key1),
|
| - reinterpret_cast<char*>(key2)) == 0;
|
| - }
|
| - const char* AddOrDisposeString(char* str, uint32_t hash);
|
| -
|
| - // Mapping of strings by String::Hash to const char* strings.
|
| - HashMap names_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(StringsStorage);
|
| -};
|
| -
|
| -
|
| -class CodeEntry {
|
| - public:
|
| - // CodeEntry doesn't own name strings, just references them.
|
| - INLINE(CodeEntry(Logger::LogEventsAndTags tag,
|
| - const char* name_prefix,
|
| - const char* name,
|
| - const char* resource_name,
|
| - int line_number,
|
| - int security_token_id));
|
| -
|
| - INLINE(bool is_js_function() const) { return is_js_function_tag(tag_); }
|
| - INLINE(const char* name_prefix() const) { return name_prefix_; }
|
| - INLINE(bool has_name_prefix() const) { return name_prefix_[0] != '\0'; }
|
| - INLINE(const char* name() const) { return name_; }
|
| - INLINE(const char* resource_name() const) { return resource_name_; }
|
| - INLINE(int line_number() const) { return line_number_; }
|
| - INLINE(int shared_id() const) { return shared_id_; }
|
| - INLINE(void set_shared_id(int shared_id)) { shared_id_ = shared_id; }
|
| - INLINE(int security_token_id() const) { return security_token_id_; }
|
| -
|
| - INLINE(static bool is_js_function_tag(Logger::LogEventsAndTags tag));
|
| -
|
| - void CopyData(const CodeEntry& source);
|
| - uint32_t GetCallUid() const;
|
| - bool IsSameAs(CodeEntry* entry) const;
|
| -
|
| - static const char* const kEmptyNamePrefix;
|
| -
|
| - private:
|
| - Logger::LogEventsAndTags tag_;
|
| - const char* name_prefix_;
|
| - const char* name_;
|
| - const char* resource_name_;
|
| - int line_number_;
|
| - int shared_id_;
|
| - int security_token_id_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(CodeEntry);
|
| -};
|
| -
|
| -
|
| -class ProfileTree;
|
| -
|
| -class ProfileNode {
|
| - public:
|
| - INLINE(ProfileNode(ProfileTree* tree, CodeEntry* entry));
|
| -
|
| - ProfileNode* FindChild(CodeEntry* entry);
|
| - ProfileNode* FindOrAddChild(CodeEntry* entry);
|
| - INLINE(void IncrementSelfTicks()) { ++self_ticks_; }
|
| - INLINE(void IncreaseSelfTicks(unsigned amount)) { self_ticks_ += amount; }
|
| - INLINE(void IncreaseTotalTicks(unsigned amount)) { total_ticks_ += amount; }
|
| -
|
| - INLINE(CodeEntry* entry() const) { return entry_; }
|
| - INLINE(unsigned self_ticks() const) { return self_ticks_; }
|
| - INLINE(unsigned total_ticks() const) { return total_ticks_; }
|
| - INLINE(const List<ProfileNode*>* children() const) { return &children_list_; }
|
| - double GetSelfMillis() const;
|
| - double GetTotalMillis() const;
|
| -
|
| - void Print(int indent);
|
| -
|
| - private:
|
| - INLINE(static bool CodeEntriesMatch(void* entry1, void* entry2)) {
|
| - return reinterpret_cast<CodeEntry*>(entry1)->IsSameAs(
|
| - reinterpret_cast<CodeEntry*>(entry2));
|
| - }
|
| -
|
| - INLINE(static uint32_t CodeEntryHash(CodeEntry* entry)) {
|
| - return entry->GetCallUid();
|
| - }
|
| -
|
| - ProfileTree* tree_;
|
| - CodeEntry* entry_;
|
| - unsigned total_ticks_;
|
| - unsigned self_ticks_;
|
| - // Mapping from CodeEntry* to ProfileNode*
|
| - HashMap children_;
|
| - List<ProfileNode*> children_list_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(ProfileNode);
|
| -};
|
| -
|
| -
|
| -class ProfileTree {
|
| - public:
|
| - ProfileTree();
|
| - ~ProfileTree();
|
| -
|
| - void AddPathFromEnd(const Vector<CodeEntry*>& path);
|
| - void AddPathFromStart(const Vector<CodeEntry*>& path);
|
| - void CalculateTotalTicks();
|
| - void FilteredClone(ProfileTree* src, int security_token_id);
|
| -
|
| - double TicksToMillis(unsigned ticks) const {
|
| - return ticks * ms_to_ticks_scale_;
|
| - }
|
| - ProfileNode* root() const { return root_; }
|
| - void SetTickRatePerMs(double ticks_per_ms);
|
| -
|
| - void ShortPrint();
|
| - void Print() {
|
| - root_->Print(0);
|
| - }
|
| -
|
| - private:
|
| - template <typename Callback>
|
| - void TraverseDepthFirst(Callback* callback);
|
| -
|
| - CodeEntry root_entry_;
|
| - ProfileNode* root_;
|
| - double ms_to_ticks_scale_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(ProfileTree);
|
| -};
|
| -
|
| -
|
| -class CpuProfile {
|
| - public:
|
| - CpuProfile(const char* title, unsigned uid)
|
| - : title_(title), uid_(uid) { }
|
| -
|
| - // Add pc -> ... -> main() call path to the profile.
|
| - void AddPath(const Vector<CodeEntry*>& path);
|
| - void CalculateTotalTicks();
|
| - void SetActualSamplingRate(double actual_sampling_rate);
|
| - CpuProfile* FilteredClone(int security_token_id);
|
| -
|
| - INLINE(const char* title() const) { return title_; }
|
| - INLINE(unsigned uid() const) { return uid_; }
|
| - INLINE(const ProfileTree* top_down() const) { return &top_down_; }
|
| - INLINE(const ProfileTree* bottom_up() const) { return &bottom_up_; }
|
| -
|
| - void UpdateTicksScale();
|
| -
|
| - void ShortPrint();
|
| - void Print();
|
| -
|
| - private:
|
| - const char* title_;
|
| - unsigned uid_;
|
| - ProfileTree top_down_;
|
| - ProfileTree bottom_up_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(CpuProfile);
|
| -};
|
| -
|
| -
|
| -class CodeMap {
|
| - public:
|
| - CodeMap() : next_shared_id_(1) { }
|
| - void AddCode(Address addr, CodeEntry* entry, unsigned size);
|
| - void MoveCode(Address from, Address to);
|
| - CodeEntry* FindEntry(Address addr);
|
| - int GetSharedId(Address addr);
|
| -
|
| - void Print();
|
| -
|
| - private:
|
| - struct CodeEntryInfo {
|
| - CodeEntryInfo(CodeEntry* an_entry, unsigned a_size)
|
| - : entry(an_entry), size(a_size) { }
|
| - CodeEntry* entry;
|
| - unsigned size;
|
| - };
|
| -
|
| - struct CodeTreeConfig {
|
| - typedef Address Key;
|
| - typedef CodeEntryInfo Value;
|
| - static const Key kNoKey;
|
| - static const Value NoValue() { return CodeEntryInfo(NULL, 0); }
|
| - static int Compare(const Key& a, const Key& b) {
|
| - return a < b ? -1 : (a > b ? 1 : 0);
|
| - }
|
| - };
|
| - typedef SplayTree<CodeTreeConfig> CodeTree;
|
| -
|
| - class CodeTreePrinter {
|
| - public:
|
| - void Call(const Address& key, const CodeEntryInfo& value);
|
| - };
|
| -
|
| - void DeleteAllCoveredCode(Address start, Address end);
|
| -
|
| - // Fake CodeEntry pointer to distinguish shared function entries.
|
| - static CodeEntry* const kSharedFunctionCodeEntry;
|
| -
|
| - CodeTree tree_;
|
| - int next_shared_id_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(CodeMap);
|
| -};
|
| -
|
| -
|
| -class CpuProfilesCollection {
|
| - public:
|
| - CpuProfilesCollection();
|
| - ~CpuProfilesCollection();
|
| -
|
| - bool StartProfiling(const char* title, unsigned uid);
|
| - bool StartProfiling(String* title, unsigned uid);
|
| - CpuProfile* StopProfiling(int security_token_id,
|
| - const char* title,
|
| - double actual_sampling_rate);
|
| - List<CpuProfile*>* Profiles(int security_token_id);
|
| - const char* GetName(String* name) {
|
| - return function_and_resource_names_.GetName(name);
|
| - }
|
| - const char* GetName(int args_count) {
|
| - return function_and_resource_names_.GetName(args_count);
|
| - }
|
| - CpuProfile* GetProfile(int security_token_id, unsigned uid);
|
| - bool IsLastProfile(const char* title);
|
| - void RemoveProfile(CpuProfile* profile);
|
| - bool HasDetachedProfiles() { return detached_profiles_.length() > 0; }
|
| -
|
| - CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
|
| - String* name, String* resource_name, int line_number);
|
| - CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, const char* name);
|
| - CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
|
| - const char* name_prefix, String* name);
|
| - CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, int args_count);
|
| - CodeEntry* NewCodeEntry(int security_token_id);
|
| -
|
| - // Called from profile generator thread.
|
| - void AddPathToCurrentProfiles(const Vector<CodeEntry*>& path);
|
| -
|
| - // Limits the number of profiles that can be simultaneously collected.
|
| - static const int kMaxSimultaneousProfiles = 100;
|
| -
|
| - private:
|
| - const char* GetFunctionName(String* name) {
|
| - return function_and_resource_names_.GetFunctionName(name);
|
| - }
|
| - const char* GetFunctionName(const char* name) {
|
| - return function_and_resource_names_.GetFunctionName(name);
|
| - }
|
| - int GetProfileIndex(unsigned uid);
|
| - List<CpuProfile*>* GetProfilesList(int security_token_id);
|
| - int TokenToIndex(int security_token_id);
|
| -
|
| - INLINE(static bool UidsMatch(void* key1, void* key2)) {
|
| - return key1 == key2;
|
| - }
|
| -
|
| - StringsStorage function_and_resource_names_;
|
| - List<CodeEntry*> code_entries_;
|
| - List<List<CpuProfile*>* > profiles_by_token_;
|
| - // Mapping from profiles' uids to indexes in the second nested list
|
| - // of profiles_by_token_.
|
| - HashMap profiles_uids_;
|
| - List<CpuProfile*> detached_profiles_;
|
| -
|
| - // Accessed by VM thread and profile generator thread.
|
| - List<CpuProfile*> current_profiles_;
|
| - Semaphore* current_profiles_semaphore_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection);
|
| -};
|
| -
|
| -
|
| -class SampleRateCalculator {
|
| - public:
|
| - SampleRateCalculator()
|
| - : result_(Logger::kSamplingIntervalMs * kResultScale),
|
| - ticks_per_ms_(Logger::kSamplingIntervalMs),
|
| - measurements_count_(0),
|
| - wall_time_query_countdown_(1) {
|
| - }
|
| -
|
| - double ticks_per_ms() {
|
| - return result_ / static_cast<double>(kResultScale);
|
| - }
|
| - void Tick();
|
| - void UpdateMeasurements(double current_time);
|
| -
|
| - // Instead of querying current wall time each tick,
|
| - // we use this constant to control query intervals.
|
| - static const unsigned kWallTimeQueryIntervalMs = 100;
|
| -
|
| - private:
|
| - // As the result needs to be accessed from a different thread, we
|
| - // use type that guarantees atomic writes to memory. There should
|
| - // be <= 1000 ticks per second, thus storing a value of a 10 ** 5
|
| - // order should provide enough precision while keeping away from a
|
| - // potential overflow.
|
| - static const int kResultScale = 100000;
|
| -
|
| - AtomicWord result_;
|
| - // All other fields are accessed only from the sampler thread.
|
| - double ticks_per_ms_;
|
| - unsigned measurements_count_;
|
| - unsigned wall_time_query_countdown_;
|
| - double last_wall_time_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(SampleRateCalculator);
|
| -};
|
| -
|
| -
|
| -class ProfileGenerator {
|
| - public:
|
| - explicit ProfileGenerator(CpuProfilesCollection* profiles);
|
| -
|
| - INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
|
| - String* name,
|
| - String* resource_name,
|
| - int line_number)) {
|
| - return profiles_->NewCodeEntry(tag, name, resource_name, line_number);
|
| - }
|
| -
|
| - INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
|
| - const char* name)) {
|
| - return profiles_->NewCodeEntry(tag, name);
|
| - }
|
| -
|
| - INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
|
| - const char* name_prefix,
|
| - String* name)) {
|
| - return profiles_->NewCodeEntry(tag, name_prefix, name);
|
| - }
|
| -
|
| - INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
|
| - int args_count)) {
|
| - return profiles_->NewCodeEntry(tag, args_count);
|
| - }
|
| -
|
| - INLINE(CodeEntry* NewCodeEntry(int security_token_id)) {
|
| - return profiles_->NewCodeEntry(security_token_id);
|
| - }
|
| -
|
| - void RecordTickSample(const TickSample& sample);
|
| -
|
| - INLINE(CodeMap* code_map()) { return &code_map_; }
|
| -
|
| - INLINE(void Tick()) { sample_rate_calc_.Tick(); }
|
| - INLINE(double actual_sampling_rate()) {
|
| - return sample_rate_calc_.ticks_per_ms();
|
| - }
|
| -
|
| - static const char* const kAnonymousFunctionName;
|
| - static const char* const kProgramEntryName;
|
| - static const char* const kGarbageCollectorEntryName;
|
| -
|
| - private:
|
| - INLINE(CodeEntry* EntryForVMState(StateTag tag));
|
| -
|
| - CpuProfilesCollection* profiles_;
|
| - CodeMap code_map_;
|
| - CodeEntry* program_entry_;
|
| - CodeEntry* gc_entry_;
|
| - SampleRateCalculator sample_rate_calc_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(ProfileGenerator);
|
| -};
|
| -
|
| -
|
| class HeapEntry;
|
| class HeapSnapshot;
|
|
|
| @@ -1106,6 +690,8 @@ class HeapSnapshotJSONSerializer {
|
| DISALLOW_COPY_AND_ASSIGN(HeapSnapshotJSONSerializer);
|
| };
|
|
|
| +
|
| } } // namespace v8::internal
|
|
|
| -#endif // V8_PROFILE_GENERATOR_H_
|
| +#endif // V8_HEAP_SNAPSHOT_GENERATOR_H_
|
| +
|
|
|