Version 2.14.0-204.0.dev
Merge commit '00d6b8972a63f92ec590e4e0d1f4b045071f26e7' into 'dev'
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index bfa05f5..2fbc03f 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -42,6 +42,7 @@
V(ExceptionHandlers) \
V(Context) \
V(ContextScope) \
+ V(Sentinel) \
V(SingleTargetCache) \
V(UnlinkedCall) \
V(MonomorphicSmiableCall) \
@@ -217,8 +218,6 @@
kNumPredefinedCids,
};
-constexpr ClassId kSentinelCid = kNeverCid;
-
// Keep these in sync with the cid numbering above.
const int kTypedDataCidRemainderInternal = 0;
const int kTypedDataCidRemainderView = 1;
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 243f69a..fd75159 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -570,11 +570,7 @@
void WriteCanonicalSetLayout(Serializer* s) {
if (represents_canonical_set_) {
s->WriteUnsigned(table_length_);
- if (kAllCanonicalObjectsAreIncludedIntoSet) {
- ASSERT(objects_.length() == gaps_.length());
- } else {
- s->WriteUnsigned(objects_.length() - gaps_.length());
- }
+ s->WriteUnsigned(objects_.length() - gaps_.length());
for (auto gap : gaps_) {
s->WriteUnsigned(gap);
}
@@ -608,8 +604,7 @@
}
const auto table_length = d->ReadUnsigned();
- first_element_ =
- kAllCanonicalObjectsAreIncludedIntoSet ? 0 : d->ReadUnsigned();
+ first_element_ = d->ReadUnsigned();
const intptr_t count = stop_index_ - (start_index_ + first_element_);
auto table = StartDeserialization(d, table_length, count);
for (intptr_t i = start_index_ + first_element_; i < stop_index_; i++) {
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 215bca5..8a0978b 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -757,7 +757,7 @@
// No IC data checks. Try resolve target using the propagated cid.
const intptr_t receiver_cid =
instr->ArgumentValueAt(receiver_idx)->Type()->ToCid();
- if (receiver_cid != kDynamicCid) {
+ if (receiver_cid != kDynamicCid && receiver_cid != kSentinelCid) {
const Class& receiver_class =
Class::Handle(Z, isolate_group()->class_table()->At(receiver_cid));
const Function& function =
@@ -781,7 +781,7 @@
const intptr_t cid = class_ids[i];
// Skip sentinel cid. It may appear in the unreachable code after
// inlining a method which doesn't return.
- if (cid == kNeverCid) continue;
+ if (cid == kSentinelCid) continue;
const Class& cls =
Class::Handle(Z, isolate_group()->class_table()->At(cid));
const Function& target =
@@ -1051,7 +1051,7 @@
const intptr_t receiver_idx = call->type_args_len() > 0 ? 1 : 0;
const intptr_t receiver_cid =
call->ArgumentValueAt(receiver_idx)->Type()->ToCid();
- if (receiver_cid != kDynamicCid) {
+ if (receiver_cid != kDynamicCid && receiver_cid != kSentinelCid) {
const Class& receiver_class =
Class::Handle(Z, isolate_group()->class_table()->At(receiver_cid));
const Function& function =
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 62d0044..5e299f0 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -2277,6 +2277,7 @@
auto& members = Array::Handle(Z);
auto& constants = Array::Handle(Z);
auto& retained_constants = GrowableObjectArray::Handle(Z);
+ auto& obj = Object::Handle(Z);
auto& constant = Instance::Handle(Z);
SafepointWriteRwLocker ml(T, T->isolate_group()->program_lock());
@@ -2308,7 +2309,12 @@
retained_constants = GrowableObjectArray::New();
if (!constants.IsNull()) {
for (intptr_t j = 0; j < constants.Length(); j++) {
- constant ^= constants.At(j);
+ obj = constants.At(j);
+ if ((obj.ptr() == HashTableBase::UnusedMarker().ptr()) ||
+ (obj.ptr() == HashTableBase::DeletedMarker().ptr())) {
+ continue;
+ }
+ constant ^= obj.ptr();
bool retain = consts_to_retain_.HasKey(&constant);
if (retain) {
retained_constants.Add(constant);
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 529eda6..88d1f2f 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -602,11 +602,7 @@
const intptr_t right_cid = instr->right()->Type()->ToCid();
// If exact classes (cids) are known and they differ, the result
// of strict compare can be computed.
- // The only exception is comparison with special sentinel value
- // (used for lazy initialization) which can be compared to a
- // value of any type. Sentinel value has kNeverCid.
if ((left_cid != kDynamicCid) && (right_cid != kDynamicCid) &&
- (left_cid != kNeverCid) && (right_cid != kNeverCid) &&
(left_cid != right_cid)) {
const bool result = (instr->kind() != Token::kEQ_STRICT);
SetValue(instr, Bool::Get(result));
@@ -852,7 +848,7 @@
if (!FLAG_fields_may_be_reset) {
const Field& field = instr->field();
ASSERT(field.is_static());
- auto& obj = Instance::Handle(Z);
+ auto& obj = Object::Handle(Z);
if (field.is_final() && instr->IsFieldInitialized(&obj)) {
if (obj.IsSmi() || (obj.IsOld() && obj.IsCanonical())) {
SetValue(instr, obj);
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index aad4fe7..b65dc1a 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -1149,7 +1149,7 @@
return field().ptr() == other.AsLoadStaticField()->field().ptr();
}
-bool LoadStaticFieldInstr::IsFieldInitialized(Instance* field_value) const {
+bool LoadStaticFieldInstr::IsFieldInitialized(Object* field_value) const {
if (FLAG_fields_may_be_reset) {
return false;
}
@@ -1170,7 +1170,7 @@
return false;
}
if (field_value == nullptr) {
- field_value = &Instance::Handle();
+ field_value = &Object::Handle();
}
*field_value = only_isolate->field_table()->At(field.field_id());
return (field_value->ptr() != Object::sentinel().ptr()) &&
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index e14e142..91fe069 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -5561,7 +5561,7 @@
virtual CompileType ComputeType() const;
const Field& field() const { return field_; }
- bool IsFieldInitialized(Instance* field_value = nullptr) const;
+ bool IsFieldInitialized(Object* field_value = nullptr) const;
bool calls_initializer() const { return calls_initializer_; }
void set_calls_initializer(bool value) { calls_initializer_ = value; }
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index d576993..3163f63 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -3669,7 +3669,7 @@
FlowGraphInliner::ExactnessInfo* exactness) {
COMPILER_TIMINGS_TIMER_SCOPE(flow_graph->thread(), InlineRecognizedMethod);
- if (receiver_cid == kNeverCid) {
+ if (receiver_cid == kSentinelCid) {
// Receiver was defined in dead code and was replaced by the sentinel.
// Original receiver cid is lost, so don't try to inline recognized
// methods.
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 8ff2339..c396f37 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -739,8 +739,8 @@
cid_ = kNullCid;
}
// Same for sentinel.
- if ((type_ != NULL) && type_->IsNeverType()) {
- cid_ = kNeverCid;
+ if ((type_ != NULL) && type_->IsSentinelType()) {
+ cid_ = kSentinelCid;
}
}
@@ -761,8 +761,8 @@
cid_ = kDynamicCid;
} else if (type_->IsNullType()) {
cid_ = kNullCid;
- } else if (type_->IsNeverType()) {
- cid_ = kNeverCid;
+ } else if (type_->IsSentinelType()) {
+ cid_ = kSentinelCid;
} else if (type_->IsFunctionType() || type_->IsDartFunctionType()) {
cid_ = kClosureCid;
} else if (type_->type_class_id() != kIllegalCid) {
@@ -1514,7 +1514,7 @@
AbstractType* abstract_type = &AbstractType::ZoneHandle(field.type());
TraceStrongModeType(this, *abstract_type);
ASSERT(field.is_static());
- auto& obj = Instance::Handle();
+ auto& obj = Object::Handle();
const bool is_initialized = IsFieldInitialized(&obj);
if (field.is_final() && is_initialized) {
if (!obj.IsNull()) {
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc
index 4cb966e..87d459a 100644
--- a/runtime/vm/compiler/backend/type_propagator_test.cc
+++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -191,7 +191,7 @@
{
SafepointWriteRwLocker locker(thread,
thread->isolate_group()->program_lock());
- thread->isolate_group()->RegisterStaticField(field, Instance::Handle());
+ thread->isolate_group()->RegisterStaticField(field, Object::Handle());
}
FlowGraphBuilderHelper H;
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index e33e569..4a737b1 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -140,8 +140,13 @@
}
if (all_cids_known) {
+ const intptr_t receiver_cid = class_ids[0];
+ if (receiver_cid == kSentinelCid) {
+ // Unreachable call.
+ return false;
+ }
const Class& receiver_class =
- Class::Handle(Z, IG->class_table()->At(class_ids[0]));
+ Class::Handle(Z, IG->class_table()->At(receiver_cid));
if (!receiver_class.is_finalized()) {
// Do not eagerly finalize classes. ResolveDynamicForReceiverClass can
// cause class finalization, since callee's receiver class may not be
diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc
index d85926f..a9bd54f 100644
--- a/runtime/vm/compiler/frontend/constant_reader.cc
+++ b/runtime/vm/compiler/frontend/constant_reader.cc
@@ -21,7 +21,7 @@
translation_helper_(helper->translation_helper_),
active_class_(active_class),
script_(helper->script()),
- result_(Instance::Handle(zone_)) {}
+ result_(Object::Handle(zone_)) {}
InstancePtr ConstantReader::ReadConstantInitializer() {
Tag tag = helper_->ReadTag(); // read tag.
@@ -33,7 +33,7 @@
"Not a constant expression: unexpected kernel tag %s (%d)",
Reader::TagName(tag), tag);
}
- return result_.ptr();
+ return Instance::RawCast(result_.ptr());
}
InstancePtr ConstantReader::ReadConstantExpression() {
@@ -58,7 +58,7 @@
"Not a constant expression: unexpected kernel tag %s (%d)",
Reader::TagName(tag), tag);
}
- return result_.ptr();
+ return Instance::RawCast(result_.ptr());
}
ObjectPtr ConstantReader::ReadAnnotations() {
@@ -89,7 +89,7 @@
H.thread()->isolate_group()->kernel_constants_mutex());
const auto& constants_array = Array::Handle(Z, H.info().constants());
ASSERT(constant_index < constants_array.Length());
- result_ ^= constants_array.At(constant_index);
+ result_ = constants_array.At(constant_index);
}
// On miss, evaluate, and insert value.
@@ -102,7 +102,7 @@
ASSERT(constant_index < constants_array.Length());
constants_array.SetAt(constant_index, result_);
}
- return result_.ptr();
+ return Instance::RawCast(result_.ptr());
}
bool ConstantReader::IsInstanceConstant(intptr_t constant_index,
diff --git a/runtime/vm/compiler/frontend/constant_reader.h b/runtime/vm/compiler/frontend/constant_reader.h
index b4e52c4..733a463 100644
--- a/runtime/vm/compiler/frontend/constant_reader.h
+++ b/runtime/vm/compiler/frontend/constant_reader.h
@@ -47,7 +47,7 @@
TranslationHelper& translation_helper_;
ActiveClass* active_class_;
const Script& script_;
- Instance& result_;
+ Object& result_;
DISALLOW_COPY_AND_ASSIGN(ConstantReader);
};
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 8aa7359..ecca290 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -1141,6 +1141,10 @@
return -kWordSize;
}
+word Sentinel::NextFieldOffset() {
+ return -kWordSize;
+}
+
word UnlinkedCall::NextFieldOffset() {
return -kWordSize;
}
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 32cbeee..7b746fe 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -890,6 +890,12 @@
static word NextFieldOffset();
};
+class Sentinel : public AllStatic {
+ public:
+ static word InstanceSize();
+ static word NextFieldOffset();
+};
+
class UnlinkedCall : public AllStatic {
public:
static word InstanceSize();
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 56e8f0e..e3d2c5d 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -529,6 +529,7 @@
static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
static constexpr dart::compiler::target::word Script_InstanceSize = 48;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word Sentinel_InstanceSize = 4;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
16;
static constexpr dart::compiler::target::word StackTrace_InstanceSize = 20;
@@ -1074,6 +1075,7 @@
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
static constexpr dart::compiler::target::word Script_InstanceSize = 80;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
32;
static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
@@ -1609,6 +1611,7 @@
static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
static constexpr dart::compiler::target::word Script_InstanceSize = 48;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word Sentinel_InstanceSize = 4;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
16;
static constexpr dart::compiler::target::word StackTrace_InstanceSize = 20;
@@ -2155,6 +2158,7 @@
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
static constexpr dart::compiler::target::word Script_InstanceSize = 80;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
32;
static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
@@ -2699,6 +2703,7 @@
static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
static constexpr dart::compiler::target::word Script_InstanceSize = 56;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
32;
static constexpr dart::compiler::target::word StackTrace_InstanceSize = 24;
@@ -3244,6 +3249,7 @@
static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
static constexpr dart::compiler::target::word Script_InstanceSize = 56;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
32;
static constexpr dart::compiler::target::word StackTrace_InstanceSize = 24;
@@ -3778,6 +3784,7 @@
static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
static constexpr dart::compiler::target::word Script_InstanceSize = 48;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word Sentinel_InstanceSize = 4;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
16;
static constexpr dart::compiler::target::word StackTrace_InstanceSize = 20;
@@ -4317,6 +4324,7 @@
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
static constexpr dart::compiler::target::word Script_InstanceSize = 80;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
32;
static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
@@ -4846,6 +4854,7 @@
static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
static constexpr dart::compiler::target::word Script_InstanceSize = 48;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word Sentinel_InstanceSize = 4;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
16;
static constexpr dart::compiler::target::word StackTrace_InstanceSize = 20;
@@ -5386,6 +5395,7 @@
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
static constexpr dart::compiler::target::word Script_InstanceSize = 80;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
32;
static constexpr dart::compiler::target::word StackTrace_InstanceSize = 40;
@@ -5924,6 +5934,7 @@
static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
static constexpr dart::compiler::target::word Script_InstanceSize = 56;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
32;
static constexpr dart::compiler::target::word StackTrace_InstanceSize = 24;
@@ -6463,6 +6474,7 @@
static constexpr dart::compiler::target::word RegExp_InstanceSize = 80;
static constexpr dart::compiler::target::word Script_InstanceSize = 56;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
32;
static constexpr dart::compiler::target::word StackTrace_InstanceSize = 24;
@@ -7064,6 +7076,7 @@
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 60;
static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Sentinel_InstanceSize = 4;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 20;
@@ -7671,6 +7684,7 @@
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
@@ -8282,6 +8296,7 @@
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
@@ -8889,6 +8904,7 @@
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 80;
static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 48;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 24;
@@ -9497,6 +9513,7 @@
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 80;
static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 48;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 24;
@@ -10095,6 +10112,7 @@
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 60;
static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Sentinel_InstanceSize = 4;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 20;
@@ -10695,6 +10713,7 @@
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
@@ -11299,6 +11318,7 @@
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 72;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 40;
@@ -11899,6 +11919,7 @@
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 80;
static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 48;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 24;
@@ -12500,6 +12521,7 @@
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 80;
static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 48;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_Sentinel_InstanceSize = 8;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_StackTrace_InstanceSize = 24;
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index 08f4fe7..43df0cb 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -379,6 +379,7 @@
SIZEOF(RegExp, InstanceSize, UntaggedRegExp) \
SIZEOF(Script, InstanceSize, UntaggedScript) \
SIZEOF(SendPort, InstanceSize, UntaggedSendPort) \
+ SIZEOF(Sentinel, InstanceSize, UntaggedSentinel) \
SIZEOF(SingleTargetCache, InstanceSize, UntaggedSingleTargetCache) \
SIZEOF(StackTrace, InstanceSize, UntaggedStackTrace) \
SIZEOF(String, InstanceSize, UntaggedString) \
diff --git a/runtime/vm/field_table.cc b/runtime/vm/field_table.cc
index bd20207..6809ff4 100644
--- a/runtime/vm/field_table.cc
+++ b/runtime/vm/field_table.cc
@@ -49,7 +49,7 @@
}
intptr_t FieldTable::FieldOffsetFor(intptr_t field_id) {
- return field_id * sizeof(InstancePtr); // NOLINT
+ return field_id * sizeof(ObjectPtr); // NOLINT
}
bool FieldTable::Register(const Field& field, intptr_t expected_field_id) {
@@ -88,7 +88,7 @@
free_head_ = field_id;
}
-void FieldTable::SetAt(intptr_t index, InstancePtr raw_instance) {
+void FieldTable::SetAt(intptr_t index, ObjectPtr raw_instance) {
ASSERT(index < capacity_);
table_[index] = raw_instance;
}
@@ -99,7 +99,7 @@
Grow(new_capacity);
}
- ASSERT(table_[index] == InstancePtr());
+ ASSERT(table_[index] == ObjectPtr());
if (index >= top_) {
top_ = index + 1;
}
@@ -109,14 +109,14 @@
ASSERT(new_capacity > capacity_);
auto old_table = table_;
- auto new_table = static_cast<InstancePtr*>(
- malloc(new_capacity * sizeof(InstancePtr))); // NOLINT
+ auto new_table = static_cast<ObjectPtr*>(
+ malloc(new_capacity * sizeof(ObjectPtr))); // NOLINT
intptr_t i;
for (i = 0; i < top_; i++) {
new_table[i] = old_table[i];
}
for (; i < new_capacity; i++) {
- new_table[i] = InstancePtr();
+ new_table[i] = ObjectPtr();
}
capacity_ = new_capacity;
old_tables_->Add(old_table);
@@ -134,9 +134,9 @@
IsolateGroup::Current()->program_lock()->IsCurrentThreadReader());
FieldTable* clone = new FieldTable(for_isolate);
- auto new_table = static_cast<InstancePtr*>(
- malloc(capacity_ * sizeof(InstancePtr))); // NOLINT
- memmove(new_table, table_, capacity_ * sizeof(InstancePtr));
+ auto new_table =
+ static_cast<ObjectPtr*>(malloc(capacity_ * sizeof(ObjectPtr))); // NOLINT
+ memmove(new_table, table_, capacity_ * sizeof(ObjectPtr));
ASSERT(clone->table_ == nullptr);
clone->table_ = new_table;
clone->capacity_ = capacity_;
@@ -153,8 +153,7 @@
ASSERT(visitor != NULL);
visitor->set_gc_root_type("static fields table");
- visitor->VisitPointers(reinterpret_cast<ObjectPtr*>(&table_[0]),
- reinterpret_cast<ObjectPtr*>(&table_[top_ - 1]));
+ visitor->VisitPointers(&table_[0], &table_[top_ - 1]);
visitor->clear_gc_root_type();
}
diff --git a/runtime/vm/field_table.h b/runtime/vm/field_table.h
index 8b2f473..84b3b5e 100644
--- a/runtime/vm/field_table.h
+++ b/runtime/vm/field_table.h
@@ -27,7 +27,7 @@
capacity_(0),
free_head_(-1),
table_(nullptr),
- old_tables_(new MallocGrowableArray<InstancePtr*>()),
+ old_tables_(new MallocGrowableArray<ObjectPtr*>()),
isolate_(isolate),
is_ready_to_use_(isolate == nullptr) {}
@@ -39,7 +39,7 @@
intptr_t NumFieldIds() const { return top_; }
intptr_t Capacity() const { return capacity_; }
- InstancePtr* table() { return table_; }
+ ObjectPtr* table() { return table_; }
void FreeOldTables();
@@ -58,11 +58,11 @@
// to an existing static field value.
void Free(intptr_t index);
- InstancePtr At(intptr_t index) const {
+ ObjectPtr At(intptr_t index) const {
ASSERT(IsValidIndex(index));
return table_[index];
}
- void SetAt(intptr_t index, InstancePtr raw_instance);
+ void SetAt(intptr_t index, ObjectPtr raw_instance);
FieldTable* Clone(Isolate* for_isolate);
@@ -86,10 +86,10 @@
// element, last element contains -1.
intptr_t free_head_;
- InstancePtr* table_;
+ ObjectPtr* table_;
// When table_ grows and have to reallocated, keep the old one here
// so it will get freed when its are no longer in use.
- MallocGrowableArray<InstancePtr*>* old_tables_;
+ MallocGrowableArray<ObjectPtr*>* old_tables_;
// If non-NULL, it will specify the isolate this field table belongs to.
// Growing the field table will keep the cached field table on the isolate's
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 183dabc..234a43a 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -910,7 +910,7 @@
#endif // DEBUG
void IsolateGroup::RegisterStaticField(const Field& field,
- const Instance& initial_value) {
+ const Object& initial_value) {
ASSERT(program_lock()->IsCurrentThreadWriter());
ASSERT(field.is_static());
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index fd19306..69dc7bc 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -786,7 +786,7 @@
MutatorThreadPool* thread_pool() { return thread_pool_.get(); }
void RegisterClass(const Class& cls);
- void RegisterStaticField(const Field& field, const Instance& initial_value);
+ void RegisterStaticField(const Field& field, const Object& initial_value);
void FreeStaticField(const Field& field);
static bool AreIsolateGroupsEnabled() {
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 2402951..5be85a1 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -2110,7 +2110,8 @@
: cls_(Class::Handle(zone)),
cls_fields_(Array::Handle(zone)),
entry_(Object::Handle(zone)),
- value_(Instance::Handle(zone)),
+ value_(Object::Handle(zone)),
+ instance_(Instance::Handle(zone)),
type_(AbstractType::Handle(zone)),
cache_(SubtypeTestCache::Handle(zone)),
entries_(Array::Handle(zone)),
@@ -2186,7 +2187,7 @@
if (field.needs_load_guard()) {
return; // Already guarding.
}
- value_ ^= instance.GetField(field);
+ value_ = instance.GetField(field);
if (value_.ptr() == Object::sentinel().ptr()) {
if (field.is_late()) {
// Late fields already have lazy initialization logic.
@@ -2202,8 +2203,9 @@
DART_FORCE_INLINE
void CheckValueType(bool null_safety,
- const Instance& value,
+ const Object& value,
const Field& field) {
+ ASSERT(!value.IsSentinel());
if (!null_safety && value.IsNull()) {
return;
}
@@ -2225,7 +2227,7 @@
} else {
instance_cid_or_signature_ = Smi::New(cid);
if (cls_.NumTypeArguments() > 0) {
- instance_type_arguments_ = value_.GetTypeArguments();
+ instance_type_arguments_ = Instance::Cast(value).GetTypeArguments();
} else {
instance_type_arguments_ = TypeArguments::null();
}
@@ -2270,8 +2272,9 @@
}
if (!cache_hit) {
- if (!value.IsAssignableTo(type_, instantiator_type_arguments_,
- function_type_arguments_)) {
+ instance_ ^= value.ptr();
+ if (!instance_.IsAssignableTo(type_, instantiator_type_arguments_,
+ function_type_arguments_)) {
ASSERT(!FLAG_identity_reload);
field.set_needs_load_guard(true);
} else {
@@ -2287,7 +2290,8 @@
Class& cls_;
Array& cls_fields_;
Object& entry_;
- Instance& value_;
+ Object& value_;
+ Instance& instance_;
AbstractType& type_;
SubtypeTestCache& cache_;
Array& entries_;
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index c9f1b29..7e59984 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -213,7 +213,7 @@
external_name_field_(Field::Handle(Z)),
potential_natives_(GrowableObjectArray::Handle(Z)),
potential_pragma_functions_(GrowableObjectArray::Handle(Z)),
- static_field_value_(Instance::Handle(Z)),
+ static_field_value_(Object::Handle(Z)),
pragma_class_(Class::Handle(Z)),
name_index_handle_(Smi::Handle(Z)),
expression_evaluation_library_(Library::Handle(Z)) {
@@ -483,7 +483,7 @@
external_name_field_(Field::Handle(Z)),
potential_natives_(GrowableObjectArray::Handle(Z)),
potential_pragma_functions_(GrowableObjectArray::Handle(Z)),
- static_field_value_(Instance::Handle(Z)),
+ static_field_value_(Object::Handle(Z)),
pragma_class_(Class::Handle(Z)),
name_index_handle_(Smi::Handle(Z)),
expression_evaluation_library_(Library::Handle(Z)) {
@@ -1628,7 +1628,7 @@
/* is_reflectable = */ false,
/* is_late = */ false, klass, Object::dynamic_type(),
TokenPosition::kNoSource, TokenPosition::kNoSource);
- IG->RegisterStaticField(deleted_enum_sentinel, Instance::Handle());
+ IG->RegisterStaticField(deleted_enum_sentinel, Object::Handle());
fields_.Add(&deleted_enum_sentinel);
}
@@ -2159,9 +2159,9 @@
return script.ptr();
}
-InstancePtr KernelLoader::GenerateFieldAccessors(const Class& klass,
- const Field& field,
- FieldHelper* field_helper) {
+ObjectPtr KernelLoader::GenerateFieldAccessors(const Class& klass,
+ const Field& field,
+ FieldHelper* field_helper) {
const Tag tag = helper_.PeekTag();
const bool has_initializer = (tag == kSomething);
@@ -2255,8 +2255,7 @@
}
// If static, we do need a getter that evaluates the initializer if necessary.
- return field_helper->IsStatic() ? Instance::sentinel().ptr()
- : Instance::null();
+ return field_helper->IsStatic() ? Object::sentinel().ptr() : Object::null();
}
LibraryPtr KernelLoader::LookupLibraryOrNull(NameIndex library) {
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index 91d28c2..cd3dbcb 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -320,9 +320,9 @@
}
// Returns the initial field value for a static function (if applicable).
- InstancePtr GenerateFieldAccessors(const Class& klass,
- const Field& field,
- FieldHelper* field_helper);
+ ObjectPtr GenerateFieldAccessors(const Class& klass,
+ const Field& field,
+ FieldHelper* field_helper);
bool FieldNeedsSetter(FieldHelper* field_helper);
void LoadLibraryImportsAndExports(Library* library,
@@ -403,7 +403,7 @@
Field& external_name_field_;
GrowableObjectArray& potential_natives_;
GrowableObjectArray& potential_pragma_functions_;
- Instance& static_field_value_;
+ Object& static_field_value_;
Class& pragma_class_;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index e153091..fae5e39b 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -167,6 +167,7 @@
ClassPtr Object::exception_handlers_class_ = static_cast<ClassPtr>(RAW_NULL);
ClassPtr Object::context_class_ = static_cast<ClassPtr>(RAW_NULL);
ClassPtr Object::context_scope_class_ = static_cast<ClassPtr>(RAW_NULL);
+ClassPtr Object::sentinel_class_ = static_cast<ClassPtr>(RAW_NULL);
ClassPtr Object::singletargetcache_class_ = static_cast<ClassPtr>(RAW_NULL);
ClassPtr Object::unlinkedcall_class_ = static_cast<ClassPtr>(RAW_NULL);
ClassPtr Object::monomorphicsmiablecall_class_ =
@@ -770,25 +771,20 @@
cls.set_is_declaration_loaded();
cls.set_is_type_finalized();
+ // Allocate and initialize Sentinel class.
+ cls = Class::New<Sentinel, RTN::Sentinel>(isolate_group);
+ sentinel_class_ = cls.ptr();
+
// Allocate and initialize the sentinel values.
{
- *sentinel_ ^=
- Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld,
- Instance::ContainsCompressedPointers());
-
- *transition_sentinel_ ^=
- Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld,
- Instance::ContainsCompressedPointers());
+ *sentinel_ ^= Sentinel::New();
+ *transition_sentinel_ ^= Sentinel::New();
}
// Allocate and initialize optimizing compiler constants.
{
- *unknown_constant_ ^=
- Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld,
- Instance::ContainsCompressedPointers());
- *non_constant_ ^=
- Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld,
- Instance::ContainsCompressedPointers());
+ *unknown_constant_ ^= Sentinel::New();
+ *non_constant_ ^= Sentinel::New();
}
// Allocate the remaining VM internal classes.
@@ -1201,13 +1197,13 @@
ASSERT(!empty_exception_handlers_->IsSmi());
ASSERT(empty_exception_handlers_->IsExceptionHandlers());
ASSERT(!sentinel_->IsSmi());
- ASSERT(sentinel_->IsInstance());
+ ASSERT(sentinel_->IsSentinel());
ASSERT(!transition_sentinel_->IsSmi());
- ASSERT(transition_sentinel_->IsInstance());
+ ASSERT(transition_sentinel_->IsSentinel());
ASSERT(!unknown_constant_->IsSmi());
- ASSERT(unknown_constant_->IsInstance());
+ ASSERT(unknown_constant_->IsSentinel());
ASSERT(!non_constant_->IsSmi());
- ASSERT(non_constant_->IsInstance());
+ ASSERT(non_constant_->IsSentinel());
ASSERT(!bool_true_->IsSmi());
ASSERT(bool_true_->IsBool());
ASSERT(!bool_false_->IsSmi());
@@ -1379,6 +1375,7 @@
SET_CLASS_NAME(exception_handlers, ExceptionHandlers);
SET_CLASS_NAME(context, Context);
SET_CLASS_NAME(context_scope, ContextScope);
+ SET_CLASS_NAME(sentinel, Sentinel);
SET_CLASS_NAME(singletargetcache, SingleTargetCache);
SET_CLASS_NAME(unlinkedcall, UnlinkedCall);
SET_CLASS_NAME(monomorphicsmiablecall, MonomorphicSmiableCall);
@@ -4951,6 +4948,8 @@
return Symbols::Context().ToCString();
case kContextScopeCid:
return Symbols::ContextScope().ToCString();
+ case kSentinelCid:
+ return Symbols::Sentinel().ToCString();
case kSingleTargetCacheCid:
return Symbols::SingleTargetCache().ToCString();
case kICDataCid:
@@ -10828,7 +10827,7 @@
if (!closure_field.IsNull()) {
ASSERT(closure_field.is_static());
const Instance& closure =
- Instance::Handle(zone, closure_field.StaticValue());
+ Instance::Handle(zone, Instance::RawCast(closure_field.StaticValue()));
ASSERT(!closure.IsNull());
ASSERT(closure.IsClosure());
return closure.ptr();
@@ -10924,7 +10923,7 @@
bool Field::IsUninitialized() const {
Thread* thread = Thread::Current();
const FieldTable* field_table = thread->isolate()->field_table();
- const InstancePtr raw_value = field_table->At(field_id());
+ const ObjectPtr raw_value = field_table->At(field_id());
ASSERT(raw_value != Object::transition_sentinel().ptr());
return raw_value == Object::sentinel().ptr();
}
@@ -11287,9 +11286,10 @@
return false; // Not found.
}
-void Field::SetStaticValue(const Instance& value) const {
+void Field::SetStaticValue(const Object& value) const {
auto thread = Thread::Current();
ASSERT(thread->IsMutatorThread());
+ ASSERT(value.IsNull() || value.IsSentinel() || value.IsInstance());
ASSERT(is_static()); // Valid only for static dart fields.
const intptr_t id = field_id();
@@ -17706,6 +17706,25 @@
return prev_cstr;
}
+SentinelPtr Sentinel::New() {
+ return static_cast<SentinelPtr>(
+ Object::Allocate(Sentinel::kClassId, Sentinel::InstanceSize(), Heap::kOld,
+ Sentinel::ContainsCompressedPointers()));
+}
+
+const char* Sentinel::ToCString() const {
+ if (ptr() == Object::sentinel().ptr()) {
+ return "sentinel";
+ } else if (ptr() == Object::transition_sentinel().ptr()) {
+ return "transition_sentinel";
+ } else if (ptr() == Object::unknown_constant().ptr()) {
+ return "unknown_constant";
+ } else if (ptr() == Object::non_constant().ptr()) {
+ return "non_constant";
+ }
+ return "Sentinel(unknown)";
+}
+
ArrayPtr MegamorphicCache::buckets() const {
return untag()->buckets();
}
@@ -18808,13 +18827,15 @@
if (hash != 0) {
return hash;
}
- const Class& cls = Class::Handle(clazz());
+ Zone* zone = thread->zone();
+ const Class& cls = Class::Handle(zone, clazz());
NoSafepointScope no_safepoint(thread);
const intptr_t instance_size = SizeFromClass();
ASSERT(instance_size != 0);
hash = instance_size / kWordSize;
uword this_addr = reinterpret_cast<uword>(this->untag());
- Instance& member = Instance::Handle();
+ Object& obj = Object::Handle(zone);
+ Instance& instance = Instance::Handle(zone);
const auto unboxed_fields_bitmap =
thread->isolate_group()->shared_class_table()->GetUnboxedFieldsMapAt(
@@ -18833,8 +18854,13 @@
*reinterpret_cast<uint32_t*>(this_addr + offset));
}
} else {
- member ^= *reinterpret_cast<ObjectPtr*>(this_addr + offset);
- hash = CombineHashes(hash, member.CanonicalizeHash());
+ obj = *reinterpret_cast<ObjectPtr*>(this_addr + offset);
+ if (obj.IsSentinel()) {
+ hash = CombineHashes(hash, 11);
+ } else {
+ instance ^= obj.ptr();
+ hash = CombineHashes(hash, instance.CanonicalizeHash());
+ }
}
}
hash = FinalizeHash(hash, String::kHashBits);
@@ -19476,14 +19502,6 @@
const char* Instance::ToCString() const {
if (IsNull()) {
return "null";
- } else if (ptr() == Object::sentinel().ptr()) {
- return "sentinel";
- } else if (ptr() == Object::transition_sentinel().ptr()) {
- return "transition_sentinel";
- } else if (ptr() == Object::unknown_constant().ptr()) {
- return "unknown_constant";
- } else if (ptr() == Object::non_constant().ptr()) {
- return "non_constant";
} else if (Thread::Current()->no_safepoint_scope_depth() > 0) {
// Can occur when running disassembler.
return "Instance";
@@ -19943,6 +19961,10 @@
return type_class_id() == kNeverCid;
}
+bool AbstractType::IsSentinelType() const {
+ return type_class_id() == kSentinelCid;
+}
+
bool AbstractType::IsTopTypeForInstanceOf() const {
const classid_t cid = type_class_id();
if (cid == kDynamicCid || cid == kVoidCid) {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 105f60c..898c813 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -453,10 +453,10 @@
V(ExceptionHandlers, empty_exception_handlers) \
V(Array, extractor_parameter_types) \
V(Array, extractor_parameter_names) \
- V(Instance, sentinel) \
- V(Instance, transition_sentinel) \
- V(Instance, unknown_constant) \
- V(Instance, non_constant) \
+ V(Sentinel, sentinel) \
+ V(Sentinel, transition_sentinel) \
+ V(Sentinel, unknown_constant) \
+ V(Sentinel, non_constant) \
V(Bool, bool_true) \
V(Bool, bool_false) \
V(Smi, smi_illegal_cid) \
@@ -521,6 +521,7 @@
static ClassPtr deopt_info_class() { return deopt_info_class_; }
static ClassPtr context_class() { return context_class_; }
static ClassPtr context_scope_class() { return context_scope_class_; }
+ static ClassPtr sentinel_class() { return sentinel_class_; }
static ClassPtr api_error_class() { return api_error_class_; }
static ClassPtr language_error_class() { return language_error_class_; }
static ClassPtr unhandled_exception_class() {
@@ -830,6 +831,7 @@
static ClassPtr deopt_info_class_; // Class of DeoptInfo.
static ClassPtr context_class_; // Class of the Context vm object.
static ClassPtr context_scope_class_; // Class of ContextScope vm object.
+ static ClassPtr sentinel_class_; // Class of Sentinel vm object.
static ClassPtr singletargetcache_class_; // Class of SingleTargetCache.
static ClassPtr unlinkedcall_class_; // Class of UnlinkedCall.
static ClassPtr
@@ -4024,8 +4026,8 @@
void SetStaticConstFieldValue(const Instance& value,
bool assert_initializing_store = true) const;
- inline InstancePtr StaticValue() const;
- void SetStaticValue(const Instance& value) const;
+ inline ObjectPtr StaticValue() const;
+ void SetStaticValue(const Object& value) const;
inline intptr_t field_id() const;
inline void set_field_id(intptr_t field_id) const;
@@ -6870,6 +6872,29 @@
friend class Object;
};
+// Class of special sentinel values:
+// - Object::sentinel() is a value that cannot be produced by Dart code.
+// It can be used to mark special values, for example to distinguish
+// "uninitialized" fields.
+// - Object::transition_sentinel() is a value marking that we are transitioning
+// from sentinel, e.g., computing a field value. Used to detect circular
+// initialization of static fields.
+// - Object::unknown_constant() and Object::non_constant() are optimizing
+// compiler's constant propagation constants.
+class Sentinel : public Object {
+ public:
+ static intptr_t InstanceSize() {
+ return RoundedAllocationSize(sizeof(UntaggedSentinel));
+ }
+
+ static SentinelPtr New();
+
+ private:
+ FINAL_HEAP_OBJECT_IMPLEMENTATION(Sentinel, Object);
+ friend class Class;
+ friend class Object;
+};
+
class MegamorphicCache : public CallSiteData {
public:
static const intptr_t kInitialCapacity = 16;
@@ -8011,6 +8036,9 @@
// Check if this type represents the 'Never' type.
bool IsNeverType() const;
+ // Check if this type represents the 'Sentinel' type.
+ bool IsSentinelType() const;
+
// Check if this type represents the 'Object' type.
bool IsObjectType() const { return type_class_id() == kInstanceCid; }
@@ -11638,7 +11666,7 @@
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
-InstancePtr Field::StaticValue() const {
+ObjectPtr Field::StaticValue() const {
ASSERT(is_static()); // Valid only for static dart fields.
return Isolate::Current()->field_table()->At(field_id());
}
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index 9ee1b59..99b66cd 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -1312,6 +1312,7 @@
case kLinkedHashMapCid:
case kMintCid:
case kNeverCid:
+ case kSentinelCid:
case kNullCid:
case kObjectPoolCid:
case kOneByteStringCid:
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 1c23fa8..3f91520 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -403,7 +403,7 @@
return;
}
if (is_static()) {
- const Instance& valueObj = Instance::Handle(StaticValue());
+ const Object& valueObj = Object::Handle(StaticValue());
jsobj.AddProperty("staticValue", valueObj);
}
@@ -932,6 +932,25 @@
Object::PrintJSONImpl(stream, ref);
}
+void Sentinel::PrintJSONImpl(JSONStream* stream, bool ref) const {
+ // Handle certain special sentinel values.
+ if (ptr() == Object::sentinel().ptr()) {
+ JSONObject jsobj(stream);
+ jsobj.AddProperty("type", "Sentinel");
+ jsobj.AddProperty("kind", "NotInitialized");
+ jsobj.AddProperty("valueAsString", "<not initialized>");
+ return;
+ } else if (ptr() == Object::transition_sentinel().ptr()) {
+ JSONObject jsobj(stream);
+ jsobj.AddProperty("type", "Sentinel");
+ jsobj.AddProperty("kind", "BeingInitialized");
+ jsobj.AddProperty("valueAsString", "<being initialized>");
+ return;
+ }
+
+ Object::PrintJSONImpl(stream, ref);
+}
+
void MegamorphicCache::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
@@ -1075,19 +1094,6 @@
void Instance::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
- // Handle certain special instance values.
- if (ptr() == Object::sentinel().ptr()) {
- jsobj.AddProperty("type", "Sentinel");
- jsobj.AddProperty("kind", "NotInitialized");
- jsobj.AddProperty("valueAsString", "<not initialized>");
- return;
- } else if (ptr() == Object::transition_sentinel().ptr()) {
- jsobj.AddProperty("type", "Sentinel");
- jsobj.AddProperty("kind", "BeingInitialized");
- jsobj.AddProperty("valueAsString", "<being initialized>");
- return;
- }
-
PrintSharedInstanceJSON(&jsobj, ref);
// TODO(regis): Wouldn't it be simpler to provide a Closure::PrintJSONImpl()?
if (IsClosure()) {
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 7afae88..de6a837 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -3035,7 +3035,7 @@
{
SafepointWriteRwLocker locker(thread,
thread->isolate_group()->program_lock());
- thread->isolate_group()->RegisterStaticField(field, Instance::sentinel());
+ thread->isolate_group()->RegisterStaticField(field, Object::sentinel());
}
return field.ptr();
}
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 410779e..5340a96 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -584,6 +584,7 @@
TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *
Smi::Value(raw_obj->untag()->length()))
VARIABLE_COMPRESSED_VISITOR(ContextScope, raw_obj->untag()->num_variables_)
+NULL_VISITOR(Sentinel)
VARIABLE_VISITOR(InstructionsTable, raw_obj->untag()->length_)
NULL_VISITOR(Mint)
NULL_VISITOR(Double)
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 9dafa28..b9f09a5 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -2364,6 +2364,11 @@
friend class SnapshotReader;
};
+class UntaggedSentinel : public UntaggedObject {
+ RAW_HEAP_OBJECT_IMPLEMENTATION(Sentinel);
+ VISIT_NOTHING();
+};
+
class UntaggedSingleTargetCache : public UntaggedObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(SingleTargetCache);
POINTER_FIELD(CodePtr, target)
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index a533e45..3ca81e8 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -600,6 +600,7 @@
MESSAGE_SNAPSHOT_UNREACHABLE(PatchClass);
MESSAGE_SNAPSHOT_UNREACHABLE(PcDescriptors);
MESSAGE_SNAPSHOT_UNREACHABLE(Script);
+MESSAGE_SNAPSHOT_UNREACHABLE(Sentinel);
MESSAGE_SNAPSHOT_UNREACHABLE(SingleTargetCache);
MESSAGE_SNAPSHOT_UNREACHABLE(String);
MESSAGE_SNAPSHOT_UNREACHABLE(SubtypeTestCache);
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index df247e6..533119d 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -227,6 +227,7 @@
V(SavedTryContextVar, ":saved_try_context_var") \
V(Script, "Script") \
V(SecondArg, "y") \
+ V(Sentinel, "Sentinel") \
V(Set, "set") \
V(SetterPrefix, "set:") \
V(SingleTargetCache, "SingleTargetCache") \
diff --git a/runtime/vm/tagged_pointer.h b/runtime/vm/tagged_pointer.h
index 790050c..765af22 100644
--- a/runtime/vm/tagged_pointer.h
+++ b/runtime/vm/tagged_pointer.h
@@ -339,6 +339,7 @@
DEFINE_TAGGED_POINTER(ExceptionHandlers, Object)
DEFINE_TAGGED_POINTER(Context, Object)
DEFINE_TAGGED_POINTER(ContextScope, Object)
+DEFINE_TAGGED_POINTER(Sentinel, Object)
DEFINE_TAGGED_POINTER(SingleTargetCache, Object)
DEFINE_TAGGED_POINTER(UnlinkedCall, Object)
DEFINE_TAGGED_POINTER(MonomorphicSmiableCall, Object)
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index f0cb6c1..a9ff835 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -1043,7 +1043,7 @@
// is important for code size (although code size on X64 is not a priority).
uword saved_stack_limit_;
uword stack_overflow_flags_;
- InstancePtr* field_table_values_;
+ ObjectPtr* field_table_values_;
Heap* heap_;
uword volatile top_exit_frame_info_;
StoreBufferBlock* store_buffer_block_;
@@ -1133,7 +1133,7 @@
intptr_t ffi_marshalled_arguments_size_ = 0;
uint64_t* ffi_marshalled_arguments_;
- InstancePtr* field_table_values() const { return field_table_values_; }
+ ObjectPtr* field_table_values() const { return field_table_values_; }
// Reusable handles support.
#define REUSABLE_HANDLE_FIELDS(object) object* object##_handle_;
diff --git a/tools/VERSION b/tools/VERSION
index 875ad99..7c86e03 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 203
+PRERELEASE 204
PRERELEASE_PATCH 0
\ No newline at end of file