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 |