Files
sdk/runtime/vm/thread_registry.h
T
Matthew Dempsky 6d5f763952 [vm] Eliminate Mutex/Monitor indirection where possible
In many cases, the Mutexes and Monitors have to be marked "mutable"
because they're used to synchronize const accessor methods.

Small text segment improvement for Product builds:

$ size dart.{arm,x64}.{before,after}
   text	   data	    bss	    dec	    hex	filename
19726069	 409960	 392332	20528361	1393ce9	dart.arm.before
19725525	 409960	 392332	20527817	1393ac9	dart.arm.after
22576021	 600376	1782824	24959221	17cd8f5	dart.x64.before
22574821	 600376	1782824	24958021	17cd445	dart.x64.after

Change-Id: I68f5cd5ad452044df8bfebd160910496036a3e6b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101745
Commit-Queue: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
2019-05-13 21:17:51 +00:00

93 lines
3.1 KiB
C++

// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifndef RUNTIME_VM_THREAD_REGISTRY_H_
#define RUNTIME_VM_THREAD_REGISTRY_H_
#include "vm/globals.h"
#include "vm/growable_array.h"
#include "vm/isolate.h"
#include "vm/lockers.h"
#include "vm/stack_frame.h"
#include "vm/thread.h"
namespace dart {
#ifndef PRODUCT
class JSONStream;
class JSONArray;
#endif
// Unordered collection of threads relating to a particular isolate.
class ThreadRegistry {
public:
ThreadRegistry()
: threads_lock_(),
active_list_(NULL),
free_list_(NULL),
mutator_thread_(NULL) {}
~ThreadRegistry();
void VisitObjectPointers(ObjectPointerVisitor* visitor,
ValidationPolicy validate_frames);
void ReleaseStoreBuffers();
void AcquireMarkingStacks();
void ReleaseMarkingStacks();
Thread* mutator_thread() const { return mutator_thread_; }
#ifndef PRODUCT
void PrintJSON(JSONStream* stream) const;
#endif
// Calculates the sum of the max memory usage in bytes of each thread.
uintptr_t ThreadHighWatermarksTotalLocked() const;
intptr_t CountZoneHandles() const;
intptr_t CountScopedHandles() const;
private:
Thread* active_list() const { return active_list_; }
Monitor* threads_lock() const { return &threads_lock_; }
Thread* GetFreeThreadLocked(Isolate* isolate, bool is_mutator);
void ReturnThreadLocked(bool is_mutator, Thread* thread);
void AddToActiveListLocked(Thread* thread);
void RemoveFromActiveListLocked(Thread* thread);
Thread* GetFromFreelistLocked(Isolate* isolate);
void ReturnToFreelistLocked(Thread* thread);
// This monitor protects the threads list for an isolate, it is used whenever
// we need to iterate over threads (both active and free) in an isolate.
mutable Monitor threads_lock_;
Thread* active_list_; // List of active threads in the isolate.
Thread* free_list_; // Free list of Thread objects that can be reused.
// TODO(asiva): Currently we treat a mutator thread as a special thread
// and always schedule execution of Dart code on the same mutator thread
// object. The ApiLocalScope has been made thread specific but we still
// have scenarios where we do a temporary exit of an Isolate with live
// zones/handles in the API scope :
// - Dart_RunLoop()
// - IsolateSaver in Dart_NewNativePort
// Similarly, tracking async_stack_trace requires that we always reschedule
// on the same thread.
// We probably need a mechanism to return to the specific thread only
// for these specific cases. We should also determine if the embedder
// should allow exiting an isolate with live state in zones/handles in
// which case a new API for returning to the specific thread needs to be
// added.
Thread* mutator_thread_;
friend class Isolate;
friend class SafepointHandler;
friend class Scavenger;
DISALLOW_COPY_AND_ASSIGN(ThreadRegistry);
};
} // namespace dart
#endif // RUNTIME_VM_THREAD_REGISTRY_H_