Index: runtime/vm/parser.h |
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h |
index 815f97860dd9fcb920039dbb77c3620f610ad113..e852456c62f5cac79e1638f80acef414213dd69b 100644 |
--- a/runtime/vm/parser.h |
+++ b/runtime/vm/parser.h |
@@ -39,26 +39,47 @@ struct QualIdent; |
class TopLevel; |
class RecursionChecker; |
-// We cache computed compile-time constants in a map so we can look them |
-// up when the same code gets compiled again. The map key is a pair |
-// (script url, token position) which is encoded in an array with 2 |
-// elements: |
+// We cache compile time constants during compilation. This allows us |
+// to look them up when the same code gets compiled again. During |
+// background compilation, we are not able to evaluate the constants |
+// so this cache is necessary to support background compilation. |
+// |
+// There are two places a constant can be cached, depending on whether |
+// the script is in the vm heap (snapshot) or not. |
+// |
+// When a script is in the vm heap, we are not able to cache the |
+// constants on the script itself (it is read-only) so we cache them |
+// in a per-isolate shared map in the object store. In this case the |
+// map key is a pair (array) with 2 elements: |
+// |
// - key[0] contains the canonicalized url of the script. |
// - key[1] contains the token position of the constant in the script. |
- |
-// ConstantPosKey allows us to look up a constant in the map without |
-// allocating a key pair (array). |
-struct ConstantPosKey : ValueObject { |
- ConstantPosKey(const String& url, TokenPosition pos) |
+// |
+// The VMConstantsMap type is used to implement this per-isolate map. |
+// |
+// When a script is not in the vm heap, we cache the constants with |
+// the script itself. This is helpful during isolate reloading, as it |
+// allows us to reference the compile time constants associated with a |
+// particular version of a script. In this case the map key is simply |
+// the TokenPosition where the constant is defined. |
+// |
+// The ConstantsMap type is used to implement this per-script map. |
+ |
+// The key for the per-isolate compile time constants map. By using a |
+// ValueObject we are able to look up a constant without allocating a |
+// key pair (array). |
+// The per-script compile-time constants map. |
+struct UrlAndPosKey : ValueObject { |
+ UrlAndPosKey(const String& url, TokenPosition pos) |
: script_url(url), token_pos(pos) { } |
const String& script_url; |
TokenPosition token_pos; |
}; |
- |
-class ConstMapKeyEqualsTraits { |
+// The per-isolate compile-time constants map. |
+class VMConstMapKeyEqualsTraits { |
public: |
- static const char* Name() { return "ConstMapKeyEqualsTraits"; } |
+ static const char* Name() { return "VMConstMapKeyEqualsTraits"; } |
static bool ReportStats() { return false; } |
static bool IsMatch(const Object& a, const Object& b) { |
@@ -67,7 +88,7 @@ class ConstMapKeyEqualsTraits { |
// Compare raw strings of script url symbol and raw smi of token positon. |
return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1)); |
} |
- static bool IsMatch(const ConstantPosKey& key1, const Object& b) { |
+ static bool IsMatch(const UrlAndPosKey& key1, const Object& b) { |
const Array& key2 = Array::Cast(b); |
// Compare raw strings of script url symbol and token positon. |
return (key1.script_url.raw() == key2.At(0)) |
@@ -79,12 +100,12 @@ class ConstMapKeyEqualsTraits { |
intptr_t pos = Smi::Value(Smi::RawCast(key.At(1))); |
return HashValue(url_hash, pos); |
} |
- static uword Hash(const ConstantPosKey& key) { |
+ static uword Hash(const UrlAndPosKey& key) { |
return HashValue(String::HashRawSymbol(key.script_url.raw()), |
key.token_pos.value()); |
} |
- // Used by CachConstantValue if a new constant is added to the map. |
- static RawObject* NewKey(const ConstantPosKey& key) { |
+ // Used by CacheConstantValue if a new constant is added to the map. |
+ static RawObject* NewKey(const UrlAndPosKey& key) { |
const Array& key_obj = Array::Handle(Array::New(2)); |
key_obj.SetAt(0, key.script_url); |
key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos.value()))); |
@@ -96,6 +117,39 @@ class ConstMapKeyEqualsTraits { |
return url_hash * pos % (Smi::kMaxValue - 13); |
} |
}; |
+typedef UnorderedHashMap<VMConstMapKeyEqualsTraits> VMConstantsMap; |
+ |
+class ConstMapKeyEqualsTraits { |
+ public: |
+ static const char* Name() { return "ConstMapKeyEqualsTraits"; } |
+ static bool ReportStats() { return false; } |
+ |
+ static bool IsMatch(const Object& a, const Object& b) { |
+ const Smi& key1 = Smi::Cast(a); |
+ const Smi& key2 = Smi::Cast(b); |
+ return (key1.Value() == key2.Value()); |
+ } |
+ static bool IsMatch(const TokenPosition& key1, const Object& b) { |
+ const Smi& key2 = Smi::Cast(b); |
+ return (key1.value() == key2.Value()); |
+ } |
+ static uword Hash(const Object& obj) { |
+ const Smi& key = Smi::Cast(obj); |
+ return HashValue(key.Value()); |
+ } |
+ static uword Hash(const TokenPosition& key) { |
+ return HashValue(key.value()); |
+ } |
+ // Used by CacheConstantValue if a new constant is added to the map. |
+ static RawObject* NewKey(const TokenPosition& key) { |
+ return Smi::New(key.value()); |
+ } |
+ |
+ private: |
+ static uword HashValue(intptr_t pos) { |
+ return pos % (Smi::kMaxValue - 13); |
+ } |
+}; |
typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap; |
// The class ParsedFunction holds the result of parsing a function. |
@@ -278,7 +332,7 @@ class Parser : public ValueObject { |
// given static field. |
static ParsedFunction* ParseStaticFieldInitializer(const Field& field); |
- static void InsertCachedConstantValue(const String& url, |
+ static void InsertCachedConstantValue(const Script& script, |
TokenPosition token_pos, |
const Instance& value); |