OLD | NEW |
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 1123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 ic_data, | 1134 ic_data, |
1135 stub); | 1135 stub); |
1136 | 1136 |
1137 // Return the ICData. The single target stub will jump to continue in the | 1137 // Return the ICData. The single target stub will jump to continue in the |
1138 // IC call stub. | 1138 // IC call stub. |
1139 arguments.SetReturn(ic_data); | 1139 arguments.SetReturn(ic_data); |
1140 #endif | 1140 #endif |
1141 } | 1141 } |
1142 | 1142 |
1143 | 1143 |
| 1144 DEFINE_RUNTIME_ENTRY(UnlinkedCall, 2) { |
| 1145 #if defined(TARGET_ARCH_DBC) |
| 1146 // DBC does not use switchable calls. |
| 1147 UNREACHABLE(); |
| 1148 #else |
| 1149 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); |
| 1150 const UnlinkedCall& unlinked = |
| 1151 UnlinkedCall::CheckedHandle(zone, arguments.ArgAt(1)); |
| 1152 |
| 1153 DartFrameIterator iterator; |
| 1154 StackFrame* caller_frame = iterator.NextFrame(); |
| 1155 ASSERT(caller_frame->IsDartFrame()); |
| 1156 const Code& caller_code = |
| 1157 Code::Handle(zone, caller_frame->LookupDartCode()); |
| 1158 const Function& caller_function = |
| 1159 Function::Handle(zone, caller_frame->LookupDartFunction()); |
| 1160 |
| 1161 // We lost the original ICData when we patched to the monomorphic case. |
| 1162 const String& name = String::Handle(zone, unlinked.target_name()); |
| 1163 const Array& descriptor = Array::Handle(zone, unlinked.args_descriptor()); |
| 1164 const ICData& ic_data = |
| 1165 ICData::Handle(zone, ICData::New(caller_function, |
| 1166 name, |
| 1167 descriptor, |
| 1168 Thread::kNoDeoptId, |
| 1169 1, /* args_tested */ |
| 1170 false /* static_call */)); |
| 1171 |
| 1172 // Maybe add the new target. |
| 1173 Class& cls = Class::Handle(zone, receiver.clazz()); |
| 1174 ArgumentsDescriptor args_desc(descriptor); |
| 1175 Function& target_function = Function::Handle(zone, |
| 1176 Resolver::ResolveDynamicForReceiverClass(cls, |
| 1177 name, |
| 1178 args_desc)); |
| 1179 if (target_function.IsNull()) { |
| 1180 target_function = InlineCacheMissHelper(receiver, descriptor, name); |
| 1181 } |
| 1182 if (target_function.IsNull()) { |
| 1183 ASSERT(!FLAG_lazy_dispatchers); |
| 1184 } else { |
| 1185 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function); |
| 1186 } |
| 1187 |
| 1188 if (!target_function.IsNull() && |
| 1189 !target_function.HasOptionalParameters()) { |
| 1190 if (!target_function.HasCode()) { |
| 1191 const Error& error = |
| 1192 Error::Handle(Compiler::CompileFunction(thread, target_function)); |
| 1193 if (!error.IsNull()) { |
| 1194 Exceptions::PropagateError(error); |
| 1195 } |
| 1196 } |
| 1197 |
| 1198 const Code& target_code = |
| 1199 Code::Handle(zone, target_function.CurrentCode()); |
| 1200 const Smi& expected_cid = |
| 1201 Smi::Handle(zone, Smi::New(receiver.GetClassId())); |
| 1202 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, |
| 1203 expected_cid, target_code); |
| 1204 // Return the ICData. The miss stub will jump to continue in the IC call |
| 1205 // stub. |
| 1206 arguments.SetReturn(ic_data); |
| 1207 return; |
| 1208 } |
| 1209 |
| 1210 // Patch to call through stub. |
| 1211 const Code& stub = |
| 1212 Code::Handle(zone, StubCode::ICCallThroughCode_entry()->code()); |
| 1213 ASSERT(!Isolate::Current()->compilation_allowed()); |
| 1214 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), |
| 1215 caller_code, |
| 1216 ic_data, |
| 1217 stub); |
| 1218 |
| 1219 // Return the ICData. The miss stub will jump to continue in the IC lookup |
| 1220 // stub. |
| 1221 arguments.SetReturn(ic_data); |
| 1222 #endif // !DBC |
| 1223 } |
| 1224 |
| 1225 |
1144 // Handle a miss of a megamorphic cache. | 1226 // Handle a miss of a megamorphic cache. |
1145 // Arg0: Receiver. | 1227 // Arg0: Receiver. |
1146 // Returns: the ICData used to continue with a polymorphic call. | 1228 // Returns: the ICData used to continue with a polymorphic call. |
1147 DEFINE_RUNTIME_ENTRY(MonomorphicMiss, 1) { | 1229 DEFINE_RUNTIME_ENTRY(MonomorphicMiss, 1) { |
1148 #if defined(TARGET_ARCH_DBC) | 1230 #if defined(TARGET_ARCH_DBC) |
1149 // DBC does not use switchable calls. | 1231 // DBC does not use switchable calls. |
1150 UNREACHABLE(); | 1232 UNREACHABLE(); |
1151 #else | 1233 #else |
1152 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); | 1234 const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); |
1153 | 1235 |
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2216 const intptr_t elm_size = old_data.ElementSizeInBytes(); | 2298 const intptr_t elm_size = old_data.ElementSizeInBytes(); |
2217 const TypedData& new_data = | 2299 const TypedData& new_data = |
2218 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); | 2300 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); |
2219 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); | 2301 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); |
2220 typed_data_cell.SetAt(0, new_data); | 2302 typed_data_cell.SetAt(0, new_data); |
2221 arguments.SetReturn(new_data); | 2303 arguments.SetReturn(new_data); |
2222 } | 2304 } |
2223 | 2305 |
2224 | 2306 |
2225 } // namespace dart | 2307 } // namespace dart |
OLD | NEW |