Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(771)

Side by Side Diff: runtime/vm/instructions_x64.h

Issue 1301963003: VM: Clean up and fix bugs in instructions patterns (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: s/Pattern::InstructionLength/Pattern::pattern_length_in_bytes/g Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 // Classes that describe assembly patterns as used by inline caches. 4 // Classes that describe assembly patterns as used by inline caches.
5 5
6 #ifndef VM_INSTRUCTIONS_X64_H_ 6 #ifndef VM_INSTRUCTIONS_X64_H_
7 #define VM_INSTRUCTIONS_X64_H_ 7 #define VM_INSTRUCTIONS_X64_H_
8 8
9 #ifndef VM_INSTRUCTIONS_H_ 9 #ifndef VM_INSTRUCTIONS_H_
10 #error Do not include instructions_ia32.h directly; use instructions.h instead. 10 #error Do not include instructions_ia32.h directly; use instructions.h instead.
11 #endif 11 #endif
12 12
13 #include "vm/allocation.h" 13 #include "vm/allocation.h"
14 #include "vm/object.h" 14 #include "vm/object.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 // Forward declarations. 18 // Forward declarations.
19 class RawClass; 19 class RawClass;
20 class Immediate; 20 class Immediate;
21 class RawObject; 21 class RawObject;
22 22
23 // Abstract class for all instruction pattern classes. 23
24 class InstructionPattern : public ValueObject { 24 intptr_t IndexFromPPLoad(uword start);
25
26
27 // Template class for all instruction pattern classes.
28 // P has to specify a static pattern and a pattern length method.
29 template<class P> class InstructionPattern : public ValueObject {
25 public: 30 public:
26 explicit InstructionPattern(uword pc) : start_(pc) { 31 explicit InstructionPattern(uword pc) : start_(pc) {
27 ASSERT(pc != 0); 32 ASSERT(pc != 0);
28 } 33 }
29 virtual ~InstructionPattern() {}
30 34
31 // Call to check if the instruction pattern at 'pc' match the instruction. 35 // Call to check if the instruction pattern at 'pc' match the instruction.
32 virtual bool IsValid() const { 36 // 'P::pattern()' returns the expected byte pattern in form of an integer
33 return TestBytesWith(pattern(), pattern_length_in_bytes()); 37 // array with length of 'P::pattern_length_in_bytes()'. A '-1' element means
38 // 'any byte'.
39 bool IsValid() const {
40 return TestBytesWith(P::pattern(), P::pattern_length_in_bytes());
34 } 41 }
35 42
36 // 'pattern' returns the expected byte pattern in form of an integer array
37 // with length of 'pattern_length_in_bytes'. A '-1' element means 'any byte'.
38 virtual const int* pattern() const = 0;
39 virtual int pattern_length_in_bytes() const = 0;
40
41 static intptr_t IndexFromPPLoad(uword start);
42 static intptr_t OffsetFromPPIndex(intptr_t index);
43
44 protected: 43 protected:
45 uword start() const { return start_; } 44 uword start() const { return start_; }
46 45
47 private: 46 private:
48 // Returns true if the 'num_bytes' bytes at 'start_' correspond to 47 // Returns true if the 'num_bytes' bytes at 'start_' correspond to
49 // array of integers 'data'. 'data' elements are either a byte or -1, which 48 // array of integers 'data'. 'data' elements are either a byte or -1, which
50 // represents any byte. 49 // represents any byte.
51 bool TestBytesWith(const int* data, int num_bytes) const; 50 bool TestBytesWith(const int* data, int num_bytes) const {
51 ASSERT(data != NULL);
52 const uint8_t* byte_array = reinterpret_cast<const uint8_t*>(start_);
53 for (int i = 0; i < num_bytes; i++) {
54 // Skip comparison for data[i] < 0.
55 if ((data[i] >= 0) && (byte_array[i] != (0xFF & data[i]))) {
56 return false;
57 }
58 }
59 return true;
60 }
52 61
53 const uword start_; 62 const uword start_;
54 63
55 DISALLOW_COPY_AND_ASSIGN(InstructionPattern); 64 DISALLOW_COPY_AND_ASSIGN(InstructionPattern);
56 }; 65 };
57 66
58 67
59 class JumpPattern : public InstructionPattern { 68 class JumpPattern : public InstructionPattern<JumpPattern> {
60 public: 69 public:
61 JumpPattern(uword pc, const Code& code) 70 JumpPattern(uword pc, const Code& code)
62 : InstructionPattern(pc), 71 : InstructionPattern(pc),
63 object_pool_(ObjectPool::Handle(code.GetObjectPool())) {} 72 object_pool_(ObjectPool::Handle(code.GetObjectPool())) {}
64 static int InstructionLength() { 73
65 return kLengthInBytes;
66 }
67 uword TargetAddress() const; 74 uword TargetAddress() const;
68 void SetTargetAddress(uword new_target) const; 75 void SetTargetAddress(uword new_target) const;
69 virtual int pattern_length_in_bytes() const {
70 return kLengthInBytes;
71 }
72 76
73 static const int kLengthInBytes = 7; 77 static const int kLengthInBytes = 7;
78 static int pattern_length_in_bytes() { return kLengthInBytes; }
79 static const int* pattern() {
80 // 07: 41 ff a7 imm32 jmpq [reg + off]
81 static const int kJumpPattern[kLengthInBytes] =
82 {0x41, 0xFF, -1, -1, -1, -1, -1};
83 return kJumpPattern;
84 }
74 private: 85 private:
75 virtual const int* pattern() const;
76 const ObjectPool& object_pool_; 86 const ObjectPool& object_pool_;
77 87
78 DISALLOW_COPY_AND_ASSIGN(JumpPattern); 88 DISALLOW_COPY_AND_ASSIGN(JumpPattern);
79 }; 89 };
80 90
81 91
82 // 5 byte call instruction. 92 // 5 byte call instruction.
83 class ShortCallPattern : public InstructionPattern { 93 class ShortCallPattern : public InstructionPattern<ShortCallPattern> {
84 public: 94 public:
85 explicit ShortCallPattern(uword pc) : InstructionPattern(pc) {} 95 explicit ShortCallPattern(uword pc) : InstructionPattern(pc) {}
86 static int InstructionLength() {
87 return kLengthInBytes;
88 }
89
90 virtual int pattern_length_in_bytes() const {
91 return kLengthInBytes;
92 }
93 96
94 void SetTargetAddress(uword new_target) const; 97 void SetTargetAddress(uword new_target) const;
95 98
99 static int pattern_length_in_bytes() { return kLengthInBytes; }
100 static const int* pattern() {
101 static const int kCallPattern[kLengthInBytes] = {0xE8, -1, -1, -1, -1};
102 return kCallPattern;
103 }
104
96 private: 105 private:
97 static const int kLengthInBytes = 5; 106 static const int kLengthInBytes = 5;
98 virtual const int* pattern() const;
99
100 DISALLOW_COPY_AND_ASSIGN(ShortCallPattern); 107 DISALLOW_COPY_AND_ASSIGN(ShortCallPattern);
101 }; 108 };
102 109
103 110
104 class ReturnPattern : public InstructionPattern { 111 class ReturnPattern : public InstructionPattern<ReturnPattern> {
105 public: 112 public:
106 explicit ReturnPattern(uword pc) : InstructionPattern(pc) {} 113 explicit ReturnPattern(uword pc) : InstructionPattern(pc) {}
107 114
108 virtual const int* pattern() const; 115 static const int* pattern() {
109 virtual int pattern_length_in_bytes() const { return kLengthInBytes; } 116 static const int kReturnPattern[kLengthInBytes] = { 0xC3 };
117 return kReturnPattern;
118 }
119
120 static int pattern_length_in_bytes() { return kLengthInBytes; }
110 121
111 private: 122 private:
112 static const int kLengthInBytes = 1; 123 static const int kLengthInBytes = 1;
113 }; 124 };
114 125
115 126
116 // push rbp 127 // push rbp
117 // mov rbp, rsp 128 // mov rbp, rsp
118 class ProloguePattern : public InstructionPattern { 129 class ProloguePattern : public InstructionPattern<ProloguePattern> {
119 public: 130 public:
120 explicit ProloguePattern(uword pc) : InstructionPattern(pc) {} 131 explicit ProloguePattern(uword pc) : InstructionPattern(pc) {}
121 132
122 virtual const int* pattern() const; 133 static const int* pattern() {
123 virtual int pattern_length_in_bytes() const { return kLengthInBytes; } 134 static const int kProloguePattern[kLengthInBytes] =
135 { 0x55, 0x48, 0x89, 0xe5 };
136 return kProloguePattern;
137 }
138
139 static int pattern_length_in_bytes() { return kLengthInBytes; }
124 140
125 private: 141 private:
126 static const int kLengthInBytes = 4; 142 static const int kLengthInBytes = 4;
127 }; 143 };
128 144
129 145
130 // mov rbp, rsp 146 // mov rbp, rsp
131 class SetFramePointerPattern : public InstructionPattern { 147 class SetFramePointerPattern :
148 public InstructionPattern<SetFramePointerPattern> {
132 public: 149 public:
133 explicit SetFramePointerPattern(uword pc) : InstructionPattern(pc) {} 150 explicit SetFramePointerPattern(uword pc) : InstructionPattern(pc) {}
134 151
135 virtual const int* pattern() const; 152 static const int* pattern() {
136 virtual int pattern_length_in_bytes() const { return kLengthInBytes; } 153 static const int kFramePointerPattern[kLengthInBytes] =
154 { 0x48, 0x89, 0xe5 };
155 return kFramePointerPattern;
156 }
157
158 static int pattern_length_in_bytes() { return kLengthInBytes; }
137 159
138 private: 160 private:
139 static const int kLengthInBytes = 3; 161 static const int kLengthInBytes = 3;
140 }; 162 };
141 163
142 } // namespace dart 164 } // namespace dart
143 165
144 #endif // VM_INSTRUCTIONS_X64_H_ 166 #endif // VM_INSTRUCTIONS_X64_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698