Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1433)

Unified Diff: runtime/vm/object.cc

Issue 22851003: Initial support for length guards on final fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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());
}

Powered by Google App Engine
This is Rietveld 408576698