| Index: runtime/vm/object.cc
|
| diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
|
| index 37937607faffbee22881acfc5961af2afb298b2d..a7211a718db53899d177b1f8816d7bf969a40267 100644
|
| --- a/runtime/vm/object.cc
|
| +++ b/runtime/vm/object.cc
|
| @@ -5382,11 +5382,27 @@ bool Function::HasBreakpoint() const {
|
| }
|
|
|
|
|
| +void Function::InstallOptimizedCode(const Code& code, bool is_osr) const {
|
| + // We may not have previous code if 'always_optimize' is set.
|
| + if (!is_osr && HasCode()) {
|
| + Code::Handle(CurrentCode()).DisableDartCode();
|
| + }
|
| + AttachCode(code);
|
| +}
|
| +
|
| +
|
| void Function::SetInstructions(const Code& value) const {
|
| + ASSERT(Thread::Current()->IsMutatorThread());
|
| + SetInstructionsSafe(value);
|
| +}
|
| +
|
| +
|
| +void Function::SetInstructionsSafe(const Code& value) const {
|
| StorePointer(&raw_ptr()->code_, value.raw());
|
| StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint());
|
| }
|
|
|
| +
|
| void Function::AttachCode(const Code& value) const {
|
| // Finish setting up code before activating it.
|
| value.set_owner(*this);
|
| @@ -6492,7 +6508,8 @@ RawFunction* Function::New(const String& name,
|
| result.set_is_inlinable(true);
|
| result.set_allows_hoisting_check_class(true);
|
| result.set_allows_bounds_check_generalization(true);
|
| - result.SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code()));
|
| + result.SetInstructionsSafe(
|
| + Code::Handle(StubCode::LazyCompile_entry()->code()));
|
| if (kind == RawFunction::kClosureFunction) {
|
| const ClosureData& data = ClosureData::Handle(ClosureData::New());
|
| result.set_data(data);
|
| @@ -12084,7 +12101,7 @@ void ICData::set_deopt_id(intptr_t value) const {
|
| }
|
|
|
|
|
| -void ICData::set_ic_data(const Array& value) const {
|
| +void ICData::set_ic_data_array(const Array& value) const {
|
| ASSERT(!value.IsNull());
|
| StorePointer(&raw_ptr()->ic_data_, value.raw());
|
| }
|
| @@ -12192,9 +12209,9 @@ intptr_t ICData::NumberOfUsedChecks() const {
|
| }
|
|
|
|
|
| -void ICData::WriteSentinel(const Array& data) const {
|
| +void ICData::WriteSentinel(const Array& data, intptr_t test_entry_length) {
|
| ASSERT(!data.IsNull());
|
| - for (intptr_t i = 1; i <= TestEntryLength(); i++) {
|
| + for (intptr_t i = 1; i <= test_entry_length; i++) {
|
| data.SetAt(data.Length() - i, smi_illegal_cid());
|
| }
|
| }
|
| @@ -12247,8 +12264,7 @@ void ICData::AddTarget(const Function& target) const {
|
| Array& data = Array::Handle(ic_data());
|
| const intptr_t new_len = data.Length() + TestEntryLength();
|
| data = Array::Grow(data, new_len, Heap::kOld);
|
| - set_ic_data(data);
|
| - WriteSentinel(data);
|
| + WriteSentinel(data, TestEntryLength());
|
| intptr_t data_pos = old_num * TestEntryLength();
|
| ASSERT(!target.IsNull());
|
| data.SetAt(data_pos++, target);
|
| @@ -12256,6 +12272,9 @@ void ICData::AddTarget(const Function& target) const {
|
| // call has been executed.
|
| const Smi& value = Smi::Handle(Smi::New(0));
|
| data.SetAt(data_pos, value);
|
| + // Multithreaded access to ICData requires setting of array to be the last
|
| + // operation.
|
| + set_ic_data_array(data);
|
| }
|
|
|
|
|
| @@ -12293,8 +12312,7 @@ void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
|
| }
|
| const intptr_t new_len = data.Length() + TestEntryLength();
|
| data = Array::Grow(data, new_len, Heap::kOld);
|
| - set_ic_data(data);
|
| - WriteSentinel(data);
|
| + WriteSentinel(data, TestEntryLength());
|
| intptr_t data_pos = old_num * TestEntryLength();
|
| Smi& value = Smi::Handle();
|
| for (intptr_t i = 0; i < class_ids.length(); i++) {
|
| @@ -12307,6 +12325,9 @@ void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
|
| data.SetAt(data_pos++, target);
|
| value = Smi::New(1);
|
| data.SetAt(data_pos, value);
|
| + // Multithreaded access to ICData requires setting of array to be the last
|
| + // operation.
|
| + set_ic_data_array(data);
|
| }
|
|
|
|
|
| @@ -12326,8 +12347,7 @@ void ICData::AddReceiverCheck(intptr_t receiver_class_id,
|
| Array& data = Array::Handle(ic_data());
|
| const intptr_t new_len = data.Length() + TestEntryLength();
|
| data = Array::Grow(data, new_len, Heap::kOld);
|
| - set_ic_data(data);
|
| - WriteSentinel(data);
|
| + WriteSentinel(data, TestEntryLength());
|
| intptr_t data_pos = old_num * TestEntryLength();
|
| if ((receiver_class_id == kSmiCid) && (data_pos > 0)) {
|
| ASSERT(GetReceiverClassIdAt(0) != kSmiCid);
|
| @@ -12341,6 +12361,9 @@ void ICData::AddReceiverCheck(intptr_t receiver_class_id,
|
| data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id)));
|
| data.SetAt(data_pos + 1, target);
|
| data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count)));
|
| + // Multithreaded access to ICData requires setting of array to be the last
|
| + // operation.
|
| + set_ic_data_array(data);
|
| }
|
|
|
|
|
| @@ -12636,8 +12659,8 @@ RawICData* ICData::New(const Function& owner,
|
| 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);
|
| - result.WriteSentinel(ic_data);
|
| + WriteSentinel(ic_data, result.TestEntryLength());
|
| + result.set_ic_data_array(ic_data);
|
| return result.raw();
|
| }
|
|
|
|
|