Commit 01eb8ff9 authored by Dominik Inführ's avatar Dominik Inführ Committed by V8 LUCI CQ

[heap] Support --expose-gc with shared heap

--shared-string-table assumes that all old strings are in the shared
heap. However, when also using --expose-gc we create an external string
for the GC function name. So far external strings are always allocated
in the local old space though, which results in a heap verification
error. This CL creates external string in the shared old heap with
--shared-string-table enabled.

In order to pass all the tests this CL also has to:

* Stop marking into the shared heap for VisitEmbeddedPointer and
  VisitCodePointer.
* Relax DCHECK in String::GetFlatContent: We cannot check the thread
  id for any shared string. Even if that string isn't really shared atm.

Bug: v8:11708
Change-Id: I51fec5ba038d035be5fe5e1277ef9286efc8dc2a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3447371Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79022}
parent 211a4240
......@@ -16,6 +16,7 @@
#include "src/heap/read-only-heap.h"
#include "src/logging/local-logger.h"
#include "src/logging/log.h"
#include "src/objects/instance-type.h"
#include "src/objects/literal-objects-inl.h"
#include "src/objects/module-inl.h"
#include "src/objects/oddball.h"
......@@ -1071,7 +1072,8 @@ FactoryBase<Impl>::RefineAllocationTypeForInPlaceInternalizableString(
#ifdef DEBUG
InstanceType instance_type = string_map.instance_type();
DCHECK(InstanceTypeChecker::IsInternalizedString(instance_type) ||
String::IsInPlaceInternalizable(instance_type));
String::IsInPlaceInternalizable(instance_type) ||
InstanceTypeChecker::IsExternalString(instance_type));
#endif
if (FLAG_single_generation && allocation == AllocationType::kYoung) {
allocation = AllocationType::kOld;
......
......@@ -1056,14 +1056,20 @@ MaybeHandle<String> Factory::NewExternalStringFromOneByte(
Handle<Map> map = resource->IsCacheable()
? external_one_byte_string_map()
: uncached_external_one_byte_string_map();
AllocationType type = RefineAllocationTypeForInPlaceInternalizableString(
AllocationType::kOld, *map);
ExternalOneByteString external_string =
ExternalOneByteString::cast(New(map, AllocationType::kOld));
ExternalOneByteString::cast(New(map, type));
DisallowGarbageCollection no_gc;
external_string.AllocateExternalPointerEntries(isolate());
external_string.set_length(static_cast<int>(length));
external_string.set_raw_hash_field(String::kEmptyHashField);
external_string.SetResource(isolate(), resource);
isolate()->heap()->RegisterExternalString(external_string);
Heap* owner_heap = isolate()->OwnsStringTable()
? isolate()->heap()
: isolate()->shared_isolate()->heap();
owner_heap->RegisterExternalString(external_string);
return Handle<String>(external_string, isolate());
}
......@@ -1078,14 +1084,20 @@ MaybeHandle<String> Factory::NewExternalStringFromTwoByte(
Handle<Map> map = resource->IsCacheable() ? external_string_map()
: uncached_external_string_map();
ExternalTwoByteString string =
ExternalTwoByteString::cast(New(map, AllocationType::kOld));
AllocationType type = RefineAllocationTypeForInPlaceInternalizableString(
AllocationType::kOld, *map);
ExternalTwoByteString string = ExternalTwoByteString::cast(New(map, type));
DisallowGarbageCollection no_gc;
string.AllocateExternalPointerEntries(isolate());
string.set_length(static_cast<int>(length));
string.set_raw_hash_field(String::kEmptyHashField);
string.SetResource(isolate(), resource);
isolate()->heap()->RegisterExternalString(string);
Heap* owner_heap = isolate()->OwnsStringTable()
? isolate()->heap()
: isolate()->shared_isolate()->heap();
owner_heap->RegisterExternalString(string);
return Handle<ExternalTwoByteString>(string, isolate());
}
......
......@@ -115,6 +115,8 @@ void MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitEmbeddedPointer(
DCHECK(RelocInfo::IsEmbeddedObjectMode(rinfo->rmode()));
HeapObject object =
rinfo->target_object(ObjectVisitorWithCageBases::cage_base());
if (!is_shared_heap_ && object.InSharedHeap()) return;
if (!concrete_visitor()->marking_state()->IsBlackOrGrey(object)) {
if (host.IsWeakObject(object)) {
local_weak_objects_->weak_objects_in_code_local.Push(
......@@ -132,6 +134,8 @@ void MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitCodeTarget(
Code host, RelocInfo* rinfo) {
DCHECK(RelocInfo::IsCodeTargetMode(rinfo->rmode()));
Code target = Code::GetCodeFromTargetAddress(rinfo->target_address());
if (!is_shared_heap_ && target.InSharedHeap()) return;
MarkObject(host, target);
concrete_visitor()->RecordRelocSlot(host, rinfo, target);
}
......
......@@ -720,7 +720,7 @@ String::FlatContent String::GetFlatContent(
//
// TODO(v8:12007): Currently character data is never overwritten for
// shared strings.
DCHECK_IMPLIES(GetIsolateFromHeapObject(*this, &isolate) && !IsShared(),
DCHECK_IMPLIES(GetIsolateFromHeapObject(*this, &isolate) && !InSharedHeap(),
ThreadId::Current() == isolate->thread_id());
}
#endif
......
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --shared-string-table --allow-natives-syntax --expose-gc
gc();
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