зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 10 changesets (bug 1641090) for asan bustage on ProtocolFuzzer.h. CLOSED TREE
Backed out changeset 9c5e95745919 (bug 1641090) Backed out changeset df8809d1542b (bug 1641090) Backed out changeset 92cde6ee6ade (bug 1641090) Backed out changeset 23d5d734d0bd (bug 1641090) Backed out changeset 6af841322f4d (bug 1641090) Backed out changeset 2ce016edb6fc (bug 1641090) Backed out changeset a513d47956f9 (bug 1641090) Backed out changeset 48bc9ce7afeb (bug 1641090) Backed out changeset 173a1c2e3e55 (bug 1641090) Backed out changeset c915cb660411 (bug 1641090)
This commit is contained in:
Родитель
315b834a0e
Коммит
b4ad19225c
|
@ -71,6 +71,7 @@
|
|||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/hash_tables.h"
|
||||
|
||||
// Windows-style drive letter support and pathname separator characters can be
|
||||
// enabled and disabled independently, to aid testing. These #defines are
|
||||
|
@ -245,4 +246,24 @@ class FilePath {
|
|||
# define FILE_PATH_LITERAL(x) L##x
|
||||
#endif // OS_WIN
|
||||
|
||||
// Implement hash function so that we can use FilePaths in hashsets and maps.
|
||||
#if defined(COMPILER_GCC) && !defined(ANDROID)
|
||||
namespace __gnu_cxx {
|
||||
|
||||
template <>
|
||||
struct hash<FilePath> {
|
||||
size_t operator()(const FilePath& f) const {
|
||||
return hash<FilePath::StringType>()(f.value());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __gnu_cxx
|
||||
#elif defined(COMPILER_MSVC)
|
||||
namespace stdext {
|
||||
|
||||
inline size_t hash_value(const FilePath& f) { return hash_value(f.value()); }
|
||||
|
||||
} // namespace stdext
|
||||
#endif // COMPILER
|
||||
|
||||
#endif // BASE_FILE_PATH_H_
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
|
||||
//
|
||||
// Deal with the differences between Microsoft and GNU implemenations
|
||||
// of hash_map. Allows all platforms to use |base::hash_map| and
|
||||
// |base::hash_set|.
|
||||
// eg:
|
||||
// base::hash_map<int> my_map;
|
||||
// base::hash_set<int> my_set;
|
||||
//
|
||||
|
||||
#ifndef BASE_HASH_TABLES_H_
|
||||
#define BASE_HASH_TABLES_H_
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "base/string16.h"
|
||||
|
||||
#if defined(COMPILER_MSVC) || (defined(ANDROID) && defined(_STLP_STD_NAME))
|
||||
# ifdef COMPILER_MSVC
|
||||
# pragma push_macro("_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS")
|
||||
# define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
|
||||
# endif
|
||||
|
||||
// Suppress -Wshadow warnings from stlport headers.
|
||||
# ifdef __GNUC__
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wshadow"
|
||||
# if MOZ_GCC_VERSION_AT_LEAST(4, 9, 0)
|
||||
# pragma GCC diagnostic ignored "-Wshadow-local"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# include <hash_map>
|
||||
# include <hash_set>
|
||||
|
||||
# ifdef __GNUC__
|
||||
# if MOZ_GCC_VERSION_AT_LEAST(4, 9, 0)
|
||||
# pragma GCC diagnostic pop // -Wshadow-local
|
||||
# endif
|
||||
# pragma GCC diagnostic pop // -Wshadow
|
||||
# endif
|
||||
|
||||
# ifdef COMPILER_MSVC
|
||||
# pragma pop_macro("_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS")
|
||||
# endif
|
||||
namespace base {
|
||||
# ifdef ANDROID
|
||||
using _STLP_STD_NAME::hash_map;
|
||||
using _STLP_STD_NAME::hash_set;
|
||||
# else
|
||||
using stdext::hash_map;
|
||||
using stdext::hash_set;
|
||||
# endif
|
||||
} // namespace base
|
||||
#elif defined(COMPILER_GCC)
|
||||
// This is a hack to disable the gcc 4.4 warning about hash_map and hash_set
|
||||
// being deprecated. We can get rid of this when we upgrade to VS2008 and we
|
||||
// can use <tr1/unordered_map> and <tr1/unordered_set>.
|
||||
# ifdef __DEPRECATED
|
||||
# define CHROME_OLD__DEPRECATED __DEPRECATED
|
||||
# undef __DEPRECATED
|
||||
# endif
|
||||
|
||||
# include <ext/hash_map>
|
||||
# include <ext/hash_set>
|
||||
# include <string>
|
||||
|
||||
# ifdef CHROME_OLD__DEPRECATED
|
||||
# define __DEPRECATED CHROME_OLD__DEPRECATED
|
||||
# undef CHROME_OLD__DEPRECATED
|
||||
# endif
|
||||
|
||||
namespace base {
|
||||
using __gnu_cxx::hash_map;
|
||||
using __gnu_cxx::hash_set;
|
||||
} // namespace base
|
||||
|
||||
namespace __gnu_cxx {
|
||||
|
||||
// The GNU C++ library provides identiy hash functions for many integral types,
|
||||
// but not for |long long|. This hash function will truncate if |size_t| is
|
||||
// narrower than |long long|. This is probably good enough for what we will
|
||||
// use it for.
|
||||
|
||||
# define DEFINE_TRIVIAL_HASH(integral_type) \
|
||||
template <> \
|
||||
struct hash<integral_type> { \
|
||||
std::size_t operator()(integral_type value) const { \
|
||||
return static_cast<std::size_t>(value); \
|
||||
} \
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_HASH(long long);
|
||||
DEFINE_TRIVIAL_HASH(unsigned long long);
|
||||
|
||||
# undef DEFINE_TRIVIAL_HASH
|
||||
|
||||
// Implement string hash functions so that strings of various flavors can
|
||||
// be used as keys in STL maps and sets. The hash algorithm comes from the
|
||||
// GNU C++ library, in <tr1/functional>. It is duplicated here because GCC
|
||||
// versions prior to 4.3.2 are unable to compile <tr1/functional> when RTTI
|
||||
// is disabled, as it is in our build.
|
||||
|
||||
# define DEFINE_STRING_HASH(string_type) \
|
||||
template <> \
|
||||
struct hash<string_type> { \
|
||||
std::size_t operator()(const string_type& s) const { \
|
||||
std::size_t result = 0; \
|
||||
for (string_type::const_iterator i = s.begin(); i != s.end(); ++i) \
|
||||
result = (result * 131) + *i; \
|
||||
return result; \
|
||||
} \
|
||||
}
|
||||
|
||||
DEFINE_STRING_HASH(std::string);
|
||||
DEFINE_STRING_HASH(std::wstring);
|
||||
|
||||
# if defined(WCHAR_T_IS_UTF32)
|
||||
// If string16 and std::wstring are not the same type, provide a
|
||||
// specialization for string16.
|
||||
DEFINE_STRING_HASH(string16);
|
||||
# endif // WCHAR_T_IS_UTF32
|
||||
|
||||
# undef DEFINE_STRING_HASH
|
||||
|
||||
} // namespace __gnu_cxx
|
||||
|
||||
#endif // COMPILER
|
||||
|
||||
#endif // BASE_HASH_TABLES_H_
|
|
@ -0,0 +1,104 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef BASE_ID_MAP_H__
|
||||
#define BASE_ID_MAP_H__
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/hash_tables.h"
|
||||
#include "base/logging.h"
|
||||
|
||||
// This object maintains a list of IDs that can be quickly converted to
|
||||
// objects. It is implemented as a hash table, optimized for
|
||||
// relatively small data sets (in the common case, there will be exactly one
|
||||
// item in the list).
|
||||
//
|
||||
// Items can be inserted into the container with arbitrary ID, but the caller
|
||||
// must ensure they are unique. Inserting IDs and relying on automatically
|
||||
// generated ones is not allowed because they can collide.
|
||||
template <class T>
|
||||
class IDMap {
|
||||
private:
|
||||
typedef base::hash_map<int32_t, T> HashTable;
|
||||
typedef typename HashTable::iterator iterator;
|
||||
|
||||
public:
|
||||
// support const iterators over the items
|
||||
// Note, use iterator->first to get the ID, iterator->second to get the T*
|
||||
typedef typename HashTable::const_iterator const_iterator;
|
||||
|
||||
IDMap() : next_id_(1) {}
|
||||
IDMap(const IDMap& other) : next_id_(other.next_id_), data_(other.data_) {}
|
||||
|
||||
const_iterator begin() const { return data_.begin(); }
|
||||
const_iterator end() const { return data_.end(); }
|
||||
|
||||
// Adds a view with an automatically generated unique ID. See AddWithID.
|
||||
int32_t Add(const T& data) {
|
||||
int32_t this_id = next_id_;
|
||||
DCHECK(data_.find(this_id) == data_.end()) << "Inserting duplicate item";
|
||||
data_[this_id] = data;
|
||||
next_id_++;
|
||||
return this_id;
|
||||
}
|
||||
|
||||
// Adds a new data member with the specified ID. The ID must not be in
|
||||
// the list. The caller either must generate all unique IDs itself and use
|
||||
// this function, or allow this object to generate IDs and call Add. These
|
||||
// two methods may not be mixed, or duplicate IDs may be generated
|
||||
void AddWithID(const T& data, int32_t id) {
|
||||
DCHECK(data_.find(id) == data_.end()) << "Inserting duplicate item";
|
||||
data_[id] = data;
|
||||
}
|
||||
|
||||
void Remove(int32_t id) {
|
||||
iterator i = data_.find(id);
|
||||
if (i == data_.end()) {
|
||||
NOTREACHED() << "Attempting to remove an item not in the list";
|
||||
return;
|
||||
}
|
||||
data_.erase(i);
|
||||
}
|
||||
|
||||
void RemoveIfPresent(int32_t id) {
|
||||
iterator i = data_.find(id);
|
||||
if (i != data_.end()) {
|
||||
data_.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ReplaceWithID(const T& data, int32_t id) {
|
||||
DCHECK(data_.find(id) != data_.end()) << "item doesn't exist";
|
||||
data_[id] = data;
|
||||
}
|
||||
|
||||
bool IsEmpty() const { return data_.empty(); }
|
||||
|
||||
void Clear() { data_.clear(); }
|
||||
|
||||
bool HasData(const T& data) const {
|
||||
// XXX would like to use <algorithm> here ...
|
||||
for (const_iterator it = begin(); it != end(); ++it)
|
||||
if (data == it->second) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
T Lookup(int32_t id) const {
|
||||
const_iterator i = data_.find(id);
|
||||
if (i == data_.end()) return T();
|
||||
return i->second;
|
||||
}
|
||||
|
||||
size_t size() const { return data_.size(); }
|
||||
|
||||
protected:
|
||||
// The next ID that we will return from Add()
|
||||
int32_t next_id_;
|
||||
|
||||
HashTable data_;
|
||||
};
|
||||
|
||||
#endif // BASE_ID_MAP_H__
|
|
@ -649,10 +649,9 @@ int32_t IToplevelProtocol::Register(IProtocol* aRouted) {
|
|||
// Inherit our event target from our manager.
|
||||
if (IProtocol* manager = aRouted->Manager()) {
|
||||
MutexAutoLock lock(mEventTargetMutex);
|
||||
if (nsCOMPtr<nsIEventTarget> target = mEventTargetMap.Get(manager->Id())) {
|
||||
MOZ_ASSERT(!mEventTargetMap.Contains(id),
|
||||
"Don't insert with an existing ID");
|
||||
mEventTargetMap.Put(id, target);
|
||||
if (nsCOMPtr<nsIEventTarget> target =
|
||||
mEventTargetMap.Lookup(manager->Id())) {
|
||||
mEventTargetMap.AddWithID(target, id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,20 +661,19 @@ int32_t IToplevelProtocol::Register(IProtocol* aRouted) {
|
|||
int32_t IToplevelProtocol::RegisterID(IProtocol* aRouted, int32_t aId) {
|
||||
aRouted->SetId(aId);
|
||||
aRouted->ActorConnected();
|
||||
MOZ_ASSERT(!mActorMap.Contains(aId), "Don't insert with an existing ID");
|
||||
mActorMap.Put(aId, aRouted);
|
||||
mActorMap.AddWithID(aRouted, aId);
|
||||
return aId;
|
||||
}
|
||||
|
||||
IProtocol* IToplevelProtocol::Lookup(int32_t aId) { return mActorMap.Get(aId); }
|
||||
IProtocol* IToplevelProtocol::Lookup(int32_t aId) {
|
||||
return mActorMap.Lookup(aId);
|
||||
}
|
||||
|
||||
void IToplevelProtocol::Unregister(int32_t aId) {
|
||||
MOZ_ASSERT(mActorMap.Contains(aId),
|
||||
"Attempting to remove an ID not in the actor map");
|
||||
mActorMap.Remove(aId);
|
||||
|
||||
MutexAutoLock lock(mEventTargetMutex);
|
||||
mEventTargetMap.Remove(aId);
|
||||
mEventTargetMap.RemoveIfPresent(aId);
|
||||
}
|
||||
|
||||
Shmem::SharedMemory* IToplevelProtocol::CreateSharedMemory(
|
||||
|
@ -708,22 +706,16 @@ Shmem::SharedMemory* IToplevelProtocol::CreateSharedMemory(
|
|||
|
||||
*aId = shmem.Id(Shmem::PrivateIPDLCaller());
|
||||
Shmem::SharedMemory* rawSegment = segment.get();
|
||||
MOZ_ASSERT(!mShmemMap.Contains(*aId), "Don't insert with an existing ID");
|
||||
mShmemMap.Put(*aId, segment.forget().take());
|
||||
mShmemMap.AddWithID(segment.forget().take(), *aId);
|
||||
return rawSegment;
|
||||
}
|
||||
|
||||
Shmem::SharedMemory* IToplevelProtocol::LookupSharedMemory(Shmem::id_t aId) {
|
||||
return mShmemMap.Get(aId);
|
||||
return mShmemMap.Lookup(aId);
|
||||
}
|
||||
|
||||
bool IToplevelProtocol::IsTrackingSharedMemory(Shmem::SharedMemory* segment) {
|
||||
for (const auto& iter : mShmemMap) {
|
||||
if (segment == iter.GetData()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return mShmemMap.HasData(segment);
|
||||
}
|
||||
|
||||
bool IToplevelProtocol::DestroySharedMemory(Shmem& shmem) {
|
||||
|
@ -736,8 +728,6 @@ bool IToplevelProtocol::DestroySharedMemory(Shmem& shmem) {
|
|||
Message* descriptor =
|
||||
shmem.UnshareFrom(Shmem::PrivateIPDLCaller(), MSG_ROUTING_CONTROL);
|
||||
|
||||
MOZ_ASSERT(mShmemMap.Contains(aId),
|
||||
"Attempting to remove an ID not in the shmem map");
|
||||
mShmemMap.Remove(aId);
|
||||
Shmem::Dealloc(Shmem::PrivateIPDLCaller(), segment);
|
||||
|
||||
|
@ -751,8 +741,9 @@ bool IToplevelProtocol::DestroySharedMemory(Shmem& shmem) {
|
|||
}
|
||||
|
||||
void IToplevelProtocol::DeallocShmems() {
|
||||
for (const auto& cit : mShmemMap) {
|
||||
Shmem::Dealloc(Shmem::PrivateIPDLCaller(), cit.GetData());
|
||||
for (IDMap<SharedMemory*>::const_iterator cit = mShmemMap.begin();
|
||||
cit != mShmemMap.end(); ++cit) {
|
||||
Shmem::Dealloc(Shmem::PrivateIPDLCaller(), cit->second);
|
||||
}
|
||||
mShmemMap.Clear();
|
||||
}
|
||||
|
@ -764,8 +755,7 @@ bool IToplevelProtocol::ShmemCreated(const Message& aMsg) {
|
|||
if (!rawmem) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(!mShmemMap.Contains(id), "Don't insert with an existing ID");
|
||||
mShmemMap.Put(id, rawmem.forget().take());
|
||||
mShmemMap.AddWithID(rawmem.forget().take(), id);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -779,8 +769,6 @@ bool IToplevelProtocol::ShmemDestroyed(const Message& aMsg) {
|
|||
|
||||
Shmem::SharedMemory* rawmem = LookupSharedMemory(id);
|
||||
if (rawmem) {
|
||||
MOZ_ASSERT(mShmemMap.Contains(id),
|
||||
"Attempting to remove an ID not in the shmem map");
|
||||
mShmemMap.Remove(id);
|
||||
Shmem::Dealloc(Shmem::PrivateIPDLCaller(), rawmem);
|
||||
}
|
||||
|
@ -794,7 +782,7 @@ already_AddRefed<nsIEventTarget> IToplevelProtocol::GetMessageEventTarget(
|
|||
Maybe<MutexAutoLock> lock;
|
||||
lock.emplace(mEventTargetMutex);
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target = mEventTargetMap.Get(route);
|
||||
nsCOMPtr<nsIEventTarget> target = mEventTargetMap.Lookup(route);
|
||||
|
||||
if (aMsg.is_constructor()) {
|
||||
ActorHandle handle;
|
||||
|
@ -804,13 +792,18 @@ already_AddRefed<nsIEventTarget> IToplevelProtocol::GetMessageEventTarget(
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// If this function is called more than once for the same message, the actor
|
||||
// handle ID will already be in the map, but it should have the same target.
|
||||
nsCOMPtr<nsIEventTarget> existingTgt = mEventTargetMap.Get(handle.mId);
|
||||
// If this function is called more than once for the same message,
|
||||
// the actor handle ID will already be in the map and the AddWithID
|
||||
// call below will trigger a crash in DEBUG builds. Avoid this by
|
||||
// removing the entry first and ASSERTing that if the ID has already
|
||||
// been inserted, it matches the provided |aMsg| ID. If the ASSERT fails,
|
||||
// the map contains a different event target which is unexpected.
|
||||
nsCOMPtr<nsIEventTarget> existingTgt = mEventTargetMap.Lookup(handle.mId);
|
||||
MOZ_ASSERT(existingTgt == target || existingTgt == nullptr);
|
||||
mEventTargetMap.RemoveIfPresent(handle.mId);
|
||||
#endif /* DEBUG */
|
||||
|
||||
mEventTargetMap.Put(handle.mId, target);
|
||||
mEventTargetMap.AddWithID(target, handle.mId);
|
||||
}
|
||||
|
||||
return target.forget();
|
||||
|
@ -822,7 +815,7 @@ already_AddRefed<nsIEventTarget> IToplevelProtocol::GetActorEventTarget(
|
|||
aActor->Id() != kFreedActorId);
|
||||
|
||||
MutexAutoLock lock(mEventTargetMutex);
|
||||
nsCOMPtr<nsIEventTarget> target = mEventTargetMap.Get(aActor->Id());
|
||||
nsCOMPtr<nsIEventTarget> target = mEventTargetMap.Lookup(aActor->Id());
|
||||
return target.forget();
|
||||
}
|
||||
|
||||
|
@ -851,7 +844,16 @@ void IToplevelProtocol::SetEventTargetForActorInternal(
|
|||
|
||||
MutexAutoLock lock(mEventTargetMutex);
|
||||
// FIXME bug 1445121 - sometimes the id is already mapped.
|
||||
mEventTargetMap.Put(id, aEventTarget);
|
||||
// (IDMap debug-asserts that the existing state is as expected.)
|
||||
bool replace = false;
|
||||
#ifdef DEBUG
|
||||
replace = mEventTargetMap.Lookup(id) != nullptr;
|
||||
#endif
|
||||
if (replace) {
|
||||
mEventTargetMap.ReplaceWithID(aEventTarget, id);
|
||||
} else {
|
||||
mEventTargetMap.AddWithID(aEventTarget, id);
|
||||
}
|
||||
}
|
||||
|
||||
void IToplevelProtocol::ReplaceEventTargetForActor(
|
||||
|
@ -864,8 +866,7 @@ void IToplevelProtocol::ReplaceEventTargetForActor(
|
|||
MOZ_RELEASE_ASSERT(id != kNullActorId && id != kFreedActorId);
|
||||
|
||||
MutexAutoLock lock(mEventTargetMutex);
|
||||
MOZ_ASSERT(mEventTargetMap.Contains(id), "Only replace an existing ID");
|
||||
mEventTargetMap.Put(id, aEventTarget);
|
||||
mEventTargetMap.ReplaceWithID(aEventTarget, id);
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#ifndef mozilla_ipc_ProtocolUtils_h
|
||||
#define mozilla_ipc_ProtocolUtils_h 1
|
||||
|
||||
#include "base/id_map.h"
|
||||
#include "base/process.h"
|
||||
#include "base/process_util.h"
|
||||
#include "chrome/common/ipc_message_utils.h"
|
||||
|
@ -32,9 +33,6 @@
|
|||
#include "mozilla/UniquePtr.h"
|
||||
#include "MainThreadUtils.h"
|
||||
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
#if defined(ANDROID) && defined(DEBUG)
|
||||
# include <android/log.h>
|
||||
#endif
|
||||
|
@ -520,9 +518,6 @@ class IToplevelProtocol : public IProtocol {
|
|||
|
||||
int32_t NextId();
|
||||
|
||||
template <class T>
|
||||
using IDMap = nsDataHashtable<nsUint32HashKey, T>;
|
||||
|
||||
base::ProcessId mOtherPid;
|
||||
|
||||
// NOTE NOTE NOTE
|
||||
|
|
|
@ -3275,6 +3275,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
#include "prenv.h"
|
||||
#endif // DEBUG
|
||||
|
||||
#include "base/id_map.h"
|
||||
#include "mozilla/Tainting.h"
|
||||
#include "mozilla/ipc/MessageChannel.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче