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

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

Issue 1858283002: Initial SIMDBC interpreter. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: cleanup Created 4 years, 8 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #ifndef VM_CONSTANTS_DBC_H_
6 #define VM_CONSTANTS_DBC_H_
7
8 #include "platform/globals.h"
9 #include "platform/assert.h"
10 #include "platform/utils.h"
11
12
13 namespace dart {
14
15 // List of Dart Bytecode instructions.
16 //
17 // INTERPRETER STATE
18 //
19 // current frame info (see stack_frame_dbc.h for layout)
20 // v-----^-----v
21 // ~----+----~ ~----+-------+-------+-~ ~-+-------+-------+-~
22 // ~ | ~ ~ | FP[0] | FP[1] | ~ ~ | SP[-1]| SP[0] |
23 // ~----+----~ ~----+-------+-------+-~ ~-+-------+-------+-~
24 // ^ ^
25 // FP SP
26 //
27 //
28 // The state of execution is captured in few interpreter registers:
29 //
30 // FP - base of the cFurrent frame
zra 2016/04/08 22:37:34 cFurrent -> current
Vyacheslav Egorov (Google) 2016/04/11 10:49:10 Done.
31 // SP - top of the stack (TOS) for the current frame
32 // PP - object pool for the currently execution function
33 //
34 // Frame info stored below FP additionally contains pointers to the currently
35 // executing function and code (see stack_frame_dbc.h for more information).
36 //
37 // In the unoptimized code most of bytecodes take operands implicitly from
38 // stack and store results again on the stack. Constant operands are usually
39 // taken from the object pool by index.
40 //
41 // ENCODING
42 //
43 // Each instruction is a 32-bit integer with opcode stored in the least
44 // significant byte. The following operand encodings are used:
45 //
46 // 0........8.......16.......24.......32
47 // +--------+--------+--------+--------+
48 // | opcode |~~~~~~~~~~~~~~~~~~~~~~~~~~| 0: no operands
49 // +--------+--------+--------+--------+
50 //
51 // +--------+--------+--------+--------+
52 // | opcode | A |~~~~~~~~~~~~~~~~~| A: single unsigned 8-bit operand
53 // +--------+--------+--------+--------+
54 //
55 // +--------+--------+--------+--------+
56 // | opcode | A | D | A_D: unsigned 8-bit operand and
57 // +--------+--------+--------+--------+ unsigned 16-bit operand
58 //
59 // +--------+--------+--------+--------+
60 // | opcode | A | X | A_X: unsigned 8-bit operand and
61 // +--------+--------+--------+--------+ signed 16-bit operand
62 //
63 // +--------+--------+--------+--------+
64 // | opcode |~~~~~~~~| D | D: unsigned 16-bit operand
65 // +--------+--------+--------+--------+
66 //
67 // +--------+--------+--------+--------+
68 // | opcode |~~~~~~~~| X | X: signed 16-bit operand
69 // +--------+--------+--------+--------+
70 //
71 // +--------+--------+--------+--------+
72 // | opcode | A | B | C | A_B_C: 3 unsigned 8-bit operands
73 // +--------+--------+--------+--------+
74 //
75 // +--------+--------+--------+--------+
76 // | opcode | T | T: signed 24-bit operand
77 // +--------+--------+--------+--------+
78 //
79 //
80 // INSTRUCTIONS
81 //
82 // - Trap
83 //
84 // Unreachable instruction.
85 //
86 // - Compile
87 //
88 // Compile current function and start executing newly produced code
89 // (used to implement LazyCompileStub);
90 //
91 // - Intrinsic id
92 //
93 // Execute intrinsic with the given id. If intrinsic returns true then
94 // return from the current function to the caller passing value produced
95 // by the intrinsic as a result;
96 //
97 // - Drop1; DropR n; Drop n
98 //
99 // Drop 1 or n values from the stack, if instruction is DropR push the first
100 // dropped value to the stack;
101 //
102 // - Jump target
103 //
104 // Jump to the given target. Target is specified as offset from the PC of the
105 // jump instruction.
106 //
107 // - Return R; ReturnTOS
108 //
109 // Return to the caller using either a value from the given register or a
110 // value from the top-of-stack as a result.
111 //
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
114 // take argument count from it.
115 //
116 // - Move rA, rX
117 //
118 // FP[rA] <- FP[rX]
119 // Note: rX is singed so it can be used to address parameters which are
120 // at negative indices with respect to FP.
121 //
122 // - Push rX
123 //
124 // Push FP[rX] to the stack.
125 //
126 // - LoadConstant rA, D; PushConstant D
127 //
128 // Load value at index D from constant pool into rA or push it onto the
zra 2016/04/08 22:37:34 FP[rA]?
Vyacheslav Egorov (Google) 2016/04/11 10:49:10 Done.
129 // stack.
130 //
131 // - StoreLocal rX; PopLocal rX
132 //
133 // Store top of the stack into FP[rX] and pop it if needed.
134 //
135 // - StaticCall ArgC, D
136 //
137 // Invoke function in SP[0] with arguments SP[-(1+ArgC)], ..., SP[-1] and
138 // argument descriptor PP[D].
139 //
140 // - InstanceCall ArgC, D; InstanceCall2 ArgC, D; InstanceCall3 ArgC, D
141 //
142 // Lookup and invoke method using ICData in PP[D] with arguments
143 // SP[-(1+ArgC)], ..., SP[-1].
144 //
145 // - NativeCall, NativeBootstrapCall
146 //
147 // Invoke native function SP[-1] with argc_tag SP[0].
148 //
149 // - AddTOS; SubTOS; MulTOS; BitOrTOS; BitAndTOS; EqualTOS; LessThanTOS;
150 // GreaterThanTOS;
151 //
152 // 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
154 // then pops operands and pushes result on the stack and skips the next
155 // instruction (which implements a slow path fallback).
156 //
157 // - StoreStaticTOS D
158 //
159 // Stores TOS into the static field PP[D].
160 //
161 // - PushStatic
162 //
163 // Pushes value of the static field PP[D] on to the stack.
164 //
165 // - InitStaticTOS
166 //
167 // Takes static field from TOS and ensures that it is initialized.
168 //
169 // - IfNeStrictTOS; IfEqStrictTOS; IfNeStrictNumTOS; IfEqStrictNumTOS
zra 2016/04/08 22:37:34 What does Strict mean here? Will there be non-Stri
Vyacheslav Egorov (Google) 2016/04/11 10:49:10 Strict means the same it means in Token::kEQ_STRIC
170 //
171 // Skips the next instruction unless the given condition holds. 'Num'
172 // variants perform number check while non-Num variants just compare
173 // RawObject pointers.
174 //
175 // Used to implement conditional jump:
176 //
177 // IfNeStrictTOS
178 // Jump T ;; jump if not equal
179 //
180 // - CreateArrayTOS
181 //
182 // Allocate array of length SP[0] with type arguments SP[-1].
183 //
184 // - Allocate D
185 //
186 // Allocate object of class PP[D] with no type arguments.
187 //
188 // - AllocateT
189 //
190 // Allocate object of class SP[0] with type arguments SP[-1].
191 //
192 // - StoreIndexedTOS
193 //
194 // 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.
196 //
197 // - StoreField rA, B, rC
198 //
199 // Store value FP[rC] into object FP[rA] at offset (in words) B.
200 //
201 // - StoreFieldTOS D
202 //
203 // Store value SP[0] into object SP[-1] at offset (in words) D.
204 //
205 // - LoadField rA, rB, C
206 //
207 // Load value at offset (in words) C from object FP[rB] into FP[rA].
208 //
209 // - LoadFieldTOS D
210 //
211 // Push value at offset (in words) D from object SP[0].
212 //
213 // - BooleanNegateTOS
214 //
215 // SP[0] = !SP[0]
216 //
217 // - Throw A
218 //
219 // Throw (Rethrow if A != 0) exception. Exception object and stack object
220 // are taken from TOS.
221 //
222 // - Entry A, B, rC
223 //
224 // Function prologue for the function with no optional or named arguments:
225 // A - expected number of positional arguments;
226 // B - number of local slots to reserve;
227 // rC - specifies context register to initialize with empty context.
228 //
229 // - EntryOpt A, B, C
230 //
231 // Function prologue for the function with optional or named arguments:
232 // A - expected number of positional arguments;
233 // B - number of optional arguments;
234 // C - number of named arguments;
235 //
236 // Only one of B and C can be not 0.
237 //
238 // If B is not 0 then EntryOpt bytecode is followed by B LoadConstant
239 // bytecodes specifying default values for optional arguments.
240 //
241 // If C is not 0 then EntryOpt is followed by 2 * B LoadConstant bytecodes.
242 // Bytecode at 2 * i specifies name of the i-th named argument and at
243 // 2 * i + 1 default value. rA part of the LoadConsant bytecode specifies
244 // the location of the parameter on the stack. Here named arguments are
245 // sorted alphabetically to enable linear matching similar to how function
246 // prologues are implemented on other architectures.
247 //
248 // Note: Unlike Entry bytecode EntryOpt does not setup the frame for
249 // local variables this is done by a separate bytecode Frame.
250 //
251 // - Frame D
252 //
253 // Reserve and initialize with null space for D local variables.
254 //
255 // - SetFrame A
256 //
257 // Reinitialize SP assuming that current frame has size A.
258 // Used to drop temporaries from the stack in the exception handler.
259 //
260 // - AllocateContext D
261 //
262 // Allocate Context object assuming for D context variables.
263 //
264 // - CloneContext
265 //
266 // Clone context stored in TOS.
267 //
268 // - MoveSpecial rA, D
269 //
270 // Copy special values from inside interpreter to FP[rA]. Currently only
271 // used to pass exception object (D = 0) and stack trace object (D = 1) to
272 // catch handler.
273 //
274 // - InstantiateType D
275 //
276 // Instantiate type PP[D] with instantiator type arguments SP[0].
277 //
278 // - InstantiateTypeArgumentsTOS D
279 //
280 // Instantiate type arguments PP[D] with instantiator SP[0].
281 //
282 // - AssertAssignable D
283 //
284 // Assert that SP[-3] is assignable to variable named SP[0] of type
285 // SP[-1] with type arguments SP[-2] using SubtypeTestCache PP[D].
286 //
287 // - AssertBoolean A
288 //
289 // Assert that TOS is a boolean (A = 1) or that TOS is not null (A = 0).
290 //
291 // - CheckStack
292 //
293 // Compare SP against isolate stack limit and call StackOverflow handler if
294 // necessary.
295 //
296 // - DebugStep, DebugBreak A
297 //
298 // Debugger support. DebugBreak is bytecode that can be patched into the
299 // instruction stream to trigger in place breakpoint.
300 //
301 // When patching instance or static call with DebugBreak we set A to
302 // match patched call's argument count so that Return instructions continue
303 // to work.
304 //
305 // TODO(vegorov) the way we replace calls with DebugBreak does not work
306 // with our smi fast paths because DebugBreak is simply skipped.
307 //
308 // BYTECODE LIST FORMAT
309 //
310 // Bytecode list below is specified using the following format:
311 //
312 // V(BytecodeName, OperandForm, Op1, Op2, Op3)
313 //
314 // - OperandForm specifies operand encoding and should be one of 0, A, T, A_D,
315 // A_X, X, D (see ENCODING section above).
316 //
317 // - Op1, Op2, Op2 specify operand meaning. Possible values:
318 //
319 // ___ ignored / non-existent operand
320 // num immediate operand
321 // lit constant literal from object pool
322 // reg register (unsigned FP relative local)
323 // xeg x-register (signed FP relative local)
324 //
325 #define BYTECODES_LIST(V) \
326 V(Trap, 0, ___, ___, ___) \
327 V(Compile, 0, ___, ___, ___) \
328 V(Intrinsic, A, num, ___, ___) \
329 V(Drop1, 0, ___, ___, ___) \
330 V(DropR, A, num, ___, ___) \
331 V(Drop, A, num, ___, ___) \
332 V(Jump, T, tgt, ___, ___) \
zra 2016/04/08 22:37:34 tgt is not in the key above.
Vyacheslav Egorov (Google) 2016/04/11 10:49:10 Done.
333 V(Return, A, num, ___, ___) \
334 V(ReturnTOS, 0, ___, ___, ___) \
335 V(Move, A_X, reg, xeg, ___) \
336 V(Push, X, xeg, ___, ___) \
337 V(LoadConstant, A_D, reg, lit, ___) \
338 V(PushConstant, D, lit, ___, ___) \
339 V(StoreLocal, X, xeg, ___, ___) \
340 V(PopLocal, X, xeg, ___, ___) \
341 V(StaticCall, A_D, num, num, ___) \
342 V(InstanceCall, A_D, num, num, ___) \
343 V(InstanceCall2, A_D, num, num, ___) \
344 V(InstanceCall3, A_D, num, num, ___) \
345 V(NativeCall, 0, ___, ___, ___) \
346 V(NativeBootstrapCall, 0, ___, ___, ___) \
347 V(AddTOS, 0, ___, ___, ___) \
348 V(SubTOS, 0, ___, ___, ___) \
349 V(MulTOS, 0, ___, ___, ___) \
350 V(BitOrTOS, 0, ___, ___, ___) \
351 V(BitAndTOS, 0, ___, ___, ___) \
352 V(EqualTOS, 0, ___, ___, ___) \
353 V(LessThanTOS, 0, ___, ___, ___) \
354 V(GreaterThanTOS, 0, ___, ___, ___) \
355 V(StoreStaticTOS, D, lit, ___, ___) \
356 V(PushStatic, D, lit, ___, ___) \
357 V(InitStaticTOS, 0, ___, ___, ___) \
358 V(IfNeStrictTOS, 0, ___, ___, ___) \
359 V(IfEqStrictTOS, 0, ___, ___, ___) \
360 V(IfNeStrictNumTOS, 0, ___, ___, ___) \
361 V(IfEqStrictNumTOS, 0, ___, ___, ___) \
362 V(CreateArrayTOS, 0, ___, ___, ___) \
363 V(Allocate, D, lit, ___, ___) \
364 V(AllocateT, 0, ___, ___, ___) \
365 V(StoreIndexedTOS, 0, ___, ___, ___) \
366 V(StoreField, A_B_C, reg, reg, reg) \
367 V(StoreFieldTOS, D, num, ___, ___) \
368 V(LoadField, A_B_C, reg, reg, reg) \
369 V(LoadFieldTOS, D, num, ___, ___) \
370 V(BooleanNegateTOS, 0, ___, ___, ___) \
371 V(Throw, A, num, ___, ___) \
372 V(Entry, A_B_C, num, num, num) \
373 V(EntryOpt, A_B_C, num, num, num) \
374 V(Frame, D, num, ___, ___) \
375 V(SetFrame, A, num, ___, num) \
376 V(AllocateContext, D, num, ___, ___) \
377 V(CloneContext, 0, ___, ___, ___) \
378 V(MoveSpecial, A_D, reg, num, ___) \
379 V(InstantiateType, D, lit, ___, ___) \
380 V(InstantiateTypeArgumentsTOS, A_D, num, lit, ___) \
381 V(AssertAssignable, D, num, lit, ___) \
382 V(AssertBoolean, A, num, ___, ___) \
383 V(CheckStack, 0, ___, ___, ___) \
384 V(DebugStep, 0, ___, ___, ___) \
385 V(DebugBreak, A, num, ___, ___) \
386
387 class Bytecode {
388 public:
389 enum Opcode {
390 #define DECLARE_BYTECODE(name, encoding, op1, op2, op3) k##name,
391 BYTECODES_LIST(DECLARE_BYTECODE)
392 #undef DECLARE_BYTECODE
393 };
394
395 static uint32_t Encode(Opcode op, uintptr_t a, uintptr_t b, uintptr_t c) {
396 ASSERT((a & 0xFF) == a);
397 ASSERT((b & 0xFF) == b);
398 ASSERT((c & 0xFF) == c);
399 return op | (a << 8) | (b << 16) | (c << 24);
400 }
401
402 static uint32_t Encode(Opcode op, uintptr_t a, uintptr_t d) {
403 ASSERT((a & 0x00FF) == a);
404 ASSERT((d & 0xFFFF) == d);
405 return op | (a << 8) | (d << 16);
406 }
407
408 static uint32_t Encode(Opcode op, uint32_t abc) {
409 return op | (abc << 8);
410 }
411
412 static uint32_t EncodeSigned(Opcode op, uintptr_t a, intptr_t x) {
413 ASSERT((a & 0x00FF) == a);
414 ASSERT((x << 16) >> 16 == x);
415 return op | (a << 8) | (x << 16);
416 }
417
418 static uint32_t EncodeSigned(Opcode op, intptr_t x) {
419 ASSERT((x << 8) >> 8 == x);
420 return op | (x << 8);
421 }
422
423 static uint32_t Encode(Opcode op) {
424 return op;
425 }
426
427 DART_FORCE_INLINE static Opcode DecodeOpcode(uint32_t bc) {
428 return static_cast<Opcode>(bc & 0xFF);
429 }
430
431 DART_FORCE_INLINE static uint8_t DecodeArgc(uint32_t call) {
432 #if defined(DEBUG)
433 const Opcode op = DecodeOpcode(call);
434 ASSERT(op == Bytecode::kStaticCall ||
zra 2016/04/08 22:37:34 parens around each 'a == b'
Vyacheslav Egorov (Google) 2016/04/11 10:49:10 Done.
435 op == Bytecode::kInstanceCall ||
436 op == Bytecode::kInstanceCall2 ||
437 op == Bytecode::kInstanceCall3 ||
438 op == Bytecode::kDebugBreak);
439 #endif
440 return (call >> 8) & 0xFF;
441 }
442 };
443
444 // Various dummy declarations to make shared code compile.
445 // TODO(vegorov) we need to prune away as much dead code as possible instead
446 // of just making it compile.
447 typedef int16_t Register;
448
449 const int16_t FPREG = 0;
450 const int16_t SPREG = 1;
451 const intptr_t kNumberOfCpuRegisters = 20;
452 const intptr_t kDartAvailableCpuRegs = 0;
453 const intptr_t kNoRegister = -1;
454 const intptr_t kReservedCpuRegisters = 0;
455 const intptr_t ARGS_DESC_REG = 0;
456 const intptr_t CODE_REG = 0;
457 const intptr_t kExceptionObjectReg = 0;
458 const intptr_t kStackTraceObjectReg = 0;
459 const intptr_t CTX = 0;
460
461 enum FpuRegister { kNoFpuRegister = -1, kFakeFpuRegister };
462 const FpuRegister FpuTMP = kFakeFpuRegister;
463 const intptr_t kNumberOfFpuRegisters = 1;
464
465 enum Condition { EQ, NE };
466
467 class Instr { };
468
469 } // namespace dart
470
471 #endif // VM_CONSTANTS_DBC_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698