Chromium Code Reviews| 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 7187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7198 return num_args_tested() + 1 /* target function*/; | 7198 return num_args_tested() + 1 /* target function*/; |
| 7199 } | 7199 } |
| 7200 | 7200 |
| 7201 | 7201 |
| 7202 intptr_t ICData::NumberOfChecks() const { | 7202 intptr_t ICData::NumberOfChecks() const { |
| 7203 // Do not count the sentinel; | 7203 // Do not count the sentinel; |
| 7204 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1; | 7204 return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1; |
| 7205 } | 7205 } |
| 7206 | 7206 |
| 7207 | 7207 |
| 7208 void ICData::WriteSentinel() const { | |
| 7209 const Array& data = Array::Handle(ic_data()); | |
|
siva
2012/07/24 00:14:06
const Smi& sentinel_value = Smi::Handle(Smi::New(k
srdjan
2012/07/24 00:25:31
Done.
| |
| 7210 for (intptr_t i = 1; i <= TestEntryLength(); i++) { | |
| 7211 data.SetAt(data.Length() - i, Smi::Handle(Smi::New(kIllegalObjectKind))); | |
|
siva
2012/07/24 00:14:06
data.SetAt(data.Length() - i, sentinel_value);
srdjan
2012/07/24 00:25:31
Done.
| |
| 7212 } | |
| 7213 } | |
| 7214 | |
| 7215 | |
| 7208 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, | 7216 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids, |
| 7209 const Function& target) const { | 7217 const Function& target) const { |
| 7210 ASSERT(num_args_tested() > 1); // Otherwise use 'AddReceiverCheck'. | 7218 ASSERT(num_args_tested() > 1); // Otherwise use 'AddReceiverCheck'. |
| 7211 ASSERT(class_ids.length() == num_args_tested()); | 7219 ASSERT(class_ids.length() == num_args_tested()); |
| 7212 intptr_t old_num = NumberOfChecks(); | 7220 const intptr_t old_num = NumberOfChecks(); |
| 7213 Array& data = Array::Handle(ic_data()); | 7221 Array& data = Array::Handle(ic_data()); |
| 7214 intptr_t new_len = data.Length() + TestEntryLength(); | 7222 const intptr_t new_len = data.Length() + TestEntryLength(); |
| 7215 data = Array::Grow(data, new_len, Heap::kOld); | 7223 data = Array::Grow(data, new_len, Heap::kOld); |
| 7216 set_ic_data(data); | 7224 set_ic_data(data); |
| 7225 WriteSentinel(); | |
| 7217 intptr_t data_pos = old_num * TestEntryLength(); | 7226 intptr_t data_pos = old_num * TestEntryLength(); |
| 7218 for (intptr_t i = 0; i < class_ids.length(); i++) { | 7227 for (intptr_t i = 0; i < class_ids.length(); i++) { |
| 7219 // Null is used as terminating value, do not add it. | 7228 // kIllegalObjectKind is used as terminating value, do not add it. |
| 7220 ASSERT(class_ids[i] != kNullClass); | |
| 7221 ASSERT(class_ids[i] != kIllegalObjectKind); | 7229 ASSERT(class_ids[i] != kIllegalObjectKind); |
| 7222 data.SetAt(data_pos++, Smi::Handle(Smi::New(class_ids[i]))); | 7230 data.SetAt(data_pos++, Smi::Handle(Smi::New(class_ids[i]))); |
| 7223 } | 7231 } |
| 7224 ASSERT(!target.IsNull()); | 7232 ASSERT(!target.IsNull()); |
| 7225 data.SetAt(data_pos, target); | 7233 data.SetAt(data_pos, target); |
| 7226 } | 7234 } |
| 7227 | 7235 |
| 7228 | 7236 |
| 7229 void ICData::AddReceiverCheck(intptr_t receiver_class_id, | 7237 void ICData::AddReceiverCheck(intptr_t receiver_class_id, |
| 7230 const Function& target) const { | 7238 const Function& target) const { |
| 7231 ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'. | 7239 ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'. |
| 7232 // Not supporting collection of null receivers. | |
| 7233 ASSERT(receiver_class_id != kNullClass); | |
| 7234 ASSERT(receiver_class_id != kIllegalObjectKind); | 7240 ASSERT(receiver_class_id != kIllegalObjectKind); |
| 7235 ASSERT(!target.IsNull()); | 7241 ASSERT(!target.IsNull()); |
| 7236 | 7242 |
| 7237 intptr_t old_num = NumberOfChecks(); | 7243 const intptr_t old_num = NumberOfChecks(); |
| 7238 Array& data = Array::Handle(ic_data()); | 7244 Array& data = Array::Handle(ic_data()); |
| 7239 intptr_t new_len = data.Length() + TestEntryLength(); | 7245 const intptr_t new_len = data.Length() + TestEntryLength(); |
| 7240 data = Array::Grow(data, new_len, Heap::kOld); | 7246 data = Array::Grow(data, new_len, Heap::kOld); |
| 7241 set_ic_data(data); | 7247 set_ic_data(data); |
| 7248 WriteSentinel(); | |
| 7242 intptr_t data_pos = old_num * TestEntryLength(); | 7249 intptr_t data_pos = old_num * TestEntryLength(); |
| 7243 if ((receiver_class_id == kSmi) && (data_pos > 0)) { | 7250 if ((receiver_class_id == kSmi) && (data_pos > 0)) { |
| 7244 // Instert kSmi in position 0. | 7251 // Instert kSmi in position 0. |
| 7245 const intptr_t zero_class_id = GetReceiverClassIdAt(0); | 7252 const intptr_t zero_class_id = GetReceiverClassIdAt(0); |
| 7246 ASSERT(zero_class_id != kSmi); // Simple duplicate entry check. | 7253 ASSERT(zero_class_id != kSmi); // Simple duplicate entry check. |
| 7247 const Function& zero_target = Function::Handle(GetTargetAt(0)); | 7254 const Function& zero_target = Function::Handle(GetTargetAt(0)); |
| 7248 data.SetAt(0, Smi::Handle(Smi::New(receiver_class_id))); | 7255 data.SetAt(0, Smi::Handle(Smi::New(receiver_class_id))); |
| 7249 data.SetAt(1, target); | 7256 data.SetAt(1, target); |
| 7250 data.SetAt(data_pos, Smi::Handle(Smi::New(zero_class_id))); | 7257 data.SetAt(data_pos, Smi::Handle(Smi::New(zero_class_id))); |
| 7251 data.SetAt(data_pos + 1, zero_target); | 7258 data.SetAt(data_pos + 1, zero_target); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7363 } | 7370 } |
| 7364 result.set_function(function); | 7371 result.set_function(function); |
| 7365 result.set_target_name(target_name); | 7372 result.set_target_name(target_name); |
| 7366 result.set_id(id); | 7373 result.set_id(id); |
| 7367 result.set_num_args_tested(num_args_tested); | 7374 result.set_num_args_tested(num_args_tested); |
| 7368 // Number of array elements in one test entry (num_args_tested + 1) | 7375 // Number of array elements in one test entry (num_args_tested + 1) |
| 7369 intptr_t len = result.TestEntryLength(); | 7376 intptr_t len = result.TestEntryLength(); |
| 7370 // IC data array must be null terminated (sentinel entry). | 7377 // IC data array must be null terminated (sentinel entry). |
| 7371 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); | 7378 const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld)); |
| 7372 result.set_ic_data(ic_data); | 7379 result.set_ic_data(ic_data); |
| 7380 result.WriteSentinel(); | |
| 7373 return result.raw(); | 7381 return result.raw(); |
| 7374 } | 7382 } |
| 7375 | 7383 |
| 7376 | 7384 |
| 7377 RawSubtypeTestCache* SubtypeTestCache::New() { | 7385 RawSubtypeTestCache* SubtypeTestCache::New() { |
| 7378 const Class& cls = Class::Handle(Object::subtypetestcache_class()); | 7386 const Class& cls = Class::Handle(Object::subtypetestcache_class()); |
| 7379 ASSERT(!cls.IsNull()); | 7387 ASSERT(!cls.IsNull()); |
| 7380 SubtypeTestCache& result = SubtypeTestCache::Handle(); | 7388 SubtypeTestCache& result = SubtypeTestCache::Handle(); |
| 7381 { | 7389 { |
| 7382 // SubtypeTestCache objects are long living objects, allocate them in the | 7390 // SubtypeTestCache objects are long living objects, allocate them in the |
| (...skipping 3492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10875 const String& str = String::Handle(pattern()); | 10883 const String& str = String::Handle(pattern()); |
| 10876 const char* format = "JSRegExp: pattern=%s flags=%s"; | 10884 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 10877 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 10885 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 10878 char* chars = reinterpret_cast<char*>( | 10886 char* chars = reinterpret_cast<char*>( |
| 10879 Isolate::Current()->current_zone()->Allocate(len + 1)); | 10887 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 10880 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 10888 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 10881 return chars; | 10889 return chars; |
| 10882 } | 10890 } |
| 10883 | 10891 |
| 10884 } // namespace dart | 10892 } // namespace dart |
| OLD | NEW |