@@ -114,16 +114,16 @@ static VALUE bs_instrumentation_enabled_set(VALUE self, VALUE enabled);
114114static VALUE bs_readonly_set (VALUE self , VALUE enabled );
115115static VALUE bs_revalidation_set (VALUE self , VALUE enabled );
116116static VALUE bs_compile_option_crc32_set (VALUE self , VALUE crc32_v );
117- static VALUE bs_rb_fetch (VALUE self , VALUE cachedir_v , VALUE path_v , VALUE handler , VALUE args );
118- static VALUE bs_rb_precompile (VALUE self , VALUE cachedir_v , VALUE path_v , VALUE handler );
117+ static VALUE bs_rb_fetch (VALUE self , VALUE cachedir_v , VALUE namespace_v , VALUE path_v , VALUE handler , VALUE args );
118+ static VALUE bs_rb_precompile (VALUE self , VALUE cachedir_v , VALUE namespace_v , VALUE path_v , VALUE handler );
119119
120120/* Helpers */
121121enum cache_status {
122122 miss ,
123123 hit ,
124124 stale ,
125125};
126- static void bs_cache_path (const char * cachedir , const VALUE path , char (* cache_path )[MAX_CACHEPATH_SIZE ]);
126+ static void bs_cache_path (VALUE cachedir_v , VALUE namespace_v , VALUE path_v , char (* cache_path )[MAX_CACHEPATH_SIZE ]);
127127static int bs_read_key (int fd , struct bs_cache_key * key );
128128static enum cache_status cache_key_equal_fast_path (struct bs_cache_key * k1 , struct bs_cache_key * k2 );
129129static int cache_key_equal_slow_path (struct bs_cache_key * current_key , struct bs_cache_key * cached_key , const VALUE input_data );
@@ -143,7 +143,7 @@ static uint32_t get_ruby_platform(void);
143143 */
144144static int bs_storage_to_output (VALUE handler , VALUE args , VALUE storage_data , VALUE * output_data );
145145static VALUE prot_input_to_output (VALUE arg );
146- static void bs_input_to_output (VALUE handler , VALUE args , VALUE input_data , VALUE * output_data , int * exception_tag );
146+ static void bs_input_to_output (VALUE handler , VALUE args , VALUE input_data , VALUE pathval , VALUE * output_data , int * exception_tag );
147147static int bs_input_to_storage (VALUE handler , VALUE args , VALUE input_data , VALUE pathval , VALUE * storage_data );
148148struct s2o_data ;
149149struct i2o_data ;
@@ -302,8 +302,8 @@ Init_bootsnap(void)
302302 rb_define_module_function (rb_mBootsnap , "instrumentation_enabled=" , bs_instrumentation_enabled_set , 1 );
303303 rb_define_module_function (rb_mBootsnap_CompileCache_Native , "readonly=" , bs_readonly_set , 1 );
304304 rb_define_module_function (rb_mBootsnap_CompileCache_Native , "revalidation=" , bs_revalidation_set , 1 );
305- rb_define_module_function (rb_mBootsnap_CompileCache_Native , "fetch" , bs_rb_fetch , 4 );
306- rb_define_module_function (rb_mBootsnap_CompileCache_Native , "precompile" , bs_rb_precompile , 3 );
305+ rb_define_module_function (rb_mBootsnap_CompileCache_Native , "fetch" , bs_rb_fetch , 5 );
306+ rb_define_module_function (rb_mBootsnap_CompileCache_Native , "precompile" , bs_rb_precompile , 4 );
307307 rb_define_module_function (rb_mBootsnap_CompileCache_Native , "compile_option_crc32=" , bs_compile_option_crc32_set , 1 );
308308
309309 current_umask = umask (0777 );
@@ -420,13 +420,28 @@ get_ruby_platform(void)
420420 * The path will look something like: <cachedir>/12/34567890abcdef
421421 */
422422static void
423- bs_cache_path (const char * cachedir , const VALUE path , char (* cache_path )[MAX_CACHEPATH_SIZE ])
423+ bs_cache_path (VALUE cachedir_v , VALUE namespace_v , VALUE path_v , char (* cache_path )[MAX_CACHEPATH_SIZE ])
424424{
425- uint64_t hash = fnv1a_64 (path );
425+ FilePathValue (path_v );
426+
427+ Check_Type (cachedir_v , T_STRING );
428+ Check_Type (path_v , T_STRING );
429+ if (!NIL_P (namespace_v )) {
430+ Check_Type (namespace_v , T_STRING );
431+ }
432+
433+ if (RSTRING_LEN (cachedir_v ) > MAX_CACHEDIR_SIZE ) {
434+ rb_raise (rb_eArgError , "cachedir too long" );
435+ }
436+
437+ const char * cachedir = RSTRING_PTR (cachedir_v );
438+ const char * namespace = NIL_P (namespace_v ) ? "" : RSTRING_PTR (namespace_v );
439+
440+ uint64_t hash = fnv1a_64 (path_v );
426441 uint8_t first_byte = (hash >> (64 - 8 ));
427442 uint64_t remainder = hash & 0x00ffffffffffffff ;
428443
429- sprintf (* cache_path , "%s/%02" PRIx8 "/%014" PRIx64 , cachedir , first_byte , remainder );
444+ sprintf (* cache_path , "%s%s /%02" PRIx8 "/%014" PRIx64 , cachedir , namespace , first_byte , remainder );
430445}
431446
432447/*
@@ -498,25 +513,14 @@ static void bs_cache_key_digest(struct bs_cache_key *key,
498513 * conversions on the ruby VALUE arguments before passing them along.
499514 */
500515static VALUE
501- bs_rb_fetch (VALUE self , VALUE cachedir_v , VALUE path_v , VALUE handler , VALUE args )
516+ bs_rb_fetch (VALUE self , VALUE cachedir_v , VALUE namespace_v , VALUE path_v , VALUE handler , VALUE args )
502517{
503- FilePathValue (path_v );
504-
505- Check_Type (cachedir_v , T_STRING );
506- Check_Type (path_v , T_STRING );
507-
508- if (RSTRING_LEN (cachedir_v ) > MAX_CACHEDIR_SIZE ) {
509- rb_raise (rb_eArgError , "cachedir too long" );
510- }
511-
512- char * cachedir = RSTRING_PTR (cachedir_v );
513- char * path = RSTRING_PTR (path_v );
514518 char cache_path [MAX_CACHEPATH_SIZE ];
515519
516520 /* generate cache path to cache_path */
517- bs_cache_path (cachedir , path_v , & cache_path );
521+ bs_cache_path (cachedir_v , namespace_v , path_v , & cache_path );
518522
519- return bs_fetch (path , path_v , cache_path , handler , args );
523+ return bs_fetch (RSTRING_PTR ( path_v ) , path_v , cache_path , handler , args );
520524}
521525
522526/*
@@ -525,25 +529,13 @@ bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE path_v, VALUE handler, VALUE arg
525529 * and doesn't return the content.
526530 */
527531static VALUE
528- bs_rb_precompile (VALUE self , VALUE cachedir_v , VALUE path_v , VALUE handler )
532+ bs_rb_precompile (VALUE self , VALUE cachedir_v , VALUE namespace_v , VALUE path_v , VALUE handler )
529533{
530- FilePathValue (path_v );
531-
532- Check_Type (cachedir_v , T_STRING );
533- Check_Type (path_v , T_STRING );
534-
535- if (RSTRING_LEN (cachedir_v ) > MAX_CACHEDIR_SIZE ) {
536- rb_raise (rb_eArgError , "cachedir too long" );
537- }
538-
539- char * cachedir = RSTRING_PTR (cachedir_v );
540- char * path = RSTRING_PTR (path_v );
541534 char cache_path [MAX_CACHEPATH_SIZE ];
542-
543535 /* generate cache path to cache_path */
544- bs_cache_path (cachedir , path_v , & cache_path );
536+ bs_cache_path (cachedir_v , namespace_v , path_v , & cache_path );
545537
546- return bs_precompile (path , path_v , cache_path , handler );
538+ return bs_precompile (RSTRING_PTR ( path_v ) , path_v , cache_path , handler );
547539}
548540
549541static int bs_open_noatime (const char * path , int flags ) {
@@ -963,7 +955,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
963955 exception_message = path_v ;
964956 goto fail_errno ;
965957 }
966- bs_input_to_output (handler , args , input_data , & output_data , & exception_tag );
958+ bs_input_to_output (handler , args , input_data , path_v , & output_data , & exception_tag );
967959 if (exception_tag != 0 ) goto raise ;
968960 goto succeed ;
969961 } else if (res == CACHE_MISS || res == CACHE_STALE ) valid_cache = 0 ;
@@ -989,7 +981,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
989981 /* If input_to_storage raised Bootsnap::CompileCache::Uncompilable, don't try
990982 * to cache anything; just return input_to_output(input_data) */
991983 if (storage_data == rb_cBootsnap_CompileCache_UNCOMPILABLE ) {
992- bs_input_to_output (handler , args , input_data , & output_data , & exception_tag );
984+ bs_input_to_output (handler , args , input_data , path_v , & output_data , & exception_tag );
993985 if (exception_tag != 0 ) goto raise ;
994986 goto succeed ;
995987 }
@@ -1009,7 +1001,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
10091001
10101002 if (output_data == rb_cBootsnap_CompileCache_UNCOMPILABLE ) {
10111003 /* If storage_to_output returned `Uncompilable` we fallback to `input_to_output` */
1012- bs_input_to_output (handler , args , input_data , & output_data , & exception_tag );
1004+ bs_input_to_output (handler , args , input_data , path_v , & output_data , & exception_tag );
10131005 if (exception_tag != 0 ) goto raise ;
10141006 } else if (NIL_P (output_data )) {
10151007 /* If output_data is nil, delete the cache entry and generate the output
@@ -1023,7 +1015,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
10231015 goto fail_errno ;
10241016 }
10251017 }
1026- bs_input_to_output (handler , args , input_data , & output_data , & exception_tag );
1018+ bs_input_to_output (handler , args , input_data , path_v , & output_data , & exception_tag );
10271019 if (exception_tag != 0 ) goto raise ;
10281020 }
10291021
@@ -1181,6 +1173,7 @@ struct i2o_data {
11811173 VALUE handler ;
11821174 VALUE args ;
11831175 VALUE input_data ;
1176+ VALUE pathval ;
11841177};
11851178
11861179struct i2s_data {
@@ -1210,12 +1203,13 @@ bs_storage_to_output(VALUE handler, VALUE args, VALUE storage_data, VALUE * outp
12101203}
12111204
12121205static void
1213- bs_input_to_output (VALUE handler , VALUE args , VALUE input_data , VALUE * output_data , int * exception_tag )
1206+ bs_input_to_output (VALUE handler , VALUE args , VALUE input_data , VALUE path_v , VALUE * output_data , int * exception_tag )
12141207{
12151208 struct i2o_data i2o_data = {
12161209 .handler = handler ,
12171210 .args = args ,
12181211 .input_data = input_data ,
1212+ .pathval = path_v ,
12191213 };
12201214 * output_data = rb_protect (prot_input_to_output , (VALUE )& i2o_data , exception_tag );
12211215}
@@ -1224,7 +1218,7 @@ static VALUE
12241218prot_input_to_output (VALUE arg )
12251219{
12261220 struct i2o_data * data = (struct i2o_data * )arg ;
1227- return rb_funcall (data -> handler , rb_intern ("input_to_output" ), 2 , data -> input_data , data -> args );
1221+ return rb_funcall (data -> handler , rb_intern ("input_to_output" ), 3 , data -> input_data , data -> pathval , data -> args );
12281222}
12291223
12301224static VALUE
0 commit comments