Skip to content

Commit 7286812

Browse files
doujiang24agentzh
authored andcommitted
feature: added support for ARM64 (Aarch64).
now we require OpenResty's LuaJIT branch to work properly on ARM64 since we make use of the thread.exdata Lua API. On architectures other than ARM64, the thread.exdata API also saves the per-request global env table and closure objects for each light thread, which gives a nice ~10% speedup for the simplest Lua handler location loaded by wrk over HTTP 1.1. We now use proper userdata instead of lightuserdata for the ngx.shared.DICT Lua objects. we also mask off the bits higher than 47-bit of lightuserdata keys based on C static variable addresses. We also implemented the pure C API for the ndk.* API (to be used in lua-resty-core). Thanks Dejiang Zhu and Zexuan Luo for the development work of this patch. Thanks Cloudflare for sponsoring this work. Signed-off-by: Yichun Zhang (agentzh) <[email protected]>
1 parent f64ec8c commit 7286812

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1106
-215
lines changed

.travis.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ install:
7272
- git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx
7373
- git clone https://github.com/openresty/openresty-devel-utils.git
7474
- git clone https://github.com/openresty/mockeagain.git
75-
- git clone https://github.com/openresty/lua-cjson.git
75+
- git clone https://github.com/openresty/lua-cjson.git lua-cjson
7676
- git clone https://github.com/openresty/lua-upstream-nginx-module.git ../lua-upstream-nginx-module
7777
- git clone https://github.com/openresty/echo-nginx-module.git ../echo-nginx-module
7878
- git clone https://github.com/openresty/nginx-eval-module.git ../nginx-eval-module
@@ -89,7 +89,7 @@ install:
8989
- git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache
9090
- git clone https://github.com/openresty/lua-resty-mysql.git ../lua-resty-mysql
9191
- git clone https://github.com/openresty/stream-lua-nginx-module.git ../stream-lua-nginx-module
92-
- git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git
92+
- git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git luajit2
9393

9494
before_script:
9595
- mysql -uroot -e 'create database ngx_test; grant all on ngx_test.* to "ngx_test"@"%" identified by "ngx_test"; flush privileges;'

src/ngx_http_lua_accessby.c

+2
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,11 @@ ngx_http_lua_access_by_chunk(lua_State *L, ngx_http_request_t *r)
261261
/* move code closure to new coroutine */
262262
lua_xmove(L, co, 1);
263263

264+
#ifndef OPENRESTY_LUAJIT
264265
/* set closure's env table to new coroutine's globals table */
265266
ngx_http_lua_get_globals_table(co);
266267
lua_setfenv(co, -2);
268+
#endif
267269

268270
/* save nginx request in coroutine globals table */
269271
ngx_http_lua_set_req(co, r);

src/ngx_http_lua_balancer.c

+3
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ ngx_http_lua_balancer_by_chunk(lua_State *L, ngx_http_request_t *r)
362362

363363
/* init nginx context in Lua VM */
364364
ngx_http_lua_set_req(L, r);
365+
366+
#ifndef OPENRESTY_LUAJIT
365367
ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */);
366368

367369
/* {{{ make new env inheriting main thread's globals table */
@@ -372,6 +374,7 @@ ngx_http_lua_balancer_by_chunk(lua_State *L, ngx_http_request_t *r)
372374
/* }}} */
373375

374376
lua_setfenv(L, -2); /* set new running env for the code closure */
377+
#endif /* OPENRESTY_LUAJIT */
375378

376379
lua_pushcfunction(L, ngx_http_lua_traceback);
377380
lua_insert(L, 1); /* put it under chunk and args */

src/ngx_http_lua_bodyfilterby.c

