Index: src/address-map.h |
diff --git a/src/address-map.h b/src/address-map.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..df32f89c1ea33cd78bf6c386245b013ac2c1832c |
--- /dev/null |
+++ b/src/address-map.h |
@@ -0,0 +1,184 @@ |
+// 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_ADDRESS_MAP_H_ |
+#define V8_ADDRESS_MAP_H_ |
+ |
+#include "src/assert-scope.h" |
+#include "src/hashmap.h" |
+#include "src/objects.h" |
+ |
+namespace v8 { |
+namespace internal { |
+ |
+class AddressMapBase { |
+ protected: |
+ static void SetValue(HashMap::Entry* entry, uint32_t v) { |
+ entry->value = reinterpret_cast<void*>(v); |
+ } |
+ |
+ static uint32_t GetValue(HashMap::Entry* entry) { |
+ return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value)); |
+ } |
+ |
+ inline static HashMap::Entry* LookupEntry(HashMap* map, HeapObject* obj, |
+ bool insert) { |
+ if (insert) { |
+ map->LookupOrInsert(Key(obj), Hash(obj)); |
+ } |
+ return map->Lookup(Key(obj), Hash(obj)); |
+ } |
+ |
+ private: |
+ static uint32_t Hash(HeapObject* obj) { |
+ return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); |
+ } |
+ |
+ static void* Key(HeapObject* obj) { |
+ return reinterpret_cast<void*>(obj->address()); |
+ } |
+}; |
+ |
+ |
+class RootIndexMap : public AddressMapBase { |
+ public: |
+ explicit RootIndexMap(Isolate* isolate); |
+ |
+ static const int kInvalidRootIndex = -1; |
+ |
+ int Lookup(HeapObject* obj) { |
+ HashMap::Entry* entry = LookupEntry(map_, obj, false); |
+ if (entry) return GetValue(entry); |
+ return kInvalidRootIndex; |
+ } |
+ |
+ private: |
+ HashMap* map_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RootIndexMap); |
+}; |
+ |
+ |
+class BackReference { |
+ public: |
+ explicit BackReference(uint32_t bitfield) : bitfield_(bitfield) {} |
+ |
+ BackReference() : bitfield_(kInvalidValue) {} |
+ |
+ static BackReference SourceReference() { return BackReference(kSourceValue); } |
+ |
+ static BackReference GlobalProxyReference() { |
+ return BackReference(kGlobalProxyValue); |
+ } |
+ |
+ static BackReference LargeObjectReference(uint32_t index) { |
+ return BackReference(SpaceBits::encode(LO_SPACE) | |
+ ChunkOffsetBits::encode(index)); |
+ } |
+ |
+ static BackReference DummyReference() { return BackReference(kDummyValue); } |
+ |
+ static BackReference Reference(AllocationSpace space, uint32_t chunk_index, |
+ uint32_t chunk_offset) { |
+ DCHECK(IsAligned(chunk_offset, kObjectAlignment)); |
+ DCHECK_NE(LO_SPACE, space); |
+ return BackReference( |
+ SpaceBits::encode(space) | ChunkIndexBits::encode(chunk_index) | |
+ ChunkOffsetBits::encode(chunk_offset >> kObjectAlignmentBits)); |
+ } |
+ |
+ bool is_valid() const { return bitfield_ != kInvalidValue; } |
+ bool is_source() const { return bitfield_ == kSourceValue; } |
+ bool is_global_proxy() const { return bitfield_ == kGlobalProxyValue; } |
+ |
+ AllocationSpace space() const { |
+ DCHECK(is_valid()); |
+ return SpaceBits::decode(bitfield_); |
+ } |
+ |
+ uint32_t chunk_offset() const { |
+ DCHECK(is_valid()); |
+ return ChunkOffsetBits::decode(bitfield_) << kObjectAlignmentBits; |
+ } |
+ |
+ uint32_t large_object_index() const { |
+ DCHECK(is_valid()); |
+ DCHECK(chunk_index() == 0); |
+ return ChunkOffsetBits::decode(bitfield_); |
+ } |
+ |
+ uint32_t chunk_index() const { |
+ DCHECK(is_valid()); |
+ return ChunkIndexBits::decode(bitfield_); |
+ } |
+ |
+ uint32_t reference() const { |
+ DCHECK(is_valid()); |
+ return bitfield_ & (ChunkOffsetBits::kMask | ChunkIndexBits::kMask); |
+ } |
+ |
+ uint32_t bitfield() const { return bitfield_; } |
+ |
+ private: |
+ static const uint32_t kInvalidValue = 0xFFFFFFFF; |
+ static const uint32_t kSourceValue = 0xFFFFFFFE; |
+ static const uint32_t kGlobalProxyValue = 0xFFFFFFFD; |
+ static const uint32_t kDummyValue = 0xFFFFFFFC; |
+ static const int kChunkOffsetSize = kPageSizeBits - kObjectAlignmentBits; |
+ static const int kChunkIndexSize = 32 - kChunkOffsetSize - kSpaceTagSize; |
+ |
+ public: |
+ static const int kMaxChunkIndex = (1 << kChunkIndexSize) - 1; |
+ |
+ private: |
+ class ChunkOffsetBits : public BitField<uint32_t, 0, kChunkOffsetSize> {}; |
+ class ChunkIndexBits |
+ : public BitField<uint32_t, ChunkOffsetBits::kNext, kChunkIndexSize> {}; |
+ class SpaceBits |
+ : public BitField<AllocationSpace, ChunkIndexBits::kNext, kSpaceTagSize> { |
+ }; |
+ |
+ uint32_t bitfield_; |
+}; |
+ |
+ |
+// Mapping objects to their location after deserialization. |
+// This is used during building, but not at runtime by V8. |
+class BackReferenceMap : public AddressMapBase { |
+ public: |
+ BackReferenceMap() |
+ : no_allocation_(), map_(new HashMap(HashMap::PointersMatch)) {} |
+ |
+ ~BackReferenceMap() { delete map_; } |
+ |
+ BackReference Lookup(HeapObject* obj) { |
+ HashMap::Entry* entry = LookupEntry(map_, obj, false); |
+ return entry ? BackReference(GetValue(entry)) : BackReference(); |
+ } |
+ |
+ void Add(HeapObject* obj, BackReference b) { |
+ DCHECK(b.is_valid()); |
+ DCHECK_NULL(LookupEntry(map_, obj, false)); |
+ HashMap::Entry* entry = LookupEntry(map_, obj, true); |
+ SetValue(entry, b.bitfield()); |
+ } |
+ |
+ void AddSourceString(String* string) { |
+ Add(string, BackReference::SourceReference()); |
+ } |
+ |
+ void AddGlobalProxy(HeapObject* global_proxy) { |
+ Add(global_proxy, BackReference::GlobalProxyReference()); |
+ } |
+ |
+ private: |
+ DisallowHeapAllocation no_allocation_; |
+ HashMap* map_; |
+ DISALLOW_COPY_AND_ASSIGN(BackReferenceMap); |
+}; |
+ |
+} // namespace internal |
+} // namespace v8 |
+ |
+#endif // V8_ADDRESS_MAP_H_ |