[ptr-compr] Remove i::GetIsolateFromWritableObject(HeapObject, Isolate*)
... and add i::GetIsolateFromHeapObject(HeapObject, Isolate*) and i::IsReadOnlyHeapObject(HeapObject) instead. Previously the removed function was also used for checking if given heap object is a read only object. But if pointer compression is enabled the i::GetIsolateFromHeapObject() will succeed for both read only and writable heap objects. Bug: v8:9379, v8:7703 Change-Id: Ib0a9babafe32f43716dac70620b51657dfb97d7c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1667416 Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#62291}
This commit is contained in:
parent
05f56d94e3
commit
b4e9d6c0a8
@ -5365,20 +5365,15 @@ Local<Value> Symbol::Name() const {
|
|||||||
i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
|
i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
|
||||||
|
|
||||||
i::Isolate* isolate;
|
i::Isolate* isolate;
|
||||||
if (!i::GetIsolateFromWritableObject(*sym, &isolate)) {
|
if (!i::GetIsolateFromHeapObject(*sym, &isolate)) {
|
||||||
// If the Symbol is in RO_SPACE, then its name must be too. Since RO_SPACE
|
// Symbol is in RO_SPACE, which means that its name is also in RO_SPACE.
|
||||||
// objects are immovable we can use the Handle(Address*) constructor with
|
// Since RO_SPACE objects are immovable we can use the Handle(Address*)
|
||||||
// the address of the name field in the Symbol object without needing an
|
// constructor with the address of the name field in the Symbol object
|
||||||
// isolate.
|
// without needing an isolate.
|
||||||
#ifdef V8_COMPRESS_POINTERS
|
DCHECK(!COMPRESS_POINTERS_BOOL);
|
||||||
// Compressed fields can't serve as handle locations.
|
|
||||||
// TODO(ishell): get Isolate as a parameter.
|
|
||||||
isolate = i::Isolate::Current();
|
|
||||||
#else
|
|
||||||
i::Handle<i::HeapObject> ro_name(reinterpret_cast<i::Address*>(
|
i::Handle<i::HeapObject> ro_name(reinterpret_cast<i::Address*>(
|
||||||
sym->GetFieldAddress(i::Symbol::kNameOffset)));
|
sym->GetFieldAddress(i::Symbol::kNameOffset)));
|
||||||
return Utils::ToLocal(ro_name);
|
return Utils::ToLocal(ro_name);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i::Handle<i::Object> name(sym->name(), isolate);
|
i::Handle<i::Object> name(sym->name(), isolate);
|
||||||
@ -6238,8 +6233,7 @@ bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
|
|||||||
|
|
||||||
// It is safe to call GetIsolateFromWritableHeapObject because
|
// It is safe to call GetIsolateFromWritableHeapObject because
|
||||||
// SupportsExternalization already checked that the object is writable.
|
// SupportsExternalization already checked that the object is writable.
|
||||||
i::Isolate* isolate;
|
i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
|
||||||
i::GetIsolateFromWritableObject(obj, &isolate);
|
|
||||||
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
|
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
|
||||||
|
|
||||||
CHECK(resource && resource->data());
|
CHECK(resource && resource->data());
|
||||||
@ -6266,8 +6260,7 @@ bool v8::String::MakeExternal(
|
|||||||
|
|
||||||
// It is safe to call GetIsolateFromWritableHeapObject because
|
// It is safe to call GetIsolateFromWritableHeapObject because
|
||||||
// SupportsExternalization already checked that the object is writable.
|
// SupportsExternalization already checked that the object is writable.
|
||||||
i::Isolate* isolate;
|
i::Isolate* isolate = i::GetIsolateFromWritableObject(obj);
|
||||||
i::GetIsolateFromWritableObject(obj, &isolate);
|
|
||||||
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
|
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
|
||||||
|
|
||||||
CHECK(resource && resource->data());
|
CHECK(resource && resource->data());
|
||||||
|
@ -2510,10 +2510,10 @@ void Map::MapPrint(std::ostream& os) { // NOLINT
|
|||||||
layout_descriptor().ShortPrint(os);
|
layout_descriptor().ShortPrint(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
Isolate* isolate;
|
|
||||||
// Read-only maps can't have transitions, which is fortunate because we need
|
// Read-only maps can't have transitions, which is fortunate because we need
|
||||||
// the isolate to iterate over the transitions.
|
// the isolate to iterate over the transitions.
|
||||||
if (GetIsolateFromWritableObject(*this, &isolate)) {
|
if (!IsReadOnlyHeapObject(*this)) {
|
||||||
|
Isolate* isolate = GetIsolateFromWritableObject(*this);
|
||||||
DisallowHeapAllocation no_gc;
|
DisallowHeapAllocation no_gc;
|
||||||
TransitionsAccessor transitions(isolate, *this, &no_gc);
|
TransitionsAccessor transitions(isolate, *this, &no_gc);
|
||||||
int nof_transitions = transitions.NumberOfTransitions();
|
int nof_transitions = transitions.NumberOfTransitions();
|
||||||
|
@ -33,8 +33,8 @@ bool HandleBase::IsDereferenceAllowed(DereferenceCheckMode mode) const {
|
|||||||
Object object(*location_);
|
Object object(*location_);
|
||||||
if (object.IsSmi()) return true;
|
if (object.IsSmi()) return true;
|
||||||
HeapObject heap_object = HeapObject::cast(object);
|
HeapObject heap_object = HeapObject::cast(object);
|
||||||
Isolate* isolate;
|
if (IsReadOnlyHeapObject(heap_object)) return true;
|
||||||
if (!GetIsolateFromWritableObject(heap_object, &isolate)) return true;
|
Isolate* isolate = GetIsolateFromWritableObject(heap_object);
|
||||||
RootIndex root_index;
|
RootIndex root_index;
|
||||||
if (isolate->roots_table().IsRootHandleLocation(location_, &root_index) &&
|
if (isolate->roots_table().IsRootHandleLocation(location_, &root_index) &&
|
||||||
RootsTable::IsImmortalImmovable(root_index)) {
|
RootsTable::IsImmortalImmovable(root_index)) {
|
||||||
|
@ -239,19 +239,21 @@ inline Heap* GetHeapFromWritableObject(HeapObject object) {
|
|||||||
|
|
||||||
inline Isolate* GetIsolateFromWritableObject(HeapObject object) {
|
inline Isolate* GetIsolateFromWritableObject(HeapObject object) {
|
||||||
#ifdef V8_COMPRESS_POINTERS
|
#ifdef V8_COMPRESS_POINTERS
|
||||||
return Isolate::FromRoot(GetIsolateRoot(object.ptr()));
|
Isolate* isolate = Isolate::FromRoot(GetIsolateRoot(object.ptr()));
|
||||||
|
DCHECK_NOT_NULL(isolate);
|
||||||
|
return isolate;
|
||||||
#else
|
#else
|
||||||
return Isolate::FromHeap(GetHeapFromWritableObject(object));
|
return Isolate::FromHeap(GetHeapFromWritableObject(object));
|
||||||
#endif // V8_COMPRESS_POINTERS
|
#endif // V8_COMPRESS_POINTERS
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool GetIsolateFromWritableObject(HeapObject obj, Isolate** isolate) {
|
inline bool GetIsolateFromHeapObject(HeapObject object, Isolate** isolate) {
|
||||||
#ifdef V8_COMPRESS_POINTERS
|
#ifdef V8_COMPRESS_POINTERS
|
||||||
*isolate = GetIsolateFromWritableObject(obj);
|
*isolate = GetIsolateFromWritableObject(object);
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
heap_internals::MemoryChunk* chunk =
|
heap_internals::MemoryChunk* chunk =
|
||||||
heap_internals::MemoryChunk::FromHeapObject(obj);
|
heap_internals::MemoryChunk::FromHeapObject(object);
|
||||||
if (chunk->InReadOnlySpace()) {
|
if (chunk->InReadOnlySpace()) {
|
||||||
*isolate = nullptr;
|
*isolate = nullptr;
|
||||||
return false;
|
return false;
|
||||||
@ -261,6 +263,12 @@ inline bool GetIsolateFromWritableObject(HeapObject obj, Isolate** isolate) {
|
|||||||
#endif // V8_COMPRESS_POINTERS
|
#endif // V8_COMPRESS_POINTERS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool IsReadOnlyHeapObject(HeapObject object) {
|
||||||
|
heap_internals::MemoryChunk* chunk =
|
||||||
|
heap_internals::MemoryChunk::FromHeapObject(object);
|
||||||
|
return chunk->InReadOnlySpace();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
|
||||||
|
@ -44,6 +44,13 @@ void MarkingBarrierForDescriptorArray(Heap* heap, HeapObject host,
|
|||||||
inline Heap* GetHeapFromWritableObject(HeapObject object);
|
inline Heap* GetHeapFromWritableObject(HeapObject object);
|
||||||
inline Isolate* GetIsolateFromWritableObject(HeapObject object);
|
inline Isolate* GetIsolateFromWritableObject(HeapObject object);
|
||||||
|
|
||||||
|
// Returns true if it succeeded to obtain isolate from given object.
|
||||||
|
// If it fails then the object is definitely a read-only object but it may also
|
||||||
|
// succeed for read only objects if pointer compression is enabled.
|
||||||
|
inline bool GetIsolateFromHeapObject(HeapObject object, Isolate** isolate);
|
||||||
|
|
||||||
|
inline bool IsReadOnlyHeapObject(HeapObject object);
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
|
||||||
|
@ -146,15 +146,15 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
|
|||||||
int size = this->Size(); // Byte size of the original string.
|
int size = this->Size(); // Byte size of the original string.
|
||||||
// Abort if size does not allow in-place conversion.
|
// Abort if size does not allow in-place conversion.
|
||||||
if (size < ExternalString::kUncachedSize) return false;
|
if (size < ExternalString::kUncachedSize) return false;
|
||||||
Isolate* isolate;
|
|
||||||
// Read-only strings cannot be made external, since that would mutate the
|
// Read-only strings cannot be made external, since that would mutate the
|
||||||
// string.
|
// string.
|
||||||
if (!GetIsolateFromWritableObject(*this, &isolate)) return false;
|
if (IsReadOnlyHeapObject(*this)) return false;
|
||||||
Heap* heap = isolate->heap();
|
Isolate* isolate = GetIsolateFromWritableObject(*this);
|
||||||
bool is_internalized = this->IsInternalizedString();
|
bool is_internalized = this->IsInternalizedString();
|
||||||
bool has_pointers = StringShape(*this).IsIndirect();
|
bool has_pointers = StringShape(*this).IsIndirect();
|
||||||
|
|
||||||
if (has_pointers) {
|
if (has_pointers) {
|
||||||
heap->NotifyObjectLayoutChange(*this, size, no_allocation);
|
isolate->heap()->NotifyObjectLayoutChange(*this, size, no_allocation);
|
||||||
}
|
}
|
||||||
// Morph the string to an external string by replacing the map and
|
// Morph the string to an external string by replacing the map and
|
||||||
// reinitializing the fields. This won't work if the space the existing
|
// reinitializing the fields. This won't work if the space the existing
|
||||||
@ -163,7 +163,7 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
|
|||||||
// the address of the backing store. When we encounter uncached external
|
// the address of the backing store. When we encounter uncached external
|
||||||
// strings in generated code, we need to bailout to runtime.
|
// strings in generated code, we need to bailout to runtime.
|
||||||
Map new_map;
|
Map new_map;
|
||||||
ReadOnlyRoots roots(heap);
|
ReadOnlyRoots roots(isolate);
|
||||||
if (size < ExternalString::kSizeOfAllExternalStrings) {
|
if (size < ExternalString::kSizeOfAllExternalStrings) {
|
||||||
if (is_internalized) {
|
if (is_internalized) {
|
||||||
new_map = roots.uncached_external_internalized_string_map();
|
new_map = roots.uncached_external_internalized_string_map();
|
||||||
@ -177,10 +177,11 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
|
|||||||
|
|
||||||
// Byte size of the external String object.
|
// Byte size of the external String object.
|
||||||
int new_size = this->SizeFromMap(new_map);
|
int new_size = this->SizeFromMap(new_map);
|
||||||
heap->CreateFillerObjectAt(this->address() + new_size, size - new_size,
|
isolate->heap()->CreateFillerObjectAt(
|
||||||
ClearRecordedSlots::kNo);
|
this->address() + new_size, size - new_size, ClearRecordedSlots::kNo);
|
||||||
if (has_pointers) {
|
if (has_pointers) {
|
||||||
heap->ClearRecordedSlotRange(this->address(), this->address() + new_size);
|
isolate->heap()->ClearRecordedSlotRange(this->address(),
|
||||||
|
this->address() + new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are storing the new map using release store after creating a filler for
|
// We are storing the new map using release store after creating a filler for
|
||||||
@ -189,7 +190,7 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
|
|||||||
|
|
||||||
ExternalTwoByteString self = ExternalTwoByteString::cast(*this);
|
ExternalTwoByteString self = ExternalTwoByteString::cast(*this);
|
||||||
self.SetResource(isolate, resource);
|
self.SetResource(isolate, resource);
|
||||||
heap->RegisterExternalString(*this);
|
isolate->heap()->RegisterExternalString(*this);
|
||||||
if (is_internalized) self.Hash(); // Force regeneration of the hash value.
|
if (is_internalized) self.Hash(); // Force regeneration of the hash value.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -218,18 +219,16 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
|
|||||||
int size = this->Size(); // Byte size of the original string.
|
int size = this->Size(); // Byte size of the original string.
|
||||||
// Abort if size does not allow in-place conversion.
|
// Abort if size does not allow in-place conversion.
|
||||||
if (size < ExternalString::kUncachedSize) return false;
|
if (size < ExternalString::kUncachedSize) return false;
|
||||||
Isolate* isolate;
|
|
||||||
// Read-only strings cannot be made external, since that would mutate the
|
// Read-only strings cannot be made external, since that would mutate the
|
||||||
// string.
|
// string.
|
||||||
if (!GetIsolateFromWritableObject(*this, &isolate)) return false;
|
if (IsReadOnlyHeapObject(*this)) return false;
|
||||||
Heap* heap = isolate->heap();
|
Isolate* isolate = GetIsolateFromWritableObject(*this);
|
||||||
bool is_internalized = this->IsInternalizedString();
|
bool is_internalized = this->IsInternalizedString();
|
||||||
bool has_pointers = StringShape(*this).IsIndirect();
|
bool has_pointers = StringShape(*this).IsIndirect();
|
||||||
|
|
||||||
if (has_pointers) {
|
if (has_pointers) {
|
||||||
heap->NotifyObjectLayoutChange(*this, size, no_allocation);
|
isolate->heap()->NotifyObjectLayoutChange(*this, size, no_allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Morph the string to an external string by replacing the map and
|
// Morph the string to an external string by replacing the map and
|
||||||
// reinitializing the fields. This won't work if the space the existing
|
// reinitializing the fields. This won't work if the space the existing
|
||||||
// string occupies is too small for a regular external string. Instead, we
|
// string occupies is too small for a regular external string. Instead, we
|
||||||
@ -237,7 +236,7 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
|
|||||||
// the address of the backing store. When we encounter uncached external
|
// the address of the backing store. When we encounter uncached external
|
||||||
// strings in generated code, we need to bailout to runtime.
|
// strings in generated code, we need to bailout to runtime.
|
||||||
Map new_map;
|
Map new_map;
|
||||||
ReadOnlyRoots roots(heap);
|
ReadOnlyRoots roots(isolate);
|
||||||
if (size < ExternalString::kSizeOfAllExternalStrings) {
|
if (size < ExternalString::kSizeOfAllExternalStrings) {
|
||||||
new_map = is_internalized
|
new_map = is_internalized
|
||||||
? roots.uncached_external_one_byte_internalized_string_map()
|
? roots.uncached_external_one_byte_internalized_string_map()
|
||||||
@ -250,10 +249,11 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
|
|||||||
|
|
||||||
// Byte size of the external String object.
|
// Byte size of the external String object.
|
||||||
int new_size = this->SizeFromMap(new_map);
|
int new_size = this->SizeFromMap(new_map);
|
||||||
heap->CreateFillerObjectAt(this->address() + new_size, size - new_size,
|
isolate->heap()->CreateFillerObjectAt(
|
||||||
ClearRecordedSlots::kNo);
|
this->address() + new_size, size - new_size, ClearRecordedSlots::kNo);
|
||||||
if (has_pointers) {
|
if (has_pointers) {
|
||||||
heap->ClearRecordedSlotRange(this->address(), this->address() + new_size);
|
isolate->heap()->ClearRecordedSlotRange(this->address(),
|
||||||
|
this->address() + new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are storing the new map using release store after creating a filler for
|
// We are storing the new map using release store after creating a filler for
|
||||||
@ -262,7 +262,7 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
|
|||||||
|
|
||||||
ExternalOneByteString self = ExternalOneByteString::cast(*this);
|
ExternalOneByteString self = ExternalOneByteString::cast(*this);
|
||||||
self.SetResource(isolate, resource);
|
self.SetResource(isolate, resource);
|
||||||
heap->RegisterExternalString(*this);
|
isolate->heap()->RegisterExternalString(*this);
|
||||||
if (is_internalized) self.Hash(); // Force regeneration of the hash value.
|
if (is_internalized) self.Hash(); // Force regeneration of the hash value.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -272,9 +272,8 @@ bool String::SupportsExternalization() {
|
|||||||
return i::ThinString::cast(*this).actual().SupportsExternalization();
|
return i::ThinString::cast(*this).actual().SupportsExternalization();
|
||||||
}
|
}
|
||||||
|
|
||||||
Isolate* isolate;
|
|
||||||
// RO_SPACE strings cannot be externalized.
|
// RO_SPACE strings cannot be externalized.
|
||||||
if (!GetIsolateFromWritableObject(*this, &isolate)) {
|
if (IsReadOnlyHeapObject(*this)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,6 +289,7 @@ bool String::SupportsExternalization() {
|
|||||||
DCHECK_LE(ExternalString::kUncachedSize, this->Size());
|
DCHECK_LE(ExternalString::kUncachedSize, this->Size());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Isolate* isolate = GetIsolateFromWritableObject(*this);
|
||||||
return !isolate->heap()->IsInGCPostProcessing();
|
return !isolate->heap()->IsInGCPostProcessing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user