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