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 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 I->object_store()->set_async_star_move_next_helper(null_function); | 495 I->object_store()->set_async_star_move_next_helper(null_function); |
496 I->object_store()->set_complete_on_async_return(null_function); | 496 I->object_store()->set_complete_on_async_return(null_function); |
497 I->object_store()->set_async_star_stream_controller(null_class); | 497 I->object_store()->set_async_star_stream_controller(null_class); |
498 } | 498 } |
499 DropClasses(); | 499 DropClasses(); |
500 DropLibraries(); | 500 DropLibraries(); |
501 | 501 |
502 BindStaticCalls(); | 502 BindStaticCalls(); |
503 SwitchICCalls(); | 503 SwitchICCalls(); |
504 | 504 |
505 ShareMegamorphicBuckets(); | 505 ProgramVisitor::Dedup(); |
506 DedupStackMaps(); | |
507 DedupCodeSourceMaps(); | |
508 DedupLists(); | |
509 | |
510 if (FLAG_dedup_instructions) { | |
511 // Reduces binary size but obfuscates profiler results. | |
512 DedupInstructions(); | |
513 } | |
514 | 506 |
515 zone_ = NULL; | 507 zone_ = NULL; |
516 } | 508 } |
517 | 509 |
518 intptr_t symbols_before = -1; | 510 intptr_t symbols_before = -1; |
519 intptr_t symbols_after = -1; | 511 intptr_t symbols_after = -1; |
520 intptr_t capacity = -1; | 512 intptr_t capacity = -1; |
521 if (FLAG_trace_precompiler) { | 513 if (FLAG_trace_precompiler) { |
522 Symbols::GetStats(I, &symbols_before, &capacity); | 514 Symbols::GetStats(I, &symbols_before, &capacity); |
523 } | 515 } |
(...skipping 1739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2263 UnlinkedCallSet canonical_unlinked_calls_; | 2255 UnlinkedCallSet canonical_unlinked_calls_; |
2264 }; | 2256 }; |
2265 | 2257 |
2266 ASSERT(!I->compilation_allowed()); | 2258 ASSERT(!I->compilation_allowed()); |
2267 SwitchICCallsVisitor visitor(Z); | 2259 SwitchICCallsVisitor visitor(Z); |
2268 ProgramVisitor::VisitFunctions(&visitor); | 2260 ProgramVisitor::VisitFunctions(&visitor); |
2269 #endif | 2261 #endif |
2270 } | 2262 } |
2271 | 2263 |
2272 | 2264 |
2273 void Precompiler::ShareMegamorphicBuckets() { | |
2274 const GrowableObjectArray& table = GrowableObjectArray::Handle( | |
2275 Z, I->object_store()->megamorphic_cache_table()); | |
2276 if (table.IsNull()) return; | |
2277 MegamorphicCache& cache = MegamorphicCache::Handle(Z); | |
2278 | |
2279 const intptr_t capacity = 1; | |
2280 const Array& buckets = Array::Handle( | |
2281 Z, Array::New(MegamorphicCache::kEntryLength * capacity, Heap::kOld)); | |
2282 const Function& handler = | |
2283 Function::Handle(Z, MegamorphicCacheTable::miss_handler(I)); | |
2284 MegamorphicCache::SetEntry(buckets, 0, MegamorphicCache::smi_illegal_cid(), | |
2285 handler); | |
2286 | |
2287 for (intptr_t i = 0; i < table.Length(); i++) { | |
2288 cache ^= table.At(i); | |
2289 cache.set_buckets(buckets); | |
2290 cache.set_mask(capacity - 1); | |
2291 cache.set_filled_entry_count(0); | |
2292 } | |
2293 } | |
2294 | |
2295 | |
2296 void Precompiler::DedupStackMaps() { | |
2297 class DedupStackMapsVisitor : public FunctionVisitor { | |
2298 public: | |
2299 explicit DedupStackMapsVisitor(Zone* zone) | |
2300 : zone_(zone), | |
2301 canonical_stackmaps_(), | |
2302 code_(Code::Handle(zone)), | |
2303 stackmaps_(Array::Handle(zone)), | |
2304 stackmap_(StackMap::Handle(zone)) {} | |
2305 | |
2306 void Visit(const Function& function) { | |
2307 if (!function.HasCode()) { | |
2308 return; | |
2309 } | |
2310 code_ = function.CurrentCode(); | |
2311 stackmaps_ = code_.stackmaps(); | |
2312 if (stackmaps_.IsNull()) return; | |
2313 for (intptr_t i = 0; i < stackmaps_.Length(); i++) { | |
2314 stackmap_ ^= stackmaps_.At(i); | |
2315 stackmap_ = DedupStackMap(stackmap_); | |
2316 stackmaps_.SetAt(i, stackmap_); | |
2317 } | |
2318 } | |
2319 | |
2320 RawStackMap* DedupStackMap(const StackMap& stackmap) { | |
2321 const StackMap* canonical_stackmap = | |
2322 canonical_stackmaps_.LookupValue(&stackmap); | |
2323 if (canonical_stackmap == NULL) { | |
2324 canonical_stackmaps_.Insert( | |
2325 &StackMap::ZoneHandle(zone_, stackmap.raw())); | |
2326 return stackmap.raw(); | |
2327 } else { | |
2328 return canonical_stackmap->raw(); | |
2329 } | |
2330 } | |
2331 | |
2332 private: | |
2333 Zone* zone_; | |
2334 StackMapSet canonical_stackmaps_; | |
2335 Code& code_; | |
2336 Array& stackmaps_; | |
2337 StackMap& stackmap_; | |
2338 }; | |
2339 | |
2340 DedupStackMapsVisitor visitor(Z); | |
2341 ProgramVisitor::VisitFunctions(&visitor); | |
2342 } | |
2343 | |
2344 | |
2345 void Precompiler::DedupCodeSourceMaps() { | |
2346 class DedupCodeSourceMapsVisitor : public FunctionVisitor { | |
2347 public: | |
2348 explicit DedupCodeSourceMapsVisitor(Zone* zone) | |
2349 : zone_(zone), | |
2350 canonical_code_source_maps_(), | |
2351 code_(Code::Handle(zone)), | |
2352 code_source_map_(CodeSourceMap::Handle(zone)) {} | |
2353 | |
2354 void Visit(const Function& function) { | |
2355 if (!function.HasCode()) { | |
2356 return; | |
2357 } | |
2358 code_ = function.CurrentCode(); | |
2359 code_source_map_ = code_.code_source_map(); | |
2360 ASSERT(!code_source_map_.IsNull()); | |
2361 code_source_map_ = DedupCodeSourceMap(code_source_map_); | |
2362 code_.set_code_source_map(code_source_map_); | |
2363 } | |
2364 | |
2365 RawCodeSourceMap* DedupCodeSourceMap(const CodeSourceMap& code_source_map) { | |
2366 const CodeSourceMap* canonical_code_source_map = | |
2367 canonical_code_source_maps_.LookupValue(&code_source_map); | |
2368 if (canonical_code_source_map == NULL) { | |
2369 canonical_code_source_maps_.Insert( | |
2370 &CodeSourceMap::ZoneHandle(zone_, code_source_map.raw())); | |
2371 return code_source_map.raw(); | |
2372 } else { | |
2373 return canonical_code_source_map->raw(); | |
2374 } | |
2375 } | |
2376 | |
2377 private: | |
2378 Zone* zone_; | |
2379 CodeSourceMapSet canonical_code_source_maps_; | |
2380 Code& code_; | |
2381 CodeSourceMap& code_source_map_; | |
2382 }; | |
2383 | |
2384 DedupCodeSourceMapsVisitor visitor(Z); | |
2385 ProgramVisitor::VisitFunctions(&visitor); | |
2386 } | |
2387 | |
2388 | |
2389 void Precompiler::DedupLists() { | |
2390 class DedupListsVisitor : public FunctionVisitor { | |
2391 public: | |
2392 explicit DedupListsVisitor(Zone* zone) | |
2393 : zone_(zone), | |
2394 canonical_lists_(), | |
2395 code_(Code::Handle(zone)), | |
2396 list_(Array::Handle(zone)) {} | |
2397 | |
2398 void Visit(const Function& function) { | |
2399 code_ = function.CurrentCode(); | |
2400 if (!code_.IsNull()) { | |
2401 list_ = code_.stackmaps(); | |
2402 if (!list_.IsNull()) { | |
2403 list_ = DedupList(list_); | |
2404 code_.set_stackmaps(list_); | |
2405 } | |
2406 list_ = code_.inlined_id_to_function(); | |
2407 if (!list_.IsNull()) { | |
2408 list_ = DedupList(list_); | |
2409 code_.set_inlined_id_to_function(list_); | |
2410 } | |
2411 } | |
2412 | |
2413 list_ = function.parameter_types(); | |
2414 if (!list_.IsNull()) { | |
2415 if (!function.IsSignatureFunction() && !function.IsClosureFunction() && | |
2416 (function.name() != Symbols::Call().raw()) && !list_.InVMHeap()) { | |
2417 // Parameter types not needed for function type tests. | |
2418 for (intptr_t i = 0; i < list_.Length(); i++) { | |
2419 list_.SetAt(i, Object::dynamic_type()); | |
2420 } | |
2421 } | |
2422 list_ = DedupList(list_); | |
2423 function.set_parameter_types(list_); | |
2424 } | |
2425 | |
2426 list_ = function.parameter_names(); | |
2427 if (!list_.IsNull()) { | |
2428 if (!function.HasOptionalNamedParameters() && !list_.InVMHeap()) { | |
2429 // Parameter names not needed for resolution. | |
2430 for (intptr_t i = 0; i < list_.Length(); i++) { | |
2431 list_.SetAt(i, Symbols::OptimizedOut()); | |
2432 } | |
2433 } | |
2434 list_ = DedupList(list_); | |
2435 function.set_parameter_names(list_); | |
2436 } | |
2437 } | |
2438 | |
2439 RawArray* DedupList(const Array& list) { | |
2440 const Array* canonical_list = canonical_lists_.LookupValue(&list); | |
2441 if (canonical_list == NULL) { | |
2442 canonical_lists_.Insert(&Array::ZoneHandle(zone_, list.raw())); | |
2443 return list.raw(); | |
2444 } else { | |
2445 return canonical_list->raw(); | |
2446 } | |
2447 } | |
2448 | |
2449 private: | |
2450 Zone* zone_; | |
2451 ArraySet canonical_lists_; | |
2452 Code& code_; | |
2453 Array& list_; | |
2454 }; | |
2455 | |
2456 DedupListsVisitor visitor(Z); | |
2457 ProgramVisitor::VisitFunctions(&visitor); | |
2458 } | |
2459 | |
2460 | |
2461 void Precompiler::DedupInstructions() { | |
2462 class DedupInstructionsVisitor : public FunctionVisitor { | |
2463 public: | |
2464 explicit DedupInstructionsVisitor(Zone* zone) | |
2465 : zone_(zone), | |
2466 canonical_instructions_set_(), | |
2467 code_(Code::Handle(zone)), | |
2468 instructions_(Instructions::Handle(zone)) {} | |
2469 | |
2470 void Visit(const Function& function) { | |
2471 if (!function.HasCode()) { | |
2472 ASSERT(function.HasImplicitClosureFunction()); | |
2473 return; | |
2474 } | |
2475 code_ = function.CurrentCode(); | |
2476 instructions_ = code_.instructions(); | |
2477 instructions_ = DedupOneInstructions(instructions_); | |
2478 code_.SetActiveInstructions(instructions_); | |
2479 code_.set_instructions(instructions_); | |
2480 function.SetInstructions(code_); // Update cached entry point. | |
2481 } | |
2482 | |
2483 RawInstructions* DedupOneInstructions(const Instructions& instructions) { | |
2484 const Instructions* canonical_instructions = | |
2485 canonical_instructions_set_.LookupValue(&instructions); | |
2486 if (canonical_instructions == NULL) { | |
2487 canonical_instructions_set_.Insert( | |
2488 &Instructions::ZoneHandle(zone_, instructions.raw())); | |
2489 return instructions.raw(); | |
2490 } else { | |
2491 return canonical_instructions->raw(); | |
2492 } | |
2493 } | |
2494 | |
2495 private: | |
2496 Zone* zone_; | |
2497 InstructionsSet canonical_instructions_set_; | |
2498 Code& code_; | |
2499 Instructions& instructions_; | |
2500 }; | |
2501 | |
2502 DedupInstructionsVisitor visitor(Z); | |
2503 ProgramVisitor::VisitFunctions(&visitor); | |
2504 } | |
2505 | |
2506 | |
2507 void Precompiler::FinalizeAllClasses() { | 2265 void Precompiler::FinalizeAllClasses() { |
2508 Library& lib = Library::Handle(Z); | 2266 Library& lib = Library::Handle(Z); |
2509 Class& cls = Class::Handle(Z); | 2267 Class& cls = Class::Handle(Z); |
2510 | 2268 |
2511 for (intptr_t i = 0; i < libraries_.Length(); i++) { | 2269 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
2512 lib ^= libraries_.At(i); | 2270 lib ^= libraries_.At(i); |
2513 if (!lib.Loaded()) { | 2271 if (!lib.Loaded()) { |
2514 String& uri = String::Handle(Z, lib.url()); | 2272 String& uri = String::Handle(Z, lib.url()); |
2515 String& msg = String::Handle( | 2273 String& msg = String::Handle( |
2516 Z, | 2274 Z, |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3568 | 3326 |
3569 ASSERT(FLAG_precompiled_mode); | 3327 ASSERT(FLAG_precompiled_mode); |
3570 const bool optimized = function.IsOptimizable(); // False for natives. | 3328 const bool optimized = function.IsOptimizable(); // False for natives. |
3571 DartPrecompilationPipeline pipeline(zone, field_type_map); | 3329 DartPrecompilationPipeline pipeline(zone, field_type_map); |
3572 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized); | 3330 return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized); |
3573 } | 3331 } |
3574 | 3332 |
3575 #endif // DART_PRECOMPILER | 3333 #endif // DART_PRECOMPILER |
3576 | 3334 |
3577 } // namespace dart | 3335 } // namespace dart |
OLD | NEW |