Skip to content

Commit a52f6bd

Browse files
Grouped all boolean flags in JSFunctionDef together as 1-bit bitfields. Reverted previous bool : 1 changes in other structs; only JSFunctionDef is optimized in this PR. This reduces the memory footprint for JSFunctionDef.
1 parent 88132e0 commit a52f6bd

File tree

1 file changed

+51
-48
lines changed

1 file changed

+51
-48
lines changed

quickjs.c

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,11 @@ struct JSRuntime {
283283

284284
JSValue current_exception;
285285
/* true if inside an out of memory error, to avoid recursing */
286-
bool in_out_of_memory : 1;
286+
bool in_out_of_memory;
287287
/* true if inside build_backtrace, to avoid recursing */
288-
bool in_build_stack_trace : 1;
288+
bool in_build_stack_trace;
289289
/* true if inside JS_FreeRuntime */
290-
bool in_free : 1;
290+
bool in_free;
291291

292292
struct JSStackFrame *current_stack_frame;
293293

@@ -314,7 +314,7 @@ struct JSRuntime {
314314
/* used to allocate, free and clone SharedArrayBuffers */
315315
JSSharedArrayBufferFunctions sab_funcs;
316316

317-
bool can_block : 1; /* true if Atomics.wait can block */
317+
bool can_block; /* true if Atomics.wait can block */
318318
uint32_t dump_flags : 24;
319319

320320
/* Shape hash table */
@@ -512,7 +512,7 @@ typedef struct JSWeakRefRecord {
512512

513513
typedef struct JSMapRecord {
514514
int ref_count; /* used during enumeration to avoid freeing the record */
515-
bool empty : 1; /* true if the record is deleted */
515+
bool empty; /* true if the record is deleted */
516516
struct JSMapState *map;
517517
struct list_head link;
518518
struct list_head hash_link;
@@ -521,7 +521,7 @@ typedef struct JSMapRecord {
521521
} JSMapRecord;
522522

523523
typedef struct JSMapState {
524-
bool is_weak : 1; /* true if WeakSet/WeakMap */
524+
bool is_weak; /* true if WeakSet/WeakMap */
525525
struct list_head records; /* list of JSMapRecord.link */
526526
uint32_t record_count;
527527
struct list_head *hash_table;
@@ -751,7 +751,7 @@ typedef enum JSIteratorHelperKindEnum {
751751

752752
typedef struct JSForInIterator {
753753
JSValue obj;
754-
bool is_array : 1;
754+
bool is_array;
755755
uint32_t array_length;
756756
uint32_t idx;
757757
} JSForInIterator;
@@ -785,13 +785,13 @@ typedef struct JSTypedArray {
785785
JSObject *buffer; /* based array buffer */
786786
uint32_t offset; /* byte offset in the array buffer */
787787
uint32_t length; /* byte length in the array buffer */
788-
bool track_rab : 1; /* auto-track length of backing array buffer */
788+
bool track_rab; /* auto-track length of backing array buffer */
789789
} JSTypedArray;
790790

791791
typedef struct JSAsyncFunctionState {
792792
JSValue this_val; /* 'this' generator argument */
793793
int argc; /* number of function arguments */
794-
bool throw_flag : 1; /* used to throw an exception in JS_CallInternal() */
794+
bool throw_flag; /* used to throw an exception in JS_CallInternal() */
795795
JSStackFrame frame;
796796
} JSAsyncFunctionState;
797797

@@ -800,7 +800,7 @@ typedef struct JSAsyncFunctionState {
800800
typedef struct JSAsyncFunctionData {
801801
JSGCObjectHeader header; /* must come first */
802802
JSValue resolving_funcs[2];
803-
bool is_active : 1; /* true if the async function state is valid */
803+
bool is_active; /* true if the async function state is valid */
804804
JSAsyncFunctionState func_state;
805805
} JSAsyncFunctionData;
806806

@@ -871,9 +871,9 @@ struct JSModuleDef {
871871
JSValue module_ns;
872872
JSValue func_obj; /* only used for JS modules */
873873
JSModuleInitFunc *init_func; /* only used for C modules */
874-
bool has_tla : 1; /* true if func_obj contains await */
875-
bool resolved : 1;
876-
bool func_created : 1;
874+
bool has_tla; /* true if func_obj contains await */
875+
bool resolved;
876+
bool func_created;
877877
JSModuleStatus status : 8;
878878
/* temp use during js_module_link() & js_module_evaluate() */
879879
int dfs_index, dfs_ancestor_index;
@@ -883,14 +883,14 @@ struct JSModuleDef {
883883
int async_parent_modules_count;
884884
int async_parent_modules_size;
885885
int pending_async_dependencies;
886-
bool async_evaluation : 1;
886+
bool async_evaluation;
887887
int64_t async_evaluation_timestamp;
888888
JSModuleDef *cycle_root;
889889
JSValue promise; /* corresponds to spec field: capability */
890890
JSValue resolving_funcs[2]; /* corresponds to spec field: capability */
891891
/* true if evaluation yielded an exception. It is saved in
892892
eval_exception */
893-
bool eval_has_exception : 1;
893+
bool eval_has_exception;
894894
JSValue eval_exception;
895895
JSValue meta_obj; /* for import.meta */
896896
};
@@ -1043,7 +1043,7 @@ typedef struct JSCallSiteData {
10431043
JSValue filename;
10441044
JSValue func;
10451045
JSValue func_name;
1046-
bool native : 1;
1046+
bool native;
10471047
int line_num;
10481048
int col_num;
10491049
} JSCallSiteData;
@@ -20008,18 +20008,20 @@ typedef enum JSParseExportEnum {
2000820008
JS_PARSE_EXPORT_DEFAULT,
2000920009
} JSParseExportEnum;
2001020010

20011-
2001220011
typedef struct JSFunctionDef {
2001320012
JSContext *ctx;
2001420013
struct JSFunctionDef *parent;
20014+
struct list_head child_list; /* list of JSFunctionDef.link */
20015+
struct list_head link;
20016+
2001520017
int parent_cpool_idx; /* index in the constant pool of the parent
2001620018
or -1 if none */
2001720019
int parent_scope_level; /* scope level in parent at point of definition */
20018-
struct list_head child_list; /* list of JSFunctionDef.link */
20019-
struct list_head link;
20020+
int eval_type; /* only valid if is_eval = true */
2002020021

20022+
/* Pack all boolean flags together as 1-bit fields to reduce struct size
20023+
while avoiding padding and compiler deoptimization. */
2002120024
bool is_eval : 1; /* true if eval code */
20022-
int eval_type; /* only valid if is_eval = true */
2002320025
bool is_global_var : 1; /* true if variables are not defined locally:
2002420026
eval global, eval module or non strict eval */
2002520027
bool is_func_expr : 1; /* true if function expression */
@@ -20041,13 +20043,17 @@ typedef struct JSFunctionDef {
2004120043
bool is_derived_class_constructor : 1;
2004220044
bool in_function_body : 1;
2004320045
bool backtrace_barrier : 1;
20046+
bool need_home_object : 1;
20047+
bool use_short_opcodes : 1; /* true if short opcodes are used in byte_code */
20048+
bool has_await : 1; /* true if await is used (used in module eval) */
20049+
2004420050
JSFunctionKindEnum func_kind : 8;
2004520051
JSParseFunctionEnum func_type : 7;
2004620052
uint8_t is_strict_mode : 1;
2004720053
JSAtom func_name; /* JS_ATOM_NULL if no name */
2004820054

2004920055
JSVarDef *vars;
20050-
uint32_t *vars_htab; /* indexes into vars[] */
20056+
uint32_t *vars_htab; // indexes into vars[]
2005120057
int var_size; /* allocated size for vars[] */
2005220058
int var_count;
2005320059
JSVarDef *args;
@@ -20066,7 +20072,6 @@ typedef struct JSFunctionDef {
2006620072
int new_target_var_idx; /* variable containg the 'new.target' value, -1 if none */
2006720073
int this_active_func_var_idx; /* variable containg the 'this.active_func' value, -1 if none */
2006820074
int home_object_var_idx;
20069-
bool need_home_object : 1;
2007020075

2007120076
int scope_level; /* index into fd->scopes if the current lexical scope */
2007220077
int scope_first; /* index into vd->vars of first lexically scoped variable */
@@ -20082,7 +20087,6 @@ typedef struct JSFunctionDef {
2008220087

2008320088
DynBuf byte_code;
2008420089
int last_opcode_pos; /* -1 if no last opcode */
20085-
bool use_short_opcodes : 1; /* true if short opcodes are used in byte_code */
2008620090

2008720091
LabelSlot *label_slots;
2008820092
int label_size; /* allocated size for label_slots[] */
@@ -20120,7 +20124,6 @@ typedef struct JSFunctionDef {
2012020124
int source_len;
2012120125

2012220126
JSModuleDef *module; /* != NULL when parsing a module */
20123-
bool has_await : 1; /* true if await is used (used in module eval) */
2012420127
} JSFunctionDef;
2012520128

2012620129
typedef struct JSToken {
@@ -20138,8 +20141,8 @@ typedef struct JSToken {
2013820141
} num;
2013920142
struct {
2014020143
JSAtom atom;
20141-
bool has_escape : 1;
20142-
bool is_reserved : 1;
20144+
bool has_escape;
20145+
bool is_reserved;
2014320146
} ident;
2014420147
struct {
2014520148
JSValue body;
@@ -20156,18 +20159,18 @@ typedef struct JSParseState {
2015620159
int col_num; /* column number of current offset */
2015720160
const char *filename;
2015820161
JSToken token;
20159-
bool got_lf : 1; /* true if got line feed before the current token */
20162+
bool got_lf; /* true if got line feed before the current token */
2016020163
const uint8_t *last_ptr;
2016120164
const uint8_t *buf_start;
2016220165
const uint8_t *buf_ptr;
2016320166
const uint8_t *buf_end;
20164-
const uint8_t *eol; /* most recently seen end-of-line character */
20165-
const uint8_t *mark; /* first token character, invariant: eol < mark */
20167+
const uint8_t *eol; // most recently seen end-of-line character
20168+
const uint8_t *mark; // first token character, invariant: eol < mark
2016620169

2016720170
/* current function code */
2016820171
JSFunctionDef *cur_func;
20169-
bool is_module : 1; /* parsing a module */
20170-
bool allow_html_comments : 1;
20172+
bool is_module; /* parsing a module */
20173+
bool allow_html_comments;
2017120174
} JSParseState;
2017220175

2017320176
typedef struct JSOpCode {
@@ -22701,7 +22704,7 @@ typedef struct JSParsePos {
2270122704
int last_col_num;
2270222705
int line_num;
2270322706
int col_num;
22704-
bool got_lf : 1;
22707+
bool got_lf;
2270522708
const uint8_t *ptr;
2270622709
const uint8_t *eol;
2270722710
const uint8_t *mark;
@@ -23114,9 +23117,9 @@ static JSAtom get_private_setter_name(JSContext *ctx, JSAtom name)
2311423117
typedef struct {
2311523118
JSFunctionDef *fields_init_fd;
2311623119
int computed_fields_count;
23117-
bool need_brand : 1;
23120+
bool need_brand;
2311823121
int brand_push_pos;
23119-
bool is_static : 1;
23122+
bool is_static;
2312023123
} ClassFieldsDef;
2312123124

2312223125
static __exception int emit_class_init_start(JSParseState *s,
@@ -35135,11 +35138,11 @@ typedef enum BCTagEnum {
3513535138
typedef struct BCWriterState {
3513635139
JSContext *ctx;
3513735140
DynBuf dbuf;
35138-
bool allow_bytecode : 1;
35139-
bool allow_sab : 1;
35140-
bool allow_reference : 1;
35141-
bool allow_source : 1;
35142-
bool allow_debug : 1;
35141+
bool allow_bytecode;
35142+
bool allow_sab;
35143+
bool allow_reference;
35144+
bool allow_source;
35145+
bool allow_debug;
3514335146
uint32_t first_atom;
3514435147
uint32_t *atom_to_idx;
3514535148
int atom_to_idx_size;
@@ -36002,9 +36005,9 @@ typedef struct BCReaderState {
3600236005
uint32_t idx_to_atom_count;
3600336006
JSAtom *idx_to_atom;
3600436007
int error_state;
36005-
bool allow_sab : 1;
36006-
bool allow_bytecode : 1;
36007-
bool allow_reference : 1;
36008+
bool allow_sab;
36009+
bool allow_bytecode;
36010+
bool allow_reference;
3600836011
/* object references */
3600936012
JSObject **objects;
3601036013
int objects_count;
@@ -41616,7 +41619,7 @@ static JSValue js_iterator_constructor(JSContext *ctx, JSValueConst new_target,
4161641619
// |index|, |count| and |running| because tcc miscompiles them
4161741620
typedef struct JSIteratorConcatData {
4161841621
int index, count; // elements (not pairs!) in values[] array
41619-
bool running : 1;
41622+
bool running;
4162041623
JSValue iter, next, values[]; // array of (object, method) pairs
4162141624
} JSIteratorConcatData;
4162241625

@@ -46223,8 +46226,8 @@ static JSValue js_regexp_Symbol_match(JSContext *ctx, JSValueConst this_val,
4622346226
typedef struct JSRegExpStringIteratorData {
4622446227
JSValue iterating_regexp;
4622546228
JSValue iterated_string;
46226-
bool global : 1;
46227-
bool unicode : 1;
46229+
bool global;
46230+
bool unicode;
4622846231
int done;
4622946232
} JSRegExpStringIteratorData;
4623046233

@@ -50419,13 +50422,13 @@ typedef struct JSPromiseData {
5041950422
JSPromiseStateEnum promise_state;
5042050423
/* 0=fulfill, 1=reject, list of JSPromiseReactionData.link */
5042150424
struct list_head promise_reactions[2];
50422-
bool is_handled : 1; /* Note: only useful to debug */
50425+
bool is_handled; /* Note: only useful to debug */
5042350426
JSValue promise_result;
5042450427
} JSPromiseData;
5042550428

5042650429
typedef struct JSPromiseFunctionDataResolved {
5042750430
int ref_count;
50428-
bool already_resolved : 1;
50431+
bool already_resolved;
5042950432
} JSPromiseFunctionDataResolved;
5043050433

5043150434
typedef struct JSPromiseFunctionData {
@@ -57090,7 +57093,7 @@ static JSValue js_atomics_isLockFree(JSContext *ctx,
5709057093

5709157094
typedef struct JSAtomicsWaiter {
5709257095
struct list_head link;
57093-
bool linked : 1;
57096+
bool linked;
5709457097
js_cond_t cond;
5709557098
int32_t *ptr;
5709657099
} JSAtomicsWaiter;

0 commit comments

Comments
 (0)