aboutsummaryrefslogtreecommitdiffstats
path: root/lib/asn1
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2011-08-01 16:11:33 +0200
committerLukas Larsson <[email protected]>2011-08-01 16:11:33 +0200
commita9b234504e155f1c44d7d1f93532c3224e10f439 (patch)
treec13d20223db3ac9e2b1ce9f0466be1570b5f15be /lib/asn1
parent673ca2801ca79c82ff9910ae7cd6578bff161851 (diff)
parentf1ed5142afc7198778df27c61db48ea0979f95e1 (diff)
downloadotp-a9b234504e155f1c44d7d1f93532c3224e10f439.tar.gz
otp-a9b234504e155f1c44d7d1f93532c3224e10f439.tar.bz2
otp-a9b234504e155f1c44d7d1f93532c3224e10f439.zip
Merge branch 'lukas/asn1/sof_length_and_default_optimizations/OTP-9440' into major
* lukas/asn1/sof_length_and_default_optimizations/OTP-9440: Use lists:mapfoldl instead for a tiny performance gain Move fixopt to do more work in ct than rt for opimized per_bin Optmized encode_length by doing some calculations at compile time rather than runtime Optmized decode_length by doing some calculations as compile time rather than runtime
Diffstat (limited to 'lib/asn1')
-rw-r--r--lib/asn1/src/asn1ct_constructed_per.erl114
-rw-r--r--lib/asn1/src/asn1rt_ber_bin_v2.erl8
-rw-r--r--lib/asn1/src/asn1rt_per_bin.erl4
3 files changed, 111 insertions, 15 deletions
diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index c1b6aa5713..b7c481547f 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -73,16 +73,23 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) ->
_ ->
ok
end,
- case {Optionals = optionals(to_textual_order(CompList)),CompList} of
- {[],EmptyCL} when EmptyCL == {[],[],[]};EmptyCL == {[],[]};EmptyCL == [] ->
+ case {Optionals = optionals(to_textual_order(CompList)),CompList,
+ is_optimized(Erule)} of
+ {[],EmptyCL,_} when EmptyCL == {[],[],[]};EmptyCL == {[],[]};EmptyCL == [] ->
emit(["%%Variable setting just to eliminate ",
"compiler warning for unused vars!",nl,
"_Val = ",{curr,val},",",nl]);
- {[],_} ->
+ {[],_,_} ->
emit([{next,val}," = ?RT_PER:list_to_record("]),
emit(["'",asn1ct_gen:list2rname(Typename),"'"]),
emit([", ",{curr,val},"),",nl]);
- _ ->
+ {_,_,true} ->
+ gen_fixoptionals(Optionals),
+ FixOpts = param_map(fun(Var) ->
+ {var,Var}
+ end,asn1ct_name:all(fixopt)),
+ emit({"{",{next,val},",Opt} = {",{curr,val},",[",FixOpts,"]},",nl});
+ {_,_,false} ->
Fixoptcall = ",Opt} = ?RT_PER:fixoptionals(",
emit({"{",{next,val},Fixoptcall,
{asis,Optionals},",",length(Optionals),
@@ -439,9 +446,7 @@ gen_encode_sof(Erule,Typename,SeqOrSetOf,D) when is_record(D,type) ->
_->
""
end,
- emit({nl,indent(3),"?RT_PER:encode_length(",
- {asis,SizeConstraint},
- ",length(Val)),",nl}),
+ gen_encode_length(SizeConstraint, is_optimized(Erule)),
emit({indent(3),"'enc_",asn1ct_gen:list2name(Typename),
"_components'(Val",ObjFun,", [])"}),
emit({nl,"].",nl}),
@@ -453,6 +458,42 @@ gen_encode_sof(Erule,Typename,SeqOrSetOf,D) when is_record(D,type) ->
end,
gen_encode_sof_components(Erule,Typename,SeqOrSetOf,NewComponentType).
+
+%% Logic copied from asn1_per_bin_rt2ct:encode_constrained_number
+gen_encode_length({Lb,Ub},true) when Ub =< 65535, Lb >= 0 ->
+ Range = Ub - Lb + 1,
+ V2 = ["(length(Val) - ",Lb,")"],
+ Encode = if
+ Range == 1 ->
+ "[]";
+ Range == 2 ->
+ {"[",V2,"]"};
+ Range =< 4 ->
+ {"[10,2,",V2,"]"};
+ Range =< 8 ->
+ {"[10,3,",V2,"]"};
+ Range =< 16 ->
+ {"[10,4,",V2,"]"};
+ Range =< 32 ->
+ {"[10,5,",V2,"]"};
+ Range =< 64 ->
+ {"[10,6,",V2,"]"};
+ Range =< 128 ->
+ {"[10,7,",V2,"]"};
+ Range =< 255 ->
+ {"[10,8,",V2,"]"};
+ Range =< 256 ->
+ {"[20,1,",V2,"]"};
+ Range =< 65536 ->
+ {"[20,2,<<",V2,":16>>]"};
+ true ->
+ {"?RT_PER:encode_length(",{asis,{Lb,Ub}},",length(Val))"}
+ end,
+ emit({nl,Encode,",",nl});
+gen_encode_length(SizeConstraint,_) ->
+ emit({nl,indent(3),"?RT_PER:encode_length(",
+ {asis,SizeConstraint},",length(Val)),",nl}).
+
gen_decode_sof(Erules,Typename,SeqOrSetOf,D) when is_record(D,type) ->
asn1ct_name:start(),
{_SeqOrSetOf,ComponentType} = D#type.def,
@@ -469,7 +510,8 @@ gen_decode_sof(Erules,Typename,SeqOrSetOf,D) when is_record(D,type) ->
_ ->
""
end,
- emit({nl,"{Num,Bytes1} = ?RT_PER:decode_length(Bytes,",{asis,SizeConstraint},"),",nl}),
+ gen_decode_length(SizeConstraint,
+ is_optimized(Erules)),
emit({"'dec_",asn1ct_gen:list2name(Typename),
"_components'(Num, Bytes1, telltype",ObjFun,", []).",nl}),
NewComponentType =
@@ -480,6 +522,41 @@ gen_decode_sof(Erules,Typename,SeqOrSetOf,D) when is_record(D,type) ->
end,
gen_decode_sof_components(Erules,Typename,SeqOrSetOf,NewComponentType).
+%% Logic copied from asn1_per_bin_rt2ct:decode_constrained_number
+gen_decode_length({Lb,Ub},true) when Ub =< 65535, Lb >= 0 ->
+ Range = Ub - Lb + 1,
+ Call = if
+ Range == 1 ->
+ "{0,Bytes}";
+ Range == 2 ->
+ "?RT_PER:getbits(Bytes,1)";
+ Range =< 4 ->
+ "?RT_PER:getbits(Bytes,2)";
+ Range =< 8 ->
+ "?RT_PER:getbits(Bytes,3)";
+ Range =< 16 ->
+ "?RT_PER:getbits(Bytes,4)";
+ Range =< 32 ->
+ "?RT_PER:getbits(Bytes,5)";
+ Range =< 64 ->
+ "?RT_PER:getbits(Bytes,6)";
+ Range =< 128 ->
+ "?RT_PER:getbits(Bytes,7)";
+ Range =< 255 ->
+ "?RT_PER:getbits(Bytes,8)";
+ Range =< 256 ->
+ "?RT_PER:getoctets(Bytes,1)";
+ Range =< 65536 ->
+ "?RT_PER:getoctets(Bytes,2)";
+ true ->
+ ["exit({not_supported,{integer_range,",Range,"}}"]
+ end,
+ emit({nl,"{Val,Remain} = ",Call,",",nl}),
+ emit({nl,"{Num,Bytes1} = {Val+",Lb,",Remain},",nl});
+gen_decode_length(SizeConstraint,_) ->
+ emit({nl,"{Num,Bytes1} = ?RT_PER:decode_length(Bytes,",
+ {asis,SizeConstraint},"),",nl}).
+
gen_encode_sof_components(Erule,Typename,SeqOrSetOf,Cont) ->
{ObjFun,ObjFun_Var} =
case Cont#type.tablecinf of
@@ -636,6 +713,27 @@ gen_dec_extension_value(_) ->
emit({"{Ext,",{next,bytes},"} = ?RT_PER:getext(",{curr,bytes},")"}),
asn1ct_name:new(bytes).
+gen_fixoptionals([{Pos,Def}|R]) ->
+ asn1ct_name:new(fixopt),
+ emit({{curr,fixopt}," = case element(",{asis,Pos},",",{curr,val},") of",nl,
+ "asn1_DEFAULT -> 0;",nl,
+ {asis,Def}," -> 0;",nl,
+ "_ -> 1",nl,
+ "end,",nl}),
+ gen_fixoptionals(R);
+gen_fixoptionals([Pos|R]) ->
+ gen_fixoptionals([{Pos,asn1_NOVALUE}|R]);
+gen_fixoptionals([]) ->
+ ok.
+
+
+param_map(Fun, [H]) ->
+ [Fun(H)];
+param_map(Fun, [H|T]) ->
+ [Fun(H),","|param_map(Fun,T)].
+
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Produce a list with positions (in the Value record) where
%% there are optional components, start with 2 because first element
diff --git a/lib/asn1/src/asn1rt_ber_bin_v2.erl b/lib/asn1/src/asn1rt_ber_bin_v2.erl
index a3bb570282..6947201167 100644
--- a/lib/asn1/src/asn1rt_ber_bin_v2.erl
+++ b/lib/asn1/src/asn1rt_ber_bin_v2.erl
@@ -1577,14 +1577,12 @@ e_object_identifier(V) when is_tuple(V) ->
e_object_identifier([E1, E2 | Tail]) ->
Head = 40*E1 + E2, % wow!
{H,Lh} = mk_object_val(Head),
- {R,Lr} = enc_obj_id_tail(Tail, [], 0),
+ {R,Lr} = lists:mapfoldl(fun enc_obj_id_tail/2,0,Tail),
{[H|R], Lh+Lr}.
-enc_obj_id_tail([], Ack, Len) ->
- {lists:reverse(Ack), Len};
-enc_obj_id_tail([H|T], Ack, Len) ->
+enc_obj_id_tail(H, Len) ->
{B, L} = mk_object_val(H),
- enc_obj_id_tail(T, [B|Ack], Len+L).
+ {B,Len+L}.
%%%%%%%%%%%
diff --git a/lib/asn1/src/asn1rt_per_bin.erl b/lib/asn1/src/asn1rt_per_bin.erl
index 6bbca26209..a124c7553d 100644
--- a/lib/asn1/src/asn1rt_per_bin.erl
+++ b/lib/asn1/src/asn1rt_per_bin.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2011. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -57,7 +57,7 @@
encode_NumericString/2, decode_NumericString/2,
encode_ObjectDescriptor/2, decode_ObjectDescriptor/1
]).
--export([complete_bytes/1]).
+-export([complete_bytes/1, getbits/2, getoctets/2]).
-define('16K',16384).
-define('32K',32768).