Commit c43380fe authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[cleanup] Avoid accessing MemoryChunk directly to get Isolate

Adds an Isolate::FromWritableHeapObject method, with a bool return value
and Isolate* out parameter, and replace most accesses to Isolate via
MemoryChunk (which handle objectsin ROSpace rather than just failing) to
use that instead.

Bug: v8:7754
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: Idb472a3d6037deed92e6fa8c8a7a1a14293e2462
Reviewed-on: https://chromium-review.googlesource.com/1144933
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54579}
parent 1baf1050
...@@ -219,6 +219,8 @@ Local<Context> ContextFromNeverReadOnlySpaceObject( ...@@ -219,6 +219,8 @@ Local<Context> ContextFromNeverReadOnlySpaceObject(
// it are removed. // it are removed.
// DO NOT USE THIS IN NEW CODE! // DO NOT USE THIS IN NEW CODE!
i::Isolate* UnsafeIsolateFromHeapObject(i::Handle<i::HeapObject> obj) { i::Isolate* UnsafeIsolateFromHeapObject(i::Handle<i::HeapObject> obj) {
// Use MemoryChunk directly instead of Isolate::FromWritableHeapObject to
// temporarily allow isolate access from read-only space objects.
i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(*obj); i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(*obj);
return chunk->heap()->isolate(); return chunk->heap()->isolate();
} }
...@@ -227,6 +229,8 @@ i::Isolate* UnsafeIsolateFromHeapObject(i::Handle<i::HeapObject> obj) { ...@@ -227,6 +229,8 @@ i::Isolate* UnsafeIsolateFromHeapObject(i::Handle<i::HeapObject> obj) {
// it are removed. // it are removed.
// DO NOT USE THIS IN NEW CODE! // DO NOT USE THIS IN NEW CODE!
Local<Context> UnsafeContextFromHeapObject(i::Handle<i::Object> obj) { Local<Context> UnsafeContextFromHeapObject(i::Handle<i::Object> obj) {
// Use MemoryChunk directly instead of Isolate::FromWritableHeapObject to
// temporarily allow isolate access from read-only space objects.
i::MemoryChunk* chunk = i::MemoryChunk* chunk =
i::MemoryChunk::FromHeapObject(i::HeapObject::cast(*obj)); i::MemoryChunk::FromHeapObject(i::HeapObject::cast(*obj));
return reinterpret_cast<Isolate*>(chunk->heap()->isolate()) return reinterpret_cast<Isolate*>(chunk->heap()->isolate())
...@@ -5973,17 +5977,18 @@ v8::String::GetExternalOneByteStringResource() const { ...@@ -5973,17 +5977,18 @@ v8::String::GetExternalOneByteStringResource() const {
Local<Value> Symbol::Name() const { Local<Value> Symbol::Name() const {
i::Handle<i::Symbol> sym = Utils::OpenHandle(this); i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(*sym); i::Isolate* isolate;
if (!i::Isolate::FromWritableHeapObject(*sym, &isolate)) {
// If the Symbol is in RO_SPACE, then its name must be too. Since RO_SPACE // If the Symbol is in RO_SPACE, then its name must be too. Since RO_SPACE
// objects are immovable we can use the Handle(T**) constructor with the // objects are immovable we can use the Handle(T**) constructor with the
// address of the name field in the Symbol object without needing an isolate. // address of the name field in the Symbol object without needing an
if (chunk->owner()->identity() == i::RO_SPACE) { // isolate.
i::Handle<i::HeapObject> ro_name(reinterpret_cast<i::HeapObject**>( i::Handle<i::HeapObject> ro_name(reinterpret_cast<i::HeapObject**>(
sym->GetFieldAddress(i::Symbol::kNameOffset))); sym->GetFieldAddress(i::Symbol::kNameOffset)));
return Utils::ToLocal(ro_name); return Utils::ToLocal(ro_name);
} }
i::Handle<i::Object> name(sym->name(), chunk->heap()->isolate()); i::Handle<i::Object> name(sym->name(), isolate);
return Utils::ToLocal(name); return Utils::ToLocal(name);
} }
...@@ -6852,13 +6857,13 @@ Local<String> v8::String::NewExternal( ...@@ -6852,13 +6857,13 @@ Local<String> v8::String::NewExternal(
bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
i::Handle<i::String> obj = Utils::OpenHandle(this); i::Handle<i::String> obj = Utils::OpenHandle(this);
i::Isolate* isolate;
if (!i::Isolate::FromWritableHeapObject(*obj, &isolate)) {
// RO_SPACE strings cannot be externalized. // RO_SPACE strings cannot be externalized.
i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(*obj);
if (chunk->owner()->identity() == i::RO_SPACE) {
return false; return false;
} }
i::Isolate* isolate = chunk->heap()->isolate();
if (i::StringShape(*obj).IsExternal()) { if (i::StringShape(*obj).IsExternal()) {
return false; // Already an external string. return false; // Already an external string.
} }
...@@ -6882,13 +6887,12 @@ bool v8::String::MakeExternal( ...@@ -6882,13 +6887,12 @@ bool v8::String::MakeExternal(
v8::String::ExternalOneByteStringResource* resource) { v8::String::ExternalOneByteStringResource* resource) {
i::Handle<i::String> obj = Utils::OpenHandle(this); i::Handle<i::String> obj = Utils::OpenHandle(this);
i::Isolate* isolate;
if (!i::Isolate::FromWritableHeapObject(*obj, &isolate)) {
// RO_SPACE strings cannot be externalized. // RO_SPACE strings cannot be externalized.
i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(*obj);
if (chunk->owner()->identity() == i::RO_SPACE) {
return false; return false;
} }
i::Isolate* isolate = chunk->heap()->isolate();
if (i::StringShape(*obj).IsExternal()) { if (i::StringShape(*obj).IsExternal()) {
return false; // Already an external string. return false; // Already an external string.
} }
...@@ -6912,10 +6916,13 @@ bool v8::String::CanMakeExternal() { ...@@ -6912,10 +6916,13 @@ bool v8::String::CanMakeExternal() {
i::Handle<i::String> obj = Utils::OpenHandle(this); i::Handle<i::String> obj = Utils::OpenHandle(this);
if (obj->IsExternalString()) return false; if (obj->IsExternalString()) return false;
i::Isolate* isolate;
if (!i::Isolate::FromWritableHeapObject(*obj, &isolate)) {
// RO_SPACE strings cannot be externalized.
return false;
}
// Only old space strings should be externalized. // Only old space strings should be externalized.
i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(*obj); return !i::Heap::InNewSpace(*obj);
i::AllocationSpace space = chunk->owner()->identity();
return space != i::NEW_SPACE && space != i::RO_SPACE;
} }
......
...@@ -26,9 +26,9 @@ bool HandleBase::IsDereferenceAllowed(DereferenceCheckMode mode) const { ...@@ -26,9 +26,9 @@ 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);
MemoryChunk* chunk = MemoryChunk::FromHeapObject(heap_object); Isolate* isolate;
if (chunk->owner()->identity() == RO_SPACE) return true; if (!Isolate::FromWritableHeapObject(heap_object, &isolate)) return true;
Heap* heap = chunk->heap(); Heap* heap = isolate->heap();
Object** roots_array_start = heap->roots_array_start(); Object** roots_array_start = heap->roots_array_start();
if (roots_array_start <= location_ && if (roots_array_start <= location_ &&
location_ < roots_array_start + Heap::kStrongRootListLength && location_ < roots_array_start + Heap::kStrongRootListLength &&
...@@ -43,7 +43,7 @@ bool HandleBase::IsDereferenceAllowed(DereferenceCheckMode mode) const { ...@@ -43,7 +43,7 @@ bool HandleBase::IsDereferenceAllowed(DereferenceCheckMode mode) const {
if (heap_object->IsCell()) return true; if (heap_object->IsCell()) return true;
if (heap_object->IsMap()) return true; if (heap_object->IsMap()) return true;
if (heap_object->IsInternalizedString()) return true; if (heap_object->IsInternalizedString()) return true;
return !heap->isolate()->IsDeferredHandle(location_); return !isolate->IsDeferredHandle(location_);
} }
return true; return true;
} }
......
...@@ -11,6 +11,15 @@ ...@@ -11,6 +11,15 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
bool Isolate::FromWritableHeapObject(HeapObject* obj, Isolate** isolate) {
i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(obj);
if (chunk->owner()->identity() == i::RO_SPACE) {
*isolate = nullptr;
return false;
}
*isolate = chunk->heap()->isolate();
return true;
}
void Isolate::set_context(Context* context) { void Isolate::set_context(Context* context) {
DCHECK(context == nullptr || context->IsContext()); DCHECK(context == nullptr || context->IsContext());
......
...@@ -556,6 +556,11 @@ class Isolate : private HiddenFactory { ...@@ -556,6 +556,11 @@ class Isolate : private HiddenFactory {
return isolate; return isolate;
} }
// Get the isolate that the given HeapObject lives in, returning true on
// success. If the object is not writable (i.e. lives in read-only space),
// return false.
inline static bool FromWritableHeapObject(HeapObject* obj, Isolate** isolate);
// Usually called by Init(), but can be called early e.g. to allow // Usually called by Init(), but can be called early e.g. to allow
// testing components that require logging but not the whole // testing components that require logging but not the whole
// isolate. // isolate.
......
...@@ -803,12 +803,12 @@ void Map::MapPrint(std::ostream& os) { // NOLINT ...@@ -803,12 +803,12 @@ void Map::MapPrint(std::ostream& os) { // NOLINT
layout_descriptor()->ShortPrint(os); layout_descriptor()->ShortPrint(os);
} }
MemoryChunk* chunk = MemoryChunk::FromHeapObject(this); 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 (chunk->owner()->identity() != RO_SPACE) { if (Isolate::FromWritableHeapObject(this, &isolate)) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
TransitionsAccessor transitions(chunk->heap()->isolate(), this, &no_gc); TransitionsAccessor transitions(isolate, this, &no_gc);
int nof_transitions = transitions.NumberOfTransitions(); int nof_transitions = transitions.NumberOfTransitions();
if (nof_transitions > 0) { if (nof_transitions > 0) {
os << "\n - transitions #" << nof_transitions << ": "; os << "\n - transitions #" << nof_transitions << ": ";
......
...@@ -2588,11 +2588,11 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) { ...@@ -2588,11 +2588,11 @@ 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::kShortSize) return false; if (size < ExternalString::kShortSize) return false;
MemoryChunk* chunk = MemoryChunk::FromHeapObject(this); 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 (chunk->owner()->identity() == RO_SPACE) return false; if (!Isolate::FromWritableHeapObject(this, &isolate)) return false;
Heap* heap = chunk->heap(); Heap* heap = isolate->heap();
bool is_one_byte = this->IsOneByteRepresentation(); bool is_one_byte = this->IsOneByteRepresentation();
bool is_internalized = this->IsInternalizedString(); bool is_internalized = this->IsInternalizedString();
bool has_pointers = StringShape(this).IsIndirect(); bool has_pointers = StringShape(this).IsIndirect();
...@@ -2673,11 +2673,11 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) { ...@@ -2673,11 +2673,11 @@ 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::kShortSize) return false; if (size < ExternalString::kShortSize) return false;
MemoryChunk* chunk = MemoryChunk::FromHeapObject(this); 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 (chunk->owner()->identity() == RO_SPACE) return false; if (!Isolate::FromWritableHeapObject(this, &isolate)) return false;
Heap* heap = chunk->heap(); Heap* heap = isolate->heap();
bool is_internalized = this->IsInternalizedString(); bool is_internalized = this->IsInternalizedString();
bool has_pointers = StringShape(this).IsIndirect(); bool has_pointers = StringShape(this).IsIndirect();
......
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