+23-27
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ static void ngx_http_lua_body_filter_by_lua_env(lua_State *L,
3232
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
3333

3434

35-
/* key for the ngx_chain_t *in pointer in the Lua thread */
36-
#define ngx_http_lua_chain_key "__ngx_cl"
37-
38-
3935
/**
4036
* Set environment table for the given code closure.
4137
*
@@ -51,12 +47,14 @@ static void
5147
ngx_http_lua_body_filter_by_lua_env(lua_State *L, ngx_http_request_t *r,
5248
ngx_chain_t *in)
5349
{
54-
/* set nginx request pointer to current lua thread's globals table */
50+
ngx_http_lua_main_conf_t *lmcf;
51+
5552
ngx_http_lua_set_req(L, r);
5653

57-
lua_pushlightuserdata(L, in);
58-
lua_setglobal(L, ngx_http_lua_chain_key);
54+
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
55+
lmcf->body_filter_chain = in;
5956

57+
#ifndef OPENRESTY_LUAJIT
6058
/**
6159
* we want to create empty environment for current script
6260
*
@@ -79,6 +77,7 @@ ngx_http_lua_body_filter_by_lua_env(lua_State *L, ngx_http_request_t *r,
7977
/* }}} */
8078

8179
lua_setfenv(L, -2); /* set new running env for the code closure */
80+
#endif /* OPENRESTY_LUAJIT */
8281
}
8382

8483

@@ -236,8 +235,8 @@ ngx_http_lua_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
236235
ngx_int_t rc;
237236
uint16_t old_context;
238237
ngx_http_cleanup_t *cln;
239-
lua_State *L;
240238
ngx_chain_t *out;
239+
ngx_http_lua_main_conf_t *lmcf;
241240

242241
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
243242
"lua body filter for user lua code, uri \"%V\"", &r->uri);
@@ -299,11 +298,8 @@ ngx_http_lua_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
299298
return NGX_ERROR;
300299
}
301300

302-
L = ngx_http_lua_get_lua_vm(r, ctx);
303-
304-
lua_getglobal(L, ngx_http_lua_chain_key);
305-
out = lua_touserdata(L, -1);
306-
lua_pop(L, 1);
301+
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
302+
out = lmcf->body_filter_chain;
307303

308304
if (in == out) {
309305
return ngx_http_next_body_filter(r, in);
@@ -345,7 +341,7 @@ ngx_http_lua_body_filter_init(void)
345341

346342

347343
int
348-
ngx_http_lua_body_filter_param_get(lua_State *L)
344+
ngx_http_lua_body_filter_param_get(lua_State *L, ngx_http_request_t *r)
349345
{
350346
u_char *data, *p;
351347
size_t size;
@@ -354,6 +350,8 @@ ngx_http_lua_body_filter_param_get(lua_State *L)
354350
int idx;
355351
ngx_chain_t *in;
356352

353+
ngx_http_lua_main_conf_t *lmcf;
354+
357355
idx = luaL_checkint(L, 2);
358356

359357
dd("index: %d", idx);
@@ -363,8 +361,8 @@ ngx_http_lua_body_filter_param_get(lua_State *L)
363361
return 1;
364362
}
365363

366-
lua_getglobal(L, ngx_http_lua_chain_key);
367-
in = lua_touserdata(L, -1);
364+
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
365+
in = lmcf->body_filter_chain;
368366

369367
if (idx == 2) {
370368
/* asking for the eof argument */
@@ -442,6 +440,8 @@ ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
442440
ngx_chain_t *cl;
443441
ngx_chain_t *in;
444442

443+
ngx_http_lua_main_conf_t *lmcf;
444+
445445
idx = luaL_checkint(L, 2);
446446

447447
dd("index: %d", idx);
@@ -450,13 +450,13 @@ ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
450450
return luaL_error(L, "bad index: %d", idx);
451451
}
452452

453+
lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
454+
453455
if (idx == 2) {
454456
/* overwriting the eof flag */
455457
last = lua_toboolean(L, 3);
456458

457-
lua_getglobal(L, ngx_http_lua_chain_key);
458-
in = lua_touserdata(L, -1);
459-
lua_pop(L, 1);
459+
in = lmcf->body_filter_chain;
460460

461461
if (last) {
462462
ctx->seen_last_in_filter = 1;
@@ -521,9 +521,7 @@ ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
521521
case LUA_TNIL:
522522
/* discard the buffers */
523523

524-
lua_getglobal(L, ngx_http_lua_chain_key); /* key val */
525-
in = lua_touserdata(L, -1);
526-
lua_pop(L, 1);
524+
in = lmcf->body_filter_chain;
527525

528526
last = 0;
529527

@@ -557,9 +555,7 @@ ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
557555
lua_typename(L, type));
558556
}
559557

560-
lua_getglobal(L, ngx_http_lua_chain_key);
561-
in = lua_touserdata(L, -1);
562-
lua_pop(L, 1);
558+
in = lmcf->body_filter_chain;
563559

564560
last = 0;
565561

@@ -625,8 +621,8 @@ ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
625621
}
626622
}
627623

