[torque] port SharedFunctionInfo class

Drive-by Torque changes:
  - kSize can be non-aligned, use SizeFor() instead for map allocation.
  - Factory functions use Torque-generated setters directly to work even
    if they are shadowed.
  - Allow class generation in the presence of custom weak fields, this
    was supported already.


Bug: v8:7793
Change-Id: I7e2df45d550ff70973e5167459050fd84db03114
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2547285
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Seth Brenith <seth.brenith@microsoft.com>
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Reviewed-by: Hannes Payer <hpayer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71371}
This commit is contained in:
Tobias Tebbi 2020-11-24 14:07:49 +01:00 committed by Commit Bot
parent f2821cfbee
commit 32e92f805a
13 changed files with 87 additions and 119 deletions

View File

@ -43,7 +43,6 @@ namespace internal {
V(PropertyArray) \
V(PropertyCell) \
V(PrototypeInfo) \
V(SharedFunctionInfo) \
V(SmallOrderedHashMap) \
V(SmallOrderedHashSet) \
V(SmallOrderedNameDictionary) \

View File

@ -423,7 +423,7 @@ bool Heap::CreateInitialMaps() {
small_ordered_name_dictionary)
#define TORQUE_ALLOCATE_MAP(NAME, Name, name) \
ALLOCATE_MAP(NAME, Name::kSize, name)
ALLOCATE_MAP(NAME, Name::SizeFor(), name)
TORQUE_DEFINED_FIXED_INSTANCE_TYPE_LIST(TORQUE_ALLOCATE_MAP);
#undef TORQUE_ALLOCATE_MAP

View File

@ -209,9 +209,6 @@ VisitorId Map::GetVisitorId(Map map) {
case CALL_HANDLER_INFO_TYPE:
return kVisitStruct;
case SHARED_FUNCTION_INFO_TYPE:
return kVisitSharedFunctionInfo;
case JS_PROXY_TYPE:
return kVisitStruct;

View File

@ -58,7 +58,6 @@ enum InstanceType : uint16_t;
V(PropertyArray) \
V(PropertyCell) \
V(PrototypeInfo) \
V(SharedFunctionInfo) \
V(ShortcutCandidate) \
V(SmallOrderedHashMap) \
V(SmallOrderedHashSet) \

View File

@ -195,7 +195,6 @@ class ZoneForwardList;
V(SeqOneByteString) \
V(SeqString) \
V(SeqTwoByteString) \
V(SharedFunctionInfo) \
V(SimpleNumberDictionary) \
V(SlicedString) \
V(SmallOrderedHashMap) \

View File

@ -187,6 +187,23 @@
#define ACCESSORS(holder, name, type, offset) \
ACCESSORS_CHECKED(holder, name, type, offset, true)
#define RENAME_TORQUE_ACCESSORS(holder, name, torque_name, type) \
inline type holder::name() const { \
return TorqueGeneratedClass::torque_name(); \
} \
inline void holder::set_##name(type value, WriteBarrierMode mode) { \
TorqueGeneratedClass::set_##torque_name(value, mode); \
}
#define RENAME_UINT16_TORQUE_ACCESSORS(holder, name, torque_name) \
uint16_t holder::name() const { \
return TorqueGeneratedClass::torque_name(); \
} \
void holder::set_##name(int value) { \
DCHECK_EQ(value, static_cast<uint16_t>(value)); \
TorqueGeneratedClass::set_##torque_name(value); \
}
#define RELAXED_ACCESSORS_CHECKED2(holder, name, type, offset, get_condition, \
set_condition) \
type holder::name(RelaxedLoadTag tag) const { \

View File

@ -269,30 +269,6 @@ class JSFinalizationRegistry::BodyDescriptor final : public BodyDescriptorBase {
}
};
class SharedFunctionInfo::BodyDescriptor final : public BodyDescriptorBase {
public:
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
static_assert(kEndOfWeakFieldsOffset == kStartOfStrongFieldsOffset,
"Leverage that strong fields directly follow weak fields"
"to call FixedBodyDescriptor<...>::IsValidSlot below");
return FixedBodyDescriptor<kStartOfWeakFieldsOffset,
kEndOfStrongFieldsOffset,
kAlignedSize>::IsValidSlot(map, obj, offset);
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject obj, int object_size,
ObjectVisitor* v) {
IterateCustomWeakPointer(obj, kFunctionDataOffset, v);
IteratePointers(obj, SharedFunctionInfo::kStartOfStrongFieldsOffset,
SharedFunctionInfo::kEndOfStrongFieldsOffset, v);
}
static inline int SizeOf(Map map, HeapObject object) {
return map.instance_size();
}
};
class AllocationSite::BodyDescriptor final : public BodyDescriptorBase {
public:
STATIC_ASSERT(AllocationSite::kCommonPointerFieldEndOffset ==
@ -1068,11 +1044,6 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
case FREE_SPACE_TYPE:
case BIGINT_TYPE:
return ReturnType();
case SHARED_FUNCTION_INFO_TYPE: {
return Op::template apply<SharedFunctionInfo::BodyDescriptor>(p1, p2, p3,
p4);
}
case ALLOCATION_SITE_TYPE:
return Op::template apply<AllocationSite::BodyDescriptor>(p1, p2, p3, p4);

View File

@ -94,9 +94,8 @@ ACCESSORS(InterpreterData, bytecode_array, BytecodeArray, kBytecodeArrayOffset)
ACCESSORS(InterpreterData, interpreter_trampoline, Code,
kInterpreterTrampolineOffset)
OBJECT_CONSTRUCTORS_IMPL(SharedFunctionInfo, HeapObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(SharedFunctionInfo)
NEVER_READ_ONLY_SPACE_IMPL(SharedFunctionInfo)
CAST_ACCESSOR(SharedFunctionInfo)
DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
RELEASE_ACQUIRE_ACCESSORS(SharedFunctionInfo, function_data, Object,
@ -106,19 +105,15 @@ RELEASE_ACQUIRE_ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object,
RELEASE_ACQUIRE_ACCESSORS(SharedFunctionInfo, script_or_debug_info, HeapObject,
kScriptOrDebugInfoOffset)
INT32_ACCESSORS(SharedFunctionInfo, function_literal_id,
kFunctionLiteralIdOffset)
RENAME_TORQUE_ACCESSORS(SharedFunctionInfo,
raw_outer_scope_info_or_feedback_metadata,
outer_scope_info_or_feedback_metadata, HeapObject)
RENAME_UINT16_TORQUE_ACCESSORS(SharedFunctionInfo,
internal_formal_parameter_count,
formal_parameter_count)
RENAME_UINT16_TORQUE_ACCESSORS(SharedFunctionInfo, raw_function_token_offset,
function_token_offset)
#if V8_SFI_HAS_UNIQUE_ID
INT_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset)
#endif
UINT16_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
UINT16_ACCESSORS(SharedFunctionInfo, internal_formal_parameter_count,
kFormalParameterCountOffset)
UINT8_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
kExpectedNofPropertiesOffset)
UINT16_ACCESSORS(SharedFunctionInfo, raw_function_token_offset,
kFunctionTokenOffsetOffset)
RELAXED_INT32_ACCESSORS(SharedFunctionInfo, flags, kFlagsOffset)
UINT8_ACCESSORS(SharedFunctionInfo, flags2, kFlags2Offset)
@ -362,9 +357,6 @@ void SharedFunctionInfo::set_raw_scope_info(ScopeInfo scope_info,
CONDITIONAL_WRITE_BARRIER(*this, kNameOrScopeInfoOffset, scope_info, mode);
}
ACCESSORS(SharedFunctionInfo, raw_outer_scope_info_or_feedback_metadata,
HeapObject, kOuterScopeInfoOrFeedbackMetadataOffset)
HeapObject SharedFunctionInfo::outer_scope_info() const {
DCHECK(!is_compiled());
DCHECK(!HasFeedbackMetadata());

View File

@ -150,7 +150,8 @@ class InterpreterData : public Struct {
// SharedFunctionInfo describes the JSFunction information that can be
// shared by multiple instances of the function.
class SharedFunctionInfo : public HeapObject {
class SharedFunctionInfo
: public TorqueGeneratedSharedFunctionInfo<SharedFunctionInfo, HeapObject> {
public:
NEVER_READ_ONLY_SPACE
DEFINE_TORQUE_GENERATED_SHARED_FUNCTION_INFO_FLAGS()
@ -222,7 +223,13 @@ class SharedFunctionInfo : public HeapObject {
// [outer scope info | feedback metadata] Shared storage for outer scope info
// (on uncompiled functions) and feedback metadata (on compiled functions).
DECL_ACCESSORS(raw_outer_scope_info_or_feedback_metadata, HeapObject)
private:
using TorqueGeneratedSharedFunctionInfo::
outer_scope_info_or_feedback_metadata;
using TorqueGeneratedSharedFunctionInfo::
set_outer_scope_info_or_feedback_metadata;
public:
// Get the outer scope info whether this function is compiled or not.
inline bool HasOuterScopeInfo() const;
inline ScopeInfo GetOuterScopeInfo() const;
@ -244,37 +251,20 @@ class SharedFunctionInfo : public HeapObject {
template <typename LocalIsolate>
inline IsCompiledScope is_compiled_scope(LocalIsolate* isolate) const;
// [length]: The function length - usually the number of declared parameters.
// Use up to 2^16-2 parameters (16 bits of values, where one is reserved for
// kDontAdaptArgumentsSentinel). The value is only reliable when the function
// has been compiled.
inline uint16_t length() const;
inline void set_length(int value);
// [internal formal parameter count]: The declared number of parameters.
// For subclass constructors, also includes new.target.
// The size of function's frame is internal_formal_parameter_count + 1.
DECL_UINT16_ACCESSORS(internal_formal_parameter_count)
private:
using TorqueGeneratedSharedFunctionInfo::formal_parameter_count;
using TorqueGeneratedSharedFunctionInfo::set_formal_parameter_count;
public:
// Set the formal parameter count so the function code will be
// called without using argument adaptor frames.
inline void DontAdaptArguments();
// [expected_nof_properties]: Expected number of properties for the
// function. The value is only reliable when the function has been compiled.
DECL_UINT8_ACCESSORS(expected_nof_properties)
// [function_literal_id] - uniquely identifies the FunctionLiteral this
// SharedFunctionInfo represents within its script, or -1 if this
// SharedFunctionInfo object doesn't correspond to a parsed FunctionLiteral.
DECL_INT32_ACCESSORS(function_literal_id)
#if V8_SFI_HAS_UNIQUE_ID
// [unique_id] - For --trace-maps purposes, an identifier that's persistent
// even if the GC moves this SharedFunctionInfo.
DECL_INT_ACCESSORS(unique_id)
#endif
// [function data]: This field holds some additional data for function.
// Currently it has one of:
// - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
@ -376,7 +366,11 @@ class SharedFunctionInfo : public HeapObject {
// start position. Can return kFunctionTokenOutOfRange if offset doesn't
// fit in 16 bits.
DECL_UINT16_ACCESSORS(raw_function_token_offset)
private:
using TorqueGeneratedSharedFunctionInfo::function_token_offset;
using TorqueGeneratedSharedFunctionInfo::set_function_token_offset;
public:
// The position of the 'function' token in the script source. Can return
// kNoSourcePosition if raw_function_token_offset() returns
// kFunctionTokenOutOfRange.
@ -611,17 +605,12 @@ class SharedFunctionInfo : public HeapObject {
int index_;
};
DECL_CAST(SharedFunctionInfo)
// Constants.
static const int kMaximumFunctionTokenOffset = kMaxUInt16 - 1;
static const uint16_t kFunctionTokenOutOfRange = static_cast<uint16_t>(-1);
STATIC_ASSERT(kMaximumFunctionTokenOffset + 1 == kFunctionTokenOutOfRange);
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
TORQUE_GENERATED_SHARED_FUNCTION_INFO_FIELDS)
static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
static const int kAlignedSize = SizeFor();
class BodyDescriptor;
@ -670,7 +659,7 @@ class SharedFunctionInfo : public HeapObject {
friend class V8HeapExplorer;
FRIEND_TEST(PreParserTest, LazyFunctionLength);
OBJECT_CONSTRUCTORS(SharedFunctionInfo, HeapObject);
TQ_OBJECT_CONSTRUCTORS(SharedFunctionInfo)
};
// Printing support.

View File

@ -47,18 +47,32 @@ bitfield struct SharedFunctionInfoFlags2 extends uint8 {
may_have_cached_code: bool: 1 bit;
}
extern class SharedFunctionInfo extends HeapObject {
@export
@customCppClass
@customMap // Just to place the map at the beginning of the roots array.
class SharedFunctionInfo extends HeapObject {
weak function_data: Object;
name_or_scope_info: String|NoSharedNameSentinel|ScopeInfo;
outer_scope_info_or_feedback_metadata: HeapObject;
script_or_debug_info: Script|DebugInfo|Undefined;
// [length]: The function length - usually the number of declared parameters.
// Use up to 2^16-2 parameters (16 bits of values, where one is reserved for
// kDontAdaptArgumentsSentinel). The value is only reliable when the function
// has been compiled.
length: int16;
formal_parameter_count: uint16;
function_token_offset: int16;
function_token_offset: uint16;
// [expected_nof_properties]: Expected number of properties for the
// function. The value is only reliable when the function has been compiled.
expected_nof_properties: uint8;
flags2: SharedFunctionInfoFlags2;
flags: SharedFunctionInfoFlags;
// [function_literal_id] - uniquely identifies the FunctionLiteral this
// SharedFunctionInfo represents within its script, or -1 if this
// SharedFunctionInfo object doesn't correspond to a parsed FunctionLiteral.
function_literal_id: int32;
// [unique_id] - For --trace-maps purposes, an identifier that's persistent
// even if the GC moves this SharedFunctionInfo.
@if(V8_SFI_HAS_UNIQUE_ID) unique_id: int32;
}

View File

@ -3735,7 +3735,8 @@ void CppClassGenerator::GenerateClass() {
<< " \"Pass in " << super_->name()
<< " as second template parameter for " << gen_name_ << ".\");\n";
hdr_ << " public: \n";
hdr_ << " using Super = P;\n\n";
hdr_ << " using Super = P;\n";
hdr_ << " using TorqueGeneratedClass = " << gen_name_ << "<D,P>;\n\n";
if (!type_->ShouldExport() && !type_->IsExtern()) {
hdr_ << " protected: // not extern or @export\n";
}
@ -3806,9 +3807,9 @@ void CppClassGenerator::GenerateClass() {
hdr_ << " size += " << index_name_and_type.name << " * "
<< field_size << ";\n";
}
if (type_->size().Alignment() < TargetArchitecture::TaggedSize()) {
hdr_ << " size = OBJECT_POINTER_ALIGN(size);\n";
}
}
if (type_->size().Alignment() < TargetArchitecture::TaggedSize()) {
hdr_ << " size = OBJECT_POINTER_ALIGN(size);\n";
}
hdr_ << " return size;\n";
hdr_ << " }\n\n";
@ -4273,7 +4274,7 @@ void ImplementationVisitor::GenerateClassDefinitions(
for (const Field& f : type->ComputeAllFields()) {
if (f.name_and_type.name == "map") continue;
if (!f.index) {
factory_impl << " result_handle->set_"
factory_impl << " result_handle->TorqueGeneratedClass::set_"
<< SnakeifyString(f.name_and_type.name) << "(";
if (f.name_and_type.type->IsSubtypeOf(
TypeOracle::GetTaggedType()) &&

View File

@ -511,16 +511,6 @@ void ClassType::Finalize() const {
TypeVisitor::VisitClassFieldsAndMethods(const_cast<ClassType*>(this),
this->decl_);
is_finalized_ = true;
if (GenerateCppClassDefinitions() || !IsExtern()) {
for (const Field& f : fields()) {
if (f.is_weak) {
Error("Generation of C++ class for Torque class ", name(),
" is not supported yet, because field ", f.name_and_type.name,
": ", *f.name_and_type.type, " is a weak field.")
.Position(f.pos);
}
}
}
CheckForDuplicateFields();
}

View File

@ -451,26 +451,26 @@ KNOWN_OBJECTS = {
("old_space", 0x02ecd): "RegExpMultipleCache",
("old_space", 0x032d5): "BuiltinsConstantsTable",
("old_space", 0x036bd): "AsyncFunctionAwaitRejectSharedFun",
("old_space", 0x036e5): "AsyncFunctionAwaitResolveSharedFun",
("old_space", 0x0370d): "AsyncGeneratorAwaitRejectSharedFun",
("old_space", 0x03735): "AsyncGeneratorAwaitResolveSharedFun",
("old_space", 0x0375d): "AsyncGeneratorYieldResolveSharedFun",
("old_space", 0x03785): "AsyncGeneratorReturnResolveSharedFun",
("old_space", 0x037ad): "AsyncGeneratorReturnClosedRejectSharedFun",
("old_space", 0x037d5): "AsyncGeneratorReturnClosedResolveSharedFun",
("old_space", 0x037fd): "AsyncIteratorValueUnwrapSharedFun",
("old_space", 0x03825): "PromiseAllResolveElementSharedFun",
("old_space", 0x0384d): "PromiseAllSettledResolveElementSharedFun",
("old_space", 0x03875): "PromiseAllSettledRejectElementSharedFun",
("old_space", 0x0389d): "PromiseAnyRejectElementSharedFun",
("old_space", 0x038c5): "PromiseCapabilityDefaultRejectSharedFun",
("old_space", 0x038ed): "PromiseCapabilityDefaultResolveSharedFun",
("old_space", 0x03915): "PromiseCatchFinallySharedFun",
("old_space", 0x0393d): "PromiseGetCapabilitiesExecutorSharedFun",
("old_space", 0x03965): "PromiseThenFinallySharedFun",
("old_space", 0x0398d): "PromiseThrowerFinallySharedFun",
("old_space", 0x039b5): "PromiseValueThunkFinallySharedFun",
("old_space", 0x039dd): "ProxyRevokeSharedFun",
("old_space", 0x036e1): "AsyncFunctionAwaitResolveSharedFun",
("old_space", 0x03705): "AsyncGeneratorAwaitRejectSharedFun",
("old_space", 0x03729): "AsyncGeneratorAwaitResolveSharedFun",
("old_space", 0x0374d): "AsyncGeneratorYieldResolveSharedFun",
("old_space", 0x03771): "AsyncGeneratorReturnResolveSharedFun",
("old_space", 0x03795): "AsyncGeneratorReturnClosedRejectSharedFun",
("old_space", 0x037b9): "AsyncGeneratorReturnClosedResolveSharedFun",
("old_space", 0x037dd): "AsyncIteratorValueUnwrapSharedFun",
("old_space", 0x03801): "PromiseAllResolveElementSharedFun",
("old_space", 0x03825): "PromiseAllSettledResolveElementSharedFun",
("old_space", 0x03849): "PromiseAllSettledRejectElementSharedFun",
("old_space", 0x0386d): "PromiseAnyRejectElementSharedFun",
("old_space", 0x03891): "PromiseCapabilityDefaultRejectSharedFun",
("old_space", 0x038b5): "PromiseCapabilityDefaultResolveSharedFun",
("old_space", 0x038d9): "PromiseCatchFinallySharedFun",
("old_space", 0x038fd): "PromiseGetCapabilitiesExecutorSharedFun",
("old_space", 0x03921): "PromiseThenFinallySharedFun",
("old_space", 0x03945): "PromiseThrowerFinallySharedFun",
("old_space", 0x03969): "PromiseValueThunkFinallySharedFun",
("old_space", 0x0398d): "ProxyRevokeSharedFun",
}
# Lower 32 bits of first page addresses for various heap spaces.