| 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/assembler.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/branch_optimizer.h" | 9 #include "vm/branch_optimizer.h" |
| 10 #include "vm/cha.h" | 10 #include "vm/cha.h" |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 thread_(thread), | 133 thread_(thread), |
| 134 zone_(NULL), | 134 zone_(NULL), |
| 135 isolate_(thread->isolate()), | 135 isolate_(thread->isolate()), |
| 136 reset_fields_(reset_fields), | 136 reset_fields_(reset_fields), |
| 137 changed_(false), | 137 changed_(false), |
| 138 function_count_(0), | 138 function_count_(0), |
| 139 class_count_(0), | 139 class_count_(0), |
| 140 selector_count_(0), | 140 selector_count_(0), |
| 141 dropped_function_count_(0), | 141 dropped_function_count_(0), |
| 142 dropped_field_count_(0), | 142 dropped_field_count_(0), |
| 143 dropped_class_count_(0), |
| 144 dropped_typearg_count_(0), |
| 145 dropped_type_count_(0), |
| 146 dropped_library_count_(0), |
| 143 libraries_(GrowableObjectArray::Handle(I->object_store()->libraries())), | 147 libraries_(GrowableObjectArray::Handle(I->object_store()->libraries())), |
| 144 pending_functions_( | 148 pending_functions_( |
| 145 GrowableObjectArray::Handle(GrowableObjectArray::New())), | 149 GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| 146 sent_selectors_(), | 150 sent_selectors_(), |
| 147 enqueued_functions_(), | 151 enqueued_functions_(), |
| 148 fields_to_retain_(), | 152 fields_to_retain_(), |
| 153 classes_to_retain_(), |
| 154 typeargs_to_retain_(), |
| 155 types_to_retain_(), |
| 149 error_(Error::Handle()) { | 156 error_(Error::Handle()) { |
| 150 } | 157 } |
| 151 | 158 |
| 152 | 159 |
| 153 void Precompiler::DoCompileAll( | 160 void Precompiler::DoCompileAll( |
| 154 Dart_QualifiedFunctionName embedder_entry_points[]) { | 161 Dart_QualifiedFunctionName embedder_entry_points[]) { |
| 155 ASSERT(I->compilation_allowed()); | 162 ASSERT(I->compilation_allowed()); |
| 156 | 163 |
| 157 { | 164 { |
| 158 StackZone stack_zone(T); | 165 StackZone stack_zone(T); |
| 159 zone_ = stack_zone.GetZone(); | 166 zone_ = stack_zone.GetZone(); |
| 160 | 167 |
| 161 // Make sure class hierarchy is stable before compilation so that CHA | 168 // Make sure class hierarchy is stable before compilation so that CHA |
| 162 // can be used. Also ensures lookup of entry points won't miss functions | 169 // can be used. Also ensures lookup of entry points won't miss functions |
| 163 // because their class hasn't been finalized yet. | 170 // because their class hasn't been finalized yet. |
| 164 FinalizeAllClasses(); | 171 FinalizeAllClasses(); |
| 165 | 172 |
| 166 const intptr_t kPrecompilerRounds = 1; | 173 const intptr_t kPrecompilerRounds = 1; |
| 167 for (intptr_t round = 0; round < kPrecompilerRounds; round++) { | 174 for (intptr_t round = 0; round < kPrecompilerRounds; round++) { |
| 168 if (FLAG_trace_precompiler) { | 175 if (FLAG_trace_precompiler) { |
| 169 OS::Print("Precompiler round %" Pd "\n", round); | 176 THR_Print("Precompiler round %" Pd "\n", round); |
| 170 } | 177 } |
| 171 | 178 |
| 172 if (round > 0) { | 179 if (round > 0) { |
| 173 ResetPrecompilerState(); | 180 ResetPrecompilerState(); |
| 174 } | 181 } |
| 175 | 182 |
| 176 // TODO(rmacnak): We should be able to do a more thorough job and drop | 183 // TODO(rmacnak): We should be able to do a more thorough job and drop |
| 177 // some | 184 // some |
| 178 // - implicit static closures | 185 // - implicit static closures |
| 179 // - field initializers | 186 // - field initializers |
| (...skipping 10 matching lines...) Expand all Loading... |
| 190 | 197 |
| 191 // Compile newly found targets and add their callees until we reach a | 198 // Compile newly found targets and add their callees until we reach a |
| 192 // fixed point. | 199 // fixed point. |
| 193 Iterate(); | 200 Iterate(); |
| 194 } | 201 } |
| 195 | 202 |
| 196 I->set_compilation_allowed(false); | 203 I->set_compilation_allowed(false); |
| 197 | 204 |
| 198 DropFunctions(); | 205 DropFunctions(); |
| 199 DropFields(); | 206 DropFields(); |
| 200 | 207 TraceTypesFromRetainedClasses(); |
| 201 // TODO(rmacnak): DropEmptyClasses(); | 208 DropTypes(); |
| 209 DropTypeArguments(); |
| 210 DropClasses(); |
| 211 DropLibraries(); |
| 202 | 212 |
| 203 BindStaticCalls(); | 213 BindStaticCalls(); |
| 204 | 214 |
| 205 DedupStackmaps(); | 215 DedupStackmaps(); |
| 206 DedupStackmapLists(); | 216 DedupStackmapLists(); |
| 207 | 217 |
| 208 if (FLAG_dedup_instructions) { | 218 if (FLAG_dedup_instructions) { |
| 209 // Reduces binary size but obfuscates profiler results. | 219 // Reduces binary size but obfuscates profiler results. |
| 210 DedupInstructions(); | 220 DedupInstructions(); |
| 211 } | 221 } |
| 212 | 222 |
| 213 I->object_store()->set_compile_time_constants(Array::null_array()); | 223 I->object_store()->set_compile_time_constants(Array::null_array()); |
| 214 I->object_store()->set_unique_dynamic_targets(Array::null_array()); | 224 I->object_store()->set_unique_dynamic_targets(Array::null_array()); |
| 215 | 225 |
| 216 zone_ = NULL; | 226 zone_ = NULL; |
| 217 } | 227 } |
| 218 | 228 |
| 219 intptr_t dropped_symbols_count = Symbols::Compact(I); | 229 intptr_t dropped_symbols_count = Symbols::Compact(I); |
| 220 | 230 |
| 221 if (FLAG_trace_precompiler) { | 231 if (FLAG_trace_precompiler) { |
| 222 THR_Print("Precompiled %" Pd " functions, %" Pd " dynamic types," | 232 THR_Print("Precompiled %" Pd " functions,", function_count_); |
| 223 " %" Pd " dynamic selectors.\n Dropped %" Pd " functions, %" Pd | 233 THR_Print(" %" Pd " dynamic types,", class_count_); |
| 224 " fields, %" Pd " symbols.\n", | 234 THR_Print(" %" Pd " dynamic selectors.\n", selector_count_); |
| 225 function_count_, | 235 |
| 226 class_count_, | 236 THR_Print("Dropped %" Pd " functions,", dropped_function_count_); |
| 227 selector_count_, | 237 THR_Print(" %" Pd " fields,", dropped_field_count_); |
| 228 dropped_function_count_, | 238 THR_Print(" %" Pd " symbols,", dropped_symbols_count); |
| 229 dropped_field_count_, | 239 THR_Print(" %" Pd " types,", dropped_type_count_); |
| 230 dropped_symbols_count); | 240 THR_Print(" %" Pd " type arguments,", dropped_typearg_count_); |
| 241 THR_Print(" %" Pd " classes,", dropped_class_count_); |
| 242 THR_Print(" %" Pd " libraries.\n", dropped_library_count_); |
| 231 } | 243 } |
| 232 } | 244 } |
| 233 | 245 |
| 234 | 246 |
| 235 void Precompiler::ClearAllCode() { | 247 void Precompiler::ClearAllCode() { |
| 236 class ClearCodeFunctionVisitor : public FunctionVisitor { | 248 class ClearCodeFunctionVisitor : public FunctionVisitor { |
| 237 void VisitFunction(const Function& function) { | 249 void VisitFunction(const Function& function) { |
| 238 function.ClearCode(); | 250 function.ClearCode(); |
| 251 function.ClearICDataArray(); |
| 239 } | 252 } |
| 240 }; | 253 }; |
| 241 ClearCodeFunctionVisitor visitor; | 254 ClearCodeFunctionVisitor visitor; |
| 242 VisitFunctions(&visitor); | 255 VisitFunctions(&visitor); |
| 243 } | 256 } |
| 244 | 257 |
| 245 | 258 |
| 246 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) { | 259 void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) { |
| 247 // Note that <rootlibrary>.main is not a root. The appropriate main will be | 260 // Note that <rootlibrary>.main is not a root. The appropriate main will be |
| 248 // discovered through _getMainClosure. | 261 // discovered through _getMainClosure. |
| 249 | 262 |
| 250 AddSelector(Symbols::NoSuchMethod()); | 263 AddSelector(Symbols::NoSuchMethod()); |
| 251 | 264 |
| 252 AddSelector(Symbols::Call()); // For speed, not correctness. | 265 AddSelector(Symbols::Call()); // For speed, not correctness. |
| 253 | 266 |
| 254 // Allocated from C++. | 267 // Allocated from C++. |
| 255 static const intptr_t kExternallyAllocatedCids[] = { | |
| 256 kBoolCid, | |
| 257 kNullCid, | |
| 258 kClosureCid, | |
| 259 | |
| 260 kSmiCid, | |
| 261 kMintCid, | |
| 262 kBigintCid, | |
| 263 kDoubleCid, | |
| 264 | |
| 265 kOneByteStringCid, | |
| 266 kTwoByteStringCid, | |
| 267 kExternalOneByteStringCid, | |
| 268 kExternalTwoByteStringCid, | |
| 269 | |
| 270 kArrayCid, | |
| 271 kImmutableArrayCid, | |
| 272 kGrowableObjectArrayCid, | |
| 273 kLinkedHashMapCid, | |
| 274 | |
| 275 kTypedDataUint8ClampedArrayCid, | |
| 276 kTypedDataUint8ArrayCid, | |
| 277 kTypedDataUint16ArrayCid, | |
| 278 kTypedDataUint32ArrayCid, | |
| 279 kTypedDataUint64ArrayCid, | |
| 280 kTypedDataInt8ArrayCid, | |
| 281 kTypedDataInt16ArrayCid, | |
| 282 kTypedDataInt32ArrayCid, | |
| 283 kTypedDataInt64ArrayCid, | |
| 284 | |
| 285 kExternalTypedDataUint8ArrayCid, | |
| 286 kExternalTypedDataUint16ArrayCid, | |
| 287 kExternalTypedDataUint32ArrayCid, | |
| 288 kExternalTypedDataUint64ArrayCid, | |
| 289 kExternalTypedDataInt8ArrayCid, | |
| 290 kExternalTypedDataInt16ArrayCid, | |
| 291 kExternalTypedDataInt32ArrayCid, | |
| 292 kExternalTypedDataInt64ArrayCid, | |
| 293 | |
| 294 kTypedDataFloat32ArrayCid, | |
| 295 kTypedDataFloat64ArrayCid, | |
| 296 | |
| 297 kTypedDataFloat32x4ArrayCid, | |
| 298 kTypedDataInt32x4ArrayCid, | |
| 299 kTypedDataFloat64x2ArrayCid, | |
| 300 | |
| 301 kInt32x4Cid, | |
| 302 kFloat32x4Cid, | |
| 303 kFloat64x2Cid, | |
| 304 | |
| 305 kTypeCid, | |
| 306 kFunctionTypeCid, | |
| 307 kTypeRefCid, | |
| 308 kTypeParameterCid, | |
| 309 kBoundedTypeCid, | |
| 310 kLibraryPrefixCid, | |
| 311 | |
| 312 kJSRegExpCid, | |
| 313 kUserTagCid, | |
| 314 kStacktraceCid, | |
| 315 kWeakPropertyCid, | |
| 316 kCapabilityCid, | |
| 317 ReceivePort::kClassId, | |
| 318 SendPort::kClassId, | |
| 319 | |
| 320 kIllegalCid | |
| 321 }; | |
| 322 | |
| 323 Class& cls = Class::Handle(Z); | 268 Class& cls = Class::Handle(Z); |
| 324 for (intptr_t i = 0; kExternallyAllocatedCids[i] != kIllegalCid; i++) { | 269 for (intptr_t cid = kInstanceCid; cid < kNumPredefinedCids; cid++) { |
| 325 cls = isolate()->class_table()->At(kExternallyAllocatedCids[i]); | 270 ASSERT(isolate()->class_table()->IsValidIndex(cid)); |
| 271 if (!isolate()->class_table()->HasValidClassAt(cid)) { |
| 272 continue; |
| 273 } |
| 274 if ((cid == kDynamicCid) || |
| 275 (cid == kVoidCid) || |
| 276 (cid == kFreeListElement)) { |
| 277 continue; |
| 278 } |
| 279 cls = isolate()->class_table()->At(cid); |
| 326 AddInstantiatedClass(cls); | 280 AddInstantiatedClass(cls); |
| 327 } | 281 } |
| 328 | 282 |
| 329 Dart_QualifiedFunctionName vm_entry_points[] = { | 283 Dart_QualifiedFunctionName vm_entry_points[] = { |
| 330 // Functions | 284 // Functions |
| 331 { "dart:async", "::", "_setScheduleImmediateClosure" }, | 285 { "dart:async", "::", "_setScheduleImmediateClosure" }, |
| 332 { "dart:core", "::", "_completeDeferredLoads"}, | 286 { "dart:core", "::", "_completeDeferredLoads" }, |
| 333 { "dart:core", "AbstractClassInstantiationError", | 287 { "dart:core", "AbstractClassInstantiationError", |
| 334 "AbstractClassInstantiationError._create" }, | 288 "AbstractClassInstantiationError._create" }, |
| 335 { "dart:core", "ArgumentError", "ArgumentError." }, | 289 { "dart:core", "ArgumentError", "ArgumentError." }, |
| 336 { "dart:core", "CyclicInitializationError", | 290 { "dart:core", "CyclicInitializationError", |
| 337 "CyclicInitializationError." }, | 291 "CyclicInitializationError." }, |
| 338 { "dart:core", "FallThroughError", "FallThroughError._create" }, | 292 { "dart:core", "FallThroughError", "FallThroughError._create" }, |
| 339 { "dart:core", "FormatException", "FormatException." }, | 293 { "dart:core", "FormatException", "FormatException." }, |
| 340 { "dart:core", "NoSuchMethodError", "NoSuchMethodError._withType" }, | 294 { "dart:core", "NoSuchMethodError", "NoSuchMethodError._withType" }, |
| 341 { "dart:core", "NullThrownError", "NullThrownError." }, | 295 { "dart:core", "NullThrownError", "NullThrownError." }, |
| 342 { "dart:core", "OutOfMemoryError", "OutOfMemoryError." }, | 296 { "dart:core", "OutOfMemoryError", "OutOfMemoryError." }, |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 Function::KindToCString(function.kind())); | 430 Function::KindToCString(function.kind())); |
| 477 } | 431 } |
| 478 | 432 |
| 479 ASSERT(!function.is_abstract()); | 433 ASSERT(!function.is_abstract()); |
| 480 ASSERT(!function.IsRedirectingFactory()); | 434 ASSERT(!function.IsRedirectingFactory()); |
| 481 | 435 |
| 482 error_ = CompileFunction(thread_, function); | 436 error_ = CompileFunction(thread_, function); |
| 483 if (!error_.IsNull()) { | 437 if (!error_.IsNull()) { |
| 484 Jump(error_); | 438 Jump(error_); |
| 485 } | 439 } |
| 440 // Used in the JIT to save type-feedback across compilations. |
| 441 function.ClearICDataArray(); |
| 486 } else { | 442 } else { |
| 487 if (FLAG_trace_precompiler) { | 443 if (FLAG_trace_precompiler) { |
| 488 // This function was compiled from somewhere other than Precompiler, | 444 // This function was compiled from somewhere other than Precompiler, |
| 489 // such as const constructors compiled by the parser. | 445 // such as const constructors compiled by the parser. |
| 490 THR_Print("Already has code: %s (%s, %s)\n", | 446 THR_Print("Already has code: %s (%s, %s)\n", |
| 491 function.ToLibNamePrefixedQualifiedCString(), | 447 function.ToLibNamePrefixedQualifiedCString(), |
| 492 function.token_pos().ToCString(), | 448 function.token_pos().ToCString(), |
| 493 Function::KindToCString(function.kind())); | 449 Function::KindToCString(function.kind())); |
| 494 } | 450 } |
| 495 } | 451 } |
| 496 | 452 |
| 497 ASSERT(function.HasCode()); | 453 ASSERT(function.HasCode()); |
| 498 AddCalleesOf(function); | 454 AddCalleesOf(function); |
| 499 } | 455 } |
| 500 | 456 |
| 501 | 457 |
| 502 void Precompiler::AddCalleesOf(const Function& function) { | 458 void Precompiler::AddCalleesOf(const Function& function) { |
| 503 ASSERT(function.HasCode()); | 459 ASSERT(function.HasCode()); |
| 504 | 460 |
| 505 const Code& code = Code::Handle(Z, function.CurrentCode()); | 461 const Code& code = Code::Handle(Z, function.CurrentCode()); |
| 506 | 462 |
| 507 const Array& table = Array::Handle(Z, code.static_calls_target_table()); | 463 const Array& table = Array::Handle(Z, code.static_calls_target_table()); |
| 508 Object& entry = Object::Handle(Z); | 464 Object& entry = Object::Handle(Z); |
| 509 Function& target = Function::Handle(Z); | 465 Function& target = Function::Handle(Z); |
| 510 for (intptr_t i = 0; i < table.Length(); i++) { | 466 for (intptr_t i = 0; i < table.Length(); i++) { |
| 511 entry = table.At(i); | 467 entry = table.At(i); |
| 512 if (entry.IsFunction()) { | 468 if (entry.IsFunction()) { |
| 513 target ^= table.At(i); | 469 target ^= entry.raw(); |
| 514 AddFunction(target); | 470 AddFunction(target); |
| 515 } | 471 } |
| 516 } | 472 } |
| 517 | 473 |
| 518 #if defined(TARGET_ARCH_IA32) | 474 #if defined(TARGET_ARCH_IA32) |
| 519 FATAL("Callee scanning unimplemented for IA32"); | 475 FATAL("Callee scanning unimplemented for IA32"); |
| 520 #endif | 476 #endif |
| 521 | 477 |
| 522 const ObjectPool& pool = ObjectPool::Handle(Z, code.GetObjectPool()); | 478 const ObjectPool& pool = ObjectPool::Handle(Z, code.GetObjectPool()); |
| 523 ICData& call_site = ICData::Handle(Z); | 479 ICData& call_site = ICData::Handle(Z); |
| 524 MegamorphicCache& cache = MegamorphicCache::Handle(Z); | 480 MegamorphicCache& cache = MegamorphicCache::Handle(Z); |
| 525 String& selector = String::Handle(Z); | 481 String& selector = String::Handle(Z); |
| 526 Field& field = Field::Handle(Z); | 482 Field& field = Field::Handle(Z); |
| 527 Class& cls = Class::Handle(Z); | 483 Class& cls = Class::Handle(Z); |
| 528 Instance& instance = Instance::Handle(Z); | 484 Instance& instance = Instance::Handle(Z); |
| 529 Code& target_code = Code::Handle(Z); | 485 Code& target_code = Code::Handle(Z); |
| 530 for (intptr_t i = 0; i < pool.Length(); i++) { | 486 for (intptr_t i = 0; i < pool.Length(); i++) { |
| 531 if (pool.InfoAt(i) == ObjectPool::kTaggedObject) { | 487 if (pool.InfoAt(i) == ObjectPool::kTaggedObject) { |
| 532 entry = pool.ObjectAt(i); | 488 entry = pool.ObjectAt(i); |
| 533 if (entry.IsICData()) { | 489 if (entry.IsICData()) { |
| 534 call_site ^= entry.raw(); | 490 call_site ^= entry.raw(); |
| 535 if (call_site.NumberOfChecks() == 1) { | 491 for (intptr_t j = 0; j < call_site.NumberOfChecks(); j++) { |
| 536 // Probably a static call. | 492 target = call_site.GetTargetAt(j); |
| 537 target = call_site.GetTargetAt(0); | |
| 538 AddFunction(target); | 493 AddFunction(target); |
| 539 if (!target.is_static()) { | 494 if (!target.is_static()) { |
| 540 // Super call (should not enqueue selector) or dynamic call with a | 495 // Super call (should not enqueue selector) or dynamic call with a |
| 541 // CHA prediction (should enqueue selector). | 496 // CHA prediction (should enqueue selector). |
| 542 selector = call_site.target_name(); | 497 selector = call_site.target_name(); |
| 543 AddSelector(selector); | 498 AddSelector(selector); |
| 544 } | 499 } |
| 545 } else { | 500 } |
| 501 if (call_site.NumberOfChecks() == 0) { |
| 546 // A dynamic call. | 502 // A dynamic call. |
| 547 selector = call_site.target_name(); | 503 selector = call_site.target_name(); |
| 548 AddSelector(selector); | 504 AddSelector(selector); |
| 549 if (selector.raw() == Symbols::Call().raw()) { | 505 if (selector.raw() == Symbols::Call().raw()) { |
| 550 // Potential closure call. | 506 // Potential closure call. |
| 551 AddClosureCall(call_site); | 507 AddClosureCall(call_site); |
| 552 } | 508 } |
| 553 } | 509 } |
| 554 } else if (entry.IsMegamorphicCache()) { | 510 } else if (entry.IsMegamorphicCache()) { |
| 555 // A dynamic call. | 511 // A dynamic call. |
| 556 cache ^= entry.raw(); | 512 cache ^= entry.raw(); |
| 557 selector = cache.target_name(); | 513 selector = cache.target_name(); |
| 558 AddSelector(selector); | 514 AddSelector(selector); |
| 559 } else if (entry.IsField()) { | 515 } else if (entry.IsField()) { |
| 560 // Potential need for field initializer. | 516 // Potential need for field initializer. |
| 561 field ^= entry.raw(); | 517 field ^= entry.raw(); |
| 562 AddField(field); | 518 AddField(field); |
| 563 } else if (entry.IsInstance()) { | 519 } else if (entry.IsInstance()) { |
| 564 // Const object, literal or args descriptor. | 520 // Const object, literal or args descriptor. |
| 565 instance ^= entry.raw(); | 521 instance ^= entry.raw(); |
| 566 AddConstObject(instance); | 522 if (entry.IsAbstractType()) { |
| 523 AddType(AbstractType::Cast(entry)); |
| 524 } else { |
| 525 AddConstObject(instance); |
| 526 } |
| 567 } else if (entry.IsFunction()) { | 527 } else if (entry.IsFunction()) { |
| 568 // Local closure function. | 528 // Local closure function. |
| 569 target ^= entry.raw(); | 529 target ^= entry.raw(); |
| 570 AddFunction(target); | 530 AddFunction(target); |
| 571 } else if (entry.IsCode()) { | 531 } else if (entry.IsCode()) { |
| 572 target_code ^= entry.raw(); | 532 target_code ^= entry.raw(); |
| 573 if (target_code.IsAllocationStubCode()) { | 533 if (target_code.IsAllocationStubCode()) { |
| 574 cls ^= target_code.owner(); | 534 cls ^= target_code.owner(); |
| 575 AddInstantiatedClass(cls); | 535 AddInstantiatedClass(cls); |
| 576 } | 536 } |
| 537 } else if (entry.IsTypeArguments()) { |
| 538 AddTypeArguments(TypeArguments::Cast(entry)); |
| 577 } | 539 } |
| 578 } | 540 } |
| 579 } | 541 } |
| 580 } | 542 } |
| 581 | 543 |
| 582 | 544 |
| 545 void Precompiler::AddTypesOf(const Class& cls) { |
| 546 if (cls.IsNull()) return; |
| 547 if (classes_to_retain_.Lookup(&cls) != NULL) return; |
| 548 classes_to_retain_.Insert(&Class::ZoneHandle(Z, cls.raw())); |
| 549 |
| 550 Array& interfaces = Array::Handle(Z, cls.interfaces()); |
| 551 AbstractType& type = AbstractType::Handle(Z); |
| 552 for (intptr_t i = 0; i < interfaces.Length(); i++) { |
| 553 type ^= interfaces.At(i); |
| 554 AddType(type); |
| 555 } |
| 556 |
| 557 AddTypeArguments(TypeArguments::Handle(Z, cls.type_parameters())); |
| 558 |
| 559 type = cls.super_type(); |
| 560 AddType(type); |
| 561 |
| 562 type = cls.mixin(); |
| 563 AddType(type); |
| 564 |
| 565 if (cls.IsTypedefClass()) { |
| 566 AddTypesOf(Function::Handle(Z, cls.signature_function())); |
| 567 } |
| 568 } |
| 569 |
| 570 |
| 571 void Precompiler::AddTypesOf(const Function& function) { |
| 572 AbstractType& type = AbstractType::Handle(Z); |
| 573 type = function.result_type(); |
| 574 AddType(type); |
| 575 for (intptr_t i = 0; i < function.NumParameters(); i++) { |
| 576 type = function.ParameterTypeAt(i); |
| 577 AddType(type); |
| 578 } |
| 579 } |
| 580 |
| 581 |
| 582 void Precompiler::AddType(const AbstractType& abstype) { |
| 583 if (abstype.IsNull()) return; |
| 584 |
| 585 if (types_to_retain_.Lookup(&abstype) != NULL) return; |
| 586 types_to_retain_.Insert(&AbstractType::ZoneHandle(Z, abstype.raw())); |
| 587 |
| 588 if (abstype.IsType()) { |
| 589 const Type& type = Type::Cast(abstype); |
| 590 const Class& cls = Class::Handle(Z, type.type_class()); |
| 591 AddTypesOf(cls); |
| 592 const TypeArguments& vector = TypeArguments::Handle(Z, abstype.arguments()); |
| 593 AddTypeArguments(vector); |
| 594 } else if (abstype.IsFunctionType()) { |
| 595 const FunctionType& func_type = FunctionType::Cast(abstype); |
| 596 const Class& cls = Class::Handle(Z, func_type.scope_class()); |
| 597 AddTypesOf(cls); |
| 598 const Function& func = Function::Handle(Z, func_type.signature()); |
| 599 AddTypesOf(func); |
| 600 const TypeArguments& vector = TypeArguments::Handle(Z, abstype.arguments()); |
| 601 AddTypeArguments(vector); |
| 602 } else if (abstype.IsBoundedType()) { |
| 603 AbstractType& type = AbstractType::Handle(Z); |
| 604 type = BoundedType::Cast(abstype).type(); |
| 605 AddType(type); |
| 606 type = BoundedType::Cast(abstype).bound(); |
| 607 AddType(type); |
| 608 } else if (abstype.IsTypeRef()) { |
| 609 AbstractType& type = AbstractType::Handle(Z); |
| 610 type = TypeRef::Cast(abstype).type(); |
| 611 AddType(type); |
| 612 } |
| 613 } |
| 614 |
| 615 |
| 616 void Precompiler::AddTypeArguments(const TypeArguments& args) { |
| 617 if (args.IsNull()) return; |
| 618 |
| 619 if (typeargs_to_retain_.Lookup(&args) != NULL) return; |
| 620 typeargs_to_retain_.Insert(&TypeArguments::ZoneHandle(Z, args.raw())); |
| 621 |
| 622 AbstractType& arg = AbstractType::Handle(Z); |
| 623 for (intptr_t i = 0; i < args.Length(); i++) { |
| 624 arg = args.TypeAt(i); |
| 625 AddType(arg); |
| 626 } |
| 627 } |
| 628 |
| 629 |
| 583 void Precompiler::AddConstObject(const Instance& instance) { | 630 void Precompiler::AddConstObject(const Instance& instance) { |
| 584 const Class& cls = Class::Handle(Z, instance.clazz()); | 631 const Class& cls = Class::Handle(Z, instance.clazz()); |
| 585 AddInstantiatedClass(cls); | 632 AddInstantiatedClass(cls); |
| 586 | 633 |
| 587 if (instance.IsClosure()) { | 634 if (instance.IsClosure()) { |
| 588 // An implicit static closure. | 635 // An implicit static closure. |
| 589 const Function& func = | 636 const Function& func = |
| 590 Function::Handle(Z, Closure::Cast(instance).function()); | 637 Function::Handle(Z, Closure::Cast(instance).function()); |
| 591 ASSERT(func.is_static()); | 638 ASSERT(func.is_static()); |
| 592 AddFunction(func); | 639 AddFunction(func); |
| 640 AddTypeArguments(TypeArguments::Handle(Z, instance.GetTypeArguments())); |
| 593 return; | 641 return; |
| 594 } | 642 } |
| 595 | 643 |
| 596 // Can't ask immediate objects if they're canoncial. | 644 // Can't ask immediate objects if they're canoncial. |
| 597 if (instance.IsSmi()) return; | 645 if (instance.IsSmi()) return; |
| 598 | 646 |
| 599 // Some Instances in the ObjectPool aren't const objects, such as | 647 // Some Instances in the ObjectPool aren't const objects, such as |
| 600 // argument descriptors. | 648 // argument descriptors. |
| 601 if (!instance.IsCanonical()) return; | 649 if (!instance.IsCanonical()) return; |
| 602 | 650 |
| 651 if (cls.NumTypeArguments() > 0) { |
| 652 AddTypeArguments(TypeArguments::Handle(Z, instance.GetTypeArguments())); |
| 653 } |
| 654 |
| 603 class ConstObjectVisitor : public ObjectPointerVisitor { | 655 class ConstObjectVisitor : public ObjectPointerVisitor { |
| 604 public: | 656 public: |
| 605 ConstObjectVisitor(Precompiler* precompiler, Isolate* isolate) : | 657 ConstObjectVisitor(Precompiler* precompiler, Isolate* isolate) : |
| 606 ObjectPointerVisitor(isolate), | 658 ObjectPointerVisitor(isolate), |
| 607 precompiler_(precompiler), | 659 precompiler_(precompiler), |
| 608 subinstance_(Object::Handle()) {} | 660 subinstance_(Object::Handle()) {} |
| 609 | 661 |
| 610 virtual void VisitPointers(RawObject** first, RawObject** last) { | 662 virtual void VisitPointers(RawObject** first, RawObject** last) { |
| 611 for (RawObject** current = first; current <= last; current++) { | 663 for (RawObject** current = first; current <= last; current++) { |
| 612 subinstance_ = *current; | 664 subinstance_ = *current; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 AddCalleesOf(function); | 727 AddCalleesOf(function); |
| 676 } | 728 } |
| 677 } | 729 } |
| 678 } | 730 } |
| 679 | 731 |
| 680 | 732 |
| 681 RawFunction* Precompiler::CompileStaticInitializer(const Field& field) { | 733 RawFunction* Precompiler::CompileStaticInitializer(const Field& field) { |
| 682 ASSERT(field.is_static()); | 734 ASSERT(field.is_static()); |
| 683 if (field.HasPrecompiledInitializer()) { | 735 if (field.HasPrecompiledInitializer()) { |
| 684 // TODO(rmacnak): Investigate why this happens for _enum_names. | 736 // TODO(rmacnak): Investigate why this happens for _enum_names. |
| 685 OS::Print("Warning: Ignoring repeated request for initializer for %s\n", | 737 THR_Print("Warning: Ignoring repeated request for initializer for %s\n", |
| 686 field.ToCString()); | 738 field.ToCString()); |
| 687 return Function::null(); | 739 return Function::null(); |
| 688 } | 740 } |
| 689 Thread* thread = Thread::Current(); | 741 Thread* thread = Thread::Current(); |
| 690 StackZone zone(thread); | 742 StackZone zone(thread); |
| 691 | 743 |
| 692 ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field); | 744 ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field); |
| 693 | 745 |
| 694 parsed_function->AllocateVariables(); | 746 parsed_function->AllocateVariables(); |
| 695 // Non-optimized code generator. | 747 // Non-optimized code generator. |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1135 // It can happen that all uses of an implicit closure inline their | 1187 // It can happen that all uses of an implicit closure inline their |
| 1136 // target function, leaving the target function uncompiled. Keep | 1188 // target function, leaving the target function uncompiled. Keep |
| 1137 // the target function anyway so we can enumerate it to bind its | 1189 // the target function anyway so we can enumerate it to bind its |
| 1138 // static calls, etc. | 1190 // static calls, etc. |
| 1139 function2 = function.ImplicitClosureFunction(); | 1191 function2 = function.ImplicitClosureFunction(); |
| 1140 retain = function2.HasCode(); | 1192 retain = function2.HasCode(); |
| 1141 } | 1193 } |
| 1142 if (retain) { | 1194 if (retain) { |
| 1143 retained_functions.Add(function); | 1195 retained_functions.Add(function); |
| 1144 function.DropUncompiledImplicitClosureFunction(); | 1196 function.DropUncompiledImplicitClosureFunction(); |
| 1197 AddTypesOf(function); |
| 1145 } else { | 1198 } else { |
| 1146 bool top_level = cls.IsTopLevel(); | 1199 bool top_level = cls.IsTopLevel(); |
| 1147 if (top_level && | 1200 if (top_level && |
| 1148 (function.kind() != RawFunction::kImplicitStaticFinalGetter)) { | 1201 (function.kind() != RawFunction::kImplicitStaticFinalGetter)) { |
| 1149 // Implicit static final getters are not added to the library | 1202 // Implicit static final getters are not added to the library |
| 1150 // dictionary in the first place. | 1203 // dictionary in the first place. |
| 1151 name = function.DictionaryName(); | 1204 name = function.DictionaryName(); |
| 1152 bool removed = lib.RemoveObject(function, name); | 1205 bool removed = lib.RemoveObject(function, name); |
| 1153 ASSERT(removed); | 1206 ASSERT(removed); |
| 1154 } | 1207 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1166 } else { | 1219 } else { |
| 1167 cls.SetFunctions(Object::empty_array()); | 1220 cls.SetFunctions(Object::empty_array()); |
| 1168 } | 1221 } |
| 1169 } | 1222 } |
| 1170 } | 1223 } |
| 1171 | 1224 |
| 1172 closures = isolate()->object_store()->closure_functions(); | 1225 closures = isolate()->object_store()->closure_functions(); |
| 1173 retained_functions = GrowableObjectArray::New(); | 1226 retained_functions = GrowableObjectArray::New(); |
| 1174 for (intptr_t j = 0; j < closures.Length(); j++) { | 1227 for (intptr_t j = 0; j < closures.Length(); j++) { |
| 1175 function ^= closures.At(j); | 1228 function ^= closures.At(j); |
| 1176 if (function.HasCode()) { | 1229 bool retain = function.HasCode(); |
| 1230 if (retain) { |
| 1177 retained_functions.Add(function); | 1231 retained_functions.Add(function); |
| 1232 AddTypesOf(function); |
| 1178 } else { | 1233 } else { |
| 1179 dropped_function_count_++; | 1234 dropped_function_count_++; |
| 1180 if (FLAG_trace_precompiler) { | 1235 if (FLAG_trace_precompiler) { |
| 1181 THR_Print("Precompilation dropping %s\n", | 1236 THR_Print("Precompilation dropping %s\n", |
| 1182 function.ToLibNamePrefixedQualifiedCString()); | 1237 function.ToLibNamePrefixedQualifiedCString()); |
| 1183 } | 1238 } |
| 1184 } | 1239 } |
| 1185 } | 1240 } |
| 1186 isolate()->object_store()->set_closure_functions(retained_functions); | 1241 isolate()->object_store()->set_closure_functions(retained_functions); |
| 1187 } | 1242 } |
| 1188 | 1243 |
| 1189 | 1244 |
| 1190 void Precompiler::DropFields() { | 1245 void Precompiler::DropFields() { |
| 1191 Library& lib = Library::Handle(Z); | 1246 Library& lib = Library::Handle(Z); |
| 1192 Class& cls = Class::Handle(Z); | 1247 Class& cls = Class::Handle(Z); |
| 1193 Array& fields = Array::Handle(Z); | 1248 Array& fields = Array::Handle(Z); |
| 1194 Field& field = Field::Handle(Z); | 1249 Field& field = Field::Handle(Z); |
| 1195 GrowableObjectArray& retained_fields = GrowableObjectArray::Handle(Z); | 1250 GrowableObjectArray& retained_fields = GrowableObjectArray::Handle(Z); |
| 1196 String& name = String::Handle(Z); | 1251 String& name = String::Handle(Z); |
| 1252 AbstractType& type = AbstractType::Handle(Z); |
| 1197 | 1253 |
| 1198 for (intptr_t i = 0; i < libraries_.Length(); i++) { | 1254 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| 1199 lib ^= libraries_.At(i); | 1255 lib ^= libraries_.At(i); |
| 1200 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | 1256 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
| 1201 while (it.HasNext()) { | 1257 while (it.HasNext()) { |
| 1202 cls = it.GetNextClass(); | 1258 cls = it.GetNextClass(); |
| 1203 if (cls.IsDynamicClass()) { | 1259 if (cls.IsDynamicClass()) { |
| 1204 continue; // class 'dynamic' is in the read-only VM isolate. | 1260 continue; // class 'dynamic' is in the read-only VM isolate. |
| 1205 } | 1261 } |
| 1206 | 1262 |
| 1207 fields = cls.fields(); | 1263 fields = cls.fields(); |
| 1208 retained_fields = GrowableObjectArray::New(); | 1264 retained_fields = GrowableObjectArray::New(); |
| 1209 for (intptr_t j = 0; j < fields.Length(); j++) { | 1265 for (intptr_t j = 0; j < fields.Length(); j++) { |
| 1210 field ^= fields.At(j); | 1266 field ^= fields.At(j); |
| 1211 bool retain = fields_to_retain_.Lookup(&field) != NULL; | 1267 bool retain = fields_to_retain_.Lookup(&field) != NULL; |
| 1212 if (retain) { | 1268 if (retain) { |
| 1213 retained_fields.Add(field); | 1269 retained_fields.Add(field); |
| 1270 type = field.type(); |
| 1271 AddType(type); |
| 1214 } else { | 1272 } else { |
| 1215 bool top_level = cls.IsTopLevel(); | 1273 bool top_level = cls.IsTopLevel(); |
| 1216 if (top_level) { | 1274 if (top_level) { |
| 1217 name = field.DictionaryName(); | 1275 name = field.DictionaryName(); |
| 1218 bool removed = lib.RemoveObject(field, name); | 1276 bool removed = lib.RemoveObject(field, name); |
| 1219 ASSERT(removed); | 1277 ASSERT(removed); |
| 1220 } | 1278 } |
| 1221 dropped_field_count_++; | 1279 dropped_field_count_++; |
| 1222 if (FLAG_trace_precompiler) { | 1280 if (FLAG_trace_precompiler) { |
| 1223 THR_Print("Precompilation dropping %s\n", | 1281 THR_Print("Precompilation dropping %s\n", |
| 1224 field.ToCString()); | 1282 field.ToCString()); |
| 1225 } | 1283 } |
| 1226 } | 1284 } |
| 1227 } | 1285 } |
| 1228 | 1286 |
| 1229 if (retained_fields.Length() > 0) { | 1287 if (retained_fields.Length() > 0) { |
| 1230 fields = Array::MakeArray(retained_fields); | 1288 fields = Array::MakeArray(retained_fields); |
| 1231 cls.SetFields(fields); | 1289 cls.SetFields(fields); |
| 1232 } else { | 1290 } else { |
| 1233 cls.SetFields(Object::empty_array()); | 1291 cls.SetFields(Object::empty_array()); |
| 1234 } | 1292 } |
| 1235 } | 1293 } |
| 1236 } | 1294 } |
| 1237 } | 1295 } |
| 1238 | 1296 |
| 1239 | 1297 |
| 1298 void Precompiler::DropTypes() { |
| 1299 Library& lib = Library::Handle(Z); |
| 1300 Class& cls = Class::Handle(Z); |
| 1301 Object& obj = Object::Handle(Z); |
| 1302 Array& arr = Array::Handle(Z); |
| 1303 GrowableObjectArray& retained_types = GrowableObjectArray::Handle(Z); |
| 1304 AbstractType& type = AbstractType::Handle(Z); |
| 1305 |
| 1306 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| 1307 lib ^= libraries_.At(i); |
| 1308 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
| 1309 while (it.HasNext()) { |
| 1310 cls = it.GetNextClass(); |
| 1311 if (cls.IsDynamicClass()) { |
| 1312 continue; // class 'dynamic' is in the read-only VM isolate. |
| 1313 } |
| 1314 obj = cls.canonical_types(); |
| 1315 if (!obj.IsArray()) { |
| 1316 // Class only has one type, keep it. |
| 1317 } else { |
| 1318 // Class has many types. |
| 1319 arr ^= obj.raw(); |
| 1320 retained_types = GrowableObjectArray::New(); |
| 1321 |
| 1322 // Always keep the first one. |
| 1323 ASSERT(arr.Length() >= 1); |
| 1324 obj = arr.At(0); |
| 1325 retained_types.Add(obj); |
| 1326 |
| 1327 for (intptr_t i = 1; i < arr.Length(); i++) { |
| 1328 obj = arr.At(i); |
| 1329 if (obj.IsNull()) { |
| 1330 continue; |
| 1331 } |
| 1332 type ^= obj.raw(); |
| 1333 bool retain = types_to_retain_.Lookup(&type) != NULL; |
| 1334 if (retain) { |
| 1335 retained_types.Add(type); |
| 1336 } else { |
| 1337 dropped_type_count_++; |
| 1338 } |
| 1339 } |
| 1340 arr = Array::MakeArray(retained_types); |
| 1341 cls.set_canonical_types(arr); |
| 1342 } |
| 1343 } |
| 1344 } |
| 1345 } |
| 1346 |
| 1347 |
| 1348 void Precompiler::DropTypeArguments() { |
| 1349 const Array& typeargs_table = |
| 1350 Array::Handle(Z, I->object_store()->canonical_type_arguments()); |
| 1351 GrowableObjectArray& retained_typeargs = |
| 1352 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 1353 TypeArguments& typeargs = TypeArguments::Handle(Z); |
| 1354 for (intptr_t i = 0; i < (typeargs_table.Length() - 1); i++) { |
| 1355 typeargs ^= typeargs_table.At(i); |
| 1356 bool retain = typeargs_to_retain_.Lookup(&typeargs) != NULL; |
| 1357 if (retain) { |
| 1358 retained_typeargs.Add(typeargs); |
| 1359 } else { |
| 1360 dropped_typearg_count_++; |
| 1361 } |
| 1362 } |
| 1363 |
| 1364 const intptr_t dict_size = |
| 1365 Utils::RoundUpToPowerOfTwo(retained_typeargs.Length() * 4 / 3); |
| 1366 const Array& new_table = Array::Handle(Z, Array::New(dict_size + 1)); |
| 1367 |
| 1368 Object& element = Object::Handle(Z); |
| 1369 for (intptr_t i = 0; i < retained_typeargs.Length(); i++) { |
| 1370 typeargs ^= retained_typeargs.At(i); |
| 1371 intptr_t hash = typeargs.Hash(); |
| 1372 intptr_t index = hash & (dict_size - 1); |
| 1373 element = new_table.At(index); |
| 1374 while (!element.IsNull()) { |
| 1375 index = (index + 1) & (dict_size - 1); |
| 1376 element = new_table.At(index); |
| 1377 } |
| 1378 new_table.SetAt(index, typeargs); |
| 1379 } |
| 1380 |
| 1381 const Smi& used = Smi::Handle(Z, Smi::New(retained_typeargs.Length())); |
| 1382 new_table.SetAt(dict_size, used); |
| 1383 |
| 1384 I->object_store()->set_canonical_type_arguments(new_table); |
| 1385 } |
| 1386 |
| 1387 |
| 1388 void Precompiler::TraceTypesFromRetainedClasses() { |
| 1389 Library& lib = Library::Handle(Z); |
| 1390 Class& cls = Class::Handle(Z); |
| 1391 Array& members = Array::Handle(Z); |
| 1392 |
| 1393 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| 1394 lib ^= libraries_.At(i); |
| 1395 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
| 1396 while (it.HasNext()) { |
| 1397 cls = it.GetNextClass(); |
| 1398 if (cls.IsDynamicClass()) { |
| 1399 continue; // class 'dynamic' is in the read-only VM isolate. |
| 1400 } |
| 1401 |
| 1402 // The subclasses array is only needed for CHA. |
| 1403 cls.ClearDirectSubclasses(); |
| 1404 |
| 1405 bool retain = false; |
| 1406 members = cls.fields(); |
| 1407 if (members.Length() > 0) { |
| 1408 retain = true; |
| 1409 } |
| 1410 members = cls.functions(); |
| 1411 if (members.Length() > 0) { |
| 1412 retain = true; |
| 1413 } |
| 1414 if (cls.is_allocated()) { |
| 1415 retain = true; |
| 1416 } |
| 1417 if (cls.is_enum_class()) { |
| 1418 // Enum classes have live instances, so we cannot unregister |
| 1419 // them. |
| 1420 retain = true; |
| 1421 } |
| 1422 members = cls.constants(); |
| 1423 if (members.Length() > 0) { |
| 1424 // --compile_all? |
| 1425 retain = true; |
| 1426 } |
| 1427 |
| 1428 if (retain) { |
| 1429 AddTypesOf(cls); |
| 1430 } |
| 1431 } |
| 1432 } |
| 1433 } |
| 1434 |
| 1435 |
| 1436 void Precompiler::DropClasses() { |
| 1437 Library& lib = Library::Handle(Z); |
| 1438 Class& cls = Class::Handle(Z); |
| 1439 Array& members = Array::Handle(Z); |
| 1440 String& name = String::Handle(Z); |
| 1441 |
| 1442 #if defined(DEBUG) |
| 1443 { |
| 1444 // Force GC for allocation stats. |
| 1445 I->heap()->CollectAllGarbage(); |
| 1446 } |
| 1447 #endif |
| 1448 |
| 1449 ClassTable* class_table = I->class_table(); |
| 1450 intptr_t num_cids = class_table->NumCids(); |
| 1451 |
| 1452 for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) { |
| 1453 if (!class_table->IsValidIndex(cid)) continue; |
| 1454 if (!class_table->HasValidClassAt(cid)) continue; |
| 1455 |
| 1456 cls = class_table->At(cid); |
| 1457 ASSERT(!cls.IsNull()); |
| 1458 |
| 1459 if (cls.IsTopLevel()) { |
| 1460 // Top-level classes are referenced directly from their library. They |
| 1461 // will only be removed as a consequence of an entire library being |
| 1462 // removed. |
| 1463 continue; |
| 1464 } |
| 1465 if (cls.is_enum_class()) { |
| 1466 // Enum classes have live instances, so we cannot unregister |
| 1467 // them. |
| 1468 continue; |
| 1469 } |
| 1470 members = cls.constants(); |
| 1471 if (members.Length() > 0) { |
| 1472 // --compile_all? |
| 1473 continue; |
| 1474 } |
| 1475 |
| 1476 bool retain = classes_to_retain_.Lookup(&cls) != NULL; |
| 1477 if (retain) { |
| 1478 continue; |
| 1479 } |
| 1480 |
| 1481 #if defined(DEBUG) |
| 1482 intptr_t instances = |
| 1483 class_table->StatsWithUpdatedSize(cid)->post_gc.new_count + |
| 1484 class_table->StatsWithUpdatedSize(cid)->post_gc.old_count; |
| 1485 if (instances != 0) { |
| 1486 FATAL2("Want to drop class %s, but it has %" Pd " instances\n", |
| 1487 cls.ToCString(), |
| 1488 instances); |
| 1489 } |
| 1490 #endif |
| 1491 |
| 1492 dropped_class_count_++; |
| 1493 if (FLAG_trace_precompiler) { |
| 1494 THR_Print("Precompilation dropping %" Pd " %s\n", cid, cls.ToCString()); |
| 1495 } |
| 1496 |
| 1497 #if defined(DEBUG) |
| 1498 class_table->Unregister(cid); |
| 1499 #endif |
| 1500 cls.set_id(kIllegalCid); // We check this when serializing. |
| 1501 |
| 1502 lib = cls.library(); |
| 1503 name = cls.DictionaryName(); |
| 1504 lib.RemoveObject(cls, name); |
| 1505 } |
| 1506 } |
| 1507 |
| 1508 |
| 1509 void Precompiler::DropLibraries() { |
| 1510 const GrowableObjectArray& retained_libraries = |
| 1511 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 1512 Library& lib = Library::Handle(Z); |
| 1513 |
| 1514 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
| 1515 lib ^= libraries_.At(i); |
| 1516 lib.DropDependencies(); |
| 1517 intptr_t entries = 0; |
| 1518 DictionaryIterator it(lib); |
| 1519 while (it.HasNext()) { |
| 1520 it.GetNext(); |
| 1521 entries++; |
| 1522 } |
| 1523 bool retain = (entries > 0) || lib.is_dart_scheme(); |
| 1524 if (retain) { |
| 1525 lib.set_index(retained_libraries.Length()); |
| 1526 retained_libraries.Add(lib); |
| 1527 } else { |
| 1528 dropped_library_count_++; |
| 1529 lib.set_index(-1); |
| 1530 if (FLAG_trace_precompiler) { |
| 1531 THR_Print("Precompilation dropping %s\n", lib.ToCString()); |
| 1532 } |
| 1533 } |
| 1534 } |
| 1535 |
| 1536 I->object_store()->set_libraries(retained_libraries); |
| 1537 libraries_ = retained_libraries.raw(); |
| 1538 } |
| 1539 |
| 1540 |
| 1240 void Precompiler::BindStaticCalls() { | 1541 void Precompiler::BindStaticCalls() { |
| 1241 class BindStaticCallsVisitor : public FunctionVisitor { | 1542 class BindStaticCallsVisitor : public FunctionVisitor { |
| 1242 public: | 1543 public: |
| 1243 explicit BindStaticCallsVisitor(Zone* zone) : | 1544 explicit BindStaticCallsVisitor(Zone* zone) : |
| 1244 code_(Code::Handle(zone)), | 1545 code_(Code::Handle(zone)), |
| 1245 table_(Array::Handle(zone)), | 1546 table_(Array::Handle(zone)), |
| 1246 pc_offset_(Smi::Handle(zone)), | 1547 pc_offset_(Smi::Handle(zone)), |
| 1247 target_(Function::Handle(zone)), | 1548 target_(Function::Handle(zone)), |
| 1248 target_code_(Code::Handle(zone)) { | 1549 target_code_(Code::Handle(zone)) { |
| 1249 } | 1550 } |
| (...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2228 CompilationPipeline::New(thread->zone(), function); | 2529 CompilationPipeline::New(thread->zone(), function); |
| 2229 | 2530 |
| 2230 ASSERT(FLAG_precompilation); | 2531 ASSERT(FLAG_precompilation); |
| 2231 const bool optimized = function.IsOptimizable(); // False for natives. | 2532 const bool optimized = function.IsOptimizable(); // False for natives. |
| 2232 return PrecompileFunctionHelper(pipeline, function, optimized); | 2533 return PrecompileFunctionHelper(pipeline, function, optimized); |
| 2233 } | 2534 } |
| 2234 | 2535 |
| 2235 #endif // DART_PRECOMPILER | 2536 #endif // DART_PRECOMPILER |
| 2236 | 2537 |
| 2237 } // namespace dart | 2538 } // namespace dart |
| OLD | NEW |