fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / slideshow / source / engine / sp_debug.cxx
bloba949809581993f16c5ca711b68402d90e2bba652
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 // sp_collector.cpp
24 // Copyright (c) 2002, 2003 Peter Dimov
26 // Permission to copy, use, modify, sell and distribute this software
27 // is granted provided this copyright notice appears in all copies.
28 // This software is provided "as is" without express or implied
29 // warranty, and with no claim as to its suitability for any purpose.
32 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
34 #include <boost/assert.hpp>
35 #include <boost/scoped_array.hpp>
36 #include <boost/scoped_ptr.hpp>
37 #include <boost/shared_ptr.hpp>
38 #include <boost/detail/lightweight_mutex.hpp>
39 #include <canvas/debug.hxx>
40 #include <cstdlib>
41 #include <map>
42 #include <deque>
43 #include <iostream>
45 typedef std::map< void const *, std::pair<void *, size_t> > map_type;
47 static map_type & get_map()
49 static map_type m;
50 return m;
53 typedef boost::detail::lightweight_mutex mutex_type;
55 static mutex_type & get_mutex()
57 static mutex_type m;
58 return m;
61 static void * init_mutex_before_main = &get_mutex();
63 namespace
65 class X;
67 struct count_layout
69 boost::detail::sp_counted_base * pi;
70 int id;
73 struct shared_ptr_layout
75 X * px;
76 count_layout pn;
80 // assume 4 byte alignment for pointers when scanning
81 size_t const pointer_align = 4;
83 typedef std::map<void const *, long> map2_type;
85 static void scan_and_count(void const * area, size_t size, map_type const & m, map2_type & m2)
87 unsigned char const * p = static_cast<unsigned char const *>(area);
89 for(size_t n = 0; n + sizeof(shared_ptr_layout) <= size; p += pointer_align, n += pointer_align)
91 shared_ptr_layout const * q = reinterpret_cast<shared_ptr_layout const *>(p);
93 if(q->pn.id == boost::detail::shared_count_id && q->pn.pi != 0 && m.count(q->pn.pi) != 0)
95 ++m2[q->pn.pi];
100 typedef std::deque<void const *> open_type;
102 static void scan_and_mark(void const * area, size_t size, map2_type & m2, open_type & open)
104 unsigned char const * p = static_cast<unsigned char const *>(area);
106 for(size_t n = 0; n + sizeof(shared_ptr_layout) <= size; p += pointer_align, n += pointer_align)
108 shared_ptr_layout const * q = reinterpret_cast<shared_ptr_layout const *>(p);
110 if(q->pn.id == boost::detail::shared_count_id && q->pn.pi != 0 && m2.count(q->pn.pi) != 0)
112 open.push_back(q->pn.pi);
113 m2.erase(q->pn.pi);
118 static void find_unreachable_objects_impl(map_type const & m, map2_type & m2)
120 // scan objects for shared_ptr members, compute internal counts
123 std::cout << "... " << m.size() << " objects in m.\n";
125 for(map_type::const_iterator i = m.begin(); i != m.end(); ++i)
127 BOOST_ASSERT(static_cast<boost::detail::sp_counted_base const *>(i->first)->use_count() != 0); // there should be no inactive counts in the map
129 scan_and_count(i->second.first, i->second.second, m, m2);
132 std::cout << "... " << m2.size() << " objects in m2.\n";
135 // mark reachable objects
138 open_type open;
140 for(map2_type::iterator i = m2.begin(); i != m2.end(); ++i)
142 boost::detail::sp_counted_base const * p = static_cast<boost::detail::sp_counted_base const *>(i->first);
143 if(p->use_count() != i->second) open.push_back(p);
146 std::cout << "... " << m2.size() << " objects in open.\n";
148 for(open_type::iterator j = open.begin(); j != open.end(); ++j)
150 m2.erase(*j);
153 while(!open.empty())
155 void const * p = open.front();
156 open.pop_front();
158 map_type::const_iterator i = m.find(p);
159 BOOST_ASSERT(i != m.end());
161 scan_and_mark(i->second.first, i->second.second, m2, open);
165 // m2 now contains the unreachable objects
168 std::size_t find_unreachable_objects(bool report)
170 map2_type m2;
172 #ifdef BOOST_HAS_THREADS
174 // This will work without the #ifdef, but some compilers warn
175 // that lock is not referenced
177 mutex_type::scoped_lock lock(get_mutex());
179 #endif
181 map_type const & m = get_map();
183 find_unreachable_objects_impl(m, m2);
185 if(report)
187 for(map2_type::iterator j = m2.begin(); j != m2.end(); ++j)
189 map_type::const_iterator i = m.find(j->first);
190 BOOST_ASSERT(i != m.end());
191 std::cout << "Unreachable object at " << i->second.first << ", " << i->second.second << " bytes long.\n";
195 return m2.size();
198 // debug hooks
200 namespace boost
203 void sp_scalar_constructor_hook(void *)
207 void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn)
209 #ifdef BOOST_HAS_THREADS
211 mutex_type::scoped_lock lock(get_mutex());
213 #endif
215 get_map()[pn] = std::make_pair(px, size);
218 void sp_scalar_destructor_hook(void *)
222 void sp_scalar_destructor_hook(void *, std::size_t, void * pn)
224 #ifdef BOOST_HAS_THREADS
226 mutex_type::scoped_lock lock(get_mutex());
228 #endif
230 get_map().erase(pn);
233 void sp_array_constructor_hook(void *)
237 void sp_array_destructor_hook(void *)
241 } // namespace boost
243 #endif // defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */