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

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

Issue 11365273: Upon script loading deoptimize only functions whose owner has been subclassed, as that is the only… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/code_generator.cc » ('j') | runtime/vm/code_generator.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/code_generator.cc » ('j') | runtime/vm/code_generator.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698