| 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; |
| 24 | 28 |
| 25 | 29 class TypeRangeCache : public ValueObject { |
| 26 class TypeRangeCache : public StackResource { | |
| 27 public: | 30 public: |
| 28 TypeRangeCache(Thread* thread, intptr_t num_cids) | 31 TypeRangeCache(Precompiler* precompiler, Thread* thread, intptr_t num_cids); |
| 29 : StackResource(thread), | 32 ~TypeRangeCache(); |
| 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 } | |
| 46 | 33 |
| 47 bool InstanceOfHasClassRange(const AbstractType& type, | 34 bool InstanceOfHasClassRange(const AbstractType& type, |
| 48 intptr_t* lower_limit, | 35 intptr_t* lower_limit, |
| 49 intptr_t* upper_limit); | 36 intptr_t* upper_limit); |
| 50 | 37 |
| 51 private: | 38 private: |
| 52 static const intptr_t kNotComputed = -1; | 39 static const intptr_t kNotComputed = -1; |
| 53 static const intptr_t kNotContiguous = -2; | 40 static const intptr_t kNotContiguous = -2; |
| 54 | 41 |
| 42 Precompiler* precompiler_; |
| 55 Thread* thread_; | 43 Thread* thread_; |
| 56 intptr_t* lower_limits_; | 44 intptr_t* lower_limits_; |
| 57 intptr_t* upper_limits_; | 45 intptr_t* upper_limits_; |
| 58 }; | 46 }; |
| 59 | 47 |
| 60 | 48 |
| 61 class SymbolKeyValueTrait { | 49 class SymbolKeyValueTrait { |
| 62 public: | 50 public: |
| 63 // Typedefs needed for the DirectChainedHashMap template. | 51 // Typedefs needed for the DirectChainedHashMap template. |
| 64 typedef const String* Key; | 52 typedef const String* Key; |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 | 309 |
| 322 void Print() const; | 310 void Print() const; |
| 323 | 311 |
| 324 const Field* field_; | 312 const Field* field_; |
| 325 intptr_t cid_; | 313 intptr_t cid_; |
| 326 }; | 314 }; |
| 327 | 315 |
| 328 typedef DirectChainedHashMap<FieldTypePair> FieldTypeMap; | 316 typedef DirectChainedHashMap<FieldTypePair> FieldTypeMap; |
| 329 | 317 |
| 330 | 318 |
| 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 |
| 331 class Precompiler : public ValueObject { | 385 class Precompiler : public ValueObject { |
| 332 public: | 386 public: |
| 333 static RawError* CompileAll( | 387 static RawError* CompileAll( |
| 334 Dart_QualifiedFunctionName embedder_entry_points[], | 388 Dart_QualifiedFunctionName embedder_entry_points[], |
| 335 bool reset_fields); | 389 bool reset_fields, |
| 390 uint8_t* jit_feedback, |
| 391 intptr_t jit_feedback_length); |
| 336 | 392 |
| 337 static RawError* CompileFunction(Precompiler* precompiler, | 393 static RawError* CompileFunction(Precompiler* precompiler, |
| 338 Thread* thread, | 394 Thread* thread, |
| 339 Zone* zone, | 395 Zone* zone, |
| 340 const Function& function, | 396 const Function& function, |
| 341 FieldTypeMap* field_type_map = NULL); | 397 FieldTypeMap* field_type_map = NULL); |
| 342 | 398 |
| 343 static RawObject* EvaluateStaticInitializer(const Field& field); | 399 static RawObject* EvaluateStaticInitializer(const Field& field); |
| 344 static RawObject* ExecuteOnce(SequenceNode* fragment); | 400 static RawObject* ExecuteOnce(SequenceNode* fragment); |
| 345 | 401 |
| 346 static RawFunction* CompileStaticInitializer(const Field& field, | 402 static RawFunction* CompileStaticInitializer(const Field& field, |
| 347 bool compute_type); | 403 bool compute_type); |
| 348 | 404 |
| 349 // Returns true if get:runtimeType is not overloaded by any class. | 405 // Returns true if get:runtimeType is not overloaded by any class. |
| 350 bool get_runtime_type_is_unique() const { | 406 bool get_runtime_type_is_unique() const { |
| 351 return get_runtime_type_is_unique_; | 407 return get_runtime_type_is_unique_; |
| 352 } | 408 } |
| 353 | 409 |
| 354 FieldTypeMap* field_type_map() { return &field_type_map_; } | 410 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); |
| 355 | 420 |
| 356 private: | 421 private: |
| 357 Precompiler(Thread* thread, bool reset_fields); | 422 Precompiler(Thread* thread, bool reset_fields); |
| 358 | 423 |
| 424 void LoadFeedback(uint8_t* jit_feedback, intptr_t jit_feedback_length); |
| 425 ParsedJSONObject* LookupFeedback(const Function& function); |
| 426 |
| 359 void DoCompileAll(Dart_QualifiedFunctionName embedder_entry_points[]); | 427 void DoCompileAll(Dart_QualifiedFunctionName embedder_entry_points[]); |
| 360 void ClearAllCode(); | 428 void ClearAllCode(); |
| 361 void AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]); | 429 void AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]); |
| 362 void AddEntryPoints(Dart_QualifiedFunctionName entry_points[]); | 430 void AddEntryPoints(Dart_QualifiedFunctionName entry_points[]); |
| 363 void Iterate(); | 431 void Iterate(); |
| 364 | 432 |
| 365 void AddType(const AbstractType& type); | 433 void AddType(const AbstractType& type); |
| 366 void AddTypesOf(const Class& cls); | 434 void AddTypesOf(const Class& cls); |
| 367 void AddTypesOf(const Function& function); | 435 void AddTypesOf(const Function& function); |
| 368 void AddTypeArguments(const TypeArguments& args); | 436 void AddTypeArguments(const TypeArguments& args); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 396 void DedupStackMaps(); | 464 void DedupStackMaps(); |
| 397 void DedupLists(); | 465 void DedupLists(); |
| 398 void DedupInstructions(); | 466 void DedupInstructions(); |
| 399 void ResetPrecompilerState(); | 467 void ResetPrecompilerState(); |
| 400 | 468 |
| 401 void CollectDynamicFunctionNames(); | 469 void CollectDynamicFunctionNames(); |
| 402 | 470 |
| 403 void PrecompileStaticInitializers(); | 471 void PrecompileStaticInitializers(); |
| 404 void PrecompileConstructors(); | 472 void PrecompileConstructors(); |
| 405 | 473 |
| 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 | |
| 418 void FinalizeAllClasses(); | 474 void FinalizeAllClasses(); |
| 419 void SortClasses(); | 475 void SortClasses(); |
| 420 void RemapClassIds(intptr_t* old_to_new_cid); | 476 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); |
| 421 | 480 |
| 422 Thread* thread() const { return thread_; } | 481 Thread* thread() const { return thread_; } |
| 423 Zone* zone() const { return zone_; } | 482 Zone* zone() const { return zone_; } |
| 424 Isolate* isolate() const { return isolate_; } | 483 Isolate* isolate() const { return isolate_; } |
| 425 | 484 |
| 426 Thread* thread_; | 485 Thread* thread_; |
| 427 Zone* zone_; | 486 Zone* zone_; |
| 428 Isolate* isolate_; | 487 Isolate* isolate_; |
| 429 | 488 |
| 430 const bool reset_fields_; | 489 const bool reset_fields_; |
| 431 | 490 |
| 491 ParsedJSONObject* jit_feedback_; |
| 492 |
| 432 bool changed_; | 493 bool changed_; |
| 433 intptr_t function_count_; | 494 intptr_t function_count_; |
| 434 intptr_t class_count_; | 495 intptr_t class_count_; |
| 435 intptr_t selector_count_; | 496 intptr_t selector_count_; |
| 436 intptr_t dropped_function_count_; | 497 intptr_t dropped_function_count_; |
| 437 intptr_t dropped_field_count_; | 498 intptr_t dropped_field_count_; |
| 438 intptr_t dropped_class_count_; | 499 intptr_t dropped_class_count_; |
| 439 intptr_t dropped_typearg_count_; | 500 intptr_t dropped_typearg_count_; |
| 440 intptr_t dropped_type_count_; | 501 intptr_t dropped_type_count_; |
| 441 intptr_t dropped_library_count_; | 502 intptr_t dropped_library_count_; |
| 442 | 503 |
| 443 GrowableObjectArray& libraries_; | 504 GrowableObjectArray& libraries_; |
| 444 const GrowableObjectArray& pending_functions_; | 505 const GrowableObjectArray& pending_functions_; |
| 445 SymbolSet sent_selectors_; | 506 SymbolSet sent_selectors_; |
| 446 FunctionSet enqueued_functions_; | 507 FunctionSet enqueued_functions_; |
| 447 FieldSet fields_to_retain_; | 508 FieldSet fields_to_retain_; |
| 448 FunctionSet functions_to_retain_; | 509 FunctionSet functions_to_retain_; |
| 449 ClassSet classes_to_retain_; | 510 ClassSet classes_to_retain_; |
| 450 TypeArgumentsSet typeargs_to_retain_; | 511 TypeArgumentsSet typeargs_to_retain_; |
| 451 AbstractTypeSet types_to_retain_; | 512 AbstractTypeSet types_to_retain_; |
| 452 InstanceSet consts_to_retain_; | 513 InstanceSet consts_to_retain_; |
| 453 FieldTypeMap field_type_map_; | 514 FieldTypeMap field_type_map_; |
| 515 TypeRangeCache* type_range_cache_; |
| 516 CidMap feedback_cid_map_; |
| 517 FunctionFeedbackMap function_feedback_map_; |
| 454 Error& error_; | 518 Error& error_; |
| 455 | 519 |
| 456 bool get_runtime_type_is_unique_; | 520 bool get_runtime_type_is_unique_; |
| 457 }; | 521 }; |
| 458 | 522 |
| 459 | 523 |
| 460 class FunctionsTraits { | 524 class FunctionsTraits { |
| 461 public: | 525 public: |
| 462 static const char* Name() { return "FunctionsTraits"; } | 526 static const char* Name() { return "FunctionsTraits"; } |
| 463 static bool ReportStats() { return false; } | 527 static bool ReportStats() { return false; } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 481 } | 545 } |
| 482 static RawObject* NewKey(const Function& function) { return function.raw(); } | 546 static RawObject* NewKey(const Function& function) { return function.raw(); } |
| 483 }; | 547 }; |
| 484 | 548 |
| 485 typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet; | 549 typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet; |
| 486 | 550 |
| 487 | 551 |
| 488 } // namespace dart | 552 } // namespace dart |
| 489 | 553 |
| 490 #endif // RUNTIME_VM_PRECOMPILER_H_ | 554 #endif // RUNTIME_VM_PRECOMPILER_H_ |
| OLD | NEW |