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 23 matching lines...) Expand all Loading... |
34 #include "vm/os.h" | 34 #include "vm/os.h" |
35 #include "vm/parser.h" | 35 #include "vm/parser.h" |
36 #include "vm/redundancy_elimination.h" | 36 #include "vm/redundancy_elimination.h" |
37 #include "vm/regexp_assembler.h" | 37 #include "vm/regexp_assembler.h" |
38 #include "vm/regexp_parser.h" | 38 #include "vm/regexp_parser.h" |
39 #include "vm/resolver.h" | 39 #include "vm/resolver.h" |
40 #include "vm/symbols.h" | 40 #include "vm/symbols.h" |
41 #include "vm/tags.h" | 41 #include "vm/tags.h" |
42 #include "vm/timeline.h" | 42 #include "vm/timeline.h" |
43 #include "vm/timer.h" | 43 #include "vm/timer.h" |
| 44 #include "vm/type_table.h" |
44 | 45 |
45 namespace dart { | 46 namespace dart { |
46 | 47 |
47 | 48 |
48 #define T (thread()) | 49 #define T (thread()) |
49 #define I (isolate()) | 50 #define I (isolate()) |
50 #define Z (zone()) | 51 #define Z (zone()) |
51 | 52 |
52 | 53 |
53 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets"); | 54 DEFINE_FLAG(bool, print_unique_targets, false, "Print unique dynaic targets"); |
(...skipping 1413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 cls.SetFields(fields); | 1468 cls.SetFields(fields); |
1468 } else { | 1469 } else { |
1469 cls.SetFields(Object::empty_array()); | 1470 cls.SetFields(Object::empty_array()); |
1470 } | 1471 } |
1471 } | 1472 } |
1472 } | 1473 } |
1473 } | 1474 } |
1474 | 1475 |
1475 | 1476 |
1476 void Precompiler::DropTypes() { | 1477 void Precompiler::DropTypes() { |
1477 Library& lib = Library::Handle(Z); | 1478 ObjectStore* object_store = I->object_store(); |
1478 Class& cls = Class::Handle(Z); | 1479 GrowableObjectArray& retained_types = |
1479 Object& obj = Object::Handle(Z); | 1480 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
1480 Array& arr = Array::Handle(Z); | 1481 Array& types_array = Array::Handle(Z); |
1481 GrowableObjectArray& retained_types = GrowableObjectArray::Handle(Z); | 1482 Type& type = Type::Handle(Z); |
1482 AbstractType& type = AbstractType::Handle(Z); | 1483 // First drop all the types that are not referenced. |
1483 | 1484 { |
1484 for (intptr_t i = 0; i < libraries_.Length(); i++) { | 1485 CanonicalTypeSet types_table(Z, object_store->canonical_types()); |
1485 lib ^= libraries_.At(i); | 1486 types_array = HashTables::ToArray(types_table, false); |
1486 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | 1487 for (intptr_t i = 0; i < (types_array.Length() - 1); i++) { |
1487 while (it.HasNext()) { | 1488 type ^= types_array.At(i); |
1488 cls = it.GetNextClass(); | 1489 bool retain = types_to_retain_.Lookup(&type) != NULL; |
1489 if (cls.IsDynamicClass()) { | 1490 if (retain) { |
1490 continue; // class 'dynamic' is in the read-only VM isolate. | 1491 retained_types.Add(type); |
1491 } | |
1492 obj = cls.canonical_types(); | |
1493 if (!obj.IsArray()) { | |
1494 // Class only has one type, keep it. | |
1495 } else { | 1492 } else { |
1496 // Class has many types. | 1493 dropped_type_count_++; |
1497 arr ^= obj.raw(); | |
1498 retained_types = GrowableObjectArray::New(); | |
1499 | |
1500 // Always keep the first one. | |
1501 ASSERT(arr.Length() >= 1); | |
1502 obj = arr.At(0); | |
1503 retained_types.Add(obj); | |
1504 | |
1505 for (intptr_t i = 1; i < arr.Length(); i++) { | |
1506 obj = arr.At(i); | |
1507 if (obj.IsNull()) { | |
1508 continue; | |
1509 } | |
1510 type ^= obj.raw(); | |
1511 bool retain = types_to_retain_.Lookup(&type) != NULL; | |
1512 if (retain) { | |
1513 retained_types.Add(type); | |
1514 } else { | |
1515 dropped_type_count_++; | |
1516 } | |
1517 } | |
1518 arr = Array::MakeArray(retained_types); | |
1519 cls.set_canonical_types(arr); | |
1520 } | 1494 } |
1521 } | 1495 } |
| 1496 types_table.Release(); |
1522 } | 1497 } |
| 1498 |
| 1499 // Now construct a new type table and save in the object store. |
| 1500 const intptr_t dict_size = |
| 1501 Utils::RoundUpToPowerOfTwo(retained_types.Length() * 4 / 3); |
| 1502 types_array = HashTables::New<CanonicalTypeSet>(dict_size, Heap::kOld); |
| 1503 CanonicalTypeSet types_table(Z, types_array.raw()); |
| 1504 bool present; |
| 1505 for (intptr_t i = 0; i < retained_types.Length(); i++) { |
| 1506 type ^= retained_types.At(i); |
| 1507 present = types_table.Insert(type); |
| 1508 ASSERT(!present); |
| 1509 } |
| 1510 object_store->set_canonical_types(types_table.Release()); |
1523 } | 1511 } |
1524 | 1512 |
1525 | 1513 |
1526 void Precompiler::DropTypeArguments() { | 1514 void Precompiler::DropTypeArguments() { |
1527 const Array& typeargs_table = | 1515 ObjectStore* object_store = I->object_store(); |
1528 Array::Handle(Z, I->object_store()->canonical_type_arguments()); | 1516 Array& typeargs_array = Array::Handle(Z); |
1529 GrowableObjectArray& retained_typeargs = | 1517 GrowableObjectArray& retained_typeargs = |
1530 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); | 1518 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
1531 TypeArguments& typeargs = TypeArguments::Handle(Z); | 1519 TypeArguments& typeargs = TypeArguments::Handle(Z); |
1532 for (intptr_t i = 0; i < (typeargs_table.Length() - 1); i++) { | 1520 // First drop all the type arguments that are not referenced. |
1533 typeargs ^= typeargs_table.At(i); | 1521 { |
1534 bool retain = typeargs_to_retain_.Lookup(&typeargs) != NULL; | 1522 CanonicalTypeArgumentsSet typeargs_table( |
1535 if (retain) { | 1523 Z, object_store->canonical_type_arguments()); |
1536 retained_typeargs.Add(typeargs); | 1524 typeargs_array = HashTables::ToArray(typeargs_table, false); |
1537 } else { | 1525 for (intptr_t i = 0; i < (typeargs_array.Length() - 1); i++) { |
1538 dropped_typearg_count_++; | 1526 typeargs ^= typeargs_array.At(i); |
| 1527 bool retain = typeargs_to_retain_.Lookup(&typeargs) != NULL; |
| 1528 if (retain) { |
| 1529 retained_typeargs.Add(typeargs); |
| 1530 } else { |
| 1531 dropped_typearg_count_++; |
| 1532 } |
1539 } | 1533 } |
| 1534 typeargs_table.Release(); |
1540 } | 1535 } |
1541 | 1536 |
| 1537 // Now construct a new type arguments table and save in the object store. |
1542 const intptr_t dict_size = | 1538 const intptr_t dict_size = |
1543 Utils::RoundUpToPowerOfTwo(retained_typeargs.Length() * 4 / 3); | 1539 Utils::RoundUpToPowerOfTwo(retained_typeargs.Length() * 4 / 3); |
1544 const Array& new_table = Array::Handle(Z, Array::New(dict_size + 1)); | 1540 typeargs_array = HashTables::New<CanonicalTypeArgumentsSet>(dict_size, |
1545 | 1541 Heap::kOld); |
1546 Object& element = Object::Handle(Z); | 1542 CanonicalTypeArgumentsSet typeargs_table(Z, typeargs_array.raw()); |
| 1543 bool present; |
1547 for (intptr_t i = 0; i < retained_typeargs.Length(); i++) { | 1544 for (intptr_t i = 0; i < retained_typeargs.Length(); i++) { |
1548 typeargs ^= retained_typeargs.At(i); | 1545 typeargs ^= retained_typeargs.At(i); |
1549 intptr_t hash = typeargs.Hash(); | 1546 present = typeargs_table.Insert(typeargs); |
1550 intptr_t index = hash & (dict_size - 1); | 1547 ASSERT(!present); |
1551 element = new_table.At(index); | |
1552 while (!element.IsNull()) { | |
1553 index = (index + 1) & (dict_size - 1); | |
1554 element = new_table.At(index); | |
1555 } | |
1556 new_table.SetAt(index, typeargs); | |
1557 } | 1548 } |
1558 | 1549 object_store->set_canonical_type_arguments(typeargs_table.Release()); |
1559 const Smi& used = Smi::Handle(Z, Smi::New(retained_typeargs.Length())); | |
1560 new_table.SetAt(dict_size, used); | |
1561 | |
1562 I->object_store()->set_canonical_type_arguments(new_table); | |
1563 } | 1550 } |
1564 | 1551 |
1565 | 1552 |
1566 void Precompiler::TraceTypesFromRetainedClasses() { | 1553 void Precompiler::TraceTypesFromRetainedClasses() { |
1567 Library& lib = Library::Handle(Z); | 1554 Library& lib = Library::Handle(Z); |
1568 Class& cls = Class::Handle(Z); | 1555 Class& cls = Class::Handle(Z); |
1569 Array& members = Array::Handle(Z); | 1556 Array& members = Array::Handle(Z); |
1570 Array& constants = Array::Handle(Z); | 1557 Array& constants = Array::Handle(Z); |
1571 GrowableObjectArray& retained_constants = GrowableObjectArray::Handle(Z); | 1558 GrowableObjectArray& retained_constants = GrowableObjectArray::Handle(Z); |
1572 Instance& constant = Instance::Handle(Z); | 1559 Instance& constant = Instance::Handle(Z); |
(...skipping 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2851 CompilationPipeline::New(thread->zone(), function); | 2838 CompilationPipeline::New(thread->zone(), function); |
2852 | 2839 |
2853 ASSERT(FLAG_precompiled_mode); | 2840 ASSERT(FLAG_precompiled_mode); |
2854 const bool optimized = function.IsOptimizable(); // False for natives. | 2841 const bool optimized = function.IsOptimizable(); // False for natives. |
2855 return PrecompileFunctionHelper(pipeline, function, optimized); | 2842 return PrecompileFunctionHelper(pipeline, function, optimized); |
2856 } | 2843 } |
2857 | 2844 |
2858 #endif // DART_PRECOMPILER | 2845 #endif // DART_PRECOMPILER |
2859 | 2846 |
2860 } // namespace dart | 2847 } // namespace dart |
OLD | NEW |