| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 #include "vm/ic_data.h" |
| 6 #include "vm/object.h" |
| 7 |
| 8 namespace dart { |
| 9 |
| 10 // ICData is a ValueObject, therefore 'data' need not be a ZoneObject. |
| 11 ICData::ICData(const Array& data) : data_(&data) { |
| 12 } |
| 13 |
| 14 |
| 15 ICData::ICData(const String& function_name, intptr_t num_args_checked) |
| 16 : data_(NULL) { |
| 17 // Array contains: function-name, num_checked, NULL check sentinel (classes, |
| 18 // target). |
| 19 const intptr_t len = kChecksStartIndex + (num_args_checked + 1); |
| 20 data_ = &Array::ZoneHandle(Array::New(len, Heap::kOld)); |
| 21 data_->SetAt(kNameIndex, function_name); |
| 22 data_->SetAt(kNumArgsCheckedIndex, Smi::Handle(Smi::New(num_args_checked))); |
| 23 } |
| 24 |
| 25 |
| 26 RawArray* ICData::data() const { |
| 27 return data_->raw(); |
| 28 } |
| 29 |
| 30 |
| 31 intptr_t ICData::ArrayElementsPerCheck() const { |
| 32 // Number of checked classes + target. |
| 33 return NumberOfArgumentsChecked() + 1; |
| 34 } |
| 35 |
| 36 |
| 37 intptr_t ICData::NumberOfArgumentsChecked() const { |
| 38 Smi& result = Smi::Handle(); |
| 39 result ^= data_->At(kNumArgsCheckedIndex); |
| 40 return result.Value(); |
| 41 } |
| 42 |
| 43 |
| 44 intptr_t ICData::NumberOfChecks() const { |
| 45 const intptr_t per_check = ArrayElementsPerCheck(); |
| 46 // Subtract function-name, num-checked and sentinel |
| 47 intptr_t len = data_->Length() - kChecksStartIndex - per_check; |
| 48 ASSERT(len % per_check == 0); |
| 49 return len / per_check; |
| 50 } |
| 51 |
| 52 |
| 53 RawString* ICData::FunctionName() const { |
| 54 String& result = String::Handle(); |
| 55 result ^= data_->At(kNameIndex); |
| 56 return result.raw(); |
| 57 } |
| 58 |
| 59 |
| 60 void ICData::AddCheck(const GrowableArray<const Class*>& classes, |
| 61 const Function& target) { |
| 62 intptr_t old_number_of_checks = NumberOfChecks(); |
| 63 intptr_t new_len = data_->Length() + ArrayElementsPerCheck(); |
| 64 data_ = &Array::ZoneHandle(Array::Grow(*data_, new_len, Heap::kOld)); |
| 65 SetCheckAt(old_number_of_checks, classes, target); |
| 66 } |
| 67 |
| 68 |
| 69 void ICData::SetCheckAt(intptr_t index, |
| 70 const GrowableArray<const Class*>& classes, |
| 71 const Function& target) { |
| 72 ASSERT((0 <= index) && (index < NumberOfChecks())); |
| 73 intptr_t pos = kChecksStartIndex + ArrayElementsPerCheck() * index; |
| 74 ASSERT(classes.length() == NumberOfArgumentsChecked()); |
| 75 for (intptr_t i = 0; i < classes.length(); i++) { |
| 76 // Null is used as terminating object, do not add it. |
| 77 ASSERT(!classes[i]->IsNull()); |
| 78 // Contract says that the class of null (NullClass) cannot be added. |
| 79 ASSERT(!classes[i]->IsNullClass()); |
| 80 data_->SetAt(pos++, *(classes[i])); |
| 81 } |
| 82 ASSERT(!target.IsNull()); |
| 83 data_->SetAt(pos, target); |
| 84 } |
| 85 |
| 86 |
| 87 void ICData::GetCheckAt(intptr_t index, |
| 88 GrowableArray<const Class*>* classes, |
| 89 Function* target) const { |
| 90 ASSERT(classes != NULL); |
| 91 ASSERT(target != NULL); |
| 92 ASSERT((0 <= index) && (index < NumberOfChecks())); |
| 93 classes->Clear(); |
| 94 intptr_t pos = 1 + 1 + ArrayElementsPerCheck() * index; |
| 95 for (intptr_t i = 0; i < NumberOfArgumentsChecked(); i++) { |
| 96 Class& cls = Class::ZoneHandle(); |
| 97 cls ^= data_->At(pos++); |
| 98 classes->Add(&cls); |
| 99 } |
| 100 (*target) ^= data_->At(pos); |
| 101 } |
| 102 |
| 103 } // namespace dart |
| OLD | NEW |