Commit e600d775 authored by Nico Hartmann's avatar Nico Hartmann Committed by Commit Bot

[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/+/2461238Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarSantiago Aboy Solanes <solanes@chromium.org>
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70877}
parent eeb74f09
......@@ -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);
}
......
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