@@ -737,7 +737,7 @@ void Object::Init(Isolate* isolate) {
737737 cls.set_next_field_offset(host_next_field_offset, target_next_field_offset);
738738 cls.set_id(Class::kClassId);
739739 cls.set_state_bits(0);
740- cls.set_is_finalized ();
740+ cls.set_is_allocate_finalized ();
741741 cls.set_is_declaration_loaded();
742742 cls.set_is_type_finalized();
743743 cls.set_type_arguments_field_offset_in_words(Class::kNoTypeArguments,
@@ -756,7 +756,7 @@ void Object::Init(Isolate* isolate) {
756756 // Allocate and initialize Never class.
757757 cls = Class::New<Instance, RTN::Instance>(kNeverCid, isolate);
758758 cls.set_num_type_arguments(0);
759- cls.set_is_finalized ();
759+ cls.set_is_allocate_finalized ();
760760 cls.set_is_declaration_loaded();
761761 cls.set_is_type_finalized();
762762 isolate->object_store()->set_never_class(cls);
@@ -766,7 +766,7 @@ void Object::Init(Isolate* isolate) {
766766 Class::New<FreeListElement::FakeInstance,
767767 RTN::FreeListElement::FakeInstance>(kFreeListElement, isolate);
768768 cls.set_num_type_arguments(0);
769- cls.set_is_finalized ();
769+ cls.set_is_allocate_finalized ();
770770 cls.set_is_declaration_loaded();
771771 cls.set_is_type_finalized();
772772
@@ -775,7 +775,7 @@ void Object::Init(Isolate* isolate) {
775775 RTN::ForwardingCorpse::FakeInstance>(kForwardingCorpse,
776776 isolate);
777777 cls.set_num_type_arguments(0);
778- cls.set_is_finalized ();
778+ cls.set_is_allocate_finalized ();
779779 cls.set_is_declaration_loaded();
780780 cls.set_is_type_finalized();
781781
@@ -1061,20 +1061,20 @@ void Object::Init(Isolate* isolate) {
10611061 cls = Class::New<Instance, RTN::Instance>(kDynamicCid, isolate);
10621062 cls.set_is_abstract();
10631063 cls.set_num_type_arguments(0);
1064- cls.set_is_finalized ();
1064+ cls.set_is_allocate_finalized ();
10651065 cls.set_is_declaration_loaded();
10661066 cls.set_is_type_finalized();
10671067 dynamic_class_ = cls.raw();
10681068
10691069 cls = Class::New<Instance, RTN::Instance>(kVoidCid, isolate);
10701070 cls.set_num_type_arguments(0);
1071- cls.set_is_finalized ();
1071+ cls.set_is_allocate_finalized ();
10721072 cls.set_is_declaration_loaded();
10731073 cls.set_is_type_finalized();
10741074 void_class_ = cls.raw();
10751075
10761076 cls = Class::New<Type, RTN::Type>(isolate);
1077- cls.set_is_finalized ();
1077+ cls.set_is_allocate_finalized ();
10781078 cls.set_is_declaration_loaded();
10791079 cls.set_is_type_finalized();
10801080
@@ -1850,7 +1850,7 @@ ErrorPtr Object::Init(Isolate* isolate,
18501850
18511851 cls = Class::New<Instance, RTN::Instance>(kNeverCid, isolate);
18521852 cls.set_num_type_arguments(0);
1853- cls.set_is_finalized ();
1853+ cls.set_is_allocate_finalized ();
18541854 cls.set_is_declaration_loaded();
18551855 cls.set_is_type_finalized();
18561856 cls.set_name(Symbols::Never());
@@ -2847,7 +2847,7 @@ ClassPtr Class::New(Isolate* isolate, bool register_class) {
28472847 // possible in this case.
28482848 result.set_is_declaration_loaded();
28492849 result.set_is_type_finalized();
2850- result.set_is_finalized ();
2850+ result.set_is_allocate_finalized ();
28512851 } else if (FakeObject::kClassId != kClosureCid) {
28522852 // VM backed classes are almost ready: run checks and resolve class
28532853 // references, but do not recompute size.
@@ -4222,6 +4222,32 @@ ErrorPtr Class::EnsureIsFinalized(Thread* thread) const {
42224222 return error.raw();
42234223}
42244224
4225+ // Ensure that code outdated by finalized class is cleaned up, new instance of
4226+ // this class is ready to be allocated.
4227+ ErrorPtr Class::EnsureIsAllocateFinalized(Thread* thread) const {
4228+ ASSERT(!IsNull());
4229+ // Finalized classes have already been parsed.
4230+ if (is_allocate_finalized()) {
4231+ return Error::null();
4232+ }
4233+ if (Compiler::IsBackgroundCompilation()) {
4234+ Compiler::AbortBackgroundCompilation(
4235+ DeoptId::kNone, "Class allocate finalization while compiling");
4236+ }
4237+ ASSERT(thread->IsMutatorThread());
4238+ ASSERT(thread != NULL);
4239+ Error& error = Error::Handle(thread->zone(), EnsureIsFinalized(thread));
4240+ if (!error.IsNull()) {
4241+ ASSERT(thread == Thread::Current());
4242+ if (thread->long_jump_base() != NULL) {
4243+ Report::LongJump(error);
4244+ UNREACHABLE();
4245+ }
4246+ }
4247+ error ^= ClassFinalizer::AllocateFinalizeClass(*this);
4248+ return error.raw();
4249+ }
4250+
42254251void Class::SetFields(const Array& value) const {
42264252 ASSERT(!value.IsNull());
42274253#if defined(DEBUG)
@@ -4415,7 +4441,7 @@ ClassPtr Class::NewNativeWrapper(const Library& library,
44154441 compiler::target::RoundedAllocationSize(target_instance_size));
44164442 cls.set_next_field_offset(host_instance_size, target_instance_size);
44174443 cls.set_num_native_fields(field_count);
4418- cls.set_is_finalized ();
4444+ cls.set_is_allocate_finalized ();
44194445 cls.set_is_declaration_loaded();
44204446 cls.set_is_type_finalized();
44214447 cls.set_is_synthesized_class();
@@ -4804,6 +4830,12 @@ void Class::set_is_finalized() const {
48044830 raw_ptr()->state_bits_));
48054831}
48064832
4833+ void Class::set_is_allocate_finalized() const {
4834+ ASSERT(!is_allocate_finalized());
4835+ set_state_bits(ClassFinalizedBits::update(ClassLayout::kAllocateFinalized,
4836+ raw_ptr()->state_bits_));
4837+ }
4838+
48074839void Class::set_is_prefinalized() const {
48084840 ASSERT(!is_finalized());
48094841 set_state_bits(ClassFinalizedBits::update(ClassLayout::kPreFinalized,
0 commit comments