Flutter Engine
The Flutter Engine
instructions_x64.cc
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6#if defined(TARGET_ARCH_X64)
7
9
10#include "vm/code_patcher.h"
11#include "vm/instructions.h"
12#include "vm/instructions_x64.h"
13
14#include "vm/constants.h"
15#include "vm/cpu.h"
16#include "vm/object.h"
17#include "vm/object_store.h"
18
19namespace dart {
20
21// [start] is the address of a displacement inside a load instruction
22intptr_t IndexFromPPLoadDisp8(uword start) {
23 int8_t offset = *reinterpret_cast<int8_t*>(start);
25}
26
27intptr_t IndexFromPPLoadDisp32(uword start) {
28 int32_t offset = LoadUnaligned(reinterpret_cast<int32_t*>(start));
30}
31
32bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
33 ASSERT(code.ContainsInstructionAt(pc));
34
35 uint8_t* bytes = reinterpret_cast<uint8_t*>(pc);
36
38 if ((bytes[0] == 0x49) || (bytes[0] == 0x4d)) {
39 if ((bytes[1] == 0x8b) || (bytes[1] == 0x3b)) { // movq, cmpq
40 if ((bytes[2] & 0xc7) == (0x80 | (THR & 7))) { // [r14+disp32]
41 int32_t offset = LoadUnaligned(reinterpret_cast<int32_t*>(pc + 3));
42 return Thread::ObjectAtOffset(offset, obj);
43 }
44 if ((bytes[2] & 0xc7) == (0x40 | (THR & 7))) { // [r14+disp8]
45 uint8_t offset = *reinterpret_cast<uint8_t*>(pc + 3);
46 return Thread::ObjectAtOffset(offset, obj);
47 }
48 }
49 }
50
51 if (((bytes[0] == 0x41) && (bytes[1] == 0xff) && (bytes[2] == 0x76))) {
52 // push [r14+disp8]
53 uint8_t offset = *reinterpret_cast<uint8_t*>(pc + 3);
54 return Thread::ObjectAtOffset(offset, obj);
55 }
56
58 if ((bytes[0] == 0x49) || (bytes[0] == 0x4d)) {
59 if ((bytes[1] == 0x8b) || (bytes[1] == 0x3b)) { // movq, cmpq
60 if ((bytes[2] & 0xc7) == (0x80 | (PP & 7))) { // [r15+disp32]
61 intptr_t index = IndexFromPPLoadDisp32(pc + 3);
62 return ObjectAtPoolIndex(code, index, obj);
63 }
64 if ((bytes[2] & 0xc7) == (0x40 | (PP & 7))) { // [r15+disp8]
65 intptr_t index = IndexFromPPLoadDisp8(pc + 3);
66 return ObjectAtPoolIndex(code, index, obj);
67 }
68 }
69 }
70
71 return false;
72}
73
75 static int16_t indirect_call_pattern[] = {
76 0xff, -1 /* 0x53 or 0x56 */, 0x07, // callq [RBX/RSI + 0x7]
77 };
78 static int16_t direct_call_pattern[] = {
79 0xe8, -1, -1, -1, -1, // callq [PC + <offset>]
80 };
81 static int16_t pattern_disp8[] = {
82 0x4d, 0x8b, 0x4f, -1, // movq R9, [PP + offset]
83 };
84 static int16_t pattern_disp32[] = {
85 0x4d, 0x8b, 0x8f, -1, -1, -1, -1, // movq R9, [PP + offset]
86 };
87
88 uword pc = pc_;
89 if (MatchesPattern(pc, direct_call_pattern,
90 ARRAY_SIZE(direct_call_pattern))) {
91 pc -= ARRAY_SIZE(direct_call_pattern);
92 } else if (MatchesPattern(pc, indirect_call_pattern,
93 ARRAY_SIZE(indirect_call_pattern))) {
94 pc -= ARRAY_SIZE(indirect_call_pattern);
95 } else {
96 FATAL("Failed to decode at %" Px, pc_);
97 }
98
99 if (MatchesPattern(pc, pattern_disp8, ARRAY_SIZE(pattern_disp8))) {
100 return IndexFromPPLoadDisp8(pc - 1);
101 } else if (MatchesPattern(pc, pattern_disp32, ARRAY_SIZE(pattern_disp32))) {
102 return IndexFromPPLoadDisp32(pc - 4);
103 } else {
104 FATAL("Failed to decode at %" Px, pc);
105 }
106}
107
108} // namespace dart
109
110#endif // defined TARGET_ARCH_X64
static intptr_t IndexFromOffset(intptr_t offset)
Definition: object.h:5676
static bool ObjectAtOffset(intptr_t offset, Object *object)
Definition: thread.cc:1205
#define ASSERT(E)
#define FATAL(error)
Definition: dart_vm.cc:33
bool ObjectAtPoolIndex(const Code &code, intptr_t index, Object *obj)
Definition: instructions.cc:14
const Register THR
uintptr_t uword
Definition: globals.h:501
bool MatchesPattern(uword end, const int16_t *pattern, intptr_t size)
Definition: code_patcher.cc:46
bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code &code, Object *obj)
static T LoadUnaligned(const T *ptr)
Definition: unaligned.h:14
const Register PP
intptr_t IndexFromPPLoadDisp32(uword start)
intptr_t IndexFromPPLoadDisp8(uword start)
COMPILE_ASSERT(kUnreachableReference==WeakTable::kNoValue)
#define Px
Definition: globals.h:410
SeparatedVector2 offset
#define ARRAY_SIZE(array)
Definition: globals.h:72