From bd0280e8d6570b5a1ce785b1518d3d7b6b68ec33 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Wed, 27 Jul 2016 15:53:21 -0700 Subject: Pick up changes from the Samba repository: commit 59d530c0b692dae41ea271bfdb473f212615041b Author: Douglas Bagnall Date: Tue Mar 1 14:18:52 2016 +1300 ndr: Use ndr_steal to avoid long lists When pulling complex structures like nt-acls, a long list of tokens may be produced. By removing tokens along the way with ndr_token_steal, future calls to retrieve from the token list are not as expensive. Signed-off-by: Douglas Bagnall Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam commit 9af628a488d2b628e6c33917be7030602eeb5fde Author: Douglas Bagnall Date: Fri Feb 26 17:01:37 2016 +1300 ndr: avoid unnecessary searches of token list When pulling complex structures like nt-acls, a long list of tokens may be produced. This change means the token list won't be walked in the buffers case if the switch value is not needed. Signed-off-by: Douglas Bagnall Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam Change-Id: I0e0ce345e5184e0cd180b0079dd693a7ed3f31ef Reviewed-on: https://code.wireshark.org/review/16736 Reviewed-by: Guy Harris --- tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 57 +++++++++++++++++++------- 1 file changed, 42 insertions(+), 15 deletions(-) (limited to 'tools/pidl') diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm index 09456c2325..94f4855dd6 100644 --- a/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm +++ b/tools/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm @@ -321,6 +321,25 @@ sub check_null_pointer($$$$) } } +sub is_deferred_switch_non_empty($) +{ + # 1 if there needs to be a deferred branch in an ndr_pull/push, + # 0 otherwise. + my ($e) = @_; + my $have_default = 0; + foreach my $el (@{$e->{ELEMENTS}}) { + if ($el->{CASE} eq "default") { + $have_default = 1; + } + if ($el->{TYPE} ne "EMPTY") { + if (ContainsDeferred($el, $el->{LEVELS}[0])) { + return 1; + } + } + } + return ! $have_default; +} + sub ParseArrayPullGetSize($$$$$$) { my ($self,$e,$l,$ndr,$var_name,$env) = @_; @@ -1923,11 +1942,13 @@ sub ParseUnionPush($$$$) $self->ParseUnionPushPrimitives($e, $ndr, $varname); $self->deindent; $self->pidl("}"); - $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); - $self->indent; - $self->ParseUnionPushDeferred($e, $ndr, $varname); - $self->deindent; - $self->pidl("}"); + if (is_deferred_switch_non_empty($e)) { + $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); + $self->indent; + $self->ParseUnionPushDeferred($e, $ndr, $varname); + $self->deindent; + $self->pidl("}"); + } $self->end_flags($e, $ndr); } @@ -2072,7 +2093,7 @@ sub ParseUnionPull($$$$) { my ($self,$e,$ndr,$varname) = @_; my $switch_type = $e->{SWITCH_TYPE}; - + my $needs_deferred_switch = is_deferred_switch_non_empty($e); $self->pidl("uint32_t level;"); if (defined($switch_type)) { if (Parse::Pidl::Typelist::typeIs($switch_type, "ENUM")) { @@ -2093,21 +2114,27 @@ sub ParseUnionPull($$$$) $self->start_flags($e, $ndr); - $self->pidl("level = ndr_pull_get_switch_value($ndr, $varname);"); - $self->pidl("NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);"); $self->pidl("if (ndr_flags & NDR_SCALARS) {"); $self->indent; + if (! $needs_deferred_switch) { + $self->pidl("/* This token is not used again */"); + $self->pidl("level = ndr_pull_steal_switch_value($ndr, $varname);"); + } else { + $self->pidl("level = ndr_pull_get_switch_value($ndr, $varname);"); + } $self->ParseUnionPullPrimitives($e,$ndr,$varname,$switch_type); $self->deindent; $self->pidl("}"); - - $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); - $self->indent; - $self->ParseUnionPullDeferred($e,$ndr,$varname); - $self->deindent; - $self->pidl("}"); - + if ($needs_deferred_switch) { + $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); + $self->indent; + $self->pidl("/* The token is not needed after this. */"); + $self->pidl("level = ndr_pull_steal_switch_value($ndr, $varname);"); + $self->ParseUnionPullDeferred($e,$ndr,$varname); + $self->deindent; + $self->pidl("}"); + } $self->add_deferred(); $self->end_flags($e, $ndr); -- cgit v1.2.1