@@ -2104,8 +2104,7 @@ void GuardFieldLengthInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
21042104
21052105LocationSummary* StoreStaticFieldInstr::MakeLocationSummary (Zone* zone,
21062106 bool opt) const {
2107- const bool can_call_to_throw =
2108- FLAG_experimental_shared_data && !field ().is_shared ();
2107+ const bool can_call_to_throw = FLAG_experimental_shared_data;
21092108 LocationSummary* locs = new (zone)
21102109 LocationSummary (zone, 1 , 1 ,
21112110 can_call_to_throw ? LocationSummary::kCallOnSlowPath
@@ -2122,18 +2121,44 @@ void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
21222121
21232122 compiler->used_static_fields ().Add (&field ());
21242123
2125- if (FLAG_experimental_shared_data && !field ().is_shared ()) {
2126- ThrowErrorSlowPathCode* slow_path = new FieldAccessErrorSlowPath (this );
2124+ if (FLAG_experimental_shared_data) {
21272125 if (value ()->NeedsWriteBarrier ()) {
21282126 // Value input is a writable register and should be manually preserved
21292127 // across allocation slow-path. Add it to live_registers set which
21302128 // determines which registers to preserve.
21312129 locs ()->live_registers ()->Add (Location::RegisterLocation (in));
21322130 }
2133- compiler->AddSlowPathCode (slow_path);
2131+ if (!field ().is_shared ()) {
2132+ ThrowErrorSlowPathCode* slow_path = new FieldAccessErrorSlowPath (this );
2133+ compiler->AddSlowPathCode (slow_path);
21342134
2135- __ LoadIsolate (temp);
2136- __ BranchIfZero (temp, slow_path->entry_label ());
2135+ __ LoadIsolate (temp);
2136+ __ BranchIfZero (temp, slow_path->entry_label ());
2137+ } else {
2138+ // TODO(dartbug.com/61078): use field static type information to decide
2139+ // whether the following value check is needed or not.
2140+ auto throw_if_cant_be_shared_slow_path =
2141+ new ThrowIfValueCantBeSharedSlowPath (this , in);
2142+ compiler->AddSlowPathCode (throw_if_cant_be_shared_slow_path);
2143+
2144+ compiler::Label allow_store;
2145+ __ BranchIfSmi (in, &allow_store, compiler::Assembler::kNearJump );
2146+
2147+ __ movl (temp, compiler::FieldAddress (
2148+ in, compiler::target::Object::tags_offset ()));
2149+ __ testl (temp, compiler::Immediate (
2150+ 1 << compiler::target::UntaggedObject::kImmutableBit ));
2151+ __ j (NOT_ZERO, &allow_store);
2152+
2153+ // Allow TypedData because they contain non-structural mutable state.
2154+ __ LoadClassId (temp, in);
2155+ __ CompareImmediate (temp, kFirstTypedDataCid );
2156+ __ BranchIf (LESS, throw_if_cant_be_shared_slow_path->entry_label ());
2157+ __ CompareImmediate (temp, kLastTypedDataCid );
2158+ __ BranchIf (GREATER, throw_if_cant_be_shared_slow_path->entry_label ());
2159+
2160+ __ Bind (&allow_store);
2161+ }
21372162 }
21382163
21392164 __ movl (temp,
0 commit comments