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,
bool CodeGenerator::IsMaterializableFromRoot(
Handle<HeapObject> object, Heap::RootListIndex* index_return) {
if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) {
return isolate()->heap()->GetRootListIndex(object, index_return);
Heap::RootListIndex index;
if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall() &&
isolate()->heap()->GetRootListIndex(*object, &index) &&
!Heap::RootCanBeWrittenAfterInitialization(index)) {
*index_return = index;
return true;
}
return false;
}
......
......@@ -4907,29 +4907,84 @@ bool Heap::InSpace(Address addr, AllocationSpace space) {
}
bool Heap::RootIsImmortalImmovable(int root_index) {
switch (root_index) {
#define CASE(name) \
case Heap::k##name##RootIndex: \
// static
bool Heap::RootIsImmortalImmovable(RootListIndex index) {
// 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.
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;
IMMORTAL_IMMOVABLE_ROOT_LIST(CASE);
#undef CASE
default:
return false;
}
}
bool Heap::GetRootListIndex(Handle<HeapObject> object,
Heap::RootListIndex* index_return) {
Object* ptr = *object;
#define IMMORTAL_IMMOVABLE_ROOT(Name) \
if (ptr == roots_[Heap::k##Name##RootIndex]) { \
*index_return = k##Name##RootIndex; \
return true; \
bool Heap::GetRootListIndex(Object* object, RootListIndex* index_return) const {
for (size_t i = 0; i < arraysize(roots_); ++i) {
if (roots_[i] == object) {
*index_return = static_cast<RootListIndex>(i);
return true;
}
}
IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT)
#undef IMMORTAL_IMMOVABLE_ROOT
return false;
}
......
......@@ -324,60 +324,6 @@ namespace internal {
V(to_string_tag_symbol, symbolToStringTag, Symbol.toStringTag) \
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.
class HeapStats;
class Isolate;
......@@ -995,7 +941,6 @@ class Heap {
return reinterpret_cast<Address*>(&roots_[kStoreBufferTopRootIndex]);
}
static bool RootIsImmortalImmovable(int root_index);
void CheckHandleCount();
#ifdef VERIFY_HEAP
......@@ -1187,7 +1132,7 @@ class Heap {
#define STRING_INDEX_DECLARATION(name, str) k##name##RootIndex,
INTERNALIZED_STRING_LIST(STRING_INDEX_DECLARATION)
#undef STRING_DECLARATION
#undef STRING_INDEX_DECLARATION
#define SYMBOL_INDEX_DECLARATION(name) k##name##RootIndex,
PRIVATE_SYMBOL_LIST(SYMBOL_INDEX_DECLARATION)
......@@ -1211,9 +1156,11 @@ class Heap {
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.
bool GetRootListIndex(Handle<HeapObject> object,
Heap::RootListIndex* index_return);
bool GetRootListIndex(Object* object, RootListIndex* index_return) const;
Object* root(RootListIndex index) { return roots_[index]; }
......
......@@ -2872,20 +2872,9 @@ bool HConstant::ImmortalImmovable() const {
Heap* heap = isolate()->heap();
DCHECK(!object_.IsKnownGlobal(heap->minus_zero_value()));
DCHECK(!object_.IsKnownGlobal(heap->nan_value()));
return
#define IMMORTAL_IMMOVABLE_ROOT(name) \
object_.IsKnownGlobal(heap->root(Heap::k##name##RootIndex)) ||
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;
Heap::RootListIndex index;
return heap->GetRootListIndex(object_.GetRawAddress(), &index) &&
Heap::RootIsImmortalImmovable(index);
}
......
......@@ -1934,7 +1934,8 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start,
// Repeats are not subject to the write barrier so we can only use
// immortal immovable root members. They are never in new space.
if (current != start && root_index != RootIndexMap::kInvalidRootIndex &&
Heap::RootIsImmortalImmovable(root_index) &&
Heap::RootIsImmortalImmovable(
static_cast<Heap::RootListIndex>(root_index)) &&
current_contents == current[-1]) {
DCHECK(!serializer_->isolate()->heap()->InNewSpace(current_contents));
int repeat_count = 1;
......
......@@ -129,6 +129,11 @@ class Unique {
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.
template <class U>
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