| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/class_finalizer.h" | 5 #include "vm/class_finalizer.h" |
| 6 | 6 |
| 7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| 11 #include "vm/object_store.h" | 11 #include "vm/object_store.h" |
| 12 #include "vm/parser.h" | 12 #include "vm/parser.h" |
| 13 #include "vm/symbols.h" | 13 #include "vm/symbols.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 DEFINE_FLAG(bool, error_on_malformed_type, false, | 17 DEFINE_FLAG(bool, error_on_malformed_type, false, |
| 18 "Report error for malformed types."); | 18 "Report error for malformed types."); |
| 19 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); | 19 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes."); |
| 20 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); | 20 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization."); |
| 21 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); | 21 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization."); |
| 22 DECLARE_FLAG(bool, enable_type_checks); | 22 DECLARE_FLAG(bool, enable_type_checks); |
| 23 | 23 DECLARE_FLAG(bool, use_cha); |
| 24 | 24 |
| 25 bool ClassFinalizer::AllClassesFinalized() { | 25 bool ClassFinalizer::AllClassesFinalized() { |
| 26 ObjectStore* object_store = Isolate::Current()->object_store(); | 26 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 27 const GrowableObjectArray& classes = | 27 const GrowableObjectArray& classes = |
| 28 GrowableObjectArray::Handle(object_store->pending_classes()); | 28 GrowableObjectArray::Handle(object_store->pending_classes()); |
| 29 return classes.Length() == 0; | 29 return classes.Length() == 0; |
| 30 } | 30 } |
| 31 | 31 |
| 32 | 32 |
| 33 // Removes optimized code once we load more classes, since --use_cha based |
| 34 // optimizations may have become invalid. |
| 35 // TODO(srdjan): Note which functions use which CHA decision and deoptimize |
| 36 // only the necessary ones. |
| 37 static void RemoveOptimizedCode() { |
| 38 ASSERT(FLAG_use_cha); |
| 39 // Deoptimize all live frames. |
| 40 DeoptimizeAll(); |
| 41 // Switch all functions' code to unoptimized. |
| 42 const ClassTable& class_table = *Isolate::Current()->class_table(); |
| 43 Class& cls = Class::Handle(); |
| 44 Array& array = Array::Handle(); |
| 45 Function& function = Function::Handle(); |
| 46 const intptr_t num_cids = class_table.NumCids(); |
| 47 for (intptr_t i = kInstanceCid; i < num_cids; i++) { |
| 48 if (!class_table.HasValidClassAt(i)) continue; |
| 49 cls = class_table.At(i); |
| 50 ASSERT(!cls.IsNull()); |
| 51 array = cls.functions(); |
| 52 intptr_t num_functions = array.IsNull() ? 0 : array.Length(); |
| 53 for (intptr_t f = 0; f < num_functions; f++) { |
| 54 function ^= array.At(f); |
| 55 ASSERT(!function.IsNull()); |
| 56 if (function.HasOptimizedCode()) { |
| 57 function.SwitchToUnoptimizedCode(); |
| 58 } |
| 59 } |
| 60 } |
| 61 } |
| 62 |
| 63 |
| 33 // Class finalization occurs: | 64 // Class finalization occurs: |
| 34 // a) when bootstrap process completes (VerifyBootstrapClasses). | 65 // a) when bootstrap process completes (VerifyBootstrapClasses). |
| 35 // b) after the user classes are loaded (dart_api). | 66 // b) after the user classes are loaded (dart_api). |
| 36 bool ClassFinalizer::FinalizePendingClasses() { | 67 bool ClassFinalizer::FinalizePendingClasses() { |
| 37 bool retval = true; | 68 bool retval = true; |
| 38 Isolate* isolate = Isolate::Current(); | 69 Isolate* isolate = Isolate::Current(); |
| 39 ASSERT(isolate != NULL); | 70 ASSERT(isolate != NULL); |
| 40 ObjectStore* object_store = isolate->object_store(); | 71 ObjectStore* object_store = isolate->object_store(); |
| 41 const Error& error = Error::Handle(object_store->sticky_error()); | 72 const Error& error = Error::Handle(object_store->sticky_error()); |
| 42 if (!error.IsNull()) { | 73 if (!error.IsNull()) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 PrintClassInformation(cls); | 108 PrintClassInformation(cls); |
| 78 } | 109 } |
| 79 } | 110 } |
| 80 // Clear pending classes array. | 111 // Clear pending classes array. |
| 81 class_array = GrowableObjectArray::New(); | 112 class_array = GrowableObjectArray::New(); |
| 82 object_store->set_pending_classes(class_array); | 113 object_store->set_pending_classes(class_array); |
| 83 } else { | 114 } else { |
| 84 retval = false; | 115 retval = false; |
| 85 } | 116 } |
| 86 isolate->set_long_jump_base(base); | 117 isolate->set_long_jump_base(base); |
| 118 if (FLAG_use_cha) { |
| 119 RemoveOptimizedCode(); |
| 120 } |
| 87 return retval; | 121 return retval; |
| 88 } | 122 } |
| 89 | 123 |
| 90 | 124 |
| 91 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. | 125 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. |
| 92 // No cycles are allowed. | 126 // No cycles are allowed. |
| 93 void ClassFinalizer::CollectInterfaces(const Class& cls, | 127 void ClassFinalizer::CollectInterfaces(const Class& cls, |
| 94 const GrowableObjectArray& collected) { | 128 const GrowableObjectArray& collected) { |
| 95 const Array& interface_array = Array::ZoneHandle(cls.interfaces()); | 129 const Array& interface_array = Array::ZoneHandle(cls.interfaces()); |
| 96 AbstractType& interface = AbstractType::Handle(); | 130 AbstractType& interface = AbstractType::Handle(); |
| (...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1615 void ClassFinalizer::ReportError(const char* format, ...) { | 1649 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1616 va_list args; | 1650 va_list args; |
| 1617 va_start(args, format); | 1651 va_start(args, format); |
| 1618 const Error& error = Error::Handle( | 1652 const Error& error = Error::Handle( |
| 1619 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1653 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1620 va_end(args); | 1654 va_end(args); |
| 1621 ReportError(error); | 1655 ReportError(error); |
| 1622 } | 1656 } |
| 1623 | 1657 |
| 1624 } // namespace dart | 1658 } // namespace dart |
| OLD | NEW |