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 #include "vm/parser.h" | 5 #include "vm/parser.h" |
6 | 6 |
7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
9 #include "vm/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
(...skipping 11890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11901 | 11901 |
11902 bool Parser::IsInstantiatorRequired() const { | 11902 bool Parser::IsInstantiatorRequired() const { |
11903 ASSERT(!current_function().IsNull()); | 11903 ASSERT(!current_function().IsNull()); |
11904 if (current_function().is_static() && | 11904 if (current_function().is_static() && |
11905 !current_function().IsInFactoryScope()) { | 11905 !current_function().IsInFactoryScope()) { |
11906 return false; | 11906 return false; |
11907 } | 11907 } |
11908 return current_class().NumTypeParameters() > 0; | 11908 return current_class().NumTypeParameters() > 0; |
11909 } | 11909 } |
11910 | 11910 |
| 11911 // We cache computed compile-time constants in a map so we can look them |
| 11912 // up when the same code gets compiled again. The map key is a pair |
| 11913 // (script url, token position) which is encoded in an array with 2 |
| 11914 // elements: |
| 11915 // - key[0] contains the canonicalized url of the script. |
| 11916 // - key[1] contains the token position of the constant in the script. |
| 11917 |
| 11918 // ConstantPosKey allows us to look up a constant in the map without |
| 11919 // allocating a key pair (array). |
| 11920 struct ConstantPosKey : ValueObject { |
| 11921 ConstantPosKey(const String& url, intptr_t pos) |
| 11922 : script_url(url), token_pos(pos) { } |
| 11923 const String& script_url; |
| 11924 intptr_t token_pos; |
| 11925 }; |
| 11926 |
11911 | 11927 |
11912 class ConstMapKeyEqualsTraits { | 11928 class ConstMapKeyEqualsTraits { |
11913 public: | 11929 public: |
11914 static bool IsMatch(const Object& a, const Object& b) { | 11930 static bool IsMatch(const Object& a, const Object& b) { |
11915 return String::Cast(a).Equals(String::Cast(b)); | 11931 const Array& key1 = Array::Cast(a); |
| 11932 const Array& key2 = Array::Cast(b); |
| 11933 // Compare raw strings of script url symbol and raw smi of token positon. |
| 11934 return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1)); |
11916 } | 11935 } |
11917 static bool IsMatch(const char* key, const Object& b) { | 11936 static bool IsMatch(const ConstantPosKey& key1, const Object& b) { |
11918 return String::Cast(b).Equals(key); | 11937 const Array& key2 = Array::Cast(b); |
| 11938 // Compare raw strings of script url symbol and token positon. |
| 11939 return (key1.script_url.raw() == key2.At(0)) |
| 11940 && (key1.token_pos == Smi::Value(Smi::RawCast(key2.At(1)))); |
11919 } | 11941 } |
11920 static uword Hash(const Object& obj) { | 11942 static uword Hash(const Object& obj) { |
11921 return String::Cast(obj).Hash(); | 11943 const Array& key = Array::Cast(obj); |
| 11944 intptr_t url_hash = String::HashRawSymbol(String::RawCast(key.At(0))); |
| 11945 intptr_t pos = Smi::Value(Smi::RawCast(key.At(1))); |
| 11946 return HashValue(url_hash, pos); |
11922 } | 11947 } |
11923 static uword Hash(const char* key) { | 11948 static uword Hash(const ConstantPosKey& key) { |
11924 return String::Hash(key, strlen(key)); | 11949 return HashValue(String::HashRawSymbol(key.script_url.raw()), |
| 11950 key.token_pos); |
| 11951 } |
| 11952 // Used by CachConstantValue if a new constant is added to the map. |
| 11953 static RawObject* NewKey(const ConstantPosKey& key) { |
| 11954 const Array& key_obj = Array::Handle(Array::New(2)); |
| 11955 key_obj.SetAt(0, key.script_url); |
| 11956 key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos))); |
| 11957 return key_obj.raw();; |
| 11958 } |
| 11959 |
| 11960 private: |
| 11961 static uword HashValue(intptr_t url_hash, intptr_t pos) { |
| 11962 return url_hash * pos % (Smi::kMaxValue - 13); |
11925 } | 11963 } |
11926 }; | 11964 }; |
11927 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap; | 11965 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap; |
11928 | 11966 |
11929 | 11967 |
11930 void Parser::CacheConstantValue(intptr_t token_pos, const Instance& value) { | 11968 void Parser::CacheConstantValue(intptr_t token_pos, const Instance& value) { |
11931 String& key = String::Handle(Z, script_.url()); | 11969 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); |
11932 String& suffix = | |
11933 String::Handle(Z, String::NewFormatted("_%" Pd "", token_pos)); | |
11934 key = Symbols::FromConcat(key, suffix); | |
11935 if (isolate()->object_store()->compile_time_constants() == Array::null()) { | 11970 if (isolate()->object_store()->compile_time_constants() == Array::null()) { |
11936 const intptr_t kInitialConstMapSize = 16; | 11971 const intptr_t kInitialConstMapSize = 16; |
11937 isolate()->object_store()->set_compile_time_constants( | 11972 isolate()->object_store()->set_compile_time_constants( |
11938 Array::Handle(Z, HashTables::New<ConstantsMap>(kInitialConstMapSize, | 11973 Array::Handle(Z, HashTables::New<ConstantsMap>(kInitialConstMapSize, |
11939 Heap::kNew))); | 11974 Heap::kNew))); |
11940 } | 11975 } |
11941 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); | 11976 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); |
11942 constants.UpdateOrInsert(key, value); | 11977 constants.InsertNewOrGetValue(key, value); |
11943 if (FLAG_compiler_stats) { | 11978 if (FLAG_compiler_stats) { |
11944 isolate_->compiler_stats()->num_cached_consts = constants.NumOccupied(); | 11979 isolate_->compiler_stats()->num_cached_consts = constants.NumOccupied(); |
11945 } | 11980 } |
11946 isolate()->object_store()->set_compile_time_constants(constants.Release()); | 11981 isolate()->object_store()->set_compile_time_constants(constants.Release()); |
11947 } | 11982 } |
11948 | 11983 |
11949 | 11984 |
11950 bool Parser::GetCachedConstant(intptr_t token_pos, Instance* value) { | 11985 bool Parser::GetCachedConstant(intptr_t token_pos, Instance* value) { |
11951 if (isolate()->object_store()->compile_time_constants() == Array::null()) { | 11986 if (isolate()->object_store()->compile_time_constants() == Array::null()) { |
11952 return false; | 11987 return false; |
11953 } | 11988 } |
11954 // We don't want to allocate anything in the heap here since this code | 11989 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); |
11955 // is called from the optimizing compiler in the background thread. Allocate | |
11956 // the key value in the zone instead. | |
11957 // const char* key = Z->PrintToString("%s_%" Pd "", | |
11958 // String::Handle(Z, script_.url()).ToCString(), | |
11959 // token_pos); | |
11960 | |
11961 const String& key = String::Handle(Z, | |
11962 Symbols::NewFormatted("%s_%" Pd "", | |
11963 String::Handle(Z, script_.url()).ToCString(), | |
11964 token_pos)); | |
11965 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); | 11990 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); |
11966 bool is_present = false; | 11991 bool is_present = false; |
11967 *value ^= constants.GetOrNull(key, &is_present); | 11992 *value ^= constants.GetOrNull(key, &is_present); |
11968 ASSERT(constants.Release().raw() == | 11993 ASSERT(constants.Release().raw() == |
11969 isolate()->object_store()->compile_time_constants()); | 11994 isolate()->object_store()->compile_time_constants()); |
11970 if (FLAG_compiler_stats && is_present) { | 11995 if (FLAG_compiler_stats && is_present) { |
11971 isolate_->compiler_stats()->num_const_cache_hits++; | 11996 isolate_->compiler_stats()->num_const_cache_hits++; |
11972 } | 11997 } |
11973 return is_present; | 11998 return is_present; |
11974 } | 11999 } |
(...skipping 2331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14306 void Parser::SkipQualIdent() { | 14331 void Parser::SkipQualIdent() { |
14307 ASSERT(IsIdentifier()); | 14332 ASSERT(IsIdentifier()); |
14308 ConsumeToken(); | 14333 ConsumeToken(); |
14309 if (CurrentToken() == Token::kPERIOD) { | 14334 if (CurrentToken() == Token::kPERIOD) { |
14310 ConsumeToken(); // Consume the kPERIOD token. | 14335 ConsumeToken(); // Consume the kPERIOD token. |
14311 ExpectIdentifier("identifier expected after '.'"); | 14336 ExpectIdentifier("identifier expected after '.'"); |
14312 } | 14337 } |
14313 } | 14338 } |
14314 | 14339 |
14315 } // namespace dart | 14340 } // namespace dart |
OLD | NEW |