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

Side by Side Diff: runtime/vm/code_generator.cc

Issue 2279563002: AOT: Single target stub. (Closed)
Patch Set: . 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/code_generator.h" 5 #include "vm/code_generator.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 #include "vm/ast.h" 8 #include "vm/ast.h"
9 #include "vm/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 1008 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 StackFrame* caller_frame = iterator.NextFrame(); 1019 StackFrame* caller_frame = iterator.NextFrame();
1020 ASSERT(caller_frame != NULL); 1020 ASSERT(caller_frame != NULL);
1021 OS::PrintErr("StaticCallMissHandler at %#" Px 1021 OS::PrintErr("StaticCallMissHandler at %#" Px
1022 " target %s (%" Pd ", %" Pd ")\n", 1022 " target %s (%" Pd ", %" Pd ")\n",
1023 caller_frame->pc(), target.ToCString(), cids[0], cids[1]); 1023 caller_frame->pc(), target.ToCString(), cids[0], cids[1]);
1024 } 1024 }
1025 arguments.SetReturn(target); 1025 arguments.SetReturn(target);
1026 } 1026 }
1027 1027
1028 1028
1029 #if !defined(TARGET_ARCH_DBC)
1030 static bool IsSingleTarget(Zone* zone,
1031 intptr_t lower_cid,
1032 intptr_t upper_cid,
1033 const Function& target,
1034 const String& name) {
1035 Class& cls = Class::Handle(zone);
1036 ClassTable* table = Isolate::Current()->class_table();
siva 2016/08/30 23:54:53 why not pass the isolate down to this function as
rmacnak 2016/08/31 16:42:57 Done.
1037 Function& other_target = Function::Handle(zone);
1038 for (intptr_t cid = lower_cid; cid <= upper_cid; cid++) {
1039 if (!table->HasValidClassAt(cid)) continue;
1040 cls = table->At(cid);
1041 if (cls.is_abstract()) continue;
1042 if (!cls.is_allocated()) continue;
1043 other_target = Resolver::ResolveDynamicAnyArgs(zone, cls, name,
1044 false /* allow_add */);
1045 if (other_target.raw() != target.raw()) {
1046 return false;
1047 }
1048 }
1049 return true;
1050 }
1051 #endif
1052
1053
1054 // Handle a miss of a single target cache.
1055 // Arg0: Receiver.
1056 // Returns: the ICData used to continue with a polymorphic call.
1057 DEFINE_RUNTIME_ENTRY(SingleTargetMiss, 1) {
1058 #if defined(TARGET_ARCH_DBC)
1059 // DBC does not use switchable calls.
1060 UNREACHABLE();
1061 #else
1062 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
1063
1064 DartFrameIterator iterator;
1065 StackFrame* caller_frame = iterator.NextFrame();
1066 ASSERT(caller_frame->IsDartFrame());
1067 const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
1068 const Function& caller_function =
1069 Function::Handle(zone, caller_frame->LookupDartFunction());
1070
1071 SingleTargetCache& cache = SingleTargetCache::Handle(zone);
1072 cache ^= CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(),
1073 caller_code);
1074 Code& old_target_code = Code::Handle(zone, cache.target());
1075 Function& old_target = Function::Handle(zone);
1076 old_target ^= old_target_code.owner();
1077
1078 // We lost the original ICData when we patched to the monomorphic case.
1079 const String& name = String::Handle(zone, old_target.name());
1080 ASSERT(!old_target.HasOptionalParameters());
1081 const Array& descriptor = Array::Handle(zone,
1082 ArgumentsDescriptor::New(old_target.num_fixed_parameters()));
1083 const ICData& ic_data =
1084 ICData::Handle(zone, ICData::New(caller_function,
1085 name,
1086 descriptor,
1087 Thread::kNoDeoptId,
1088 1, /* args_tested */
1089 false /* static_call */));
1090
1091 // Maybe add the new target.
1092 Class& cls = Class::Handle(zone, receiver.clazz());
1093 ArgumentsDescriptor args_desc(descriptor);
1094 Function& target_function = Function::Handle(zone,
1095 Resolver::ResolveDynamicForReceiverClass(cls,
1096 name,
1097 args_desc));
1098 if (target_function.IsNull()) {
1099 target_function = InlineCacheMissHelper(receiver, descriptor, name);
1100 }
1101 if (target_function.IsNull()) {
1102 ASSERT(!FLAG_lazy_dispatchers);
1103 } else {
1104 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
1105 }
1106
1107 if (old_target.raw() == target_function.raw()) {
1108 intptr_t lower, upper;
1109 if (receiver.GetClassId() < cache.lower_limit()) {
1110 lower = receiver.GetClassId();
1111 upper = cache.upper_limit();
1112 } else {
1113 lower = cache.lower_limit();
1114 upper = receiver.GetClassId();
1115 }
1116
1117 if (IsSingleTarget(zone, lower, upper, target_function, name)) {
1118 cache.set_lower_limit(lower);
1119 cache.set_upper_limit(upper);
1120 // Return the ICData. The single target stub will jump to continue in the
1121 // IC call stub.
1122 arguments.SetReturn(ic_data);
1123 return;
1124 }
1125 }
1126
1127 // Call site is not single target, switch to call using ICData.
1128 const Code& stub =
1129 Code::Handle(zone, StubCode::ICCallThroughCode_entry()->code());
1130 ASSERT(!Isolate::Current()->compilation_allowed());
1131 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(),
1132 caller_code,
1133 ic_data,
1134 stub);
1135
1136 // Return the ICData. The single target stub will jump to continue in the
1137 // IC call stub.
1138 arguments.SetReturn(ic_data);
1139 #endif
1140 }
1141
1142
1029 // Handle a miss of a megamorphic cache. 1143 // Handle a miss of a megamorphic cache.
Florian Schneider 2016/08/30 20:42:34 Comment: s/megamorphic/monomorphic/
rmacnak 2016/08/31 16:42:56 Done.
1030 // Arg0: Receiver. 1144 // Arg0: Receiver.
1031 // Returns: the ICData used to continue with a polymorphic call. 1145 // Returns: the ICData used to continue with a polymorphic call.
1032 DEFINE_RUNTIME_ENTRY(MonomorphicMiss, 1) { 1146 DEFINE_RUNTIME_ENTRY(MonomorphicMiss, 1) {
1033 #if defined(TARGET_ARCH_DBC) 1147 #if defined(TARGET_ARCH_DBC)
1034 // DBC does not use switchable calls. 1148 // DBC does not use switchable calls.
1035 UNREACHABLE(); 1149 UNREACHABLE();
1036 #else 1150 #else
1037 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); 1151 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
1038 1152
1039 DartFrameIterator iterator; 1153 DartFrameIterator iterator;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 args_desc)); 1191 args_desc));
1078 if (target_function.IsNull()) { 1192 if (target_function.IsNull()) {
1079 target_function = InlineCacheMissHelper(receiver, descriptor, name); 1193 target_function = InlineCacheMissHelper(receiver, descriptor, name);
1080 } 1194 }
1081 if (target_function.IsNull()) { 1195 if (target_function.IsNull()) {
1082 ASSERT(!FLAG_lazy_dispatchers); 1196 ASSERT(!FLAG_lazy_dispatchers);
1083 } else { 1197 } else {
1084 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function); 1198 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
1085 } 1199 }
1086 1200
1201 if (old_target.raw() == target_function.raw()) {
1202 intptr_t lower, upper;
1203 if (old_expected_cid.Value() < receiver.GetClassId()) {
1204 lower = old_expected_cid.Value();
1205 upper = receiver.GetClassId();
1206 } else {
1207 lower = receiver.GetClassId();
1208 upper = old_expected_cid.Value();
1209 }
1210
1211 if (IsSingleTarget(zone, lower, upper, target_function, name)) {
1212 const SingleTargetCache& cache =
1213 SingleTargetCache::Handle(SingleTargetCache::New());
1214 const Code& code = Code::Handle(target_function.CurrentCode());
1215 cache.set_target(code);
1216 cache.set_entry_point(code.UncheckedEntryPoint());
1217 cache.set_lower_limit(lower);
1218 cache.set_upper_limit(upper);
1219 const Code& stub = Code::Handle(zone,
1220 StubCode::SingleTargetCall_entry()->code());
1221 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(),
1222 caller_code,
1223 cache,
1224 stub);
1225 // Return the ICData. The miss stub will jump to continue in the IC call
1226 // stub.
1227 arguments.SetReturn(ic_data);
1228 return;
1229 }
1230 }
1231
1087 // Patch to call through stub. 1232 // Patch to call through stub.
1088 const Code& stub = 1233 const Code& stub =
1089 Code::Handle(zone, StubCode::ICCallThroughCode_entry()->code()); 1234 Code::Handle(zone, StubCode::ICCallThroughCode_entry()->code());
1090 ASSERT(!Isolate::Current()->compilation_allowed()); 1235 ASSERT(!Isolate::Current()->compilation_allowed());
1091 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), 1236 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(),
1092 caller_code, 1237 caller_code,
1093 ic_data, 1238 ic_data,
1094 stub); 1239 stub);
1095 1240
1096 // Return the ICData. The miss stub will jump to continue in the IC lookup 1241 // Return the ICData. The miss stub will jump to continue in the IC lookup
(...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after
2070 const intptr_t elm_size = old_data.ElementSizeInBytes(); 2215 const intptr_t elm_size = old_data.ElementSizeInBytes();
2071 const TypedData& new_data = 2216 const TypedData& new_data =
2072 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); 2217 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld));
2073 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); 2218 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size);
2074 typed_data_cell.SetAt(0, new_data); 2219 typed_data_cell.SetAt(0, new_data);
2075 arguments.SetReturn(new_data); 2220 arguments.SetReturn(new_data);
2076 } 2221 }
2077 2222
2078 2223
2079 } // namespace dart 2224 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/assembler_x64.cc ('k') | runtime/vm/object.h » ('j') | runtime/vm/object.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698