Index: src/heap/identity-map.h |
diff --git a/src/heap/identity-map.h b/src/heap/identity-map.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a3f1921ebccf2d43a1813f38021b7676ea8a09cf |
--- /dev/null |
+++ b/src/heap/identity-map.h |
@@ -0,0 +1,115 @@ |
+// Copyright 2015 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef V8_HEAP_IDENTITY_MAP_H_ |
+#define V8_HEAP_IDENTITY_MAP_H_ |
+ |
+#include "src/handles.h" |
+ |
+namespace v8 { |
+namespace internal { |
+ |
+class Heap; |
+ |
+// Base class of identity maps contains shared code for all template |
+// instantions. |
+class IdentityMapBase { |
+ public: |
+ // Enable or disable concurrent mode for this map. Concurrent mode implies |
+ // taking the heap's relocation lock during most operations. |
+ void SetConcurrent(bool concurrent) { concurrent_ = concurrent; } |
+ |
+ protected: |
+ // Allow Tester to access internals, including changing the address of objects |
+ // within the {keys_} array in order to simulate a moving GC. |
+ friend class IdentityMapTester; |
+ |
+ typedef void** RawEntry; |
+ |
+ IdentityMapBase(Heap* heap, Zone* zone) |
+ : heap_(heap), |
+ zone_(zone), |
+ concurrent_(false), |
+ gc_counter_(-1), |
+ size_(0), |
+ mask_(0), |
+ keys_(nullptr), |
+ values_(nullptr) {} |
+ ~IdentityMapBase(); |
+ |
+ RawEntry GetEntry(Handle<Object> handle); |
+ RawEntry FindEntry(Handle<Object> handle); |
+ |
+ private: |
+ // Internal implementation should not be called directly by subclasses. |
+ int LookupIndex(Object* address); |
+ int InsertIndex(Object* address); |
+ void Rehash(); |
+ void Resize(); |
+ |
+ RawEntry Lookup(Handle<Object> handle) { |
Benedikt Meurer
2015/04/27 04:04:18
Style nit: Since these methods are private, and al
titzer
2015/04/27 10:43:03
Done.
|
+ AllowHandleDereference for_lookup; |
+ int index = LookupIndex(*handle); |
Benedikt Meurer
2015/04/27 04:04:18
How about size_t here, and check for index < size_
titzer
2015/04/27 10:43:03
I think int works better here, since we are using
|
+ return index >= 0 ? &values_[index] : nullptr; |
+ } |
+ |
+ RawEntry Insert(Handle<Object> handle) { |
Benedikt Meurer
2015/04/27 04:04:17
Style nit: Since these methods are private, and al
titzer
2015/04/27 10:43:03
Done.
|
+ AllowHandleDereference for_lookup; |
+ int index = InsertIndex(*handle); |
+ DCHECK_GE(index, 0); |
+ return &values_[index]; |
+ } |
+ |
+ int Hash(Object* address) { |
Benedikt Meurer
2015/04/27 04:04:18
Style nit: Since these methods are private, and al
titzer
2015/04/27 10:43:03
Done.
|
+ uintptr_t raw_address = reinterpret_cast<uintptr_t>(address); |
+ CHECK_NE(0, raw_address); // cannot store Smi 0 as a key here, sorry. |
+ // xor some of the upper bits, since the lower 2 or 3 are usually aligned. |
+ return static_cast<int>((raw_address >> 11) ^ raw_address); |
Benedikt Meurer
2015/04/27 04:04:17
Down casting to int looks wrong here. How about us
Sven Panne
2015/04/27 06:26:47
Veto from the *San sheriff, too: This line is caus
titzer
2015/04/27 07:57:51
This is the computation of a hashcode from an addr
titzer
2015/04/27 10:43:03
size_t isn't any safer than int. As per below comm
|
+ } |
+ |
+ Heap* heap_; |
+ Zone* zone_; |
+ bool concurrent_; |
+ int gc_counter_; |
+ int size_; |
+ int mask_; |
+ Object** keys_; |
+ void** values_; |
+}; |
+ |
+// Implements an identity map from object addresses to a given value type {V}. |
+// The value type {V} must be reinterpret_cast'able to void*. |
+// The map is robust w.r.t. garbage collection through coordination with the |
+// supplied {heap}. |
+// Note that in general, SMIs are valid keys, but {SMI #0} is _not_ a valid key. |
+template <typename V> |
+class IdentityMap : public IdentityMapBase { |
+ public: |
+ IdentityMap(Heap* heap, Zone* zone) : IdentityMapBase(heap, zone) {} |
+ |
+ // Searches this map for the given key using the object's address |
+ // as the identity, returning: |
+ // found => a pointer to the storage location for the value |
+ // not found => a pointer to a new storage location for the value |
+ V* Get(Handle<Object> handle) { |
+ return reinterpret_cast<V*>(GetEntry(handle)); |
+ } |
+ |
+ // Searches this map for the given key using the object's address |
+ // as the identity, returning: |
+ // found => a pointer to the storage location for the value |
+ // not found => {nullptr} |
+ V* Find(Handle<Object> handle) { |
+ return reinterpret_cast<V*>(FindEntry(handle)); |
+ } |
+ |
+ // Set the value for the given key. |
+ void Set(Handle<Object> handle, V value) { |
+ *(reinterpret_cast<V*>(GetEntry(handle))) = value; |
+ } |
+}; |
+} |
+} // namespace v8::internal |
+ |
+#endif // V8_HEAP_IDENTITY_MAP_H_ |