Exemple #1
0
// parse the heap to find valid objects and initialize metadata, then
// add edges for every known root pointer and every known obj->obj ptr.
HeapGraph makeHeapGraph(bool include_free) {
  HeapGraph g;
  PtrMap blocks;

  // parse the heap once to create a PtrMap for pointer filtering. Create
  // one node for every parsed block, including NativeData and AsyncFuncFrame
  // blocks. Only include free blocks if requested.
  MM().forEachHeader([&](Header* h) {
    if (h->kind() != HeaderKind::Free || include_free) {
      blocks.insert(h); // adds interval [h, h+h->size[
    }
  });
  blocks.prepare();

  // initialize nodes by iterating over PtrMap's regions
  g.nodes.reserve(blocks.size());
  blocks.iterate([&](const Header* h, size_t size) {
    g.nodes.push_back(HeapGraph::Node{h, -1, -1});
  });

  // find roots
  PtrFilter<RootMarker> rmark(g, blocks);
  scanRoots(rmark);

  // find heap->heap pointers
  for (size_t i = 0, n = g.nodes.size(); i < n; i++) {
    auto h = g.nodes[i].h;
    PtrFilter<ObjMarker> omark(g, blocks, h);
    scanHeader(h, omark);
  }
  g.nodes.shrink_to_fit();
  g.ptrs.shrink_to_fit();
  g.roots.shrink_to_fit();
  return g;
}
const VarCharType& VarCharType::InstanceInternal(const std::size_t length) {
  static PtrMap<size_t, VarCharType> instance_map;
  PtrMap<size_t, VarCharType>::iterator imit = instance_map.find(length);
  if (imit == instance_map.end()) {
    imit = instance_map.insert(length, new VarCharType(length, nullable_internal)).first;
  }
  return *(imit->second);
}
 /**
  * @brief Get a reference to the singleton instance of this Operation.
  *
  * @param target_type The target type to coerce input values to.
  * @return A reference to the singleton instance of this Operation.
  **/
 static const NumericCastOperation& Instance(const Type &target_type) {
   static PtrMap<const Type*, NumericCastOperation> instance_map;
   PtrMap<const Type*, NumericCastOperation>::iterator instance_map_it =
       instance_map.find(&target_type);
   if (instance_map_it == instance_map.end()) {
     instance_map_it = instance_map.insert(&target_type,
                                           new NumericCastOperation(target_type)).first;
   }
   return *(instance_map_it->second);
 }
 // Remove all references to objects belonging to a given cell
 void removeCell(const MWWorld::Ptr::CellStore *cell)
 {
   PtrMap::iterator it2, it = sounds.begin();
   while(it != sounds.end())
     {
       // Make sure to increase the iterator before we erase it.
       it2 = it++;
       if(it2->first.getCell() == cell)
         clearAll(it2);
     }
 }
 void updatePositions(MWWorld::Ptr ptr)
 {
   // Find the reference (if any)
   PtrMap::iterator it = sounds.find(ptr);
   if(it != sounds.end())
     {
       // Then find all sounds in it (if any)
       IDMap::iterator it2 = it->second.begin();
       for(;it2 != it->second.end(); it2++)
         {
           // Get the sound (if it still exists)
           SoundPtr snd = it2->second.lock();
           if(snd)
             // Update position
             setPos(snd, ptr);
         }
     }
 }
    bool isPlaying(MWWorld::Ptr ptr, const std::string &id) const
    {
      PtrMap::const_iterator it = sounds.find(ptr);
      if(it != sounds.end())
        {
          IDMap::const_iterator it2 = it->second.find(id);
          if(it2 != it->second.end())
            {
              // Get a shared_ptr from the weak_ptr
              SoundPtr snd = it2->second.lock();;

              // Is it still alive?
              if(snd)
                {
                  // Then return its status!
                  return snd->isPlaying();
                }
            }
        }
      // Nothing found, sound is not playing
      return false;
    }
 // Stop a sound and remove it from the list. If id="" then
 // remove the entire object and stop all its sounds.
 void remove(MWWorld::Ptr ptr, const std::string &id = "")
 {
   PtrMap::iterator it = sounds.find(ptr);
   if(it != sounds.end())
     {
       if(id == "")
         // Kill all references to 'ptr'
         clearAll(it);
       else
         {
           // Only find the id we're looking for
           IDMap::iterator it2 = it->second.find(id);
           if(it2 != it->second.end())
             {
               // Stop the sound and remove it from the list
               SoundPtr snd = it2->second.lock();
               if(snd) snd->stop();
               it->second.erase(it2);
             }
         }
     }
 }
    // Clears all the sub-elements of a given iterator, and then
    // removes it from 'sounds'.
    void clearAll(PtrMap::iterator it)
    {
      IDMap::iterator sit = it->second.begin();

      while(sit != it->second.end())
        {
          // Get sound pointer, if any
          SoundPtr snd = sit->second.lock();

          // Stop the sound
          if(snd) snd->stop();

          sit++;
        }

      // Remove the ptr reference
      sounds.erase(it);
    }
