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

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

Issue 2314133003: AOT: Use a cid range check when possible to implement type tests. (Closed)
Patch Set: . Created 4 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
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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 return Error::null(); 194 return Error::null();
195 } else { 195 } else {
196 Thread* thread = Thread::Current(); 196 Thread* thread = Thread::Current();
197 const Error& error = Error::Handle(thread->sticky_error()); 197 const Error& error = Error::Handle(thread->sticky_error());
198 thread->clear_sticky_error(); 198 thread->clear_sticky_error();
199 return error.raw(); 199 return error.raw();
200 } 200 }
201 } 201 }
202 202
203 203
204 bool TypeRangeCache::InstanceOfHasClassRange(const AbstractType& type,
205 intptr_t* lower_limit,
206 intptr_t* upper_limit) {
207 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
208
209 if (!type.IsInstantiated()) return false;
210 if (type.IsFunctionType()) return false;
211
212 const TypeArguments& type_arguments =
213 TypeArguments::Handle(type.arguments());
214 if (!type_arguments.IsNull() &&
215 !type_arguments.IsRaw(0, type_arguments.Length())) return false;
216
217
218 intptr_t type_cid = type.type_class_id();
219 if (lower_limits_[type_cid] == kNotContiguous) return false;
220 if (lower_limits_[type_cid] != kNotComputed) {
221 *lower_limit = lower_limits_[type_cid];
222 *upper_limit = upper_limits_[type_cid];
223 return true;
224 }
225
226
227 *lower_limit = -1;
228 *upper_limit = -1;
229 intptr_t last_matching_cid = -1;
230
231 ClassTable* table = thread_->isolate()->class_table();
232 Class& cls = Class::Handle();
233 AbstractType& cls_type = AbstractType::Handle();
234 for (intptr_t cid = kInstanceCid; cid < table->NumCids(); cid++) {
235 if (!table->HasValidClassAt(cid)) continue;
236 if (cid == kVoidCid) continue;
237 if (cid == kDynamicCid) continue;
238 cls = table->At(cid);
239 if (cls.is_abstract()) continue;
240 if (cls.is_patch()) continue;
241 if (cls.IsTopLevel()) continue;
242
243 cls_type = cls.DeclarationType();
rmacnak 2016/09/07 01:20:27 Regis, should I used DeclarationType or RareType?
regis 2016/09/07 17:06:07 RareType, because DeclarationType would yield an u
rmacnak 2016/09/07 22:21:28 Done.
244 if (cls_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) {
245 last_matching_cid = cid;
246 if (*lower_limit == -1) {
247 // Found beginning of range.
248 *lower_limit = cid;
249 } else if (*upper_limit == -1) {
250 // Expanding range.
251 } else {
252 // Found a second range.
253 lower_limits_[type_cid] = kNotContiguous;
254 return false;
255 }
256 } else {
257 if (*lower_limit == -1) {
258 // Still before range.
259 } else if (*upper_limit == -1) {
260 // Found end of range.
261 *upper_limit = last_matching_cid;
262 } else {
263 // After range.
264 }
265 }
266 }
267 ASSERT(*lower_limit != -1); // Class is at least a subtype of itself.
268
269 if (*upper_limit == -1) {
270 ASSERT(last_matching_cid != -1);
271 *upper_limit = last_matching_cid;
272 }
273
274 OS::Print("Type check for is %s is cid range [%" Pd ", %" Pd "]\n",
275 type.ToCString(), *lower_limit, *upper_limit);
276
277 lower_limits_[type_cid] = *lower_limit;
278 upper_limits_[type_cid] = *upper_limit;
279 return true;
280 }
281
282
204 Precompiler::Precompiler(Thread* thread, bool reset_fields) : 283 Precompiler::Precompiler(Thread* thread, bool reset_fields) :
205 thread_(thread), 284 thread_(thread),
206 zone_(NULL), 285 zone_(NULL),
207 isolate_(thread->isolate()), 286 isolate_(thread->isolate()),
208 reset_fields_(reset_fields), 287 reset_fields_(reset_fields),
209 changed_(false), 288 changed_(false),
210 function_count_(0), 289 function_count_(0),
211 class_count_(0), 290 class_count_(0),
212 selector_count_(0), 291 selector_count_(0),
213 dropped_function_count_(0), 292 dropped_function_count_(0),
(...skipping 26 matching lines...) Expand all
240 StackZone stack_zone(T); 319 StackZone stack_zone(T);
241 zone_ = stack_zone.GetZone(); 320 zone_ = stack_zone.GetZone();
242 321
243 { HANDLESCOPE(T); 322 { HANDLESCOPE(T);
244 // Make sure class hierarchy is stable before compilation so that CHA 323 // Make sure class hierarchy is stable before compilation so that CHA
245 // can be used. Also ensures lookup of entry points won't miss functions 324 // can be used. Also ensures lookup of entry points won't miss functions
246 // because their class hasn't been finalized yet. 325 // because their class hasn't been finalized yet.
247 FinalizeAllClasses(); 326 FinalizeAllClasses();
248 327
249 SortClasses(); 328 SortClasses();
329 TypeRangeCache trc(T, I->class_table()->NumCids());
250 330
251 // Precompile static initializers to compute result type information. 331 // Precompile static initializers to compute result type information.
252 PrecompileStaticInitializers(); 332 PrecompileStaticInitializers();
253 333
254 // Precompile constructors to compute type information for final fields. 334 // Precompile constructors to compute type information for final fields.
255 ClearAllCode(); 335 ClearAllCode();
256 PrecompileConstructors(); 336 PrecompileConstructors();
257 337
258 for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) { 338 for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) {
259 if (FLAG_trace_precompiler) { 339 if (FLAG_trace_precompiler) {
(...skipping 2320 matching lines...) Expand 10 before | Expand all | Expand 10 after
2580 GrowableArray<intptr_t> inlining_black_list; 2660 GrowableArray<intptr_t> inlining_black_list;
2581 2661
2582 while (!done) { 2662 while (!done) {
2583 const intptr_t prev_deopt_id = thread()->deopt_id(); 2663 const intptr_t prev_deopt_id = thread()->deopt_id();
2584 thread()->set_deopt_id(0); 2664 thread()->set_deopt_id(0);
2585 LongJumpScope jump; 2665 LongJumpScope jump;
2586 const intptr_t val = setjmp(*jump.Set()); 2666 const intptr_t val = setjmp(*jump.Set());
2587 if (val == 0) { 2667 if (val == 0) {
2588 FlowGraph* flow_graph = NULL; 2668 FlowGraph* flow_graph = NULL;
2589 2669
2590 // Class hierarchy analysis is registered with the isolate in the 2670 // Class hierarchy analysis is registered with the thread in the
2591 // constructor and unregisters itself upon destruction. 2671 // constructor and unregisters itself upon destruction.
2592 CHA cha(thread()); 2672 CHA cha(thread());
2593 2673
2594 // TimerScope needs an isolate to be properly terminated in case of a 2674 // TimerScope needs an isolate to be properly terminated in case of a
2595 // LongJump. 2675 // LongJump.
2596 { 2676 {
2597 CSTAT_TIMER_SCOPE(thread(), graphbuilder_timer); 2677 CSTAT_TIMER_SCOPE(thread(), graphbuilder_timer);
2598 ZoneGrowableArray<const ICData*>* ic_data_array = 2678 ZoneGrowableArray<const ICData*>* ic_data_array =
2599 new(zone) ZoneGrowableArray<const ICData*>(); 2679 new(zone) ZoneGrowableArray<const ICData*>();
2600 #ifndef PRODUCT 2680 #ifndef PRODUCT
2601 TimelineDurationScope tds(thread(), 2681 TimelineDurationScope tds(thread(),
2602 compiler_timeline, 2682 compiler_timeline,
2603 "BuildFlowGraph"); 2683 "BuildFlowGraph");
2604 #endif // !PRODUCT 2684 #endif // !PRODUCT
2605 flow_graph = pipeline->BuildFlowGraph(zone, 2685 flow_graph = pipeline->BuildFlowGraph(zone,
2606 parsed_function(), 2686 parsed_function(),
2607 *ic_data_array, 2687 *ic_data_array,
2608 Compiler::kNoOSRDeoptId); 2688 Compiler::kNoOSRDeoptId);
2609 } 2689 }
2610 2690
2611 const bool print_flow_graph = 2691 const bool print_flow_graph =
2612 (FLAG_print_flow_graph || 2692 (FLAG_print_flow_graph ||
2613 (optimized() && FLAG_print_flow_graph_optimized)) && 2693 (optimized() && FLAG_print_flow_graph_optimized)) &&
2614 FlowGraphPrinter::ShouldPrint(function); 2694 FlowGraphPrinter::ShouldPrint(function);
2615 2695
2616 if (print_flow_graph) {
2617 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
2618 }
2619
2620 if (optimized()) { 2696 if (optimized()) {
2621 #ifndef PRODUCT 2697 #ifndef PRODUCT
2622 TimelineDurationScope tds(thread(), 2698 TimelineDurationScope tds(thread(),
2623 compiler_timeline, 2699 compiler_timeline,
2624 "ComputeSSA"); 2700 "ComputeSSA");
2625 #endif // !PRODUCT 2701 #endif // !PRODUCT
2626 CSTAT_TIMER_SCOPE(thread(), ssa_timer); 2702 CSTAT_TIMER_SCOPE(thread(), ssa_timer);
2627 // Transform to SSA (virtual register 0 and no inlining arguments). 2703 // Transform to SSA (virtual register 0 and no inlining arguments).
2628 flow_graph->ComputeSSA(0, NULL); 2704 flow_graph->ComputeSSA(0, NULL);
2629 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2705 DEBUG_ASSERT(flow_graph->VerifyUseLists());
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2734 flow_graph->Canonicalize(); 2810 flow_graph->Canonicalize();
2735 } 2811 }
2736 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2812 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2737 2813
2738 { 2814 {
2739 #ifndef PRODUCT 2815 #ifndef PRODUCT
2740 TimelineDurationScope tds2(thread(), 2816 TimelineDurationScope tds2(thread(),
2741 compiler_timeline, 2817 compiler_timeline,
2742 "BranchSimplifier"); 2818 "BranchSimplifier");
2743 #endif // !PRODUCT 2819 #endif // !PRODUCT
2820
2744 BranchSimplifier::Simplify(flow_graph); 2821 BranchSimplifier::Simplify(flow_graph);
2745 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2822 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2746 2823
2747 IfConverter::Simplify(flow_graph); 2824 IfConverter::Simplify(flow_graph);
2748 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 2825 DEBUG_ASSERT(flow_graph->VerifyUseLists());
2749 } 2826 }
2750 2827
2751 if (FLAG_constant_propagation) { 2828 if (FLAG_constant_propagation) {
2752 #ifndef PRODUCT 2829 #ifndef PRODUCT
2753 TimelineDurationScope tds2(thread(), 2830 TimelineDurationScope tds2(thread(),
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
2976 // Compute and store graph informations (call & instruction counts) 3053 // Compute and store graph informations (call & instruction counts)
2977 // to be later used by the inliner. 3054 // to be later used by the inliner.
2978 FlowGraphInliner::CollectGraphInfo(flow_graph, true); 3055 FlowGraphInliner::CollectGraphInfo(flow_graph, true);
2979 3056
2980 { 3057 {
2981 #ifndef PRODUCT 3058 #ifndef PRODUCT
2982 TimelineDurationScope tds2(thread(), 3059 TimelineDurationScope tds2(thread(),
2983 compiler_timeline, 3060 compiler_timeline,
2984 "AllocateRegisters"); 3061 "AllocateRegisters");
2985 #endif // !PRODUCT 3062 #endif // !PRODUCT
3063
2986 // Perform register allocation on the SSA graph. 3064 // Perform register allocation on the SSA graph.
2987 FlowGraphAllocator allocator(*flow_graph); 3065 FlowGraphAllocator allocator(*flow_graph);
2988 allocator.AllocateRegisters(); 3066 allocator.AllocateRegisters();
2989 } 3067 }
2990 3068
2991 if (print_flow_graph) { 3069 if (print_flow_graph) {
2992 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); 3070 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
2993 } 3071 }
2994 } 3072 }
2995 3073
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
3179 3257
3180 ASSERT(FLAG_precompiled_mode); 3258 ASSERT(FLAG_precompiled_mode);
3181 const bool optimized = function.IsOptimizable(); // False for natives. 3259 const bool optimized = function.IsOptimizable(); // False for natives.
3182 DartPrecompilationPipeline pipeline(zone, field_type_map); 3260 DartPrecompilationPipeline pipeline(zone, field_type_map);
3183 return PrecompileFunctionHelper(&pipeline, function, optimized); 3261 return PrecompileFunctionHelper(&pipeline, function, optimized);
3184 } 3262 }
3185 3263
3186 #endif // DART_PRECOMPILER 3264 #endif // DART_PRECOMPILER
3187 3265
3188 } // namespace dart 3266 } // namespace dart
OLDNEW
« runtime/vm/aot_optimizer.cc ('K') | « runtime/vm/precompiler.h ('k') | runtime/vm/thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698