Commit bd75b0ba authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

Reland "[torque] allow exported classes with custom C++ class"

This is a reland of 26f10ecd

Change compared to original CL:
The deserializer changes StrongDescriptorArray to DescriptorArray.
Since this CL uses separate BodyDescriptors for the two kinds of
descriptor arrays, this caused a DCHECK failure when the deserializer
changes the map while the object is visited from the concurrent marking
thread. Fix this by disabling the corresponding checks.


Original change's description:
> [torque] allow exported classes with custom C++ class
>
> Introduce a new annotation @customCppClass that can be used for
> non-extern @export classes, that is, generate everything, remove
> boilerplate from all the internal lists and switches, but allow
> a custom C++ class, which in turn also allows overwriting the generated
> print and verify functions.
>
> Port DescriptorArray and StrongDescriptorArray as an example.
>
> Bug: v8:7793
> Change-Id: I744e52fb4102ac49c0097f1c95bb17d301975bf0
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2489687
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
> Reviewed-by: Seth Brenith <seth.brenith@microsoft.com>
> Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#70989}

Bug: v8:7793
Change-Id: I7505fb111896991d16d7d113704c8c3676669f34
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2526383Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71048}
parent a7857d44
......@@ -294,8 +294,6 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
case BYTECODE_ARRAY_TYPE:
case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
case ARRAY_BOILERPLATE_DESCRIPTION_TYPE:
case DESCRIPTOR_ARRAY_TYPE:
case STRONG_DESCRIPTOR_ARRAY_TYPE:
case TRANSITION_ARRAY_TYPE:
case FEEDBACK_CELL_TYPE:
case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
......
......@@ -252,11 +252,6 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
#undef MAKE_TORQUE_CASE
case DESCRIPTOR_ARRAY_TYPE:
case STRONG_DESCRIPTOR_ARRAY_TYPE:
DescriptorArray::cast(*this).DescriptorArrayVerify(isolate);
break;
case FOREIGN_TYPE:
break; // No interesting fields.
......
......@@ -169,10 +169,6 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
#undef MAKE_TORQUE_CASE
case DESCRIPTOR_ARRAY_TYPE:
case STRONG_DESCRIPTOR_ARRAY_TYPE:
DescriptorArray::cast(*this).DescriptorArrayPrint(os);
break;
case FOREIGN_TYPE:
Foreign::cast(*this).ForeignPrint(os);
break;
......
......@@ -347,6 +347,13 @@ FixedArray ConcurrentMarkingVisitor::Cast(HeapObject object) {
return FixedArray::unchecked_cast(object);
}
// The Deserializer changes the map from StrongDescriptorArray to
// DescriptorArray
template <>
StrongDescriptorArray ConcurrentMarkingVisitor::Cast(HeapObject object) {
return StrongDescriptorArray::unchecked_cast(DescriptorArray::cast(object));
}
class ConcurrentMarking::JobTask : public v8::JobTask {
public:
JobTask(ConcurrentMarking* concurrent_marking, unsigned mark_compact_epoch,
......
......@@ -121,6 +121,10 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
#include "torque-generated/factory.inc"
// Avoid the Torque-generated factory function to shadow the one from
// FactoryBase.
using FactoryBase::NewDescriptorArray;
Handle<Oddball> NewOddball(Handle<Map> map, const char* to_string,
Handle<Object> to_number, const char* type_of,
byte kind);
......
......@@ -25,7 +25,6 @@ namespace internal {
V(Context) \
V(CoverageInfo) \
V(DataHandler) \
V(DescriptorArray) \
V(EmbedderDataArray) \
V(EphemeronHashTable) \
V(FeedbackCell) \
......
......@@ -386,7 +386,6 @@ bool Heap::CreateInitialMaps() {
ALLOCATE_PRIMITIVE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol,
Context::SYMBOL_FUNCTION_INDEX)
ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign)
ALLOCATE_VARSIZE_MAP(STRONG_DESCRIPTOR_ARRAY_TYPE, strong_descriptor_array)
ALLOCATE_PRIMITIVE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean,
Context::BOOLEAN_FUNCTION_INDEX);
......@@ -428,8 +427,11 @@ bool Heap::CreateInitialMaps() {
TORQUE_DEFINED_FIXED_INSTANCE_TYPE_LIST(TORQUE_ALLOCATE_MAP);
#undef TORQUE_ALLOCATE_MAP
#define TORQUE_ALLOCATE_VARSIZE_MAP(NAME, Name, name) \
ALLOCATE_VARSIZE_MAP(NAME, name)
#define TORQUE_ALLOCATE_VARSIZE_MAP(NAME, Name, name) \
/* The DescriptorArray map is pre-allocated and initialized above. */ \
if (NAME != DESCRIPTOR_ARRAY_TYPE) { \
ALLOCATE_VARSIZE_MAP(NAME, name) \
}
TORQUE_DEFINED_VARSIZE_INSTANCE_TYPE_LIST(TORQUE_ALLOCATE_VARSIZE_MAP);
#undef TORQUE_ALLOCATE_VARSIZE_MAP
......
......@@ -170,9 +170,7 @@ class DescriptorArray
"Weak fields extend up to the end of the header.");
static_assert(kDescriptorsOffset == kHeaderSize,
"Variable-size array follows header.");
// We use this visitor to also visitor to also visit the enum_cache, which is
// the only tagged field in the header, and placed at the end of the header.
using BodyDescriptor = FlexibleWeakBodyDescriptor<kStartOfStrongFieldsOffset>;
class BodyDescriptor;
// Layout of descriptor.
// Naming is consistent with Dictionary classes for easy templating.
......
......@@ -16,8 +16,9 @@ struct DescriptorEntry {
value: JSAny|Weak<Map>|AccessorInfo|AccessorPair|ClassPositions;
}
@generateCppClass
extern class DescriptorArray extends HeapObject {
@export
@customCppClass
class DescriptorArray extends HeapObject {
const number_of_all_descriptors: uint16;
number_of_descriptors: uint16;
raw_number_of_marked_descriptors: uint16;
......@@ -27,5 +28,4 @@ extern class DescriptorArray extends HeapObject {
}
// A descriptor array where all values are held strongly.
extern class StrongDescriptorArray extends DescriptorArray
generates 'TNode<DescriptorArray>';
class StrongDescriptorArray extends DescriptorArray {}
......@@ -202,10 +202,6 @@ VisitorId Map::GetVisitorId(Map map) {
case PROPERTY_CELL_TYPE:
return kVisitPropertyCell;
case DESCRIPTOR_ARRAY_TYPE:
case STRONG_DESCRIPTOR_ARRAY_TYPE:
return kVisitDescriptorArray;
case TRANSITION_ARRAY_TYPE:
return kVisitTransitionArray;
......
......@@ -40,7 +40,6 @@ enum InstanceType : uint16_t;
V(CodeDataContainer) \
V(Context) \
V(DataHandler) \
V(DescriptorArray) \
V(EmbedderDataArray) \
V(EphemeronHashTable) \
V(FeedbackCell) \
......
......@@ -104,7 +104,6 @@ class ZoneForwardList;
V(DataHandler) \
V(DeoptimizationData) \
V(DependentCode) \
V(DescriptorArray) \
V(EmbedderDataArray) \
V(EphemeronHashTable) \
V(ExternalOneByteString) \
......@@ -281,7 +280,6 @@ class ZoneForwardList;
V(ModuleContext) \
V(NonNullForeign) \
V(ScriptContext) \
V(StrongDescriptorArray) \
V(WithContext)
#define HEAP_OBJECT_TYPE_LIST(V) \
......
......@@ -945,10 +945,6 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
p4);
case PROPERTY_ARRAY_TYPE:
return Op::template apply<PropertyArray::BodyDescriptor>(p1, p2, p3, p4);
case DESCRIPTOR_ARRAY_TYPE:
case STRONG_DESCRIPTOR_ARRAY_TYPE:
return Op::template apply<DescriptorArray::BodyDescriptor>(p1, p2, p3,
p4);
case TRANSITION_ARRAY_TYPE:
return Op::template apply<TransitionArray::BodyDescriptor>(p1, p2, p3,
p4);
......
......@@ -4,6 +4,7 @@
#ifndef V8_OBJECTS_TORQUE_DEFINED_CLASSES_H_
#define V8_OBJECTS_TORQUE_DEFINED_CLASSES_H_
#include "src/objects/descriptor-array.h"
#include "src/objects/fixed-array.h"
#include "src/objects/heap-object.h"
#include "src/objects/objects.h"
......
......@@ -85,8 +85,6 @@ class Symbol;
V(Map, bytecode_array_map, BytecodeArrayMap) \
V(Map, code_data_container_map, CodeDataContainerMap) \
V(Map, coverage_info_map, CoverageInfoMap) \
V(Map, descriptor_array_map, DescriptorArrayMap) \
V(Map, strong_descriptor_array_map, StrongDescriptorArrayMap) \
V(Map, fixed_double_array_map, FixedDoubleArrayMap) \
V(Map, global_dictionary_map, GlobalDictionaryMap) \
V(Map, many_closures_cell_map, ManyClosuresCellMap) \
......
......@@ -85,6 +85,7 @@ static const char* const ANNOTATION_ABSTRACT = "@abstract";
static const char* const ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT =
"@hasSameInstanceTypeAsParent";
static const char* const ANNOTATION_GENERATE_CPP_CLASS = "@generateCppClass";
static const char* const ANNOTATION_CUSTOM_CPP_CLASS = "@customCppClass";
static const char* const ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT =
"@highestInstanceTypeWithinParentClassRange";
static const char* const ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT =
......@@ -135,6 +136,7 @@ enum class ClassFlag {
kIsShape = 1 << 5,
kHasSameInstanceTypeAsParent = 1 << 6,
kGenerateCppClassDefinitions = 1 << 7,
kCustomCppClass = 1 << 8,
kHighestInstanceTypeWithinParent = 1 << 9,
kLowestInstanceTypeWithinParent = 1 << 10,
kUndefinedLayout = 1 << 11,
......
......@@ -3829,7 +3829,7 @@ void CppClassGenerator::GenerateClass() {
hdr_ << "};\n\n";
if (!type_->IsExtern()) {
if (type_->ShouldGenerateFullClassDefinition()) {
GenerateClassExport(type_, hdr_, inl_);
}
}
......@@ -4542,8 +4542,10 @@ void ImplementationVisitor::GenerateBodyDescriptors(
if (type->size().SingleValue()) {
h_contents << " return " << *type->size().SingleValue() << ";\n";
} else {
// We use an unchecked_cast here because this is used for concurrent
// marking, where we shouldn't re-read the map.
h_contents << " return " << name
<< "::cast(raw_object).AllocatedSize();\n";
<< "::unchecked_cast(raw_object).AllocatedSize();\n";
}
h_contents << " }\n\n";
......
......@@ -889,8 +889,9 @@ base::Optional<ParseResult> MakeClassDeclaration(
child_results,
{ANNOTATION_GENERATE_PRINT, ANNOTATION_NO_VERIFIER, ANNOTATION_ABSTRACT,
ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT,
ANNOTATION_GENERATE_CPP_CLASS, ANNOTATION_GENERATE_BODY_DESCRIPTOR,
ANNOTATION_EXPORT, ANNOTATION_DO_NOT_GENERATE_CAST,
ANNOTATION_GENERATE_CPP_CLASS, ANNOTATION_CUSTOM_CPP_CLASS,
ANNOTATION_GENERATE_BODY_DESCRIPTOR, ANNOTATION_EXPORT,
ANNOTATION_DO_NOT_GENERATE_CAST,
ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT,
ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT},
{ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE,
......@@ -909,6 +910,9 @@ base::Optional<ParseResult> MakeClassDeclaration(
if (annotations.Contains(ANNOTATION_GENERATE_CPP_CLASS)) {
flags |= ClassFlag::kGenerateCppClassDefinitions;
}
if (annotations.Contains(ANNOTATION_CUSTOM_CPP_CLASS)) {
flags |= ClassFlag::kCustomCppClass;
}
if (annotations.Contains(ANNOTATION_DO_NOT_GENERATE_CAST)) {
flags |= ClassFlag::kDoNotGenerateCast;
}
......
......@@ -287,6 +287,15 @@ const ClassType* TypeVisitor::ComputeType(
Error("Class \"", decl->name->value,
"\" requires a layout but doesn't have one");
}
if (flags & ClassFlag::kCustomCppClass) {
if (!(flags & ClassFlag::kExport)) {
Error("Only exported classes can have a custom C++ class.");
}
if (flags & ClassFlag::kExtern) {
Error("No need to specify ", ANNOTATION_CUSTOM_CPP_CLASS,
", extern classes always have a custom C++ class.");
}
}
if (flags & ClassFlag::kExtern) {
if (decl->generates) {
bool enforce_tnode_type = true;
......
......@@ -683,6 +683,9 @@ class ClassType final : public AggregateType {
return flags_ & ClassFlag::kGenerateCppClassDefinitions || !IsExtern() ||
ShouldGenerateBodyDescriptor();
}
bool ShouldGenerateFullClassDefinition() const {
return !IsExtern() && !(flags_ & ClassFlag::kCustomCppClass);
}
bool ShouldExport() const { return flags_ & ClassFlag::kExport; }
bool IsShape() const { return flags_ & ClassFlag::kIsShape; }
bool HasStaticSize() const;
......
This diff is collapsed.
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