OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 #ifndef VM_DEOPT_INSTRUCTIONS_H_ | 5 #ifndef VM_DEOPT_INSTRUCTIONS_H_ |
6 #define VM_DEOPT_INSTRUCTIONS_H_ | 6 #define VM_DEOPT_INSTRUCTIONS_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/code_generator.h" | 10 #include "vm/code_generator.h" |
11 #include "vm/growable_array.h" | 11 #include "vm/growable_array.h" |
12 #include "vm/object.h" | 12 #include "vm/object.h" |
13 | 13 |
14 namespace dart { | 14 namespace dart { |
15 | 15 |
16 class Location; | 16 class Location; |
17 class Value; | 17 class Value; |
| 18 class MaterializeObjectInstr; |
18 | 19 |
19 // Holds all data relevant for execution of deoptimization instructions. | 20 // Holds all data relevant for execution of deoptimization instructions. |
20 class DeoptimizationContext : public ValueObject { | 21 class DeoptimizationContext : public ValueObject { |
21 public: | 22 public: |
22 // 'to_frame_start' points to the return address just below the frame's | 23 // 'to_frame_start' points to the return address just below the frame's |
23 // stack pointer (kPcAddressOffsetFromSp). 'num_args' is 0 if there are no | 24 // stack pointer (kPcAddressOffsetFromSp). 'num_args' is 0 if there are no |
24 // arguments or if there are optional arguments. | 25 // arguments or if there are optional arguments. |
25 DeoptimizationContext(intptr_t* to_frame_start, | 26 DeoptimizationContext(intptr_t* to_frame_start, |
26 intptr_t to_frame_size, | 27 intptr_t to_frame_size, |
27 const Array& object_table, | 28 const Array& object_table, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 kUint32x4FpuRegister, | 105 kUint32x4FpuRegister, |
105 kStackSlot, | 106 kStackSlot, |
106 kDoubleStackSlot, | 107 kDoubleStackSlot, |
107 kInt64StackSlot, | 108 kInt64StackSlot, |
108 kFloat32x4StackSlot, | 109 kFloat32x4StackSlot, |
109 kUint32x4StackSlot, | 110 kUint32x4StackSlot, |
110 kPcMarker, | 111 kPcMarker, |
111 kCallerFp, | 112 kCallerFp, |
112 kCallerPc, | 113 kCallerPc, |
113 kSuffix, | 114 kSuffix, |
| 115 kMaterializedObjectRef, |
| 116 kMaterializeObject |
114 }; | 117 }; |
115 | 118 |
116 static DeoptInstr* Create(intptr_t kind_as_int, intptr_t from_index); | 119 static DeoptInstr* Create(intptr_t kind_as_int, intptr_t from_index); |
117 | 120 |
118 DeoptInstr() {} | 121 DeoptInstr() {} |
119 virtual ~DeoptInstr() {} | 122 virtual ~DeoptInstr() {} |
120 | 123 |
121 virtual const char* ToCString() const = 0; | 124 virtual const char* ToCString() const = 0; |
122 | 125 |
123 virtual void Execute(DeoptimizationContext* deopt_context, | 126 virtual void Execute(DeoptimizationContext* deopt_context, |
124 intptr_t to_index) = 0; | 127 intptr_t* to_addr) = 0; |
125 | 128 |
126 virtual DeoptInstr::Kind kind() const = 0; | 129 virtual DeoptInstr::Kind kind() const = 0; |
127 | 130 |
128 bool Equals(const DeoptInstr& other) const { | 131 bool Equals(const DeoptInstr& other) const { |
129 return (kind() == other.kind()) && (from_index() == other.from_index()); | 132 return (kind() == other.kind()) && (from_index() == other.from_index()); |
130 } | 133 } |
131 | 134 |
132 // Decode the payload of a suffix command. Return the suffix length and | 135 // Decode the payload of a suffix command. Return the suffix length and |
133 // set the output parameter info_number to the index of the shared suffix. | 136 // set the output parameter info_number to the index of the shared suffix. |
134 static intptr_t DecodeSuffix(intptr_t from_index, intptr_t* info_number); | 137 static intptr_t DecodeSuffix(intptr_t from_index, intptr_t* info_number); |
135 | 138 |
136 // Get the function and return address which is encoded in this | 139 // Get the function and return address which is encoded in this |
137 // kRetAfterAddress deopt instruction. | 140 // kRetAfterAddress deopt instruction. |
138 static uword GetRetAddress(DeoptInstr* instr, | 141 static uword GetRetAddress(DeoptInstr* instr, |
139 const Array& object_table, | 142 const Array& object_table, |
140 Function* func); | 143 Function* func); |
141 | 144 |
| 145 // Return number of initialized fields in the object that will be |
| 146 // materialized by kMaterializeObject instruction. |
| 147 static intptr_t GetFieldCount(DeoptInstr* instr) { |
| 148 ASSERT(instr->kind() == DeoptInstr::kMaterializeObject); |
| 149 return instr->from_index(); |
| 150 } |
| 151 |
142 protected: | 152 protected: |
| 153 friend class DeoptInfoBuilder; |
| 154 |
143 virtual intptr_t from_index() const = 0; | 155 virtual intptr_t from_index() const = 0; |
144 | 156 |
145 friend class DeoptInfoBuilder; | |
146 | |
147 private: | 157 private: |
148 DISALLOW_COPY_AND_ASSIGN(DeoptInstr); | 158 DISALLOW_COPY_AND_ASSIGN(DeoptInstr); |
149 }; | 159 }; |
150 | 160 |
151 | 161 |
152 // Builds a deoptimization info table, one DeoptInfo at a time. Call AddXXX | 162 // Builds a deoptimization info table, one DeoptInfo at a time. Call AddXXX |
153 // methods in the order of their target, starting wih deoptimized code | 163 // methods in the order of their target, starting wih deoptimized code |
154 // continuation pc and ending with the first argument of the deoptimized | 164 // continuation pc and ending with the first argument of the deoptimized |
155 // code. Call CreateDeoptInfo to write the accumulated instructions into | 165 // code. Call CreateDeoptInfo to write the accumulated instructions into |
156 // the heap and reset the builder's internal state for the next DeoptInfo. | 166 // the heap and reset the builder's internal state for the next DeoptInfo. |
157 class DeoptInfoBuilder : public ValueObject { | 167 class DeoptInfoBuilder : public ValueObject { |
158 public: | 168 public: |
159 explicit DeoptInfoBuilder(const intptr_t num_args); | 169 explicit DeoptInfoBuilder(const intptr_t num_args); |
160 | 170 |
161 // 'object_table' holds all objects referred to by DeoptInstr in | 171 // 'object_table' holds all objects referred to by DeoptInstr in |
162 // all DeoptInfo instances for a single Code object. | 172 // all DeoptInfo instances for a single Code object. |
163 const GrowableObjectArray& object_table() { return object_table_; } | 173 const GrowableObjectArray& object_table() { return object_table_; } |
164 | 174 |
165 // Return address before instruction. | 175 // Return address before instruction. |
166 void AddReturnAddress(const Function& function, | 176 void AddReturnAddress(const Function& function, |
167 intptr_t deopt_id, | 177 intptr_t deopt_id, |
168 intptr_t to_index); | 178 intptr_t to_index); |
169 | 179 |
170 // Copy from optimized frame to unoptimized. | 180 // Copy from optimized frame to unoptimized. |
171 void AddCopy(Value* value, const Location& from_loc, intptr_t to_index); | 181 void AddCopy(Value* value, const Location& from_loc, intptr_t to_index); |
172 void AddPcMarker(const Function& function, intptr_t to_index); | 182 void AddPcMarker(const Function& function, intptr_t to_index); |
173 void AddCallerFp(intptr_t to_index); | 183 void AddCallerFp(intptr_t to_index); |
174 void AddCallerPc(intptr_t to_index); | 184 void AddCallerPc(intptr_t to_index); |
175 | 185 |
| 186 // Add object to be materialized. Emit kMaterializeObject instruction. |
| 187 void AddMaterialization(MaterializeObjectInstr* mat); |
| 188 |
| 189 // For every materialized object emit instructions describing data required |
| 190 // for materialization: class of the instance to allocate and field-value |
| 191 // pairs for initialization. |
| 192 // Emitted instructions are expected to follow return-address slot emitted |
| 193 // first. This way they become a part of the bottom-most deoptimized frame |
| 194 // and are discoverable by GC. |
| 195 // At deoptimization they will be removed by the stub at the very end: |
| 196 // after they were used to materialize objects. |
| 197 // Returns the index of the next stack slot. Used for verification. |
| 198 intptr_t EmitMaterializationArguments(); |
| 199 |
176 RawDeoptInfo* CreateDeoptInfo(); | 200 RawDeoptInfo* CreateDeoptInfo(); |
177 | 201 |
| 202 // Mark the actual start of the frame description after all materialization |
| 203 // instructions were emitted. Used for verification purposes. |
| 204 void MarkFrameStart() { |
| 205 ASSERT(frame_start_ == -1); |
| 206 frame_start_ = instructions_.length(); |
| 207 } |
| 208 |
178 private: | 209 private: |
179 class TrieNode; | 210 class TrieNode; |
180 | 211 |
181 intptr_t FindOrAddObjectInTable(const Object& obj) const; | 212 intptr_t FindOrAddObjectInTable(const Object& obj) const; |
| 213 intptr_t FindMaterialization(MaterializeObjectInstr* mat) const; |
182 intptr_t CalculateStackIndex(const Location& from_loc) const; | 214 intptr_t CalculateStackIndex(const Location& from_loc) const; |
183 | 215 |
| 216 intptr_t FrameSize() const { |
| 217 return instructions_.length() - frame_start_; |
| 218 } |
| 219 |
| 220 void AddConstant(const Object& obj, intptr_t to_index); |
| 221 |
184 GrowableArray<DeoptInstr*> instructions_; | 222 GrowableArray<DeoptInstr*> instructions_; |
185 const GrowableObjectArray& object_table_; | 223 const GrowableObjectArray& object_table_; |
186 const intptr_t num_args_; | 224 const intptr_t num_args_; |
187 | 225 |
188 // Used to compress entries by sharing suffixes. | 226 // Used to compress entries by sharing suffixes. |
189 TrieNode* trie_root_; | 227 TrieNode* trie_root_; |
190 intptr_t current_info_number_; | 228 intptr_t current_info_number_; |
191 | 229 |
| 230 intptr_t frame_start_; |
| 231 GrowableArray<MaterializeObjectInstr*> materializations_; |
| 232 |
192 DISALLOW_COPY_AND_ASSIGN(DeoptInfoBuilder); | 233 DISALLOW_COPY_AND_ASSIGN(DeoptInfoBuilder); |
193 }; | 234 }; |
194 | 235 |
195 | 236 |
196 // Utilities for managing the deopt table and its entries. The table is | 237 // Utilities for managing the deopt table and its entries. The table is |
197 // stored in an Array in the heap. It consists of triples of (PC offset, | 238 // stored in an Array in the heap. It consists of triples of (PC offset, |
198 // info, reason). Elements of each entry are stored consecutively in the | 239 // info, reason). Elements of each entry are stored consecutively in the |
199 // array. | 240 // array. |
200 class DeoptTable : public AllStatic { | 241 class DeoptTable : public AllStatic { |
201 public: | 242 public: |
(...skipping 18 matching lines...) Expand all Loading... |
220 DeoptInfo* info, | 261 DeoptInfo* info, |
221 Smi* reason); | 262 Smi* reason); |
222 | 263 |
223 private: | 264 private: |
224 static const intptr_t kEntrySize = 3; | 265 static const intptr_t kEntrySize = 3; |
225 }; | 266 }; |
226 | 267 |
227 } // namespace dart | 268 } // namespace dart |
228 | 269 |
229 #endif // VM_DEOPT_INSTRUCTIONS_H_ | 270 #endif // VM_DEOPT_INSTRUCTIONS_H_ |
OLD | NEW |