| Index: runtime/vm/code_patcher_x64.cc
 | 
| ===================================================================
 | 
| --- runtime/vm/code_patcher_x64.cc	(revision 22595)
 | 
| +++ runtime/vm/code_patcher_x64.cc	(working copy)
 | 
| @@ -125,6 +125,46 @@
 | 
|  };
 | 
|  
 | 
|  
 | 
| +// The expected code pattern of a dart closure call:
 | 
| +//  00: 49 ba imm64  mov R10, immediate 2      ; 10 bytes
 | 
| +//  10: 49 bb imm64  mov R11, target_address   ; 10 bytes
 | 
| +//  20: 41 ff d3     call R11                  ; 3 bytes
 | 
| +//  23: <- return_address
 | 
| +class ClosureCall : public ValueObject {
 | 
| + public:
 | 
| +  explicit ClosureCall(uword return_address)
 | 
| +      : start_(return_address - kCallPatternSize) {
 | 
| +    ASSERT(IsValid(return_address));
 | 
| +  }
 | 
| +
 | 
| +  static bool IsValid(uword return_address) {
 | 
| +    uint8_t* code_bytes =
 | 
| +        reinterpret_cast<uint8_t*>(return_address - kCallPatternSize);
 | 
| +    return (code_bytes[00] == 0x49) && (code_bytes[01] == 0xBA) &&
 | 
| +           (code_bytes[10] == 0x49) && (code_bytes[11] == 0xBB) &&
 | 
| +           (code_bytes[20] == 0x41) && (code_bytes[21] == 0xFF) &&
 | 
| +           (code_bytes[22] == 0xD3);
 | 
| +  }
 | 
| +
 | 
| +  RawArray* arguments_descriptor() const {
 | 
| +    return *reinterpret_cast<RawArray**>(start_ + 2);
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  static const int kCallPatternSize = 10 + 10 + 3;
 | 
| +  uword start_;
 | 
| +  DISALLOW_IMPLICIT_CONSTRUCTORS(ClosureCall);
 | 
| +};
 | 
| +
 | 
| +
 | 
| +RawArray* CodePatcher::GetClosureArgDescAt(uword return_address,
 | 
| +                                           const Code& code) {
 | 
| +  ASSERT(code.ContainsInstructionAt(return_address));
 | 
| +  ClosureCall call(return_address);
 | 
| +  return call.arguments_descriptor();
 | 
| +}
 | 
| +
 | 
| +
 | 
|  uword CodePatcher::GetStaticCallTargetAt(uword return_address,
 | 
|                                           const Code& code) {
 | 
|    ASSERT(code.ContainsInstructionAt(return_address));
 | 
| 
 |