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

Unified Diff: runtime/vm/code_generator.cc

Issue 1418863003: Precompilation: Generate instance calls as IC calls that can switch to Megamoprhic calls. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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 | « no previous file | runtime/vm/code_patcher.h » ('j') | runtime/vm/code_patcher_ia32.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/code_generator.cc
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index bc33bca5998156f222e6cc78b0f023b858511200..e7c4225461e45dee005ea8fd4ab38bf8022105b1 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -61,6 +61,7 @@ DEFINE_FLAG(bool, trace_type_checks, false, "Trace runtime type checks.");
DECLARE_FLAG(int, deoptimization_counter_threshold);
DECLARE_FLAG(bool, trace_compiler);
DECLARE_FLAG(bool, warn_on_javascript_compatibility);
+DECLARE_FLAG(int, max_polymorphic_checks);
DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement.");
DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement.");
@@ -779,11 +780,9 @@ static bool ResolveCallThroughGetter(const Instance& receiver,
// Handle other invocations (implicit closures, noSuchMethod).
RawFunction* InlineCacheMissHelper(
const Instance& receiver,
- const ICData& ic_data) {
- const Array& args_descriptor = Array::Handle(ic_data.arguments_descriptor());
-
+ const Array& args_descriptor,
+ const String& target_name) {
const Class& receiver_class = Class::Handle(receiver.clazz());
- const String& target_name = String::Handle(ic_data.target_name());
Function& result = Function::Handle();
if (!ResolveCallThroughGetter(receiver,
@@ -828,7 +827,12 @@ static RawFunction* InlineCacheMissHandler(
String::Handle(ic_data.target_name()).ToCString(),
receiver.ToCString());
}
- target_function = InlineCacheMissHelper(receiver, ic_data);
+ const Array& args_descriptor =
+ Array::Handle(ic_data.arguments_descriptor());
+ const String& target_name = String::Handle(ic_data.target_name());
+ target_function = InlineCacheMissHelper(receiver,
+ args_descriptor,
+ target_name);
}
if (target_function.IsNull()) {
ASSERT(!FLAG_lazy_dispatchers);
@@ -1014,11 +1018,15 @@ DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) {
// Returns: target function to call.
DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) {
const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
- const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
+ const Object& ic_data_or_cache = Object::Handle(arguments.ArgAt(1));
const Array& descriptor = Array::CheckedHandle(arguments.ArgAt(2));
- const String& name = String::Handle(ic_data.target_name());
- const MegamorphicCache& cache = MegamorphicCache::Handle(
- MegamorphicCacheTable::Lookup(isolate, name, descriptor));
+ String& name = String::Handle();
srdjan 2015/11/03 22:30:49 zone is already defined here, please use it for ha
rmacnak 2015/11/03 23:54:29 Done
+ if (ic_data_or_cache.IsICData()) {
+ name = ICData::Cast(ic_data_or_cache).target_name();
+ } else {
+ ASSERT(ic_data_or_cache.IsMegamorphicCache());
+ name = MegamorphicCache::Cast(ic_data_or_cache).target_name();
+ }
Class& cls = Class::Handle(receiver.clazz());
ASSERT(!cls.IsNull());
if (FLAG_trace_ic || FLAG_trace_ic_miss_in_optimized) {
@@ -1032,17 +1040,41 @@ DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) {
name,
args_desc));
if (target_function.IsNull()) {
- target_function = InlineCacheMissHelper(receiver, ic_data);
+ target_function = InlineCacheMissHelper(receiver, descriptor, name);
}
if (target_function.IsNull()) {
ASSERT(!FLAG_lazy_dispatchers);
+ // TODO(rmacnak): Consider inserting null into the cache.
arguments.SetReturn(target_function);
return;
}
- // Insert function found into cache and return it.
- cache.EnsureCapacity();
- const Smi& class_id = Smi::Handle(Smi::New(cls.id()));
- cache.Insert(class_id, target_function);
+
+ if (ic_data_or_cache.IsICData()) {
+ const ICData& ic_data = ICData::Cast(ic_data_or_cache);
+ if (ic_data.NumberOfChecks() == FLAG_max_polymorphic_checks) {
srdjan 2015/11/03 22:30:49 Use '>=', it is more reliable than '=='
rmacnak 2015/11/03 23:54:29 Done.
+ // Switch
+ const MegamorphicCache& cache = MegamorphicCache::Handle(
+ MegamorphicCacheTable::Lookup(isolate, name, descriptor));
+ DartFrameIterator iterator;
+ StackFrame* miss_function_frame = iterator.NextFrame();
+ ASSERT(miss_function_frame->IsDartFrame());
+ StackFrame* caller_frame = iterator.NextFrame();
+ ASSERT(caller_frame->IsDartFrame());
+ const Code& code = Code::Handle(caller_frame->LookupDartCode());
+ const Code& stub =
+ Code::Handle(StubCode::MegamorphicLookup_entry()->code());
+ CodePatcher::PatchSwitchableCallAt(caller_frame->pc(),
+ code, ic_data, cache, stub);
+ } else {
+ ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
+ }
+ } else {
+ const MegamorphicCache& cache = MegamorphicCache::Cast(ic_data_or_cache);
+ // Insert function found into cache and return it.
+ cache.EnsureCapacity();
+ const Smi& class_id = Smi::Handle(Smi::New(cls.id()));
+ cache.Insert(class_id, target_function);
+ }
arguments.SetReturn(target_function);
}
@@ -1055,10 +1087,16 @@ DEFINE_RUNTIME_ENTRY(MegamorphicCacheMissHandler, 3) {
DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethodDispatcher, 4) {
ASSERT(!FLAG_lazy_dispatchers);
const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
- const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
+ const Object& ic_data_or_cache = Object::Handle(arguments.ArgAt(1));
const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(2));
const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(3));
- const String& target_name = String::Handle(ic_data.target_name());
+ String& target_name = String::Handle();
+ if (ic_data_or_cache.IsICData()) {
+ target_name = ICData::Cast(ic_data_or_cache).target_name();
+ } else {
+ ASSERT(ic_data_or_cache.IsMegamorphicCache());
+ target_name = MegamorphicCache::Cast(ic_data_or_cache).target_name();
+ }
Class& cls = Class::Handle(receiver.clazz());
Function& function = Function::Handle();
« no previous file with comments | « no previous file | runtime/vm/code_patcher.h » ('j') | runtime/vm/code_patcher_ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698