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 |