| Index: runtime/vm/code_patcher_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/code_patcher_ia32.cc (revision 15101)
|
| +++ runtime/vm/code_patcher_ia32.cc (working copy)
|
| @@ -14,7 +14,7 @@
|
|
|
| namespace dart {
|
|
|
| -// The pattern of a Dart call is:
|
| +// The pattern of a Dart instance call is:
|
| // 1: mov ECX, immediate 1
|
| // 2: mov EDX, immediate 2
|
| // 3: call target_address
|
| @@ -97,45 +97,74 @@
|
| };
|
|
|
|
|
| -// The expected pattern of a dart static call:
|
| -// mov ECX, function_object
|
| +// The expected pattern of a dart instance call:
|
| +// mov ECX, ic-data
|
| // mov EDX, argument_descriptor_array
|
| // call target_address
|
| // <- return address
|
| -class StaticCall : public DartCallPattern {
|
| +class InstanceCall : public DartCallPattern {
|
| public:
|
| - explicit StaticCall(uword return_address)
|
| + explicit InstanceCall(uword return_address)
|
| : DartCallPattern(return_address) {}
|
|
|
| - RawFunction* function() const {
|
| - Function& f = Function::Handle();
|
| - f ^= reinterpret_cast<RawObject*>(immediate_one());
|
| - return f.raw();
|
| + RawICData* ic_data() const {
|
| + ICData& ic_data = ICData::Handle();
|
| + ic_data ^= reinterpret_cast<RawObject*>(immediate_one());
|
| + return ic_data.raw();
|
| }
|
|
|
| private:
|
| - DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall);
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall);
|
| };
|
|
|
|
|
| -// The expected pattern of a dart instance call:
|
| -// mov ECX, ic-data
|
| +// The expected pattern of a dart static call:
|
| // mov EDX, argument_descriptor_array
|
| // call target_address
|
| // <- return address
|
| -class InstanceCall : public DartCallPattern {
|
| +class StaticCall : public ValueObject {
|
| public:
|
| - explicit InstanceCall(uword return_address)
|
| - : DartCallPattern(return_address) {}
|
| + explicit StaticCall(uword return_address)
|
| + : start_(return_address - (kNumInstructions * kInstructionSize)) {
|
| + ASSERT(IsValid(return_address));
|
| + ASSERT(kInstructionSize == Assembler::kCallExternalLabelSize);
|
| + }
|
|
|
| - RawICData* ic_data() const {
|
| - ICData& ic_data = ICData::Handle();
|
| - ic_data ^= reinterpret_cast<RawObject*>(immediate_one());
|
| - return ic_data.raw();
|
| + static bool IsValid(uword return_address) {
|
| + uint8_t* code_bytes =
|
| + reinterpret_cast<uint8_t*>(
|
| + return_address - (kNumInstructions * kInstructionSize));
|
| + return (code_bytes[0] == 0xBA) &&
|
| + (code_bytes[1 * kInstructionSize] == 0xE8);
|
| }
|
|
|
| + uword target() const {
|
| + const uword offset = *reinterpret_cast<uword*>(call_address() + 1);
|
| + return return_address() + offset;
|
| + }
|
| +
|
| + void set_target(uword target) const {
|
| + uword* target_addr = reinterpret_cast<uword*>(call_address() + 1);
|
| + uword offset = target - return_address();
|
| + *target_addr = offset;
|
| + CPU::FlushICache(call_address(), kInstructionSize);
|
| + }
|
| +
|
| + static const int kNumInstructions = 2;
|
| + static const int kInstructionSize = 5; // All instructions have same length.
|
| +
|
| private:
|
| - DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall);
|
| + uword return_address() const {
|
| + return start_ + kNumInstructions * kInstructionSize;
|
| + }
|
| +
|
| + uword call_address() const {
|
| + return start_ + 1 * kInstructionSize;
|
| + }
|
| +
|
| + uword start_;
|
| +
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall);
|
| };
|
|
|
|
|
|
|