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

Side by Side Diff: runtime/vm/code_patcher_x64.cc

Issue 1175523002: Object pool with support for untagged entries. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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
« no previous file with comments | « runtime/vm/code_patcher_mips.cc ('k') | runtime/vm/compiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
13 #include "vm/instructions.h" 13 #include "vm/instructions.h"
14 #include "vm/object.h" 14 #include "vm/object.h"
15 #include "vm/raw_object.h" 15 #include "vm/raw_object.h"
16 16
17 namespace dart { 17 namespace dart {
18 18
19 // The expected pattern of a Dart unoptimized call (static and instance): 19 // The expected pattern of a Dart unoptimized call (static and instance):
20 // 0: 49 8b 9f imm32 mov RBX, [PP + off] 20 // 0: 49 8b 9f imm32 mov RBX, [PP + off]
21 // 7: 41 ff 97 imm32 call [PP + off] 21 // 7: 41 ff 97 imm32 call [PP + off]
22 // 14 <- return address 22 // 14 <- return address
23 class UnoptimizedCall : public ValueObject { 23 class UnoptimizedCall : public ValueObject {
24 public: 24 public:
25 UnoptimizedCall(uword return_address, const Code& code) 25 UnoptimizedCall(uword return_address, const Code& code)
26 : start_(return_address - kCallPatternSize), 26 : start_(return_address - kCallPatternSize),
27 object_pool_(Array::Handle(code.ObjectPool())) { 27 object_pool_(ObjectPool::Handle(code.GetObjectPool())) {
28 ASSERT(IsValid(return_address)); 28 ASSERT(IsValid(return_address));
29 ASSERT((kCallPatternSize - 7) == Assembler::kCallExternalLabelSize); 29 ASSERT((kCallPatternSize - 7) == Assembler::kCallExternalLabelSize);
30 } 30 }
31 31
32 static const int kCallPatternSize = 14; 32 static const int kCallPatternSize = 14;
33 33
34 static bool IsValid(uword return_address) { 34 static bool IsValid(uword return_address) {
35 uint8_t* code_bytes = 35 uint8_t* code_bytes =
36 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize); 36 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize);
37 return (code_bytes[0] == 0x49) && (code_bytes[1] == 0x8B) && 37 return (code_bytes[0] == 0x49) && (code_bytes[1] == 0x8B) &&
38 (code_bytes[2] == 0x9F) && 38 (code_bytes[2] == 0x9F) &&
39 (code_bytes[7] == 0x41) && (code_bytes[8] == 0xFF) && 39 (code_bytes[7] == 0x41) && (code_bytes[8] == 0xFF) &&
40 (code_bytes[9] == 0x97); 40 (code_bytes[9] == 0x97);
41 } 41 }
42 42
43 RawObject* ic_data() const { 43 RawObject* ic_data() const {
44 intptr_t index = InstructionPattern::IndexFromPPLoad(start_ + 3); 44 intptr_t index = InstructionPattern::IndexFromPPLoad(start_ + 3);
45 return object_pool_.At(index); 45 return object_pool_.ObjectAt(index);
46 } 46 }
47 47
48 uword target() const { 48 uword target() const {
49 intptr_t index = InstructionPattern::IndexFromPPLoad(start_ + 10); 49 intptr_t index = InstructionPattern::IndexFromPPLoad(start_ + 10);
50 return reinterpret_cast<uword>(object_pool_.At(index)); 50 return object_pool_.RawValueAt(index);
51 } 51 }
52 52
53 void set_target(uword target) const { 53 void set_target(uword target) const {
54 intptr_t index = InstructionPattern::IndexFromPPLoad(start_ + 10); 54 intptr_t index = InstructionPattern::IndexFromPPLoad(start_ + 10);
55 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(target)); 55 object_pool_.SetRawValueAt(index, target);
56 object_pool_.SetAt(index, smi);
57 // No need to flush the instruction cache, since the code is not modified. 56 // No need to flush the instruction cache, since the code is not modified.
58 } 57 }
59 58
60 private: 59 private:
61 uword start_; 60 uword start_;
62 const Array& object_pool_; 61 const ObjectPool& object_pool_;
63 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall); 62 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall);
64 }; 63 };
65 64
66 65
67 class InstanceCall : public UnoptimizedCall { 66 class InstanceCall : public UnoptimizedCall {
68 public: 67 public:
69 InstanceCall(uword return_address, const Code& code) 68 InstanceCall(uword return_address, const Code& code)
70 : UnoptimizedCall(return_address, code) { 69 : UnoptimizedCall(return_address, code) {
71 #if defined(DEBUG) 70 #if defined(DEBUG)
72 ICData& test_ic_data = ICData::Handle(); 71 ICData& test_ic_data = ICData::Handle();
(...skipping 24 matching lines...) Expand all
97 96
98 97
99 // The expected pattern of a call where the target is loaded from 98 // The expected pattern of a call where the target is loaded from
100 // the object pool: 99 // the object pool:
101 // 0: 41 ff 97 imm32 call [PP + off] 100 // 0: 41 ff 97 imm32 call [PP + off]
102 // 7: <- return address 101 // 7: <- return address
103 class PoolPointerCall : public ValueObject { 102 class PoolPointerCall : public ValueObject {
104 public: 103 public:
105 explicit PoolPointerCall(uword return_address, const Code& code) 104 explicit PoolPointerCall(uword return_address, const Code& code)
106 : start_(return_address - kCallPatternSize), 105 : start_(return_address - kCallPatternSize),
107 object_pool_(Array::Handle(code.ObjectPool())) { 106 object_pool_(ObjectPool::Handle(code.GetObjectPool())) {
108 ASSERT(IsValid(return_address)); 107 ASSERT(IsValid(return_address));
109 } 108 }
110 109
111 static const int kCallPatternSize = 7; 110 static const int kCallPatternSize = 7;
112 111
113 static bool IsValid(uword return_address) { 112 static bool IsValid(uword return_address) {
114 uint8_t* code_bytes = 113 uint8_t* code_bytes =
115 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize); 114 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize);
116 return (code_bytes[0] == 0x41) && (code_bytes[1] == 0xFF) && 115 return (code_bytes[0] == 0x41) && (code_bytes[1] == 0xFF) &&
117 (code_bytes[2] == 0x97); 116 (code_bytes[2] == 0x97);
118 } 117 }
119 118
120 intptr_t pp_index() const { 119 intptr_t pp_index() const {
121 return InstructionPattern::IndexFromPPLoad(start_ + 3); 120 return InstructionPattern::IndexFromPPLoad(start_ + 3);
122 } 121 }
123 122
124 uword Target() const { 123 uword Target() const {
125 return reinterpret_cast<uword>(object_pool_.At(pp_index())); 124 return reinterpret_cast<uword>(object_pool_.RawValueAt(pp_index()));
126 } 125 }
127 126
128 void SetTarget(uword target) const { 127 void SetTarget(uword target) const {
129 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(target)); 128 object_pool_.SetRawValueAt(pp_index(), target);
130 object_pool_.SetAt(pp_index(), smi);
131 // No need to flush the instruction cache, since the code is not modified. 129 // No need to flush the instruction cache, since the code is not modified.
132 } 130 }
133 131
134 protected: 132 protected:
135 uword start_; 133 uword start_;
136 const Array& object_pool_; 134 const ObjectPool& object_pool_;
137 135
138 private: 136 private:
139 DISALLOW_IMPLICIT_CONSTRUCTORS(PoolPointerCall); 137 DISALLOW_IMPLICIT_CONSTRUCTORS(PoolPointerCall);
140 }; 138 };
141 139
142 140
143 uword CodePatcher::GetStaticCallTargetAt(uword return_address, 141 uword CodePatcher::GetStaticCallTargetAt(uword return_address,
144 const Code& code) { 142 const Code& code) {
145 ASSERT(code.ContainsInstructionAt(return_address)); 143 ASSERT(code.ContainsInstructionAt(return_address));
146 PoolPointerCall call(return_address, code); 144 PoolPointerCall call(return_address, code);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 return ic_data.GetTargetAt(0); 210 return ic_data.GetTargetAt(0);
213 } 211 }
214 212
215 213
216 // The expected code pattern of an edge counter in unoptimized code: 214 // The expected code pattern of an edge counter in unoptimized code:
217 // 49 8b 87 imm32 mov RAX, [PP + offset] 215 // 49 8b 87 imm32 mov RAX, [PP + offset]
218 class EdgeCounter : public ValueObject { 216 class EdgeCounter : public ValueObject {
219 public: 217 public:
220 EdgeCounter(uword pc, const Code& code) 218 EdgeCounter(uword pc, const Code& code)
221 : end_(pc - FlowGraphCompiler::EdgeCounterIncrementSizeInBytes()), 219 : end_(pc - FlowGraphCompiler::EdgeCounterIncrementSizeInBytes()),
222 object_pool_(Array::Handle(code.ObjectPool())) { 220 object_pool_(ObjectPool::Handle(code.GetObjectPool())) {
223 ASSERT(IsValid(end_)); 221 ASSERT(IsValid(end_));
224 } 222 }
225 223
226 static bool IsValid(uword end) { 224 static bool IsValid(uword end) {
227 uint8_t* bytes = reinterpret_cast<uint8_t*>(end - 7); 225 uint8_t* bytes = reinterpret_cast<uint8_t*>(end - 7);
228 return (bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x87); 226 return (bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x87);
229 } 227 }
230 228
231 RawObject* edge_counter() const { 229 RawObject* edge_counter() const {
232 return object_pool_.At(InstructionPattern::IndexFromPPLoad(end_ - 4)); 230 return object_pool_.ObjectAt(InstructionPattern::IndexFromPPLoad(end_ - 4));
233 } 231 }
234 232
235 private: 233 private:
236 uword end_; 234 uword end_;
237 const Array& object_pool_; 235 const ObjectPool& object_pool_;
238 }; 236 };
239 237
240 238
241 RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) { 239 RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) {
242 ASSERT(code.ContainsInstructionAt(pc)); 240 ASSERT(code.ContainsInstructionAt(pc));
243 EdgeCounter counter(pc, code); 241 EdgeCounter counter(pc, code);
244 return counter.edge_counter(); 242 return counter.edge_counter();
245 } 243 }
246 244
247 } // namespace dart 245 } // namespace dart
248 246
249 #endif // defined TARGET_ARCH_X64 247 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher_mips.cc ('k') | runtime/vm/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698