src: annotate with likely/unlikely

Reviewed-By: Fedor Indutny <fedor@indutny.com>
make-http-max-header-size-gyp-configurable
Fedor Indutny 10 years ago
parent 265f9d0edc
commit 3f7ef500bd

@ -68,20 +68,29 @@ do { \
break; break;
#ifdef __GNUC__
# define LIKELY(X) __builtin_expect(!!(X), 1)
# define UNLIKELY(X) __builtin_expect(!!(X), 0)
#else
# define LIKELY(X) (X)
# define UNLIKELY(X) (X)
#endif
/* Run the notify callback FOR, returning ER if it fails */ /* Run the notify callback FOR, returning ER if it fails */
#define CALLBACK_NOTIFY_(FOR, ER) \ #define CALLBACK_NOTIFY_(FOR, ER) \
do { \ do { \
assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \
\ \
if (settings->on_##FOR) { \ if (LIKELY(settings->on_##FOR)) { \
parser->state = CURRENT_STATE(); \ parser->state = CURRENT_STATE(); \
if (0 != settings->on_##FOR(parser)) { \ if (UNLIKELY(0 != settings->on_##FOR(parser))) { \
SET_ERRNO(HPE_CB_##FOR); \ SET_ERRNO(HPE_CB_##FOR); \
} \ } \
UPDATE_STATE(parser->state); \ UPDATE_STATE(parser->state); \
\ \
/* We either errored above or got paused; get out */ \ /* We either errored above or got paused; get out */ \
if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { \ if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \
return (ER); \ return (ER); \
} \ } \
} \ } \
@ -99,15 +108,16 @@ do { \
assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \
\ \
if (FOR##_mark) { \ if (FOR##_mark) { \
if (settings->on_##FOR) { \ if (LIKELY(settings->on_##FOR)) { \
parser->state = CURRENT_STATE(); \ parser->state = CURRENT_STATE(); \
if (0 != settings->on_##FOR(parser, FOR##_mark, (LEN))) { \ if (UNLIKELY(0 != \
settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \
SET_ERRNO(HPE_CB_##FOR); \ SET_ERRNO(HPE_CB_##FOR); \
} \ } \
UPDATE_STATE(parser->state); \ UPDATE_STATE(parser->state); \
\ \
/* We either errored above or got paused; get out */ \ /* We either errored above or got paused; get out */ \
if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { \ if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \
return (ER); \ return (ER); \
} \ } \
} \ } \
@ -145,7 +155,7 @@ do { \
#define COUNT_HEADER_SIZE(V) \ #define COUNT_HEADER_SIZE(V) \
do { \ do { \
parser->nread += (V); \ parser->nread += (V); \
if (parser->nread > (HTTP_MAX_HEADER_SIZE)) { \ if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) { \
SET_ERRNO(HPE_HEADER_OVERFLOW); \ SET_ERRNO(HPE_HEADER_OVERFLOW); \
goto error; \ goto error; \
} \ } \
@ -693,7 +703,7 @@ size_t http_parser_execute (http_parser *parser,
/* this state is used after a 'Connection: close' message /* this state is used after a 'Connection: close' message
* the parser will error out if it reads another message * the parser will error out if it reads another message
*/ */
if (ch == CR || ch == LF) if (LIKELY(ch == CR || ch == LF))
break; break;
SET_ERRNO(HPE_CLOSED_CONNECTION); SET_ERRNO(HPE_CLOSED_CONNECTION);
@ -724,7 +734,7 @@ size_t http_parser_execute (http_parser *parser,
parser->type = HTTP_RESPONSE; parser->type = HTTP_RESPONSE;
UPDATE_STATE(s_res_HT); UPDATE_STATE(s_res_HT);
} else { } else {
if (ch != 'E') { if (UNLIKELY(ch != 'E')) {
SET_ERRNO(HPE_INVALID_CONSTANT); SET_ERRNO(HPE_INVALID_CONSTANT);
goto error; goto error;
} }
@ -780,7 +790,7 @@ size_t http_parser_execute (http_parser *parser,
break; break;
case s_res_first_http_major: case s_res_first_http_major:
if (ch < '0' || ch > '9') { if (UNLIKELY(ch < '0' || ch > '9')) {
SET_ERRNO(HPE_INVALID_VERSION); SET_ERRNO(HPE_INVALID_VERSION);
goto error; goto error;
} }
@ -805,7 +815,7 @@ size_t http_parser_execute (http_parser *parser,
parser->http_major *= 10; parser->http_major *= 10;
parser->http_major += ch - '0'; parser->http_major += ch - '0';
if (parser->http_major > 999) { if (UNLIKELY(parser->http_major > 999)) {
SET_ERRNO(HPE_INVALID_VERSION); SET_ERRNO(HPE_INVALID_VERSION);
goto error; goto error;
} }
@ -815,7 +825,7 @@ size_t http_parser_execute (http_parser *parser,
/* first digit of minor HTTP version */ /* first digit of minor HTTP version */
case s_res_first_http_minor: case s_res_first_http_minor:
if (!IS_NUM(ch)) { if (UNLIKELY(!IS_NUM(ch))) {
SET_ERRNO(HPE_INVALID_VERSION); SET_ERRNO(HPE_INVALID_VERSION);
goto error; goto error;
} }
@ -832,7 +842,7 @@ size_t http_parser_execute (http_parser *parser,
break; break;
} }
if (!IS_NUM(ch)) { if (UNLIKELY(!IS_NUM(ch))) {
SET_ERRNO(HPE_INVALID_VERSION); SET_ERRNO(HPE_INVALID_VERSION);
goto error; goto error;
} }
@ -840,7 +850,7 @@ size_t http_parser_execute (http_parser *parser,
parser->http_minor *= 10; parser->http_minor *= 10;
parser->http_minor += ch - '0'; parser->http_minor += ch - '0';
if (parser->http_minor > 999) { if (UNLIKELY(parser->http_minor > 999)) {
SET_ERRNO(HPE_INVALID_VERSION); SET_ERRNO(HPE_INVALID_VERSION);
goto error; goto error;
} }
@ -886,7 +896,7 @@ size_t http_parser_execute (http_parser *parser,
parser->status_code *= 10; parser->status_code *= 10;
parser->status_code += ch - '0'; parser->status_code += ch - '0';
if (parser->status_code > 999) { if (UNLIKELY(parser->status_code > 999)) {
SET_ERRNO(HPE_INVALID_STATUS); SET_ERRNO(HPE_INVALID_STATUS);
goto error; goto error;
} }
@ -939,7 +949,7 @@ size_t http_parser_execute (http_parser *parser,
parser->flags = 0; parser->flags = 0;
parser->content_length = ULLONG_MAX; parser->content_length = ULLONG_MAX;
if (!IS_ALPHA(ch)) { if (UNLIKELY(!IS_ALPHA(ch))) {
SET_ERRNO(HPE_INVALID_METHOD); SET_ERRNO(HPE_INVALID_METHOD);
goto error; goto error;
} }
@ -976,7 +986,7 @@ size_t http_parser_execute (http_parser *parser,
case s_req_method: case s_req_method:
{ {
const char *matcher; const char *matcher;
if (ch == '\0') { if (UNLIKELY(ch == '\0')) {
SET_ERRNO(HPE_INVALID_METHOD); SET_ERRNO(HPE_INVALID_METHOD);
goto error; goto error;
} }
@ -1068,7 +1078,7 @@ size_t http_parser_execute (http_parser *parser,
} }
UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
if (CURRENT_STATE() == s_dead) { if (UNLIKELY(CURRENT_STATE() == s_dead)) {
SET_ERRNO(HPE_INVALID_URL); SET_ERRNO(HPE_INVALID_URL);
goto error; goto error;
} }
@ -1090,7 +1100,7 @@ size_t http_parser_execute (http_parser *parser,
goto error; goto error;
default: default:
UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
if (CURRENT_STATE() == s_dead) { if (UNLIKELY(CURRENT_STATE() == s_dead)) {
SET_ERRNO(HPE_INVALID_URL); SET_ERRNO(HPE_INVALID_URL);
goto error; goto error;
} }
@ -1123,7 +1133,7 @@ size_t http_parser_execute (http_parser *parser,
break; break;
default: default:
UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
if (CURRENT_STATE() == s_dead) { if (UNLIKELY(CURRENT_STATE() == s_dead)) {
SET_ERRNO(HPE_INVALID_URL); SET_ERRNO(HPE_INVALID_URL);
goto error; goto error;
} }
@ -1166,7 +1176,7 @@ size_t http_parser_execute (http_parser *parser,
/* first digit of major HTTP version */ /* first digit of major HTTP version */
case s_req_first_http_major: case s_req_first_http_major:
if (ch < '1' || ch > '9') { if (UNLIKELY(ch < '1' || ch > '9')) {
SET_ERRNO(HPE_INVALID_VERSION); SET_ERRNO(HPE_INVALID_VERSION);
goto error; goto error;
} }
@ -1183,7 +1193,7 @@ size_t http_parser_execute (http_parser *parser,
break; break;
} }
if (!IS_NUM(ch)) { if (UNLIKELY(!IS_NUM(ch))) {
SET_ERRNO(HPE_INVALID_VERSION); SET_ERRNO(HPE_INVALID_VERSION);
goto error; goto error;
} }
@ -1191,7 +1201,7 @@ size_t http_parser_execute (http_parser *parser,
parser->http_major *= 10; parser->http_major *= 10;
parser->http_major += ch - '0'; parser->http_major += ch - '0';
if (parser->http_major > 999) { if (UNLIKELY(parser->http_major > 999)) {
SET_ERRNO(HPE_INVALID_VERSION); SET_ERRNO(HPE_INVALID_VERSION);
goto error; goto error;
} }
@ -1201,7 +1211,7 @@ size_t http_parser_execute (http_parser *parser,
/* first digit of minor HTTP version */ /* first digit of minor HTTP version */
case s_req_first_http_minor: case s_req_first_http_minor:
if (!IS_NUM(ch)) { if (UNLIKELY(!IS_NUM(ch))) {
SET_ERRNO(HPE_INVALID_VERSION); SET_ERRNO(HPE_INVALID_VERSION);
goto error; goto error;
} }
@ -1225,7 +1235,7 @@ size_t http_parser_execute (http_parser *parser,
/* XXX allow spaces after digit? */ /* XXX allow spaces after digit? */
if (!IS_NUM(ch)) { if (UNLIKELY(!IS_NUM(ch))) {
SET_ERRNO(HPE_INVALID_VERSION); SET_ERRNO(HPE_INVALID_VERSION);
goto error; goto error;
} }
@ -1233,7 +1243,7 @@ size_t http_parser_execute (http_parser *parser,
parser->http_minor *= 10; parser->http_minor *= 10;
parser->http_minor += ch - '0'; parser->http_minor += ch - '0';
if (parser->http_minor > 999) { if (UNLIKELY(parser->http_minor > 999)) {
SET_ERRNO(HPE_INVALID_VERSION); SET_ERRNO(HPE_INVALID_VERSION);
goto error; goto error;
} }
@ -1244,7 +1254,7 @@ size_t http_parser_execute (http_parser *parser,
/* end of request line */ /* end of request line */
case s_req_line_almost_done: case s_req_line_almost_done:
{ {
if (ch != LF) { if (UNLIKELY(ch != LF)) {
SET_ERRNO(HPE_LF_EXPECTED); SET_ERRNO(HPE_LF_EXPECTED);
goto error; goto error;
} }
@ -1269,7 +1279,7 @@ size_t http_parser_execute (http_parser *parser,
c = TOKEN(ch); c = TOKEN(ch);
if (!c) { if (UNLIKELY(!c)) {
SET_ERRNO(HPE_INVALID_HEADER_TOKEN); SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
goto error; goto error;
} }
@ -1472,7 +1482,7 @@ size_t http_parser_execute (http_parser *parser,
break; break;
case h_content_length: case h_content_length:
if (!IS_NUM(ch)) { if (UNLIKELY(!IS_NUM(ch))) {
SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
goto error; goto error;
} }
@ -1544,7 +1554,7 @@ size_t http_parser_execute (http_parser *parser,
p = p_lf; p = p_lf;
else else
p = p_cr; p = p_cr;
} else if (p_lf != NULL) { } else if (UNLIKELY(p_lf != NULL)) {
p = p_lf; p = p_lf;
} else { } else {
p = data + len; p = data + len;
@ -1565,7 +1575,7 @@ size_t http_parser_execute (http_parser *parser,
if (ch == ' ') break; if (ch == ' ') break;
if (!IS_NUM(ch)) { if (UNLIKELY(!IS_NUM(ch))) {
SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
parser->header_state = h_state; parser->header_state = h_state;
goto error; goto error;
@ -1576,7 +1586,7 @@ size_t http_parser_execute (http_parser *parser,
t += ch - '0'; t += ch - '0';
/* Overflow? Test against a conservative limit for simplicity. */ /* Overflow? Test against a conservative limit for simplicity. */
if ((ULLONG_MAX - 10) / 10 < parser->content_length) { if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) {
SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
parser->header_state = h_state; parser->header_state = h_state;
goto error; goto error;
@ -1911,7 +1921,7 @@ size_t http_parser_execute (http_parser *parser,
assert(parser->flags & F_CHUNKED); assert(parser->flags & F_CHUNKED);
unhex_val = unhex[(unsigned char)ch]; unhex_val = unhex[(unsigned char)ch];
if (unhex_val == -1) { if (UNLIKELY(unhex_val == -1)) {
SET_ERRNO(HPE_INVALID_CHUNK_SIZE); SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
goto error; goto error;
} }
@ -1949,7 +1959,7 @@ size_t http_parser_execute (http_parser *parser,
t += unhex_val; t += unhex_val;
/* Overflow? Test against a conservative limit for simplicity. */ /* Overflow? Test against a conservative limit for simplicity. */
if ((ULLONG_MAX - 16) / 16 < parser->content_length) { if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) {
SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
goto error; goto error;
} }

Loading…
Cancel
Save