Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: runtime/vm/parser.cc

Issue 1424393002: Constant cache improvement (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698