Introducing 'opcode counter' type for 'meta' opcode; replacing 'jmp_down' opcodes that are used as pointers only with 'meta' opcodes of the introduced type.

This commit is contained in:
Ruben Ayrapetyan
2014-08-28 15:17:49 +04:00
parent 5d2b535cec
commit 9d45f68370
6 changed files with 81 additions and 31 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ typedef signed long ssize_t;
/**
* Constants
*/
#define JERRY_BITSINBYTE 8
#define JERRY_BITSINBYTE 8u
/**
* Error codes
+41 -12
View File
@@ -467,18 +467,15 @@ function_declaration (int_data_t *int_data, /**< interpreter context */
const bool is_strict = int_data->is_strict;
const bool is_configurable_bindings = int_data->is_eval_code;
const opcode_counter_t jmp_down_opcode_idx = (opcode_counter_t) (int_data->pos);
opcode_t jmp_down_opcode = read_opcode (jmp_down_opcode_idx);
JERRY_ASSERT (jmp_down_opcode.op_idx == __op__idx_jmp_down);
int_data->pos = (opcode_counter_t) (jmp_down_opcode_idx + jmp_down_opcode.data.jmp_down.opcode_count);
const opcode_counter_t function_code_begin_oc = (opcode_counter_t) (int_data->pos + 1);
const opcode_counter_t function_code_opcode_idx = (opcode_counter_t) (jmp_down_opcode_idx + 1);
int_data->pos = read_meta_opcode_counter (int_data);
ecma_string_t *function_name_string_p = ecma_new_ecma_string_from_lit_index (function_name_lit_idx);
ecma_completion_value_t ret_value = ecma_op_function_declaration (int_data->lex_env_p,
function_name_string_p,
function_code_opcode_idx,
function_code_begin_oc,
args_names,
args_number,
is_strict,
@@ -618,12 +615,9 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
fill_params_list (int_data, params_number, params_names);
const opcode_counter_t jmp_down_opcode_idx = (opcode_counter_t) (int_data->pos);
opcode_t jmp_down_opcode = read_opcode (jmp_down_opcode_idx);
JERRY_ASSERT (jmp_down_opcode.op_idx == __op__idx_jmp_down);
int_data->pos = (opcode_counter_t) (jmp_down_opcode_idx + jmp_down_opcode.data.jmp_down.opcode_count);
const opcode_counter_t function_code_begin_oc = (opcode_counter_t) (int_data->pos + 1);
const opcode_counter_t function_code_opcode_idx = (opcode_counter_t) (jmp_down_opcode_idx + 1);
int_data->pos = read_meta_opcode_counter (int_data);
ecma_object_t *scope_p;
ecma_string_t *function_name_string_p = NULL;
@@ -644,7 +638,7 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
params_number,
scope_p,
is_strict,
function_code_opcode_idx);
function_code_begin_oc);
ecma_completion_value_t ret_value = set_variable_value (int_data,
dst_var_idx,
@@ -1752,6 +1746,7 @@ opfunc_meta (opcode_t opdata, /**< operation data */
case OPCODE_META_TYPE_VARG_PROP_DATA:
case OPCODE_META_TYPE_VARG_PROP_GETTER:
case OPCODE_META_TYPE_VARG_PROP_SETTER:
case OPCODE_META_TYPE_OPCODE_COUNTER:
{
JERRY_UNREACHABLE ();
}
@@ -1760,6 +1755,40 @@ opfunc_meta (opcode_t opdata, /**< operation data */
JERRY_UNREACHABLE ();
} /* opfunc_meta */
/**
* Calculate opcode counter from 'meta' opcode's data arguments.
*
* @return opcode counter
*/
opcode_counter_t
calc_meta_opcode_counter_from_meta_data (const idx_t data_1, /**< first data argument */
const idx_t data_2) /**< second data argument */
{
opcode_counter_t counter;
counter = data_1;
counter = (opcode_counter_t) (counter << (sizeof (data_2) * JERRY_BITSINBYTE));
counter = (opcode_counter_t) (counter | data_2);
return counter;
} /* calc_meta_opcode_counter_from_meta_data */
/**
* Read opcode counter from current opcode,
* that should be 'meta' opcode of type 'opcode counter'.
*/
opcode_counter_t
read_meta_opcode_counter (int_data_t *int_data) /**< interpreter context */
{
opcode_t meta_opcode = read_opcode (int_data->pos);
JERRY_ASSERT (meta_opcode.data.meta.type == OPCODE_META_TYPE_OPCODE_COUNTER);
const idx_t data_1 = meta_opcode.data.meta.data_1;
const idx_t data_2 = meta_opcode.data.meta.data_2;
return calc_meta_opcode_counter_from_meta_data (data_1, data_2);
} /* read_meta_opcode_counter */
#define GETOP_DEF_1(a, name, field1) \
inline opcode_t getop_##name (idx_t arg1) \
{ \
+5 -1
View File
@@ -57,7 +57,8 @@ typedef enum
OPCODE_META_TYPE_VARG_PROP_DATA, /**< name (lit_idx) and value (var_idx) for a data property descriptor */
OPCODE_META_TYPE_VARG_PROP_GETTER, /**< name (lit_idx) and getter (var_idx) for an accessor property descriptor */
OPCODE_META_TYPE_VARG_PROP_SETTER, /**< name (lit_idx) and setter (var_idx) for an accessor property descriptor */
OPCODE_META_TYPE_END_WITH /**< end of with statement */
OPCODE_META_TYPE_END_WITH, /**< end of with statement */
OPCODE_META_TYPE_OPCODE_COUNTER /**< opcode counter */
} opcode_meta_type;
typedef struct
@@ -72,6 +73,9 @@ typedef struct
ecma_value_t *regs_p; /**< register variables */
} int_data_t;
opcode_counter_t calc_meta_opcode_counter_from_meta_data (const idx_t data_1, const idx_t data_2);
opcode_counter_t read_meta_opcode_counter (int_data_t *int_data);
#define OP_CALLS_AND_ARGS(p, a) \
p##_2 (a, call_0, lhs, name_lit_idx) \
p##_3 (a, call_1, lhs, name_lit_idx, arg1_lit_idx) \
+23 -8
View File
@@ -894,6 +894,20 @@ parse_argument_list (argument_list_type alt, idx_t obj)
return lhs;
}
static void
rewrite_meta_opcode_counter (opcode_counter_t meta_oc,
opcode_counter_t new_value)
{
JERRY_STATIC_ASSERT (sizeof (idx_t) == 1);
const idx_t data_1 = (idx_t) (new_value >> JERRY_BITSINBYTE);
const idx_t data_2 = (idx_t) (new_value & ((1 << JERRY_BITSINBYTE) - 1));
JERRY_ASSERT (new_value == calc_meta_opcode_counter_from_meta_data (data_1, data_2));
REWRITE_OPCODE_3 (meta_oc, meta, OPCODE_META_TYPE_OPCODE_COUNTER, data_1, data_2);
}
/* function_declaration
: 'function' LT!* Identifier LT!*
'(' (LT!* Identifier (LT!* ',' LT!* Identifier)*) ? LT!* ')' LT!* function_body
@@ -905,7 +919,7 @@ static void
parse_function_declaration (void)
{
idx_t name;
opcode_counter_t jmp_oc;
opcode_counter_t meta_oc;
assert_keyword (KW_FUNCTION);
@@ -916,8 +930,8 @@ parse_function_declaration (void)
skip_newlines ();
parse_argument_list (AL_FUNC_DECL, name);
jmp_oc = opcode_counter;
DUMP_OPCODE_1 (jmp_down, INVALID_VALUE);
meta_oc = opcode_counter;
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_OPCODE_COUNTER, INVALID_VALUE, INVALID_VALUE);
token_after_newlines_must_be (TOK_OPEN_BRACE);
@@ -929,7 +943,8 @@ parse_function_declaration (void)
next_token_must_be (TOK_CLOSE_BRACE);
DUMP_VOID_OPCODE (ret);
REWRITE_OPCODE_1 (jmp_oc, jmp_down, opcode_counter - jmp_oc);
rewrite_meta_opcode_counter (meta_oc, opcode_counter);
}
/* function_expression
@@ -939,7 +954,7 @@ static idx_t
parse_function_expression (void)
{
idx_t name, lhs;
opcode_counter_t jmp_oc;
opcode_counter_t meta_oc;
assert_keyword (KW_FUNCTION);
@@ -957,8 +972,8 @@ parse_function_expression (void)
skip_newlines ();
lhs = parse_argument_list (AL_FUNC_EXPR, name);
jmp_oc = opcode_counter;
DUMP_OPCODE_1 (jmp_down, INVALID_VALUE);
meta_oc = opcode_counter;
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_OPCODE_COUNTER, INVALID_VALUE, INVALID_VALUE);
token_after_newlines_must_be (TOK_OPEN_BRACE);
@@ -970,7 +985,7 @@ parse_function_expression (void)
token_after_newlines_must_be (TOK_CLOSE_BRACE);
DUMP_VOID_OPCODE (ret);
REWRITE_OPCODE_1 (jmp_oc, jmp_down, opcode_counter - jmp_oc);
rewrite_meta_opcode_counter (meta_oc, opcode_counter);
return lhs;
}
+3 -2
View File
@@ -30,16 +30,17 @@ function f1(x)
assert(t === false);
}
var i;
var t = true;
for(var i = 1; i <= 10; i++)
for(i = 1; i <= 10; i++)
{
f1(i);
}
t = false;
for(var i = 11; i <= 20; i++)
for(i = 11; i <= 20; i++)
{
f1(i);
}
+8 -7
View File
@@ -12,14 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
var k;
function f1()
{
k = 17;
f2();
function f2()
{
assert(k > 0);
@@ -32,9 +26,16 @@ function f1()
f2();
}
k = 17;
f2();
}
for(var i = 0; i < 10000; i++)
var k;
var i;
for(i = 0; i < 10000; i++)
{
f1();
}