OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 VM_PARSER_H_ | 5 #ifndef VM_PARSER_H_ |
6 #define VM_PARSER_H_ | 6 #define VM_PARSER_H_ |
7 | 7 |
8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
9 | 9 |
10 #include "platform/assert.h" | 10 #include "platform/assert.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 class Parser; | 32 class Parser; |
33 | 33 |
34 struct CatchParamDesc; | 34 struct CatchParamDesc; |
35 class ClassDesc; | 35 class ClassDesc; |
36 struct MemberDesc; | 36 struct MemberDesc; |
37 struct ParamList; | 37 struct ParamList; |
38 struct QualIdent; | 38 struct QualIdent; |
39 class TopLevel; | 39 class TopLevel; |
40 class RecursionChecker; | 40 class RecursionChecker; |
41 | 41 |
42 // We cache computed compile-time constants in a map so we can look them | 42 // We cache compile time constants during compilation. This allows us |
43 // up when the same code gets compiled again. The map key is a pair | 43 // to look them up when the same code gets compiled again. During |
44 // (script url, token position) which is encoded in an array with 2 | 44 // background compilation, we are not able to evaluate the constants |
45 // elements: | 45 // so this cache is necessary to support background compilation. |
| 46 // |
| 47 // There are two places a constant can be cached, depending on whether |
| 48 // the script is in the vm heap (snapshot) or not. |
| 49 // |
| 50 // When a script is in the vm heap, we are not able to cache the |
| 51 // constants on the script itself (it is read-only) so we cache them |
| 52 // in a per-isolate shared map in the object store. In this case the |
| 53 // map key is a pair (array) with 2 elements: |
| 54 // |
46 // - key[0] contains the canonicalized url of the script. | 55 // - key[0] contains the canonicalized url of the script. |
47 // - key[1] contains the token position of the constant in the script. | 56 // - key[1] contains the token position of the constant in the script. |
| 57 // |
| 58 // The VMConstantsMap type is used to implement this per-isolate map. |
| 59 // |
| 60 // When a script is not in the vm heap, we cache the constants with |
| 61 // the script itself. This is helpful during isolate reloading, as it |
| 62 // allows us to reference the compile time constants associated with a |
| 63 // particular version of a script. In this case the map key is simply |
| 64 // the TokenPosition where the constant is defined. |
| 65 // |
| 66 // The ConstantsMap type is used to implement this per-script map. |
48 | 67 |
49 // ConstantPosKey allows us to look up a constant in the map without | 68 // The key for the per-isolate compile time constants map. By using a |
50 // allocating a key pair (array). | 69 // ValueObject we are able to look up a constant without allocating a |
51 struct ConstantPosKey : ValueObject { | 70 // key pair (array). |
52 ConstantPosKey(const String& url, TokenPosition pos) | 71 // The per-script compile-time constants map. |
| 72 struct UrlAndPosKey : ValueObject { |
| 73 UrlAndPosKey(const String& url, TokenPosition pos) |
53 : script_url(url), token_pos(pos) { } | 74 : script_url(url), token_pos(pos) { } |
54 const String& script_url; | 75 const String& script_url; |
55 TokenPosition token_pos; | 76 TokenPosition token_pos; |
56 }; | 77 }; |
57 | 78 |
58 | 79 // The per-isolate compile-time constants map. |
59 class ConstMapKeyEqualsTraits { | 80 class VMConstMapKeyEqualsTraits { |
60 public: | 81 public: |
61 static const char* Name() { return "ConstMapKeyEqualsTraits"; } | 82 static const char* Name() { return "VMConstMapKeyEqualsTraits"; } |
62 static bool ReportStats() { return false; } | 83 static bool ReportStats() { return false; } |
63 | 84 |
64 static bool IsMatch(const Object& a, const Object& b) { | 85 static bool IsMatch(const Object& a, const Object& b) { |
65 const Array& key1 = Array::Cast(a); | 86 const Array& key1 = Array::Cast(a); |
66 const Array& key2 = Array::Cast(b); | 87 const Array& key2 = Array::Cast(b); |
67 // Compare raw strings of script url symbol and raw smi of token positon. | 88 // Compare raw strings of script url symbol and raw smi of token positon. |
68 return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1)); | 89 return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1)); |
69 } | 90 } |
70 static bool IsMatch(const ConstantPosKey& key1, const Object& b) { | 91 static bool IsMatch(const UrlAndPosKey& key1, const Object& b) { |
71 const Array& key2 = Array::Cast(b); | 92 const Array& key2 = Array::Cast(b); |
72 // Compare raw strings of script url symbol and token positon. | 93 // Compare raw strings of script url symbol and token positon. |
73 return (key1.script_url.raw() == key2.At(0)) | 94 return (key1.script_url.raw() == key2.At(0)) |
74 && (key1.token_pos.value() == Smi::Value(Smi::RawCast(key2.At(1)))); | 95 && (key1.token_pos.value() == Smi::Value(Smi::RawCast(key2.At(1)))); |
75 } | 96 } |
76 static uword Hash(const Object& obj) { | 97 static uword Hash(const Object& obj) { |
77 const Array& key = Array::Cast(obj); | 98 const Array& key = Array::Cast(obj); |
78 intptr_t url_hash = String::HashRawSymbol(String::RawCast(key.At(0))); | 99 intptr_t url_hash = String::HashRawSymbol(String::RawCast(key.At(0))); |
79 intptr_t pos = Smi::Value(Smi::RawCast(key.At(1))); | 100 intptr_t pos = Smi::Value(Smi::RawCast(key.At(1))); |
80 return HashValue(url_hash, pos); | 101 return HashValue(url_hash, pos); |
81 } | 102 } |
82 static uword Hash(const ConstantPosKey& key) { | 103 static uword Hash(const UrlAndPosKey& key) { |
83 return HashValue(String::HashRawSymbol(key.script_url.raw()), | 104 return HashValue(String::HashRawSymbol(key.script_url.raw()), |
84 key.token_pos.value()); | 105 key.token_pos.value()); |
85 } | 106 } |
86 // Used by CachConstantValue if a new constant is added to the map. | 107 // Used by CacheConstantValue if a new constant is added to the map. |
87 static RawObject* NewKey(const ConstantPosKey& key) { | 108 static RawObject* NewKey(const UrlAndPosKey& key) { |
88 const Array& key_obj = Array::Handle(Array::New(2)); | 109 const Array& key_obj = Array::Handle(Array::New(2)); |
89 key_obj.SetAt(0, key.script_url); | 110 key_obj.SetAt(0, key.script_url); |
90 key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos.value()))); | 111 key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos.value()))); |
91 return key_obj.raw();; | 112 return key_obj.raw();; |
92 } | 113 } |
93 | 114 |
94 private: | 115 private: |
95 static uword HashValue(intptr_t url_hash, intptr_t pos) { | 116 static uword HashValue(intptr_t url_hash, intptr_t pos) { |
96 return url_hash * pos % (Smi::kMaxValue - 13); | 117 return url_hash * pos % (Smi::kMaxValue - 13); |
97 } | 118 } |
98 }; | 119 }; |
| 120 typedef UnorderedHashMap<VMConstMapKeyEqualsTraits> VMConstantsMap; |
| 121 |
| 122 class ConstMapKeyEqualsTraits { |
| 123 public: |
| 124 static const char* Name() { return "ConstMapKeyEqualsTraits"; } |
| 125 static bool ReportStats() { return false; } |
| 126 |
| 127 static bool IsMatch(const Object& a, const Object& b) { |
| 128 const Smi& key1 = Smi::Cast(a); |
| 129 const Smi& key2 = Smi::Cast(b); |
| 130 return (key1.Value() == key2.Value()); |
| 131 } |
| 132 static bool IsMatch(const TokenPosition& key1, const Object& b) { |
| 133 const Smi& key2 = Smi::Cast(b); |
| 134 return (key1.value() == key2.Value()); |
| 135 } |
| 136 static uword Hash(const Object& obj) { |
| 137 const Smi& key = Smi::Cast(obj); |
| 138 return HashValue(key.Value()); |
| 139 } |
| 140 static uword Hash(const TokenPosition& key) { |
| 141 return HashValue(key.value()); |
| 142 } |
| 143 // Used by CacheConstantValue if a new constant is added to the map. |
| 144 static RawObject* NewKey(const TokenPosition& key) { |
| 145 return Smi::New(key.value()); |
| 146 } |
| 147 |
| 148 private: |
| 149 static uword HashValue(intptr_t pos) { |
| 150 return pos % (Smi::kMaxValue - 13); |
| 151 } |
| 152 }; |
99 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap; | 153 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap; |
100 | 154 |
101 // The class ParsedFunction holds the result of parsing a function. | 155 // The class ParsedFunction holds the result of parsing a function. |
102 class ParsedFunction : public ZoneAllocated { | 156 class ParsedFunction : public ZoneAllocated { |
103 public: | 157 public: |
104 ParsedFunction(Thread* thread, const Function& function) | 158 ParsedFunction(Thread* thread, const Function& function) |
105 : thread_(thread), | 159 : thread_(thread), |
106 function_(function), | 160 function_(function), |
107 code_(Code::Handle(zone(), function.unoptimized_code())), | 161 code_(Code::Handle(zone(), function.unoptimized_code())), |
108 node_sequence_(NULL), | 162 node_sequence_(NULL), |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 | 325 |
272 // Parse and evaluate the metadata expressions at token_pos in the | 326 // Parse and evaluate the metadata expressions at token_pos in the |
273 // class namespace of class cls (which can be the implicit toplevel | 327 // class namespace of class cls (which can be the implicit toplevel |
274 // class if the metadata is at the top-level). | 328 // class if the metadata is at the top-level). |
275 static RawObject* ParseMetadata(const Field& meta_data); | 329 static RawObject* ParseMetadata(const Field& meta_data); |
276 | 330 |
277 // Build a function containing the initializer expression of the | 331 // Build a function containing the initializer expression of the |
278 // given static field. | 332 // given static field. |
279 static ParsedFunction* ParseStaticFieldInitializer(const Field& field); | 333 static ParsedFunction* ParseStaticFieldInitializer(const Field& field); |
280 | 334 |
281 static void InsertCachedConstantValue(const String& url, | 335 static void InsertCachedConstantValue(const Script& script, |
282 TokenPosition token_pos, | 336 TokenPosition token_pos, |
283 const Instance& value); | 337 const Instance& value); |
284 | 338 |
285 // Parse a function to retrieve parameter information that is not retained in | 339 // Parse a function to retrieve parameter information that is not retained in |
286 // the dart::Function object. Returns either an error if the parse fails | 340 // the dart::Function object. Returns either an error if the parse fails |
287 // (which could be the case for local functions), or a flat array of entries | 341 // (which could be the case for local functions), or a flat array of entries |
288 // for each parameter. Each parameter entry contains: | 342 // for each parameter. Each parameter entry contains: |
289 // * a Dart bool indicating whether the parameter was declared final | 343 // * a Dart bool indicating whether the parameter was declared final |
290 // * its default value (or null if none was declared) | 344 // * its default value (or null if none was declared) |
291 // * an array of metadata (or null if no metadata was declared). | 345 // * an array of metadata (or null if no metadata was declared). |
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 | 1038 |
985 intptr_t recursion_counter_; | 1039 intptr_t recursion_counter_; |
986 friend class RecursionChecker; | 1040 friend class RecursionChecker; |
987 | 1041 |
988 DISALLOW_COPY_AND_ASSIGN(Parser); | 1042 DISALLOW_COPY_AND_ASSIGN(Parser); |
989 }; | 1043 }; |
990 | 1044 |
991 } // namespace dart | 1045 } // namespace dart |
992 | 1046 |
993 #endif // VM_PARSER_H_ | 1047 #endif // VM_PARSER_H_ |
OLD | NEW |