| Index: runtime/vm/object.cc
|
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
|
| index 770559879a4ecfe123d18cb807db308b7ee06ade..766b816851780f7a02f9053e1b43dd3536d3fbfc 100644
|
| --- a/runtime/vm/object.cc
|
| +++ b/runtime/vm/object.cc
|
| @@ -59,6 +59,8 @@ DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false,
|
| DECLARE_FLAG(bool, trace_compiler);
|
| DECLARE_FLAG(bool, eliminate_type_checks);
|
| DECLARE_FLAG(bool, enable_type_checks);
|
| +DECLARE_FLAG(bool, trace_deoptimization);
|
| +DECLARE_FLAG(bool, trace_deoptimization_verbose);
|
| DECLARE_FLAG(bool, error_on_bad_override);
|
|
|
| static const char* kGetterPrefix = "get:";
|
| @@ -5306,6 +5308,7 @@ RawField* Field::New(const String& name,
|
| result.set_has_initializer(false);
|
| result.set_guarded_cid(kIllegalCid);
|
| result.set_is_nullable(false);
|
| + result.set_guarded_list_length(Field::kUnknownLength);
|
| result.set_dependent_code(Object::null_array());
|
| return result.raw();
|
| }
|
| @@ -5429,6 +5432,12 @@ void Field::DeoptimizeDependentCode() const {
|
| while (frame != NULL) {
|
| code = frame->LookupDartCode();
|
| if (IsDependentCode(code_objects, code)) {
|
| + if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
|
| + Function& function = Function::Handle(code.function());
|
| + OS::PrintErr("Deoptimizing %s because guard on field %s failed.\n",
|
| + function.ToFullyQualifiedCString(),
|
| + ToCString());
|
| + }
|
| DeoptimizeAt(code, frame->pc());
|
| }
|
| frame = iterator.NextFrame();
|
| @@ -5450,6 +5459,12 @@ void Field::DeoptimizeDependentCode() const {
|
| // If function uses dependent code switch it to unoptimized.
|
| if (function.CurrentCode() == code.raw()) {
|
| ASSERT(function.HasOptimizedCode());
|
| + if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
|
| + OS::PrintErr("Switching %s to unoptimized code because guard"
|
| + " on field %s was violated.\n",
|
| + function.ToFullyQualifiedCString(),
|
| + ToCString());
|
| + }
|
| function.SwitchToUnoptimizedCode();
|
| }
|
| }
|
| @@ -5489,6 +5504,35 @@ void Field::UpdateCid(intptr_t cid) const {
|
| }
|
|
|
|
|
| +void Field::UpdateLength(intptr_t list_length) const {
|
| + ASSERT(is_final() || (!is_final() && (list_length < Field::kUnknownLength)));
|
| + ASSERT((list_length == Field::kNoLength) ||
|
| + (list_length > Field::kUnknownLength));
|
| + ASSERT(guarded_cid() != kIllegalCid);
|
| +
|
| + const bool force_invalidate = guarded_cid() == kDynamicCid;
|
| +
|
| + const bool list_length_unknown =
|
| + (guarded_list_length() == Field::kUnknownLength);
|
| + const bool list_length_changed = (guarded_list_length() != list_length);
|
| +
|
| + if (list_length_unknown && list_length_changed && !force_invalidate) {
|
| + // List length set for first time.
|
| + set_guarded_list_length(list_length);
|
| + return;
|
| + }
|
| +
|
| + if (!list_length_changed && !force_invalidate) {
|
| + // List length unchanged.
|
| + return;
|
| + }
|
| +
|
| + // Multiple list lengths assigned here, stop tracking length.
|
| + set_guarded_list_length(Field::kNoLength);
|
| + DeoptimizeDependentCode();
|
| +}
|
| +
|
| +
|
| void LiteralToken::set_literal(const String& literal) const {
|
| StorePointer(&raw_ptr()->literal_, literal.raw());
|
| }
|
|
|