Chromium Code Reviews| 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 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 191 { | 191 { |
| 192 StackZone stack_zone(T); | 192 StackZone stack_zone(T); |
| 193 zone_ = stack_zone.GetZone(); | 193 zone_ = stack_zone.GetZone(); |
| 194 | 194 |
| 195 { HANDLESCOPE(T); | 195 { HANDLESCOPE(T); |
| 196 // Make sure class hierarchy is stable before compilation so that CHA | 196 // Make sure class hierarchy is stable before compilation so that CHA |
| 197 // can be used. Also ensures lookup of entry points won't miss functions | 197 // can be used. Also ensures lookup of entry points won't miss functions |
| 198 // because their class hasn't been finalized yet. | 198 // because their class hasn't been finalized yet. |
| 199 FinalizeAllClasses(); | 199 FinalizeAllClasses(); |
| 200 | 200 |
| 201 SortClasses(); | |
| 202 | |
| 201 // Precompile static initializers to compute result type information. | 203 // Precompile static initializers to compute result type information. |
| 202 PrecompileStaticInitializers(); | 204 PrecompileStaticInitializers(); |
| 203 | 205 |
| 204 for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) { | 206 for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) { |
| 205 if (FLAG_trace_precompiler) { | 207 if (FLAG_trace_precompiler) { |
| 206 THR_Print("Precompiler round %" Pd "\n", round); | 208 THR_Print("Precompiler round %" Pd "\n", round); |
| 207 } | 209 } |
| 208 | 210 |
| 209 if (round > 0) { | 211 if (round > 0) { |
| 210 ResetPrecompilerState(); | 212 ResetPrecompilerState(); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 337 } | 339 } |
| 338 | 340 |
| 339 | 341 |
| 340 void Precompiler::ClearAllCode() { | 342 void Precompiler::ClearAllCode() { |
| 341 class ClearCodeFunctionVisitor : public FunctionVisitor { | 343 class ClearCodeFunctionVisitor : public FunctionVisitor { |
| 342 void Visit(const Function& function) { | 344 void Visit(const Function& function) { |
| 343 function.ClearCode(); | 345 function.ClearCode(); |
| 344 function.ClearICDataArray(); | 346 function.ClearICDataArray(); |
| 345 } | 347 } |
| 346 }; | 348 }; |
| 347 ClearCodeFunctionVisitor visitor; | 349 ClearCodeFunctionVisitor function_visitor; |
| 348 VisitFunctions(&visitor); | 350 VisitFunctions(&function_visitor); |
| 351 | |
| 352 class ClearCodeClassVisitor : public ClassVisitor { | |
| 353 void Visit(const Class& cls) { | |
| 354 cls.DisableAllocationStub(); | |
| 355 } | |
| 356 }; | |
| 357 ClearCodeClassVisitor class_visitor; | |
| 358 VisitClasses(&class_visitor); | |
| 349 } | 359 } |
| 350 | 360 |
| 351 | 361 |
| 352 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) { | 362 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) { |
| 353 // Note that <rootlibrary>.main is not a root. The appropriate main will be | 363 // Note that <rootlibrary>.main is not a root. The appropriate main will be |
| 354 // discovered through _getMainClosure. | 364 // discovered through _getMainClosure. |
| 355 | 365 |
| 356 AddSelector(Symbols::NoSuchMethod()); | 366 AddSelector(Symbols::NoSuchMethod()); |
| 357 | 367 |
| 358 AddSelector(Symbols::Call()); // For speed, not correctness. | 368 AddSelector(Symbols::Call()); // For speed, not correctness. |
| (...skipping 1840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2199 error_ = cls.EnsureIsFinalized(T); | 2209 error_ = cls.EnsureIsFinalized(T); |
| 2200 if (!error_.IsNull()) { | 2210 if (!error_.IsNull()) { |
| 2201 Jump(error_); | 2211 Jump(error_); |
| 2202 } | 2212 } |
| 2203 } | 2213 } |
| 2204 } | 2214 } |
| 2205 I->set_all_classes_finalized(true); | 2215 I->set_all_classes_finalized(true); |
| 2206 } | 2216 } |
| 2207 | 2217 |
| 2208 | 2218 |
| 2219 void Precompiler::SortClasses() { | |
| 2220 ClassTable* table = I->class_table(); | |
| 2221 intptr_t num_cids = table->NumCids(); | |
| 2222 intptr_t* old_to_new_cid = new intptr_t[num_cids]; | |
| 2223 for (intptr_t cid = 0; cid < kNumPredefinedCids; cid++) { | |
| 2224 old_to_new_cid[cid] = cid; // The predefined classes cannot change cids. | |
| 2225 } | |
| 2226 for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) { | |
| 2227 old_to_new_cid[cid] = -1; | |
| 2228 } | |
| 2229 | |
| 2230 intptr_t next_new_cid = kNumPredefinedCids; | |
| 2231 GrowableArray<intptr_t> dfs_stack; | |
| 2232 Class& cls = Class::Handle(Z); | |
| 2233 GrowableObjectArray& subclasses = GrowableObjectArray::Handle(Z); | |
| 2234 | |
| 2235 // Object doesn't use its subclasses list. | |
| 2236 for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) { | |
| 2237 if (!table->HasValidClassAt(cid)) { | |
| 2238 continue; | |
| 2239 } | |
| 2240 cls = table->At(cid); | |
| 2241 if (cls.is_patch()) { | |
| 2242 continue; | |
| 2243 } | |
| 2244 cls = cls.SuperClass(); | |
| 2245 if (!cls.IsNull() && cls.IsObjectClass()) { | |
|
Florian Schneider
2016/08/26 22:14:34
cls.SuperClass() == I->object_store()->object_clas
rmacnak
2016/08/26 23:12:32
Done.
| |
| 2246 dfs_stack.Add(cid); | |
| 2247 } | |
| 2248 } | |
| 2249 | |
| 2250 while (dfs_stack.length() > 0) { | |
| 2251 intptr_t cid = dfs_stack.RemoveLast(); | |
| 2252 ASSERT(table->HasValidClassAt(cid)); | |
| 2253 cls = table->At(cid); | |
| 2254 ASSERT(!cls.IsNull()); | |
| 2255 if (old_to_new_cid[cid] == -1) { | |
| 2256 old_to_new_cid[cid] = next_new_cid++; | |
| 2257 if (FLAG_trace_precompiler) { | |
| 2258 THR_Print("%" Pd ": %s, was %" Pd "\n", | |
| 2259 old_to_new_cid[cid], cls.ToCString(), cid); | |
| 2260 } | |
| 2261 } | |
| 2262 subclasses = cls.direct_subclasses(); | |
| 2263 if (!subclasses.IsNull()) { | |
| 2264 for (intptr_t i = 0; i < subclasses.Length(); i++) { | |
| 2265 cls ^= subclasses.At(i); | |
| 2266 ASSERT(!cls.IsNull()); | |
| 2267 dfs_stack.Add(cls.id()); | |
| 2268 } | |
| 2269 } | |
| 2270 } | |
| 2271 | |
| 2272 // Top-level classes, typedefs, patch classes, etc. | |
| 2273 for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) { | |
| 2274 if (old_to_new_cid[cid] == -1) { | |
| 2275 old_to_new_cid[cid] = next_new_cid++; | |
| 2276 if (FLAG_trace_precompiler && table->HasValidClassAt(cid)) { | |
| 2277 cls = table->At(cid); | |
| 2278 THR_Print("%" Pd ": %s, was %" Pd "\n", | |
| 2279 old_to_new_cid[cid], cls.ToCString(), cid); | |
| 2280 } | |
| 2281 } | |
| 2282 } | |
| 2283 ASSERT(next_new_cid == num_cids); | |
| 2284 | |
| 2285 RemapClassIds(old_to_new_cid); | |
| 2286 delete[] old_to_new_cid; | |
| 2287 } | |
| 2288 | |
| 2289 | |
| 2290 class CidRewriteVisitor : public ObjectVisitor { | |
| 2291 public: | |
| 2292 explicit CidRewriteVisitor(intptr_t* old_to_new_cids) | |
| 2293 : old_to_new_cids_(old_to_new_cids) { } | |
| 2294 | |
| 2295 intptr_t Map(intptr_t cid) { | |
| 2296 ASSERT(cid != -1); | |
| 2297 return old_to_new_cids_[cid]; | |
| 2298 } | |
| 2299 | |
| 2300 void VisitObject(RawObject* obj) { | |
| 2301 if (obj->IsClass()) { | |
| 2302 RawClass* cls = Class::RawCast(obj); | |
| 2303 cls->ptr()->id_ = Map(cls->ptr()->id_); | |
| 2304 } else if (obj->IsField()) { | |
| 2305 RawField* field = Field::RawCast(obj); | |
| 2306 field->ptr()->guarded_cid_ = Map(field->ptr()->guarded_cid_); | |
| 2307 field->ptr()->is_nullable_ = Map(field->ptr()->is_nullable_); | |
| 2308 } else if (obj->IsTypeParameter()) { | |
| 2309 RawTypeParameter* param = TypeParameter::RawCast(obj); | |
| 2310 param->ptr()->parameterized_class_id_ = | |
| 2311 Map(param->ptr()->parameterized_class_id_); | |
| 2312 } else if (obj->IsType()) { | |
| 2313 RawType* type = Type::RawCast(obj); | |
| 2314 RawObject* id = type->ptr()->type_class_id_; | |
| 2315 if (!id->IsHeapObject()) { | |
| 2316 type->ptr()->type_class_id_ = | |
| 2317 Smi::New(Map(Smi::Value(Smi::RawCast(id)))); | |
| 2318 } | |
| 2319 } else { | |
| 2320 intptr_t old_cid = obj->GetClassId(); | |
| 2321 intptr_t new_cid = Map(old_cid); | |
| 2322 if (old_cid != new_cid) { | |
| 2323 // Don't touch objects that are unchanged. In particular, Instructions, | |
| 2324 // which are write-protected. | |
| 2325 obj->SetClassId(new_cid); | |
| 2326 } | |
| 2327 } | |
| 2328 } | |
| 2329 | |
| 2330 private: | |
| 2331 intptr_t* old_to_new_cids_; | |
| 2332 }; | |
| 2333 | |
| 2334 void Precompiler::RemapClassIds(intptr_t old_to_new_cid[]) { | |
| 2335 // Code, ICData, allocation stubs have now-invalid cids. | |
| 2336 ClearAllCode(); | |
| 2337 | |
| 2338 { | |
| 2339 HeapIterationScope his; | |
| 2340 | |
| 2341 // Update the class table. Do it before rewriting cids in headers, as the | |
| 2342 // heap walkers load an object's size *after* calling the visitor. | |
| 2343 I->class_table()->Remap(old_to_new_cid); | |
| 2344 | |
| 2345 // Rewrite cids in headers and cids in Classes, Fields, Types and | |
| 2346 // TypeParameters. | |
| 2347 { | |
| 2348 CidRewriteVisitor visitor(old_to_new_cid); | |
| 2349 I->heap()->VisitObjects(&visitor); | |
| 2350 } | |
| 2351 } | |
| 2352 | |
| 2353 #if defined(DEBUG) | |
| 2354 I->class_table()->Validate(); | |
| 2355 I->heap()->Verify(); | |
| 2356 #endif | |
| 2357 } | |
| 2358 | |
| 2359 | |
| 2209 void Precompiler::ResetPrecompilerState() { | 2360 void Precompiler::ResetPrecompilerState() { |
| 2210 changed_ = false; | 2361 changed_ = false; |
| 2211 function_count_ = 0; | 2362 function_count_ = 0; |
| 2212 class_count_ = 0; | 2363 class_count_ = 0; |
| 2213 selector_count_ = 0; | 2364 selector_count_ = 0; |
| 2214 dropped_function_count_ = 0; | 2365 dropped_function_count_ = 0; |
| 2215 dropped_field_count_ = 0; | 2366 dropped_field_count_ = 0; |
| 2216 ASSERT(pending_functions_.Length() == 0); | 2367 ASSERT(pending_functions_.Length() == 0); |
| 2217 sent_selectors_.Clear(); | 2368 sent_selectors_.Clear(); |
| 2218 enqueued_functions_.Clear(); | 2369 enqueued_functions_.Clear(); |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2930 CompilationPipeline::New(thread->zone(), function); | 3081 CompilationPipeline::New(thread->zone(), function); |
| 2931 | 3082 |
| 2932 ASSERT(FLAG_precompiled_mode); | 3083 ASSERT(FLAG_precompiled_mode); |
| 2933 const bool optimized = function.IsOptimizable(); // False for natives. | 3084 const bool optimized = function.IsOptimizable(); // False for natives. |
| 2934 return PrecompileFunctionHelper(pipeline, function, optimized); | 3085 return PrecompileFunctionHelper(pipeline, function, optimized); |
| 2935 } | 3086 } |
| 2936 | 3087 |
| 2937 #endif // DART_PRECOMPILER | 3088 #endif // DART_PRECOMPILER |
| 2938 | 3089 |
| 2939 } // namespace dart | 3090 } // namespace dart |
| OLD | NEW |