628-
lua_pushlightuserdata(L, cl);
629-
lua_setglobal(L, ngx_http_lua_chain_key);
624+
lmcf->body_filter_chain = cl;
625+
630626
return 0;
631627
}
632628

src/ngx_http_lua_bodyfilterby.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ ngx_int_t ngx_http_lua_body_filter_inline(ngx_http_request_t *r,
2121
ngx_chain_t *in);
2222
ngx_int_t ngx_http_lua_body_filter_file(ngx_http_request_t *r,
2323
ngx_chain_t *in);
24-
int ngx_http_lua_body_filter_param_get(lua_State *L);
24+
int ngx_http_lua_body_filter_param_get(lua_State *L, ngx_http_request_t *r);
2525
int ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
2626
ngx_http_lua_ctx_t *ctx);
2727

src/ngx_http_lua_cache.c

+15-2
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,14 @@ static ngx_int_t
3535
ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
3636
const char *key)
3737
{
38+
#ifndef OPENRESTY_LUAJIT
3839
int rc;
3940
u_char *err;
41+
#endif
4042

4143
/* get code cache table */
42-
lua_pushlightuserdata(L, &ngx_http_lua_code_cache_key);
44+
lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask(
45+
code_cache_key));
4346
lua_rawget(L, LUA_REGISTRYINDEX); /* sp++ */
4447

4548
dd("Code cache table to load: %p", lua_topointer(L, -1));
@@ -52,6 +55,10 @@ ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
5255
lua_getfield(L, -1, key); /* sp++ */
5356

5457
if (lua_isfunction(L, -1)) {
58+
#ifdef OPENRESTY_LUAJIT
59+
lua_remove(L, -2); /* sp-- */
60+
return NGX_OK;
61+
#else
5562
/* call closure factory to gen new closure */
5663
rc = lua_pcall(L, 0, 1, 0);
5764
if (rc == 0) {
@@ -73,6 +80,7 @@ ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
7380
key, err);
7481
lua_pop(L, 2);
7582
return NGX_ERROR;
83+
#endif /* OPENRESTY_LUAJIT */
7684
}
7785

7886
dd("Value associated with given key in code cache table is not code "
@@ -102,10 +110,13 @@ ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
102110
static ngx_int_t
103111
ngx_http_lua_cache_store_code(lua_State *L, const char *key)
104112
{
113+
#ifndef OPENRESTY_LUAJIT
105114
int rc;
115+
#endif
106116

107117
/* get code cache table */
108-
lua_pushlightuserdata(L, &ngx_http_lua_code_cache_key);
118+
lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask(
119+
code_cache_key));
109120
lua_rawget(L, LUA_REGISTRYINDEX);
110121

111122
dd("Code cache table to store: %p", lua_topointer(L, -1));
@@ -121,12 +132,14 @@ ngx_http_lua_cache_store_code(lua_State *L, const char *key)
121132
/* remove cache table, leave closure factory at top of stack */
122133
lua_pop(L, 1); /* closure */
123134

135+
#ifndef OPENRESTY_LUAJIT
124136
/* call closure factory to generate new closure */
125137
rc = lua_pcall(L, 0, 1, 0);
126138
if (rc != 0) {
127139
dd("Error: failed to call closure factory!!");
128140
return NGX_ERROR;
129141
}
142+
#endif
130143

131144
return NGX_OK;
132145
}

0 commit comments

Comments
 (0)