Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/torque/types.cc')
-rw-r--r--deps/v8/src/torque/types.cc188
1 files changed, 163 insertions, 25 deletions
diff --git a/deps/v8/src/torque/types.cc b/deps/v8/src/torque/types.cc
index e08716c98a1..a01fd596804 100644
--- a/deps/v8/src/torque/types.cc
+++ b/deps/v8/src/torque/types.cc
@@ -2,11 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <iostream>
-
#include "src/torque/types.h"
+#include <cmath>
+#include <iostream>
+
#include "src/base/bits.h"
+#include "src/base/optional.h"
#include "src/torque/ast.h"
#include "src/torque/declarable.h"
#include "src/torque/global-context.h"
@@ -471,25 +473,16 @@ void StructType::Finalize() const {
CheckForDuplicateFields();
}
-constexpr ClassFlags ClassType::kInternalFlags;
-
ClassType::ClassType(const Type* parent, Namespace* nspace,
const std::string& name, ClassFlags flags,
const std::string& generates, const ClassDeclaration* decl,
const TypeAlias* alias)
: AggregateType(Kind::kClassType, parent, nspace, name),
size_(ResidueClass::Unknown()),
- flags_(flags & ~(kInternalFlags)),
+ flags_(flags),
generates_(generates),
decl_(decl),
- alias_(alias) {
- DCHECK_EQ(flags & kInternalFlags, 0);
-}
-
-bool ClassType::HasIndexedField() const {
- if (!is_finalized_) Finalize();
- return flags_ & ClassFlag::kHasIndexedField;
-}
+ alias_(alias) {}
std::string ClassType::GetGeneratedTNodeTypeNameImpl() const {
return generates_;
@@ -510,11 +503,6 @@ void ClassType::Finalize() const {
if (is_finalized_) return;
CurrentScope::Scope scope_activator(alias_->ParentScope());
CurrentSourcePosition::Scope position_activator(decl_->pos);
- if (parent()) {
- if (const ClassType* super_class = ClassType::DynamicCast(parent())) {
- if (super_class->HasIndexedField()) flags_ |= ClassFlag::kHasIndexedField;
- }
- }
TypeVisitor::VisitClassFieldsAndMethods(const_cast<ClassType*>(this),
this->decl_);
is_finalized_ = true;
@@ -542,6 +530,122 @@ std::vector<Field> ClassType::ComputeAllFields() const {
return all_fields;
}
+std::vector<Field> ClassType::ComputeHeaderFields() const {
+ std::vector<Field> result;
+ for (Field& field : ComputeAllFields()) {
+ if (field.index) break;
+ DCHECK(*field.offset < header_size());
+ result.push_back(std::move(field));
+ }
+ return result;
+}
+
+std::vector<Field> ClassType::ComputeArrayFields() const {
+ std::vector<Field> result;
+ for (Field& field : ComputeAllFields()) {
+ if (!field.index) {
+ DCHECK(*field.offset < header_size());
+ continue;
+ }
+ result.push_back(std::move(field));
+ }
+ return result;
+}
+
+void ClassType::InitializeInstanceTypes(
+ base::Optional<int> own, base::Optional<std::pair<int, int>> range) const {
+ DCHECK(!own_instance_type_.has_value());
+ DCHECK(!instance_type_range_.has_value());
+ own_instance_type_ = own;
+ instance_type_range_ = range;
+}
+
+base::Optional<int> ClassType::OwnInstanceType() const {
+ DCHECK(GlobalContext::IsInstanceTypesInitialized());
+ return own_instance_type_;
+}
+
+base::Optional<std::pair<int, int>> ClassType::InstanceTypeRange() const {
+ DCHECK(GlobalContext::IsInstanceTypesInitialized());
+ return instance_type_range_;
+}
+
+namespace {
+void ComputeSlotKindsHelper(std::vector<ObjectSlotKind>* slots,
+ size_t start_offset,
+ const std::vector<Field>& fields) {
+ size_t offset = start_offset;
+ for (const Field& field : fields) {
+ size_t field_size = std::get<0>(field.GetFieldSizeInformation());
+ size_t slot_index = offset / TargetArchitecture::TaggedSize();
+ // Rounding-up division to find the number of slots occupied by all the
+ // fields up to and including the current one.
+ size_t used_slots =
+ (offset + field_size + TargetArchitecture::TaggedSize() - 1) /
+ TargetArchitecture::TaggedSize();
+ while (used_slots > slots->size()) {
+ slots->push_back(ObjectSlotKind::kNoPointer);
+ }
+ const Type* type = field.name_and_type.type;
+ if (auto struct_type = type->StructSupertype()) {
+ ComputeSlotKindsHelper(slots, offset, (*struct_type)->fields());
+ } else {
+ ObjectSlotKind kind;
+ if (type->IsSubtypeOf(TypeOracle::GetObjectType())) {
+ if (field.is_weak) {
+ kind = ObjectSlotKind::kCustomWeakPointer;
+ } else {
+ kind = ObjectSlotKind::kStrongPointer;
+ }
+ } else if (type->IsSubtypeOf(TypeOracle::GetTaggedType())) {
+ DCHECK(!field.is_weak);
+ kind = ObjectSlotKind::kMaybeObjectPointer;
+ } else {
+ kind = ObjectSlotKind::kNoPointer;
+ }
+ DCHECK(slots->at(slot_index) == ObjectSlotKind::kNoPointer);
+ slots->at(slot_index) = kind;
+ }
+
+ offset += field_size;
+ }
+}
+} // namespace
+
+std::vector<ObjectSlotKind> ClassType::ComputeHeaderSlotKinds() const {
+ std::vector<ObjectSlotKind> result;
+ std::vector<Field> header_fields = ComputeHeaderFields();
+ ComputeSlotKindsHelper(&result, 0, header_fields);
+ DCHECK_EQ(std::ceil(static_cast<double>(header_size()) /
+ TargetArchitecture::TaggedSize()),
+ result.size());
+ return result;
+}
+
+base::Optional<ObjectSlotKind> ClassType::ComputeArraySlotKind() const {
+ std::vector<ObjectSlotKind> kinds;
+ ComputeSlotKindsHelper(&kinds, 0, ComputeArrayFields());
+ if (kinds.empty()) return base::nullopt;
+ std::sort(kinds.begin(), kinds.end());
+ if (kinds.front() == kinds.back()) return {kinds.front()};
+ if (kinds.front() == ObjectSlotKind::kStrongPointer &&
+ kinds.back() == ObjectSlotKind::kMaybeObjectPointer) {
+ return ObjectSlotKind::kMaybeObjectPointer;
+ }
+ Error("Array fields mix types with different GC visitation requirements.")
+ .Throw();
+}
+
+bool ClassType::HasNoPointerSlots() const {
+ for (ObjectSlotKind slot : ComputeHeaderSlotKinds()) {
+ if (slot != ObjectSlotKind::kNoPointer) return false;
+ }
+ if (auto slot = ComputeArraySlotKind()) {
+ if (*slot != ObjectSlotKind::kNoPointer) return false;
+ }
+ return true;
+}
+
void ClassType::GenerateAccessors() {
// For each field, construct AST snippets that implement a CSA accessor
// function. The implementation iterator will turn the snippets into code.
@@ -620,11 +724,11 @@ void ClassType::GenerateAccessors() {
}
bool ClassType::HasStaticSize() const {
- if (IsShape()) return true;
- if (IsSubtypeOf(TypeOracle::GetJSObjectType())) return false;
- if (IsAbstract()) return false;
- if (HasIndexedField()) return false;
- return true;
+ // Abstract classes don't have instances directly, so asking this question
+ // doesn't make sense.
+ DCHECK(!IsAbstract());
+ if (IsSubtypeOf(TypeOracle::GetJSObjectType()) && !IsShape()) return false;
+ return size().SingleValue().has_value();
}
void PrintSignature(std::ostream& os, const Signature& sig, bool with_names) {
@@ -719,6 +823,21 @@ bool Signature::HasSameTypesAs(const Signature& other,
return true;
}
+namespace {
+bool FirstTypeIsContext(const std::vector<const Type*> parameter_types) {
+ return !parameter_types.empty() &&
+ parameter_types[0] == TypeOracle::GetContextType();
+}
+} // namespace
+
+bool Signature::HasContextParameter() const {
+ return FirstTypeIsContext(types());
+}
+
+bool BuiltinPointerType::HasContextParameter() const {
+ return FirstTypeIsContext(parameter_types());
+}
+
bool IsAssignableFrom(const Type* to, const Type* from) {
if (to == from) return true;
if (from->IsSubtypeOf(to)) return true;
@@ -814,6 +933,8 @@ size_t AbstractType::AlignmentLog2() const {
alignment = TargetArchitecture::TaggedSize();
} else if (this == TypeOracle::GetRawPtrType()) {
alignment = TargetArchitecture::RawPtrSize();
+ } else if (this == TypeOracle::GetExternalPointerType()) {
+ alignment = TargetArchitecture::ExternalPointerSize();
} else if (this == TypeOracle::GetVoidType()) {
alignment = 1;
} else if (this == TypeOracle::GetInt8Type()) {
@@ -881,6 +1002,9 @@ base::Optional<std::tuple<size_t, std::string>> SizeOf(const Type* type) {
} else if (type->IsSubtypeOf(TypeOracle::GetRawPtrType())) {
size = TargetArchitecture::RawPtrSize();
size_string = "kSystemPointerSize";
+ } else if (type->IsSubtypeOf(TypeOracle::GetExternalPointerType())) {
+ size = TargetArchitecture::ExternalPointerSize();
+ size_string = "kExternalPointerSize";
} else if (type->IsSubtypeOf(TypeOracle::GetVoidType())) {
size = 0;
size_string = "0";
@@ -942,10 +1066,17 @@ bool IsAllowedAsBitField(const Type* type) {
// Any integer-ish type, including bools and enums which inherit from integer
// types, are allowed. Note, however, that we always zero-extend during
// decoding regardless of signedness.
+ return IsPointerSizeIntegralType(type) || Is32BitIntegralType(type);
+}
+
+bool IsPointerSizeIntegralType(const Type* type) {
+ return type->IsSubtypeOf(TypeOracle::GetUIntPtrType()) ||
+ type->IsSubtypeOf(TypeOracle::GetIntPtrType());
+}
+
+bool Is32BitIntegralType(const Type* type) {
return type->IsSubtypeOf(TypeOracle::GetUint32Type()) ||
- type->IsSubtypeOf(TypeOracle::GetUIntPtrType()) ||
type->IsSubtypeOf(TypeOracle::GetInt32Type()) ||
- type->IsSubtypeOf(TypeOracle::GetIntPtrType()) ||
type->IsSubtypeOf(TypeOracle::GetBoolType());
}
@@ -960,6 +1091,13 @@ base::Optional<NameAndType> ExtractSimpleFieldArraySize(
return class_type.LookupField(identifier->name->value).name_and_type;
}
+std::string Type::GetRuntimeType() const {
+ // TODO(tebbi): Other types are currently unsupported, since there the TNode
+ // types and the C++ runtime types disagree.
+ DCHECK(this->IsSubtypeOf(TypeOracle::GetTaggedType()));
+ return GetGeneratedTNodeTypeName();
+}
+
} // namespace torque
} // namespace internal
} // namespace v8