| 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 Zone* zone = thread_->zone(); |
| 213 const TypeArguments& type_arguments = |
| 214 TypeArguments::Handle(zone, type.arguments()); |
| 215 if (!type_arguments.IsNull() && |
| 216 !type_arguments.IsRaw(0, type_arguments.Length())) return false; |
| 217 |
| 218 |
| 219 intptr_t type_cid = type.type_class_id(); |
| 220 if (lower_limits_[type_cid] == kNotContiguous) return false; |
| 221 if (lower_limits_[type_cid] != kNotComputed) { |
| 222 *lower_limit = lower_limits_[type_cid]; |
| 223 *upper_limit = upper_limits_[type_cid]; |
| 224 return true; |
| 225 } |
| 226 |
| 227 |
| 228 *lower_limit = -1; |
| 229 *upper_limit = -1; |
| 230 intptr_t last_matching_cid = -1; |
| 231 |
| 232 ClassTable* table = thread_->isolate()->class_table(); |
| 233 Class& cls = Class::Handle(zone); |
| 234 AbstractType& cls_type = AbstractType::Handle(zone); |
| 235 for (intptr_t cid = kInstanceCid; cid < table->NumCids(); cid++) { |
| 236 if (!table->HasValidClassAt(cid)) continue; |
| 237 if (cid == kVoidCid) continue; |
| 238 if (cid == kDynamicCid) continue; |
| 239 cls = table->At(cid); |
| 240 if (cls.is_abstract()) continue; |
| 241 if (cls.is_patch()) continue; |
| 242 if (cls.IsTopLevel()) continue; |
| 243 |
| 244 cls_type = cls.RareType(); |
| 245 if (cls_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) { |
| 246 last_matching_cid = cid; |
| 247 if (*lower_limit == -1) { |
| 248 // Found beginning of range. |
| 249 *lower_limit = cid; |
| 250 } else if (*upper_limit == -1) { |
| 251 // Expanding range. |
| 252 } else { |
| 253 // Found a second range. |
| 254 lower_limits_[type_cid] = kNotContiguous; |
| 255 return false; |
| 256 } |
| 257 } else { |
| 258 if (*lower_limit == -1) { |
| 259 // Still before range. |
| 260 } else if (*upper_limit == -1) { |
| 261 // Found end of range. |
| 262 *upper_limit = last_matching_cid; |
| 263 } else { |
| 264 // After range. |
| 265 } |
| 266 } |
| 267 } |
| 268 if (*lower_limit == -1) { |
| 269 // Not implemented by any concrete class. |
| 270 *lower_limit = kIllegalCid; |
| 271 *upper_limit = kIllegalCid; |
| 272 } |
| 273 |
| 274 if (*upper_limit == -1) { |
| 275 ASSERT(last_matching_cid != -1); |
| 276 *upper_limit = last_matching_cid; |
| 277 } |
| 278 |
| 279 if (FLAG_trace_precompiler) { |
| 280 THR_Print("Type check for %s is cid range [%" Pd ", %" Pd "]\n", |
| 281 type.ToCString(), *lower_limit, *upper_limit); |
| 282 } |
| 283 |
| 284 lower_limits_[type_cid] = *lower_limit; |
| 285 upper_limits_[type_cid] = *upper_limit; |
| 286 return true; |
| 287 } |
| 288 |
| 289 |
| 204 Precompiler::Precompiler(Thread* thread, bool reset_fields) : | 290 Precompiler::Precompiler(Thread* thread, bool reset_fields) : |
| 205 thread_(thread), | 291 thread_(thread), |
| 206 zone_(NULL), | 292 zone_(NULL), |
| 207 isolate_(thread->isolate()), | 293 isolate_(thread->isolate()), |
| 208 reset_fields_(reset_fields), | 294 reset_fields_(reset_fields), |
| 209 changed_(false), | 295 changed_(false), |
| 210 function_count_(0), | 296 function_count_(0), |
| 211 class_count_(0), | 297 class_count_(0), |
| 212 selector_count_(0), | 298 selector_count_(0), |
| 213 dropped_function_count_(0), | 299 dropped_function_count_(0), |
| (...skipping 26 matching lines...) Expand all Loading... |
| 240 StackZone stack_zone(T); | 326 StackZone stack_zone(T); |
| 241 zone_ = stack_zone.GetZone(); | 327 zone_ = stack_zone.GetZone(); |
| 242 | 328 |
| 243 { HANDLESCOPE(T); | 329 { HANDLESCOPE(T); |
| 244 // Make sure class hierarchy is stable before compilation so that CHA | 330 // 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 | 331 // can be used. Also ensures lookup of entry points won't miss functions |
| 246 // because their class hasn't been finalized yet. | 332 // because their class hasn't been finalized yet. |
| 247 FinalizeAllClasses(); | 333 FinalizeAllClasses(); |
| 248 | 334 |
| 249 SortClasses(); | 335 SortClasses(); |
| 336 TypeRangeCache trc(T, I->class_table()->NumCids()); |
| 250 | 337 |
| 251 // Precompile static initializers to compute result type information. | 338 // Precompile static initializers to compute result type information. |
| 252 PrecompileStaticInitializers(); | 339 PrecompileStaticInitializers(); |
| 253 | 340 |
| 254 // Precompile constructors to compute type information for final fields. | 341 // Precompile constructors to compute type information for final fields. |
| 255 ClearAllCode(); | 342 ClearAllCode(); |
| 256 PrecompileConstructors(); | 343 PrecompileConstructors(); |
| 257 | 344 |
| 258 for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) { | 345 for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) { |
| 259 if (FLAG_trace_precompiler) { | 346 if (FLAG_trace_precompiler) { |
| (...skipping 2320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2580 GrowableArray<intptr_t> inlining_black_list; | 2667 GrowableArray<intptr_t> inlining_black_list; |
| 2581 | 2668 |
| 2582 while (!done) { | 2669 while (!done) { |
| 2583 const intptr_t prev_deopt_id = thread()->deopt_id(); | 2670 const intptr_t prev_deopt_id = thread()->deopt_id(); |
| 2584 thread()->set_deopt_id(0); | 2671 thread()->set_deopt_id(0); |
| 2585 LongJumpScope jump; | 2672 LongJumpScope jump; |
| 2586 const intptr_t val = setjmp(*jump.Set()); | 2673 const intptr_t val = setjmp(*jump.Set()); |
| 2587 if (val == 0) { | 2674 if (val == 0) { |
| 2588 FlowGraph* flow_graph = NULL; | 2675 FlowGraph* flow_graph = NULL; |
| 2589 | 2676 |
| 2590 // Class hierarchy analysis is registered with the isolate in the | 2677 // Class hierarchy analysis is registered with the thread in the |
| 2591 // constructor and unregisters itself upon destruction. | 2678 // constructor and unregisters itself upon destruction. |
| 2592 CHA cha(thread()); | 2679 CHA cha(thread()); |
| 2593 | 2680 |
| 2594 // TimerScope needs an isolate to be properly terminated in case of a | 2681 // TimerScope needs an isolate to be properly terminated in case of a |
| 2595 // LongJump. | 2682 // LongJump. |
| 2596 { | 2683 { |
| 2597 CSTAT_TIMER_SCOPE(thread(), graphbuilder_timer); | 2684 CSTAT_TIMER_SCOPE(thread(), graphbuilder_timer); |
| 2598 ZoneGrowableArray<const ICData*>* ic_data_array = | 2685 ZoneGrowableArray<const ICData*>* ic_data_array = |
| 2599 new(zone) ZoneGrowableArray<const ICData*>(); | 2686 new(zone) ZoneGrowableArray<const ICData*>(); |
| 2600 #ifndef PRODUCT | 2687 #ifndef PRODUCT |
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3179 | 3266 |
| 3180 ASSERT(FLAG_precompiled_mode); | 3267 ASSERT(FLAG_precompiled_mode); |
| 3181 const bool optimized = function.IsOptimizable(); // False for natives. | 3268 const bool optimized = function.IsOptimizable(); // False for natives. |
| 3182 DartPrecompilationPipeline pipeline(zone, field_type_map); | 3269 DartPrecompilationPipeline pipeline(zone, field_type_map); |
| 3183 return PrecompileFunctionHelper(&pipeline, function, optimized); | 3270 return PrecompileFunctionHelper(&pipeline, function, optimized); |
| 3184 } | 3271 } |
| 3185 | 3272 |
| 3186 #endif // DART_PRECOMPILER | 3273 #endif // DART_PRECOMPILER |
| 3187 | 3274 |
| 3188 } // namespace dart | 3275 } // namespace dart |
| OLD | NEW |