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