Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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/precompiler.h" | 5 #include "vm/precompiler.h" |
| 6 | 6 |
| 7 #include "vm/aot_optimizer.h" | 7 #include "vm/aot_optimizer.h" |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
| 10 #include "vm/branch_optimizer.h" | 10 #include "vm/branch_optimizer.h" |
| (...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 823 target ^= entry.raw(); | 823 target ^= entry.raw(); |
| 824 AddFunction(target); | 824 AddFunction(target); |
| 825 } | 825 } |
| 826 } | 826 } |
| 827 | 827 |
| 828 #if defined(TARGET_ARCH_IA32) | 828 #if defined(TARGET_ARCH_IA32) |
| 829 FATAL("Callee scanning unimplemented for IA32"); | 829 FATAL("Callee scanning unimplemented for IA32"); |
| 830 #endif | 830 #endif |
| 831 | 831 |
| 832 const ObjectPool& pool = ObjectPool::Handle(Z, code.GetObjectPool()); | 832 const ObjectPool& pool = ObjectPool::Handle(Z, code.GetObjectPool()); |
| 833 ObjectPoolInfo pool_info(pool); | |
| 833 ICData& call_site = ICData::Handle(Z); | 834 ICData& call_site = ICData::Handle(Z); |
| 834 MegamorphicCache& cache = MegamorphicCache::Handle(Z); | 835 MegamorphicCache& cache = MegamorphicCache::Handle(Z); |
| 835 String& selector = String::Handle(Z); | 836 String& selector = String::Handle(Z); |
| 836 Field& field = Field::Handle(Z); | 837 Field& field = Field::Handle(Z); |
| 837 Class& cls = Class::Handle(Z); | 838 Class& cls = Class::Handle(Z); |
| 838 Instance& instance = Instance::Handle(Z); | 839 Instance& instance = Instance::Handle(Z); |
| 839 Code& target_code = Code::Handle(Z); | 840 Code& target_code = Code::Handle(Z); |
| 840 for (intptr_t i = 0; i < pool.Length(); i++) { | 841 for (intptr_t i = 0; i < pool.Length(); i++) { |
| 841 if (pool.InfoAt(i) == ObjectPool::kTaggedObject) { | 842 if (pool_info.InfoAt(i) == ObjectPool::kTaggedObject) { |
|
kustermann
2016/12/08 13:52:44
This moves the handle allocation out of the loop.
| |
| 842 entry = pool.ObjectAt(i); | 843 entry = pool.ObjectAt(i); |
| 843 if (entry.IsICData()) { | 844 if (entry.IsICData()) { |
| 844 // A dynamic call. | 845 // A dynamic call. |
| 845 call_site ^= entry.raw(); | 846 call_site ^= entry.raw(); |
| 846 ASSERT(!call_site.is_static_call()); | 847 ASSERT(!call_site.is_static_call()); |
| 847 selector = call_site.target_name(); | 848 selector = call_site.target_name(); |
| 848 AddSelector(selector); | 849 AddSelector(selector); |
| 849 if (selector.raw() == Symbols::Call().raw()) { | 850 if (selector.raw() == Symbols::Call().raw()) { |
| 850 // Potential closure call. | 851 // Potential closure call. |
| 851 const Array& arguments_descriptor = | 852 const Array& arguments_descriptor = |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1025 return; | 1026 return; |
| 1026 } | 1027 } |
| 1027 | 1028 |
| 1028 // Can't ask immediate objects if they're canoncial. | 1029 // Can't ask immediate objects if they're canoncial. |
| 1029 if (instance.IsSmi()) return; | 1030 if (instance.IsSmi()) return; |
| 1030 | 1031 |
| 1031 // Some Instances in the ObjectPool aren't const objects, such as | 1032 // Some Instances in the ObjectPool aren't const objects, such as |
| 1032 // argument descriptors. | 1033 // argument descriptors. |
| 1033 if (!instance.IsCanonical()) return; | 1034 if (!instance.IsCanonical()) return; |
| 1034 | 1035 |
| 1036 // Constants are canonicalized and we avoid repeated processing of them. | |
| 1037 if (consts_to_retain_.Lookup(&instance) != NULL) return; | |
| 1038 | |
| 1035 consts_to_retain_.Insert(&Instance::ZoneHandle(Z, instance.raw())); | 1039 consts_to_retain_.Insert(&Instance::ZoneHandle(Z, instance.raw())); |
|
kustermann
2016/12/08 13:52:44
Please note that
consts_to_retain_.Insert()
ca
Vyacheslav Egorov (Google)
2016/12/08 18:18:19
What about adding an ASSERT there?
kustermann
2016/12/08 19:14:38
If it's fine with you, I'll do it in a different C
| |
| 1036 | 1040 |
| 1037 if (cls.NumTypeArguments() > 0) { | 1041 if (cls.NumTypeArguments() > 0) { |
| 1038 AddTypeArguments(TypeArguments::Handle(Z, instance.GetTypeArguments())); | 1042 AddTypeArguments(TypeArguments::Handle(Z, instance.GetTypeArguments())); |
| 1039 } | 1043 } |
| 1040 | 1044 |
| 1041 class ConstObjectVisitor : public ObjectPointerVisitor { | 1045 class ConstObjectVisitor : public ObjectPointerVisitor { |
| 1042 public: | 1046 public: |
| 1043 ConstObjectVisitor(Precompiler* precompiler, Isolate* isolate) | 1047 ConstObjectVisitor(Precompiler* precompiler, Isolate* isolate) |
| 1044 : ObjectPointerVisitor(isolate), | 1048 : ObjectPointerVisitor(isolate), |
| 1045 precompiler_(precompiler), | 1049 precompiler_(precompiler), |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1070 Class::Handle(Z, I->object_store()->closure_class()); | 1074 Class::Handle(Z, I->object_store()->closure_class()); |
| 1071 const Function& dispatcher = Function::Handle( | 1075 const Function& dispatcher = Function::Handle( |
| 1072 Z, cache_class.GetInvocationDispatcher( | 1076 Z, cache_class.GetInvocationDispatcher( |
| 1073 Symbols::Call(), arguments_descriptor, | 1077 Symbols::Call(), arguments_descriptor, |
| 1074 RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */)); | 1078 RawFunction::kInvokeFieldDispatcher, true /* create_if_absent */)); |
| 1075 AddFunction(dispatcher); | 1079 AddFunction(dispatcher); |
| 1076 } | 1080 } |
| 1077 | 1081 |
| 1078 | 1082 |
| 1079 void Precompiler::AddField(const Field& field) { | 1083 void Precompiler::AddField(const Field& field) { |
| 1084 if (fields_to_retain_.Lookup(&field) != NULL) return; | |
| 1085 | |
| 1080 fields_to_retain_.Insert(&Field::ZoneHandle(Z, field.raw())); | 1086 fields_to_retain_.Insert(&Field::ZoneHandle(Z, field.raw())); |
| 1081 | 1087 |
| 1082 if (field.is_static()) { | 1088 if (field.is_static()) { |
| 1083 const Object& value = Object::Handle(Z, field.StaticValue()); | 1089 const Object& value = Object::Handle(Z, field.StaticValue()); |
| 1084 if (value.IsInstance()) { | 1090 if (value.IsInstance()) { |
| 1085 AddConstObject(Instance::Cast(value)); | 1091 AddConstObject(Instance::Cast(value)); |
| 1086 } | 1092 } |
| 1087 | 1093 |
| 1088 if (field.has_initializer()) { | 1094 if (field.has_initializer()) { |
| 1089 // Should not be in the middle of initialization while precompiling. | 1095 // Should not be in the middle of initialization while precompiling. |
| (...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2088 // (cid, target function, count) to (cid, target code, entry point), and | 2094 // (cid, target function, count) to (cid, target code, entry point), and |
| 2089 // replace the ICCallThroughFunction stub with ICCallThroughCode. | 2095 // replace the ICCallThroughFunction stub with ICCallThroughCode. |
| 2090 | 2096 |
| 2091 class SwitchICCallsVisitor : public FunctionVisitor { | 2097 class SwitchICCallsVisitor : public FunctionVisitor { |
| 2092 public: | 2098 public: |
| 2093 explicit SwitchICCallsVisitor(Zone* zone) | 2099 explicit SwitchICCallsVisitor(Zone* zone) |
| 2094 : zone_(zone), | 2100 : zone_(zone), |
| 2095 code_(Code::Handle(zone)), | 2101 code_(Code::Handle(zone)), |
| 2096 pool_(ObjectPool::Handle(zone)), | 2102 pool_(ObjectPool::Handle(zone)), |
| 2097 entry_(Object::Handle(zone)), | 2103 entry_(Object::Handle(zone)), |
| 2104 info_array_(TypedData::Handle(zone)), | |
| 2098 ic_(ICData::Handle(zone)), | 2105 ic_(ICData::Handle(zone)), |
| 2099 target_name_(String::Handle(zone)), | 2106 target_name_(String::Handle(zone)), |
| 2100 args_descriptor_(Array::Handle(zone)), | 2107 args_descriptor_(Array::Handle(zone)), |
| 2101 unlinked_(UnlinkedCall::Handle(zone)), | 2108 unlinked_(UnlinkedCall::Handle(zone)), |
| 2102 target_code_(Code::Handle(zone)), | 2109 target_code_(Code::Handle(zone)), |
| 2103 canonical_unlinked_calls_() {} | 2110 canonical_unlinked_calls_() {} |
| 2104 | 2111 |
| 2105 void Visit(const Function& function) { | 2112 void Visit(const Function& function) { |
| 2106 if (!function.HasCode()) { | 2113 if (!function.HasCode()) { |
| 2107 return; | 2114 return; |
| 2108 } | 2115 } |
| 2109 | 2116 |
| 2110 code_ = function.CurrentCode(); | 2117 code_ = function.CurrentCode(); |
| 2111 pool_ = code_.object_pool(); | 2118 pool_ = code_.object_pool(); |
| 2119 info_array_ = pool_.info_array(); | |
| 2120 ObjectPoolInfo pool_info(info_array_); | |
|
Florian Schneider
2016/12/08 18:30:45
Why not just:
ObjectPoolInfo pool_info(pool_);
kustermann
2016/12/08 19:14:38
So we allocate one handle per [SwitchICCallsVisito
| |
| 2112 for (intptr_t i = 0; i < pool_.Length(); i++) { | 2121 for (intptr_t i = 0; i < pool_.Length(); i++) { |
| 2113 if (pool_.InfoAt(i) != ObjectPool::kTaggedObject) continue; | 2122 if (pool_info.InfoAt(i) != ObjectPool::kTaggedObject) continue; |
|
kustermann
2016/12/08 13:52:44
Same thing: Move handle allocation out of loop.
| |
| 2114 entry_ = pool_.ObjectAt(i); | 2123 entry_ = pool_.ObjectAt(i); |
| 2115 if (entry_.IsICData()) { | 2124 if (entry_.IsICData()) { |
| 2116 // The only IC calls generated by precompilation are for switchable | 2125 // The only IC calls generated by precompilation are for switchable |
| 2117 // calls. | 2126 // calls. |
| 2118 ic_ ^= entry_.raw(); | 2127 ic_ ^= entry_.raw(); |
| 2119 ic_.ResetSwitchable(zone_); | 2128 ic_.ResetSwitchable(zone_); |
| 2120 | 2129 |
| 2121 unlinked_ = UnlinkedCall::New(); | 2130 unlinked_ = UnlinkedCall::New(); |
| 2122 target_name_ = ic_.target_name(); | 2131 target_name_ = ic_.target_name(); |
| 2123 unlinked_.set_target_name(target_name_); | 2132 unlinked_.set_target_name(target_name_); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 2143 } else { | 2152 } else { |
| 2144 return canonical_unlinked->raw(); | 2153 return canonical_unlinked->raw(); |
| 2145 } | 2154 } |
| 2146 } | 2155 } |
| 2147 | 2156 |
| 2148 private: | 2157 private: |
| 2149 Zone* zone_; | 2158 Zone* zone_; |
| 2150 Code& code_; | 2159 Code& code_; |
| 2151 ObjectPool& pool_; | 2160 ObjectPool& pool_; |
| 2152 Object& entry_; | 2161 Object& entry_; |
| 2162 TypedData& info_array_; | |
| 2153 ICData& ic_; | 2163 ICData& ic_; |
| 2154 String& target_name_; | 2164 String& target_name_; |
| 2155 Array& args_descriptor_; | 2165 Array& args_descriptor_; |
| 2156 UnlinkedCall& unlinked_; | 2166 UnlinkedCall& unlinked_; |
| 2157 Code& target_code_; | 2167 Code& target_code_; |
| 2158 UnlinkedCallSet canonical_unlinked_calls_; | 2168 UnlinkedCallSet canonical_unlinked_calls_; |
| 2159 }; | 2169 }; |
| 2160 | 2170 |
| 2161 ASSERT(!I->compilation_allowed()); | 2171 ASSERT(!I->compilation_allowed()); |
| 2162 SwitchICCallsVisitor visitor(Z); | 2172 SwitchICCallsVisitor visitor(Z); |
| (...skipping 1125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3288 | 3298 |
| 3289 ASSERT(FLAG_precompiled_mode); | 3299 ASSERT(FLAG_precompiled_mode); |
| 3290 const bool optimized = function.IsOptimizable(); // False for natives. | 3300 const bool optimized = function.IsOptimizable(); // False for natives. |
| 3291 DartPrecompilationPipeline pipeline(zone, field_type_map); | 3301 DartPrecompilationPipeline pipeline(zone, field_type_map); |
| 3292 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized); | 3302 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized); |
| 3293 } | 3303 } |
| 3294 | 3304 |
| 3295 #endif // DART_PRECOMPILER | 3305 #endif // DART_PRECOMPILER |
| 3296 | 3306 |
| 3297 } // namespace dart | 3307 } // namespace dart |
| OLD | NEW |