| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |