[TurboFan] Transition SharedFunctionInfo to kNeverSerialized (1)
This is the 1st step in series of CLs to move the SharedFunctionInfo class to kNeverSerialized and make it concurrently accessible from the background thread. This CL: * Enables direct heap reads for the most basic members of SFI if FLAG_turbo_direct_heap_reads is enabled. * Adds synchronization to SharedFunctionInfo::script_or_debug_info. Bug: v8:7790 Change-Id: Ia7d28033e9053aae5771b1b9b174de40f194534d Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2461238 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Santiago Aboy Solanes <solanes@chromium.org> Commit-Queue: Nico Hartmann <nicohartmann@chromium.org> Cr-Commit-Position: refs/heads/master@{#70877}
This commit is contained in:
parent
eeb74f09c1
commit
e600d775f1
@ -793,7 +793,6 @@ class ScopeInfoRef : public HeapObjectRef {
|
||||
V(bool, HasBuiltinId) \
|
||||
V(bool, construct_as_builtin) \
|
||||
V(bool, HasBytecodeArray) \
|
||||
V(SharedFunctionInfo::Inlineability, GetInlineability) \
|
||||
V(int, StartPosition) \
|
||||
V(bool, is_compiled) \
|
||||
V(bool, IsUserJavaScript)
|
||||
@ -807,6 +806,7 @@ class V8_EXPORT_PRIVATE SharedFunctionInfoRef : public HeapObjectRef {
|
||||
int builtin_id() const;
|
||||
int context_header_size() const;
|
||||
BytecodeArrayRef GetBytecodeArray() const;
|
||||
SharedFunctionInfo::Inlineability GetInlineability() const;
|
||||
|
||||
#define DECL_ACCESSOR(type, name) type name() const;
|
||||
BROKER_SFI_FIELDS(DECL_ACCESSOR)
|
||||
|
@ -1783,6 +1783,9 @@ class SharedFunctionInfoData : public HeapObjectData {
|
||||
int builtin_id() const { return builtin_id_; }
|
||||
int context_header_size() const { return context_header_size_; }
|
||||
ObjectData* GetBytecodeArray() const { return GetBytecodeArray_; }
|
||||
SharedFunctionInfo::Inlineability GetInlineability() const {
|
||||
return inlineability_;
|
||||
}
|
||||
void SerializeFunctionTemplateInfo(JSHeapBroker* broker);
|
||||
ObjectData* scope_info() const { return scope_info_; }
|
||||
void SerializeScopeInfoChain(JSHeapBroker* broker);
|
||||
@ -1806,11 +1809,12 @@ class SharedFunctionInfoData : public HeapObjectData {
|
||||
|
||||
private:
|
||||
int const builtin_id_;
|
||||
int context_header_size_;
|
||||
int const context_header_size_;
|
||||
ObjectData* const GetBytecodeArray_;
|
||||
#define DECL_MEMBER(type, name) type const name##_;
|
||||
BROKER_SFI_FIELDS(DECL_MEMBER)
|
||||
#undef DECL_MEMBER
|
||||
SharedFunctionInfo::Inlineability const inlineability_;
|
||||
ObjectData* function_template_info_;
|
||||
ZoneMap<int, ObjectData*> template_objects_;
|
||||
ObjectData* scope_info_;
|
||||
@ -1831,6 +1835,7 @@ SharedFunctionInfoData::SharedFunctionInfoData(
|
||||
BROKER_SFI_FIELDS(INIT_MEMBER)
|
||||
#undef INIT_MEMBER
|
||||
,
|
||||
inlineability_(object->GetInlineability()),
|
||||
function_template_info_(nullptr),
|
||||
template_objects_(broker->zone()),
|
||||
scope_info_(nullptr) {
|
||||
@ -3350,8 +3355,17 @@ int BytecodeArrayRef::handler_table_size() const {
|
||||
return BitField::decode(ObjectRef::data()->As##holder()->field()); \
|
||||
}
|
||||
|
||||
// Like IF_ACCESS_FROM_HEAP_C but we also allow direct heap access for
|
||||
// Like IF_ACCESS_FROM_HEAP[_C] but we also allow direct heap access for
|
||||
// kSerialized only for methods that we identified to be safe.
|
||||
#define IF_ACCESS_FROM_HEAP_WITH_FLAG(result, name) \
|
||||
if (data_->should_access_heap() || FLAG_turbo_direct_heap_access) { \
|
||||
AllowHandleAllocationIfNeeded handle_allocation( \
|
||||
data_->kind(), broker()->mode(), FLAG_turbo_direct_heap_access); \
|
||||
AllowHandleDereferenceIfNeeded allow_handle_dereference( \
|
||||
data_->kind(), broker()->mode(), FLAG_turbo_direct_heap_access); \
|
||||
return result##Ref(broker(), \
|
||||
broker()->CanonicalPersistentHandle(object()->name())); \
|
||||
}
|
||||
#define IF_ACCESS_FROM_HEAP_WITH_FLAG_C(name) \
|
||||
if (data_->should_access_heap() || FLAG_turbo_direct_heap_access) { \
|
||||
AllowHandleAllocationIfNeeded handle_allocation( \
|
||||
@ -3361,10 +3375,15 @@ int BytecodeArrayRef::handler_table_size() const {
|
||||
return object()->name(); \
|
||||
}
|
||||
|
||||
// Like BIMODAL_ACCESSOR_C except that we force a direct heap access if
|
||||
// Like BIMODAL_ACCESSOR[_C] except that we force a direct heap access if
|
||||
// FLAG_turbo_direct_heap_access is true (even for kSerialized). This is because
|
||||
// we identified the method to be safe to use direct heap access, but the
|
||||
// holder##Data class still needs to be serialized.
|
||||
#define BIMODAL_ACCESSOR_WITH_FLAG(holder, result, name) \
|
||||
result##Ref holder##Ref::name() const { \
|
||||
IF_ACCESS_FROM_HEAP_WITH_FLAG(result, name); \
|
||||
return result##Ref(broker(), ObjectRef::data()->As##holder()->name()); \
|
||||
}
|
||||
#define BIMODAL_ACCESSOR_WITH_FLAG_C(holder, result, name) \
|
||||
result holder##Ref::name() const { \
|
||||
IF_ACCESS_FROM_HEAP_WITH_FLAG_C(name); \
|
||||
@ -3573,9 +3592,11 @@ BIMODAL_ACCESSOR(ScopeInfo, ScopeInfo, OuterScopeInfo)
|
||||
BIMODAL_ACCESSOR_C(SharedFunctionInfo, int, builtin_id)
|
||||
BIMODAL_ACCESSOR(SharedFunctionInfo, BytecodeArray, GetBytecodeArray)
|
||||
#define DEF_SFI_ACCESSOR(type, name) \
|
||||
BIMODAL_ACCESSOR_C(SharedFunctionInfo, type, name)
|
||||
BIMODAL_ACCESSOR_WITH_FLAG_C(SharedFunctionInfo, type, name)
|
||||
BROKER_SFI_FIELDS(DEF_SFI_ACCESSOR)
|
||||
#undef DEF_SFI_ACCESSOR
|
||||
BIMODAL_ACCESSOR_C(SharedFunctionInfo, SharedFunctionInfo::Inlineability,
|
||||
GetInlineability)
|
||||
|
||||
BIMODAL_ACCESSOR_C(String, int, length)
|
||||
|
||||
|
@ -1704,7 +1704,8 @@ void Debug::FreeDebugInfoListNode(DebugInfoListNode* prev,
|
||||
// Pack script back into the
|
||||
// SFI::script_or_debug_info field.
|
||||
Handle<DebugInfo> debug_info(node->debug_info());
|
||||
debug_info->shared().set_script_or_debug_info(debug_info->script());
|
||||
debug_info->shared().set_script_or_debug_info(debug_info->script(),
|
||||
kReleaseStore);
|
||||
|
||||
delete node;
|
||||
}
|
||||
|
@ -841,8 +841,11 @@ void SharedFunctionInfo::SharedFunctionInfoVerify(ReadOnlyRoots roots) {
|
||||
HasUncompiledDataWithoutPreparseData() || HasWasmJSFunctionData() ||
|
||||
HasWasmCapiFunctionData());
|
||||
|
||||
CHECK(script_or_debug_info().IsUndefined(roots) ||
|
||||
script_or_debug_info().IsScript() || HasDebugInfo());
|
||||
{
|
||||
auto script = script_or_debug_info(kAcquireLoad);
|
||||
CHECK(script.IsUndefined(roots) || script.IsScript() ||
|
||||
script.IsDebugInfo());
|
||||
}
|
||||
|
||||
if (!is_compiled()) {
|
||||
CHECK(!HasFeedbackMetadata());
|
||||
|
@ -3054,7 +3054,7 @@ Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
|
||||
debug_info->set_debugger_hints(0);
|
||||
DCHECK_EQ(DebugInfo::kNoDebuggingId, debug_info->debugging_id());
|
||||
DCHECK(!shared->HasDebugInfo());
|
||||
debug_info->set_script(shared->script_or_debug_info());
|
||||
debug_info->set_script(shared->script_or_debug_info(kAcquireLoad));
|
||||
debug_info->set_original_bytecode_array(
|
||||
ReadOnlyRoots(heap).undefined_value());
|
||||
debug_info->set_debug_bytecode_array(ReadOnlyRoots(heap).undefined_value());
|
||||
|
@ -103,8 +103,8 @@ RELEASE_ACQUIRE_ACCESSORS(SharedFunctionInfo, function_data, Object,
|
||||
kFunctionDataOffset)
|
||||
RELEASE_ACQUIRE_ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object,
|
||||
kNameOrScopeInfoOffset)
|
||||
ACCESSORS(SharedFunctionInfo, script_or_debug_info, HeapObject,
|
||||
kScriptOrDebugInfoOffset)
|
||||
RELEASE_ACQUIRE_ACCESSORS(SharedFunctionInfo, script_or_debug_info, HeapObject,
|
||||
kScriptOrDebugInfoOffset)
|
||||
|
||||
INT32_ACCESSORS(SharedFunctionInfo, function_literal_id,
|
||||
kFunctionLiteralIdOffset)
|
||||
@ -686,7 +686,7 @@ bool SharedFunctionInfo::HasWasmCapiFunctionData() const {
|
||||
}
|
||||
|
||||
HeapObject SharedFunctionInfo::script() const {
|
||||
HeapObject maybe_script = script_or_debug_info();
|
||||
HeapObject maybe_script = script_or_debug_info(kAcquireLoad);
|
||||
if (maybe_script.IsDebugInfo()) {
|
||||
return DebugInfo::cast(maybe_script).script();
|
||||
}
|
||||
@ -694,11 +694,11 @@ HeapObject SharedFunctionInfo::script() const {
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_script(HeapObject script) {
|
||||
HeapObject maybe_debug_info = script_or_debug_info();
|
||||
HeapObject maybe_debug_info = script_or_debug_info(kAcquireLoad);
|
||||
if (maybe_debug_info.IsDebugInfo()) {
|
||||
DebugInfo::cast(maybe_debug_info).set_script(script);
|
||||
} else {
|
||||
set_script_or_debug_info(script);
|
||||
set_script_or_debug_info(script, kReleaseStore);
|
||||
}
|
||||
}
|
||||
|
||||
@ -707,18 +707,19 @@ bool SharedFunctionInfo::is_repl_mode() const {
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasDebugInfo() const {
|
||||
return script_or_debug_info().IsDebugInfo();
|
||||
return script_or_debug_info(kAcquireLoad).IsDebugInfo();
|
||||
}
|
||||
|
||||
DebugInfo SharedFunctionInfo::GetDebugInfo() const {
|
||||
DCHECK(HasDebugInfo());
|
||||
return DebugInfo::cast(script_or_debug_info());
|
||||
auto debug_info = script_or_debug_info(kAcquireLoad);
|
||||
DCHECK(debug_info.IsDebugInfo());
|
||||
return DebugInfo::cast(debug_info);
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::SetDebugInfo(DebugInfo debug_info) {
|
||||
DCHECK(!HasDebugInfo());
|
||||
DCHECK_EQ(debug_info.script(), script_or_debug_info());
|
||||
set_script_or_debug_info(debug_info);
|
||||
DCHECK_EQ(debug_info.script(), script_or_debug_info(kAcquireLoad));
|
||||
set_script_or_debug_info(debug_info, kReleaseStore);
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasInferredName() {
|
||||
|
@ -43,7 +43,8 @@ void SharedFunctionInfo::Init(ReadOnlyRoots ro_roots, int unique_id) {
|
||||
// SharedFunctionInfo in a consistent state.
|
||||
set_raw_outer_scope_info_or_feedback_metadata(ro_roots.the_hole_value(),
|
||||
SKIP_WRITE_BARRIER);
|
||||
set_script_or_debug_info(ro_roots.undefined_value(), SKIP_WRITE_BARRIER);
|
||||
set_script_or_debug_info(ro_roots.undefined_value(), kReleaseStore,
|
||||
SKIP_WRITE_BARRIER);
|
||||
set_function_literal_id(kFunctionLiteralIdInvalid);
|
||||
#if V8_SFI_HAS_UNIQUE_ID
|
||||
set_unique_id(unique_id);
|
||||
|
@ -378,7 +378,7 @@ class SharedFunctionInfo : public HeapObject {
|
||||
// [script_or_debug_info]: One of:
|
||||
// - Script from which the function originates.
|
||||
// - a DebugInfo which holds the actual script [HasDebugInfo()].
|
||||
DECL_ACCESSORS(script_or_debug_info, HeapObject)
|
||||
DECL_RELEASE_ACQUIRE_ACCESSORS(script_or_debug_info, HeapObject)
|
||||
|
||||
inline HeapObject script() const;
|
||||
inline void set_script(HeapObject script);
|
||||
|
@ -1124,7 +1124,7 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
|
||||
SetInternalReference(entry, "name_or_scope_info", name_or_scope_info,
|
||||
SharedFunctionInfo::kNameOrScopeInfoOffset);
|
||||
SetInternalReference(entry, "script_or_debug_info",
|
||||
shared.script_or_debug_info(),
|
||||
shared.script_or_debug_info(kAcquireLoad),
|
||||
SharedFunctionInfo::kScriptOrDebugInfoOffset);
|
||||
SetInternalReference(entry, "function_data",
|
||||
shared.function_data(kAcquireLoad),
|
||||
|
@ -171,7 +171,7 @@ void CodeSerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
|
||||
debug_bytecode_array = debug_info.DebugBytecodeArray();
|
||||
sfi->SetDebugBytecodeArray(debug_info.OriginalBytecodeArray());
|
||||
}
|
||||
sfi->set_script_or_debug_info(debug_info.script());
|
||||
sfi->set_script_or_debug_info(debug_info.script(), kReleaseStore);
|
||||
}
|
||||
DCHECK(!sfi->HasDebugInfo());
|
||||
|
||||
@ -179,7 +179,7 @@ void CodeSerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
|
||||
|
||||
// Restore debug info
|
||||
if (!debug_info.is_null()) {
|
||||
sfi->set_script_or_debug_info(debug_info);
|
||||
sfi->set_script_or_debug_info(debug_info, kReleaseStore);
|
||||
if (!debug_bytecode_array.is_null()) {
|
||||
sfi->SetDebugBytecodeArray(debug_bytecode_array);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user