Exemple #9
0
// parse the heap to find valid objects and initialize metadata, then
// add edges for every known root pointer and every known obj->obj ptr.
HeapGraph makeHeapGraph(bool include_free) {
  HeapGraph g;
  PtrMap blocks;

  // parse the heap once to create a PtrMap for pointer filtering. Create
  // one node for every parsed block, including NativeData and AsyncFuncFrame
  // blocks. Only include free blocks if requested.
  MM().forEachHeader([&](Header* h, size_t alloc_size) {
    if (h->kind() != HeaderKind::Free || include_free) {
      blocks.insert(h, alloc_size); // adds interval [h, h+alloc_size[
    }
  });
  blocks.prepare();

  // initialize nodes by iterating over PtrMap's regions
  g.nodes.reserve(blocks.size());
  blocks.iterate([&](const Header* h, size_t size) {
    type_scan::Index ty;
    switch (h->kind()) {
      case HeaderKind::NativeData:
        ty = h->native_.typeIndex();
        break;
      case HeaderKind::Resource:
        ty = h->res_.typeIndex();
        break;
      case HeaderKind::SmallMalloc:
      case HeaderKind::BigMalloc:
        ty = h->malloc_.typeIndex();
        break;
      default:
        ty = type_scan::kIndexUnknown;
        break;
    }
    g.nodes.push_back(
      HeapGraph::Node{h, size, false, ty, -1, -1}
    );
  });

  // find root nodes
  type_scan::Scanner scanner;
  iterateRoots([&](const void* h, size_t size, type_scan::Index tyindex) {
    // it's important that we actually scan each root node before
    // returning, since at least one will be the C++ stack, and some
    // nodes will only exist for the duration of the call to this lambda,
    // for example EphemeralPtrWrapper<T>.
    addRootNode(g, blocks, scanner, h, size, tyindex);
  });

  // find heap->heap pointers
  for (size_t i = 0, n = g.nodes.size(); i < n; i++) {
    if (g.nodes[i].is_root) continue;
    auto h = g.nodes[i].h;
    scanHeader(h, scanner);
    auto from = blocks.index(h);
    assert(from == i);
    scanner.finish(
      [&](const void* p) {
        // definitely a ptr, but maybe interior, and maybe not counted
        if (auto r = blocks.region(p)) {
          addPtr(g, from, blocks.index(r), HeapGraph::Implicit, UnknownOffset);
        }
      },
      [&](const void* p, std::size_t size) {
        conservativeScan(p, size, [&](const void** addr, const void* ptr) {
          if (auto r = blocks.region(ptr)) {
            auto to = blocks.index(r);
            auto offset = uintptr_t(addr) - uintptr_t(h);
            addPtr(g, from, to, HeapGraph::Ambiguous, offset);
          }
        });
      },
      [&](const void** addr) {
        if (auto r = blocks.region(*addr)) {
          auto to = blocks.index(r);
          auto offset = uintptr_t(addr) - uintptr_t(h);
          addPtr(g, from, to, HeapGraph::Counted, offset);
        }
      }
    );
  }
  g.nodes.shrink_to_fit();
  g.ptrs.shrink_to_fit();
  g.root_ptrs.shrink_to_fit();
  g.root_nodes.shrink_to_fit();
  return g;
}