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_; | |
Florian Schneider
2016/12/15 19:09:35
Add kind_ to the computation?
| |
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 void PopulateWithICData(const Function& func, FlowGraph* graph); | |
418 void TryApplyFeedback(ParsedJSONArray* js_icdatas, const ICData& ic); | |
355 | 419 |
356 private: | 420 private: |
357 Precompiler(Thread* thread, bool reset_fields); | 421 Precompiler(Thread* thread, bool reset_fields); |
358 | 422 |
423 void LoadFeedback(uint8_t* jit_feedback, intptr_t jit_feedback_length); | |
424 ParsedJSONObject* LookupFeedback(const Function& function); | |
425 | |
359 void DoCompileAll(Dart_QualifiedFunctionName embedder_entry_points[]); | 426 void DoCompileAll(Dart_QualifiedFunctionName embedder_entry_points[]); |
360 void ClearAllCode(); | 427 void ClearAllCode(); |
361 void AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]); | 428 void AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]); |
362 void AddEntryPoints(Dart_QualifiedFunctionName entry_points[]); | 429 void AddEntryPoints(Dart_QualifiedFunctionName entry_points[]); |
363 void Iterate(); | 430 void Iterate(); |
364 | 431 |
365 void AddType(const AbstractType& type); | 432 void AddType(const AbstractType& type); |
366 void AddTypesOf(const Class& cls); | 433 void AddTypesOf(const Class& cls); |
367 void AddTypesOf(const Function& function); | 434 void AddTypesOf(const Function& function); |
368 void AddTypeArguments(const TypeArguments& args); | 435 void AddTypeArguments(const TypeArguments& args); |
(...skipping 27 matching lines...) Expand all Loading... | |
396 void DedupStackMaps(); | 463 void DedupStackMaps(); |
397 void DedupLists(); | 464 void DedupLists(); |
398 void DedupInstructions(); | 465 void DedupInstructions(); |
399 void ResetPrecompilerState(); | 466 void ResetPrecompilerState(); |
400 | 467 |
401 void CollectDynamicFunctionNames(); | 468 void CollectDynamicFunctionNames(); |
402 | 469 |
403 void PrecompileStaticInitializers(); | 470 void PrecompileStaticInitializers(); |
404 void PrecompileConstructors(); | 471 void PrecompileConstructors(); |
405 | 472 |
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(); | 473 void FinalizeAllClasses(); |
419 void SortClasses(); | 474 void SortClasses(); |
420 void RemapClassIds(intptr_t* old_to_new_cid); | 475 void RemapClassIds(intptr_t* old_to_new_cid); |
476 void VerifyJITFeedback(); | |
477 RawScript* LookupScript(const char* uri); | |
478 intptr_t MapCid(intptr_t feedback_cid); | |
421 | 479 |
422 Thread* thread() const { return thread_; } | 480 Thread* thread() const { return thread_; } |
423 Zone* zone() const { return zone_; } | 481 Zone* zone() const { return zone_; } |
424 Isolate* isolate() const { return isolate_; } | 482 Isolate* isolate() const { return isolate_; } |
425 | 483 |
426 Thread* thread_; | 484 Thread* thread_; |
427 Zone* zone_; | 485 Zone* zone_; |
428 Isolate* isolate_; | 486 Isolate* isolate_; |
429 | 487 |
430 const bool reset_fields_; | 488 const bool reset_fields_; |
431 | 489 |
490 ParsedJSONObject* jit_feedback_; | |
491 | |
432 bool changed_; | 492 bool changed_; |
433 intptr_t function_count_; | 493 intptr_t function_count_; |
434 intptr_t class_count_; | 494 intptr_t class_count_; |
435 intptr_t selector_count_; | 495 intptr_t selector_count_; |
436 intptr_t dropped_function_count_; | 496 intptr_t dropped_function_count_; |
437 intptr_t dropped_field_count_; | 497 intptr_t dropped_field_count_; |
438 intptr_t dropped_class_count_; | 498 intptr_t dropped_class_count_; |
439 intptr_t dropped_typearg_count_; | 499 intptr_t dropped_typearg_count_; |
440 intptr_t dropped_type_count_; | 500 intptr_t dropped_type_count_; |
441 intptr_t dropped_library_count_; | 501 intptr_t dropped_library_count_; |
442 | 502 |
443 GrowableObjectArray& libraries_; | 503 GrowableObjectArray& libraries_; |
444 const GrowableObjectArray& pending_functions_; | 504 const GrowableObjectArray& pending_functions_; |
445 SymbolSet sent_selectors_; | 505 SymbolSet sent_selectors_; |
446 FunctionSet enqueued_functions_; | 506 FunctionSet enqueued_functions_; |
447 FieldSet fields_to_retain_; | 507 FieldSet fields_to_retain_; |
448 FunctionSet functions_to_retain_; | 508 FunctionSet functions_to_retain_; |
449 ClassSet classes_to_retain_; | 509 ClassSet classes_to_retain_; |
450 TypeArgumentsSet typeargs_to_retain_; | 510 TypeArgumentsSet typeargs_to_retain_; |
451 AbstractTypeSet types_to_retain_; | 511 AbstractTypeSet types_to_retain_; |
452 InstanceSet consts_to_retain_; | 512 InstanceSet consts_to_retain_; |
453 FieldTypeMap field_type_map_; | 513 FieldTypeMap field_type_map_; |
514 TypeRangeCache* type_range_cache_; | |
515 CidMap feedback_cid_map_; | |
516 FunctionFeedbackMap function_feedback_map_; | |
454 Error& error_; | 517 Error& error_; |
455 | 518 |
456 bool get_runtime_type_is_unique_; | 519 bool get_runtime_type_is_unique_; |
457 }; | 520 }; |
458 | 521 |
459 | 522 |
460 class FunctionsTraits { | 523 class FunctionsTraits { |
461 public: | 524 public: |
462 static const char* Name() { return "FunctionsTraits"; } | 525 static const char* Name() { return "FunctionsTraits"; } |
463 static bool ReportStats() { return false; } | 526 static bool ReportStats() { return false; } |
(...skipping 17 matching lines...) Expand all Loading... | |
481 } | 544 } |
482 static RawObject* NewKey(const Function& function) { return function.raw(); } | 545 static RawObject* NewKey(const Function& function) { return function.raw(); } |
483 }; | 546 }; |
484 | 547 |
485 typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet; | 548 typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet; |
486 | 549 |
487 | 550 |
488 } // namespace dart | 551 } // namespace dart |
489 | 552 |
490 #endif // RUNTIME_VM_PRECOMPILER_H_ | 553 #endif // RUNTIME_VM_PRECOMPILER_H_ |
OLD | NEW |