Chromium Code Reviews| Index: runtime/vm/ic_data.cc |
| =================================================================== |
| --- runtime/vm/ic_data.cc (revision 0) |
| +++ runtime/vm/ic_data.cc (revision 0) |
| @@ -0,0 +1,104 @@ |
| +// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +#include "vm/ic_data.h" |
| +#include "vm/object.h" |
| + |
| +namespace dart { |
| + |
| +// ICData is a ValueObject, therefore 'data' need not be a ZoneObject. |
| +ICData::ICData(const Array& data) : data_(&data) { |
| +} |
| + |
| + |
| +ICData::ICData(const String& function_name, intptr_t num_args_checked) |
| + : data_(NULL) { |
| + // Array contains: function-name, num_checked, NULL check sentinel (classes, |
| + // target). |
| + const intptr_t len = kChecksStartIndex + (num_args_checked + 1); |
| + data_ = &Array::ZoneHandle(Array::New(len, Heap::kOld)); |
| + data_->SetAt(kNameIndex, function_name); |
| + data_->SetAt(kNumArgsCheckedIndex, Smi::Handle(Smi::New(num_args_checked))); |
| +} |
| + |
| + |
| +RawArray* ICData::data() const { |
| + return data_->raw(); |
| +} |
| + |
| + |
| +intptr_t ICData::ArrayElementsPerCheck() const { |
| + // Number of checked classes + target. |
| + return NumberOfArgumentsChecked() + 1; |
| +} |
| + |
| + |
| +intptr_t ICData::NumberOfArgumentsChecked() const { |
| + Smi& result = Smi::Handle(); |
| + result ^= data_->At(kNumArgsCheckedIndex); |
| + return result.Value(); |
| +} |
| + |
| + |
| +intptr_t ICData::NumberOfChecks() const { |
| + const intptr_t per_check = ArrayElementsPerCheck(); |
| + // Subtract function-name, num-checked and sentinel |
| + intptr_t len = data_->Length() - kChecksStartIndex - per_check; |
| + ASSERT(len % per_check == 0); |
| + return len / per_check; |
| +} |
| + |
| + |
| +RawString* ICData::FunctionName() const { |
| + String& result = String::Handle(); |
| + result ^= data_->At(kNameIndex); |
| + return result.raw(); |
| +} |
| + |
| + |
| +void ICData::AddCheck(const GrowableArray<const Class*>& classes, |
| + const Function& target) { |
| + intptr_t old_number_of_checks = NumberOfChecks(); |
| + intptr_t new_len = data_->Length() + ArrayElementsPerCheck(); |
| + data_ = |
| + &Array::ZoneHandle(Array::Grow(*data_, new_len, Heap::kOld)); |
|
regis
2011/10/21 03:03:52
Should fit on one line.
srdjan
2011/10/22 07:48:53
Done.
|
| + SetCheckAt(old_number_of_checks, classes, target); |
| +} |
| + |
| + |
| +void ICData::SetCheckAt(intptr_t index, |
| + const GrowableArray<const Class*>& classes, |
| + const Function& target) { |
| + ASSERT((0 <= index) && (index < NumberOfChecks())); |
| + intptr_t pos = kChecksStartIndex + ArrayElementsPerCheck() * index; |
| + ASSERT(classes.length() == NumberOfArgumentsChecked()); |
| + for (intptr_t i = 0; i < classes.length(); i++) { |
| + // Null is used as terminating object, do not add it. |
| + ASSERT(!classes[i]->IsNull()); |
| + // Contract says that no null classes may be added. |
|
regis
2011/10/21 03:03:52
There is only one Null class. How about
// Contrac
srdjan
2011/10/22 07:48:53
Done.
|
| + ASSERT(!classes[i]->IsNullClass()); |
| + data_->SetAt(pos++, *(classes[i])); |
| + } |
| + ASSERT(!target.IsNull()); |
| + data_->SetAt(pos, target); |
| +} |
| + |
| + |
| +void ICData::GetCheckAt(intptr_t index, |
| + GrowableArray<const Class*>* classes, |
| + Function* target) const { |
| + ASSERT(classes != NULL); |
| + ASSERT(target != NULL); |
| + ASSERT((0 <= index) && (index < NumberOfChecks())); |
| + classes->Clear(); |
| + intptr_t pos = 1 + 1 + ArrayElementsPerCheck() * index; |
| + for (intptr_t i = 0; i < NumberOfArgumentsChecked(); i++) { |
| + Class& cls = Class::ZoneHandle(); |
| + cls ^= data_->At(pos++); |
| + classes->Add(&cls); |
| + } |
| + (*target) ^= data_->At(pos); |
| +} |
| + |
| +} // namespace dart |