Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
static_type_exactness_state.h
Go to the documentation of this file.
1// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_STATIC_TYPE_EXACTNESS_STATE_H_
6#define RUNTIME_VM_STATIC_TYPE_EXACTNESS_STATE_H_
7
9#include "platform/utils.h"
10
11// This header defines the list of VM implementation classes and their ids.
12//
13// Note: we assume that all builds of Dart VM use exactly the same class ids
14// for these classes.
15
16namespace dart {
17
18class Instance;
19class Type;
20
21// Representation of a state of runtime tracking of static type exactness for
22// a particular location in the program (e.g. exactness of type annotation
23// on a field).
24//
25// Given the static type G<T0, ..., Tn> we say that it is exact iff any
26// values that can be observed at this location has runtime type T such that
27// type arguments of T at G are exactly <T0, ..., Tn>.
28//
29// Currently we only support tracking for locations that are also known
30// to be monomorphic with respect to the actual class of the values it contains.
31//
32// Important: locations should never switch from tracked (kIsTriviallyExact,
33// kHasExactSuperType, kHasExactSuperClass, kNotExact) to not tracked
34// (kNotTracking) or the other way around because that would affect unoptimized
35// graphs generated by graph builder and skew deopt ids.
37 public:
38 // Values stored in the location with static type G<T0, ..., Tn> are all
39 // instances of C<T0, ..., Tn> and C<U0, ..., Un> at G has type parameters
40 // <U0, ..., Un>.
41 //
42 // For trivially exact types we can simply compare type argument
43 // vectors as pointers to check exactness. That's why we represent
44 // trivially exact locations as offset in words to the type arguments of
45 // class C. All other states are represented as non-positive values.
46 //
47 // Note: we are ignoring the type argument vector sharing optimization for
48 // now.
50 intptr_t type_arguments_offset_in_bytes) {
51 ASSERT((type_arguments_offset_in_bytes > 0) &&
52 Utils::IsInt(8, type_arguments_offset_in_bytes));
53 return StaticTypeExactnessState(type_arguments_offset_in_bytes);
54 }
55
56 static inline bool CanRepresentAsTriviallyExact(
57 intptr_t type_arguments_offset_in_bytes) {
58 return Utils::IsInt(8, type_arguments_offset_in_bytes);
59 }
60
61 // Values stored in the location with static type G<T0, ..., Tn> are all
62 // instances of class C<...> and C<U0, ..., Un> at G has type
63 // parameters <T0, ..., Tn> for any <U0, ..., Un> - that is C<...> has a
64 // supertype G<T0, ..., Tn>.
65 //
66 // For such locations we can simply check if the value stored
67 // is an instance of an expected class and we don't have to look at
68 // type arguments carried by the instance.
69 //
70 // We distinguish situations where we know that G is a superclass of C from
71 // situations where G might be superinterface of C - because in the first
72 // type arguments of G give us constant prefix of type arguments of C.
74 return StaticTypeExactnessState(kHasExactSuperType);
75 }
76
78 return StaticTypeExactnessState(kHasExactSuperClass);
79 }
80
81 // Values stored in the location don't fall under either kIsTriviallyExact
82 // or kHasExactSuperType categories.
83 //
84 // Note: that does not imply that static type annotation is not exact
85 // according to a broader definition, e.g. location might simply be
86 // polymorphic and store instances of multiple different types.
87 // However for simplicity we don't track such cases yet.
89 return StaticTypeExactnessState(kNotExact);
90 }
91
92 // The location does not track exactness of its static type at runtime.
94 return StaticTypeExactnessState(kNotTracking);
95 }
96
100
101 static StaticTypeExactnessState Compute(const Type& static_type,
102 const Instance& value,
103 bool print_trace = false);
104
105 bool IsTracking() const { return value_ != kNotTracking; }
106 bool IsUninitialized() const { return value_ == kUninitialized; }
107 bool IsHasExactSuperClass() const { return value_ == kHasExactSuperClass; }
108 bool IsHasExactSuperType() const { return value_ == kHasExactSuperType; }
109 bool IsTriviallyExact() const { return value_ > kUninitialized; }
110 bool NeedsFieldGuard() const { return value_ >= kUninitialized; }
111 bool IsExactOrUninitialized() const { return value_ > kNotExact; }
112 bool IsExact() const {
115 }
116
117 const char* ToCString() const;
118
122
123 static inline StaticTypeExactnessState Decode(int8_t value) {
125 }
126
127 int8_t Encode() const { return value_; }
130 return value_;
131 }
132
133 static constexpr int8_t kUninitialized = 0;
134
135 private:
136 static constexpr int8_t kNotTracking = -4;
137 static constexpr int8_t kNotExact = -3;
138 static constexpr int8_t kHasExactSuperType = -2;
139 static constexpr int8_t kHasExactSuperClass = -1;
140
141 explicit StaticTypeExactnessState(int8_t value) : value_(value) {}
142
143 int8_t value_;
144
145 DISALLOW_ALLOCATION();
146};
147
148} // namespace dart
149
150#endif // RUNTIME_VM_STATIC_TYPE_EXACTNESS_STATE_H_
static StaticTypeExactnessState TriviallyExact(intptr_t type_arguments_offset_in_bytes)
static bool CanRepresentAsTriviallyExact(intptr_t type_arguments_offset_in_bytes)
static StaticTypeExactnessState HasExactSuperType()
static StaticTypeExactnessState NotExact()
StaticTypeExactnessState CollapseSuperTypeExactness() const
static StaticTypeExactnessState NotTracking()
static StaticTypeExactnessState Uninitialized()
const char * ToCString() const
Definition object.cc:12971
static StaticTypeExactnessState Decode(int8_t value)
static StaticTypeExactnessState Compute(const Type &static_type, const Instance &value, bool print_trace=false)
Definition object.cc:12847
static StaticTypeExactnessState HasExactSuperClass()
static bool IsInt(intptr_t N, T value)
Definition utils.h:298
#define ASSERT(E)
uint8_t value