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

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

Issue 10933043: Use ICData to collect type feedback on instance setter value. If value is always Smi, insert a smi … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/intermediate_language.h » ('j') | 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/hash_map.h" 10 #include "vm/hash_map.h"
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 return false; 296 return false;
297 } 297 }
298 } 298 }
299 return true; 299 return true;
300 } 300 }
301 301
302 302
303 static intptr_t ReceiverClassId(InstanceCallInstr* call) { 303 static intptr_t ReceiverClassId(InstanceCallInstr* call) {
304 if (!call->HasICData()) return kIllegalCid; 304 if (!call->HasICData()) return kIllegalCid;
305 305
306 const ICData& ic_data = *call->ic_data(); 306 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks());
307 307
308 if (ic_data.NumberOfChecks() == 0) return kIllegalCid; 308 if (ic_data.NumberOfChecks() == 0) return kIllegalCid;
309 // TODO(vegorov): Add multiple receiver type support. 309 // TODO(vegorov): Add multiple receiver type support.
310 if (ic_data.NumberOfChecks() != 1) return kIllegalCid; 310 if (ic_data.NumberOfChecks() != 1) return kIllegalCid;
311 ASSERT(HasOneTarget(ic_data)); 311 ASSERT(HasOneTarget(ic_data));
312 312
313 Function& target = Function::Handle(); 313 Function& target = Function::Handle();
314 intptr_t class_id; 314 intptr_t class_id;
315 ic_data.GetOneClassCheckAt(0, &class_id, &target); 315 ic_data.GetOneClassCheckAt(0, &class_id, &target);
316 return class_id; 316 return class_id;
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 MethodRecognizer::Kind recognized_kind = 803 MethodRecognizer::Kind recognized_kind =
804 MethodRecognizer::RecognizeKind(call->function()); 804 MethodRecognizer::RecognizeKind(call->function());
805 if (recognized_kind == MethodRecognizer::kMathSqrt) { 805 if (recognized_kind == MethodRecognizer::kMathSqrt) {
806 MathSqrtInstr* sqrt = new MathSqrtInstr(call->ArgumentAt(0)->value(), call); 806 MathSqrtInstr* sqrt = new MathSqrtInstr(call->ArgumentAt(0)->value(), call);
807 call->ReplaceWith(sqrt, current_iterator()); 807 call->ReplaceWith(sqrt, current_iterator());
808 RemovePushArguments(call); 808 RemovePushArguments(call);
809 } 809 }
810 } 810 }
811 811
812 812
813 static bool ArgIsAlwaysSmi(const ICData& ic_data, intptr_t arg_n) {
814 ASSERT(ic_data.num_args_tested() > arg_n);
815 if (ic_data.NumberOfChecks() == 0) return false;
816 GrowableArray<intptr_t> class_ids;
817 Function& target = Function::Handle();
818 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
819 ic_data.GetCheckAt(i, &class_ids, &target);
820 if (class_ids[arg_n] != kSmiCid) return false;
821 }
822 return true;
823 }
824
825
813 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr) { 826 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr) {
814 if (FLAG_enable_type_checks) { 827 if (FLAG_enable_type_checks) {
815 // TODO(srdjan): Add assignable check node if --enable_type_checks. 828 // TODO(srdjan): Add assignable check node if --enable_type_checks.
816 return false; 829 return false;
817 } 830 }
818 831
819 ASSERT(instr->HasICData()); 832 ASSERT(instr->HasICData());
820 const ICData& ic_data = *instr->ic_data(); 833 const ICData& unary_ic_data =
821 if (ic_data.NumberOfChecks() == 0) { 834 ICData::Handle(instr->ic_data()->AsUnaryClassChecks());
835 if (unary_ic_data.NumberOfChecks() == 0) {
822 // No type feedback collected. 836 // No type feedback collected.
823 return false; 837 return false;
824 } 838 }
825 if (!HasOneTarget(ic_data)) { 839 if (!HasOneTarget(unary_ic_data)) {
826 // TODO(srdjan): Implement when not all targets are the same. 840 // TODO(srdjan): Implement when not all targets are the same.
827 return false; 841 return false;
828 } 842 }
829 Function& target = Function::Handle(); 843 Function& target = Function::Handle();
830 intptr_t class_id; 844 intptr_t class_id;
831 ic_data.GetOneClassCheckAt(0, &class_id, &target); 845 unary_ic_data.GetOneClassCheckAt(0, &class_id, &target);
832 if (target.kind() != RawFunction::kImplicitSetter) { 846 if (target.kind() != RawFunction::kImplicitSetter) {
833 // Not an implicit setter. 847 // Not an implicit setter.
834 // TODO(srdjan): Inline special setters. 848 // TODO(srdjan): Inline special setters.
835 return false; 849 return false;
836 } 850 }
837 // Inline implicit instance setter. 851 // Inline implicit instance setter.
838 const String& field_name = 852 const String& field_name =
839 String::Handle(Field::NameFromSetter(instr->function_name())); 853 String::Handle(Field::NameFromSetter(instr->function_name()));
840 const Field& field = Field::Handle(GetField(class_id, field_name)); 854 const Field& field = Field::Handle(GetField(class_id, field_name));
841 ASSERT(!field.IsNull()); 855 ASSERT(!field.IsNull());
842 856
843 if (InstanceCallNeedsClassCheck(instr)) { 857 if (InstanceCallNeedsClassCheck(instr)) {
844 AddCheckClass(instr, instr->ArgumentAt(0)->value()->Copy()); 858 AddCheckClass(instr, instr->ArgumentAt(0)->value()->Copy());
845 } 859 }
860 bool needs_store_barrier = true;
861 if (ArgIsAlwaysSmi(*instr->ic_data(), 1)) {
862 InsertBefore(instr,
863 new CheckSmiInstr(instr->ArgumentAt(1)->value()->Copy(),
864 instr->deopt_id()),
865 instr->env(),
866 Definition::kEffect);
867 needs_store_barrier = false;
868 }
846 // Detach environment from the original instruction because it can't 869 // Detach environment from the original instruction because it can't
847 // deoptimize. 870 // deoptimize.
848 instr->set_env(NULL); 871 instr->set_env(NULL);
849 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr( 872 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr(
850 field, 873 field,
851 instr->ArgumentAt(0)->value(), 874 instr->ArgumentAt(0)->value(),
852 instr->ArgumentAt(1)->value()); 875 instr->ArgumentAt(1)->value(),
876 needs_store_barrier);
853 instr->ReplaceWith(store, current_iterator()); 877 instr->ReplaceWith(store, current_iterator());
854 RemovePushArguments(instr); 878 RemovePushArguments(instr);
855 return true; 879 return true;
856 } 880 }
857 881
858 882
859 // TODO(fschneider): Once we get rid of the distinction between Instruction 883 // TODO(fschneider): Once we get rid of the distinction between Instruction
860 // and computation, this helper can go away. 884 // and computation, this helper can go away.
861 static void HandleRelationalOp(FlowGraphOptimizer* optimizer, 885 static void HandleRelationalOp(FlowGraphOptimizer* optimizer,
862 RelationalOpInstr* comp, 886 RelationalOpInstr* comp,
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
1393 DirectChainedHashMap<Definition*> child_map(*map); // Copy map. 1417 DirectChainedHashMap<Definition*> child_map(*map); // Copy map.
1394 OptimizeRecursive(child, &child_map); 1418 OptimizeRecursive(child, &child_map);
1395 } else { 1419 } else {
1396 OptimizeRecursive(child, map); // Reuse map for the last child. 1420 OptimizeRecursive(child, map); // Reuse map for the last child.
1397 } 1421 }
1398 } 1422 }
1399 } 1423 }
1400 1424
1401 1425
1402 } // namespace dart 1426 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698