Index: runtime/vm/instructions_dbc.cc |
diff --git a/runtime/vm/instructions_dbc.cc b/runtime/vm/instructions_dbc.cc |
index 3656722a54e31e4a55e6061c18f6ec1b57ed98a9..4dc73be8136c785b3a099c4cffdfa57aee384730 100644 |
--- a/runtime/vm/instructions_dbc.cc |
+++ b/runtime/vm/instructions_dbc.cc |
@@ -15,13 +15,54 @@ |
namespace dart { |
+static bool HasLoadFromPool(Instr instr) { |
+ switch (Bytecode::DecodeOpcode(instr)) { |
+ case Bytecode::kLoadConstant: |
+ case Bytecode::kPushConstant: |
+ case Bytecode::kStaticCall: |
+ case Bytecode::kInstanceCall1: |
+ case Bytecode::kInstanceCall2: |
+ case Bytecode::kInstanceCall1Opt: |
+ case Bytecode::kInstanceCall2Opt: |
+ case Bytecode::kStoreStaticTOS: |
+ case Bytecode::kPushStatic: |
+ case Bytecode::kAllocate: |
+ case Bytecode::kInstantiateType: |
+ case Bytecode::kInstantiateTypeArgumentsTOS: |
+ case Bytecode::kAssertAssignable: |
+ return true; |
+ default: |
+ return false; |
+ } |
+} |
+ |
+ |
+static bool GetLoadedObjectAt( |
+ uword pc, const ObjectPool& object_pool, Object* obj) { |
+ Instr instr = Bytecode::At(pc); |
+ if (HasLoadFromPool(instr)) { |
+ uint16_t index = Bytecode::DecodeD(instr); |
+ if (object_pool.InfoAt(index) == ObjectPool::kTaggedObject) { |
+ *obj = object_pool.ObjectAt(index); |
+ return true; |
+ } |
+ } |
+ return false; |
+} |
+ |
+ |
CallPattern::CallPattern(uword pc, const Code& code) |
: object_pool_(ObjectPool::Handle(code.GetObjectPool())), |
end_(pc), |
ic_data_load_end_(0), |
target_code_pool_index_(-1), |
ic_data_(ICData::Handle()) { |
- UNIMPLEMENTED(); |
+ ASSERT(code.ContainsInstructionAt(end_)); |
+ const uword call_pc = end_ - sizeof(Instr); |
+ Instr call_instr = Bytecode::At(call_pc); |
+ ASSERT(Bytecode::IsCallOpcode(call_instr)); |
+ ic_data_load_end_ = call_pc; |
+ target_code_pool_index_ = Bytecode::DecodeD(call_instr); |
} |
@@ -30,6 +71,7 @@ int CallPattern::DeoptCallPatternLengthInInstructions() { |
return 0; |
} |
+ |
int CallPattern::DeoptCallPatternLengthInBytes() { |
UNIMPLEMENTED(); |
return 0; |
@@ -109,48 +151,21 @@ uword InstructionPattern::DecodeLoadWordFromPool(uword end, |
} |
-static bool HasLoadFromPool(Instr instr) { |
- switch (Bytecode::DecodeOpcode(instr)) { |
- case Bytecode::kLoadConstant: |
- case Bytecode::kPushConstant: |
- case Bytecode::kStaticCall: |
- case Bytecode::kInstanceCall1: |
- case Bytecode::kInstanceCall2: |
- case Bytecode::kInstanceCall1Opt: |
- case Bytecode::kInstanceCall2Opt: |
- case Bytecode::kStoreStaticTOS: |
- case Bytecode::kPushStatic: |
- case Bytecode::kAllocate: |
- case Bytecode::kInstantiateType: |
- case Bytecode::kInstantiateTypeArgumentsTOS: |
- case Bytecode::kAssertAssignable: |
- return true; |
- default: |
- return false; |
- } |
-} |
- |
- |
bool DecodeLoadObjectFromPoolOrThread(uword pc, |
const Code& code, |
Object* obj) { |
ASSERT(code.ContainsInstructionAt(pc)); |
- Instr instr = Bytecode::At(pc); |
- if (HasLoadFromPool(instr)) { |
- uint16_t index = Bytecode::DecodeD(instr); |
- const ObjectPool& pool = ObjectPool::Handle(code.object_pool()); |
- if (pool.InfoAt(index) == ObjectPool::kTaggedObject) { |
- *obj = pool.ObjectAt(index); |
- return true; |
- } |
- } |
- return false; |
+ const ObjectPool& pool = ObjectPool::Handle(code.object_pool()); |
+ return GetLoadedObjectAt(pc, pool, obj); |
} |
RawICData* CallPattern::IcData() { |
- UNIMPLEMENTED(); |
- return ICData::null(); |
+ if (ic_data_.IsNull()) { |
+ bool found = GetLoadedObjectAt(ic_data_load_end_, object_pool_, &ic_data_); |
+ ASSERT(found); |
+ } |
+ return ic_data_.raw(); |
} |