17a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross/* 27a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * Copyright (C) 2016 The Android Open Source Project 37a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * 47a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * Licensed under the Apache License, Version 2.0 (the "License"); 57a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * you may not use this file except in compliance with the License. 67a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * You may obtain a copy of the License at 77a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * 87a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * http://www.apache.org/licenses/LICENSE-2.0 97a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * 107a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * Unless required by applicable law or agreed to in writing, software 117a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * distributed under the License is distributed on an "AS IS" BASIS, 127a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * See the License for the specific language governing permissions and 147a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross * limitations under the License. 157a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross */ 167a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross 177a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross#ifndef LIBMEMUNREACHABLE_LEAK_H_ 187a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross#define LIBMEMUNREACHABLE_LEAK_H_ 197a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross 207a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross#include <functional> 217a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross#include <vector> 227a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross 237a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross#include "memunreachable/memunreachable.h" 247a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross 257a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross// Custom std::hash specialization so that Leak::Backtrace can be used 267a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross// as a key in std::unordered_map. 277a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Crossnamespace std { 287a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross 297a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Crosstemplate<> 307a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Crossstruct hash<Leak::Backtrace> { 317a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross std::size_t operator()(const Leak::Backtrace& key) const { 327a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross std::size_t seed = 0; 337a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross 347a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross hash_combine(seed, key.num_frames); 357a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross for (size_t i = 0; i < key.num_frames; i++) { 367a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross hash_combine(seed, key.frames[i]); 377a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross } 387a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross 397a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross return seed; 407a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross } 417a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross 427a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross private: 437a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross template<typename T> 447a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross inline void hash_combine(std::size_t& seed, const T& v) const { 457a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross std::hash<T> hasher; 467a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 477a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross } 487a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross}; 497a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross 507a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross} // namespace std 517a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross 527a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Crossstatic bool operator==(const Leak::Backtrace& lhs, const Leak::Backtrace& rhs) { 537a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross return (lhs.num_frames == rhs.num_frames) && 547a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross memcmp(lhs.frames, rhs.frames, lhs.num_frames * sizeof(lhs.frames[0])) == 0; 557a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross} 567a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross 577a22e81c20e9a28b9cf7b99e0f46659a2b2a9de7Colin Cross#endif 58