Chromium Code Reviews| Index: runtime/vm/object.cc |
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
| index 60ad0731417277cc1b9c8a64c56948cf41ac817b..00b386d1c37c61c0577276a9bc3ac51fb46b58c0 100644 |
| --- a/runtime/vm/object.cc |
| +++ b/runtime/vm/object.cc |
| @@ -83,6 +83,9 @@ static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); |
| static const char* kSetterPrefix = "set:"; |
| static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); |
| +// A cache of VM heap allocated preinitialized empty ic data entry arrays. |
| +RawArray* ICData::cached_icdata_arrays_[kCachedICDataArrayCount]; |
| + |
| cpp_vtable Object::handle_vtable_ = 0; |
| cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 }; |
| cpp_vtable Smi::handle_vtable_ = 0; |
| @@ -12616,33 +12619,46 @@ bool ICData::IsUsedAt(intptr_t i) const { |
| } |
| -RawICData* ICData::New() { |
| - ICData& result = ICData::Handle(); |
| - { |
| - // IC data objects are long living objects, allocate them in old generation. |
| - RawObject* raw = Object::Allocate(ICData::kClassId, |
| - ICData::InstanceSize(), |
| - Heap::kOld); |
| - NoSafepointScope no_safepoint; |
| - result ^= raw; |
| +void ICData::InitOnce() { |
| + for (int i = 0; i < kCachedICDataArrayCount; i++) { |
| + cached_icdata_arrays_[i] = ICData::NewNonCachedEmptyICDataArray(i); |
| } |
| - result.set_deopt_id(Thread::kNoDeoptId); |
| - result.set_state_bits(0); |
| - return result.raw(); |
| } |
| -RawICData* ICData::New(const Function& owner, |
| - const String& target_name, |
| - const Array& arguments_descriptor, |
| - intptr_t deopt_id, |
| - intptr_t num_args_tested) { |
| +RawArray* ICData::NewNonCachedEmptyICDataArray(intptr_t num_args_tested) { |
| + // IC data array must be null terminated (sentinel entry). |
| + const intptr_t len = TestEntryLengthFor(num_args_tested); |
| + const Array& array = Array::Handle(Array::New(len, Heap::kOld)); |
| + array.MakeImmutable(); |
| + WriteSentinel(array, len); |
|
siva
2015/10/27 21:32:44
Array should be made immutable after the sentinel
srdjan
2015/10/27 21:53:18
Done. It should have crashed, Siva is fixing it.
|
| + return array.raw(); |
| +} |
| + |
| + |
| +RawArray* ICData::NewEmptyICDataArray(intptr_t num_args_tested) { |
| + ASSERT(num_args_tested >= 0); |
| + if (num_args_tested < kCachedICDataArrayCount) { |
| + return cached_icdata_arrays_[num_args_tested]; |
| + } |
| + return NewNonCachedEmptyICDataArray(num_args_tested); |
| +} |
| + |
| + |
| + |
| +// Does not initialize ICData array. |
| +RawICData* ICData::NewDescriptor(Zone* zone, |
| + const Function& owner, |
| + const String& target_name, |
| + const Array& arguments_descriptor, |
| + intptr_t deopt_id, |
| + intptr_t num_args_tested) { |
| ASSERT(!owner.IsNull()); |
| ASSERT(!target_name.IsNull()); |
| ASSERT(!arguments_descriptor.IsNull()); |
| ASSERT(Object::icdata_class() != Class::null()); |
| ASSERT(num_args_tested >= 0); |
| - ICData& result = ICData::Handle(); |
| + ICData& result = ICData::Handle(zone); |
| { |
| // IC data objects are long living objects, allocate them in old generation. |
| RawObject* raw = Object::Allocate(ICData::kClassId, |
| @@ -12657,12 +12673,41 @@ RawICData* ICData::New(const Function& owner, |
| result.set_deopt_id(deopt_id); |
| result.set_state_bits(0); |
| result.SetNumArgsTested(num_args_tested); |
| - // Number of array elements in one test entry. |
| - 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)); |
| - WriteSentinel(ic_data, result.TestEntryLength()); |
| - result.set_ic_data_array(ic_data); |
| + return result.raw(); |
| +} |
| + |
| + |
| +RawICData* ICData::New() { |
| + ICData& result = ICData::Handle(); |
| + { |
| + // IC data objects are long living objects, allocate them in old generation. |
| + RawObject* raw = Object::Allocate(ICData::kClassId, |
| + ICData::InstanceSize(), |
| + Heap::kOld); |
| + NoSafepointScope no_safepoint; |
| + result ^= raw; |
| + } |
| + result.set_deopt_id(Thread::kNoDeoptId); |
| + result.set_state_bits(0); |
| + return result.raw(); |
| +} |
| + |
| + |
| +RawICData* ICData::New(const Function& owner, |
| + const String& target_name, |
| + const Array& arguments_descriptor, |
| + intptr_t deopt_id, |
| + intptr_t num_args_tested) { |
| + Zone* zone = Thread::Current()->zone(); |
| + const ICData& result = ICData::Handle(zone, |
| + NewDescriptor(zone, |
| + owner, |
| + target_name, |
| + arguments_descriptor, |
| + deopt_id, |
| + num_args_tested)); |
| + result.set_ic_data_array( |
| + Array::Handle(zone, NewEmptyICDataArray(num_args_tested))); |
| return result.raw(); |
| } |