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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |