diff --git a/BUILD.gn b/BUILD.gn index ad4a5bd57d..32a716a240 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -628,6 +628,8 @@ source_set("v8_base") { "include/v8config.h", "src/accessors.cc", "src/accessors.h", + "src/address-map.cc", + "src/address-map.h", "src/allocation.cc", "src/allocation.h", "src/allocation-site-scopes.cc", diff --git a/src/address-map.cc b/src/address-map.cc new file mode 100644 index 0000000000..681661af29 --- /dev/null +++ b/src/address-map.cc @@ -0,0 +1,38 @@ +// 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. + +#include "src/address-map.h" +#include "src/heap/heap.h" +#include "src/isolate.h" +#include "src/objects-inl.h" + +namespace v8 { +namespace internal { + +RootIndexMap::RootIndexMap(Isolate* isolate) { + map_ = isolate->root_index_map(); + if (map_ != NULL) return; + map_ = new HashMap(HashMap::PointersMatch); + for (uint32_t i = 0; i < Heap::kStrongRootListLength; i++) { + Heap::RootListIndex root_index = static_cast(i); + Object* root = isolate->heap()->root(root_index); + // Omit root entries that can be written after initialization. They must + // not be referenced through the root list in the snapshot. + if (root->IsHeapObject() && + isolate->heap()->RootCanBeTreatedAsConstant(root_index)) { + HeapObject* heap_object = HeapObject::cast(root); + HashMap::Entry* entry = LookupEntry(map_, heap_object, false); + if (entry != NULL) { + // Some are initialized to a previous value in the root list. + DCHECK_LT(GetValue(entry), i); + } else { + SetValue(LookupEntry(map_, heap_object, true), i); + } + } + } + isolate->set_root_index_map(map_); +} + +} // namespace internal +} // namespace v8 diff --git a/src/address-map.h b/src/address-map.h new file mode 100644 index 0000000000..df32f89c1e --- /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(v); + } + + static uint32_t GetValue(HashMap::Entry* entry) { + return static_cast(reinterpret_cast(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(reinterpret_cast(obj->address())); + } + + static void* Key(HeapObject* obj) { + return reinterpret_cast(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 {}; + class ChunkIndexBits + : public BitField {}; + class SpaceBits + : public BitField { + }; + + 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_ diff --git a/src/compiler/code-generator.cc b/src/compiler/code-generator.cc index 3c265c64c9..1d2be38274 100644 --- a/src/compiler/code-generator.cc +++ b/src/compiler/code-generator.cc @@ -4,11 +4,11 @@ #include "src/compiler/code-generator.h" +#include "src/address-map.h" #include "src/compiler/code-generator-impl.h" #include "src/compiler/linkage.h" #include "src/compiler/pipeline.h" #include "src/frames-inl.h" -#include "src/snapshot/serialize.h" // TODO(turbofan): RootIndexMap namespace v8 { namespace internal { diff --git a/src/context-measure.h b/src/context-measure.h index adfefbf1ae..8f2dd314a3 100644 --- a/src/context-measure.h +++ b/src/context-measure.h @@ -5,7 +5,9 @@ #ifndef V8_CONTEXT_MEASURE_H_ #define V8_CONTEXT_MEASURE_H_ -#include "src/snapshot/serialize.h" +#include "src/address-map.h" +#include "src/assert-scope.h" +#include "src/objects.h" namespace v8 { namespace internal { diff --git a/src/snapshot/serialize.cc b/src/snapshot/serialize.cc index 51892de3eb..a6ca6e1946 100644 --- a/src/snapshot/serialize.cc +++ b/src/snapshot/serialize.cc @@ -354,31 +354,6 @@ const char* ExternalReferenceEncoder::NameOfAddress(Isolate* isolate, } -RootIndexMap::RootIndexMap(Isolate* isolate) { - map_ = isolate->root_index_map(); - if (map_ != NULL) return; - map_ = new HashMap(HashMap::PointersMatch); - for (uint32_t i = 0; i < Heap::kStrongRootListLength; i++) { - Heap::RootListIndex root_index = static_cast(i); - Object* root = isolate->heap()->root(root_index); - // Omit root entries that can be written after initialization. They must - // not be referenced through the root list in the snapshot. - if (root->IsHeapObject() && - isolate->heap()->RootCanBeTreatedAsConstant(root_index)) { - HeapObject* heap_object = HeapObject::cast(root); - HashMap::Entry* entry = LookupEntry(map_, heap_object, false); - if (entry != NULL) { - // Some are initialized to a previous value in the root list. - DCHECK_LT(GetValue(entry), i); - } else { - SetValue(LookupEntry(map_, heap_object, true), i); - } - } - } - isolate->set_root_index_map(map_); -} - - class CodeAddressMap: public CodeEventLogger { public: explicit CodeAddressMap(Isolate* isolate) diff --git a/src/snapshot/serialize.h b/src/snapshot/serialize.h index d3c70acf4a..c6faadfb32 100644 --- a/src/snapshot/serialize.h +++ b/src/snapshot/serialize.h @@ -5,7 +5,7 @@ #ifndef V8_SNAPSHOT_SERIALIZE_H_ #define V8_SNAPSHOT_SERIALIZE_H_ -#include "src/hashmap.h" +#include "src/address-map.h" #include "src/heap/heap.h" #include "src/objects.h" #include "src/snapshot/snapshot-source-sink.h" @@ -70,54 +70,6 @@ class ExternalReferenceEncoder { }; -class AddressMapBase { - protected: - static void SetValue(HashMap::Entry* entry, uint32_t v) { - entry->value = reinterpret_cast(v); - } - - static uint32_t GetValue(HashMap::Entry* entry) { - return static_cast(reinterpret_cast(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(reinterpret_cast(obj->address())); - } - - static void* Key(HeapObject* obj) { - return reinterpret_cast(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 PartialCacheIndexMap : public AddressMapBase { public: PartialCacheIndexMap() : map_(HashMap::PointersMatch) {} @@ -140,125 +92,6 @@ class PartialCacheIndexMap : public AddressMapBase { }; -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 {}; - class ChunkIndexBits - : public BitField {}; - class SpaceBits - : public BitField { - }; - - 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); -}; - - class HotObjectsList { public: HotObjectsList() : index_(0) { diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp index ab0c1d62a8..3937737fd6 100644 --- a/tools/gyp/v8.gyp +++ b/tools/gyp/v8.gyp @@ -385,6 +385,8 @@ '../../include/v8config.h', '../../src/accessors.cc', '../../src/accessors.h', + '../../src/address-map.cc', + '../../src/address-map.h', '../../src/allocation.cc', '../../src/allocation.h', '../../src/allocation-site-scopes.cc',