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

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

Issue 2556193003: VM: Make precompiler process constants/fields only once, avoid using pool.InfoAt() (Closed)
Patch Set: Created 4 years 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
« runtime/vm/object.h ('K') | « runtime/vm/object.cc ('k') | 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) 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
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
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
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
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
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
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
OLDNEW
« runtime/vm/object.h ('K') | « runtime/vm/object.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698