Version 2.16.0-65.0.dev
Merge commit 'db9d61f3af61310dde776ece95cf37108c64912d' into 'dev'
diff --git a/DEPS b/DEPS
index 580a590..135c437 100644
--- a/DEPS
+++ b/DEPS
@@ -140,7 +140,7 @@
"pool_rev": "7abe634002a1ba8a0928eded086062f1307ccfae",
"process_rev": "56ece43b53b64c63ae51ec184b76bd5360c28d0b",
"protobuf_rev": "c1eb6cb51af39ccbaa1a8e19349546586a5c8e31",
- "pub_rev": "96404e0749864c9fbf8b12e1d424e8078809e00a",
+ "pub_rev": "b9edfa5e288ea3d1a57d1db054ef844ae7b27d99",
"pub_semver_rev": "a43ad72fb6b7869607581b5fedcb186d1e74276a",
"root_certificates_rev": "692f6d6488af68e0121317a9c2c9eb393eb0ee50",
"rust_revision": "b7856f695d65a8ebc846754f97d15814bcb1c244",
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 6decb04..1dbf213 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -132,20 +132,6 @@
}
}
-Representation FlowGraph::UnboxedFieldRepresentationOf(const Field& field) {
- switch (field.UnboxedFieldCid()) {
- case kDoubleCid:
- return kUnboxedDouble;
- case kFloat32x4Cid:
- return kUnboxedFloat32x4;
- case kFloat64x2Cid:
- return kUnboxedFloat64x2;
- default:
- RELEASE_ASSERT(field.is_non_nullable_integer());
- return kUnboxedInt64;
- }
-}
-
void FlowGraph::ReplaceCurrentInstruction(ForwardInstructionIterator* iterator,
Instruction* current,
Instruction* replacement) {
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h
index 815b361..2c82c13 100644
--- a/runtime/vm/compiler/backend/flow_graph.h
+++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -157,8 +157,6 @@
static Representation ReturnRepresentationOf(const Function& function);
- static Representation UnboxedFieldRepresentationOf(const Field& field);
-
// The number of variables (or boxes) inside the functions frame - meaning
// below the frame pointer. This does not include the expression stack.
intptr_t num_stack_locals() const {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 47bcbbbef..e31b958 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -203,30 +203,6 @@
ArchSpecificInitialization();
}
-bool FlowGraphCompiler::IsUnboxedField(const Field& field) {
- // The `field.is_non_nullable_integer()` is set in the kernel loader and can
- // only be set if we consume a AOT kernel (annotated with inferred types).
- ASSERT(!field.is_non_nullable_integer() || FLAG_precompiled_mode);
- const bool valid_class =
- ((SupportsUnboxedDoubles() && (field.guarded_cid() == kDoubleCid)) ||
- (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat32x4Cid)) ||
- (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat64x2Cid)) ||
- field.is_non_nullable_integer());
- return field.is_unboxing_candidate() && !field.is_nullable() && valid_class;
-}
-
-bool FlowGraphCompiler::IsPotentialUnboxedField(const Field& field) {
- if (FLAG_precompiled_mode) {
- // kernel_loader.cc:ReadInferredType sets the guarded cid for fields based
- // on inferred types from TFA (if available). The guarded cid is therefore
- // proven to be correct.
- return IsUnboxedField(field);
- }
- return field.is_unboxing_candidate() &&
- (FlowGraphCompiler::IsUnboxedField(field) ||
- (field.guarded_cid() == kIllegalCid));
-}
-
void FlowGraphCompiler::InitCompiler() {
compressed_stackmaps_builder_ =
new (zone()) CompressedStackMapsBuilder(zone());
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 5d9b0ad..e195a18 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -465,9 +465,6 @@
static bool SupportsHardwareDivision();
static bool CanConvertInt64ToDouble();
- static bool IsUnboxedField(const Field& field);
- static bool IsPotentialUnboxedField(const Field& field);
-
// Accessors.
compiler::Assembler* assembler() const { return assembler_; }
const ParsedFunction& parsed_function() const { return parsed_function_; }
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index e901f3b..4ca03ed 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -894,17 +894,17 @@
bool LoadFieldInstr::IsUnboxedDartFieldLoad() const {
return slot().representation() == kTagged && slot().IsDartField() &&
- FlowGraphCompiler::IsUnboxedField(slot().field());
+ slot().IsUnboxed();
}
bool LoadFieldInstr::IsPotentialUnboxedDartFieldLoad() const {
return slot().representation() == kTagged && slot().IsDartField() &&
- FlowGraphCompiler::IsPotentialUnboxedField(slot().field());
+ slot().IsPotentialUnboxed();
}
Representation LoadFieldInstr::representation() const {
if (IsUnboxedDartFieldLoad() && CompilerState::Current().is_optimizing()) {
- return FlowGraph::UnboxedFieldRepresentationOf(slot().field());
+ return slot().UnboxedRepresentation();
}
return slot().representation();
}
@@ -963,12 +963,12 @@
bool StoreInstanceFieldInstr::IsUnboxedDartFieldStore() const {
return slot().representation() == kTagged && slot().IsDartField() &&
- FlowGraphCompiler::IsUnboxedField(slot().field());
+ slot().IsUnboxed();
}
bool StoreInstanceFieldInstr::IsPotentialUnboxedDartFieldStore() const {
return slot().representation() == kTagged && slot().IsDartField() &&
- FlowGraphCompiler::IsPotentialUnboxedField(slot().field());
+ slot().IsPotentialUnboxed();
}
Representation StoreInstanceFieldInstr::RequiredInputRepresentation(
@@ -979,7 +979,7 @@
return kTagged;
}
if (IsUnboxedDartFieldStore() && CompilerState::Current().is_optimizing()) {
- return FlowGraph::UnboxedFieldRepresentationOf(slot().field());
+ return slot().UnboxedRepresentation();
}
return slot().representation();
}
@@ -6181,7 +6181,7 @@
}
bool Utf8ScanInstr::IsScanFlagsUnboxed() const {
- return FlowGraphCompiler::IsUnboxedField(scan_flags_field_.field());
+ return scan_flags_field_.IsUnboxed();
}
InvokeMathCFunctionInstr::InvokeMathCFunctionInstr(
diff --git a/runtime/vm/compiler/backend/slot.cc b/runtime/vm/compiler/backend/slot.cc
index b4b9920..75afb9a 100644
--- a/runtime/vm/compiler/backend/slot.cc
+++ b/runtime/vm/compiler/backend/slot.cc
@@ -331,6 +331,58 @@
return SlotCache::Instance(thread).Canonicalize(slot);
}
+FieldGuardState::FieldGuardState(const Field& field)
+ : state_(GuardedCidBits::encode(field.guarded_cid()) |
+ IsNonNullableIntegerBit::encode(field.is_non_nullable_integer()) |
+ IsUnboxingCandidateBit::encode(field.is_unboxing_candidate()) |
+ IsNullableBit::encode(field.is_nullable())) {}
+
+bool FieldGuardState::IsUnboxed() const {
+ ASSERT(!is_non_nullable_integer() || FLAG_precompiled_mode);
+ const bool valid_class = ((FlowGraphCompiler::SupportsUnboxedDoubles() &&
+ (guarded_cid() == kDoubleCid)) ||
+ (FlowGraphCompiler::SupportsUnboxedSimd128() &&
+ (guarded_cid() == kFloat32x4Cid)) ||
+ (FlowGraphCompiler::SupportsUnboxedSimd128() &&
+ (guarded_cid() == kFloat64x2Cid)) ||
+ is_non_nullable_integer());
+ return is_unboxing_candidate() && !is_nullable() && valid_class;
+}
+
+bool FieldGuardState::IsPotentialUnboxed() const {
+ if (FLAG_precompiled_mode) {
+ // kernel_loader.cc:ReadInferredType sets the guarded cid for fields based
+ // on inferred types from TFA (if available). The guarded cid is therefore
+ // proven to be correct.
+ return IsUnboxed();
+ }
+
+ return is_unboxing_candidate() &&
+ (IsUnboxed() || (guarded_cid() == kIllegalCid));
+}
+
+bool Slot::IsUnboxed() const {
+ return field_guard_state().IsUnboxed();
+}
+
+bool Slot::IsPotentialUnboxed() const {
+ return field_guard_state().IsPotentialUnboxed();
+}
+
+Representation Slot::UnboxedRepresentation() const {
+ switch (field_guard_state().guarded_cid()) {
+ case kDoubleCid:
+ return kUnboxedDouble;
+ case kFloat32x4Cid:
+ return kUnboxedFloat32x4;
+ case kFloat64x2Cid:
+ return kUnboxedFloat64x2;
+ default:
+ RELEASE_ASSERT(field_guard_state().is_non_nullable_integer());
+ return kUnboxedInt64;
+ }
+}
+
const Slot& Slot::Get(const Field& field,
const ParsedFunction* parsed_function) {
Thread* thread = Thread::Current();
@@ -354,16 +406,18 @@
is_nullable = false;
}
+ FieldGuardState field_guard_state(field);
+
bool used_guarded_state = false;
- if (field.guarded_cid() != kIllegalCid &&
- field.guarded_cid() != kDynamicCid) {
+ if (field_guard_state.guarded_cid() != kIllegalCid &&
+ field_guard_state.guarded_cid() != kDynamicCid) {
// Use guarded state if it is more precise then what we already have.
if (nullable_cid == kDynamicCid) {
- nullable_cid = field.guarded_cid();
+ nullable_cid = field_guard_state.guarded_cid();
used_guarded_state = true;
}
- if (is_nullable && !field.is_nullable()) {
+ if (is_nullable && !field_guard_state.is_nullable()) {
is_nullable = false;
used_guarded_state = true;
}
@@ -377,10 +431,10 @@
used_guarded_state = false;
}
- if (field.is_non_nullable_integer()) {
+ if (field_guard_state.is_non_nullable_integer()) {
ASSERT(FLAG_precompiled_mode);
is_nullable = false;
- if (FlowGraphCompiler::IsUnboxedField(field)) {
+ if (field_guard_state.IsUnboxed()) {
rep = kUnboxedInt64;
}
}
@@ -397,7 +451,7 @@
IsSentinelVisibleBit::encode(field.is_late() && field.is_final() &&
!field.has_initializer()),
nullable_cid, compiler::target::Field::OffsetOf(field), &field, &type,
- rep));
+ rep, field_guard_state));
// If properties of this slot were based on the guarded state make sure
// to add the field to the list of guarded fields. Note that during background
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index a31e9a9..88c1dd8 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -166,6 +166,35 @@
NONNULLABLE_BOXED_NATIVE_SLOTS_LIST(V) \
UNBOXED_NATIVE_SLOTS_LIST(V)
+class FieldGuardState {
+ public:
+ FieldGuardState() : state_(0) {}
+ explicit FieldGuardState(const Field& field);
+
+ intptr_t guarded_cid() const { return GuardedCidBits::decode(state_); }
+ bool is_non_nullable_integer() const {
+ return IsNonNullableIntegerBit::decode(state_);
+ }
+ bool is_unboxing_candidate() const {
+ return IsUnboxingCandidateBit::decode(state_);
+ }
+ bool is_nullable() const { return IsNullableBit::decode(state_); }
+
+ bool IsUnboxed() const;
+ bool IsPotentialUnboxed() const;
+
+ private:
+ using GuardedCidBits = BitField<int32_t, ClassIdTagType, 0, 16>;
+ using IsNonNullableIntegerBit =
+ BitField<int32_t, bool, GuardedCidBits::kNextBit, 1>;
+ using IsUnboxingCandidateBit =
+ BitField<int32_t, bool, IsNonNullableIntegerBit::kNextBit, 1>;
+ using IsNullableBit =
+ BitField<int32_t, bool, IsUnboxingCandidateBit::kNextBit, 1>;
+
+ const int32_t state_;
+};
+
// Slot is an abstraction that describes an readable (and possibly writeable)
// location within an object.
//
@@ -298,6 +327,10 @@
return kind() == Kind::kCapturedVariable || kind() == Kind::kContext_parent;
}
+ bool IsUnboxed() const;
+ bool IsPotentialUnboxed() const;
+ Representation UnboxedRepresentation() const;
+
private:
friend class FlowGraphDeserializer; // For GetNativeSlot.
@@ -307,12 +340,14 @@
intptr_t offset_in_bytes,
const void* data,
const AbstractType* static_type,
- Representation representation)
+ Representation representation,
+ const FieldGuardState& field_guard_state = FieldGuardState())
: kind_(kind),
flags_(bits),
cid_(cid),
offset_in_bytes_(offset_in_bytes),
representation_(representation),
+ field_guard_state_(field_guard_state),
data_(data),
static_type_(static_type) {}
@@ -323,7 +358,8 @@
other.offset_in_bytes_,
other.data_,
other.static_type_,
- other.representation_) {}
+ other.representation_,
+ other.field_guard_state_) {}
using IsImmutableBit = BitField<int8_t, bool, 0, 1>;
using IsNullableBit = BitField<int8_t, bool, IsImmutableBit::kNextBit, 1>;
@@ -342,6 +378,10 @@
static AcqRelAtomic<Slot*> native_fields_;
static const Slot& GetNativeSlot(Kind kind);
+ const FieldGuardState& field_guard_state() const {
+ return field_guard_state_;
+ }
+
const Kind kind_;
const int8_t flags_; // is_immutable, is_nullable
const ClassIdTagType cid_; // Concrete cid of a value or kDynamicCid.
@@ -349,6 +389,8 @@
const intptr_t offset_in_bytes_;
const Representation representation_;
+ const FieldGuardState field_guard_state_;
+
// Kind dependent data:
// - name as a Dart String object for local variables;
// - name as a C string for native slots;
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
index 85ed2b5..a0da87b 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -1050,7 +1050,8 @@
// [Intrinsifier::CanIntrinsifyFieldAccessor])
auto zone = flow_graph->zone();
const auto& function = flow_graph->function();
- ASSERT(Intrinsifier::CanIntrinsifyFieldAccessor(function));
+ ASSERT(
+ Intrinsifier::CanIntrinsifyFieldAccessor(flow_graph->parsed_function()));
auto& field = Field::Handle(zone, function.accessor_field());
if (CompilerState::Current().should_clone_fields()) {
@@ -1072,12 +1073,10 @@
// We only support cases where we do not have to create a box (whose
// allocation could fail).
- ASSERT(function.HasUnboxedReturnValue() ||
- !FlowGraphCompiler::IsUnboxedField(field));
+ ASSERT(function.HasUnboxedReturnValue() || !slot.IsUnboxed());
// We might need to unbox the field value before returning.
- if (function.HasUnboxedReturnValue() &&
- !FlowGraphCompiler::IsUnboxedField(field)) {
+ if (function.HasUnboxedReturnValue() && !slot.IsUnboxed()) {
ASSERT(FLAG_precompiled_mode);
field_value = builder.AddUnboxInstr(
FlowGraph::ReturnRepresentationOf(flow_graph->function()),
@@ -1093,21 +1092,19 @@
// [Intrinsifier::CanIntrinsifyFieldAccessor])
auto zone = flow_graph->zone();
const auto& function = flow_graph->function();
- ASSERT(Intrinsifier::CanIntrinsifyFieldAccessor(function));
+ ASSERT(
+ Intrinsifier::CanIntrinsifyFieldAccessor(flow_graph->parsed_function()));
auto& field = Field::Handle(zone, function.accessor_field());
if (CompilerState::Current().should_clone_fields()) {
field = field.CloneFromOriginal();
}
ASSERT(field.is_instance() && !field.is_final());
- ASSERT(!function.HasUnboxedParameters() ||
- FlowGraphCompiler::IsUnboxedField(field));
-
const auto& slot = Slot::Get(field, &flow_graph->parsed_function());
+ ASSERT(!function.HasUnboxedParameters() || slot.IsUnboxed());
- const auto barrier_mode = FlowGraphCompiler::IsUnboxedField(field)
- ? kNoStoreBarrier
- : kEmitStoreBarrier;
+ const auto barrier_mode =
+ slot.IsUnboxed() ? kNoStoreBarrier : kEmitStoreBarrier;
flow_graph->CreateCommonConstants();
GraphEntryInstr* graph_entry = flow_graph->graph_entry();
@@ -1118,14 +1115,13 @@
auto value = builder.AddParameter(1, /*with_frame=*/false);
VerifyParameterIsBoxed(&builder, 0);
- if (!function.HasUnboxedParameters() &&
- FlowGraphCompiler::IsUnboxedField(field)) {
+ if (!function.HasUnboxedParameters() && slot.IsUnboxed()) {
// We do not support storing to possibly guarded fields in JIT in graph
// intrinsics.
ASSERT(FLAG_precompiled_mode);
- value = builder.AddUnboxInstr(
- FlowGraph::UnboxedFieldRepresentationOf(field), new Value(value),
- /*is_checked=*/true);
+ value =
+ builder.AddUnboxInstr(slot.UnboxedRepresentation(), new Value(value),
+ /*is_checked=*/true);
}
builder.AddInstruction(new (zone) StoreInstanceFieldInstr(
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index f343f73..4ba80d9f 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -25,7 +25,9 @@
namespace compiler {
-bool Intrinsifier::CanIntrinsify(const Function& function) {
+bool Intrinsifier::CanIntrinsify(const ParsedFunction& parsed_function) {
+ const Function& function = parsed_function.function();
+
if (FLAG_trace_intrinsifier) {
THR_Print("CanIntrinsify %s ->", function.ToQualifiedCString());
}
@@ -45,7 +47,8 @@
}
return false;
}
- if (!function.is_intrinsic() && !CanIntrinsifyFieldAccessor(function)) {
+ if (!function.is_intrinsic() &&
+ !CanIntrinsifyFieldAccessor(parsed_function)) {
if (FLAG_trace_intrinsifier) {
THR_Print("No, not intrinsic function.\n");
}
@@ -73,7 +76,10 @@
return true;
}
-bool Intrinsifier::CanIntrinsifyFieldAccessor(const Function& function) {
+bool Intrinsifier::CanIntrinsifyFieldAccessor(
+ const ParsedFunction& parsed_function) {
+ const Function& function = parsed_function.function();
+
const bool is_getter = function.IsImplicitGetterFunction();
const bool is_setter = function.IsImplicitSetterFunction();
if (!is_getter && !is_setter) return false;
@@ -97,11 +103,13 @@
// We only graph intrinsify implicit instance getters/setter for now.
if (!field.is_instance()) return false;
+ const auto& slot = Slot::Get(field, &parsed_function);
+
if (is_getter) {
// We don't support complex getter cases.
if (field.is_late() || field.needs_load_guard()) return false;
- if (FlowGraphCompiler::IsPotentialUnboxedField(field)) {
+ if (slot.IsPotentialUnboxed()) {
if (function.HasUnboxedReturnValue()) {
// In AOT mode: Unboxed fields contain the unboxed value and can be
// returned in unboxed form.
@@ -136,7 +144,7 @@
// avoid the need for boxing (which we cannot do in the intrinsic).
if (function.HasUnboxedParameters()) {
ASSERT(FLAG_precompiled_mode);
- if (!FlowGraphCompiler::IsUnboxedField(field)) {
+ if (!slot.IsUnboxed()) {
return false;
}
}
@@ -253,8 +261,7 @@
// Returns true if fall-through code can be omitted.
bool Intrinsifier::Intrinsify(const ParsedFunction& parsed_function,
FlowGraphCompiler* compiler) {
- const Function& function = parsed_function.function();
- if (!CanIntrinsify(function)) {
+ if (!CanIntrinsify(parsed_function)) {
return false;
}
@@ -262,6 +269,7 @@
return compiler->intrinsic_slow_path_label()->IsUnused();
}
+ const Function& function = parsed_function.function();
#if !defined(HASH_IN_OBJECT_HEADER)
// These two are more complicated on 32 bit platforms, where the
// identity hash is not stored in the header of the object. We
diff --git a/runtime/vm/compiler/intrinsifier.h b/runtime/vm/compiler/intrinsifier.h
index 835f73f..681b606 100644
--- a/runtime/vm/compiler/intrinsifier.h
+++ b/runtime/vm/compiler/intrinsifier.h
@@ -35,8 +35,8 @@
private:
friend class GraphIntrinsifier; // For CanIntrinsifyFieldAccessor.
- static bool CanIntrinsify(const Function& function);
- static bool CanIntrinsifyFieldAccessor(const Function& function);
+ static bool CanIntrinsify(const ParsedFunction& parsed_function);
+ static bool CanIntrinsifyFieldAccessor(const ParsedFunction& parsed_function);
};
} // namespace compiler
diff --git a/sdk/lib/_internal/vm/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart
index 8ce0776..8812068 100644
--- a/sdk/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk/lib/_internal/vm/bin/socket_patch.dart
@@ -1396,7 +1396,8 @@
if (i == errorEvent) {
if (!isClosing) {
- reportError(nativeGetError(), null, "");
+ final err = nativeGetError();
+ reportError(err, null, err.message);
}
} else if (!isClosed) {
// If the connection is closed right after it's accepted, there's a
diff --git a/tools/VERSION b/tools/VERSION
index 536a2a3..d0ff84a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 64
+PRERELEASE 65
PRERELEASE_PATCH 0
\ No newline at end of file