20#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
27 ic_data_array_ =
function.ic_data_array();
28 if (ic_data_array_.
IsNull()) {
34 if (edge_counters_.
IsNull()) {
38 for (intptr_t
i = 0;
i < edge_counters_.
Length();
i++) {
39 edge_counters_.
SetAt(
i, Object::smi_zero());
47 object_(
Object::Handle(zone)),
48 name_(
String::Handle(zone)),
49 new_cls_(
Class::Handle(zone)),
50 new_lib_(
Library::Handle(zone)),
51 new_function_(
Function::Handle(zone)),
52 new_field_(
Field::Handle(zone)),
53 entries_(
Array::Handle(zone)),
57 args_desc_array_(
Array::Handle(zone)),
58 ic_data_array_(
Array::Handle(zone)),
59 edge_counters_(
Array::Handle(zone)),
61 ic_data_(
ICData::Handle(zone)) {}
67#ifdef TARGET_ARCH_IA32
70 if (!
code.is_alive()) {
73 instrs_ =
code.instructions();
76 intptr_t offsets_length =
code.pointer_offsets_length();
78 for (intptr_t
i = 0;
i < offsets_length;
i++) {
82 if (!raw_object->IsHeapObject()) {
86 if (object_.IsICData()) {
87 Reset(ICData::Cast(object_));
91 pool_ =
code.object_pool();
103 intptr_t hi = ic_data_array.
Length() - 1;
105 intptr_t mid = (hi - lo + 1) / 2 + lo;
108 *ic_data ^= ic_data_array.
At(mid);
109 if (ic_data->
deopt_id() == deopt_id) {
111 }
else if (ic_data->
deopt_id() > deopt_id) {
117 FATAL(
"Missing deopt id %" Pd "\n", deopt_id);
121 if (
code.is_optimized()) {
125 object_ =
code.owner();
126 if (!object_.IsFunction()) {
131 if (
function.kind() == UntaggedFunction::kIrregexpFunction) {
140 ic_data_array_ =
function.ic_data_array();
141 if (ic_data_array_.
IsNull()) {
146 descriptors_ =
code.pc_descriptors();
149 FATAL(
"%s has IC calls but no ic_data_array\n",
150 function.ToFullyQualifiedCString());
156 descriptors_ =
code.pc_descriptors();
163 if (!object_.IsICData()) {
169 ? StubCode::OneArgCheckInlineCacheWithExactnessCheck()
170 : StubCode::OneArgCheckInlineCache();
174 " resetting to polymorphic dispatch, %s\n",
182 for (intptr_t
i = 0;
i <
pool.Length();
i++) {
184 if (entry_type != ObjectPool::EntryType::kTaggedObject) {
187 object_ =
pool.ObjectAt(
i);
188 if (object_.IsICData()) {
189 Reset(ICData::Cast(object_));
195 const Class& old_cls)
const {
204 for (intptr_t
i = 0;
i < field_list.
Length();
i++) {
209 for (intptr_t j = 0; j < old_field_list.
Length(); j++) {
211 old_name = old_field.
name();
212 if (
name.Equals(old_name)) {
222 reload_context->AddStaticFieldMapping(old_field, field);
239 if (old_constants.
IsNull() || old_constants.
Length() == 0) {
242 TIR_Print(
"Copied %" Pd " canonical constants for class `%s`\n",
248 const Type& old_declaration_type =
Type::Handle(old_cls.declaration_type());
249 if (old_declaration_type.
IsNull()) {
252 set_declaration_type(old_declaration_type);
258 static const char*
Name() {
return "EnumMapTraits"; }
261 return a.ptr() ==
b.ptr();
266 return String::Cast(obj).Hash();
283 for (intptr_t
i = 0;
i < funcs.
Length();
i++) {
297 if (!owner.IsPatchClass()) {
307 for (intptr_t
i = 0;
i < field_list.
Length();
i++) {
311 if (!owner.IsPatchClass()) {
313 field.set_owner(patch);
315 field.ForceDynamicGuardedCidAndLength();
320 const Class& new_cls)
const {
328 for (intptr_t
i = 0;
i < funcs.
Length();
i++) {
329 old_func ^= funcs.
At(
i);
331 selector = old_func.
name();
333 if (!new_func.
IsNull() && new_func.is_static()) {
341 irc->AddBecomeMapping(old_closure, new_closure);
355 ?
"Enum class cannot be redefined to be a non-enum class: %s"
356 :
"Class cannot be redefined to be a enum class: %s",
372 ErrorPtr ToError() {
return error_.
ptr(); }
383 StringPtr ToString() {
385 "Classes cannot change their @pragma('vm:deeply-immutable'): %s",
396 StringPtr ToString() {
408 StringPtr ToString() {
420 StringPtr ToString() {
433 "Limitation: type parameters have changed for %s",
from_.
ToCString());
438 jsobj.
AddProperty(
"type",
"ReasonForCancellingReload");
439 jsobj.
AddProperty(
"kind",
"TypeParametersChanged");
442 "Limitation: changing type parameters "
443 "does not work with hot reload.");
453 StringPtr ToString() {
455 "Original class ('%s') is prefinalized and replacement class "
467 StringPtr ToString() {
493 new (context->
zone())
504 group_context->AddReasonForCancelling(
505 new (context->
zone())
518 if (!
error.IsNull()) {
520 new (context->
zone())
530 new (context->
zone())
540 new (context->
zone())
546 bool field_removed =
false;
551 field_removed =
true;
557 for (intptr_t
i = 0, n = old_fields.
Length();
i < n;
i++) {
558 old_field ^= old_fields.
At(
i);
559 new_field ^= new_fields.
At(
i);
564 field_removed =
true;
567 old_name = old_field.
name();
568 new_name = new_field.
name();
569 if (!old_name.
Equals(new_name)) {
570 field_removed =
true;
577 new (context->
zone())
586 new (context->
zone())
596 if (!CanReloadFinalized(replacement, context))
return;
599 if (!CanReloadPreFinalized(replacement, context))
return;
602 id(), replacement.
id());
606 const Field& field)
const {
616 const auto end_index =
619 ASSERT(unboxed_fields_map.Get(start_index));
620 for (intptr_t
i = start_index;
i < end_index;
i++) {
621 unboxed_fields_map.Clear(
i);
626bool Class::RequiresInstanceMorphing(
ClassTable* class_table,
627 const Class& replacement)
const {
641 const Array& replacement_fields =
645 if (
fields.Length() != replacement_fields.Length())
return true;
660 for (intptr_t
i = 0;
i <
fields.Length();
i++) {
667 field_name = field.name();
668 replacement_field_name = replacement_field.name();
669 if (!field_name.Equals(replacement_field_name))
return true;
670 if (field.is_unboxed() && !replacement_field.is_unboxed()) {
673 if (field.is_unboxed() && (field.type() != replacement_field.type())) {
676 if (!field.is_unboxed() && replacement_field.is_unboxed()) {
681 if (field.needs_load_guard()) {
682 ASSERT(!field.is_unboxed());
683 ASSERT(!replacement_field.is_unboxed());
684 replacement_field.set_needs_load_guard(
true);
690bool Class::CanReloadFinalized(
const Class& replacement,
691 ProgramReloadContext* context)
const {
694 auto group_context = context->group_reload_context();
695 auto class_table = group_context->isolate_group()->class_table();
697 group_context->AddReasonForCancelling(
698 new (context->zone())
699 TypeParametersChanged(context->zone(), *
this, replacement));
702 if (RequiresInstanceMorphing(class_table, replacement)) {
703 ASSERT(
id() == replacement.id());
708 context->zone(), class_table, *
this, replacement);
709 group_context->EnsureHasInstanceMorpherFor(
cid, instance_morpher);
714bool Class::CanReloadPreFinalized(
const Class& replacement,
715 ProgramReloadContext* context)
const {
717 if (!replacement.is_prefinalized()) {
718 context->group_reload_context()->AddReasonForCancelling(
719 new (context->zone())
720 PreFinalizedConflict(context->zone(), *
this, replacement));
725 context->group_reload_context()->AddReasonForCancelling(
726 new (context->zone())
727 InstanceSizeConflict(context->zone(), *
this, replacement));
744 if (!
object.IsLibraryPrefix())
continue;
746 if (!
prefix.is_deferred_load())
continue;
750 while (original_it.
HasNext()) {
751 object = original_it.
GetNext();
752 if (!
object.IsLibraryPrefix())
continue;
753 original_prefix ^=
object.
ptr();
755 original_name = original_prefix.
name();
756 if (!
name.Equals(original_name))
continue;
761 context->AddBecomeMapping(original_prefix,
prefix);
768 if (rule == ICData::kInstance) {
773 if (num_args == 2 &&
len >= 2) {
785 if ((
target.ptr() == smi_op_target.
ptr()) && (class_ids[0] == kSmiCid) &&
786 (class_ids[1] == kSmiCid)) {
798 }
else if (rule == ICData::kNoRebind || rule == ICData::kNSMDispatch) {
802 }
else if (rule == ICData::kStatic || rule == ICData::kSuper) {
804 if (old_target_.
IsNull()) {
805 FATAL(
"old_target is nullptr.\n");
807 name_ = old_target_.
name();
809 if (rule == ICData::kStatic) {
810 ASSERT(old_target_.is_static() ||
811 old_target_.
kind() == UntaggedFunction::kConstructor);
813 new_cls_ = old_target_.
Owner();
815 if (new_target_.
kind() != old_target_.
kind()) {
820 caller_ = ic.
Owner();
821 ASSERT(!caller_.is_static());
822 new_cls_ = caller_.
Owner();
829 if (new_target_.
IsNull() ||
832 VTIR_Print(
"Cannot rebind static call to %s from %s\n",
839 FATAL(
"Unexpected rebind rule.");
static intptr_t LengthOf(const ArrayPtr array)
ObjectPtr At(intptr_t index) const
void SetAt(intptr_t index, const Object &value) const
StringPtr target_name() const
ArrayPtr arguments_descriptor() const
void ResetCaches(const Code &code)
void ResetSwitchableCalls(const Code &code)
void Reset(const ICData &ic)
void ZeroEdgeCounters(const Function &function)
CallSiteResetter(Zone *zone)
UnboxedFieldBitmap GetUnboxedFieldsMapAt(intptr_t cid) const
void SetUnboxedFieldsMapAt(intptr_t cid, UnboxedFieldBitmap map)
void PatchFieldsAndFunctions() const
void CopyDeclarationType(const Class &old_cls) const
intptr_t NumTypeParameters() const
LibraryPtr library() const
void CopyCanonicalConstants(const Class &old_cls) const
bool is_declaration_loaded() const
intptr_t host_next_field_offset() const
static intptr_t UnboxedFieldSizeInBytesByCid(intptr_t cid)
intptr_t NumTypeArguments() const
bool is_deeply_immutable() const
ArrayPtr constants() const
uint16_t num_native_fields() const
void MigrateImplicitStaticClosures(ProgramReloadContext *context, const Class &new_cls) const
ArrayPtr OffsetToFieldMap(ClassTable *class_table=nullptr) const
intptr_t host_instance_size() const
ErrorPtr EnsureIsFinalized(Thread *thread) const
bool is_prefinalized() const
KernelProgramInfoPtr KernelProgramInfo() const
void CopyStaticFieldValues(ProgramReloadContext *reload_context, const Class &old_cls) const
ErrorPtr EnsureIsAllocateFinalized(Thread *thread) const
ClassPtr SuperClass(ClassTable *class_table=nullptr) const
void set_constants(const Array &value) const
bool is_enum_class() const
void MarkFieldBoxedDuringReload(ClassTable *class_table, const Field &field) const
bool is_allocate_finalized() const
void CheckReload(const Class &replacement, ProgramReloadContext *context) const
intptr_t NumTypeParameters(Thread *thread) const
bool is_finalized() const
ArrayPtr current_functions() const
void EnsureDeclarationLoaded() const
static void PatchInstanceCallAt(uword return_address, const Code &caller_code, const Object &data, const Code &target)
static CodePtr GetInstanceCallAt(uword return_address, const Code &caller_code, Object *data)
ConstClassFieldRemoved(Zone *zone, const Class &from, const Class &to)
ConstToNonConstClass(Zone *zone, const Class &from, const Class &to)
DeeplyImmutableChange(Zone *zone, const Class &from, const Class &to)
EnsureFinalizedError(Zone *zone, const Class &from, const Class &to, const Error &error)
EnumClassConflict(Zone *zone, const Class &from, const Class &to)
static bool IsMatch(const Object &a, const Object &b)
static const char * Name()
static uword Hash(const Object &obj)
static bool ReportStats()
virtual const char * ToErrorCString() const
ObjectPtr RawOwner() const
intptr_t guarded_cid() const
intptr_t field_id() const
intptr_t HostOffset() const
void set_is_unboxed_unsafe(bool b) const
void set_field_id_unsafe(intptr_t field_id) const
void set_owner(const Object &value) const
ObjectPtr RawOwner() const
bool AreValidArguments(intptr_t num_type_arguments, intptr_t num_arguments, const Array &argument_names, String *error_message) const
TokenPosition token_pos() const
bool IsClosureFunction() const
FunctionPtr ImplicitClosureFunction() const
UntaggedFunction::Kind kind() const
ClosurePtr ImplicitStaticClosure() const
bool HasImplicitClosureFunction() const
intptr_t deopt_id() const
void TruncateTo(intptr_t num_checks, const CallSiteResetter &proof_of_reload) const
void ClearCountAt(intptr_t index, const CallSiteResetter &proof_of_reload) const
intptr_t NumArgsTested() const
RebindRule rebind_rule() const
FunctionPtr GetTargetAt(intptr_t index) const
void GetCheckAt(intptr_t index, GrowableArray< intptr_t > *class_ids, Function *target) const
void Clear(const CallSiteResetter &proof_of_reload) const
bool is_tracking_exactness() const
void set_is_megamorphic(bool value) const
void ClearAndSetStaticTarget(const Function &func, const CallSiteResetter &proof_of_reload) const
FunctionPtr Owner() const
static InstanceMorpher * CreateFromClassDescriptors(Zone *zone, ClassTable *class_table, const Class &from, const Class &to)
InstanceSizeConflict(Zone *zone, const Class &from, const Class &to)
uword PayloadStart() const
void FreeStaticField(const Field &field)
SafepointRwLock * program_lock()
static IsolateGroup * Current()
void AddProperty(const char *name, bool b) const
bool is_deferred_load() const
void CheckReload(const Library &replacement, ProgramReloadContext *context) const
intptr_t kernel_library_index() const
NativeFieldsConflict(Zone *zone, const Class &from, const Class &to)
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
void SetCanonical() const
virtual const char * ToCString() const
static ObjectPtr RawCast(ObjectPtr obj)
void set_kernel_library_index(intptr_t index) const
PreFinalizedConflict(Zone *zone, const Class &from, const Class &to)
static bool IsSameClass(const Class &a, const Class &b)
IsolateGroupReloadContext * group_reload_context()
static FunctionPtr ResolveDynamicAnyArgs(Zone *zone, const Class &receiver_class, const String &function_name, bool allow_add)
static FunctionPtr ResolveFunction(Zone *zone, const Class &receiver_class, const String &function_name)
static StringPtr NewFormatted(const char *format,...) PRINTF_ATTRIBUTE(1
bool Equals(const String &str) const
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
static Thread * Current()
IsolateGroup * isolate_group() const
static const TokenPosition kMinSource
void AppendTo(JSONArray *array)
TypeParametersChanged(Zone *zone, const Class &from, const Class &to)
const uint8_t uint32_t uint32_t GError ** error
Dart_NativeFunction function
#define VTIR_Print(format,...)
#define TIR_Print(format,...)
static void FindICData(const Array &ic_data_array, intptr_t deopt_id, ICData *ic_data)
static constexpr intptr_t kCompressedWordSizeLog2
static T LoadUnaligned(const T *ptr)
DECLARE_FLAG(bool, show_invisible_frames)
static constexpr intptr_t kFirstICData
static constexpr intptr_t kEdgeCounters