Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/flow_graph_compiler.h" | 9 #include "vm/flow_graph_compiler.h" |
| 10 #include "vm/locations.h" | 10 #include "vm/locations.h" |
| 11 #include "vm/object.h" | 11 #include "vm/object.h" |
| 12 #include "vm/os.h" | 12 #include "vm/os.h" |
| 13 #include "vm/scopes.h" | 13 #include "vm/scopes.h" |
| 14 #include "vm/stub_code.h" | 14 #include "vm/stub_code.h" |
| 15 | 15 |
| 16 namespace dart { | 16 namespace dart { |
| 17 | 17 |
| 18 MethodRecognizer::Kind MethodRecognizer::RecognizeKind( | |
| 19 const Function& function) { | |
| 20 // Only core library methods can be recognized. | |
| 21 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | |
| 22 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); | |
| 23 const Class& function_class = Class::Handle(function.owner()); | |
| 24 if ((function_class.library() != core_lib.raw()) && | |
| 25 (function_class.library() != core_impl_lib.raw())) { | |
| 26 return kUnknown; | |
| 27 } | |
| 28 const String& recognize_name = String::Handle(function.name()); | |
| 29 const String& recognize_class = String::Handle(function_class.Name()); | |
| 30 String& test_function_name = String::Handle(); | |
| 31 String& test_class_name = String::Handle(); | |
| 32 #define RECOGNIZE_FUNCTION(class_name, function_name, enum_name) \ | |
| 33 test_function_name = String::NewSymbol(#function_name); \ | |
| 34 test_class_name = String::NewSymbol(#class_name); \ | |
| 35 if (recognize_name.Equals(test_function_name) && \ | |
| 36 recognize_class.Equals(test_class_name)) { \ | |
| 37 return k##enum_name; \ | |
| 38 } | |
| 39 RECOGNIZED_LIST(RECOGNIZE_FUNCTION) | |
| 40 #undef RECOGNIZE_FUNCTION | |
| 41 return kUnknown; | |
| 42 } | |
| 43 | |
| 44 | |
| 45 const char* MethodRecognizer::KindToCString(Kind kind) { | |
| 46 #define KIND_TO_STRING(class_name, function_name, enum_name) \ | |
| 47 if (kind == k##enum_name) return #enum_name; | |
| 48 RECOGNIZED_LIST(KIND_TO_STRING) | |
| 49 #undef KIND_TO_STRING | |
| 50 return "?"; | |
| 51 } | |
| 52 | |
| 53 | |
| 18 // ==== Support for visiting flow graphs. | 54 // ==== Support for visiting flow graphs. |
| 19 #define DEFINE_ACCEPT(ShortName, ClassName) \ | 55 #define DEFINE_ACCEPT(ShortName, ClassName) \ |
| 20 void ClassName::Accept(FlowGraphVisitor* visitor) { \ | 56 void ClassName::Accept(FlowGraphVisitor* visitor) { \ |
| 21 visitor->Visit##ShortName(this); \ | 57 visitor->Visit##ShortName(this); \ |
| 22 } | 58 } |
| 23 | 59 |
| 24 FOR_EACH_COMPUTATION(DEFINE_ACCEPT) | 60 FOR_EACH_COMPUTATION(DEFINE_ACCEPT) |
| 25 | 61 |
| 26 #undef DEFINE_ACCEPT | 62 #undef DEFINE_ACCEPT |
| 27 | 63 |
| 28 | 64 |
| 29 #define DEFINE_ACCEPT(ShortName) \ | 65 #define DEFINE_ACCEPT(ShortName) \ |
| 30 Instruction* ShortName##Instr::Accept(FlowGraphVisitor* visitor) { \ | 66 Instruction* ShortName##Instr::Accept(FlowGraphVisitor* visitor) { \ |
| 31 visitor->Visit##ShortName(this); \ | 67 visitor->Visit##ShortName(this); \ |
| 32 return StraightLineSuccessor(); \ | 68 return StraightLineSuccessor(); \ |
| 33 } | 69 } |
| 34 | 70 |
| 35 FOR_EACH_INSTRUCTION(DEFINE_ACCEPT) | 71 FOR_EACH_INSTRUCTION(DEFINE_ACCEPT) |
| 36 | 72 |
| 37 #undef DEFINE_ACCEPT | 73 #undef DEFINE_ACCEPT |
| 38 | 74 |
| 39 | 75 |
| 40 // Truee iff. the v2 is above v1 on stack, or one of them is constant. | 76 // True iff. the v2 is above v1 on stack, or one of them is constant. |
| 41 static bool VerifyValues(Value* v1, Value* v2) { | 77 static bool VerifyValues(Value* v1, Value* v2) { |
| 42 ASSERT(v1->IsUse() && v2->IsUse()); | 78 ASSERT(v1->IsUse() && v2->IsUse()); |
| 43 return (v1->AsUse()->definition()->temp_index() + 1) == | 79 return (v1->AsUse()->definition()->temp_index() + 1) == |
| 44 v2->AsUse()->definition()->temp_index(); | 80 v2->AsUse()->definition()->temp_index(); |
| 45 } | 81 } |
| 46 | 82 |
| 47 | 83 |
| 48 // Default implementation of visiting basic blocks. Can be overridden. | 84 // Default implementation of visiting basic blocks. Can be overridden. |
| 49 void FlowGraphVisitor::VisitBlocks() { | 85 void FlowGraphVisitor::VisitBlocks() { |
| 50 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 86 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| (...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 998 } | 1034 } |
| 999 | 1035 |
| 1000 | 1036 |
| 1001 LocationSummary* StaticCallComp::MakeLocationSummary() const { | 1037 LocationSummary* StaticCallComp::MakeLocationSummary() const { |
| 1002 return MakeCallSummary(); | 1038 return MakeCallSummary(); |
| 1003 } | 1039 } |
| 1004 | 1040 |
| 1005 | 1041 |
| 1006 void StaticCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1042 void StaticCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1007 ASSERT(VerifyCallComputation(this)); | 1043 ASSERT(VerifyCallComputation(this)); |
| 1044 Label done; | |
| 1045 if (recognized() == MethodRecognizer::kMathSqrt) { | |
| 1046 compiler->GenerateInlinedMathSqrt(&done); | |
|
srdjan
2012/06/14 23:30:08
Add comment that it fall throughs to static call.
regis
2012/06/15 00:33:59
Done.
| |
| 1047 } | |
| 1008 compiler->GenerateStaticCall(cid(), | 1048 compiler->GenerateStaticCall(cid(), |
| 1009 token_index(), | 1049 token_index(), |
| 1010 try_index(), | 1050 try_index(), |
| 1011 function(), | 1051 function(), |
| 1012 ArgumentCount(), | 1052 ArgumentCount(), |
| 1013 argument_names()); | 1053 argument_names()); |
| 1054 __ Bind(&done); | |
| 1014 } | 1055 } |
| 1015 | 1056 |
| 1016 | 1057 |
| 1017 LocationSummary* UseVal::MakeLocationSummary() const { | 1058 LocationSummary* UseVal::MakeLocationSummary() const { |
| 1018 return NULL; | 1059 return NULL; |
| 1019 } | 1060 } |
| 1020 | 1061 |
| 1021 | 1062 |
| 1022 void UseVal::EmitNativeCode(FlowGraphCompiler* compiler) { | 1063 void UseVal::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1023 UNIMPLEMENTED(); | 1064 UNIMPLEMENTED(); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1137 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 1178 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
| 1138 compiler->GenerateCall(token_index(), try_index(), &label, | 1179 compiler->GenerateCall(token_index(), try_index(), &label, |
| 1139 PcDescriptors::kOther); | 1180 PcDescriptors::kOther); |
| 1140 __ Drop(2); // Discard type arguments and receiver. | 1181 __ Drop(2); // Discard type arguments and receiver. |
| 1141 } | 1182 } |
| 1142 | 1183 |
| 1143 | 1184 |
| 1144 #undef __ | 1185 #undef __ |
| 1145 | 1186 |
| 1146 } // namespace dart | 1187 } // namespace dart |
| OLD | NEW |