OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/cpu.h" | 8 #include "vm/cpu.h" |
9 #include "vm/constants_x64.h" | 9 #include "vm/constants_x64.h" |
10 #include "vm/instructions.h" | 10 #include "vm/instructions.h" |
11 #include "vm/object.h" | 11 #include "vm/object.h" |
12 | 12 |
13 namespace dart { | 13 namespace dart { |
14 | 14 |
15 void ShortCallPattern::SetTargetAddress(uword target) const { | 15 void ShortCallPattern::SetTargetAddress(uword target) const { |
16 ASSERT(IsValid()); | 16 ASSERT(IsValid()); |
17 *reinterpret_cast<uint32_t*>(start() + 1) = target - start() - kLengthInBytes; | 17 *reinterpret_cast<uint32_t*>(start() + 1) = target - start() - kLengthInBytes; |
18 CPU::FlushICache(start() + 1, kWordSize); | 18 CPU::FlushICache(start() + 1, kWordSize); |
19 } | 19 } |
20 | 20 |
21 | 21 |
22 bool DecodeLoadObjectFromPoolOrThread(uword pc, | 22 bool DecodeLoadObjectFromPoolOrThread(uword pc, |
23 const Code& code, | 23 const Code& code, |
24 Object* obj) { | 24 Object* obj) { |
25 ASSERT(code.ContainsInstructionAt(pc)); | 25 ASSERT(code.ContainsInstructionAt(pc)); |
26 | 26 |
27 uint8_t* bytes = reinterpret_cast<uint8_t*>(pc); | 27 uint8_t* bytes = reinterpret_cast<uint8_t*>(pc); |
28 | |
28 COMPILE_ASSERT(PP == R15); | 29 COMPILE_ASSERT(PP == R15); |
29 if (((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x9f)) || | 30 if ((bytes[0] == 0x49) || (bytes[0] == 0x4d)) { |
30 ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x87)) || | 31 if ((bytes[1] == 0x8b) || (bytes[1] == 0x3b)) { // movq, cmpq |
31 ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0xa7)) || | 32 if ((bytes[2] & 0xc7) == (0x80 | (PP & 7))) { // [R15+disp32] |
32 ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x9f)) || | 33 intptr_t index = IndexFromPPLoad(pc + 3); |
33 ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x97))) { | 34 const ObjectPool& pool = ObjectPool::Handle(code.object_pool()); |
34 intptr_t index = IndexFromPPLoad(pc + 3); | 35 if (pool.InfoAt(index) == ObjectPool::kTaggedObject) { |
35 const ObjectPool& pool = ObjectPool::Handle(code.object_pool()); | 36 *obj = pool.ObjectAt(index); |
36 if (pool.InfoAt(index) == ObjectPool::kTaggedObject) { | 37 return true; |
37 *obj = pool.ObjectAt(index); | 38 } |
38 return true; | 39 } |
40 if ((bytes[2] & 0xc7) == (0x40 | (PP & 7))) { // [R15+disp8] | |
41 intptr_t index = IndexFromPPLoadDisp8(pc + 3); | |
42 const ObjectPool& pool = ObjectPool::Handle(code.object_pool()); | |
43 if (pool.InfoAt(index) == ObjectPool::kTaggedObject) { | |
44 *obj = pool.ObjectAt(index); | |
45 return true; | |
46 } | |
47 } | |
39 } | 48 } |
40 } | 49 } |
50 | |
41 COMPILE_ASSERT(THR == R14); | 51 COMPILE_ASSERT(THR == R14); |
42 if (((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x86)) || | 52 if ((bytes[0] == 0x49) || (bytes[0] == 0x4d)) { |
43 ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0xb6)) || | 53 if ((bytes[1] == 0x8b) || (bytes[1] == 0x3b)) { // movq, cmpq |
44 ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x96)) || | 54 if ((bytes[2] & 0xc7) == (0x40 | (R14 & 7))) { |
Florian Schneider
2016/04/15 16:57:49
s/R14/THR/g for consistency with PP above.
Maybe
sra1
2016/04/15 17:55:00
Done.
| |
45 ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x9e)) || | 55 // [r14+disp8] |
Florian Schneider
2016/04/15 16:57:49
Move to prev line.
sra1
2016/04/15 17:55:00
Done.
| |
46 ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x9e)) || | 56 uint8_t offset = *reinterpret_cast<uint8_t*>(pc + 3); |
47 ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0xa6))) { | 57 return Thread::ObjectAtOffset(offset, obj); |
48 int32_t offset = *reinterpret_cast<int32_t*>(pc + 3); | 58 } |
49 return Thread::ObjectAtOffset(offset, obj); | 59 if ((bytes[2] & 0307) == (0x80 | (R14 & 7))) { |
Florian Schneider
2016/04/15 16:57:49
Please don't use octal literals...
if ((bytes[2]
sra1
2016/04/15 17:55:00
Done. I missed that one. (mod r/m fields correspon
sra1
2016/04/15 17:55:00
Done.
| |
60 // [r14+disp32] | |
61 int32_t offset = *reinterpret_cast<int32_t*>(pc + 3); | |
62 return Thread::ObjectAtOffset(offset, obj); | |
63 } | |
64 } | |
50 } | 65 } |
51 if (((bytes[0] == 0x41) && (bytes[1] == 0xff) && (bytes[2] == 0x76)) || | 66 if (((bytes[0] == 0x41) && (bytes[1] == 0xff) && (bytes[2] == 0x76))) { |
52 ((bytes[0] == 0x49) && (bytes[1] == 0x3b) && (bytes[2] == 0x66)) || | 67 // push [r14+disp8] |
53 ((bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x46)) || | |
54 ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x5e)) || | |
55 ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x66)) || | |
56 ((bytes[0] == 0x4d) && (bytes[1] == 0x8b) && (bytes[2] == 0x6e))) { | |
57 uint8_t offset = *reinterpret_cast<uint8_t*>(pc + 3); | 68 uint8_t offset = *reinterpret_cast<uint8_t*>(pc + 3); |
58 return Thread::ObjectAtOffset(offset, obj); | 69 return Thread::ObjectAtOffset(offset, obj); |
59 } | 70 } |
60 | 71 |
61 return false; | 72 return false; |
62 } | 73 } |
63 | 74 |
64 } // namespace dart | 75 } // namespace dart |
65 | 76 |
66 #endif // defined TARGET_ARCH_X64 | 77 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |