Skip to content

Commit

Permalink
refactor(debug): prefer Vector over std::vector
Browse files Browse the repository at this point in the history
Reduce our use of std::vector to reduce binary bloat:
#689
  • Loading branch information
strager committed Nov 5, 2023
1 parent 585a843 commit fcb4dc2
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 13 deletions.
9 changes: 7 additions & 2 deletions src/quick-lint-js/debug/debug-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
#include <quick-lint-js/assert.h>
#include <quick-lint-js/container/async-byte-queue.h>
#include <quick-lint-js/container/byte-buffer.h>
#include <quick-lint-js/container/monotonic-allocator.h>
#include <quick-lint-js/container/vector-profiler.h>
#include <quick-lint-js/container/vector.h>
#include <quick-lint-js/debug/debug-server-fs.h>
#include <quick-lint-js/debug/debug-server.h>
#include <quick-lint-js/debug/find-debug-server.h>
Expand Down Expand Up @@ -108,7 +110,7 @@ std::shared_ptr<Debug_Server> Debug_Server::create() {
return instance;
}

std::vector<std::shared_ptr<Debug_Server>> Debug_Server::instances() {
Vector<std::shared_ptr<Debug_Server>> Debug_Server::instances() {
return Instance_Tracker<Debug_Server>::instances();
}

Expand Down Expand Up @@ -399,7 +401,10 @@ void Debug_Server::publish_lsp_documents_if_needed() {
return;
}

std::vector<Trace_LSP_Document_State> document_states;
Monotonic_Allocator temporary_allocator(
"Debug_Server::publish_lsp_documents_if_needed");
Vector<Trace_LSP_Document_State> document_states("document_states",
&temporary_allocator);
{
Lock_Ptr<LSP_Documents> documents = documents_raw->lock();
document_states.reserve(documents->documents.size());
Expand Down
7 changes: 4 additions & 3 deletions src/quick-lint-js/debug/debug-server.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <mongoose.h>
#include <quick-lint-js/container/result.h>
#include <quick-lint-js/container/vector-profiler.h>
#include <quick-lint-js/container/vector.h>
#include <quick-lint-js/port/thread.h>
#include <quick-lint-js/util/synchronized.h>
#include <string>
Expand All @@ -34,7 +35,7 @@ class Debug_Server {

public:
static std::shared_ptr<Debug_Server> create();
static std::vector<std::shared_ptr<Debug_Server>> instances();
static Vector<std::shared_ptr<Debug_Server>> instances();

explicit Debug_Server(Create_Tag);

Expand Down Expand Up @@ -109,8 +110,8 @@ class Debug_Server {

// Used by server thread only:
// Each backend is associated with one WebSocket connection.
std::vector<std::unique_ptr<Trace_Flusher_WebSocket_Backend>>
tracer_backends_;
Vector<std::unique_ptr<Trace_Flusher_WebSocket_Backend>> tracer_backends_{
"Debug_Server::tracer_backends_", new_delete_resource()};
#if QLJS_FEATURE_VECTOR_PROFILING
Vector_Max_Size_Histogram_By_Owner max_size_histogram_;
#endif
Expand Down
19 changes: 11 additions & 8 deletions src/quick-lint-js/util/instance-tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#pragma once

#include <memory>
#include <quick-lint-js/container/vector.h>
#include <quick-lint-js/port/vector-erase.h>
#include <quick-lint-js/util/synchronized.h>
#include <vector>

namespace quick_lint_js {
// Maintains a global list of instances of Tracked. Each Tracked must be managed
Expand All @@ -18,16 +18,17 @@ template <class Tracked>
class Instance_Tracker {
public:
static void track(std::shared_ptr<Tracked> instance) {
Lock_Ptr<std::vector<std::weak_ptr<Tracked>>> weak_instances =
Lock_Ptr<Vector<std::weak_ptr<Tracked>>> weak_instances =
weak_instances_.lock();
sanitize_instances(weak_instances);
weak_instances->push_back(std::move(instance));
}

static std::vector<std::shared_ptr<Tracked>> instances() {
std::vector<std::shared_ptr<Tracked>> instances;
static Vector<std::shared_ptr<Tracked>> instances() {
Vector<std::shared_ptr<Tracked>> instances("Instance_Tracker::instances",
new_delete_resource());
{
Lock_Ptr<std::vector<std::weak_ptr<Tracked>>> weak_instances =
Lock_Ptr<Vector<std::weak_ptr<Tracked>>> weak_instances =
weak_instances_.lock();
sanitize_instances(weak_instances);
instances.reserve(weak_instances->size());
Expand All @@ -38,12 +39,14 @@ class Instance_Tracker {
}
}
}
// NOTE(strager): We cannot wink (e.g. use Linked_Bump_Allocator and return
// a Span) because std::shared_ptr destructors need to be called.
return instances;
}

private:
static void sanitize_instances(
Lock_Ptr<std::vector<std::weak_ptr<Tracked>>>& weak_instances) {
Lock_Ptr<Vector<std::weak_ptr<Tracked>>>& weak_instances) {
erase_if(*weak_instances, [](const std::weak_ptr<Tracked>& weak_instance) {
return weak_instance.expired();
});
Expand All @@ -53,8 +56,8 @@ class Instance_Tracker {
sanitize_instances(weak_instances_.lock());
}

static inline Synchronized<std::vector<std::weak_ptr<Tracked>>>
weak_instances_;
static inline Synchronized<Vector<std::weak_ptr<Tracked>>> weak_instances_{
"Instance_Tracker::weak_instances_", new_delete_resource()};
};
}

Expand Down
4 changes: 4 additions & 0 deletions src/quick-lint-js/util/synchronized.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ class Lock_Ptr;
template <class Data>
class Synchronized {
public:
// Construct Data, forwarding arguments to Data's constructor.
template <class... Args>
explicit Synchronized(Args&&... args) : data_(std::forward<Args>(args)...) {}

// Acquire the mutex. When the returned lock_ptr is destructed, the mutex is
// released.
Lock_Ptr<Data> lock();
Expand Down

0 comments on commit fcb4dc2

Please sign in to comment.