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 "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/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 8230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8241 ASSERT(class_ids[i] != kIllegalCid); | 8241 ASSERT(class_ids[i] != kIllegalCid); |
| 8242 data.SetAt(data_pos++, Smi::Handle(Smi::New(class_ids[i]))); | 8242 data.SetAt(data_pos++, Smi::Handle(Smi::New(class_ids[i]))); |
| 8243 } | 8243 } |
| 8244 ASSERT(!target.IsNull()); | 8244 ASSERT(!target.IsNull()); |
| 8245 data.SetAt(data_pos++, target); | 8245 data.SetAt(data_pos++, target); |
| 8246 data.SetAt(data_pos, Smi::Handle(Smi::New(1))); | 8246 data.SetAt(data_pos, Smi::Handle(Smi::New(1))); |
| 8247 } | 8247 } |
| 8248 | 8248 |
| 8249 | 8249 |
| 8250 void ICData::AddReceiverCheck(intptr_t receiver_class_id, | 8250 void ICData::AddReceiverCheck(intptr_t receiver_class_id, |
| 8251 const Function& target) const { | 8251 const Function& target, |
| 8252 intptr_t count) const { | |
| 8252 #if defined(DEBUG) | 8253 #if defined(DEBUG) |
| 8253 GrowableArray<intptr_t> class_ids(1); | 8254 GrowableArray<intptr_t> class_ids(1); |
| 8254 class_ids.Add(receiver_class_id); | 8255 class_ids.Add(receiver_class_id); |
| 8255 ASSERT(!HasCheck(class_ids)); | 8256 ASSERT(!HasCheck(class_ids)); |
| 8256 #endif // DEBUG | 8257 #endif // DEBUG |
| 8257 ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'. | 8258 ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'. |
| 8258 ASSERT(receiver_class_id != kIllegalCid); | 8259 ASSERT(receiver_class_id != kIllegalCid); |
| 8259 | 8260 |
| 8260 const intptr_t old_num = NumberOfChecks(); | 8261 const intptr_t old_num = NumberOfChecks(); |
| 8261 Array& data = Array::Handle(ic_data()); | 8262 Array& data = Array::Handle(ic_data()); |
| 8262 const intptr_t new_len = data.Length() + TestEntryLength(); | 8263 const intptr_t new_len = data.Length() + TestEntryLength(); |
| 8263 data = Array::Grow(data, new_len, Heap::kOld); | 8264 data = Array::Grow(data, new_len, Heap::kOld); |
| 8264 set_ic_data(data); | 8265 set_ic_data(data); |
| 8265 WriteSentinel(); | 8266 WriteSentinel(); |
| 8266 intptr_t data_pos = old_num * TestEntryLength(); | 8267 intptr_t data_pos = old_num * TestEntryLength(); |
| 8267 if ((receiver_class_id == kSmiCid) && (data_pos > 0)) { | 8268 if ((receiver_class_id == kSmiCid) && (data_pos > 0)) { |
| 8268 ASSERT(GetReceiverClassIdAt(0) != kSmiCid); | 8269 ASSERT(GetReceiverClassIdAt(0) != kSmiCid); |
| 8269 // Move class occupying position 0 to the data_pos. | 8270 // Move class occupying position 0 to the data_pos. |
| 8270 for (intptr_t i = 0; i < TestEntryLength(); i++) { | 8271 for (intptr_t i = 0; i < TestEntryLength(); i++) { |
| 8271 data.SetAt(data_pos + i, Object::Handle(data.At(i))); | 8272 data.SetAt(data_pos + i, Object::Handle(data.At(i))); |
| 8272 } | 8273 } |
| 8273 // Insert kSmiCid in position 0. | 8274 // Insert kSmiCid in position 0. |
| 8274 data_pos = 0; | 8275 data_pos = 0; |
| 8275 } | 8276 } |
| 8276 data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id))); | 8277 data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id))); |
| 8277 data.SetAt(data_pos + 1, target); | 8278 data.SetAt(data_pos + 1, target); |
| 8278 data.SetAt(data_pos + 2, Smi::Handle(Smi::New(1))); | 8279 data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count))); |
| 8279 } | 8280 } |
| 8280 | 8281 |
| 8281 | 8282 |
| 8282 void ICData::GetCheckAt(intptr_t index, | 8283 void ICData::GetCheckAt(intptr_t index, |
| 8283 GrowableArray<intptr_t>* class_ids, | 8284 GrowableArray<intptr_t>* class_ids, |
| 8284 Function* target) const { | 8285 Function* target) const { |
| 8285 ASSERT(index < NumberOfChecks()); | 8286 ASSERT(index < NumberOfChecks()); |
| 8286 ASSERT(class_ids != NULL); | 8287 ASSERT(class_ids != NULL); |
| 8287 ASSERT(target != NULL); | 8288 ASSERT(target != NULL); |
| 8288 class_ids->Clear(); | 8289 class_ids->Clear(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8331 | 8332 |
| 8332 | 8333 |
| 8333 RawFunction* ICData::GetTargetAt(intptr_t index) const { | 8334 RawFunction* ICData::GetTargetAt(intptr_t index) const { |
| 8334 const Array& data = Array::Handle(ic_data()); | 8335 const Array& data = Array::Handle(ic_data()); |
| 8335 const intptr_t data_pos = index * TestEntryLength() + num_args_tested(); | 8336 const intptr_t data_pos = index * TestEntryLength() + num_args_tested(); |
| 8336 ASSERT(Object::Handle(data.At(data_pos)).IsFunction()); | 8337 ASSERT(Object::Handle(data.At(data_pos)).IsFunction()); |
| 8337 return reinterpret_cast<RawFunction*>(data.At(data_pos)); | 8338 return reinterpret_cast<RawFunction*>(data.At(data_pos)); |
| 8338 } | 8339 } |
| 8339 | 8340 |
| 8340 | 8341 |
| 8342 void ICData::IncrementCountAt(intptr_t index, intptr_t value) const { | |
| 8343 ASSERT(0 <= value); | |
| 8344 ASSERT(value <= Smi::kMaxValue); | |
| 8345 | |
| 8346 const intptr_t count = GetCountAt(index); | |
| 8347 if (count == Smi::kMaxValue) { | |
|
srdjan
2013/04/24 17:16:44
Why not:
if (count < Smi::kMaxValue) {
SetCount
Vyacheslav Egorov (Google)
2013/04/24 17:50:32
Done.
| |
| 8348 return; | |
| 8349 } | |
| 8350 | |
| 8351 SetCountAt(index, Utils::Minimum(count + value, Smi::kMaxValue)); | |
| 8352 } | |
| 8353 | |
| 8354 | |
| 8355 void ICData::SetCountAt(intptr_t index, intptr_t value) const { | |
| 8356 ASSERT(0 <= value); | |
| 8357 ASSERT(value <= Smi::kMaxValue); | |
| 8358 | |
| 8359 const Array& data = Array::Handle(ic_data()); | |
| 8360 const intptr_t data_pos = index * TestEntryLength() + | |
| 8361 CountIndexFor(num_args_tested()); | |
| 8362 data.SetAt(data_pos, Smi::Handle(Smi::New(value))); | |
| 8363 } | |
| 8364 | |
| 8365 | |
| 8341 intptr_t ICData::GetCountAt(intptr_t index) const { | 8366 intptr_t ICData::GetCountAt(intptr_t index) const { |
| 8342 const Array& data = Array::Handle(ic_data()); | 8367 const Array& data = Array::Handle(ic_data()); |
| 8343 const intptr_t data_pos = index * TestEntryLength() + | 8368 const intptr_t data_pos = index * TestEntryLength() + |
| 8344 CountIndexFor(num_args_tested()); | 8369 CountIndexFor(num_args_tested()); |
| 8345 Smi& smi = Smi::Handle(); | 8370 Smi& smi = Smi::Handle(); |
| 8346 smi ^= data.At(data_pos); | 8371 smi ^= data.At(data_pos); |
| 8347 return smi.Value(); | 8372 return smi.Value(); |
| 8348 } | 8373 } |
| 8349 | 8374 |
| 8350 | 8375 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 8378 } | 8403 } |
| 8379 const intptr_t kNumArgsTested = 1; | 8404 const intptr_t kNumArgsTested = 1; |
| 8380 ICData& result = ICData::Handle(ICData::New( | 8405 ICData& result = ICData::Handle(ICData::New( |
| 8381 Function::Handle(function()), | 8406 Function::Handle(function()), |
| 8382 String::Handle(target_name()), | 8407 String::Handle(target_name()), |
| 8383 deopt_id(), | 8408 deopt_id(), |
| 8384 kNumArgsTested)); | 8409 kNumArgsTested)); |
| 8385 const intptr_t len = NumberOfChecks(); | 8410 const intptr_t len = NumberOfChecks(); |
| 8386 for (intptr_t i = 0; i < len; i++) { | 8411 for (intptr_t i = 0; i < len; i++) { |
| 8387 const intptr_t class_id = GetClassIdAt(i, arg_nr); | 8412 const intptr_t class_id = GetClassIdAt(i, arg_nr); |
| 8413 const intptr_t count = GetCountAt(i); | |
| 8388 intptr_t duplicate_class_id = -1; | 8414 intptr_t duplicate_class_id = -1; |
| 8389 const intptr_t result_len = result.NumberOfChecks(); | 8415 const intptr_t result_len = result.NumberOfChecks(); |
| 8390 for (intptr_t k = 0; k < result_len; k++) { | 8416 for (intptr_t k = 0; k < result_len; k++) { |
| 8391 if (class_id == result.GetReceiverClassIdAt(k)) { | 8417 if (class_id == result.GetReceiverClassIdAt(k)) { |
| 8392 duplicate_class_id = k; | 8418 duplicate_class_id = k; |
| 8393 break; | 8419 break; |
| 8394 } | 8420 } |
| 8395 } | 8421 } |
| 8396 if (duplicate_class_id >= 0) { | 8422 if (duplicate_class_id >= 0) { |
| 8397 // This check is valid only when checking the receiver. | 8423 // This check is valid only when checking the receiver. |
| 8398 ASSERT((arg_nr != 0) || | 8424 ASSERT((arg_nr != 0) || |
| 8399 (result.GetTargetAt(duplicate_class_id) == GetTargetAt(i))); | 8425 (result.GetTargetAt(duplicate_class_id) == GetTargetAt(i))); |
| 8426 result.IncrementCountAt(duplicate_class_id, count); | |
| 8400 } else { | 8427 } else { |
| 8401 // This will make sure that Smi is first if it exists. | 8428 // This will make sure that Smi is first if it exists. |
| 8402 result.AddReceiverCheck(class_id, | 8429 result.AddReceiverCheck(class_id, |
| 8403 Function::Handle(GetTargetAt(i))); | 8430 Function::Handle(GetTargetAt(i)), |
| 8431 count); | |
| 8404 } | 8432 } |
| 8405 } | 8433 } |
| 8406 return result.raw(); | 8434 return result.raw(); |
| 8407 } | 8435 } |
| 8408 | 8436 |
| 8409 | 8437 |
| 8410 bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const { | 8438 bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const { |
| 8411 if (NumberOfChecks() == 0) return false; | 8439 if (NumberOfChecks() == 0) return false; |
| 8412 Class& cls = Class::Handle(); | 8440 Class& cls = Class::Handle(); |
| 8413 const intptr_t len = NumberOfChecks(); | 8441 const intptr_t len = NumberOfChecks(); |
| (...skipping 4719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13133 } | 13161 } |
| 13134 return result.raw(); | 13162 return result.raw(); |
| 13135 } | 13163 } |
| 13136 | 13164 |
| 13137 | 13165 |
| 13138 const char* WeakProperty::ToCString() const { | 13166 const char* WeakProperty::ToCString() const { |
| 13139 return "_WeakProperty"; | 13167 return "_WeakProperty"; |
| 13140 } | 13168 } |
| 13141 | 13169 |
| 13142 } // namespace dart | 13170 } // namespace dart |
| OLD | NEW |