[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}
This commit is contained in:
parent
6a63a6d4cf
commit
84e83da99a
@ -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: \
|
||||
return true;
|
||||
IMMORTAL_IMMOVABLE_ROOT_LIST(CASE);
|
||||
#undef CASE
|
||||
// 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;
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user