| 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 #ifndef RUNTIME_VM_PRECOMPILER_H_ | 5 #ifndef RUNTIME_VM_PRECOMPILER_H_ |
| 6 #define RUNTIME_VM_PRECOMPILER_H_ | 6 #define RUNTIME_VM_PRECOMPILER_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/hash_map.h" | 9 #include "vm/hash_map.h" |
| 10 #include "vm/hash_table.h" | 10 #include "vm/hash_table.h" |
| 11 #include "vm/object.h" | 11 #include "vm/object.h" |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 // Forward declarations. | 15 // Forward declarations. |
| 16 class Class; | 16 class Class; |
| 17 class Error; | 17 class Error; |
| 18 class Field; | 18 class Field; |
| 19 class Function; | 19 class Function; |
| 20 class GrowableObjectArray; | 20 class GrowableObjectArray; |
| 21 class RawError; | 21 class RawError; |
| 22 class SequenceNode; | 22 class SequenceNode; |
| 23 class String; | 23 class String; |
| 24 class ParsedJSONObject; | |
| 25 class ParsedJSONArray; | |
| 26 class Precompiler; | |
| 27 class FlowGraph; | |
| 28 | 24 |
| 29 class TypeRangeCache : public ValueObject { | 25 |
| 26 class TypeRangeCache : public StackResource { |
| 30 public: | 27 public: |
| 31 TypeRangeCache(Precompiler* precompiler, Thread* thread, intptr_t num_cids); | 28 TypeRangeCache(Thread* thread, intptr_t num_cids) |
| 32 ~TypeRangeCache(); | 29 : StackResource(thread), |
| 30 thread_(thread), |
| 31 lower_limits_(thread->zone()->Alloc<intptr_t>(num_cids)), |
| 32 upper_limits_(thread->zone()->Alloc<intptr_t>(num_cids)) { |
| 33 for (intptr_t i = 0; i < num_cids; i++) { |
| 34 lower_limits_[i] = kNotComputed; |
| 35 upper_limits_[i] = kNotComputed; |
| 36 } |
| 37 // We don't re-enter the precompiler. |
| 38 ASSERT(thread->type_range_cache() == NULL); |
| 39 thread->set_type_range_cache(this); |
| 40 } |
| 41 |
| 42 ~TypeRangeCache() { |
| 43 ASSERT(thread_->type_range_cache() == this); |
| 44 thread_->set_type_range_cache(NULL); |
| 45 } |
| 33 | 46 |
| 34 bool InstanceOfHasClassRange(const AbstractType& type, | 47 bool InstanceOfHasClassRange(const AbstractType& type, |
| 35 intptr_t* lower_limit, | 48 intptr_t* lower_limit, |
| 36 intptr_t* upper_limit); | 49 intptr_t* upper_limit); |
| 37 | 50 |
| 38 private: | 51 private: |
| 39 static const intptr_t kNotComputed = -1; | 52 static const intptr_t kNotComputed = -1; |
| 40 static const intptr_t kNotContiguous = -2; | 53 static const intptr_t kNotContiguous = -2; |
| 41 | 54 |
| 42 Precompiler* precompiler_; | |
| 43 Thread* thread_; | 55 Thread* thread_; |
| 44 intptr_t* lower_limits_; | 56 intptr_t* lower_limits_; |
| 45 intptr_t* upper_limits_; | 57 intptr_t* upper_limits_; |
| 46 }; | 58 }; |
| 47 | 59 |
| 48 | 60 |
| 49 class SymbolKeyValueTrait { | 61 class SymbolKeyValueTrait { |
| 50 public: | 62 public: |
| 51 // Typedefs needed for the DirectChainedHashMap template. | 63 // Typedefs needed for the DirectChainedHashMap template. |
| 52 typedef const String* Key; | 64 typedef const String* Key; |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 | 321 |
| 310 void Print() const; | 322 void Print() const; |
| 311 | 323 |
| 312 const Field* field_; | 324 const Field* field_; |
| 313 intptr_t cid_; | 325 intptr_t cid_; |
| 314 }; | 326 }; |
| 315 | 327 |
| 316 typedef DirectChainedHashMap<FieldTypePair> FieldTypeMap; | 328 typedef DirectChainedHashMap<FieldTypePair> FieldTypeMap; |
| 317 | 329 |
| 318 | 330 |
| 319 struct IntptrPair { | |
| 320 // Typedefs needed for the DirectChainedHashMap template. | |
| 321 typedef intptr_t Key; | |
| 322 typedef intptr_t Value; | |
| 323 typedef IntptrPair Pair; | |
| 324 | |
| 325 static Key KeyOf(Pair kv) { return kv.key_; } | |
| 326 | |
| 327 static Value ValueOf(Pair kv) { return kv.value_; } | |
| 328 | |
| 329 static inline intptr_t Hashcode(Key key) { return key; } | |
| 330 | |
| 331 static inline bool IsKeyEqual(Pair pair, Key key) { return pair.key_ == key; } | |
| 332 | |
| 333 IntptrPair(intptr_t key, intptr_t value) : key_(key), value_(value) {} | |
| 334 | |
| 335 IntptrPair() : key_(kIllegalCid), value_(kIllegalCid) {} | |
| 336 | |
| 337 Key key_; | |
| 338 Value value_; | |
| 339 }; | |
| 340 | |
| 341 typedef DirectChainedHashMap<IntptrPair> CidMap; | |
| 342 | |
| 343 | |
| 344 struct FunctionFeedbackKey { | |
| 345 FunctionFeedbackKey() : owner_cid_(kIllegalCid), token_(0), kind_(0) {} | |
| 346 FunctionFeedbackKey(intptr_t owner_cid, intptr_t token, intptr_t kind) | |
| 347 : owner_cid_(owner_cid), token_(token), kind_(kind) {} | |
| 348 | |
| 349 intptr_t owner_cid_; | |
| 350 intptr_t token_; | |
| 351 intptr_t kind_; | |
| 352 }; | |
| 353 | |
| 354 | |
| 355 struct FunctionFeedbackPair { | |
| 356 // Typedefs needed for the DirectChainedHashMap template. | |
| 357 typedef FunctionFeedbackKey Key; | |
| 358 typedef ParsedJSONObject* Value; | |
| 359 typedef FunctionFeedbackPair Pair; | |
| 360 | |
| 361 static Key KeyOf(Pair kv) { return kv.key_; } | |
| 362 | |
| 363 static Value ValueOf(Pair kv) { return kv.value_; } | |
| 364 | |
| 365 static inline intptr_t Hashcode(Key key) { | |
| 366 return key.token_ ^ key.owner_cid_ ^ key.kind_; | |
| 367 } | |
| 368 | |
| 369 static inline bool IsKeyEqual(Pair pair, Key key) { | |
| 370 return (pair.key_.owner_cid_ == key.owner_cid_) && | |
| 371 (pair.key_.token_ == key.token_) && (pair.key_.kind_ == key.kind_); | |
| 372 } | |
| 373 | |
| 374 FunctionFeedbackPair(Key key, Value value) : key_(key), value_(value) {} | |
| 375 | |
| 376 FunctionFeedbackPair() : key_(), value_(NULL) {} | |
| 377 | |
| 378 Key key_; | |
| 379 Value value_; | |
| 380 }; | |
| 381 | |
| 382 typedef DirectChainedHashMap<FunctionFeedbackPair> FunctionFeedbackMap; | |
| 383 | |
| 384 | |
| 385 class Precompiler : public ValueObject { | 331 class Precompiler : public ValueObject { |
| 386 public: | 332 public: |
| 387 static RawError* CompileAll( | 333 static RawError* CompileAll( |
| 388 Dart_QualifiedFunctionName embedder_entry_points[], | 334 Dart_QualifiedFunctionName embedder_entry_points[], |
| 389 bool reset_fields, | 335 bool reset_fields); |
| 390 uint8_t* jit_feedback, | |
| 391 intptr_t jit_feedback_length); | |
| 392 | 336 |
| 393 static RawError* CompileFunction(Precompiler* precompiler, | 337 static RawError* CompileFunction(Precompiler* precompiler, |
| 394 Thread* thread, | 338 Thread* thread, |
| 395 Zone* zone, | 339 Zone* zone, |
| 396 const Function& function, | 340 const Function& function, |
| 397 FieldTypeMap* field_type_map = NULL); | 341 FieldTypeMap* field_type_map = NULL); |
| 398 | 342 |
| 399 static RawObject* EvaluateStaticInitializer(const Field& field); | 343 static RawObject* EvaluateStaticInitializer(const Field& field); |
| 400 static RawObject* ExecuteOnce(SequenceNode* fragment); | 344 static RawObject* ExecuteOnce(SequenceNode* fragment); |
| 401 | 345 |
| 402 static RawFunction* CompileStaticInitializer(const Field& field, | 346 static RawFunction* CompileStaticInitializer(const Field& field, |
| 403 bool compute_type); | 347 bool compute_type); |
| 404 | 348 |
| 405 // Returns true if get:runtimeType is not overloaded by any class. | 349 // Returns true if get:runtimeType is not overloaded by any class. |
| 406 bool get_runtime_type_is_unique() const { | 350 bool get_runtime_type_is_unique() const { |
| 407 return get_runtime_type_is_unique_; | 351 return get_runtime_type_is_unique_; |
| 408 } | 352 } |
| 409 | 353 |
| 410 FieldTypeMap* field_type_map() { return &field_type_map_; } | 354 FieldTypeMap* field_type_map() { return &field_type_map_; } |
| 411 TypeRangeCache* type_range_cache() { return type_range_cache_; } | |
| 412 void set_type_range_cache(TypeRangeCache* value) { | |
| 413 type_range_cache_ = value; | |
| 414 } | |
| 415 | |
| 416 bool HasFeedback() const { return jit_feedback_ != NULL; } | |
| 417 static void PopulateWithICData(const Function& func, FlowGraph* graph); | |
| 418 void TryApplyFeedback(const Function& func, FlowGraph* graph); | |
| 419 void TryApplyFeedback(ParsedJSONArray* js_icdatas, const ICData& ic); | |
| 420 | 355 |
| 421 private: | 356 private: |
| 422 Precompiler(Thread* thread, bool reset_fields); | 357 Precompiler(Thread* thread, bool reset_fields); |
| 423 | 358 |
| 424 void LoadFeedback(uint8_t* jit_feedback, intptr_t jit_feedback_length); | |
| 425 ParsedJSONObject* LookupFeedback(const Function& function); | |
| 426 | |
| 427 void DoCompileAll(Dart_QualifiedFunctionName embedder_entry_points[]); | 359 void DoCompileAll(Dart_QualifiedFunctionName embedder_entry_points[]); |
| 428 void ClearAllCode(); | 360 void ClearAllCode(); |
| 429 void AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]); | 361 void AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]); |
| 430 void AddEntryPoints(Dart_QualifiedFunctionName entry_points[]); | 362 void AddEntryPoints(Dart_QualifiedFunctionName entry_points[]); |
| 431 void Iterate(); | 363 void Iterate(); |
| 432 | 364 |
| 433 void AddType(const AbstractType& type); | 365 void AddType(const AbstractType& type); |
| 434 void AddTypesOf(const Class& cls); | 366 void AddTypesOf(const Class& cls); |
| 435 void AddTypesOf(const Function& function); | 367 void AddTypesOf(const Function& function); |
| 436 void AddTypeArguments(const TypeArguments& args); | 368 void AddTypeArguments(const TypeArguments& args); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 464 void DedupStackMaps(); | 396 void DedupStackMaps(); |
| 465 void DedupLists(); | 397 void DedupLists(); |
| 466 void DedupInstructions(); | 398 void DedupInstructions(); |
| 467 void ResetPrecompilerState(); | 399 void ResetPrecompilerState(); |
| 468 | 400 |
| 469 void CollectDynamicFunctionNames(); | 401 void CollectDynamicFunctionNames(); |
| 470 | 402 |
| 471 void PrecompileStaticInitializers(); | 403 void PrecompileStaticInitializers(); |
| 472 void PrecompileConstructors(); | 404 void PrecompileConstructors(); |
| 473 | 405 |
| 406 template <typename T> |
| 407 class Visitor : public ValueObject { |
| 408 public: |
| 409 virtual ~Visitor() {} |
| 410 virtual void Visit(const T& obj) = 0; |
| 411 }; |
| 412 typedef Visitor<Function> FunctionVisitor; |
| 413 typedef Visitor<Class> ClassVisitor; |
| 414 |
| 415 void VisitFunctions(FunctionVisitor* visitor); |
| 416 void VisitClasses(ClassVisitor* visitor); |
| 417 |
| 474 void FinalizeAllClasses(); | 418 void FinalizeAllClasses(); |
| 475 void SortClasses(); | 419 void SortClasses(); |
| 476 void RemapClassIds(intptr_t* old_to_new_cid); | 420 void RemapClassIds(intptr_t* old_to_new_cid); |
| 477 void VerifyJITFeedback(); | |
| 478 RawScript* LookupScript(const char* uri); | |
| 479 intptr_t MapCid(intptr_t feedback_cid); | |
| 480 | 421 |
| 481 Thread* thread() const { return thread_; } | 422 Thread* thread() const { return thread_; } |
| 482 Zone* zone() const { return zone_; } | 423 Zone* zone() const { return zone_; } |
| 483 Isolate* isolate() const { return isolate_; } | 424 Isolate* isolate() const { return isolate_; } |
| 484 | 425 |
| 485 Thread* thread_; | 426 Thread* thread_; |
| 486 Zone* zone_; | 427 Zone* zone_; |
| 487 Isolate* isolate_; | 428 Isolate* isolate_; |
| 488 | 429 |
| 489 const bool reset_fields_; | 430 const bool reset_fields_; |
| 490 | 431 |
| 491 ParsedJSONObject* jit_feedback_; | |
| 492 | |
| 493 bool changed_; | 432 bool changed_; |
| 494 intptr_t function_count_; | 433 intptr_t function_count_; |
| 495 intptr_t class_count_; | 434 intptr_t class_count_; |
| 496 intptr_t selector_count_; | 435 intptr_t selector_count_; |
| 497 intptr_t dropped_function_count_; | 436 intptr_t dropped_function_count_; |
| 498 intptr_t dropped_field_count_; | 437 intptr_t dropped_field_count_; |
| 499 intptr_t dropped_class_count_; | 438 intptr_t dropped_class_count_; |
| 500 intptr_t dropped_typearg_count_; | 439 intptr_t dropped_typearg_count_; |
| 501 intptr_t dropped_type_count_; | 440 intptr_t dropped_type_count_; |
| 502 intptr_t dropped_library_count_; | 441 intptr_t dropped_library_count_; |
| 503 | 442 |
| 504 GrowableObjectArray& libraries_; | 443 GrowableObjectArray& libraries_; |
| 505 const GrowableObjectArray& pending_functions_; | 444 const GrowableObjectArray& pending_functions_; |
| 506 SymbolSet sent_selectors_; | 445 SymbolSet sent_selectors_; |
| 507 FunctionSet enqueued_functions_; | 446 FunctionSet enqueued_functions_; |
| 508 FieldSet fields_to_retain_; | 447 FieldSet fields_to_retain_; |
| 509 FunctionSet functions_to_retain_; | 448 FunctionSet functions_to_retain_; |
| 510 ClassSet classes_to_retain_; | 449 ClassSet classes_to_retain_; |
| 511 TypeArgumentsSet typeargs_to_retain_; | 450 TypeArgumentsSet typeargs_to_retain_; |
| 512 AbstractTypeSet types_to_retain_; | 451 AbstractTypeSet types_to_retain_; |
| 513 InstanceSet consts_to_retain_; | 452 InstanceSet consts_to_retain_; |
| 514 FieldTypeMap field_type_map_; | 453 FieldTypeMap field_type_map_; |
| 515 TypeRangeCache* type_range_cache_; | |
| 516 CidMap feedback_cid_map_; | |
| 517 FunctionFeedbackMap function_feedback_map_; | |
| 518 Error& error_; | 454 Error& error_; |
| 519 | 455 |
| 520 bool get_runtime_type_is_unique_; | 456 bool get_runtime_type_is_unique_; |
| 521 }; | 457 }; |
| 522 | 458 |
| 523 | 459 |
| 524 class FunctionsTraits { | 460 class FunctionsTraits { |
| 525 public: | 461 public: |
| 526 static const char* Name() { return "FunctionsTraits"; } | 462 static const char* Name() { return "FunctionsTraits"; } |
| 527 static bool ReportStats() { return false; } | 463 static bool ReportStats() { return false; } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 545 } | 481 } |
| 546 static RawObject* NewKey(const Function& function) { return function.raw(); } | 482 static RawObject* NewKey(const Function& function) { return function.raw(); } |
| 547 }; | 483 }; |
| 548 | 484 |
| 549 typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet; | 485 typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet; |
| 550 | 486 |
| 551 | 487 |
| 552 } // namespace dart | 488 } // namespace dart |
| 553 | 489 |
| 554 #endif // RUNTIME_VM_PRECOMPILER_H_ | 490 #endif // RUNTIME_VM_PRECOMPILER_H_ |
| OLD | NEW |