2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-15 13:02:11 +00:00

Optimize member function calls to use less string manipulation.

[SVN r83937]
This commit is contained in:
Steven Watanabe
2013-04-16 23:54:54 +00:00
parent 1f1f57dd08
commit 061f998f43
8 changed files with 181 additions and 31 deletions

View File

@@ -54,35 +54,28 @@ void unknown_rule( FRAME *, char const * key, module_t *, OBJECT * rule_name );
* evaluate_rule() - execute a rule invocation
*/
LIST * evaluate_rule( OBJECT * rulename, FRAME * frame )
LIST * evaluate_rule( RULE * rule, OBJECT * rulename, FRAME * frame )
{
LIST * result = L0;
RULE * rule;
profile_frame prof[ 1 ];
module_t * prev_module = frame->module;
rule = bindrule( rulename, frame->module );
if ( DEBUG_COMPILE )
{
/* Try hard to indicate in which module the rule is going to execute. */
if ( rule->module != frame->module && rule->procedure && !object_equal(
rulename, function_rulename( rule->procedure ) ) )
char buf[ 256 ] = "";
if ( rule->module->name )
{
char buf[ 256 ] = "";
if ( rule->module->name )
strncat( buf, object_str( rule->module->name ), sizeof( buf ) -
1 );
strncat( buf, ".", sizeof( buf ) - 1 );
if ( strncmp( buf, object_str( rule->name ), strlen( buf ) ) == 0 )
{
strncat( buf, object_str( rule->module->name ), sizeof( buf ) -
1 );
strncat( buf, ".", sizeof( buf ) - 1 );
buf[ 0 ] = 0;
}
strncat( buf, object_str( rule->name ), sizeof( buf ) - 1 );
debug_compile( 1, buf, frame );
}
else
{
debug_compile( 1, object_str( rulename ), frame );
}
strncat( buf, object_str( rule->name ), sizeof( buf ) - 1 );
debug_compile( 1, buf, frame );
lol_print( frame->args );
printf( "\n" );
@@ -238,7 +231,7 @@ LIST * call_rule( OBJECT * rulename, FRAME * caller_frame, ... )
}
va_end( va );
result = evaluate_rule( rulename, inner );
result = evaluate_rule( bindrule( rulename, inner->module ), rulename, inner );
frame_free( inner );

View File

@@ -20,10 +20,11 @@
#include "frames.h"
#include "lists.h"
#include "object.h"
#include "rules.h"
void compile_builtins();
LIST * evaluate_rule( OBJECT * rulename, FRAME * );
LIST * evaluate_rule( RULE * rule, OBJECT * rulename, FRAME * );
LIST * call_rule( OBJECT * rulename, FRAME * caller_frame, ... );
/* Flags for compile_set(), etc */

View File

@@ -96,6 +96,7 @@ void backtrace_line( FRAME * );
#define INSTR_GET_ON 65
#define INSTR_CALL_RULE 39
#define INSTR_CALL_MEMBER_RULE 66
#define INSTR_APPLY_MODIFIERS 40
#define INSTR_APPLY_INDEX 41
@@ -472,12 +473,111 @@ static LIST * function_call_rule( JAM_FUNCTION * function, FRAME * frame,
}
}
result = evaluate_rule( rulename, inner );
result = evaluate_rule( bindrule( rulename, inner->module ), rulename, inner );
frame_free( inner );
object_free( rulename );
return result;
}
static LIST * function_call_member_rule( JAM_FUNCTION * function, FRAME * frame, STACK * s, int n_args, OBJECT * rulename, OBJECT * file, int line )
{
FRAME inner[ 1 ];
int i;
LIST * first = stack_pop( s );
LIST * result = L0;
LIST * trailing;
RULE * rule;
module_t * module;
OBJECT * real_rulename = 0;
frame->file = file;
frame->line = line;
if ( list_empty( first ) )
{
backtrace_line( frame );
printf( "warning: object is empty\n" );
backtrace( frame );
list_free( first );
for( i = 0; i < n_args; ++i )
{
list_free( stack_pop( s ) );
}
return result;
}
/* FIXME: handle generic case */
assert( list_length( first ) == 1 );
module = bindmodule( list_front( first ) );
if ( module->class_module )
{
rule = bindrule( rulename, module );
real_rulename = object_copy( function_rulename( rule->procedure ) );
}
else
{
string buf[ 1 ];
string_new( buf );
string_append( buf, object_str( list_front( first ) ) );
string_push_back( buf, '.' );
string_append( buf, object_str( rulename ) );
real_rulename = object_new( buf->value );
string_free( buf );
rule = bindrule( real_rulename, frame->module );
}
frame_init( inner );
inner->prev = frame;
inner->prev_user = frame->module->user_module ? frame : frame->prev_user;
inner->module = frame->module; /* This gets fixed up in evaluate_rule(), below. */
for( i = 0; i < n_args; ++i )
{
lol_add( inner->args, stack_at( s, n_args - i - 1 ) );
}
for( i = 0; i < n_args; ++i )
{
stack_pop( s );
}
if ( list_length( first ) > 1 )
{
string buf[ 1 ];
LIST * trailing = L0;
LISTITER iter = list_begin( first ), end = list_end( first );
iter = list_next( iter );
string_new( buf );
for ( ; iter != end; iter = list_next( iter ) )
{
string_append( buf, object_str( list_item( iter ) ) );
string_push_back( buf, '.' );
string_append( buf, object_str( rulename ) );
trailing = list_push_back( trailing, object_new( buf->value ) );
string_truncate( buf, 0 );
}
string_free( buf );
if ( inner->args->count == 0 )
lol_add( inner->args, trailing );
else
{
LIST * * const l = &inner->args->list[ 0 ];
*l = list_append( trailing, *l );
}
}
result = evaluate_rule( rule, real_rulename, inner );
frame_free( inner );
object_free( rulename );
object_free( real_rulename );
return result;
}
/* Variable expansion */
@@ -2557,11 +2657,29 @@ static void compile_parse( PARSE * parse, compiler * c, int result_location )
current_file = object_str( parse->file );
current_line = parse->line;
group = parse_expansion( &s );
var_parse_group_compile( group, c );
var_parse_group_free( group );
compile_emit( c, INSTR_CALL_RULE, n );
compile_emit( c, compile_emit_constant( c, parse->string ), parse->line
);
if ( group->elems->size == 2 &&
dynamic_array_at( VAR_PARSE *, group->elems, 0 )->type == VAR_PARSE_TYPE_VAR &&
dynamic_array_at( VAR_PARSE *, group->elems, 1 )->type == VAR_PARSE_TYPE_STRING &&
( object_str( ( (VAR_PARSE_STRING *)dynamic_array_at( VAR_PARSE *, group->elems, 1 ) )->s )[ 0 ] == '.' ) )
{
VAR_PARSE_STRING * access = (VAR_PARSE_STRING *)dynamic_array_at( VAR_PARSE *, group->elems, 1 );
OBJECT * member = object_new( object_str( access->s ) + 1 );
/* Emit the object */
var_parse_var_compile( (VAR_PARSE_VAR *)dynamic_array_at( VAR_PARSE *, group->elems, 0 ), c );
var_parse_group_free( group );
compile_emit( c, INSTR_CALL_MEMBER_RULE, n );
compile_emit( c, compile_emit_constant( c, member ), parse->line );
object_free( member );
}
else
{
var_parse_group_compile( group, c );
var_parse_group_free( group );
compile_emit( c, INSTR_CALL_RULE, n );
compile_emit( c, compile_emit_constant( c, parse->string ), parse->line );
}
adjust_result( c, RESULT_STACK, result_location );
}
else if ( parse->type == PARSE_RULES )
@@ -2840,7 +2958,7 @@ static void type_check_range( OBJECT * type_name, LISTITER iter, LISTITER end,
/* Prepare the argument list */
lol_add( frame->args, list_new( object_copy( list_item( iter ) ) ) );
error = evaluate_rule( type_name, frame );
error = evaluate_rule( bindrule( type_name, frame->module ), type_name, frame );
if ( !list_empty( error ) )
argument_error( object_str( list_front( error ) ), called, caller,
@@ -3396,6 +3514,7 @@ FUNCTION * function_bind_variables( FUNCTION * f, module_t * module,
case INSTR_APPEND: op_code = INSTR_APPEND_FIXED; break;
case INSTR_DEFAULT: op_code = INSTR_DEFAULT_FIXED; break;
case INSTR_RETURN: return (FUNCTION *)new_func;
case INSTR_CALL_MEMBER_RULE:
case INSTR_CALL_RULE: ++i; continue;
case INSTR_PUSH_MODULE:
{
@@ -4114,6 +4233,15 @@ LIST * function_run( FUNCTION * function_, FRAME * frame, STACK * s )
break;
}
case INSTR_CALL_MEMBER_RULE:
{
OBJECT * rule_name = function_get_constant( function, code[1].op_code );
LIST * result = function_call_member_rule( function, frame, s, code->arg, rule_name, function->file, code[1].arg );
stack_push( s, result );
++code;
break;
}
case INSTR_RULE:
function_set_rule( function, frame, s, code->arg );
break;

View File

@@ -96,9 +96,10 @@ void headers( TARGET * t )
if ( lol_get( frame->args, 1 ) )
{
OBJECT * rulename = list_front( hdrrule );
/* The third argument to HDRRULE is the bound name of $(<). */
lol_add( frame->args, list_new( object_copy( t->boundname ) ) );
list_free( evaluate_rule( list_front( hdrrule ), frame ) );
list_free( evaluate_rule( bindrule( rulename, frame->module ), rulename, frame ) );
}
/* Clean up. */

View File

@@ -739,6 +739,7 @@ static void call_timing_rule( TARGET * target, timing_info const * const time )
/* Prepare the argument list. */
FRAME frame[ 1 ];
OBJECT * rulename = list_front( timing_rule );
frame_init( frame );
/* args * :: $(__TIMING_RULE__[2-]) */
@@ -756,7 +757,7 @@ static void call_timing_rule( TARGET * target, timing_info const * const time )
outf_double( time->system ) ) );
/* Call the rule. */
evaluate_rule( list_front( timing_rule ), frame );
evaluate_rule( bindrule( rulename , root_module() ), rulename, frame );
/* Clean up. */
frame_free( frame );
@@ -795,6 +796,7 @@ static void call_action_rule
/* Prepare the argument list. */
FRAME frame[ 1 ];
OBJECT * rulename = list_front( action_rule );
frame_init( frame );
/* args * :: $(__ACTION_RULE__[2-]) */
@@ -822,7 +824,7 @@ static void call_action_rule
lol_add( frame->args, L0 );
/* Call the rule. */
evaluate_rule( list_front( action_rule ), frame );
evaluate_rule( bindrule( rulename, root_module() ), rulename, frame );
/* Clean up. */
frame_free( frame );

View File

@@ -62,6 +62,7 @@ LIST * sequence_transform( FRAME * frame, int flags )
OBJECT * function_name = list_front( function );
LISTITER args_begin = list_next( list_begin( function ) ), args_end = list_end( function );
LISTITER iter = list_begin( sequence ), end = list_end( sequence );
RULE * rule = bindrule( function_name, frame->prev->module );
for ( ; iter != end; iter = list_next( iter ) )
{
@@ -73,7 +74,7 @@ LIST * sequence_transform( FRAME * frame, int flags )
inner->module = frame->prev->module;
lol_add( inner->args, list_push_back( list_copy_range( function, args_begin, args_end ), object_copy( list_item( iter ) ) ) );
result = list_append( result, evaluate_rule( function_name, inner ) );
result = list_append( result, evaluate_rule( rule, function_name, inner ) );
frame_free( inner );
}

View File

@@ -54,7 +54,10 @@ void call_bind_rule( OBJECT * target_, OBJECT * boundname_ )
lol_add( frame->args, list_new( boundname ) );
if ( lol_get( frame->args, 1 ) )
list_free( evaluate_rule( list_front( bind_rule ), frame ) );
{
OBJECT * rulename = list_front( bind_rule );
list_free( evaluate_rule( bindrule( rulename, root_module() ), rulename, frame ) );
}
/* Clean up */
frame_free( frame );