[erlang-questions] hipe binary matching problem with R12B-1?

Steve Vinoski vinoski@REDACTED
Sat Mar 1 07:50:13 CET 2008


Just out of curiosity I've been going back through some Wide Finder
code to see how it fares under R12B-1, given the improvements in
binaries in this new release. Generally I'm seeing some pretty good
performance improvements with no code changes. Unfortunately I think
I'm also seeing a bug.

Below find the results of compiling and running the example code at
the bottom of this message. Using "c" to compile gives the right
answer; using "hipe:c" gives the wrong answer. This is on Redhat Linux
ES 4, with erlang R12B-1 built with smp, threads, hipe, and kernel
poll enabled.

Within the code, on the second instance of function check/2 you'll
find a commented-out guard. If you uncomment the guard, then the code
works correctly with both "c" and "hipe:c".

Note that if you want to try it for yourself, make sure there's a
space at the end of the string within the binary you pass to
wrong_result:get/1, as shown in shell prompts 2 and 4 below.

--steve


$ erl
Erlang (BEAM) emulator version 5.6.1 [source] [smp:8]
[async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.6.1  (abort with ^G)
1> c(wrong_result).
{ok,wrong_result}
2> wrong_result:get(<<"200x/2006/10/02/Linux-Journal ">>).
{ok,<<"2006/10/02/Linux-Journal">>}
3> hipe:c(wrong_result).
{ok,wrong_result}
4> wrong_result:get(<<"200x/2006/10/02/Linux-Journal ">>).
wrong_answer

========
-module(wrong_result).
-export([get/1]).

check(Bin) ->
    check(Bin, 0).
check(<<$ , _/binary>>, 0) ->
    {nomatch, 0};
check(Bin, Len) ->  %when Len < size(Bin) ->
    case Bin of
        <<Front:Len/binary, $ , _/binary>> ->
            {ok, Front};
        <<_:Len/binary, $., _/binary>> ->
            {nomatch, Len};
        _ ->
            check(Bin, Len+1)
    end.

get(<<>>) ->
    nomatch;
get(Bin) ->
    <<Front:16/binary, Tail/binary>> = Bin,
    case Front of
        <<_:3/binary,"x/",Y:4/binary,$/,M:2/binary,$/,D:2/binary,$/>> ->
            case check(Tail) of
                {ok, Match} ->
                    {ok, <<Y/binary,$/,M/binary,$/,D/binary,$/,Match/binary>>};
                {nomatch, Skip} ->
                    {skip, Skip+size(Front)};
                _ -> wrong_answer
            end;
        _ -> nomatch
    end.



More information about the erlang-questions mailing list