Skip to content

Commit 9532380

Browse files
committed
Byte code related symbolic constants and macros in vm.h get better names
and comments. Space consumed by opcode triplets are reduced to 16 bits down from 32 bits. This reduces the opcode triplet tables by 220 bytes. New symbolic constants and defines were also added to describe common operations. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
1 parent 00f759e commit 9532380

File tree

2 files changed

+140
-60
lines changed

2 files changed

+140
-60
lines changed

jerry-core/vm/vm.c

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,15 @@ vm_init (ecma_compiled_code_t *program_p) /**< pointer to byte-code data */
153153
/**
154154
* Decode table for opcodes.
155155
*/
156-
static const uint32_t vm_decode_table[] =
156+
static const uint16_t vm_decode_table[] =
157157
{
158158
CBC_OPCODE_LIST
159159
};
160160

161161
/**
162162
* Decode table for extended opcodes.
163163
*/
164-
static const uint32_t vm_ext_decode_table[] =
164+
static const uint16_t vm_ext_decode_table[] =
165165
{
166166
CBC_EXT_OPCODE_LIST
167167
};
@@ -801,11 +801,11 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
801801
}
802802

803803
free_flags = 0;
804-
if (opcode_data & (VM_OC_GET_DATA_MASK << VM_OC_GET_DATA_SHIFT))
804+
if (VM_OC_HAS_GET_ARGS (opcode_data))
805805
{
806-
uint32_t operands = VM_OC_GET_DATA_GET_ID (opcode_data);
806+
uint32_t operands = VM_OC_GET_ARGS_GET_INDEX (opcode_data);
807807

808-
if (operands >= VM_OC_GET_DATA_GET_ID (VM_OC_GET_LITERAL))
808+
if (operands >= VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_LITERAL))
809809
{
810810
uint16_t literal_index;
811811
READ_LITERAL_INDEX (literal_index);
@@ -815,20 +815,20 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
815815

816816
switch (operands)
817817
{
818-
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_STACK_LITERAL):
818+
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_STACK_LITERAL):
819819
{
820820
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
821821
right_value = left_value;
822822
left_value = *(--stack_top_p);
823823
free_flags = (uint8_t) ((free_flags << 1) | VM_FREE_LEFT_VALUE);
824824
break;
825825
}
826-
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_LITERAL_BYTE):
826+
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_LITERAL_BYTE):
827827
{
828828
right_value = *(byte_code_p++);
829829
break;
830830
}
831-
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_LITERAL_LITERAL):
831+
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_LITERAL_LITERAL):
832832
{
833833
uint16_t literal_index;
834834
READ_LITERAL_INDEX (literal_index);
@@ -837,7 +837,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
837837
free_flags |= VM_FREE_RIGHT_VALUE);
838838
break;
839839
}
840-
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_THIS_LITERAL):
840+
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_THIS_LITERAL):
841841
{
842842
right_value = left_value;
843843
left_value = ecma_copy_value (frame_ctx_p->this_binding);
@@ -846,7 +846,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
846846
}
847847
default:
848848
{
849-
JERRY_ASSERT (operands == VM_OC_GET_DATA_GET_ID (VM_OC_GET_LITERAL));
849+
JERRY_ASSERT (operands == VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_LITERAL));
850850
break;
851851
}
852852
}
@@ -855,22 +855,22 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
855855
{
856856
switch (operands)
857857
{
858-
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_STACK):
858+
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_STACK):
859859
{
860860
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
861861
left_value = *(--stack_top_p);
862862
free_flags = VM_FREE_LEFT_VALUE;
863863
break;
864864
}
865-
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_STACK_STACK):
865+
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_STACK_STACK):
866866
{
867867
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end + 1);
868868
right_value = *(--stack_top_p);
869869
left_value = *(--stack_top_p);
870870
free_flags = VM_FREE_LEFT_VALUE | VM_FREE_RIGHT_VALUE;
871871
break;
872872
}
873-
case VM_OC_GET_DATA_GET_ID (VM_OC_GET_BYTE):
873+
case VM_OC_GET_ARGS_GET_INDEX (VM_OC_GET_BYTE):
874874
{
875875
right_value = *(byte_code_p++);
876876
break;
@@ -1227,7 +1227,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
12271227
case VM_OC_POST_INCR:
12281228
case VM_OC_POST_DECR:
12291229
{
1230-
uint32_t base = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_PROP_PRE_INCR;
1230+
uint32_t opcode_flags = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_PROP_PRE_INCR;
12311231

12321232
last_completion_value = ecma_op_to_number (left_value);
12331233

@@ -1244,9 +1244,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
12441244
ecma_integer_value_t int_value = (ecma_integer_value_t) result;
12451245
ecma_integer_value_t int_increase;
12461246

1247-
if (base & 0x2)
1247+
if (opcode_flags & VM_OC_DECREMENT_OPERATOR_FLAG)
12481248
{
1249-
/* For decrement operators */
12501249
if (int_value <= (ECMA_INTEGER_NUMBER_MIN << ECMA_DIRECT_SHIFT))
12511250
{
12521251
int_increase = 0;
@@ -1270,12 +1269,12 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
12701269

12711270
if (int_increase != 0)
12721271
{
1273-
/* Post operators require the unmodifed number value. */
1274-
if (base & 0x4)
1272+
/* Postfix operators require the unmodifed number value. */
1273+
if (opcode_flags & VM_OC_POST_INCR_DECR_OPERATOR_FLAG)
12751274
{
12761275
if (opcode_data & VM_OC_PUT_STACK)
12771276
{
1278-
if (base & 0x1)
1277+
if (opcode_flags & VM_OC_IDENT_INCR_DECR_OPERATOR_FLAG)
12791278
{
12801279
JERRY_ASSERT (opcode == CBC_POST_INCR_IDENT_PUSH_RESULT
12811280
|| opcode == CBC_POST_DECR_IDENT_PUSH_RESULT);
@@ -1313,18 +1312,18 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
13131312
ecma_number_t increase = ECMA_NUMBER_ONE;
13141313
ecma_number_t result_number = ecma_get_number_from_value (result);
13151314

1316-
if (base & 0x2)
1315+
if (opcode_flags & VM_OC_DECREMENT_OPERATOR_FLAG)
13171316
{
13181317
/* For decrement operators */
13191318
increase = ECMA_NUMBER_MINUS_ONE;
13201319
}
13211320

13221321
/* Post operators require the unmodifed number value. */
1323-
if (base & 0x4)
1322+
if (opcode_flags & VM_OC_POST_INCR_DECR_OPERATOR_FLAG)
13241323
{
13251324
if (opcode_data & VM_OC_PUT_STACK)
13261325
{
1327-
if (base & 0x1)
1326+
if (opcode_flags & VM_OC_IDENT_INCR_DECR_OPERATOR_FLAG)
13281327
{
13291328
JERRY_ASSERT (opcode == CBC_POST_INCR_IDENT_PUSH_RESULT
13301329
|| opcode == CBC_POST_DECR_IDENT_PUSH_RESULT);
@@ -1433,7 +1432,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
14331432
goto error;
14341433
}
14351434

1436-
if (opcode_data & (VM_OC_PUT_DATA_MASK << VM_OC_PUT_DATA_SHIFT))
1435+
if (VM_OC_HAS_PUT_RESULT (opcode_data))
14371436
{
14381437
result = last_completion_value;
14391438
}
@@ -1465,7 +1464,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
14651464
goto error;
14661465
}
14671466

1468-
JERRY_ASSERT (opcode_data & (VM_OC_PUT_DATA_MASK << VM_OC_PUT_DATA_SHIFT));
1467+
JERRY_ASSERT (VM_OC_HAS_PUT_RESULT (opcode_data));
14691468
result = last_completion_value;
14701469
break;
14711470
}
@@ -1536,7 +1535,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
15361535
case VM_OC_BRANCH_IF_LOGICAL_TRUE:
15371536
case VM_OC_BRANCH_IF_LOGICAL_FALSE:
15381537
{
1539-
uint32_t base = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_BRANCH_IF_TRUE;
1538+
uint32_t opcode_flags = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_BRANCH_IF_TRUE;
15401539

15411540
last_completion_value = ecma_op_to_boolean (left_value);
15421541

@@ -1546,11 +1545,14 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
15461545
}
15471546

15481547
JERRY_ASSERT (free_flags & VM_FREE_LEFT_VALUE);
1549-
if (last_completion_value == ecma_make_simple_value ((base & 0x1) ? ECMA_SIMPLE_VALUE_FALSE
1550-
: ECMA_SIMPLE_VALUE_TRUE))
1548+
1549+
bool branch_if_false = (opcode_flags & VM_OC_BRANCH_IF_FALSE_FLAG);
1550+
1551+
if (last_completion_value == ecma_make_simple_value (branch_if_false ? ECMA_SIMPLE_VALUE_FALSE
1552+
: ECMA_SIMPLE_VALUE_TRUE))
15511553
{
15521554
byte_code_p = byte_code_start_p + branch_offset;
1553-
if (base & 0x2)
1555+
if (opcode_flags & VM_OC_LOGICAL_BRANCH_FLAG)
15541556
{
15551557
free_flags = 0;
15561558
++stack_top_p;
@@ -2170,7 +2172,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
21702172
}
21712173
}
21722174

2173-
if (opcode_data & (VM_OC_PUT_DATA_MASK << VM_OC_PUT_DATA_SHIFT))
2175+
if (VM_OC_HAS_PUT_RESULT (opcode_data))
21742176
{
21752177
if (opcode_data & VM_OC_PUT_IDENT)
21762178
{

jerry-core/vm/vm.h

Lines changed: 109 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,33 +29,71 @@
2929
* @{
3030
*/
3131

32-
#define VM_OC_GET_DATA_SHIFT 24
33-
#define VM_OC_GET_DATA_MASK 0x1f
34-
#define VM_OC_GET_DATA_CREATE_ID(V) \
35-
(((V) & VM_OC_GET_DATA_MASK) << VM_OC_GET_DATA_SHIFT)
36-
#define VM_OC_GET_DATA_GET_ID(O) \
37-
(((O) >> VM_OC_GET_DATA_SHIFT) & VM_OC_GET_DATA_MASK)
32+
/**
33+
* Each CBC opcode is transformed to three vm opcodes:
34+
*
35+
* - first opcode is a "get arguments" opcode which specifies
36+
* the type (register, literal, stack, etc.) and number
37+
* (from 0 to 2) of input arguments
38+
* - second opcode is a "group" opcode which specifies
39+
* the actual operation (add, increment, call, etc.)
40+
* - third opcode is a "put result" opcode which specifies
41+
* the destination where the result is stored (register,
42+
* stack, etc.)
43+
*/
44+
45+
/**
46+
* Position of "get arguments" opcode.
47+
*/
48+
#define VM_OC_GET_ARGS_SHIFT 7
49+
50+
/**
51+
* Mask of "get arguments" opcode.
52+
*/
53+
#define VM_OC_GET_ARGS_MASK 0x1f
54+
55+
/**
56+
* Generate the binary representation of a "get arguments" opcode.
57+
*/
58+
#define VM_OC_GET_ARGS_CREATE_INDEX(V) (((V) & VM_OC_GET_ARGS_MASK) << VM_OC_GET_ARGS_SHIFT)
59+
60+
/**
61+
* Extract the "get arguments" opcode.
62+
*/
63+
#define VM_OC_GET_ARGS_GET_INDEX(O) (((O) >> VM_OC_GET_ARGS_SHIFT) & VM_OC_GET_ARGS_MASK)
64+
65+
/**
66+
* Checks whether the result is stored somewhere.
67+
*/
68+
#define VM_OC_HAS_GET_ARGS(V) ((V) & (VM_OC_GET_ARGS_MASK << VM_OC_GET_ARGS_SHIFT))
3869

3970
/**
4071
* Argument getters that are part of the opcodes.
4172
*/
4273
typedef enum
4374
{
44-
VM_OC_GET_NONE = VM_OC_GET_DATA_CREATE_ID (0), /**< do nothing */
45-
VM_OC_GET_STACK = VM_OC_GET_DATA_CREATE_ID (1), /**< pop one elemnet from the stack */
46-
VM_OC_GET_STACK_STACK = VM_OC_GET_DATA_CREATE_ID (2), /**< pop two elemnets from the stack */
47-
VM_OC_GET_BYTE = VM_OC_GET_DATA_CREATE_ID (3), /**< read a byte */
48-
49-
VM_OC_GET_LITERAL = VM_OC_GET_DATA_CREATE_ID (4), /**< resolve literal */
50-
VM_OC_GET_STACK_LITERAL = VM_OC_GET_DATA_CREATE_ID (5), /**< pop one elemnet from the stack and resolve a literal*/
51-
VM_OC_GET_LITERAL_BYTE = VM_OC_GET_DATA_CREATE_ID (6), /**< pop one elemnet from stack and read a byte */
52-
VM_OC_GET_LITERAL_LITERAL = VM_OC_GET_DATA_CREATE_ID (7), /**< resolve two literals */
53-
VM_OC_GET_THIS_LITERAL = VM_OC_GET_DATA_CREATE_ID (8), /**< get this and resolve a literal */
75+
VM_OC_GET_NONE = VM_OC_GET_ARGS_CREATE_INDEX (0), /**< do nothing */
76+
VM_OC_GET_STACK = VM_OC_GET_ARGS_CREATE_INDEX (1), /**< pop one elemnet from the stack */
77+
VM_OC_GET_STACK_STACK = VM_OC_GET_ARGS_CREATE_INDEX (2), /**< pop two elemnets from the stack */
78+
VM_OC_GET_BYTE = VM_OC_GET_ARGS_CREATE_INDEX (3), /**< read a byte */
79+
80+
VM_OC_GET_LITERAL = VM_OC_GET_ARGS_CREATE_INDEX (4), /**< resolve literal */
81+
VM_OC_GET_STACK_LITERAL = VM_OC_GET_ARGS_CREATE_INDEX (5), /**< pop one elemnet from the stack
82+
* and resolve a literal */
83+
VM_OC_GET_LITERAL_BYTE = VM_OC_GET_ARGS_CREATE_INDEX (6), /**< pop one elemnet from stack and read a byte */
84+
VM_OC_GET_LITERAL_LITERAL = VM_OC_GET_ARGS_CREATE_INDEX (7), /**< resolve two literals */
85+
VM_OC_GET_THIS_LITERAL = VM_OC_GET_ARGS_CREATE_INDEX (8), /**< get this and resolve a literal */
5486
} vm_oc_get_types;
5587

56-
#define VM_OC_GROUP_MASK 0xff
57-
#define VM_OC_GROUP_GET_INDEX(O) \
58-
((O) & VM_OC_GROUP_MASK)
88+
/**
89+
* Mask of "group" opcode.
90+
*/
91+
#define VM_OC_GROUP_MASK 0x7f
92+
93+
/**
94+
* Extract the "group" opcode.
95+
*/
96+
#define VM_OC_GROUP_GET_INDEX(O) ((O) & VM_OC_GROUP_MASK)
5997

6098
/**
6199
* Opcodes.
@@ -88,12 +126,12 @@ typedef enum
88126

89127
/* These eight opcodes must be in this order. */
90128
VM_OC_PROP_PRE_INCR, /**< prefix increment of a property */
91-
VM_OC_PRE_INCR, /**< prefix increment */
92129
VM_OC_PROP_PRE_DECR, /**< prop prefix decrement of a property */
93-
VM_OC_PRE_DECR, /**< prefix decrement */
94130
VM_OC_PROP_POST_INCR, /**< prop postfix increment of a property */
95-
VM_OC_POST_INCR, /**< postfix increment */
96131
VM_OC_PROP_POST_DECR, /**< prop postfix decrement of a property */
132+
VM_OC_PRE_INCR, /**< prefix increment */
133+
VM_OC_PRE_DECR, /**< prefix decrement */
134+
VM_OC_POST_INCR, /**< postfix increment */
97135
VM_OC_POST_DECR, /**< postfix decrement */
98136

99137
VM_OC_PROP_DELETE, /**< delete property */
@@ -163,20 +201,60 @@ typedef enum
163201
VM_OC_JUMP_AND_EXIT_CONTEXT, /**< jump and exit context */
164202
} vm_oc_types;
165203

166-
#define VM_OC_PUT_DATA_SHIFT 12
167-
#define VM_OC_PUT_DATA_MASK 0xf
168-
#define VM_OC_PUT_DATA_CREATE_FLAG(V) \
169-
(((V) & VM_OC_PUT_DATA_MASK) << VM_OC_PUT_DATA_SHIFT)
204+
/**
205+
* Decrement operator.
206+
*/
207+
#define VM_OC_DECREMENT_OPERATOR_FLAG 0x1
208+
209+
/**
210+
* Postfix increment/decrement operator.
211+
*/
212+
#define VM_OC_POST_INCR_DECR_OPERATOR_FLAG 0x2
213+
214+
/**
215+
* An named variable is updated by the increment/decrement operator.
216+
*/
217+
#define VM_OC_IDENT_INCR_DECR_OPERATOR_FLAG 0x4
218+
219+
/**
220+
* Jump to target offset if input value is logical false.
221+
*/
222+
#define VM_OC_BRANCH_IF_FALSE_FLAG 0x1
223+
224+
/**
225+
* Branch optimized for logical and/or opcodes.
226+
*/
227+
#define VM_OC_LOGICAL_BRANCH_FLAG 0x2
228+
229+
/**
230+
* Position of "put result" opcode.
231+
*/
232+
#define VM_OC_PUT_RESULT_SHIFT 12
233+
234+
/**
235+
* Mask of "put result" opcode.
236+
*/
237+
#define VM_OC_PUT_RESULT_MASK 0xf
238+
239+
/**
240+
* Generate a "put result" opcode flag bit.
241+
*/
242+
#define VM_OC_PUT_RESULT_CREATE_FLAG(V) (((V) & VM_OC_PUT_RESULT_MASK) << VM_OC_PUT_RESULT_SHIFT)
243+
244+
/**
245+
* Checks whether the result is stored somewhere.
246+
*/
247+
#define VM_OC_HAS_PUT_RESULT(V) ((V) & (VM_OC_PUT_RESULT_MASK << VM_OC_PUT_RESULT_SHIFT))
170248

171249
/**
172-
* Result writers that are part of the opcodes.
250+
* Specify where the result is stored
173251
*/
174252
typedef enum
175253
{
176-
VM_OC_PUT_IDENT = VM_OC_PUT_DATA_CREATE_FLAG (0x1),
177-
VM_OC_PUT_REFERENCE = VM_OC_PUT_DATA_CREATE_FLAG (0x2),
178-
VM_OC_PUT_STACK = VM_OC_PUT_DATA_CREATE_FLAG (0x4),
179-
VM_OC_PUT_BLOCK = VM_OC_PUT_DATA_CREATE_FLAG (0x8),
254+
VM_OC_PUT_IDENT = VM_OC_PUT_RESULT_CREATE_FLAG (0x1),
255+
VM_OC_PUT_REFERENCE = VM_OC_PUT_RESULT_CREATE_FLAG (0x2),
256+
VM_OC_PUT_STACK = VM_OC_PUT_RESULT_CREATE_FLAG (0x4),
257+
VM_OC_PUT_BLOCK = VM_OC_PUT_RESULT_CREATE_FLAG (0x8),
180258
} vm_oc_put_types;
181259

182260
/**

0 commit comments

Comments
 (0)