| 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 |