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

Unified Diff: runtime/vm/object.cc

Issue 254723003: Remember all deopt reasons in ic_data, not just the last one. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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
Index: runtime/vm/object.cc
===================================================================
--- runtime/vm/object.cc (revision 35415)
+++ runtime/vm/object.cc (working copy)
@@ -10708,7 +10708,8 @@
}
-RawDeoptInfo* Code::GetDeoptInfoAtPc(uword pc, intptr_t* deopt_reason) const {
+RawDeoptInfo* Code::GetDeoptInfoAtPc(uword pc,
+ DeoptReasonId* deopt_reason) const {
ASSERT(is_optimized());
const Instructions& instrs = Instructions::Handle(instructions());
uword code_entry = instrs.EntryPoint();
@@ -10723,7 +10724,8 @@
DeoptTable::GetEntry(table, i, &offset, &info, &reason);
if (pc == (code_entry + offset.Value())) {
ASSERT(!info.IsNull());
- *deopt_reason = reason.Value();
+ ASSERT(static_cast<uword>(reason.Value()) < kDeoptNumReasons);
srdjan 2014/04/25 20:54:16 Why the cast?
regis 2014/04/25 23:38:28 Done. Casting to unsigned was to catch negative va
+ *deopt_reason = static_cast<DeoptReasonId>(reason.Value());
return info.raw();
}
}
@@ -11417,7 +11419,7 @@
const char* kFormat = "ICData target:'%s' num-args: %" Pd
" num-checks: %" Pd "";
const String& name = String::Handle(target_name());
- const intptr_t num_args = num_args_tested();
+ const intptr_t num_args = NumArgsTested();
const intptr_t num_checks = NumberOfChecks();
intptr_t len = OS::SNPrint(NULL, 0, kFormat, name.ToCString(),
num_args, num_checks) + 1;
@@ -11427,9 +11429,9 @@
}
-void ICData::set_function(const Function& value) const {
+void ICData::set_owner(const Function& value) const {
ASSERT(!value.IsNull());
- StorePointer(&raw_ptr()->function_, value.raw());
+ StorePointer(&raw_ptr()->owner_, value.raw());
}
@@ -11445,37 +11447,84 @@
}
void ICData::set_deopt_id(intptr_t value) const {
+ ASSERT(value <= kMaxInt32);
raw_ptr()->deopt_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 {
ASSERT(!value.IsNull());
StorePointer(&raw_ptr()->ic_data_, value.raw());
}
-void ICData::set_deopt_reason(intptr_t deopt_reason) const {
- raw_ptr()->deopt_reason_ = deopt_reason;
+intptr_t ICData::NumArgsTested() const {
+ return NumArgsTestedBits::decode(raw_ptr()->state_bits_);
}
-void ICData::set_is_closure_call(bool value) const {
- raw_ptr()->is_closure_call_ = value ? 1 : 0;
+
+void ICData::SetNumArgsTested(intptr_t value) const {
+ ASSERT(Utils::IsUint(2, value));
+ raw_ptr()->state_bits_ =
+ NumArgsTestedBits::update(value, raw_ptr()->state_bits_);
}
+uint32_t ICData::DeoptReasons() const {
+ return DeoptReasonBits::decode(raw_ptr()->state_bits_);
+}
+
+
+void ICData::SetDeoptReasons(uint32_t reasons) const {
+ raw_ptr()->state_bits_ =
+ DeoptReasonBits::update(reasons, raw_ptr()->state_bits_);
+}
+
+
+bool ICData::HasDeoptReason(DeoptReasonId reason) const {
+ return (DeoptReasons() & (1 << reason)) != 0;
+}
+
+
+void ICData::AddDeoptReason(DeoptReasonId reason) const {
+ SetDeoptReasons(DeoptReasons() | (1 << reason));
+}
+
+
+bool ICData::IssuedJSWarning() const {
+ return IssuedJSWarningBit::decode(raw_ptr()->state_bits_);
+}
+
+
+void ICData::SetIssuedJSWarning() const {
+ raw_ptr()->state_bits_ =
+ IssuedJSWarningBit::update(true, raw_ptr()->state_bits_);
+}
+
+
+bool ICData::IsClosureCall() const {
+ return IsClosureCallBit::decode(raw_ptr()->state_bits_);
+}
+
+
+void ICData::SetIsClosureCall() const {
+ raw_ptr()->state_bits_ =
+ IsClosureCallBit::update(true, raw_ptr()->state_bits_);
+}
+
+
+void ICData::set_state_bits(uint32_t bits) const {
+ raw_ptr()->state_bits_ = bits;
+}
+
+
intptr_t ICData::TestEntryLengthFor(intptr_t num_args) {
return num_args + 1 /* target function*/ + 1 /* frequency */;
}
intptr_t ICData::TestEntryLength() const {
- return TestEntryLengthFor(num_args_tested());
+ return TestEntryLengthFor(NumArgsTested());
}
@@ -11520,16 +11569,16 @@
// Used for unoptimized static calls when no class-ids are checked.
void ICData::AddTarget(const Function& target) const {
ASSERT(!target.IsNull());
- if (num_args_tested() > 0) {
+ if (NumArgsTested() > 0) {
// Create a fake cid entry, so that we can store the target.
- GrowableArray<intptr_t> class_ids(num_args_tested());
- for (intptr_t i = 0; i < num_args_tested(); i++) {
+ GrowableArray<intptr_t> class_ids(NumArgsTested());
+ for (intptr_t i = 0; i < NumArgsTested(); i++) {
class_ids.Add(kObjectCid);
}
AddCheck(class_ids, target);
return;
}
- ASSERT(num_args_tested() >= 0);
+ ASSERT(NumArgsTested() >= 0);
// Can add only once.
const intptr_t old_num = NumberOfChecks();
ASSERT(old_num == 0);
@@ -11550,26 +11599,26 @@
const Function& target) const {
ASSERT(!target.IsNull());
DEBUG_ASSERT(!HasCheck(class_ids));
- ASSERT(num_args_tested() > 1); // Otherwise use 'AddReceiverCheck'.
- ASSERT(class_ids.length() == num_args_tested());
+ ASSERT(NumArgsTested() > 1); // Otherwise use 'AddReceiverCheck'.
+ ASSERT(class_ids.length() == NumArgsTested());
const intptr_t old_num = NumberOfChecks();
Array& data = Array::Handle(ic_data());
- // ICData of static calls with num_args_tested() > 0 have initially a
+ // ICData of static calls with NumArgsTested() > 0 have initially a
// dummy set of cids entered (see ICData::AddTarget). That entry is
// overwritten by first real type feedback data.
if (old_num == 1) {
bool has_dummy_entry = true;
- for (intptr_t i = 0; i < num_args_tested(); i++) {
+ for (intptr_t i = 0; i < NumArgsTested(); i++) {
if (Smi::Value(Smi::RawCast(data.At(i))) != kObjectCid) {
has_dummy_entry = false;
break;
}
}
if (has_dummy_entry) {
- ASSERT(target.raw() == data.At(num_args_tested()));
+ ASSERT(target.raw() == data.At(NumArgsTested()));
// Replace dummy entry.
Smi& value = Smi::Handle();
- for (intptr_t i = 0; i < num_args_tested(); i++) {
+ for (intptr_t i = 0; i < NumArgsTested(); i++) {
ASSERT(class_ids[i] != kIllegalCid);
value = Smi::New(class_ids[i]);
data.SetAt(i, value);
@@ -11605,7 +11654,7 @@
ASSERT(!HasCheck(class_ids));
#endif // DEBUG
ASSERT(!target.IsNull());
- ASSERT(num_args_tested() == 1); // Otherwise use 'AddCheck'.
+ ASSERT(NumArgsTested() == 1); // Otherwise use 'AddCheck'.
ASSERT(receiver_class_id != kIllegalCid);
const intptr_t old_num = NumberOfChecks();
@@ -11639,7 +11688,7 @@
class_ids->Clear();
const Array& data = Array::Handle(ic_data());
intptr_t data_pos = index * TestEntryLength();
- for (intptr_t i = 0; i < num_args_tested(); i++) {
+ for (intptr_t i = 0; i < NumArgsTested(); i++) {
class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++))));
}
(*target) ^= data.At(data_pos++);
@@ -11651,7 +11700,7 @@
Function* target) const {
ASSERT(class_id != NULL);
ASSERT(target != NULL);
- ASSERT(num_args_tested() == 1);
+ ASSERT(NumArgsTested() == 1);
const Array& data = Array::Handle(ic_data());
const intptr_t data_pos = index * TestEntryLength();
*class_id = Smi::Value(Smi::RawCast(data.At(data_pos)));
@@ -11660,7 +11709,7 @@
intptr_t ICData::GetCidAt(intptr_t index) const {
- ASSERT(num_args_tested() == 1);
+ ASSERT(NumArgsTested() == 1);
const Array& data = Array::Handle(ic_data());
const intptr_t data_pos = index * TestEntryLength();
return Smi::Value(Smi::RawCast(data.At(data_pos)));
@@ -11684,7 +11733,7 @@
RawFunction* ICData::GetTargetAt(intptr_t index) const {
- const intptr_t data_pos = index * TestEntryLength() + num_args_tested();
+ const intptr_t data_pos = index * TestEntryLength() + NumArgsTested();
ASSERT(Object::Handle(Array::Handle(ic_data()).At(data_pos)).IsFunction());
NoGCScope no_gc;
@@ -11706,7 +11755,7 @@
const Array& data = Array::Handle(ic_data());
const intptr_t data_pos = index * TestEntryLength() +
- CountIndexFor(num_args_tested());
+ CountIndexFor(NumArgsTested());
data.SetAt(data_pos, Smi::Handle(Smi::New(value)));
}
@@ -11714,7 +11763,7 @@
intptr_t ICData::GetCountAt(intptr_t index) const {
const Array& data = Array::Handle(ic_data());
const intptr_t data_pos = index * TestEntryLength() +
- CountIndexFor(num_args_tested());
+ CountIndexFor(NumArgsTested());
return Smi::Value(Smi::RawCast(data.At(data_pos)));
}
@@ -11743,14 +11792,14 @@
RawICData* ICData::AsUnaryClassChecksForArgNr(intptr_t arg_nr) const {
ASSERT(!IsNull());
- ASSERT(num_args_tested() > arg_nr);
- if ((arg_nr == 0) && (num_args_tested() == 1)) {
+ ASSERT(NumArgsTested() > arg_nr);
+ if ((arg_nr == 0) && (NumArgsTested() == 1)) {
// Frequent case.
return raw();
}
const intptr_t kNumArgsTested = 1;
ICData& result = ICData::Handle(ICData::New(
- Function::Handle(function()),
+ Function::Handle(owner()),
String::Handle(target_name()),
Array::Handle(arguments_descriptor()),
deopt_id(),
@@ -11779,8 +11828,8 @@
count);
}
}
- // Copy deoptimization reason.
- result.set_deopt_reason(deopt_reason());
+ // Copy deoptimization reasons.
+ result.SetDeoptReasons(DeoptReasons());
return result.raw();
}
@@ -11819,7 +11868,7 @@
bool ICData::HasReceiverClassId(intptr_t class_id) const {
- ASSERT(num_args_tested() > 0);
+ ASSERT(NumArgsTested() > 0);
const intptr_t len = NumberOfChecks();
for (intptr_t i = 0; i < len; i++) {
const intptr_t test_class_id = GetReceiverClassIdAt(i);
@@ -11846,12 +11895,12 @@
}
-RawICData* ICData::New(const Function& caller_function,
+RawICData* ICData::New(const Function& owner,
const String& target_name,
const Array& arguments_descriptor,
intptr_t deopt_id,
intptr_t num_args_tested) {
- ASSERT(!caller_function.IsNull());
+ ASSERT(!owner.IsNull());
ASSERT(!target_name.IsNull());
ASSERT(!arguments_descriptor.IsNull());
ASSERT(Object::icdata_class() != Class::null());
@@ -11865,13 +11914,12 @@
NoGCScope no_gc;
result ^= raw;
}
- result.set_function(caller_function);
+ result.set_owner(owner);
result.set_target_name(target_name);
result.set_arguments_descriptor(arguments_descriptor);
result.set_deopt_id(deopt_id);
- result.set_num_args_tested(num_args_tested);
- result.set_deopt_reason(kDeoptUnknown);
- result.set_is_closure_call(false);
+ 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).
« runtime/vm/object.h ('K') | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698