7247a1b3b7
This is a reland of commit 135443706b
Original change's description:
> [vm] Avoid expanding/flattening type arguments vectors in Type objects
>
> Previously, vectors of type arguments were expanded to include type
> arguments corresponding to superclasses both in the instances of
> generic classes and in Type objects (after type finalization).
> As a result, Type objects after finalization could be recursive and
> need to use extra TypeRef objects to break loops. The finalization of
> types was very complex and sometimes slow.
>
> This change simplifies the representation of Type objects: now they
> always have short type argument vectors, corresponding only to
> the type parameters of their own classes (both before and after
> finalization). Vectors of type arguments in the instances of generic
> classes are still expanded/flattened.
>
> This greatly simplifies type finalization, makes Type objects
> non-recursive and removes the need to create and handle excessive
> TypeRefs for type arguments corresponding to superclasses,
> as those type arguments are no longer included into types.
> The only remaining use of TypeRefs is for bounds of type parameters.
>
> In order to expand/flatten type arguments, new methods Type::GetInstanceTypeArguments / Class::GetInstanceTypeArguments
> are introduced. They build canonical declaration type arguments
> once (for each class), and then instantiate them as needed.
>
> There are also simple helper methods to shrink type arguments (TypeArguments::FromInstanceTypeArguments) and expand type arguments without filling type arguments corresponding to superclasses (TypeArguments::ToInstantiatorTypeArguments).
>
> Time of edge case 'regress_51960_test' 15min -> 300ms.
>
> TEST=ci, runtime/tests/vm/dart/regress_51960_test.dart
>
> Fixes https://github.com/dart-lang/sdk/issues/52022
> Fixes https://github.com/dart-lang/sdk/issues/51960
>
> Change-Id: I75b466b74698a33c0bb5e1dcbd29542e413812a1
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/295060
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
> Commit-Queue: Alexander Markov <alexmarkov@google.com>
TEST=runtime/tests/vm/dart/regress_b_278841863_test.dart
Fixes b/278841863.
Change-Id: Ib1e20055bfb26e1df0a077300c69f0bec7152480
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/296300
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
60 lines
2.1 KiB
C++
60 lines
2.1 KiB
C++
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#include "vm/bootstrap_natives.h"
|
|
#include "vm/debugger.h"
|
|
#include "vm/exceptions.h"
|
|
#include "vm/native_entry.h"
|
|
#include "vm/object_store.h"
|
|
#include "vm/runtime_entry.h"
|
|
|
|
namespace dart {
|
|
|
|
DEFINE_NATIVE_ENTRY(AsyncStarMoveNext_debuggerStepCheck, 0, 1) {
|
|
#if !defined(PRODUCT)
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Closure, async_op, arguments->NativeArgAt(0));
|
|
Debugger* debugger = isolate->debugger();
|
|
if (debugger != nullptr) {
|
|
debugger->MaybeAsyncStepInto(async_op);
|
|
}
|
|
#endif
|
|
return Object::null();
|
|
}
|
|
|
|
// Instantiate generic [closure] using the type argument T
|
|
// corresponding to Future<T> in the given [future] instance
|
|
// (which may extend or implement Future).
|
|
DEFINE_NATIVE_ENTRY(SuspendState_instantiateClosureWithFutureTypeArgument,
|
|
0,
|
|
2) {
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Closure, closure, arguments->NativeArgAt(0));
|
|
GET_NON_NULL_NATIVE_ARGUMENT(Instance, future, arguments->NativeArgAt(1));
|
|
IsolateGroup* isolate_group = thread->isolate_group();
|
|
|
|
const auto& future_class =
|
|
Class::Handle(zone, isolate_group->object_store()->future_class());
|
|
ASSERT(future_class.NumTypeArguments() == 1);
|
|
|
|
const auto& cls = Class::Handle(zone, future.clazz());
|
|
auto& type = Type::Handle(zone, cls.GetInstantiationOf(zone, future_class));
|
|
ASSERT(!type.IsNull());
|
|
if (!type.IsInstantiated()) {
|
|
const auto& instance_type_args =
|
|
TypeArguments::Handle(zone, future.GetTypeArguments());
|
|
type ^=
|
|
type.InstantiateFrom(instance_type_args, Object::null_type_arguments(),
|
|
kNoneFree, Heap::kOld);
|
|
}
|
|
auto& type_args = TypeArguments::Handle(zone, type.arguments());
|
|
ASSERT(type_args.IsNull() || type_args.Length() == 1);
|
|
type_args = type_args.Canonicalize(thread, nullptr);
|
|
|
|
ASSERT(closure.delayed_type_arguments() ==
|
|
Object::empty_type_arguments().ptr());
|
|
closure.set_delayed_type_arguments(type_args);
|
|
return closure.ptr();
|
|
}
|
|
|
|
} // namespace dart
|