Chromium Code Reviews| Index: vm/code_generator.cc |
| =================================================================== |
| --- vm/code_generator.cc (revision 14048) |
| +++ vm/code_generator.cc (working copy) |
| @@ -748,6 +748,39 @@ |
| } |
| +bool UpdateResolvedStaticCall(const Code& code, |
| + intptr_t offset, |
| + const Code& target_code) { |
| + GrowableObjectArray& resolved_static_calls = |
| + GrowableObjectArray::Handle(code.resolved_static_calls()); |
| + intptr_t index = -1; |
| + if (resolved_static_calls.IsNull()) { |
| + resolved_static_calls = GrowableObjectArray::New(2, Heap::kOld); |
| + code.set_resolved_static_calls(resolved_static_calls); |
| + } else { |
| + // Search for the offset in the resolved static calls. |
| + intptr_t len = resolved_static_calls.Length(); |
|
srdjan
2012/10/25 20:00:48
const intptr_t len
Ivan Posva
2012/10/25 23:45:41
Done.
|
| + Object& off = Object::Handle(); |
| + for (intptr_t i = 0; i < len; i += 2) { |
|
srdjan
2012/10/25 20:00:48
Maybe it would be good to have the length, entries
Ivan Posva
2012/10/25 23:45:41
Done.
|
| + off = resolved_static_calls.At(i); |
| + if (Smi::Cast(off).Value() == offset) { |
| + index = i; |
| + break; |
| + } |
| + } |
| + } |
| + if (index == -1) { |
| + // The static call with this offset is not yet present: Add it. |
| + resolved_static_calls.Add(Smi::Handle(Smi::New(offset))); |
| + resolved_static_calls.Add(target_code); |
| + } else { |
| + // Overwrite the currently recorded target. |
| + resolved_static_calls.SetAt(index + 1, target_code); |
|
srdjan
2012/10/25 20:00:48
ditto
Ivan Posva
2012/10/25 23:45:41
Done.
|
| + } |
| + return index != -1; |
| +} |
| + |
| + |
| DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { |
| // This function is called after successful resolving and compilation of |
| // the target method. |
| @@ -759,10 +792,15 @@ |
| Function& target_function = Function::Handle(); |
| CodePatcher::GetStaticCallAt(caller_frame->pc(), &target_function, &target); |
| ASSERT(target_function.HasCode()); |
| - uword new_target = Code::Handle(target_function.CurrentCode()).EntryPoint(); |
| + Code& target_code = Code::Handle(target_function.CurrentCode()); |
|
srdjan
2012/10/25 20:00:48
const Code
Ivan Posva
2012/10/25 23:45:41
Done.
|
| + uword new_target = target_code.EntryPoint(); |
| // Verify that we are not patching repeatedly. |
| ASSERT(target != new_target); |
| CodePatcher::PatchStaticCallAt(caller_frame->pc(), new_target); |
| + Code& code = Code::Handle(caller_frame->LookupDartCode()); |
|
srdjan
2012/10/25 20:00:48
ditto
Ivan Posva
2012/10/25 23:45:41
Done.
|
| + UpdateResolvedStaticCall(code, |
| + caller_frame->pc() - code.EntryPoint(), |
| + target_code); |
|
siva
2012/10/25 22:29:52
bool found = Update....;
ASSERT(!found);
Ivan Posva
2012/10/25 23:45:41
Done.
|
| if (FLAG_trace_patching) { |
| OS::Print("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", |
| caller_frame->pc(), |
| @@ -1433,10 +1471,16 @@ |
| Function& target_function = Function::Handle(); |
| CodePatcher::GetStaticCallAt(frame->pc(), &target_function, &target); |
| ASSERT(target_function.HasCode()); |
| - const uword new_entry_point = |
| - Code::Handle(function.CurrentCode()).EntryPoint(); |
| + ASSERT(target_function.raw() == function.raw()); |
| + const Code& target_code = Code::Handle(function.CurrentCode()); |
| + const uword new_entry_point = target_code.EntryPoint(); |
| ASSERT(target != new_entry_point); // Why patch otherwise. |
| CodePatcher::PatchStaticCallAt(frame->pc(), new_entry_point); |
| + const Code& code = Code::Handle(frame->LookupDartCode()); |
| + bool found = UpdateResolvedStaticCall(code, |
| + frame->pc() - code.EntryPoint(), |
| + target_code); |
| + ASSERT(found); |
| if (FLAG_trace_patching) { |
| OS::Print("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", |
| frame->pc(), |