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

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

Issue 2815533003: Refactor AOT deduplication steps so they can run before an app-jit snapshot as well. (Closed)
Patch Set: . Created 3 years, 8 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
« no previous file with comments | « runtime/vm/precompiler.h ('k') | runtime/vm/program_visitor.h » ('j') | 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 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/precompiler.h ('k') | runtime/vm/program_visitor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698