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

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

Issue 2572423004: Reapply "Save and restore feedback from JIT." (Closed)
Patch Set: Created 4 years 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
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/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/become.h" 10 #include "vm/become.h"
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 const intptr_t piece_len = strlen(segments[k]); 203 const intptr_t piece_len = strlen(segments[k]);
204 memmove(result + pos, piece, piece_len); 204 memmove(result + pos, piece, piece_len);
205 pos += piece_len; 205 pos += piece_len;
206 ASSERT(pos <= alloc_len); 206 ASSERT(pos <= alloc_len);
207 } 207 }
208 result[pos] = '\0'; 208 result[pos] = '\0';
209 return result; 209 return result;
210 } 210 }
211 211
212 212
213 // Remove private keys, but retain getter/setter/constructor/mixin manglings.
214 RawString* String::RemovePrivateKey(const String& name) {
215 ASSERT(name.IsOneByteString());
216 GrowableArray<uint8_t> without_key(name.Length());
217 intptr_t i = 0;
218 while (i < name.Length()) {
219 while (i < name.Length()) {
220 uint8_t c = name.CharAt(i++);
221 if (c == '@') break;
222 without_key.Add(c);
223 }
224 while (i < name.Length()) {
225 uint8_t c = name.CharAt(i);
226 if ((c < '0') || (c > '9')) break;
227 i++;
228 }
229 }
230
231 return String::FromLatin1(without_key.data(), without_key.length());
232 }
233
234
213 // Takes a vm internal name and makes it suitable for external user. 235 // Takes a vm internal name and makes it suitable for external user.
214 // 236 //
215 // Examples: 237 // Examples:
216 // 238 //
217 // Internal getter and setter prefixes are changed: 239 // Internal getter and setter prefixes are changed:
218 // 240 //
219 // get:foo -> foo 241 // get:foo -> foo
220 // set:foo -> foo= 242 // set:foo -> foo=
221 // 243 //
222 // Private name mangling is removed, possibly multiple times: 244 // Private name mangling is removed, possibly multiple times:
(...skipping 6788 matching lines...) Expand 10 before | Expand all | Expand 10 after
7011 String::Handle(zone, func_script.GetSnippet(from_line, from_col, to_line, 7033 String::Handle(zone, func_script.GetSnippet(from_line, from_col, to_line,
7012 to_col + last_tok_len)); 7034 to_col + last_tok_len));
7013 ASSERT(!result.IsNull()); 7035 ASSERT(!result.IsNull());
7014 return result.raw(); 7036 return result.raw();
7015 } 7037 }
7016 7038
7017 7039
7018 // Construct fingerprint from token stream. The token stream contains also 7040 // Construct fingerprint from token stream. The token stream contains also
7019 // arguments. 7041 // arguments.
7020 int32_t Function::SourceFingerprint() const { 7042 int32_t Function::SourceFingerprint() const {
7021 uint32_t result = 0; 7043 return Script::Handle(script()).SourceFingerprint(token_pos(),
7022 Zone* zone = Thread::Current()->zone(); 7044 end_token_pos());
7023 TokenStream::Iterator tokens_iterator(
7024 zone, TokenStream::Handle(zone, Script::Handle(zone, script()).tokens()),
7025 token_pos());
7026 Object& obj = Object::Handle(zone);
7027 String& literal = String::Handle(zone);
7028 while (tokens_iterator.CurrentPosition() < end_token_pos()) {
7029 uint32_t val = 0;
7030 obj = tokens_iterator.CurrentToken();
7031 if (obj.IsSmi()) {
7032 val = Smi::Cast(obj).Value();
7033 } else {
7034 literal = tokens_iterator.MakeLiteralToken(obj);
7035 val = literal.Hash();
7036 }
7037 result = 31 * result + val;
7038 tokens_iterator.Advance();
7039 }
7040 result = result & ((static_cast<uint32_t>(1) << 31) - 1);
7041 ASSERT(result <= static_cast<uint32_t>(kMaxInt32));
7042 return result;
7043 } 7045 }
7044 7046
7045 7047
7046 void Function::SaveICDataMap( 7048 void Function::SaveICDataMap(
7047 const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data, 7049 const ZoneGrowableArray<const ICData*>& deopt_id_to_ic_data,
7048 const Array& edge_counters_array) const { 7050 const Array& edge_counters_array) const {
7049 // Compute number of ICData objects to save. 7051 // Compute number of ICData objects to save.
7050 // Store edge counter array in the first slot. 7052 // Store edge counter array in the first slot.
7051 intptr_t count = 1; 7053 intptr_t count = 1;
7052 for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) { 7054 for (intptr_t i = 0; i < deopt_id_to_ic_data.length(); i++) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
7132 } 7134 }
7133 } 7135 }
7134 7136
7135 7137
7136 bool Function::CheckSourceFingerprint(const char* prefix, int32_t fp) const { 7138 bool Function::CheckSourceFingerprint(const char* prefix, int32_t fp) const {
7137 if ((kernel_function() == NULL) && (SourceFingerprint() != fp)) { 7139 if ((kernel_function() == NULL) && (SourceFingerprint() != fp)) {
7138 const bool recalculatingFingerprints = false; 7140 const bool recalculatingFingerprints = false;
7139 if (recalculatingFingerprints) { 7141 if (recalculatingFingerprints) {
7140 // This output can be copied into a file, then used with sed 7142 // This output can be copied into a file, then used with sed
7141 // to replace the old values. 7143 // to replace the old values.
7142 // sed -i .bak -f /tmp/newkeys runtime/vm/method_recognizer.h 7144 // sed -i.bak -f /tmp/newkeys runtime/vm/method_recognizer.h
7143 THR_Print("s/0x%08x/0x%08x/\n", fp, SourceFingerprint()); 7145 THR_Print("s/0x%08x/0x%08x/\n", fp, SourceFingerprint());
7144 } else { 7146 } else {
7145 THR_Print( 7147 THR_Print(
7146 "FP mismatch while recognizing method %s:" 7148 "FP mismatch while recognizing method %s:"
7147 " expecting 0x%08x found 0x%08x\n", 7149 " expecting 0x%08x found 0x%08x\n",
7148 ToFullyQualifiedCString(), fp, SourceFingerprint()); 7150 ToFullyQualifiedCString(), fp, SourceFingerprint());
7149 return false; 7151 return false;
7150 } 7152 }
7151 } 7153 }
7152 return true; 7154 return true;
(...skipping 1842 matching lines...) Expand 10 before | Expand all | Expand 10 after
8995 TokenPosition end_pos = *first_token_index; 8997 TokenPosition end_pos = *first_token_index;
8996 while (tkit.CurrentTokenKind() != Token::kNEWLINE && 8998 while (tkit.CurrentTokenKind() != Token::kNEWLINE &&
8997 tkit.CurrentTokenKind() != Token::kEOS) { 8999 tkit.CurrentTokenKind() != Token::kEOS) {
8998 end_pos = tkit.CurrentPosition(); 9000 end_pos = tkit.CurrentPosition();
8999 tkit.Advance(); 9001 tkit.Advance();
9000 } 9002 }
9001 *last_token_index = end_pos; 9003 *last_token_index = end_pos;
9002 } 9004 }
9003 9005
9004 9006
9007 int32_t Script::SourceFingerprint() const {
9008 return SourceFingerprint(TokenPosition(TokenPosition::kMinSourcePos),
9009 TokenPosition(TokenPosition::kMaxSourcePos));
9010 }
9011
9012
9013 int32_t Script::SourceFingerprint(TokenPosition start,
9014 TokenPosition end) const {
9015 uint32_t result = 0;
9016 Zone* zone = Thread::Current()->zone();
9017 TokenStream::Iterator tokens_iterator(
9018 zone, TokenStream::Handle(zone, tokens()), start);
9019 Object& obj = Object::Handle(zone);
9020 String& literal = String::Handle(zone);
9021 while ((tokens_iterator.CurrentTokenKind() != Token::kEOS) &&
9022 (tokens_iterator.CurrentPosition() < end)) {
9023 uint32_t val = 0;
9024 obj = tokens_iterator.CurrentToken();
9025 if (obj.IsSmi()) {
9026 val = Smi::Cast(obj).Value();
9027 } else {
9028 literal = tokens_iterator.MakeLiteralToken(obj);
9029 if (tokens_iterator.CurrentTokenKind() == Token::kIDENT ||
9030 tokens_iterator.CurrentTokenKind() == Token::kINTERPOL_VAR) {
9031 literal = String::RemovePrivateKey(literal);
9032 }
9033 val = literal.Hash();
9034 }
9035 result = 31 * result + val;
9036 tokens_iterator.Advance();
9037 }
9038 result = result & ((static_cast<uint32_t>(1) << 31) - 1);
9039 ASSERT(result <= static_cast<uint32_t>(kMaxInt32));
9040 return result;
9041 }
9042
9043
9005 RawString* Script::GetLine(intptr_t line_number, Heap::Space space) const { 9044 RawString* Script::GetLine(intptr_t line_number, Heap::Space space) const {
9006 const String& src = String::Handle(Source()); 9045 const String& src = String::Handle(Source());
9007 if (src.IsNull()) { 9046 if (src.IsNull()) {
9008 ASSERT(Dart::snapshot_kind() == Snapshot::kAppAOT); 9047 ASSERT(Dart::snapshot_kind() == Snapshot::kAppAOT);
9009 return Symbols::OptimizedOut().raw(); 9048 return Symbols::OptimizedOut().raw();
9010 } 9049 }
9011 intptr_t relative_line_number = line_number - line_offset(); 9050 intptr_t relative_line_number = line_number - line_offset();
9012 intptr_t current_line = 1; 9051 intptr_t current_line = 1;
9013 intptr_t line_start_idx = -1; 9052 intptr_t line_start_idx = -1;
9014 intptr_t last_char_idx = -1; 9053 intptr_t last_char_idx = -1;
(...skipping 3935 matching lines...) Expand 10 before | Expand all | Expand 10 after
12950 ObjectStore* store = Isolate::Current()->object_store(); 12989 ObjectStore* store = Isolate::Current()->object_store();
12951 ASSERT((target.raw() == store->simple_instance_of_true_function()) || 12990 ASSERT((target.raw() == store->simple_instance_of_true_function()) ||
12952 (target.raw() == store->simple_instance_of_false_function())); 12991 (target.raw() == store->simple_instance_of_false_function()));
12953 const String& instance_of_name = String::Handle( 12992 const String& instance_of_name = String::Handle(
12954 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()).raw()); 12993 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()).raw());
12955 ASSERT(target_name() == instance_of_name.raw()); 12994 ASSERT(target_name() == instance_of_name.raw());
12956 return true; 12995 return true;
12957 } 12996 }
12958 12997
12959 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, 12998 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
12960 const Function& target) const { 12999 const Function& target,
13000 intptr_t count) const {
12961 ASSERT(!target.IsNull()); 13001 ASSERT(!target.IsNull());
12962 ASSERT((target.name() == target_name()) || ValidateInterceptor(target)); 13002 ASSERT((target.name() == target_name()) || ValidateInterceptor(target));
12963 DEBUG_ASSERT(!HasCheck(class_ids)); 13003 DEBUG_ASSERT(!HasCheck(class_ids));
12964 ASSERT(NumArgsTested() > 1); // Otherwise use 'AddReceiverCheck'. 13004 ASSERT(NumArgsTested() > 1); // Otherwise use 'AddReceiverCheck'.
12965 ASSERT(class_ids.length() == NumArgsTested()); 13005 ASSERT(class_ids.length() == NumArgsTested());
12966 const intptr_t old_num = NumberOfChecks(); 13006 const intptr_t old_num = NumberOfChecks();
12967 Array& data = Array::Handle(ic_data()); 13007 Array& data = Array::Handle(ic_data());
12968 // ICData of static calls with NumArgsTested() > 0 have initially a 13008 // ICData of static calls with NumArgsTested() > 0 have initially a
12969 // dummy set of cids entered (see ICData::AddTarget). That entry is 13009 // dummy set of cids entered (see ICData::AddTarget). That entry is
12970 // overwritten by first real type feedback data. 13010 // overwritten by first real type feedback data.
(...skipping 23 matching lines...) Expand all
12994 intptr_t data_pos = index * TestEntryLength(); 13034 intptr_t data_pos = index * TestEntryLength();
12995 Smi& value = Smi::Handle(); 13035 Smi& value = Smi::Handle();
12996 for (intptr_t i = 0; i < class_ids.length(); i++) { 13036 for (intptr_t i = 0; i < class_ids.length(); i++) {
12997 // kIllegalCid is used as terminating value, do not add it. 13037 // kIllegalCid is used as terminating value, do not add it.
12998 ASSERT(class_ids[i] != kIllegalCid); 13038 ASSERT(class_ids[i] != kIllegalCid);
12999 value = Smi::New(class_ids[i]); 13039 value = Smi::New(class_ids[i]);
13000 data.SetAt(data_pos++, value); 13040 data.SetAt(data_pos++, value);
13001 } 13041 }
13002 ASSERT(!target.IsNull()); 13042 ASSERT(!target.IsNull());
13003 data.SetAt(data_pos++, target); 13043 data.SetAt(data_pos++, target);
13004 value = Smi::New(1); 13044 value = Smi::New(count);
13005 data.SetAt(data_pos, value); 13045 data.SetAt(data_pos, value);
13006 // Multithreaded access to ICData requires setting of array to be the last 13046 // Multithreaded access to ICData requires setting of array to be the last
13007 // operation. 13047 // operation.
13008 set_ic_data_array(data); 13048 set_ic_data_array(data);
13009 } 13049 }
13010 13050
13011 13051
13012 RawArray* ICData::FindFreeIndex(intptr_t* index) const { 13052 RawArray* ICData::FindFreeIndex(intptr_t* index) const {
13013 // The final entry is always the sentinel value, don't consider it 13053 // The final entry is always the sentinel value, don't consider it
13014 // when searching. 13054 // when searching.
(...skipping 9750 matching lines...) Expand 10 before | Expand all | Expand 10 after
22765 return UserTag::null(); 22805 return UserTag::null();
22766 } 22806 }
22767 22807
22768 22808
22769 const char* UserTag::ToCString() const { 22809 const char* UserTag::ToCString() const {
22770 const String& tag_label = String::Handle(label()); 22810 const String& tag_label = String::Handle(label());
22771 return tag_label.ToCString(); 22811 return tag_label.ToCString();
22772 } 22812 }
22773 22813
22774 } // namespace dart 22814 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698