Chromium Code Reviews| 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" |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 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 | 33 // Removes optimized code once we load more classes, since --use_cha based |
| 34 // optimizations may have become invalid. | 34 // optimizations may have become invalid. |
| 35 // TODO(srdjan): Note which functions use which CHA decision and deoptimize | 35 // Only methods which owner classes where subclasses can be invalid. |
| 36 // only the necessary ones. | 36 // TODO(srdjan): Be even more precise by recording the exact CHA optimziation. |
|
Florian Schneider
2012/11/15 00:46:06
s/optimziation/optimization/
srdjan
2012/11/15 01:04:44
Done.
| |
| 37 static void RemoveOptimizedCode() { | 37 static void RemoveOptimizedCode( |
| 38 const GrowableArray<intptr_t>& added_subclasses_to_cids) { | |
| 38 ASSERT(FLAG_use_cha); | 39 ASSERT(FLAG_use_cha); |
| 40 if (added_subclasses_to_cids.is_empty()) return; | |
| 39 // Deoptimize all live frames. | 41 // Deoptimize all live frames. |
| 40 DeoptimizeAll(); | 42 DeoptimizeAll(); |
| 41 // Switch all functions' code to unoptimized. | 43 // Switch all functions' code to unoptimized. |
| 42 const ClassTable& class_table = *Isolate::Current()->class_table(); | 44 const ClassTable& class_table = *Isolate::Current()->class_table(); |
| 43 Class& cls = Class::Handle(); | 45 Class& cls = Class::Handle(); |
| 44 Array& array = Array::Handle(); | 46 Array& array = Array::Handle(); |
| 45 Function& function = Function::Handle(); | 47 Function& function = Function::Handle(); |
| 46 const intptr_t num_cids = class_table.NumCids(); | 48 for (intptr_t i = 0; i < added_subclasses_to_cids.length(); i++) { |
| 47 for (intptr_t i = kInstanceCid; i < num_cids; i++) { | 49 intptr_t cid = added_subclasses_to_cids[i]; |
| 48 if (!class_table.HasValidClassAt(i)) continue; | 50 cls = class_table.At(cid); |
| 49 cls = class_table.At(i); | |
| 50 ASSERT(!cls.IsNull()); | 51 ASSERT(!cls.IsNull()); |
| 51 array = cls.functions(); | 52 array = cls.functions(); |
| 52 intptr_t num_functions = array.IsNull() ? 0 : array.Length(); | 53 intptr_t num_functions = array.IsNull() ? 0 : array.Length(); |
| 53 for (intptr_t f = 0; f < num_functions; f++) { | 54 for (intptr_t f = 0; f < num_functions; f++) { |
| 54 function ^= array.At(f); | 55 function ^= array.At(f); |
| 55 ASSERT(!function.IsNull()); | 56 ASSERT(!function.IsNull()); |
| 56 if (function.HasOptimizedCode()) { | 57 if (function.HasOptimizedCode()) { |
| 57 function.SwitchToUnoptimizedCode(); | 58 function.SwitchToUnoptimizedCode(); |
| 58 } | 59 } |
| 59 } | 60 } |
| 60 } | 61 } |
| 61 } | 62 } |
| 62 | 63 |
| 63 | 64 |
| 65 void AddSuperType(const Type& type, | |
| 66 GrowableArray<intptr_t>* finalized_super_classes) { | |
| 67 ASSERT(type.HasResolvedTypeClass()); | |
| 68 if (type.IsObjectType()) { | |
| 69 return; | |
| 70 } | |
| 71 const Class& cls = Class::Handle(type.type_class()); | |
| 72 ASSERT(cls.is_finalized()); | |
| 73 const intptr_t cid = cls.id(); | |
| 74 for (intptr_t i = 0; i < finalized_super_classes->length(); i++) { | |
| 75 if ((*finalized_super_classes)[i] == cid) { | |
| 76 // Already added. | |
| 77 return; | |
| 78 } | |
| 79 } | |
| 80 finalized_super_classes->Add(cid); | |
| 81 const Type& super_type = Type::Handle(cls.super_type()); | |
| 82 AddSuperType(super_type, finalized_super_classes); | |
| 83 } | |
| 84 | |
| 85 | |
| 86 // Use array instead of set since we expect very few subclassed classes | |
| 87 // to occur. | |
| 88 static void CollectFinalizedSuperClasses( | |
| 89 const GrowableObjectArray& pending_classes, | |
| 90 GrowableArray<intptr_t>* finalized_super_classes) { | |
| 91 Class& cls = Class::Handle(); | |
| 92 Type& super_type = Type::Handle(); | |
| 93 for (intptr_t i = 0; i < pending_classes.Length(); i++) { | |
| 94 cls ^= pending_classes.At(i); | |
| 95 ASSERT(!cls.is_finalized()); | |
| 96 super_type ^= cls.super_type(); | |
| 97 if (!super_type.IsNull()) { | |
| 98 if (super_type.HasResolvedTypeClass() && | |
| 99 Class::Handle(super_type.type_class()).is_finalized()) { | |
| 100 AddSuperType(super_type, finalized_super_classes); | |
| 101 } | |
| 102 } | |
| 103 } | |
| 104 } | |
| 105 | |
| 106 | |
| 64 // Class finalization occurs: | 107 // Class finalization occurs: |
| 65 // a) when bootstrap process completes (VerifyBootstrapClasses). | 108 // a) when bootstrap process completes (VerifyBootstrapClasses). |
| 66 // b) after the user classes are loaded (dart_api). | 109 // b) after the user classes are loaded (dart_api). |
| 67 bool ClassFinalizer::FinalizePendingClasses() { | 110 bool ClassFinalizer::FinalizePendingClasses() { |
| 68 bool retval = true; | 111 bool retval = true; |
| 69 Isolate* isolate = Isolate::Current(); | 112 Isolate* isolate = Isolate::Current(); |
| 70 ASSERT(isolate != NULL); | 113 ASSERT(isolate != NULL); |
| 71 ObjectStore* object_store = isolate->object_store(); | 114 ObjectStore* object_store = isolate->object_store(); |
| 72 const Error& error = Error::Handle(object_store->sticky_error()); | 115 const Error& error = Error::Handle(object_store->sticky_error()); |
| 73 if (!error.IsNull()) { | 116 if (!error.IsNull()) { |
| 74 return false; | 117 return false; |
| 75 } | 118 } |
| 76 if (AllClassesFinalized()) { | 119 if (AllClassesFinalized()) { |
| 77 return true; | 120 return true; |
| 78 } | 121 } |
| 122 | |
| 123 GrowableArray<intptr_t> added_subclasses_to_cids; | |
| 79 LongJump* base = isolate->long_jump_base(); | 124 LongJump* base = isolate->long_jump_base(); |
| 80 LongJump jump; | 125 LongJump jump; |
| 81 isolate->set_long_jump_base(&jump); | 126 isolate->set_long_jump_base(&jump); |
| 82 if (setjmp(*jump.Set()) == 0) { | 127 if (setjmp(*jump.Set()) == 0) { |
| 83 GrowableObjectArray& class_array = GrowableObjectArray::Handle(); | 128 GrowableObjectArray& class_array = GrowableObjectArray::Handle(); |
| 84 class_array = object_store->pending_classes(); | 129 class_array = object_store->pending_classes(); |
| 85 ASSERT(!class_array.IsNull()); | 130 ASSERT(!class_array.IsNull()); |
| 131 // Collect superclasses that were already finalized before this run of | |
| 132 // finalization. | |
| 133 CollectFinalizedSuperClasses(class_array, &added_subclasses_to_cids); | |
| 86 Class& cls = Class::Handle(); | 134 Class& cls = Class::Handle(); |
| 87 // First resolve all superclasses. | 135 // First resolve all superclasses. |
| 88 for (intptr_t i = 0; i < class_array.Length(); i++) { | 136 for (intptr_t i = 0; i < class_array.Length(); i++) { |
| 89 cls ^= class_array.At(i); | 137 cls ^= class_array.At(i); |
| 90 if (FLAG_trace_class_finalization) { | 138 if (FLAG_trace_class_finalization) { |
| 91 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString()); | 139 OS::Print("Resolving super and interfaces: %s\n", cls.ToCString()); |
| 92 } | 140 } |
| 93 ResolveSuperType(cls); | 141 ResolveSuperType(cls); |
| 94 if (cls.is_interface()) { | 142 if (cls.is_interface()) { |
| 95 ResolveFactoryClass(cls); | 143 ResolveFactoryClass(cls); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 109 } | 157 } |
| 110 } | 158 } |
| 111 // Clear pending classes array. | 159 // Clear pending classes array. |
| 112 class_array = GrowableObjectArray::New(); | 160 class_array = GrowableObjectArray::New(); |
| 113 object_store->set_pending_classes(class_array); | 161 object_store->set_pending_classes(class_array); |
| 114 } else { | 162 } else { |
| 115 retval = false; | 163 retval = false; |
| 116 } | 164 } |
| 117 isolate->set_long_jump_base(base); | 165 isolate->set_long_jump_base(base); |
| 118 if (FLAG_use_cha) { | 166 if (FLAG_use_cha) { |
| 119 RemoveOptimizedCode(); | 167 RemoveOptimizedCode(added_subclasses_to_cids); |
| 120 } | 168 } |
| 121 return retval; | 169 return retval; |
| 122 } | 170 } |
| 123 | 171 |
| 124 | 172 |
| 125 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. | 173 // Adds all interfaces of cls into 'collected'. Duplicate entries may occur. |
| 126 // No cycles are allowed. | 174 // No cycles are allowed. |
| 127 void ClassFinalizer::CollectInterfaces(const Class& cls, | 175 void ClassFinalizer::CollectInterfaces(const Class& cls, |
| 128 const GrowableObjectArray& collected) { | 176 const GrowableObjectArray& collected) { |
| 129 const Array& interface_array = Array::ZoneHandle(cls.interfaces()); | 177 const Array& interface_array = Array::ZoneHandle(cls.interfaces()); |
| (...skipping 1519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1649 void ClassFinalizer::ReportError(const char* format, ...) { | 1697 void ClassFinalizer::ReportError(const char* format, ...) { |
| 1650 va_list args; | 1698 va_list args; |
| 1651 va_start(args, format); | 1699 va_start(args, format); |
| 1652 const Error& error = Error::Handle( | 1700 const Error& error = Error::Handle( |
| 1653 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); | 1701 Parser::FormatError(Script::Handle(), -1, "Error", format, args)); |
| 1654 va_end(args); | 1702 va_end(args); |
| 1655 ReportError(error); | 1703 ReportError(error); |
| 1656 } | 1704 } |
| 1657 | 1705 |
| 1658 } // namespace dart | 1706 } // namespace dart |
| OLD | NEW |