runtime: Add lambda box/unbox object equality
A lambda that is boxed with box-lambda is now stored as a weak reference
in a global runtime table (lambda::BoxTable). Repeatedly boxing the same
lambda closure value will always return the same java.lang.Object back.
Since there is no way to observe the address of an object, a GC can
happen and clean up the table of any dead boxed lambdas, which can also
shrink the table to prevent the memory use from growing too much.
(Note that a lambda closure is immutable, so hashing over it is
guaranteed safe.)
Change-Id: I786c1323ff14eed937936b303d511875f9642524
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc
index e48d170..c591a51 100644
--- a/runtime/base/mutex.cc
+++ b/runtime/base/mutex.cc
@@ -61,6 +61,7 @@
Mutex* Locks::thread_suspend_count_lock_ = nullptr;
Mutex* Locks::trace_lock_ = nullptr;
Mutex* Locks::unexpected_signal_lock_ = nullptr;
+Mutex* Locks::lambda_table_lock_ = nullptr;
struct AllMutexData {
// A guard for all_mutexes_ that's not a mutex (Mutexes must CAS to acquire and busy wait).
@@ -946,6 +947,7 @@
DCHECK(thread_suspend_count_lock_ != nullptr);
DCHECK(trace_lock_ != nullptr);
DCHECK(unexpected_signal_lock_ != nullptr);
+ DCHECK(lambda_table_lock_ != nullptr);
} else {
// Create global locks in level order from highest lock level to lowest.
LockLevel current_lock_level = kInstrumentEntrypointsLock;
@@ -1048,6 +1050,10 @@
DCHECK(reference_queue_soft_references_lock_ == nullptr);
reference_queue_soft_references_lock_ = new Mutex("ReferenceQueue soft references lock", current_lock_level);
+ UPDATE_CURRENT_LOCK_LEVEL(kLambdaTableLock);
+ DCHECK(lambda_table_lock_ == nullptr);
+ lambda_table_lock_ = new Mutex("lambda table lock", current_lock_level);
+
UPDATE_CURRENT_LOCK_LEVEL(kAbortLock);
DCHECK(abort_lock_ == nullptr);
abort_lock_ = new Mutex("abort lock", current_lock_level, true);