Commit 84e83da9 authored by bmeurer's avatar bmeurer Committed by Commit bot

[heap] Unify the immortal immovable root detection mechanism.

Uniformly use the Heap::GetRootListIndex() and
Heap::RootIsImmortalImmovable() methods to detect immortal immovable
roots in the optimizing compilers.

R=jarin@chromium.org

Review URL: https://codereview.chromium.org/1178853002

Cr-Commit-Position: refs/heads/master@{#28933}
parent 6a63a6d4
...@@ -220,8 +220,12 @@ bool CodeGenerator::IsMaterializableFromFrame(Handle<HeapObject> object, ...@@ -220,8 +220,12 @@ bool CodeGenerator::IsMaterializableFromFrame(Handle<HeapObject> object,
bool CodeGenerator::IsMaterializableFromRoot( bool CodeGenerator::IsMaterializableFromRoot(
Handle<HeapObject> object, Heap::RootListIndex* index_return) { Handle<HeapObject> object, Heap::RootListIndex* index_return) {
if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { Heap::RootListIndex index;
return isolate()->heap()->GetRootListIndex(object, index_return); if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall() &&
isolate()->heap()->GetRootListIndex(*object, &index) &&
!Heap::RootCanBeWrittenAfterInitialization(index)) {
*index_return = index;
return true;
} }
return false; return false;
} }
......
...@@ -4907,29 +4907,84 @@ bool Heap::InSpace(Address addr, AllocationSpace space) { ...@@ -4907,29 +4907,84 @@ bool Heap::InSpace(Address addr, AllocationSpace space) {
} }
bool Heap::RootIsImmortalImmovable(int root_index) { // static
switch (root_index) { bool Heap::RootIsImmortalImmovable(RootListIndex index) {
#define CASE(name) \ // Heap roots that are known to be immortal immovable, for which we can safely
case Heap::k##name##RootIndex: \ // skip write barriers. This list is not complete and has omissions.
switch (index) {
case Heap::kByteArrayMapRootIndex:
case Heap::kFreeSpaceMapRootIndex:
case Heap::kOnePointerFillerMapRootIndex:
case Heap::kTwoPointerFillerMapRootIndex:
case Heap::kUndefinedValueRootIndex:
case Heap::kTheHoleValueRootIndex:
case Heap::kNullValueRootIndex:
case Heap::kTrueValueRootIndex:
case Heap::kFalseValueRootIndex:
case Heap::kUninitializedValueRootIndex:
case Heap::kCellMapRootIndex:
case Heap::kGlobalPropertyCellMapRootIndex:
case Heap::kSharedFunctionInfoMapRootIndex:
case Heap::kMetaMapRootIndex:
case Heap::kHeapNumberMapRootIndex:
case Heap::kMutableHeapNumberMapRootIndex:
case Heap::kFloat32x4MapRootIndex:
case Heap::kNativeContextMapRootIndex:
case Heap::kFixedArrayMapRootIndex:
case Heap::kCodeMapRootIndex:
case Heap::kScopeInfoMapRootIndex:
case Heap::kFixedCOWArrayMapRootIndex:
case Heap::kFixedDoubleArrayMapRootIndex:
case Heap::kWeakCellMapRootIndex:
case Heap::kNoInterceptorResultSentinelRootIndex:
case Heap::kHashTableMapRootIndex:
case Heap::kOrderedHashTableMapRootIndex:
case Heap::kEmptyFixedArrayRootIndex:
case Heap::kEmptyByteArrayRootIndex:
case Heap::kEmptyDescriptorArrayRootIndex:
case Heap::kArgumentsMarkerRootIndex:
case Heap::kSymbolMapRootIndex:
case Heap::kSloppyArgumentsElementsMapRootIndex:
case Heap::kFunctionContextMapRootIndex:
case Heap::kCatchContextMapRootIndex:
case Heap::kWithContextMapRootIndex:
case Heap::kBlockContextMapRootIndex:
case Heap::kModuleContextMapRootIndex:
case Heap::kScriptContextMapRootIndex:
case Heap::kUndefinedMapRootIndex:
case Heap::kTheHoleMapRootIndex:
case Heap::kNullMapRootIndex:
case Heap::kBooleanMapRootIndex:
case Heap::kUninitializedMapRootIndex:
case Heap::kArgumentsMarkerMapRootIndex:
case Heap::kJSMessageObjectMapRootIndex:
case Heap::kForeignMapRootIndex:
case Heap::kNeanderMapRootIndex:
case Heap::kempty_stringRootIndex:
#define STRING_INDEX_DECLARATION(Name, str) case Heap::k##Name##RootIndex:
INTERNALIZED_STRING_LIST(STRING_INDEX_DECLARATION)
#undef STRING_INDEX_DECLARATION
#define SYMBOL_INDEX_DECLARATION(Name) case Heap::k##Name##RootIndex:
PRIVATE_SYMBOL_LIST(SYMBOL_INDEX_DECLARATION)
#undef SYMBOL_INDEX_DECLARATION
#define STRING_TYPE_INDEX_DECLARATION(NAME, size, name, Name) \
case Heap::k##Name##MapRootIndex:
STRING_TYPE_LIST(STRING_TYPE_INDEX_DECLARATION)
#undef STRING_TYPE_INDEX_DECLARATION
return true; return true;
IMMORTAL_IMMOVABLE_ROOT_LIST(CASE);
#undef CASE
default: default:
return false; return false;
} }
} }
bool Heap::GetRootListIndex(Handle<HeapObject> object, bool Heap::GetRootListIndex(Object* object, RootListIndex* index_return) const {
Heap::RootListIndex* index_return) { for (size_t i = 0; i < arraysize(roots_); ++i) {
Object* ptr = *object; if (roots_[i] == object) {
#define IMMORTAL_IMMOVABLE_ROOT(Name) \ *index_return = static_cast<RootListIndex>(i);
if (ptr == roots_[Heap::k##Name##RootIndex]) { \ return true;
*index_return = k##Name##RootIndex; \ }
return true; \
} }
IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT)
#undef IMMORTAL_IMMOVABLE_ROOT
return false; return false;
} }
......
...@@ -324,60 +324,6 @@ namespace internal { ...@@ -324,60 +324,6 @@ namespace internal {
V(to_string_tag_symbol, symbolToStringTag, Symbol.toStringTag) \ V(to_string_tag_symbol, symbolToStringTag, Symbol.toStringTag) \
V(unscopables_symbol, symbolUnscopables, Symbol.unscopables) V(unscopables_symbol, symbolUnscopables, Symbol.unscopables)
// Heap roots that are known to be immortal immovable, for which we can safely
// skip write barriers. This list is not complete and has omissions.
#define IMMORTAL_IMMOVABLE_ROOT_LIST(V) \
V(ByteArrayMap) \
V(FreeSpaceMap) \
V(OnePointerFillerMap) \
V(TwoPointerFillerMap) \
V(UndefinedValue) \
V(TheHoleValue) \
V(NullValue) \
V(TrueValue) \
V(FalseValue) \
V(UninitializedValue) \
V(CellMap) \
V(GlobalPropertyCellMap) \
V(SharedFunctionInfoMap) \
V(MetaMap) \
V(HeapNumberMap) \
V(MutableHeapNumberMap) \
V(Float32x4Map) \
V(NativeContextMap) \
V(FixedArrayMap) \
V(CodeMap) \
V(ScopeInfoMap) \
V(FixedCOWArrayMap) \
V(FixedDoubleArrayMap) \
V(WeakCellMap) \
V(NoInterceptorResultSentinel) \
V(HashTableMap) \
V(OrderedHashTableMap) \
V(EmptyFixedArray) \
V(EmptyByteArray) \
V(EmptyDescriptorArray) \
V(ArgumentsMarker) \
V(SymbolMap) \
V(SloppyArgumentsElementsMap) \
V(FunctionContextMap) \
V(CatchContextMap) \
V(WithContextMap) \
V(BlockContextMap) \
V(ModuleContextMap) \
V(ScriptContextMap) \
V(UndefinedMap) \
V(TheHoleMap) \
V(NullMap) \
V(BooleanMap) \
V(UninitializedMap) \
V(ArgumentsMarkerMap) \
V(JSMessageObjectMap) \
V(ForeignMap) \
V(NeanderMap) \
V(empty_string) \
PRIVATE_SYMBOL_LIST(V)
// Forward declarations. // Forward declarations.
class HeapStats; class HeapStats;
class Isolate; class Isolate;
...@@ -995,7 +941,6 @@ class Heap { ...@@ -995,7 +941,6 @@ class Heap {
return reinterpret_cast<Address*>(&roots_[kStoreBufferTopRootIndex]); return reinterpret_cast<Address*>(&roots_[kStoreBufferTopRootIndex]);
} }
static bool RootIsImmortalImmovable(int root_index);
void CheckHandleCount(); void CheckHandleCount();
#ifdef VERIFY_HEAP #ifdef VERIFY_HEAP
...@@ -1187,7 +1132,7 @@ class Heap { ...@@ -1187,7 +1132,7 @@ class Heap {
#define STRING_INDEX_DECLARATION(name, str) k##name##RootIndex, #define STRING_INDEX_DECLARATION(name, str) k##name##RootIndex,
INTERNALIZED_STRING_LIST(STRING_INDEX_DECLARATION) INTERNALIZED_STRING_LIST(STRING_INDEX_DECLARATION)
#undef STRING_DECLARATION #undef STRING_INDEX_DECLARATION
#define SYMBOL_INDEX_DECLARATION(name) k##name##RootIndex, #define SYMBOL_INDEX_DECLARATION(name) k##name##RootIndex,
PRIVATE_SYMBOL_LIST(SYMBOL_INDEX_DECLARATION) PRIVATE_SYMBOL_LIST(SYMBOL_INDEX_DECLARATION)
...@@ -1211,9 +1156,11 @@ class Heap { ...@@ -1211,9 +1156,11 @@ class Heap {
kSmiRootsStart = kStringTableRootIndex + 1 kSmiRootsStart = kStringTableRootIndex + 1
}; };
// Check if {index} is the index of an immortal immovable root.
static bool RootIsImmortalImmovable(RootListIndex index);
// Get the root list index for {object} if such a root list index exists. // Get the root list index for {object} if such a root list index exists.
bool GetRootListIndex(Handle<HeapObject> object, bool GetRootListIndex(Object* object, RootListIndex* index_return) const;
Heap::RootListIndex* index_return);
Object* root(RootListIndex index) { return roots_[index]; } Object* root(RootListIndex index) { return roots_[index]; }
......
...@@ -2872,20 +2872,9 @@ bool HConstant::ImmortalImmovable() const { ...@@ -2872,20 +2872,9 @@ bool HConstant::ImmortalImmovable() const {
Heap* heap = isolate()->heap(); Heap* heap = isolate()->heap();
DCHECK(!object_.IsKnownGlobal(heap->minus_zero_value())); DCHECK(!object_.IsKnownGlobal(heap->minus_zero_value()));
DCHECK(!object_.IsKnownGlobal(heap->nan_value())); DCHECK(!object_.IsKnownGlobal(heap->nan_value()));
return Heap::RootListIndex index;
#define IMMORTAL_IMMOVABLE_ROOT(name) \ return heap->GetRootListIndex(object_.GetRawAddress(), &index) &&
object_.IsKnownGlobal(heap->root(Heap::k##name##RootIndex)) || Heap::RootIsImmortalImmovable(index);
IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT)
#undef IMMORTAL_IMMOVABLE_ROOT
#define INTERNALIZED_STRING(name, value) \
object_.IsKnownGlobal(heap->name()) ||
INTERNALIZED_STRING_LIST(INTERNALIZED_STRING)
#undef INTERNALIZED_STRING
#define STRING_TYPE(NAME, size, name, Name) \
object_.IsKnownGlobal(heap->name##_map()) ||
STRING_TYPE_LIST(STRING_TYPE)
#undef STRING_TYPE
false;
} }
......
...@@ -1934,7 +1934,8 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start, ...@@ -1934,7 +1934,8 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start,
// Repeats are not subject to the write barrier so we can only use // Repeats are not subject to the write barrier so we can only use
// immortal immovable root members. They are never in new space. // immortal immovable root members. They are never in new space.
if (current != start && root_index != RootIndexMap::kInvalidRootIndex && if (current != start && root_index != RootIndexMap::kInvalidRootIndex &&
Heap::RootIsImmortalImmovable(root_index) && Heap::RootIsImmortalImmovable(
static_cast<Heap::RootListIndex>(root_index)) &&
current_contents == current[-1]) { current_contents == current[-1]) {
DCHECK(!serializer_->isolate()->heap()->InNewSpace(current_contents)); DCHECK(!serializer_->isolate()->heap()->InNewSpace(current_contents));
int repeat_count = 1; int repeat_count = 1;
......
...@@ -129,6 +129,11 @@ class Unique { ...@@ -129,6 +129,11 @@ class Unique {
return Unique<T>(reinterpret_cast<Address>(*handle), handle); return Unique<T>(reinterpret_cast<Address>(*handle), handle);
} }
T* GetRawAddress() const {
DCHECK(IsInitialized());
return reinterpret_cast<T*>(raw_address_);
}
friend class UniqueSet<T>; // Uses internal details for speed. friend class UniqueSet<T>; // Uses internal details for speed.
template <class U> template <class U>
friend class Unique; // For comparing raw_address values. friend class Unique; // For comparing raw_address values.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment