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

Unified Diff: runtime/vm/precompiler.cc

Issue 2314133003: AOT: Use a cid range check when possible to implement type tests. (Closed)
Patch Set: symbols Created 4 years, 3 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
« no previous file with comments | « runtime/vm/precompiler.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/precompiler.cc
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 7579680c7f5a3185facd5268bb27924c24bc9981..985617c748d2e4d2b92f757873b2d1a40586703a 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -201,6 +201,92 @@ RawError* Precompiler::CompileAll(
}
+bool TypeRangeCache::InstanceOfHasClassRange(const AbstractType& type,
+ intptr_t* lower_limit,
+ intptr_t* upper_limit) {
+ ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
+
+ if (!type.IsInstantiated()) return false;
+ if (type.IsFunctionType()) return false;
+
+ Zone* zone = thread_->zone();
+ const TypeArguments& type_arguments =
+ TypeArguments::Handle(zone, type.arguments());
+ if (!type_arguments.IsNull() &&
+ !type_arguments.IsRaw(0, type_arguments.Length())) return false;
+
+
+ intptr_t type_cid = type.type_class_id();
+ if (lower_limits_[type_cid] == kNotContiguous) return false;
+ if (lower_limits_[type_cid] != kNotComputed) {
+ *lower_limit = lower_limits_[type_cid];
+ *upper_limit = upper_limits_[type_cid];
+ return true;
+ }
+
+
+ *lower_limit = -1;
+ *upper_limit = -1;
+ intptr_t last_matching_cid = -1;
+
+ ClassTable* table = thread_->isolate()->class_table();
+ Class& cls = Class::Handle(zone);
+ AbstractType& cls_type = AbstractType::Handle(zone);
+ for (intptr_t cid = kInstanceCid; cid < table->NumCids(); cid++) {
+ if (!table->HasValidClassAt(cid)) continue;
+ if (cid == kVoidCid) continue;
+ if (cid == kDynamicCid) continue;
+ cls = table->At(cid);
+ if (cls.is_abstract()) continue;
+ if (cls.is_patch()) continue;
+ if (cls.IsTopLevel()) continue;
+
+ cls_type = cls.RareType();
+ if (cls_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) {
+ last_matching_cid = cid;
+ if (*lower_limit == -1) {
+ // Found beginning of range.
+ *lower_limit = cid;
+ } else if (*upper_limit == -1) {
+ // Expanding range.
+ } else {
+ // Found a second range.
+ lower_limits_[type_cid] = kNotContiguous;
+ return false;
+ }
+ } else {
+ if (*lower_limit == -1) {
+ // Still before range.
+ } else if (*upper_limit == -1) {
+ // Found end of range.
+ *upper_limit = last_matching_cid;
+ } else {
+ // After range.
+ }
+ }
+ }
+ if (*lower_limit == -1) {
+ // Not implemented by any concrete class.
+ *lower_limit = kIllegalCid;
+ *upper_limit = kIllegalCid;
+ }
+
+ if (*upper_limit == -1) {
+ ASSERT(last_matching_cid != -1);
+ *upper_limit = last_matching_cid;
+ }
+
+ if (FLAG_trace_precompiler) {
+ THR_Print("Type check for %s is cid range [%" Pd ", %" Pd "]\n",
+ type.ToCString(), *lower_limit, *upper_limit);
+ }
+
+ lower_limits_[type_cid] = *lower_limit;
+ upper_limits_[type_cid] = *upper_limit;
+ return true;
+}
+
+
Precompiler::Precompiler(Thread* thread, bool reset_fields) :
thread_(thread),
zone_(NULL),
@@ -247,6 +333,7 @@ void Precompiler::DoCompileAll(
FinalizeAllClasses();
SortClasses();
+ TypeRangeCache trc(T, I->class_table()->NumCids());
// Precompile static initializers to compute result type information.
PrecompileStaticInitializers();
@@ -2587,7 +2674,7 @@ bool PrecompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
if (val == 0) {
FlowGraph* flow_graph = NULL;
- // Class hierarchy analysis is registered with the isolate in the
+ // Class hierarchy analysis is registered with the thread in the
// constructor and unregisters itself upon destruction.
CHA cha(thread());
« no previous file with comments | « runtime/vm/precompiler.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698