| Index: vm/object.cc
|
| ===================================================================
|
| --- vm/object.cc (revision 5374)
|
| +++ vm/object.cc (working copy)
|
| @@ -85,12 +85,12 @@
|
| reinterpret_cast<RawClass*>(RAW_NULL);
|
| RawClass* Object::context_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| RawClass* Object::context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| +RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| RawClass* Object::api_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| RawClass* Object::language_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| RawClass* Object::unhandled_exception_class_ =
|
| reinterpret_cast<RawClass*>(RAW_NULL);
|
| RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| -RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
|
| #undef RAW_NULL
|
|
|
| int Object::GetSingletonClassIndex(const RawClass* raw_class) {
|
| @@ -145,6 +145,8 @@
|
| return kContextClass;
|
| } else if (raw_class == context_scope_class()) {
|
| return kContextScopeClass;
|
| + } else if (raw_class == icdata_class()) {
|
| + return kICDataClass;
|
| } else if (raw_class == api_error_class()) {
|
| return kApiErrorClass;
|
| } else if (raw_class == language_error_class()) {
|
| @@ -153,8 +155,6 @@
|
| return kUnhandledExceptionClass;
|
| } else if (raw_class == unwind_error_class()) {
|
| return kUnwindErrorClass;
|
| - } else if (raw_class == icdata_class()) {
|
| - return kICDataClass;
|
| }
|
| return kInvalidIndex;
|
| }
|
| @@ -188,11 +188,11 @@
|
| case kExceptionHandlersClass: return exception_handlers_class();
|
| case kContextClass: return context_class();
|
| case kContextScopeClass: return context_scope_class();
|
| + case kICDataClass: return icdata_class();
|
| case kApiErrorClass: return api_error_class();
|
| case kLanguageErrorClass: return language_error_class();
|
| case kUnhandledExceptionClass: return unhandled_exception_class();
|
| case kUnwindErrorClass: return unwind_error_class();
|
| - case kICDataClass: return icdata_class();
|
| default: break;
|
| }
|
| UNREACHABLE();
|
| @@ -226,6 +226,7 @@
|
| case kExceptionHandlersClass: return "ExceptionHandlers";
|
| case kContextClass: return "Context";
|
| case kContextScopeClass: return "ContextScope";
|
| + case kICDataClass: return "ICData";
|
| case kApiErrorClass: return "ApiError";
|
| case kLanguageErrorClass: return "LanguageError";
|
| case kUnhandledExceptionClass: return "UnhandledException";
|
| @@ -376,6 +377,9 @@
|
| cls = Class::New<ContextScope>();
|
| context_scope_class_ = cls.raw();
|
|
|
| + cls = Class::New<ICData>();
|
| + icdata_class_ = cls.raw();
|
| +
|
| cls = Class::New<ApiError>();
|
| api_error_class_ = cls.raw();
|
|
|
| @@ -388,9 +392,6 @@
|
| cls = Class::New<UnwindError>();
|
| unwind_error_class_ = cls.raw();
|
|
|
| - cls = Class::New<ICData>();
|
| - icdata_class_ = cls.raw();
|
| -
|
| ASSERT(class_class() != null_);
|
| }
|
|
|
| @@ -5873,6 +5874,123 @@
|
| }
|
|
|
|
|
| +const char* ICData::ToCString() const {
|
| + return "ICData";
|
| +}
|
| +
|
| +
|
| +void ICData::set_function(const Function& value) const {
|
| + raw_ptr()->function_ = value.raw();
|
| +}
|
| +
|
| +
|
| +void ICData::set_target_name(const String& value) const {
|
| + raw_ptr()->target_name_ = value.raw();
|
| +}
|
| +
|
| +
|
| +void ICData::set_id(intptr_t value) const {
|
| + raw_ptr()->id_ = value;
|
| +}
|
| +
|
| +
|
| +void ICData::set_num_args_tested(intptr_t value) const {
|
| + raw_ptr()->num_args_tested_ = value;
|
| +}
|
| +
|
| +
|
| +void ICData::set_ic_data(const Array& value) const {
|
| + raw_ptr()->ic_data_ = value.raw();
|
| +}
|
| +
|
| +
|
| +intptr_t ICData::TestEntryLength() const {
|
| + return num_args_tested() + 1 /* target function*/;
|
| +}
|
| +
|
| +
|
| +intptr_t ICData::NumberOfChecks() const {
|
| + // Do not count the sentinel;
|
| + return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1;
|
| +}
|
| +
|
| +
|
| +void ICData::AddCheck(const GrowableArray<const Class*>& classes,
|
| + const Function& target) const {
|
| + ASSERT(classes.length() == num_args_tested());
|
| + intptr_t old_num = NumberOfChecks();
|
| + Array& data = Array::Handle(ic_data());
|
| + intptr_t new_len = data.Length() + TestEntryLength();
|
| + data = Array::Grow(data, new_len, Heap::kOld);
|
| + set_ic_data(data);
|
| + intptr_t data_pos = old_num * TestEntryLength();
|
| + for (intptr_t i = 0; i < classes.length(); i++) {
|
| + // Null is used as terminating value, do not add it.
|
| + ASSERT(!classes[i]->IsNull());
|
| + data.SetAt(data_pos++, *(classes[i]));
|
| + }
|
| + ASSERT(!target.IsNull());
|
| + data.SetAt(data_pos, target);
|
| +}
|
| +
|
| +
|
| +void ICData::GetCheckAt(intptr_t index,
|
| + GrowableArray<const Class*>* classes,
|
| + Function* target) const {
|
| + ASSERT(classes != NULL);
|
| + ASSERT(target != NULL);
|
| + classes->Clear();
|
| + const Array& data = Array::Handle(ic_data());
|
| + intptr_t data_pos = index * TestEntryLength();
|
| + for (intptr_t i = 0; i < num_args_tested(); i++) {
|
| + Class& cls = Class::ZoneHandle();
|
| + cls ^= data.At(data_pos++);
|
| + classes->Add(&cls);
|
| + }
|
| + (*target) ^= data.At(data_pos);
|
| +}
|
| +
|
| +
|
| +void ICData::GetOneClassCheckAt(
|
| + int index, Class* cls, Function* target) const {
|
| + ASSERT(cls != NULL);
|
| + ASSERT(target != NULL);
|
| + ASSERT(num_args_tested() == 1);
|
| + const Array& data = Array::Handle(ic_data());
|
| + intptr_t data_pos = index * TestEntryLength();
|
| + *cls ^= data.At(data_pos);
|
| + *target ^= data.At(data_pos + 1);
|
| +}
|
| +
|
| +
|
| +RawICData* ICData::New(const Function& function,
|
| + const String& target_name,
|
| + intptr_t id,
|
| + intptr_t num_args_tested) {
|
| + ASSERT(num_args_tested > 0);
|
| + const Class& cls = Class::Handle(Object::icdata_class());
|
| + ASSERT(!cls.IsNull());
|
| + ICData& result = ICData::Handle();
|
| + {
|
| + // IC data objects ar long living objects, allocate them in old generation.
|
| + RawObject* raw =
|
| + Object::Allocate(cls, ICData::InstanceSize(), Heap::kOld);
|
| + NoGCScope no_gc;
|
| + result ^= raw;
|
| + }
|
| + result.set_function(function);
|
| + result.set_target_name(target_name);
|
| + result.set_id(id);
|
| + result.set_num_args_tested(num_args_tested);
|
| + // Number of array elements in one test entry (num_args_tested + 1)
|
| + intptr_t len = result.TestEntryLength();
|
| + // IC data array must be null terminated (sentinel entry).
|
| + const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld));
|
| + result.set_ic_data(ic_data);
|
| + return result.raw();
|
| +}
|
| +
|
| +
|
| const char* Error::ToErrorCString() const {
|
| UNREACHABLE();
|
| return "Internal Error";
|
| @@ -8746,121 +8864,4 @@
|
| return chars;
|
| }
|
|
|
| -
|
| -const char* ICData::ToCString() const {
|
| - return "ICData";
|
| -}
|
| -
|
| -
|
| -void ICData::set_function(const Function& value) const {
|
| - raw_ptr()->function_ = value.raw();
|
| -}
|
| -
|
| -
|
| -void ICData::set_target_name(const String& value) const {
|
| - raw_ptr()->target_name_ = value.raw();
|
| -}
|
| -
|
| -
|
| -void ICData::set_id(intptr_t value) const {
|
| - raw_ptr()->id_ = value;
|
| -}
|
| -
|
| -
|
| -void ICData::set_num_args_tested(intptr_t value) const {
|
| - raw_ptr()->num_args_tested_ = value;
|
| -}
|
| -
|
| -
|
| -void ICData::set_ic_data(const Array& value) const {
|
| - raw_ptr()->ic_data_ = value.raw();
|
| -}
|
| -
|
| -
|
| -intptr_t ICData::TestEntryLength() const {
|
| - return num_args_tested() + 1 /* target function*/;
|
| -}
|
| -
|
| -
|
| -intptr_t ICData::NumberOfChecks() const {
|
| - // Do not count the sentinel;
|
| - return (Array::Handle(ic_data()).Length() / TestEntryLength()) - 1;
|
| -}
|
| -
|
| -
|
| -void ICData::AddCheck(const GrowableArray<const Class*>& classes,
|
| - const Function& target) const {
|
| - ASSERT(classes.length() == num_args_tested());
|
| - intptr_t old_num = NumberOfChecks();
|
| - Array& data = Array::Handle(ic_data());
|
| - intptr_t new_len = data.Length() + TestEntryLength();
|
| - data = Array::Grow(data, new_len, Heap::kOld);
|
| - set_ic_data(data);
|
| - intptr_t data_pos = old_num * TestEntryLength();
|
| - for (intptr_t i = 0; i < classes.length(); i++) {
|
| - // Null is used as terminating value, do not add it.
|
| - ASSERT(!classes[i]->IsNull());
|
| - data.SetAt(data_pos++, *(classes[i]));
|
| - }
|
| - ASSERT(!target.IsNull());
|
| - data.SetAt(data_pos, target);
|
| -}
|
| -
|
| -
|
| -void ICData::GetCheckAt(intptr_t index,
|
| - GrowableArray<const Class*>* classes,
|
| - Function* target) const {
|
| - ASSERT(classes != NULL);
|
| - ASSERT(target != NULL);
|
| - classes->Clear();
|
| - const Array& data = Array::Handle(ic_data());
|
| - intptr_t data_pos = index * TestEntryLength();
|
| - for (intptr_t i = 0; i < num_args_tested(); i++) {
|
| - Class& cls = Class::ZoneHandle();
|
| - cls ^= data.At(data_pos++);
|
| - classes->Add(&cls);
|
| - }
|
| - (*target) ^= data.At(data_pos);
|
| -}
|
| -
|
| -
|
| -void ICData::GetOneClassCheckAt(
|
| - int index, Class* cls, Function* target) const {
|
| - ASSERT(cls != NULL);
|
| - ASSERT(target != NULL);
|
| - ASSERT(num_args_tested() == 1);
|
| - const Array& data = Array::Handle(ic_data());
|
| - intptr_t data_pos = index * TestEntryLength();
|
| - *cls ^= data.At(data_pos);
|
| - *target ^= data.At(data_pos + 1);
|
| -}
|
| -
|
| -
|
| -RawICData* ICData::New(const Function& function,
|
| - const String& target_name,
|
| - intptr_t id,
|
| - intptr_t num_args_tested) {
|
| - ASSERT(num_args_tested > 0);
|
| - const Class& cls = Class::Handle(Object::icdata_class());
|
| - ASSERT(!cls.IsNull());
|
| - ICData& result = ICData::Handle();
|
| - {
|
| - // IC data objects ar long living objects, allocate them in old generation.
|
| - RawObject* raw =
|
| - Object::Allocate(cls, ICData::InstanceSize(), Heap::kOld);
|
| - NoGCScope no_gc;
|
| - result ^= raw;
|
| - }
|
| - result.set_function(function);
|
| - result.set_target_name(target_name);
|
| - result.set_id(id);
|
| - result.set_num_args_tested(num_args_tested);
|
| - // Number of array elements in one test entry (num_args_tested + 1)
|
| - intptr_t len = result.TestEntryLength();
|
| - // IC data array must be null terminated (sentinel entry).
|
| - const Array& ic_data = Array::Handle(Array::New(len, Heap::kOld));
|
| - result.set_ic_data(ic_data);
|
| - return result.raw();
|
| -}
|
| -
|
| } // namespace dart
|
|
|