| 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 |