Index: runtime/vm/object.cc |
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
index 4a4d707d5c5cd3cac0f91bdf8a57269eadb03e4f..b698fd376a9f0c786b35e59b55a049af5969e7ed 100644 |
--- a/runtime/vm/object.cc |
+++ b/runtime/vm/object.cc |
@@ -210,6 +210,28 @@ static const char* MergeSubStrings(Zone* zone, |
} |
+// Remove private keys, but retain getter/setter/constructor/mixin manglings. |
+RawString* String::RemovePrivateKey(const String& name) { |
+ ASSERT(name.IsOneByteString()); |
+ GrowableArray<uint8_t> without_key(name.Length()); |
+ intptr_t i = 0; |
+ while (i < name.Length()) { |
+ while (i < name.Length()) { |
+ uint8_t c = name.CharAt(i++); |
+ if (c == '@') break; |
+ without_key.Add(c); |
+ } |
+ while (i < name.Length()) { |
+ uint8_t c = name.CharAt(i); |
+ if ((c < '0') || (c > '9')) break; |
+ i++; |
+ } |
+ } |
+ |
+ return String::FromLatin1(without_key.data(), without_key.length()); |
+} |
+ |
+ |
// Takes a vm internal name and makes it suitable for external user. |
// |
// Examples: |
@@ -7018,28 +7040,8 @@ RawString* Function::GetSource() const { |
// Construct fingerprint from token stream. The token stream contains also |
// arguments. |
int32_t Function::SourceFingerprint() const { |
- uint32_t result = 0; |
- Zone* zone = Thread::Current()->zone(); |
- TokenStream::Iterator tokens_iterator( |
- zone, TokenStream::Handle(zone, Script::Handle(zone, script()).tokens()), |
- token_pos()); |
- Object& obj = Object::Handle(zone); |
- String& literal = String::Handle(zone); |
- while (tokens_iterator.CurrentPosition() < end_token_pos()) { |
- uint32_t val = 0; |
- obj = tokens_iterator.CurrentToken(); |
- if (obj.IsSmi()) { |
- val = Smi::Cast(obj).Value(); |
- } else { |
- literal = tokens_iterator.MakeLiteralToken(obj); |
- val = literal.Hash(); |
- } |
- result = 31 * result + val; |
- tokens_iterator.Advance(); |
- } |
- result = result & ((static_cast<uint32_t>(1) << 31) - 1); |
- ASSERT(result <= static_cast<uint32_t>(kMaxInt32)); |
- return result; |
+ return Script::Handle(script()).SourceFingerprint(token_pos(), |
+ end_token_pos()); |
} |
@@ -7139,7 +7141,7 @@ bool Function::CheckSourceFingerprint(const char* prefix, int32_t fp) const { |
if (recalculatingFingerprints) { |
// This output can be copied into a file, then used with sed |
// to replace the old values. |
- // sed -i .bak -f /tmp/newkeys runtime/vm/method_recognizer.h |
+ // sed -i.bak -f /tmp/newkeys runtime/vm/method_recognizer.h |
THR_Print("s/0x%08x/0x%08x/\n", fp, SourceFingerprint()); |
} else { |
THR_Print( |
@@ -9002,6 +9004,43 @@ void Script::TokenRangeAtLine(intptr_t line_number, |
} |
+int32_t Script::SourceFingerprint() const { |
+ return SourceFingerprint(TokenPosition(TokenPosition::kMinSourcePos), |
+ TokenPosition(TokenPosition::kMaxSourcePos)); |
+} |
+ |
+ |
+int32_t Script::SourceFingerprint(TokenPosition start, |
+ TokenPosition end) const { |
+ uint32_t result = 0; |
+ Zone* zone = Thread::Current()->zone(); |
+ TokenStream::Iterator tokens_iterator( |
+ zone, TokenStream::Handle(zone, tokens()), start); |
+ Object& obj = Object::Handle(zone); |
+ String& literal = String::Handle(zone); |
+ while ((tokens_iterator.CurrentTokenKind() != Token::kEOS) && |
+ (tokens_iterator.CurrentPosition() < end)) { |
+ uint32_t val = 0; |
+ obj = tokens_iterator.CurrentToken(); |
+ if (obj.IsSmi()) { |
+ val = Smi::Cast(obj).Value(); |
+ } else { |
+ literal = tokens_iterator.MakeLiteralToken(obj); |
+ if (tokens_iterator.CurrentTokenKind() == Token::kIDENT || |
+ tokens_iterator.CurrentTokenKind() == Token::kINTERPOL_VAR) { |
+ literal = String::RemovePrivateKey(literal); |
+ } |
+ val = literal.Hash(); |
+ } |
+ result = 31 * result + val; |
+ tokens_iterator.Advance(); |
+ } |
+ result = result & ((static_cast<uint32_t>(1) << 31) - 1); |
+ ASSERT(result <= static_cast<uint32_t>(kMaxInt32)); |
+ return result; |
+} |
+ |
+ |
RawString* Script::GetLine(intptr_t line_number, Heap::Space space) const { |
const String& src = String::Handle(Source()); |
if (src.IsNull()) { |
@@ -12957,7 +12996,8 @@ bool ICData::ValidateInterceptor(const Function& target) const { |
} |
void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, |
- const Function& target) const { |
+ const Function& target, |
+ intptr_t count) const { |
ASSERT(!target.IsNull()); |
ASSERT((target.name() == target_name()) || ValidateInterceptor(target)); |
DEBUG_ASSERT(!HasCheck(class_ids)); |
@@ -13001,7 +13041,7 @@ void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, |
} |
ASSERT(!target.IsNull()); |
data.SetAt(data_pos++, target); |
- value = Smi::New(1); |
+ value = Smi::New(count); |
data.SetAt(data_pos, value); |
// Multithreaded access to ICData requires setting of array to be the last |
// operation. |