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

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: 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
« no previous file with comments | « runtime/vm/code_patcher_dbc.cc ('k') | runtime/vm/cpu.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 current frame
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 signed 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 FP[rA] or push it onto the
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
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 LoadConstant 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 // tgt jump target relative to the PC of the current instruction
325 //
326 // TODO(vegorov) jump targets should be encoded relative to PC of the next
327 // instruction because PC is incremeted immediately after fetch
328 // and before decoding.
329 //
330 #define BYTECODES_LIST(V) \
331 V(Trap, 0, ___, ___, ___) \
332 V(Compile, 0, ___, ___, ___) \
333 V(Intrinsic, A, num, ___, ___) \
334 V(Drop1, 0, ___, ___, ___) \
335 V(DropR, A, num, ___, ___) \
336 V(Drop, A, num, ___, ___) \
337 V(Jump, T, tgt, ___, ___) \
338 V(Return, A, num, ___, ___) \
339 V(ReturnTOS, 0, ___, ___, ___) \
340 V(Move, A_X, reg, xeg, ___) \
341 V(Push, X, xeg, ___, ___) \
342 V(LoadConstant, A_D, reg, lit, ___) \
343 V(PushConstant, D, lit, ___, ___) \
344 V(StoreLocal, X, xeg, ___, ___) \
345 V(PopLocal, X, xeg, ___, ___) \
346 V(StaticCall, A_D, num, num, ___) \
347 V(InstanceCall, A_D, num, num, ___) \
348 V(InstanceCall2, A_D, num, num, ___) \
349 V(InstanceCall3, A_D, num, num, ___) \
350 V(NativeCall, 0, ___, ___, ___) \
351 V(NativeBootstrapCall, 0, ___, ___, ___) \
352 V(AddTOS, 0, ___, ___, ___) \
353 V(SubTOS, 0, ___, ___, ___) \
354 V(MulTOS, 0, ___, ___, ___) \
355 V(BitOrTOS, 0, ___, ___, ___) \
356 V(BitAndTOS, 0, ___, ___, ___) \
357 V(EqualTOS, 0, ___, ___, ___) \
358 V(LessThanTOS, 0, ___, ___, ___) \
359 V(GreaterThanTOS, 0, ___, ___, ___) \
360 V(StoreStaticTOS, D, lit, ___, ___) \
361 V(PushStatic, D, lit, ___, ___) \
362 V(InitStaticTOS, 0, ___, ___, ___) \
363 V(IfNeStrictTOS, 0, ___, ___, ___) \
364 V(IfEqStrictTOS, 0, ___, ___, ___) \
365 V(IfNeStrictNumTOS, 0, ___, ___, ___) \
366 V(IfEqStrictNumTOS, 0, ___, ___, ___) \
367 V(CreateArrayTOS, 0, ___, ___, ___) \
368 V(Allocate, D, lit, ___, ___) \
369 V(AllocateT, 0, ___, ___, ___) \
370 V(StoreIndexedTOS, 0, ___, ___, ___) \
371 V(StoreField, A_B_C, reg, reg, reg) \
372 V(StoreFieldTOS, D, num, ___, ___) \
373 V(LoadField, A_B_C, reg, reg, reg) \
374 V(LoadFieldTOS, D, num, ___, ___) \
375 V(BooleanNegateTOS, 0, ___, ___, ___) \
376 V(Throw, A, num, ___, ___) \
377 V(Entry, A_B_C, num, num, num) \
378 V(EntryOpt, A_B_C, num, num, num) \
379 V(Frame, D, num, ___, ___) \
380 V(SetFrame, A, num, ___, num) \
381 V(AllocateContext, D, num, ___, ___) \
382 V(CloneContext, 0, ___, ___, ___) \
383 V(MoveSpecial, A_D, reg, num, ___) \
384 V(InstantiateType, D, lit, ___, ___) \
385 V(InstantiateTypeArgumentsTOS, A_D, num, lit, ___) \
386 V(AssertAssignable, D, num, lit, ___) \
387 V(AssertBoolean, A, num, ___, ___) \
388 V(CheckStack, 0, ___, ___, ___) \
389 V(DebugStep, 0, ___, ___, ___) \
390 V(DebugBreak, A, num, ___, ___) \
391
392 typedef uint32_t Instr;
393
394 class Bytecode {
395 public:
396 enum Opcode {
397 #define DECLARE_BYTECODE(name, encoding, op1, op2, op3) k##name,
398 BYTECODES_LIST(DECLARE_BYTECODE)
399 #undef DECLARE_BYTECODE
400 };
401
402 static const intptr_t kOpShift = 0;
403 static const intptr_t kAShift = 8;
404 static const intptr_t kAMask = 0xFF;
405 static const intptr_t kBShift = 16;
406 static const intptr_t kBMask = 0xFF;
407 static const intptr_t kCShift = 24;
408 static const intptr_t kCMask = 0xFF;
409 static const intptr_t kDShift = 16;
410 static const intptr_t kDMask = 0xFFFF;
411
412 static Instr Encode(Opcode op, uintptr_t a, uintptr_t b, uintptr_t c) {
413 ASSERT((a & kAMask) == a);
414 ASSERT((b & kBMask) == b);
415 ASSERT((c & kCMask) == c);
416 return op | (a << kAShift) | (b << kBShift) | (c << kCShift);
417 }
418
419 static Instr Encode(Opcode op, uintptr_t a, uintptr_t d) {
420 ASSERT((a & kAMask) == a);
421 ASSERT((d & kDMask) == d);
422 return op | (a << kAShift) | (d << kDShift);
423 }
424
425 static Instr EncodeSigned(Opcode op, uintptr_t a, intptr_t x) {
426 ASSERT((a & kAMask) == a);
427 ASSERT((x << kDShift) >> kDShift == x);
428 return op | (a << kAShift) | (x << kDShift);
429 }
430
431 static Instr EncodeSigned(Opcode op, intptr_t x) {
432 ASSERT((x << kAShift) >> kAShift == x);
433 return op | (x << kAShift);
434 }
435
436 static Instr Encode(Opcode op) {
437 return op;
438 }
439
440 DART_FORCE_INLINE static uint8_t DecodeA(Instr bc) {
441 return (bc >> kAShift) & kAMask;
442 }
443
444 DART_FORCE_INLINE static uint16_t DecodeD(Instr bc) {
445 return (bc >> kDShift) & kDMask;
446 }
447
448 DART_FORCE_INLINE static Opcode DecodeOpcode(Instr bc) {
449 return static_cast<Opcode>(bc & 0xFF);
450 }
451
452 DART_FORCE_INLINE static uint8_t DecodeArgc(Instr call) {
453 #if defined(DEBUG)
454 const Opcode op = DecodeOpcode(call);
455 ASSERT((op == Bytecode::kStaticCall) ||
456 (op == Bytecode::kInstanceCall) ||
457 (op == Bytecode::kInstanceCall2) ||
458 (op == Bytecode::kInstanceCall3) ||
459 (op == Bytecode::kDebugBreak));
460 #endif
461 return (call >> 8) & 0xFF;
462 }
463 };
464
465 // Various dummy declarations to make shared code compile.
466 // TODO(vegorov) we need to prune away as much dead code as possible instead
467 // of just making it compile.
468 typedef int16_t Register;
469
470 const int16_t FPREG = 0;
471 const int16_t SPREG = 1;
472 const intptr_t kNumberOfCpuRegisters = 20;
473 const intptr_t kDartAvailableCpuRegs = 0;
474 const intptr_t kNoRegister = -1;
475 const intptr_t kReservedCpuRegisters = 0;
476 const intptr_t ARGS_DESC_REG = 0;
477 const intptr_t CODE_REG = 0;
478 const intptr_t kExceptionObjectReg = 0;
479 const intptr_t kStackTraceObjectReg = 0;
480 const intptr_t CTX = 0;
481
482 enum FpuRegister { kNoFpuRegister = -1, kFakeFpuRegister };
483 const FpuRegister FpuTMP = kFakeFpuRegister;
484 const intptr_t kNumberOfFpuRegisters = 1;
485
486 enum Condition { EQ, NE };
487
488 } // namespace dart
489
490 #endif // VM_CONSTANTS_DBC_H_
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher_dbc.cc ('k') | runtime/vm/cpu.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698