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

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

Issue 1207093002: Carefully restructure TryCreatICData and add guessing for getters and setters; helps --noopt a lot (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: x Created 5 years, 5 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 } 160 }
161 161
162 162
163 // TODO(srdjan): Test/support other number types as well. 163 // TODO(srdjan): Test/support other number types as well.
164 static bool IsNumberCid(intptr_t cid) { 164 static bool IsNumberCid(intptr_t cid) {
165 return (cid == kSmiCid) || (cid == kDoubleCid); 165 return (cid == kSmiCid) || (cid == kDoubleCid);
166 } 166 }
167 167
168 168
169 bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) { 169 bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) {
170 // TODO(srdjan): Investigate failures in:
171 // corelib/big_integer_arith_vm_test
172 // dart2js/members_test
173 // language/try_catch_optimized1_test
174 ASSERT(call->HasICData()); 170 ASSERT(call->HasICData());
175 if (call->ic_data()->NumberOfUsedChecks() > 0) { 171 if (call->ic_data()->NumberOfUsedChecks() > 0) {
176 // This occurs when an instance call has too many checks, will be converted 172 // This occurs when an instance call has too many checks, will be converted
177 // to megamorphic call. 173 // to megamorphic call.
178 return false; 174 return false;
179 } 175 }
180 if (FLAG_warn_on_javascript_compatibility) { 176 if (FLAG_warn_on_javascript_compatibility) {
181 // Do not make the instance call megamorphic if the callee needs to decode 177 // Do not make the instance call megamorphic if the callee needs to decode
182 // the calling code sequence to lookup the ic data and verify if a warning 178 // the calling code sequence to lookup the ic data and verify if a warning
183 // has already been issued or not. 179 // has already been issued or not.
(...skipping 23 matching lines...) Expand all
207 const intptr_t cid_0 = class_ids[0]; 203 const intptr_t cid_0 = class_ids[0];
208 const intptr_t cid_1 = class_ids[1]; 204 const intptr_t cid_1 = class_ids[1];
209 if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) { 205 if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) {
210 class_ids[0] = cid_1; 206 class_ids[0] = cid_1;
211 } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) { 207 } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) {
212 class_ids[1] = cid_0; 208 class_ids[1] = cid_0;
213 } 209 }
214 } 210 }
215 } 211 }
216 212
213 bool all_cids_known = true;
217 for (intptr_t i = 0; i < class_ids.length(); i++) { 214 for (intptr_t i = 0; i < class_ids.length(); i++) {
218 if (class_ids[i] == kDynamicCid) { 215 if (class_ids[i] == kDynamicCid) {
219 // Not all cid-s known. 216 // Not all cid-s known.
220 return false; 217 all_cids_known = false;
218 break;
221 } 219 }
222 } 220 }
223 221
224 const Array& args_desc_array = Array::Handle(Z, 222 if (all_cids_known) {
225 ArgumentsDescriptor::New(call->ArgumentCount(), call->argument_names())); 223 const Array& args_desc_array = Array::Handle(Z,
226 ArgumentsDescriptor args_desc(args_desc_array); 224 ArgumentsDescriptor::New(call->ArgumentCount(),
227 const Class& receiver_class = Class::Handle(Z, 225 call->argument_names()));
228 isolate()->class_table()->At(class_ids[0])); 226 ArgumentsDescriptor args_desc(args_desc_array);
229 const Function& function = Function::Handle(Z, 227 const Class& receiver_class = Class::Handle(Z,
230 Resolver::ResolveDynamicForReceiverClass( 228 isolate()->class_table()->At(class_ids[0]));
231 receiver_class, 229 const Function& function = Function::Handle(Z,
232 call->function_name(), 230 Resolver::ResolveDynamicForReceiverClass(
233 args_desc)); 231 receiver_class,
234 if (function.IsNull()) { 232 call->function_name(),
235 return false; 233 args_desc));
234 if (function.IsNull()) {
235 return false;
236 }
237
238 // Create new ICData, do not modify the one attached to the instruction
239 // since it is attached to the assembly instruction itself.
240 // TODO(srdjan): Prevent modification of ICData object that is
241 // referenced in assembly code.
242 const ICData& ic_data = ICData::ZoneHandle(Z,
243 ICData::NewFrom(*call->ic_data(), class_ids.length()));
244 if (class_ids.length() > 1) {
245 ic_data.AddCheck(class_ids, function);
246 } else {
247 ASSERT(class_ids.length() == 1);
248 ic_data.AddReceiverCheck(class_ids[0], function);
249 }
250 call->set_ic_data(&ic_data);
251 return true;
236 } 252 }
237 // Create new ICData, do not modify the one attached to the instruction 253
238 // since it is attached to the assembly instruction itself. 254 // Check if getter or setter in function's class and class is currently leaf.
239 // TODO(srdjan): Prevent modification of ICData object that is 255 if ((call->token_kind() == Token::kGET) ||
240 // referenced in assembly code. 256 (call->token_kind() == Token::kSET)) {
241 ICData& ic_data = ICData::ZoneHandle(Z, ICData::New( 257 const Class& owner_class = Class::Handle(Z, function().Owner());
242 flow_graph_->function(), 258 if (!owner_class.is_abstract() &&
243 call->function_name(), 259 !CHA::HasSubclasses(owner_class) &&
244 args_desc_array, 260 !CHA::IsImplemented(owner_class)) {
245 call->deopt_id(), 261 const Array& args_desc_array = Array::Handle(Z,
246 class_ids.length())); 262 ArgumentsDescriptor::New(call->ArgumentCount(),
247 if (class_ids.length() > 1) { 263 call->argument_names()));
248 ic_data.AddCheck(class_ids, function); 264 ArgumentsDescriptor args_desc(args_desc_array);
249 } else { 265 const Function& function = Function::Handle(Z,
250 ASSERT(class_ids.length() == 1); 266 Resolver::ResolveDynamicForReceiverClass(owner_class,
251 ic_data.AddReceiverCheck(class_ids[0], function); 267 call->function_name(),
268 args_desc));
269 if (!function.IsNull()) {
Cutch 2015/06/24 22:17:18 to match the style above: if (function.IsNull())
srdjan 2015/06/24 22:29:26 Done.
270 const ICData& ic_data = ICData::ZoneHandle(Z,
271 ICData::NewFrom(*call->ic_data(), class_ids.length()));
272 ic_data.AddReceiverCheck(owner_class.id(), function);
273 call->set_ic_data(&ic_data);
274 return true;
275 }
276 }
252 } 277 }
253 call->set_ic_data(&ic_data); 278
254 return true; 279 return false;
255 } 280 }
256 281
257 282
258 const ICData& FlowGraphOptimizer::TrySpecializeICData(const ICData& ic_data, 283 const ICData& FlowGraphOptimizer::TrySpecializeICData(const ICData& ic_data,
259 intptr_t cid) { 284 intptr_t cid) {
260 ASSERT(ic_data.NumArgsTested() == 1); 285 ASSERT(ic_data.NumArgsTested() == 1);
261 286
262 if ((ic_data.NumberOfUsedChecks() == 1) && ic_data.HasReceiverClassId(cid)) { 287 if ((ic_data.NumberOfUsedChecks() == 1) && ic_data.HasReceiverClassId(cid)) {
263 return ic_data; // Nothing to do 288 return ic_data; // Nothing to do
264 } 289 }
(...skipping 8444 matching lines...) Expand 10 before | Expand all | Expand 10 after
8709 8734
8710 // Insert materializations at environment uses. 8735 // Insert materializations at environment uses.
8711 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 8736 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
8712 CreateMaterializationAt( 8737 CreateMaterializationAt(
8713 exits_collector_.exits()[i], alloc, *slots); 8738 exits_collector_.exits()[i], alloc, *slots);
8714 } 8739 }
8715 } 8740 }
8716 8741
8717 8742
8718 } // namespace dart 8743 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698