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

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

Issue 10796103: Use kIllegalObjectKind instead of NULL object to terminate ICData array (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 months 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | 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/object.h" 5 #include "vm/object.h"
6 6
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/bigint_operations.h" 9 #include "vm/bigint_operations.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 7194 matching lines...) Expand 10 before | Expand all | Expand 10 after
7205 return num_args_tested() + 1 /* target function*/; 7205 return num_args_tested() + 1 /* target function*/;
7206 } 7206 }
7207 7207
7208 7208
7209 intptr_t ICData::NumberOfChecks() const { 7209 intptr_t ICData::NumberOfChecks() const {
7210 // Do not count the sentinel; 7210 // Do not count the sentinel;
7211 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1; 7211 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1;
7212 } 7212 }
7213 7213
7214 7214
7215 void ICData::WriteSentinel() const {
7216 const Smi& sentinel_value = Smi::Handle(Smi::New(kIllegalObjectKind));
7217 const Array& data = Array::Handle(ic_data());
7218 for (intptr_t i = 1; i <= TestEntryLength(); i++) {
7219 data.SetAt(data.Length() - i, sentinel_value);
7220 }
7221 }
7222
7223
7215 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, 7224 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
7216 const Function& target) const { 7225 const Function& target) const {
7217 ASSERT(num_args_tested() > 1); // Otherwise use 'AddReceiverCheck'. 7226 ASSERT(num_args_tested() > 1); // Otherwise use 'AddReceiverCheck'.
7218 ASSERT(class_ids.length() == num_args_tested()); 7227 ASSERT(class_ids.length() == num_args_tested());
7219 intptr_t old_num = NumberOfChecks(); 7228 const intptr_t old_num = NumberOfChecks();
7220 Array& data = Array::Handle(ic_data()); 7229 Array& data = Array::Handle(ic_data());
7221 intptr_t new_len = data.Length() + TestEntryLength(); 7230 const intptr_t new_len = data.Length() + TestEntryLength();
7222 data = Array::Grow(data, new_len, Heap::kOld); 7231 data = Array::Grow(data, new_len, Heap::kOld);
7223 set_ic_data(data); 7232 set_ic_data(data);
7233 WriteSentinel();
7224 intptr_t data_pos = old_num * TestEntryLength(); 7234 intptr_t data_pos = old_num * TestEntryLength();
7225 for (intptr_t i = 0; i < class_ids.length(); i++) { 7235 for (intptr_t i = 0; i < class_ids.length(); i++) {
7226 // Null is used as terminating value, do not add it. 7236 // kIllegalObjectKind is used as terminating value, do not add it.
7227 ASSERT(class_ids[i] != kNullClass);
7228 ASSERT(class_ids[i] != kIllegalObjectKind); 7237 ASSERT(class_ids[i] != kIllegalObjectKind);
7229 data.SetAt(data_pos++, Smi::Handle(Smi::New(class_ids[i]))); 7238 data.SetAt(data_pos++, Smi::Handle(Smi::New(class_ids[i])));
7230 } 7239 }
7231 ASSERT(!target.IsNull()); 7240 ASSERT(!target.IsNull());
7232 data.SetAt(data_pos, target); 7241 data.SetAt(data_pos, target);
7233 } 7242 }
7234 7243
7235 7244
7236 void ICData::AddReceiverCheck(intptr_t receiver_class_id, 7245 void ICData::AddReceiverCheck(intptr_t receiver_class_id,
7237 const Function& target) const { 7246 const Function& target) const {
7238 ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'. 7247 ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'.
7239 // Not supporting collection of null receivers.
7240 ASSERT(receiver_class_id != kNullClass);
7241 ASSERT(receiver_class_id != kIllegalObjectKind); 7248 ASSERT(receiver_class_id != kIllegalObjectKind);
7242 ASSERT(!target.IsNull()); 7249 ASSERT(!target.IsNull());
7243 7250
7244 intptr_t old_num = NumberOfChecks(); 7251 const intptr_t old_num = NumberOfChecks();
7245 Array& data = Array::Handle(ic_data()); 7252 Array& data = Array::Handle(ic_data());
7246 intptr_t new_len = data.Length() + TestEntryLength(); 7253 const intptr_t new_len = data.Length() + TestEntryLength();
7247 data = Array::Grow(data, new_len, Heap::kOld); 7254 data = Array::Grow(data, new_len, Heap::kOld);
7248 set_ic_data(data); 7255 set_ic_data(data);
7256 WriteSentinel();
7249 intptr_t data_pos = old_num * TestEntryLength(); 7257 intptr_t data_pos = old_num * TestEntryLength();
7250 if ((receiver_class_id == kSmi) && (data_pos > 0)) { 7258 if ((receiver_class_id == kSmi) && (data_pos > 0)) {
7251 // Instert kSmi in position 0. 7259 // Instert kSmi in position 0.
7252 const intptr_t zero_class_id = GetReceiverClassIdAt(0); 7260 const intptr_t zero_class_id = GetReceiverClassIdAt(0);
7253 ASSERT(zero_class_id != kSmi); // Simple duplicate entry check. 7261 ASSERT(zero_class_id != kSmi); // Simple duplicate entry check.
7254 const Function& zero_target = Function::Handle(GetTargetAt(0)); 7262 const Function& zero_target = Function::Handle(GetTargetAt(0));
7255 data.SetAt(0, Smi::Handle(Smi::New(receiver_class_id))); 7263 data.SetAt(0, Smi::Handle(Smi::New(receiver_class_id)));
7256 data.SetAt(1, target); 7264 data.SetAt(1, target);
7257 data.SetAt(data_pos, Smi::Handle(Smi::New(zero_class_id))); 7265 data.SetAt(data_pos, Smi::Handle(Smi::New(zero_class_id)));
7258 data.SetAt(data_pos + 1, zero_target); 7266 data.SetAt(data_pos + 1, zero_target);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
7371 } 7379 }
7372 result.set_function(function); 7380 result.set_function(function);
7373 result.set_target_name(target_name); 7381 result.set_target_name(target_name);
7374 result.set_id(id); 7382 result.set_id(id);
7375 result.set_num_args_tested(num_args_tested); 7383 result.set_num_args_tested(num_args_tested);
7376 // Number of array elements in one test entry (num_args_tested + 1) 7384 // Number of array elements in one test entry (num_args_tested + 1)
7377 intptr_t len = result.TestEntryLength(); 7385 intptr_t len = result.TestEntryLength();
7378 // IC data array must be null terminated (sentinel entry). 7386 // IC data array must be null terminated (sentinel entry).
7379 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); 7387 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld));
7380 result.set_ic_data(ic_data); 7388 result.set_ic_data(ic_data);
7389 result.WriteSentinel();
7381 return result.raw(); 7390 return result.raw();
7382 } 7391 }
7383 7392
7384 7393
7385 RawSubtypeTestCache* SubtypeTestCache::New() { 7394 RawSubtypeTestCache* SubtypeTestCache::New() {
7386 ASSERT(Object::subtypetestcache_class() != Class::null()); 7395 ASSERT(Object::subtypetestcache_class() != Class::null());
7387 SubtypeTestCache& result = SubtypeTestCache::Handle(); 7396 SubtypeTestCache& result = SubtypeTestCache::Handle();
7388 { 7397 {
7389 // SubtypeTestCache objects are long living objects, allocate them in the 7398 // SubtypeTestCache objects are long living objects, allocate them in the
7390 // old generation. 7399 // old generation.
(...skipping 3370 matching lines...) Expand 10 before | Expand all | Expand 10 after
10761 const String& str = String::Handle(pattern()); 10770 const String& str = String::Handle(pattern());
10762 const char* format = "JSRegExp: pattern=%s flags=%s"; 10771 const char* format = "JSRegExp: pattern=%s flags=%s";
10763 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); 10772 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags());
10764 char* chars = reinterpret_cast<char*>( 10773 char* chars = reinterpret_cast<char*>(
10765 Isolate::Current()->current_zone()->Allocate(len + 1)); 10774 Isolate::Current()->current_zone()->Allocate(len + 1));
10766 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); 10775 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags());
10767 return chars; 10776 return chars;
10768 } 10777 }
10769 10778
10770 } // namespace dart 10779 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698