Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1014)

Unified Diff: runtime/vm/object.cc

Issue 1410363005: Make ICData changes thread safe (first compute array, then set it). Install code in the main thread… (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address comments Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/regexp_assembler_ir.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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();
}
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/regexp_assembler_ir.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698