[torque] replace name mangling with unique numbering

Name mangling is hard to get right and not easy to read.
This CL replaces the remaining name mangling of types and generics
with simpler names that are not always unique, but then fixes them
up by appending a unique counter.

For struct types, this required an @export annotation since we use some
struct types in CSA.

Drive-by-fixes:

- Overwrite the copy constructor of Type to clear the list
of alias names when creating a new type.

- Change the existing append-a-number scheme to have different
  counters for each name. This the number of changed names when adding
  something and is more readable.

Bug: v8:7793
Change-Id: Ied11ea1a251130f4562ddc0d81967368349e0bf6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1866650
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64449}
This commit is contained in:
Tobias Tebbi 2019-10-22 10:14:23 +02:00 committed by Commit Bot
parent 578d4a8ff7
commit 419b4e7ea5
13 changed files with 107 additions and 63 deletions

View File

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@export
struct Arguments {
const frame: FrameWithArguments;
const base: RawPtr;
@ -14,6 +15,7 @@ extern macro GetFrameArguments(FrameWithArguments, intptr): Arguments;
namespace arguments {
@export
struct ArgumentsInfo {
frame: Frame;
argument_count: bint;

View File

@ -3708,6 +3708,7 @@ macro ConvertToRelativeIndex(indexNumber: Number, lengthIntPtr: intptr):
extern builtin ObjectToString(Context, JSAny): JSAny;
extern builtin StringRepeat(Context, String, Number): String;
@export
struct KeyValuePair {
key: JSAny;
value: JSAny;

View File

@ -6,6 +6,7 @@
namespace iterator {
// Returned from IteratorBuiltinsAssembler::GetIterator().
@export
struct IteratorRecord {
// iteratorRecord.[[Iterator]]
object: JSReceiver;

View File

@ -20,6 +20,7 @@ namespace typed_array {
type BigUint64Elements;
type BigInt64Elements;
@export
struct TypedArrayElementsInfo {
// Calculates the number of bytes required for specified number of elements.
CalculateByteLength(lengthSmi: PositiveSmi): uintptr labels IfInvalid {

View File

@ -1061,14 +1061,16 @@ struct ExternConstDeclaration : Declaration {
struct StructDeclaration : TypeDeclaration {
DEFINE_AST_NODE_LEAF_BOILERPLATE(StructDeclaration)
StructDeclaration(SourcePosition pos, Identifier* name,
StructDeclaration(SourcePosition pos, StructFlags flags, Identifier* name,
std::vector<Declaration*> methods,
std::vector<StructFieldExpression> fields,
std::vector<Identifier*> generic_parameters)
: TypeDeclaration(kKind, pos, name),
flags(flags),
methods(std::move(methods)),
fields(std::move(fields)),
generic_parameters(std::move(generic_parameters)) {}
StructFlags flags;
std::vector<Declaration*> methods;
std::vector<StructFieldExpression> fields;
std::vector<Identifier*> generic_parameters;

View File

@ -106,6 +106,9 @@ enum class ClassFlag {
};
using ClassFlags = base::Flags<ClassFlag>;
enum class StructFlag { kNone = 0, kExport = 1 << 0 };
using StructFlags = base::Flags<StructFlag>;
} // namespace torque
} // namespace internal
} // namespace v8

View File

@ -339,8 +339,9 @@ Callable* DeclarationVisitor::Specialize(
Declarations::CreateIntrinsic(declaration->name->value, type_signature);
} else {
BuiltinDeclaration* builtin = BuiltinDeclaration::cast(declaration);
callable = CreateBuiltin(builtin, generated_name, readable_name.str(),
type_signature, *body);
callable =
CreateBuiltin(builtin, GlobalContext::MakeUniqueName(generated_name),
readable_name.str(), type_signature, *body);
}
key.generic->specializations().Add(key.specialized_types, callable);
return callable;

View File

@ -168,9 +168,7 @@ TorqueMacro* Declarations::CreateTorqueMacro(std::string external_name,
Signature signature,
base::Optional<Statement*> body,
bool is_user_defined) {
// TODO(tebbi): Switch to more predictable names to improve incremental
// compilation.
external_name += "_" + std::to_string(GlobalContext::FreshId());
external_name = GlobalContext::MakeUniqueName(external_name);
return RegisterDeclarable(std::unique_ptr<TorqueMacro>(new TorqueMacro(
std::move(external_name), std::move(readable_name), std::move(signature),
body, is_user_defined, exported_to_csa)));
@ -215,10 +213,10 @@ Macro* Declarations::DeclareMacro(
Method* Declarations::CreateMethod(AggregateType* container_type,
const std::string& name, Signature signature,
Statement* body) {
std::string generated_name{container_type->GetGeneratedMethodName(name)};
Method* result = RegisterDeclarable(std::unique_ptr<Method>(
new Method(container_type, container_type->GetGeneratedMethodName(name),
name, std::move(signature), body)));
std::string generated_name = GlobalContext::MakeUniqueName(
"Method_" + container_type->SimpleName() + "_" + name);
Method* result = RegisterDeclarable(std::unique_ptr<Method>(new Method(
container_type, generated_name, name, std::move(signature), body)));
container_type->RegisterMethod(result);
return result;
}
@ -274,8 +272,7 @@ NamespaceConstant* Declarations::DeclareNamespaceConstant(Identifier* name,
const Type* type,
Expression* body) {
CheckAlreadyDeclared<Value>(name->value, "constant");
std::string external_name =
name->value + "_" + std::to_string(GlobalContext::FreshId());
std::string external_name = GlobalContext::MakeUniqueName(name->value);
NamespaceConstant* result =
new NamespaceConstant(name, std::move(external_name), type, body);
Declare(name->value, std::unique_ptr<Declarable>(result));
@ -297,8 +294,7 @@ std::string Declarations::GetGeneratedCallableName(
const std::string& name, const TypeVector& specialized_types) {
std::string result = name;
for (auto type : specialized_types) {
std::string type_string = type->MangledName();
result += std::to_string(type_string.size()) + type_string;
result += "_" + type->SimpleName();
}
return result;
}

View File

@ -64,7 +64,9 @@ class GlobalContext : public ContextualClass<GlobalContext> {
return Get().force_assert_statements_;
}
static Ast* ast() { return &Get().ast_; }
static size_t FreshId() { return Get().fresh_id_++; }
static std::string MakeUniqueName(const std::string& base) {
return base + "_" + std::to_string(Get().fresh_ids_[base]++);
}
struct PerFileStreams {
std::stringstream csa_headerfile;
@ -83,7 +85,7 @@ class GlobalContext : public ContextualClass<GlobalContext> {
std::vector<std::string> cpp_includes_;
std::map<SourceId, PerFileStreams> generated_per_file_;
GlobalClassList classes_;
size_t fresh_id_ = 0;
std::map<std::string, size_t> fresh_ids_;
friend class LanguageServerData;
};

View File

@ -873,6 +873,10 @@ base::Optional<ParseResult> MakeSpecializationDeclaration(
base::Optional<ParseResult> MakeStructDeclaration(
ParseResultIterator* child_results) {
bool is_export = child_results->NextAs<bool>();
StructFlags flags = StructFlag::kNone;
if (is_export) flags |= StructFlag::kExport;
auto name = child_results->NextAs<Identifier*>();
if (!IsValidTypeName(name->value)) {
NamingConventionError("Struct", name, "UpperCamelCase");
@ -881,9 +885,9 @@ base::Optional<ParseResult> MakeStructDeclaration(
LintGenericParameters(generic_parameters);
auto methods = child_results->NextAs<std::vector<Declaration*>>();
auto fields = child_results->NextAs<std::vector<StructFieldExpression>>();
Declaration* result =
MakeNode<StructDeclaration>(name, std::move(methods), std::move(fields),
std::move(generic_parameters));
Declaration* result = MakeNode<StructDeclaration>(
flags, name, std::move(methods), std::move(fields),
std::move(generic_parameters));
return ParseResult{result};
}
@ -1998,7 +2002,7 @@ struct TorqueGrammar : Grammar {
Sequence({Token("generates"), &externalString})),
&optionalClassBody},
AsSingletonVector<Declaration*, MakeClassDeclaration>()),
Rule({Token("struct"), &name,
Rule({CheckIf(Token("@export")), Token("struct"), &name,
TryOrDefault<GenericParameters>(&genericParameters), Token("{"),
List<Declaration*>(&method),
List<StructFieldExpression>(&structField), Token("}")},

View File

@ -265,6 +265,8 @@ class TypeOracle : public ContextualClass<TypeOracle> {
static void FinalizeAggregateTypes();
static size_t FreshTypeId() { return Get().next_type_id_++; }
private:
const Type* GetBuiltinType(const std::string& name) {
return Declarations::LookupGlobalType(name);
@ -277,6 +279,7 @@ class TypeOracle : public ContextualClass<TypeOracle> {
std::vector<std::unique_ptr<AggregateType>> aggregate_types_;
std::vector<std::unique_ptr<Type>> top_types_;
std::vector<std::unique_ptr<Namespace>> struct_namespaces_;
size_t next_type_id_ = 0;
};
} // namespace torque

View File

@ -15,6 +15,15 @@ namespace v8 {
namespace internal {
namespace torque {
// This custom copy constructor doesn't copy aliases_ and id_ because they
// should be distinct for each type.
Type::Type(const Type& other) V8_NOEXCEPT : TypeBase(other),
parent_(other.parent_),
aliases_(),
id_(TypeOracle::FreshTypeId()) {}
Type::Type(TypeBase::Kind kind, const Type* parent)
: TypeBase(kind), parent_(parent), id_(TypeOracle::FreshTypeId()) {}
std::string Type::ToString() const {
if (aliases_.size() == 0) return ToExplicitString();
if (aliases_.size() == 1) return *aliases_.begin();
@ -34,6 +43,11 @@ std::string Type::ToString() const {
return result.str();
}
std::string Type::SimpleName() const {
if (aliases_.empty()) return SimpleNameImpl();
return *aliases_.begin();
}
bool Type::IsSubtypeOf(const Type* supertype) const {
if (supertype->IsTopType()) return true;
if (IsNever()) return true;
@ -116,15 +130,13 @@ std::string BuiltinPointerType::ToExplicitString() const {
return result.str();
}
std::string BuiltinPointerType::MangledName() const {
std::string BuiltinPointerType::SimpleNameImpl() const {
std::stringstream result;
result << "FT";
result << "BuiltinPointer";
for (const Type* t : parameter_types_) {
std::string arg_type_string = t->MangledName();
result << arg_type_string.size() << arg_type_string;
result << "_" << t->SimpleName();
}
std::string return_type_string = return_type_->MangledName();
result << return_type_string.size() << return_type_string;
result << "_" << return_type_->SimpleName();
return result.str();
}
@ -143,12 +155,15 @@ std::string UnionType::ToExplicitString() const {
return result.str();
}
std::string UnionType::MangledName() const {
std::string UnionType::SimpleNameImpl() const {
std::stringstream result;
result << "UT";
bool first = true;
for (const Type* t : types_) {
std::string arg_type_string = t->MangledName();
result << arg_type_string.size() << arg_type_string;
if (!first) {
result << "_OR_";
}
first = false;
result << t->SimpleName();
}
return result.str();
}
@ -273,8 +288,22 @@ const Field& AggregateType::LookupField(const std::string& name) const {
return LookupFieldInternal(name);
}
StructType::StructType(Namespace* nspace, const StructDeclaration* decl,
MaybeSpecializationKey specialized_from)
: AggregateType(Kind::kStructType, nullptr, nspace,
ComputeName(decl->name->value, specialized_from)),
decl_(decl),
specialized_from_(specialized_from) {
if (decl->flags & StructFlag::kExport) {
generated_type_name_ = "TorqueStruct" + name();
} else {
generated_type_name_ =
GlobalContext::MakeUniqueName("TorqueStruct" + SimpleName());
}
}
std::string StructType::GetGeneratedTypeNameImpl() const {
return "TorqueStruct" + MangledName();
return generated_type_name_;
}
// static
@ -296,15 +325,12 @@ std::string StructType::ComputeName(
return s.str();
}
std::string StructType::MangledName() const {
std::string StructType::SimpleNameImpl() const {
std::stringstream result;
// TODO(gsps): Add 'ST' as a prefix once we can control the generated type
// name from Torque code
result << decl_->name->value;
if (specialized_from_) {
for (const Type* t : specialized_from_->specialized_types) {
std::string arg_type_string = t->MangledName();
result << arg_type_string.size() << arg_type_string;
result << "_" << t->SimpleName();
}
}
return result.str();
@ -589,9 +615,7 @@ bool IsAssignableFrom(const Type* to, const Type* from) {
return TypeOracle::IsImplicitlyConvertableFrom(to, from);
}
bool operator<(const Type& a, const Type& b) {
return a.MangledName() < b.MangledName();
}
bool operator<(const Type& a, const Type& b) { return a.id() < b.id(); }
VisitResult ProjectStructField(VisitResult structure,
const std::string& fieldname) {

View File

@ -84,8 +84,13 @@ class V8_EXPORT_PRIVATE Type : public TypeBase {
public:
virtual bool IsSubtypeOf(const Type* supertype) const;
// Default rendering for error messages etc.
std::string ToString() const;
virtual std::string MangledName() const = 0;
// This name is not unique, but short and somewhat descriptive.
// Used for naming generated code.
virtual std::string SimpleName() const;
bool IsVoid() const { return IsAbstractName(VOID_TYPE_STRING); }
bool IsNever() const { return IsAbstractName(NEVER_TYPE_STRING); }
bool IsBool() const { return IsAbstractName(BOOL_TYPE_STRING); }
@ -106,16 +111,19 @@ class V8_EXPORT_PRIVATE Type : public TypeBase {
virtual std::vector<std::string> GetRuntimeTypes() const { return {}; }
static const Type* CommonSupertype(const Type* a, const Type* b);
void AddAlias(std::string alias) const { aliases_.insert(std::move(alias)); }
size_t id() const { return id_; }
protected:
Type(TypeBase::Kind kind, const Type* parent)
: TypeBase(kind), parent_(parent) {}
Type(TypeBase::Kind kind, const Type* parent);
Type(const Type& other) V8_NOEXCEPT;
Type& operator=(const Type& other) = delete;
const Type* parent() const { return parent_; }
void set_parent(const Type* t) { parent_ = t; }
int Depth() const;
virtual std::string ToExplicitString() const = 0;
virtual std::string GetGeneratedTypeNameImpl() const = 0;
virtual std::string GetGeneratedTNodeTypeNameImpl() const = 0;
virtual std::string SimpleNameImpl() const = 0;
private:
bool IsAbstractName(const std::string& name) const;
@ -123,6 +131,7 @@ class V8_EXPORT_PRIVATE Type : public TypeBase {
// If {parent_} is not nullptr, then this type is a subtype of {parent_}.
const Type* parent_;
mutable std::set<std::string> aliases_;
size_t id_;
};
using TypeVector = std::vector<const Type*>;
@ -169,7 +178,6 @@ std::ostream& operator<<(std::ostream& os, const Field& name_and_type);
class TopType final : public Type {
public:
DECLARE_TYPE_BOILERPLATE(TopType)
std::string MangledName() const override { return "top"; }
std::string GetGeneratedTypeNameImpl() const override { UNREACHABLE(); }
std::string GetGeneratedTNodeTypeNameImpl() const override {
return source_type_->GetGeneratedTNodeTypeName();
@ -189,6 +197,8 @@ class TopType final : public Type {
: Type(Kind::kTopType, nullptr),
reason_(std::move(reason)),
source_type_(source_type) {}
std::string SimpleNameImpl() const override { return "TopType"; }
std::string reason_;
const Type* source_type_;
};
@ -198,11 +208,6 @@ class AbstractType final : public Type {
DECLARE_TYPE_BOILERPLATE(AbstractType)
const std::string& name() const { return name_; }
std::string ToExplicitString() const override { return name(); }
std::string MangledName() const override {
std::string str(name());
std::replace(str.begin(), str.end(), ' ', '_');
return "AT" + str;
}
std::string GetGeneratedTypeNameImpl() const override {
return IsConstexpr() ? generated_type_ : "TNode<" + generated_type_ + ">";
}
@ -243,6 +248,12 @@ class AbstractType final : public Type {
!non_constexpr_version->IsConstexpr());
}
std::string SimpleNameImpl() const override {
if (IsConstexpr())
return "constexpr_" + NonConstexprVersion()->SimpleName();
return name();
}
void SetConstexprVersion(const AbstractType* type) const {
DCHECK_EQ(GetConstexprName(name()), type->name());
constexpr_version_ = type;
@ -262,7 +273,6 @@ class V8_EXPORT_PRIVATE BuiltinPointerType final : public Type {
public:
DECLARE_TYPE_BOILERPLATE(BuiltinPointerType)
std::string ToExplicitString() const override;
std::string MangledName() const override;
std::string GetGeneratedTypeNameImpl() const override {
return parent()->GetGeneratedTypeName();
}
@ -296,6 +306,7 @@ class V8_EXPORT_PRIVATE BuiltinPointerType final : public Type {
parameter_types_(parameter_types),
return_type_(return_type),
function_pointer_type_id_(function_pointer_type_id) {}
std::string SimpleNameImpl() const override;
const TypeVector parameter_types_;
const Type* const return_type_;
@ -312,8 +323,6 @@ struct TypeLess {
class V8_EXPORT_PRIVATE UnionType final : public Type {
public:
DECLARE_TYPE_BOILERPLATE(UnionType)
std::string ToExplicitString() const override;
std::string MangledName() const override;
std::string GetGeneratedTypeNameImpl() const override {
return "TNode<" + GetGeneratedTNodeTypeName() + ">";
}
@ -376,6 +385,7 @@ class V8_EXPORT_PRIVATE UnionType final : public Type {
types_.insert(t);
}
}
std::string ToExplicitString() const override;
void Subtract(const Type* t);
@ -396,6 +406,7 @@ class V8_EXPORT_PRIVATE UnionType final : public Type {
private:
explicit UnionType(const Type* t) : Type(Kind::kUnionType, t), types_({t}) {}
void RecomputeParent();
std::string SimpleNameImpl() const override;
std::set<const Type*, TypeLess> types_;
};
@ -405,7 +416,6 @@ const Type* SubtractType(const Type* a, const Type* b);
class AggregateType : public Type {
public:
DECLARE_TYPE_BOILERPLATE(AggregateType)
std::string MangledName() const override { return name_; }
std::string GetGeneratedTypeNameImpl() const override { UNREACHABLE(); }
std::string GetGeneratedTNodeTypeNameImpl() const override { UNREACHABLE(); }
@ -423,10 +433,6 @@ class AggregateType : public Type {
const std::string& name() const { return name_; }
Namespace* nspace() const { return namespace_; }
std::string GetGeneratedMethodName(const std::string& name) const {
return "_method_" + name_ + "_" + name;
}
virtual const Field& RegisterField(Field field) {
fields_.push_back(field);
return fields_.back();
@ -453,6 +459,7 @@ class AggregateType : public Type {
void CheckForDuplicateFields() const;
// Use this lookup if you do not want to trigger finalization on this type.
const Field& LookupFieldInternal(const std::string& name) const;
std::string SimpleNameImpl() const override { return name_; }
protected:
mutable bool is_finalized_;
@ -471,9 +478,7 @@ class StructType final : public AggregateType {
using MaybeSpecializationKey =
base::Optional<SpecializationKey<GenericStructType>>;
std::string ToExplicitString() const override;
std::string GetGeneratedTypeNameImpl() const override;
std::string MangledName() const override;
const MaybeSpecializationKey& GetSpecializedFrom() const {
return specialized_from_;
}
@ -486,18 +491,17 @@ class StructType final : public AggregateType {
private:
friend class TypeOracle;
StructType(Namespace* nspace, const StructDeclaration* decl,
MaybeSpecializationKey specialized_from = base::nullopt)
: AggregateType(Kind::kStructType, nullptr, nspace,
ComputeName(decl->name->value, specialized_from)),
decl_(decl),
specialized_from_(specialized_from) {}
MaybeSpecializationKey specialized_from = base::nullopt);
void Finalize() const override;
std::string ToExplicitString() const override;
std::string SimpleNameImpl() const override;
static std::string ComputeName(const std::string& basename,
MaybeSpecializationKey specialized_from);
const StructDeclaration* decl_;
std::string generated_type_name_;
MaybeSpecializationKey specialized_from_;
};