OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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_CONSTANTS_DBC_H_ | 5 #ifndef VM_CONSTANTS_DBC_H_ |
6 #define VM_CONSTANTS_DBC_H_ | 6 #define VM_CONSTANTS_DBC_H_ |
7 | 7 |
8 #include "platform/globals.h" | 8 #include "platform/globals.h" |
9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
10 #include "platform/utils.h" | 10 #include "platform/utils.h" |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 // Note: return instruction knows how many arguments to remove from the | 112 // Note: return instruction knows how many arguments to remove from the |
113 // stack because it can look at the call instruction at caller's PC and | 113 // stack because it can look at the call instruction at caller's PC and |
114 // take argument count from it. | 114 // take argument count from it. |
115 // | 115 // |
116 // - Move rA, rX | 116 // - Move rA, rX |
117 // | 117 // |
118 // FP[rA] <- FP[rX] | 118 // FP[rA] <- FP[rX] |
119 // Note: rX is signed so it can be used to address parameters which are | 119 // Note: rX is signed so it can be used to address parameters which are |
120 // at negative indices with respect to FP. | 120 // at negative indices with respect to FP. |
121 // | 121 // |
| 122 // - Swap rA, rX |
| 123 // |
| 124 // FP[rA], FP[rX] <- FP[rX], FP[rA] |
| 125 // Note: rX is signed so it can be used to address parameters which are |
| 126 // at negative indices with respect to FP. |
| 127 // |
122 // - Push rX | 128 // - Push rX |
123 // | 129 // |
124 // Push FP[rX] to the stack. | 130 // Push FP[rX] to the stack. |
125 // | 131 // |
126 // - LoadConstant rA, D; PushConstant D | 132 // - LoadConstant rA, D; PushConstant D |
127 // | 133 // |
128 // Load value at index D from constant pool into FP[rA] or push it onto the | 134 // Load value at index D from constant pool into FP[rA] or push it onto the |
129 // stack. | 135 // stack. |
130 // | 136 // |
131 // - StoreLocal rX; PopLocal rX | 137 // - StoreLocal rX; PopLocal rX |
132 // | 138 // |
133 // Store top of the stack into FP[rX] and pop it if needed. | 139 // Store top of the stack into FP[rX] and pop it if needed. |
134 // | 140 // |
135 // - StaticCall ArgC, D | 141 // - StaticCall ArgC, D |
136 // | 142 // |
137 // Invoke function in SP[0] with arguments SP[-(1+ArgC)], ..., SP[-1] and | 143 // Invoke function in SP[0] with arguments SP[-(1+ArgC)], ..., SP[-1] and |
138 // argument descriptor PP[D]. | 144 // argument descriptor PP[D]. |
139 // | 145 // |
140 // - InstanceCall ArgC, D; InstanceCall2 ArgC, D; InstanceCall3 ArgC, D | 146 // - InstanceCall<N> ArgC, D; InstanceCall<N>Opt ArgC, D |
141 // | 147 // |
142 // Lookup and invoke method using ICData in PP[D] with arguments | 148 // Lookup and invoke method with N checked arguments using ICData in PP[D] |
143 // SP[-(1+ArgC)], ..., SP[-1]. | 149 // with arguments SP[-(1+ArgC)], ..., SP[-1]. |
144 // | 150 // |
145 // - NativeCall, NativeBootstrapCall | 151 // - NativeCall, NativeBootstrapCall |
146 // | 152 // |
147 // Invoke native function SP[-1] with argc_tag SP[0]. | 153 // Invoke native function SP[-1] with argc_tag SP[0]. |
148 // | 154 // |
149 // - AddTOS; SubTOS; MulTOS; BitOrTOS; BitAndTOS; EqualTOS; LessThanTOS; | 155 // - AddTOS; SubTOS; MulTOS; BitOrTOS; BitAndTOS; EqualTOS; LessThanTOS; |
150 // GreaterThanTOS; | 156 // GreaterThanTOS; |
151 // | 157 // |
152 // Smi fast-path for a corresponding method. Checks if SP[0] and SP[-1] are | 158 // Smi fast-path for a corresponding method. Checks if SP[0] and SP[-1] are |
153 // both smis and result of SP[0] <op> SP[-1] is a smi - if this is true | 159 // both smis and result of SP[0] <op> SP[-1] is a smi - if this is true |
154 // then pops operands and pushes result on the stack and skips the next | 160 // then pops operands and pushes result on the stack and skips the next |
155 // instruction (which implements a slow path fallback). | 161 // instruction (which implements a slow path fallback). |
156 // | 162 // |
157 // - StoreStaticTOS D | 163 // - StoreStaticTOS D |
158 // | 164 // |
159 // Stores TOS into the static field PP[D]. | 165 // Stores TOS into the static field PP[D]. |
160 // | 166 // |
161 // - PushStatic | 167 // - PushStatic |
162 // | 168 // |
163 // Pushes value of the static field PP[D] on to the stack. | 169 // Pushes value of the static field PP[D] on to the stack. |
164 // | 170 // |
165 // - InitStaticTOS | 171 // - InitStaticTOS |
166 // | 172 // |
167 // Takes static field from TOS and ensures that it is initialized. | 173 // Takes static field from TOS and ensures that it is initialized. |
168 // | 174 // |
169 // - IfNeStrictTOS; IfEqStrictTOS; IfNeStrictNumTOS; IfEqStrictNumTOS | 175 // - If<Cond>(Num)TOS |
| 176 // If<Cond>(Num) rA, rD |
| 177 // |
| 178 // Cond is either NeStrict or EqStrict |
170 // | 179 // |
171 // Skips the next instruction unless the given condition holds. 'Num' | 180 // Skips the next instruction unless the given condition holds. 'Num' |
172 // variants perform number check while non-Num variants just compare | 181 // variants perform number check while non-Num variants just compare |
173 // RawObject pointers. | 182 // RawObject pointers. |
174 // | 183 // |
175 // Used to implement conditional jump: | 184 // Used to implement conditional jump: |
176 // | 185 // |
177 // IfNeStrictTOS | 186 // IfNeStrictTOS |
178 // Jump T ;; jump if not equal | 187 // Jump T ;; jump if not equal |
179 // | 188 // |
180 // - CreateArrayTOS | 189 // - CreateArrayTOS |
181 // | 190 // |
182 // Allocate array of length SP[0] with type arguments SP[-1]. | 191 // Allocate array of length SP[0] with type arguments SP[-1]. |
183 // | 192 // |
184 // - Allocate D | 193 // - Allocate D |
185 // | 194 // |
186 // Allocate object of class PP[D] with no type arguments. | 195 // Allocate object of class PP[D] with no type arguments. |
187 // | 196 // |
188 // - AllocateT | 197 // - AllocateT |
189 // | 198 // |
190 // Allocate object of class SP[0] with type arguments SP[-1]. | 199 // Allocate object of class SP[0] with type arguments SP[-1]. |
191 // | 200 // |
192 // - StoreIndexedTOS | 201 // - StoreIndexedTOS |
193 // | 202 // |
194 // Store SP[0] into array SP[-2] at index SP[-1]. No typechecking is done. | 203 // Store SP[0] into array SP[-2] at index SP[-1]. No typechecking is done. |
195 // SP[-2] is assumed to be a RawArray, SP[-1] to be a smi. | 204 // SP[-2] is assumed to be a RawArray, SP[-1] to be a smi. |
196 // | 205 // |
| 206 // - StoreIndexed rA, rB, rC |
| 207 // |
| 208 // Store rC into array rA at index rB. No typechecking is done. |
| 209 // rA is assumed to be a RawArray, rB to be a smi. |
| 210 // |
197 // - StoreField rA, B, rC | 211 // - StoreField rA, B, rC |
198 // | 212 // |
199 // Store value FP[rC] into object FP[rA] at offset (in words) B. | 213 // Store value FP[rC] into object FP[rA] at offset (in words) B. |
200 // | 214 // |
201 // - StoreFieldTOS D | 215 // - StoreFieldTOS D |
202 // | 216 // |
203 // Store value SP[0] into object SP[-1] at offset (in words) D. | 217 // Store value SP[0] into object SP[-1] at offset (in words) D. |
204 // | 218 // |
205 // - LoadField rA, rB, C | 219 // - LoadField rA, rB, C |
206 // | 220 // |
207 // Load value at offset (in words) C from object FP[rB] into FP[rA]. | 221 // Load value at offset (in words) C from object FP[rB] into FP[rA]. |
208 // | 222 // |
209 // - LoadFieldTOS D | 223 // - LoadFieldTOS D |
210 // | 224 // |
211 // Push value at offset (in words) D from object SP[0]. | 225 // Push value at offset (in words) D from object SP[0]. |
212 // | 226 // |
213 // - BooleanNegateTOS | 227 // - BooleanNegateTOS |
214 // | 228 // |
215 // SP[0] = !SP[0] | 229 // SP[0] = !SP[0] |
216 // | 230 // |
| 231 // - BooleanNegate rA, rD |
| 232 // |
| 233 // FP[rA] = !FP[rD] |
| 234 // |
217 // - Throw A | 235 // - Throw A |
218 // | 236 // |
219 // Throw (Rethrow if A != 0) exception. Exception object and stack object | 237 // Throw (Rethrow if A != 0) exception. Exception object and stack object |
220 // are taken from TOS. | 238 // are taken from TOS. |
221 // | 239 // |
222 // - Entry A, B, rC | 240 // - Entry A, B, rC |
223 // | 241 // |
224 // Function prologue for the function with no optional or named arguments: | 242 // Function prologue for the function with no optional or named arguments: |
225 // A - expected number of positional arguments; | 243 // A - expected number of positional arguments; |
226 // B - number of local slots to reserve; | 244 // B - number of local slots to reserve; |
227 // rC - specifies context register to initialize with empty context. | 245 // rC - specifies context register to initialize with empty context. |
228 // | 246 // |
229 // - EntryOpt A, B, C | 247 // - EntryOptional A, B, C |
230 // | 248 // |
231 // Function prologue for the function with optional or named arguments: | 249 // Function prologue for the function with optional or named arguments: |
232 // A - expected number of positional arguments; | 250 // A - expected number of positional arguments; |
233 // B - number of optional arguments; | 251 // B - number of optional arguments; |
234 // C - number of named arguments; | 252 // C - number of named arguments; |
235 // | 253 // |
236 // Only one of B and C can be not 0. | 254 // Only one of B and C can be not 0. |
237 // | 255 // |
238 // If B is not 0 then EntryOpt bytecode is followed by B LoadConstant | 256 // If B is not 0 then EntryOptional bytecode is followed by B LoadConstant |
239 // bytecodes specifying default values for optional arguments. | 257 // bytecodes specifying default values for optional arguments. |
240 // | 258 // |
241 // If C is not 0 then EntryOpt is followed by 2 * B LoadConstant bytecodes. | 259 // If C is not 0 then EntryOptional is followed by 2 * B LoadConstant |
| 260 // bytecodes. |
242 // Bytecode at 2 * i specifies name of the i-th named argument and at | 261 // Bytecode at 2 * i specifies name of the i-th named argument and at |
243 // 2 * i + 1 default value. rA part of the LoadConstant bytecode specifies | 262 // 2 * i + 1 default value. rA part of the LoadConstant bytecode specifies |
244 // the location of the parameter on the stack. Here named arguments are | 263 // the location of the parameter on the stack. Here named arguments are |
245 // sorted alphabetically to enable linear matching similar to how function | 264 // sorted alphabetically to enable linear matching similar to how function |
246 // prologues are implemented on other architectures. | 265 // prologues are implemented on other architectures. |
247 // | 266 // |
248 // Note: Unlike Entry bytecode EntryOpt does not setup the frame for | 267 // Note: Unlike Entry bytecode EntryOptional does not setup the frame for |
249 // local variables this is done by a separate bytecode Frame. | 268 // local variables this is done by a separate bytecode Frame. |
250 // | 269 // |
| 270 // - EntryOptimized A, D |
| 271 // |
| 272 // Function prologue for optimized functions with no optional or named |
| 273 // arguments. |
| 274 // A - expected number of positional arguments; |
| 275 // B - number of local slots to reserve for registers; |
| 276 // |
| 277 // Note: reserved slots are not initialized because optimized code |
| 278 // has stack maps attached to call sites. |
| 279 // |
| 280 // - HotCheck A, D |
| 281 // |
| 282 // Increment current function's usage counter by A and check if it |
| 283 // exceeds D. If it does trigger (re)optimization of the current |
| 284 // function. |
| 285 // |
251 // - Frame D | 286 // - Frame D |
252 // | 287 // |
253 // Reserve and initialize with null space for D local variables. | 288 // Reserve and initialize with null space for D local variables. |
254 // | 289 // |
255 // - SetFrame A | 290 // - SetFrame A |
256 // | 291 // |
257 // Reinitialize SP assuming that current frame has size A. | 292 // Reinitialize SP assuming that current frame has size A. |
258 // Used to drop temporaries from the stack in the exception handler. | 293 // Used to drop temporaries from the stack in the exception handler. |
259 // | 294 // |
260 // - AllocateContext D | 295 // - AllocateContext D |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 // | 330 // |
296 // - DebugStep, DebugBreak A | 331 // - DebugStep, DebugBreak A |
297 // | 332 // |
298 // Debugger support. DebugBreak is bytecode that can be patched into the | 333 // Debugger support. DebugBreak is bytecode that can be patched into the |
299 // instruction stream to trigger in place breakpoint. | 334 // instruction stream to trigger in place breakpoint. |
300 // | 335 // |
301 // When patching instance or static call with DebugBreak we set A to | 336 // When patching instance or static call with DebugBreak we set A to |
302 // match patched call's argument count so that Return instructions continue | 337 // match patched call's argument count so that Return instructions continue |
303 // to work. | 338 // to work. |
304 // | 339 // |
| 340 // TODO(vegorov) the way we replace calls with DebugBreak does not work |
| 341 // with our smi fast paths because DebugBreak is simply skipped. |
| 342 // |
305 // - LoadClassIdTOS, LoadClassId rA, D | 343 // - LoadClassIdTOS, LoadClassId rA, D |
306 // | 344 // |
307 // LoadClassIdTOS loads the class id from the object at SP[0] and stores it | 345 // LoadClassIdTOS loads the class id from the object at SP[0] and stores it |
308 // to SP[0]. LoadClassId loads the class id from FP[rA] and stores it to | 346 // to SP[0]. LoadClassId loads the class id from FP[rA] and stores it to |
309 // FP[D]. | 347 // FP[D]. |
310 // | 348 // |
311 // TODO(vegorov) the way we replace calls with DebugBreak does not work | 349 // - Deopt ArgC, D |
312 // with our smi fast paths because DebugBreak is simply skipped. | 350 // |
| 351 // If D != 0 then trigger eager deoptimization with deopt id (D - 1). |
| 352 // If D == 0 then trigger lazy deoptimization. |
| 353 // |
| 354 // The meaning of operand ArgC (encoded as A operand) matches that of an |
| 355 // ArgC operand in call instructions. This is needed because we could |
| 356 // potentially patch calls instructions with a lazy deopt and we need to |
| 357 // ensure that any Return/ReturnTOS instructions |
| 358 // returning from the patched calls will continue to function, |
| 359 // e.g. in bytecode sequences like |
| 360 // |
| 361 // InstanceCall ... <- lazy deopt inside first call |
| 362 // InstanceCall ... <- patches seconds call with Deopt |
313 // | 363 // |
314 // BYTECODE LIST FORMAT | 364 // BYTECODE LIST FORMAT |
315 // | 365 // |
316 // Bytecode list below is specified using the following format: | 366 // Bytecode list below is specified using the following format: |
317 // | 367 // |
318 // V(BytecodeName, OperandForm, Op1, Op2, Op3) | 368 // V(BytecodeName, OperandForm, Op1, Op2, Op3) |
319 // | 369 // |
320 // - OperandForm specifies operand encoding and should be one of 0, A, T, A_D, | 370 // - OperandForm specifies operand encoding and should be one of 0, A, T, A_D, |
321 // A_X, X, D (see ENCODING section above). | 371 // A_X, X, D (see ENCODING section above). |
322 // | 372 // |
323 // - Op1, Op2, Op2 specify operand meaning. Possible values: | 373 // - Op1, Op2, Op2 specify operand meaning. Possible values: |
324 // | 374 // |
325 // ___ ignored / non-existent operand | 375 // ___ ignored / non-existent operand |
326 // num immediate operand | 376 // num immediate operand |
327 // lit constant literal from object pool | 377 // lit constant literal from object pool |
328 // reg register (unsigned FP relative local) | 378 // reg register (unsigned FP relative local) |
329 // xeg x-register (signed FP relative local) | 379 // xeg x-register (signed FP relative local) |
330 // tgt jump target relative to the PC of the current instruction | 380 // tgt jump target relative to the PC of the current instruction |
331 // | 381 // |
332 // TODO(vegorov) jump targets should be encoded relative to PC of the next | 382 // TODO(vegorov) jump targets should be encoded relative to PC of the next |
333 // instruction because PC is incremeted immediately after fetch | 383 // instruction because PC is incremeted immediately after fetch |
334 // and before decoding. | 384 // and before decoding. |
335 // | 385 // |
336 #define BYTECODES_LIST(V) \ | 386 #define BYTECODES_LIST(V) \ |
337 V(Trap, 0, ___, ___, ___) \ | 387 V(Trap, 0, ___, ___, ___) \ |
338 V(Compile, 0, ___, ___, ___) \ | 388 V(Compile, 0, ___, ___, ___) \ |
| 389 V(HotCheck, A_D, num, num, ___) \ |
339 V(Intrinsic, A, num, ___, ___) \ | 390 V(Intrinsic, A, num, ___, ___) \ |
340 V(Drop1, 0, ___, ___, ___) \ | 391 V(Drop1, 0, ___, ___, ___) \ |
341 V(DropR, A, num, ___, ___) \ | 392 V(DropR, A, num, ___, ___) \ |
342 V(Drop, A, num, ___, ___) \ | 393 V(Drop, A, num, ___, ___) \ |
343 V(Jump, T, tgt, ___, ___) \ | 394 V(Jump, T, tgt, ___, ___) \ |
344 V(Return, A, num, ___, ___) \ | 395 V(Return, A, reg, ___, ___) \ |
345 V(ReturnTOS, 0, ___, ___, ___) \ | 396 V(ReturnTOS, 0, ___, ___, ___) \ |
346 V(Move, A_X, reg, xeg, ___) \ | 397 V(Move, A_X, reg, xeg, ___) \ |
| 398 V(Swap, A_X, reg, xeg, ___) \ |
347 V(Push, X, xeg, ___, ___) \ | 399 V(Push, X, xeg, ___, ___) \ |
348 V(LoadConstant, A_D, reg, lit, ___) \ | 400 V(LoadConstant, A_D, reg, lit, ___) \ |
349 V(LoadClassId, A_D, reg, reg, ___) \ | 401 V(LoadClassId, A_D, reg, reg, ___) \ |
350 V(LoadClassIdTOS, 0, ___, ___, ___) \ | 402 V(LoadClassIdTOS, 0, ___, ___, ___) \ |
351 V(PushConstant, D, lit, ___, ___) \ | 403 V(PushConstant, D, lit, ___, ___) \ |
352 V(StoreLocal, X, xeg, ___, ___) \ | 404 V(StoreLocal, X, xeg, ___, ___) \ |
353 V(PopLocal, X, xeg, ___, ___) \ | 405 V(PopLocal, X, xeg, ___, ___) \ |
354 V(StaticCall, A_D, num, num, ___) \ | 406 V(StaticCall, A_D, num, num, ___) \ |
355 V(InstanceCall, A_D, num, num, ___) \ | 407 V(InstanceCall1, A_D, num, num, ___) \ |
356 V(InstanceCall2, A_D, num, num, ___) \ | 408 V(InstanceCall2, A_D, num, num, ___) \ |
357 V(InstanceCall3, A_D, num, num, ___) \ | 409 V(InstanceCall1Opt, A_D, num, num, ___) \ |
| 410 V(InstanceCall2Opt, A_D, num, num, ___) \ |
358 V(NativeCall, 0, ___, ___, ___) \ | 411 V(NativeCall, 0, ___, ___, ___) \ |
359 V(NativeBootstrapCall, 0, ___, ___, ___) \ | 412 V(NativeBootstrapCall, 0, ___, ___, ___) \ |
360 V(AddTOS, 0, ___, ___, ___) \ | 413 V(AddTOS, 0, ___, ___, ___) \ |
361 V(SubTOS, 0, ___, ___, ___) \ | 414 V(SubTOS, 0, ___, ___, ___) \ |
362 V(MulTOS, 0, ___, ___, ___) \ | 415 V(MulTOS, 0, ___, ___, ___) \ |
363 V(BitOrTOS, 0, ___, ___, ___) \ | 416 V(BitOrTOS, 0, ___, ___, ___) \ |
364 V(BitAndTOS, 0, ___, ___, ___) \ | 417 V(BitAndTOS, 0, ___, ___, ___) \ |
365 V(EqualTOS, 0, ___, ___, ___) \ | 418 V(EqualTOS, 0, ___, ___, ___) \ |
366 V(LessThanTOS, 0, ___, ___, ___) \ | 419 V(LessThanTOS, 0, ___, ___, ___) \ |
367 V(GreaterThanTOS, 0, ___, ___, ___) \ | 420 V(GreaterThanTOS, 0, ___, ___, ___) \ |
368 V(StoreStaticTOS, D, lit, ___, ___) \ | 421 V(StoreStaticTOS, D, lit, ___, ___) \ |
369 V(PushStatic, D, lit, ___, ___) \ | 422 V(PushStatic, D, lit, ___, ___) \ |
370 V(InitStaticTOS, 0, ___, ___, ___) \ | 423 V(InitStaticTOS, 0, ___, ___, ___) \ |
371 V(IfNeStrictTOS, 0, ___, ___, ___) \ | 424 V(IfNeStrictTOS, 0, ___, ___, ___) \ |
372 V(IfEqStrictTOS, 0, ___, ___, ___) \ | 425 V(IfEqStrictTOS, 0, ___, ___, ___) \ |
373 V(IfNeStrictNumTOS, 0, ___, ___, ___) \ | 426 V(IfNeStrictNumTOS, 0, ___, ___, ___) \ |
374 V(IfEqStrictNumTOS, 0, ___, ___, ___) \ | 427 V(IfEqStrictNumTOS, 0, ___, ___, ___) \ |
| 428 V(IfNeStrict, A_D, reg, reg, ___) \ |
| 429 V(IfEqStrict, A_D, reg, reg, ___) \ |
| 430 V(IfNeStrictNum, A_D, reg, reg, ___) \ |
| 431 V(IfEqStrictNum, A_D, reg, reg, ___) \ |
375 V(CreateArrayTOS, 0, ___, ___, ___) \ | 432 V(CreateArrayTOS, 0, ___, ___, ___) \ |
376 V(Allocate, D, lit, ___, ___) \ | 433 V(Allocate, D, lit, ___, ___) \ |
377 V(AllocateT, 0, ___, ___, ___) \ | 434 V(AllocateT, 0, ___, ___, ___) \ |
378 V(StoreIndexedTOS, 0, ___, ___, ___) \ | 435 V(StoreIndexedTOS, 0, ___, ___, ___) \ |
379 V(StoreField, A_B_C, reg, reg, reg) \ | 436 V(StoreIndexed, A_B_C, reg, reg, reg) \ |
| 437 V(StoreField, A_B_C, reg, num, reg) \ |
380 V(StoreFieldTOS, D, num, ___, ___) \ | 438 V(StoreFieldTOS, D, num, ___, ___) \ |
381 V(LoadField, A_B_C, reg, reg, reg) \ | 439 V(LoadField, A_B_C, reg, reg, num) \ |
382 V(LoadFieldTOS, D, num, ___, ___) \ | 440 V(LoadFieldTOS, D, num, ___, ___) \ |
383 V(BooleanNegateTOS, 0, ___, ___, ___) \ | 441 V(BooleanNegateTOS, 0, ___, ___, ___) \ |
| 442 V(BooleanNegate, A_D, reg, reg, ___) \ |
384 V(Throw, A, num, ___, ___) \ | 443 V(Throw, A, num, ___, ___) \ |
385 V(Entry, A_B_C, num, num, num) \ | 444 V(Entry, A_B_C, num, num, num) \ |
386 V(EntryOpt, A_B_C, num, num, num) \ | 445 V(EntryOptional, A_B_C, num, num, num) \ |
| 446 V(EntryOptimized, A_D, num, num, ___) \ |
387 V(Frame, D, num, ___, ___) \ | 447 V(Frame, D, num, ___, ___) \ |
388 V(SetFrame, A, num, ___, num) \ | 448 V(SetFrame, A, num, ___, num) \ |
389 V(AllocateContext, D, num, ___, ___) \ | 449 V(AllocateContext, D, num, ___, ___) \ |
390 V(CloneContext, 0, ___, ___, ___) \ | 450 V(CloneContext, 0, ___, ___, ___) \ |
391 V(MoveSpecial, A_D, reg, num, ___) \ | 451 V(MoveSpecial, A_D, reg, num, ___) \ |
392 V(InstantiateType, D, lit, ___, ___) \ | 452 V(InstantiateType, D, lit, ___, ___) \ |
393 V(InstantiateTypeArgumentsTOS, A_D, num, lit, ___) \ | 453 V(InstantiateTypeArgumentsTOS, A_D, num, lit, ___) \ |
394 V(AssertAssignable, D, num, lit, ___) \ | 454 V(AssertAssignable, D, num, lit, ___) \ |
395 V(AssertBoolean, A, num, ___, ___) \ | 455 V(AssertBoolean, A, num, ___, ___) \ |
396 V(CheckStack, 0, ___, ___, ___) \ | 456 V(CheckStack, 0, ___, ___, ___) \ |
397 V(DebugStep, 0, ___, ___, ___) \ | 457 V(DebugStep, 0, ___, ___, ___) \ |
398 V(DebugBreak, A, num, ___, ___) \ | 458 V(DebugBreak, A, num, ___, ___) \ |
| 459 V(Deopt, A_D, num, num, ___) \ |
399 | 460 |
400 typedef uint32_t Instr; | 461 typedef uint32_t Instr; |
401 | 462 |
402 class Bytecode { | 463 class Bytecode { |
403 public: | 464 public: |
404 enum Opcode { | 465 enum Opcode { |
405 #define DECLARE_BYTECODE(name, encoding, op1, op2, op3) k##name, | 466 #define DECLARE_BYTECODE(name, encoding, op1, op2, op3) k##name, |
406 BYTECODES_LIST(DECLARE_BYTECODE) | 467 BYTECODES_LIST(DECLARE_BYTECODE) |
407 #undef DECLARE_BYTECODE | 468 #undef DECLARE_BYTECODE |
408 }; | 469 }; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 } | 511 } |
451 | 512 |
452 DART_FORCE_INLINE static uint16_t DecodeD(Instr bc) { | 513 DART_FORCE_INLINE static uint16_t DecodeD(Instr bc) { |
453 return (bc >> kDShift) & kDMask; | 514 return (bc >> kDShift) & kDMask; |
454 } | 515 } |
455 | 516 |
456 DART_FORCE_INLINE static Opcode DecodeOpcode(Instr bc) { | 517 DART_FORCE_INLINE static Opcode DecodeOpcode(Instr bc) { |
457 return static_cast<Opcode>(bc & 0xFF); | 518 return static_cast<Opcode>(bc & 0xFF); |
458 } | 519 } |
459 | 520 |
| 521 DART_FORCE_INLINE static bool IsCallOpcode(Instr instr) { |
| 522 switch (DecodeOpcode(instr)) { |
| 523 case Bytecode::kStaticCall: |
| 524 case Bytecode::kInstanceCall1: |
| 525 case Bytecode::kInstanceCall2: |
| 526 case Bytecode::kInstanceCall1Opt: |
| 527 case Bytecode::kInstanceCall2Opt: |
| 528 case Bytecode::kDebugBreak: |
| 529 return true; |
| 530 |
| 531 default: |
| 532 return false; |
| 533 } |
| 534 } |
| 535 |
460 DART_FORCE_INLINE static uint8_t DecodeArgc(Instr call) { | 536 DART_FORCE_INLINE static uint8_t DecodeArgc(Instr call) { |
461 #if defined(DEBUG) | 537 ASSERT(IsCallOpcode(call)); |
462 const Opcode op = DecodeOpcode(call); | |
463 ASSERT((op == Bytecode::kStaticCall) || | |
464 (op == Bytecode::kInstanceCall) || | |
465 (op == Bytecode::kInstanceCall2) || | |
466 (op == Bytecode::kInstanceCall3) || | |
467 (op == Bytecode::kDebugBreak)); | |
468 #endif | |
469 return (call >> 8) & 0xFF; | 538 return (call >> 8) & 0xFF; |
470 } | 539 } |
471 | 540 |
472 static Instr At(uword pc) { return *reinterpret_cast<Instr*>(pc); } | 541 static Instr At(uword pc) { return *reinterpret_cast<Instr*>(pc); } |
473 | 542 |
474 private: | 543 private: |
475 DISALLOW_ALLOCATION(); | 544 DISALLOW_ALLOCATION(); |
476 DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecode); | 545 DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecode); |
477 }; | 546 }; |
478 | 547 |
479 // Various dummy declarations to make shared code compile. | 548 // Various dummy declarations to make shared code compile. |
480 // TODO(vegorov) we need to prune away as much dead code as possible instead | 549 // TODO(vegorov) we need to prune away as much dead code as possible instead |
481 // of just making it compile. | 550 // of just making it compile. |
482 typedef int16_t Register; | 551 typedef int16_t Register; |
483 | 552 |
484 const int16_t FPREG = 0; | 553 const int16_t FPREG = 0; |
485 const int16_t SPREG = 1; | 554 const int16_t SPREG = 1; |
486 const intptr_t kNumberOfCpuRegisters = 20; | 555 const intptr_t kNumberOfCpuRegisters = 20; |
487 const intptr_t kDartAvailableCpuRegs = 0; | 556 const intptr_t kDartAvailableCpuRegs = -1; |
488 const intptr_t kNoRegister = -1; | 557 const intptr_t kNoRegister = -1; |
489 const intptr_t kReservedCpuRegisters = 0; | 558 const intptr_t kReservedCpuRegisters = 0; |
490 const intptr_t ARGS_DESC_REG = 0; | 559 const intptr_t ARGS_DESC_REG = 0; |
491 const intptr_t CODE_REG = 0; | 560 const intptr_t CODE_REG = 0; |
492 const intptr_t kExceptionObjectReg = 0; | 561 const intptr_t kExceptionObjectReg = 0; |
493 const intptr_t kStackTraceObjectReg = 0; | 562 const intptr_t kStackTraceObjectReg = 0; |
494 const intptr_t CTX = 0; | 563 const intptr_t CTX = 0; |
495 | 564 |
496 enum FpuRegister { | 565 enum FpuRegister { |
497 kNoFpuRegister = -1, | 566 kNoFpuRegister = -1, |
498 kFakeFpuRegister, | 567 kFakeFpuRegister, |
499 kNumberOfDummyFpuRegisters, | 568 kNumberOfDummyFpuRegisters, |
500 }; | 569 }; |
501 const FpuRegister FpuTMP = kFakeFpuRegister; | 570 const FpuRegister FpuTMP = kFakeFpuRegister; |
502 const intptr_t kNumberOfFpuRegisters = 1; | 571 const intptr_t kNumberOfFpuRegisters = 1; |
503 | 572 |
504 enum Condition { EQ, NE }; | 573 enum Condition { EQ, NE }; |
505 | 574 |
506 } // namespace dart | 575 } // namespace dart |
507 | 576 |
508 #endif // VM_CONSTANTS_DBC_H_ | 577 #endif // VM_CONSTANTS_DBC_H_ |
OLD | NEW |