Add opcodes for increment and decrement; add optimizer

This commit is contained in:
Ilmir Usmanov 2014-07-24 19:27:58 +04:00
parent c837c7d435
commit 3b0fef6e04
11 changed files with 170 additions and 32 deletions

View File

@ -162,7 +162,8 @@ SOURCES_JERRY = \
$(wildcard ./src/libecmaobjects/*.c) \
$(wildcard ./src/libecmaoperations/*.c) \
$(wildcard ./src/liballocator/*.c) \
$(wildcard ./src/libcoreint/*.c) ) \
$(wildcard ./src/libcoreint/*.c) \
$(wildcard ./src/liboptimizer/*.c) ) \
$(wildcard src/libruntime/target/$(TARGET_SYSTEM)/*.c)
INCLUDES_JERRY = \
@ -173,6 +174,7 @@ INCLUDES_JERRY = \
-I src/libecmaobjects \
-I src/libecmaoperations \
-I src/liballocator \
-I src/liboptimizer \
-I src/libcoreint
ifeq ($(OPTION_NDEBUG),enable)

View File

@ -256,6 +256,26 @@ OP_CODE_DECL (in, T_IDX_IDX_IDX,
var_left,
var_right)
/** dst = var_right++. */
OP_CODE_DECL (post_incr, T_IDX_IDX,
dst,
var_right)
/** dst = var_right--. */
OP_CODE_DECL (post_decr, T_IDX_IDX,
dst,
var_right)
/** dst = ++var_right. */
OP_CODE_DECL (pre_incr, T_IDX_IDX,
dst,
var_right)
/** dst = --var_right. */
OP_CODE_DECL (pre_decr, T_IDX_IDX,
dst,
var_right)
// Assignment operators.
// Assign value to LEFT operand based on value of RIGHT operand.

View File

@ -372,6 +372,10 @@ do_number_arithmetic(struct __int_data *int_data, /**< interpreter context */
op(b_not) \
op(instanceof) \
op(in) \
op(post_incr) \
op(post_decr) \
op(pre_incr) \
op(pre_decr) \
op(reg_var_decl)
#define DEFINE_UNIMPLEMENTED_OP(op) \
@ -879,6 +883,10 @@ GETOP_IMPL_1 (jmp, opcode_idx)
GETOP_IMPL_1 (jmp_up, opcode_count)
GETOP_IMPL_1 (jmp_down, opcode_count)
GETOP_IMPL_3 (addition, dst, var_left, var_right)
GETOP_IMPL_2 (post_incr, dst, var_right)
GETOP_IMPL_2 (post_decr, dst, var_right)
GETOP_IMPL_2 (pre_incr, dst, var_right)
GETOP_IMPL_2 (pre_decr, dst, var_right)
GETOP_IMPL_3 (substraction, dst, var_left, var_right)
GETOP_IMPL_3 (division, dst, var_left, var_right)
GETOP_IMPL_3 (multiplication, dst, var_left, var_right)

View File

@ -110,6 +110,10 @@ typedef ecma_completion_value_t (*opfunc)(OPCODE, struct __int_data *);
op(in)
#define OP_ARITHMETIC(op) \
op(post_incr) \
op(post_decr) \
op(pre_incr) \
op(pre_decr) \
op(addition) \
op(substraction) \
op(division) \

View File

@ -23,9 +23,8 @@
#define INVALID_VALUE 255
static token tok;
static OPCODE opcode, opcodes_buffer[MAX_OPCODES];
static uint8_t current_opcode_in_buffer = 0;
static uint8_t opcode_counter = 0;
static OPCODE opcode;
static T_IDX opcode_counter = 0;
static T_IDX temp_name_stack[MAX_OPCODES], temp_name_stack_head = 0, max_temp_name;
#ifdef __HOST
@ -172,23 +171,6 @@ integer_one (void)
return lhs;
}
static void
save_opcode (void)
{
JERRY_ASSERT (current_opcode_in_buffer < MAX_OPCODES);
opcodes_buffer[current_opcode_in_buffer++] = opcode;
}
static void
dump_saved_opcodes (void)
{
uint8_t i;
for (i = 0; i < current_opcode_in_buffer; i++)
serializer_dump_opcode (&opcodes_buffer[i]);
current_opcode_in_buffer = 0;
}
/* property_name
: Identifier
| StringLiteral
@ -859,18 +841,18 @@ parse_left_hand_side_expression (void)
static T_IDX
parse_postfix_expression (void)
{
T_IDX expr = parse_left_hand_side_expression ();
T_IDX expr = parse_left_hand_side_expression (), lhs;
tok = lexer_next_token ();
if (tok.type == TOK_DOUBLE_PLUS)
{
opcode = getop_addition (expr, expr, integer_one ());
save_opcode ();
lhs = next_temp_name ();
DUMP_OPCODE (post_incr, lhs, expr);
}
else if (tok.type == TOK_DOUBLE_MINUS)
{
opcode = getop_substraction (expr, expr, integer_one ());
save_opcode ();
lhs = next_temp_name ();
DUMP_OPCODE (post_decr, lhs, expr);
}
else
lexer_save_token (tok);
@ -890,13 +872,15 @@ parse_unary_expression (void)
switch (tok.type)
{
case TOK_DOUBLE_PLUS:
lhs = next_temp_name ();
NEXT (expr, unary_expression);
DUMP_OPCODE (addition, expr, expr, integer_one ());
DUMP_OPCODE (pre_incr, lhs, expr);
return expr;
case TOK_DOUBLE_MINUS:
lhs = next_temp_name ();
NEXT (expr, unary_expression);
DUMP_OPCODE (substraction, expr, expr, integer_one ());
DUMP_OPCODE (pre_decr, lhs, expr);
return expr;
case TOK_PLUS:
@ -1198,7 +1182,7 @@ parse_assignment_expression (void)
lhs = parse_conditional_expression (&was_conditional);
if (was_conditional)
{
goto end;
return lhs;
}
skip_newlines ();
@ -1268,8 +1252,6 @@ parse_assignment_expression (void)
lexer_save_token (tok);
}
end:
dump_saved_opcodes ();
return lhs;
}

View File

@ -0,0 +1,57 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "optimizer-passes.h"
#include "opcodes.h"
#include "deserializer.h"
#define NAME_TO_ID(op) (__op__idx_##op)
/* Reorder bytecode like
call_n ...
assignment ... +
var_?_end
to
assignment ... +
call_n ...
var_?_end
*/
static void
optimize_calls (OPCODE *opcodes)
{
OPCODE *current_opcode;
for (current_opcode = opcodes;
current_opcode->op_idx != NAME_TO_ID (exitval);
current_opcode++)
{
if (current_opcode->op_idx == NAME_TO_ID (call_n)
&& (current_opcode + 1)->op_idx == NAME_TO_ID (assignment))
{
OPCODE temp = *current_opcode;
*current_opcode = *(current_opcode + 1);
*(current_opcode + 1) = temp;
}
}
}
void
optimizer_run_passes (OPCODE* opcodes)
{
optimize_calls (opcodes);
}

View File

@ -0,0 +1,24 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OPTIMIZER_PASSES_H
#define OPTIMIZER_PASSES_H
#include "globals.h"
#include "opcodes.h"
void optimizer_run_passes (OPCODE *);
#endif // OPTIMIZER_PASSES_H

View File

@ -28,4 +28,6 @@ void serializer_dump_opcode (const void *);
void serializer_rewrite_opcode (const uint8_t, const void *);
void serializer_print_opcodes (void);
#endif // SERIALIZER_H

View File

@ -146,3 +146,27 @@ serializer_rewrite_opcode (const uint8_t loc, const void *opcode)
__printf ("// REWRITE\n");
}
void
serializer_print_opcodes (void)
{
int loc = -1, i;
OPCODE* opcode;
int opcode_num;
__printf ("AFTER OPTIMIZER:\n");
do
{
loc++;
opcode = bytecode_opcodes + loc;
opcode_num = (int)((char*)opcode)[0];
__printf ("%03d: %20s ", loc, opcode_names[opcode_num]);
for (i = 1; i < opcode_sizes[opcode_num]; i++)
__printf ("%4d ", ((char*)opcode)[i]);
__printf ("\n");
}
while (opcode->op_idx != __op__idx_exitval);
}

View File

@ -46,5 +46,10 @@ serializer_rewrite_opcode (const uint8_t offset, const void *opcode)
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( offset, opcode);
}
void
serializer_print_opcodes (void)
{
JERRY_UNREACHABLE ();
}
TODO (Dump memory)

View File

@ -37,6 +37,7 @@
#include "parser.h"
#include "serializer.h"
#include "deserializer.h"
#include "optimizer-passes.h"
#define MAX_STRINGS 100
#define MAX_NUMS 25
@ -49,6 +50,7 @@ jerry_run( const char *script_source,
int nums[MAX_NUMS];
uint8_t strings_num, nums_count;
uint8_t offset;
const OPCODE *opcodes;
mem_init();
@ -68,7 +70,15 @@ jerry_run( const char *script_source,
parser_init ();
parser_parse_program ();
init_int (deserialize_bytecode ());
opcodes = deserialize_bytecode ();
optimizer_run_passes ((OPCODE *) opcodes);
#ifdef __HOST
serializer_print_opcodes ();
#endif
init_int (opcodes);
run_int ();
} /* jerry_run */