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