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). |